summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2020-03-04 02:58:39 +0300
committerOxore <oxore@protonmail.com>2020-03-04 02:58:39 +0300
commit0a6fad82f83d7a79aa7eadf73a21e6e80c8e810d (patch)
tree37a7e5aad4eb9b7fe547eeff2fb1bf28814145d6
parent52b665108f6f2203df251eec273184b142ee2e16 (diff)
Add third operand, format code
-rw-r--r--src/core.rs74
-rw-r--r--src/main.rs2
-rw-r--r--src/memory.rs3
-rw-r--r--src/rom.rs6
4 files changed, 58 insertions, 27 deletions
diff --git a/src/core.rs b/src/core.rs
index a85d830..992f12c 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -1,5 +1,5 @@
-use crate::rom::Rom;
use crate::memory::Memory;
+use crate::rom::Rom;
use std::fmt;
#[derive(Debug, Clone, Copy)]
@@ -66,6 +66,7 @@ struct IncompleteOp {
size: usize,
operand1: Option<IncompleteOperand>,
operand2: Option<IncompleteOperand>,
+ operand3: Option<IncompleteOperand>,
}
#[derive(Debug, Clone)]
@@ -74,6 +75,7 @@ pub struct Op {
size: usize,
operand1: Option<Operand>,
operand2: Option<Operand>,
+ operand3: Option<Operand>,
}
pub struct Core {
@@ -136,186 +138,217 @@ const OP_LUT: [IncompleteOp; u8::max_value() as usize + 1] = {
size: 1,
operand1: None,
operand2: None,
+ operand3: None,
}; u8::max_value() as usize + 1];
lut[OPCODE_NOP as usize] = IncompleteOp {
opname: Opname::Nop,
size: 1,
operand1: None,
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P0 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(0)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_LJMP as usize] = IncompleteOp {
opname: Opname::Ljmp,
size: 3,
operand1: Some(IncompleteOperand::Addr16),
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P1 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(1)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P2 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(2)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P3 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(3)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_JNZ as usize] = IncompleteOp {
opname: Opname::Jnz,
size: 2,
operand1: Some(IncompleteOperand::Reladdr),
operand2: None,
+ operand3: None,
};
lut[OPCODE_MOV_A_DATA as usize] = IncompleteOp {
opname: Opname::Mov,
size: 2,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Data),
+ operand3: None,
};
lut[OPCODE_MOV_DIRECT_DATA as usize] = IncompleteOp {
opname: Opname::Mov,
size: 3,
operand1: Some(IncompleteOperand::Direct),
operand2: Some(IncompleteOperand::Data),
+ operand3: None,
};
lut[OPCODE_SJMP as usize] = IncompleteOp {
opname: Opname::Sjmp,
size: 2,
operand1: Some(IncompleteOperand::Reladdr),
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P4 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(4)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_MOV_DPTR_DATA16 as usize] = IncompleteOp {
opname: Opname::Mov16,
size: 3,
operand1: Some(IncompleteOperand::Dptr),
operand2: Some(IncompleteOperand::Data16),
+ operand3: None,
};
lut[OPCODE_AJMP_P5 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(5)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_PUSH as usize] = IncompleteOp {
opname: Opname::Push,
size: 2,
operand1: Some(IncompleteOperand::Direct),
operand2: None,
+ operand3: None,
};
lut[OPCODE_AJMP_P6 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(6)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_POP as usize] = IncompleteOp {
opname: Opname::Pop,
size: 2,
operand1: Some(IncompleteOperand::Direct),
operand2: None,
+ operand3: None,
};
lut[OPCODE_MOV_A_AT_DPTR as usize] = IncompleteOp {
opname: Opname::MovxFrom,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::AtDptr),
+ operand3: None,
};
lut[OPCODE_AJMP_P7 as usize] = IncompleteOp {
opname: Opname::Ajmp,
size: 2,
operand1: Some(IncompleteOperand::Addr11(7)),
operand2: None,
+ operand3: None,
};
lut[OPCODE_MOV_A_DIRECT as usize] = IncompleteOp {
opname: Opname::Mov,
size: 2,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Direct),
+ operand3: None,
};
lut[OPCODE_MOV_A_INDIRECT_R0 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Indirect(Register::R0)),
+ operand3: None,
};
lut[OPCODE_MOV_A_INDIRECT_R1 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Indirect(Register::R1)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R0 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R0)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R1 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R1)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R2 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R2)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R3 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R3)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R4 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R4)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R5 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R5)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R6 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R6)),
+ operand3: None,
};
lut[OPCODE_MOV_A_R7 as usize] = IncompleteOp {
opname: Opname::Mov,
size: 1,
operand1: Some(IncompleteOperand::Acc),
operand2: Some(IncompleteOperand::Register(Register::R7)),
+ operand3: None,
};
lut[OPCODE_MOV_AT_DPTR_A as usize] = IncompleteOp {
opname: Opname::MovxTo,
size: 1,
operand1: Some(IncompleteOperand::AtDptr),
operand2: Some(IncompleteOperand::Acc),
+ operand3: None,
};
lut
};
@@ -393,25 +426,24 @@ impl Core {
/// Get current instruction
pub fn op(&self) -> Op {
let op = IncompleteOp::from_u8(self.progmem.get(self.pc));
- let operand1 = if let Some(incomplete_operand) = op.operand1 {
- Some(self.fetch_operand(incomplete_operand, 1))
- } else {
- None
- };
- let operand2_offset = match &operand1 {
- Some(operand) => operand.size() as u16,
- _ => 0,
- };
- let operand2 = if let Some(incomplete_operand) = op.operand2 {
- Some(self.fetch_operand(incomplete_operand, operand2_offset))
- } else {
- None
- };
+ let mut operands: Vec<Option<Operand>> = vec![op.operand1, op.operand2, op.operand3]
+ .iter()
+ .scan(1, |offset, &x| {
+ Some(if let Some(incomplete_operand) = x {
+ let operand = self.fetch_operand(incomplete_operand, *offset);
+ *offset += operand.size() as u16;
+ Some(operand)
+ } else {
+ None
+ })
+ })
+ .collect();
Op {
opname: op.opname,
size: op.size,
- operand1,
- operand2,
+ operand3: operands.remove(2),
+ operand2: operands.remove(1),
+ operand1: operands.remove(0),
}
}
@@ -456,12 +488,8 @@ impl Core {
fn fetch_operand(&self, operand: IncompleteOperand, offset: u16) -> Operand {
match operand {
IncompleteOperand::Acc => Operand::Acc,
- IncompleteOperand::Direct => {
- Operand::Direct(self.progmem.get(self.pc + offset))
- }
- IncompleteOperand::Data => {
- Operand::Data(self.progmem.get(self.pc + offset))
- }
+ IncompleteOperand::Direct => Operand::Direct(self.progmem.get(self.pc + offset)),
+ IncompleteOperand::Data => Operand::Data(self.progmem.get(self.pc + offset)),
IncompleteOperand::Data16 => Operand::Data16({
let high = self.progmem.get(self.pc + offset);
let low = self.progmem.get(self.pc + offset + 1);
diff --git a/src/main.rs b/src/main.rs
index 05b32c2..b23d31d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,8 +8,8 @@ use std::thread;
use std::time::Duration;
mod core;
-mod rom;
mod memory;
+mod rom;
use self::core::Core;
use self::rom::Rom;
diff --git a/src/memory.rs b/src/memory.rs
index 372a029..3949f75 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -1,7 +1,8 @@
extern crate num_traits;
pub trait Memory<Addr>
- where Addr: Copy + core::ops::Add<Output = Addr> + num_traits::identities::One
+where
+ Addr: Copy + core::ops::Add<Output = Addr> + num_traits::identities::One,
{
fn get(&self, a: Addr) -> u8;
diff --git a/src/rom.rs b/src/rom.rs
index c054575..82775a4 100644
--- a/src/rom.rs
+++ b/src/rom.rs
@@ -1,5 +1,5 @@
-use std::fmt;
use crate::memory::Memory;
+use std::fmt;
pub struct Rom {
array: [u8; u16::max_value() as usize + 1],
@@ -86,7 +86,9 @@ impl HexLine {
impl Rom {
/// Empty constructor
pub fn new() -> Self {
- Self { array: [0; u16::max_value() as usize + 1] }
+ Self {
+ array: [0; u16::max_value() as usize + 1],
+ }
}
/// Constructor from hex