mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01:29:55 +00:00
sine table and bit shifting of signed values fixed
This commit is contained in:
parent
32d82e8e56
commit
39a8508daa
93
compiler/examples/cube3d-c64-float.p8
Normal file
93
compiler/examples/cube3d-c64-float.p8
Normal file
@ -0,0 +1,93 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
const uword width = 40
|
||||
const uword height = 25
|
||||
|
||||
; vertices
|
||||
float[8] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
|
||||
float[8] ycoor = [ -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0 ]
|
||||
float[8] zcoor = [ -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ]
|
||||
|
||||
; storage for rotated coordinates
|
||||
float[len(xcoor)] rotatedx=0.0
|
||||
float[len(ycoor)] rotatedy=0.0
|
||||
float[len(zcoor)] rotatedz=-1.0
|
||||
|
||||
sub start() {
|
||||
float time=0.0
|
||||
while(true) {
|
||||
rotate_vertices(time)
|
||||
c64.CLEARSCR()
|
||||
draw_edges()
|
||||
time+=0.2
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
float xc = xcoor[i]
|
||||
float yc = ycoor[i]
|
||||
float zc = zcoor[i]
|
||||
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(float x, float z) -> byte {
|
||||
return x/(5.0+z) * (height as float) as byte + width // 2
|
||||
}
|
||||
|
||||
sub toscreeny(float y, float z) -> byte {
|
||||
return y/(5.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 {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
%option enable_floats ; @todo needed for now to avoid compile error in c64lib
|
||||
|
||||
~ main {
|
||||
|
||||
@ -7,85 +7,104 @@
|
||||
const uword height = 25
|
||||
|
||||
; vertices
|
||||
float[8] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
|
||||
float[8] ycoor = [ -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0 ]
|
||||
float[8] zcoor = [ -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ]
|
||||
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 ]
|
||||
|
||||
; storage for rotated coordinates
|
||||
float[len(xcoor)] rotatedx=0.0
|
||||
float[len(ycoor)] rotatedy=0.0
|
||||
float[len(zcoor)] rotatedz=-1.0
|
||||
word[len(xcoor)] rotatedx=0
|
||||
word[len(ycoor)] rotatedy=0
|
||||
word[len(zcoor)] rotatedz=-32767
|
||||
|
||||
sub start() {
|
||||
float time=0.0
|
||||
uword anglex
|
||||
uword angley
|
||||
uword anglez
|
||||
while(true) {
|
||||
rotate_vertices(time)
|
||||
c64.CLEARSCR()
|
||||
draw_edges()
|
||||
time+=0.2
|
||||
rotate_vertices(anglex, angley, anglez)
|
||||
; c64.CLEARSCR()
|
||||
; draw_edges()
|
||||
anglex+=256
|
||||
angley+=83
|
||||
anglez+=201
|
||||
}
|
||||
}
|
||||
|
||||
sub rotate_vertices(float t) {
|
||||
sub rotate_vertices(uword ax, uword ay, uword az) {
|
||||
; 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)
|
||||
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_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
|
||||
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')
|
||||
|
||||
for ubyte i in 0 to len(xcoor)-1 {
|
||||
float xc = xcoor[i]
|
||||
float yc = ycoor[i]
|
||||
float zc = zcoor[i]
|
||||
rotatedx[i] = Axx*xc + Axy*yc + Axz*zc
|
||||
rotatedy[i] = Ayx*xc + Ayy*yc + Ayz*zc
|
||||
rotatedz[i] = Azx*xc + Azy*yc + Azz*zc
|
||||
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!
|
||||
}
|
||||
}
|
||||
|
||||
sub draw_edges() {
|
||||
|
||||
sub toscreenx(float x, float z) -> byte {
|
||||
return x/(5.0+z) * (height as float) as byte + width // 2
|
||||
sub toscreenx(word x, word z) -> ubyte {
|
||||
return msb(x) and 31
|
||||
}
|
||||
|
||||
sub toscreeny(float y, float z) -> byte {
|
||||
return y/(5.0+z) * (height as float) as byte + height // 2
|
||||
sub toscreeny(word y, word z) -> ubyte {
|
||||
return msb(y) and 15
|
||||
}
|
||||
|
||||
; 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 {
|
||||
float rz = rotatedz[i]
|
||||
if rz >= 0.1 {
|
||||
ubyte sx = toscreenx(rotatedx[i], rz) as ubyte
|
||||
ubyte sy = toscreeny(rotatedy[i], rz) as ubyte
|
||||
word rz = rotatedz[i]
|
||||
if rz >= 100 {
|
||||
ubyte sx = toscreenx(rotatedx[i], rz)
|
||||
ubyte sy = toscreeny(rotatedy[i], rz)
|
||||
c64scr.setchrclr(sx, sy, 46, i+2)
|
||||
}
|
||||
}
|
||||
|
||||
for ubyte i in 0 to len(xcoor)-1 {
|
||||
float rz = rotatedz[i]
|
||||
if rz < 0.1 {
|
||||
ubyte sx = toscreenx(rotatedx[i], rz) as ubyte
|
||||
ubyte sy = toscreeny(rotatedy[i], rz) as ubyte
|
||||
word rz = rotatedz[i]
|
||||
if rz < 100 {
|
||||
ubyte sx = toscreenx(rotatedx[i], rz)
|
||||
ubyte sy = toscreeny(rotatedy[i], rz)
|
||||
c64scr.setchrclr(sx, sy, 81, i+2)
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
||||
c64.STROUT("balloon sprites!\n")
|
||||
c64.STROUT("...we are all floating...\n")
|
||||
|
||||
const uword sprite_address_ptr = &balloonsprite // 64
|
||||
const uword sprite_address_ptr = $0a00 // 64
|
||||
c64.SPRPTR0 = sprite_address_ptr
|
||||
c64.SPRPTR1 = sprite_address_ptr
|
||||
c64.SPRPTR2 = sprite_address_ptr
|
||||
|
36
compiler/examples/swirl-c64-float.p8
Normal file
36
compiler/examples/swirl-c64-float.p8
Normal file
@ -0,0 +1,36 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
const uword width = 40
|
||||
const uword height = 25
|
||||
|
||||
sub start() {
|
||||
|
||||
float t
|
||||
ubyte color
|
||||
|
||||
while true {
|
||||
float x = sin(t)
|
||||
float y = cos(t*1.1356)
|
||||
ubyte xx=screenx(x)
|
||||
ubyte yy=screeny(y)
|
||||
|
||||
;c64.COLOR = color
|
||||
;c64scr.PLOT(xx,yy)
|
||||
;c64.CHROUT('Q') ; shift-q = filled circle
|
||||
c64scr.setchrclr(xx, yy, 81, color)
|
||||
|
||||
t += 0.08
|
||||
color++
|
||||
}
|
||||
}
|
||||
|
||||
sub screenx(float x) -> ubyte {
|
||||
return (x * width/2.2) + width/2.0 as ubyte
|
||||
}
|
||||
sub screeny(float y) -> ubyte {
|
||||
return (y * height/2.2) + height/2.0 as ubyte
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
%option enable_floats ; @todo needed for now to avoid compile error in c64lib
|
||||
|
||||
~ main {
|
||||
|
||||
@ -8,29 +8,20 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
float t
|
||||
uword anglex
|
||||
uword angley
|
||||
ubyte color
|
||||
|
||||
while true {
|
||||
float x = sin(t)
|
||||
float y = cos(t*1.1356)
|
||||
ubyte xx=screenx(x)
|
||||
ubyte yy=screeny(y)
|
||||
|
||||
;c64.COLOR = color
|
||||
;c64scr.PLOT(xx,yy)
|
||||
;c64.CHROUT('Q') ; shift-q = filled circle
|
||||
word x = sin8(msb(anglex)) as word
|
||||
word y = cos8(msb(angley)) as word
|
||||
ubyte xx=msb(x*39) + 20 ; -127..127 -> 0..39
|
||||
ubyte yy=msb(y*24) + 12 ; -127..127 -> 0..24
|
||||
c64scr.setchrclr(xx, yy, 81, color)
|
||||
|
||||
t += 0.08
|
||||
anglex+=800
|
||||
angley+=947
|
||||
color++
|
||||
}
|
||||
}
|
||||
|
||||
sub screenx(float x) -> ubyte {
|
||||
return (x * width/2.2) + width/2.0 as ubyte
|
||||
}
|
||||
sub screeny(float y) -> ubyte {
|
||||
return (y * height/2.2) + height/2.0 as ubyte
|
||||
}
|
||||
}
|
||||
|
@ -5,148 +5,39 @@
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
ubyte i=0
|
||||
memory byte b1 = $c000
|
||||
memory byte b2 = $c001
|
||||
memory word w1 = $c002
|
||||
memory word w2 = $c004
|
||||
|
||||
vm_write_str("sin 0 ")
|
||||
i=0
|
||||
vm_write_num(sin8(0))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin 50 ")
|
||||
i=50
|
||||
vm_write_num(sin8(50))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin8(i))
|
||||
vm_write_char('\n')
|
||||
b1=50
|
||||
b2=-50
|
||||
w1=100
|
||||
w2=-100
|
||||
|
||||
vm_write_str("sin 128 ")
|
||||
i=128
|
||||
vm_write_num(sin8(128))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin8(i))
|
||||
vm_write_char('\n')
|
||||
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')
|
||||
|
||||
vm_write_str("sin 140 ")
|
||||
i=140
|
||||
vm_write_num(sin8(140))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin 250 ")
|
||||
i=250
|
||||
vm_write_num(sin8(250))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos 0 ")
|
||||
i=0
|
||||
vm_write_num(cos8(0))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos 50 ")
|
||||
i=50
|
||||
vm_write_num(cos8(50))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos 128 ")
|
||||
i=128
|
||||
vm_write_num(cos8(128))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos 140 ")
|
||||
i=140
|
||||
vm_write_num(cos8(140))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos8(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos 250 ")
|
||||
i=250
|
||||
vm_write_num(cos8(250))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos8(i))
|
||||
vm_write_char('\n')
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin16 0 ")
|
||||
i=0
|
||||
vm_write_num(sin16(0))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin16 50 ")
|
||||
i=50
|
||||
vm_write_num(sin16(50))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin16 128 ")
|
||||
i=128
|
||||
vm_write_num(sin16(128))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin16 140 ")
|
||||
i=140
|
||||
vm_write_num(sin16(140))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("sin16 250 ")
|
||||
i=250
|
||||
vm_write_num(sin16(250))
|
||||
vm_write_char(':')
|
||||
vm_write_num(sin16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos16 0 ")
|
||||
i=0
|
||||
vm_write_num(cos16(0))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos16 50 ")
|
||||
i=50
|
||||
vm_write_num(cos16(50))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos16 128 ")
|
||||
i=128
|
||||
vm_write_num(cos16(128))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos16 140 ")
|
||||
i=140
|
||||
vm_write_num(cos16(140))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
vm_write_str("cos16 250 ")
|
||||
i=250
|
||||
vm_write_num(cos16(250))
|
||||
vm_write_char(':')
|
||||
vm_write_num(cos16(i))
|
||||
vm_write_char('\n')
|
||||
|
||||
}
|
||||
}
|
||||
|
79
compiler/examples/whizzine.p8
Normal file
79
compiler/examples/whizzine.p8
Normal file
@ -0,0 +1,79 @@
|
||||
%import c64utils
|
||||
%option enable_floats ; @todo needed for now to avoid compile error in c64lib
|
||||
|
||||
|
||||
~ spritedata $0a00 {
|
||||
; this memory block contains the sprite data
|
||||
; it must start on an address aligned to 64 bytes.
|
||||
%option force_output ; make sure the data in this block appears in the resulting program
|
||||
|
||||
ubyte[63] balloonsprite = [ %00000000,%01111111,%00000000,
|
||||
%00000001,%11111111,%11000000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000011,%11100011,%11100000,
|
||||
%00000111,%11011100,%11110000,
|
||||
%00000111,%11011101,%11110000,
|
||||
%00000111,%11011100,%11110000,
|
||||
%00000011,%11100011,%11100000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000010,%11111111,%10100000,
|
||||
%00000001,%01111111,%01000000,
|
||||
%00000001,%00111110,%01000000,
|
||||
%00000000,%10011100,%10000000,
|
||||
%00000000,%10011100,%10000000,
|
||||
%00000000,%01001001,%00000000,
|
||||
%00000000,%01001001,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00011100,%00000000 ]
|
||||
}
|
||||
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
const uword sprite_address_ptr = $0a00 // 64
|
||||
c64.SPRPTR0 = sprite_address_ptr
|
||||
c64.SPRPTR1 = sprite_address_ptr
|
||||
c64.SPRPTR2 = sprite_address_ptr
|
||||
c64.SPRPTR3 = sprite_address_ptr
|
||||
c64.SPRPTR4 = sprite_address_ptr
|
||||
c64.SPRPTR5 = sprite_address_ptr
|
||||
c64.SPRPTR6 = sprite_address_ptr
|
||||
c64.SPRPTR7 = sprite_address_ptr
|
||||
|
||||
c64.SPENA = 255 ; enable all sprites
|
||||
c64utils.set_rasterirq(240) ; enable animation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
~ irq {
|
||||
|
||||
ubyte angle=0
|
||||
|
||||
sub irq() {
|
||||
const uword SP0X = $d000
|
||||
const uword SP0Y = $d001
|
||||
|
||||
c64.EXTCOL--
|
||||
|
||||
angle++
|
||||
c64.MSIGX=0
|
||||
for ubyte i in 0 to 14 step 2 {
|
||||
word x = (sin8(angle*2-i*8) as word)+190
|
||||
byte y = cos8(angle*3-i*8)
|
||||
lsr(y)
|
||||
@(SP0X+i) = lsb(x)
|
||||
@(SP0Y+i) = y+150 as ubyte
|
||||
|
||||
lsr(c64.MSIGX)
|
||||
if msb(x) c64.MSIGX |= %10000000
|
||||
}
|
||||
|
||||
c64.EXTCOL++
|
||||
}
|
||||
|
||||
}
|
@ -783,8 +783,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
val arg = args.single()
|
||||
val dt = arg.resultingDatatype(namespace, heap)
|
||||
when (dt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.SHL_BYTE)
|
||||
DataType.UWORD -> prog.instr(Opcode.SHL_WORD)
|
||||
DataType.UBYTE, DataType.BYTE -> prog.instr(Opcode.SHL_BYTE)
|
||||
DataType.UWORD, DataType.WORD -> prog.instr(Opcode.SHL_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
// this function doesn't return a value on the stack so we pop it directly into the argument register/variable again
|
||||
@ -794,8 +794,10 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
val arg = args.single()
|
||||
val dt = arg.resultingDatatype(namespace, heap)
|
||||
when (dt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.SHR_BYTE)
|
||||
DataType.UWORD -> prog.instr(Opcode.SHR_WORD)
|
||||
DataType.UBYTE -> prog.instr(Opcode.SHR_UBYTE)
|
||||
DataType.BYTE -> prog.instr(Opcode.SHR_SBYTE)
|
||||
DataType.UWORD -> prog.instr(Opcode.SHR_UWORD)
|
||||
DataType.WORD -> prog.instr(Opcode.SHR_SWORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
// this function doesn't return a value on the stack so we pop it directly into the argument register/variable again
|
||||
|
@ -81,12 +81,18 @@ enum class Opcode {
|
||||
SHL_MEM_WORD,
|
||||
SHL_VAR_BYTE,
|
||||
SHL_VAR_WORD,
|
||||
SHR_BYTE,
|
||||
SHR_WORD,
|
||||
SHR_MEM_BYTE,
|
||||
SHR_MEM_WORD,
|
||||
SHR_VAR_BYTE,
|
||||
SHR_VAR_WORD,
|
||||
SHR_UBYTE,
|
||||
SHR_SBYTE,
|
||||
SHR_UWORD,
|
||||
SHR_SWORD,
|
||||
SHR_MEM_UBYTE,
|
||||
SHR_MEM_SBYTE,
|
||||
SHR_MEM_UWORD,
|
||||
SHR_MEM_SWORD,
|
||||
SHR_VAR_UBYTE,
|
||||
SHR_VAR_SBYTE,
|
||||
SHR_VAR_UWORD,
|
||||
SHR_VAR_SWORD,
|
||||
ROL_BYTE,
|
||||
ROL_WORD,
|
||||
ROL_MEM_BYTE,
|
||||
@ -259,7 +265,8 @@ enum class Opcode {
|
||||
val opcodesWithVarArgument = setOf(
|
||||
Opcode.INC_VAR_B, Opcode.INC_VAR_W, Opcode.DEC_VAR_B, Opcode.DEC_VAR_W,
|
||||
Opcode.INC_VAR_UB, Opcode.INC_VAR_UW, Opcode.DEC_VAR_UB, Opcode.DEC_VAR_UW,
|
||||
Opcode.SHR_VAR_BYTE, Opcode.SHR_VAR_WORD, Opcode.SHL_VAR_BYTE, Opcode.SHL_VAR_WORD,
|
||||
Opcode.SHR_VAR_SBYTE, Opcode.SHR_VAR_UBYTE, Opcode.SHR_VAR_SWORD, Opcode.SHR_VAR_UWORD,
|
||||
Opcode.SHL_VAR_BYTE, Opcode.SHL_VAR_WORD,
|
||||
Opcode.ROL_VAR_BYTE, Opcode.ROL_VAR_WORD, Opcode.ROR_VAR_BYTE, Opcode.ROR_VAR_WORD,
|
||||
Opcode.ROL2_VAR_BYTE, Opcode.ROL2_VAR_WORD, Opcode.ROR2_VAR_BYTE, Opcode.ROR2_VAR_WORD,
|
||||
Opcode.POP_VAR_BYTE, Opcode.POP_VAR_WORD, Opcode.POP_VAR_FLOAT,
|
||||
|
@ -235,11 +235,13 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun shr(): Value {
|
||||
val v = integerValue()
|
||||
if(type==DataType.UBYTE)
|
||||
return Value(type, (v ushr 1) and 255)
|
||||
if(type==DataType.UWORD)
|
||||
return Value(type, (v ushr 1) and 65535)
|
||||
throw ValueException("invalid type for shr: $type")
|
||||
return when(type){
|
||||
DataType.UBYTE -> Value(type, (v ushr 1) and 255)
|
||||
DataType.BYTE -> TODO("shr sbyte")
|
||||
DataType.UWORD -> Value(type, (v ushr 1) and 65535)
|
||||
DataType.WORD -> TODO("shr sword")
|
||||
else -> throw ValueException("invalid type for shr: $type")
|
||||
}
|
||||
}
|
||||
|
||||
fun rol(carry: Boolean): Pair<Value, Boolean> {
|
||||
|
@ -922,16 +922,18 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
// an in place operation that consists of a push-value / op / push-index-value / pop-into-indexed-var
|
||||
return when(ins.opcode) {
|
||||
Opcode.SHL_BYTE -> AsmFragment(" asl $variable+$index", 8)
|
||||
Opcode.SHR_BYTE -> AsmFragment(" lsr $variable+$index", 8)
|
||||
Opcode.SHL_WORD -> AsmFragment(" asl $variable+$index | rol $variable+${index+1}", 8)
|
||||
Opcode.SHR_WORD -> AsmFragment(" lsr $variable+${index+1},x | ror $variable+$index", 8)
|
||||
Opcode.SHR_UBYTE -> AsmFragment(" lsr $variable+$index", 8)
|
||||
Opcode.SHR_SBYTE -> AsmFragment(" lda $variable+$index | asl a | ror $variable+$index")
|
||||
Opcode.SHL_WORD -> AsmFragment(" asl $variable+${index+1} | rol $variable+$index", 8)
|
||||
Opcode.SHR_UWORD -> AsmFragment(" lsr $variable+${index+1} | ror $variable+$index", 8)
|
||||
Opcode.SHR_SWORD -> AsmFragment(" lda $variable+${index+1} | asl a | ror $variable+${index+1} | ror $variable+$index", 8)
|
||||
Opcode.ROL_BYTE -> AsmFragment(" rol $variable+$index", 8)
|
||||
Opcode.ROR_BYTE -> AsmFragment(" ror $variable+$index", 8)
|
||||
Opcode.ROL_WORD -> AsmFragment(" rol $variable+$index | rol $variable+${index+1}", 8)
|
||||
Opcode.ROL_WORD -> AsmFragment(" rol $variable+${index+1} | rol $variable+$index", 8)
|
||||
Opcode.ROR_WORD -> AsmFragment(" ror $variable+${index+1} | ror $variable+$index", 8)
|
||||
Opcode.ROL2_BYTE -> AsmFragment(" lda $variable+$index | cmp #\$80 | rol $variable+$index", 8)
|
||||
Opcode.ROR2_BYTE -> AsmFragment(" lda $variable+$index | lsr a | bcc + | ora #\$80 |+ | sta $variable+$index", 10)
|
||||
Opcode.ROL2_WORD -> AsmFragment(" asl $variable+$index | rol $variable+${index+1} | bcc + | inc $variable+$index |+",20)
|
||||
Opcode.ROL2_WORD -> AsmFragment(" asl $variable+${index+1} | rol $variable+$index | bcc + | inc $variable+$index |+",20) // todo wrong???
|
||||
Opcode.ROR2_WORD -> AsmFragment(" lsr $variable+${index+1} | ror $variable+$index | bcc + | lda $variable+${index+1} | ora #\$80 | sta $variable+${index+1} |+", 30)
|
||||
Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> AsmFragment(" inc $variable+$index", 2)
|
||||
Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> AsmFragment(" dec $variable+$index", 5)
|
||||
@ -974,9 +976,11 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
|
||||
return when (ins.opcode) {
|
||||
Opcode.SHL_BYTE -> AsmFragment(" txa | $loadX asl $variable,x | tax", 10)
|
||||
Opcode.SHR_BYTE -> AsmFragment(" txa | $loadX lsr $variable,x | tax", 10)
|
||||
Opcode.SHR_UBYTE -> AsmFragment(" txa | $loadX lsr $variable,x | tax", 10)
|
||||
Opcode.SHR_SBYTE -> AsmFragment("$saveX $loadX lda $variable,x | asl a | ror $variable,x $restoreX", 10)
|
||||
Opcode.SHL_WORD -> AsmFragment("$saveX $loadXWord asl $variable,x | rol $variable+1,x $restoreX", 10)
|
||||
Opcode.SHR_WORD -> AsmFragment("$saveX $loadXWord lsr $variable+1,x | ror $variable,x $restoreX", 10)
|
||||
Opcode.SHR_UWORD -> AsmFragment("$saveX $loadXWord lsr $variable+1,x | ror $variable,x $restoreX", 10)
|
||||
Opcode.SHR_SWORD -> AsmFragment("$saveX $loadXWord lda $variable+1,x | asl a | ror $variable+1,x | ror $variable,x $restoreX", 10)
|
||||
Opcode.ROL_BYTE -> AsmFragment(" txa | $loadX rol $variable,x | tax", 10)
|
||||
Opcode.ROR_BYTE -> AsmFragment(" txa | $loadX ror $variable,x | tax", 10)
|
||||
Opcode.ROL_WORD -> AsmFragment("$saveX $loadXWord rol $variable,x | rol $variable+1,x $restoreX", 10)
|
||||
@ -999,14 +1003,16 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun sameMemOperation(address: Int, ins: Instruction): AsmFragment? {
|
||||
// an in place operation that consists of a push-mem / op / pop-mem sequence
|
||||
// an in place operation that consists of push-mem / op / pop-mem
|
||||
val addr = address.toHex()
|
||||
val addrHi = (address+1).toHex()
|
||||
return when(ins.opcode) {
|
||||
Opcode.SHL_BYTE -> AsmFragment(" asl $addr", 10)
|
||||
Opcode.SHR_BYTE -> AsmFragment(" lsr $addr", 10)
|
||||
Opcode.SHR_UBYTE -> AsmFragment(" lsr $addr", 10)
|
||||
Opcode.SHR_SBYTE -> AsmFragment(" lda $addr | asl a | ror $addr", 10)
|
||||
Opcode.SHL_WORD -> AsmFragment(" asl $addr | rol $addrHi", 10)
|
||||
Opcode.SHR_WORD -> AsmFragment(" lsr $addrHi | ror $addr", 10)
|
||||
Opcode.SHR_UWORD -> AsmFragment(" lsr $addrHi | ror $addr", 10)
|
||||
Opcode.SHR_SWORD -> AsmFragment(" lda $addrHi | asl a | ror $addrHi | ror $addr", 10)
|
||||
Opcode.ROL_BYTE -> AsmFragment(" rol $addr", 10)
|
||||
Opcode.ROR_BYTE -> AsmFragment(" ror $addr", 10)
|
||||
Opcode.ROL_WORD -> AsmFragment(" rol $addr | rol $addrHi", 10)
|
||||
@ -1030,7 +1036,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
else -> AsmFragment(" asl $variable", 10)
|
||||
}
|
||||
}
|
||||
Opcode.SHR_BYTE -> {
|
||||
Opcode.SHR_UBYTE -> {
|
||||
when (variable) {
|
||||
"A" -> AsmFragment(" lsr a", 10)
|
||||
"X" -> AsmFragment(" txa | lsr a | tax", 10)
|
||||
@ -1038,12 +1044,25 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
else -> AsmFragment(" lsr $variable", 10)
|
||||
}
|
||||
}
|
||||
Opcode.SHR_SBYTE -> {
|
||||
// arithmetic shift right (keep sign bit)
|
||||
when (variable) {
|
||||
"A" -> AsmFragment(" cmp #$80 | ror a", 10)
|
||||
"X" -> AsmFragment(" txa | cmp #$80 | ror a | tax", 10)
|
||||
"Y" -> AsmFragment(" tya | cmp #$80 | ror a | tay", 10)
|
||||
else -> AsmFragment(" lda $variable | asl a | ror $variable", 10)
|
||||
}
|
||||
}
|
||||
Opcode.SHL_WORD -> {
|
||||
AsmFragment(" asl $variable | rol $variable+1", 10)
|
||||
}
|
||||
Opcode.SHR_WORD -> {
|
||||
Opcode.SHR_UWORD -> {
|
||||
AsmFragment(" lsr $variable+1 | ror $variable", 10)
|
||||
}
|
||||
Opcode.SHR_SWORD -> {
|
||||
// arithmetic shift right (keep sign bit)
|
||||
AsmFragment(" lda $variable+1 | asl a | ror $variable+1 | ror $variable", 10)
|
||||
}
|
||||
Opcode.ROL_BYTE -> {
|
||||
when (variable) {
|
||||
"A" -> AsmFragment(" rol a", 10)
|
||||
@ -2880,7 +2899,18 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment ->
|
||||
" lda ${hexVal(segment[0])} | eor #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
|
||||
// push var byte | bytevalue
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE)) { segment ->
|
||||
" lda ${segment[0].callLabel} | ora #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
// push var byte & bytevalue
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE)) { segment ->
|
||||
" lda ${segment[0].callLabel} | and #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
// push var byte ^ bytevalue
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment ->
|
||||
" lda ${segment[0].callLabel} | eor #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
|
||||
// 16 bit addition avoiding excessive stack usage
|
||||
// @todo optimize this even more with longer asmpatterns (avoid stack use altogether on most common operations)
|
||||
|
@ -22,8 +22,8 @@ val BuiltinFunctions = mapOf(
|
||||
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", IntegerDatatypes)), null),
|
||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", IntegerDatatypes)), null),
|
||||
// these few have a return value depending on the argument(s):
|
||||
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
||||
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
||||
@ -303,7 +303,7 @@ private fun builtinSin8(args: List<IExpression>, position: Position, namespace:I
|
||||
throw SyntaxError("sin8 requires one argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (32767.5* sin(rad)).toInt().shr(8).toShort(), position = position)
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (32767.0* sin(rad)).toInt().shr(8).toShort(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinCos8(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
@ -311,7 +311,7 @@ private fun builtinCos8(args: List<IExpression>, position: Position, namespace:I
|
||||
throw SyntaxError("cos8 requires one argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (32767.5* cos(rad)).toInt().shr(8).toShort(), position = position)
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (32767.0* cos(rad)).toInt().shr(8).toShort(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinSin16(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
@ -319,7 +319,7 @@ private fun builtinSin16(args: List<IExpression>, position: Position, namespace:
|
||||
throw SyntaxError("sin16 requires one argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
|
||||
return LiteralValue(DataType.WORD, wordvalue = (32767.5* sin(rad)).toInt(), position = position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = (32767.0* sin(rad)).toInt(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinCos16(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
@ -327,7 +327,7 @@ private fun builtinCos16(args: List<IExpression>, position: Position, namespace:
|
||||
throw SyntaxError("cos16 requires one argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val rad = constval.asNumericValue!!.toDouble() /256.0 * 2.0 * PI
|
||||
return LiteralValue(DataType.WORD, wordvalue = (32767.5* cos(rad)).toInt(), position = position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = (32767.0* cos(rad)).toInt(), position = position)
|
||||
}
|
||||
|
||||
private fun numericLiteral(value: Number, position: Position): LiteralValue {
|
||||
|
@ -564,16 +564,26 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(v, DataType.UWORD)
|
||||
evalstack.push(v.shl())
|
||||
}
|
||||
Opcode.SHR_BYTE -> {
|
||||
Opcode.SHR_UBYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UBYTE)
|
||||
evalstack.push(v.shr())
|
||||
}
|
||||
Opcode.SHR_WORD -> {
|
||||
Opcode.SHR_SBYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.BYTE)
|
||||
evalstack.push(v.shr())
|
||||
}
|
||||
Opcode.SHR_UWORD -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD)
|
||||
evalstack.push(v.shr())
|
||||
}
|
||||
Opcode.SHR_SWORD -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.WORD)
|
||||
evalstack.push(v.shr())
|
||||
}
|
||||
Opcode.ROL_BYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UBYTE)
|
||||
@ -691,18 +701,30 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
val newValue = value.shl()
|
||||
mem.setUWord(addr, newValue.integerValue())
|
||||
}
|
||||
Opcode.SHR_MEM_BYTE -> {
|
||||
Opcode.SHR_MEM_UBYTE -> {
|
||||
val addr = ins.arg!!.integerValue()
|
||||
val value = Value(DataType.UBYTE, mem.getUByte(addr))
|
||||
val newValue = value.shr()
|
||||
mem.setUByte(addr, newValue.integerValue().toShort())
|
||||
}
|
||||
Opcode.SHR_MEM_WORD -> {
|
||||
Opcode.SHR_MEM_SBYTE -> {
|
||||
val addr = ins.arg!!.integerValue()
|
||||
val value = Value(DataType.BYTE, mem.getSByte(addr))
|
||||
val newValue = value.shr()
|
||||
mem.setSByte(addr, newValue.integerValue().toShort())
|
||||
}
|
||||
Opcode.SHR_MEM_UWORD -> {
|
||||
val addr = ins.arg!!.integerValue()
|
||||
val value = Value(DataType.UWORD, mem.getUWord(addr))
|
||||
val newValue = value.shr()
|
||||
mem.setUWord(addr, newValue.integerValue())
|
||||
}
|
||||
Opcode.SHR_MEM_SWORD -> {
|
||||
val addr = ins.arg!!.integerValue()
|
||||
val value = Value(DataType.WORD, mem.getSWord(addr))
|
||||
val newValue = value.shr()
|
||||
mem.setSWord(addr, newValue.integerValue())
|
||||
}
|
||||
Opcode.ROL_MEM_BYTE -> {
|
||||
val addr = ins.arg!!.integerValue()
|
||||
val value = Value(DataType.UBYTE, mem.getUByte(addr))
|
||||
@ -867,16 +889,26 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(variable, DataType.UWORD)
|
||||
variables[ins.callLabel] =variable.shl()
|
||||
}
|
||||
Opcode.SHR_VAR_BYTE -> {
|
||||
Opcode.SHR_VAR_UBYTE -> {
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
checkDt(variable, DataType.UBYTE)
|
||||
variables[ins.callLabel] =variable.shr()
|
||||
}
|
||||
Opcode.SHR_VAR_WORD -> {
|
||||
Opcode.SHR_VAR_SBYTE -> {
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
checkDt(variable, DataType.BYTE)
|
||||
variables[ins.callLabel] =variable.shr()
|
||||
}
|
||||
Opcode.SHR_VAR_UWORD -> {
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
checkDt(variable, DataType.UWORD)
|
||||
variables[ins.callLabel] =variable.shr()
|
||||
}
|
||||
Opcode.SHR_VAR_SWORD -> {
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
checkDt(variable, DataType.WORD)
|
||||
variables[ins.callLabel] =variable.shr()
|
||||
}
|
||||
Opcode.ROL_VAR_BYTE -> {
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
checkDt(variable, DataType.UBYTE)
|
||||
@ -1529,19 +1561,19 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
Syscall.FUNC_COS -> evalstack.push(Value(DataType.FLOAT, cos(evalstack.pop().numericValue().toDouble())))
|
||||
Syscall.FUNC_SIN8 -> {
|
||||
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
|
||||
evalstack.push(Value(DataType.BYTE, (32767.5* sin(rad)).toInt().shr(8).toShort()))
|
||||
evalstack.push(Value(DataType.BYTE, (32767.0* sin(rad)).toInt().shr(8).toShort()))
|
||||
}
|
||||
Syscall.FUNC_SIN16 -> {
|
||||
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
|
||||
evalstack.push(Value(DataType.WORD, (32767.5* sin(rad)).toInt()))
|
||||
evalstack.push(Value(DataType.WORD, (32767.0* sin(rad)).toInt()))
|
||||
}
|
||||
Syscall.FUNC_COS8 -> {
|
||||
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
|
||||
evalstack.push(Value(DataType.BYTE, (32767.5* cos(rad)).toInt().shr(8).toShort()))
|
||||
evalstack.push(Value(DataType.BYTE, (32767.0* cos(rad)).toInt().shr(8).toShort()))
|
||||
}
|
||||
Syscall.FUNC_COS16 -> {
|
||||
val rad = evalstack.pop().numericValue().toDouble() /256.0 * 2.0 * PI
|
||||
evalstack.push(Value(DataType.WORD, (32767.5* cos(rad)).toInt()))
|
||||
evalstack.push(Value(DataType.WORD, (32767.0* cos(rad)).toInt()))
|
||||
}
|
||||
Syscall.FUNC_ROUND -> evalstack.push(Value(DataType.WORD, evalstack.pop().numericValue().toDouble().roundToInt()))
|
||||
Syscall.FUNC_ABS -> {
|
||||
|
@ -923,25 +923,26 @@ class TestStackVmOpcodes {
|
||||
|
||||
@Test
|
||||
fun testSHR() {
|
||||
// @todo test SHR signed byte + signed word
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, 9.99)),
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 3)),
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 61005)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 3)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 249)),
|
||||
Instruction(Opcode.SHR_BYTE), // 124
|
||||
Instruction(Opcode.SHR_UBYTE), // 124
|
||||
Instruction(Opcode.DISCARD_BYTE),
|
||||
Instruction(Opcode.SHR_BYTE), // 1
|
||||
Instruction(Opcode.SHR_BYTE), // 0
|
||||
Instruction(Opcode.SHR_BYTE), // 0
|
||||
Instruction(Opcode.SHR_UBYTE), // 1
|
||||
Instruction(Opcode.SHR_UBYTE), // 0
|
||||
Instruction(Opcode.SHR_UBYTE), // 0
|
||||
Instruction(Opcode.DISCARD_BYTE),
|
||||
Instruction(Opcode.SHR_WORD), // 30502
|
||||
Instruction(Opcode.SHR_UWORD), // 30502
|
||||
Instruction(Opcode.DISCARD_WORD),
|
||||
Instruction(Opcode.SHR_WORD), // 1
|
||||
Instruction(Opcode.SHR_WORD), // 0
|
||||
Instruction(Opcode.SHR_WORD), // 0
|
||||
Instruction(Opcode.SHR_UWORD), // 1
|
||||
Instruction(Opcode.SHR_UWORD), // 0
|
||||
Instruction(Opcode.SHR_UWORD), // 0
|
||||
Instruction(Opcode.DISCARD_WORD),
|
||||
Instruction(Opcode.SHR_BYTE) // error on float
|
||||
Instruction(Opcode.SHR_UBYTE) // error on float
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(6)
|
||||
|
@ -531,6 +531,7 @@ _raster_irq_handler
|
||||
; @todo move to c64fp.p8 and enable float-checkin astchecker.process(decl: VarDecl) again
|
||||
|
||||
const float PI = 3.141592653589793
|
||||
const float TWOPI = 6.283185307179586
|
||||
|
||||
|
||||
asmsub FREADS32 () -> clobbers(A,X,Y) -> () {
|
||||
|
@ -936,7 +936,7 @@ func_sin16 .proc
|
||||
sta ESTACK_HI+1,x
|
||||
rts
|
||||
|
||||
_ := 32767.5 * sin(range(256+64) * rad(360.0/256.0))
|
||||
_ := 32767 * sin(range(256+64) * rad(360.0/256.0))
|
||||
sinecos8lo .byte <_
|
||||
sinecos8hi .byte >_
|
||||
.pend
|
||||
|
Loading…
x
Reference in New Issue
Block a user