Skip to content

Commit 342bb8a

Browse files
Converted Z80 to use emulator-hal traits (#7)
* Converted Z80 to use emulator-hal traits * Updated emulator-hal * Added a hacky Signalable trait to replace the Z80 signals * Minor fixes * Fixed timing tests and added no io tests option * Fixed genesis Z80 bus issue * Fixed addressing for BusAccess impl of Z80 * Fixed tests and clippy lints
1 parent 6e7e315 commit 342bb8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1017
-556
lines changed

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ For more about the Sega Genesis support, check out this series I wrote about imp
2121
I've also generated rustdocs of the workspace. All the various crates within moa
2222
are listed in the crates section in the sidebar on the left. There's not a lot
2323
of doc comments in the code yet but I plan to eventually write more:
24-
[rustdocs for moa_core](http://jabberwocky.ca/moa/doc/moa_core/)
25-
[rustdocs for ym2612](http://jabberwocky.ca/moa/doc/moa_peripherals_yamaha/ym2612/index.html)
24+
[moa_core](http://jabberwocky.ca/moa/doc/moa_core/)
25+
[moa_m68k](http://jabberwocky.ca/moa/doc/moa_m68k/)
26+
[moa_z80](http://jabberwocky.ca/moa/doc/moa_z80/)
27+
[ym2612](http://jabberwocky.ca/moa/doc/moa_peripherals_yamaha/ym2612/index.html)
2628

2729
This repository uses submodules, so make sure to clone with
2830
```sh

emulator/core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ log = "0.4"
88
femtos = "0.1"
99
thiserror = "1.0"
1010
moa-host = { path = "../libraries/host" }
11-
emulator-hal = { path = "../libraries/emulator-hal/emulator-hal" }
11+
emulator-hal = { path = "../libraries/emulator-hal/emulator-hal", features = ["femtos"] }

emulator/core/src/devices.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ pub trait Inspectable {
171171
fn inspect(&mut self, system: &System, args: &[&str]) -> Result<(), Error>;
172172
}
173173

174+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
175+
pub enum Signal {
176+
Reset,
177+
BusRequest,
178+
}
179+
180+
pub trait Signalable {
181+
fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error>;
182+
fn signal(&mut self, signal: Signal) -> Option<bool>;
183+
}
174184

175185
pub trait Transmutable {
176186
#[inline]
@@ -197,6 +207,11 @@ pub trait Transmutable {
197207
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
198208
None
199209
}
210+
211+
#[inline]
212+
fn as_signalable(&mut self) -> Option<&mut dyn Signalable> {
213+
None
214+
}
200215
}
201216

202217
pub type TransmutableBox = Rc<RefCell<Box<dyn Transmutable>>>;

emulator/core/src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,9 @@ impl<E> From<HostError<E>> for Error {
7171
Self::Other("other".to_string())
7272
}
7373
}
74+
75+
impl From<fmt::Error> for Error {
76+
fn from(err: fmt::Error) -> Self {
77+
Self::Other(format!("{:?}", err))
78+
}
79+
}

emulator/core/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ mod memory;
77
mod system;
88

99
pub use crate::devices::{
10-
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Device,
10+
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Signalable, Signal, Transmutable, TransmutableBox,
11+
Device,
1112
};
1213
pub use crate::devices::{
1314
read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable,
@@ -17,4 +18,4 @@ pub use crate::interrupts::InterruptController;
1718
pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory};
1819
pub use crate::system::System;
1920

20-
pub use emulator_hal::bus::{BusAccess};
21+
pub use emulator_hal::BusAccess;

emulator/core/src/memory.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::rc::Rc;
44
use std::cell::RefCell;
55
use std::fmt::Write;
66
use femtos::Instant;
7+
use emulator_hal::{self, BusAccess, ErrorType};
78

89
use crate::error::Error;
910
use crate::devices::{Address, Addressable, Transmutable, Device, read_beu16};
@@ -236,7 +237,7 @@ impl Bus {
236237

237238
let to = if count < 16 { count / 2 } else { 8 };
238239
for _ in 0..to {
239-
let word = self.read_beu16(clock, addr);
240+
let word = Addressable::read_beu16(self, clock, addr);
240241
if word.is_err() {
241242
println!("{}", line);
242243
return;
@@ -353,7 +354,7 @@ impl Addressable for BusPort {
353354
for i in (0..data.len()).step_by(self.data_width as usize) {
354355
let addr_index = (addr + i as Address) & self.address_mask;
355356
let end = cmp::min(i + self.data_width as usize, data.len());
356-
subdevice.read(clock, addr_index, &mut data[i..end])?;
357+
Addressable::read(&mut *subdevice, clock, addr_index, &mut data[i..end])?;
357358
}
358359
Ok(())
359360
}
@@ -364,7 +365,7 @@ impl Addressable for BusPort {
364365
for i in (0..data.len()).step_by(self.data_width as usize) {
365366
let addr_index = (addr + i as Address) & self.address_mask;
366367
let end = cmp::min(i + self.data_width as usize, data.len());
367-
subdevice.write(clock, addr_index, &data[i..end])?;
368+
Addressable::write(&mut *subdevice, clock, addr_index, &data[i..end])?;
368369
}
369370
Ok(())
370371
}
@@ -412,9 +413,7 @@ where
412413
}
413414
}
414415

415-
use emulator_hal::bus::{self, BusAccess};
416-
417-
impl bus::Error for Error {}
416+
impl ErrorType for Error {}
418417

419418
impl BusAccess<u64> for &mut dyn Addressable {
420419
type Instant = Instant;
@@ -430,3 +429,18 @@ impl BusAccess<u64> for &mut dyn Addressable {
430429
Ok(data.len())
431430
}
432431
}
432+
433+
impl BusAccess<u64> for Bus {
434+
type Instant = Instant;
435+
type Error = Error;
436+
437+
fn read(&mut self, now: Instant, addr: Address, data: &mut [u8]) -> Result<usize, Self::Error> {
438+
Addressable::read(self, now, addr, data)?;
439+
Ok(data.len())
440+
}
441+
442+
fn write(&mut self, now: Instant, addr: Address, data: &[u8]) -> Result<usize, Self::Error> {
443+
Addressable::write(self, now, addr, data)?;
444+
Ok(data.len())
445+
}
446+
}

emulator/cpus/m68k/src/debugger.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
use core::fmt;
44

5-
use emulator_hal::time;
6-
use emulator_hal::bus::{self, BusAccess};
7-
use emulator_hal::step::{Inspect, Debug};
5+
use emulator_hal::{Instant as BusInstant, ErrorType, BusAccess, Inspect, Debug};
86

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

@@ -31,7 +29,7 @@ pub enum M68kInfo {
3129
impl<Bus, BusError, Instant, Writer> Inspect<M68kAddress, Bus, Writer> for M68k<Instant>
3230
where
3331
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
34-
BusError: bus::Error,
32+
BusError: ErrorType,
3533
Writer: fmt::Write,
3634
{
3735
type InfoType = M68kInfo;
@@ -60,8 +58,8 @@ where
6058
impl<Bus, BusError, Instant, Writer> Debug<M68kAddress, Bus, Writer> for M68k<Instant>
6159
where
6260
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
63-
BusError: bus::Error,
64-
Instant: time::Instant,
61+
BusError: ErrorType,
62+
Instant: BusInstant,
6563
Writer: fmt::Write,
6664
{
6765
// TODO this should be a new type

emulator/cpus/m68k/src/decode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Instruction Decoding
22

33
use core::marker::PhantomData;
4-
use emulator_hal::bus::BusAccess;
4+
use emulator_hal::BusAccess;
55

66
use crate::{M68kType, M68kError, M68kBusPort, M68kAddress, Exceptions};
77
use crate::instructions::{

emulator/cpus/m68k/src/execute.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Instruction Execution
22

3-
use emulator_hal::time;
4-
use emulator_hal::step::Step;
5-
use emulator_hal::bus::{self, BusAccess};
3+
use emulator_hal::{Instant as BusInstant, ErrorType, BusAccess, Step};
64

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

3634
impl<Instant> M68kCycle<Instant>
3735
where
38-
Instant: time::Instant,
36+
Instant: BusInstant,
3937
{
4038
#[inline]
4139
pub fn default(cputype: M68kType, data_width: u8) -> Self {
@@ -77,8 +75,8 @@ where
7775
impl<Bus, BusError, Instant> Step<M68kAddress, Bus> for M68k<Instant>
7876
where
7977
Bus: BusAccess<M68kAddress, Instant = Instant, Error = BusError>,
80-
BusError: bus::Error,
81-
Instant: time::Instant,
78+
BusError: ErrorType,
79+
Instant: BusInstant,
8280
{
8381
type Error = M68kError<BusError>;
8482

emulator/cpus/m68k/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ pub use crate::memory::{M68kAddress, M68kAddressSpace, M68kBusPort};
1818
pub use crate::decode::{M68kDecoder, InstructionDecoding};
1919
pub use crate::execute::{M68kCycle, M68kCycleExecutor};
2020
pub use crate::timing::M68kInstructionTiming;
21-
//pub use crate::instructions::{Instruction, Target, Size, Sign, XRegister, BaseRegister, IndexRegister, Direction};
21+
pub use crate::instructions::*;

emulator/cpus/m68k/src/memory.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use core::cmp;
22
use core::fmt::Write;
3-
use emulator_hal::time;
4-
use emulator_hal::bus::BusAccess;
3+
use emulator_hal::{Instant as BusInstant, BusAccess};
54

65
use crate::{M68kError, CpuInfo};
76
use crate::state::Exceptions;
@@ -65,7 +64,7 @@ impl FunctionCode {
6564

6665
impl<Instant> Default for MemoryRequest<Instant>
6766
where
68-
Instant: time::Instant,
67+
Instant: BusInstant,
6968
{
7069
fn default() -> Self {
7170
Self {
@@ -138,7 +137,7 @@ pub struct M68kBusPort<Instant> {
138137

139138
impl<Instant> Default for M68kBusPort<Instant>
140139
where
141-
Instant: time::Instant,
140+
Instant: BusInstant,
142141
{
143142
fn default() -> Self {
144143
Self {

emulator/cpus/m68k/src/moa.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use femtos::{Instant, Duration};
2-
use emulator_hal::bus;
2+
use emulator_hal::{ErrorType, BusAdapter};
33

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

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

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

1615
let mut executor = cycle.begin(self, &mut adapter);
1716
executor.check_breakpoints()?;
@@ -60,7 +59,7 @@ impl<BusError> From<Error> for M68kError<BusError> {
6059
}
6160
}
6261

63-
impl<BusError: bus::Error> From<M68kError<BusError>> for Error {
62+
impl<BusError: ErrorType> From<M68kError<BusError>> for Error {
6463
fn from(err: M68kError<BusError>) -> Self {
6564
match err {
6665
M68kError::Halted => Self::Other("cpu halted".to_string()),
@@ -86,11 +85,17 @@ impl Debuggable for M68k<Instant> {
8685
}
8786
}
8887

89-
fn print_current_step(&mut self, _system: &System) -> Result<(), Error> {
88+
fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
89+
let mut bus = system.bus.borrow_mut();
90+
let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> = BusAdapter::new(&mut *bus, |addr| addr as u64);
91+
9092
// TODO this is called by the debugger, but should be called some other way
91-
//let _ = self.decoder.decode_at(&mut self.bus, true, self.state.pc);
92-
//self.decoder.dump_decoded(&mut self.bus);
93-
//self.dump_state();
93+
let mut decoder = M68kDecoder::new(self.info.chip, true, self.state.pc);
94+
decoder.decode_at(&mut adapter, &mut M68kBusPort::default(), true, self.state.pc)?;
95+
decoder.dump_decoded(system.clock, &mut adapter);
96+
let mut writer = String::new();
97+
self.dump_state(&mut writer)?;
98+
println!("{}", writer);
9499
Ok(())
95100
}
96101

@@ -99,8 +104,7 @@ impl Debuggable for M68k<Instant> {
99104
let mut memory = M68kBusPort::from_info(&self.info, system.clock);
100105

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

105109
decoder.dump_disassembly(&mut adapter, &mut memory, addr as u32, count as u32);
106110
}

emulator/cpus/m68k/src/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use femtos::Frequency;
44
use core::fmt::{self, Write};
5-
use emulator_hal::time;
5+
use emulator_hal::Instant as BusInstant;
66

77
use crate::{M68kDebugger, M68kCycle};
88
use crate::instructions::Target;
@@ -243,7 +243,7 @@ impl M68kState {
243243

244244
impl<Instant> M68k<Instant>
245245
where
246-
Instant: time::Instant,
246+
Instant: BusInstant,
247247
{
248248
pub fn new(info: CpuInfo) -> Self {
249249
M68k {

emulator/cpus/m68k/src/tests.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(test)]
22
mod decode_unit_tests {
33
use femtos::Instant;
4-
use emulator_hal::bus::BusAccess;
4+
use emulator_hal::BusAccess;
55
use emulator_hal_memory::MemoryBlock;
66

77
use crate::M68kType;
@@ -13,7 +13,7 @@ mod decode_unit_tests {
1313

1414
fn run_decode_test<F>(cputype: M68kType, mut test_func: F)
1515
where
16-
F: FnMut(&mut InstructionDecoding<'_, MemoryBlock<u32, Instant>, Instant>),
16+
F: FnMut(&mut InstructionDecoding<'_, MemoryBlock<Instant>, Instant>),
1717
{
1818
let mut memory = MemoryBlock::from(vec![0; 0x0000100]);
1919
let mut decoder = M68kDecoder::new(cputype, true, 0);
@@ -316,8 +316,7 @@ mod decode_unit_tests {
316316
#[cfg(test)]
317317
mod execute_unit_tests {
318318
use femtos::{Instant, Frequency};
319-
use emulator_hal::bus::BusAccess;
320-
use emulator_hal::step::Step;
319+
use emulator_hal::{Step, BusAccess};
321320
use emulator_hal_memory::MemoryBlock;
322321

323322
use crate::{M68k, M68kType};
@@ -330,7 +329,7 @@ mod execute_unit_tests {
330329
#[allow(clippy::uninit_vec)]
331330
fn run_execute_test<F>(cputype: M68kType, mut test_func: F)
332331
where
333-
F: FnMut(M68kCycleExecutor<&mut MemoryBlock<u32, Instant>, Instant>),
332+
F: FnMut(M68kCycleExecutor<&mut MemoryBlock<Instant>, Instant>),
334333
{
335334
// Insert basic initialization
336335
let len = 0x10_0000;

emulator/cpus/m68k/tests/decode_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use femtos::{Instant, Frequency};
2-
use emulator_hal::bus::BusAccess;
2+
use emulator_hal::BusAccess;
33
use emulator_hal_memory::MemoryBlock;
44

55
use moa_m68k::{M68k, M68kType, M68kAddress};
@@ -64,7 +64,7 @@ const DECODE_TESTS: &'static [TestCase] = &[
6464
];
6565

6666

67-
fn init_decode_test(cputype: M68kType) -> (M68k<Instant>, M68kCycle<Instant>, MemoryBlock<u32, Instant>) {
67+
fn init_decode_test(cputype: M68kType) -> (M68k<Instant>, M68kCycle<Instant>, MemoryBlock<Instant>) {
6868
// Insert basic initialization
6969
let len = 0x2000;
7070
let mut data = Vec::with_capacity(len);

0 commit comments

Comments
 (0)