summaryrefslogtreecommitdiff
path: root/src
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
parentb5be6c86d3764131d328389ceeedeb2af46039cc (diff)
Add ram and rom, implement basic MOV functionality
Diffstat (limited to 'src')
-rw-r--r--src/core.rs66
-rw-r--r--src/main.rs8
-rw-r--r--src/rom.rs (renamed from src/ram.rs)6
3 files changed, 62 insertions, 18 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)
}
}
}
diff --git a/src/main.rs b/src/main.rs
index 358ac4e..dc2f600 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,14 +7,14 @@ use std::thread::sleep;
use std::{thread, time};
mod core;
-mod ram;
+mod rom;
use self::core::Core;
fn core_worker(mut core: Core, should_stop: &Mutex<bool>, cvar: &Condvar) {
loop {
while !(*should_stop.lock().unwrap()) {
- core.step();
println!("{}", core.op());
+ core.step();
sleep(time::Duration::from_millis(1000));
}
@@ -55,7 +55,7 @@ fn main() {
let asyncpair = Arc::new((Mutex::new(false), Condvar::new()));
let asyncpair2 = asyncpair.clone();
- let core = match Core::new_with_ram_from_hex(data) {
+ let core = match Core::new_with_rom_from_hex(data) {
Ok(value) => value,
Err(err_string) => {
println!("{}", err_string);
@@ -63,8 +63,6 @@ fn main() {
}
};
- println!("{}", core.op());
-
thread::spawn(move || {
let (ref should_stop, ref condvar) = *asyncpair2;
core_worker(core, should_stop, condvar);
diff --git a/src/ram.rs b/src/rom.rs
index c9a0641..77e6431 100644
--- a/src/ram.rs
+++ b/src/rom.rs
@@ -1,10 +1,10 @@
use std::fmt;
-pub struct Ram {
+pub struct Rom {
pub array: [u8; u16::max_value() as usize + 1],
}
-impl fmt::Debug for Ram {
+impl fmt::Debug for Rom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut v: Vec<char> = vec![];
for (c, x) in self.array.iter().enumerate() {
@@ -82,7 +82,7 @@ impl HexLine {
}
}
-impl Ram {
+impl Rom {
pub fn from_hex(hex: String) -> Result<Self, String> {
let mut array = [0; u16::max_value() as usize + 1];
for (linenum, line) in hex.lines().enumerate() {