diff --git a/compiler/build.gradle b/compiler/build.gradle index fb95dbe7e..5e1834491 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -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' diff --git a/compiler/res/prog8lib/cx16/graphics.p8 b/compiler/res/prog8lib/cx16/graphics.p8 index 05f72e037..ded477762 100644 --- a/compiler/res/prog8lib/cx16/graphics.p8 +++ b/compiler/res/prog8lib/cx16/graphics.p8 @@ -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) { diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 3a0984b14..e55bb0404 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -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) diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 938d50053..18e8ca627 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -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 diff --git a/compiler/src/prog8/ast/processing/VerifyFunctionArgTypes.kt b/compiler/src/prog8/ast/processing/VerifyFunctionArgTypes.kt index 6726c23de..db1a168dc 100644 --- a/compiler/src/prog8/ast/processing/VerifyFunctionArgTypes.kt +++ b/compiler/src/prog8/ast/processing/VerifyFunctionArgTypes.kt @@ -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.* diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 960633b88..5c97ff565 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -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" -> { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 5a1e8c08f..c03f2b270 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -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") diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 7a8eef332..971831496 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -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) { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 74879df44..78212e7f2 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -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") } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index ac6763d8f..aff71241e 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -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 -> { diff --git a/examples/cx16/cobramk3-gfx.p8 b/examples/cx16/cobramk3-gfx.p8 index c0442ac41..a20856d42 100644 --- a/examples/cx16/cobramk3-gfx.p8 +++ b/examples/cx16/cobramk3-gfx.p8 @@ -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) } } diff --git a/examples/cx16/datetime.p8 b/examples/cx16/datetime.p8 index ef81fc0ea..fa89dc9df 100644 --- a/examples/cx16/datetime.p8 +++ b/examples/cx16/datetime.p8 @@ -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 { diff --git a/examples/cx16/imageviewer/bmp_module.p8 b/examples/cx16/imageviewer/bmp_module.p8 index 1e6d3198f..a76310252 100644 --- a/examples/cx16/imageviewer/bmp_module.p8 +++ b/examples/cx16/imageviewer/bmp_module.p8 @@ -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()) } } diff --git a/examples/cx16/imageviewer/imageviewer.p8 b/examples/cx16/imageviewer/imageviewer.p8 index 027bd5472..a45cf2475 100644 --- a/examples/cx16/imageviewer/imageviewer.p8 +++ b/examples/cx16/imageviewer/imageviewer.p8 @@ -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 diff --git a/examples/cx16/imageviewer/koala_module.p8 b/examples/cx16/imageviewer/koala_module.p8 index 977ec2585..1ba1645cf 100644 --- a/examples/cx16/imageviewer/koala_module.p8 +++ b/examples/cx16/imageviewer/koala_module.p8 @@ -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 diff --git a/examples/cx16/imageviewer/pcx_module.p8 b/examples/cx16/imageviewer/pcx_module.p8 index 509306d54..05926e5d1 100644 --- a/examples/cx16/imageviewer/pcx_module.p8 +++ b/examples/cx16/imageviewer/pcx_module.p8 @@ -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 diff --git a/examples/cx16/mandelbrot-gfx-colors.p8 b/examples/cx16/mandelbrot-gfx-colors.p8 index c2d1d48f5..844faaef5 100644 --- a/examples/cx16/mandelbrot-gfx-colors.p8 +++ b/examples/cx16/mandelbrot-gfx-colors.p8 @@ -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')