mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-13 21:37:08 +00:00
6809: Improved support for large types
This commit is contained in:
parent
88b2bbd434
commit
b387ece71d
@ -38,6 +38,8 @@ object MLine {
|
||||
|
||||
def tfr(source: M6809Register.Value, target: M6809Register.Value): MLine = MLine(TFR, TwoRegisters(source, target), Constant.Zero)
|
||||
|
||||
def exg(source: M6809Register.Value, target: M6809Register.Value): MLine = MLine(EXG, TwoRegisters(source, target), Constant.Zero)
|
||||
|
||||
def pp(opcode: MOpcode.Value, registers: M6809Register.Value*): MLine = MLine(opcode, RegisterSet(registers.toSet), Constant.Zero)
|
||||
|
||||
def indexedS(opcode: MOpcode.Value, offset: Int = 0): MLine =
|
||||
@ -79,12 +81,12 @@ object MLine {
|
||||
|
||||
def variable(ctx: CompilationContext, opcode : MOpcode.Value, variable: Variable, offset: Int = 0): MLine = {
|
||||
variable match {
|
||||
case v: VariableInMemory => MLine.absolute(opcode, v.toAddress)
|
||||
case v: VariableInMemory => MLine.absolute(opcode, v.toAddress + offset)
|
||||
case v: StackVariable =>
|
||||
val size = variable.typ.size
|
||||
if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset, size))
|
||||
else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset, size))
|
||||
else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset, size))
|
||||
if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset + offset, size))
|
||||
else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset + offset, size))
|
||||
else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset + offset, size))
|
||||
case _ => ???
|
||||
}
|
||||
}
|
||||
@ -177,9 +179,9 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
|
||||
case (EXG, TwoRegisters(r1, r2)) => overlaps(r1) || overlaps(r2)
|
||||
case (op, _) if MOpcode.ChangesAAlways(op) => overlaps(A) || addrMode.changesRegister(reg)
|
||||
case (op, _) if MOpcode.ChangesBAlways(op) => overlaps(B) || addrMode.changesRegister(reg)
|
||||
case (LDA, _) => overlaps(A) || addrMode.changesRegister(reg)
|
||||
case (LDB, _) => overlaps(B) || addrMode.changesRegister(reg)
|
||||
case (LDD, _) => overlaps(D) || addrMode.changesRegister(reg)
|
||||
case (LDA | ANDA | ADDA | ADCA | SUBA | SBCA | EORA | ORA | BITA, _) => overlaps(A) || addrMode.changesRegister(reg)
|
||||
case (LDB | ANDB | ADDB | ADCB | SUBB | SBCB | EORB | ORB | BITB, _) => overlaps(B) || addrMode.changesRegister(reg)
|
||||
case (LDD | ADDD | SUBD, _) => overlaps(D) || addrMode.changesRegister(reg)
|
||||
case (LDU | LEAU, _) => reg == U || addrMode.changesRegister(reg)
|
||||
case (LDS | LEAS, _) => reg == S || addrMode.changesRegister(reg)
|
||||
case (LDX | LEAX, _) => reg == X || addrMode.changesRegister(reg)
|
||||
@ -187,10 +189,17 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
|
||||
case (MUL, _) => overlaps(D)
|
||||
case (ABX, _) => reg == X
|
||||
case (NOP | SWI | SWI2 | SWI3 | SYNC, _) => false
|
||||
case _ => true // TODO
|
||||
case (STA | STB | STD | STS | STU | STX | STY, _) => false
|
||||
case (SEX | DAA, _) => overlaps(A)
|
||||
case (JSR | SWI | SWI2 | SWI3, _) => true
|
||||
case _ => addrMode.changesRegister(reg)
|
||||
}
|
||||
}
|
||||
|
||||
def changesCarryFlag: Boolean = !MOpcode.PreservesC(opcode)
|
||||
|
||||
|
||||
|
||||
def readsRegister(reg: M6809Register.Value): Boolean = {
|
||||
import M6809Register._
|
||||
def overlaps(other: M6809Register.Value): Boolean = {
|
||||
|
@ -46,7 +46,6 @@ object MOpcode extends Enumeration {
|
||||
val ChangesAAlways: Set[MOpcode.Value] = Set(ADDA, ADCA, SUBA, SBCA, ANDA, ORA, EORA, SEX, DAA)
|
||||
val ChangesBAlways: Set[MOpcode.Value] = Set(ADDB, ADCB, SUBB, SBCB, ANDB, ORB, EORB)
|
||||
val ChangesDAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
|
||||
val ChangesCFAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
|
||||
val ReadsAAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
|
||||
val AccessesWordInMemory: Set[MOpcode.Value] = Set(ADDD, SUBD, LDD, STD, LDX, LDY, LDU, LDS, STX, STY, STU, STS, CMPD, CMPX, CMPY, CMPU, CMPS)
|
||||
val AllLinear: Set[MOpcode.Value] = Set(
|
||||
@ -78,6 +77,15 @@ object MOpcode extends Enumeration {
|
||||
CMPA, CMPB, CMPD, CMPX, CMPY, CMPU, CMPS,
|
||||
MUL,
|
||||
)
|
||||
val PreservesC: Set[MOpcode.Value] = Set(
|
||||
ANDA, ANDB, BITA, BITB, DEC, EXG, INC,
|
||||
LDA, LDB, LDD, LDX, LDY, LDU, LDS,
|
||||
LEAS, LEAX, LEAY, LEAU,
|
||||
NOP, ORA, ORB,
|
||||
PSHS, PSHU, PULS, PULU,
|
||||
STA, STB, STD, STX, STY, STS, STU,
|
||||
TFR, TST
|
||||
)
|
||||
// The following are incomplete:
|
||||
val ChangesN: Set[MOpcode.Value] = Set(
|
||||
CWAI, ORCC, ANDCC,
|
||||
|
@ -1,11 +1,13 @@
|
||||
package millfork.compiler.m6809
|
||||
|
||||
import java.util.concurrent.AbstractExecutorService
|
||||
|
||||
import millfork.CompilationFlag
|
||||
import millfork.assembly.m6809.{DAccumulatorIndexed, Immediate, Indexed, InherentB, MLine, MLine0, MOpcode, RegisterSet, TwoRegisters}
|
||||
import millfork.compiler.{AbstractExpressionCompiler, BranchIfFalse, BranchIfTrue, BranchSpec, ComparisonType, CompilationContext, NoBranching}
|
||||
import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SeparateBytesExpression, SumExpression, VariableExpression}
|
||||
import millfork.assembly.m6809.MOpcode._
|
||||
import millfork.env.{AssemblyOrMacroParamSignature, BuiltInBooleanType, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FlagBooleanType, FunctionInMemory, FunctionPointerType, Label, M6809RegisterVariable, MacroFunction, MathOperator, MemoryAddressConstant, MemoryVariable, NonFatalCompilationException, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, ThingInMemory, Type, Variable, VariableInMemory, VariablePointy}
|
||||
import millfork.env.{AssemblyOrMacroParamSignature, BuiltInBooleanType, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FlagBooleanType, FunctionInMemory, FunctionPointerType, Label, M6809RegisterVariable, MacroFunction, MathOperator, MemoryAddressConstant, MemoryVariable, NonFatalCompilationException, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, StructureConstant, ThingInMemory, Type, Variable, VariableInMemory, VariablePointy}
|
||||
|
||||
import scala.collection.GenTraversableOnce
|
||||
|
||||
@ -357,7 +359,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
size match {
|
||||
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ADDB)
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true)
|
||||
case _ => ctx.log.error("Long addition not implemented yet", fce.position); Nil
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ADDB)
|
||||
}
|
||||
case "+'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -372,15 +374,14 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
case (true, false) => lc ++ rc ++ add
|
||||
case (true, true) => rc ++ stashAIfNeeded(ctx, lc) ++ add
|
||||
}
|
||||
case 2 => ???
|
||||
case _ => ???
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ADDA)
|
||||
}
|
||||
case "-=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, SUBB)
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false)
|
||||
case _ => ???
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, SUBB)
|
||||
}
|
||||
case "-'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -390,8 +391,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
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 _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, SUBA)
|
||||
}
|
||||
case "*=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -417,21 +417,21 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
size match {
|
||||
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ANDB)
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ANDA, ANDB, commutative = true)
|
||||
case _ => ???
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ANDB)
|
||||
}
|
||||
case "|=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ORB)
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ORA, ORB, commutative = true)
|
||||
case _ => ???
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ORB)
|
||||
}
|
||||
case "^=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
size match {
|
||||
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, EORB)
|
||||
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, EORA, EORB, commutative = true)
|
||||
case _ => ???
|
||||
case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, EORB)
|
||||
}
|
||||
case "<<=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -441,6 +441,8 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = true))
|
||||
case 2 =>
|
||||
handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true))
|
||||
case _ =>
|
||||
M6809LargeBuiltins.compileShiftInPlace(ctx, size, l, r, left = true)
|
||||
}
|
||||
case "<<'=" =>
|
||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||
@ -455,6 +457,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
size match {
|
||||
case 1 => handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = false))
|
||||
case 2 => handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = false))
|
||||
case _ => M6809LargeBuiltins.compileShiftInPlace(ctx, size, l, r, left = false)
|
||||
}
|
||||
case ">>'=" => ???
|
||||
case ">>>>=" => ???
|
||||
@ -499,7 +502,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
case 2 =>
|
||||
compileToD(ctx, paramExpr) ++ storeD(callCtx, VariableExpression(paramVar.name + "`aa"))
|
||||
case _ =>
|
||||
???
|
||||
M6809LargeBuiltins.storeLarge(callCtx, VariableExpression(paramVar.name + "`aa"), paramExpr)
|
||||
}
|
||||
}
|
||||
case AssemblyOrMacroParamSignature(signature) =>
|
||||
@ -647,6 +650,11 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
else lines
|
||||
}
|
||||
|
||||
def stashCarryIfNeeded(ctx: CompilationContext, lines: List[MLine]): List[MLine] = {
|
||||
if (lines.exists(_.changesCarryFlag)) MLine.pp(PSHS, M6809Register.CC) :: (lines :+ MLine.pp(PULS, M6809Register.CC))
|
||||
else lines
|
||||
}
|
||||
|
||||
def storeA(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashAIfNeeded, STA)
|
||||
|
||||
def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashBIfNeeded, STB)
|
||||
@ -839,4 +847,74 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
def compileToByteReads(ctx: CompilationContext, source: Expression, targetSize: Int): List[List[MLine]] = {
|
||||
val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, source)
|
||||
ctx.env.eval(source) match {
|
||||
case Some(const) =>
|
||||
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyteBe(targetSize - 1 - i, targetSize))))
|
||||
case None =>
|
||||
sourceType.size match {
|
||||
case 0 => ???
|
||||
case 1 =>
|
||||
List.tabulate(targetSize)(i =>
|
||||
if (sourceType.isSigned) {
|
||||
if (i == 0) compileToB(ctx, source) :+ MLine.tfr(M6809Register.B, M6809Register.A)
|
||||
else if (i == 1) List(
|
||||
MLine.tfr(M6809Register.A, M6809Register.B),
|
||||
MLine.inherent(SEX),
|
||||
MLine.tfr(M6809Register.B, M6809Register.A)
|
||||
)
|
||||
else List(MLine.tfr(M6809Register.A, M6809Register.B))
|
||||
} else {
|
||||
if (i == 0) compileToB(ctx, source)
|
||||
else List(MLine.immediate(LDB, 0))
|
||||
}
|
||||
)
|
||||
case 2 =>
|
||||
List.tabulate(targetSize)(i =>
|
||||
if (sourceType.isSigned) {
|
||||
if (i == 0) compileToD(ctx, source)
|
||||
else if (i == 1) List(MLine.tfr(M6809Register.A, M6809Register.B))
|
||||
else if (i == 2) {
|
||||
if (targetSize > 3) List(
|
||||
MLine.tfr(M6809Register.A, M6809Register.B),
|
||||
MLine.inherent(SEX),
|
||||
MLine.tfr(M6809Register.B, M6809Register.A)
|
||||
) else List(
|
||||
MLine.tfr(M6809Register.A, M6809Register.B),
|
||||
MLine.inherent(SEX)
|
||||
)
|
||||
} else List(MLine.tfr(M6809Register.A, M6809Register.B))
|
||||
} else {
|
||||
if (i == 0) compileToD(ctx, source)
|
||||
else if (i == 1) List(MLine.tfr(M6809Register.A, M6809Register.B))
|
||||
else List(MLine.immediate(LDB, 0))
|
||||
}
|
||||
)
|
||||
case _ =>
|
||||
source match {
|
||||
case LiteralExpression(value, size) =>
|
||||
val const = NumericConstant(value, size)
|
||||
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyte(i))))
|
||||
case GeneratedConstantExpression(const, _) =>
|
||||
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyteBe(targetSize - 1 - i, targetSize))))
|
||||
case VariableExpression(name) =>
|
||||
val v = ctx.env.get[Variable](name)
|
||||
List.tabulate(targetSize)(i => List(if (i < v.typ.size) MLine.variable(ctx, LDB, v, v.typ.size - 1 - i) else MLine.immediate(LDB, 0)))
|
||||
case e:FunctionCallExpression =>
|
||||
ctx.env.maybeGet[NormalFunction](e.functionName) match {
|
||||
case Some(function) =>
|
||||
val load = M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING)
|
||||
val v = ctx.env.get[VariableInMemory](function.name + ".return")
|
||||
List.tabulate(targetSize) { i =>
|
||||
if (i == 0) load :+ MLine.variable(ctx, LDB, v, v.typ.size - 1 - i)
|
||||
else List(if (i < v.typ.size) MLine.variable(ctx, LDB, v, v.typ.size - 1 - i) else MLine.immediate(LDB, 0))
|
||||
}
|
||||
case _ => ???
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
238
src/main/scala/millfork/compiler/m6809/M6809LargeBuiltins.scala
Normal file
238
src/main/scala/millfork/compiler/m6809/M6809LargeBuiltins.scala
Normal file
@ -0,0 +1,238 @@
|
||||
package millfork.compiler.m6809
|
||||
|
||||
import millfork.assembly.m6809.{Immediate, MLine, MLine0, MOpcode, TwoRegisters}
|
||||
import millfork.compiler.{AbstractExpressionCompiler, CompilationContext}
|
||||
import millfork.node.{Expression, LhsExpression, M6809Register}
|
||||
import millfork.assembly.m6809.MOpcode._
|
||||
import millfork.env.{Constant, NumericConstant}
|
||||
|
||||
import scala.collection.GenTraversableOnce
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object M6809LargeBuiltins {
|
||||
|
||||
def compileShiftInPlace(ctx: CompilationContext, size: Int, target: LhsExpression, shiftValue: Expression, left: Boolean): List[MLine] = {
|
||||
val (targetAddr, targetInit): (Option[Constant], List[MLine]) = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
|
||||
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr) -> Nil
|
||||
case xs => None -> xs
|
||||
}
|
||||
val oneShift = if (left) {
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
List.tabulate(size)(i => MLine.absolute(if (i == 0) ASL else ROL, addr + (size - 1 - i)))
|
||||
case None =>
|
||||
List.tabulate(size)(i => MLine.indexedX(if (i == 0) ASL else ROL, size - 1 - i))
|
||||
}
|
||||
} else {
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
List.tabulate(size)(i => MLine.absolute(if (i == 0) LSR else ROR, addr + i))
|
||||
case None =>
|
||||
List.tabulate(size)(i => MLine.indexedX(if (i == 0) LSR else ROR, i))
|
||||
}
|
||||
}
|
||||
targetInit ++ (M6809ExpressionCompiler.compileToB(ctx, shiftValue) match {
|
||||
case List(MLine0(LDB, Immediate, NumericConstant(n, _))) if n >= 0 && (n - 1) * size < 4 =>
|
||||
List.fill(n.toInt)(oneShift).flatten
|
||||
case xs@List(MLine0(LDB, Immediate, c)) if c.isProvablyGreaterOrEqualThan(1) =>
|
||||
val label = ctx.nextLabel("sr")
|
||||
xs ++ List(MLine.label(label)) ++ oneShift ++ List(MLine.inherentB(DEC), MLine.shortBranch(BNE, label))
|
||||
case xs =>
|
||||
val loop = ctx.nextLabel("sr")
|
||||
val skip = ctx.nextLabel("ss")
|
||||
M6809ExpressionCompiler.stashXIfNeeded(ctx, xs) ++ List(
|
||||
MLine.label(loop),
|
||||
MLine.inherentB(DEC),
|
||||
MLine.immediate(CMPB, -1),
|
||||
MLine.shortBranch(BEQ, skip)) ++ oneShift ++ List(
|
||||
MLine.shortBranch(BRA, loop),
|
||||
MLine.label(skip)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
def storeLarge(ctx: CompilationContext, target: LhsExpression, source: Expression): List[MLine] = {
|
||||
val byteCount = AbstractExpressionCompiler.getExpressionType(ctx, target).size
|
||||
val byteLoads = M6809ExpressionCompiler.compileToByteReads(ctx, source, byteCount)
|
||||
val (targetAddr, targetInit): (Option[Constant], List[MLine]) = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
|
||||
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr) -> Nil
|
||||
case xs => None -> xs
|
||||
}
|
||||
// TODO: use loop for very large structures
|
||||
// TODO: use D to speed up certain loads
|
||||
targetInit ++ byteLoads.zipWithIndex.flatMap{ case (loadByte, ix) =>
|
||||
M6809ExpressionCompiler.stashXIfNeeded(ctx, loadByte) :+ ( targetAddr match {
|
||||
case Some(addr) => MLine.absolute(STB, addr + (byteCount - 1 - ix))
|
||||
case None => MLine.indexedX(STB, byteCount - 1 - ix)
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
def convertToLda(ldb: List[MLine]): List[MLine] = {
|
||||
ldb match {
|
||||
case List(l@MLine0(LDB, _, _)) => List(l.copy(opcode = LDA))
|
||||
case List(l@MLine0(TFR, TwoRegisters(M6809Register.A, M6809Register.B), _)) => List(l.copy(addrMode = TwoRegisters(M6809Register.B, M6809Register.A)))
|
||||
case _ => MLine.exg(M6809Register.A, M6809Register.B) :: (ldb :+ MLine.exg(M6809Register.A, M6809Register.B))
|
||||
}
|
||||
}
|
||||
|
||||
def compileInc(ctx: CompilationContext, target: LhsExpression): List[MLine] = {
|
||||
val sizeInBytes = AbstractExpressionCompiler.getExpressionType(ctx, target).size
|
||||
val result = new ListBuffer[MLine]()
|
||||
val targetAddr: Option[Constant] = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
|
||||
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr)
|
||||
case xs =>
|
||||
result ++= xs
|
||||
None
|
||||
}
|
||||
val skipLabel = ctx.nextLabel("in")
|
||||
for (i <- 0 until sizeInBytes) {
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result += MLine.absolute(INC, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result += MLine.indexedX(INC, sizeInBytes - 1 - i)
|
||||
}
|
||||
if (i != sizeInBytes - 1) {
|
||||
result += MLine.shortBranch(BNE, skipLabel)
|
||||
}
|
||||
}
|
||||
result += MLine.label(skipLabel)
|
||||
result.toList
|
||||
}
|
||||
|
||||
def modifyInPlaceViaX(ctx: CompilationContext, target: LhsExpression, argument: Expression, opcode: MOpcode.Value): List[MLine] = {
|
||||
if (opcode == ADDB) ctx.env.eval(argument) match {
|
||||
case Some(NumericConstant(1, _)) =>
|
||||
return compileInc(ctx, target)
|
||||
case _ =>
|
||||
}
|
||||
val sizeInBytes = AbstractExpressionCompiler.getExpressionType(ctx, target).size
|
||||
val byteLoads = M6809ExpressionCompiler.compileToByteReads(ctx, argument, sizeInBytes)
|
||||
val result = new ListBuffer[MLine]()
|
||||
val targetAddr: Option[Constant] = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
|
||||
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr)
|
||||
case xs =>
|
||||
result ++= xs
|
||||
ctx.log.error("Invalid left-hand-side expression", target.position)
|
||||
None
|
||||
}
|
||||
var firstNonzeroByte = 0
|
||||
for (i <- 0 until sizeInBytes) {
|
||||
val ldb = byteLoads(i)
|
||||
val magicConstant =
|
||||
ldb match {
|
||||
case List(MLine0(LDB, Immediate, NumericConstant(x, _))) => Some(x.toInt & 0xff)
|
||||
case _ => None
|
||||
}
|
||||
(opcode, magicConstant) match {
|
||||
|
||||
case (ORB | EORB, Some(0)) =>
|
||||
// nothing
|
||||
case (ANDB, Some(0xff)) =>
|
||||
// nothing
|
||||
case (EORB, Some(0xff)) =>
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result += MLine.absolute(COM, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result += MLine.indexedX(COM, sizeInBytes - 1 - i)
|
||||
}
|
||||
|
||||
case (ADDB | SUBB | ADDA | SUBA, Some(0)) if i == firstNonzeroByte =>
|
||||
firstNonzeroByte = i + 1
|
||||
|
||||
case (SUBA, _) => ???
|
||||
|
||||
case (ADDA, _) if i == firstNonzeroByte =>
|
||||
val lda = convertToLda(ldb)
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= lda
|
||||
result += MLine.absolute(ADCA, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.inherent(DAA)
|
||||
result += MLine.absolute(STA, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, lda)
|
||||
result += MLine.indexedX(ADCA, sizeInBytes - 1 - i)
|
||||
result += MLine.inherent(DAA)
|
||||
result += MLine.indexedX(STA, sizeInBytes - 1 - i)
|
||||
}
|
||||
|
||||
case (ADDA, _) if i != firstNonzeroByte =>
|
||||
val lda = convertToLda(ldb)
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, lda)
|
||||
result += MLine.absolute(ADCA, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.inherent(DAA)
|
||||
result += MLine.absolute(STA, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, lda))
|
||||
result += MLine.indexedX(ADCA, sizeInBytes - 1 - i)
|
||||
result += MLine.inherent(DAA)
|
||||
result += MLine.indexedX(STA, sizeInBytes - 1 - i)
|
||||
}
|
||||
|
||||
case (SUBB, _) if i == firstNonzeroByte =>
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= ldb
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.absolute(LDB, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.accessAndPullS(SUBB)
|
||||
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb)
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.indexedX(LDB, sizeInBytes - 1 - i)
|
||||
result += MLine.accessAndPullS(SUBB)
|
||||
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
|
||||
}
|
||||
|
||||
case (SUBB, _) if i != firstNonzeroByte =>
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, ldb)
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.absolute(LDB, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.accessAndPullS(SBCB)
|
||||
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb))
|
||||
result += MLine.pp(PSHS, M6809Register.B)
|
||||
result += MLine.indexedX(LDB, sizeInBytes - 1 - i)
|
||||
result += MLine.accessAndPullS(SBCB)
|
||||
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
|
||||
}
|
||||
case (ADDB, _) if i != firstNonzeroByte =>
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, ldb)
|
||||
result += MLine.absolute(ADCB, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb))
|
||||
result += MLine.indexedX(ADCB, sizeInBytes - 1 - i)
|
||||
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
|
||||
}
|
||||
case _ =>
|
||||
targetAddr match {
|
||||
case Some(addr) =>
|
||||
result ++= ldb
|
||||
result += MLine.absolute(opcode, addr + (sizeInBytes - 1 - i))
|
||||
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
|
||||
case None =>
|
||||
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb)
|
||||
result += MLine.indexedX(opcode, sizeInBytes - 1 - i)
|
||||
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
|
||||
}
|
||||
}
|
||||
}
|
||||
result.toList
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,12 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
|
||||
M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING)
|
||||
case 1 => M6809ExpressionCompiler.compileToB(ctx, e)
|
||||
case 2 => M6809ExpressionCompiler.compileToD(ctx, e)
|
||||
case _ =>
|
||||
if (ctx.function.hasElidedReturnVariable) {
|
||||
Nil
|
||||
} else {
|
||||
M6809LargeBuiltins.storeLarge(ctx, VariableExpression(ctx.function.name + ".return"), e)
|
||||
}
|
||||
}
|
||||
}
|
||||
(eval ++ rts) -> Nil
|
||||
@ -65,6 +71,7 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
|
||||
case _ => M6809ExpressionCompiler.compileToB(ctx, source) ++ M6809ExpressionCompiler.storeB(ctx, destination)
|
||||
}
|
||||
case 2 => M6809ExpressionCompiler.compileToD(ctx, source) ++ M6809ExpressionCompiler.storeD(ctx, destination)
|
||||
case _ => M6809LargeBuiltins.storeLarge(ctx, destination, source)
|
||||
}) -> Nil
|
||||
case ExpressionStatement(expression) =>
|
||||
M6809ExpressionCompiler.compile(ctx, expression, MExpressionTarget.NOTHING) -> Nil
|
||||
|
@ -34,6 +34,10 @@ class MemoryBank(val index: Int, val isBigEndian: Boolean) {
|
||||
if (isBigEndian) readByte(addr + 3) + (readByte(addr + 2) << 8) + (readByte(addr + 1) << 16) + (readByte(addr) << 24)
|
||||
else readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + (readByte(addr + 3) << 24)
|
||||
|
||||
def readLongLong(addr: Int): Long =
|
||||
if (isBigEndian) readLong(addr).toLong.<<(32) + readLong(addr + 4).&(1L.<<(32).-(1))
|
||||
else readLong(addr + 4).toLong.<<(32) + readLong(addr).&(1L.<<(32).-(1))
|
||||
|
||||
def readWord(addrHi: Int, addrLo: Int): Int = readByte(addrLo) + (readByte(addrHi) << 8)
|
||||
|
||||
val output: Array[Byte] = Array.fill[Byte](1 << 16)(0)
|
||||
|
@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
|
||||
class FarwordTest extends FunSuite with Matchers {
|
||||
|
||||
test("Int24 assignment") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output3 @$c000
|
||||
| int24 output2 @$c004
|
||||
@ -29,7 +29,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 assignment 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output3 @$c000
|
||||
| int24 output2 @$c004
|
||||
@ -48,12 +48,12 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
""".stripMargin) { m =>
|
||||
m.readMedium(0xc000) should equal(0x23344)
|
||||
m.readMedium(0xc004) should equal(0x7788)
|
||||
m.readMedium(0xc008) should equal(0x55)
|
||||
m.readWord(0xc008) should equal(0x55)
|
||||
}
|
||||
}
|
||||
|
||||
test("Int24 assignment 3") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output0 @$c000
|
||||
| int24 output1 @$c003
|
||||
@ -70,7 +70,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 addition") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -90,7 +90,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 addition 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -104,7 +104,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 subtraction") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -124,7 +124,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 subtraction 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -138,7 +138,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Int24 subtraction 3") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -158,7 +158,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Int24 AND") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output @$c000
|
||||
| void main () {
|
||||
@ -178,7 +178,7 @@ class FarwordTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Int24 INC/DEC") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int24 output0 @$c000
|
||||
| int24 output1 @$c004
|
||||
|
@ -28,7 +28,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Long assignment") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output4 @$c000
|
||||
| long output2 @$c004
|
||||
@ -47,7 +47,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long assignment 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output4 @$c000
|
||||
| long output2 @$c004
|
||||
@ -66,11 +66,11 @@ class LongTest extends FunSuite with Matchers {
|
||||
""".stripMargin) { m =>
|
||||
m.readLong(0xc000) should equal(0x11223344)
|
||||
m.readLong(0xc004) should equal(0x7788)
|
||||
m.readLong(0xc008) should equal(0x55)
|
||||
m.readWord(0xc008) should equal(0x55)
|
||||
}
|
||||
}
|
||||
test("Long addition") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -90,7 +90,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long addition 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -104,7 +104,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long addition 3") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -138,7 +138,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long subtraction") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -158,7 +158,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long subtraction 2") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -172,7 +172,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Long subtraction 3") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -192,7 +192,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Long AND") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -212,7 +212,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Long INC/DEC") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output0 @$c000
|
||||
| long output1 @$c004
|
||||
@ -252,7 +252,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Returning long") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
@ -267,7 +267,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Various combinations involving promotions") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| long output0 @$c000
|
||||
| long output1 @$c004
|
||||
@ -329,7 +329,7 @@ class LongTest extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Larger than long") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| int64 output0 @$c000
|
||||
| int64 output1 @$c008
|
||||
@ -364,18 +364,11 @@ class LongTest extends FunSuite with Matchers {
|
||||
| return param
|
||||
| }
|
||||
""".stripMargin) { m =>
|
||||
m.readLong(0xc000) should equal(0x91929394)
|
||||
m.readLong(0xc008) should equal(0x929394)
|
||||
m.readLong(0xc010) should equal(0x9394)
|
||||
m.readLong(0xc018) should equal(0x94)
|
||||
|
||||
m.readLong(0xc004) should equal(0)
|
||||
m.readLong(0xc00c) should equal(0)
|
||||
m.readLong(0xc014) should equal(0)
|
||||
m.readLong(0xc01c) should equal(0)
|
||||
|
||||
m.readLong(0xc020) should equal(0x91929394)
|
||||
m.readLong(0xc024) should equal(0x01010101)
|
||||
m.readLongLong(0xc000) should equal(0x91929394L)
|
||||
m.readLongLong(0xc008) should equal(0x929394L)
|
||||
m.readLongLong(0xc010) should equal(0x9394L)
|
||||
m.readLongLong(0xc018) should equal(0x94L)
|
||||
m.readLongLong(0xc020) should equal(0x0101010191929394L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
""".stripMargin){m => m.readWord(0xc000) should equal(0xfffe)}
|
||||
}
|
||||
test("Sbyte to Long") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
|
||||
| long output @$c000
|
||||
| void main () {
|
||||
| output = 421
|
||||
@ -46,7 +46,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Optimize pointless sign extension") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
|
||||
| array output [10] @$c000
|
||||
| word w
|
||||
| void main () {
|
||||
@ -66,7 +66,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
| return 5
|
||||
| }
|
||||
""".stripMargin){m =>
|
||||
m.readWord(0xc000) should equal(440)
|
||||
m.readWord(0xc001, 0xc000) should equal(440)
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Check multilayered conversions of signed and unsigned types") {
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)(
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
|
||||
"""
|
||||
|long output @$c000
|
||||
|noinline sbyte f() = $FE
|
||||
@ -140,7 +140,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Signed16 to int32 extension") {
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)(
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
|
||||
"""
|
||||
|int32 output @$c000
|
||||
|
|
||||
@ -156,7 +156,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Signed16 to int32 extension 2") {
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)(
|
||||
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
|
||||
"""
|
||||
|int32 output @$c000
|
||||
|
|
||||
|
@ -50,7 +50,7 @@ object Settings {
|
||||
|
||||
/**
|
||||
* Should the Motorola 6809 tests be enabled?
|
||||
* Motorola 6809 emulation is not yet implemented, so keep this false for the time being.
|
||||
* Motorola 6809 emulation is currently under development and more and more tests are ran against it.
|
||||
*/
|
||||
val enableMotorola6809Tests: Boolean = true
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user