From 7c1d5cadd775479b3bf69d346454edd2201b4706 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 10 Apr 2023 18:43:51 +0200 Subject: [PATCH] fix sort and reverse on strings on 6502 codegen --- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 21 ++++++++++++ .../codegen/intermediate/BuiltinFuncGen.kt | 4 +-- compiler/res/prog8lib/virtual/textio.p8 | 2 ++ docs/source/todo.rst | 5 +-- examples/numbergame.p8 | 3 -- examples/test.p8 | 13 ++++++- .../src/prog8/intermediate/IMSyscall.kt | 34 +++++++++---------- virtualmachine/src/prog8/vm/SysCalls.kt | 2 +- virtualmachine/src/prog8/vm/VirtualMachine.kt | 2 +- 9 files changed, 59 insertions(+), 27 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 5746cb6e7..3bb4551fe 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -1,5 +1,6 @@ package prog8.codegen.cpu6502 +import prog8.code.StStaticVariable import prog8.code.ast.* import prog8.code.core.* import prog8.codegen.cpu6502.assignment.* @@ -337,6 +338,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, lda #$numElements 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 -> { asmgen.out(""" lda #<$varName @@ -381,6 +392,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, lda #$numElements""") 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") else -> throw AssemblyError("weird type") } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 8de1d46e3..cd61dc6ee 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -273,7 +273,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe addToResult(result, tr, tr.resultReg, -1) result += IRCodeChunk(null, null).also { 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.SYSCALL, immediate = syscall.number) } @@ -298,7 +298,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe addToResult(result, tr, tr.resultReg, -1) result += IRCodeChunk(null, null).also { 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.SYSCALL, immediate = syscall.number) } diff --git a/compiler/res/prog8lib/virtual/textio.p8 b/compiler/res/prog8lib/virtual/textio.p8 index de834dfb4..8c6b8d0fc 100644 --- a/compiler/res/prog8lib/virtual/textio.p8 +++ b/compiler/res/prog8lib/virtual/textio.p8 @@ -127,6 +127,8 @@ sub input_chars (uword buffer) -> ubyte { %ir {{ loadm.w r65535,txt.input_chars.buffer push.w r65535 + load.b r65535,80 + push.b r65535 syscall 6 pop.b r0 returnreg.b r0 diff --git a/docs/source/todo.rst b/docs/source/todo.rst index f64b02443..e7552b270 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO 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: +- 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: 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) diff --git a/examples/numbergame.p8 b/examples/numbergame.p8 index 3014a590c..c579e04ee 100644 --- a/examples/numbergame.p8 +++ b/examples/numbergame.p8 @@ -1,7 +1,6 @@ %import textio %import conv %import math -%import test_stack %zeropage basicsafe ; The classic number guessing game. @@ -61,8 +60,6 @@ main { txt.print("Thanks for playing, ") txt.print(name) txt.print(".\n") - - ; test_stack.test() } } } diff --git a/examples/test.p8 b/examples/test.p8 index a9f967b3f..e566fd3d1 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,7 +5,18 @@ main { 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) } } diff --git a/intermediate/src/prog8/intermediate/IMSyscall.kt b/intermediate/src/prog8/intermediate/IMSyscall.kt index 9ef784d98..50ff88a3e 100644 --- a/intermediate/src/prog8/intermediate/IMSyscall.kt +++ b/intermediate/src/prog8/intermediate/IMSyscall.kt @@ -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. enum class IMSyscall(val number: Int) { - SORT_UBYTE(10000), - SORT_BYTE(10001), - SORT_UWORD(10002), - SORT_WORD(10003), - ANY_BYTE(10004), - ANY_WORD(10005), - ANY_FLOAT(10006), - ALL_BYTE(10007), - ALL_WORD(10008), - ALL_FLOAT(10009), - REVERSE_BYTES(10010), - REVERSE_WORDS(10011), - REVERSE_FLOATS(10012), - COMPARE_STRINGS(10013), - STRING_CONTAINS(10014), - BYTEARRAY_CONTAINS(10015), - WORDARRAY_CONTAINS(10016) + SORT_UBYTE(0x1000), + SORT_BYTE(0x1001), + SORT_UWORD(0x1002), + SORT_WORD(0x1003), + ANY_BYTE(0x1004), + ANY_WORD(0x1005), + ANY_FLOAT(0x1006), + ALL_BYTE(0x1007), + ALL_WORD(0x1008), + ALL_FLOAT(0x1009), + REVERSE_BYTES(0x100a), + REVERSE_WORDS(0x100b), + REVERSE_FLOATS(0x100c), + COMPARE_STRINGS(0x100d), + STRING_CONTAINS(0x100e), + BYTEARRAY_CONTAINS(0x100f), + WORDARRAY_CONTAINS(0x1010) } diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index 67061a597..8e4127034 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -119,7 +119,7 @@ object SysCalls { if(maxlen>0) input = input.substring(0, min(input.length, maxlen)) vm.memory.setString(vm.valueStack.popw().toInt(), input, true) - vm.valueStack.pushw(input.length.toUShort()) + vm.valueStack.push(input.length.toUByte()) } Syscall.SLEEP -> { val duration = vm.valueStack.popw().toLong() diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index db434f601..a658b327c 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -2299,7 +2299,7 @@ class VirtualMachine(irProgram: IRProgram) { val y = valueStack.popw() val x = valueStack.popw() 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. } }