mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 08:29:25 +00:00
more asm output
This commit is contained in:
parent
f42a036fc5
commit
595bf7ad4b
124
compiler/examples/cube3d-novm.p8
Normal file
124
compiler/examples/cube3d-novm.p8
Normal file
@ -0,0 +1,124 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ irq {
|
||||
uword global_time
|
||||
ubyte time_changed
|
||||
|
||||
sub irq() {
|
||||
global_time++
|
||||
time_changed = 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
~ main {
|
||||
|
||||
const uword width = 320
|
||||
const uword height = 200
|
||||
|
||||
; 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 ]
|
||||
|
||||
; edges (msb=from vertex, lsb=to vertex)
|
||||
uword[12] 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(1) {
|
||||
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 {
|
||||
uword x=i*2+width//2-width//10
|
||||
;vm_gfx_line(x, 130, i*10.w, 199, 6)
|
||||
}
|
||||
|
||||
rotate_vertices(flt(irq.global_time) / 30.0)
|
||||
draw_edges()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub rotate_vertices(t: float) {
|
||||
; 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 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(x: float, z: float) -> word {
|
||||
return floor(x/(4.2+z) * flt(height)) + width // 2
|
||||
}
|
||||
|
||||
sub toscreeny(y: float, z: float) -> word {
|
||||
return floor(y/(4.2+z) * flt(height)) + height // 2
|
||||
}
|
||||
|
||||
; draw all edges of the object
|
||||
for uword edge in edges {
|
||||
ubyte e_from = msb(edge)
|
||||
ubyte e_to = lsb(edge)
|
||||
|
||||
word x1 = toscreenx(rotatedx[e_from], rotatedz[e_from])
|
||||
word y1 = toscreeny(rotatedy[e_from], rotatedz[e_from])
|
||||
word x2 = toscreenx(rotatedx[e_to], rotatedz[e_to])
|
||||
word y2 = toscreeny(rotatedy[e_to], rotatedz[e_to])
|
||||
ubyte color = e_from+e_to
|
||||
;vm_gfx_line(x1, y1, x2, y2)
|
||||
}
|
||||
|
||||
; 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
sub start() {
|
||||
|
||||
ubyte pixely = 255
|
||||
ubyte derp = 0
|
||||
ubyte ub = 0
|
||||
byte b = 99
|
||||
byte b2 = 100
|
||||
word w = 999
|
||||
@ -18,6 +18,22 @@ sub start() {
|
||||
float fl1 = 1.1
|
||||
float fl2 = 2.2
|
||||
|
||||
byte[5] barr1
|
||||
byte[5] barr2
|
||||
ubyte[5] ubarr1
|
||||
ubyte[5] ubarr2
|
||||
word[5] warr1
|
||||
word[5] warr2
|
||||
uword[5] uwarr1
|
||||
uword[5] uwarr2
|
||||
float[5] farr1
|
||||
float[5] farr2
|
||||
byte[2,3] bmatrix1
|
||||
byte[2,3] bmatrix2
|
||||
ubyte[2,3] ubmatrix1
|
||||
ubyte[2,3] ubmatrix2
|
||||
|
||||
|
||||
memory byte mbyte = $c000
|
||||
memory byte mbyte2 = $d000
|
||||
memory ubyte mubyte = $c001
|
||||
@ -29,20 +45,59 @@ sub start() {
|
||||
memory float mfloat = $c006
|
||||
memory float mfloat2 = $d006
|
||||
|
||||
|
||||
barr1[2]=42
|
||||
ubarr1[2]=42
|
||||
warr1[2]=12555
|
||||
uwarr1[2]=42555
|
||||
farr1[2]=42.5678
|
||||
|
||||
barr1[2] = b
|
||||
ubarr1[2] = ub
|
||||
warr1[2] = w
|
||||
uwarr1[2] = uw
|
||||
farr1[2] = fl1
|
||||
|
||||
barr1[2] = mbyte
|
||||
ubarr1[2] = mubyte
|
||||
warr1[2] = mword
|
||||
uwarr1[2] = muword
|
||||
farr1[2] = mfloat
|
||||
|
||||
b= barr1[2]
|
||||
ub = ubarr1[2]
|
||||
w = warr1[2]
|
||||
uw = uwarr1[2]
|
||||
fl1 = farr1[2]
|
||||
|
||||
mbyte= barr1[2]
|
||||
mubyte = ubarr1[2]
|
||||
mword = warr1[2]
|
||||
muword = uwarr1[2]
|
||||
mfloat = farr1[2]
|
||||
|
||||
barr1[2] = barr2[3]
|
||||
ubarr1[2] = ubarr2[3]
|
||||
warr1[2] = warr2[3]
|
||||
uwarr1[2] = uwarr2[3]
|
||||
farr1[2] = farr2[3]
|
||||
|
||||
|
||||
|
||||
; b = 1
|
||||
; derp = 1
|
||||
; ub = 1
|
||||
; w = 1
|
||||
; uw = 1
|
||||
; fl1 = 2.345
|
||||
;
|
||||
; b = b2
|
||||
; derp = pixely
|
||||
; ub = pixely
|
||||
; w = w2
|
||||
; uw = uw2
|
||||
; fl1 = fl2
|
||||
;
|
||||
; b = mbyte
|
||||
; derp = mubyte
|
||||
; ub = mubyte
|
||||
; w = mword
|
||||
; uw = muword
|
||||
; fl1 = mfloat
|
||||
@ -53,22 +108,22 @@ sub start() {
|
||||
; muword = 1
|
||||
; mfloat = 3.456
|
||||
|
||||
%breakpoint
|
||||
|
||||
mbyte = b
|
||||
mubyte = derp
|
||||
mword = w
|
||||
muword = uw
|
||||
mfloat = fl2
|
||||
|
||||
%breakpoint
|
||||
|
||||
mbyte = mbyte2
|
||||
mubyte = mubyte2
|
||||
mword = mword2
|
||||
muword = muword2
|
||||
mfloat = mfloat2
|
||||
|
||||
; %breakpoint
|
||||
;
|
||||
; mbyte = b
|
||||
; mubyte = ub
|
||||
; mword = w
|
||||
; muword = uw
|
||||
; mfloat = fl2
|
||||
;
|
||||
; %breakpoint
|
||||
;
|
||||
; mbyte = mbyte2
|
||||
; mubyte = mubyte2
|
||||
; mword = mword2
|
||||
; muword = muword2
|
||||
; mfloat = mfloat2
|
||||
;
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import prog8.ast.DataType
|
||||
import prog8.ast.Register
|
||||
import prog8.compiler.*
|
||||
import prog8.compiler.intermediate.*
|
||||
import prog8.stackvm.Syscall
|
||||
import prog8.stackvm.syscallsForStackVm
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
@ -391,58 +392,58 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.SYSCALL -> {
|
||||
if (ins.arg!!.numericValue() in syscallsForStackVm.map { it.callNr })
|
||||
throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}")
|
||||
TODO("syscall $ins")
|
||||
val call = Syscall.values().find { it.callNr==ins.arg.numericValue() }
|
||||
" jsr prog8_lib.${call.toString().toLowerCase()}"
|
||||
}
|
||||
Opcode.BREAKPOINT -> {
|
||||
breakpointCounter++
|
||||
"_prog8_breakpoint_$breakpointCounter\tnop"
|
||||
}
|
||||
|
||||
// todo weer aanzetten?
|
||||
// Opcode.PUSH_BYTE -> {
|
||||
// " lda #${ins.arg!!.integerValue().toHex()} | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
// }
|
||||
// Opcode.PUSH_WORD -> {
|
||||
// val value = ins.arg!!.integerValue().toHex()
|
||||
// " lda #<$value | sta ${ESTACK_LO.toHex()},x | lda #>$value | sta ${ESTACK_HI.toHex()},x | dex"
|
||||
// }
|
||||
// Opcode.PUSH_FLOAT -> {
|
||||
// val floatConst = getFloatConst(ins.arg)
|
||||
// " lda #<$floatConst | ldy #>$floatConst | jsr prog8_lib.push_float"
|
||||
// }
|
||||
// Opcode.PUSH_VAR_BYTE -> {
|
||||
// when(ins.callLabel) {
|
||||
// "X" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
// "A" -> " sta ${ESTACK_LO.toHex()},x | dex"
|
||||
// "Y" -> " tya | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
// else -> " lda ${ins.callLabel} | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
// }
|
||||
// }
|
||||
// Opcode.PUSH_VAR_WORD -> {
|
||||
// when (ins.callLabel) {
|
||||
// "AX" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
// "XY" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
// "AY" -> " sta ${ESTACK_LO.toHex()},x | pha | tya | sta ${ESTACK_HI.toHex()},x | pla | dex"
|
||||
// else -> " lda ${ins.callLabel} | ldy ${ins.callLabel}+1 | sta ${ESTACK_LO.toHex()},x | pha | tya | sta ${ESTACK_HI.toHex()},x | pla | dex"
|
||||
// }
|
||||
// }
|
||||
// Opcode.PUSH_VAR_FLOAT -> " lda #<${ins.callLabel} | ldy #>${ins.callLabel}| jsr prog8_lib.push_float"
|
||||
// Opcode.PUSH_MEM_B, Opcode.PUSH_MEM_UB -> {
|
||||
// """
|
||||
// lda ${ins.arg!!.integerValue().toHex()}
|
||||
// sta ${ESTACK_LO.toHex()},x
|
||||
// dex
|
||||
// """
|
||||
// }
|
||||
// Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_UW -> {
|
||||
// """
|
||||
// lda ${ins.arg!!.integerValue().toHex()}
|
||||
// sta ${ESTACK_LO.toHex()},x
|
||||
// lda ${(ins.arg.integerValue()+1).toHex()}
|
||||
// sta ${ESTACK_HI.toHex()},x
|
||||
// dex
|
||||
// """
|
||||
// }
|
||||
Opcode.PUSH_BYTE -> {
|
||||
" lda #${ins.arg!!.integerValue().toHex()} | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
}
|
||||
Opcode.PUSH_WORD -> {
|
||||
val value = ins.arg!!.integerValue().toHex()
|
||||
" lda #<$value | sta ${ESTACK_LO.toHex()},x | lda #>$value | sta ${ESTACK_HI.toHex()},x | dex"
|
||||
}
|
||||
Opcode.PUSH_FLOAT -> {
|
||||
val floatConst = getFloatConst(ins.arg!!)
|
||||
" lda #<$floatConst | ldy #>$floatConst | jsr prog8_lib.push_float"
|
||||
}
|
||||
Opcode.PUSH_VAR_BYTE -> {
|
||||
when(ins.callLabel) {
|
||||
"X" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
"A" -> " sta ${ESTACK_LO.toHex()},x | dex"
|
||||
"Y" -> " tya | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
else -> " lda ${ins.callLabel} | sta ${ESTACK_LO.toHex()},x | dex"
|
||||
}
|
||||
}
|
||||
Opcode.PUSH_VAR_WORD -> {
|
||||
when (ins.callLabel) {
|
||||
"AX" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
"XY" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself")
|
||||
"AY" -> " sta ${ESTACK_LO.toHex()},x | pha | tya | sta ${ESTACK_HI.toHex()},x | pla | dex"
|
||||
else -> " lda ${ins.callLabel} | ldy ${ins.callLabel}+1 | sta ${ESTACK_LO.toHex()},x | pha | tya | sta ${ESTACK_HI.toHex()},x | pla | dex"
|
||||
}
|
||||
}
|
||||
Opcode.PUSH_VAR_FLOAT -> " lda #<${ins.callLabel} | ldy #>${ins.callLabel}| jsr prog8_lib.push_float"
|
||||
Opcode.PUSH_MEM_B, Opcode.PUSH_MEM_UB -> {
|
||||
"""
|
||||
lda ${ins.arg!!.integerValue().toHex()}
|
||||
sta ${ESTACK_LO.toHex()},x
|
||||
dex
|
||||
"""
|
||||
}
|
||||
Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_UW -> {
|
||||
"""
|
||||
lda ${ins.arg!!.integerValue().toHex()}
|
||||
sta ${ESTACK_LO.toHex()},x
|
||||
lda ${(ins.arg.integerValue()+1).toHex()}
|
||||
sta ${ESTACK_HI.toHex()},x
|
||||
dex
|
||||
"""
|
||||
}
|
||||
|
||||
Opcode.POP_MEM_B, Opcode.POP_MEM_UB -> {
|
||||
"""
|
||||
@ -635,6 +636,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
sta ${(ESTACK_LO+1).toHex()},x
|
||||
"""
|
||||
}
|
||||
Opcode.NEG_F -> " jsr prog8_lib.neg_f"
|
||||
Opcode.INV_BYTE -> {
|
||||
"""
|
||||
lda ${(ESTACK_LO + 1).toHex()},x
|
||||
@ -768,7 +770,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
|
||||
// check for operations that modify a single value, by putting it on the stack (and popping it afterwards)
|
||||
if((opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[2]==Opcode.POP_VAR_BYTE) ||
|
||||
(opcodes[0]==Opcode.PUSH_VAR_WORD && opcodes[2]==Opcode.POP_VAR_WORD)) {
|
||||
(opcodes[0]==Opcode.PUSH_VAR_WORD && opcodes[2]==Opcode.POP_VAR_WORD) ||
|
||||
(opcodes[0]==Opcode.PUSH_VAR_FLOAT && opcodes[2]==Opcode.POP_VAR_FLOAT)) {
|
||||
if (segment[0].callLabel == segment[2].callLabel) {
|
||||
val fragment = sameVarOperation(segment[0].callLabel!!, segment[1])
|
||||
if (fragment != null) {
|
||||
@ -778,7 +781,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
else if((opcodes[0]==Opcode.PUSH_MEM_UB && opcodes[2]==Opcode.POP_MEM_UB) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_UW && opcodes[2]==Opcode.POP_MEM_UW)) {
|
||||
(opcodes[0]==Opcode.PUSH_MEM_B && opcodes[2]==Opcode.POP_MEM_B) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_UW && opcodes[2]==Opcode.POP_MEM_UW) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_W && opcodes[2]==Opcode.POP_MEM_W) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_FLOAT && opcodes[2]==Opcode.POP_MEM_FLOAT)) {
|
||||
if(segment[0].arg==segment[2].arg) {
|
||||
val fragment = sameMemOperation(segment[0].arg!!.integerValue(), segment[1])
|
||||
if(fragment!=null) {
|
||||
@ -1004,6 +1010,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
else -> AsmFragment(" lda $variable | sta ${C64Zeropage.SCRATCH_W1} | lda $variable+1 | sta ${C64Zeropage.SCRATCH_W1+1} | jsr prog8_lib.ror2_word | lda ${C64Zeropage.SCRATCH_W1} | sta $variable | lda ${C64Zeropage.SCRATCH_W1+1} | sta $variable+1", 30)
|
||||
}
|
||||
}
|
||||
// Opcode.SYSCALL -> {
|
||||
// TODO("optimize SYSCALL $ins in-place on variable $variable")
|
||||
// }
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@ -1182,6 +1191,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
|
||||
// @todo add all indexed assignment forms
|
||||
|
||||
// assignment: var = bytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment ->
|
||||
|
Loading…
Reference in New Issue
Block a user