Add support for Atari 8 bit systems

This commit is contained in:
drmortalwombat 2023-03-08 15:51:27 +01:00
parent 0f4f0ed297
commit 4f89ad7680
10 changed files with 173 additions and 10 deletions

View File

@ -105,6 +105,7 @@ A list of source files can be provided.
* pet16 : Commodore PET, 16K RAM (0x0400..0x4000)
* pet32 : Commodore PET, 32K RAM (0x0400..0x8000)
* nes : Nintendo entertainment system, NROM 32 K ROM
* atari : Atari 8bit systems, (0x2000..0xbc00)
### Files generated

View File

@ -60,6 +60,33 @@ __asm bsinit
sta 0xff3f
}
#pragma code(code)
#elif defined(__ATARI__)
__asm bsout
{
tax
lda 0xe407
pha
lda 0xe406
pha
txa
}
__asm bsin
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot
{
}
__asm bsinit
{
}
#else
#define bsout 0xffd2
#define bsin 0xffe4
@ -69,11 +96,13 @@ __asm bsinit
void iocharmap(IOCharMap chmap)
{
giocharmap = chmap;
giocharmap = chmap;
#if !defined(__ATARI__)
if (chmap == IOCHM_PETSCII_1)
putch(128 + 14);
else if (chmap == IOCHM_PETSCII_2)
putch(14);
#endif
}
__asm putpch

View File

@ -166,6 +166,8 @@ w0:
#elif defined(OSCAR_TARGET_BIN)
#elif defined(__ATARI__)
#elif defined(OSCAR_TARGET_NES)
sei
cld
@ -284,7 +286,9 @@ bcode:
#endif
spexit:
#if !defined(OSCAR_TARGET_NES)
#if defined(__ATARI__) || defined(OSCAR_TARGET_NES)
jmp spexit
#else
lda #$4c
sta $54
lda #0

View File

@ -48,6 +48,30 @@ __asm bsplot
sta 0xff3f
}
#pragma code(code)
#elif defined(__ATARI__)
__asm bsout
{
tax
lda 0xe407
pha
lda 0xe406
pha
txa
}
__asm bsin
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot
{
}
#else
#define bsout 0xffd2
#define bsplot 0xfff0
@ -56,6 +80,13 @@ __asm bsplot
__asm putpch
{
#if defined(__ATARI__)
cmp #10
bne w1
lda #0x9b
w1:
jmp bsout
#else
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
@ -109,12 +140,13 @@ __asm putpch
jsr bsout
dex
bpl l1
#endif
}
__asm getpch
{
jsr bsin
#if !defined(__ATARI__)
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
@ -137,6 +169,7 @@ __asm getpch
w2:
eor #$20
w3:
#endif
}
void putchar(char c)

View File

@ -22,6 +22,20 @@ clock_t clock(void)
sta accu + 2
lda #0
sta accu + 3
#elif defined(__ATARI__)
loop:
lda $14
ldx $13
ldy $12
cmp $14
bne loop
sta accu + 0
stx accu + 1
sty accu + 2
lda #0
sta accu + 3
#else
lda $a2
sta accu + 0

View File

@ -51,7 +51,23 @@ void Compiler::AddDefine(const Ident* ident, const char* value)
bool Compiler::ParseSource(void)
{
if (mCompilerOptions & COPT_EXTENDED_ZERO_PAGE)
if (mTargetMachine == TMACH_ATARI)
{
BC_REG_WORK_Y = 0x80;
BC_REG_WORK = 0x81;
BC_REG_FPARAMS = 0x8b;
BC_REG_FPARAMS_END = 0x97;
BC_REG_IP = 0x97;
BC_REG_ACCU = 0x99;
BC_REG_ADDR = 0x9d;
BC_REG_STACK = 0xa1;
BC_REG_LOCALS = 0xa3;
BC_REG_TMP = 0xa5;
BC_REG_TMP_SAVED = 0xc5;
}
else if (mCompilerOptions & COPT_EXTENDED_ZERO_PAGE)
{
BC_REG_FPARAMS = 0x0d;
BC_REG_FPARAMS_END = 0x25;
@ -212,7 +228,10 @@ bool Compiler::GenerateCode(void)
LinkerRegion* regionZeroPage = mLinker->FindRegion(identZeroPage);
if (!regionZeroPage)
{
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
if (mTargetMachine == TMACH_ATARI)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
else
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
}
LinkerRegion* regionStartup = mLinker->FindRegion(identStartup);
@ -285,6 +304,12 @@ bool Compiler::GenerateCode(void)
else
regionStartup = mLinker->AddRegion(identStartup, 0x1201, 0x1300);
break;
case TMACH_ATARI:
if (mCompilerOptions & COPT_NATIVE)
regionStartup = mLinker->AddRegion(identStartup, 0x2000, 0x2080);
else
regionStartup = mLinker->AddRegion(identStartup, 0x2000, 0x2100);
break;
}
}
else if (mTargetMachine == TMACH_NES)
@ -323,6 +348,9 @@ bool Compiler::GenerateCode(void)
case TMACH_VIC20_24K:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1300, 0x1400);
break;
case TMACH_ATARI:
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
break;
}
}
@ -398,6 +426,9 @@ bool Compiler::GenerateCode(void)
case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0600, 0x8000);
break;
case TMACH_ATARI:
regionMain = mLinker->AddRegion(identMain, 0x2200, 0xbc00);
break;
}
}
else
@ -440,6 +471,9 @@ bool Compiler::GenerateCode(void)
case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0480, 0x8000);
break;
case TMACH_ATARI:
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xbc00);
break;
}
}
}
@ -756,10 +790,20 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_TARGET_PRG)
{
strcat_s(prgPath, "prg");
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath);
mLinker->WritePrgFile(prgPath);
if (mTargetMachine == TMACH_ATARI)
{
strcat_s(prgPath, "xex");
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath);
mLinker->WriteXexFile(prgPath);
}
else
{
strcat_s(prgPath, "prg");
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath);
mLinker->WritePrgFile(prgPath);
}
}
else if (mCompilerOptions & COPT_TARGET_CRT16)
{

View File

@ -52,7 +52,8 @@ enum TargetMachine
TMACH_PET_16K,
TMACH_PET_32K,
TMACH_PLUS4,
TMACH_NES
TMACH_NES,
TMACH_ATARI
};

View File

@ -664,6 +664,37 @@ bool Linker::WritePrgFile(DiskImage* image, const char* filename)
return false;
}
bool Linker::WriteXexFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
// prefix
fputc(0xff, file); fputc(0xff, file);
// first segment
fputc(mProgramStart & 0xff, file);
fputc(mProgramStart >> 8, file);
fputc((mProgramEnd - 1) & 0xff, file);
fputc((mProgramEnd - 1) >> 8, file);
int done = fwrite(mMemory + mProgramStart, 1, mProgramEnd - mProgramStart, file);
fputc(0xe0, file);
fputc(0x02, file);
fputc(0xe1, file);
fputc(0x02, file);
fputc(mProgramStart & 0xff, file);
fputc(mProgramStart >> 8, file);
fclose(file);
return true;
}
else
return false;
}
bool Linker::WritePrgFile(const char* filename)
{
FILE* file;

View File

@ -223,6 +223,7 @@ public:
bool WritePrgFile(DiskImage * image, const char* filename);
bool WritePrgFile(const char* filename);
bool WriteXexFile(const char* filename);
bool WriteMapFile(const char* filename);
bool WriteAsmFile(const char* filename);
bool WriteLblFile(const char* filename);

View File

@ -312,6 +312,11 @@ int main2(int argc, const char** argv)
compiler->mCompilerOptions |= COPT_EXTENDED_ZERO_PAGE;
compiler->AddDefine(Ident::Unique("__NES__"), "1");
}
else if (!strcmp(targetMachine, "atari"))
{
compiler->mTargetMachine = TMACH_ATARI;
compiler->AddDefine(Ident::Unique("__ATARI__"), "1");
}
else
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid target machine option", targetMachine);