From: Jacob Casper Date: Tue, 16 Jan 2024 01:14:55 +0000 (-0600) Subject: Refactor machine types to separate file X-Git-Url: https://git.jacobcasper.com/?a=commitdiff_plain;h=5a34417306c564ec0b47c893836df914140ebc6c;p=mix.git Refactor machine types to separate file --- diff --git a/src/machine.rs b/src/machine.rs new file mode 100644 index 0000000..33bbcef --- /dev/null +++ b/src/machine.rs @@ -0,0 +1,117 @@ +#[derive(Debug, Default, Copy, Clone)] +pub struct MixBit { + pub v: u8, +} + +impl MixBit { + // Clamps a u8 to a u6 + // 0b0011_1111 = 64 + fn value(&self) -> u8 { + return self.v & 0b0011_1111; + } + + fn as_value(&self) -> MixBit { + MixBit { v: self.value() } + } +} + +// Useful function for "packed" bits like those used for opcodes +fn address(high: MixBit, low: MixBit) -> u16 { + return ((high.value() as u16) << 6) | low.value() as u16; +} + +// > Each byte contains an unspecified amount of information but it must be capable of holding at +// > least 64 distinct values. +// > A computer word consists of five bytes and a sign. The sign portion has only two possible +// values, + and -. +// u8 is the smallest standard primitive, no bounds checking for now. +#[derive(Debug, Default, Copy, Clone)] +pub struct Word { + pub sign: bool, + pub bytes: [MixBit; 5], +} + +impl Word { + fn new(sign: bool, bytes: [MixBit; 5]) -> Word { + Word { sign, bytes } + } + // 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 { + sign = self.sign; + } else { + l_clamp = l - 1; + } + let r_clamp = r % 5; + let mut bytes = [MixBit::default(); 5]; + for n in l_clamp..r_clamp { + bytes[n] = self.bytes[n]; + } + Word { sign, bytes } + } + + pub fn address(&self) -> i16 { + let magnitude = ((self.bytes[0].value() as i16) << 6) | self.bytes[1].value() as i16; + match self.sign { + true => magnitude, + false => -magnitude, + } + } +} + +// 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 { + // Accumulator + rA: Word, + // Extension + rX: Word, + // Index registers: Should only hold 2 bytes together with a sign. + rI1: Word, + rI2: Word, + rI3: Word, + rI4: Word, + rI5: Word, + rI6: Word, + // Jump: holds two bytes; it behaves as if its sign is always + + rJ: Word, +} + +// having three values: LESS, EQUAL, or GREATER +#[derive(Debug, Default)] +enum ComparisonIndicator { + Less, + #[default] + Equal, + Greater, +} + +#[derive(Debug)] +pub struct Machine { + 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], + // and input-output devices + // TODO? +} + +impl Machine { + fn default() -> Machine { + Machine { + registers: Registers::default(), + overflow: false, + comp: ComparisonIndicator::Equal, + memory: [Word::default(); 4000], + } + } +} diff --git a/src/main.rs b/src/main.rs index 9108572..d63ec15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,120 +1,5 @@ -#[derive(Debug, Default, Copy, Clone)] -struct MixBit { - v: u8, -} - -impl MixBit { - // Clamps a u8 to a u6 - // 0b0011_1111 = 64 - fn value(&self) -> u8 { - return self.v & 0b0011_1111; - } - - fn as_value(&self) -> MixBit { - MixBit { v: self.value() } - } -} - -// Useful function for "packed" bits like those used for opcodes -fn address(high: MixBit, low: MixBit) -> u16 { - return ((high.value() as u16) << 6) | low.value() as u16; -} - -// > Each byte contains an unspecified amount of information but it must be capable of holding at -// > least 64 distinct values. -// > A computer word consists of five bytes and a sign. The sign portion has only two possible -// values, + and -. -// u8 is the smallest standard primitive, no bounds checking for now. -#[derive(Debug, Default, Copy, Clone)] -struct Word { - sign: bool, - bytes: [MixBit; 5], -} - -impl Word { - fn new(sign: bool, bytes: [MixBit; 5]) -> Word { - Word { sign, bytes } - } - // 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. - fn field_specification(&self, l: usize, r: usize) -> Word { - let mut sign = false; - let mut l_clamp = l; - if l == 0 { - sign = self.sign; - } else { - l_clamp = l - 1; - } - let r_clamp = r % 5; - let mut bytes = [MixBit::default(); 5]; - for n in l_clamp..r_clamp { - bytes[n] = self.bytes[n]; - } - Word { sign, bytes } - } - - fn address(&self) -> i16 { - let magnitude = ((self.bytes[0].value() as i16) << 6) | self.bytes[1].value() as i16; - match self.sign { - true => magnitude, - false => -magnitude, - } - } -} - -// 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 { - // Accumulator - rA: Word, - // Extension - rX: Word, - // Index registers: Should only hold 2 bytes together with a sign. - rI1: Word, - rI2: Word, - rI3: Word, - rI4: Word, - rI5: Word, - rI6: Word, - // Jump: holds two bytes; it behaves as if its sign is always + - rJ: Word, -} - -// having three values: LESS, EQUAL, or GREATER -#[derive(Debug, Default)] -enum ComparisonIndicator { - Less, - #[default] - Equal, - Greater, -} - -#[derive(Debug)] -struct Machine { - 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], - // and input-output devices - // TODO? -} - -impl Machine { - fn default() -> Machine { - Machine { - registers: Registers::default(), - overflow: false, - comp: ComparisonIndicator::Equal, - memory: [Word::default(); 4000], - } - } -} +mod machine; +use crate::machine::*; fn main() { let fs = (Word {