summaryrefslogtreecommitdiff
path: root/src/AddressingModes.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/AddressingModes.scala')
-rw-r--r--src/AddressingModes.scala52
1 files changed, 35 insertions, 17 deletions
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