Skip to content

Commit

Permalink
Converted Z80 to use emulator-hal traits
Browse files Browse the repository at this point in the history
  • Loading branch information
transistorfet committed Apr 1, 2024
1 parent 6e7e315 commit 40266aa
Show file tree
Hide file tree
Showing 27 changed files with 679 additions and 2,065 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ For more about the Sega Genesis support, check out this series I wrote about imp
I've also generated rustdocs of the workspace. All the various crates within moa
are listed in the crates section in the sidebar on the left. There's not a lot
of doc comments in the code yet but I plan to eventually write more:
[rustdocs for moa_core](http://jabberwocky.ca/moa/doc/moa_core/)
[rustdocs for ym2612](http://jabberwocky.ca/moa/doc/moa_peripherals_yamaha/ym2612/index.html)
[moa_core](http://jabberwocky.ca/moa/doc/moa_core/)
[moa_m68k](http://jabberwocky.ca/moa/doc/moa_m68k/)
[moa_z80](http://jabberwocky.ca/moa/doc/moa_z80/)
[ym2612](http://jabberwocky.ca/moa/doc/moa_peripherals_yamaha/ym2612/index.html)

This repository uses submodules, so make sure to clone with
```sh
Expand Down
12 changes: 5 additions & 7 deletions emulator/cpus/m68k/src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

use core::fmt;

use emulator_hal::time;
use emulator_hal::bus::{self, BusAccess};
use emulator_hal::step::{Inspect, Debug};
use emulator_hal::{Instant as BusInstant, Error as ErrorType, BusAccess, Inspect, Debug};

use crate::{M68k, M68kError, M68kAddress, M68kCycleExecutor};

Expand All @@ -28,10 +26,10 @@ pub enum M68kInfo {
State,
}

impl<Bus, BusError, Instant, Writer> Inspect<M68kAddress, Bus, Writer> for M68k<Instant>
impl<Bus, BusError, Instant, Writer> Inspect<Bus, Writer> for M68k<Instant>
where
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
BusError: bus::Error,
BusError: ErrorType,
Writer: fmt::Write,
{
type InfoType = M68kInfo;
Expand Down Expand Up @@ -60,8 +58,8 @@ where
impl<Bus, BusError, Instant, Writer> Debug<M68kAddress, Bus, Writer> for M68k<Instant>
where
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
BusError: bus::Error,
Instant: time::Instant,
BusError: ErrorType,
Instant: BusInstant,
Writer: fmt::Write,
{
// TODO this should be a new type
Expand Down
2 changes: 1 addition & 1 deletion emulator/cpus/m68k/src/decode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Instruction Decoding

use core::marker::PhantomData;
use emulator_hal::bus::BusAccess;
use emulator_hal::{Instant as BusInstant, Error as BusError, BusAccess, Step};

use crate::{M68kType, M68kError, M68kBusPort, M68kAddress, Exceptions};
use crate::instructions::{
Expand Down
13 changes: 6 additions & 7 deletions emulator/cpus/m68k/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Instruction Execution

use emulator_hal::time;
use emulator_hal::step::Step;
use emulator_hal::bus::{self, BusAccess};
use emulator_hal::{Instant as BusInstant, Error, BusAccess, Step};

use crate::{M68k, M68kType, M68kError, M68kState};
use crate::state::{Status, Flags, Exceptions, InterruptPriority};
Expand Down Expand Up @@ -35,7 +33,7 @@ pub struct M68kCycle<Instant> {

impl<Instant> M68kCycle<Instant>
where
Instant: time::Instant,
Instant: BusInstant,
{
#[inline]
pub fn default(cputype: M68kType, data_width: u8) -> Self {
Expand Down Expand Up @@ -74,12 +72,13 @@ where
}
}

impl<Bus, BusError, Instant> Step<M68kAddress, Bus> for M68k<Instant>
impl<Bus, BusError, Instant> Step<Bus> for M68k<Instant>
where
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
BusError: bus::Error,
Instant: time::Instant,
BusError: Error,
Instant: BusInstant,
{
type Instant = Instant;
type Error = M68kError<BusError>;

fn is_running(&mut self) -> bool {
Expand Down
19 changes: 19 additions & 0 deletions emulator/cpus/m68k/src/interrupts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

use crate::state::InterruptPriority;

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Interrupt {
priority: InterruptPriority,
vector: u8,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct InterruptAcknowledge {
priority: InterruptPriority,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InterruptState {
pub current_ipl: InterruptPriority,
pub pending_ipl: InterruptPriority,
}
7 changes: 3 additions & 4 deletions emulator/cpus/m68k/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core::cmp;
use core::fmt::Write;
use emulator_hal::time;
use emulator_hal::bus::BusAccess;
use emulator_hal::{Instant as BusInstant, BusAccess};

use crate::{M68kError, CpuInfo};
use crate::state::Exceptions;
Expand Down Expand Up @@ -65,7 +64,7 @@ impl FunctionCode {

impl<Instant> Default for MemoryRequest<Instant>
where
Instant: time::Instant,
Instant: BusInstant,
{
fn default() -> Self {
Self {
Expand Down Expand Up @@ -138,7 +137,7 @@ pub struct M68kBusPort<Instant> {

impl<Instant> Default for M68kBusPort<Instant>
where
Instant: time::Instant,
Instant: BusInstant,
{
fn default() -> Self {
Self {
Expand Down
12 changes: 6 additions & 6 deletions emulator/cpus/m68k/src/moa.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use femtos::{Instant, Duration};
use emulator_hal::bus;
use emulator_hal::{Error as ErrorType, BusAdapter};

use moa_core::{System, Error, Address, Steppable, Interruptable, Addressable, Debuggable, Transmutable};

Expand All @@ -10,8 +10,8 @@ impl Steppable for M68k<Instant> {
let cycle = M68kCycle::new(self, system.clock);

let mut bus = system.bus.borrow_mut();
let mut adapter: bus::BusAdapter<u32, u64, &mut dyn Addressable, Error> =
bus::BusAdapter::new(&mut *bus, |addr| addr as u64, |err| err);
let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> =
BusAdapter::new(&mut *bus, |addr| addr as u64, |err| err);

let mut executor = cycle.begin(self, &mut adapter);
executor.check_breakpoints()?;
Expand Down Expand Up @@ -60,7 +60,7 @@ impl<BusError> From<Error> for M68kError<BusError> {
}
}

impl<BusError: bus::Error> From<M68kError<BusError>> for Error {
impl<BusError: ErrorType> From<M68kError<BusError>> for Error {
fn from(err: M68kError<BusError>) -> Self {
match err {
M68kError::Halted => Self::Other("cpu halted".to_string()),
Expand Down Expand Up @@ -99,8 +99,8 @@ impl Debuggable for M68k<Instant> {
let mut memory = M68kBusPort::from_info(&self.info, system.clock);

let mut bus = system.bus.borrow_mut();
let mut adapter: bus::BusAdapter<u32, u64, &mut dyn Addressable, Error> =
bus::BusAdapter::new(&mut *bus, |addr| addr as u64, |err| err);
let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> =
BusAdapter::new(&mut *bus, |addr| addr as u64, |err| err);

decoder.dump_disassembly(&mut adapter, &mut memory, addr as u32, count as u32);
}
Expand Down
4 changes: 2 additions & 2 deletions emulator/cpus/m68k/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use femtos::Frequency;
use core::fmt::{self, Write};
use emulator_hal::time;
use emulator_hal::Instant as BusInstant;

use crate::{M68kDebugger, M68kCycle};
use crate::instructions::Target;
Expand Down Expand Up @@ -243,7 +243,7 @@ impl M68kState {

impl<Instant> M68k<Instant>
where
Instant: time::Instant,
Instant: BusInstant,
{
pub fn new(info: CpuInfo) -> Self {
M68k {
Expand Down
2 changes: 1 addition & 1 deletion emulator/cpus/m68k/tests/decode_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use femtos::{Instant, Frequency};
use emulator_hal::bus::BusAccess;
use emulator_hal::BusAccess;
use emulator_hal_memory::MemoryBlock;

use moa_m68k::{M68k, M68kType, M68kAddress};
Expand Down
3 changes: 1 addition & 2 deletions emulator/cpus/m68k/tests/execute_tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use femtos::{Instant, Frequency};
use emulator_hal::bus::BusAccess;
use emulator_hal::step::Step;
use emulator_hal::{BusAccess, Step};
use emulator_hal_memory::MemoryBlock;

use moa_m68k::{M68k, M68kType, M68kAddress};
Expand Down
2 changes: 1 addition & 1 deletion emulator/cpus/m68k/tests/musashi_timing_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use femtos::{Instant, Frequency};
use emulator_hal::bus::BusAccess;
use emulator_hal::BusAccess;
use emulator_hal_memory::MemoryBlock;

use moa_m68k::{M68k, M68kType, M68kAddress};
Expand Down
2 changes: 1 addition & 1 deletion emulator/cpus/m68k/tests/timing_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use femtos::{Instant, Frequency};
use emulator_hal::bus::BusAccess;
use emulator_hal::BusAccess;
use emulator_hal_memory::MemoryBlock;

use moa_m68k::{M68k, M68kType, M68kAddress};
Expand Down
4 changes: 3 additions & 1 deletion emulator/cpus/z80/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
log = "0.4"
thiserror = "1.0"
femtos = "0.1"
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal", features = ["femtos"] }

# TODO the goal is to make these optional, or remove them entirely
moa-core = { path = "../../core" }
moa-signals = { path = "../../libraries/signals" }
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal" }
55 changes: 8 additions & 47 deletions emulator/cpus/z80/src/debugger.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,20 @@
use moa_core::{System, Error, Address, Debuggable};

use crate::state::{Z80, Z80Error};
use crate::decode::Z80Decoder;
use crate::instructions::Register;

use crate::state::{Z80Error, Z80Address};

#[derive(Clone, Default)]
pub struct Z80Debugger {
pub(crate) skip_breakpoint: usize,
pub(crate) breakpoints: Vec<u16>,
}

impl Debuggable for Z80 {
fn add_breakpoint(&mut self, addr: Address) {
self.debugger.breakpoints.push(addr as u16);
}

fn remove_breakpoint(&mut self, addr: Address) {
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == addr as u16) {
self.debugger.breakpoints.remove(index);
}
}

fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
self.decoder.decode_at(&mut self.port, system.clock, self.state.pc)?;
self.decoder.dump_decoded(&mut self.port);
self.dump_state(system.clock);
Ok(())
}

fn print_disassembly(&mut self, _system: &System, addr: Address, count: usize) {
let mut decoder = Z80Decoder::default();
decoder.dump_disassembly(&mut self.port, addr as u16, count as u16);
}

fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
match args[0] {
"l" => self.state.reg[Register::L as usize] = 0x05,
_ => {
return Ok(true);
},
}
Ok(false)
}
}

impl Z80 {
pub fn check_breakpoints(&mut self) -> Result<(), Z80Error> {
for breakpoint in &self.debugger.breakpoints {
if *breakpoint == self.state.pc {
if self.debugger.skip_breakpoint > 0 {
self.debugger.skip_breakpoint -= 1;
impl Z80Debugger {
pub fn check_breakpoints(&mut self, pc: Z80Address) -> Result<(), Z80Error> {
for breakpoint in &self.breakpoints {
if *breakpoint == pc {
if self.skip_breakpoint > 0 {
self.skip_breakpoint -= 1;
return Ok(());
} else {
self.debugger.skip_breakpoint = 1;
self.skip_breakpoint = 1;
return Err(Z80Error::Breakpoint);
}
}
Expand Down
Loading

0 comments on commit 40266aa

Please sign in to comment.