mirror of
https://github.com/irmen/prog8.git
synced 2024-10-31 09:08:02 +00:00
fixed some array codegen issues
This commit is contained in:
parent
fd84152a2b
commit
a6bba824d3
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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!")
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user