From 35b0b5972f5dcdd4f265e48046e5af2c3e363392 Mon Sep 17 00:00:00 2001 From: Richard Date: Fri, 29 Aug 2025 22:20:12 +0200 Subject: [PATCH] ops --- data/bootsand.um | Bin 0 -> 57388 bytes src/cpu.rs | 283 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 271 insertions(+), 12 deletions(-) create mode 100644 data/bootsand.um diff --git a/data/bootsand.um b/data/bootsand.um new file mode 100644 index 0000000000000000000000000000000000000000..0310f415b51de97cc9ecd65fde67374abf4211a3 GIT binary patch literal 57388 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 h#~%kRBpTW Option; + fn read(&mut self) -> Option; fn write(&mut self, c: u8); } -struct NoConsole; - -impl Console for NoConsole { - fn read(&self) -> Option { - None - } - fn write(&mut self, _c: u8) {} -} - #[derive(Debug)] pub enum CpuError { ProgramEnd, InvalidInstruction, UnexpectedInput, InvalidArray, - ArrayOutOfBounds + ArrayOutOfBounds, + DivideByZero, + Halt, + LargeAlloc, + InvalidOutput } #[derive(Debug)] pub struct Cpu { reg: [u32; 8], arr: HashMap>, + iarr: u32, finger: u32, out: Option, in_reg: Option @@ -42,6 +38,7 @@ impl Cpu { Cpu { reg: [0;8], arr: arrays, + iarr: 1, finger: 0, in_reg: None, out: None @@ -159,6 +156,65 @@ impl Cpu { Ok(()) } + fn handle_div(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + let b = self.gr(i.b); + let c = self.gr(i.c); + if c == 0 { + return Err(CpuError::DivideByZero); + } + let (a, _) = b.overflowing_div(c); + self.sr(i.a, a); + Ok(()) + } + + fn handle_nand(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + let b = ! self.gr(i.b); + let c = ! self.gr(i.c); + let a = b & c; + self.sr(i.a, a); + Ok(()) + } + + fn handle_halt(&mut self, _i:NormalInstruction) -> Result<(), CpuError>{ + Err(CpuError::Halt) + } + + fn handle_alc(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + let c = self.gr(i.c) as usize; + if c > 1048576 { + return Err(CpuError::LargeAlloc); + } + let aid = self.iarr; + self.iarr += 1; + let v = vec![0; c]; + self.arr.insert(aid, v); + self.sr(i.b, aid); + Ok(()) + } + + fn handle_abn(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + let c = self.gr(i.c); + if c == 0 || ! self.arr.contains_key(&c){ + return Err(CpuError::InvalidArray); + } + self.arr.remove(&c); + Ok(()) + } + fn handle_out(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + let c = self.gr(i.c); + if c > 255 { + return Err(CpuError::InvalidOutput); + } + self.out = Some(c as u8); + Ok(()) + } + + fn handle_inp(&mut self, i:NormalInstruction) -> Result<(), CpuError>{ + self.sr(i.c, 0xffffffff); + self.in_reg = Some(i.c); + Ok(()) + } + fn exec(&mut self, instruction: Instruction)-> Result<(), CpuError>{ //println!("{:?}", instruction); match instruction { @@ -168,6 +224,13 @@ impl Cpu { Instruction::ArrayAmend(i) => self.handle_amd(i), Instruction::Add(i) => self.handle_add(i), Instruction::Multiply(i) => self.handle_mul(i), + Instruction::Divide(i) => self.handle_div(i), + Instruction::NotAnd(i) => self.handle_nand(i), + Instruction::Halt(i) => self.handle_halt(i), + Instruction::Allocate(i) => self.handle_alc(i), + Instruction::Abandon(i) => self.handle_abn(i), + Instruction::Output(i) => self.handle_out(i), + Instruction::Input(i) => self.handle_inp(i), _ => Err(CpuError::InvalidInstruction) } } @@ -207,6 +270,45 @@ impl Cpu { #[cfg(test)] mod tests{ use super::*; + struct NoConsole; + + impl Console for NoConsole { + fn read(&mut self) -> Option { + None + } + fn write(&mut self, _c: u8) {} + } + + struct BufConsole { + inb: Vec, + inptr: usize, + outb: Vec + } + + impl BufConsole { + fn make() -> BufConsole { + BufConsole { + inb: vec![], + inptr: 0, + outb: vec![] + } + } + } + + impl Console for BufConsole { + fn read(&mut self) -> Option { + if self.inptr >= self.inb.len() { + None + } else { + let r = self.inb[self.inptr]; + self.inptr += 1; + Some(r) + } + } + fn write(&mut self, c: u8) { + self.outb.push(c); + } + } fn ezop(op:u32, a:u32, b:u32, c:u32) -> u32 { match op { @@ -317,7 +419,7 @@ mod tests{ } - #[test] + #[test] fn test_amd_nooff() -> Result<(), String> { let pgm = vec!( ezop(2, 1, 2, 3) ); let mut c = Cpu::new(pgm); @@ -373,4 +475,161 @@ mod tests{ assert_eq!(c.reg, exp); Ok(()) } + + #[test] + fn test_div() -> Result<(), CpuError> { + let pgm = vec!( ezop(5, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 2048, 2, 0, 0, 0, 0]; + c.run(&mut NoConsole{})?; + let exp = [0, 1024, 2048, 2, 0, 0, 0, 0]; + assert_eq!(c.reg, exp); + Ok(()) + } + + #[test] + fn test_div_zero() -> Result<(), String> { + let pgm = vec!( ezop(5, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 1338, 3, 0, 0, 0, 0, 0]; + match c.run(&mut NoConsole{}) { + Err(CpuError::DivideByZero) => Ok(()), + Err(_) => Err(String::from("Invalid error")), + Ok(_) => Err(String::from("Expected err got ok")) + } + } + + #[test] + fn test_nand() -> Result<(), CpuError> { + let pgm = vec!( ezop(6, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0x5a5a00ff, 0xdede00ff, 0, 0, 0, 0]; + c.run(&mut NoConsole{})?; + let exp = [0, 0x2121ff00, 0x5a5a00ff, 0xdede00ff, 0, 0, 0, 0]; + assert_eq!(c.reg, exp); + Ok(()) + } + + #[test] + fn test_halt() -> Result<(), String> { + let pgm = vec!( ezop(7, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + match c.run(&mut NoConsole{}) { + Err(CpuError::Halt) => Ok(()), + Err(_) => Err(String::from("Invalid error")), + Ok(_) => Err(String::from("Expected err got ok")) + } + } + + #[test] + fn test_alc_large() -> Result<(), String> { + let pgm = vec!( ezop(8, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 1338, 33, 0xffffffff, 0, 0, 0, 0]; + match c.run(&mut NoConsole{}) { + Err(CpuError::LargeAlloc) => Ok(()), + Err(_) => Err(String::from("Invalid error")), + Ok(_) => Err(String::from("Expected err got ok")) + } + } + + #[test] + fn test_alc() -> Result<(), CpuError> { + let pgm = vec!( ezop(8, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 1338, 33, 5, 0, 0, 0, 0]; + if let Err(e) = c.run(&mut NoConsole{}) { + return Err(e) + } + let exp = [0, 1338, 1, 5, 0, 0, 0, 0]; + assert_eq!(c.reg, exp); + if let Some(arr) = c.arr.get(&1){ + assert_eq!(arr,&vec![0,0,0,0,0] ); + Ok(()) + } else { + Err(CpuError::InvalidArray) + } + } + + #[test] + fn test_abn() -> Result<(), CpuError> { + let pgm = vec!( ezop(9, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.arr.insert(1338, vec![0,0,0,0]); + c.reg = [0, 0, 0, 1338, 0, 0, 0, 0]; + c.run(&mut NoConsole{})?; + if c.arr.contains_key(&1338) { + Err(CpuError::InvalidArray) + } else { + Ok(()) + } + } + + #[test] + fn test_abn_zero() -> Result<(), String> { + let pgm = vec!( ezop(9, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0, 0, 0, 0, 0, 0]; + match c.run(&mut NoConsole{}) { + Err(CpuError::InvalidArray) => Ok(()), + Err(_) => Err(String::from("Invalid error")), + Ok(_) => Err(String::from("Expected err got ok")) + } + } + + #[test] + fn test_out() -> Result<(), String> { + let pgm = vec!( ezop(10, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0, 128, 0, 0, 0, 0]; + let mut cons = BufConsole::make(); + if let Err(e) = c.run(&mut cons) { + return Err(format!("unexpected err {:?}", e)); + }; + assert_eq!(cons.outb, vec!(128)); + Ok(()) + } + + #[test] + fn test_out_inv() -> Result<(), String> { + let pgm = vec!( ezop(10, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0, 1337, 0, 0, 0, 0]; + let mut cons = BufConsole::make(); + match c.run(&mut cons) { + Err(CpuError::InvalidOutput) => Ok(()), + Ok(_) => Err(format!("unexpected ok")), + Err(e) => Err(format!("unexpected err {:?}", e)) + } + + } + + #[test] + fn test_inp() -> Result<(), String> { + let pgm = vec!( ezop(11, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0, 0, 0, 0, 0, 0]; + let mut cons = BufConsole::make(); + cons.inb.push(128); + if let Err(e) = c.run(&mut cons) { + return Err(format!("unexpected err {:?}", e)); + }; + let exp = [0, 0, 0, 128, 0, 0, 0, 0]; + assert_eq!(c.reg, exp); + Ok(()) + } + + #[test] + fn test_inp_fail() -> Result<(), String> { + let pgm = vec!( ezop(11, 1, 2, 3) ); + let mut c = Cpu::new(pgm); + c.reg = [0, 0, 0, 0, 0, 0, 0, 0]; + let mut cons = BufConsole::make(); + if let Err(e) = c.run(&mut cons) { + return Err(format!("unexpected err {:?}", e)); + }; + let exp = [0, 0, 0, 0xffffffff, 0, 0, 0, 0]; + assert_eq!(c.reg, exp); + Ok(()) + } } \ No newline at end of file