diff --git a/compiler/examples/cube3d-c64.p8 b/compiler/examples/cube3d-c64.p8 index 31783e11d..6c4f442ff 100644 --- a/compiler/examples/cube3d-c64.p8 +++ b/compiler/examples/cube3d-c64.p8 @@ -1,4 +1,5 @@ %import c64utils +%import c64flt ~ main { @@ -6,104 +7,89 @@ const uword height = 25 ; vertices - byte[8] xcoor = [ -100, -100, -100, -100, 100, 100, 100, 100 ] - byte[8] ycoor = [ -100, -100, 100, 100, -100, -100, 100, 100 ] - byte[8] zcoor = [ -100, 100, -100, 100, -100, 100, -100, 100 ] + byte[8] xcoor = [ -50, -50, -50, -50, 50, 50, 50, 50 ] + byte[8] ycoor = [ -50, -50, 50, 50, -50, -50, 50, 50 ] + byte[8] zcoor = [ -50, 50, -50, 50, -50, 50, -50, 50 ] ; storage for rotated coordinates - word[len(xcoor)] rotatedx=0 - word[len(ycoor)] rotatedy=0 - word[len(zcoor)] rotatedz=-32767 + float[len(xcoor)] rotatedx=0.0 + float[len(ycoor)] rotatedy=0.0 + float[len(zcoor)] rotatedz=-1.0 sub start() { uword anglex uword angley uword anglez while(true) { - rotate_vertices(anglex, angley, anglez) - ; c64.CLEARSCR() - ; draw_edges() - anglex+=256 - angley+=83 - anglez+=201 + rotate_vertices(msb(anglex), msb(angley), msb(anglez)) + c64.CLEARSCR() + draw_edges() + anglex+=1000 + angley+=333 + anglez+=807 } } - sub rotate_vertices(uword ax, uword ay, uword az) { + sub rotate_vertices(ubyte ax, ubyte ay, ubyte az) { ; rotate around origin (0,0,0) ; set up the 3d rotation matrix values - word cosa = cos8(msb(ax)) as word - word sina = sin8(msb(ax)) as word - word cosb = cos8(msb(ay)) as word - word sinb = sin8(msb(ay)) as word - word cosc = cos8(msb(az)) as word - word sinc = sin8(msb(az)) as word + float cosa = cos8(ax) as float / 128.0 + float sina = sin8(ax) as float / 128.0 + float cosb = cos8(ay) as float / 128.0 + float sinb = sin8(ay) as float / 128.0 + float cosc = cos8(az) as float / 128.0 + float sinc = sin8(az) as float / 128.0 - word cosa_sinb = msb(cosa*sinb) - word sina_sinb = msb(sina*sinb) - - c64.CHROUT('>') - c64scr.print_w(cosa_sinb) - c64.CHROUT(',') - c64scr.print_w(sina_sinb) - c64.CHROUT('\n') - - word Axx = msb(cosa*cosb) - word Axy = msb(cosa_sinb*sinc - sina*cosc) - word Axz = msb(cosa_sinb*cosc + sina*sinc) - word Ayx = msb(sina*cosb) - word Ayy = msb(sina_sinb*sinc + cosa*cosc) - word Ayz = msb(sina_sinb*cosc - cosa*sinc) - word Azx = -sinb - word Azy = msb(cosb*sinc) - word Azz = msb(cosb*cosc) - - c64.CHROUT('>') - c64scr.print_w(Axx) - c64.CHROUT(',') - c64scr.print_w(Axy) - c64.CHROUT(',') - c64scr.print_w(Axz) - c64.CHROUT('\n') + 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 { - word xc = xcoor[i] - word yc = ycoor[i] - word zc = zcoor[i] - rotatedx[i] = Axx*xc ;+ Axy*yc + Axz*zc ; @todo wrong code generated? crash! - rotatedy[i] = Ayx*xc ;+ Ayy*yc + Ayz*zc ; @todo wrong code generated? crash! - rotatedz[i] = Azx*xc ;+ Azy*yc + Azz*zc ; @todo wrong code generated? crash! + float xc = xcoor[i] as float + float yc = ycoor[i] as float + float zc = zcoor[i] as float + rotatedx[i] = Axx*xc + Axy*yc + Axz*zc + rotatedy[i] = Ayx*xc + Ayy*yc + Ayz*zc + rotatedz[i] = Azx*xc + Azy*yc + Azz*zc } } sub draw_edges() { - sub toscreenx(word x, word z) -> ubyte { - return msb(x) and 31 + sub toscreenx(float x, float z) -> byte { + return x/(250.0+z) * (height as float) as byte + width // 2 } - sub toscreeny(word y, word z) -> ubyte { - return msb(y) and 15 + sub toscreeny(float y, float z) -> byte { + return y/(250.0+z) * (height as float) as byte + height // 2 } ; plot the points of the 3d cube ; first the points on the back, then the points on the front (painter algorithm) for ubyte i in 0 to len(xcoor)-1 { - word rz = rotatedz[i] - if rz >= 100 { - ubyte sx = toscreenx(rotatedx[i], rz) - ubyte sy = toscreeny(rotatedy[i], rz) + float rz = rotatedz[i] + if rz >= 0.1 { + ubyte sx = toscreenx(rotatedx[i], rz) as ubyte + ubyte sy = toscreeny(rotatedy[i], rz) as ubyte c64scr.setchrclr(sx, sy, 46, i+2) } } for ubyte i in 0 to len(xcoor)-1 { - word rz = rotatedz[i] - if rz < 100 { - ubyte sx = toscreenx(rotatedx[i], rz) - ubyte sy = toscreeny(rotatedy[i], rz) + float rz = rotatedz[i] + if rz < 0.1 { + ubyte sx = toscreenx(rotatedx[i], rz) as ubyte + ubyte sy = toscreeny(rotatedy[i], rz) as ubyte c64scr.setchrclr(sx, sy, 81, i+2) } } diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 27caadf28..9e9191de1 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -2,44 +2,15 @@ ~ main { - sub start() { - memory byte b1 = $c000 - memory byte b2 = $c001 - memory word w1 = $c002 - memory word w2 = $c004 - - float x =4.34 - ubyte xx= x as ubyte - float y = x * 5.55 - y =xx as float - - b1=50 - b2=-50 - w1=100 - w2=-100 - - c64scr.print_b(b1) - c64.CHROUT('/') - lsr(b1) - c64scr.print_b(b1) - c64.CHROUT('\n') - c64scr.print_b(b2) - c64.CHROUT('/') - lsr(b2) - c64scr.print_b(b2) - c64.CHROUT('\n') - c64scr.print_w(w1) - c64.CHROUT('/') - lsr(w1) - c64scr.print_w(w1) - c64.CHROUT('\n') - c64scr.print_w(w2) - c64.CHROUT('/') - lsr(w2) - c64scr.print_w(w2) - c64.CHROUT('\n') - - + word[1] rotatedx + sub start() { + word xc = 2 +rpt: + word w = 2*xc + rotatedx[0] = w ; @ok! + rotatedx[0] = 2*xc ; @todo wrong code generated? crash! + c64.CHROUT('.') + goto rpt } } diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 3a1dcd389..457c02f0a 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -564,7 +564,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Opcode.WRITE_INDEXED_VAR_WORD -> { """ inx - inx lda ${ESTACK_LO.toHex()},x asl a tay diff --git a/prog8lib/prog8lib.p8 b/prog8lib/prog8lib.p8 index 0d8042cd2..d97345f6b 100644 --- a/prog8lib/prog8lib.p8 +++ b/prog8lib/prog8lib.p8 @@ -1006,7 +1006,7 @@ mult16 lda #$00 sta multiply_words_result+2 ; clear upper bits of product sta multiply_words_result+3 ldx #16 ; for all 16 bits... -- lsr c64.SCRATCH_ZPWORD1+1 ; divide multiplier by 2 +- lsr c64.SCRATCH_ZPWORD1+1 ; divide multiplier by 2 ror c64.SCRATCH_ZPWORD1 bcc + lda multiply_words_result+2 ; get upper half of product and add multiplicand