1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-07 16:29:59 +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 ">>>>" => case ">>>>" =>
val (l, r, 2) = assertArithmeticBinary(ctx, params) val (l, r, 2) = assertArithmeticBinary(ctx, params)
??? targetifyA(target, compileToHL(ctx, l) ++ Z80Shifting.compileNonetShiftRight(ctx, r), isSigned = false)
case "<<" => case "<<" =>
val (l, r, size) = assertArithmeticBinary(ctx, params) val (l, r, size) = assertArithmeticBinary(ctx, params)
size match { size match {

View File

@ -4,6 +4,7 @@ import millfork.CompilationFlag
import millfork.assembly.z80.{NoRegisters, ZLine, ZOpcode} import millfork.assembly.z80.{NoRegisters, ZLine, ZOpcode}
import millfork.compiler.CompilationContext import millfork.compiler.CompilationContext
import millfork.env.NumericConstant import millfork.env.NumericConstant
import millfork.error.ErrorReporting
import millfork.node.{Expression, LhsExpression, ZRegister} import millfork.node.{Expression, LhsExpression, ZRegister}
import scala.collection.GenTraversableOnce 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) val o = oneRegister(op)
writeByte(bank, index, o.opcode + internalRegisterIndex(reg) * o.multiplier) writeByte(bank, index, o.opcode + internalRegisterIndex(reg) * o.multiplier)
index + 1 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) => case ZLine(op, OneRegister(reg), _, _) if cbOneRegister.contains(op) =>
val o = cbOneRegister(op) val o = cbOneRegister(op)
writeByte(bank, index, 0xcb) writeByte(bank, index, 0xcb)

View File

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