From 75e5471dd1e7e2ccde603f6d0e0d0acaa3ff880e Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 8 May 2022 15:37:30 +0200 Subject: [PATCH] Add support for d64 image creation --- README.md | 17 +- include/c64/kernalio.c | 60 ++++++ include/c64/kernalio.h | 2 + oscar64/Compiler.cpp | 129 ++++++++--- oscar64/Compiler.h | 3 +- oscar64/CompilerTypes.h | 5 +- oscar64/DiskImage.cpp | 352 +++++++++++++++++++++++++++++++ oscar64/DiskImage.h | 29 +++ oscar64/Linker.cpp | 8 + oscar64/Linker.h | 2 + oscar64/NativeCodeGenerator.cpp | 28 +++ oscar64/oscar64.cpp | 60 +++++- oscar64/oscar64.rc | 8 +- oscar64/oscar64.vcxproj | 2 + oscar64/oscar64.vcxproj.filters | 6 + oscar64setup/oscar64setup.vdproj | 266 ++++++++++++++++++++++- samples/memmap/build.sh | 1 + samples/memmap/charsetload.c | 44 ++++ samples/memmap/charsetload.d64 | Bin 0 -> 174848 bytes samples/memmap/make.bat | 1 + 20 files changed, 981 insertions(+), 42 deletions(-) create mode 100644 oscar64/DiskImage.cpp create mode 100644 oscar64/DiskImage.h create mode 100644 samples/memmap/charsetload.c create mode 100644 samples/memmap/charsetload.d64 diff --git a/README.md b/README.md index e05998a..307bff9 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ The compiler is command line driven, and creates an executable .prg file. * -O3: aggressive optimization for speed * -Os: optimize for size * -tf: target format, may be prg, crt or bin +* -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 + A list of source files can be provided. @@ -111,6 +115,13 @@ Creates vice monitor commands to define all static labels. One can load the label file in the monitor using the load_labels (ll) command or provide it on the command line for vice with the "-moncommands" command line argument. +### Creating a d64 disk file + +The compiler can create a .d64 disk file, that includes the compiled .prg file as the first file in the directory and a series of additional resource files. The name of the disk file is provided with the -d64 command line options, additional files with the -f or -fz option. + + oscar64 charsetload.c -d64=charsetload.d64 -fz=../resources/charset.bin + +The compressed files can be loaded into memory and decompressed using the oscar_expand_lzo function from oscar.h or on the fly while reading from disk with the krnio_read_lzo function. ### Building the samples @@ -437,10 +448,14 @@ Embedds a custom character set into the prg file at 0xc800..0xcfff and switches Embedds a custom character set into the prg file at 0xc000..0xc7ff and copies it to 0xd000 on startup. This frees this area for stack and heap usage. -#### Copy character set "charsetcopy.c" +#### Copy character set "charsetexpand.c" Embedds a custom character set into the prg file at 0xc000..0xc7ff using lz comression and expands it to 0xd000 on startup. This frees this area for stack and heap usage. +#### Custom character set "charsetload.c" + +Builds a .d64 image containing the compiled .prg and the compressed character set. The program reads the character set at runtime from disk. + #### Easyflash banking "easyflash.c" When compiling for easyflash, the linker will place the code and data section into bank 0 and copy it to 0x0900..0x7fff at startup. The remaining banks are free to be used for data or additional codes and can be banked in as needed. This sample uses banks one to six for additional functions. diff --git a/include/c64/kernalio.c b/include/c64/kernalio.c index 720594a..22bb5cd 100644 --- a/include/c64/kernalio.c +++ b/include/c64/kernalio.c @@ -274,6 +274,66 @@ int krnio_read(char fnum, char * data, int num) #pragma native(krnio_read) +int krnio_read_lzo(char fnum, char * data) +{ + if (krnio_pstatus[fnum] == KRNIO_EOF) + return 0; + + if (krnio_chkin(fnum)) + { + int i = 0; + char ch; + char cmd = 0; + krnioerr err; + + for(;;) + { + ch = krnio_chrin(); + err = krnio_status(); + if (err && err != KRNIO_EOF) + break; + + if (cmd & 0x80) + { + + char * dp = data + i, * cp = dp - ch; + + cmd &= 0x7f; + i += cmd; + + char n = 0x00; + do { + dp[n] = cp[n]; + n++; + } while (n != cmd); + cmd = 0; + } + else if (cmd) + { + data[i++] = (char)ch; + cmd--; + } + else if (ch) + cmd = ch; + else + break; + + if (err) + break; + + } + + krnio_pstatus[fnum] = err; + + krnio_clrchn(); + return i; + } + else + return -1; +} + +#pragma native(krnio_read_lzo) + int krnio_gets(char fnum, char * data, int num) { if (krnio_pstatus[fnum] == KRNIO_EOF) diff --git a/include/c64/kernalio.h b/include/c64/kernalio.h index 93780a9..721074e 100644 --- a/include/c64/kernalio.h +++ b/include/c64/kernalio.h @@ -81,6 +81,8 @@ int krnio_puts(char fnum, const char * data); int krnio_read(char fnum, char * data, int num); +int krnio_read_lzo(char fnum, char * data); + // read a line from the given file, terminated by a CR or LF character // and appends a zero byte. diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 0f7a998..2bf2f40 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -263,31 +263,34 @@ bool Compiler::GenerateCode(void) // Register native runtime functions - RegisterRuntime(loc, Ident::Unique("mul16by8")); - RegisterRuntime(loc, Ident::Unique("fsplitt")); - RegisterRuntime(loc, Ident::Unique("fsplitx")); - RegisterRuntime(loc, Ident::Unique("fsplita")); - RegisterRuntime(loc, Ident::Unique("faddsub")); - RegisterRuntime(loc, Ident::Unique("fmul")); - RegisterRuntime(loc, Ident::Unique("fdiv")); - RegisterRuntime(loc, Ident::Unique("mul16")); - RegisterRuntime(loc, Ident::Unique("divs16")); - RegisterRuntime(loc, Ident::Unique("mods16")); - RegisterRuntime(loc, Ident::Unique("divu16")); - RegisterRuntime(loc, Ident::Unique("modu16")); - RegisterRuntime(loc, Ident::Unique("bitshift")); - RegisterRuntime(loc, Ident::Unique("ffloor")); - RegisterRuntime(loc, Ident::Unique("fceil")); - RegisterRuntime(loc, Ident::Unique("ftoi")); - RegisterRuntime(loc, Ident::Unique("ffromi")); - RegisterRuntime(loc, Ident::Unique("fcmp")); - RegisterRuntime(loc, Ident::Unique("bcexec")); - RegisterRuntime(loc, Ident::Unique("jmpaddr")); - RegisterRuntime(loc, Ident::Unique("mul32")); - RegisterRuntime(loc, Ident::Unique("divs32")); - RegisterRuntime(loc, Ident::Unique("mods32")); - RegisterRuntime(loc, Ident::Unique("divu32")); - RegisterRuntime(loc, Ident::Unique("modu32")); + if (mInterCodeModule->mProcedures.Size() > 0) + { + RegisterRuntime(loc, Ident::Unique("mul16by8")); + RegisterRuntime(loc, Ident::Unique("fsplitt")); + RegisterRuntime(loc, Ident::Unique("fsplitx")); + RegisterRuntime(loc, Ident::Unique("fsplita")); + RegisterRuntime(loc, Ident::Unique("faddsub")); + RegisterRuntime(loc, Ident::Unique("fmul")); + RegisterRuntime(loc, Ident::Unique("fdiv")); + RegisterRuntime(loc, Ident::Unique("mul16")); + RegisterRuntime(loc, Ident::Unique("divs16")); + RegisterRuntime(loc, Ident::Unique("mods16")); + RegisterRuntime(loc, Ident::Unique("divu16")); + RegisterRuntime(loc, Ident::Unique("modu16")); + RegisterRuntime(loc, Ident::Unique("bitshift")); + RegisterRuntime(loc, Ident::Unique("ffloor")); + RegisterRuntime(loc, Ident::Unique("fceil")); + RegisterRuntime(loc, Ident::Unique("ftoi")); + RegisterRuntime(loc, Ident::Unique("ffromi")); + RegisterRuntime(loc, Ident::Unique("fcmp")); + RegisterRuntime(loc, Ident::Unique("bcexec")); + RegisterRuntime(loc, Ident::Unique("jmpaddr")); + RegisterRuntime(loc, Ident::Unique("mul32")); + RegisterRuntime(loc, Ident::Unique("divs32")); + RegisterRuntime(loc, Ident::Unique("mods32")); + RegisterRuntime(loc, Ident::Unique("divu32")); + RegisterRuntime(loc, Ident::Unique("modu32")); + } // Register extended byte code functions @@ -419,7 +422,65 @@ bool Compiler::GenerateCode(void) return mErrors->mErrorCount == 0; } -bool Compiler::WriteOutputFile(const char* targetPath) +bool Compiler::BuildLZO(const char* targetPath) +{ + mPreprocessor->mCompilerOptions = mCompilerOptions; + mLinker->mCompilerOptions = mCompilerOptions; + + CompilationUnit* cunit; + + char data[65536]; + int n = 0; + + while (mErrors->mErrorCount == 0 && (cunit = mCompilationUnits->PendingUnit())) + { + if (mPreprocessor->EmbedData("Compressing", cunit->mFileName, true, 0, 65536, SFM_BINARY_LZO)) + { + Scanner* scanner = new Scanner(mErrors, mPreprocessor); + while (scanner->mToken == TK_INTEGER) + { + data[n++] = scanner->mTokenInteger; + do { + scanner->NextToken(); + } while (scanner->mToken == TK_COMMA); + } + } + else + mErrors->Error(cunit->mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", cunit->mFileName); + } + + if (mErrors->mErrorCount == 0) + { + char prgPath[200]; + + strcpy_s(prgPath, targetPath); + int i = strlen(prgPath); + while (i > 0 && prgPath[i - 1] != '.') + i--; + if (i > 0) + prgPath[i] = 0; + + strcat_s(prgPath, "lzo"); + if (mCompilerOptions & COPT_VERBOSE) + printf("Writing <%s>\n", prgPath); + + FILE* file; + fopen_s(&file, prgPath, "wb"); + if (file) + { + int done = fwrite(data, 1, n, file); + fclose(file); + return done == n; + } + else + return false; + } + else + return false; + +} + +bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64) { char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200]; @@ -465,6 +526,22 @@ bool Compiler::WriteOutputFile(const char* targetPath) } + if (d64) + { + int i = strlen(prgPath); + while (i > 0 && prgPath[i - 1] != '.') + i--; + if (i > 0) + prgPath[i - 1] = 0; + + while (i > 0 && prgPath[i - 1] != '/' && prgPath[i - 1] != '\\') + i--; + + d64->OpenFile(prgPath + i); + mLinker->WritePrgFile(d64); + d64->CloseFile(); + } + if (mCompilerOptions & COPT_VERBOSE) printf("Writing <%s>\n", mapPath); mLinker->WriteMapFile(mapPath); diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index 2df5bcb..0c178a4 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -38,9 +38,10 @@ public: GrowingArray mDefines; + bool BuildLZO(const char* targetPath); bool ParseSource(void); bool GenerateCode(void); - bool WriteOutputFile(const char* targetPath); + bool WriteOutputFile(const char* targetPath, DiskImage * d64); int ExecuteCode(bool profile); void AddDefine(const Ident* ident, const char* value); diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h index 6e81dbf..94748a0 100644 --- a/oscar64/CompilerTypes.h +++ b/oscar64/CompilerTypes.h @@ -17,9 +17,10 @@ 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_VERBOSE = 0x1000000000ULL; -static const uint64 COPT_VERBOSE2 = 0x2000000000ULL; +static const uint64 COPT_VERBOSE = 0x10000000000ULL; +static const uint64 COPT_VERBOSE2 = 0x20000000000ULL; static const uint64 COPT_NATIVE = 0x01000000; diff --git a/oscar64/DiskImage.cpp b/oscar64/DiskImage.cpp new file mode 100644 index 0000000..601d28d --- /dev/null +++ b/oscar64/DiskImage.cpp @@ -0,0 +1,352 @@ +#include "DiskImage.h" + +static char SectorsPerTrack[] = { + 0, + + 21, 21, 21, 21, + 21, 21, 21, 21, + 21, 21, 21, 21, + 21, 21, 21, 21, + 21, + + 19, 19, 19, 19, + 19, 19, 19, + + 18, 18, 18, 18, + 18, 18, + + 17, 17, 17, 17, + 17, + + 0, 0, 0, 0, 0 +}; + +static char A2P(char ch) +{ + if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') + return (ch ^ 0x20) & 0xdf; + else + return ch; +} + +DiskImage::DiskImage(const char* fname) +{ + for (int i = 0; i < 41; i++) + for (int j = 0; j < 21; j++) + memset(mSectors[i][j], 0, 256); + + // init bam + + uint8* bam = mSectors[18][0]; + + bam[0] = 18; bam[1] = 1; bam[2] = 0x41; bam[3] = 0; + for (int i = 1; i < 36; i++) + { + uint8* dp = bam + 4 * i; + dp[0] = SectorsPerTrack[i]; + unsigned k = (1 << SectorsPerTrack[i]) - 1; + dp[3] = (k >> 16) & 255; + dp[2] = (k >> 8) & 255; + dp[1] = k & 255; + } + + for (int i = 0x90; i < 0xab; i++) + bam[i] = 0xa0; + + char dname[200]; + int i = strlen(fname); + + while (i > 0 && fname[i - 1] != '/' && fname[i - 1] != '\\') + i--; + + int j = 0; + while (j < 16 && fname[i + j] && fname[i + j] != '.') + { + bam[0x90 + j] = A2P(fname[i + j]); + j++; + } + + // DIsk ID + bam[0xa2] = 'C'; + bam[0xa3] = 'N'; + + // DOS TYPE + bam[0xa5] = '2'; + bam[0xa6] = 'A'; + + MarkBAMSector(18, 0); + + uint8* dir = mSectors[18][1]; + + MarkBAMSector(18, 1); + + +} + +void DiskImage::MarkBAMSector(int track, int sector) +{ + uint8* bam = mSectors[18][0]; + + uint8* dp = bam + 4 * track; + + if (dp[sector >> 3] & (1 << (sector & 7))) + { + dp[sector >> 3] &= ~(1 << (sector & 7)); + dp[0]--; + } +} + +int DiskImage::AllocBAMSector(int track, int sector) +{ + uint8* bam = mSectors[18][0]; + + uint8* dp = bam + 4 * track; + + if (dp[0] > 0) + { + sector += 4; + if (sector >= SectorsPerTrack[track]) + sector -= SectorsPerTrack[track]; + + while (!(dp[sector >> 3] & (1 << (sector & 7)))) + { + sector++; + if (sector >= SectorsPerTrack[track]) + sector -= SectorsPerTrack[track]; + } + + MarkBAMSector(track, sector); + + return sector; + } + else + return -1; +} + +int DiskImage::AllocBAMTrack(int track) +{ + uint8* bam = mSectors[18][0]; + + if (track < 18) + { + while (track > 0 && bam[4 * track] == 0) + track--; + if (track != 0) + return track; + else + track = 19; + } + + while (track < 36 && bam[4 * track] == 0) + track++; + + return track; +} + +DiskImage::~DiskImage(void) +{ + +} + +bool DiskImage::WriteImage(const char* fname) +{ + FILE* file; + fopen_s(&file, fname, "wb"); + if (file) + { + for (int i = 1; i < 36; i++) + { + for(int j=0; j 0 && fname[i - 1] != '/' && fname[i - 1] != '\\') + i--; + + int j = 0; + while (j < 16 && fname[i + j] && fname[i + j] != '.') + { + dname[j] = A2P(fname[i + j]); + j++; + } + dname[j] = 0; + + if (OpenFile(dname)) + { + uint8 buffer[65536], cbuffer[65536]; + int size = fread(buffer, 1, 65536, file); + int csize = 0; + + if (compressed) + { + int pos = 0; + while (pos < size) + { + int pi = 0; + while (pi < 127 && pos < size) + { + int bi = pi, bj = 0; + for (int i = 1; i < (pos < 255 ? pos : 255); i++) + { + int j = 0; + while (j < 127 && pos + j < size && buffer[pos - i + j] == buffer[pos + j]) + j++; + + if (j > bj) + { + bi = i; + bj = j; + } + } + + if (bj >= 4) + { + if (pi > 0) + { + cbuffer[csize++] = pi; + for (int i = 0; i < pi; i++) + cbuffer[csize++] = buffer[pos - pi + i]; + pi = 0; + } + + cbuffer[csize++] = 128 + bj; + cbuffer[csize++] = bi; + pos += bj; + } + else + { + pos++; + pi++; + } + } + + if (pi > 0) + { + cbuffer[csize++] = pi; + for (int i = 0; i < pi; i++) + cbuffer[csize++] = buffer[pos - pi + i]; + } + } + + cbuffer[csize++] = 0; + WriteBytes(cbuffer, csize); + } + else + WriteBytes(buffer, size); + CloseFile(); + } + + fclose(file); + return true; + } + else + return false; +} + +int DiskImage::WriteBytes(const uint8* data, int size) +{ + uint8* dp = mSectors[mTrack][mSector]; + for (int i = 0; i < size; i++) + { + dp[mBytes] = data[i]; + mBytes++; + + if (mBytes >= 256) + { + mSector = AllocBAMSector(mTrack, mSector); + if (mSector < 0) + { + mTrack = AllocBAMTrack(mTrack); + mSector = AllocBAMSector(mTrack, 0); + } + + dp[0] = mTrack; + dp[1] = mSector; + + mBytes = 2; + if (!++mDirEntry[30]) + mDirEntry[31]++; + + dp = mSectors[mTrack][mSector]; + } + + dp[1] = mBytes; + } + return 0; +} diff --git a/oscar64/DiskImage.h b/oscar64/DiskImage.h new file mode 100644 index 0000000..25683a8 --- /dev/null +++ b/oscar64/DiskImage.h @@ -0,0 +1,29 @@ +#pragma once + +#include "MachineTypes.h" + +class DiskImage +{ +public: + DiskImage(const char * name); + ~DiskImage(void); + + bool WriteImage(const char* fname); + + bool OpenFile(const char* fname); + void CloseFile(void); + + int WriteBytes(const uint8* data, int size); + bool WriteFile(const char* fname, bool compressed); + +protected: + uint8 mSectors[41][21][256]; + + void MarkBAMSector(int track, int sector); + int AllocBAMSector(int track, int sector); + int AllocBAMTrack(int track); + + uint8 * mDirEntry; + int mTrack, mSector, mBytes; + +}; diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index d9b6052..914a50c 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -540,6 +540,14 @@ bool Linker::WriteBinFile(const char* filename) return false; } +bool Linker::WritePrgFile(DiskImage* image) +{ + mMemory[mProgramStart - 2] = mProgramStart & 0xff; + mMemory[mProgramStart - 1] = mProgramStart >> 8; + + return image->WriteBytes(mMemory + mProgramStart - 2, mProgramEnd - mProgramStart + 2); +} + bool Linker::WritePrgFile(const char* filename) { FILE* file; diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 06d2d00..99a4e16 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -5,6 +5,7 @@ #include "Array.h" #include "Errors.h" #include "Disassembler.h" +#include "DiskImage.h" class InterCodeProcedure; @@ -188,6 +189,7 @@ public: // void AddReference(const LinkerReference& ref); + bool WritePrgFile(DiskImage * image); bool WritePrgFile(const char* filename); bool WriteMapFile(const char* filename); bool WriteAsmFile(const char* filename); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a212242..30c05a6 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -11436,6 +11436,34 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc) mBranch = ASMIT_BCC; break; } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && + mIns[i + 1].mType == ASMIT_ADC && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 1].SameEffectiveAddress(mIns[i + 2]) && + HasAsmInstructionMode(ASMIT_INC, mIns[i + 2].mMode) && + !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z))) + { + changed = true; + + NativeCodeBasicBlock* iblock = proc->AllocateBlock(); + NativeCodeBasicBlock* fblock = proc->AllocateBlock(); + + fblock->mTrueJump = mTrueJump; + fblock->mFalseJump = mFalseJump; + fblock->mBranch = mBranch; + + for (int j = i + 3; j < mIns.Size(); j++) + fblock->mIns.Push(mIns[j]); + iblock->mIns.Push(mIns[i + 2]); + mIns.SetSize(i); + iblock->mIns[0].mType = ASMIT_INC; + iblock->mTrueJump = fblock; + iblock->mBranch = ASMIT_JMP; + + mTrueJump = fblock; + mFalseJump = iblock; + mBranch = ASMIT_BCC; + break; + } else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 && mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index b0c8254..0a5e155 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -8,6 +8,7 @@ #include #endif #include "Compiler.h" +#include "DiskImage.h" #ifdef _WIN32 bool GetProductAndVersion(char* strProductName, char* strProductVersion) @@ -63,7 +64,7 @@ int main2(int argc, const char** argv) if (argc > 1) { - char basePath[200], crtPath[200], includePath[200], targetPath[200]; + char basePath[200], crtPath[200], includePath[200], targetPath[200], diskPath[200]; char strProductName[100], strProductVersion[200]; #ifdef _WIN32 @@ -73,7 +74,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.6.125"); + strcpy(strProductVersion, "1.7.126"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); @@ -103,6 +104,9 @@ int main2(int argc, const char** argv) Location loc; + GrowingArray dataFiles(nullptr); + GrowingArray dataFileCompressed(false); + compiler->mPreprocessor->AddPath(basePath); strcpy_s(includePath, basePath); strcat_s(includePath, "include/"); @@ -113,6 +117,7 @@ int main2(int argc, const char** argv) bool emulate = false, profile = false; targetPath[0] = 0; + diskPath[0] = 0; char targetFormat[20]; strcpy_s(targetFormat, "prg"); @@ -126,6 +131,16 @@ int main2(int argc, const char** argv) { compiler->mPreprocessor->AddPath(arg + 3); } + else if (arg[1] == 'f' && arg[2] == '=') + { + dataFiles.Push(arg + 3); + dataFileCompressed.Push(false); + } + else if (arg[1] == 'f' && arg[2] == 'z' && arg[3] == '=') + { + dataFiles.Push(arg + 4); + dataFileCompressed.Push(true); + } else if (arg[1] == 'o' && arg[2] == '=') { strcpy_s(targetPath, arg + 3); @@ -134,6 +149,10 @@ int main2(int argc, const char** argv) { strcpy_s(crtPath, arg + 4); } + else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=') + { + strcpy_s(diskPath, arg + 5); + } else if (arg[1] == 't' && arg[2] == 'f' && arg[3] == '=') { strcpy_s(targetFormat, arg + 4); @@ -209,6 +228,11 @@ int main2(int argc, const char** argv) compiler->mCompilerOptions |= COPT_TARGET_BIN; compiler->AddDefine(Ident::Unique("OSCAR_TARGET_BIN"), "1"); } + else if (!strcmp(targetFormat, "lzo")) + { + compiler->mCompilerOptions |= COPT_TARGET_LZO; + compiler->AddDefine(Ident::Unique("OSCAR_TARGET_LZO"), "1"); + } else compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid target format option", targetFormat); @@ -224,9 +248,35 @@ int main2(int argc, const char** argv) if (crtPath[0]) compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr); - if (compiler->ParseSource() && compiler->GenerateCode()) + if (compiler->mCompilerOptions & COPT_TARGET_LZO) { - compiler->WriteOutputFile(targetPath); + compiler->BuildLZO(targetPath); + } + else if (compiler->ParseSource() && compiler->GenerateCode()) + { + DiskImage* d64 = nullptr; + + if (diskPath[0]) + d64 = new DiskImage(diskPath); + + compiler->WriteOutputFile(targetPath, d64); + + if (d64) + { + for (int i = 0; i < dataFiles.Size(); i++) + { + if (!d64->WriteFile(dataFiles[i], dataFileCompressed[i])) + { + printf("Could not embedd disk file %s\n", dataFiles[i]); + return 20; + } + } + if (!d64->WriteImage(diskPath)) + { + printf("Could not write disk image %s\n", diskPath); + return 20; + } + } if (emulate) compiler->ExecuteCode(profile); @@ -238,7 +288,7 @@ int main2(int argc, const char** argv) } else { - printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-e] [-n] [-dSYMBOL[=value]] [-v] {source.c}\n"); + printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=target] [-e] [-n] {-dSYMBOL[=value]} [-v] [-d64=diskname] {-f[z]=file.xxx} {source.c}\n"); return 0; } diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 58af906..9f0fe70 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,6,125,0 - PRODUCTVERSION 1,6,125,0 + FILEVERSION 1,7,126,0 + PRODUCTVERSION 1,7,126,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.6.125.0" + VALUE "FileVersion", "1.7.126.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.6.125.0" + VALUE "ProductVersion", "1.7.126.0" END END BLOCK "VarFileInfo" diff --git a/oscar64/oscar64.vcxproj b/oscar64/oscar64.vcxproj index b5aaddc..023f311 100644 --- a/oscar64/oscar64.vcxproj +++ b/oscar64/oscar64.vcxproj @@ -150,6 +150,7 @@ + @@ -175,6 +176,7 @@ + diff --git a/oscar64/oscar64.vcxproj.filters b/oscar64/oscar64.vcxproj.filters index 99c9015..d4cd396 100644 --- a/oscar64/oscar64.vcxproj.filters +++ b/oscar64/oscar64.vcxproj.filters @@ -75,6 +75,9 @@ Source Files + + Source Files + @@ -146,6 +149,9 @@ Header Files + + Header Files + diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index d158536..9d27c4d 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -34,6 +34,12 @@ } "Entry" { + "MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_04ABABC55200450383686DD782DD1548" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -160,6 +166,12 @@ } "Entry" { + "MsmKey" = "8:_326B44043E3720E0A341FB5627DA8873" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -172,6 +184,12 @@ } "Entry" { + "MsmKey" = "8:_36B4A1247BFCE001E1BAE7560E9CFEEA" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_379EE3C17FEC4C5EA79D07668CD05FC4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -244,6 +262,12 @@ } "Entry" { + "MsmKey" = "8:_458189403F0009BC49371204B74F3BD3" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_47A877D439EE429BAB64C52FEF69EDA4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -370,6 +394,12 @@ } "Entry" { + "MsmKey" = "8:_749A2BA18335F50EB53CCE7029861FBC" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -430,6 +460,12 @@ } "Entry" { + "MsmKey" = "8:_8667075410229C38BF63AC1CC776055E" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_8827B6B07A1C4B32B08DF784E090381D" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -586,6 +622,12 @@ } "Entry" { + "MsmKey" = "8:_B2F1B217D45A434DBA8EC21095F4D717" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_B4265CBF352343D2867DBCCE67D9F493" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -754,6 +796,12 @@ } "Entry" { + "MsmKey" = "8:_DD5A4DD822437085CD584319732F2D4D" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_DEADBEA270134B77800770802B21859C" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -814,6 +862,12 @@ } "Entry" { + "MsmKey" = "8:_EA3C0BCB01F2639DFA2E37EC8436E5F6" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_ED872D39D58443D590B7C80604BC0FF4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -844,6 +898,12 @@ } "Entry" { + "MsmKey" = "8:_F20F5618C7576D758C01D89C87469AF8" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_F35970F9D8FA46B09F36D7E9DE5532CA" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -1025,6 +1085,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03D7013B0D39A89CEA9D267005ADCE39" + { + "SourcePath" = "8:VCRUNTIME140.dll" + "TargetName" = "8:VCRUNTIME140.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04ABABC55200450383686DD782DD1548" { "SourcePath" = "8:..\\samples\\games\\lander.c" @@ -1445,6 +1525,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_326B44043E3720E0A341FB5627DA8873" + { + "SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF" { "SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c" @@ -1485,6 +1585,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_36B4A1247BFCE001E1BAE7560E9CFEEA" + { + "SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_379EE3C17FEC4C5EA79D07668CD05FC4" { "SourcePath" = "8:..\\samples\\memmap\\easyflash.c" @@ -1725,6 +1845,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_458189403F0009BC49371204B74F3BD3" + { + "SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_47A877D439EE429BAB64C52FEF69EDA4" { "SourcePath" = "8:..\\samples\\memmap\\largemem.c" @@ -2145,6 +2285,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749A2BA18335F50EB53CCE7029861FBC" + { + "SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" { "SourcePath" = "8:..\\samples\\resources\\breakoutchars.bin" @@ -2345,6 +2505,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8667075410229C38BF63AC1CC776055E" + { + "SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8827B6B07A1C4B32B08DF784E090381D" { "SourcePath" = "8:..\\samples\\memmap\\tsr.c" @@ -2865,6 +3045,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B2F1B217D45A434DBA8EC21095F4D717" + { + "SourcePath" = "8:..\\samples\\memmap\\charsetload.c" + "TargetName" = "8:charsetload.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}:_B4265CBF352343D2867DBCCE67D9F493" { "SourcePath" = "8:..\\include\\c64\\joystick.c" @@ -3425,6 +3625,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DD5A4DD822437085CD584319732F2D4D" + { + "SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DEADBEA270134B77800770802B21859C" { "SourcePath" = "8:..\\samples\\games\\connectfour.c" @@ -3625,6 +3845,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EA3C0BCB01F2639DFA2E37EC8436E5F6" + { + "SourcePath" = "8:VERSION.dll" + "TargetName" = "8:VERSION.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ED872D39D58443D590B7C80604BC0FF4" { "SourcePath" = "8:..\\samples\\kernalio\\fileread.c" @@ -3725,6 +3965,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F20F5618C7576D758C01D89C87469AF8" + { + "SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "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:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F35970F9D8FA46B09F36D7E9DE5532CA" { "SourcePath" = "8:..\\include\\c64\\charwin.h" @@ -4101,15 +4361,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{012BAFFC-85BE-4D95-A9FB-7203B5435FF1}" - "PackageCode" = "8:{ABEDA3FF-5D70-41AE-9FBC-FA8BCE3C85E7}" + "ProductCode" = "8:{75E6858C-F4C7-408B-A9E2-E1DC9B2FD03B}" + "PackageCode" = "8:{B04A68D8-DF4C-49FC-A0A4-2C51B24676B9}" "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.6.125" + "ProductVersion" = "8:1.7.126" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/memmap/build.sh b/samples/memmap/build.sh index 214ec30..95e4873 100644 --- a/samples/memmap/build.sh +++ b/samples/memmap/build.sh @@ -5,6 +5,7 @@ ../../bin/oscar64 charsethi.c ../../bin/oscar64 charsetcopy.c ../../bin/oscar64 charsetexpand.c +../../bin/oscar64 charsetload.c -d64=charsetload.d64 -fz=../resources/charset.bin ../../bin/oscar64 easyflash.c -n -tf=crt ../../bin/oscar64 easyflashreloc.c -n -tf=crt ../../bin/oscar64 easyflashshared.c -n -tf=crt diff --git a/samples/memmap/charsetload.c b/samples/memmap/charsetload.c new file mode 100644 index 0000000..650d8ab --- /dev/null +++ b/samples/memmap/charsetload.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +#define Screen ((char *)0xcc00) +#define Charset ((char *)0xc000) + +int main(void) +{ + // Set name for file and open it on drive 9 + krnio_setnam("CHARSET,P,R"); + if (krnio_open(2, 8, 2)) + { + // Read the content of the file into the charset buffer, + // decompressing on the fly + krnio_read_lzo(2, Charset); + + // Close the file + krnio_close(2); + } + + // Change display address to new screen and charset + + vic_setmode(VICM_TEXT, Screen, Charset) + + for(int i=0; i<1000; i++) + Screen[i] = (char)i; + + // wait for keypress + + getchar(); + + // restore VIC + + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000) + + // restore basic ROM + mmap_set(MMAP_ROM); + + return 0; +} + + diff --git a/samples/memmap/charsetload.d64 b/samples/memmap/charsetload.d64 new file mode 100644 index 0000000000000000000000000000000000000000..ae1dbe01dab89af0b4f162a55a987a2e43cdad4c GIT binary patch literal 174848 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 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 J0KhNee*mD=)xQ7$ literal 0 HcmV?d00001 diff --git a/samples/memmap/make.bat b/samples/memmap/make.bat index 8e4e863..cdefdb1 100644 --- a/samples/memmap/make.bat +++ b/samples/memmap/make.bat @@ -4,6 +4,7 @@ call ..\..\bin\oscar64 charsetlo.c call ..\..\bin\oscar64 charsethi.c call ..\..\bin\oscar64 charsetcopy.c call ..\..\bin\oscar64 charsetexpand.c +call ..\..\bin\oscar64 charsetload.c -d64=charsetload.d64 -fz=../resources/charset.bin call ..\..\bin\oscar64 easyflash.c -n -tf=crt call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt