Prepare support for VIC20 and C128

This commit is contained in:
drmortalwombat 2023-03-02 20:19:47 +01:00
parent e09361295e
commit f34aa2dcbe
10 changed files with 347 additions and 29 deletions

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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

2
include/vic20/vic.c Normal file
View File

@ -0,0 +1,2 @@
#include "vic.h"

27
include/vic20/vic.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef VIC20_VIC
#define VIC20_VIC
#include <c64/types.h>
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

View File

@ -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);

View File

@ -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);

View File

@ -28,7 +28,8 @@ public:
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
uint64 mCompilerOptions;
TargetMachine mTargetMachine;
uint64 mCompilerOptions;
struct Define
{

View File

@ -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
};

View File

@ -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;
}