summaryrefslogtreecommitdiff
path: root/src/core.rs
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-11-18 02:41:34 +0300
committerOxore <oxore@protonmail.com>2019-11-18 02:41:34 +0300
commitd5ad463a3c1b43d508fb28b23509e7fe2539d334 (patch)
treefcbb7a5058c18dfc96ab3919f18146e6dd19946a /src/core.rs
parent59e2c93bb5fd4301a7653c568419376374c2c33a (diff)
Implement LUT for opcode to Op translation
Diffstat (limited to 'src/core.rs')
-rw-r--r--src/core.rs235
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]
}
}