mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-27 11:30:19 +00:00
Z80: RLA and RL A are two very different instructions
This commit is contained in:
parent
2ef79d6894
commit
453ce93952
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
})
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user