summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bedrock.rs22
-rw-r--r--src/core.rs20
-rw-r--r--src/device_bus.rs71
-rw-r--r--src/emulator.rs16
-rw-r--r--src/lib.rs24
-rw-r--r--src/processor.rs164
-rw-r--r--src/signal.rs12
7 files changed, 145 insertions, 184 deletions
diff --git a/src/bedrock.rs b/src/bedrock.rs
deleted file mode 100644
index 8d03e12..0000000
--- a/src/bedrock.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use crate::*;
-
-
-pub struct Bedrock<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> {
- pub mem: ProgramMemory,
- pub wst: Stack,
- pub rst: Stack,
- pub dev: DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF>,
- pub cyc: usize,
-}
-
-impl<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> Bedrock<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> {
- pub fn new(device_bus: DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF>) -> Self {
- Self {
- mem: ProgramMemory::new(),
- wst: Stack::new(),
- rst: Stack::new(),
- dev: device_bus,
- cyc: 0,
- }
- }
-}
diff --git a/src/core.rs b/src/core.rs
new file mode 100644
index 0000000..2143e3d
--- /dev/null
+++ b/src/core.rs
@@ -0,0 +1,20 @@
+use crate::*;
+
+
+pub struct BedrockCore {
+ pub mem: ProgramMemory,
+ pub wst: Stack,
+ pub rst: Stack,
+ pub cycle: usize,
+}
+
+impl BedrockCore {
+ pub fn new() -> Self {
+ Self {
+ mem: ProgramMemory::new(),
+ wst: Stack::new(),
+ rst: Stack::new(),
+ cycle: 0,
+ }
+ }
+}
diff --git a/src/device_bus.rs b/src/device_bus.rs
index aaa0717..6a04f66 100644
--- a/src/device_bus.rs
+++ b/src/device_bus.rs
@@ -1,6 +1,5 @@
use crate::*;
-
pub trait Device {
fn read(&mut self, port: u8) -> u8;
fn write(&mut self, port: u8, value: u8) -> Option<Signal>;
@@ -13,70 +12,8 @@ impl Device for () {
fn wake(&mut self) -> bool { false }
}
-
-pub struct DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> {
- pub dev_0: D0,
- pub dev_1: D1,
- pub dev_2: D2,
- pub dev_3: D3,
- pub dev_4: D4,
- pub dev_5: D5,
- pub dev_6: D6,
- pub dev_7: D7,
- pub dev_8: D8,
- pub dev_9: D9,
- pub dev_a: DA,
- pub dev_b: DB,
- pub dev_c: DC,
- pub dev_d: DD,
- pub dev_e: DE,
- pub dev_f: DF,
-}
-
-impl<D0:Device, D1:Device, D2:Device, D3:Device, D4:Device, D5:Device, D6:Device, D7:Device,
- D8:Device, D9:Device, DA:Device, DB:Device, DC:Device, DD:Device, DE:Device, DF:Device>
-DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> {
- pub fn read_u8(&mut self, port: u8) -> u8 {
- match port & 0xf0 {
- 0x00 => self.dev_0.read(port & 0x0f),
- 0x10 => self.dev_1.read(port & 0x0f),
- 0x20 => self.dev_2.read(port & 0x0f),
- 0x30 => self.dev_3.read(port & 0x0f),
- 0x40 => self.dev_4.read(port & 0x0f),
- 0x50 => self.dev_5.read(port & 0x0f),
- 0x60 => self.dev_6.read(port & 0x0f),
- 0x70 => self.dev_7.read(port & 0x0f),
- 0x80 => self.dev_8.read(port & 0x0f),
- 0x90 => self.dev_9.read(port & 0x0f),
- 0xA0 => self.dev_a.read(port & 0x0f),
- 0xB0 => self.dev_b.read(port & 0x0f),
- 0xC0 => self.dev_c.read(port & 0x0f),
- 0xD0 => self.dev_d.read(port & 0x0f),
- 0xE0 => self.dev_e.read(port & 0x0f),
- 0xF0 => self.dev_f.read(port & 0x0f),
- _ => unreachable!(),
- }
- }
-
- pub fn write_u8(&mut self, port: u8, value: u8) -> Option<Signal> {
- match port & 0xf0 {
- 0x00 => self.dev_0.write(port & 0x0f, value),
- 0x10 => self.dev_1.write(port & 0x0f, value),
- 0x20 => self.dev_2.write(port & 0x0f, value),
- 0x30 => self.dev_3.write(port & 0x0f, value),
- 0x40 => self.dev_4.write(port & 0x0f, value),
- 0x50 => self.dev_5.write(port & 0x0f, value),
- 0x60 => self.dev_6.write(port & 0x0f, value),
- 0x70 => self.dev_7.write(port & 0x0f, value),
- 0x80 => self.dev_8.write(port & 0x0f, value),
- 0x90 => self.dev_9.write(port & 0x0f, value),
- 0xA0 => self.dev_a.write(port & 0x0f, value),
- 0xB0 => self.dev_b.write(port & 0x0f, value),
- 0xC0 => self.dev_c.write(port & 0x0f, value),
- 0xD0 => self.dev_d.write(port & 0x0f, value),
- 0xE0 => self.dev_e.write(port & 0x0f, value),
- 0xF0 => self.dev_f.write(port & 0x0f, value),
- _ => unreachable!(),
- }
- }
+pub trait DeviceBus {
+ fn read(&mut self, port: u8) -> u8;
+ fn write(&mut self, port: u8, value: u8) -> Option<Signal>;
+ fn wake(&mut self) -> bool;
}
diff --git a/src/emulator.rs b/src/emulator.rs
new file mode 100644
index 0000000..d149ddd
--- /dev/null
+++ b/src/emulator.rs
@@ -0,0 +1,16 @@
+use crate::*;
+
+
+pub struct BedrockEmulator<DB> {
+ pub core: BedrockCore,
+ pub dev: DB,
+}
+
+impl<DB: DeviceBus> BedrockEmulator<DB> {
+ pub fn new(device_bus: DB) -> Self {
+ Self {
+ core: BedrockCore::new(),
+ dev: device_bus,
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 8fd363e..f8fa3d6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,21 +1,31 @@
-mod bedrock;
-mod device_bus;
mod processor;
mod program_memory;
mod stack;
-pub use bedrock::Bedrock;
-pub use device_bus::{Device, DeviceBus};
-pub use processor::Signal;
pub use program_memory::ProgramMemory;
pub use stack::Stack;
+mod core;
+mod device_bus;
+mod signal;
+mod emulator;
+
+pub use core::BedrockCore;
+pub use device_bus::{Device, DeviceBus};
+pub use signal::Signal;
+pub use emulator::BedrockEmulator;
+
+
pub mod macros {
#[macro_export]
macro_rules! read_hh { ($v:expr) => { ($v>>24) as u8 }; }
#[macro_export]
macro_rules! read_hl { ($v:expr) => { ($v>>16) as u8 }; }
#[macro_export]
+ macro_rules! read_lh { ($v:expr) => { ($v>>8) as u8 }; }
+ #[macro_export]
+ macro_rules! read_ll { ($v:expr) => { $v as u8 }; }
+ #[macro_export]
macro_rules! read_h { ($v:expr) => { ($v>>8) as u8 }; }
#[macro_export]
macro_rules! read_l { ($v:expr) => { $v as u8 }; }
@@ -27,6 +37,10 @@ pub mod macros {
#[macro_export]
macro_rules! write_hl { ($v:expr, $low:expr) => { $v = $v & 0xff00ffff | (($low as u32) << 16) }; }
#[macro_export]
+ macro_rules! write_lh { ($v:expr, $high:expr) => { $v = $v & 0xffff00ff | (($high as u32) << 8) }; }
+ #[macro_export]
+ macro_rules! write_ll { ($v:expr, $low:expr) => { $v = $v & 0xffffff00 | ($low as u32) }; }
+ #[macro_export]
macro_rules! write_h { ($v:expr, $high:expr) => { $v = $v & 0x00ff | (($high as u16) << 8) }; }
#[macro_export]
macro_rules! write_l { ($v:expr, $low:expr) => { $v = $v & 0xff00 | ($low as u16) }; }
diff --git a/src/processor.rs b/src/processor.rs
index dc55e4b..2934e11 100644
--- a/src/processor.rs
+++ b/src/processor.rs
@@ -1,44 +1,29 @@
+use emulator::BedrockEmulator;
+
use crate::*;
use std::ops::*;
-#[derive(Copy, Clone, Debug)]
-pub enum Signal {
- Sleep,
- Fork,
- Halt,
- Debug1,
- Debug2,
- Debug3,
- Debug4,
- Debug5,
- Debug6,
-}
-
-
-impl <
- D0:Device, D1:Device, D2:Device, D3:Device, D4:Device, D5:Device, D6:Device, D7:Device,
- D8:Device, D9:Device, DA:Device, DB:Device, DC:Device, DD:Device, DE:Device, DF:Device,
-> Bedrock<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> {
- pub fn evaluate(&mut self, cycles: usize) -> Option<Signal> {
- macro_rules! WPSH1 { ($x:expr) => { self.wst.push_u8($x) }; }
- macro_rules! RPSH1 { ($x:expr) => { self.rst.push_u8($x) }; }
+impl <DB: DeviceBus> BedrockEmulator<DB> {
+ pub fn evaluate(&mut self, cycles: usize, debug: bool) -> Option<Signal> {
+ macro_rules! WPSH1 { ($x:expr) => { self.core.wst.push_u8($x) }; }
+ macro_rules! RPSH1 { ($x:expr) => { self.core.rst.push_u8($x) }; }
macro_rules! WPSH2 { ($x:expr,$y:expr) => { WPSH1!($x); WPSH1!($y); }; }
- macro_rules! RPSH2 { ($x:expr,$y:expr) => { WPSH1!($x); WPSH1!($y); }; }
- macro_rules! WPSHD { ($d:expr) => { self.wst.push_u16($d) }; }
- macro_rules! RPSHD { ($d:expr) => { self.rst.push_u16($d) }; }
- macro_rules! WPSHB { ($x:expr) => { self.wst.push_u8(0u8.wrapping_sub($x as u8)) }; }
- macro_rules! RPSHB { ($x:expr) => { self.rst.push_u8(0u8.wrapping_sub($x as u8)) }; }
+ macro_rules! RPSH2 { ($x:expr,$y:expr) => { RPSH1!($x); RPSH1!($y); }; }
+ macro_rules! WPSHD { ($d:expr) => { self.core.wst.push_u16($d) }; }
+ macro_rules! RPSHD { ($d:expr) => { self.core.rst.push_u16($d) }; }
+ macro_rules! WPSHB { ($x:expr) => { self.core.wst.push_u8(0u8.wrapping_sub($x as u8)) }; }
+ macro_rules! RPSHB { ($x:expr) => { self.core.rst.push_u8(0u8.wrapping_sub($x as u8)) }; }
- macro_rules! WPOP1 { ($x:ident) => { let $x = self.wst.pop_u8(); }; }
- macro_rules! RPOP1 { ($x:ident) => { let $x = self.rst.pop_u8(); }; }
+ macro_rules! WPOP1 { ($x:ident) => { let $x = self.core.wst.pop_u8(); }; }
+ macro_rules! RPOP1 { ($x:ident) => { let $x = self.core.rst.pop_u8(); }; }
macro_rules! WPOP2 { ($x:ident,$y:ident) => { WPOP1!($y); WPOP1!($x); }; }
- macro_rules! RPOP2 { ($x:ident,$y:ident) => { WPOP1!($y); WPOP1!($x); }; }
- macro_rules! WPOPD { ($d:ident) => { let $d = self.wst.pop_u16(); }; }
- macro_rules! RPOPD { ($d:ident) => { let $d = self.rst.pop_u16(); }; }
+ macro_rules! RPOP2 { ($x:ident,$y:ident) => { RPOP1!($y); RPOP1!($x); }; }
+ macro_rules! WPOPD { ($d:ident) => { let $d = self.core.wst.pop_u16(); }; }
+ macro_rules! RPOPD { ($d:ident) => { let $d = self.core.rst.pop_u16(); }; }
- macro_rules! WGETV { ($i:expr) => { self.wst.mem[self.wst.sp.wrapping_sub($i) as usize] }; }
- macro_rules! RGETV { ($i:expr) => { self.rst.mem[self.rst.sp.wrapping_sub($i) as usize] }; }
+ macro_rules! WGETV { ($i:expr) => { self.core.wst.mem[self.core.wst.sp.wrapping_sub($i) as usize] }; }
+ macro_rules! RGETV { ($i:expr) => { self.core.rst.mem[self.core.rst.sp.wrapping_sub($i) as usize] }; }
macro_rules! WGET1 { ($x:ident) => { let $x = WGETV!(1); }; }
macro_rules! RGET1 { ($x:ident) => { let $x = RGETV!(1); }; }
macro_rules! WGET1N { ($x:ident) => { let $x = WGETV!(2); }; }
@@ -52,31 +37,30 @@ impl <
macro_rules! WGETDN { ($d:ident) => { let $d = u16::from_be_bytes([WGETV!(4),WGETV!(3)]); }; }
macro_rules! RGETDN { ($d:ident) => { let $d = u16::from_be_bytes([RGETV!(4),RGETV!(3)]); }; }
- macro_rules! MEM { ($a:expr) => { self.mem.mem[$a as usize] }; }
- macro_rules! MEMN { ($a:expr) => { self.mem.mem[$a.wrapping_add(1) as usize] }; }
- macro_rules! DEV { ($p:expr) => { self.dev.read_u8($p) }; }
- macro_rules! DEVN { ($p:expr) => { self.dev.read_u8($p.wrapping_add(1)) }; }
+ macro_rules! PCSET { ($a:expr) => { self.core.mem.pc=$a }; }
+ macro_rules! MEM { ($a:expr) => { self.core.mem.mem[$a as usize] }; }
+ macro_rules! MEMN { ($a:expr) => { self.core.mem.mem[$a.wrapping_add(1) as usize] }; }
+ macro_rules! DEV { ($p:expr) => { self.dev.read($p) }; }
+ macro_rules! DEVN { ($p:expr) => { self.dev.read($p.wrapping_add(1)) }; }
- macro_rules! MLIT1 { ($x:ident) => { let $x = self.mem.read_u8_next(); }; }
+ macro_rules! MLIT1 { ($x:ident) => { let $x = self.core.mem.read_u8_next(); }; }
macro_rules! MLIT2 { ($x:ident,$y:ident) => { MLIT1!($x); MLIT1!($y); }; }
- macro_rules! MLITD { ($d:ident) => { let $d = self.mem.read_u16_next(); }; }
+ macro_rules! MLITD { ($d:ident) => { let $d = self.core.mem.read_u16_next(); }; }
macro_rules! DSET1 { ($p:expr,$x:expr) => {
- let s = self.dev.write_u8($p, $x);
+ let s = self.dev.write($p, $x);
if s.is_some() { return s };
}; }
macro_rules! DSET2 { ($p:expr,$x:expr,$y:expr) => {
- let s1 = self.dev.write_u8($p, $x);
- let s2 = self.dev.write_u8($p.wrapping_add(1), $y);
- match s1.is_some() {
- true => s1,
- false => s2,
- }
+ let s1 = self.dev.write($p, $x);
+ let s2 = self.dev.write($p.wrapping_add(1), $y);
+ if s1.is_some() { return s1 };
+ if s2.is_some() { return s2 };
}; }
macro_rules! math {
- ($v:expr; ADD $i:expr) => { $v = $v.wrapping_sub($i); };
- ($v:expr; SUB $i:expr) => { $v = $v.wrapping_add($i); };
+ ($v:expr; ADD $i:expr) => { $v = $v.wrapping_add($i); };
+ ($v:expr; SUB $i:expr) => { $v = $v.wrapping_sub($i); };
($v:expr; IOR $i:expr) => { $v = $v.bitor($i); };
($v:expr; XOR $i:expr) => { $v = $v.bitxor($i); };
($v:expr; AND $i:expr) => { $v = $v.bitand($i); };
@@ -101,21 +85,21 @@ impl <
};
}
- let end = self.cyc + cycles;
- while self.cyc < end {
- self.cyc += 1;
+ let end = self.core.cycle + cycles;
+ while self.core.cycle < end {
+ self.core.cycle += 1;
- match self.mem.read_u8_next() {
+ match self.core.mem.read_u8_next() {
/* HLT */ 0x00 => { return Some(Signal::Halt); }
- /* JMP */ 0x01 => { WPOPD!(a); self.mem.pc=a; }
- /* JCN */ 0x02 => { WPOPD!(a); WPOP1!(t); if t!=0 {self.mem.pc=a}; }
- /* JCK */ 0x03 => { WPOPD!(a); WGET1!(t); if t!=0 {self.mem.pc=a}; }
+ /* JMP */ 0x01 => { WPOPD!(a); PCSET!(a); }
+ /* JCN */ 0x02 => { WPOPD!(a); WPOP1!(t); if t!=0 {PCSET!(a)}; }
+ /* JCK */ 0x03 => { WPOPD!(a); WGET1!(t); if t!=0 {PCSET!(a)}; }
/* LDA */ 0x04 => { WPOPD!(a); WPSH1!(MEM!(a)); }
/* STA */ 0x05 => { WPOPD!(a); WPOP1!(x); MEM!(a)=x; }
/* LDD */ 0x06 => { WPOP1!(p); WPSH1!(DEV!(p)); }
/* STD */ 0x07 => { WPOP1!(p); WPOP1!(x); DSET1!(p,x); }
/* PSH */ 0x08 => { RPOP1!(x); WPSH1!(x); }
- /* POP */ 0x09 => { math!(self.wst.sp; SUB 1); }
+ /* POP */ 0x09 => { math!(self.core.wst.sp; SUB 1); }
/* CPY */ 0x0A => { RGET1!(x); WPSH1!(x); }
/* SPL */ 0x0B => { WPOP1!(x); split!(x=>a,b); WPSH2!(a,b); }
/* DUP */ 0x0C => { WGET1!(x); WPSH1!(x); }
@@ -140,15 +124,15 @@ impl <
/* REV */ 0x1F => { math!(WGETV!(1); REV); }
/* NOP */ 0x20 => { }
- /* JMS */ 0x21 => { WPOPD!(a); RPSHD!(self.mem.pc); self.mem.pc=a; }
- /* JCS */ 0x22 => { WPOPD!(a); WPOP1!(t); if t!=0 {RPSHD!(self.mem.pc); self.mem.pc=a}; }
- /* JCK* */ 0x23 => { WPOPD!(a); WGETD!(t); if t!=0 {self.mem.pc=a}; }
+ /* JMS */ 0x21 => { WPOPD!(a); RPSHD!(self.core.mem.pc); PCSET!(a); }
+ /* JCS */ 0x22 => { WPOPD!(a); WPOP1!(t); if t!=0 {RPSHD!(self.core.mem.pc); PCSET!(a)}; }
+ /* JCK* */ 0x23 => { WPOPD!(a); WGETD!(t); if t!=0 {PCSET!(a)}; }
/* LDA* */ 0x24 => { WPOPD!(a); WPSH2!(MEM!(a),MEMN!(a)); }
/* STA* */ 0x25 => { WPOPD!(a); WPOP2!(x,y); MEM!(a)=x; MEMN!(a)=y; }
/* LDD* */ 0x26 => { WPOP1!(p); WPSH2!(DEV!(p),DEVN!(p)); }
/* STD* */ 0x27 => { WPOP1!(p); WPOP2!(x,y); DSET2!(p,x,y); }
/* PSH* */ 0x28 => { RPOP2!(x,y); WPSH2!(x,y); }
- /* POP* */ 0x29 => { math!(self.wst.sp; SUB 2); }
+ /* POP* */ 0x29 => { math!(self.core.wst.sp; SUB 2); }
/* CPY* */ 0x2A => { RGET2!(x,y); WPSH2!(x,y); }
/* SPL* */ 0x2B => { WPOP2!(x,y); split!(x=>a,b); split!(y=>c,d); WPSH2!(a,b); WPSH2!(c,d); }
/* DUP* */ 0x2C => { WGET2!(x,y); WPSH2!(x,y); }
@@ -172,16 +156,16 @@ impl <
/* TAL* */ 0x3E => { WPOPD!(x); WPSH1!(x.count_ones() as u8); }
/* REV* */ 0x3F => { WPOPD!(x); WPSHD!(x.reverse_bits()); }
- /* DB1 */ 0x40 => { return Some(Signal::Debug1); }
- /* JMP: */ 0x41 => { MLITD!(a); self.mem.pc=a; }
- /* JCN: */ 0x42 => { MLITD!(a); WPOP1!(t); if t!=0 {self.mem.pc=a}; }
- /* JCK: */ 0x43 => { MLITD!(a); WGET1!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB1 */ 0x40 => { if debug { return Some(Signal::Debug1); } }
+ /* JMP: */ 0x41 => { MLITD!(a); PCSET!(a); }
+ /* JCN: */ 0x42 => { MLITD!(a); WPOP1!(t); if t!=0 {PCSET!(a)}; }
+ /* JCK: */ 0x43 => { MLITD!(a); WGET1!(t); if t!=0 {PCSET!(a)}; }
/* LDA: */ 0x44 => { MLITD!(a); WPSH1!(MEM!(a)); }
/* STA: */ 0x45 => { MLITD!(a); WPOP1!(x); MEM!(a)=x; }
/* LDD: */ 0x46 => { MLIT1!(p); WPSH1!(DEV!(p)); }
/* STD: */ 0x47 => { MLIT1!(p); WPOP1!(x); DSET1!(p,x); }
/* PSH: */ 0x48 => { MLIT1!(x); WPSH1!(x); }
- /* POP: */ 0x49 => { math!(self.mem.pc; ADD 1); }
+ /* POP: */ 0x49 => { math!(self.core.mem.pc; ADD 1); }
/* CPY: */ 0x4A => { MLIT1!(x); WPSH1!(x); RPSH1!(x); }
/* SPL: */ 0x4B => { MLIT1!(x); split!(x=>a,b); WPSH2!(a,b); }
/* DUP: */ 0x4C => { MLIT1!(x); WPSH1!(x); WPSH1!(x); }
@@ -205,16 +189,16 @@ impl <
/* TAL: */ 0x5E => { MLIT1!(x); WPSH1!(x.count_ones() as u8); }
/* REV: */ 0x5F => { MLIT1!(x); WPSH1!(x.reverse_bits()); }
- /* DB2 */ 0x60 => { return Some(Signal::Debug2); }
- /* JMS: */ 0x61 => { MLITD!(a); RPSHD!(self.mem.pc); self.mem.pc=a; }
- /* JCS: */ 0x62 => { MLITD!(a); WPOP1!(t); if t!=0 {RPSHD!(self.mem.pc); self.mem.pc=a}; }
- /* JCK*: */ 0x63 => { MLITD!(a); WGETD!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB2 */ 0x60 => { if debug { return Some(Signal::Debug2); } }
+ /* JMS: */ 0x61 => { MLITD!(a); RPSHD!(self.core.mem.pc); PCSET!(a); }
+ /* JCS: */ 0x62 => { MLITD!(a); WPOP1!(t); if t!=0 {RPSHD!(self.core.mem.pc); PCSET!(a)}; }
+ /* JCK*: */ 0x63 => { MLITD!(a); WGETD!(t); if t!=0 {PCSET!(a)}; }
/* LDA*: */ 0x64 => { MLITD!(a); WPSH2!(MEM!(a),MEMN!(a)); }
/* STA*: */ 0x65 => { MLITD!(a); WPOP2!(x,y); MEM!(a)=x; MEMN!(a)=y; }
/* LDD*: */ 0x66 => { MLIT1!(p); WPSH2!(DEV!(p),DEVN!(p)); }
/* STD*: */ 0x67 => { MLIT1!(p); WPOP2!(x,y); DSET2!(p,x,y); }
/* PSH*: */ 0x68 => { MLIT2!(x,y); WPSH2!(x,y); }
- /* POP*: */ 0x69 => { math!(self.mem.pc; ADD 2); }
+ /* POP*: */ 0x69 => { math!(self.core.mem.pc; ADD 2); }
/* CPY*: */ 0x6A => { MLIT2!(x,y); WPSH2!(x,y); RPSH2!(x,y); }
/* SPL*: */ 0x6B => { MLIT2!(x,y); split!(x=>a,b); split!(y=>c,d); WPSH2!(a,b); WPSH2!(c,d); }
/* DUP*: */ 0x6C => { MLIT2!(x,y); WPSH2!(x,y); WPSH2!(x,y); }
@@ -238,16 +222,16 @@ impl <
/* TAL*: */ 0x7E => { MLITD!(x); WPSH1!(x.count_ones() as u8); }
/* REV*: */ 0x7F => { MLITD!(x); WPSHD!(x.reverse_bits()); }
- /* DB3 */ 0x80 => { return Some(Signal::Debug3); }
- /* JMPr */ 0x81 => { RPOPD!(a); self.mem.pc=a; }
- /* JCNr */ 0x82 => { RPOPD!(a); RPOP1!(t); if t!=0 {self.mem.pc=a}; }
- /* JCKr */ 0x83 => { RPOPD!(a); RGET1!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB3 */ 0x80 => { if debug { return Some(Signal::Debug3); } }
+ /* JMPr */ 0x81 => { RPOPD!(a); PCSET!(a); }
+ /* JCNr */ 0x82 => { RPOPD!(a); RPOP1!(t); if t!=0 {PCSET!(a)}; }
+ /* JCKr */ 0x83 => { RPOPD!(a); RGET1!(t); if t!=0 {PCSET!(a)}; }
/* LDAr */ 0x84 => { RPOPD!(a); RPSH1!(MEM!(a)); }
/* STAr */ 0x85 => { RPOPD!(a); RPOP1!(x); MEM!(a)=x; }
/* LDDr */ 0x86 => { RPOP1!(p); RPSH1!(DEV!(p)); }
/* STDr */ 0x87 => { RPOP1!(p); RPOP1!(x); DSET1!(p,x); }
/* PSHr */ 0x88 => { WPOP1!(x); RPSH1!(x); }
- /* POPr */ 0x89 => { math!(self.rst.sp; SUB 1); }
+ /* POPr */ 0x89 => { math!(self.core.rst.sp; SUB 1); }
/* CPYr */ 0x8A => { WGET1!(x); RPSH1!(x); }
/* SPLr */ 0x8B => { RPOP1!(x); split!(x=>a,b); RPSH2!(a,b); }
/* DUPr */ 0x8C => { RGET1!(x); RPSH1!(x); }
@@ -271,16 +255,16 @@ impl <
/* TALr */ 0x9E => { math!(RGETV!(1); TAL); }
/* REVr */ 0x9F => { math!(RGETV!(1); REV); }
- /* DB4 */ 0xA0 => { return Some(Signal::Debug4); }
- /* JMSr */ 0xA1 => { RPOPD!(a); WPSHD!(self.mem.pc); self.mem.pc=a; }
- /* JCSr */ 0xA2 => { RPOPD!(a); RPOP1!(t); if t!=0 {WPSHD!(self.mem.pc); self.mem.pc=a}; }
- /* JCKr* */ 0xA3 => { RPOPD!(a); RGETD!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB4 */ 0xA0 => { if debug { return Some(Signal::Debug4); } }
+ /* JMSr */ 0xA1 => { RPOPD!(a); WPSHD!(self.core.mem.pc); PCSET!(a); }
+ /* JCSr */ 0xA2 => { RPOPD!(a); RPOP1!(t); if t!=0 {WPSHD!(self.core.mem.pc); PCSET!(a)}; }
+ /* JCKr* */ 0xA3 => { RPOPD!(a); RGETD!(t); if t!=0 {PCSET!(a)}; }
/* LDAr* */ 0xA4 => { RPOPD!(a); RPSH2!(MEM!(a),MEMN!(a)); }
/* STAr* */ 0xA5 => { RPOPD!(a); RPOP2!(x,y); MEM!(a)=x; MEMN!(a)=y; }
/* LDDr* */ 0xA6 => { RPOP1!(p); RPSH2!(DEV!(p),DEVN!(p)); }
/* STDr* */ 0xA7 => { RPOP1!(p); RPOP2!(x,y); DSET2!(p,x,y); }
/* PSHr* */ 0xA8 => { WPOP2!(x,y); RPSH2!(x,y); }
- /* POPr* */ 0xA9 => { math!(self.rst.sp; SUB 2); }
+ /* POPr* */ 0xA9 => { math!(self.core.rst.sp; SUB 2); }
/* CPYr* */ 0xAA => { WGET2!(x,y); RPSH2!(x,y); }
/* SPLr* */ 0xAB => { RPOP2!(x,y); split!(x=>a,b); split!(y=>c,d); RPSH2!(a,b); RPSH2!(c,d); }
/* DUPr* */ 0xAC => { RGET2!(x,y); RPSH2!(x,y); }
@@ -304,16 +288,16 @@ impl <
/* TALr* */ 0xBE => { RPOPD!(x); RPSH1!(x.count_ones() as u8); }
/* REVr* */ 0xBF => { RPOPD!(x); RPSHD!(x.reverse_bits()); }
- /* DB5 */ 0xC0 => { return Some(Signal::Debug5); }
- /* JMPr: */ 0xC1 => { MLITD!(a); self.mem.pc=a; }
- /* JCNr: */ 0xC2 => { MLITD!(a); RPOP1!(t); if t!=0 {self.mem.pc=a}; }
- /* JCKr: */ 0xC3 => { MLITD!(a); RGET1!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB5 */ 0xC0 => { if debug { return Some(Signal::Debug5); } }
+ /* JMPr: */ 0xC1 => { MLITD!(a); PCSET!(a); }
+ /* JCNr: */ 0xC2 => { MLITD!(a); RPOP1!(t); if t!=0 {PCSET!(a)}; }
+ /* JCKr: */ 0xC3 => { MLITD!(a); RGET1!(t); if t!=0 {PCSET!(a)}; }
/* LDAr: */ 0xC4 => { MLITD!(a); RPSH1!(MEM!(a)); }
/* STAr: */ 0xC5 => { MLITD!(a); RPOP1!(x); MEM!(a)=x; }
/* LDDr: */ 0xC6 => { MLIT1!(p); RPSH1!(DEV!(p)); }
/* STDr: */ 0xC7 => { MLIT1!(p); RPOP1!(x); DSET1!(p,x); }
/* PSHr: */ 0xC8 => { MLIT1!(x); RPSH1!(x); }
- /* POPr: */ 0xC9 => { math!(self.mem.pc; ADD 1); }
+ /* POPr: */ 0xC9 => { math!(self.core.mem.pc; ADD 1); }
/* CPYr: */ 0xCA => { MLIT1!(x); RPSH1!(x); WPSH1!(x); }
/* SPLr: */ 0xCB => { MLIT1!(x); split!(x=>a,b); RPSH2!(a,b); }
/* DUPr: */ 0xCC => { MLIT1!(x); RPSH1!(x); RPSH1!(x); }
@@ -337,16 +321,16 @@ impl <
/* TALr: */ 0xDE => { MLIT1!(x); RPSH1!(x.count_ones() as u8); }
/* REVr: */ 0xDF => { MLIT1!(x); RPSH1!(x.reverse_bits()); }
- /* DB6 */ 0xE0 => { return Some(Signal::Debug6); }
- /* JMSr: */ 0xE1 => { MLITD!(a); WPSHD!(self.mem.pc); self.mem.pc=a; }
- /* JCSr: */ 0xE2 => { MLITD!(a); RPOP1!(t); if t!=0 {WPSHD!(self.mem.pc); self.mem.pc=a}; }
- /* JCKr*: */ 0xE3 => { MLITD!(a); RGETD!(t); if t!=0 {self.mem.pc=a}; }
+ /* DB6 */ 0xE0 => { if debug { return Some(Signal::Debug6); } }
+ /* JMSr: */ 0xE1 => { MLITD!(a); WPSHD!(self.core.mem.pc); PCSET!(a); }
+ /* JCSr: */ 0xE2 => { MLITD!(a); RPOP1!(t); if t!=0 {WPSHD!(self.core.mem.pc); PCSET!(a)}; }
+ /* JCKr*: */ 0xE3 => { MLITD!(a); RGETD!(t); if t!=0 {PCSET!(a)}; }
/* LDAr*: */ 0xE4 => { MLITD!(a); RPSH2!(MEM!(a),MEMN!(a)); }
/* STAr*: */ 0xE5 => { MLITD!(a); RPOP2!(x,y); MEM!(a)=x; MEMN!(a)=y; }
/* LDDr*: */ 0xE6 => { MLIT1!(p); RPSH2!(DEV!(p),DEVN!(p)); }
/* STDr*: */ 0xE7 => { MLIT1!(p); RPOP2!(x,y); DSET2!(p,x,y); }
/* PSHr*: */ 0xE8 => { MLIT2!(x,y); RPSH2!(x,y); }
- /* POPr*: */ 0xE9 => { math!(self.mem.pc; ADD 2); }
+ /* POPr*: */ 0xE9 => { math!(self.core.mem.pc; ADD 2); }
/* CPYr*: */ 0xEA => { MLIT2!(x,y); RPSH2!(x,y); WPSH2!(x,y); }
/* SPLr*: */ 0xEB => { MLIT2!(x,y); split!(x=>a,b); split!(y=>c,d); RPSH2!(a,b); RPSH2!(c,d); }
/* DUPr*: */ 0xEC => { MLIT2!(x,y); RPSH2!(x,y); RPSH2!(x,y); }
diff --git a/src/signal.rs b/src/signal.rs
new file mode 100644
index 0000000..9959901
--- /dev/null
+++ b/src/signal.rs
@@ -0,0 +1,12 @@
+#[derive(Copy, Clone, Debug)]
+pub enum Signal {
+ Sleep,
+ Fork,
+ Halt,
+ Debug1,
+ Debug2,
+ Debug3,
+ Debug4,
+ Debug5,
+ Debug6,
+}