[NO TESTS] WIP
This commit is contained in:
parent
8630125e4d
commit
6ee73379bb
1 changed files with 246 additions and 67 deletions
313
src/vm.rs
313
src/vm.rs
|
@ -130,6 +130,9 @@ impl Uxn {
|
|||
match self.lda1(self.pc) {
|
||||
Err(e) => return Err(UxnError::MemoryError(e)),
|
||||
Ok(opcode) => {
|
||||
// The value of PC is defined to be the value of the NEXT pc ala Mips
|
||||
self.pc += 1;
|
||||
|
||||
// Extract flags
|
||||
let sflag: u8 = opcode & 0x20 >> 5;
|
||||
let rflag: u8 = opcode & 0x40 >> 6;
|
||||
|
@ -144,7 +147,11 @@ impl Uxn {
|
|||
}
|
||||
};
|
||||
|
||||
// FIXME: Keep flag is unimplemented
|
||||
// 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");
|
||||
}
|
||||
|
||||
match (kflag, rflag, sflag, icode) {
|
||||
(0, 0, 0, 0x00) => {
|
||||
// BRK
|
||||
|
@ -152,39 +159,39 @@ impl Uxn {
|
|||
}
|
||||
(_, _, 0, 0x00) => {
|
||||
// LIT1
|
||||
wst.borrow_mut().push1(self.lda1(self.pc + 1)?);
|
||||
wst.borrow_mut().push1(self.lda1(self.pc + 1)?)?;
|
||||
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 + 1)?)?;
|
||||
self.pc += 2;
|
||||
continue 'run;
|
||||
}
|
||||
(_, _, 0, 0x01) => {
|
||||
// INC1
|
||||
let a = wst.borrow_mut().pop1()?;
|
||||
wst.borrow_mut().push1(a + 1);
|
||||
wst.borrow_mut().push1(a + 1)?;
|
||||
}
|
||||
(_, _, 1, 0x01) => {
|
||||
// INC1
|
||||
let a = wst.borrow_mut().pop2()?;
|
||||
wst.borrow_mut().push2(a + 1);
|
||||
wst.borrow_mut().push2(a + 1)?;
|
||||
}
|
||||
(_, _, 0, 0x02) => {
|
||||
// POP1
|
||||
wst.borrow_mut().pop1();
|
||||
wst.borrow_mut().pop1()?;
|
||||
}
|
||||
(_, _, 1, 0x02) => {
|
||||
// POP2
|
||||
wst.borrow_mut().pop2();
|
||||
wst.borrow_mut().pop2()?;
|
||||
}
|
||||
(_, _, 0, 0x03) => {
|
||||
// NIP1 a b -- a
|
||||
let mut wst = wst.borrow_mut();
|
||||
let keep = wst.pop1()?;
|
||||
wst.pop1();
|
||||
wst.pop1()?;
|
||||
wst.push1(keep)?;
|
||||
}
|
||||
(_, _, 1, 0x03) => {
|
||||
|
@ -352,85 +359,257 @@ impl Uxn {
|
|||
}
|
||||
(_, _, _, 0x0c) => {
|
||||
// JMP
|
||||
()
|
||||
let delta = wst.borrow_mut().pop1()? as i8;
|
||||
self.pc += delta as u16;
|
||||
}
|
||||
(_, _, _, 0x0d) => {
|
||||
// JCN
|
||||
()
|
||||
(_, _, 0, 0x0d) => {
|
||||
// JCN1 cnd8 addr8 (relative)
|
||||
let delta = wst.borrow_mut().pop1()? as i8;
|
||||
let cnd = wst.borrow_mut().pop1()?;
|
||||
if cnd != 0 {
|
||||
self.pc += delta;
|
||||
}
|
||||
(_, _, _, 0x0e) => {
|
||||
// JSR
|
||||
()
|
||||
}
|
||||
(_, _, _, 0x0f) => {
|
||||
// STH
|
||||
()
|
||||
(_, _, 2, 0x0d) => {
|
||||
// JCN2 cnd8 addr16 (absolute)
|
||||
let addr = wst.borrow_mut().pop2()?;
|
||||
let cnd = wst.borrow_mut().pop1()?;
|
||||
if cnd != 0 {
|
||||
self.pc = addr;
|
||||
}
|
||||
(_, _, _, 0x10) => {
|
||||
// LDZ
|
||||
()
|
||||
}
|
||||
(_, _, _, 0x11) => {
|
||||
// STZ
|
||||
()
|
||||
(_, _, 0, 0x0e) => {
|
||||
// JSR1 addr8 (relative)
|
||||
rst.borrow_mut().push2(self.pc);
|
||||
self.pc += (wst.borrow_mut().pop1()? as i8);
|
||||
}
|
||||
(_, _, _, 0x12) => {
|
||||
// LDR
|
||||
()
|
||||
(_, _, 1, 0x0e) => {
|
||||
// JSR2 addr16 (absolute)
|
||||
rst.borrow_mut().push2(self.pc);
|
||||
self.pc = wst.borrow_mut().pop2()?;
|
||||
}
|
||||
(_, _, _, 0x13) => {
|
||||
// STR
|
||||
()
|
||||
(_, _, 0, 0x0f) => {
|
||||
// STH1 a
|
||||
rst.borrow_mut().push1(wst.borrow_mut().pop1()?)?;
|
||||
}
|
||||
(_, _, _, 0x14) => {
|
||||
// LDA
|
||||
()
|
||||
(_, _, 1, 0x0f) => {
|
||||
// STH2 a
|
||||
rst.borrow_mut().push2(wst.borrow_mut().pop2()?)?;
|
||||
}
|
||||
(_, _, _, 0x15) => {
|
||||
// STA
|
||||
()
|
||||
(_, _, 0, 0x10) => {
|
||||
// LDZ1 a -- b8
|
||||
let wst = wst.borrow_mut();
|
||||
let val = self.memory.borrow().get1(wst.pop1()? as u16)?;
|
||||
wst.push1(val)?;
|
||||
}
|
||||
(_, _, _, 0x16) => {
|
||||
// DEI
|
||||
()
|
||||
(_, _, 1, 0x10) => {
|
||||
// LDZ2 a -- b16
|
||||
let wst = wst.borrow_mut();
|
||||
let val = self.memory.borrow().get2(wst.pop1()? as u16)?;
|
||||
wst.push2(val)?;
|
||||
}
|
||||
(_, _, _, 0x17) => {
|
||||
// DEO
|
||||
()
|
||||
(_, _, 0, 0x11) => {
|
||||
// STZ1 val addr8 --
|
||||
let wst = wst.borrow_mut();
|
||||
let addr = wst.pop1()?;
|
||||
let val = wst.pop1()?;
|
||||
self.memory.borrow_mut().set1(addr as u16, val);
|
||||
}
|
||||
(_, _, _, 0x18) => {
|
||||
// ADD
|
||||
()
|
||||
(_, _, 1, 0x11) => {
|
||||
// STZ2 val16 addr8 --
|
||||
let wst = wst.borrow_mut();
|
||||
let addr = wst.pop1()?;
|
||||
let val = wst.pop2()?;
|
||||
self.memory.borrow_mut().set2(addr as u16, val);
|
||||
}
|
||||
(_, _, _, 0x19) => {
|
||||
// SUB
|
||||
()
|
||||
(_, _, 0, 0x12) => {
|
||||
// LDR1 addr8 -- a8
|
||||
let wst = wst.borrow_mut();
|
||||
let delta = wst.pop1()? as i8;
|
||||
let val = self.memory.borrow().get1(self.pc + delta)?;
|
||||
wst.push1(val)?;
|
||||
}
|
||||
(_, _, _, 0x1a) => {
|
||||
// MUL
|
||||
()
|
||||
(_, _, 1, 0x12) => {
|
||||
// LDR2 addr8 -- a16
|
||||
let wst = wst.borrow_mut();
|
||||
let delta = wst.pop1()? as i8;
|
||||
let val = self.memory.borrow().get2(self.pc + delta)?;
|
||||
wst.push2(val)?;
|
||||
}
|
||||
(_, _, _, 0x1b) => {
|
||||
// DIV
|
||||
()
|
||||
(_, _, 0, 0x13) => {
|
||||
// STR1 val8 addr8
|
||||
let wst = wst.borrow_mut();
|
||||
let delta = wst.pop1()? as i8;
|
||||
let val = wst.pop1()?;
|
||||
self.memory.borrow_mut().set1(self.pc + delta, val);
|
||||
}
|
||||
(_, _, _, 0x1c) => {
|
||||
// AND
|
||||
()
|
||||
(_, _, 1, 0x13) => {
|
||||
// STR2 val16 addr8
|
||||
let wst = wst.borrow_mut();
|
||||
let delta = wst.pop1()? as i8;
|
||||
let val = wst.pop2()?;
|
||||
self.memory.borrow_mut().set2(self.pc + delta, val);
|
||||
}
|
||||
(_, _, _, 0x1d) => {
|
||||
// OR
|
||||
()
|
||||
(_, _, 0, 0x14) => {
|
||||
// LDA1 a16 -- a8
|
||||
let wst = wst.borrow_mut();
|
||||
let addr = wst.pop2()?;
|
||||
let val = self.memory.borrow_mut().get1(addr)?;
|
||||
wst.push1(val)?;
|
||||
}
|
||||
(_, _, _, 0x1e) => {
|
||||
// XOR
|
||||
()
|
||||
(_, _, 1, 0x14) => {
|
||||
// LDA2 a16 -- a16
|
||||
let wst = wst.borrow_mut();
|
||||
let addr = wst.pop2()?;
|
||||
let val = self.memory.borrow_mut().get2(addr)?;
|
||||
wst.push2(val)?;
|
||||
}
|
||||
(_, _, _, 0x1f) => {
|
||||
// SFT
|
||||
()
|
||||
(_, _, 0, 0x15) => {
|
||||
// STA1 val a16 --
|
||||
let 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 wst = wst.borrow_mut();
|
||||
let addr = wst.pop2()?;
|
||||
let val = wst.pop2()?;
|
||||
self.memory.borrow_mut().set2(addr, val)?;
|
||||
}
|
||||
(_, _, 0, 0x16) => {
|
||||
// DEI1 port8 -- a8
|
||||
let wst = wst.borrow_mut();
|
||||
let port = wst.pop1()?;
|
||||
wst.push1(self.dei1(port));
|
||||
}
|
||||
(_, _, 1, 0x16) => {
|
||||
// DEI2 port8 -- a16
|
||||
let wst = wst.borrow_mut();
|
||||
let port = wst.pop1()?;
|
||||
wst.push2(self.dei2(port));
|
||||
}
|
||||
(_, _, 0, 0x17) => {
|
||||
// DEO1 a8 port8 --
|
||||
let wst = wst.borrow_mut();
|
||||
let port = wst.pop1()?;
|
||||
let val = wst.pop1()?;
|
||||
self.deo1(port, val);
|
||||
}
|
||||
(_, _, 1, 0x17) => {
|
||||
// DEO2 a16 port8 --
|
||||
let wst = wst.borrow_mut();
|
||||
let port = wst.pop1()?;
|
||||
let val = wst.pop2()?;
|
||||
self.deo2(port, val);
|
||||
}
|
||||
(_, _, 0, 0x18) => {
|
||||
// ADD1 a b -- c
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a + b)?;
|
||||
}
|
||||
(_, _, 1, 0x18) => {
|
||||
// ADD2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a + b)?;
|
||||
}
|
||||
(_, _, 0, 0x19) => {
|
||||
// SUB1 a b -- c
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a - b)?;
|
||||
}
|
||||
(_, _, 1, 0x19) => {
|
||||
// SUB2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a - b)?;
|
||||
}
|
||||
(_, _, 0, 0x1a) => {
|
||||
// MUL1 a b -- c
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a * b)?;
|
||||
}
|
||||
(_, _, 1, 0x1a) => {
|
||||
// MUL2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a * b)?;
|
||||
}
|
||||
(_, _, 0, 0x1b) => {
|
||||
// DIV1 a b -- c
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a / b)?;
|
||||
}
|
||||
(_, _, 1, 0x1b) => {
|
||||
// DIV2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a / b)?;
|
||||
}
|
||||
(_, _, 0, 0x1c) => {
|
||||
// AND1 a8 b8 -- c8
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a & b)?;
|
||||
}
|
||||
(_, _, 1, 0x1c) => {
|
||||
// AND2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a & b)?;
|
||||
}
|
||||
(_, _, 0, 0x1d) => {
|
||||
// OR1 a8 b8 -- c8
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a | b)?;
|
||||
}
|
||||
(_, _, 1, 0x1d) => {
|
||||
// OR2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a | b)?;
|
||||
}
|
||||
(_, _, 0, 0x1e) => {
|
||||
// XOR1 a8 b8 -- c8
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop1()?;
|
||||
let a = wst.pop1()?;
|
||||
wst.push1(a ^ b)?;
|
||||
}
|
||||
(_, _, 1, 0x1e) => {
|
||||
// XOR2 a16 b16 -- c16
|
||||
let wst = wst.borrow_mut();
|
||||
let b = wst.pop2()?;
|
||||
let a = wst.pop2()?;
|
||||
wst.push2(a ^ b)?;
|
||||
}
|
||||
(_, _, 0, 0x1f) => {
|
||||
// SFT1
|
||||
unimplemented!()
|
||||
}
|
||||
(_, _, 1, 0x1f) => {
|
||||
// SFT2
|
||||
unimplemented!()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue