diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-02 17:39:52 +1200 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-03 13:12:29 +1200 |
commit | 69588112045ebb4f1a8c6d561ac019be8dbbaf6d (patch) | |
tree | 2874329dc9f1f9cbcfe130f4771dcc505a3a1eef | |
parent | f6e9349f60d003fca8dce6d4f6c76a1ad0c0e56d (diff) | |
download | bedrock-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.rs | 92 | ||||
-rw-r--r-- | src/stack.rs | 16 |
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]) } |