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(stack, 0x0000, StackStart, StackEnd)
|
||||||
#pragma section(bss, 0x0000, BSSStart, BSSEnd)
|
#pragma section(bss, 0x0000, BSSStart, BSSEnd)
|
||||||
|
|
||||||
char spentry;
|
char spentry = 0;
|
||||||
|
|
||||||
int main(void);
|
int main(void);
|
||||||
|
|
||||||
|
__asm inp_exit
|
||||||
|
{
|
||||||
|
lda #$4c
|
||||||
|
sta $54
|
||||||
|
lda #0
|
||||||
|
sta $13
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
__asm startup
|
__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 0x0b
|
||||||
byt 0x08
|
byt 0x08
|
||||||
byt 0x0a
|
byt 0x0a
|
||||||
|
@ -24,7 +70,7 @@ __asm startup
|
||||||
byt 0x00
|
byt 0x00
|
||||||
byt 0x00
|
byt 0x00
|
||||||
byt 0x00
|
byt 0x00
|
||||||
|
#endif
|
||||||
// Clear BSS Segment
|
// Clear BSS Segment
|
||||||
|
|
||||||
tsx
|
tsx
|
||||||
|
@ -60,6 +106,21 @@ l2: dey
|
||||||
bne l2
|
bne l2
|
||||||
w2:
|
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
|
// Init byte code
|
||||||
|
|
||||||
lda #<bcode
|
lda #<bcode
|
||||||
|
@ -67,10 +128,6 @@ w2:
|
||||||
lda #>bcode
|
lda #>bcode
|
||||||
sta ip + 1
|
sta ip + 1
|
||||||
|
|
||||||
lda #<StackEnd - 2
|
|
||||||
sta sp
|
|
||||||
lda #>StackEnd - 2
|
|
||||||
sta sp + 1
|
|
||||||
pexec:
|
pexec:
|
||||||
ldy #0
|
ldy #0
|
||||||
exec:
|
exec:
|
||||||
|
@ -96,6 +153,7 @@ bcode:
|
||||||
byt >main
|
byt >main
|
||||||
byt BC_CALL * 2
|
byt BC_CALL * 2
|
||||||
byt BC_EXIT * 2
|
byt BC_EXIT * 2
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma startup(startup)
|
#pragma startup(startup)
|
||||||
|
@ -561,15 +619,6 @@ __asm inp_nop
|
||||||
|
|
||||||
#pragma bytecode(BC_NOP, 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)
|
#pragma bytecode(BC_EXIT, inp_exit)
|
||||||
|
|
||||||
__asm inp_jsr
|
__asm inp_jsr
|
||||||
|
|
|
@ -3670,6 +3670,15 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 1].mCode = BC_NOP;
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
progress = true;
|
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
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -3765,6 +3774,23 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i].mCode = BC_NOP;
|
mIns[i].mCode = BC_NOP;
|
||||||
progress = true;
|
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
|
#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)
|
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);
|
LinkerRegion* regionStartup = mLinker->FindRegion(identStartup);
|
||||||
if (!regionStartup)
|
if (!regionStartup)
|
||||||
|
{
|
||||||
|
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||||
regionStartup = mLinker->AddRegion(identStartup, 0x0801, 0x0900);
|
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)
|
if (!regionBytecode)
|
||||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
||||||
|
}
|
||||||
|
|
||||||
LinkerRegion* regionMain = mLinker->FindRegion(identMain);
|
LinkerRegion* regionMain = mLinker->FindRegion(identMain);
|
||||||
|
|
||||||
LinkerSection * sectionStartup = mLinker->AddSection(identStartup, LST_DATA);
|
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);
|
regionStartup->mSections.Push(sectionStartup);
|
||||||
|
|
||||||
|
if (regionBytecode)
|
||||||
regionBytecode->mSections.Push(sectionBytecode);
|
regionBytecode->mSections.Push(sectionBytecode);
|
||||||
|
|
||||||
if (!mLinker->IsSectionPlaced(mCompilationUnits->mSectionCode))
|
if (!mLinker->IsSectionPlaced(mCompilationUnits->mSectionCode))
|
||||||
{
|
{
|
||||||
if (!regionMain)
|
if (!regionMain)
|
||||||
|
{
|
||||||
|
if (regionBytecode)
|
||||||
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
||||||
|
else
|
||||||
|
regionMain = mLinker->AddRegion(identMain, 0x0900, 0xa000);
|
||||||
|
}
|
||||||
|
|
||||||
regionMain->mSections.Push(mCompilationUnits->mSectionCode);
|
regionMain->mSections.Push(mCompilationUnits->mSectionCode);
|
||||||
regionMain->mSections.Push(mCompilationUnits->mSectionData);
|
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
|
// 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++)
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
|
@ -285,10 +308,13 @@ bool Compiler::GenerateCode(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mLinker->CollectReferences();
|
mLinker->CollectReferences();
|
||||||
|
|
||||||
mLinker->ReferenceObject(dcrtstart->mLinkerObject);
|
mLinker->ReferenceObject(dcrtstart->mLinkerObject);
|
||||||
|
|
||||||
|
if (!(mCompilerOptions & COPT_NATIVE))
|
||||||
mLinker->ReferenceObject(byteCodeObject);
|
mLinker->ReferenceObject(byteCodeObject);
|
||||||
|
|
||||||
mLinker->Link();
|
mLinker->Link();
|
||||||
|
@ -298,7 +324,7 @@ bool Compiler::GenerateCode(void)
|
||||||
|
|
||||||
bool Compiler::WriteOutputFile(const char* targetPath)
|
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);
|
strcpy_s(prgPath, targetPath);
|
||||||
int i = strlen(prgPath);
|
int i = strlen(prgPath);
|
||||||
|
@ -309,14 +335,25 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
strcpy_s(mapPath, prgPath);
|
strcpy_s(mapPath, prgPath);
|
||||||
strcpy_s(asmPath, prgPath);
|
strcpy_s(asmPath, prgPath);
|
||||||
strcpy_s(lblPath, prgPath);
|
strcpy_s(lblPath, prgPath);
|
||||||
|
strcpy_s(crtPath, prgPath);
|
||||||
|
|
||||||
strcat_s(prgPath, "prg");
|
strcat_s(prgPath, "prg");
|
||||||
strcat_s(mapPath, "map");
|
strcat_s(mapPath, "map");
|
||||||
strcat_s(asmPath, "asm");
|
strcat_s(asmPath, "asm");
|
||||||
strcat_s(lblPath, "lbl");
|
strcat_s(lblPath, "lbl");
|
||||||
|
strcat_s(crtPath, "crt");
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||||
|
{
|
||||||
printf("Writing <%s>\n", prgPath);
|
printf("Writing <%s>\n", prgPath);
|
||||||
mLinker->WritePrgFile(prgPath);
|
mLinker->WritePrgFile(prgPath);
|
||||||
|
}
|
||||||
|
else if (mCompilerOptions & COPT_TARGET_CRT16)
|
||||||
|
{
|
||||||
|
printf("Writing <%s>\n", crtPath);
|
||||||
|
mLinker->WriteCrtFile(crtPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("Writing <%s>\n", mapPath);
|
printf("Writing <%s>\n", mapPath);
|
||||||
mLinker->WriteMapFile(mapPath);
|
mLinker->WriteMapFile(mapPath);
|
||||||
|
@ -336,10 +373,21 @@ int Compiler::ExecuteCode(void)
|
||||||
|
|
||||||
printf("Running emulation...\n");
|
printf("Running emulation...\n");
|
||||||
Emulator* emu = new Emulator(mLinker);
|
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);
|
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
|
||||||
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
||||||
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
|
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);
|
printf("Emulation result %d\n", ecode);
|
||||||
|
|
||||||
if (ecode != 0)
|
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 = 0x00000010;
|
||||||
static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020;
|
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_NATIVE = 0x01000000;
|
||||||
|
|
||||||
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE;
|
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)
|
else if (adec->mType == DT_CONST_FUNCTION)
|
||||||
{
|
{
|
||||||
AnalyzeProcedure(adec->mValue, adec);
|
AnalyzeProcedure(adec->mValue, adec);
|
||||||
RegisterCall(adec, procDec);
|
RegisterCall(procDec, adec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,98 @@ bool Linker::WritePrgFile(const char* filename)
|
||||||
return false;
|
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)
|
bool Linker::WriteMapFile(const char* filename)
|
||||||
{
|
{
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
|
|
@ -130,6 +130,7 @@ public:
|
||||||
bool WriteMapFile(const char* filename);
|
bool WriteMapFile(const char* filename);
|
||||||
bool WriteAsmFile(const char* filename);
|
bool WriteAsmFile(const char* filename);
|
||||||
bool WriteLblFile(const char* filename);
|
bool WriteLblFile(const char* filename);
|
||||||
|
bool WriteCrtFile(const char* filename);
|
||||||
|
|
||||||
GrowingArray<LinkerReference*> mReferences;
|
GrowingArray<LinkerReference*> mReferences;
|
||||||
GrowingArray<LinkerRegion*> mRegions;
|
GrowingArray<LinkerRegion*> mRegions;
|
||||||
|
|
|
@ -978,7 +978,7 @@ void Scanner::NextRawToken(void)
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
if (!mAssemblerMode || mOffset == 1)
|
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char tkprep[128];
|
char tkprep[128];
|
||||||
|
|
|
@ -116,6 +116,9 @@ int main(int argc, const char** argv)
|
||||||
|
|
||||||
targetPath[0] = 0;
|
targetPath[0] = 0;
|
||||||
|
|
||||||
|
char targetFormat[20];
|
||||||
|
strcpy_s(targetFormat, "prg");
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
const char* arg = argv[i];
|
const char* arg = argv[i];
|
||||||
|
@ -133,9 +136,14 @@ int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
strcpy_s(crtPath, arg + 4);
|
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')
|
else if (arg[1] == 'n')
|
||||||
{
|
{
|
||||||
compiler->mCompilerOptions |= COPT_NATIVE;
|
compiler->mCompilerOptions |= COPT_NATIVE;
|
||||||
|
compiler->AddDefine(Ident::Unique("OSCAR_NATIVE_ALL"), "1");
|
||||||
}
|
}
|
||||||
else if (arg[1] == 'O')
|
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
|
// Add runtime module
|
||||||
|
|
||||||
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);
|
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);
|
||||||
|
@ -191,6 +214,7 @@ int main(int argc, const char** argv)
|
||||||
if (emulate)
|
if (emulate)
|
||||||
compiler->ExecuteCode();
|
compiler->ExecuteCode();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (compiler->mErrors->mErrorCount != 0)
|
if (compiler->mErrors->mErrorCount != 0)
|
||||||
return 20;
|
return 20;
|
||||||
|
|
Loading…
Reference in New Issue