From b33bed4dbf709031b273115f6e15631e673658a9 Mon Sep 17 00:00:00 2001 From: iximeow Date: Thu, 12 Mar 2015 02:16:29 -0700 Subject: get better instruction stream parsing working --- src/AddressingModes.scala | 52 +++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'src/AddressingModes.scala') diff --git a/src/AddressingModes.scala b/src/AddressingModes.scala index f511768..30ad696 100644 --- a/src/AddressingModes.scala +++ b/src/AddressingModes.scala @@ -6,8 +6,9 @@ import ixee.cryptopals.utils.FunctionUtils._ import scala.collection.mutable.Map sealed trait AddressingMode { - def modeName: String - override def toString: String = modeName + def name: String + def wide: Boolean + override def toString: String = name def nameifyRegister(reg: Int): String = reg match { case 0 => "pc" case 1 => "sp" @@ -15,9 +16,18 @@ sealed trait AddressingMode { case 3 => "cg" case num @ _ => s"r$num" } +} + +sealed trait NormMode extends AddressingMode { + def wide = false def stringifyWith(reg: Int): String } +sealed trait WideMode extends AddressingMode { + def wide = true + def stringifyWith(reg: Int, word: Int): String +} + sealed trait OneOpAddressing extends AddressingMode sealed trait TwoOpAddressing extends AddressingMode sealed trait TwoOpSourceAddressing extends TwoOpAddressing @@ -30,10 +40,7 @@ object TwoOpSourceAddressingModes { } object OneOpAddressingModes { - case class AddressingMode(as: Int, name: String, stringifier: String => String) extends OneOpAddressing with TwoOpSourceAddressing { - def modeName = name - def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg)) - } + trait AddressingMode extends OneOpAddressing with TwoOpSourceAddressing def apply(register: Int, mode: Int): Option[AddressingMode] = register match { case 0 => PCModes(mode) orElse General(mode) @@ -44,15 +51,21 @@ object OneOpAddressingModes { trait Modes { private val modeMap: Map[Int, AddressingMode] = Map() - case class Mode(as: Int, name: String, stringifier: String => String) extends AddressingMode(as, name, stringifier) { - def Mode(as: Int, name: String, stringifier: String => String) = this(as, name, stringifier).tap(modeMap += as -> _) + + case class Mode(as: Int, name: String, stringifier: String => String) extends AddressingMode with NormMode { + modeMap += as -> this + def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg)) + } + case class ExtraByteMode(as: Int, name: String, stringifier: (String, Int) => String) extends AddressingMode with WideMode { + modeMap += as -> this + def stringifyWith(reg: Int, const: Int): String = stringifier(nameifyRegister(reg), const) } def apply(x: Int): Option[AddressingMode] = modeMap.get(x) } object PCModes extends Modes { - Mode(3, "NextWord", reg => s"@PC+ (next word)") + ExtraByteMode(3, "NextWord", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}") } object SRModes extends Modes { Mode(2, "Const4", reg => "#4") @@ -66,7 +79,7 @@ object OneOpAddressingModes { } object General extends Modes { Mode(0, "RegisterDirect", ident) - Mode(1, "Indexed", reg => s"@PC+($reg)") + ExtraByteMode(1, "Indexed", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}($reg)") Mode(2, "RegisterIndirect", reg => s"@$reg") Mode(3, "IndirectAutoInc", reg => s"@$reg+") } @@ -79,10 +92,7 @@ object OneOpAddressingModes { object TwoOpDestAddressingModes { - case class AddressingMode(as: Int, name: String, stringifier: String => String) extends TwoOpDestAddressing { - def modeName = name - def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg)) - } + trait AddressingMode extends TwoOpDestAddressing def apply(register: Int, mode: Int): Option[AddressingMode] = register match { case 0 => PCModes(mode) orElse General(mode) @@ -92,7 +102,15 @@ object TwoOpDestAddressingModes { trait Modes { private val modeMap: Map[Int, AddressingMode] = Map() - def Mode(as: Int, name: String, stringifier: String => String) = AddressingMode(as, name, stringifier).tap(modeMap += as -> _) + + case class Mode(as: Int, name: String, stringifier: String => String) extends AddressingMode with NormMode { + modeMap += as -> this + def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg)) + } + case class ExtraByteMode(as: Int, name: String, stringifier: (String, Int) => String) extends AddressingMode with WideMode { + modeMap += as -> this + def stringifyWith(reg: Int, const: Int): String = stringifier(nameifyRegister(reg), const) + } def apply(x: Int): Option[AddressingMode] = modeMap.get(x) } @@ -101,11 +119,11 @@ object TwoOpDestAddressingModes { Mode(1, "Symbolic", reg => s" (symbolic? x(PC)?") } object SRModes extends Modes { - Mode(1, "Absolute", reg => s"&@PC+ (value at nextWord)") + ExtraByteMode(1, "Absolute", (reg, byte) => s"&${"%4x".format(byte)}") } object General extends Modes { Mode(0, "RegisterDirect", reg => s"$reg") - Mode(1, "Indexed", reg => s"@PC+($reg)") + ExtraByteMode(1, "Indexed", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}($reg)") } PCModes -- cgit v1.1