diff options
Diffstat (limited to 'src/core.rs')
-rw-r--r-- | src/core.rs | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/src/core.rs b/src/core.rs index 64f65fb..cd9dc1d 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,4 +1,4 @@ -use crate::ram::Ram; +use crate::rom::Rom; use std::fmt; #[derive(Debug, Clone)] @@ -13,6 +13,21 @@ pub enum Register { R7, } +impl Register { + fn to_ram_offset(&self) -> u8 { + match self { + Register::R0 => RAM_OFFSET_R0, + Register::R1 => RAM_OFFSET_R1, + Register::R2 => RAM_OFFSET_R2, + Register::R3 => RAM_OFFSET_R3, + Register::R4 => RAM_OFFSET_R4, + Register::R5 => RAM_OFFSET_R5, + Register::R6 => RAM_OFFSET_R6, + Register::R7 => RAM_OFFSET_R7, + } + } +} + #[derive(Debug, Clone)] pub enum Operand { Acc, @@ -31,6 +46,16 @@ pub struct Op { operand2: Option<Operand>, } +const RAM_OFFSET_ACC: u8 = 0xE0; +const RAM_OFFSET_R0: u8 = 0x00; +const RAM_OFFSET_R1: u8 = 0x01; +const RAM_OFFSET_R2: u8 = 0x02; +const RAM_OFFSET_R3: u8 = 0x03; +const RAM_OFFSET_R4: u8 = 0x04; +const RAM_OFFSET_R5: u8 = 0x05; +const RAM_OFFSET_R6: u8 = 0x06; +const RAM_OFFSET_R7: u8 = 0x07; + const OPCODE_NOP: u8 = 0x00; const OPCODE_MOV_A_DATA: u8 = 0x74; const OPCODE_MOV_DIRECT_DATA: u8 = 0x75; @@ -95,19 +120,21 @@ impl Operand { pub struct Core { pc: u16, - ram: Ram, + ram: [u8; u8::max_value() as usize], + rom: Rom, } impl Core { /// /// Constructor /// - pub fn new_with_ram_from_hex(hex: String) -> Result<Self, String> { - let ram = match Ram::from_hex(hex) { + 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 rom = match Rom::from_hex(hex) { Ok(value) => value, Err(err_string) => return Err(err_string), }; - Ok(Self { pc: 0, ram }) + Ok(Self { pc: 0, ram, rom }) } /// @@ -123,7 +150,7 @@ impl Core { /// Get current instruction /// pub fn op(&self) -> Op { - let op = Isa8051Op::from_u8(self.ram.array[self.pc as usize]); + let op = Isa8051Op::from_u8(self.rom.array[self.pc as usize]); let operand1 = if let Some(operand) = op.operand1 { Some(self.map_operand(operand, 1)) } else { @@ -162,7 +189,7 @@ impl Core { fn exec(&mut self, op: Op) { match op.opcode { Isa8051Opcode::Nop => (), - Isa8051Opcode::Mov => (), + Isa8051Opcode::Mov => (self.mov(op.operand1.unwrap(), op.operand2.unwrap())), Isa8051Opcode::Illegal => (), Isa8051Opcode::Push => (), Isa8051Opcode::Pop => (), @@ -179,6 +206,25 @@ impl Core { } } + fn mov(&mut self, o1: Operand, o2: Operand) { + let dest = match o1 { + Operand::Acc => RAM_OFFSET_ACC, + Operand::Direct(dir) => dir, + Operand::Indirect(r) => self.ram[r.to_ram_offset() as usize], + Operand::Register(r) => r.to_ram_offset(), + other => panic!("Mov: got incompatible first operand \"{:?}\"", other), + }; + let value = match o2 { + Operand::Acc => RAM_OFFSET_ACC, + Operand::Direct(dir) => dir, + Operand::Indirect(r) => self.ram[r.to_ram_offset() as usize], + Operand::Data(r) => r, + Operand::Register(r) => r.to_ram_offset(), + other => panic!("Mov: got incompatible second operand \"{:?}\"", other), + }; + self.ram[dest as usize] = value; + } + fn sjmp(&mut self, reladdr: i8) { self.pc = (self.pc as i16 + i16::from(reladdr)) as u16; } @@ -186,12 +232,12 @@ impl Core { fn map_operand(&self, operand: Isa8051Operand, offset: usize) -> Operand { match operand { Isa8051Operand::Acc => Operand::Acc, - Isa8051Operand::Direct => Operand::Direct(self.ram.array[(self.pc as usize + offset)]), - Isa8051Operand::Data => Operand::Data(self.ram.array[(self.pc as usize + offset)]), + Isa8051Operand::Direct => Operand::Direct(self.rom.array[(self.pc as usize + offset)]), + Isa8051Operand::Data => Operand::Data(self.rom.array[(self.pc as usize + offset)]), Isa8051Operand::Indirect(r) => Operand::Indirect(r), Isa8051Operand::Register(r) => Operand::Register(r), Isa8051Operand::Reladdr => { - Operand::Reladdr(self.ram.array[(self.pc as usize + offset)] as i8) + Operand::Reladdr(self.rom.array[(self.pc as usize + offset)] as i8) } } } |