From b7df86ce2a26fe444fdaa807927157a7576c6d1b Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie Date: Thu, 22 Dec 2022 23:46:19 -0700 Subject: [PATCH] Tighten all this up using helpers --- src/vm.rs | 541 +++++++++++++++++------------------------------------- 1 file changed, 166 insertions(+), 375 deletions(-) diff --git a/src/vm.rs b/src/vm.rs index 5999f23..bfc47ef 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -139,6 +139,7 @@ impl Uxn { let kflag: u8 = opcode & 0x80 >> 7; let icode: u8 = opcode & 0x1F; + // Swizzle the stacks as needed let [wst, rst] = { if rflag == 0 { [self.wst.clone(), self.rst.clone()] @@ -147,6 +148,39 @@ impl Uxn { } }; + // Some procedural abstractions over load/store sizes + let pop = |stack: Rc>| -> Result { + if sflag == 1 { + stack.borrow_mut().pop2() + } else { + Ok(stack.borrow_mut().pop1()? as u16) + } + }; + + let push = |stack: Rc>, val: u16| { + if sflag == 1 { + stack.borrow_mut().push2(val) + } else { + stack.borrow_mut().push1(val as u8) + } + }; + + let load = |addr: u16| -> Result { + if sflag == 1 { + self.memory.borrow_mut().get2(addr) + } else { + Ok(self.memory.borrow_mut().get1(addr)? as u16) + } + }; + + let store = |addr: u16, value: u16| { + if sflag == 1 { + self.memory.borrow_mut().set2(addr, value) + } else { + self.memory.borrow_mut().set1(addr, value as u8) + } + }; + // Just bail out of we get a keep flag, haven't figured out an abstraction for that yet. if kflag != 0 { panic!("Got unsupported keep-mode instruction"); @@ -159,214 +193,93 @@ impl Uxn { } (_, _, 0, 0x00) => { // LIT1 - wst.borrow_mut().push1(self.lda1(self.pc + 1)?)?; + wst.borrow_mut().push1(self.lda1(self.pc)?)?; self.pc += 1; continue 'run; } (_, _, 1, 0x00) => { // LIT2 - wst.borrow_mut().push2(self.lda2(self.pc + 1)?)?; + wst.borrow_mut().push2(self.lda2(self.pc)?)?; self.pc += 2; continue 'run; } - (_, _, 0, 0x01) => { - // INC1 - let a = wst.borrow_mut().pop1()?; - wst.borrow_mut().push1(a + 1)?; + (_, _, _, 0x01) => { + // INC + push(wst.clone(), pop(wst.clone())? + 1)?; } - (_, _, 1, 0x01) => { - // INC1 - let a = wst.borrow_mut().pop2()?; - wst.borrow_mut().push2(a + 1)?; + (_, _, _, 0x02) => { + // POP + pop(wst)?; } - (_, _, 0, 0x02) => { - // POP1 - wst.borrow_mut().pop1()?; + (_, _, _, 0x03) => { + // NIP a b -- a + let keep = pop(wst.clone())?; + pop(wst.clone())?; + push(wst.clone(), keep)?; } - (_, _, 1, 0x02) => { - // POP2 - wst.borrow_mut().pop2()?; + (_, _, _, 0x04) => { + // SWP + let a = pop(wst.clone())?; + let b = pop(wst.clone())?; + push(wst.clone(), b)?; + push(wst.clone(), a)?; } - (_, _, 0, 0x03) => { - // NIP1 a b -- a - let mut wst = wst.borrow_mut(); - let keep = wst.pop1()?; - wst.pop1()?; - wst.push1(keep)?; + (_, _, _, 0x05) => { + // ROT + let a = pop(wst.clone())?; + let b = pop(wst.clone())?; + let c = pop(wst.clone())?; + push(wst.clone(), b)?; + push(wst.clone(), c)?; + push(wst.clone(), a)?; } - (_, _, 1, 0x03) => { - // NIP2 a b -- a - let mut wst = wst.borrow_mut(); - let keep = wst.pop2()?; - wst.pop2()?; - wst.push2(keep)?; + (_, _, _, 0x06) => { + // DUP + let a = pop(wst.clone())?; + push(wst.clone(), a)?; + push(wst.clone(), a)?; } - (_, _, 0, 0x04) => { - // SWP1 - let mut wst = wst.borrow_mut(); - let a = wst.pop1()?; - let b = wst.pop1()?; - wst.push1(a)?; - wst.push1(b)?; + (_, _, _, 0x07) => { + // OVR a b -- a b a + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a)?; + push(wst.clone(), b)?; + push(wst.clone(), a)?; } - (_, _, 1, 0x04) => { - // SWP2 - let mut wst = wst.borrow_mut(); - let a = wst.pop2()?; - let b = wst.pop2()?; - wst.push2(a)?; - wst.push2(b)?; + (_, _, _, 0x08) => { + // EQU + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + wst.borrow_mut().push1(if a == b { 1 } else { 0 })?; } - (_, _, 0, 0x05) => { - // ROT1 - let mut wst = wst.borrow_mut(); - let a = wst.pop1()?; - let b = wst.pop1()?; - let c = wst.pop1()?; - wst.push1(b)?; - wst.push1(c)?; - wst.push1(a)?; + (_, _, _, 0x09) => { + // NEQ + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + wst.borrow_mut().push1(if a == b { 0 } else { 1 })?; } - (_, _, 1, 0x05) => { - // ROT2 - let mut wst = wst.borrow_mut(); - let a = wst.pop2()?; - let b = wst.pop2()?; - let c = wst.pop2()?; - wst.push2(b)?; - wst.push2(c)?; - wst.push2(a)?; + (_, _, _, 0x0a) => { + // GTH a b + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + wst.borrow_mut().push1(if a > b { 1 } else { 0 })?; } - (_, _, 0, 0x06) => { - // DUP2 - let mut wst = wst.borrow_mut(); - let a = wst.peek1()?; - wst.push1(a)?; - } - (_, _, 1, 0x06) => { - // DUP2 - let mut wst = wst.borrow_mut(); - let a = wst.peek2()?; - wst.push2(a)?; - } - (_, _, 0, 0x07) => { - // OVR1 a b -- a b a - let mut wst = wst.borrow_mut(); - if wst.idx() < 2 { - return Err(UxnError::StackError(StackError::StackUnderflow)); - } - let i = wst.idx() - 2; - let v = wst.get1(i)?; - wst.push1(v)?; - } - (_, _, 1, 0x07) => { - // OVR2 a b -- a b a - let mut wst = wst.borrow_mut(); - if wst.idx() < 4 { - return Err(UxnError::StackError(StackError::StackUnderflow)); - } - let i = wst.idx() - 4; - let v = wst.get2(i)?; - wst.push2(v)?; - } - (_, _, 0, 0x08) => { - // EQU1 - let mut wst = wst.borrow_mut(); - let a = wst.pop1()?; - let b = wst.pop1()?; - if a == b { - wst.push1(1)?; - } else { - wst.push1(0)?; - } - } - (_, _, 1, 0x08) => { - // EQU2 - let mut wst = wst.borrow_mut(); - let a = wst.pop2()?; - let b = wst.pop2()?; - if a == b { - wst.push1(1)?; - } else { - wst.push1(0)?; - } - } - (_, _, 0, 0x09) => { - // NEQ1 - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - if a == b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } - } - (_, _, 1, 0x09) => { - // NEQ2 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - if a == b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } - } - (_, _, 0, 0x0a) => { - // GTH1 a b - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - if a > b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } - } - (_, _, 1, 0x0a) => { - // GTH1 a b - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - if a > b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } - } - (_, _, 0, 0x0b) => { - // LTH1 a b - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - if a < b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } - } - (_, _, 1, 0x0b) => { - // LTH2 a b - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - if a < b { - wst.push1(0)?; - } else { - wst.push1(1)?; - } + (_, _, _, 0x0b) => { + // LTH a b + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + wst.borrow_mut().push1(if a < b { 1 } else { 0 })?; } (_, _, _, 0x0c) => { // JMP let delta = wst.borrow_mut().pop1()? as i8; - self.pc += delta as u16; + self.pc = self.pc.wrapping_add(delta as u16); } (_, _, 0, 0x0d) => { // JCN1 cnd8 addr8 (relative) let delta = wst.borrow_mut().pop1()? as i8; let cnd = wst.borrow_mut().pop1()?; - let delta = wst.borrow_mut().pop1()? as i8; if cnd != 0 { self.pc = self.pc.wrapping_add(delta as u16); } @@ -381,116 +294,59 @@ impl Uxn { } (_, _, 0, 0x0e) => { // JSR1 addr8 (relative) - rst.borrow_mut().push2(self.pc); + rst.borrow_mut().push2(self.pc)?; let delta = wst.borrow_mut().pop1()? as i8; self.pc = self.pc.wrapping_add(delta as u16); } (_, _, 1, 0x0e) => { // JSR2 addr16 (absolute) - rst.borrow_mut().push2(self.pc); + rst.borrow_mut().push2(self.pc)?; self.pc = wst.borrow_mut().pop2()?; } - (_, _, 0, 0x0f) => { - // STH1 a - rst.borrow_mut().push1(wst.borrow_mut().pop1()?)?; + (_, _, _, 0x0f) => { + // STH a + push(rst, pop(wst)?)?; } - (_, _, 1, 0x0f) => { - // STH2 a - rst.borrow_mut().push2(wst.borrow_mut().pop2()?)?; + (_, _, _, 0x10) => { + // LDZ a -- b8 + push(wst.clone(), load(wst.borrow_mut().pop1()? as u16)?)?; } - (_, _, 0, 0x10) => { - // LDZ1 a -- b8 - let mut wst = wst.borrow_mut(); - let val = self.memory.borrow().get1(wst.pop1()? as u16)?; - wst.push1(val)?; + (_, _, _, 0x11) => { + // STZ val addr8 -- + let addr = wst.borrow_mut().pop1()? as u16; + store(addr, pop(wst.clone())?)?; } - (_, _, 1, 0x10) => { - // LDZ2 a -- b16 - let mut wst = wst.borrow_mut(); - let val = self.memory.borrow().get2(wst.pop1()? as u16)?; - wst.push2(val)?; + (_, _, _, 0x12) => { + // LDR addr8 -- a8 + let delta = wst.borrow_mut().pop1()? as i8; + push(wst.clone(), load(self.pc.wrapping_add(delta as u16))?)?; } - (_, _, 0, 0x11) => { - // STZ1 val addr8 -- - let mut wst = wst.borrow_mut(); - let addr = wst.pop1()?; - let val = wst.pop1()?; - self.memory.borrow_mut().set1(addr as u16, val); + (_, _, _, 0x13) => { + // STR val8 addr8 + let delta = wst.borrow_mut().pop1()?; + store(self.pc.wrapping_add(delta as u16), pop(wst.clone())?)?; } - (_, _, 1, 0x11) => { - // STZ2 val16 addr8 -- - let mut wst = wst.borrow_mut(); - let addr = wst.pop1()?; - let val = wst.pop2()?; - self.memory.borrow_mut().set2(addr as u16, val); + (_, _, _, 0x14) => { + // LDA a16 + let addr = wst.borrow_mut().pop2()?; + push(wst.clone(), load(addr)?)?; } - (_, _, 0, 0x12) => { - // LDR1 addr8 -- a8 - let mut wst = wst.borrow_mut(); - let delta = wst.pop1()? as i8; - let val = self.memory.borrow().get1(self.pc.wrapping_add(delta as u16))?; - wst.push1(val)?; - } - (_, _, 1, 0x12) => { - // LDR2 addr8 -- a16 - let mut wst = wst.borrow_mut(); - let delta = wst.pop1()? as i8; - let val = self.memory.borrow().get2(self.pc.wrapping_add(delta as u16))?; - wst.push2(val)?; - } - (_, _, 0, 0x13) => { - // STR1 val8 addr8 - let mut wst = wst.borrow_mut(); - let delta = wst.pop1()?; - let val = wst.pop1()?; - self.memory.borrow_mut().set1(self.pc.wrapping_add(delta as u16), val); - } - (_, _, 1, 0x13) => { - // STR2 val16 addr8 - let mut wst = wst.borrow_mut(); - let delta = wst.pop1()? as i8; - let val = wst.pop2()?; - self.memory.borrow_mut().set2(self.pc.wrapping_add(delta as u16), val); - } - (_, _, 0, 0x14) => { - // LDA1 a16 -- a8 - let mut wst = wst.borrow_mut(); - let addr = wst.pop2()?; - let val = self.memory.borrow_mut().get1(addr)?; - wst.push1(val)?; - } - (_, _, 1, 0x14) => { - // LDA2 a16 -- a16 - let mut wst = wst.borrow_mut(); - let addr = wst.pop2()?; - let val = self.memory.borrow_mut().get2(addr)?; - wst.push2(val)?; - } - (_, _, 0, 0x15) => { - // STA1 val a16 -- - let mut wst = wst.borrow_mut(); - let addr = wst.pop2()?; - let val = wst.pop1()?; - self.memory.borrow_mut().set1(addr, val)?; - } - (_, _, 1, 0x15) => { - // STA1 val a16 -- - let mut wst = wst.borrow_mut(); - let addr = wst.pop2()?; - let val = wst.pop2()?; - self.memory.borrow_mut().set2(addr, val)?; + (_, _, _, 0x15) => { + // STA val a16 -- + let addr = wst.borrow_mut().pop2()?; + store(addr, pop(wst.clone())?)?; } (_, _, 0, 0x16) => { - // DEI1 port8 -- a8 + // DEI port8 -- a8 let mut wst = wst.borrow_mut(); let port = wst.pop1()?; - wst.push1(self.dei1(port)); + wst.push1(self.dei1(port))?; } (_, _, 1, 0x16) => { // DEI2 port8 -- a16 let mut wst = wst.borrow_mut(); let port = wst.pop1()?; - wst.push2(self.dei2(port)); + wst.push2(self.dei2(port))?; } (_, _, 0, 0x17) => { // DEO1 a8 port8 -- @@ -506,121 +362,56 @@ impl Uxn { let val = wst.pop2()?; self.deo2(port, val); } - (_, _, 0, 0x18) => { - // ADD1 a b -- c - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a + b)?; + (_, _, _, 0x18) => { + // ADD a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a + b)?; } - (_, _, 1, 0x18) => { - // ADD2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a + b)?; + (_, _, _, 0x19) => { + // SUB a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a - b)?; } - (_, _, 0, 0x19) => { - // SUB1 a b -- c - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a - b)?; + (_, _, _, 0x1a) => { + // MUL a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a * b)?; } - (_, _, 1, 0x19) => { - // SUB2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a - b)?; + (_, _, _, 0x1b) => { + // DIV a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a / b)?; } - (_, _, 0, 0x1a) => { - // MUL1 a b -- c - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a * b)?; + (_, _, _, 0x1c) => { + // AND a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a & b)?; } - (_, _, 1, 0x1a) => { - // MUL2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a * b)?; + (_, _, _, 0x1d) => { + // OR a b -- c + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a | b)?; } - (_, _, 0, 0x1b) => { - // DIV1 a b -- c - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a / b)?; + (_, _, _, 0x1e) => { + // XOR a8 b8 -- c8 + let b = pop(wst.clone())?; + let a = pop(wst.clone())?; + push(wst.clone(), a ^ b)?; } - (_, _, 1, 0x1b) => { - // DIV2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a / b)?; - } - (_, _, 0, 0x1c) => { - // AND1 a8 b8 -- c8 - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a & b)?; - } - (_, _, 1, 0x1c) => { - // AND2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a & b)?; - } - (_, _, 0, 0x1d) => { - // OR1 a8 b8 -- c8 - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a | b)?; - } - (_, _, 1, 0x1d) => { - // OR2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a | b)?; - } - (_, _, 0, 0x1e) => { - // XOR1 a8 b8 -- c8 - let mut wst = wst.borrow_mut(); - let b = wst.pop1()?; - let a = wst.pop1()?; - wst.push1(a ^ b)?; - } - (_, _, 1, 0x1e) => { - // XOR2 a16 b16 -- c16 - let mut wst = wst.borrow_mut(); - let b = wst.pop2()?; - let a = wst.pop2()?; - wst.push2(a ^ b)?; - } - (_, _, 0, 0x1f) => { - // SFT1 a shift8 -- b - let mut wst = wst.borrow_mut(); - let shift = wst.pop1()?; + (_, _, _, 0x1f) => { + // SFT a shift8 -- b + let shift = wst.borrow_mut().pop1()?; let [left, right] = [shift >> 4, shift & 0xF]; - let a = wst.pop1()?; - wst.push1((a >> right) << left)?; + let a = pop(wst.clone())?; + push(wst.clone(), (a >> right) << left)?; } - (_, _, 1, 0x1f) => { - // SFT2 a shift8 -- b - let mut wst = wst.borrow_mut(); - let shift = wst.pop1()?; - let [left, right] = [shift >> 4, shift & 0xF]; - let a = wst.pop2()?; - wst.push2((a >> right) << left)?; - } - _ => unreachable!() + _ => unreachable!(), } } }