adding CommanderX16 virtual registers language support, rewrite cx16 examples

This commit is contained in:
Irmen de Jong 2020-12-21 20:38:00 +01:00
parent daaa83ee7d
commit dcb81e6bea
17 changed files with 350 additions and 99 deletions

View File

@ -1,11 +1,11 @@
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.20"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.21"
}
}
plugins {
// id "org.jetbrains.kotlin.jvm" version "1.4.20"
// id "org.jetbrains.kotlin.jvm" version "1.4.21"
id 'application'
id 'org.jetbrains.dokka' version "0.9.18"
id 'com.github.johnrengelman.shadow' version '5.2.0'

View File

@ -13,8 +13,7 @@ graphics {
sub enable_bitmap_mode() {
; enable bitmap screen, erase it and set colors to black/white.
void cx16.screen_set_mode($80)
cx16.r0 = 0
cx16.GRAPH_init()
cx16.GRAPH_init(0)
clear_screen(1, 0)
}
@ -31,11 +30,7 @@ graphics {
}
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
cx16.r0 = x1
cx16.r1 = y1
cx16.r2 = x2
cx16.r3 = y2
cx16.GRAPH_draw_line()
cx16.GRAPH_draw_line(x1, y1, x2, y2)
}
sub circle(uword xcenter, ubyte ycenter, ubyte radius) {

View File

@ -190,53 +190,54 @@ romsub $ff6b = mouse_get(ubyte zpdataptr @X) clobbers(A)
romsub $ff71 = mouse_scan() clobbers(A, X, Y)
romsub $ff53 = joystick_scan() clobbers(A, X, Y)
romsub $ff56 = joystick_get(ubyte joynr @A) -> ubyte @A, ubyte @X, ubyte @Y
romsub $ff4d = clock_set_date_time() clobbers(A, X, Y) ; args: r0, r1, r2, r3L
romsub $ff50 = clock_get_date_time() clobbers(A, X, Y) ; outout args: r0, r1, r2, r3L
romsub $ff4d = clock_set_date_time(uword yearmonth @R0, uword dayhours @R1, uword minsecs @R2, ubyte jiffies @R3) clobbers(A, X, Y)
romsub $ff50 = clock_get_date_time() clobbers(A, X, Y) -> uword @R0, uword @R1, uword @R2, ubyte @R3 ; result registers see clock_set_date_time()
; TODO specify the correct clobbers for alle these functions below, we now assume all 3 regs are clobbered
; high level graphics & fonts
romsub $ff20 = GRAPH_init() clobbers(A,X,Y) ; uses vectors=r0
romsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y)
romsub $ff23 = GRAPH_clear() clobbers(A,X,Y)
romsub $ff26 = GRAPH_set_window() clobbers(A,X,Y) ; uses x=r0, y=r1, width=r2, height=r3
romsub $ff26 = GRAPH_set_window(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y)
romsub $ff29 = GRAPH_set_colors(ubyte stroke @A, ubyte fill @X, ubyte background @Y) clobbers (A,X,Y)
romsub $ff2c = GRAPH_draw_line() clobbers(A,X,Y) ; uses x1=r0, y1=r1, x2=r2, y2=r3
romsub $ff2f = GRAPH_draw_rect(ubyte fill @Pc) clobbers(A,X,Y) ; uses x=r0, y=r1, width=r2, height=r3, cornerradius=r4
romsub $ff32 = GRAPH_move_rect() clobbers(A,X,Y) ; uses sx=r0, sy=r1, tx=r2, ty=r3, width=r4, height=r5
romsub $ff35 = GRAPH_draw_oval(ubyte fill @Pc) clobbers(A,X,Y) ; uses x=r0, y=r1, width=r2, height=r3
romsub $ff38 = GRAPH_draw_image() clobbers(A,X,Y) ; uses x=r0, y=r1, ptr=r2, width=r3, height=r4
romsub $ff3b = GRAPH_set_font() clobbers(A,X,Y) ; uses ptr=r0
romsub $ff2c = GRAPH_draw_line(uword x1 @R0, uword y1 @R1, uword x2 @R2, uword y2 @R3) clobbers(A,X,Y)
romsub $ff2f = GRAPH_draw_rect(uword x @R0, uword y @R1, uword width @R2, uword height @R3, uword cornerradius @R4, ubyte fill @Pc) clobbers(A,X,Y)
romsub $ff32 = GRAPH_move_rect(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword width @R4, uword height @R5) clobbers(A,X,Y)
romsub $ff35 = GRAPH_draw_oval(uword x @R0, uword y @R1, uword width @R2, uword height @R3, ubyte fill @Pc) clobbers(A,X,Y)
romsub $ff38 = GRAPH_draw_image(uword x @R0, uword y @R1, uword ptr @R2, uword width @R3, uword height @R4) clobbers(A,X,Y)
romsub $ff3b = GRAPH_set_font(uword fontptr @R0) clobbers(A,X,Y)
romsub $ff3e = GRAPH_get_char_size(ubyte baseline @A, ubyte width @X, ubyte height_or_style @Y, ubyte is_control @Pc) clobbers(A,X,Y)
romsub $ff41 = GRAPH_put_char(ubyte char @A) clobbers(A,X,Y) ; uses x=r0, y=r1
romsub $ff41 = GRAPH_put_char(uword x @R0, uword y @R1, ubyte char @A) clobbers(A,X,Y)
romsub $ff41 = GRAPH_put_next_char(ubyte char @A) clobbers(A,X,Y) ; alias for the routine above that doesn't reset the position of the initial character
; framebuffer
romsub $fef6 = FB_init() clobbers(A,X,Y)
romsub $fef9 = FB_get_info() clobbers(X,Y) -> byte @A ; also outputs width=r0, height=r1
romsub $fefc = FB_set_palette(ubyte index @A, ubyte bytecount @X) clobbers(A,X,Y) ; also uses pointer=r0
romsub $feff = FB_cursor_position() clobbers(A,X,Y) ; uses x=r0, y=r1
romsub $ff02 = FB_cursor_next_line() clobbers(A,X,Y) ; uses x=r0
romsub $fef9 = FB_get_info() clobbers(X,Y) -> byte @A, uword @R0, uword @R1 ; width=r0, height=r1
romsub $fefc = FB_set_palette(uword pointer @R0, ubyte index @A, ubyte bytecount @X) clobbers(A,X,Y)
romsub $feff = FB_cursor_position(uword x @R0, uword y @R1) clobbers(A,X,Y)
romsub $ff02 = FB_cursor_next_line(uword x @R0) clobbers(A,X,Y)
romsub $ff05 = FB_get_pixel() clobbers(X,Y) -> ubyte @A
romsub $ff08 = FB_get_pixels() clobbers(A,X,Y) ; uses ptr=r0, count=r1
romsub $ff08 = FB_get_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y)
romsub $ff0b = FB_set_pixel(ubyte color @A) clobbers(A,X,Y)
romsub $ff0e = FB_set_pixels() clobbers(A,X,Y) ; uses ptr=r0, count=r1
romsub $ff0e = FB_set_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y)
romsub $ff11 = FB_set_8_pixels(ubyte pattern @A, ubyte color @X) clobbers(A,X,Y)
romsub $ff14 = FB_set_8_pixels_opaque(ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) ; also uses r0L=pattern
romsub $ff17 = FB_fill_pixels(ubyte color @A) clobbers(A,X,Y) ; also uses count=r0, step=r1
romsub $ff1a = FB_filter_pixels() clobbers(A,X,Y) ; uses ptr=r0, count=r1
romsub $ff1d = FB_move_pixels() clobbers(A,X,Y) ; uses sx=r0, sy=r1, tx=r2, ty=r3, count=r4
romsub $ff14 = FB_set_8_pixels_opaque(ubyte mask @A, ubyte color1 @X, ubyte color2 @Y, ubyte pattern @R0) clobbers(A,X,Y)
romsub $ff17 = FB_fill_pixels(ubyte color @A, uword count @R0, uword pstep @R1) clobbers(A,X,Y)
romsub $ff1a = FB_filter_pixels(uword pointer @ R0, uword count @R1) clobbers(A,X,Y)
romsub $ff1d = FB_move_pixels(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword count @R4) clobbers(A,X,Y)
; misc
romsub $fef0 = sprite_set_image(ubyte number @A, ubyte width @X, ubyte height @Y, ubyte apply_mask @Pc) clobbers(A,X,Y) -> ubyte @Pc ; also uses pixels=r0, mask=r1, bpp=r2L
romsub $fef3 = sprite_set_position(ubyte number @A) clobbers(A,X,Y) ; also uses x=r0 and y=r1
romsub $fee4 = memory_fill(ubyte value @A) clobbers(A,X,Y) ; uses address=r0, num_bytes=r1
romsub $fee7 = memory_copy() clobbers(A,X,Y) ; uses source=r0, target=r1, num_bytes=r2
romsub $feea = memory_crc() clobbers(A,X,Y) ; uses address=r0, num_bytes=r1 result->r2
romsub $feed = memory_decompress() clobbers(A,X,Y) ; uses input=r0, output=r1 result->r1
romsub $fedb = console_init() clobbers(A,X,Y) ; uses x=r0, y=r1, width=r2, height=r3
romsub $fef0 = sprite_set_image(ubyte number @A, ubyte width @X, ubyte height @Y, uword pixels @R0, uword mask @R1, ubyte bpp @R2, ubyte apply_mask @Pc) clobbers(A,X,Y) -> ubyte @Pc
romsub $fef3 = sprite_set_position(ubyte number @A, uword x @R0, uword y @R1) clobbers(A,X,Y)
romsub $fee4 = memory_fill(uword address @R0, uword num_bytes @R1, ubyte value @A) clobbers(A,X,Y)
romsub $fee7 = memory_copy(uword source @R0, uword target @R1, uword num_bytes @R2) clobbers(A,X,Y)
romsub $feea = memory_crc(uword address @R0, uword num_bytes @R1) clobbers(A,X,Y) -> uword @R2
romsub $feed = memory_decompress(uword input @R0, uword output @R1) clobbers(A,X,Y) -> uword @R1 ; last address +1 is result in R1
romsub $fedb = console_init(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y)
romsub $fede = console_put_char(ubyte char @A, ubyte wrapping @Pc) clobbers(A,X,Y)
romsub $fee1 = console_get_char() clobbers(X,Y) -> ubyte @A
romsub $fed8 = console_put_image() clobbers(A,X,Y) ; uses ptr=r0, width=r1, height=r2
romsub $fed5 = console_set_paging_message() clobbers(A,X,Y) ; uses messageptr=r0
romsub $fed8 = console_put_image(uword pointer @R0, uword width @R1, uword height @R2) clobbers(A,X,Y)
romsub $fed5 = console_set_paging_message(uword msgptr @R0) clobbers(A,X,Y)
romsub $fed2 = kbdbuf_put(ubyte key @A) clobbers(A,X,Y)
romsub $fecf = entropy_get() -> ubyte @A, ubyte @X, ubyte @Y
romsub $fecc = monitor() clobbers(A,X,Y)

View File

@ -289,6 +289,22 @@ internal class AstChecker(private val program: Program,
regCounts[CpuRegister.Y]=regCounts.getValue(CpuRegister.Y)+1
}
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> { /* no sensible way to count this */ }
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> { /* no sensible way to count this */ }
null ->
if(p.statusflag!=null)
statusflagCounts[p.statusflag] = statusflagCounts.getValue(p.statusflag) + 1

View File

@ -4,7 +4,6 @@ import prog8.ast.IFunctionCall
import prog8.ast.INameScope
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.Expression
import prog8.ast.expressions.FunctionCall
import prog8.ast.statements.*

View File

@ -1145,10 +1145,10 @@ $counterVar .byte 0""")
"%asminclude" -> {
val sourcecode = loadAsmIncludeFile(stmt.args[0].str!!, stmt.definingModule().source)
val scopeprefix = stmt.args[1].str ?: ""
if(!scopeprefix.isBlank())
if(scopeprefix.isNotBlank())
out("$scopeprefix\t.proc")
assemblyLines.add(sourcecode.trimEnd().trimStart('\n'))
if(!scopeprefix.isBlank())
if(scopeprefix.isNotBlank())
out(" .pend\n")
}
"%asmbinary" -> {

View File

@ -117,8 +117,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
when(func.name) {
"memset" -> {
// use the ROM function of the Cx16
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope) // TODO register R0
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope) // TODO register R1
asmgen.assignExpressionToRegister(fcall.args[2], RegisterOrPair.A)
val sub = (fcall as FunctionCallStatement).definingSubroutine()!!
asmgen.saveRegister(CpuRegister.X, false, sub)
@ -136,9 +136,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
// use the ROM function of the Cx16
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[2], "cx16.r2", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope) // TODO register R0
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope) // TODO register R1
asmgen.assignExpressionToVariable(fcall.args[2], "cx16.r2", DataType.UWORD, scope) // TODO register R2
val sub = (fcall as FunctionCallStatement).definingSubroutine()!!
asmgen.saveRegister(CpuRegister.X, false, sub)
asmgen.out(" jsr cx16.memory_copy")

View File

@ -1366,6 +1366,22 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
RegisterOrPair.FAC1 -> asmgen.out(" jsr floats.push_fac1")
RegisterOrPair.FAC2 -> asmgen.out(" jsr floats.push_fac2")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register onto stack")
}
}
else if(reg.statusflag!=null) {

View File

@ -113,6 +113,15 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
argi.value.second.registerOrPair == RegisterOrPair.Y -> {
asmgen.out(" ldy P8ESTACK_LO+${argi.index},x")
}
argi.value.second.registerOrPair in setOf(RegisterOrPair.R0, RegisterOrPair.R1, RegisterOrPair.R2, RegisterOrPair.R3, RegisterOrPair.R4, RegisterOrPair.R5, RegisterOrPair.R6, RegisterOrPair.R7,
RegisterOrPair.R8, RegisterOrPair.R9, RegisterOrPair.R10, RegisterOrPair.R11, RegisterOrPair.R12, RegisterOrPair.R13, RegisterOrPair.R14, RegisterOrPair.R15) -> {
asmgen.out("""
lda P8ESTACK_LO+${argi.index},x
sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()}
lda P8ESTACK_HI+${argi.index},x
sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()}+1
""")
}
else -> throw AssemblyError("weird argument")
}
}

View File

@ -688,6 +688,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.Y -> asmgen.out(" inx | ldy P8ESTACK_LO,x")
RegisterOrPair.AX -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldx #0")
RegisterOrPair.AY -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy #0")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("assign stack byte to cx16 register")
else -> throw AssemblyError("can't assign byte from stack to register pair XY")
}
}
@ -696,6 +712,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}")
RegisterOrPair.AY-> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x")
RegisterOrPair.XY-> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("assign stack word to cx16 register")
else -> throw AssemblyError("can't assign word to single byte register")
}
}
@ -736,6 +768,29 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> asmgen.out(" lda #<$sourceName | ldx #>$sourceName")
RegisterOrPair.AY -> asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx #<$sourceName | ldy #>$sourceName")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> {
asmgen.out("""
lda #<$sourceName
sta cx16.${target.register.toString().toLowerCase()}
lda #>$sourceName
sta cx16.${target.register.toString().toLowerCase()}+1
""")
}
else -> throw AssemblyError("can't load address in a single 8-bit register")
}
}
@ -869,6 +924,29 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx $sourceName+1")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy $sourceName+1")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy $sourceName+1")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> {
asmgen.out("""
lda $sourceName
sta cx16.${target.register.toString().toLowerCase()}
lda $sourceName+1
sta cx16.${target.register.toString().toLowerCase()}+1
""")
}
else -> throw AssemblyError("can't load word in a single 8-bit register")
}
}
@ -1034,6 +1112,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign byte var")
}
}
TargetStorageKind.STACK -> {
@ -1190,6 +1284,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> { asmgen.out(" ldx #0") }
RegisterOrPair.XY -> { asmgen.out(" tax | ldy #0") }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign from register A")
}
CpuRegister.X -> when(target.register!!) {
RegisterOrPair.A -> { asmgen.out(" txa") }
@ -1199,6 +1309,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> { asmgen.out(" txa | ldx #0") }
RegisterOrPair.XY -> { asmgen.out(" ldy #0") }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign from register X")
}
CpuRegister.Y -> when(target.register!!) {
RegisterOrPair.A -> { asmgen.out(" tya") }
@ -1208,6 +1334,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AX -> { asmgen.out(" tya | ldx #0") }
RegisterOrPair.XY -> { asmgen.out(" tya | tax | ldy #0") }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign from register Y")
}
}
}
@ -1267,18 +1409,66 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AY -> { asmgen.out(" stx P8ZP_SCRATCH_REG | ldy P8ZP_SCRATCH_REG") }
RegisterOrPair.AX -> { }
RegisterOrPair.XY -> { asmgen.out(" stx P8ZP_SCRATCH_REG | ldy P8ZP_SCRATCH_REG | tax") }
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("assign reg.pair to cx16 register")
else -> throw AssemblyError("expected reg pair")
}
RegisterOrPair.AY -> when(target.register!!) {
RegisterOrPair.AY -> { }
RegisterOrPair.AX -> { asmgen.out(" sty P8ZP_SCRATCH_REG | ldx P8ZP_SCRATCH_REG") }
RegisterOrPair.XY -> { asmgen.out(" tax") }
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("assign reg.pair to cx16 register")
else -> throw AssemblyError("expected reg pair")
}
RegisterOrPair.XY -> when(target.register!!) {
RegisterOrPair.AY -> { asmgen.out(" txa") }
RegisterOrPair.AX -> { asmgen.out(" txa | sty P8ZP_SCRATCH_REG | ldx P8ZP_SCRATCH_REG") }
RegisterOrPair.XY -> { }
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("assign reg.pair to cx16 register")
else -> throw AssemblyError("expected reg pair")
}
else -> throw AssemblyError("expected reg pair")
@ -1382,6 +1572,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AY -> asmgen.out(" lda #${byte.toHex()} | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldx #${byte.toHex()} | ldy #0")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign constant byte")
}
TargetStorageKind.STACK -> {
asmgen.out("""
@ -1551,6 +1757,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AY -> asmgen.out(" lda ${address.toHex()} | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldy ${address.toHex()} | ldy #0")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign memory byte")
}
TargetStorageKind.STACK -> {
asmgen.out("""
@ -1582,6 +1804,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.AY -> asmgen.out(" ldy #0")
RegisterOrPair.XY -> asmgen.out(" tax | ldy #0")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
RegisterOrPair.R0,
RegisterOrPair.R1,
RegisterOrPair.R2,
RegisterOrPair.R3,
RegisterOrPair.R4,
RegisterOrPair.R5,
RegisterOrPair.R6,
RegisterOrPair.R7,
RegisterOrPair.R8,
RegisterOrPair.R9,
RegisterOrPair.R10,
RegisterOrPair.R11,
RegisterOrPair.R12,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> TODO("cx16 register assign memory byte")
}
}
TargetStorageKind.STACK -> {

View File

@ -18,8 +18,7 @@ main {
uword anglez
void cx16.screen_set_mode($80)
cx16.r0 = 0
cx16.GRAPH_init()
cx16.GRAPH_init(0)
cx16.GRAPH_set_colors(13, 6, 6)
cx16.GRAPH_clear()
print_ship_name()
@ -28,12 +27,7 @@ main {
rotate_vertices(msb(anglex), msb(angley), msb(anglez))
cx16.GRAPH_set_colors(0, 0, 0)
cx16.r0 = 32
cx16.r1 = 10
cx16.r2 = 256
cx16.r3 = 185
cx16.r4 = 0
cx16.GRAPH_draw_rect(true)
cx16.GRAPH_draw_rect(32, 10, 256, 185, 0, true)
cx16.GRAPH_set_colors(1, 0, 0)
draw_lines_hiddenremoval()
@ -52,20 +46,20 @@ main {
cx16.r1 = 8
ubyte c
for c in "ship: "
cx16.GRAPH_put_char(c)
cx16.GRAPH_put_next_char(c)
for c in shipdata.shipName
cx16.GRAPH_put_char(c)
cx16.GRAPH_put_next_char(c)
cx16.r0 += 16
print_number_gfx(shipdata.totalNumberOfPoints)
for c in " vertices, "
cx16.GRAPH_put_char(c)
cx16.GRAPH_put_next_char(c)
print_number_gfx(shipdata.totalNumberOfEdges)
for c in " edges, "
cx16.GRAPH_put_char(c)
cx16.GRAPH_put_next_char(c)
print_number_gfx(shipdata.totalNumberOfFaces)
for c in " faces"
cx16.GRAPH_put_char(c)
cx16.GRAPH_put_next_char(c)
}
asmsub print_number_gfx(ubyte num @ A) clobbers(A,Y) {
@ -136,11 +130,10 @@ main {
ubyte @zp vTo = shipdata.edgesTo[i]
word persp1 = 200 + rotatedz[vFrom]/256
word persp2 = 200 + rotatedz[vTo]/256
cx16.r0 = rotatedx[vFrom] / persp1 + screen_width/2 as uword
cx16.r1 = rotatedy[vFrom] / persp1 + screen_height/2 as uword
cx16.r2 = rotatedx[vTo] / persp2 + screen_width/2 as uword
cx16.r3 = rotatedy[vTo] / persp2 + screen_height/2 as uword
cx16.GRAPH_draw_line()
cx16.GRAPH_draw_line(rotatedx[vFrom] / persp1 + screen_width/2 as uword,
rotatedy[vFrom] / persp1 + screen_height/2 as uword,
rotatedx[vTo] / persp2 + screen_width/2 as uword,
rotatedy[vTo] / persp2 + screen_height/2 as uword)
}
}
@ -217,11 +210,10 @@ main {
ubyte vTo = shipdata.edgesTo[edgeidx]
word persp1 = 200 + rotatedz[vFrom]/256
word persp2 = 200 + rotatedz[vTo]/256
cx16.r0 = rotatedx[vFrom] / persp1 + screen_width/2 as uword
cx16.r1 = rotatedy[vFrom] / persp1 + screen_height/2 as uword
cx16.r2 = rotatedx[vTo] / persp2 + screen_width/2 as uword
cx16.r3 = rotatedy[vTo] / persp2 + screen_height/2 as uword
cx16.GRAPH_draw_line()
cx16.GRAPH_draw_line(rotatedx[vFrom] / persp1 + screen_width/2 as uword,
rotatedy[vFrom] / persp1 + screen_height/2 as uword,
rotatedx[vTo] / persp2 + screen_width/2 as uword,
rotatedy[vTo] / persp2 + screen_height/2 as uword)
}
}

View File

@ -8,11 +8,7 @@ main {
sub start() {
cx16.r0 = mkword(8, 2020 - 1900)
cx16.r1 = mkword(19, 27)
cx16.r2 = mkword(0, 16)
cx16.r3 = 0
cx16.clock_set_date_time()
cx16.clock_set_date_time(mkword(8, 2020 - 1900), mkword(19, 27), mkword(0, 16), 0)
txt.lowercase()
repeat {

View File

@ -110,10 +110,8 @@ bmp_module {
}
}
1 -> {
for x in 0 to width-1 step 8 {
cx16.r0 = c64.CHRIN()
cx16.FB_set_8_pixels_opaque(255, 255, 0)
}
for x in 0 to width-1 step 8
cx16.FB_set_8_pixels_opaque(255, 255, 0, c64.CHRIN())
}
}

View File

@ -8,6 +8,9 @@
%import bmp_module
;; %import ci_module
; TODO fix crash after first image (occurs since cx16 register support was added in compiler)
main {
sub start() {
; trick to check if we're running on sdcard or host system shared folder

View File

@ -44,9 +44,7 @@ koala_module {
cx16.r1 = cy as uword + d
cx16.FB_cursor_position()
get_8_pixels()
cx16.r0 = &pixels
cx16.r1 = 8
cx16.FB_set_pixels()
cx16.FB_set_pixels(pixels, 8)
}
}
cy_times_forty += 40

View File

@ -106,17 +106,13 @@ bitmap {
b &= %00111111
ubyte dat = c64.CHRIN()
repeat b {
if y_ok {
cx16.r0 = dat
cx16.FB_set_8_pixels_opaque(255, 255, 0)
}
if y_ok
cx16.FB_set_8_pixels_opaque(255, 255, 0, dat)
px += 8
}
} else {
if y_ok {
cx16.r0 = b
cx16.FB_set_8_pixels_opaque(255, 255, 0)
}
if y_ok
cx16.FB_set_8_pixels_opaque(255, 255, 0, b)
px += 8
}
if px==width

View File

@ -29,9 +29,7 @@ main {
for pixely in 0 to height-1 {
float yy = YL+dy*(pixely as float)
cx16.r0 = 0
cx16.r1 = pixely
cx16.FB_cursor_position()
cx16.FB_cursor_position(0, pixely)
for pixelx in 0 to width-1 {
float xx = XL+dx*(pixelx as float)
@ -71,18 +69,14 @@ main {
txt.print_b(max_iter)
txt.print(" iter")
cx16.r0 = 0
cx16.r1 = 0
cx16.r2 = 0
cx16.r3 = 0
cx16.clock_set_date_time()
cx16.clock_set_date_time(0, 0, 0, 0)
cx16.r0=0
cx16.FB_init()
}
sub print_time() {
cx16.clock_get_date_time()
void cx16.clock_get_date_time()
txt.plot(33, 12)
if lsb(cx16.r2) < 10
c64.CHROUT('0')