diff options
Diffstat (limited to 'src/core.rs')
-rw-r--r-- | src/core.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/core.rs b/src/core.rs index 10bb05b..01ec71f 100644 --- a/src/core.rs +++ b/src/core.rs @@ -36,6 +36,7 @@ pub enum Operand { Data(u8), Register(Register), Reladdr(i8), + Addr11(u16), } #[derive(Debug, Clone)] @@ -57,9 +58,17 @@ const RAM_OFFSET_R6: u8 = 0x06; const RAM_OFFSET_R7: u8 = 0x07; const OPCODE_NOP: u8 = 0x00; +const OPCODE_AJMP_P0: u8 = 0x01; +const OPCODE_AJMP_P1: u8 = 0x21; +const OPCODE_AJMP_P2: u8 = 0x41; +const OPCODE_AJMP_P3: u8 = 0x61; const OPCODE_MOV_A_DATA: u8 = 0x74; const OPCODE_MOV_DIRECT_DATA: u8 = 0x75; const OPCODE_SJMP: u8 = 0x80; +const OPCODE_AJMP_P4: u8 = 0x81; +const OPCODE_AJMP_P5: u8 = 0xA1; +const OPCODE_AJMP_P6: u8 = 0xC1; +const OPCODE_AJMP_P7: u8 = 0xE1; const OPCODE_MOV_A_DIRECT: u8 = 0xE5; const OPCODE_MOV_A_INDIRECT_R0: u8 = 0xE6; const OPCODE_MOV_A_INDIRECT_R1: u8 = 0xE7; @@ -87,6 +96,30 @@ const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = { operand1: None, operand2: None, }; + lut[OPCODE_AJMP_P0 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(0)), + operand2: None, + }; + lut[OPCODE_AJMP_P1 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(1)), + operand2: None, + }; + lut[OPCODE_AJMP_P2 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(2)), + operand2: None, + }; + lut[OPCODE_AJMP_P3 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(3)), + operand2: None, + }; lut[OPCODE_MOV_A_DATA as usize] = Isa8051Op { opcode: Isa8051Opcode::Mov, size: 2, @@ -105,6 +138,30 @@ const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = { operand1: Some(Isa8051Operand::Reladdr), operand2: None, }; + lut[OPCODE_AJMP_P4 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(4)), + operand2: None, + }; + lut[OPCODE_AJMP_P5 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(5)), + operand2: None, + }; + lut[OPCODE_AJMP_P6 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(6)), + operand2: None, + }; + lut[OPCODE_AJMP_P7 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ajmp, + size: 2, + operand1: Some(Isa8051Operand::Addr11(7)), + operand2: None, + }; lut[OPCODE_MOV_A_DIRECT as usize] = Isa8051Op { opcode: Isa8051Opcode::Mov, size: 2, @@ -198,6 +255,7 @@ impl fmt::Display for Operand { Operand::Data(data) => format!("#{}", data), Operand::Register(r) => format!("{:?}", r), Operand::Reladdr(rel) => format!("{}", rel), + Operand::Addr11(rel) => format!("{}", rel), } ) } @@ -226,6 +284,7 @@ impl Operand { Operand::Data(_) => 1, Operand::Register(_) => 0, Operand::Reladdr(_) => 1, + Operand::Addr11(_) => 1, } } } @@ -315,6 +374,16 @@ impl Core { panic!("SJMP has no operand given") } } + Isa8051Opcode::Ajmp => { + if let Some(operand) = op.operand1 { + match operand { + Operand::Addr11(addr) => self.ajmp(addr), + _ => panic!("AJMP got incompatible operand"), + } + } else { + panic!("AJMP has no operand given") + } + } } } @@ -341,6 +410,10 @@ impl Core { self.pc = (self.pc as i16 + i16::from(reladdr)) as u16; } + fn ajmp(&mut self, pageaddr: u16) { + self.pc = (self.pc & !0x4FFu16) + pageaddr as u16; + } + fn map_operand(&self, operand: Isa8051Operand, offset: usize) -> Operand { match operand { Isa8051Operand::Acc => Operand::Acc, @@ -351,6 +424,9 @@ impl Core { Isa8051Operand::Reladdr => { Operand::Reladdr(self.rom.array[(self.pc as usize + offset)] as i8) } + Isa8051Operand::Addr11(high) => Operand::Addr11( + self.rom.array[(self.pc as usize + offset)] as u16 + (u16::from(high) << 8), + ), } } } @@ -363,11 +439,13 @@ pub enum Isa8051Operand { Indirect(Register), Register(Register), Reladdr, + Addr11(u8), } #[derive(Debug, Clone, Copy)] pub enum Isa8051Opcode { Nop, + Ajmp, Mov, Push, Pop, |