fix a configurable compilation target, add working example

This commit is contained in:
Irmen de Jong 2025-01-17 22:58:51 +01:00
parent e8f3af6981
commit bc7b086f0f
10 changed files with 503 additions and 50 deletions

View File

@ -68,14 +68,14 @@ class ConfigFileTarget(
return emptyList()
val result = mutableListOf<UIntRange>()
val ranges = rangesStr.split(",").map { it.trim() }
for(rangeStr in ranges) {
if ('-' in rangeStr) {
val (fromStr, toStr) = rangeStr.split("-")
for(r in ranges) {
if ('-' in r) {
val (fromStr, toStr) = r.split("-")
val from = parseInt(fromStr.trim())
val to = parseInt(toStr.trim())
result.add(from..to)
} else {
val address = parseInt(rangesStr)
val address = parseInt(r)
result.add(address..address)
}
}

View File

@ -29,14 +29,12 @@ class UnusedCodeRemover(private val program: Program,
val subroutines = it.statements.filterIsInstance<Subroutine>()
val push = subroutines.single { it.name == "push" }
val pushw = subroutines.single { it.name == "pushw" }
val pushret = subroutines.single { it.name == "push_returnaddress" }
val pop = subroutines.single { it.name == "pop" }
val popw = subroutines.single { it.name == "popw" }
neverRemoveSubroutines.add(push)
neverRemoveSubroutines.add(pushw)
neverRemoveSubroutines.add(pop)
neverRemoveSubroutines.add(popw)
neverRemoveSubroutines.add(pushret)
}
program.allBlocks.singleOrNull { it.name=="floats" } ?.let {

View File

@ -1,9 +1,18 @@
.PHONY: all clean
all: main.prg
all: main-c64.prg main-cx16.prg main-pet.prg
clean:
rm -f *.prg *.PRG *.asm *.vice-*
main.prg: main.p8
prog8c -target ./target.properties -srcdirs libraries main.p8 -sourcelines
main-c64.prg: main.p8 tinyc64.properties
prog8c -target ./tinyc64.properties main.p8 -sourcelines
mv main.prg $@
main-cx16.prg: main.p8 tinycx16.properties
prog8c -target ./tinycx16.properties main.p8 -sourcelines
mv main.prg $@
main-pet.prg: main.p8 tinypet.properties
prog8c -target ./tinypet.properties main.p8 -sourcelines
mv main.prg $@

View File

@ -0,0 +1,190 @@
%option no_symbol_prefixing, ignore_unused
; Tiny syslib for minimalistic programs that can run on a C64
sys {
extsub $FFD2 = CHROUT(ubyte character @ A) ; output a character
; these push/pop routines are always required by the compiler:
inline asmsub push(ubyte value @A) {
%asm {{
pha
}}
}
inline asmsub pushw(uword value @AY) {
%asm {{
pha
tya
pha
}}
}
inline asmsub pop() -> ubyte @A {
%asm {{
pla
}}
}
inline asmsub popw() -> uword @AY {
%asm {{
pla
tay
pla
}}
}
asmsub reset_system() {
; Soft-reset the system back to initial power-on Basic prompt.
%asm {{
sei
lda #14
sta $01 ; bank the kernal in
jmp ($fffc) ; reset vector
}}
}
}
p8_sys_startup {
%option force_output
asmsub init_system() {
%asm {{
rts
}}
}
asmsub init_system_phase2() {
%asm {{
rts
}}
}
asmsub cleanup_at_exit() {
; executed when the main subroutine does rts
%asm {{
_exitcodeCarry = *+1
lda #0
lsr a
_exitcode = *+1
lda #0 ; exit code possibly modified in exit()
_exitcodeX = *+1
ldx #0
_exitcodeY = *+1
ldy #0
rts
}}
}
}
cx16 {
; the sixteen virtual 16-bit registers that the CX16 has defined in the zeropage
; they are simulated on the C64 as well but their location in memory is different
; (because there's no room for them in the zeropage in the default configuration)
; Note that when using ZP options that free up more of the zeropage (such as %zeropage kernalsafe)
; there might be enough space to put them there after all, and the compiler will change these addresses!
&uword r0 = $cfe0
&uword r1 = $cfe2
&uword r2 = $cfe4
&uword r3 = $cfe6
&uword r4 = $cfe8
&uword r5 = $cfea
&uword r6 = $cfec
&uword r7 = $cfee
&uword r8 = $cff0
&uword r9 = $cff2
&uword r10 = $cff4
&uword r11 = $cff6
&uword r12 = $cff8
&uword r13 = $cffa
&uword r14 = $cffc
&uword r15 = $cffe
&word r0s = $cfe0
&word r1s = $cfe2
&word r2s = $cfe4
&word r3s = $cfe6
&word r4s = $cfe8
&word r5s = $cfea
&word r6s = $cfec
&word r7s = $cfee
&word r8s = $cff0
&word r9s = $cff2
&word r10s = $cff4
&word r11s = $cff6
&word r12s = $cff8
&word r13s = $cffa
&word r14s = $cffc
&word r15s = $cffe
&ubyte r0L = $cfe0
&ubyte r1L = $cfe2
&ubyte r2L = $cfe4
&ubyte r3L = $cfe6
&ubyte r4L = $cfe8
&ubyte r5L = $cfea
&ubyte r6L = $cfec
&ubyte r7L = $cfee
&ubyte r8L = $cff0
&ubyte r9L = $cff2
&ubyte r10L = $cff4
&ubyte r11L = $cff6
&ubyte r12L = $cff8
&ubyte r13L = $cffa
&ubyte r14L = $cffc
&ubyte r15L = $cffe
&ubyte r0H = $cfe1
&ubyte r1H = $cfe3
&ubyte r2H = $cfe5
&ubyte r3H = $cfe7
&ubyte r4H = $cfe9
&ubyte r5H = $cfeb
&ubyte r6H = $cfed
&ubyte r7H = $cfef
&ubyte r8H = $cff1
&ubyte r9H = $cff3
&ubyte r10H = $cff5
&ubyte r11H = $cff7
&ubyte r12H = $cff9
&ubyte r13H = $cffb
&ubyte r14H = $cffd
&ubyte r15H = $cfff
&byte r0sL = $cfe0
&byte r1sL = $cfe2
&byte r2sL = $cfe4
&byte r3sL = $cfe6
&byte r4sL = $cfe8
&byte r5sL = $cfea
&byte r6sL = $cfec
&byte r7sL = $cfee
&byte r8sL = $cff0
&byte r9sL = $cff2
&byte r10sL = $cff4
&byte r11sL = $cff6
&byte r12sL = $cff8
&byte r13sL = $cffa
&byte r14sL = $cffc
&byte r15sL = $cffe
&byte r0sH = $cfe1
&byte r1sH = $cfe3
&byte r2sH = $cfe5
&byte r3sH = $cfe7
&byte r4sH = $cfe9
&byte r5sH = $cfeb
&byte r6sH = $cfed
&byte r7sH = $cfef
&byte r8sH = $cff1
&byte r9sH = $cff3
&byte r10sH = $cff5
&byte r11sH = $cff7
&byte r12sH = $cff9
&byte r13sH = $cffb
&byte r14sH = $cffd
&byte r15sH = $cfff
}

View File

@ -1,9 +1,9 @@
%option no_symbol_prefixing, ignore_unused
; Tiny syslib for minimalistic programs that can run on a X16
sys {
extsub $ff00 = CHAROUT(ubyte character @A)
extsub $FFD2 = CHROUT(ubyte character @ A) ; output a character
; these push/pop routines are always required by the compiler:
@ -16,19 +16,8 @@ sys {
inline asmsub pushw(uword value @AY) {
%asm {{
pha
phy
}}
}
inline asmsub push_returnaddress(uword address @XY) {
%asm {{
; push like JSR would: address-1, MSB first then LSB
cpx #0
bne +
dey
+ dex
phy
phx
tya
pha
}}
}
@ -40,19 +29,25 @@ sys {
inline asmsub popw() -> uword @AY {
%asm {{
ply
pla
tay
pla
}}
}
asmsub reset_system() {
; Soft-reset the system back to initial power-on status
; TODO
asmsub reset_system() {
; Soft-reset the system back to initial power-on Basic prompt.
; We do this via the SMC so that a true reset is performed that also resets the Vera fully.
; (note: this is an asmsub on purpose! don't change into a normal sub)
%asm {{
sei
jmp *
ldx #$42
ldy #2
lda #0
jmp $fec9 ; i2c_write_byte
}}
}
}
@ -192,5 +187,4 @@ cx16 {
&byte r13sH = $001d
&byte r14sH = $001f
&byte r15sH = $0021
}

View File

@ -0,0 +1,186 @@
%option no_symbol_prefixing, ignore_unused
; Tiny syslib for minimalistic programs that can run on a PET
sys {
extsub $FFD2 = CHROUT(ubyte character @ A) ; output a character
; these push/pop routines are always required by the compiler:
inline asmsub push(ubyte value @A) {
%asm {{
pha
}}
}
inline asmsub pushw(uword value @AY) {
%asm {{
pha
tya
pha
}}
}
inline asmsub pop() -> ubyte @A {
%asm {{
pla
}}
}
inline asmsub popw() -> uword @AY {
%asm {{
pla
tay
pla
}}
}
asmsub reset_system() {
; Soft-reset the system back to initial power-on Basic prompt.
%asm {{
sei
jmp ($fffc) ; reset vector
}}
}
}
p8_sys_startup {
%option force_output
asmsub init_system() {
%asm {{
rts
}}
}
asmsub init_system_phase2() {
%asm {{
rts
}}
}
asmsub cleanup_at_exit() {
; executed when the main subroutine does rts
%asm {{
_exitcodeCarry = *+1
lda #0
lsr a
_exitcode = *+1
lda #0 ; exit code possibly modified in exit()
_exitcodeX = *+1
ldx #0
_exitcodeY = *+1
ldy #0
rts
}}
}
}
cx16 {
; they are simulated on the PET as well but their location in memory is different
; (because there's no room for them in the zeropage)
; we select the top page of RAM (assume 32Kb)
&uword r0 = $7fe0
&uword r1 = $7fe2
&uword r2 = $7fe4
&uword r3 = $7fe6
&uword r4 = $7fe8
&uword r5 = $7fea
&uword r6 = $7fec
&uword r7 = $7fee
&uword r8 = $7ff0
&uword r9 = $7ff2
&uword r10 = $7ff4
&uword r11 = $7ff6
&uword r12 = $7ff8
&uword r13 = $7ffa
&uword r14 = $7ffc
&uword r15 = $7ffe
&word r0s = $7fe0
&word r1s = $7fe2
&word r2s = $7fe4
&word r3s = $7fe6
&word r4s = $7fe8
&word r5s = $7fea
&word r6s = $7fec
&word r7s = $7fee
&word r8s = $7ff0
&word r9s = $7ff2
&word r10s = $7ff4
&word r11s = $7ff6
&word r12s = $7ff8
&word r13s = $7ffa
&word r14s = $7ffc
&word r15s = $7ffe
&ubyte r0L = $7fe0
&ubyte r1L = $7fe2
&ubyte r2L = $7fe4
&ubyte r3L = $7fe6
&ubyte r4L = $7fe8
&ubyte r5L = $7fea
&ubyte r6L = $7fec
&ubyte r7L = $7fee
&ubyte r8L = $7ff0
&ubyte r9L = $7ff2
&ubyte r10L = $7ff4
&ubyte r11L = $7ff6
&ubyte r12L = $7ff8
&ubyte r13L = $7ffa
&ubyte r14L = $7ffc
&ubyte r15L = $7ffe
&ubyte r0H = $7fe1
&ubyte r1H = $7fe3
&ubyte r2H = $7fe5
&ubyte r3H = $7fe7
&ubyte r4H = $7fe9
&ubyte r5H = $7feb
&ubyte r6H = $7fed
&ubyte r7H = $7fef
&ubyte r8H = $7ff1
&ubyte r9H = $7ff3
&ubyte r10H = $7ff5
&ubyte r11H = $7ff7
&ubyte r12H = $7ff9
&ubyte r13H = $7ffb
&ubyte r14H = $7ffd
&ubyte r15H = $7fff
&byte r0sL = $7fe0
&byte r1sL = $7fe2
&byte r2sL = $7fe4
&byte r3sL = $7fe6
&byte r4sL = $7fe8
&byte r5sL = $7fea
&byte r6sL = $7fec
&byte r7sL = $7fee
&byte r8sL = $7ff0
&byte r9sL = $7ff2
&byte r10sL = $7ff4
&byte r11sL = $7ff6
&byte r12sL = $7ff8
&byte r13sL = $7ffa
&byte r14sL = $7ffc
&byte r15sL = $7ffe
&byte r0sH = $7fe1
&byte r1sH = $7fe3
&byte r2sH = $7fe5
&byte r3sH = $7fe7
&byte r4sH = $7fe9
&byte r5sH = $7feb
&byte r6sH = $7fed
&byte r7sH = $7fef
&byte r8sH = $7ff1
&byte r9sH = $7ff3
&byte r10sH = $7ff5
&byte r11sH = $7ff7
&byte r12sH = $7ff9
&byte r13sH = $7ffb
&byte r14sH = $7ffd
&byte r15sH = $7fff
}

View File

@ -1,10 +1,13 @@
%import syslib
%zeropage basicsafe
main {
sub start() {
for cx16.r0L in "Hello, world!\n" {
sys.CHAROUT(cx16.r0L)
ubyte char
sys.CHROUT(14) ; lowercase
for char in "\nHello, World!\n" {
sys.CHROUT(char)
}
}
}

View File

@ -0,0 +1,37 @@
# configuration file for a C64 like Prog8 compilation target
cpu = 6502
program = CBMPRG
encoding = petscii
load_address = $0801
memtop = $cfe0
startup_reserved = 20
bss_highram_start = $c000
bss_highram_end = $cfdf
bss_goldenram_start = 0
bss_goldenram_end = 0
# io_regions specifies memory-mapped I/O registers that should be treated differentely.
# it can be zero or more memory address ranges (inclusive) separated by comma
io_regions = 0,1,$d000-$dfff
# zeropage scratch variables. zp_scratch_reg must always be zp_scratch_b1+1 !
zp_scratch_b1 = $02
zp_scratch_reg = $03
zp_scratch_w1 = $fb
zp_scratch_w2 = $fd
# free zeropage locations for the various zp usage methods
# zero or more zeropage address ranges (inclusive).
zp_fullsafe = $02-$90,$92-$9f,$a3-$bf,$c1,$c2,$c3,$c4,$c6-$ca,$cf-$f4,$f7-$ff
zp_kernalsafe = $02-$25,$39-$48,$4b-$4f,$51,$52,$53,$57,$58,$59,$5a,$5b,$5c,$5d,$5e,$5f,$60-$8f,$ff
zp_basicsafe = $02-$06,$0a,$0e,$92,$96,$9b,$9c,$9e,$9f,$a6,$b0,$b1,$be,$bf,$f9
# the start of the 32 bytes used by the R0-R15 virtual registers. Can be in Zeropage or elsewhere.
virtual_registers = $cfe0
# Where can we find the standard library (syslib.p8). You can still add more paths manually using -srcdirs
library = ./libraries/tinyc64
# TODO should the 64tass arguments be in here too perhaps? So that the "program" parameter that now selects 1 of a few fixed sets of arguments, can be removed?
# TODO should an emulator command line also be in here perhaps? So that -emu will work too.

View File

@ -0,0 +1,37 @@
# configuration file for a Commander X16 like Prog8 compilation target
cpu = 65C02
program = CBMPRG
encoding = petscii
load_address = $0801
memtop = $9f00
startup_reserved = 20
bss_highram_start = $a00
bss_highram_end = $bfff
bss_goldenram_start = $0400
bss_goldenram_end = $07ff
# io_regions specifies memory-mapped I/O registers that should be treated differentely.
# it can be zero or more memory address ranges (inclusive) separated by comma
io_regions = 0,1,$9f00-$9fff
# zeropage scratch variables. zp_scratch_reg must always be zp_scratch_b1+1 !
zp_scratch_b1 = $7a
zp_scratch_reg = $7b
zp_scratch_w1 = $7c
zp_scratch_w2 = $7e
# free zeropage locations for the various zp usage methods
# zero or more zeropage address ranges (inclusive).
zp_fullsafe = $22-$ff
zp_kernalsafe = $22-$7f,$a9-$ff
zp_basicsafe = $22-$7f
# the start of the 32 bytes used by the R0-R15 virtual registers. Can be in Zeropage or elsewhere.
virtual_registers = $02
# Where can we find the standard library (syslib.p8). You can still add more paths manually using -srcdirs
library = ./libraries/tinycx16
# TODO should the 64tass arguments be in here too perhaps? So that the "program" parameter that now selects 1 of a few fixed sets of arguments, can be removed?
# TODO should an emulator command line also be in here perhaps? So that -emu will work too.

View File

@ -1,12 +1,11 @@
# configuration file for a flexible Prog8 compilation target
# TODO note: values below are just garbage example values for now
# configuration file for a PET like Prog8 compilation target
cpu = 65C02
cpu = 6502
program = CBMPRG
encoding = iso
load_address = $0801
memtop = $d000
startup_reserved = 32
encoding = petscii
load_address = $0401
memtop = $8000
startup_reserved = 20
bss_highram_start = 0
bss_highram_end = 0
bss_goldenram_start = 0
@ -14,25 +13,25 @@ bss_goldenram_end = 0
# io_regions specifies memory-mapped I/O registers that should be treated differentely.
# it can be zero or more memory address ranges (inclusive) separated by comma
io_regions = $d000-$dfff
io_regions = $e800-$e8ff
# zeropage scratch variables. zp_scratch_reg must always be zp_scratch_b1+1 !
zp_scratch_b1 = $e0
zp_scratch_reg = $e1
zp_scratch_w1 = $e2
zp_scratch_w2 = $e4
zp_scratch_b1 = $b3
zp_scratch_reg = $b4
zp_scratch_w1 = $b6
zp_scratch_w2 = $b8
# free zeropage locations for the various zp usage methods
# zero or more zeropage address ranges (inclusive).
zp_fullsafe = $00-$ff
zp_kernalsafe = $00-$e0
zp_basicsafe = $00-$7f
zp_fullsafe = $00-$8c,$90-$96,$9c,$9d,$9f-$a6,$ab-$ff
zp_kernalsafe = $00-$8c,$90-$96,$9c,$9d,$9f-$a6,$ab-$ff
zp_basicsafe = $b3-$ba
# the start of the 32 bytes used by the R0-R15 virtual registers. Can be in Zeropage or elsewhere.
virtual_registers = $10
virtual_registers = $7fe0
# Where can we find the standard library (syslib.p8). You can still add more paths manually using -srcdirs
library = ~/dev/prog8/mylibrary
library = ./libraries/tinypet
# TODO should the 64tass arguments be in here too perhaps? So that the "program" parameter that now selects 1 of a few fixed sets of arguments, can be removed?
# TODO should an emulator command line also be in here perhaps? So that -emu will work too.