diff --git a/src/isa.rs b/src/isa.rs index e4d737a..3821e1b 100644 --- a/src/isa.rs +++ b/src/isa.rs @@ -42,8 +42,8 @@ impl Icode { pub const RETURN: u8 = 0x1 << 6; pub const KEEP: u8 = 0x1 << 7; - // Hacking around the weird official names for some things - pub const XOR: u8 = Icode::ORA; + // Hacking around the official names for some things + pub const XOR: u8 = Icode::EOR; pub const EQ: u8 = Icode::EQL; pub const NE: u8 = Icode::NEQ; pub const GT: u8 = Icode::GTH; diff --git a/src/vm.rs b/src/vm.rs index 716191e..2b6707e 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -418,7 +418,7 @@ impl Uxn { push(wst.clone(), a | b)?; } (_, _, _, Icode::EOR) => { - // XOR a8 b8 -- c8 + // XOR a b -- c8 let b = pop(wst.clone())?; let a = pop(wst.clone())?; push(wst.clone(), a ^ b)?; @@ -426,7 +426,7 @@ impl Uxn { (_, _, _, Icode::SFT) => { // SFT a shift8 -- b let shift = wst.borrow_mut().pop1()?; - let [left, right] = [shift >> 4, shift & 0xF]; + let [left, right] = [shift >> 4 & 0xF, shift & 0xF]; let a = pop(wst.clone())?; push(wst.clone(), (a >> right) << left)?; } diff --git a/tests/vm_tests.rs b/tests/vm_tests.rs index 251ec99..c73c337 100644 --- a/tests/vm_tests.rs +++ b/tests/vm_tests.rs @@ -713,3 +713,282 @@ fn test_sta2() { assert_eq!(vm.wst.borrow().idx(), 0); assert_eq!(vm.lda2(0x010c), Ok(0xFFEE)); } + +#[test] +fn test_add() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xFF, 0x01, Icode::ADD, Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x00)); +} + +#[test] +fn test_add2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xFF, 0x00, + Icode::LIT, 0x01, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + // u16 + u16 + Icode::ADD | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0xFF01)); +} + +#[test] +fn test_sub() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xFF, 0x01, Icode::SUB, Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0xFE)); +} + +#[test] +fn test_sub2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xFF, 0xFF, + Icode::LIT, 0x01, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::SUB | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0xFFFE)); +} + +#[test] +fn test_mul() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x4, 0x4, Icode::MUL, Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x10)); +} + +#[test] +fn test_mul2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xFF, 0xFF, + Icode::LIT, 0x01, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::MUL | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0xFFFF)); +} + +#[test] +fn test_div() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x10, 0x4, Icode::DIV, Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x4)); +} + +#[test] +fn test_div2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x10, 0x00, + Icode::LIT, 0x2, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::DIV | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0x0800)); +} + +#[test] +fn test_and() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xF, 0x1, Icode::AND, Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x1)); +} + +#[test] +fn test_and2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x10, 0x03, + Icode::LIT, 0x2, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::AND | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0x0002)); +} + +#[test] +fn test_or() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xF, 0x1, + Icode::OR, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0xF)); +} + +#[test] +fn test_or2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x10, 0x03, + Icode::LIT, 0x2, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::OR | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0x1003)); +} + +#[test] +fn test_xor() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0xF, 0x1, + Icode::XOR, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0xE)); +} + +#[test] +fn test_xor2() { + // The incantation for adding a u8 to a u16 is probably something involving using [ LIT #00 SWP ] but yeesh. + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x10, 0x03, + Icode::LIT, 0x2, + + // Promote u8 to u16 by stuffing an #00 in there. Yes coulda used a bigger lit but playing with the upcast. + Icode::LIT, 0x0, + Icode::SWP, + + Icode::XOR | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0x1001)); +} + +#[test] +fn test_sft_l() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x0F, 0x10, + Icode::SFT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x1E)); +} + +#[test] +fn test_sft_r() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x0F, 0x01, + Icode::SFT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 1); + assert_eq!(vm.wst.borrow().peek1(), Ok(0x07)); +} + +#[test] +fn test_sft_rl2() { + nofmt::pls! { + let mut vm = Uxn::of1(&[ + Icode::LIT | Icode::SHORT, 0x80, 0x01, + Icode::LIT, 0x21, // Shift truncates, so this will unset all the bits + Icode::SFT | Icode::SHORT, + Icode::BRK + ]); + } + assert_eq!(vm.run(64), Err(UxnError::Break)); + assert_eq!(vm.wst.borrow().idx(), 2); + assert_eq!(vm.wst.borrow().peek2(), Ok(0x0000)); +}