Prepare cartdridge linking
This commit is contained in:
parent
6481e119e4
commit
6444428489
|
@ -6,12 +6,58 @@ void StackStart, StackEnd, BSSStart, BSSEnd;
|
|||
#pragma section(stack, 0x0000, StackStart, StackEnd)
|
||||
#pragma section(bss, 0x0000, BSSStart, BSSEnd)
|
||||
|
||||
char spentry;
|
||||
char spentry = 0;
|
||||
|
||||
int main(void);
|
||||
|
||||
__asm inp_exit
|
||||
{
|
||||
lda #$4c
|
||||
sta $54
|
||||
lda #0
|
||||
sta $13
|
||||
rts
|
||||
}
|
||||
|
||||
|
||||
__asm startup
|
||||
{
|
||||
#ifdef OSCAR_TARGET_CRT16
|
||||
byt 0x09
|
||||
byt 0x80
|
||||
byt 0xbc
|
||||
byt 0xfe
|
||||
byt 0xc3
|
||||
byt 0xc2
|
||||
byt 0xcd
|
||||
byt 0x38
|
||||
byt 0x30
|
||||
|
||||
// Copy cartridge rom to ram
|
||||
|
||||
ldx #$40
|
||||
ldy #$00
|
||||
lda #$80
|
||||
sta ip + 1
|
||||
lda #$08
|
||||
sta sp + 1
|
||||
sty ip
|
||||
sty sp
|
||||
l0: lda (ip), y
|
||||
sta (sp), y
|
||||
iny
|
||||
bne l0
|
||||
inc ip + 1
|
||||
inc sp + 1
|
||||
dex
|
||||
bne l0
|
||||
lda $01
|
||||
and #$fc
|
||||
ora #$02
|
||||
sta $01
|
||||
jmp w0
|
||||
w0:
|
||||
#else
|
||||
byt 0x0b
|
||||
byt 0x08
|
||||
byt 0x0a
|
||||
|
@ -24,7 +70,7 @@ __asm startup
|
|||
byt 0x00
|
||||
byt 0x00
|
||||
byt 0x00
|
||||
|
||||
#endif
|
||||
// Clear BSS Segment
|
||||
|
||||
tsx
|
||||
|
@ -60,6 +106,21 @@ l2: dey
|
|||
bne l2
|
||||
w2:
|
||||
|
||||
lda #<StackEnd - 2
|
||||
sta sp
|
||||
lda #>StackEnd - 2
|
||||
sta sp + 1
|
||||
|
||||
#ifdef OSCAR_NATIVE_ALL
|
||||
|
||||
// All native code
|
||||
jsr main
|
||||
pexec:
|
||||
exec:
|
||||
jmp inp_exit
|
||||
|
||||
#else
|
||||
|
||||
// Init byte code
|
||||
|
||||
lda #<bcode
|
||||
|
@ -67,10 +128,6 @@ w2:
|
|||
lda #>bcode
|
||||
sta ip + 1
|
||||
|
||||
lda #<StackEnd - 2
|
||||
sta sp
|
||||
lda #>StackEnd - 2
|
||||
sta sp + 1
|
||||
pexec:
|
||||
ldy #0
|
||||
exec:
|
||||
|
@ -96,6 +153,7 @@ bcode:
|
|||
byt >main
|
||||
byt BC_CALL * 2
|
||||
byt BC_EXIT * 2
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma startup(startup)
|
||||
|
@ -561,15 +619,6 @@ __asm inp_nop
|
|||
|
||||
#pragma bytecode(BC_NOP, inp_nop)
|
||||
|
||||
__asm inp_exit
|
||||
{
|
||||
lda #$4c
|
||||
sta $54
|
||||
lda #0
|
||||
sta $13
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_EXIT, inp_exit)
|
||||
|
||||
__asm inp_jsr
|
||||
|
|
|
@ -3670,6 +3670,15 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
mIns[i + 1].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mCode == BC_STORE_REG_16 &&
|
||||
mIns[i + 1].LoadsRegister(BC_REG_ACCU) &&
|
||||
mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal)
|
||||
{
|
||||
mIns[i + 0].mCode = BC_NOP;
|
||||
mIns[i + 1].mRegister = mIns[i + 0].mRegister;
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
|
@ -3765,6 +3774,23 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
mIns[i].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if ((mIns[i].mCode == BC_CONST_16 || mIns[i].mCode == BC_CONST_P8 || mIns[i].mCode == BC_CONST_N8) &&
|
||||
(mIns[i + 1].mCode == BC_CONST_16 || mIns[i + 1].mCode == BC_CONST_P8 || mIns[i + 1].mCode == BC_CONST_N8 || mIns[i + 1].mCode == BC_CONST_32) && mIns[i].mRegister == mIns[i + 1].mRegister)
|
||||
{
|
||||
mIns[i].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (mIns[i].mCode == BC_CONST_32 && mIns[i + 1].mCode == BC_CONST_32 && mIns[i].mRegister == mIns[i + 1].mRegister)
|
||||
{
|
||||
mIns[i].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (mIns[i].mCode == BC_CONST_8 && mIns[i + 1].mCode == BC_CONST_8 && mIns[i].mRegister == mIns[i + 1].mRegister)
|
||||
{
|
||||
mIns[i].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||
{
|
||||
|
|
|
@ -124,24 +124,44 @@ bool Compiler::GenerateCode(void)
|
|||
|
||||
LinkerRegion* regionStartup = mLinker->FindRegion(identStartup);
|
||||
if (!regionStartup)
|
||||
{
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x0801, 0x0900);
|
||||
else
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x0800, 0x0900);
|
||||
}
|
||||
|
||||
LinkerRegion* regionBytecode = mLinker->FindRegion(identBytecode);
|
||||
LinkerRegion* regionBytecode = nullptr;
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
{
|
||||
regionBytecode = mLinker->FindRegion(identBytecode);
|
||||
if (!regionBytecode)
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
||||
}
|
||||
|
||||
LinkerRegion* regionMain = mLinker->FindRegion(identMain);
|
||||
|
||||
LinkerSection * sectionStartup = mLinker->AddSection(identStartup, LST_DATA);
|
||||
LinkerSection * sectionBytecode = mLinker->AddSection(identBytecode, LST_DATA);
|
||||
LinkerSection* sectionBytecode = nullptr;
|
||||
if (regionBytecode)
|
||||
{
|
||||
sectionBytecode = mLinker->AddSection(identBytecode, LST_DATA);
|
||||
}
|
||||
|
||||
regionStartup->mSections.Push(sectionStartup);
|
||||
|
||||
if (regionBytecode)
|
||||
regionBytecode->mSections.Push(sectionBytecode);
|
||||
|
||||
if (!mLinker->IsSectionPlaced(mCompilationUnits->mSectionCode))
|
||||
{
|
||||
if (!regionMain)
|
||||
{
|
||||
if (regionBytecode)
|
||||
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
||||
else
|
||||
regionMain = mLinker->AddRegion(identMain, 0x0900, 0xa000);
|
||||
}
|
||||
|
||||
regionMain->mSections.Push(mCompilationUnits->mSectionCode);
|
||||
regionMain->mSections.Push(mCompilationUnits->mSectionData);
|
||||
|
@ -239,9 +259,12 @@ bool Compiler::GenerateCode(void)
|
|||
}
|
||||
}
|
||||
|
||||
LinkerObject* byteCodeObject = nullptr;
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
{
|
||||
// Compile used byte code functions
|
||||
|
||||
LinkerObject* byteCodeObject = mLinker->AddObject(loc, Ident::Unique("bytecode"), sectionBytecode, LOT_RUNTIME);
|
||||
byteCodeObject = mLinker->AddObject(loc, Ident::Unique("bytecode"), sectionBytecode, LOT_RUNTIME);
|
||||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
|
@ -285,10 +308,13 @@ bool Compiler::GenerateCode(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLinker->CollectReferences();
|
||||
|
||||
mLinker->ReferenceObject(dcrtstart->mLinkerObject);
|
||||
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
mLinker->ReferenceObject(byteCodeObject);
|
||||
|
||||
mLinker->Link();
|
||||
|
@ -298,7 +324,7 @@ bool Compiler::GenerateCode(void)
|
|||
|
||||
bool Compiler::WriteOutputFile(const char* targetPath)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200];
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], crtPath[200];
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
int i = strlen(prgPath);
|
||||
|
@ -309,14 +335,25 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
|||
strcpy_s(mapPath, prgPath);
|
||||
strcpy_s(asmPath, prgPath);
|
||||
strcpy_s(lblPath, prgPath);
|
||||
strcpy_s(crtPath, prgPath);
|
||||
|
||||
strcat_s(prgPath, "prg");
|
||||
strcat_s(mapPath, "map");
|
||||
strcat_s(asmPath, "asm");
|
||||
strcat_s(lblPath, "lbl");
|
||||
strcat_s(crtPath, "crt");
|
||||
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
printf("Writing <%s>\n", prgPath);
|
||||
mLinker->WritePrgFile(prgPath);
|
||||
}
|
||||
else if (mCompilerOptions & COPT_TARGET_CRT16)
|
||||
{
|
||||
printf("Writing <%s>\n", crtPath);
|
||||
mLinker->WriteCrtFile(crtPath);
|
||||
}
|
||||
|
||||
|
||||
printf("Writing <%s>\n", mapPath);
|
||||
mLinker->WriteMapFile(mapPath);
|
||||
|
@ -336,10 +373,21 @@ int Compiler::ExecuteCode(void)
|
|||
|
||||
printf("Running emulation...\n");
|
||||
Emulator* emu = new Emulator(mLinker);
|
||||
|
||||
int ecode = 20;
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
|
||||
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
||||
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
|
||||
int ecode = emu->Emulate(2061);
|
||||
ecode = emu->Emulate(2061);
|
||||
}
|
||||
else if (mCompilerOptions & COPT_TARGET_CRT16)
|
||||
{
|
||||
memcpy(emu->mMemory + 0x8000, mLinker->mMemory + 0x0800, 0x4000);
|
||||
ecode = emu->Emulate(0x8009);
|
||||
}
|
||||
|
||||
printf("Emulation result %d\n", ecode);
|
||||
|
||||
if (ecode != 0)
|
||||
|
|
|
@ -8,6 +8,11 @@ static const uint64 COPT_OPTIMIZE_INLINE = 0x00000002;
|
|||
static const uint64 COPT_OPTIMIZE_AUTO_INLINE = 0x00000010;
|
||||
static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020;
|
||||
|
||||
static const uint64 COPT_TARGET_PRG = 0x100000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT512 = 0x400000000ULL;
|
||||
static const uint64 COPT_TARGET_COPY = 0x800000000ULL;
|
||||
|
||||
static const uint64 COPT_NATIVE = 0x01000000;
|
||||
|
||||
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE;
|
||||
|
|
|
@ -197,7 +197,7 @@ void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
|
|||
else if (adec->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
AnalyzeProcedure(adec->mValue, adec);
|
||||
RegisterCall(adec, procDec);
|
||||
RegisterCall(procDec, adec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -333,6 +333,98 @@ bool Linker::WritePrgFile(const char* filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Linker::WriteCrtFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
struct CRIHeader
|
||||
{
|
||||
char mSignature[16];
|
||||
uint32 mHeaderLength;
|
||||
uint16 mVersion, mHardware;
|
||||
uint8 mExrom, mGameLine;
|
||||
uint8 mPad[6];
|
||||
char mName[32];
|
||||
} criHeader = { 0 };
|
||||
|
||||
memcpy(criHeader.mSignature, "C64 CARTRIDGE ", 16);
|
||||
criHeader.mHeaderLength = 0x40000000;
|
||||
criHeader.mVersion = 0x0001;
|
||||
criHeader.mHardware = 0x2000;
|
||||
criHeader.mExrom = 1;
|
||||
criHeader.mGameLine = 1;
|
||||
memset(criHeader.mName, 0, 32);
|
||||
strcpy_s(criHeader.mName, "OSCAR");
|
||||
|
||||
fwrite(&criHeader, sizeof(CRIHeader), 1, file);
|
||||
|
||||
struct CHIPHeader
|
||||
{
|
||||
char mSignature[4];
|
||||
uint32 mPacketLength;
|
||||
uint16 mChipType, mBankNumber, mLoadAddress, mImageSize;
|
||||
} chipHeader = { 0 };
|
||||
|
||||
memcpy(chipHeader.mSignature, "CHIP", 4);
|
||||
chipHeader.mPacketLength = 0x10200000;
|
||||
chipHeader.mChipType = 0;
|
||||
chipHeader.mBankNumber = 0;
|
||||
chipHeader.mImageSize = 0x0020;
|
||||
|
||||
char * bootmem = new char[8192];
|
||||
|
||||
chipHeader.mLoadAddress = 0x0080;
|
||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||
fwrite(bootmem, 1, 0x2000, file);
|
||||
|
||||
bootmem[0x1ffc] = 0x00;
|
||||
bootmem[0x1ffd] = 0xe0;
|
||||
|
||||
char bootcode[] = {
|
||||
0xa9, 0x87,
|
||||
0x8d, 0x02, 0xde,
|
||||
0xa9, 0x01,
|
||||
0x8d, 0x00, 0xde,
|
||||
0x6c, 0xfc, 0xff
|
||||
};
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < sizeof(bootcode); i++)
|
||||
{
|
||||
bootmem[j++] = 0xa9;
|
||||
bootmem[j++] = bootcode[i];
|
||||
bootmem[j++] = 0x8d;
|
||||
bootmem[j++] = i;
|
||||
bootmem[j++] = 0x04;
|
||||
}
|
||||
bootmem[j++] = 0x4c;
|
||||
bootmem[j++] = 0x00;
|
||||
bootmem[j++] = 0x04;
|
||||
|
||||
chipHeader.mLoadAddress = 0x00e0;
|
||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||
fwrite(bootmem, 1, 0x2000, file);
|
||||
|
||||
chipHeader.mBankNumber = 0x100;
|
||||
|
||||
chipHeader.mLoadAddress = 0x0080;
|
||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||
fwrite(mMemory + 0x0800, 1, 0x2000, file);
|
||||
|
||||
chipHeader.mLoadAddress = 0x00a0;
|
||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||
fwrite(mMemory + 0x2800, 1, 0x2000, file);
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Linker::WriteMapFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
|
|
@ -130,6 +130,7 @@ public:
|
|||
bool WriteMapFile(const char* filename);
|
||||
bool WriteAsmFile(const char* filename);
|
||||
bool WriteLblFile(const char* filename);
|
||||
bool WriteCrtFile(const char* filename);
|
||||
|
||||
GrowingArray<LinkerReference*> mReferences;
|
||||
GrowingArray<LinkerRegion*> mRegions;
|
||||
|
|
|
@ -978,7 +978,7 @@ void Scanner::NextRawToken(void)
|
|||
|
||||
case '#':
|
||||
{
|
||||
if (!mAssemblerMode || mOffset == 1)
|
||||
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1)
|
||||
{
|
||||
int n = 0;
|
||||
char tkprep[128];
|
||||
|
|
|
@ -116,6 +116,9 @@ int main(int argc, const char** argv)
|
|||
|
||||
targetPath[0] = 0;
|
||||
|
||||
char targetFormat[20];
|
||||
strcpy_s(targetFormat, "prg");
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
const char* arg = argv[i];
|
||||
|
@ -133,9 +136,14 @@ int main(int argc, const char** argv)
|
|||
{
|
||||
strcpy_s(crtPath, arg + 4);
|
||||
}
|
||||
else if (arg[1] == 't' && arg[2] == 'f' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(targetFormat, arg + 4);
|
||||
}
|
||||
else if (arg[1] == 'n')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_NATIVE;
|
||||
compiler->AddDefine(Ident::Unique("OSCAR_NATIVE_ALL"), "1");
|
||||
}
|
||||
else if (arg[1] == 'O')
|
||||
{
|
||||
|
@ -180,6 +188,21 @@ int main(int argc, const char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (!strcmp(targetFormat, "prg"))
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_TARGET_PRG;
|
||||
compiler->AddDefine(Ident::Unique("OSCAR_TARGET_PRG"), "1");
|
||||
}
|
||||
else if (!strcmp(targetFormat, "crt"))
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_TARGET_CRT16;
|
||||
compiler->AddDefine(Ident::Unique("OSCAR_TARGET_CRT16"), "1");
|
||||
}
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid target format option", targetFormat);
|
||||
|
||||
if (compiler->mErrors->mErrorCount == 0)
|
||||
{
|
||||
// Add runtime module
|
||||
|
||||
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);
|
||||
|
@ -191,6 +214,7 @@ int main(int argc, const char** argv)
|
|||
if (emulate)
|
||||
compiler->ExecuteCode();
|
||||
}
|
||||
}
|
||||
|
||||
if (compiler->mErrors->mErrorCount != 0)
|
||||
return 20;
|
||||
|
|
Loading…
Reference in New Issue