diff --git a/README.md b/README.md index dbccc86..29f712f 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/include/conio.c b/include/conio.c index 96b711c..ea6a5b7 100644 --- a/include/conio.c +++ b/include/conio.c @@ -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 diff --git a/include/crt.c b/include/crt.c index 0901e94..3e78b24 100644 --- a/include/crt.c +++ b/include/crt.c @@ -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 diff --git a/include/stdio.c b/include/stdio.c index 99cef20..b26a753 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -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) diff --git a/include/time.c b/include/time.c index 0a43255..820e139 100644 --- a/include/time.c +++ b/include/time.c @@ -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 diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 9210ebf..56c4cb9 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -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) { diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h index f6f1105..edbc236 100644 --- a/oscar64/CompilerTypes.h +++ b/oscar64/CompilerTypes.h @@ -52,7 +52,8 @@ enum TargetMachine TMACH_PET_16K, TMACH_PET_32K, TMACH_PLUS4, - TMACH_NES + TMACH_NES, + TMACH_ATARI }; diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index b841cb0..3352637 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -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; diff --git a/oscar64/Linker.h b/oscar64/Linker.h index f5d85be..a00502e 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -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); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 86e02ef..3968c0b 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -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);