diff options
Diffstat (limited to 'src/emulators/headless_emulator.rs')
-rw-r--r-- | src/emulators/headless_emulator.rs | 157 |
1 files changed, 73 insertions, 84 deletions
diff --git a/src/emulators/headless_emulator.rs b/src/emulators/headless_emulator.rs index 9207b3d..b07b06e 100644 --- a/src/emulators/headless_emulator.rs +++ b/src/emulators/headless_emulator.rs @@ -1,83 +1,4 @@ use crate::*; -use bedrock_core::*; - - -pub struct HeadlessDeviceBus { - pub sys: SystemDevice, - pub mem: MemoryDevice, - pub mat: MathDevice, - pub clk: ClockDevice, - pub loc: LocalDevice, - pub rem: RemoteDevice, - pub fs1: FileDevice, - pub fs2: FileDevice, -} - -impl HeadlessDeviceBus { - pub fn new(config: &EmulatorConfig) -> Self { - Self { - sys: SystemDevice::new(), - mem: MemoryDevice::new(), - mat: MathDevice::new(), - clk: ClockDevice::new(), - loc: LocalDevice::new(config), - rem: RemoteDevice::new(), - fs1: FileDevice::new(), - fs2: FileDevice::new(), - } - } -} - -impl DeviceBus for HeadlessDeviceBus { - fn read(&mut self, port: u8) -> u8 { - match port & 0xf0 { - 0x00 => self.sys.read(port & 0x0f), - 0x10 => self.mem.read(port & 0x0f), - 0x20 => self.mat.read(port & 0x0f), - 0x30 => self.clk.read(port & 0x0f), - 0x80 => self.loc.read(port & 0x0f), - 0x90 => self.rem.read(port & 0x0f), - 0xa0 => self.fs1.read(port & 0x0f), - 0xb0 => self.fs2.read(port & 0x0f), - _ => 0 - } - } - - fn write(&mut self, port: u8, value: u8) -> Option<Signal> { - match port & 0xf0 { - 0x00 => self.sys.write(port & 0x0f, value), - 0x10 => self.mem.write(port & 0x0f, value), - 0x20 => self.mat.write(port & 0x0f, value), - 0x30 => self.clk.write(port & 0x0f, value), - 0x80 => self.loc.write(port & 0x0f, value), - 0x90 => self.rem.write(port & 0x0f, value), - 0xa0 => self.fs1.write(port & 0x0f, value), - 0xb0 => self.fs2.write(port & 0x0f, value), - _ => None - } - } - - fn wake(&mut self) -> bool { - macro_rules! rouse { - ($id:expr, $dev:ident) => { - if self.sys.can_wake($id) && self.$dev.wake() { - self.sys.wake_id = $id; - self.sys.asleep = false; - return true; - } - }; - } - rouse!(0xb, fs2); - rouse!(0xa, fs1); - rouse!(0x9, rem); - rouse!(0x8, loc); - rouse!(0x3, clk); - rouse!(0x2, mat); - rouse!(0x1, mem); - rouse!(0x0, sys); - return false; - } -} pub struct HeadlessEmulator { @@ -85,6 +6,7 @@ pub struct HeadlessEmulator { pub debug: DebugState, } + impl HeadlessEmulator { pub fn new(config: &EmulatorConfig, debug: bool) -> Self { Self { @@ -97,7 +19,7 @@ impl HeadlessEmulator { self.br.core.mem.load_program(bytecode); } - pub fn run(&mut self, debug: bool) -> EmulatorSignal { + pub fn run(&mut self) -> ! { loop { match self.br.evaluate(BATCH_SIZE, self.debug.enabled) { Some(Signal::Fork) => { @@ -110,12 +32,12 @@ impl HeadlessEmulator { std::thread::sleep(MIN_TICK_DURATION); } Some(Signal::Halt) => { - self.br.dev.loc.flush(); - log::info!("Program halted, exiting."); + self.br.dev.stream.flush(); + info!("Program halted, exiting."); self.debug.debug_summary(&self.br.core); - return EmulatorSignal::Halt; + std::process::exit(0); } - Some(Signal::Debug1) => if debug { + Some(Signal::Debug(Debug::Debug1)) => { self.debug.debug_summary(&self.br.core); } _ => (), @@ -123,3 +45,70 @@ impl HeadlessEmulator { } } } + + +pub struct HeadlessDeviceBus { + pub system: SystemDevice, + pub memory: MemoryDevice, + pub math: MathDevice, + pub clock: ClockDevice, + pub stream: StreamDevice, + pub file: FileDevice, +} + +impl HeadlessDeviceBus { + pub fn new(config: &EmulatorConfig) -> Self { + Self { + system: SystemDevice::new(0b1111_0000_1010_0000), + memory: MemoryDevice::new(), + math: MathDevice::new(), + clock: ClockDevice::new(), + stream: StreamDevice::new(&config), + file: FileDevice::new(), + } + } +} + + +impl DeviceBus for HeadlessDeviceBus { + fn read(&mut self, port: u8) -> u8 { + match port & 0xf0 { + 0x00 => self.system.read(port & 0x0f), + 0x10 => self.memory.read(port & 0x0f), + 0x20 => self.math .read(port & 0x0f), + 0x30 => self.clock .read(port & 0x0f), + 0x80 => self.stream.read(port & 0x0f), + 0xa0 => self.file .read(port & 0x0f), + _ => 0 + } + } + + fn write(&mut self, port: u8, value: u8) -> Option<Signal> { + match port & 0xf0 { + 0x00 => self.system.write(port & 0x0f, value), + 0x10 => self.memory.write(port & 0x0f, value), + 0x20 => self.math .write(port & 0x0f, value), + 0x30 => self.clock .write(port & 0x0f, value), + 0x80 => self.stream.write(port & 0x0f, value), + 0xa0 => self.file .write(port & 0x0f, value), + _ => None + } + } + + fn wake(&mut self) -> bool { + macro_rules! rouse { + ($id:expr, $dev:ident) => { + let is_eligible = test_bit!(self.system.wakers, 0x8000 >> $id); + if is_eligible && self.$dev.wake() { + self.system.waker = $id; + self.system.asleep = false; + return true; + } + }; + } + rouse!(0xa, file ); + rouse!(0x8, stream); + rouse!(0x3, clock ); + return false; + } +} |