diff options
author | Oxore <oxore@protonmail.com> | 2020-03-04 02:58:39 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2020-03-04 02:58:39 +0300 |
commit | 0a6fad82f83d7a79aa7eadf73a21e6e80c8e810d (patch) | |
tree | 37a7e5aad4eb9b7fe547eeff2fb1bf28814145d6 | |
parent | 52b665108f6f2203df251eec273184b142ee2e16 (diff) |
Add third operand, format code
-rw-r--r-- | src/core.rs | 74 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/memory.rs | 3 | ||||
-rw-r--r-- | src/rom.rs | 6 |
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; @@ -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 |