Add support for d64 image creation

This commit is contained in:
drmortalwombat 2022-05-08 15:37:30 +02:00
parent c7de44b015
commit 75e5471dd1
20 changed files with 981 additions and 42 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -263,6 +263,8 @@ bool Compiler::GenerateCode(void)
// Register native runtime functions
if (mInterCodeModule->mProcedures.Size() > 0)
{
RegisterRuntime(loc, Ident::Unique("mul16by8"));
RegisterRuntime(loc, Ident::Unique("fsplitt"));
RegisterRuntime(loc, Ident::Unique("fsplitx"));
@ -288,6 +290,7 @@ bool Compiler::GenerateCode(void)
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);

View File

@ -38,9 +38,10 @@ public:
GrowingArray<Define> 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);

View File

@ -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;

352
oscar64/DiskImage.cpp Normal file
View File

@ -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<SectorsPerTrack[i]; j++)
fwrite(mSectors[i][j], 1, 256, file);
}
fclose(file);
return true;
}
else
return false;
}
bool DiskImage::OpenFile(const char* fname)
{
int si = 1;
int di = 0;
for(;;)
{
mDirEntry = mSectors[18][si] + di;
if (mDirEntry[2])
{
di += 32;
if (di == 256)
{
di = 0;
if (mSectors[18][si][0])
si = mSectors[18][si][1];
else
{
int ni = AllocBAMSector(18, si);
mSectors[18][si][0] = 18;
mSectors[18][si][0] = ni;
si = ni;
}
}
}
else
{
mTrack = AllocBAMTrack(17);
mSector = AllocBAMSector(mTrack, 0);
mDirEntry[2] = 0x82;
mDirEntry[3] = mTrack;
mDirEntry[4] = mSector;
mBytes = 2;
for (int i = 0; i < 16; i++)
mDirEntry[5 + i] = 0xa0;
int i = 0;
while (fname[i])
{
mDirEntry[5 + i] = A2P(fname[i]);
i++;
}
mDirEntry[30] = 1;
return true;
}
}
return false;
}
void DiskImage::CloseFile(void)
{
}
bool DiskImage::WriteFile(const char* fname, bool compressed)
{
FILE* file;
fopen_s(&file, fname, "rb");
if (file)
{
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] != '.')
{
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;
}

29
oscar64/DiskImage.h Normal file
View File

@ -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;
};

View File

@ -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;

View File

@ -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);

View File

@ -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]) &&

View File

@ -8,6 +8,7 @@
#include <mach-o/dyld.h>
#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<const char*> dataFiles(nullptr);
GrowingArray<bool> 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;
}

View File

@ -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"

View File

@ -150,6 +150,7 @@
<ClCompile Include="Compiler.cpp" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="Disassembler.cpp" />
<ClCompile Include="DiskImage.cpp" />
<ClCompile Include="Emulator.cpp" />
<ClCompile Include="Errors.cpp" />
<ClCompile Include="GlobalAnalyzer.cpp" />
@ -175,6 +176,7 @@
<ClInclude Include="CompilerTypes.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="Disassembler.h" />
<ClInclude Include="DiskImage.h" />
<ClInclude Include="Emulator.h" />
<ClInclude Include="Errors.h" />
<ClInclude Include="GlobalAnalyzer.h" />

View File

@ -75,6 +75,9 @@
<ClCompile Include="MachineTypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DiskImage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Array.h">
@ -146,6 +149,9 @@
<ClInclude Include="CompilerTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DiskImage.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">

View File

@ -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:"

View File

@ -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

View File

@ -0,0 +1,44 @@
#include <c64/vic.h>
#include <c64/memmap.h>
#include <c64/kernalio.h>
#include <stdio.h>
#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;
}

Binary file not shown.

View File

@ -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