Add overlay support
This commit is contained in:
parent
0aa9ca0c70
commit
0055911491
20
README.md
20
README.md
|
@ -448,6 +448,22 @@ the start of the stack section. The size of the stack and the minimum size of t
|
||||||
|
|
||||||
The linker will throw an error if the heap or stack cannot be placed without collision.
|
The linker will throw an error if the heap or stack cannot be placed without collision.
|
||||||
|
|
||||||
|
|
||||||
|
#### Overlays
|
||||||
|
|
||||||
|
The linker can generate overlay files that are stored as .prg in the .d64 when selected as target.
|
||||||
|
|
||||||
|
The mechanism uses the cartridge bank to denote up to 64 overlays. Each bank can be associated with one overlay file, which will then contain the used content of this bank.
|
||||||
|
|
||||||
|
#pragma overlay( ovl1, 1 )
|
||||||
|
|
||||||
|
The overlay file can then be loaded in memory during program execution:
|
||||||
|
|
||||||
|
krnio_setnam(P"OVL1");
|
||||||
|
krnio_load(1, 8, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Inline Assembler
|
### Inline Assembler
|
||||||
|
|
||||||
Inline assembler can be embedded inside of any functions, regardles of their compilation target of byte code or native.
|
Inline assembler can be embedded inside of any functions, regardles of their compilation target of byte code or native.
|
||||||
|
@ -608,6 +624,10 @@ An alternative to calling the function in the cartridge ROM itself is to copy it
|
||||||
|
|
||||||
This sample will use the memory area starting from 0x0400 for the main code section when copying the code, using the stack page 0x100 for the startup itself, thus wasting small amount of RAM space.
|
This sample will use the memory area starting from 0x0400 for the main code section when copying the code, using the stack page 0x100 for the startup itself, thus wasting small amount of RAM space.
|
||||||
|
|
||||||
|
#### Dynamic overlays "overlay.c"
|
||||||
|
|
||||||
|
When compiling for .d64 format, the linker will place code and data sections from virtual cartridge banks into overlay files. These files can be loaded when needed and called using normal function calls.
|
||||||
|
|
||||||
|
|
||||||
#### Terminate stay resident "tsr.c"
|
#### Terminate stay resident "tsr.c"
|
||||||
|
|
||||||
|
|
|
@ -546,9 +546,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
||||||
while (i > 0 && prgPath[i - 1] != '/' && prgPath[i - 1] != '\\')
|
while (i > 0 && prgPath[i - 1] != '/' && prgPath[i - 1] != '\\')
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
d64->OpenFile(prgPath + i);
|
mLinker->WritePrgFile(d64, prgPath + i);
|
||||||
mLinker->WritePrgFile(d64);
|
|
||||||
d64->CloseFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCompilerOptions & COPT_VERBOSE)
|
if (mCompilerOptions & COPT_VERBOSE)
|
||||||
|
|
|
@ -82,14 +82,25 @@ uint8* LinkerObject::AddSpace(int size)
|
||||||
return mData;
|
return mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkerOverlay::LinkerOverlay(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkerOverlay::~LinkerOverlay(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Linker::Linker(Errors* errors)
|
Linker::Linker(Errors* errors)
|
||||||
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mCompilerOptions(COPT_DEFAULT)
|
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mOverlays(nullptr), mCompilerOptions(COPT_DEFAULT)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
mCartridgeBankUsed[i] = 0;
|
mCartridgeBankUsed[i] = 0;
|
||||||
mCartridgeBankSize[i] = 0;
|
mCartridgeBankStart[i] = 0x10000;
|
||||||
memset(mCartridge[i], 0, 0x4000);
|
mCartridgeBankEnd[i] = 0x00000;
|
||||||
|
memset(mCartridge[i], 0, 0x10000);
|
||||||
}
|
}
|
||||||
memset(mMemory, 0, 0x10000);
|
memset(mMemory, 0, 0x10000);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +158,17 @@ LinkerSection* Linker::FindSection(const Ident* section)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkerOverlay* Linker::AddOverlay(const Location& location, const Ident* ident, int bank)
|
||||||
|
{
|
||||||
|
LinkerOverlay* lovl = new LinkerOverlay;
|
||||||
|
lovl->mLocation = location;
|
||||||
|
lovl->mIdent = ident;
|
||||||
|
lovl->mBank = bank;
|
||||||
|
mOverlays.Push(lovl);
|
||||||
|
|
||||||
|
return lovl;
|
||||||
|
}
|
||||||
|
|
||||||
bool Linker::IsSectionPlaced(LinkerSection* section)
|
bool Linker::IsSectionPlaced(LinkerSection* section)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mRegions.Size(); i++)
|
for (int i = 0; i < mRegions.Size(); i++)
|
||||||
|
@ -376,7 +398,7 @@ void Linker::Link(void)
|
||||||
{
|
{
|
||||||
LinkerRegion* lrgn = mRegions[i];
|
LinkerRegion* lrgn = mRegions[i];
|
||||||
|
|
||||||
if (lrgn->mNonzero)
|
if (lrgn->mNonzero && lrgn->mCartridgeBanks == 0)
|
||||||
{
|
{
|
||||||
if (lrgn->mStart < mProgramStart)
|
if (lrgn->mStart < mProgramStart)
|
||||||
mProgramStart = lrgn->mStart;
|
mProgramStart = lrgn->mStart;
|
||||||
|
@ -461,9 +483,11 @@ void Linker::Link(void)
|
||||||
if (obj->mRegion->mCartridgeBanks & (1ULL << i))
|
if (obj->mRegion->mCartridgeBanks & (1ULL << i))
|
||||||
{
|
{
|
||||||
mCartridgeBankUsed[i] = true;
|
mCartridgeBankUsed[i] = true;
|
||||||
memcpy(mCartridge[i] + obj->mAddress - 0x8000, obj->mData, obj->mSize);
|
memcpy(mCartridge[i] + obj->mAddress, obj->mData, obj->mSize);
|
||||||
if (obj->mAddress - 0x8000 + obj->mSize > mCartridgeBankSize[i])
|
if (obj->mAddress < mCartridgeBankStart[i])
|
||||||
mCartridgeBankSize[i] = obj->mAddress - 0x8000 + obj->mSize;
|
mCartridgeBankStart[i] = obj->mAddress;
|
||||||
|
if (obj->mAddress + obj->mSize > mCartridgeBankEnd[i])
|
||||||
|
mCartridgeBankEnd[i] = obj->mAddress + obj->mSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,7 +517,7 @@ void Linker::Link(void)
|
||||||
{
|
{
|
||||||
if (obj->mRegion->mCartridgeBanks & (1ULL << i))
|
if (obj->mRegion->mCartridgeBanks & (1ULL << i))
|
||||||
{
|
{
|
||||||
dp = mCartridge[i] + obj->mAddress - 0x8000 + ref->mOffset;
|
dp = mCartridge[i] + obj->mAddress + ref->mOffset;
|
||||||
|
|
||||||
if (ref->mFlags & LREF_LOWBYTE)
|
if (ref->mFlags & LREF_LOWBYTE)
|
||||||
{
|
{
|
||||||
|
@ -569,12 +593,38 @@ bool Linker::WriteBinFile(const char* filename)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Linker::WritePrgFile(DiskImage* image)
|
bool Linker::WritePrgFile(DiskImage* image, const char* filename)
|
||||||
{
|
{
|
||||||
mMemory[mProgramStart - 2] = mProgramStart & 0xff;
|
if (image->OpenFile(filename))
|
||||||
mMemory[mProgramStart - 1] = mProgramStart >> 8;
|
{
|
||||||
|
mMemory[mProgramStart - 2] = mProgramStart & 0xff;
|
||||||
|
mMemory[mProgramStart - 1] = mProgramStart >> 8;
|
||||||
|
|
||||||
return image->WriteBytes(mMemory + mProgramStart - 2, mProgramEnd - mProgramStart + 2);
|
image->WriteBytes(mMemory + mProgramStart - 2, mProgramEnd - mProgramStart + 2);
|
||||||
|
image->CloseFile();
|
||||||
|
|
||||||
|
for (int i = 0; i < mOverlays.Size(); i++)
|
||||||
|
{
|
||||||
|
if (image->OpenFile(mOverlays[i]->mIdent->mString))
|
||||||
|
{
|
||||||
|
int b = mOverlays[i]->mBank;
|
||||||
|
int s = mCartridgeBankStart[b];
|
||||||
|
|
||||||
|
mCartridge[b][s - 2] = s & 0xff;
|
||||||
|
mCartridge[b][s - 1] = s >> 8;
|
||||||
|
|
||||||
|
image->WriteBytes(mCartridge[b] + s - 2, mCartridgeBankEnd[b] - s + 2);
|
||||||
|
|
||||||
|
image->CloseFile();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Linker::WritePrgFile(const char* filename)
|
bool Linker::WritePrgFile(const char* filename)
|
||||||
|
@ -742,7 +792,8 @@ bool Linker::WriteCrtFile(const char* filename)
|
||||||
fwrite(bootmem + 0x2000, 1, 0x2000, file);
|
fwrite(bootmem + 0x2000, 1, 0x2000, file);
|
||||||
|
|
||||||
mCartridgeBankUsed[0] = true;
|
mCartridgeBankUsed[0] = true;
|
||||||
mCartridgeBankSize[0] = usedlz + 0x200;
|
mCartridgeBankStart[0] = 0x8000;
|
||||||
|
mCartridgeBankEnd[0] = 0x8000 + usedlz + 0x200;
|
||||||
|
|
||||||
for (int i = 1; i < 64; i++)
|
for (int i = 1; i < 64; i++)
|
||||||
{
|
{
|
||||||
|
@ -752,11 +803,11 @@ bool Linker::WriteCrtFile(const char* filename)
|
||||||
|
|
||||||
chipHeader.mLoadAddress = 0x0080;
|
chipHeader.mLoadAddress = 0x0080;
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(mCartridge[i] + 0x0000, 1, 0x2000, file);
|
fwrite(mCartridge[i] + 0x8000, 1, 0x2000, file);
|
||||||
|
|
||||||
chipHeader.mLoadAddress = 0x00a0;
|
chipHeader.mLoadAddress = 0x00a0;
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(mCartridge[i] + 0x2000, 1, 0x2000, file);
|
fwrite(mCartridge[i] + 0xa000, 1, 0x2000, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,7 +864,7 @@ bool Linker::WriteMapFile(const char* filename)
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
if (mCartridgeBankUsed[i])
|
if (mCartridgeBankUsed[i])
|
||||||
fprintf(file, "%02d : %04x\n", i, mCartridgeBankSize[i]);
|
fprintf(file, "%02d : %04x .. %04x (%04x)\n", i, mCartridgeBankStart[i], mCartridgeBankEnd[i], mCartridgeBankEnd[i] - mCartridgeBankStart[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,7 +924,7 @@ bool Linker::WriteAsmFile(const char* filename)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
||||||
i++;
|
i++;
|
||||||
mNativeDisassembler.Disassemble(file, mCartridge[i] - 0x8000, i, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
mNativeDisassembler.Disassemble(file, mCartridge[i], i, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mNativeDisassembler.Disassemble(file, mMemory, 0, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
mNativeDisassembler.Disassemble(file, mMemory, 0, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||||
|
@ -884,7 +935,7 @@ bool Linker::WriteAsmFile(const char* filename)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
||||||
i++;
|
i++;
|
||||||
mNativeDisassembler.DumpMemory(file, mCartridge[i] - 0x8000, i, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
|
mNativeDisassembler.DumpMemory(file, mCartridge[i], i, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mNativeDisassembler.DumpMemory(file, mMemory, 0, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
|
mNativeDisassembler.DumpMemory(file, mMemory, 0, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
|
||||||
|
|
|
@ -172,6 +172,17 @@ public:
|
||||||
void MarkRelevant(void);
|
void MarkRelevant(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LinkerOverlay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LinkerOverlay(void);
|
||||||
|
~LinkerOverlay(void);
|
||||||
|
|
||||||
|
Location mLocation;
|
||||||
|
const Ident * mIdent;
|
||||||
|
int mBank;
|
||||||
|
};
|
||||||
|
|
||||||
class Linker
|
class Linker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -190,9 +201,11 @@ public:
|
||||||
|
|
||||||
LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type, int alignment = 1);
|
LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type, int alignment = 1);
|
||||||
|
|
||||||
|
LinkerOverlay* AddOverlay(const Location& location, const Ident* ident, int bank);
|
||||||
|
|
||||||
// void AddReference(const LinkerReference& ref);
|
// void AddReference(const LinkerReference& ref);
|
||||||
|
|
||||||
bool WritePrgFile(DiskImage * image);
|
bool WritePrgFile(DiskImage * image, const char* filename);
|
||||||
bool WritePrgFile(const char* filename);
|
bool WritePrgFile(const char* filename);
|
||||||
bool WriteMapFile(const char* filename);
|
bool WriteMapFile(const char* filename);
|
||||||
bool WriteAsmFile(const char* filename);
|
bool WriteAsmFile(const char* filename);
|
||||||
|
@ -206,13 +219,14 @@ public:
|
||||||
GrowingArray<LinkerRegion*> mRegions;
|
GrowingArray<LinkerRegion*> mRegions;
|
||||||
GrowingArray<LinkerSection*> mSections;
|
GrowingArray<LinkerSection*> mSections;
|
||||||
GrowingArray<LinkerObject*> mObjects;
|
GrowingArray<LinkerObject*> mObjects;
|
||||||
|
GrowingArray<LinkerOverlay*> mOverlays;
|
||||||
|
|
||||||
uint8 mMemory[0x10000];
|
uint8 mMemory[0x10000];
|
||||||
uint8 mCartridge[64][0x4000];
|
uint8 mCartridge[64][0x10000];
|
||||||
|
|
||||||
bool mCartridgeBankUsed[64];
|
bool mCartridgeBankUsed[64];
|
||||||
|
|
||||||
uint32 mCartridgeBankSize[64];
|
uint32 mCartridgeBankStart[64], mCartridgeBankEnd[64];
|
||||||
|
|
||||||
int mProgramStart, mProgramEnd;
|
int mProgramStart, mProgramEnd;
|
||||||
|
|
||||||
|
|
|
@ -3607,6 +3607,33 @@ void Parser::ParsePragma(void)
|
||||||
|
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "overlay"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* overlayIdent = mScanner->mTokenIdent;
|
||||||
|
mScanner->NextToken();
|
||||||
|
|
||||||
|
int bank = 0;
|
||||||
|
|
||||||
|
ConsumeToken(TK_COMMA);
|
||||||
|
|
||||||
|
Expression* exp;
|
||||||
|
|
||||||
|
exp = ParseRExpression();
|
||||||
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
bank = exp->mDecValue->mInteger;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Integer number for bank expected");
|
||||||
|
|
||||||
|
LinkerOverlay* lovl = mCompilationUnits->mLinker->AddOverlay(mScanner->mLocation, overlayIdent, bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else if (!strcmp(mScanner->mTokenIdent->mString, "section"))
|
else if (!strcmp(mScanner->mTokenIdent->mString, "section"))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.11.173");
|
strcpy(strProductVersion, "1.12.174");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,11,173,0
|
FILEVERSION 1,12,174,0
|
||||||
PRODUCTVERSION 1,11,173,0
|
PRODUCTVERSION 1,12,174,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.11.173.0"
|
VALUE "FileVersion", "1.12.174.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.11.173.0"
|
VALUE "ProductVersion", "1.12.174.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -838,6 +838,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_E3FF6A8B315C439DA54DE18DB39FB3AD"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_E4138658F1F544CF86255EDC1659936D"
|
"MsmKey" = "8:_E4138658F1F544CF86255EDC1659936D"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -3777,6 +3783,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"IsolateTo" = "8:"
|
||||||
}
|
}
|
||||||
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E3FF6A8B315C439DA54DE18DB39FB3AD"
|
||||||
|
{
|
||||||
|
"SourcePath" = "8:..\\samples\\memmap\\overlay.c"
|
||||||
|
"TargetName" = "8:overlay.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}:_E4138658F1F544CF86255EDC1659936D"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E4138658F1F544CF86255EDC1659936D"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\samples\\kernalio\\charread.c"
|
"SourcePath" = "8:..\\samples\\kernalio\\charread.c"
|
||||||
|
@ -4424,15 +4450,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{B37C3691-BB18-4F82-B574-F47BF7A70D6E}"
|
"ProductCode" = "8:{2FD4FD95-A0D1-4DC0-A9F4-DE9085C7F327}"
|
||||||
"PackageCode" = "8:{1B3B4C99-2560-4BE0-8F6A-05067CD5006F}"
|
"PackageCode" = "8:{9C02A8C7-2D5F-4FAB-8185-219EDC622E4E}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.11.173"
|
"ProductVersion" = "8:1.12.174"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
|
@ -10,3 +10,4 @@
|
||||||
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
||||||
../../bin/oscar64 easyflashshared.c -n -tf=crt
|
../../bin/oscar64 easyflashshared.c -n -tf=crt
|
||||||
../../bin/oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
../../bin/oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
||||||
|
../../bin/oscar64 overlay.c -n -d64=overlay.d64
|
||||||
|
|
|
@ -10,3 +10,4 @@ call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt
|
||||||
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
||||||
call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt
|
call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt
|
||||||
call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
||||||
|
call ..\..\bin\oscar64 overlay.c -n -d64=overlay.d64
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include <c64/memmap.h>
|
||||||
|
#include <c64/charwin.h>
|
||||||
|
#include <c64/cia.h>
|
||||||
|
#include <c64/vic.h>
|
||||||
|
#include <c64/kernalio.h>
|
||||||
|
|
||||||
|
// Common memory area for all overlays
|
||||||
|
|
||||||
|
#pragma region( main, 0x0900, 0x8000, , , { code, data, bss, heap, stack } )
|
||||||
|
|
||||||
|
// Section and region for first overlay bank
|
||||||
|
|
||||||
|
#pragma overlay( ovl1, 1 )
|
||||||
|
#pragma section( bcode1, 0 )
|
||||||
|
#pragma section( bdata1, 0 )
|
||||||
|
#pragma region(bank1, 0x8000, 0xc000, , 1, { bcode1, bdata1 } )
|
||||||
|
|
||||||
|
// Section and region for second overlay bank
|
||||||
|
|
||||||
|
#pragma overlay( ovl2, 2 )
|
||||||
|
#pragma section( bcode2, 0 )
|
||||||
|
#pragma section( bdata2, 0 )
|
||||||
|
#pragma region(bank2, 0x8000, 0xc000, , 2, { bcode2, bdata2 } )
|
||||||
|
|
||||||
|
#pragma overlay( ovl3, 3 )
|
||||||
|
#pragma section( bcode3, 0 )
|
||||||
|
#pragma section( bdata3, 0 )
|
||||||
|
#pragma region(bank3, 0x8000, 0xc000, , 3, { bcode3, bdata3 } )
|
||||||
|
|
||||||
|
#pragma overlay( ovl4, 4 )
|
||||||
|
#pragma section( bcode4, 0 )
|
||||||
|
#pragma section( bdata4, 0 )
|
||||||
|
#pragma region(bank4, 0x8000, 0xc000, , 4, { bcode4, bdata4 } )
|
||||||
|
|
||||||
|
#pragma overlay( ovl5, 5 )
|
||||||
|
#pragma section( bcode5, 0 )
|
||||||
|
#pragma section( bdata5, 0 )
|
||||||
|
#pragma region(bank5, 0x8000, 0xc000, , 5, { bcode5, bdata5 } )
|
||||||
|
|
||||||
|
#pragma overlay( ovl6, 6 )
|
||||||
|
#pragma section( bcode6, 0 )
|
||||||
|
#pragma section( bdata6, 0 )
|
||||||
|
#pragma region(bank6, 0x8000, 0xc000, , 6, { bcode6, bdata6 } )
|
||||||
|
|
||||||
|
// Charwin in shared memory section
|
||||||
|
|
||||||
|
CharWin cw;
|
||||||
|
|
||||||
|
// Now switch code generation to bank 1
|
||||||
|
|
||||||
|
#pragma code ( bcode1 )
|
||||||
|
#pragma data ( bdata1 )
|
||||||
|
|
||||||
|
// Print into shared charwin
|
||||||
|
|
||||||
|
void print1(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is first overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now switch code generation to bank 2
|
||||||
|
|
||||||
|
#pragma code ( bcode2 )
|
||||||
|
#pragma data ( bdata2 )
|
||||||
|
|
||||||
|
void print2(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is second overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma code ( bcode3 )
|
||||||
|
#pragma data ( bdata3 )
|
||||||
|
|
||||||
|
void print3(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is third overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma code ( bcode4 )
|
||||||
|
#pragma data ( bdata4 )
|
||||||
|
|
||||||
|
void print4(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is fourth overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma code ( bcode5 )
|
||||||
|
#pragma data ( bdata5 )
|
||||||
|
|
||||||
|
void print5(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is fifth overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma code ( bcode6 )
|
||||||
|
#pragma data ( bdata6 )
|
||||||
|
|
||||||
|
void print6(void)
|
||||||
|
{
|
||||||
|
cwin_put_string(&cw, p"This is sixth overlay", 7);
|
||||||
|
cwin_cursor_newline(&cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switching code generation back to shared section
|
||||||
|
|
||||||
|
#pragma code ( code )
|
||||||
|
#pragma data ( data )
|
||||||
|
|
||||||
|
// Load an overlay section into memory
|
||||||
|
|
||||||
|
void load(const char * fname)
|
||||||
|
{
|
||||||
|
krnio_setnam(fname);
|
||||||
|
krnio_load(1, 8, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Kernal memory only
|
||||||
|
mmap_set(MMAP_NO_BASIC);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Call function in overlay 1
|
||||||
|
load(P"OVL1");
|
||||||
|
print1();
|
||||||
|
|
||||||
|
// Call function in overlay 2
|
||||||
|
load(P"OVL2");
|
||||||
|
print2();
|
||||||
|
|
||||||
|
load(P"OVL3");
|
||||||
|
print3();
|
||||||
|
|
||||||
|
load(P"OVL4");
|
||||||
|
print4();
|
||||||
|
|
||||||
|
load(P"OVL5");
|
||||||
|
print5();
|
||||||
|
|
||||||
|
load(P"OVL6");
|
||||||
|
print6();
|
||||||
|
|
||||||
|
mmap_set(MMAP_ROM);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue