fix sort and reverse on strings on 6502 codegen

This commit is contained in:
Irmen de Jong 2023-04-10 18:43:51 +02:00
parent dd1592b03b
commit 7c1d5cadd7
9 changed files with 59 additions and 27 deletions

View File

@ -1,5 +1,6 @@
package prog8.codegen.cpu6502 package prog8.codegen.cpu6502
import prog8.code.StStaticVariable
import prog8.code.ast.* import prog8.code.ast.*
import prog8.code.core.* import prog8.code.core.*
import prog8.codegen.cpu6502.assignment.* import prog8.codegen.cpu6502.assignment.*
@ -337,6 +338,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
lda #$numElements lda #$numElements
jsr prog8_lib.func_reverse_w""") jsr prog8_lib.func_reverse_w""")
} }
DataType.STR -> {
val stringLength = (symbol as StStaticVariable).length!!-1
asmgen.out("""
lda #<$varName
ldy #>$varName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #$stringLength
jsr prog8_lib.func_reverse_b""")
}
DataType.ARRAY_F -> { DataType.ARRAY_F -> {
asmgen.out(""" asmgen.out("""
lda #<$varName lda #<$varName
@ -381,6 +392,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
lda #$numElements""") lda #$numElements""")
asmgen.out(if (decl.type == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w") asmgen.out(if (decl.type == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w")
} }
DataType.STR -> {
val stringLength = (symbol as StStaticVariable).length!!-1
asmgen.out("""
lda #<$varName
ldy #>$varName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #$stringLength
jsr prog8_lib.func_sort_ub""")
}
DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported") DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported")
else -> throw AssemblyError("weird type") else -> throw AssemblyError("weird type")
} }

View File

@ -273,7 +273,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
result += IRCodeChunk(null, null).also { result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg) it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = array.length) it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length)
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg) it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number) it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
} }
@ -298,7 +298,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
result += IRCodeChunk(null, null).also { result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg) it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = array.length) it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length)
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg) it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number) it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
} }

View File

@ -127,6 +127,8 @@ sub input_chars (uword buffer) -> ubyte {
%ir {{ %ir {{
loadm.w r65535,txt.input_chars.buffer loadm.w r65535,txt.input_chars.buffer
push.w r65535 push.w r65535
load.b r65535,80
push.b r65535
syscall 6 syscall 6
pop.b r0 pop.b r0
returnreg.b r0 returnreg.b r0

View File

@ -3,8 +3,6 @@ TODO
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
test vm array reverse, sort, string containment, string input, float array containment (how translated? there is no syscall)
... ...
@ -35,6 +33,9 @@ Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
Compiler: Compiler:
- ir: investigate passing parameters to function calls using fixed set of regs r60000,r60001, etc.
these have to be offset somehow by the subroutine number (?) somehow to have a unique list of them per subroutine.
also only if we can optimize the subroutine to replace the parameter variables to those registers.
- ir: can we determine for the loop variable in forloops if it could be kept in a (virtual) register instead of a real variable? Need to be able to check if the variable is used by another statement beside just the for loop. - ir: can we determine for the loop variable in forloops if it could be kept in a (virtual) register instead of a real variable? Need to be able to check if the variable is used by another statement beside just the for loop.
- ir: mechanism to determine for chunks which registers are getting input values from "outside" - ir: mechanism to determine for chunks which registers are getting input values from "outside"
- ir: mechanism to determine for chunks which registers are passing values out? (i.e. are used again in another chunk) - ir: mechanism to determine for chunks which registers are passing values out? (i.e. are used again in another chunk)

View File

@ -1,7 +1,6 @@
%import textio %import textio
%import conv %import conv
%import math %import math
%import test_stack
%zeropage basicsafe %zeropage basicsafe
; The classic number guessing game. ; The classic number guessing game.
@ -61,8 +60,6 @@ main {
txt.print("Thanks for playing, ") txt.print("Thanks for playing, ")
txt.print(name) txt.print(name)
txt.print(".\n") txt.print(".\n")
; test_stack.test()
} }
} }
} }

View File

@ -5,7 +5,18 @@
main { main {
sub start() { sub start() {
math.rndseed(11111,22222) str name = "irmen"
reverse(name)
txt.print(name)
txt.nl()
sort(name)
txt.print(name)
txt.nl()
txt.print_ub('@' in name)
txt.nl()
txt.print_ub('i' in name)
txt.nl()
sys.wait(60)
} }
} }

View File

@ -5,21 +5,21 @@ package prog8.intermediate
// Note that in the VM these are translated into whatever the corresponding Syscall number in the VM is. // Note that in the VM these are translated into whatever the corresponding Syscall number in the VM is.
enum class IMSyscall(val number: Int) { enum class IMSyscall(val number: Int) {
SORT_UBYTE(10000), SORT_UBYTE(0x1000),
SORT_BYTE(10001), SORT_BYTE(0x1001),
SORT_UWORD(10002), SORT_UWORD(0x1002),
SORT_WORD(10003), SORT_WORD(0x1003),
ANY_BYTE(10004), ANY_BYTE(0x1004),
ANY_WORD(10005), ANY_WORD(0x1005),
ANY_FLOAT(10006), ANY_FLOAT(0x1006),
ALL_BYTE(10007), ALL_BYTE(0x1007),
ALL_WORD(10008), ALL_WORD(0x1008),
ALL_FLOAT(10009), ALL_FLOAT(0x1009),
REVERSE_BYTES(10010), REVERSE_BYTES(0x100a),
REVERSE_WORDS(10011), REVERSE_WORDS(0x100b),
REVERSE_FLOATS(10012), REVERSE_FLOATS(0x100c),
COMPARE_STRINGS(10013), COMPARE_STRINGS(0x100d),
STRING_CONTAINS(10014), STRING_CONTAINS(0x100e),
BYTEARRAY_CONTAINS(10015), BYTEARRAY_CONTAINS(0x100f),
WORDARRAY_CONTAINS(10016) WORDARRAY_CONTAINS(0x1010)
} }

View File

@ -119,7 +119,7 @@ object SysCalls {
if(maxlen>0) if(maxlen>0)
input = input.substring(0, min(input.length, maxlen)) input = input.substring(0, min(input.length, maxlen))
vm.memory.setString(vm.valueStack.popw().toInt(), input, true) vm.memory.setString(vm.valueStack.popw().toInt(), input, true)
vm.valueStack.pushw(input.length.toUShort()) vm.valueStack.push(input.length.toUByte())
} }
Syscall.SLEEP -> { Syscall.SLEEP -> {
val duration = vm.valueStack.popw().toLong() val duration = vm.valueStack.popw().toLong()

View File

@ -2299,7 +2299,7 @@ class VirtualMachine(irProgram: IRProgram) {
val y = valueStack.popw() val y = valueStack.popw()
val x = valueStack.popw() val x = valueStack.popw()
val color = Color(window!!.getpixel(x.toInt(), y.toInt())) val color = Color(window!!.getpixel(x.toInt(), y.toInt()))
registers.setUB(0, color.green.toUByte()) valueStack.push(color.green.toUByte()) // gets called from a syscall, return value via stack.
} }
} }