fix asm stack bug

This commit is contained in:
Irmen de Jong 2019-01-05 18:02:17 +01:00
parent 9f4ac37a00
commit 4f213191dc
4 changed files with 59 additions and 103 deletions

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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