diff --git a/src/main/scala/millfork/compiler/mos/BuiltIns.scala b/src/main/scala/millfork/compiler/mos/BuiltIns.scala index 8b9b61ff..5f42ac95 100644 --- a/src/main/scala/millfork/compiler/mos/BuiltIns.scala +++ b/src/main/scala/millfork/compiler/mos/BuiltIns.scala @@ -100,7 +100,7 @@ object BuiltIns { val preparations = parts._1 val finalRead = wrapInSedCldIfNeeded(decimal, parts._2) if (preserveA && AssemblyLine.treatment(preparations, State.A) != Treatment.Unchanged) { - AssemblyLine.implied(PHA) :: (preparations ++ (AssemblyLine.implied(PLA) :: finalRead)) + AssemblyLine.implied(PHA) :: (MosExpressionCompiler.fixTsx(preparations) ++ (AssemblyLine.implied(PLA) :: finalRead)) } else { preparations ++ finalRead } diff --git a/src/main/scala/millfork/compiler/mos/PseudoregisterBuiltIns.scala b/src/main/scala/millfork/compiler/mos/PseudoregisterBuiltIns.scala index 72d3ffa7..81951e96 100644 --- a/src/main/scala/millfork/compiler/mos/PseudoregisterBuiltIns.scala +++ b/src/main/scala/millfork/compiler/mos/PseudoregisterBuiltIns.scala @@ -95,7 +95,7 @@ object PseudoregisterBuiltIns { AssemblyLine.zeropage(LDA, reg, 1), AssemblyLine.implied(PHA), AssemblyLine.zeropage(LDA, reg), - AssemblyLine.implied(PHA)) ++ compileRight ++ List( + AssemblyLine.implied(PHA)) ++ MosExpressionCompiler.fixTsx(MosExpressionCompiler.fixTsx(compileRight)) ++ List( prepareCarry, AssemblyLine.implied(PLA), AssemblyLine.zeropage(op, reg), diff --git a/src/test/scala/millfork/test/StackVarSuite.scala b/src/test/scala/millfork/test/StackVarSuite.scala index b2670382..4ee964d7 100644 --- a/src/test/scala/millfork/test/StackVarSuite.scala +++ b/src/test/scala/millfork/test/StackVarSuite.scala @@ -142,6 +142,55 @@ class StackVarSuite extends FunSuite with Matchers { } } + test("Recursion 2") { + EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80)(""" + | array output [6] @$c000 + | byte fails @$c010 + | void main () { + | word w + | byte i + | for i,0,until,output.length { + | w = fib(i) + | if w.hi != 0 { fails += 1 } + | output[i] = w.lo + | } + | } + | word fib(byte i) { + | stack byte j + | j = i + | if j < 2 { + | return 1 + | } + | return fib(j-1) + fib(j-2) + | } + """.stripMargin){ m => + m.readByte(0xc010) should equal(0) + m.readByte(0xc000) should equal(1) + m.readByte(0xc001) should equal(1) + m.readByte(0xc002) should equal(2) + m.readByte(0xc003) should equal(3) + m.readByte(0xc004) should equal(5) + m.readByte(0xc005) should equal(8) + } + } + + test("Complex stack-related stuff") { + EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80)(""" + | byte output @$c000 + | array id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + | void main() { + | stack byte i + | i = b($4) + | output = b(id[b($2)]|id[b(i)]) + | } + | noinline byte b(byte a) { + | return a + | } + """.stripMargin){ m => + m.readByte(0xc000) should equal(6) + } + } + test("Indexing") { EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80)("""