diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index 7b32d11b0..859e833b8 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -517,18 +517,13 @@ internal class AsmGen2(val program: Program, private fun readAndPushArrayvalueWithIndexA(arrayDt: DataType, variable: IdentifierReference) { val variablename = asmIdentifierName(variable) - when (ArrayElementTypes.getValue(arrayDt).memorySize()) { - 1 -> {} - 2 -> out(" asl a") - 5 -> out(" sta ${C64Zeropage.SCRATCH_REG} | asl a | asl a | clc | adc ${C64Zeropage.SCRATCH_REG}") - else -> throw AssemblyError("invalid memory size") - } when (arrayDt) { DataType.STR, DataType.STR_S, DataType.ARRAY_UB, DataType.ARRAY_B -> out(" tay | lda $variablename,y | sta $ESTACK_LO_HEX,x | dex") DataType.ARRAY_UW, DataType.ARRAY_W -> - out(" tay | lda $variablename,y | sta $ESTACK_LO_HEX,x | lda $variablename+1,y | sta $ESTACK_HI_HEX,x | dex") + out(" asl a | tay | lda $variablename,y | sta $ESTACK_LO_HEX,x | lda $variablename+1,y | sta $ESTACK_HI_HEX,x | dex") DataType.ARRAY_F -> + // index * 5 is done in the subroutine that's called out(""" sta $ESTACK_LO_HEX,x dex @@ -541,6 +536,26 @@ internal class AsmGen2(val program: Program, } } + private fun popAndWriteArrayvalueWithIndexA(arrayDt: DataType, variablename: String) { + when (arrayDt) { + DataType.STR, DataType.STR_S, DataType.ARRAY_UB, DataType.ARRAY_B -> + out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $variablename,y") + DataType.ARRAY_UW, DataType.ARRAY_W -> + out(" asl a | tay | inx | lda $ESTACK_LO_HEX,x | sta $variablename,y | lda $ESTACK_HI_HEX,x | sta $variablename+1,y") + DataType.ARRAY_F -> + // index * 5 is done in the subroutine that's called + out(""" + sta $ESTACK_LO_HEX,x + dex + lda #<$variablename + ldy #>$variablename + jsr c64flt.pop_float_to_indexed_var + """) + else -> + throw AssemblyError("weird array type") + } + } + private fun saveRegister(register: Register) { when(register) { Register.A -> out(" pha") @@ -1087,8 +1102,8 @@ $endLabel""") TODO("non-const forloop with step -1") } else -> when (iterableDt) { - DataType.ARRAY_UB, DataType.ARRAY_B -> TODO() - DataType.ARRAY_UW, DataType.ARRAY_W -> TODO() + DataType.ARRAY_UB, DataType.ARRAY_B -> TODO("non-const forloop bytes") + DataType.ARRAY_UW, DataType.ARRAY_W -> TODO("non-const forloop words") else -> throw AssemblyError("range expression can only be byte or word") } } @@ -2080,13 +2095,10 @@ $endLabel""") } } - // TODO: use optimized routines such as mul_10 - - private fun translateBinaryOperatorBytes(operator: String, types: DataType) { when(operator) { "**" -> throw AssemblyError("** operator requires floats") - "*" -> out(" jsr prog8_lib.mul_byte") + "*" -> out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier "/" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b") "%" -> { if(types==DataType.BYTE) @@ -2278,7 +2290,11 @@ $endLabel""") targetArrayIdx!=null -> { val index = targetArrayIdx.arrayspec.index val targetName = asmIdentifierName(targetArrayIdx.identifier) - TODO("assign wordvar $sourceName to array $targetName [ $index ]") + val arrayDt = targetArrayIdx.identifier.inferType(program)!! + out(" lda $sourceName | sta $ESTACK_LO_HEX,x | lda $sourceName+1 | sta $ESTACK_HI_HEX,x | dex") + translateExpression(index) + out(" inx | lda $ESTACK_LO_HEX,x") + popAndWriteArrayvalueWithIndexA(arrayDt, targetName) } else -> TODO("assign wordvar to $target") } @@ -2307,7 +2323,9 @@ $endLabel""") targetArrayIdx!=null -> { val index = targetArrayIdx.arrayspec.index val targetName = asmIdentifierName(targetArrayIdx.identifier) - TODO("assign floatvar $sourceName to array $targetName [ $index ]") + out(" lda #<$sourceName | ldy #>$sourceName | jsr c64flt.push_float") + translateExpression(index) + out(" lda #<$targetName | ldy #>$targetName | jsr c64flt.pop_float_to_indexed_var") } else -> TODO("assign floatvar to $target") } @@ -2331,7 +2349,11 @@ $endLabel""") targetArrayIdx!=null -> { val index = targetArrayIdx.arrayspec.index val targetName = asmIdentifierName(targetArrayIdx.identifier) - TODO("assign bytevar to array $targetName [ $index ] ") + val arrayDt = targetArrayIdx.identifier.inferType(program)!! + out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex") + translateExpression(index) + out(" inx | lda $ESTACK_LO_HEX,x") + popAndWriteArrayvalueWithIndexA(arrayDt, targetName) } target.memoryAddress != null -> { val addressExpr = target.memoryAddress.addressExpression @@ -2518,7 +2540,9 @@ $endLabel""") translateExpression(index) out(""" inx - ldy $ESTACK_LO_HEX,x + lda $ESTACK_LO_HEX,x + asl a + tay lda #<${word.toHex()} sta $targetName,y lda #>${word.toHex()} @@ -2674,31 +2698,6 @@ $endLabel""") } } - private fun popAndWriteArrayvalueWithIndexA(arrayDt: DataType, variablename: String) { - when (ArrayElementTypes.getValue(arrayDt).memorySize()) { - 1 -> {} - 2 -> out(" asl a") - 5 -> out(" sta ${C64Zeropage.SCRATCH_REG} | asl a | asl a | clc | adc ${C64Zeropage.SCRATCH_REG}") - else -> throw AssemblyError("invalid memory size") - } - when (arrayDt) { - DataType.STR, DataType.STR_S, DataType.ARRAY_UB, DataType.ARRAY_B -> - out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $variablename,y") - DataType.ARRAY_UW, DataType.ARRAY_W -> - out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $variablename,y | lda $ESTACK_HI_HEX,x | sta $variablename+1,y") - DataType.ARRAY_F -> - out(""" - sta $ESTACK_LO_HEX,x - dex - lda #<$variablename - ldy #>$variablename - jsr c64flt.pop_float_to_indexed_var - """) - else -> - throw AssemblyError("weird array type") - } - } - private fun assignFromMemoryByte(target: AssignTarget, address: Int?, identifier: IdentifierReference?) { val targetIdent = target.identifier val targetArrayIdx = target.arrayindexed diff --git a/examples/cube3d-stackvm.p8 b/examples/cube3d-stackvm.p8 deleted file mode 100644 index 52dfceef7..000000000 --- a/examples/cube3d-stackvm.p8 +++ /dev/null @@ -1,122 +0,0 @@ -%output raw -%launcher none -%import c64flt - -irq { - uword global_time - ubyte time_changed - - sub irq() { - ; activated automatically if run in StackVm - global_time++ - time_changed = 1 - } -} - - -main { - - const uword width = 320 - const uword height = 200 - - ; vertices - float[] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ] - float[] ycoor = [ -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0 ] - float[] zcoor = [ -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ] - - ; edges (msb=from vertex, lsb=to vertex) - uword[] edges = [$0001, $0103, $0302, $0200, $0405, $0507, $0706, $0604, $0004, $0105, $0206, $0307] - - ; storage for rotated coordinates - float[len(xcoor)] rotatedx - float[len(ycoor)] rotatedy - float[len(zcoor)] rotatedz - - sub start() { - while true { - if irq.time_changed { - irq.time_changed = 0 - vm_gfx_clearscr(0) - vm_gfx_text(8, 6, 1, "Spin") - vm_gfx_text(29, 11, 1, "to Win !") - - for uword i in 0 to width/10 { - vm_gfx_line(i*2+width/2-width/10, 130, i*10.w, 199, 6) - } - - rotate_vertices(irq.global_time as float / 30.0) - draw_edges() - } - } - } - - sub rotate_vertices(float t) { - ; rotate around origin (0,0,0) - - ; set up the 3d rotation matrix values - float cosa = cos(t) - float sina = sin(t) - float cosb = cos(t*0.33) - float sinb = sin(t*0.33) - float cosc = cos(t*0.78) - float sinc = sin(t*0.78) - - float cosa_sinb = cosa*sinb - float sina_sinb = sina*sinb - float Axx = cosa*cosb - float Axy = cosa_sinb*sinc - sina*cosc - float Axz = cosa_sinb*cosc + sina*sinc - float Ayx = sina*cosb - float Ayy = sina_sinb*sinc + cosa*cosc - float Ayz = sina_sinb*cosc - cosa*sinc - float Azx = -sinb - float Azy = cosb*sinc - float Azz = cosb*cosc - - for ubyte i in 0 to len(xcoor)-1 { - rotatedx[i] = Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i] - rotatedy[i] = Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i] - rotatedz[i] = Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i] - } - } - - - sub draw_edges() { - - sub toscreenx(float x, float z) -> word { - return x/(4.2+z) * (height as float) as word + width / 2 - } - - sub toscreeny(float y, float z) -> word { - return y/(4.2+z) * (height as float) as word + height / 2 - } - - ; draw all edges of the object - for uword edge in edges { - ubyte e_from = msb(edge) - ubyte e_to = lsb(edge) - vm_gfx_line(toscreenx(rotatedx[e_from], rotatedz[e_from]), toscreeny(rotatedy[e_from], rotatedz[e_from]), - toscreenx(rotatedx[e_to], rotatedz[e_to]), toscreeny(rotatedy[e_to], rotatedz[e_to]), e_from+e_to) - } - - ; accentuate the vertices a bit with small boxes - for ubyte i in 0 to len(xcoor)-1 { - word sx = toscreenx(rotatedx[i], rotatedz[i]) - word sy = toscreeny(rotatedy[i], rotatedz[i]) - ubyte color=i+2 - vm_gfx_pixel(sx-1, sy-1, color) - vm_gfx_pixel(sx, sy-1, color) - vm_gfx_pixel(sx+1, sy-1, color) - vm_gfx_pixel(sx-1, sy, color) - vm_gfx_pixel(sx, sy, color) - vm_gfx_pixel(sx+1, sy, color) - vm_gfx_pixel(sx-1, sy+1, color) - vm_gfx_pixel(sx, sy+1, color) - vm_gfx_pixel(sx+1, sy+1, color) - vm_gfx_pixel(sx, sy-2, color) - vm_gfx_pixel(sx+2, sy, color) - vm_gfx_pixel(sx, sy+2, color) - vm_gfx_pixel(sx-2, sy, color) - } - } -} diff --git a/examples/mandelbrot-stackvm.p8 b/examples/mandelbrot-stackvm.p8 deleted file mode 100644 index 8dc1c283e..000000000 --- a/examples/mandelbrot-stackvm.p8 +++ /dev/null @@ -1,40 +0,0 @@ -%output raw -%launcher none -%import c64flt - -main { - const uword width = 320 / 2 - const uword height = 256 / 2 - const uword xoffset = 40 - const uword yoffset = 30 - - sub start() { - vm_gfx_clearscr(11) - vm_gfx_text(2, 1, 1, "Calculating Mandelbrot Fractal...") - - for ubyte pixely in yoffset to yoffset+height-1 { - float yy = (pixely-yoffset as float)/3.6/height+0.4 - - for uword pixelx in xoffset to xoffset+width-1 { - float xx = (pixelx-xoffset as float)/3.0/width+0.2 - - float xsquared = 0.0 - float ysquared = 0.0 - float x = 0.0 - float y = 0.0 - ubyte iter = 0 - - while (iter<32 and xsquared+ysquared<4.0) { - y = x*y*2.0 + yy - x = xsquared - ysquared + xx - xsquared = x*x - ysquared = y*y - iter++ - } - - vm_gfx_pixel(pixelx, pixely, iter) - } - } - vm_gfx_text(11, 21, 1, "Finished!") - } -} diff --git a/examples/swirl-stackvm.p8 b/examples/swirl-stackvm.p8 deleted file mode 100644 index c2923ef5e..000000000 --- a/examples/swirl-stackvm.p8 +++ /dev/null @@ -1,32 +0,0 @@ -%output raw -%launcher none -%import c64flt - -main { - - const uword width = 320 - const uword height = 200 - - sub start() { - - vm_gfx_clearscr(0) - - float t - ubyte color - - while true { - float x = sin(t*1.01) + cos(t*1.1234) - float y = cos(t) + sin(t*0.03456) - vm_gfx_pixel(screenx(x), screeny(y), color/16) - t += 0.01 - color++ - } - } - - sub screenx(float x) -> word { - return (x*width/4.1) + width / 2.0 as word - } - sub screeny(float y) -> word { - return (y*height/4.1) + height / 2.0 as word - } -} diff --git a/examples/test.p8 b/examples/test.p8 index 326933643..faa00d46d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,50 +8,36 @@ main { sub start() { - ubyte ub1 = 123 - ubyte ub2 = 222 - uword uw = 1111 - uword uw2 = 2222 - word[] warr = [1111, 2222] - float[] farr = [1.111, 2.222] + word[] warr = [1111, 2222, 3333, 4444] + byte[] barr = [11, 22, 33, 44] - c64scr.print_ub(ub1) - c64.CHROUT(',') - c64scr.print_ub(ub2) - c64.CHROUT('\n') - c64scr.print_uw(uw) - c64.CHROUT(',') - c64scr.print_uw(uw2) - c64.CHROUT('\n') - c64scr.print_w(warr[0]) - c64.CHROUT(',') - c64scr.print_w(warr[1]) - c64.CHROUT('\n') - c64flt.print_f(farr[0]) - c64.CHROUT(',') - c64flt.print_f(farr[1]) + word ww = 9999 + byte bb = 99 + + c64scr.print_b(barr[2]) c64.CHROUT('\n') - swap(ub1, ub2) - swap(uw,uw2) - swap(warr[0], warr[1]) - swap(farr[0], farr[1]) ; TODO CRASHES + barr[2] = 55 + c64scr.print_b(barr[2]) + c64.CHROUT('\n') - c64scr.print_ub(ub1) - c64.CHROUT(',') - c64scr.print_ub(ub2) + barr[2] = bb + c64scr.print_b(barr[2]) c64.CHROUT('\n') - c64scr.print_uw(uw) - c64.CHROUT(',') - c64scr.print_uw(uw2) + + @($0400+72) = X + + c64scr.print_w(warr[2]) c64.CHROUT('\n') - c64scr.print_w(warr[0]) - c64.CHROUT(',') - c64scr.print_w(warr[1]) + + warr[2] = 5555 + c64scr.print_w(warr[2]) c64.CHROUT('\n') - c64flt.print_f(farr[0]) - c64.CHROUT(',') - c64flt.print_f(farr[1]) + + warr[2] = ww + c64scr.print_w(warr[2]) c64.CHROUT('\n') + + @($0400+73) = X } }