More cartridge hacking
This commit is contained in:
parent
6444428489
commit
9833656fcf
|
@ -1,6 +1,19 @@
|
||||||
// crt.c
|
// crt.c
|
||||||
#include <crt.h>
|
#include <crt.h>
|
||||||
|
|
||||||
|
#define tmpy __tmpy
|
||||||
|
#define tmp __tmp
|
||||||
|
|
||||||
|
#define ip __ip
|
||||||
|
#define accu __accu
|
||||||
|
#define addr __addr
|
||||||
|
#define sp __sp
|
||||||
|
#define fp __fp
|
||||||
|
|
||||||
|
#define sregs __sregs
|
||||||
|
#define regs __regs
|
||||||
|
|
||||||
|
|
||||||
void StackStart, StackEnd, BSSStart, BSSEnd;
|
void StackStart, StackEnd, BSSStart, BSSEnd;
|
||||||
|
|
||||||
#pragma section(stack, 0x0000, StackStart, StackEnd)
|
#pragma section(stack, 0x0000, StackStart, StackEnd)
|
||||||
|
@ -51,12 +64,12 @@ l0: lda (ip), y
|
||||||
inc sp + 1
|
inc sp + 1
|
||||||
dex
|
dex
|
||||||
bne l0
|
bne l0
|
||||||
lda $01
|
|
||||||
and #$fc
|
|
||||||
ora #$02
|
|
||||||
sta $01
|
|
||||||
jmp w0
|
jmp w0
|
||||||
w0:
|
w0:
|
||||||
|
lda #$3f
|
||||||
|
sta $00
|
||||||
|
lda #$36
|
||||||
|
sta $01
|
||||||
#else
|
#else
|
||||||
byt 0x0b
|
byt 0x0b
|
||||||
byt 0x08
|
byt 0x08
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
#ifndef CRT_H
|
#ifndef CRT_H
|
||||||
#define CRT_H
|
#define CRT_H
|
||||||
|
|
||||||
#define tmpy 0x02
|
|
||||||
#define tmp 0x03
|
|
||||||
|
|
||||||
#define ip 0x19
|
|
||||||
#define accu 0x1b
|
|
||||||
#define addr 0x1f
|
|
||||||
#define sp 0x23
|
|
||||||
#define fp 0x25
|
|
||||||
|
|
||||||
#define sregs 0x43
|
|
||||||
#define regs 0x53
|
|
||||||
|
|
||||||
extern char spentry;
|
extern char spentry;
|
||||||
|
|
||||||
enum ByteCode
|
enum ByteCode
|
||||||
|
|
|
@ -156,10 +156,43 @@ void * memclr(void * dst, int size)
|
||||||
|
|
||||||
void * memcpy(void * dst, const void * src, int size)
|
void * memcpy(void * dst, const void * src, int size)
|
||||||
{
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
ldx size + 1
|
||||||
|
beq _w1
|
||||||
|
ldy #0
|
||||||
|
_loop1:
|
||||||
|
lda (src), y
|
||||||
|
sta (dst), y
|
||||||
|
iny
|
||||||
|
bne _loop1
|
||||||
|
inc src + 1
|
||||||
|
inc dst + 1
|
||||||
|
dex
|
||||||
|
bne _loop1
|
||||||
|
_w1:
|
||||||
|
ldy size
|
||||||
|
beq _w2
|
||||||
|
dey
|
||||||
|
beq _w3
|
||||||
|
_loop2:
|
||||||
|
lda (src), y
|
||||||
|
sta (dst), y
|
||||||
|
dey
|
||||||
|
bne _loop2
|
||||||
|
_w3:
|
||||||
|
lda (src), y
|
||||||
|
sta (dst), y
|
||||||
|
_w2:
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
#if 0
|
||||||
|
|
||||||
char * d = dst, * s = src;
|
char * d = dst, * s = src;
|
||||||
while (size--)
|
while (size--)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
return dst;
|
return dst;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void * memmove(void * dst, const void * src, int size)
|
void * memmove(void * dst, const void * src, int size)
|
||||||
|
|
|
@ -25,4 +25,16 @@ static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_IN
|
||||||
|
|
||||||
static const uint64 COPT_OPTIMIZE_ALL = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;
|
static const uint64 COPT_OPTIMIZE_ALL = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;
|
||||||
|
|
||||||
|
struct CompilerSettings
|
||||||
|
{
|
||||||
|
uint64 mCompilerFlags;
|
||||||
|
uint8 mRegWork;
|
||||||
|
uint8 mRegFParam;
|
||||||
|
uint8 mRegIP;
|
||||||
|
uint8 mRegAccu;
|
||||||
|
uint8 mRegAddr;
|
||||||
|
uint8 mRegStack;
|
||||||
|
uint8 mRegLocals;
|
||||||
|
uint8 mRegTmp;
|
||||||
|
uint8 mRegTmpSaved;
|
||||||
|
};
|
||||||
|
|
|
@ -45,7 +45,12 @@ uint8* LinkerObject::AddSpace(int size)
|
||||||
Linker::Linker(Errors* errors)
|
Linker::Linker(Errors* errors)
|
||||||
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr)
|
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
mCartridgeBankUsed[i] = 0;
|
||||||
|
memset(mCartridge[i], 0, 0x4000);
|
||||||
|
}
|
||||||
|
memset(mMemory, 0, 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker::~Linker(void)
|
Linker::~Linker(void)
|
||||||
|
@ -62,6 +67,8 @@ LinkerRegion* Linker::AddRegion(const Ident* region, int start, int end)
|
||||||
lrgn->mEnd = end;
|
lrgn->mEnd = end;
|
||||||
lrgn->mUsed = 0;
|
lrgn->mUsed = 0;
|
||||||
lrgn->mNonzero = 0;
|
lrgn->mNonzero = 0;
|
||||||
|
lrgn->mCartridge = -1;
|
||||||
|
lrgn->mFlags = 0;
|
||||||
mRegions.Push(lrgn);
|
mRegions.Push(lrgn);
|
||||||
return lrgn;
|
return lrgn;
|
||||||
}
|
}
|
||||||
|
@ -136,6 +143,7 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L
|
||||||
obj->mSize = 0;
|
obj->mSize = 0;
|
||||||
obj->mIdent = ident;
|
obj->mIdent = ident;
|
||||||
obj->mSection = section;
|
obj->mSection = section;
|
||||||
|
obj->mRegion = nullptr;
|
||||||
obj->mProc = nullptr;
|
obj->mProc = nullptr;
|
||||||
obj->mFlags = 0;
|
obj->mFlags = 0;
|
||||||
section->mObjects.Push(obj);
|
section->mObjects.Push(obj);
|
||||||
|
@ -195,6 +203,7 @@ void Linker::Link(void)
|
||||||
lobj->mFlags |= LOBJF_PLACED;
|
lobj->mFlags |= LOBJF_PLACED;
|
||||||
lobj->mAddress = lrgn->mStart + lrgn->mUsed;
|
lobj->mAddress = lrgn->mStart + lrgn->mUsed;
|
||||||
lrgn->mUsed += lobj->mSize;
|
lrgn->mUsed += lobj->mSize;
|
||||||
|
lobj->mRegion = lrgn;
|
||||||
|
|
||||||
if (lsec->mType == LST_DATA)
|
if (lsec->mType == LST_DATA)
|
||||||
lrgn->mNonzero = lrgn->mUsed;
|
lrgn->mNonzero = lrgn->mUsed;
|
||||||
|
@ -266,7 +275,15 @@ void Linker::Link(void)
|
||||||
obj->mAddress = obj->mSection->mEnd;
|
obj->mAddress = obj->mSection->mEnd;
|
||||||
else if (obj->mFlags & LOBJF_REFERENCED)
|
else if (obj->mFlags & LOBJF_REFERENCED)
|
||||||
{
|
{
|
||||||
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
|
if (obj->mRegion->mCartridge >= 0)
|
||||||
|
{
|
||||||
|
mCartridgeBankUsed[obj->mRegion->mCartridge] = true;
|
||||||
|
memcpy(mCartridge[obj->mRegion->mCartridge] + obj->mAddress - obj->mRegion->mStart, obj->mData, obj->mSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +296,12 @@ void Linker::Link(void)
|
||||||
LinkerObject* robj = ref->mRefObject;
|
LinkerObject* robj = ref->mRefObject;
|
||||||
|
|
||||||
int raddr = robj->mAddress + ref->mRefOffset;
|
int raddr = robj->mAddress + ref->mRefOffset;
|
||||||
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
|
uint8* dp;
|
||||||
|
|
||||||
|
if (obj->mRegion->mCartridge < 0)
|
||||||
|
dp = mMemory + obj->mAddress + ref->mOffset;
|
||||||
|
else
|
||||||
|
dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - obj->mRegion->mStart + ref->mOffset;
|
||||||
|
|
||||||
if (ref->mFlags & LREF_LOWBYTE)
|
if (ref->mFlags & LREF_LOWBYTE)
|
||||||
*dp++ = raddr & 0xff;
|
*dp++ = raddr & 0xff;
|
||||||
|
@ -353,8 +375,8 @@ bool Linker::WriteCrtFile(const char* filename)
|
||||||
criHeader.mHeaderLength = 0x40000000;
|
criHeader.mHeaderLength = 0x40000000;
|
||||||
criHeader.mVersion = 0x0001;
|
criHeader.mVersion = 0x0001;
|
||||||
criHeader.mHardware = 0x2000;
|
criHeader.mHardware = 0x2000;
|
||||||
criHeader.mExrom = 1;
|
criHeader.mExrom = 0;
|
||||||
criHeader.mGameLine = 1;
|
criHeader.mGameLine = 0;
|
||||||
memset(criHeader.mName, 0, 32);
|
memset(criHeader.mName, 0, 32);
|
||||||
strcpy_s(criHeader.mName, "OSCAR");
|
strcpy_s(criHeader.mName, "OSCAR");
|
||||||
|
|
||||||
|
@ -375,22 +397,26 @@ bool Linker::WriteCrtFile(const char* filename)
|
||||||
|
|
||||||
char * bootmem = new char[8192];
|
char * bootmem = new char[8192];
|
||||||
|
|
||||||
|
memset(bootmem, 0, 0x2000);
|
||||||
|
|
||||||
chipHeader.mLoadAddress = 0x0080;
|
chipHeader.mLoadAddress = 0x0080;
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(bootmem, 1, 0x2000, file);
|
fwrite(mMemory + 0x0800, 1, 0x2000, file);
|
||||||
|
|
||||||
|
memcpy(bootmem, mMemory + 0x2800, 0x1800);
|
||||||
|
|
||||||
bootmem[0x1ffc] = 0x00;
|
bootmem[0x1ffc] = 0x00;
|
||||||
bootmem[0x1ffd] = 0xe0;
|
bootmem[0x1ffd] = 0xff;
|
||||||
|
|
||||||
char bootcode[] = {
|
char bootcode[] = {
|
||||||
0xa9, 0x87,
|
0xa9, 0x87,
|
||||||
0x8d, 0x02, 0xde,
|
0x8d, 0x02, 0xde,
|
||||||
0xa9, 0x01,
|
0xa9, 0x00,
|
||||||
0x8d, 0x00, 0xde,
|
0x8d, 0x00, 0xde,
|
||||||
0x6c, 0xfc, 0xff
|
0x6c, 0xfc, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
int j = 0;
|
int j = 0x1f00;
|
||||||
for (int i = 0; i < sizeof(bootcode); i++)
|
for (int i = 0; i < sizeof(bootcode); i++)
|
||||||
{
|
{
|
||||||
bootmem[j++] = 0xa9;
|
bootmem[j++] = 0xa9;
|
||||||
|
@ -407,15 +433,21 @@ bool Linker::WriteCrtFile(const char* filename)
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(bootmem, 1, 0x2000, file);
|
fwrite(bootmem, 1, 0x2000, file);
|
||||||
|
|
||||||
chipHeader.mBankNumber = 0x100;
|
for (int i = 1; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mCartridgeBankUsed[i])
|
||||||
|
{
|
||||||
|
chipHeader.mBankNumber = i << 8;
|
||||||
|
|
||||||
chipHeader.mLoadAddress = 0x0080;
|
chipHeader.mLoadAddress = 0x0080;
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(mMemory + 0x0800, 1, 0x2000, file);
|
fwrite(mCartridge[i] + 0x0000, 1, 0x2000, file);
|
||||||
|
|
||||||
chipHeader.mLoadAddress = 0x00a0;
|
chipHeader.mLoadAddress = 0x00a0;
|
||||||
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
fwrite(&chipHeader, sizeof(chipHeader), 1, file);
|
||||||
fwrite(mMemory + 0x2800, 1, 0x2000, file);
|
fwrite(mCartridge[i] + 0x2000, 1, 0x2000, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return true;
|
return true;
|
||||||
|
@ -514,7 +546,10 @@ bool Linker::WriteAsmFile(const char* filename)
|
||||||
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||||
break;
|
break;
|
||||||
case LOT_NATIVE_CODE:
|
case LOT_NATIVE_CODE:
|
||||||
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
if (obj->mRegion->mCartridge < 0)
|
||||||
|
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||||
|
else
|
||||||
|
mNativeDisassembler.Disassemble(file, mCartridge[obj->mRegion->mCartridge] - obj->mRegion->mStart, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,9 @@ class LinkerRegion
|
||||||
public:
|
public:
|
||||||
const Ident* mIdent;
|
const Ident* mIdent;
|
||||||
|
|
||||||
|
uint32 mFlags;
|
||||||
int mStart, mEnd, mUsed, mNonzero;
|
int mStart, mEnd, mUsed, mNonzero;
|
||||||
|
int mCartridge;
|
||||||
|
|
||||||
GrowingArray<LinkerSection*> mSections;
|
GrowingArray<LinkerSection*> mSections;
|
||||||
|
|
||||||
|
@ -89,6 +91,7 @@ public:
|
||||||
int mAddress;
|
int mAddress;
|
||||||
int mSize;
|
int mSize;
|
||||||
LinkerSection * mSection;
|
LinkerSection * mSection;
|
||||||
|
LinkerRegion * mRegion;
|
||||||
uint8 * mData;
|
uint8 * mData;
|
||||||
InterCodeProcedure* mProc;
|
InterCodeProcedure* mProc;
|
||||||
uint32 mFlags;
|
uint32 mFlags;
|
||||||
|
@ -138,6 +141,10 @@ public:
|
||||||
GrowingArray<LinkerObject*> mObjects;
|
GrowingArray<LinkerObject*> mObjects;
|
||||||
|
|
||||||
uint8 mMemory[0x10000];
|
uint8 mMemory[0x10000];
|
||||||
|
uint8 mCartridge[64][0x4000];
|
||||||
|
|
||||||
|
bool mCartridgeBankUsed[64];
|
||||||
|
|
||||||
int mProgramStart, mProgramEnd;
|
int mProgramStart, mProgramEnd;
|
||||||
|
|
||||||
void ReferenceObject(LinkerObject* obj);
|
void ReferenceObject(LinkerObject* obj);
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "MachineTypes.h"
|
||||||
|
|
||||||
|
uint8 BC_REG_WORK = 0x03;
|
||||||
|
uint8 BC_REG_WORK_Y = 0x02;
|
||||||
|
uint8 BC_REG_FPARAMS = 0x0d;
|
||||||
|
|
||||||
|
uint8 BC_REG_IP = 0x19;
|
||||||
|
uint8 BC_REG_ACCU = 0x1b;
|
||||||
|
uint8 BC_REG_ADDR = 0x1f;
|
||||||
|
uint8 BC_REG_STACK = 0x23;
|
||||||
|
uint8 BC_REG_LOCALS = 0x25;
|
||||||
|
|
||||||
|
uint8 BC_REG_TMP = 0x43;
|
||||||
|
uint8 BC_REG_TMP_SAVED = 0x53;
|
||||||
|
|
|
@ -81,15 +81,16 @@ inline int sprintf_s(char* buffer, int size, const char* format, ...)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const uint8 BC_REG_WORK = 0x03;
|
extern uint8 BC_REG_WORK;
|
||||||
static const uint8 BC_REG_FPARAMS = 0x0d;
|
extern uint8 BC_REG_WORK_Y;
|
||||||
|
extern uint8 BC_REG_FPARAMS;
|
||||||
|
|
||||||
static const uint8 BC_REG_IP = 0x19;
|
extern uint8 BC_REG_IP;
|
||||||
static const uint8 BC_REG_ACCU = 0x1b;
|
extern uint8 BC_REG_ACCU;
|
||||||
static const uint8 BC_REG_ADDR = 0x1f;
|
extern uint8 BC_REG_ADDR;
|
||||||
static const uint8 BC_REG_STACK = 0x23;
|
extern uint8 BC_REG_STACK;
|
||||||
static const uint8 BC_REG_LOCALS = 0x25;
|
extern uint8 BC_REG_LOCALS;
|
||||||
|
|
||||||
static const uint8 BC_REG_TMP = 0x43;
|
extern uint8 BC_REG_TMP;
|
||||||
static const uint8 BC_REG_TMP_SAVED = 0x53;
|
extern uint8 BC_REG_TMP_SAVED;
|
||||||
|
|
||||||
|
|
|
@ -2288,6 +2288,16 @@ Expression* Parser::ParseAssemblerOperand(void)
|
||||||
return ParseAssemblerAddOperand();
|
return ParseAssemblerAddOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
||||||
|
{
|
||||||
|
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
decaccu->mIdent = ident;
|
||||||
|
decaccu->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
decaccu->mSize = 2;
|
||||||
|
decaccu->mInteger = value;
|
||||||
|
mScope->Insert(decaccu->mIdent, decaccu);
|
||||||
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseAssembler(void)
|
Expression* Parser::ParseAssembler(void)
|
||||||
{
|
{
|
||||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||||
|
@ -2295,6 +2305,18 @@ Expression* Parser::ParseAssembler(void)
|
||||||
|
|
||||||
mScanner->SetAssemblerMode(true);
|
mScanner->SetAssemblerMode(true);
|
||||||
|
|
||||||
|
AddAssemblerRegister(Ident::Unique("__tmpy"), BC_REG_WORK_Y);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__tmp"), BC_REG_WORK);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__ip"), BC_REG_IP);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__accu"), BC_REG_ACCU);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__addr"), BC_REG_ADDR);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__fp"), BC_REG_LOCALS);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__sp"), BC_REG_STACK);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__sregs"), BC_REG_TMP_SAVED);
|
||||||
|
AddAssemblerRegister(Ident::Unique("__regs"), BC_REG_TMP);
|
||||||
|
|
||||||
|
AddAssemblerRegister(Ident::Unique("accu"), BC_REG_ACCU);
|
||||||
|
|
||||||
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
decaccu->mIdent = Ident::Unique("accu");
|
decaccu->mIdent = Ident::Unique("accu");
|
||||||
decaccu->mBase = TheUnsignedIntTypeDeclaration;
|
decaccu->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
@ -2612,6 +2634,48 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "register"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* reg = mScanner->mTokenIdent;
|
||||||
|
int index = 0;
|
||||||
|
mScanner->NextToken();
|
||||||
|
|
||||||
|
ConsumeToken(TK_COMMA);
|
||||||
|
Expression* exp = ParseRExpression();
|
||||||
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger >= 2 && exp->mDecValue->mInteger < 0x100)
|
||||||
|
index = exp->mDecValue->mInteger;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Integer number for start expected");
|
||||||
|
|
||||||
|
if (!strcmp(reg->mString, "__tmpy"))
|
||||||
|
BC_REG_WORK_Y = index;
|
||||||
|
else if (!strcmp(reg->mString, "__tmp"))
|
||||||
|
BC_REG_WORK = index;
|
||||||
|
else if (!strcmp(reg->mString, "__ip"))
|
||||||
|
BC_REG_IP = index;
|
||||||
|
else if (!strcmp(reg->mString, "__accu"))
|
||||||
|
BC_REG_ACCU = index;
|
||||||
|
else if (!strcmp(reg->mString, "__addr"))
|
||||||
|
BC_REG_ADDR = index;
|
||||||
|
else if (!strcmp(reg->mString, "__sp"))
|
||||||
|
BC_REG_STACK = index;
|
||||||
|
else if (!strcmp(reg->mString, "__fp"))
|
||||||
|
BC_REG_LOCALS = index;
|
||||||
|
else if (!strcmp(reg->mString, "__sregs"))
|
||||||
|
BC_REG_TMP_SAVED = index;
|
||||||
|
else if (!strcmp(reg->mString, "__regs"))
|
||||||
|
BC_REG_TMP = index;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Unknown register name");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Register name expected");
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else if (!strcmp(mScanner->mTokenIdent->mString, "bytecode"))
|
else if (!strcmp(mScanner->mTokenIdent->mString, "bytecode"))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -2765,7 +2829,7 @@ void Parser::ParsePragma(void)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
||||||
Expression* exp;
|
Expression* exp;
|
||||||
int start = 0, end = 0, flags = 0;
|
int start = 0, end = 0, flags = 0, bank = -1;
|
||||||
|
|
||||||
ConsumeToken(TK_COMMA);
|
ConsumeToken(TK_COMMA);
|
||||||
|
|
||||||
|
@ -2785,11 +2849,25 @@ void Parser::ParsePragma(void)
|
||||||
|
|
||||||
ConsumeToken(TK_COMMA);
|
ConsumeToken(TK_COMMA);
|
||||||
|
|
||||||
exp = ParseRExpression();
|
if (mScanner->mToken != TK_COMMA)
|
||||||
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
{
|
||||||
flags = exp->mDecValue->mInteger;
|
exp = ParseRExpression();
|
||||||
else
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Integer number for flags expected");
|
flags = exp->mDecValue->mInteger;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Integer number for flags expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsumeToken(TK_COMMA);
|
||||||
|
|
||||||
|
if (mScanner->mToken != TK_COMMA)
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
LinkerRegion* rgn = mCompilationUnits->mLinker->FindRegion(regionIdent);
|
LinkerRegion* rgn = mCompilationUnits->mLinker->FindRegion(regionIdent);
|
||||||
if (!rgn)
|
if (!rgn)
|
||||||
|
@ -2797,6 +2875,9 @@ void Parser::ParsePragma(void)
|
||||||
else if (rgn->mStart != start || rgn->mEnd != end)
|
else if (rgn->mStart != start || rgn->mEnd != end)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Conflicting linker region definition");
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Conflicting linker region definition");
|
||||||
|
|
||||||
|
rgn->mFlags = flags;
|
||||||
|
rgn->mCartridge = bank;
|
||||||
|
|
||||||
ConsumeToken(TK_COMMA);
|
ConsumeToken(TK_COMMA);
|
||||||
ConsumeToken(TK_OPEN_BRACE);
|
ConsumeToken(TK_OPEN_BRACE);
|
||||||
if (!ConsumeTokenIf(TK_CLOSE_BRACE))
|
if (!ConsumeTokenIf(TK_CLOSE_BRACE))
|
||||||
|
@ -2861,6 +2942,9 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkerSection* lsec = mCompilationUnits->mLinker->FindSection(sectionIdent);
|
LinkerSection* lsec = mCompilationUnits->mLinker->FindSection(sectionIdent);
|
||||||
|
if (!lsec)
|
||||||
|
lsec = mCompilationUnits->mLinker->AddSection(sectionIdent, LST_DATA);
|
||||||
|
|
||||||
if (dstart)
|
if (dstart)
|
||||||
{
|
{
|
||||||
dstart->mSection = lsec;
|
dstart->mSection = lsec;
|
||||||
|
@ -2877,6 +2961,50 @@ void Parser::ParsePragma(void)
|
||||||
|
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "code"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* sectionIdent = mScanner->mTokenIdent;
|
||||||
|
mScanner->NextToken();
|
||||||
|
LinkerSection* lsec = mCompilationUnits->mLinker->FindSection(sectionIdent);
|
||||||
|
if (lsec)
|
||||||
|
{
|
||||||
|
mCodeSection = lsec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Section not defined");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Section name expected");
|
||||||
|
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "data"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* sectionIdent = mScanner->mTokenIdent;
|
||||||
|
mScanner->NextToken();
|
||||||
|
LinkerSection* lsec = mCompilationUnits->mLinker->FindSection(sectionIdent);
|
||||||
|
if (lsec)
|
||||||
|
{
|
||||||
|
mDataSection = lsec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Section not defined");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Section name expected");
|
||||||
|
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
|
@ -45,6 +45,8 @@ protected:
|
||||||
Expression* ParseAssemblerAddOperand(void);
|
Expression* ParseAssemblerAddOperand(void);
|
||||||
Expression* ParseAssemblerOperand(void);
|
Expression* ParseAssemblerOperand(void);
|
||||||
|
|
||||||
|
void AddAssemblerRegister(const Ident* ident, int value);
|
||||||
|
|
||||||
Expression* ParseStatement(void);
|
Expression* ParseStatement(void);
|
||||||
Expression* ParseSwitchStatement(void);
|
Expression* ParseSwitchStatement(void);
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@
|
||||||
<ClCompile Include="InterCode.cpp" />
|
<ClCompile Include="InterCode.cpp" />
|
||||||
<ClCompile Include="InterCodeGenerator.cpp" />
|
<ClCompile Include="InterCodeGenerator.cpp" />
|
||||||
<ClCompile Include="Linker.cpp" />
|
<ClCompile Include="Linker.cpp" />
|
||||||
|
<ClCompile Include="MachineTypes.cpp" />
|
||||||
<ClCompile Include="NativeCodeGenerator.cpp" />
|
<ClCompile Include="NativeCodeGenerator.cpp" />
|
||||||
<ClCompile Include="NumberSet.cpp" />
|
<ClCompile Include="NumberSet.cpp" />
|
||||||
<ClCompile Include="oscar64.cpp" />
|
<ClCompile Include="oscar64.cpp" />
|
||||||
|
|
|
@ -72,6 +72,9 @@
|
||||||
<ClCompile Include="GlobalAnalyzer.cpp">
|
<ClCompile Include="GlobalAnalyzer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="MachineTypes.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Array.h">
|
<ClInclude Include="Array.h">
|
||||||
|
|
Loading…
Reference in New Issue