[NO TESTS] WIP
This commit is contained in:
parent
6bf7c7425e
commit
6e92ae507f
1 changed files with 111 additions and 46 deletions
157
src/vm.rs
157
src/vm.rs
|
@ -17,6 +17,18 @@ pub enum UxnError {
|
|||
DivisionByZero,
|
||||
}
|
||||
|
||||
impl From<StackError> for UxnError {
|
||||
fn from(e: StackError) -> UxnError {
|
||||
UxnError::StackError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MemoryError> for UxnError {
|
||||
fn from(e: MemoryError) -> UxnError {
|
||||
UxnError::MemoryError(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Uxn {
|
||||
memory: Rc<RefCell<TrivialMemory>>,
|
||||
|
@ -93,6 +105,10 @@ impl Uxn {
|
|||
self.memory.borrow().get1(address)
|
||||
}
|
||||
|
||||
pub fn lda2(&mut self, address: u16) -> Result<u16, MemoryError> {
|
||||
self.memory.borrow().get2(address)
|
||||
}
|
||||
|
||||
// Run one clock cycle (instruction)
|
||||
pub fn step(&mut self) -> Result<(), UxnError> {
|
||||
Ok(())
|
||||
|
@ -115,21 +131,22 @@ impl Uxn {
|
|||
Err(e) => return Err(UxnError::MemoryError(e)),
|
||||
Ok(opcode) => {
|
||||
// Extract flags
|
||||
let sflag: bool = opcode & 0x20 != 0;
|
||||
let rflag: bool = opcode & 0x40 != 0;
|
||||
let kflag: bool = opcode & 0x80 != 0;
|
||||
let sflag: u8 = opcode & 0x20 >> 5;
|
||||
let rflag: u8 = opcode & 0x40 >> 6;
|
||||
let kflag: u8 = opcode & 0x80 >> 7;
|
||||
let icode: u8 = opcode & 0x1F;
|
||||
|
||||
let wst = || if rflag { self.wst } else { self.rst };
|
||||
let wst = || if rflag == 1 { self.wst } else { self.rst };
|
||||
let mut wd = 0u8; // Accumulated pop
|
||||
let mut widx = || {
|
||||
assert!(wd <= wst().idx);
|
||||
wst().idx - wd
|
||||
}; // Current index
|
||||
let rst = || if rflag { self.rst } else { self.wst };
|
||||
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
|
||||
match (kflag, rflag, sflag, icode) {
|
||||
(0, 0, 0, 0x00) => {
|
||||
// BRK
|
||||
|
@ -137,24 +154,24 @@ impl Uxn {
|
|||
}
|
||||
(_, _, 0, 0x00) => {
|
||||
// LIT1
|
||||
wst().push1(self.ld1(self.pc + 1));
|
||||
wst().push1(self.lda1(self.pc + 1)?);
|
||||
self.pc += 1;
|
||||
continue 'run;
|
||||
}
|
||||
(_, _, 1, 0x00) => {
|
||||
// LIT2
|
||||
wst().push2(self.ld2(self.pc + 1));
|
||||
wst().push2(self.lda2(self.pc + 1)?);
|
||||
self.pc += 2;
|
||||
continue 'run;
|
||||
}
|
||||
(_, _, 0, 0x01) => {
|
||||
// INC1
|
||||
let a = wst().pop1();
|
||||
let a = wst().pop1()?;
|
||||
wst().push1(a + 1);
|
||||
}
|
||||
(_, _, 1, 0x01) => {
|
||||
// INC1
|
||||
let a = wst().pop2();
|
||||
let a = wst().pop2()?;
|
||||
wst().push2(a + 1);
|
||||
}
|
||||
(_, _, 0, 0x02) => {
|
||||
|
@ -167,63 +184,111 @@ impl Uxn {
|
|||
}
|
||||
(_, _, 0, 0x03) => {
|
||||
// NIP1 a b -- a
|
||||
let keep = wst().pop1();
|
||||
let keep = wst().pop1()?;
|
||||
wst().pop1();
|
||||
wst().push1(keep);
|
||||
wst().push1(keep)?;
|
||||
}
|
||||
(_, _, 1, 0x03) => {
|
||||
// NIP2 a b -- a
|
||||
let keep = wst().pop12();
|
||||
wst().pop2();
|
||||
wst().push2(keep);
|
||||
let keep = wst().pop2()?;
|
||||
wst().pop2()?;
|
||||
wst().push2(keep)?;
|
||||
}
|
||||
(_, _, 0, 0x04) => {
|
||||
// SWP1
|
||||
let a = wst().pop1();
|
||||
let b = wst().pop1();
|
||||
wst().push1(a);
|
||||
wst().push1(b);
|
||||
let a = wst().pop1()?;
|
||||
let b = wst().pop1()?;
|
||||
wst().push1(a)?;
|
||||
wst().push1(b)?;
|
||||
}
|
||||
(_, _, 1, 0x04) => {
|
||||
// SWP2
|
||||
let a = wst().pop2();
|
||||
let b = wst().pop2();
|
||||
wst().push2(a);
|
||||
wst().push2(b);
|
||||
let a = wst().pop2()?;
|
||||
let b = wst().pop2()?;
|
||||
wst().push2(a)?;
|
||||
wst().push2(b)?;
|
||||
}
|
||||
(_, _, 0, 0x05) => {
|
||||
// ROT
|
||||
let a = wst().pop1();
|
||||
let b = wst().pop1();
|
||||
let c = wst().pop1();
|
||||
wst().push1(b);
|
||||
wst().push1(c);
|
||||
wst().push1(a);
|
||||
let a = wst().pop1()?;
|
||||
let b = wst().pop1()?;
|
||||
let c = wst().pop1()?;
|
||||
wst().push1(b)?;
|
||||
wst().push1(c)?;
|
||||
wst().push1(a)?;
|
||||
}
|
||||
(_, _, 1, 0x05) => {
|
||||
// ROT
|
||||
let a = wst().pop2();
|
||||
let b = wst().pop2();
|
||||
let c = wst().pop2();
|
||||
wst().push2(b);
|
||||
wst().push2(c);
|
||||
wst().push2(a);
|
||||
let a = wst().pop2()?;
|
||||
let b = wst().pop2()?;
|
||||
let c = wst().pop2()?;
|
||||
wst().push2(b)?;
|
||||
wst().push2(c)?;
|
||||
wst().push2(a)?;
|
||||
}
|
||||
(_, _, _, 0x06) => {
|
||||
// DUP
|
||||
()
|
||||
(_, _, 0, 0x06) => {
|
||||
// DUP2
|
||||
let a = wst().peek1()?;
|
||||
wst().push1(a)?;
|
||||
}
|
||||
(_, _, _, 0x07) => {
|
||||
// OVR
|
||||
()
|
||||
(_, _, 1, 0x06) => {
|
||||
// DUP2
|
||||
let a = wst().peek2()?;
|
||||
wst().push2(a)?;
|
||||
}
|
||||
(_, _, _, 0x08) => {
|
||||
// EQ
|
||||
()
|
||||
(_, _, 0, 0x07) => {
|
||||
// OVR1 a b -- a b a
|
||||
if wst().idx < 2 {
|
||||
return Err(UxnError::StackError(StackError::StackUnderflow));
|
||||
}
|
||||
wst().push1(wst().get1(wst().idx - 2)?)?;
|
||||
}
|
||||
(_, _, _, 0x09) => {
|
||||
// NEQ
|
||||
()
|
||||
(_, _, 1, 0x07) => {
|
||||
// OVR2 a b -- a b a
|
||||
if wst().idx < 4 {
|
||||
return Err(UxnError::StackError(StackError::StackUnderflow));
|
||||
}
|
||||
wst().push2(wst().get2(wst().idx - 4)?)?;
|
||||
}
|
||||
(_, _, 0, 0x08) => {
|
||||
// EQU1
|
||||
let a = wst().pop1()?;
|
||||
let b = wst().pop1()?;
|
||||
if a == b {
|
||||
wst().push1(1)?;
|
||||
} else {
|
||||
wst().push1(0)?;
|
||||
}
|
||||
}
|
||||
(_, _, 1, 0x08) => {
|
||||
// EQU2
|
||||
let a = wst().pop2()?;
|
||||
let b = wst().pop2()?;
|
||||
if a == b {
|
||||
wst().push1(1)?;
|
||||
} else {
|
||||
wst().push1(0)?;
|
||||
}
|
||||
}
|
||||
(_, _, 0, 0x09) => {
|
||||
// NEQ1
|
||||
let a = wst().pop1()?;
|
||||
let b = wst().pop1()?;
|
||||
if a == b {
|
||||
wst().push1(0)?;
|
||||
} else {
|
||||
wst().push1(1)?;
|
||||
}
|
||||
}
|
||||
(_, _, 1, 0x09) => {
|
||||
// NEQ2
|
||||
let a = wst().pop2()?;
|
||||
let b = wst().pop2()?;
|
||||
if a == b {
|
||||
wst().push1(0)?;
|
||||
} else {
|
||||
wst().push1(1)?;
|
||||
}
|
||||
}
|
||||
(_, _, _, 0x0a) => {
|
||||
// GTH
|
||||
|
|
Loading…
Reference in a new issue