summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core.rs235
-rw-r--r--src/main.rs3
2 files changed, 121 insertions, 117 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]
}
}
diff --git a/src/main.rs b/src/main.rs
index dc2f600..8eb1648 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -50,7 +50,8 @@ fn main() {
println!("Please, specify ihex file");
return;
}
- let data = fs::read_to_string(&args[1]).unwrap_or_else(|_| panic!("Unable to read file {}", &args[1]));
+ let data =
+ fs::read_to_string(&args[1]).unwrap_or_else(|_| panic!("Unable to read file {}", &args[1]));
let asyncpair = Arc::new((Mutex::new(false), Condvar::new()));
let asyncpair2 = asyncpair.clone();