From 7bd685bfa30474e8af5675aa622a502ba2f18797 Mon Sep 17 00:00:00 2001 From: Oxore Date: Mon, 18 Nov 2019 04:01:59 +0300 Subject: Implement LJMP instruction --- src/core.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core.rs b/src/core.rs index 01ec71f..f239cdd 100644 --- a/src/core.rs +++ b/src/core.rs @@ -37,6 +37,7 @@ pub enum Operand { Register(Register), Reladdr(i8), Addr11(u16), + Addr16(u16), } #[derive(Debug, Clone)] @@ -59,6 +60,7 @@ const RAM_OFFSET_R7: u8 = 0x07; const OPCODE_NOP: u8 = 0x00; const OPCODE_AJMP_P0: u8 = 0x01; +const OPCODE_LJMP: u8 = 0x02; const OPCODE_AJMP_P1: u8 = 0x21; const OPCODE_AJMP_P2: u8 = 0x41; const OPCODE_AJMP_P3: u8 = 0x61; @@ -102,6 +104,12 @@ const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = { operand1: Some(Isa8051Operand::Addr11(0)), operand2: None, }; + lut[OPCODE_LJMP as usize] = Isa8051Op { + opcode: Isa8051Opcode::Ljmp, + size: 3, + operand1: Some(Isa8051Operand::Addr16), + operand2: None, + }; lut[OPCODE_AJMP_P1 as usize] = Isa8051Op { opcode: Isa8051Opcode::Ajmp, size: 2, @@ -256,6 +264,7 @@ impl fmt::Display for Operand { Operand::Register(r) => format!("{:?}", r), Operand::Reladdr(rel) => format!("{}", rel), Operand::Addr11(rel) => format!("{}", rel), + Operand::Addr16(rel) => format!("{}", rel), } ) } @@ -285,6 +294,7 @@ impl Operand { Operand::Register(_) => 0, Operand::Reladdr(_) => 1, Operand::Addr11(_) => 1, + Operand::Addr16(_) => 2, } } } @@ -384,6 +394,16 @@ impl Core { panic!("AJMP has no operand given") } } + Isa8051Opcode::Ljmp => { + if let Some(operand) = op.operand1 { + match operand { + Operand::Addr16(addr) => self.ljmp(addr), + _ => panic!("LJMP got incompatible operand"), + } + } else { + panic!("LJMP has no operand given") + } + } } } @@ -411,7 +431,11 @@ impl Core { } fn ajmp(&mut self, pageaddr: u16) { - self.pc = (self.pc & !0x4FFu16) + pageaddr as u16; + self.pc = (self.pc & !0x4FFu16) + pageaddr; + } + + fn ljmp(&mut self, pageaddr: u16) { + self.pc = pageaddr; } fn map_operand(&self, operand: Isa8051Operand, offset: usize) -> Operand { @@ -427,6 +451,10 @@ impl Core { Isa8051Operand::Addr11(high) => Operand::Addr11( self.rom.array[(self.pc as usize + offset)] as u16 + (u16::from(high) << 8), ), + Isa8051Operand::Addr16 => Operand::Addr16( + (u16::from(self.rom.array[(self.pc as usize + offset)]) << 8) + + u16::from(self.rom.array[(self.pc as usize + offset + 1)]), + ), } } } @@ -440,12 +468,14 @@ pub enum Isa8051Operand { Register(Register), Reladdr, Addr11(u8), + Addr16, } #[derive(Debug, Clone, Copy)] pub enum Isa8051Opcode { Nop, Ajmp, + Ljmp, Mov, Push, Pop, -- cgit v1.2.3