From 4955030f13c1d79aef005bb3d292224302afcdfa Mon Sep 17 00:00:00 2001 From: Oxore Date: Tue, 19 Nov 2019 02:47:35 +0300 Subject: Implement Push and Pop instructions --- src/core.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/core.rs b/src/core.rs index 37886c5..74f79b0 100644 --- a/src/core.rs +++ b/src/core.rs @@ -73,6 +73,7 @@ pub struct Core { } const RAM_OFFSET_ACC: u8 = 0xE0; +const RAM_OFFSET_SP: u8 = 0x80; const RAM_OFFSET_R0: u8 = 0x00; const RAM_OFFSET_R1: u8 = 0x01; const RAM_OFFSET_R2: u8 = 0x02; @@ -82,6 +83,9 @@ const RAM_OFFSET_R5: u8 = 0x05; const RAM_OFFSET_R6: u8 = 0x06; const RAM_OFFSET_R7: u8 = 0x07; +const RESET_VALUE_ACC: u8 = 0x00; +const RESET_VALUE_SP: u8 = 0x07; + const OPCODE_NOP: u8 = 0x00; const OPCODE_AJMP_P0: u8 = 0x01; const OPCODE_LJMP: u8 = 0x02; @@ -321,7 +325,9 @@ impl IncompleteOp { impl Core { /// Constructor pub fn new_with_rom_from_hex(hex: String) -> Result { - let ram: [u8; u8::max_value() as usize + 1] = [0; u8::max_value() as usize + 1]; + let mut ram: [u8; u8::max_value() as usize + 1] = [0; u8::max_value() as usize + 1]; + ram[RAM_OFFSET_SP as usize] = RESET_VALUE_SP; + ram[RAM_OFFSET_ACC as usize] = RESET_VALUE_ACC; let rom = match Rom::from_hex(hex) { Ok(value) => value, Err(err_string) => return Err(err_string), @@ -377,10 +383,13 @@ impl Core { fn exec(&mut self, op: Op) { match op.opname { Opname::Nop => (), - Opname::Mov => (self.mov(op.operand1.unwrap(), op.operand2.unwrap())), + Opname::Mov => self.mov( + op.operand1.expect("MOV has no first operand given"), + op.operand2.expect("MOV has no second operand given"), + ), Opname::Illegal => (), - Opname::Push => (), - Opname::Pop => (), + Opname::Push => self.push(op.operand1.expect("PUSH has no operand given")), + Opname::Pop => self.pop(op.operand1.expect("POP has no operand given")), Opname::Sjmp => { if let Some(operand) = op.operand1 { match operand { @@ -466,6 +475,26 @@ impl Core { self.ram[dest as usize] = value; } + fn push(&mut self, o: Operand) { + match o { + Operand::Direct(offset) => { + self.ram[RAM_OFFSET_SP as usize] += 1; + self.ram[self.ram[RAM_OFFSET_SP as usize] as usize] = self.ram[offset as usize]; + } + other => panic!("PUSH got incompatible operand \"{:?}\"", other), + } + } + + fn pop(&mut self, o: Operand) { + match o { + Operand::Direct(offset) => { + self.ram[offset as usize] = self.ram[self.ram[RAM_OFFSET_SP as usize] as usize]; + self.ram[RAM_OFFSET_SP as usize] -= 1; + } + other => panic!("POP got incompatible operand \"{:?}\"", other), + } + } + fn sjmp(&mut self, reladdr: i8) { self.pc = (self.pc as i16 + i16::from(reladdr)) as u16; } -- cgit v1.2.3