Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable
at main 2.7 kB view raw
1// Copyright (C) 2025 Thom Hayward. 2// 3// This program is free software: you can redistribute it and/or modify it under 4// the terms of the GNU General Public License as published by the Free Software 5// Foundation, version 3. 6// 7// This program is distributed in the hope that it will be useful, but WITHOUT 8// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 10// details. 11// 12// You should have received a copy of the GNU General Public License along with 13// this program. If not, see <https://www.gnu.org/licenses/>. 14// 15/// A reference to a register of the UM-32. 16#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 17pub enum Register { 18 #[default] 19 R0, 20 R1, 21 R2, 22 R3, 23 R4, 24 R5, 25 R6, 26 R7, 27} 28 29impl std::fmt::Display for Register { 30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 31 write!(f, "r{}", *self as u8) 32 } 33} 34 35impl Register { 36 /// Encodes the register as the 'a' parameter of an encoded 37 /// instruction (bits 6..=8). 38 pub fn encode_a(self) -> u32 { 39 ((self as u32) & 0x7) << 6 40 } 41 42 /// Encodes the register as the 'b' parameter of an encoded 43 /// instruction (bits 3..=5). 44 pub fn encode_b(self) -> u32 { 45 ((self as u32) & 0x7) << 3 46 } 47 48 /// Encodes the register as the 'c' parameter of an encoded 49 /// instruction (bits 0..=2). 50 pub fn encode_c(self) -> u32 { 51 (self as u32) & 0x7 52 } 53 54 /// Encodes the register as the 'a' parameter of an `Orthography` 55 /// operation. 56 /// 57 /// This is *only* valid for `Orthography` operations. 58 pub fn encode_a_ortho(self) -> u32 { 59 ((self as u32) & 0x7) << 25 60 } 61 62 pub fn from_u8(index: u8) -> Self { 63 match index { 64 0 => Register::R0, 65 1 => Register::R1, 66 2 => Register::R2, 67 3 => Register::R3, 68 4 => Register::R4, 69 5 => Register::R5, 70 6 => Register::R6, 71 7 => Register::R7, 72 _ => unreachable!(), 73 } 74 } 75} 76 77/// A set of registers. 78#[derive(Debug, Default)] 79pub struct Page([u32; 8]); 80 81impl std::ops::Index<Register> for Page { 82 type Output = u32; 83 #[inline(always)] 84 fn index(&self, index: Register) -> &Self::Output { 85 &self.0[index as usize] 86 } 87} 88 89impl std::ops::IndexMut<Register> for Page { 90 #[inline(always)] 91 fn index_mut(&mut self, index: Register) -> &mut Self::Output { 92 &mut self.0[index as usize] 93 } 94} 95 96impl From<[u32; 8]> for Page { 97 fn from(value: [u32; 8]) -> Self { 98 Self(value) 99 } 100}