diff --git a/include/conio.c b/include/conio.c index de5cdfb..4961a5f 100644 --- a/include/conio.c +++ b/include/conio.c @@ -2,6 +2,44 @@ static IOCharMap giocharmap = IOCHM_ASCII; +#if defined(__C128__) +#pragma code(lowcode) +__asm bsout +{ + ldx #0 + stx 0xff00 + jsr 0xffd2 + sta 0xff01 +} +__asm bsin +{ + lda #0 + sta 0xff00 + jsr 0xffe4 + sta 0xff01 +} +__asm bsplot +{ + lda #0 + sta 0xff00 + jsr 0xfff0 + sta 0xff01 +} +__asm bsinit +{ + lda #0 + sta 0xff00 + jsr 0xff81 + sta 0xff01 +} +#pragma code(code) +#else +#define bsout 0xffd2 +#define bsin 0xffe4 +#define bsplot 0xfff0 +#define bsinit 0xff81 +#endif + void iocharmap(IOCharMap chmap) { giocharmap = chmap; @@ -38,12 +76,12 @@ __asm putpch beq w3 and #$df w3: - jmp 0xffd2 + jmp bsout } __asm getpch { - jsr 0xffe4 + jsr bsin ldx giocharmap cpx #IOCHM_ASCII @@ -117,7 +155,7 @@ void putch(int c) { __asm { lda c - jsr 0xffd2 + jsr bsout } } @@ -125,7 +163,7 @@ void clrscr(void) { __asm { - jsr $ff5b + jsr bsinit } } @@ -141,7 +179,7 @@ void gotoxy(int cx, int cy) ldx cy ldy cx clc - jsr $fff0 + jsr bsplot } } diff --git a/include/crt.c b/include/crt.c index e6e4157..bfa6bc8 100644 --- a/include/crt.c +++ b/include/crt.c @@ -145,6 +145,10 @@ w0: byt 0x00 byt 0x00 +#if defined(__C128__) + sta 0xff01 +#endif + tsx stx spentry @@ -241,6 +245,10 @@ spexit: sta $13 lda #$19 sta $16 +#if defined(__C128__) + lda #0 + sta 0xff00 +#endif rts } diff --git a/include/stdio.c b/include/stdio.c index 65d9b49..0386b36 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -2,6 +2,37 @@ #include "conio.h" #include "stdlib.h" +#if defined(__C128__) +#pragma code(lowcode) +__asm bsout +{ + ldx #0 + stx 0xff00 + jsr 0xffd2 + sta 0xff01 +} +__asm bsplot +{ + lda #0 + sta 0xff00 + jsr 0xfff0 + sta 0xff01 +} +__asm bsin +{ + lda #0 + sta 0xff00 + jsr 0xffcf + sta 0xff01 +} + +#pragma code(code) +#else +#define bsout 0xffd2 +#define bsplot 0xfff0 +#define bsin 0xffcf +#endif + __asm putpch { ldx giocharmap @@ -32,24 +63,24 @@ __asm putpch beq w3 and #$df w3: - jmp 0xffd2 + jmp bsout t1: sec - jsr 0xfff0 + jsr bsplot tya and #3 eor #3 tax lda #$20 l1: - jsr 0xffd2 + jsr bsout dex bpl l1 } __asm getpch { - jsr 0xffcf + jsr bsin ldx giocharmap cpx #IOCHM_ASCII diff --git a/include/vic20/vic.c b/include/vic20/vic.c new file mode 100644 index 0000000..dae5843 --- /dev/null +++ b/include/vic20/vic.c @@ -0,0 +1,2 @@ +#include "vic.h" + diff --git a/include/vic20/vic.h b/include/vic20/vic.h new file mode 100644 index 0000000..ea7fb9c --- /dev/null +++ b/include/vic20/vic.h @@ -0,0 +1,27 @@ +#ifndef VIC20_VIC +#define VIC20_VIC + +#include + +struct VICI +{ + volatile byte hpos; + volatile byte vpos; + volatile byte ncols; + volatile byte nrows; + volatile byte beam; + volatile byte mempos; + + volatile byte hlpen, vlpen; + volatile byte xpaddle, ypaddle; + volatile byte oscfreq[4]; + volatile byte volcol; + volatile byte color; +}; + +#define vici (*((struct VICI *)0x9000)) + +#pragma compile("vic.c") + +#endif + diff --git a/oscar64/CompilationUnits.h b/oscar64/CompilationUnits.h index 0933942..2fb55f2 100644 --- a/oscar64/CompilationUnits.h +++ b/oscar64/CompilationUnits.h @@ -28,7 +28,7 @@ public: DeclarationScope* mRuntimeScope; - LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage; + LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage, * mSectionLowCode; Linker* mLinker; bool AddUnit(Location & location, const char* name, const char * from); diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 712e35d..f8655e5 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -22,6 +22,7 @@ Compiler::Compiler(void) mCompilationUnits->mSectionHeap = mLinker->AddSection(Ident::Unique("heap"), LST_HEAP); mCompilationUnits->mSectionStack = mLinker->AddSection(Ident::Unique("stack"), LST_STACK); mCompilationUnits->mSectionZeroPage = mLinker->AddSection(Ident::Unique("zeropage"), LST_ZEROPAGE); + mCompilationUnits->mSectionLowCode = nullptr; mCompilationUnits->mSectionStack->mSize = 4096; mCompilationUnits->mSectionHeap->mSize = 1024; @@ -65,6 +66,24 @@ bool Compiler::ParseSource(void) #endif } + switch (mTargetMachine) + { + case TMACH_VIC20: + case TMACH_VIC20_3K: + case TMACH_VIC20_8K: + mCompilationUnits->mSectionStack->mSize = 512; + mCompilationUnits->mSectionHeap->mSize = 512; + break; + case TMACH_VIC20_16K: + case TMACH_VIC20_24K: + mCompilationUnits->mSectionStack->mSize = 1024; + mCompilationUnits->mSectionHeap->mSize = 1024; + break; + case TMACH_C128: + mCompilationUnits->mSectionLowCode = mLinker->AddSection(Ident::Unique("lowcode"), LST_DATA); + break; + } + mPreprocessor->mCompilerOptions = mCompilerOptions; mLinker->mCompilerOptions = mCompilerOptions; @@ -177,6 +196,7 @@ bool Compiler::GenerateCode(void) const Ident* identMain = Ident::Unique("main"); const Ident* identCode = Ident::Unique("code"); const Ident* identZeroPage = Ident::Unique("zeropage"); + const Ident* identLowcode = Ident::Unique("lowcode"); LinkerRegion* regionZeroPage = mLinker->FindRegion(identZeroPage); if (!regionZeroPage) @@ -185,10 +205,61 @@ bool Compiler::GenerateCode(void) } LinkerRegion* regionStartup = mLinker->FindRegion(identStartup); + LinkerRegion* regionLowcode = nullptr; + if (!regionStartup) { if (mCompilerOptions & COPT_TARGET_PRG) - regionStartup = mLinker->AddRegion(identStartup, 0x0801, 0x0900); + { + switch (mTargetMachine) + { + case TMACH_C64: + if (mCompilerOptions & COPT_NATIVE) + regionStartup = mLinker->AddRegion(identStartup, 0x0801, 0x0880); + else + regionStartup = mLinker->AddRegion(identStartup, 0x0801, 0x0900); + break; + case TMACH_C128: + if (mCompilerOptions & COPT_NATIVE) + { + regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1c80); + regionLowcode = mLinker->AddRegion(identLowcode, 0x1c80, 0x1d00); + } + else + { + regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1c80); + regionLowcode = mLinker->AddRegion(identLowcode, 0x1c80, 0x1d00); + } + regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode); + break; + case TMACH_C128B: + if (mCompilerOptions & COPT_NATIVE) + regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1c80); + else + regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1d00); + break; + case TMACH_VIC20: + if (mCompilerOptions & COPT_NATIVE) + regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080); + else + regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1100); + break; + case TMACH_VIC20_3K: + if (mCompilerOptions & COPT_NATIVE) + regionStartup = mLinker->AddRegion(identStartup, 0x0401, 0x0480); + else + regionStartup = mLinker->AddRegion(identStartup, 0x0401, 0x0500); + break; + case TMACH_VIC20_8K: + case TMACH_VIC20_16K: + case TMACH_VIC20_24K: + if (mCompilerOptions & COPT_NATIVE) + regionStartup = mLinker->AddRegion(identStartup, 0x1201, 0x1280); + else + regionStartup = mLinker->AddRegion(identStartup, 0x1201, 0x1300); + break; + } + } else regionStartup = mLinker->AddRegion(identStartup, 0x0800, 0x0900); } @@ -198,7 +269,30 @@ bool Compiler::GenerateCode(void) { regionBytecode = mLinker->FindRegion(identBytecode); if (!regionBytecode) - regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00); + { + switch (mTargetMachine) + { + case TMACH_C64: + regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00); + break; + case TMACH_C128: + case TMACH_C128B: + regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00); + break; + case TMACH_VIC20: + regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200); + break; + case TMACH_VIC20_3K: + regionBytecode = mLinker->AddRegion(identBytecode, 0x0500, 0x0600); + break; + case TMACH_VIC20_8K: + case TMACH_VIC20_16K: + case TMACH_VIC20_24K: + regionBytecode = mLinker->AddRegion(identBytecode, 0x1300, 0x1400); + break; + } + + } } LinkerRegion* regionMain = mLinker->FindRegion(identMain); @@ -224,9 +318,65 @@ bool Compiler::GenerateCode(void) if (!(mCompilerOptions & COPT_TARGET_PRG)) regionMain = mLinker->AddRegion(identMain, 0x0900, 0x4700); else if (regionBytecode) - regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000); + { + switch (mTargetMachine) + { + case TMACH_C64: + regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000); + break; + case TMACH_C128: + regionMain = mLinker->AddRegion(identMain, 0x1e00, 0xfe00); + break; + case TMACH_C128B: + regionMain = mLinker->AddRegion(identMain, 0x1e00, 0x4000); + break; + case TMACH_VIC20: + regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00); + break; + case TMACH_VIC20_3K: + regionMain = mLinker->AddRegion(identMain, 0x0600, 0x1e00); + break; + case TMACH_VIC20_8K: + regionMain = mLinker->AddRegion(identMain, 0x1400, 0x4000); + break; + case TMACH_VIC20_16K: + regionMain = mLinker->AddRegion(identMain, 0x1400, 0x6000); + break; + case TMACH_VIC20_24K: + regionMain = mLinker->AddRegion(identMain, 0x1400, 0x8000); + break; + } + } else - regionMain = mLinker->AddRegion(identMain, 0x0900, 0xa000); + { + switch (mTargetMachine) + { + case TMACH_C64: + regionMain = mLinker->AddRegion(identMain, 0x0880, 0xa000); + break; + case TMACH_C128: + regionMain = mLinker->AddRegion(identMain, 0x1d00, 0xfe00); + break; + case TMACH_C128B: + regionMain = mLinker->AddRegion(identMain, 0x1c80, 0x4000); + break; + case TMACH_VIC20: + regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00); + break; + case TMACH_VIC20_3K: + regionMain = mLinker->AddRegion(identMain, 0x0580, 0x1e00); + break; + case TMACH_VIC20_8K: + regionMain = mLinker->AddRegion(identMain, 0x1280, 0x4000); + break; + case TMACH_VIC20_16K: + regionMain = mLinker->AddRegion(identMain, 0x1280, 0x6000); + break; + case TMACH_VIC20_24K: + regionMain = mLinker->AddRegion(identMain, 0x1280, 0x8000); + break; + } + } } regionMain->mSections.Push(mCompilationUnits->mSectionCode); diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index 0c178a4..66ebc5c 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -28,7 +28,8 @@ public: GrowingArray mByteCodeFunctions; - uint64 mCompilerOptions; + TargetMachine mTargetMachine; + uint64 mCompilerOptions; struct Define { diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h index 54fadfe..ef14a1e 100644 --- a/oscar64/CompilerTypes.h +++ b/oscar64/CompilerTypes.h @@ -37,16 +37,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 | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER; -struct CompilerSettings +enum TargetMachine { - uint64 mCompilerFlags; - uint8 mRegWork; - uint8 mRegFParam; - uint8 mRegIP; - uint8 mRegAccu; - uint8 mRegAddr; - uint8 mRegStack; - uint8 mRegLocals; - uint8 mRegTmp; - uint8 mRegTmpSaved; + TMACH_C64, + TMACH_VIC20, + TMACH_VIC20_3K, + TMACH_VIC20_8K, + TMACH_VIC20_16K, + TMACH_VIC20_24K, + TMACH_C128, + TMACH_C128B }; + + diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index e5dde27..3775c71 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -122,6 +122,9 @@ int main2(int argc, const char** argv) char targetFormat[20]; strcpy_s(targetFormat, "prg"); + char targetMachine[20]; + strcpy_s(targetMachine, "c64"); + compiler->AddDefine(Ident::Unique("__OSCAR64C__"), "1"); compiler->AddDefine(Ident::Unique("__STDC__"), "1"); compiler->AddDefine(Ident::Unique("__STDC_VERSION__"), "199901L"); @@ -161,6 +164,10 @@ int main2(int argc, const char** argv) { strcpy_s(targetFormat, arg + 4); } + else if (arg[1] == 't' && arg[2] == 'm' && arg[3] == '=') + { + strcpy_s(targetMachine, arg + 4); + } else if (arg[1] == 'n') { compiler->mCompilerOptions |= COPT_NATIVE; @@ -225,11 +232,65 @@ int main2(int argc, const char** argv) } } + char basicStart[10]; + strcpy_s(basicStart, "0x0801"); + + if (!strcmp(targetMachine, "c64")) + { + compiler->mTargetMachine = TMACH_C64; + compiler->AddDefine(Ident::Unique("__C64__"), "1"); + } + else if (!strcmp(targetMachine, "c128")) + { + strcpy_s(basicStart, "0x1c01"); + compiler->mTargetMachine = TMACH_C128; + compiler->AddDefine(Ident::Unique("__C128__"), "1"); + } + else if (!strcmp(targetMachine, "c128b")) + { + strcpy_s(basicStart, "0x1c01"); + compiler->mTargetMachine = TMACH_C128B; + compiler->AddDefine(Ident::Unique("__C128B__"), "1"); + } + else if (!strcmp(targetMachine, "vic20")) + { + strcpy_s(basicStart, "0x1001"); + compiler->mTargetMachine = TMACH_VIC20; + compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); + } + else if (!strcmp(targetMachine, "vic20+3")) + { + strcpy_s(basicStart, "0x0401"); + compiler->mTargetMachine = TMACH_VIC20_3K; + compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); + } + else if (!strcmp(targetMachine, "vic20+8")) + { + strcpy_s(basicStart, "0x1201"); + compiler->mTargetMachine = TMACH_VIC20_8K; + compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); + } + else if (!strcmp(targetMachine, "vic20+16")) + { + strcpy_s(basicStart, "0x1201"); + compiler->mTargetMachine = TMACH_VIC20_16K; + compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); + } + else if (!strcmp(targetMachine, "vic20+24")) + { + strcpy_s(basicStart, "0x1201"); + compiler->mTargetMachine = TMACH_VIC20_24K; + compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); + } + else + compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid target machine option", targetMachine); + + if (!strcmp(targetFormat, "prg")) { compiler->mCompilerOptions |= COPT_TARGET_PRG; compiler->AddDefine(Ident::Unique("OSCAR_TARGET_PRG"), "1"); - compiler->AddDefine(Ident::Unique("OSCAR_BASIC_START"), "0x0801"); + compiler->AddDefine(Ident::Unique("OSCAR_BASIC_START"), basicStart); } else if (!strcmp(targetFormat, "crt")) { @@ -245,7 +306,7 @@ int main2(int argc, const char** argv) { compiler->mCompilerOptions |= COPT_TARGET_LZO; compiler->AddDefine(Ident::Unique("OSCAR_TARGET_LZO"), "1"); - compiler->AddDefine(Ident::Unique("OSCAR_BASIC_START"), "0x0801"); + compiler->AddDefine(Ident::Unique("OSCAR_BASIC_START"), basicStart); } else compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid target format option", targetFormat); @@ -302,7 +363,7 @@ int main2(int argc, const char** argv) } else { - printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=target] [-e] [-n] {-dSYMBOL[=value]} [-v] [-d64=diskname] {-f[z]=file.xxx} {source.c}\n"); + printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=target] [-tm=machine] [-e] [-n] {-dSYMBOL[=value]} [-v] [-d64=diskname] {-f[z]=file.xxx} {source.c}\n"); return 0; }