[NO TESTS] WIP

This commit is contained in:
Reid 'arrdem' McKenzie 2022-12-20 10:33:39 -07:00
parent 6e92ae507f
commit 2bc93922bc

142
src/vm.rs
View file

@ -31,12 +31,12 @@ impl From<MemoryError> for UxnError {
#[derive(Debug)] #[derive(Debug)]
pub struct Uxn { pub struct Uxn {
memory: Rc<RefCell<TrivialMemory>>, pub memory: Rc<RefCell<TrivialMemory>>,
// Note: Using Rc so we can start with many NullDevs and replace them // Note: Using Rc so we can start with many NullDevs and replace them
devices: [Rc<RefCell<dyn Device>>; 16], pub devices: [Rc<RefCell<dyn Device>>; 16],
pc: u16, // Program counter pub pc: u16, // Program counter
wst: Stack, // Data stack pub wst: Stack, // Data stack
rst: Stack, // Return stack pointer pub rst: Stack, // Return stack pointer
} }
impl Uxn { impl Uxn {
@ -136,15 +136,13 @@ impl Uxn {
let kflag: u8 = opcode & 0x80 >> 7; let kflag: u8 = opcode & 0x80 >> 7;
let icode: u8 = opcode & 0x1F; let icode: u8 = opcode & 0x1F;
let wst = || if rflag == 1 { self.wst } else { self.rst }; let [wst, rst] = {
let mut wd = 0u8; // Accumulated pop if rflag == 0 {
let mut widx = || { [&mut self.wst, &mut self.rst]
assert!(wd <= wst().idx); } else {
wst().idx - wd [&mut self.wst, &mut self.rst]
}; // Current index }
let rst = || if rflag == 1 { self.rst } else { self.wst }; };
let mut rd = 0u8; // Accumulated pop
let mut ridx = || rst().idx - rd; // Current index
// FIXME: Keep flag is unimplemented // FIXME: Keep flag is unimplemented
match (kflag, rflag, sflag, icode) { match (kflag, rflag, sflag, icode) {
@ -154,140 +152,140 @@ impl Uxn {
} }
(_, _, 0, 0x00) => { (_, _, 0, 0x00) => {
// LIT1 // LIT1
wst().push1(self.lda1(self.pc + 1)?); wst.push1(self.lda1(self.pc + 1)?);
self.pc += 1; self.pc += 1;
continue 'run; continue 'run;
} }
(_, _, 1, 0x00) => { (_, _, 1, 0x00) => {
// LIT2 // LIT2
wst().push2(self.lda2(self.pc + 1)?); wst.push2(self.lda2(self.pc + 1)?);
self.pc += 2; self.pc += 2;
continue 'run; continue 'run;
} }
(_, _, 0, 0x01) => { (_, _, 0, 0x01) => {
// INC1 // INC1
let a = wst().pop1()?; let a = wst.pop1()?;
wst().push1(a + 1); wst.push1(a + 1);
} }
(_, _, 1, 0x01) => { (_, _, 1, 0x01) => {
// INC1 // INC1
let a = wst().pop2()?; let a = wst.pop2()?;
wst().push2(a + 1); wst.push2(a + 1);
} }
(_, _, 0, 0x02) => { (_, _, 0, 0x02) => {
// POP1 // POP1
wst().pop1(); wst.pop1();
} }
(_, _, 1, 0x02) => { (_, _, 1, 0x02) => {
// POP2 // POP2
wst().pop2(); wst.pop2();
} }
(_, _, 0, 0x03) => { (_, _, 0, 0x03) => {
// NIP1 a b -- a // NIP1 a b -- a
let keep = wst().pop1()?; let keep = wst.pop1()?;
wst().pop1(); wst.pop1();
wst().push1(keep)?; wst.push1(keep)?;
} }
(_, _, 1, 0x03) => { (_, _, 1, 0x03) => {
// NIP2 a b -- a // NIP2 a b -- a
let keep = wst().pop2()?; let keep = wst.pop2()?;
wst().pop2()?; wst.pop2()?;
wst().push2(keep)?; wst.push2(keep)?;
} }
(_, _, 0, 0x04) => { (_, _, 0, 0x04) => {
// SWP1 // SWP1
let a = wst().pop1()?; let a = wst.pop1()?;
let b = wst().pop1()?; let b = wst.pop1()?;
wst().push1(a)?; wst.push1(a)?;
wst().push1(b)?; wst.push1(b)?;
} }
(_, _, 1, 0x04) => { (_, _, 1, 0x04) => {
// SWP2 // SWP2
let a = wst().pop2()?; let a = wst.pop2()?;
let b = wst().pop2()?; let b = wst.pop2()?;
wst().push2(a)?; wst.push2(a)?;
wst().push2(b)?; wst.push2(b)?;
} }
(_, _, 0, 0x05) => { (_, _, 0, 0x05) => {
// ROT // ROT
let a = wst().pop1()?; let a = wst.pop1()?;
let b = wst().pop1()?; let b = wst.pop1()?;
let c = wst().pop1()?; let c = wst.pop1()?;
wst().push1(b)?; wst.push1(b)?;
wst().push1(c)?; wst.push1(c)?;
wst().push1(a)?; wst.push1(a)?;
} }
(_, _, 1, 0x05) => { (_, _, 1, 0x05) => {
// ROT // ROT
let a = wst().pop2()?; let a = wst.pop2()?;
let b = wst().pop2()?; let b = wst.pop2()?;
let c = wst().pop2()?; let c = wst.pop2()?;
wst().push2(b)?; wst.push2(b)?;
wst().push2(c)?; wst.push2(c)?;
wst().push2(a)?; wst.push2(a)?;
} }
(_, _, 0, 0x06) => { (_, _, 0, 0x06) => {
// DUP2 // DUP2
let a = wst().peek1()?; let a = wst.peek1()?;
wst().push1(a)?; wst.push1(a)?;
} }
(_, _, 1, 0x06) => { (_, _, 1, 0x06) => {
// DUP2 // DUP2
let a = wst().peek2()?; let a = wst.peek2()?;
wst().push2(a)?; wst.push2(a)?;
} }
(_, _, 0, 0x07) => { (_, _, 0, 0x07) => {
// OVR1 a b -- a b a // OVR1 a b -- a b a
if wst().idx < 2 { if wst.idx < 2 {
return Err(UxnError::StackError(StackError::StackUnderflow)); return Err(UxnError::StackError(StackError::StackUnderflow));
} }
wst().push1(wst().get1(wst().idx - 2)?)?; wst.push1(wst.get1(wst.idx - 2)?)?;
} }
(_, _, 1, 0x07) => { (_, _, 1, 0x07) => {
// OVR2 a b -- a b a // OVR2 a b -- a b a
if wst().idx < 4 { if wst.idx < 4 {
return Err(UxnError::StackError(StackError::StackUnderflow)); return Err(UxnError::StackError(StackError::StackUnderflow));
} }
wst().push2(wst().get2(wst().idx - 4)?)?; wst.push2(wst.get2(wst.idx - 4)?)?;
} }
(_, _, 0, 0x08) => { (_, _, 0, 0x08) => {
// EQU1 // EQU1
let a = wst().pop1()?; let a = wst.pop1()?;
let b = wst().pop1()?; let b = wst.pop1()?;
if a == b { if a == b {
wst().push1(1)?; wst.push1(1)?;
} else { } else {
wst().push1(0)?; wst.push1(0)?;
} }
} }
(_, _, 1, 0x08) => { (_, _, 1, 0x08) => {
// EQU2 // EQU2
let a = wst().pop2()?; let a = wst.pop2()?;
let b = wst().pop2()?; let b = wst.pop2()?;
if a == b { if a == b {
wst().push1(1)?; wst.push1(1)?;
} else { } else {
wst().push1(0)?; wst.push1(0)?;
} }
} }
(_, _, 0, 0x09) => { (_, _, 0, 0x09) => {
// NEQ1 // NEQ1
let a = wst().pop1()?; let a = wst.pop1()?;
let b = wst().pop1()?; let b = wst.pop1()?;
if a == b { if a == b {
wst().push1(0)?; wst.push1(0)?;
} else { } else {
wst().push1(1)?; wst.push1(1)?;
} }
} }
(_, _, 1, 0x09) => { (_, _, 1, 0x09) => {
// NEQ2 // NEQ2
let a = wst().pop2()?; let a = wst.pop2()?;
let b = wst().pop2()?; let b = wst.pop2()?;
if a == b { if a == b {
wst().push1(0)?; wst.push1(0)?;
} else { } else {
wst().push1(1)?; wst.push1(1)?;
} }
} }
(_, _, _, 0x0a) => { (_, _, _, 0x0a) => {