summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2024-09-02 17:39:52 +1200
committerBen Bridle <bridle.benjamin@gmail.com>2024-09-03 13:12:29 +1200
commit69588112045ebb4f1a8c6d561ac019be8dbbaf6d (patch)
tree2874329dc9f1f9cbcfe130f4771dcc505a3a1eef
parentf6e9349f60d003fca8dce6d4f6c76a1ad0c0e56d (diff)
downloadbedrock-core-69588112045ebb4f1a8c6d561ac019be8dbbaf6d.zip
Improve efficiency of some instructions
When a value is to be read and kept on the stack, instead of popping and immediately pushing it we now use a more efficient `get` stack method. The pop_u16 stack method has also been changed to a variation that assembles to fewer CPU instructions.
-rw-r--r--src/processor.rs92
-rw-r--r--src/stack.rs16
2 files changed, 62 insertions, 46 deletions
diff --git a/src/processor.rs b/src/processor.rs
index c9cde82..9c999c0 100644
--- a/src/processor.rs
+++ b/src/processor.rs
@@ -33,6 +33,10 @@ impl<D: DeviceBus> Processor<D> {
macro_rules! r_pop_8 { ($v:ident) => { let $v = self.rst.pop_u8(); }; }
macro_rules! w_pop_16 { ($v:ident) => { let $v = self.wst.pop_u16(); }; }
macro_rules! r_pop_16 { ($v:ident) => { let $v = self.rst.pop_u16(); }; }
+ macro_rules! w_get_8 { ($v:ident) => { let $v = self.wst.get_u8(); }; }
+ macro_rules! r_get_8 { ($v:ident) => { let $v = self.rst.get_u8(); }; }
+ macro_rules! w_get_16 { ($v:ident) => { let $v = self.wst.get_u16(); }; }
+ macro_rules! r_get_16 { ($v:ident) => { let $v = self.rst.get_u16(); }; }
macro_rules! m_read_8 { ($a:expr) => { self.mem.read_u8($a) }; }
macro_rules! m_read_16 { ($a:expr) => { self.mem.read_u16($a) }; }
macro_rules! m_lit_8 { ($l:ident) => { let $l = self.mem.read_u8_next(); }; }
@@ -57,25 +61,25 @@ impl<D: DeviceBus> Processor<D> {
/* HLT */ 0x00 => { return Some(Signal::Halt); }
/* JMP */ 0x01 => { w_pop_16!(a); jump!(a); }
/* JCN */ 0x02 => { w_pop_16!(a); w_pop_8!(t); if t!=0 {jump!(a)}; }
- /* JKN */ 0x03 => { w_pop_16!(a); w_pop_8!(t); w_psh_8!(t); if t!=0 {jump!(a)}; }
+ /* JKN */ 0x03 => { w_pop_16!(a); w_get_8!(t); if t!=0 {jump!(a)}; }
/* EQU */ 0x04 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x==y)); }
- /* NKQ */ 0x05 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x); w_psh_8!(y); w_psh_8!(truth!(x!=y)); }
+ /* NKQ */ 0x05 => { w_pop_8!(y); w_get_8!(x); w_psh_8!(y); w_psh_8!(truth!(x!=y)); }
/* LTH */ 0x06 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x <y)); }
/* GTH */ 0x07 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x >y)); }
/* LDA */ 0x08 => { w_pop_16!(a); w_psh_8!(m_read_8!(a)); }
/* STA */ 0x09 => { w_pop_16!(a); w_pop_8!(v); m_write_8!(v,a); }
- /* LKA */ 0x0A => { w_pop_16!(a); w_psh_16!(a); w_psh_8!(m_read_8!(a)); }
- /* SKA */ 0x0B => { w_pop_8!(v); w_pop_16!(a); w_psh_16!(a); m_write_8!(v,a); }
+ /* LKA */ 0x0A => { w_get_16!(a); w_psh_8!(m_read_8!(a)); }
+ /* SKA */ 0x0B => { w_pop_8!(v); w_get_16!(a); m_write_8!(v,a); }
/* LDD */ 0x0C => { w_pop_8!(p); w_psh_8!(d_read_8!(p)); }
/* STD */ 0x0D => { w_pop_8!(p); w_pop_8!(v); d_write_8!(v,p); }
/* SHF */ 0x0E => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(shf!(x,y)); }
/* SHC */ 0x0F => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(shc!(x,y)); }
/* PSH */ 0x10 => { r_pop_8!(x); w_psh_8!(x); }
- /* PSK */ 0x11 => { r_pop_8!(x); r_psh_8!(x); w_psh_8!(x); }
+ /* PSK */ 0x11 => { r_get_8!(x); w_psh_8!(x); }
/* POP */ 0x12 => { w_pop_8!(_x); }
/* SPL */ 0x13 => { w_pop_8!(x); nyb!(x=>a,b); w_psh_8!(a); w_psh_8!(b); }
- /* DUP */ 0x14 => { w_pop_8!(x); w_psh_8!(x); w_psh_8!(x); }
- /* OVR */ 0x15 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x); w_psh_8!(y); w_psh_8!(x); }
+ /* DUP */ 0x14 => { w_get_8!(x); w_psh_8!(x); }
+ /* OVR */ 0x15 => { w_pop_8!(y); w_get_8!(x); w_psh_8!(y); w_psh_8!(x); }
/* SWP */ 0x16 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(y); w_psh_8!(x); }
/* ROT */ 0x17 => { w_pop_8!(z); w_pop_8!(y); w_pop_8!(x); w_psh_8!(y); w_psh_8!(z); w_psh_8!(x); }
/* ADD */ 0x18 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.wrapping_add(y)); }
@@ -90,25 +94,25 @@ impl<D: DeviceBus> Processor<D> {
/* DB1 */ 0x20 => { return Some(Signal::Debug(DebugVariant::DB1)); }
/* JSR */ 0x21 => { w_pop_16!(a); r_psh_16!(pc!()); jump!(a); }
/* JSN */ 0x22 => { w_pop_16!(a); w_pop_8!(t); if t!=0 {r_psh_16!(pc!()); jump!(a)}; }
- /* JKN* */ 0x23 => { w_pop_16!(a); w_pop_16!(t); w_psh_16!(t); if t!=0 {jump!(a)}; }
+ /* JKN* */ 0x23 => { w_pop_16!(a); w_get_16!(t); if t!=0 {jump!(a)}; }
/* EQU* */ 0x24 => { w_pop_16!(y); w_pop_16!(x); w_psh_8!(truth!(x==y)); }
- /* NKQ* */ 0x25 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x); w_psh_16!(y); w_psh_8!(truth!(x!=y)); }
+ /* NKQ* */ 0x25 => { w_pop_16!(y); w_get_16!(x); w_psh_16!(y); w_psh_8!(truth!(x!=y)); }
/* LTH* */ 0x26 => { w_pop_16!(y); w_pop_16!(x); w_psh_8!(truth!(x <y)); }
/* GTH* */ 0x27 => { w_pop_16!(y); w_pop_16!(x); w_psh_8!(truth!(x >y)); }
/* LDA* */ 0x28 => { w_pop_16!(a); w_psh_16!(m_read_16!(a)); }
/* STA* */ 0x29 => { w_pop_16!(a); w_pop_16!(v); m_write_16!(v,a); }
- /* LKA* */ 0x2A => { w_pop_16!(a); w_psh_16!(a); w_psh_16!(m_read_16!(a)); }
- /* SKA* */ 0x2B => { w_pop_16!(v); w_pop_16!(a); w_psh_16!(a); m_write_16!(v,a); }
+ /* LKA* */ 0x2A => { w_get_16!(a); w_psh_16!(m_read_16!(a)); }
+ /* SKA* */ 0x2B => { w_pop_16!(v); w_get_16!(a); m_write_16!(v,a); }
/* LDD* */ 0x2C => { w_pop_8!(p); w_psh_16!(d_read_16!(p)); }
/* STD* */ 0x2D => { w_pop_8!(p); w_pop_16!(v); d_write_16!(v,p); }
/* SHF* */ 0x2E => { w_pop_8!(y); w_pop_16!(x); w_psh_16!(shf!(x,y)); }
/* SHC* */ 0x2F => { w_pop_8!(y); w_pop_16!(x); w_psh_16!(shc!(x,y)); }
/* PSH* */ 0x30 => { r_pop_16!(x); w_psh_16!(x); }
- /* PSK* */ 0x31 => { r_pop_16!(x); r_psh_16!(x); w_psh_16!(x); }
+ /* PSK* */ 0x31 => { r_get_16!(x); w_psh_16!(x); }
/* POP* */ 0x32 => { w_pop_16!(_x); }
/* SPL* */ 0x33 => { w_pop_8!(y); w_pop_8!(x); nyb!(x=>a,b); nyb!(y=>c,d); w_psh_8!(a); w_psh_8!(b); w_psh_8!(c); w_psh_8!(d); }
- /* DUP* */ 0x34 => { w_pop_16!(x); w_psh_16!(x); w_psh_16!(x); }
- /* OVR* */ 0x35 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x); w_psh_16!(y); w_psh_16!(x); }
+ /* DUP* */ 0x34 => { w_get_16!(x); w_psh_16!(x); }
+ /* OVR* */ 0x35 => { w_pop_16!(y); w_get_16!(x); w_psh_16!(y); w_psh_16!(x); }
/* SWP* */ 0x36 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(y); w_psh_16!(x); }
/* ROT* */ 0x37 => { w_pop_16!(z); w_pop_16!(y); w_pop_16!(x); w_psh_16!(y); w_psh_16!(z); w_psh_16!(x); }
/* ADD* */ 0x38 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x.wrapping_add(y)); }
@@ -123,15 +127,15 @@ impl<D: DeviceBus> Processor<D> {
/* DB2 */ 0x40 => { return Some(Signal::Debug(DebugVariant::DB2)); }
/* JMP: */ 0x41 => { m_lit_16!(a); jump!(a); }
/* JCN: */ 0x42 => { m_lit_16!(a); w_pop_8!(t); if t!=0{jump!(a)}; }
- /* JKN: */ 0x43 => { m_lit_16!(a); w_pop_8!(t); w_psh_8!(t); if t!=0{jump!(a)}; }
+ /* JKN: */ 0x43 => { m_lit_16!(a); w_get_8!(t); if t!=0{jump!(a)}; }
/* EQU: */ 0x44 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(truth!(x==y)); }
- /* NKQ: */ 0x45 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(x); w_psh_8!(y); w_psh_8!(truth!(x!=y)); }
+ /* NKQ: */ 0x45 => { m_lit_8!(y); w_get_8!(x); w_psh_8!(y); w_psh_8!(truth!(x!=y)); }
/* LTH: */ 0x46 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(truth!(x <y)); }
/* GTH: */ 0x47 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(truth!(x >y)); }
/* LDA: */ 0x48 => { m_lit_16!(a); w_psh_8!(m_read_8!(a)); }
/* STA: */ 0x49 => { m_lit_16!(a); w_pop_8!(v); m_write_8!(v,a); }
/* LKA: */ 0x4A => { m_lit_16!(a); w_psh_16!(a); w_psh_8!(m_read_8!(a)); }
- /* SKA: */ 0x4B => { m_lit_8!(v); w_pop_16!(a); w_psh_16!(a); m_write_8!(v,a); }
+ /* SKA: */ 0x4B => { m_lit_8!(v); w_get_16!(a); m_write_8!(v,a); }
/* LDD: */ 0x4C => { m_lit_8!(p); w_psh_8!(d_read_8!(p)); }
/* STD: */ 0x4D => { m_lit_8!(p); w_pop_8!(v); d_write_8!(v,p); }
/* SHF: */ 0x4E => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(shf!(x,y)); }
@@ -141,7 +145,7 @@ impl<D: DeviceBus> Processor<D> {
/* POP: */ 0x52 => { m_lit_8!(_x); }
/* SPL: */ 0x53 => { m_lit_8!(x); nyb!(x=>a,b); w_psh_8!(a); w_psh_8!(b); }
/* DUP: */ 0x54 => { m_lit_8!(x); w_psh_8!(x); w_psh_8!(x); }
- /* OVR: */ 0x55 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(x); w_psh_8!(y); w_psh_8!(x); }
+ /* OVR: */ 0x55 => { m_lit_8!(y); w_get_8!(x); w_psh_8!(y); w_psh_8!(x); }
/* SWP: */ 0x56 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(y); w_psh_8!(x); }
/* ROT: */ 0x57 => { m_lit_8!(z); w_pop_8!(y); w_pop_8!(x); w_psh_8!(y); w_psh_8!(z); w_psh_8!(x); }
/* ADD: */ 0x58 => { m_lit_8!(y); w_pop_8!(x); w_psh_8!(x.wrapping_add(y)); }
@@ -156,15 +160,15 @@ impl<D: DeviceBus> Processor<D> {
/* DB3 */ 0x60 => { return Some(Signal::Debug(DebugVariant::DB3)); }
/* JSR: */ 0x61 => { m_lit_16!(a); r_psh_16!(pc!()); jump!(a); }
/* JSN: */ 0x62 => { m_lit_16!(a); w_pop_8!(t); if t!=0 {r_psh_16!(pc!()); jump!(a)}; }
- /* JKN*: */ 0x63 => { m_lit_16!(a); w_pop_16!(t); w_psh_16!(t); if t!=0 {jump!(a)}; }
+ /* JKN*: */ 0x63 => { m_lit_16!(a); w_get_16!(t); if t!=0 {jump!(a)}; }
/* EQU*: */ 0x64 => { m_lit_16!(y); w_pop_16!(x); w_psh_8!(truth!(x==y)); }
- /* NKQ*: */ 0x65 => { m_lit_16!(y); w_pop_16!(x); w_psh_16!(x); w_psh_16!(y); w_psh_8!(truth!(x!=y)); }
+ /* NKQ*: */ 0x65 => { m_lit_16!(y); w_get_16!(x); w_psh_16!(y); w_psh_8!(truth!(x!=y)); }
/* LTH*: */ 0x66 => { m_lit_16!(y); w_pop_16!(x); w_psh_8!(truth!(x <y)); }
/* GTH*: */ 0x67 => { m_lit_16!(y); w_pop_16!(x); w_psh_8!(truth!(x >y)); }
/* LDA*: */ 0x68 => { m_lit_16!(a); w_psh_16!(m_read_16!(a)); }
/* STA*: */ 0x69 => { m_lit_16!(a); w_pop_16!(v); m_write_16!(v,a); }
/* LKA*: */ 0x6A => { m_lit_16!(a); w_psh_16!(a); w_psh_16!(m_read_16!(a)); }
- /* SKA*: */ 0x6B => { m_lit_16!(v); w_pop_16!(a); w_psh_16!(a); m_write_16!(v,a); }
+ /* SKA*: */ 0x6B => { m_lit_16!(v); w_get_16!(a); m_write_16!(v,a); }
/* LDD*: */ 0x6C => { m_lit_8!(p); w_psh_16!(d_read_16!(p)); }
/* STD*: */ 0x6D => { m_lit_8!(p); w_pop_16!(v); d_write_16!(v,p); }
/* SHF*: */ 0x6E => { m_lit_8!(y); w_pop_16!(x); w_psh_16!(shf!(x,y)); }
@@ -174,7 +178,7 @@ impl<D: DeviceBus> Processor<D> {
/* POP*: */ 0x72 => { m_lit_16!(_x); }
/* SPL*: */ 0x73 => { m_lit_8!(x); m_lit_8!(y); nyb!(x=>a,b); nyb!(y=>c,d); w_psh_8!(a); w_psh_8!(b); w_psh_8!(c); w_psh_8!(d); }
/* DUP*: */ 0x74 => { m_lit_16!(x); w_psh_16!(x); w_psh_16!(x); }
- /* OVR*: */ 0x75 => { m_lit_16!(y); w_pop_16!(x); w_psh_16!(x); w_psh_16!(y); w_psh_16!(x); }
+ /* OVR*: */ 0x75 => { m_lit_16!(y); w_get_16!(x); w_psh_16!(y); w_psh_16!(x); }
/* SWP*: */ 0x76 => { m_lit_16!(y); w_pop_16!(x); w_psh_16!(y); w_psh_16!(x); }
/* ROT*: */ 0x77 => { m_lit_16!(z); w_pop_16!(y); w_pop_16!(x); w_psh_16!(y); w_psh_16!(z); w_psh_16!(x); }
/* ADD*: */ 0x78 => { m_lit_16!(y); w_pop_16!(x); w_psh_16!(x.wrapping_add(y)); }
@@ -189,25 +193,25 @@ impl<D: DeviceBus> Processor<D> {
/* DB4 */ 0x80 => { return Some(Signal::Debug(DebugVariant::DB4)); }
/* JMPr */ 0x81 => { r_pop_16!(a); jump!(a); }
/* JCNr */ 0x82 => { r_pop_16!(a); r_pop_8!(t); if t!=0{jump!(a)}; }
- /* JKNr */ 0x83 => { r_pop_16!(a); r_pop_8!(t); r_psh_8!(t); if t!=0{jump!(a)}; }
+ /* JKNr */ 0x83 => { r_pop_16!(a); r_get_8!(t); if t!=0{jump!(a)}; }
/* EQUr */ 0x84 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x==y)); }
- /* NKQr */ 0x85 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x); r_psh_8!(y); r_psh_8!(truth!(x!=y)); }
+ /* NKQr */ 0x85 => { r_pop_8!(y); r_get_8!(x); r_psh_8!(y); r_psh_8!(truth!(x!=y)); }
/* LTHr */ 0x86 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x <y)); }
/* GTHr */ 0x87 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x >y)); }
/* LDAr */ 0x88 => { r_pop_16!(a); r_psh_8!(m_read_8!(a)); }
/* STAr */ 0x89 => { r_pop_16!(a); r_pop_8!(v); m_write_8!(v,a); }
- /* LKAr */ 0x8A => { r_pop_16!(a); r_psh_16!(a); r_psh_8!(m_read_8!(a)); }
- /* SKAr */ 0x8B => { r_pop_8!(v); r_pop_16!(a); r_psh_16!(a); m_write_8!(v,a); }
+ /* LKAr */ 0x8A => { r_get_16!(a); r_psh_8!(m_read_8!(a)); }
+ /* SKAr */ 0x8B => { r_pop_8!(v); r_get_16!(a); m_write_8!(v,a); }
/* LDDr */ 0x8C => { r_pop_8!(p); r_psh_8!(d_read_8!(p)); }
/* STDr */ 0x8D => { r_pop_8!(p); r_pop_8!(v); d_write_8!(v,p); }
/* SHFr */ 0x8E => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(shf!(x,y)); }
/* SHCr */ 0x8F => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(shc!(x,y)); }
/* PSHr */ 0x90 => { w_pop_8!(x); r_psh_8!(x); }
- /* PSKr */ 0x91 => { w_pop_8!(x); w_psh_8!(x); r_psh_8!(x); }
+ /* PSKr */ 0x91 => { w_get_8!(x); r_psh_8!(x); }
/* POPr */ 0x92 => { r_pop_8!(_x); }
/* SPLr */ 0x93 => { r_pop_8!(x); nyb!(x=>a,b); r_psh_8!(a); r_psh_8!(b); }
- /* DUPr */ 0x94 => { r_pop_8!(x); r_psh_8!(x); r_psh_8!(x); }
- /* OVRr */ 0x95 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x); r_psh_8!(y); r_psh_8!(x); }
+ /* DUPr */ 0x94 => { r_get_8!(x); r_psh_8!(x); }
+ /* OVRr */ 0x95 => { r_pop_8!(y); r_get_8!(x); r_psh_8!(y); r_psh_8!(x); }
/* SWPr */ 0x96 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(y); r_psh_8!(x); }
/* ROTr */ 0x97 => { r_pop_8!(z); r_pop_8!(y); r_pop_8!(x); r_psh_8!(y); r_psh_8!(z); r_psh_8!(x); }
/* ADDr */ 0x98 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.wrapping_add(y)); }
@@ -223,25 +227,25 @@ impl<D: DeviceBus> Processor<D> {
/* DB5 */ 0xA0 => { return Some(Signal::Debug(DebugVariant::DB5)); }
/* JSRr */ 0xA1 => { r_pop_16!(a); w_psh_16!(pc!()); jump!(a); }
/* JSNr */ 0xA2 => { r_pop_16!(a); r_pop_8!(t); if t!=0 {w_psh_16!(pc!()); jump!(a)}; }
- /* JKNr* */ 0xA3 => { r_pop_16!(a); r_pop_16!(t); r_psh_16!(t); if t!=0 {jump!(a)}; }
+ /* JKNr* */ 0xA3 => { r_pop_16!(a); r_get_16!(t); if t!=0 {jump!(a)}; }
/* EQUr* */ 0xA4 => { r_pop_16!(y); r_pop_16!(x); r_psh_8!(truth!(x==y)); }
- /* NKQr* */ 0xA5 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x); r_psh_16!(y); r_psh_8!(truth!(x!=y)); }
+ /* NKQr* */ 0xA5 => { r_pop_16!(y); r_get_16!(x); r_psh_16!(y); r_psh_8!(truth!(x!=y)); }
/* LTHr* */ 0xA6 => { r_pop_16!(y); r_pop_16!(x); r_psh_8!(truth!(x <y)); }
/* GTHr* */ 0xA7 => { r_pop_16!(y); r_pop_16!(x); r_psh_8!(truth!(x >y)); }
/* LDAr* */ 0xA8 => { r_pop_16!(a); r_psh_16!(m_read_16!(a)); }
/* STAr* */ 0xA9 => { r_pop_16!(a); r_pop_16!(v); m_write_16!(v,a); }
- /* LKAr* */ 0xAA => { r_pop_16!(a); r_psh_16!(a); r_psh_16!(m_read_16!(a)); }
- /* SKAr* */ 0xAB => { r_pop_16!(v); r_pop_16!(a); r_psh_16!(a); m_write_16!(v,a); }
+ /* LKAr* */ 0xAA => { r_get_16!(a); r_psh_16!(m_read_16!(a)); }
+ /* SKAr* */ 0xAB => { r_pop_16!(v); r_get_16!(a); m_write_16!(v,a); }
/* LDDr* */ 0xAC => { r_pop_8!(p); r_psh_16!(d_read_16!(p)); }
/* STDr* */ 0xAD => { r_pop_8!(p); r_pop_16!(v); d_write_16!(v,p); }
/* SHFr* */ 0xAE => { r_pop_8!(y); r_pop_16!(x); r_psh_16!(shf!(x,y)); }
/* SHCr* */ 0xAF => { r_pop_8!(y); r_pop_16!(x); r_psh_16!(shc!(x,y)); }
/* PSHr* */ 0xB0 => { w_pop_16!(x); r_psh_16!(x); }
- /* PSKr* */ 0xB1 => { w_pop_16!(x); w_psh_16!(x); r_psh_16!(x); }
+ /* PSKr* */ 0xB1 => { w_get_16!(x); r_psh_16!(x); }
/* POPr* */ 0xB2 => { r_pop_16!(_x); }
/* SPLr* */ 0xB3 => { r_pop_8!(y); r_pop_8!(x); nyb!(x=>a,b); nyb!(y=>c,d); r_psh_8!(a); r_psh_8!(b); r_psh_8!(c); r_psh_8!(d); }
- /* DUPr* */ 0xB4 => { r_pop_16!(x); r_psh_16!(x); r_psh_16!(x); }
- /* OVRr* */ 0xB5 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x); r_psh_16!(y); r_psh_16!(x); }
+ /* DUPr* */ 0xB4 => { r_get_16!(x); r_psh_16!(x); }
+ /* OVRr* */ 0xB5 => { r_pop_16!(y); r_get_16!(x); r_psh_16!(y); r_psh_16!(x); }
/* SWPr* */ 0xB6 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(y); r_psh_16!(x); }
/* ROTr* */ 0xB7 => { r_pop_16!(z); r_pop_16!(y); r_pop_16!(x); r_psh_16!(y); r_psh_16!(z); r_psh_16!(x); }
/* ADDr* */ 0xB8 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x.wrapping_add(y)); }
@@ -256,15 +260,15 @@ impl<D: DeviceBus> Processor<D> {
/* DB6 */ 0xC0 => { return Some(Signal::Debug(DebugVariant::DB6)); }
/* JMPr: */ 0xC1 => { m_lit_16!(a); jump!(a); }
/* JCNr: */ 0xC2 => { m_lit_16!(a); r_pop_8!(t); if t!=0{jump!(a)}; }
- /* JKNr: */ 0xC3 => { m_lit_16!(a); r_pop_8!(t); r_psh_8!(t); if t!=0{jump!(a)}; }
+ /* JKNr: */ 0xC3 => { m_lit_16!(a); r_get_8!(t); if t!=0{jump!(a)}; }
/* EQUr: */ 0xC4 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(truth!(x==y)); }
- /* NKQr: */ 0xC5 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(x); r_psh_8!(y); r_psh_8!(truth!(x!=y)); }
+ /* NKQr: */ 0xC5 => { m_lit_8!(y); r_get_8!(x); r_psh_8!(y); r_psh_8!(truth!(x!=y)); }
/* LTHr: */ 0xC6 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(truth!(x <y)); }
/* GTHr: */ 0xC7 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(truth!(x >y)); }
/* LDAr: */ 0xC8 => { m_lit_16!(a); r_psh_8!(m_read_8!(a)); }
/* STAr: */ 0xC9 => { m_lit_16!(a); r_pop_8!(v); m_write_8!(v,a); }
/* LKAr: */ 0xCA => { m_lit_16!(a); r_psh_16!(a); r_psh_8!(m_read_8!(a)); }
- /* SKAr: */ 0xCB => { m_lit_8!(v); r_pop_16!(a); r_psh_16!(a); m_write_8!(v,a); }
+ /* SKAr: */ 0xCB => { m_lit_8!(v); r_get_16!(a); m_write_8!(v,a); }
/* LDDr: */ 0xCC => { m_lit_8!(p); r_psh_8!(d_read_8!(p)); }
/* STDr: */ 0xCD => { m_lit_8!(p); r_pop_8!(v); d_write_8!(v,p); }
/* SHFr: */ 0xCE => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(shf!(x,y)); }
@@ -274,7 +278,7 @@ impl<D: DeviceBus> Processor<D> {
/* POPr: */ 0xD2 => { m_lit_8!(_x); }
/* SPLr: */ 0xD3 => { m_lit_8!(x); nyb!(x=>a,b); r_psh_8!(a); r_psh_8!(b); }
/* DUPr: */ 0xD4 => { m_lit_8!(x); r_psh_8!(x); r_psh_8!(x); }
- /* OVRr: */ 0xD5 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(x); r_psh_8!(y); r_psh_8!(x); }
+ /* OVRr: */ 0xD5 => { m_lit_8!(y); r_get_8!(x); r_psh_8!(y); r_psh_8!(x); }
/* SWPr: */ 0xD6 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(y); r_psh_8!(x); }
/* ROTr: */ 0xD7 => { m_lit_8!(z); r_pop_8!(y); r_pop_8!(x); r_psh_8!(y); r_psh_8!(z); r_psh_8!(x); }
/* ADDr: */ 0xD8 => { m_lit_8!(y); r_pop_8!(x); r_psh_8!(x.wrapping_add(y)); }
@@ -289,15 +293,15 @@ impl<D: DeviceBus> Processor<D> {
/* NOP */ 0xE0 => { }
/* JSRr: */ 0xE1 => { m_lit_16!(a); w_psh_16!(pc!()); jump!(a); }
/* JSNr: */ 0xE2 => { m_lit_16!(a); r_pop_8!(t); if t!=0 {w_psh_16!(pc!()); jump!(a)}; }
- /* JKNr*: */ 0xE3 => { m_lit_16!(a); r_pop_16!(t); r_psh_16!(t); if t!=0 {jump!(a)}; }
+ /* JKNr*: */ 0xE3 => { m_lit_16!(a); r_get_16!(t); if t!=0 {jump!(a)}; }
/* EQUr*: */ 0xE4 => { m_lit_16!(y); r_pop_16!(x); r_psh_8!(truth!(x==y)); }
- /* NKQr*: */ 0xE5 => { m_lit_16!(y); r_pop_16!(x); r_psh_16!(x); r_psh_16!(y); r_psh_8!(truth!(x!=y)); }
+ /* NKQr*: */ 0xE5 => { m_lit_16!(y); r_get_16!(x); r_psh_16!(y); r_psh_8!(truth!(x!=y)); }
/* LTHr*: */ 0xE6 => { m_lit_16!(y); r_pop_16!(x); r_psh_8!(truth!(x <y)); }
/* GTHr*: */ 0xE7 => { m_lit_16!(y); r_pop_16!(x); r_psh_8!(truth!(x >y)); }
/* LDAr*: */ 0xE8 => { m_lit_16!(a); r_psh_16!(m_read_16!(a)); }
/* STAr*: */ 0xE9 => { m_lit_16!(a); r_pop_16!(v); m_write_16!(v,a); }
/* LKAr*: */ 0xEA => { m_lit_16!(a); r_psh_16!(a); r_psh_16!(m_read_16!(a)); }
- /* SKAr*: */ 0xEB => { m_lit_16!(v); r_pop_16!(a); r_psh_16!(a); m_write_16!(v,a); }
+ /* SKAr*: */ 0xEB => { m_lit_16!(v); r_get_16!(a); m_write_16!(v,a); }
/* LDDr*: */ 0xEC => { m_lit_8!(p); r_psh_16!(d_read_16!(p)); }
/* STDr*: */ 0xED => { m_lit_8!(p); r_pop_16!(v); d_write_16!(v,p); }
/* SHFr*: */ 0xEE => { m_lit_8!(y); r_pop_16!(x); r_psh_16!(shf!(x,y)); }
@@ -307,7 +311,7 @@ impl<D: DeviceBus> Processor<D> {
/* POPr*: */ 0xF2 => { m_lit_16!(_x); }
/* SPLr*: */ 0xF3 => { m_lit_8!(x); m_lit_8!(y); nyb!(x=>a,b); nyb!(y=>c,d); r_psh_8!(a); r_psh_8!(b); r_psh_8!(c); r_psh_8!(d); }
/* DUPr*: */ 0xF4 => { m_lit_16!(x); r_psh_16!(x); r_psh_16!(x); }
- /* OVRr*: */ 0xF5 => { m_lit_16!(y); r_pop_16!(x); r_psh_16!(x); r_psh_16!(y); r_psh_16!(x); }
+ /* OVRr*: */ 0xF5 => { m_lit_16!(y); r_get_16!(x); r_psh_16!(y); r_psh_16!(x); }
/* SWPr*: */ 0xF6 => { m_lit_16!(y); r_pop_16!(x); r_psh_16!(y); r_psh_16!(x); }
/* ROTr*: */ 0xF7 => { m_lit_16!(z); r_pop_16!(y); r_pop_16!(x); r_psh_16!(y); r_psh_16!(z); r_psh_16!(x); }
/* ADDr*: */ 0xF8 => { m_lit_16!(y); r_pop_16!(x); r_psh_16!(x.wrapping_add(y)); }
diff --git a/src/stack.rs b/src/stack.rs
index 2a0a514..14e1799 100644
--- a/src/stack.rs
+++ b/src/stack.rs
@@ -28,8 +28,20 @@ impl Stack {
}
pub fn pop_u16(&mut self) -> u16 {
- let byte_low = self.pop_u8();
- let byte_high = self.pop_u8();
+ self.sp = self.sp.wrapping_sub(1);
+ let byte_low = self.mem[self.sp as usize];
+ self.sp = self.sp.wrapping_sub(1);
+ let byte_high = self.mem[self.sp as usize];
+ u16::from_be_bytes([byte_high, byte_low])
+ }
+
+ pub fn get_u8(&mut self) -> u8 {
+ self.mem[self.sp.wrapping_sub(1) as usize]
+ }
+
+ pub fn get_u16(&mut self) -> u16 {
+ let byte_low = self.mem[self.sp.wrapping_sub(1) as usize];
+ let byte_high = self.mem[self.sp.wrapping_sub(2) as usize];
u16::from_be_bytes([byte_high, byte_low])
}