1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Z80: The >>>> operator

This commit is contained in:
Karol Stasiak 2018-07-23 13:49:59 +02:00
parent a39064cf76
commit 85243c96a7
4 changed files with 38 additions and 9 deletions

View File

@ -322,7 +322,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
}
case ">>>>" =>
val (l, r, 2) = assertArithmeticBinary(ctx, params)
???
targetifyA(target, compileToHL(ctx, l) ++ Z80Shifting.compileNonetShiftRight(ctx, r), isSigned = false)
case "<<" =>
val (l, r, size) = assertArithmeticBinary(ctx, params)
size match {

View File

@ -4,6 +4,7 @@ import millfork.CompilationFlag
import millfork.assembly.z80.{NoRegisters, ZLine, ZOpcode}
import millfork.compiler.CompilationContext
import millfork.env.NumericConstant
import millfork.error.ErrorReporting
import millfork.node.{Expression, LhsExpression, ZRegister}
import scala.collection.GenTraversableOnce
@ -185,4 +186,28 @@ object Z80Shifting {
}
}
def compileNonetShiftRight(ctx: CompilationContext, rhs: Expression): List[ZLine] = {
import ZOpcode._
import ZRegister._
ctx.env.eval(rhs) match {
case Some(NumericConstant(0, _)) =>
List(ZLine.ld8(A, L))
case Some(NumericConstant(n, _)) if n < 0 =>
ErrorReporting.error("Negative shift amount", rhs.position) // TODO
Nil
case Some(NumericConstant(n, _)) if n >= 9 =>
List(ZLine.ldImm8(A, 0))
case Some(NumericConstant(1, _)) =>
List(ZLine.register(SRL, H), ZLine.ld8(A, L), ZLine.register(RR, A))
case Some(NumericConstant(2, _)) =>
List(ZLine.register(SRL, H), ZLine.ld8(A, L), ZLine.register(RR, A), ZLine.register(SRL, A))
case Some(NumericConstant(n, _)) =>
List(ZLine.register(SRL, H), ZLine.ld8(A, L)) ++ (List.fill(n.toInt)(ZLine.register(RR, A)) :+ ZLine.imm8(AND, 0x1ff >> n))
case _ =>
ErrorReporting.error("Non-constant shift amount", rhs.position) // TODO
Nil
}
}
}

View File

@ -140,6 +140,9 @@ 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(op, OneRegister(reg), _, _) if cbOneRegister.contains(op) =>
val o = cbOneRegister(op)
writeByte(bank, index, 0xcb)

View File

@ -1,7 +1,7 @@
package millfork.test
import millfork.Cpu
import millfork.test.emu.{EmuBenchmarkRun, EmuCrossPlatformBenchmarkRun, EmuUnoptimizedRun}
import millfork.test.emu.{EmuBenchmarkRun, EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun}
import org.scalatest.{FunSuite, Matchers}
/**
@ -10,22 +10,23 @@ import org.scalatest.{FunSuite, Matchers}
class NonetSuite extends FunSuite with Matchers {
test("Nonet operations") {
val m = EmuUnoptimizedRun(
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)(
"""
| array output [3] @$c000
| array input = [5,6,7]
| array output [5] @$c000
| void main () {
| word a
| a = $110
| output[1] = a >>>> 1
| output[2] = a >>>> 2
| output[3] = a >>>> 3
| output[4] = a >>>> 4
| }
| void copyEntry(byte index) {
| output[index] = input[index]
| }
""".stripMargin)
""".stripMargin) { m =>
m.readByte(0xc001) should equal(0x88)
m.readByte(0xc002) should equal(0x44)
m.readByte(0xc003) should equal(0x22)
m.readByte(0xc004) should equal(0x11)
}
}
test("Nonet left shift") {