diff --git a/README.md b/README.md index 472a128..94c1ad5 100644 --- a/README.md +++ b/README.md @@ -75,20 +75,21 @@ The compiler is command line driven, and creates an executable .prg file. * -n : create pure native code for all functions * -d : define a symbol (e.g. NOFLOAT or NOLONG to avoid float/long code in printf) * -O1 or -O : default optimizations -* -O0: disable optimizations -* -O2: more aggressive speed optimizations including auto inline of small functions -* -O3: aggressive optimization for speed -* -Os: optimize for size -* -Oi: enable auto inline of small functions (part of O2/O3) -* -Oa: optimize inline assembler (part of O2/O3) -* -Oz: enable auto placement of global variables in zero page (part of O3) -* -g: create source level debug info and add source line numbers to asm listing -* -tf: target format, may be prg, crt or bin +* -O0 : disable optimizations +* -O2 : more aggressive speed optimizations including auto inline of small functions +* -O3 : aggressive optimization for speed +* -Os : optimize for size +* -Oi : enable auto inline of small functions (part of O2/O3) +* -Oa : optimize inline assembler (part of O2/O3) +* -Oz : enable auto placement of global variables in zero page (part of O3) +* -g : create source level debug info and add source line numbers to asm listing +* -tf : target format, may be prg, crt or bin * -tm : target machine * -d64 : create a d64 disk image * -f : add a binary file to the disk image * -fz : add a compressed binary file to the disk image * -xz : extended zero page usage, more zero page space, but no return to basic +* -cid : cartridge type ID, used by vice emulator A list of source files can be provided. @@ -114,6 +115,24 @@ A list of source files can be provided. * atari : Atari 8bit systems, (0x2000..0xbc00) * x16 : Commander X16, (0x0800..0x9f00) +#### C64 Cartridge formats + +Three cartridge formats are supported + +* -tf=crt : creates an easyflash cartridge with common code expanded from bank 0 into memory +* -tf=crt8 : creates a generic 8KB cartridge from 0x8000-0xa000 with autostart header +* -tf=crt16 : creates a generic 16KB cartridge from 0x8000-0xc000 with autostart header +* -cid=nnn : specifies the type ID, used by vice emul + +The easyflash format cartridge expands the first 16KB bank into memory to provide a +common area of "code" and "data". This is taken from the standard code and data section in region "main". + +The generic cartridge formats use the region "rom" from the first bank and include an autostart header. +The sections "code" and "data" are placed into this "rom" region. The "bss", "stack" and "heap" sections +are placed into the "main" region from 0x0800 to 0x8000. + +The layout can be changed by defining own "main" and "rom" regions. + ### Files generated The main file generated by the compiler is a .prg, .crt or .bin with the code and constant data. Additional files are created to support debugging and analysis: diff --git a/include/crt.c b/include/crt.c index da1578c..d4087bf 100644 --- a/include/crt.c +++ b/include/crt.c @@ -64,7 +64,7 @@ __asm p4irq __asm startup { st0: -#ifdef OSCAR_TARGET_CRT16 +#ifdef OSCAR_TARGET_CRT_EASYFLASH byt 0x09 byt 0x80 byt 0xbc @@ -165,6 +165,25 @@ w0: lda #$36 sta $01 +#elif defined(OSCAR_TARGET_CRT8) || defined(OSCAR_TARGET_CRT16) + +// Start at 0x8000 autostart vectors + + byt 0x09 + byt 0x80 + byt 0x09 + byt 0x80 + byt 0xc3 + byt 0xc2 + byt 0xcd + byt 0x38 + byt 0x30 + + lda #$e7 + sta $01 + lda #$2f + sta $00 + #elif defined(OSCAR_TARGET_BIN) #elif defined(__ATARI__) diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index c8fdfbb..575fff5 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -33,6 +33,8 @@ Compiler::Compiler(void) mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker, mCompilationUnits->mSectionCode); mInterCodeModule = new InterCodeModule(mErrors, mLinker); mGlobalAnalyzer = new GlobalAnalyzer(mErrors, mLinker); + + mCartridgeID = 0x0000; } Compiler::~Compiler(void) @@ -350,6 +352,11 @@ bool Compiler::GenerateCode(void) break; } } + else if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16)) + { + regionStartup = mLinker->AddRegion(identStartup, 0x8000, 0x8080); + regionStartup->mCartridgeBanks = 1; + } else regionStartup = mLinker->AddRegion(identStartup, 0x0800, 0x0900); } @@ -469,7 +476,11 @@ bool Compiler::GenerateCode(void) switch (mTargetMachine) { case TMACH_C64: - regionMain = mLinker->AddRegion(identMain, 0x0880, 0xa000); + + if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16)) + regionMain = mLinker->AddRegion(identMain, 0x0800, 0x8000); + else + regionMain = mLinker->AddRegion(identMain, 0x0880, 0xa000); break; case TMACH_X16: regionMain = mLinker->AddRegion(identMain, 0x0880, 0x9f00); @@ -540,6 +551,20 @@ bool Compiler::GenerateCode(void) } } + if (!regionRom) + { + if (mCompilerOptions & COPT_TARGET_CRT8) + { + regionRom = mLinker->AddRegion(identRom, 0x8080, 0xa000); + regionRom->mCartridgeBanks = 1; + } + else if (mCompilerOptions & COPT_TARGET_CRT16) + { + regionRom = mLinker->AddRegion(identRom, 0x8080, 0xc000); + regionRom->mCartridgeBanks = 1; + } + } + if (regionRom) { regionRom->mSections.Push(mCompilationUnits->mSectionCode); @@ -873,12 +898,12 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64) mLinker->WritePrgFile(prgPath); } } - else if (mCompilerOptions & COPT_TARGET_CRT16) + else if (mCompilerOptions & COPT_TARGET_CRT) { strcat_s(prgPath, "crt"); if (mCompilerOptions & COPT_VERBOSE) printf("Writing <%s>\n", prgPath); - mLinker->WriteCrtFile(prgPath); + mLinker->WriteCrtFile(prgPath, mCartridgeID); } else if (mCompilerOptions & COPT_TARGET_BIN) { @@ -962,7 +987,7 @@ int Compiler::ExecuteCode(bool profile) emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8; ecode = emu->Emulate(2061); } - else if (mCompilerOptions & COPT_TARGET_CRT16) + else if (mCompilerOptions & COPT_TARGET_CRT) { memcpy(emu->mMemory + 0x8000, mLinker->mMemory + 0x0800, 0x4000); ecode = emu->Emulate(0x8009); diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index a627005..28af8b7 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -30,6 +30,7 @@ public: TargetMachine mTargetMachine; uint64 mCompilerOptions; + uint16 mCartridgeID; struct Define { diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h index 9226ba7..25cafb0 100644 --- a/oscar64/CompilerTypes.h +++ b/oscar64/CompilerTypes.h @@ -2,35 +2,38 @@ #include "MachineTypes.h" -static const uint64 COPT_OPTIMIZE_BASIC = 0x00000001; -static const uint64 COPT_OPTIMIZE_INLINE = 0x00000002; -static const uint64 COPT_OPTIMIZE_ASSEMBLER = 0x00000004; +static const uint64 COPT_OPTIMIZE_BASIC = 1ULL << 0; +static const uint64 COPT_OPTIMIZE_INLINE = 1ULL << 1; +static const uint64 COPT_OPTIMIZE_ASSEMBLER = 1ULL << 2; -static const uint64 COPT_OPTIMIZE_AUTO_INLINE = 0x00000010; -static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020; -static const uint64 COPT_OPTIMIZE_AUTO_UNROLL = 0x00000040; -static const uint64 COPT_OPTIMIZE_CONST_EXPRESSIONS = 0x00000080; -static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 0x00000100; +static const uint64 COPT_OPTIMIZE_AUTO_INLINE = 1ULL << 4; +static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 1ULL << 5; +static const uint64 COPT_OPTIMIZE_AUTO_UNROLL = 1ULL << 6; +static const uint64 COPT_OPTIMIZE_CONST_EXPRESSIONS = 1ULL << 7; +static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8; -static const uint64 COPT_OPTIMIZE_CODE_SIZE = 0x00001000; +static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16; +static const uint64 COPT_NATIVE = 1ULL << 17; +static const uint64 COPT_EXTENDED_ZERO_PAGE = 1ULL << 20; -static const uint64 COPT_EXTENDED_ZERO_PAGE = 0x00010000; +static const uint64 COPT_TARGET_PRG = 1ULL << 32; +static const uint64 COPT_TARGET_CRT8 = 1ULL << 33; +static const uint64 COPT_TARGET_CRT16 = 1ULL << 34; +static const uint64 COPT_TARGET_CRT_EASYFLASH = 1ULL << 35; -static const uint64 COPT_TARGET_PRG = 0x100000000ULL; -static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL; -static const uint64 COPT_TARGET_CRT512 = 0x400000000ULL; -static const uint64 COPT_TARGET_COPY = 0x800000000ULL; -static const uint64 COPT_TARGET_BIN = 0x1000000000ULL; -static const uint64 COPT_TARGET_LZO = 0x2000000000ULL; -static const uint64 COPT_TARGET_NES = 0x4000000000ULL; +static const uint64 COPT_TARGET_CRT = COPT_TARGET_CRT8 | COPT_TARGET_CRT16 | COPT_TARGET_CRT_EASYFLASH; -static const uint64 COPT_VERBOSE = 0x10000000000ULL; -static const uint64 COPT_VERBOSE2 = 0x20000000000ULL; -static const uint64 COPT_VERBOSE3 = 0x40000000000ULL; +static const uint64 COPT_TARGET_COPY = 1ULL << 36; +static const uint64 COPT_TARGET_BIN = 1ULL << 37; +static const uint64 COPT_TARGET_LZO = 1ULL << 38; +static const uint64 COPT_TARGET_NES = 1ULL << 39; -static const uint64 COPT_DEBUGINFO = 0x100000000000ULL; +static const uint64 COPT_VERBOSE = 1ULL << 48; +static const uint64 COPT_VERBOSE2 = 1ULL << 49; +static const uint64 COPT_VERBOSE3 = 1ULL << 50; + +static const uint64 COPT_DEBUGINFO = 1ULL << 51; -static const uint64 COPT_NATIVE = 0x01000000; static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 4ff9f48..2d245bd 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -451,7 +451,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo } else if (exp->mDecValue->mType == DT_CONST_POINTER) { - RegisterProc(Analyze(exp->mDecValue->mValue, procDec, false)); + RegisterProc(Analyze(exp->mDecValue->mValue, procDec, true)); } else if (exp->mDecValue->mType == DT_CONST_ADDRESS) { diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 8661d45..44d929e 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -820,7 +820,17 @@ static int memlzcomp(uint8 * dp, const uint8 * sp, int size) return csize; } -bool Linker::WriteCrtFile(const char* filename) +static uint16 flip16(uint16 w) +{ + return (w >> 8) | (w << 8); +} + +static uint32 flip32(uint32 d) +{ + return uint32(flip16(uint16(d >> 16))) | (uint32(flip16(uint16(d))) << 16); +} + +bool Linker::WriteCrtFile(const char* filename, uint16 id) { FILE* file; fopen_s(&file, filename, "wb"); @@ -830,7 +840,8 @@ bool Linker::WriteCrtFile(const char* filename) { char mSignature[16]; uint32 mHeaderLength; - uint16 mVersion, mHardware; + uint16 mVersion; + uint8 mIDHi, mIDLo; uint8 mExrom, mGameLine; uint8 mPad[6]; char mName[32]; @@ -839,9 +850,25 @@ bool Linker::WriteCrtFile(const char* filename) memcpy(criHeader.mSignature, "C64 CARTRIDGE ", 16); criHeader.mHeaderLength = 0x40000000; criHeader.mVersion = 0x0001; - criHeader.mHardware = 0x2000; - criHeader.mExrom = 0; - criHeader.mGameLine = 0; + criHeader.mIDHi = uint8(id >> 8); + criHeader.mIDLo = uint8(id & 0xff); + + if (mCompilerOptions & COPT_TARGET_CRT8) + { + criHeader.mExrom = 0; + criHeader.mGameLine = 1; + } + else if (mCompilerOptions & COPT_TARGET_CRT16) + { + criHeader.mExrom = 0; + criHeader.mGameLine = 0; + } + else + { + criHeader.mExrom = 0; + criHeader.mGameLine = 0; + } + memset(criHeader.mName, 0, 32); strcpy_s(criHeader.mName, "OSCAR"); @@ -854,80 +881,132 @@ bool Linker::WriteCrtFile(const char* filename) uint16 mChipType, mBankNumber, mLoadAddress, mImageSize; } chipHeader = { 0 }; - memcpy(chipHeader.mSignature, "CHIP", 4); - chipHeader.mPacketLength = 0x10200000; - chipHeader.mChipType = 0; - chipHeader.mBankNumber = 0; - chipHeader.mImageSize = 0x0020; - uint8 bootmem[0x4000]; - - memset(bootmem, 0, 0x4000); - - LinkerRegion * mainRegion = FindRegion(Ident::Unique("main")); - LinkerRegion * startupRegion = FindRegion(Ident::Unique("startup")); - - memcpy(bootmem, mMemory + startupRegion->mStart, startupRegion->mNonzero - startupRegion->mStart); - int usedlz = memlzcomp(bootmem + 0x0100, mMemory + mainRegion->mStart, mainRegion->mNonzero - mainRegion->mStart); - - Location loc; - - if (usedlz > 0x03e00) + if (mCompilerOptions & COPT_TARGET_CRT_EASYFLASH) // EASYFLASH { - mErrors->Error(loc, ERRR_INSUFFICIENT_MEMORY, "Can not fit main region into first ROM bank"); - fclose(file); - return false; - } + memcpy(chipHeader.mSignature, "CHIP", 4); + chipHeader.mPacketLength = 0x10200000; + chipHeader.mChipType = 0; + chipHeader.mBankNumber = 0; + chipHeader.mImageSize = 0x0020; - bootmem[0x3ffc] = 0x00; - bootmem[0x3ffd] = 0xff; + uint8 bootmem[0x4000]; - uint8 bootcode[] = { - 0xa9, 0x87, - 0x8d, 0x02, 0xde, - 0xa9, 0x00, - 0x8d, 0x00, 0xde, - 0x6c, 0xfc, 0xff - }; + memset(bootmem, 0, 0x4000); - int j = 0x3f00; - for (int i = 0; i < sizeof(bootcode); i++) - { - bootmem[j++] = 0xa9; - bootmem[j++] = bootcode[i]; - bootmem[j++] = 0x8d; - bootmem[j++] = i; - bootmem[j++] = 0x04; - } - bootmem[j++] = 0x4c; - bootmem[j++] = 0x00; - bootmem[j++] = 0x04; + LinkerRegion* mainRegion = FindRegion(Ident::Unique("main")); + LinkerRegion* startupRegion = FindRegion(Ident::Unique("startup")); - chipHeader.mLoadAddress = 0x0080; - fwrite(&chipHeader, sizeof(chipHeader), 1, file); - fwrite(bootmem, 1, 0x2000, file); + memcpy(bootmem, mMemory + startupRegion->mStart, startupRegion->mNonzero - startupRegion->mStart); + int usedlz = memlzcomp(bootmem + 0x0100, mMemory + mainRegion->mStart, mainRegion->mNonzero - mainRegion->mStart); - chipHeader.mLoadAddress = 0x00e0; - fwrite(&chipHeader, sizeof(chipHeader), 1, file); - fwrite(bootmem + 0x2000, 1, 0x2000, file); + Location loc; - mCartridgeBankUsed[0] = true; - mCartridgeBankStart[0] = 0x8000; - mCartridgeBankEnd[0] = 0x8000 + usedlz + 0x200; - - for (int i = 1; i < 64; i++) - { - if (mCartridgeBankUsed[i]) + if (usedlz > 0x03e00) { - chipHeader.mBankNumber = i << 8; + mErrors->Error(loc, ERRR_INSUFFICIENT_MEMORY, "Can not fit main region into first ROM bank"); + fclose(file); + return false; + } - chipHeader.mLoadAddress = 0x0080; - fwrite(&chipHeader, sizeof(chipHeader), 1, file); - fwrite(mCartridge[i] + 0x8000, 1, 0x2000, file); + bootmem[0x3ffc] = 0x00; + bootmem[0x3ffd] = 0xff; - chipHeader.mLoadAddress = 0x00a0; - fwrite(&chipHeader, sizeof(chipHeader), 1, file); - fwrite(mCartridge[i] + 0xa000, 1, 0x2000, file); + uint8 bootcode[] = { + 0xa9, 0x87, + 0x8d, 0x02, 0xde, + 0xa9, 0x00, + 0x8d, 0x00, 0xde, + 0x6c, 0xfc, 0xff + }; + + int j = 0x3f00; + for (int i = 0; i < sizeof(bootcode); i++) + { + bootmem[j++] = 0xa9; + bootmem[j++] = bootcode[i]; + bootmem[j++] = 0x8d; + bootmem[j++] = i; + bootmem[j++] = 0x04; + } + bootmem[j++] = 0x4c; + bootmem[j++] = 0x00; + bootmem[j++] = 0x04; + + chipHeader.mLoadAddress = 0x0080; + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(bootmem, 1, 0x2000, file); + + chipHeader.mLoadAddress = 0x00e0; + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(bootmem + 0x2000, 1, 0x2000, file); + + mCartridgeBankUsed[0] = true; + mCartridgeBankStart[0] = 0x8000; + mCartridgeBankEnd[0] = 0x8000 + usedlz + 0x200; + + for (int i = 1; i < 64; i++) + { + if (mCartridgeBankUsed[i]) + { + chipHeader.mBankNumber = i << 8; + + chipHeader.mLoadAddress = 0x0080; + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(mCartridge[i] + 0x8000, 1, 0x2000, file); + + chipHeader.mLoadAddress = 0x00a0; + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(mCartridge[i] + 0xa000, 1, 0x2000, file); + } + } + } + else if (mCompilerOptions & COPT_TARGET_CRT8) + { + int numBanks = 64; + while (numBanks > 1 && !mCartridgeBankUsed[numBanks - 1]) + numBanks--; + + memcpy(chipHeader.mSignature, "CHIP", 4); + chipHeader.mPacketLength = flip32(0x10 + 0x2000); + chipHeader.mChipType = 0; + chipHeader.mBankNumber = 0; + chipHeader.mImageSize = flip16(0x2000); + + for (int i = 0; i < numBanks; i++) + { + if (mCartridgeBankUsed[i]) + { + chipHeader.mBankNumber = flip16(uint16(i)); + + chipHeader.mLoadAddress = flip16(0x8000); + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(mCartridge[i] + 0x8000, 1, 0x2000, file); + } + } + } + else if (mCompilerOptions & COPT_TARGET_CRT16) + { + int numBanks = 64; + while (numBanks > 1 && !mCartridgeBankUsed[numBanks - 1]) + numBanks--; + + memcpy(chipHeader.mSignature, "CHIP", 4); + chipHeader.mPacketLength = flip32(0x10 + 0x4000); + chipHeader.mChipType = 0; + chipHeader.mBankNumber = 0; + chipHeader.mImageSize = flip16(0x4000); + + for (int i = 0; i < numBanks; i++) + { + if (mCartridgeBankUsed[i]) + { + chipHeader.mBankNumber = flip16(uint16(i)); + + chipHeader.mLoadAddress = flip16(0x8000); + fwrite(&chipHeader, sizeof(chipHeader), 1, file); + fwrite(mCartridge[i] + 0x8000, 1, 0x4000, file); + } } } diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 3fc3389..1124644 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -247,7 +247,7 @@ public: bool WriteMapFile(const char* filename); bool WriteAsmFile(const char* filename); bool WriteLblFile(const char* filename); - bool WriteCrtFile(const char* filename); + bool WriteCrtFile(const char* filename, uint16 id); bool WriteBinFile(const char* filename); bool WriteNesFile(const char* filename, TargetMachine machine); bool WriteMlbFile(const char* filename, TargetMachine machine); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 51f937a..6b31589 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -74,7 +74,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.18.197"); + strcpy(strProductVersion, "1.19.198"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); @@ -168,6 +168,12 @@ int main2(int argc, const char** argv) { strcpy_s(targetMachine, arg + 4); } + else if (arg[1] == 'c' && arg[2] == 'i' && arg[3] == 'd' && arg[4] == '=') + { + char cid[10]; + strcpy_s(cid, arg + 5); + compiler->mCartridgeID = atoi(cid); + } else if (arg[1] == 'n') { compiler->mCompilerOptions |= COPT_NATIVE; @@ -378,10 +384,22 @@ int main2(int argc, const char** argv) compiler->AddDefine(Ident::Unique("OSCAR_BASIC_START"), basicStart); } else if (!strcmp(targetFormat, "crt")) + { + compiler->mCompilerOptions |= COPT_TARGET_CRT_EASYFLASH; + compiler->mCartridgeID = 0x0020; + + compiler->AddDefine(Ident::Unique("OSCAR_TARGET_CRT_EASYFLASH"), "1"); + } + else if (!strcmp(targetFormat, "crt16")) { compiler->mCompilerOptions |= COPT_TARGET_CRT16; compiler->AddDefine(Ident::Unique("OSCAR_TARGET_CRT16"), "1"); } + else if (!strcmp(targetFormat, "crt8")) + { + compiler->mCompilerOptions |= COPT_TARGET_CRT8; + compiler->AddDefine(Ident::Unique("OSCAR_TARGET_CRT8"), "1"); + } else if (!strcmp(targetFormat, "bin")) { compiler->mCompilerOptions |= COPT_TARGET_BIN; diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 0281f96..d215671 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,18,197,0 - PRODUCTVERSION 1,18,197,0 + FILEVERSION 1,19,198,0 + PRODUCTVERSION 1,19,198,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.18.197.0" + VALUE "FileVersion", "1.19.198.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.18.197.0" + VALUE "ProductVersion", "1.19.198.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index dcfa319..1d1c78f 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -856,6 +856,12 @@ } "Entry" { + "MsmKey" = "8:_CACD2FA2FFF3488AB6C5A0E5980B7805" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_CC473A7B399D4B31A9DC8C94F7771EF7" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -3987,6 +3993,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CACD2FA2FFF3488AB6C5A0E5980B7805" + { + "SourcePath" = "8:..\\samples\\memmap\\magicdesk.c" + "TargetName" = "8:magicdesk.c" + "Tag" = "8:" + "Folder" = "8:_A62A71A6A08941C5964B90112D87731F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CC473A7B399D4B31A9DC8C94F7771EF7" { "SourcePath" = "8:..\\samples\\memmap\\charsethi.c" @@ -5129,15 +5155,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{BD84D458-D051-4806-8F62-7615360BA28B}" - "PackageCode" = "8:{E20C48E9-5990-4069-B296-44E92B26D64F}" + "ProductCode" = "8:{1E7DBEE1-2479-49F8-9F5B-1DA786C469FD}" + "PackageCode" = "8:{F178C72F-3E89-41CE-8310-E30ADA97F214}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.18.197" + "ProductVersion" = "8:1.19.198" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/memmap/magicdesk.c b/samples/memmap/magicdesk.c new file mode 100644 index 0000000..898b215 --- /dev/null +++ b/samples/memmap/magicdesk.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +// Set rom region end at 0x9f80 to leave some space for copy code +#pragma region(rom, 0x8080, 0x9f80, , 0, { code, data } ) + +// We do not want to pollute main RAM region with our data +#pragma region(main, 0xc000, 0xd000, , , { bss, stack, heap }) +#pragma stacksize( 256 ) + +// Region and code for a cross bank copy routine +#pragma section( ccode, 0 ) +#pragma region( crom, 0x9f80, 0xa000, , 0, { ccode }, 0x0380 ) + +CharWin cw; + +// Copy code from any bank to RAM, returns to bank 0, this code is +// copied from bank 0 to RAM at 0x0380 at program start + +#pragma code ( ccode ) + +__export void ccopy(char bank, char * dst, const char * src, unsigned n) +{ + *((volatile char *)0xde00) = bank; + while (n) + { + *dst++ = *src++; + n--; + } + *((volatile char *)0xde00) = 0; +} + +// Region of code to be executed from RAM after copied from 2nd ROM +// bank + +#pragma section( bcode1, 0 ) +#pragma section( bdata1, 0 ) +#pragma region(bank1, 0x8000, 0xa000, , 1, { bcode1, bdata1 }, 0x2000 ) + +#pragma code ( bcode1 ) +#pragma data ( bdata1 ) + +// Print into shared charwin + +void print1(void) +{ + cwin_put_string(&cw, p"This is first bank", 1); + cwin_cursor_newline(&cw); +} + +// Back to main sections in bank 0 + +#pragma code ( code ) +#pragma data ( data ) + + +int main(void) +{ + // Enable ROM + mmap_set(MMAP_ROM); + + // Init CIAs (no kernal rom was executed so far) + cia_init(); + + // Copy ccopy code to RAM + for(char i=0; i<128; i++) + ((char *)0x0380)[i] = ((char *)0x9f80)[i]; + + // Init VIC + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1800); + + // Prepare output window + cwin_init(&cw, (char *)0x0400, 0, 0, 40, 25); + cwin_clear(&cw); + + // Write first line + cwin_put_string(&cw, p"Hello World", 7); + cwin_cursor_newline(&cw); + + // Copy bank 1 to RAM + ccopy(1, (char *)0x2000, (char *)0x8000, 0x2000); + + // Call function in copy + print1(); + + // Third line + cwin_put_string(&cw, p"Final words", 14); + cwin_cursor_newline(&cw); + + while (true) ; + + return 0; +} diff --git a/samples/memmap/make.bat b/samples/memmap/make.bat index 7382770..2c03d0a 100644 --- a/samples/memmap/make.bat +++ b/samples/memmap/make.bat @@ -11,3 +11,4 @@ call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG call ..\..\bin\oscar64 overlay.c -n -d64=overlay.d64 +call ..\..\bin\oscar64 magicdesk.c -n -tf=crt8 -cid=19