diff --git a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala index ca320be1..41222882 100644 --- a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala +++ b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala @@ -494,12 +494,18 @@ object AssemblyLine { def absoluteX(opcode: Opcode.Value, thing: ThingInMemory, offset: Int = 0) = AssemblyLine(opcode, AddrMode.AbsoluteX, thing.toAddress + offset) + def indexedY(opcode: Opcode.Value, addr: Int) = + AssemblyLine(opcode, AddrMode.IndexedY, NumericConstant(addr & 0xff, 1)) + def indexedY(opcode: Opcode.Value, addr: Constant) = AssemblyLine(opcode, AddrMode.IndexedY, addr) def indexedY(opcode: Opcode.Value, thing: ThingInMemory, offset: Int = 0) = AssemblyLine(opcode, AddrMode.IndexedY, thing.toAddress + offset) + def indexedSY(opcode: Opcode.Value, offset: Int = 0) = + AssemblyLine(opcode, AddrMode.IndexedSY, NumericConstant(offset & 0xff, 1)) + def stackRelative(opcode: Opcode.Value, addr: Int) = AssemblyLine(opcode, AddrMode.Stack, NumericConstant(addr & 0xff, 1)) } diff --git a/src/main/scala/millfork/assembly/mos/opt/ChangeIndexRegisterOptimization.scala b/src/main/scala/millfork/assembly/mos/opt/ChangeIndexRegisterOptimization.scala index 0d5a33b8..935bb406 100644 --- a/src/main/scala/millfork/assembly/mos/opt/ChangeIndexRegisterOptimization.scala +++ b/src/main/scala/millfork/assembly/mos/opt/ChangeIndexRegisterOptimization.scala @@ -38,14 +38,14 @@ class ChangeIndexRegisterOptimization(preferX2Y: Boolean) extends AssemblyOptimi OpcodeClasses.ReadsYAlways(l.opcode) || OpcodeClasses.ChangesX(l.opcode) || OpcodeClasses.ChangesY(l.opcode) || - Set(AbsoluteX, AbsoluteY, ZeroPageY, ZeroPageX, IndexedX, IndexedY)(l.addrMode) + Set(AbsoluteX, AbsoluteY, ZeroPageY, ZeroPageX, IndexedX, IndexedY, LongIndexedY, IndexedSY)(l.addrMode) ) val usesY = code.exists(l => OpcodeClasses.ReadsXAlways(l.opcode) || OpcodeClasses.ReadsYAlways(l.opcode) || OpcodeClasses.ChangesX(l.opcode) || OpcodeClasses.ChangesY(l.opcode) || - Set(AbsoluteX, AbsoluteY, ZeroPageY, ZeroPageX, IndexedX, IndexedY)(l.addrMode) + Set(AbsoluteX, AbsoluteY, ZeroPageY, ZeroPageX, IndexedX, IndexedY, LongIndexedY, IndexedSY)(l.addrMode) ) if (!usesX && !usesY) { return code @@ -109,6 +109,7 @@ class ChangeIndexRegisterOptimization(preferX2Y: Boolean) extends AssemblyOptimi case AssemblyLine0(_, ZeroPageY, _) :: xs if loaded != Some(Y) => false case AssemblyLine0(_, IndexedY, _) :: xs if dir == Y2X || loaded != Some(Y) => false case AssemblyLine0(_, LongIndexedY, _) :: xs if dir == Y2X || loaded != Some(Y) => false + case AssemblyLine0(_, IndexedSY, _) :: xs if dir == Y2X || loaded != Some(Y) => false case AssemblyLine0(_, AbsoluteX, _) :: xs if loaded != Some(X) => false case AssemblyLine0(_, LongAbsoluteX, _) :: xs if loaded != Some(X) => false case AssemblyLine0(_, ZeroPageX, _) :: xs if loaded != Some(X) => false @@ -225,6 +226,8 @@ class ChangeIndexRegisterOptimization(preferX2Y: Boolean) extends AssemblyOptimi case (x@AssemblyLine0(_, AbsoluteY, _)) :: xs => x.copy(addrMode = AbsoluteX) :: switchY2X(xs) case (x@AssemblyLine0(_, ZeroPageY, _)) :: xs => x.copy(addrMode = ZeroPageX) :: switchY2X(xs) case AssemblyLine0(_, IndexedY, _) :: xs => log.fatal("Unexpected IndexedY") + case AssemblyLine0(_, LongIndexedY, _) :: xs => log.fatal("Unexpected LongIndexedY") + case AssemblyLine0(_, IndexedSY, _) :: xs => log.fatal("Unexpected IndexedSY") case x::xs => x :: switchY2X(xs) case Nil => Nil diff --git a/src/main/scala/millfork/output/MosAssembler.scala b/src/main/scala/millfork/output/MosAssembler.scala index f4245df0..1d313655 100644 --- a/src/main/scala/millfork/output/MosAssembler.scala +++ b/src/main/scala/millfork/output/MosAssembler.scala @@ -50,7 +50,7 @@ class MosAssembler(program: Program, writeByte(bank, index, MosAssembler.opcodeFor(op, Relative, options)) writeByte(bank, index + 1, AssertByte(param - (index + 2))) index + 2 - case AssemblyLine0(op, am@(Immediate | ZeroPage | ZeroPageX | ZeroPageY | IndexedY | IndexedX | IndexedZ | LongIndexedY | LongIndexedZ | Stack), param) => + case AssemblyLine0(op, am@(Immediate | ZeroPage | ZeroPageX | ZeroPageY | IndexedY | IndexedX | IndexedZ | IndexedSY | LongIndexedY | LongIndexedZ | Stack), param) => writeByte(bank, index, MosAssembler.opcodeFor(op, am, options)) writeByte(bank, index + 1, param) index + 2 diff --git a/src/test/resources/cpu.js b/src/test/resources/cpu.js index 3a612b6e..be399f64 100644 --- a/src/test/resources/cpu.js +++ b/src/test/resources/cpu.js @@ -2898,6 +2898,7 @@ var STA_stack_relative_indirect_indexed_y= { execute:function(cpu, bytes) { cpu.cycle_count+=7; + // TODO: fixes below are not well-tested! if(cpu.p.e) { var location_loc = 0x100 | ((cpu.r.s + bytes[0]) & 0xff), low_byte = cpu.mmu.read_byte(location_loc), @@ -2907,41 +2908,16 @@ var STA_stack_relative_indirect_indexed_y= { } else { high_byte = cpu.mmu.read_byte(location_loc+1); } - var absolute_location = ((high_byte<<8)|low_byte)+cpu.r.y, - b; - if(absolute_location>=0x10000) { - b = cpu.mmu.read_byte_long(absolute_location, cpu.r.dbr+1); - } else { - b = cpu.mmu.read_byte(absolute_location); - } - cpu.mmu.store_byte(b, cpu.r.a); + var absolute_location = ((high_byte<<8)|low_byte)+cpu.r.y; + cpu.mmu.store_byte(absolute_location, cpu.r.a); } else { var location_loc = cpu.r.s + bytes[0], absolute_location = cpu.mmu.read_word(location_loc)+cpu.r.y; if(cpu.p.m) { - var b; - if(absolute_location>=0x10000) { - b = cpu.mmu.read_byte_long(absolute_location, cpu.r.dbr+1); - } else { - b = cpu.mmu.read_byte(absolute_location); - } - cpu.mmu.store_byte(b, cpu.r.a); + cpu.mmu.store_byte(absolute_location, cpu.r.a); } else { cpu.cycle_count++; - - var low_byte, high_byte; - if(absolute_location>=0x10000) { - low_byte = cpu.mmu.read_byte_long(absolute_location, cpu.r.dbr+1); - high_byte = cpu.mmu.read_byte_long(absolute_location+1, cpu.r.dbr+1); - } else { - low_byte = cpu.mmu.read_byte(absolute_location); - if(absolute_location===0xffff) { - high_byte = cpu.mmu.read_byte_long(0, cpu.r.dbr+1); - } else { - high_byte = cpu.mmu.read_byte(absolute_location); - } - } - cpu.mmu.store_word((high_byte<<8)|low_byte, cpu.r.a); + cpu.mmu.store_word(absolute_location, cpu.r.a); } } }