mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
adding CommanderX16 virtual registers language support, rewrite cx16 examples
This commit is contained in:
parent
daaa83ee7d
commit
dcb81e6bea
@ -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'
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.*
|
||||
|
@ -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" -> {
|
||||
|
@ -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")
|
||||
|
@ -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) {
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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 -> {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
Loading…
x
Reference in New Issue
Block a user