Add device libraries for various C computers

This commit is contained in:
drmortalwombat 2023-03-05 15:13:02 +01:00
parent 6189e0cc49
commit 9bd7b5cd48
11 changed files with 559 additions and 1 deletions

78
include/c128/vdc.c Normal file
View File

@ -0,0 +1,78 @@
#include "vdc.h"
inline void vdc_reg(VDCRegister reg)
{
vdc.addr = reg;
do {} while (vdc.addr < 128);
}
inline void vdc_write(byte data)
{
vdc.data = data;
}
inline byte vdc_read(void)
{
return vdc.data;
}
void vdc_reg_write(VDCRegister reg, byte data)
{
vdc_reg(reg);
vdc_write(data);
}
byte vdc_reg_read(VDCRegister reg)
{
vdc_reg(reg);
return vdc_read();
}
void vdc_mem_addr(unsigned addr)
{
vdc_reg_write(VDCR_ADDRH, addr >> 8);
vdc_reg_write(VDCR_ADDRL, addr);
vdc_reg(VDCR_DATA);
}
inline void vdc_mem_write(char data)
{
vdc_write(data);
}
inline char vdc_mem_read(void)
{
return vdc_read();
}
void vdc_mem_write_at(unsigned addr, char data)
{
vdc_mem_addr(addr);
vdc_write(data);
}
char vdc_mem_read_at(unsigned addr)
{
vdc_mem_addr(addr);
return vdc_read();
}
void vdc_mem_write_buffer(unsigned addr, const char * data, char size)
{
vdc_mem_addr(addr);
for(char i=0; i<size; i++)
vdc_write(data[i]);
}
void vdc_mem_read_buffer(unsigned addr, char * data, char size)
{
vdc_mem_addr(addr);
for(char i=0; i<size; i++)
data[i] = vdc_read();
}

95
include/c128/vdc.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef C128_VDC_H
#define C128_VDC_H
#include <c64/types.h>
enum VDCRegister
{
VDCR_HTOTAL,
VDCR_HDISPLAY,
VDCR_HSYNC,
VDCR_SYNCSIZE,
VDCR_VTOTAL,
VDCR_VADJUST,
VDCR_VDISPLAY,
VDCR_VSYNC,
VDCR_LACE,
VDCR_CSIZE,
VDCR_CURSOR_START,
VDCR_CURSOR_END,
VDCR_DISP_ADDRH,
VDCR_DISP_ADDRL,
VDCR_CURSOR_ADDRH,
VDCR_CURSOR_ADDRL,
VDCR_LPEN_Y,
VDCR_LPEN_X,
VDCR_ADDRH,
VDCR_ADDRL,
VDCR_ATTR_ADDRH,
VDCR_ATTR_ADDRL,
VDCR_CWIDTH,
VDCR_CHEIGHT,
VDCR_VSCROLL,
VDCR_HSCROLL,
VDCR_COLOR,
VDCR_ROWINC,
VDCR_CHAR_ADDRH,
VDCR_UNDERLINE,
VDCR_DSIZE,
VDCR_DATA,
VDCR_BLOCK_ADDRH,
VDCR_BLOCK_ADDRL,
VDCR_HSTART,
VDCR_HEND,
VDCR_REFRESH
};
struct VDC
{
volatile char addr;
volatile char data;
};
#define vdc (*((struct VDC *)0xd600))
inline void vdc_reg(VDCRegister reg);
inline void vdc_write(byte data);
inline byte vdc_read(void);
void vdc_reg_write(VDCRegister reg, byte data);
byte vdc_reg_read(VDCRegister reg);
void vdc_mem_addr(unsigned addr);
inline void vdc_mem_write(char data);
inline char vdc_mem_read(void);
void vdc_mem_write_at(unsigned addr, char data);
char vdc_mem_read_at(unsigned addr);
void vdc_mem_write_buffer(unsigned addr, const char * data, char size);
void vdc_mem_read_buffer(unsigned addr, char * data, char size);
#pragma compile("vdc.c")
#endif

View File

@ -33,6 +33,33 @@ __asm bsinit
sta 0xff01 sta 0xff01
} }
#pragma code(code) #pragma code(code)
#elif defined(__PLUS4__)
#pragma code(lowcode)
__asm bsout
{
sta 0xff3e
jsr 0xffd2
sta 0xff3f
}
__asm bsin
{
sta 0xff3e
jsr 0xffe4
sta 0xff3f
}
__asm bsplot
{
sta 0xff3e
jsr 0xfff0
sta 0xff3f
}
__asm bsinit
{
sta 0xff3e
jsr 0xff81
sta 0xff3f
}
#pragma code(code)
#else #else
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
@ -66,12 +93,25 @@ __asm putpch
bcc w3 bcc w3
cmp #123 cmp #123
bcs w3 bcs w3
#if defined(__CBMPET__)
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else
cmp #97 cmp #97
bcs w2 bcs w2
cmp #91 cmp #91
bcs w3 bcs w3
w2: w2:
eor #$20 eor #$20
#endif
cpx #IOCHM_PETSCII_2 cpx #IOCHM_PETSCII_2
beq w3 beq w3
and #$df and #$df

View File

@ -24,6 +24,41 @@ char spentry = 0;
int main(void); int main(void);
#if defined (__PLUS4__)
#pragma code(lowcode)
__asm p4irqx
{
sta $ff3f
pla
tax
pla
rti
}
__asm p4irq
{
pha
txa
pha
sta $ff3e
lda #>p4irqx
pha
lda #<p4irqx
pha
tsx
lda $0105, x
pha
pha
txa
pha
tya
pha
jmp $ce00
}
#pragma code(code)
#endif
__asm startup __asm startup
{ {
@ -150,6 +185,12 @@ w0:
#if defined(__C128__) #if defined(__C128__)
sta 0xff01 sta 0xff01
#elif defined(__PLUS4__)
lda #<p4irq
sta $fffe
lda #>p4irq
sta $ffff
sta $ff3f
#endif #endif
tsx tsx
@ -253,7 +294,8 @@ spexit:
#if defined(__C128__) #if defined(__C128__)
lda #0 lda #0
sta 0xff00 sta 0xff00
#endif #elif defined(__PLUS4__)
sta $ff3e
#endif #endif
rts rts
} }

73
include/plus4/ted.c Normal file
View File

@ -0,0 +1,73 @@
#include "ted.h"
void ted_waitBottom(void)
{
while (!(ted.vscan_high & 1))
;
}
void ted_waitTop(void)
{
while (ted.vscan_high & 1)
;
}
void ted_waitFrame(void)
{
while (ted.vscan_high & 1)
;
while (!(ted.vscan_high & 1))
;
}
void ted_waitLine(int line)
{
char upper = (char)(line >> 8) & 1;
char lower = (char)line;
do
{
while (ted.vscan_low != lower)
;
} while ((ted.vscan_high & 1) != upper);
}
void ted_setmode(TedMode mode, char * text, char * font)
{
switch (mode)
{
case TEDM_TEXT:
ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_RSEL | 3;
ted.ctrl2 = TED_CTRL2_CSEL;
break;
case TEDM_TEXT_MC:
ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_RSEL | 3;
ted.ctrl2 = TED_CTRL2_CSEL | TED_CTRL2_MCM;
break;
case TEDM_TEXT_ECM:
ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_ECM | TED_CTRL1_RSEL | 3;
ted.ctrl2 = TED_CTRL2_CSEL;
break;
case TEDM_HIRES:
ted.ctrl1 = TED_CTRL1_BMM | TED_CTRL1_DEN | TED_CTRL1_RSEL | 3;
ted.ctrl2 = TED_CTRL2_CSEL;
break;
case TEDM_HIRES_MC:
ted.ctrl1 = TED_CTRL1_BMM | TED_CTRL1_DEN | TED_CTRL1_RSEL | 3;
ted.ctrl2 = TED_CTRL2_CSEL | TED_CTRL2_MCM;
break;
default:
__assume(false);
}
ted.vid_ptr = (unsigned)text >> 8;
if (mode < TEDM_HIRES)
{
ted.char_ptr = (unsigned)font >> 8;
}
else
{
ted.sound1_high = (ted.sound1_high & 0x3) | ((unsigned)font >> 10);
}
}

102
include/plus4/ted.h Normal file
View File

@ -0,0 +1,102 @@
#ifndef PLUS4_TED_H
#define PLUS4_TED_H
#include <c64/types.h>
#define TED_CTRL1_RSEL 0x08
#define TED_CTRL1_DEN 0x10
#define TED_CTRL1_BMM 0x20
#define TED_CTRL1_ECM 0x40
#define TED_CTRL2_CSEL 0x08
#define TED_CTRL2_MCM 0x10
#define TED_CTRL2_RES 0x20
#define TED_CTRL2_NTSC 0x40
#define TED_CTRL2_INV 0x80
#define TED_INTR_RST 0x02
#define TED_INTR_LPEN 0x04
#define TED_INTR_CNT1 0x08
#define TED_INTR_CNT2 0x10
#define TED_INTR_CNT3 0x20
#define TED_INTR_IRQ 0x80
#define TED_SND_SQUARE1 0x10
#define TES_SND_SQUARE2 0x20
#define TES_SND_NOISE2 0x40
#define TES_SND_DA 0x80
#define TES_CHAR_ROM 0x04
struct TED
{
volatile word timer0;
volatile word timer1;
volatile word timer2;
volatile byte ctrl1;
volatile byte ctrl2;
volatile byte keybin;
volatile byte intr_ctrl;
volatile byte intr_enable;
volatile byte raster;
volatile word cursor_pos;
volatile byte sound1_low;
volatile byte sound2_low;
volatile byte sound2_high;
volatile byte sound_ctrl;
volatile byte sound1_high;
volatile byte char_ptr;
volatile byte vid_ptr;
volatile byte color_back;
volatile byte color_back1;
volatile byte color_back2;
volatile byte color_back3;
volatile byte color_border;
volatile byte char_pos_high;
volatile byte char_pos_low;
volatile byte vscan_high;
volatile byte vscan_low;
volatile byte hscan;
volatile byte flash;
};
enum TedMode
{
TEDM_TEXT,
TEDM_TEXT_MC,
TEDM_TEXT_ECM,
TEDM_HIRES,
TEDM_HIRES_MC
};
// set the display mode and base address. This will also
// adapt the bank.
void ted_setmode(TedMode mode, char * text, char * font);
// wait for the beam to reach the bottom of the visual area
inline void ted_waitBottom(void);
// wait for the beam to reach the top of the frame
inline void ted_waitTop(void);
// wait for the top of the frame and then for the bottom of the visual area
inline void ted_waitFrame(void);
// wait for a specific raster line
void ted_waitLine(int line);
// reference to the TED chip
#define ted (*((struct TED *)0xff00))
#pragma compile("ted.c")
#endif

View File

@ -26,6 +26,27 @@ __asm bsin
sta 0xff01 sta 0xff01
} }
#pragma code(code)
#elif defined(__PLUS4__)
#pragma code(lowcode)
__asm bsout
{
sta 0xff3e
jsr 0xffd2
sta 0xff3f
}
__asm bsin
{
sta 0xff3e
jsr 0xffe4
sta 0xff3f
}
__asm bsplot
{
sta 0xff3e
jsr 0xfff0
sta 0xff3f
}
#pragma code(code) #pragma code(code)
#else #else
#define bsout 0xffd2 #define bsout 0xffd2
@ -53,12 +74,24 @@ __asm putpch
bcc w3 bcc w3
cmp #123 cmp #123
bcs w3 bcs w3
#if defined(__CBMPET__)
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else
cmp #97 cmp #97
bcs w2 bcs w2
cmp #91 cmp #91
bcs w3 bcs w3
w2: w2:
eor #$20 eor #$20
#endif
cpx #IOCHM_PETSCII_2 cpx #IOCHM_PETSCII_2
beq w3 beq w3
and #$df and #$df

View File

@ -4,6 +4,25 @@ clock_t clock(void)
{ {
__asm __asm
{ {
#if defined(__PLUS4__)
lda $a5
sta accu + 0
lda $a4
sta accu + 1
lda $a3
sta accu + 2
lda #0
sta accu + 3
#elif defined(__CBMPET__)
lda $8f
sta accu + 0
lda $8e
sta accu + 1
lda $8d
sta accu + 2
lda #0
sta accu + 3
#else
lda $a2 lda $a2
sta accu + 0 sta accu + 0
lda $a1 lda $a1
@ -12,5 +31,6 @@ clock_t clock(void)
sta accu + 2 sta accu + 2
lda #0 lda #0
sta accu + 3 sta accu + 3
#endif
} }
} }

View File

@ -72,15 +72,18 @@ bool Compiler::ParseSource(void)
case TMACH_VIC20: case TMACH_VIC20:
case TMACH_VIC20_3K: case TMACH_VIC20_3K:
case TMACH_VIC20_8K: case TMACH_VIC20_8K:
case TMACH_PET_8K:
mCompilationUnits->mSectionStack->mSize = 512; mCompilationUnits->mSectionStack->mSize = 512;
mCompilationUnits->mSectionHeap->mSize = 512; mCompilationUnits->mSectionHeap->mSize = 512;
break; break;
case TMACH_PET_16K:
case TMACH_VIC20_16K: case TMACH_VIC20_16K:
case TMACH_VIC20_24K: case TMACH_VIC20_24K:
mCompilationUnits->mSectionStack->mSize = 1024; mCompilationUnits->mSectionStack->mSize = 1024;
mCompilationUnits->mSectionHeap->mSize = 1024; mCompilationUnits->mSectionHeap->mSize = 1024;
break; break;
case TMACH_C128: case TMACH_C128:
case TMACH_PLUS4:
mCompilationUnits->mSectionLowCode = mLinker->AddSection(Ident::Unique("lowcode"), LST_DATA); mCompilationUnits->mSectionLowCode = mLinker->AddSection(Ident::Unique("lowcode"), LST_DATA);
break; break;
case TMACH_NES: case TMACH_NES:
@ -246,6 +249,19 @@ bool Compiler::GenerateCode(void)
else else
regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1d00); regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1d00);
break; break;
case TMACH_PLUS4:
if (mCompilerOptions & COPT_NATIVE)
{
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1100);
}
else
{
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1000);
}
regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode);
break;
case TMACH_VIC20: case TMACH_VIC20:
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080); regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
@ -253,6 +269,9 @@ bool Compiler::GenerateCode(void)
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1100); regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1100);
break; break;
case TMACH_VIC20_3K: case TMACH_VIC20_3K:
case TMACH_PET_8K:
case TMACH_PET_16K:
case TMACH_PET_32K:
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
regionStartup = mLinker->AddRegion(identStartup, 0x0401, 0x0480); regionStartup = mLinker->AddRegion(identStartup, 0x0401, 0x0480);
else else
@ -289,10 +308,14 @@ bool Compiler::GenerateCode(void)
case TMACH_C128B: case TMACH_C128B:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00); regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00);
break; break;
case TMACH_PLUS4:
case TMACH_VIC20: case TMACH_VIC20:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200); regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200);
break; break;
case TMACH_VIC20_3K: case TMACH_VIC20_3K:
case TMACH_PET_8K:
case TMACH_PET_16K:
case TMACH_PET_32K:
regionBytecode = mLinker->AddRegion(identBytecode, 0x0500, 0x0600); regionBytecode = mLinker->AddRegion(identBytecode, 0x0500, 0x0600);
break; break;
case TMACH_VIC20_8K: case TMACH_VIC20_8K:
@ -348,6 +371,9 @@ bool Compiler::GenerateCode(void)
case TMACH_C128B: case TMACH_C128B:
regionMain = mLinker->AddRegion(identMain, 0x1e00, 0x4000); regionMain = mLinker->AddRegion(identMain, 0x1e00, 0x4000);
break; break;
case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1200, 0xfc00);
break;
case TMACH_VIC20: case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00); regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00);
break; break;
@ -363,6 +389,15 @@ bool Compiler::GenerateCode(void)
case TMACH_VIC20_24K: case TMACH_VIC20_24K:
regionMain = mLinker->AddRegion(identMain, 0x1400, 0x8000); regionMain = mLinker->AddRegion(identMain, 0x1400, 0x8000);
break; break;
case TMACH_PET_8K:
regionMain = mLinker->AddRegion(identMain, 0x0600, 0x2000);
break;
case TMACH_PET_16K:
regionMain = mLinker->AddRegion(identMain, 0x0600, 0x4000);
break;
case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0600, 0x8000);
break;
} }
} }
else else
@ -378,6 +413,9 @@ bool Compiler::GenerateCode(void)
case TMACH_C128B: case TMACH_C128B:
regionMain = mLinker->AddRegion(identMain, 0x1c80, 0x4000); regionMain = mLinker->AddRegion(identMain, 0x1c80, 0x4000);
break; break;
case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1100, 0xfc00);
break;
case TMACH_VIC20: case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00); regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00);
break; break;
@ -393,6 +431,15 @@ bool Compiler::GenerateCode(void)
case TMACH_VIC20_24K: case TMACH_VIC20_24K:
regionMain = mLinker->AddRegion(identMain, 0x1280, 0x8000); regionMain = mLinker->AddRegion(identMain, 0x1280, 0x8000);
break; break;
case TMACH_PET_8K:
regionMain = mLinker->AddRegion(identMain, 0x0480, 0x2000);
break;
case TMACH_PET_16K:
regionMain = mLinker->AddRegion(identMain, 0x0480, 0x4000);
break;
case TMACH_PET_32K:
regionMain = mLinker->AddRegion(identMain, 0x0480, 0x8000);
break;
} }
} }
} }

View File

@ -48,6 +48,10 @@ enum TargetMachine
TMACH_VIC20_24K, TMACH_VIC20_24K,
TMACH_C128, TMACH_C128,
TMACH_C128B, TMACH_C128B,
TMACH_PET_8K,
TMACH_PET_16K,
TMACH_PET_32K,
TMACH_PLUS4,
TMACH_NES TMACH_NES
}; };

View File

@ -282,6 +282,30 @@ int main2(int argc, const char** argv)
compiler->mTargetMachine = TMACH_VIC20_24K; compiler->mTargetMachine = TMACH_VIC20_24K;
compiler->AddDefine(Ident::Unique("__VIC20__"), "1"); compiler->AddDefine(Ident::Unique("__VIC20__"), "1");
} }
else if (!strcmp(targetMachine, "pet"))
{
strcpy_s(basicStart, "0x0401");
compiler->mTargetMachine = TMACH_PET_8K;
compiler->AddDefine(Ident::Unique("__CBMPET__"), "1");
}
else if (!strcmp(targetMachine, "pet16"))
{
strcpy_s(basicStart, "0x0401");
compiler->mTargetMachine = TMACH_PET_16K;
compiler->AddDefine(Ident::Unique("__CBMPET__"), "1");
}
else if (!strcmp(targetMachine, "pet32"))
{
strcpy_s(basicStart, "0x0401");
compiler->mTargetMachine = TMACH_PET_32K;
compiler->AddDefine(Ident::Unique("__CBMPET__"), "1");
}
else if (!strcmp(targetMachine, "plus4"))
{
strcpy_s(basicStart, "0x1001");
compiler->mTargetMachine = TMACH_PLUS4;
compiler->AddDefine(Ident::Unique("__PLUS4__"), "1");
}
else if (!strcmp(targetMachine, "nes")) else if (!strcmp(targetMachine, "nes"))
{ {
compiler->mTargetMachine = TMACH_NES; compiler->mTargetMachine = TMACH_NES;