diff options
Diffstat (limited to 'src/core.rs')
-rw-r--r-- | src/core.rs | 235 |
1 files changed, 119 insertions, 116 deletions
diff --git a/src/core.rs b/src/core.rs index cd9dc1d..415afa0 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,7 +1,7 @@ use crate::rom::Rom; use std::fmt; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum Register { R0, R1, @@ -74,6 +74,118 @@ const OPCODE_PUSH: u8 = 0xC0; const OPCODE_POP: u8 = 0xD0; const OPCODE_SJMP: u8 = 0xD2; +const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = { + let mut lut = [Isa8051Op { + opcode: Isa8051Opcode::Illegal, + size: 1, + operand1: None, + operand2: None, + }; u8::max_value() as usize + 1]; + lut[OPCODE_NOP as usize] = Isa8051Op { + opcode: Isa8051Opcode::Nop, + size: 1, + operand1: None, + operand2: None, + }; + lut[OPCODE_MOV_A_DATA as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 2, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Data), + }; + lut[OPCODE_MOV_DIRECT_DATA as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 3, + operand1: Some(Isa8051Operand::Direct), + operand2: Some(Isa8051Operand::Data), + }; + lut[OPCODE_MOV_A_DIRECT as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 2, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Direct), + }; + lut[OPCODE_MOV_A_INDIRECT_R0 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Indirect(Register::R0)), + }; + lut[OPCODE_MOV_A_INDIRECT_R1 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Indirect(Register::R1)), + }; + lut[OPCODE_MOV_A_R0 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R0)), + }; + lut[OPCODE_MOV_A_R1 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R1)), + }; + lut[OPCODE_MOV_A_R2 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R2)), + }; + lut[OPCODE_MOV_A_R3 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R3)), + }; + lut[OPCODE_MOV_A_R4 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R4)), + }; + lut[OPCODE_MOV_A_R5 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R5)), + }; + lut[OPCODE_MOV_A_R6 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R6)), + }; + lut[OPCODE_MOV_A_R7 as usize] = Isa8051Op { + opcode: Isa8051Opcode::Mov, + size: 1, + operand1: Some(Isa8051Operand::Acc), + operand2: Some(Isa8051Operand::Register(Register::R7)), + }; + lut[OPCODE_PUSH as usize] = Isa8051Op { + opcode: Isa8051Opcode::Push, + size: 2, + operand1: Some(Isa8051Operand::Direct), + operand2: None, + }; + lut[OPCODE_POP as usize] = Isa8051Op { + opcode: Isa8051Opcode::Pop, + size: 2, + operand1: Some(Isa8051Operand::Direct), + operand2: None, + }; + lut[OPCODE_SJMP as usize] = Isa8051Op { + opcode: Isa8051Opcode::Sjmp, + size: 2, + operand1: Some(Isa8051Operand::Reladdr), + operand2: None, + }; + lut +}; + impl fmt::Display for Operand { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -120,7 +232,7 @@ impl Operand { pub struct Core { pc: u16, - ram: [u8; u8::max_value() as usize], + ram: [u8; u8::max_value() as usize + 1], rom: Rom, } @@ -129,7 +241,7 @@ impl Core { /// Constructor /// pub fn new_with_rom_from_hex(hex: String) -> Result<Self, String> { - let ram: [u8; u8::max_value() as usize] = [0; u8::max_value() as usize]; + let ram: [u8; u8::max_value() as usize + 1] = [0; u8::max_value() as usize + 1]; let rom = match Rom::from_hex(hex) { Ok(value) => value, Err(err_string) => return Err(err_string), @@ -243,7 +355,7 @@ impl Core { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum Isa8051Operand { Acc, Direct, @@ -253,7 +365,7 @@ pub enum Isa8051Operand { Reladdr, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum Isa8051Opcode { Nop, Mov, @@ -269,7 +381,7 @@ impl fmt::Display for Isa8051Opcode { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct Isa8051Op { opcode: Isa8051Opcode, size: usize, @@ -279,115 +391,6 @@ pub struct Isa8051Op { impl Isa8051Op { fn from_u8(data: u8) -> Self { - match data { - OPCODE_NOP => Isa8051Op { - opcode: Isa8051Opcode::Nop, - size: 1, - operand1: None, - operand2: None, - }, - OPCODE_MOV_A_DATA => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 2, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Data), - }, - OPCODE_MOV_DIRECT_DATA => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 3, - operand1: Some(Isa8051Operand::Direct), - operand2: Some(Isa8051Operand::Data), - }, - OPCODE_MOV_A_DIRECT => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 2, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Direct), - }, - OPCODE_MOV_A_INDIRECT_R0 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Indirect(Register::R0)), - }, - OPCODE_MOV_A_INDIRECT_R1 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Indirect(Register::R1)), - }, - OPCODE_MOV_A_R0 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R0)), - }, - OPCODE_MOV_A_R1 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R1)), - }, - OPCODE_MOV_A_R2 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R2)), - }, - OPCODE_MOV_A_R3 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R3)), - }, - OPCODE_MOV_A_R4 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R4)), - }, - OPCODE_MOV_A_R5 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R5)), - }, - OPCODE_MOV_A_R6 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R6)), - }, - OPCODE_MOV_A_R7 => Isa8051Op { - opcode: Isa8051Opcode::Mov, - size: 1, - operand1: Some(Isa8051Operand::Acc), - operand2: Some(Isa8051Operand::Register(Register::R7)), - }, - OPCODE_PUSH => Isa8051Op { - opcode: Isa8051Opcode::Push, - size: 2, - operand1: Some(Isa8051Operand::Direct), - operand2: None, - }, - OPCODE_POP => Isa8051Op { - opcode: Isa8051Opcode::Pop, - size: 2, - operand1: Some(Isa8051Operand::Direct), - operand2: None, - }, - OPCODE_SJMP => Isa8051Op { - opcode: Isa8051Opcode::Sjmp, - size: 2, - operand1: Some(Isa8051Operand::Reladdr), - operand2: None, - }, - _ => Isa8051Op { - opcode: Isa8051Opcode::Illegal, - size: 1, - operand1: None, - operand2: None, - }, - } + OP_LUT[data as usize] } } |