diff --git a/src/main/scala/millfork/assembly/z80/ZLine.scala b/src/main/scala/millfork/assembly/z80/ZLine.scala index b45f986c..bf009276 100644 --- a/src/main/scala/millfork/assembly/z80/ZLine.scala +++ b/src/main/scala/millfork/assembly/z80/ZLine.scala @@ -12,6 +12,8 @@ import millfork.node.ZRegister object ZFlag extends Enumeration { val Z, P, C, S, H, N = Value + + val AllButSZ: Seq[Value] = Seq(P, C, H, N) } sealed trait ZRegisters @@ -179,7 +181,6 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case JR => 2 case o if ZOpcodeClasses.EdInstructions(o) => 2 case o if ZOpcodeClasses.CbInstructions(o) => 2 - case o if ZOpcodeClasses.CbInstructionsUnlessA(o) => if (registers == OneRegister(ZRegister.A)) 1 else 2 case _ => 1 // TODO!!! } val fromParams = registers match { @@ -244,6 +245,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case RST => s" RST $parameter" case IM => s" IM $parameter" case EX_AF_AF => " EX AF,AF'" + case EX_DE_HL => " EX DE,HL" case LD_AHLI => " LD A,(HLI)" case LD_AHLD => " LD A,(HLD)" case LD_HLIA => " LD (HLI),A" @@ -373,7 +375,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case OneRegisterOffset(s, _) => r == s case _ => r == A } - case INC | DEC | RL | RLC | RR | RRC | SLA | SLL | SRA | SRL => registers match { + case INC | DEC | RL | RLC | RR | RRC | SLA | SLL | SRA | SRL | SWAP => registers match { case OneRegister(MEM_HL) => r == H || r == L case OneRegister(MEM_BC) => r == B || r == C case OneRegister(MEM_DE) => r == D || r == E @@ -401,11 +403,12 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case OneRegisterOffset(s, _) => r == s case _ => false } + case EX_DE_HL => r == D || r == E || r == H || r == L case JP | JR | RET | RETI | RETN | POP | DISCARD_A | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_HL | DISCARD_F => false case DJNZ => r == B - case DAA | NEG | CPL => r == A + case DAA | NEG | CPL | RLA | RRA | RLCA | RRCA => r == A case LABEL | DI | EI | NOP | HALT => false case _ => true // TODO } @@ -511,7 +514,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case TwoRegistersOffset(s, _, _) => r == s case _ => false } - case INC | DEC | RL | RLC | RR | RRC | SLA | SLL | SRA | SRL => registers match { + case INC | DEC | RL | RLC | RR | RRC | SLA | SLL | SRA | SRL | SWAP => registers match { case OneRegister(s) => r == s case OneRegisterOffset(s, _) => r == s case _ => false @@ -534,10 +537,11 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case OneRegisterOffset(s, _) => r == s case _ => false } + case EX_DE_HL => r == D || r == E || r == H || r == L case JP | JR | RET | RETI | RETN | PUSH | DISCARD_A | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_HL | DISCARD_F => false - case ADD | ADC | AND | OR | XOR | SUB | SBC | DAA | NEG | CPL => r == A + case ADD | ADC | AND | OR | XOR | SUB | SBC | DAA | NEG | CPL | RLA | RRA | RLCA | RRCA => r == A case CP => false case DJNZ => r == B case LABEL | DI | EI | NOP | HALT => false @@ -568,6 +572,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case JP | JR | RET | RETI | RETN | PUSH | DJNZ | DAA | DISCARD_A | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_HL | DISCARD_F => false + case EX_DE_HL | NEG => false case LABEL | DI | EI | NOP => false case _ => true // TODO } @@ -589,6 +594,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta case JP | JR | RET | RETI | RETN | PUSH | DJNZ | DAA | DISCARD_A | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_HL | DISCARD_F => false + case EX_DE_HL | NEG => false case LABEL | DI | EI | NOP | HALT => false case _ => true // TODO } diff --git a/src/main/scala/millfork/assembly/z80/ZOpcode.scala b/src/main/scala/millfork/assembly/z80/ZOpcode.scala index f7097a7d..ba4fdb52 100644 --- a/src/main/scala/millfork/assembly/z80/ZOpcode.scala +++ b/src/main/scala/millfork/assembly/z80/ZOpcode.scala @@ -19,6 +19,7 @@ object ZOpcode extends Enumeration { POP, PUSH, NOP, RLC, RRC, RL, RR, SLA, SRA, SRL, SLL, RLD, RRD, + RLCA, RLA, RRA, RRCA, EXX, EX_DE_HL, EX_AF_AF, EX_SP, RST, IM, EI, DI, DJNZ, JP, JR, CALL, RET, RETN, RETI, HALT, @@ -46,8 +47,7 @@ object ZOpcodeClasses { val AllSingleBit: Set[ZOpcode.Value] = RES ++ SET ++ BIT val RES_or_SET: Set[ZOpcode.Value] = RES ++ SET - val CbInstructions: Set[ZOpcode.Value] = Set(SLA, SRA, SRL, SLL) ++ BIT ++ RES ++ SET - val CbInstructionsUnlessA = Set(RLC, RRC, RL, RR) + val CbInstructions: Set[ZOpcode.Value] = Set(SLA, SRA, SRL, SLL, RLC, RRC, RL, RR) ++ BIT ++ RES ++ SET val EdInstructions: Set[ZOpcode.Value] = Set(NEG, RETN, RETI, IM, RRD, RLD, INI, INIR, OUTI, OUTIR, IND, INDR, OUTD, OUTDR, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR) ++ BIT ++ RES ++ SET diff --git a/src/main/scala/millfork/assembly/z80/opt/CoarseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/z80/opt/CoarseFlowAnalyzer.scala index 062585ce..1c449fc1 100644 --- a/src/main/scala/millfork/assembly/z80/opt/CoarseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/z80/opt/CoarseFlowAnalyzer.scala @@ -1,10 +1,10 @@ package millfork.assembly.z80.opt -import millfork.assembly.opt.{AnyStatus, SingleStatus} +import millfork.assembly.opt.{AnyStatus, SingleStatus, Status} import millfork.assembly.z80._ import millfork.env.{Label, MemoryAddressConstant, NormalFunction, NumericConstant} import millfork.node.ZRegister -import millfork.CompilationOptions +import millfork.{CompilationOptions, Cpu} /** * @author Karol Stasiak @@ -102,6 +102,8 @@ object CoarseFlowAnalyzer { currentStatus = currentStatus.setRegister(t, currentStatus.getRegister(s)) case ZLine(LD | LD_16, TwoRegistersOffset(t, s, o), _, _) => currentStatus = currentStatus.setRegister(t, currentStatus.getRegister(s, o), o) + case ZLine(EX_DE_HL, _, _, _) => + currentStatus = currentStatus.copy(d = currentStatus.h, e = currentStatus.l, h = currentStatus.d, l = currentStatus.e) case ZLine(ADD_16, TwoRegisters(t, s), _, _) => currentStatus = currentStatus.copy(cf = AnyStatus, zf = AnyStatus, sf = AnyStatus, pf = AnyStatus, hf = AnyStatus) .setRegister(t, (currentStatus.getRegister(t) <*> currentStatus.getRegister(s)) ((m, n) => (m + n) & 0xffff)) @@ -113,6 +115,13 @@ object CoarseFlowAnalyzer { currentStatus = currentStatus.copy(cf = AnyStatus, zf = AnyStatus, sf = AnyStatus, pf = AnyStatus, hf = AnyStatus) .setRegister(r, currentStatus.getRegister(r).map(_.>>(1).&(0x7f))) + + case ZLine(RLA | RRA | RLCA | RRCA, _, _, _) => + currentStatus = currentStatus.copy( + a = AnyStatus, cf = AnyStatus, + zf = AnyStatus, + pf = AnyStatus, hf = Status.SingleFalse) + case ZLine(opcode, registers, _, _) => currentStatus = currentStatus.copy(cf = AnyStatus, zf = AnyStatus, sf = AnyStatus, pf = AnyStatus, hf = AnyStatus) if (ZOpcodeClasses.ChangesAAlways(opcode)) currentStatus = currentStatus.copy(a = AnyStatus) diff --git a/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala index cd4a02ed..cbb5c5f2 100644 --- a/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala @@ -227,6 +227,8 @@ object ReverseFlowAnalyzer { currentImportance = currentImportance.butWritesRegister(t, o).butReadsRegister(s, o) case ZLine(LD | LD_16, TwoRegisters(t, s), _, _) => currentImportance = currentImportance.butWritesRegister(t).butReadsRegister(s) + case ZLine(EX_DE_HL, TwoRegisters(t, s), _, _) => + currentImportance = currentImportance.copy(d = currentImportance.h, e = currentImportance.l, h = currentImportance.d, l = currentImportance.e) case ZLine(ADD_16, TwoRegisters(t, s), _, _) => currentImportance = currentImportance.butReadsRegister(t).butReadsRegister(s) case ZLine(ADC_16 | SBC_16, TwoRegisters(t, s), _, _) => @@ -243,7 +245,7 @@ object ReverseFlowAnalyzer { ) case ZLine(OR | AND, OneRegister(ZRegister.A), _, _) => currentImportance = currentImportance.copy( - a = currentImportance.zf ~ currentImportance.sf ~ currentImportance.pf, + a = currentImportance.zf ~ currentImportance.sf ~ currentImportance.pf ~ currentImportance.a, cf = Unimportant, zf = Unimportant, sf = Unimportant, @@ -429,9 +431,13 @@ object ReverseFlowAnalyzer { } case ZLine(SLA | SRL, OneRegister(r), _, _) => - currentImportance = currentImportance.butReadsRegister(r).butWritesFlag(ZFlag.C).butWritesFlag(ZFlag.Z) + currentImportance = currentImportance.butReadsRegister(r).copy(cf = Unimportant, zf = Unimportant, hf = Unimportant, nf = Unimportant, pf = Unimportant) case ZLine(RL | RR | RLC | RRC, OneRegister(r), _, _) => - currentImportance = currentImportance.butReadsRegister(r).butReadsFlag(ZFlag.C).butWritesFlag(ZFlag.Z) + currentImportance = currentImportance.butReadsRegister(r).copy(cf = Important, zf = Unimportant, hf = Unimportant, nf = Unimportant, pf = Unimportant) + case ZLine(SWAP, OneRegister(r), _, _) => + currentImportance = currentImportance.butReadsRegister(r).copy(cf = Unimportant, zf = Unimportant, hf = Unimportant, nf = Unimportant, pf = Unimportant) + case ZLine(RLA | RRA | RLCA | RRCA, _, _, _) => + currentImportance = currentImportance.butReadsRegister(ZRegister.A).copy(cf = Important, hf = Unimportant, nf = Unimportant) case _ => currentImportance = finalImportance // TODO } diff --git a/src/main/scala/millfork/compiler/z80/Z80BulkMemoryOperations.scala b/src/main/scala/millfork/compiler/z80/Z80BulkMemoryOperations.scala index b46d3ffe..cbe69db7 100644 --- a/src/main/scala/millfork/compiler/z80/Z80BulkMemoryOperations.scala +++ b/src/main/scala/millfork/compiler/z80/Z80BulkMemoryOperations.scala @@ -278,7 +278,7 @@ object Z80BulkMemoryOperations { // TODO: tricks with AND? for (_ <- 0 until n.toInt) { builder += ZLine.register(OR, ZRegister.A) - builder += ZLine.register(RR, ZRegister.A) + builder += ZLine.implied(RRA) } builder += ZLine.ld8(element, ZRegister.A) Some(builder.toList) diff --git a/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala b/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala index 8d911d53..d7ce4e5b 100644 --- a/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala +++ b/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala @@ -89,7 +89,7 @@ object Z80DecimalBuiltIns { case 1 => Nil case x => val add1 = List(ZLine.register(ADD, D), ZLine.implied(DAA), ZLine.ld8(E, A)) - val times10 = List(ZLine.register(RL, A), ZLine.register(RL, A), ZLine.register(RL, A), ZLine.register(RL, A), ZLine.imm8(AND, 0xf0)) + val times10 = List(ZLine.implied(RLA), ZLine.implied(RLA), ZLine.implied(RLA), ZLine.implied(RLA), ZLine.imm8(AND, 0xf0)) // TODO: rethink this: val ways = if (ctx.options.flag(CompilationFlag.OptimizeForSpeed)) waysOptimizedForCycles else waysOptimizedForBytes ZLine.ld8(D, A) :: ZLine.ld8(E, A) :: ways(x).flatMap { diff --git a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala index 3ad83617..6c555736 100644 --- a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala @@ -497,7 +497,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] { List( ZLine.ld8(ZRegister.L, ZRegister.A), ZLine.ldImm8(ZRegister.A, 0), - ZLine.register(RL, ZRegister.A), + ZLine.implied(RLA), ZLine.ld8(ZRegister.H, ZRegister.A)) } case ZExpressionTarget.BC => @@ -510,7 +510,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] { List( ZLine.ld8(ZRegister.C, ZRegister.A), ZLine.ldImm8(ZRegister.A, 0), - ZLine.register(RL, ZRegister.A), + ZLine.implied(RLA), ZLine.ld8(ZRegister.B, ZRegister.A)) } case ZExpressionTarget.DE => @@ -523,7 +523,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] { List( ZLine.ld8(ZRegister.E, ZRegister.A), ZLine.ldImm8(ZRegister.A, 0), - ZLine.register(RL, ZRegister.A), + ZLine.implied(RLA), ZLine.ld8(ZRegister.D, ZRegister.A)) } }) diff --git a/src/main/scala/millfork/compiler/z80/Z80Multiply.scala b/src/main/scala/millfork/compiler/z80/Z80Multiply.scala index cadf1606..080729ee 100644 --- a/src/main/scala/millfork/compiler/z80/Z80Multiply.scala +++ b/src/main/scala/millfork/compiler/z80/Z80Multiply.scala @@ -54,9 +54,10 @@ object Z80Multiply { label(lblStart), register(OR, A), ld8(A, D), - register(RR, A), + implied(RRA), ld8(D, A), jumpR(ctx, lblAdd, IfFlagSet(ZFlag.C)), + register(OR, A), jumpR(ctx, lblLoop, IfFlagClear(ZFlag.Z)), ld8(A, C)) } diff --git a/src/main/scala/millfork/compiler/z80/Z80Shifting.scala b/src/main/scala/millfork/compiler/z80/Z80Shifting.scala index fc21358d..05460cdc 100644 --- a/src/main/scala/millfork/compiler/z80/Z80Shifting.scala +++ b/src/main/scala/millfork/compiler/z80/Z80Shifting.scala @@ -26,9 +26,9 @@ object Z80Shifting { val extendedOps = ctx.options.flag(CompilationFlag.EmitExtended80Opcodes) val op = if (extendedOps) { - if (left) ZOpcode.ADD else ZOpcode.SRL + if (left) ZLine.register(ZOpcode.ADD, ZRegister.A) else ZLine.register(ZOpcode.SRL, ZRegister.A) } else { - if (left) ZOpcode.ADD else ZOpcode.RRC + if (left) ZLine.register(ZOpcode.ADD, ZRegister.A) else ZLine.implied(ZOpcode.RRCA) } val l = Z80ExpressionCompiler.compileToA(ctx, lhs) env.eval(rhs) match { @@ -38,12 +38,12 @@ object Z80Shifting { } else if (i >= 8) { l :+ ZLine.ldImm8(ZRegister.A, 0) } else { - l ++ List.tabulate(i.toInt)(_ => ZLine.register(op, ZRegister.A)) ++ fixAfterShiftIfNeeded(extendedOps, left, i) + l ++ List.tabulate(i.toInt)(_ => op) ++ fixAfterShiftIfNeeded(extendedOps, left, i) } case _ => val calcCount = Z80ExpressionCompiler.compileToA(ctx, rhs) :+ ZLine.ld8(ZRegister.B, ZRegister.A) val l = Z80ExpressionCompiler.stashBCIfChanged(ctx, Z80ExpressionCompiler.compileToA(ctx, lhs)) - val loopBody = ZLine.register(op, ZRegister.A) :: fixAfterShiftIfNeeded(extendedOps, left, 1) + val loopBody = op :: fixAfterShiftIfNeeded(extendedOps, left, 1) val label = Z80Compiler.nextLabel("sh") calcCount ++ l ++ List(ZLine.label(label)) ++ loopBody ++ ZLine.djnz(ctx, label) } @@ -52,11 +52,11 @@ object Z80Shifting { def compile8BitShiftInPlace(ctx: CompilationContext, lhs: LhsExpression, rhs: Expression, left: Boolean): List[ZLine] = { val env = ctx.env val extendedOps = ctx.options.flag(CompilationFlag.EmitExtended80Opcodes) - val op = + val (op, opLine) = if (extendedOps) { - if (left) ZOpcode.ADD else ZOpcode.SRL + if (left) ZOpcode.ADD -> ZLine.register(ZOpcode.ADD, ZRegister.A) else ZOpcode.SRL -> ZLine.register(ZOpcode.SRL, ZRegister.A) } else { - if (left) ZOpcode.ADD else ZOpcode.RRC + if (left) ZOpcode.ADD -> ZLine.register(ZOpcode.ADD, ZRegister.A) else ZOpcode.LABEL -> ZLine.implied(ZOpcode.RRCA) } env.eval(rhs) match { case Some(NumericConstant(i, _)) => @@ -110,7 +110,7 @@ object Z80Shifting { l ++ List.tabulate(i.toInt)(_ => ZLine.register(ZOpcode.SLA, register)) } else { l ++ List(ZLine.ld8(ZRegister.A, register)) ++ - List.tabulate(i.toInt)(_ => ZLine.register(op, ZRegister.A)) ++ + List.tabulate(i.toInt)(_ => opLine) ++ fixAfterShiftIfNeeded(extendedOps, left, i) ++ List(ZLine.ld8(register, ZRegister.A)) } @@ -150,18 +150,18 @@ object Z80Shifting { l ++ (1L until i).flatMap(_ => List( ZLine.ld8(ZRegister.A, ZRegister.H), ZLine.register(ZOpcode.OR, ZRegister.A), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.H, ZRegister.A), ZLine.ld8(ZRegister.A, ZRegister.L), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.L, ZRegister.A) )) ++ List( ZLine.ld8(ZRegister.A, ZRegister.H), ZLine.register(ZOpcode.OR, ZRegister.A), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.H, ZRegister.A), ZLine.ld8(ZRegister.A, ZRegister.L), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.L, ZRegister.A) ) } @@ -187,16 +187,16 @@ object Z80Shifting { ZLine.register(ZOpcode.ADD, ZRegister.A), ZLine.ld8(ZRegister.L, ZRegister.A), ZLine.ld8(ZRegister.A, ZRegister.H), - ZLine.register(ZOpcode.RL, ZRegister.A), + ZLine.implied(ZOpcode.RLA), ZLine.ld8(ZRegister.H, ZRegister.A)) } else { List( ZLine.ld8(ZRegister.A, ZRegister.H), ZLine.register(ZOpcode.OR, ZRegister.A), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.H, ZRegister.A), ZLine.ld8(ZRegister.A, ZRegister.L), - ZLine.register(ZOpcode.RR, ZRegister.A), + ZLine.implied(ZOpcode.RRA), ZLine.ld8(ZRegister.L, ZRegister.A)) } } @@ -221,14 +221,14 @@ object Z80Shifting { if (extended) List(ZLine.register(SRL, H), ZLine.ld8(A, L), ZLine.register(RR, A)) else - List(ZLine.ld8(A, H), ZLine.register(RR, A), ZLine.ld8(A, L), ZLine.register(RR, A)) + List(ZLine.ld8(A, H), ZLine.implied(RRA), ZLine.ld8(A, L), ZLine.implied(RRA)) case Some(NumericConstant(2, _)) if extended=> - List(ZLine.register(SRL, H), ZLine.ld8(A, L), ZLine.register(RR, A), ZLine.register(SRL, A)) + List(ZLine.register(SRL, H), ZLine.ld8(A, L), ZLine.implied(RRA), ZLine.register(SRL, A)) case Some(NumericConstant(n, _)) => if (extended) - List(ZLine.register(SRL, H), ZLine.ld8(A, L)) ++ (List.fill(n.toInt)(ZLine.register(RR, A)) :+ ZLine.imm8(AND, 0x1ff >> n)) + List(ZLine.register(SRL, H), ZLine.ld8(A, L)) ++ (List.fill(n.toInt)(ZLine.implied(RRA)) :+ ZLine.imm8(AND, 0x1ff >> n)) else - List(ZLine.ld8(A, H), ZLine.register(RR, A), ZLine.ld8(A, L)) ++ (List.fill(n.toInt)(ZLine.register(RR, A)) :+ ZLine.imm8(AND, 0x1ff >> n)) + List(ZLine.ld8(A, H), ZLine.implied(RRA), ZLine.ld8(A, L)) ++ (List.fill(n.toInt)(ZLine.implied(RRA)) :+ ZLine.imm8(AND, 0x1ff >> n)) case _ => ctx.log.error("Non-constant shift amount", rhs.position) // TODO @@ -247,7 +247,7 @@ object Z80Shifting { import ZRegister._ val shiftByte = if (ix == 0) List(ZLine.register(ADD, A)) - else List(ZLine.register(RL, A)) + else List(ZLine.implied(RLA)) ld ++ shiftByte ++ st } } else { @@ -257,8 +257,8 @@ object Z80Shifting { import ZRegister._ val shiftByte = if (ix == 0) { if (extended) List(ZLine.register(SRL, A)) - else List(ZLine.register(OR, A), ZLine.register(RR, A)) - } else List(ZLine.register(RR, A)) + else List(ZLine.register(OR, A), ZLine.implied(RRA)) + } else List(ZLine.implied(RRA)) ld ++ shiftByte ++ st } } diff --git a/src/main/scala/millfork/output/Z80Assembler.scala b/src/main/scala/millfork/output/Z80Assembler.scala index cc9b2719..59bba5d1 100644 --- a/src/main/scala/millfork/output/Z80Assembler.scala +++ b/src/main/scala/millfork/output/Z80Assembler.scala @@ -245,9 +245,6 @@ class Z80Assembler(program: Program, val o = oneRegister(op) writeByte(bank, index, o.opcode + internalRegisterIndex(reg) * o.multiplier) index + 1 - case ZLine(op@(RR|RRC|RL|RLC), OneRegister(A), _, _) => - writeByte(bank, index, cbOneRegister(op).opcode + 7) - index + 1 case ZLine(SLL, OneRegister(reg), _, _) => requireZ80Illegals() writeByte(bank, index, 0xcb) @@ -641,6 +638,10 @@ object Z80Assembler { implieds(EI) = 0xfb implieds(DI) = 0xf3 implieds(HALT) = 0x76 + implieds(RLCA) = 7 + implieds(RRCA) = 0xf + implieds(RLA) = 0x17 + implieds(RRA) = 0x1f immediates(ADD) = 0xc6 immediates(ADC) = 0xce diff --git a/src/main/scala/millfork/parser/Z80Parser.scala b/src/main/scala/millfork/parser/Z80Parser.scala index 41f87a47..b19177a9 100644 --- a/src/main/scala/millfork/parser/Z80Parser.scala +++ b/src/main/scala/millfork/parser/Z80Parser.scala @@ -198,10 +198,10 @@ case class Z80Parser(filename: String, input: String, currentDirectory: String, case "DEC" => one8Register(DEC) case "INC" => one8Register(INC) - case "RLA" => regA(RL) - case "RRA" => regA(RR) - case "RLCA" => regA(RLC) - case "RRCA" => regA(RRC) + case "RLA" => imm(RLA) + case "RRA" => imm(RRA) + case "RLCA" => imm(RLCA) + case "RRCA" => imm(RRCA) case "RL" => one8Register(RL) case "RR" => one8Register(RR) case "RLC" => one8Register(RLC)