Implement LDA Operation
[mix.git] / src / machine.rs
index 33bbcef..fdecd33 100644 (file)
@@ -6,7 +6,7 @@ pub struct MixBit {
 impl MixBit {
     // Clamps a u8 to a u6
     // 0b0011_1111 = 64
-    fn value(&self) -> u8 {
+    pub fn value(&self) -> u8 {
         return self.v & 0b0011_1111;
     }
 
@@ -31,29 +31,48 @@ pub struct Word {
     pub bytes: [MixBit; 5],
 }
 
+// Multiple return type for dealing with 8L+R fields from Words
+#[derive(Debug)]
+pub struct FieldSpec {
+    l: usize,
+    r: usize,
+}
+
 impl Word {
     fn new(sign: bool, bytes: [MixBit; 5]) -> Word {
         Word { sign, bytes }
     }
+
+    // The word is being used as an instruction.
+    // By definition, the 4th bit of the word is the field specification as 8L + R.
+    pub fn field_spec(&self) -> FieldSpec {
+        FieldSpec {
+            // divide by 8
+            l: (self.bytes[3].value() >> 3) as usize,
+            r: (self.bytes[3].value() % 8) as usize,
+        }
+    }
+
     // The allowable fields are those that are adjacent in a computer word, and they are
     // represented by (L:R) where L is the number of the left hand part and R is the number of the
     // right-hand part of the field.
-    pub fn field_specification(&self, l: usize, r: usize) -> Word {
-        let mut sign = false;
-        let mut l_clamp = l;
-        if l == 0 {
+    pub fn as_field_spec(&self, fs: FieldSpec) -> Word {
+        let mut sign = true;
+        let mut l_clamp = fs.l;
+        if fs.l == 0 {
             sign = self.sign;
         } else {
-            l_clamp = l - 1;
+            l_clamp = l_clamp - 1;
         }
-        let r_clamp = r % 5;
+        let r_clamp = (fs.r - 1) % 5;
         let mut bytes = [MixBit::default(); 5];
-        for n in l_clamp..r_clamp {
+        for n in l_clamp..=r_clamp {
             bytes[n] = self.bytes[n];
         }
         Word { sign, bytes }
     }
 
+    // TODO implement / respect index word (self.bytes[2] should be index)
     pub fn address(&self) -> i16 {
         let magnitude = ((self.bytes[0].value() as i16) << 6) | self.bytes[1].value() as i16;
         match self.sign {
@@ -66,20 +85,15 @@ impl Word {
 // There are nine registers in MIX.
 // We shall use a small letter "r", prefixed to the neame, to identify a MIX register.
 #[derive(Debug, Default)]
-struct Registers {
+pub struct Registers {
     // Accumulator
-    rA: Word,
+    pub a: Word,
     // Extension
-    rX: Word,
+    pub x: Word,
     // Index registers: Should only hold 2 bytes together with a sign.
-    rI1: Word,
-    rI2: Word,
-    rI3: Word,
-    rI4: Word,
-    rI5: Word,
-    rI6: Word,
+    pub i: [Word; 6],
     // Jump: holds two bytes; it behaves as if its sign is always +
-    rJ: Word,
+    pub j: Word,
 }
 
 // having three values: LESS, EQUAL, or GREATER
@@ -93,20 +107,20 @@ enum ComparisonIndicator {
 
 #[derive(Debug)]
 pub struct Machine {
-    registers: Registers,
+    pub registers: Registers,
     // Besides its registers, MIX contains:
     // an overflow toggle
     overflow: bool,
     // a comparison indicator
     comp: ComparisonIndicator,
     // memory: 4000 words of storage, each word with five bytes and a sign)
-    memory: [Word; 4000],
+    pub memory: [Word; 4000],
     // and input-output devices
     // TODO?
 }
 
 impl Machine {
-    fn default() -> Machine {
+    pub fn default() -> Machine {
         Machine {
             registers: Registers::default(),
             overflow: false,