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) * pet16 : Commodore PET, 16K RAM (0x0400..0x4000)
* pet32 : Commodore PET, 32K RAM (0x0400..0x8000) * pet32 : Commodore PET, 32K RAM (0x0400..0x8000)
* nes : Nintendo entertainment system, NROM 32 K ROM * nes : Nintendo entertainment system, NROM 32 K ROM
* atari : Atari 8bit systems, (0x2000..0xbc00)
### Files generated ### Files generated

View File

@ -60,6 +60,33 @@ __asm bsinit
sta 0xff3f sta 0xff3f
} }
#pragma code(code) #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 #else
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
@ -70,10 +97,12 @@ __asm bsinit
void iocharmap(IOCharMap chmap) void iocharmap(IOCharMap chmap)
{ {
giocharmap = chmap; giocharmap = chmap;
#if !defined(__ATARI__)
if (chmap == IOCHM_PETSCII_1) if (chmap == IOCHM_PETSCII_1)
putch(128 + 14); putch(128 + 14);
else if (chmap == IOCHM_PETSCII_2) else if (chmap == IOCHM_PETSCII_2)
putch(14); putch(14);
#endif
} }
__asm putpch __asm putpch

View File

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

View File

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

View File

@ -22,6 +22,20 @@ clock_t clock(void)
sta accu + 2 sta accu + 2
lda #0 lda #0
sta accu + 3 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 #else
lda $a2 lda $a2
sta accu + 0 sta accu + 0

View File

@ -51,7 +51,23 @@ void Compiler::AddDefine(const Ident* ident, const char* value)
bool Compiler::ParseSource(void) 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 = 0x0d;
BC_REG_FPARAMS_END = 0x25; BC_REG_FPARAMS_END = 0x25;
@ -212,6 +228,9 @@ bool Compiler::GenerateCode(void)
LinkerRegion* regionZeroPage = mLinker->FindRegion(identZeroPage); LinkerRegion* regionZeroPage = mLinker->FindRegion(identZeroPage);
if (!regionZeroPage) if (!regionZeroPage)
{ {
if (mTargetMachine == TMACH_ATARI)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
else
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
} }
@ -285,6 +304,12 @@ bool Compiler::GenerateCode(void)
else else
regionStartup = mLinker->AddRegion(identStartup, 0x1201, 0x1300); regionStartup = mLinker->AddRegion(identStartup, 0x1201, 0x1300);
break; 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) else if (mTargetMachine == TMACH_NES)
@ -323,6 +348,9 @@ bool Compiler::GenerateCode(void)
case TMACH_VIC20_24K: case TMACH_VIC20_24K:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1300, 0x1400); regionBytecode = mLinker->AddRegion(identBytecode, 0x1300, 0x1400);
break; break;
case TMACH_ATARI:
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
break;
} }
} }
@ -398,6 +426,9 @@ bool Compiler::GenerateCode(void)
case TMACH_PET_32K: case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0600, 0x8000); regionMain = mLinker->AddRegion(identMain, 0x0600, 0x8000);
break; break;
case TMACH_ATARI:
regionMain = mLinker->AddRegion(identMain, 0x2200, 0xbc00);
break;
} }
} }
else else
@ -440,6 +471,9 @@ bool Compiler::GenerateCode(void)
case TMACH_PET_32K: case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0480, 0x8000); regionMain = mLinker->AddRegion(identMain, 0x0480, 0x8000);
break; break;
case TMACH_ATARI:
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xbc00);
break;
} }
} }
} }
@ -755,12 +789,22 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcat_s(bcsPath, "bcs"); strcat_s(bcsPath, "bcs");
if (mCompilerOptions & COPT_TARGET_PRG) if (mCompilerOptions & COPT_TARGET_PRG)
{
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"); strcat_s(prgPath, "prg");
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath); printf("Writing <%s>\n", prgPath);
mLinker->WritePrgFile(prgPath); mLinker->WritePrgFile(prgPath);
} }
}
else if (mCompilerOptions & COPT_TARGET_CRT16) else if (mCompilerOptions & COPT_TARGET_CRT16)
{ {
strcat_s(prgPath, "crt"); strcat_s(prgPath, "crt");

View File

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

View File

@ -664,6 +664,37 @@ bool Linker::WritePrgFile(DiskImage* image, const char* filename)
return false; 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) bool Linker::WritePrgFile(const char* filename)
{ {
FILE* file; FILE* file;

View File

@ -223,6 +223,7 @@ public:
bool WritePrgFile(DiskImage * image, const char* filename); bool WritePrgFile(DiskImage * image, const char* filename);
bool WritePrgFile(const char* filename); bool WritePrgFile(const char* filename);
bool WriteXexFile(const char* filename);
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);

View File

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