mirror of
https://github.com/KarolS/millfork.git
synced 2025-03-18 18:29:29 +00:00
6809: Implement +', -' and <<' operators for bytes
This commit is contained in:
parent
2d19537ed3
commit
78a680c0d6
@ -88,7 +88,7 @@ object M6809Buitins {
|
||||
case (false, false) => MathOperator.Plus
|
||||
case (true, false) => MathOperator.Minus
|
||||
case (false, true) => MathOperator.DecimalPlus
|
||||
case (false, true) => MathOperator.DecimalMinus
|
||||
case (true, true) => MathOperator.DecimalMinus
|
||||
},
|
||||
constant, c
|
||||
).quickSimplify
|
||||
@ -133,27 +133,51 @@ object M6809Buitins {
|
||||
val result = ListBuffer[MLine]()
|
||||
for ((neg, load) <- addendReads) {
|
||||
if (result.isEmpty && fromScratch) {
|
||||
result ++= load
|
||||
if (neg) result += MLine.inherentB(NEG)
|
||||
if (expr.decimal) {
|
||||
if (load.nonEmpty && load.last.opcode == LDB) {
|
||||
result ++= load.init
|
||||
result += load.last.copy(opcode = LDA)
|
||||
} else {
|
||||
result ++= load
|
||||
result += MLine.tfr(M6809Register.B, M6809Register.A)
|
||||
}
|
||||
if (neg) ???
|
||||
} else {
|
||||
result ++= load
|
||||
if (neg) result += MLine.inherentB(NEG)
|
||||
}
|
||||
} else {
|
||||
load match {
|
||||
case List(l@MLine0(LDB, _, _)) =>
|
||||
if (neg) {
|
||||
result += l.copy(opcode = sub)
|
||||
if (expr.decimal) ???
|
||||
if (expr.decimal) {
|
||||
result += MLine.pp(PSHS, M6809Register.A)
|
||||
result += MLine.immediate(LDA, 0x9a)
|
||||
result += l.copy(opcode = SUBA)
|
||||
result += MLine.accessAndPullS(ADDA)
|
||||
result += MLine.inherent(DAA)
|
||||
} else {
|
||||
result += l.copy(opcode = sub)
|
||||
}
|
||||
} else {
|
||||
result += l.copy(opcode = add)
|
||||
if (expr.decimal) result += MLine.inherent(DAA)
|
||||
}
|
||||
case _ =>
|
||||
if (expr.decimal) {
|
||||
result += MLine.pp(PSHS, M6809Register.A)
|
||||
result ++= load
|
||||
result += MLine.pp(PULS, M6809Register.A)
|
||||
if (neg) {
|
||||
???
|
||||
if (expr.decimal) ???
|
||||
result += MLine.pp(PSHS, M6809Register.A)
|
||||
result ++= load
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.immediate(LDA, 0x9a)
|
||||
result += MLine.accessAndPullS(SUBA)
|
||||
result += MLine.accessAndPullS(ADDA)
|
||||
result += MLine.inherent(DAA)
|
||||
} else {
|
||||
result += MLine.pp(PSHS, M6809Register.A)
|
||||
result ++= load
|
||||
result += MLine.pp(PULS, M6809Register.A)
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.accessAndPullS(ADDA)
|
||||
result += MLine.inherent(DAA)
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
package millfork.compiler.m6809
|
||||
|
||||
import millfork.assembly.m6809.MLine
|
||||
import millfork.compiler.CompilationContext
|
||||
import millfork.node.Expression
|
||||
import millfork.assembly.m6809.MOpcode._
|
||||
import millfork.env.NumericConstant
|
||||
import millfork.node.M6809Register._
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object M6809DecimalBuiltins {
|
||||
|
||||
def compileByteDecimalShiftLeft(ctx: CompilationContext, lhs: Option[Expression], rhs: Expression): List[MLine] = {
|
||||
val load = lhs match {
|
||||
case None => List(MLine.indexedX(LDA, 0))
|
||||
case Some(l) => M6809ExpressionCompiler.compileToA(ctx, l)
|
||||
}
|
||||
val loop = ctx.env.eval(rhs) match {
|
||||
case Some(NumericConstant(0, _)) => Nil
|
||||
case Some(NumericConstant(1, _)) => List(
|
||||
MLine.pp(PSHS, A),
|
||||
MLine.accessAndPullS(ADDA),
|
||||
MLine.inherent(DAA)
|
||||
)
|
||||
case _ =>
|
||||
val labelSkip = ctx.nextLabel("ss")
|
||||
val labelRepeat = ctx.nextLabel("sr")
|
||||
M6809ExpressionCompiler.stashAIfNeeded(ctx, M6809ExpressionCompiler.compileToB(ctx, rhs)) ++ List(
|
||||
MLine.label(labelRepeat),
|
||||
MLine.immediate(CMPB, 0),
|
||||
MLine.shortBranch(BEQ, labelSkip),
|
||||
MLine.pp(PSHS, A),
|
||||
MLine.accessAndPullS(ADDA),
|
||||
MLine.inherent(DAA),
|
||||
MLine.inherentB(DEC),
|
||||
MLine.shortBranch(BRA, labelRepeat),
|
||||
MLine.label(labelSkip)
|
||||
)
|
||||
}
|
||||
val store = lhs match {
|
||||
case None => List(MLine.indexedX(STA, 0))
|
||||
case Some(l) => Nil
|
||||
}
|
||||
load ++ loop ++ store
|
||||
}
|
||||
}
|
@ -345,7 +345,12 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
M6809Buitins.compileWordShiftForD(ctx, params(1), left = false) ++
|
||||
targetifyB(ctx, target, isSigned = false)
|
||||
}
|
||||
case "<<'" => ???
|
||||
case "<<'" =>
|
||||
assertArithmeticBinary(ctx, params) match {
|
||||
case (l, r, 1) => M6809DecimalBuiltins.compileByteDecimalShiftLeft(ctx, Some(l), r) ++ targetifyA(ctx, target, isSigned = false)
|
||||
case (l, r, 2) => ???
|
||||
case (l, r, _) => ???
|
||||
}
|
||||
case ">>'" => ???
|
||||
case "+=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -354,7 +359,22 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true)
|
||||
case _ => ctx.log.error("Long addition not implemented yet", fce.position); Nil
|
||||
}
|
||||
case "+'=" => ???
|
||||
case "+'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 =>
|
||||
val lc = compileAddressToX(ctx, l)
|
||||
val rc = compileToA(ctx, r)
|
||||
val add = List(MLine.indexedX(ADDA, 0), MLine.inherent(DAA), MLine.indexedX(STA, 0))
|
||||
(lc.exists(_.changesRegister(M6809Register.A)), rc.exists(_.changesRegister(M6809Register.X))) match {
|
||||
case (false, false) => rc ++ lc ++ add
|
||||
case (false, true) => rc ++ lc ++ add
|
||||
case (true, false) => lc ++ rc ++ add
|
||||
case (true, true) => rc ++ stashAIfNeeded(ctx, lc) ++ add
|
||||
}
|
||||
case 2 => ???
|
||||
case _ => ???
|
||||
}
|
||||
case "-=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
@ -362,7 +382,17 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false)
|
||||
case _ => ???
|
||||
}
|
||||
case "-'=" => ???
|
||||
case "-'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 =>
|
||||
val lc = compileAddressToX(ctx, l)
|
||||
val rc = compileToB(ctx, r)
|
||||
lc ++ List(MLine.pp(PSHS, M6809Register.B)) ++
|
||||
rc ++ List(MLine.pp(PSHS, M6809Register.B), MLine.immediate(LDA, 0x9a), MLine.accessAndPullS(SUBA), MLine.accessAndPullS(ADDA), MLine.inherent(DAA), MLine.indexedX(STA, 0))
|
||||
case 2 => ???
|
||||
case _ => ???
|
||||
}
|
||||
case "*=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
@ -412,7 +442,13 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
case 2 =>
|
||||
handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true))
|
||||
}
|
||||
case "<<'=" => ???
|
||||
case "<<'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 =>
|
||||
compileAddressToX(ctx, l) ++ M6809DecimalBuiltins.compileByteDecimalShiftLeft(ctx, None, r)
|
||||
case 2 => ???
|
||||
}
|
||||
case ">>=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
// TODO: optimize shifts directly in memory
|
||||
|
@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
|
||||
class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
|
||||
test("Decimal byte addition") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| byte a
|
||||
@ -22,7 +22,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Decimal byte addition 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| byte a
|
||||
@ -62,7 +62,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Decimal byte subtraction") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| byte a
|
||||
@ -74,7 +74,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("In-place decimal byte addition") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| array output[3] @$c000
|
||||
| byte a
|
||||
@ -88,7 +88,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("In-place decimal byte addition 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| array output[3] @$c000
|
||||
| void main () {
|
||||
@ -108,7 +108,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("In-place decimal byte subtraction") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| byte a
|
||||
@ -181,7 +181,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Flag switching test") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
@ -192,7 +192,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Flag switching test 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
@ -203,7 +203,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Flag switching test 3") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
@ -214,7 +214,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Decimal left shift test") {
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
@ -229,7 +229,7 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Decimal left shift test 2") {
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086)(
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Ricoh, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
|
@ -22,6 +22,8 @@ class M6809Memory(memoryBank: MemoryBank, resetVector: Int) extends MemorySegmen
|
||||
|
||||
override def load(addr: Int): Int = {
|
||||
if (!memoryBank.readable(addr)) {
|
||||
val start = addr & 0xff00
|
||||
(0 until 0x100).grouped(16).map(range => (start + range.head).toHexString + range.map(i => memoryBank.output(start + i)).map(v => f" $v%02X").mkString("")).foreach(println)
|
||||
println(s"Accessing memory for read at $$${addr.toHexString}")
|
||||
???
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user