[NO TESTS] WIP
This commit is contained in:
parent
6e92ae507f
commit
2bc93922bc
1 changed files with 70 additions and 72 deletions
142
src/vm.rs
142
src/vm.rs
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in a new issue