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:
parent
a39064cf76
commit
85243c96a7
@ -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 {
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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") {
|
||||||
|
Loading…
Reference in New Issue
Block a user