summaryrefslogtreecommitdiff
path: root/src/core.rs
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-11-11 01:43:23 +0300
committerOxore <oxore@protonmail.com>2019-11-11 01:43:23 +0300
commit59e2c93bb5fd4301a7653c568419376374c2c33a (patch)
tree6d1e5913fd10c16f10bc135f6eb558fb5c682a37 /src/core.rs
parentb5be6c86d3764131d328389ceeedeb2af46039cc (diff)
Add ram and rom, implement basic MOV functionality
Diffstat (limited to 'src/core.rs')
-rw-r--r--src/core.rs66
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)
}
}
}