Compare commits
4 Commits
63c9172d1b
...
4bc1794d0f
Author | SHA1 | Date |
---|---|---|
transistor fet | 4bc1794d0f | |
transistor | 471695aff5 | |
transistor | 1c5ad3999a | |
transistor | 59199533eb |
|
@ -1247,9 +1247,10 @@ name = "rad-tests"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.2.25",
|
"clap 3.2.25",
|
||||||
|
"emulator-hal",
|
||||||
|
"emulator-hal-memory",
|
||||||
"femtos",
|
"femtos",
|
||||||
"flate2",
|
"flate2",
|
||||||
"moa-core",
|
|
||||||
"moa-z80",
|
"moa-z80",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
|
|
@ -171,6 +171,16 @@ pub trait Inspectable {
|
||||||
fn inspect(&mut self, system: &System, args: &[&str]) -> Result<(), Error>;
|
fn inspect(&mut self, system: &System, args: &[&str]) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum Signal {
|
||||||
|
Reset,
|
||||||
|
BusRequest,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Signalable {
|
||||||
|
fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error>;
|
||||||
|
fn signal(&mut self, signal: Signal) -> Option<bool>;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Transmutable {
|
pub trait Transmutable {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -197,6 +207,11 @@ pub trait Transmutable {
|
||||||
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
fn as_inspectable(&mut self) -> Option<&mut dyn Inspectable> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_signalable(&mut self) -> Option<&mut dyn Signalable> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TransmutableBox = Rc<RefCell<Box<dyn Transmutable>>>;
|
pub type TransmutableBox = Rc<RefCell<Box<dyn Transmutable>>>;
|
||||||
|
|
|
@ -71,3 +71,9 @@ impl<E> From<HostError<E>> for Error {
|
||||||
Self::Other("other".to_string())
|
Self::Other("other".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<fmt::Error> for Error {
|
||||||
|
fn from(err: fmt::Error) -> Self {
|
||||||
|
Self::Other(format!("{:?}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ mod memory;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
pub use crate::devices::{
|
pub use crate::devices::{
|
||||||
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Device,
|
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Signalable, Signal, Transmutable, TransmutableBox,
|
||||||
|
Device,
|
||||||
};
|
};
|
||||||
pub use crate::devices::{
|
pub use crate::devices::{
|
||||||
read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable,
|
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;
|
||||||
pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory};
|
pub use crate::memory::{MemoryBlock, AddressTranslator, AddressRepeater, Bus, BusPort, dump_slice, dump_memory};
|
||||||
pub use crate::system::System;
|
pub use crate::system::System;
|
||||||
|
|
||||||
pub use emulator_hal::bus::{BusAccess};
|
pub use emulator_hal::BusAccess;
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use femtos::Instant;
|
use femtos::Instant;
|
||||||
|
use emulator_hal::{self, BusAccess, Error as EmuError};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::devices::{Address, Addressable, Transmutable, Device, read_beu16};
|
use crate::devices::{Address, Addressable, Transmutable, Device, read_beu16};
|
||||||
|
@ -236,7 +237,7 @@ impl Bus {
|
||||||
|
|
||||||
let to = if count < 16 { count / 2 } else { 8 };
|
let to = if count < 16 { count / 2 } else { 8 };
|
||||||
for _ in 0..to {
|
for _ in 0..to {
|
||||||
let word = self.read_beu16(clock, addr);
|
let word = Addressable::read_beu16(self, clock, addr);
|
||||||
if word.is_err() {
|
if word.is_err() {
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
return;
|
return;
|
||||||
|
@ -353,7 +354,7 @@ impl Addressable for BusPort {
|
||||||
for i in (0..data.len()).step_by(self.data_width as usize) {
|
for i in (0..data.len()).step_by(self.data_width as usize) {
|
||||||
let addr_index = (addr + i as Address) & self.address_mask;
|
let addr_index = (addr + i as Address) & self.address_mask;
|
||||||
let end = cmp::min(i + self.data_width as usize, data.len());
|
let end = cmp::min(i + self.data_width as usize, data.len());
|
||||||
subdevice.read(clock, addr_index, &mut data[i..end])?;
|
Addressable::read(&mut *subdevice, clock, addr_index, &mut data[i..end])?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -364,7 +365,7 @@ impl Addressable for BusPort {
|
||||||
for i in (0..data.len()).step_by(self.data_width as usize) {
|
for i in (0..data.len()).step_by(self.data_width as usize) {
|
||||||
let addr_index = (addr + i as Address) & self.address_mask;
|
let addr_index = (addr + i as Address) & self.address_mask;
|
||||||
let end = cmp::min(i + self.data_width as usize, data.len());
|
let end = cmp::min(i + self.data_width as usize, data.len());
|
||||||
subdevice.write(clock, addr_index, &data[i..end])?;
|
Addressable::write(&mut *subdevice, clock, addr_index, &data[i..end])?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -412,9 +413,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use emulator_hal::bus::{self, BusAccess};
|
impl EmuError for Error {}
|
||||||
|
|
||||||
impl bus::Error for Error {}
|
|
||||||
|
|
||||||
impl BusAccess<u64> for &mut dyn Addressable {
|
impl BusAccess<u64> for &mut dyn Addressable {
|
||||||
type Instant = Instant;
|
type Instant = Instant;
|
||||||
|
@ -430,3 +429,18 @@ impl BusAccess<u64> for &mut dyn Addressable {
|
||||||
Ok(data.len())
|
Ok(data.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BusAccess<u64> for Bus {
|
||||||
|
type Instant = Instant;
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn read(&mut self, now: Instant, addr: Address, data: &mut [u8]) -> Result<usize, Self::Error> {
|
||||||
|
Addressable::read(self, now, addr, data)?;
|
||||||
|
Ok(data.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, now: Instant, addr: Address, data: &[u8]) -> Result<usize, Self::Error> {
|
||||||
|
Addressable::write(self, now, addr, data)?;
|
||||||
|
Ok(data.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,11 +86,18 @@ impl Debuggable for M68k<Instant> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_current_step(&mut self, _system: &System) -> Result<(), Error> {
|
fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
|
||||||
|
let mut bus = system.bus.borrow_mut();
|
||||||
|
let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> =
|
||||||
|
BusAdapter::new(&mut *bus, |addr| addr as u64, |err| err);
|
||||||
|
|
||||||
// TODO this is called by the debugger, but should be called some other way
|
// TODO this is called by the debugger, but should be called some other way
|
||||||
//let _ = self.decoder.decode_at(&mut self.bus, true, self.state.pc);
|
let mut decoder = M68kDecoder::new(self.info.chip, true, self.state.pc);
|
||||||
//self.decoder.dump_decoded(&mut self.bus);
|
decoder.decode_at(&mut adapter, &mut M68kBusPort::default(), true, self.state.pc)?;
|
||||||
//self.dump_state();
|
decoder.dump_decoded(system.clock, &mut adapter);
|
||||||
|
let mut writer = String::new();
|
||||||
|
self.dump_state(&mut writer)?;
|
||||||
|
println!("{}", writer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use emulator_hal::{BusAccess, Instant as EmuInstant};
|
use emulator_hal::{BusAccess, Instant as EmuInstant};
|
||||||
|
|
||||||
use crate::state::{Z80Error, Z80Address} ;
|
use crate::state::{Z80Error, Z80Address};
|
||||||
use crate::instructions::{
|
use crate::instructions::{
|
||||||
Direction, Condition, Register, RegisterPair, IndexRegister, IndexRegisterHalf, SpecialRegister, InterruptMode, Target,
|
Direction, Condition, Register, RegisterPair, IndexRegister, IndexRegisterHalf, SpecialRegister, InterruptMode, Target,
|
||||||
LoadTarget, UndocumentedCopy, Instruction,
|
LoadTarget, UndocumentedCopy, Instruction,
|
||||||
|
@ -55,27 +55,16 @@ impl Z80Decoder {
|
||||||
Ok(decoder.decoder)
|
Ok(decoder.decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pub fn dump_disassembly<Bus>(bus: &mut Bus, start: Z80Address, length: Z80Address)
|
||||||
pub fn format_instruction_bytes(&mut self) -> String {
|
where
|
||||||
let mut ins_data = String::new();
|
Bus: BusAccess<Z80Address>,
|
||||||
for offset in 0..self.decoder.end.saturating_sub(self.decoder.start) {
|
{
|
||||||
write!(ins_data, "{:02x} ", self.bus.read_u8(self.clock, self.decoder.start + offset).unwrap()).unwrap()
|
|
||||||
}
|
|
||||||
ins_data
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dump_decoded(&mut self) {
|
|
||||||
let ins_data = self.format_instruction_bytes();
|
|
||||||
println!("{:#06x}: {}\n\t{:?}\n", self.decoder.start, ins_data, self.decoder.instruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dump_disassembly(&mut self, start: Z80Address, length: Z80Address) {
|
|
||||||
let mut next = start;
|
let mut next = start;
|
||||||
while next < (start + length) {
|
while next < (start + length) {
|
||||||
match self.decode_at(self.clock, next) {
|
match Z80Decoder::decode_at(bus, Bus::Instant::START, next) {
|
||||||
Ok(()) => {
|
Ok(mut decoder) => {
|
||||||
self.dump_decoded();
|
decoder.dump_decoded(bus);
|
||||||
next = self.decoder.end;
|
next = decoder.end;
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("{:?}", err);
|
println!("{:?}", err);
|
||||||
|
@ -84,7 +73,25 @@ impl Z80Decoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
pub fn dump_decoded<Bus>(&mut self, bus: &mut Bus)
|
||||||
|
where
|
||||||
|
Bus: BusAccess<Z80Address>,
|
||||||
|
{
|
||||||
|
let ins_data = self.format_instruction_bytes(bus);
|
||||||
|
println!("{:#06x}: {}\n\t{:?}\n", self.start, ins_data, self.instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_instruction_bytes<Bus>(&mut self, bus: &mut Bus) -> String
|
||||||
|
where
|
||||||
|
Bus: BusAccess<Z80Address>,
|
||||||
|
{
|
||||||
|
let mut ins_data = String::new();
|
||||||
|
for offset in 0..self.end.saturating_sub(self.start) {
|
||||||
|
write!(ins_data, "{:02x} ", bus.read_u8(Bus::Instant::START, self.start + offset).unwrap()).unwrap()
|
||||||
|
}
|
||||||
|
ins_data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DecodeNext<'a, Bus, Instant>
|
pub struct DecodeNext<'a, Bus, Instant>
|
||||||
|
@ -107,11 +114,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_bare(
|
pub fn decode_bare(&mut self, ins: u8, extra_instruction_bytes: u16) -> Result<Instruction, Z80Error> {
|
||||||
&mut self,
|
|
||||||
ins: u8,
|
|
||||||
extra_instruction_bytes: u16,
|
|
||||||
) -> Result<Instruction, Z80Error> {
|
|
||||||
self.decoder.extra_instruction_bytes = extra_instruction_bytes;
|
self.decoder.extra_instruction_bytes = extra_instruction_bytes;
|
||||||
match get_ins_x(ins) {
|
match get_ins_x(ins) {
|
||||||
0 => match get_ins_z(ins) {
|
0 => match get_ins_z(ins) {
|
||||||
|
@ -559,11 +562,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_index_target(
|
fn decode_index_target(&mut self, index_reg: IndexRegister, z: u8) -> Result<Option<Target>, Z80Error> {
|
||||||
&mut self,
|
|
||||||
index_reg: IndexRegister,
|
|
||||||
z: u8,
|
|
||||||
) -> Result<Option<Target>, Z80Error> {
|
|
||||||
let result = match z {
|
let result = match z {
|
||||||
4 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 0))),
|
4 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 0))),
|
||||||
5 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 1))),
|
5 => Some(Target::DirectRegHalf(get_index_register_half(index_reg, 1))),
|
||||||
|
@ -578,7 +577,9 @@ where
|
||||||
|
|
||||||
|
|
||||||
fn read_instruction_byte(&mut self) -> Result<u8, Z80Error> {
|
fn read_instruction_byte(&mut self) -> Result<u8, Z80Error> {
|
||||||
let byte = self.bus.read_u8(self.clock, self.decoder.end)
|
let byte = self
|
||||||
|
.bus
|
||||||
|
.read_u8(self.clock, self.decoder.end)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
||||||
self.decoder.end = self.decoder.end.wrapping_add(1);
|
self.decoder.end = self.decoder.end.wrapping_add(1);
|
||||||
Ok(byte)
|
Ok(byte)
|
||||||
|
@ -587,7 +588,9 @@ where
|
||||||
fn read_instruction_word(&mut self) -> Result<u16, Z80Error> {
|
fn read_instruction_word(&mut self) -> Result<u16, Z80Error> {
|
||||||
let mut bytes = [0; 2];
|
let mut bytes = [0; 2];
|
||||||
for byte in bytes.iter_mut() {
|
for byte in bytes.iter_mut() {
|
||||||
*byte = self.bus.read_u8(self.clock, self.decoder.end & 0xFFFF)
|
*byte = self
|
||||||
|
.bus
|
||||||
|
.read_u8(self.clock, self.decoder.end & 0xFFFF)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
||||||
self.decoder.end = self.decoder.end.wrapping_add(1);
|
self.decoder.end = self.decoder.end.wrapping_add(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
use emulator_hal::{BusAccess, Instant as EmuInstant, Error as EmuError, Step, Inspect, Debug, IntoAddress};
|
use emulator_hal::{BusAccess, Instant as EmuInstant, Error as EmuError, Step, Inspect, Debug, IntoAddress};
|
||||||
use crate::state::{Z80, Z80Error, Z80Address, Status};
|
use crate::state::{Z80, Z80Error, Z80Address, Status};
|
||||||
|
|
||||||
|
@ -23,10 +22,9 @@ where
|
||||||
|
|
||||||
fn step(&mut self, now: Self::Instant, bus: &mut Bus) -> Result<Self::Instant, Self::Error> {
|
fn step(&mut self, now: Self::Instant, bus: &mut Bus) -> Result<Self::Instant, Self::Error> {
|
||||||
let mut executor = self.begin(now, bus)?;
|
let mut executor = self.begin(now, bus)?;
|
||||||
executor.step_one()?;
|
let clocks = executor.step_one()?;
|
||||||
self.previous_cycle = executor.end();
|
self.previous_cycle = executor.end();
|
||||||
// TODO fix this
|
Ok(now + Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32)
|
||||||
Ok(now)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +49,9 @@ where
|
||||||
|
|
||||||
fn step(&mut self, now: Self::Instant, bus: (&mut MemBus, &mut IoBus)) -> Result<Self::Instant, Self::Error> {
|
fn step(&mut self, now: Self::Instant, bus: (&mut MemBus, &mut IoBus)) -> Result<Self::Instant, Self::Error> {
|
||||||
let executor = self.begin(now, bus)?;
|
let executor = self.begin(now, bus)?;
|
||||||
executor.step_one()?;
|
let clocks = executor.step_one()?;
|
||||||
self.previous_cycle = executor.end();
|
self.previous_cycle = executor.end();
|
||||||
// TODO fix this
|
Ok(now + Instant::hertz_to_duration(self.frequency.as_hz() as u64) * clocks as u32)
|
||||||
Ok(now)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::instructions::{
|
||||||
Condition, Instruction, LoadTarget, Target, Register, InterruptMode, RegisterPair, IndexRegister, SpecialRegister,
|
Condition, Instruction, LoadTarget, Target, Register, InterruptMode, RegisterPair, IndexRegister, SpecialRegister,
|
||||||
IndexRegisterHalf, Size, Direction, UndocumentedCopy,
|
IndexRegisterHalf, Size, Direction, UndocumentedCopy,
|
||||||
};
|
};
|
||||||
use crate::state::{Z80, Z80Error, Z80State, Z80Address, Status, Flags};
|
use crate::state::{Z80, Z80Error, Z80State, Z80Signals, Z80Address, Status, Flags};
|
||||||
use crate::timing::Z80InstructionCycles;
|
use crate::timing::Z80InstructionCycles;
|
||||||
use crate::debugger::Z80Debugger;
|
use crate::debugger::Z80Debugger;
|
||||||
|
|
||||||
|
@ -41,12 +41,17 @@ impl<Instant> Z80<Instant>
|
||||||
where
|
where
|
||||||
Instant: EmuInstant,
|
Instant: EmuInstant,
|
||||||
{
|
{
|
||||||
pub(crate) fn begin<'a, Bus>(&'a mut self, clock: Instant, bus: &'a mut Bus) -> Result<ExecuteNext<'a, &mut Bus, Instant>, Z80Error>
|
pub(crate) fn begin<'a, Bus>(
|
||||||
|
&'a mut self,
|
||||||
|
clock: Instant,
|
||||||
|
bus: &'a mut Bus,
|
||||||
|
) -> Result<ExecuteNext<'a, &'a mut Bus, Instant>, Z80Error>
|
||||||
where
|
where
|
||||||
Bus: BusAccess<Z80Address, Instant = Instant>,
|
Bus: BusAccess<Z80Address, Instant = Instant>,
|
||||||
{
|
{
|
||||||
let executor = ExecuteNext {
|
let executor = ExecuteNext {
|
||||||
state: &mut self.state,
|
state: &mut self.state,
|
||||||
|
signals: &mut self.signals,
|
||||||
debugger: &mut self.debugger,
|
debugger: &mut self.debugger,
|
||||||
cycle: Z80Cycle::at_time(clock),
|
cycle: Z80Cycle::at_time(clock),
|
||||||
bus,
|
bus,
|
||||||
|
@ -61,6 +66,7 @@ where
|
||||||
Bus: BusAccess<Z80Address, Instant = Instant>,
|
Bus: BusAccess<Z80Address, Instant = Instant>,
|
||||||
{
|
{
|
||||||
state: &'a mut Z80State,
|
state: &'a mut Z80State,
|
||||||
|
signals: &'a mut Z80Signals,
|
||||||
debugger: &'a mut Z80Debugger,
|
debugger: &'a mut Z80Debugger,
|
||||||
cycle: Z80Cycle<Instant>,
|
cycle: Z80Cycle<Instant>,
|
||||||
bus: Bus,
|
bus: Bus,
|
||||||
|
@ -71,28 +77,22 @@ where
|
||||||
Bus: BusAccess<Z80Address, Instant = Instant>,
|
Bus: BusAccess<Z80Address, Instant = Instant>,
|
||||||
Instant: EmuInstant,
|
Instant: EmuInstant,
|
||||||
{
|
{
|
||||||
pub(crate) fn end(mut self) -> Z80Cycle<Instant> {
|
pub(crate) fn end(self) -> Z80Cycle<Instant> {
|
||||||
self.cycle
|
self.cycle
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn step_one(&mut self) -> Result<u16, Z80Error> {
|
pub(crate) fn step_one(&mut self) -> Result<u16, Z80Error> {
|
||||||
// TODO restore the reset and bus request signals
|
let clocks = if self.signals.reset {
|
||||||
//let clocks = if self.reset.get() {
|
self.reset()?
|
||||||
// self.reset()?
|
} else if self.signals.bus_request {
|
||||||
//} else if self.bus_request.get() {
|
4
|
||||||
// 4
|
} else {
|
||||||
//} else {
|
self.step_internal()?
|
||||||
// self.step_internal(self.cycle.current_clock)?
|
};
|
||||||
//};
|
|
||||||
|
|
||||||
//Ok(self.frequency.period_duration() * clocks as u64)
|
|
||||||
|
|
||||||
// TODO remove this when done
|
|
||||||
let clocks = self.step_internal(self.cycle.current_clock)?;
|
|
||||||
Ok(clocks)
|
Ok(clocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step_internal(&mut self, clock: Instant) -> Result<u16, Z80Error> {
|
fn step_internal(&mut self) -> Result<u16, Z80Error> {
|
||||||
match self.state.status {
|
match self.state.status {
|
||||||
Status::Init => self.init(),
|
Status::Init => self.init(),
|
||||||
Status::Halted => Err(Z80Error::Halted),
|
Status::Halted => Err(Z80Error::Halted),
|
||||||
|
@ -630,7 +630,9 @@ where
|
||||||
let parity = if count != 0 { Flags::Parity as u8 } else { 0 };
|
let parity = if count != 0 { Flags::Parity as u8 } else { 0 };
|
||||||
self.set_flags(mask, parity);
|
self.set_flags(mask, parity);
|
||||||
|
|
||||||
if (self.cycle.decoder.instruction == Instruction::LDIR || self.cycle.decoder.instruction == Instruction::LDDR) && count != 0 {
|
if (self.cycle.decoder.instruction == Instruction::LDIR || self.cycle.decoder.instruction == Instruction::LDDR)
|
||||||
|
&& count != 0
|
||||||
|
{
|
||||||
self.cycle.took_branch = true;
|
self.cycle.took_branch = true;
|
||||||
self.state.pc -= 2;
|
self.state.pc -= 2;
|
||||||
}
|
}
|
||||||
|
@ -1126,13 +1128,17 @@ where
|
||||||
|
|
||||||
fn read_port_u8(&mut self, addr: u16) -> Result<u8, Z80Error> {
|
fn read_port_u8(&mut self, addr: u16) -> Result<u8, Z80Error> {
|
||||||
self.increment_refresh(1);
|
self.increment_refresh(1);
|
||||||
Ok(self.bus.read_u8(self.cycle.current_clock, addr as Z80Address)
|
Ok(self
|
||||||
|
.bus
|
||||||
|
.read_u8(self.cycle.current_clock, addr as Z80Address)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?)
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_port_u8(&mut self, addr: u16, value: u8) -> Result<(), Z80Error> {
|
fn write_port_u8(&mut self, addr: u16, value: u8) -> Result<(), Z80Error> {
|
||||||
self.increment_refresh(1);
|
self.increment_refresh(1);
|
||||||
Ok(self.bus.write_u8(self.cycle.current_clock, addr as Z80Address, value)
|
Ok(self
|
||||||
|
.bus
|
||||||
|
.write_u8(self.cycle.current_clock, addr as Z80Address, value)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?)
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,7 +1150,9 @@ where
|
||||||
let mut bytes = [0; 2];
|
let mut bytes = [0; 2];
|
||||||
for byte in bytes.iter_mut() {
|
for byte in bytes.iter_mut() {
|
||||||
self.increment_refresh(1);
|
self.increment_refresh(1);
|
||||||
*byte = self.bus.read_u8(self.cycle.current_clock, addr & 0xFFFF)
|
*byte = self
|
||||||
|
.bus
|
||||||
|
.read_u8(self.cycle.current_clock, addr & 0xFFFF)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
||||||
addr = addr.wrapping_add(1);
|
addr = addr.wrapping_add(1);
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1167,8 @@ where
|
||||||
let mut bytes = value.to_le_bytes();
|
let mut bytes = value.to_le_bytes();
|
||||||
for byte in bytes.iter_mut() {
|
for byte in bytes.iter_mut() {
|
||||||
self.increment_refresh(1);
|
self.increment_refresh(1);
|
||||||
self.bus.write_u8(self.cycle.current_clock, addr & 0xFFFF, *byte)
|
self.bus
|
||||||
|
.write_u8(self.cycle.current_clock, addr & 0xFFFF, *byte)
|
||||||
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
.map_err(|err| Z80Error::BusError(format!("{:?}", err)))?;
|
||||||
addr = addr.wrapping_add(1);
|
addr = addr.wrapping_add(1);
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1181,7 @@ where
|
||||||
//if let Some(io) = self.ioport.as_mut() {
|
//if let Some(io) = self.ioport.as_mut() {
|
||||||
// Ok(io.read_u8(self.cycle.current_clock, addr)?)
|
// Ok(io.read_u8(self.cycle.current_clock, addr)?)
|
||||||
//} else {
|
//} else {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
mod debugger;
|
mod debugger;
|
||||||
mod decode;
|
mod decode;
|
||||||
|
mod emuhal;
|
||||||
mod execute;
|
mod execute;
|
||||||
mod instructions;
|
mod instructions;
|
||||||
|
mod moa;
|
||||||
mod state;
|
mod state;
|
||||||
mod timing;
|
mod timing;
|
||||||
mod moa;
|
|
||||||
mod emuhal;
|
|
||||||
|
|
||||||
pub use crate::state::{Z80, Z80Type, Z80Error, Z80State, Status, Flags};
|
pub use crate::state::{Z80, Z80Type, Z80Error, Z80State, Status, Flags};
|
||||||
pub use crate::decode::Z80Decoder;
|
pub use crate::decode::Z80Decoder;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
use std::any::Any;
|
||||||
use femtos::{Instant, Duration};
|
use femtos::{Instant, Duration};
|
||||||
use emulator_hal::{BusAdapter, Instant as EmuInstant};
|
use emulator_hal::{BusAdapter, Instant as EmuInstant};
|
||||||
|
|
||||||
use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Debuggable, Transmutable};
|
use moa_core::{System, Error, Address, Steppable, Addressable, Interruptable, Signalable, Signal, Debuggable, Transmutable};
|
||||||
|
|
||||||
use crate::{Z80, Z80Error, Z80Decoder};
|
use crate::{Z80, Z80Error, Z80Decoder};
|
||||||
use crate::instructions::Register;
|
use crate::instructions::Register;
|
||||||
|
@ -22,13 +22,32 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_error(&mut self, system: &System) {
|
fn on_error(&mut self, system: &System) {
|
||||||
self.dump_state(system.clock);
|
let bus = &mut *system.bus.borrow_mut();
|
||||||
|
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err)));
|
||||||
|
self.dump_state(system.clock, &mut adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interruptable for Z80<Instant> {}
|
impl Interruptable for Z80<Instant> {}
|
||||||
|
|
||||||
|
|
||||||
|
impl Signalable for Z80<Instant> {
|
||||||
|
fn set_signal(&mut self, signal: Signal, flag: bool) -> Result<(), Error> {
|
||||||
|
match signal {
|
||||||
|
Signal::Reset => self.signals.reset = flag,
|
||||||
|
Signal::BusRequest => self.signals.bus_request = flag,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signal(&mut self, signal: Signal) -> Option<bool> {
|
||||||
|
match signal {
|
||||||
|
Signal::Reset => Some(self.signals.reset),
|
||||||
|
Signal::BusRequest => Some(self.signals.bus_request),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Transmutable for Z80<Instant> {
|
impl Transmutable for Z80<Instant> {
|
||||||
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||||
Some(self)
|
Some(self)
|
||||||
|
@ -41,6 +60,11 @@ impl Transmutable for Z80<Instant> {
|
||||||
fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_signalable(&mut self) -> Option<&mut dyn Signalable> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Z80Error> for Error {
|
impl From<Z80Error> for Error {
|
||||||
|
@ -80,16 +104,16 @@ impl Debuggable for Z80<Instant> {
|
||||||
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err)));
|
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err)));
|
||||||
|
|
||||||
let decoder = Z80Decoder::decode_at(&mut adapter, system.clock, self.state.pc)?;
|
let decoder = Z80Decoder::decode_at(&mut adapter, system.clock, self.state.pc)?;
|
||||||
// TODO disabled until decoder is fixed
|
self.previous_cycle.decoder.dump_decoded(&mut adapter);
|
||||||
//self.decoder.dump_decoded(&mut self.port);
|
self.dump_state(system.clock, &mut adapter);
|
||||||
self.dump_state(system.clock);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_disassembly(&mut self, _system: &System, addr: Address, count: usize) {
|
fn print_disassembly(&mut self, system: &System, addr: Address, count: usize) {
|
||||||
// TODO disabled until decoder is fixed
|
let bus = &mut *system.bus.borrow_mut();
|
||||||
//let mut decoder = Z80Decoder::default();
|
let mut adapter = BusAdapter::new(bus, |addr| addr as u64, |err| Z80Error::BusError(format!("{:?}", err)));
|
||||||
//decoder.dump_disassembly(&mut self.port, addr as u16, count as u16);
|
|
||||||
|
Z80Decoder::dump_disassembly(&mut adapter, addr as u16, count as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
|
fn run_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
|
||||||
|
@ -102,5 +126,3 @@ impl Debuggable for Z80<Instant> {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use femtos::{Instant, Frequency};
|
use femtos::{Instant, Frequency};
|
||||||
use emulator_hal::Instant as EmuInstant;
|
use emulator_hal::{Instant as EmuInstant, BusAccess};
|
||||||
|
|
||||||
use moa_core::{Address, Bus, BusPort};
|
use moa_core::{Address, Bus, BusPort};
|
||||||
use moa_signals::Signal;
|
use moa_signals::Signal;
|
||||||
|
@ -92,6 +92,12 @@ impl Z80State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct Z80Signals {
|
||||||
|
pub reset: bool,
|
||||||
|
pub bus_request: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, thiserror::Error)]
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
pub enum Z80Error /* <B: fmt::Display> */ {
|
pub enum Z80Error /* <B: fmt::Display> */ {
|
||||||
#[error("cpu halted")]
|
#[error("cpu halted")]
|
||||||
|
@ -120,8 +126,7 @@ pub struct Z80<Instant> {
|
||||||
pub state: Z80State,
|
pub state: Z80State,
|
||||||
pub debugger: Z80Debugger,
|
pub debugger: Z80Debugger,
|
||||||
pub previous_cycle: Z80Cycle<Instant>,
|
pub previous_cycle: Z80Cycle<Instant>,
|
||||||
//pub port: BusPort,
|
pub signals: Z80Signals,
|
||||||
//pub ioport: Option<BusPort>,
|
|
||||||
// TODO activate later
|
// TODO activate later
|
||||||
//pub reset: Signal<bool>,
|
//pub reset: Signal<bool>,
|
||||||
//pub bus_request: Signal<bool>,
|
//pub bus_request: Signal<bool>,
|
||||||
|
@ -131,34 +136,22 @@ impl<Instant> Z80<Instant>
|
||||||
where
|
where
|
||||||
Instant: EmuInstant,
|
Instant: EmuInstant,
|
||||||
{
|
{
|
||||||
pub fn new(cputype: Z80Type, frequency: Frequency /*, port: BusPort, ioport: Option<BusPort>*/) -> Self {
|
pub fn new(cputype: Z80Type, frequency: Frequency) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cputype,
|
cputype,
|
||||||
frequency,
|
frequency,
|
||||||
state: Z80State::default(),
|
state: Z80State::default(),
|
||||||
debugger: Z80Debugger::default(),
|
debugger: Z80Debugger::default(),
|
||||||
previous_cycle: Z80Cycle::at_time(Instant::START),
|
previous_cycle: Z80Cycle::at_time(Instant::START),
|
||||||
//port,
|
signals: Z80Signals::default(),
|
||||||
//ioport,
|
|
||||||
//reset: Signal::new(false),
|
//reset: Signal::new(false),
|
||||||
//bus_request: Signal::new(false),
|
//bus_request: Signal::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_type(
|
pub fn from_type(cputype: Z80Type, frequency: Frequency) -> Self {
|
||||||
cputype: Z80Type,
|
|
||||||
frequency: Frequency,
|
|
||||||
bus: Rc<RefCell<Bus>>,
|
|
||||||
addr_offset: Address,
|
|
||||||
io_bus: Option<(Rc<RefCell<Bus>>, Address)>,
|
|
||||||
) -> Self {
|
|
||||||
match cputype {
|
match cputype {
|
||||||
Z80Type::Z80 => Self::new(
|
Z80Type::Z80 => Self::new(cputype, frequency),
|
||||||
cputype,
|
|
||||||
frequency,
|
|
||||||
//BusPort::new(addr_offset, 16, 8, bus),
|
|
||||||
//io_bus.map(|(io_bus, io_offset)| BusPort::new(io_offset, 16, 8, io_bus)),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +161,10 @@ where
|
||||||
self.debugger = Z80Debugger::default();
|
self.debugger = Z80Debugger::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_state(&mut self, clock: Instant) {
|
pub fn dump_state<Bus>(&mut self, clock: Instant, bus: &mut Bus)
|
||||||
|
where
|
||||||
|
Bus: BusAccess<Z80Address, Instant = Instant>,
|
||||||
|
{
|
||||||
println!("Status: {:?}", self.state.status);
|
println!("Status: {:?}", self.state.status);
|
||||||
println!("PC: {:#06x}", self.state.pc);
|
println!("PC: {:#06x}", self.state.pc);
|
||||||
println!("SP: {:#06x}", self.state.sp);
|
println!("SP: {:#06x}", self.state.sp);
|
||||||
|
@ -207,12 +203,11 @@ where
|
||||||
println!("I: {:#04x} R: {:#04x}", self.state.i, self.state.r);
|
println!("I: {:#04x} R: {:#04x}", self.state.i, self.state.r);
|
||||||
println!("IM: {:?} IFF1: {:?} IFF2: {:?}", self.state.im, self.state.iff1, self.state.iff2);
|
println!("IM: {:?} IFF1: {:?} IFF2: {:?}", self.state.im, self.state.iff1, self.state.iff2);
|
||||||
|
|
||||||
// TODO disabled until function is reimplemented
|
println!(
|
||||||
//println!(
|
"Current Instruction: {} {:?}",
|
||||||
// "Current Instruction: {} {:?}",
|
self.previous_cycle.decoder.format_instruction_bytes(bus),
|
||||||
// self.decoder.format_instruction_bytes(&mut self.port),
|
self.previous_cycle.decoder.instruction
|
||||||
// self.decoder.instruction
|
);
|
||||||
//);
|
|
||||||
println!("Previous Instruction: {:?}", self.previous_cycle.decoder.instruction);
|
println!("Previous Instruction: {:?}", self.previous_cycle.decoder.instruction);
|
||||||
println!();
|
println!();
|
||||||
// TODO disabled until function is reimplemented
|
// TODO disabled until function is reimplemented
|
||||||
|
|
|
@ -8,7 +8,7 @@ fn main() {
|
||||||
Arg::new("ROM")
|
Arg::new("ROM")
|
||||||
.short('r')
|
.short('r')
|
||||||
.long("rom")
|
.long("rom")
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::Set)
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
.help("ROM file to load at the start of memory"),
|
.help("ROM file to load at the start of memory"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::any::Any;
|
||||||
use femtos::Instant;
|
use femtos::Instant;
|
||||||
|
|
||||||
use moa_core::{Bus, Error, Address, Addressable, Transmutable};
|
use moa_core::{Bus, Device, Error, Address, Addressable, Signal, Transmutable};
|
||||||
use moa_signals::Signal;
|
//use moa_signals::Signal;
|
||||||
|
use moa_z80::Z80;
|
||||||
|
|
||||||
const DEV_NAME: &str = "coprocessor";
|
const DEV_NAME: &str = "coprocessor";
|
||||||
|
|
||||||
pub struct CoprocessorCoordinator {
|
pub struct CoprocessorCoordinator {
|
||||||
bus_request: Signal<bool>,
|
z80: Device,
|
||||||
reset: Signal<bool>,
|
//bus_request: Signal<bool>,
|
||||||
|
//reset: Signal<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl CoprocessorCoordinator {
|
impl CoprocessorCoordinator {
|
||||||
pub fn new(reset: Signal<bool>, bus_request: Signal<bool>) -> Self {
|
pub fn new(z80: Device) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bus_request,
|
z80,
|
||||||
reset,
|
//bus_request,
|
||||||
|
//reset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +34,9 @@ impl Addressable for CoprocessorCoordinator {
|
||||||
fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
fn read(&mut self, _clock: Instant, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||||
match addr {
|
match addr {
|
||||||
0x100 => {
|
0x100 => {
|
||||||
data[0] = if self.bus_request.get() && self.reset.get() {
|
let mut device = self.z80.borrow_mut();
|
||||||
|
let z80 = device.as_signalable().unwrap();
|
||||||
|
data[0] = if z80.signal(Signal::BusRequest).unwrap_or(false) && z80.signal(Signal::Reset).unwrap_or(false) {
|
||||||
0x01
|
0x01
|
||||||
} else {
|
} else {
|
||||||
0x00
|
0x00
|
||||||
|
@ -49,10 +55,14 @@ impl Addressable for CoprocessorCoordinator {
|
||||||
match addr {
|
match addr {
|
||||||
0x000 => { /* ROM vs DRAM mode */ },
|
0x000 => { /* ROM vs DRAM mode */ },
|
||||||
0x100 => {
|
0x100 => {
|
||||||
self.bus_request.set(data[0] != 0);
|
let mut device = self.z80.borrow_mut();
|
||||||
|
let z80 = device.as_signalable().unwrap();
|
||||||
|
z80.set_signal(Signal::BusRequest, data[0] == 0)?;
|
||||||
},
|
},
|
||||||
0x200 => {
|
0x200 => {
|
||||||
self.reset.set(data[0] == 0);
|
let mut device = self.z80.borrow_mut();
|
||||||
|
let z80 = device.as_signalable().unwrap();
|
||||||
|
z80.set_signal(Signal::Reset, data[0] == 0)?;
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
log::warn!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr);
|
log::warn!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr);
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use femtos::Frequency;
|
use femtos::{Instant, Frequency};
|
||||||
|
|
||||||
use moa_core::{System, Error, MemoryBlock, Bus, Address, Addressable, Device};
|
use moa_core::{System, Error, MemoryBlock, Bus, Address, Addressable, Device};
|
||||||
use moa_host::Host;
|
use moa_host::Host;
|
||||||
|
@ -68,11 +68,13 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
|
||||||
coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone());
|
coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone());
|
||||||
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
|
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
|
||||||
coproc_bus.borrow_mut().insert(0x8000, coproc_area);
|
coproc_bus.borrow_mut().insert(0x8000, coproc_area);
|
||||||
let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545), coproc_bus, 0, None);
|
let coproc = Z80::from_type(Z80Type::Z80, Frequency::from_hz(3_579_545));
|
||||||
let mut reset = coproc.reset.clone();
|
//let mut reset = coproc.reset.clone();
|
||||||
let mut bus_request = coproc.bus_request.clone();
|
//let mut bus_request = coproc.bus_request.clone();
|
||||||
reset.set(true);
|
//reset.set(true);
|
||||||
bus_request.set(true);
|
//bus_request.set(true);
|
||||||
|
let coproc = Device::new(coproc);
|
||||||
|
|
||||||
|
|
||||||
// Add coprocessor devices to the system bus so the 68000 can access them too
|
// Add coprocessor devices to the system bus so the 68000 can access them too
|
||||||
system.add_addressable_device(0x00a00000, coproc_ram)?;
|
system.add_addressable_device(0x00a00000, coproc_ram)?;
|
||||||
|
@ -80,14 +82,14 @@ pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) ->
|
||||||
system.add_addressable_device(0x00a06000, coproc_register)?;
|
system.add_addressable_device(0x00a06000, coproc_register)?;
|
||||||
//system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
//system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
||||||
system.add_device("sn_sound", coproc_sn_sound.clone())?;
|
system.add_device("sn_sound", coproc_sn_sound.clone())?;
|
||||||
system.add_device("coproc", Device::new(coproc))?;
|
system.add_device("coproc", coproc.clone())?;
|
||||||
|
|
||||||
|
|
||||||
let controllers = GenesisControllers::new(host)?;
|
let controllers = GenesisControllers::new(host)?;
|
||||||
let interrupt = controllers.get_interrupt_signal();
|
let interrupt = controllers.get_interrupt_signal();
|
||||||
system.add_addressable_device(0x00a10000, Device::new(controllers))?;
|
system.add_addressable_device(0x00a10000, Device::new(controllers))?;
|
||||||
|
|
||||||
let coproc = CoprocessorCoordinator::new(reset, bus_request);
|
let coproc = CoprocessorCoordinator::new(coproc);
|
||||||
system.add_addressable_device(0x00a11000, Device::new(coproc))?;
|
system.add_addressable_device(0x00a11000, Device::new(coproc))?;
|
||||||
|
|
||||||
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound)?;
|
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound)?;
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub fn build_trs80<H: Host>(host: &mut H, options: Trs80Options) -> Result<Syste
|
||||||
system.add_addressable_device(0x37E0 + 0x420, Device::new(video)).unwrap();
|
system.add_addressable_device(0x37E0 + 0x420, Device::new(video)).unwrap();
|
||||||
|
|
||||||
// TODO the ioport needs to be hooked up
|
// TODO the ioport needs to be hooked up
|
||||||
let cpu = Z80::from_type(Z80Type::Z80, options.frequency, system.bus.clone(), 0, None);
|
let cpu = Z80::from_type(Z80Type::Z80, options.frequency);
|
||||||
|
|
||||||
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
system.add_interruptable_device("cpu", Device::new(cpu))?;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Last run on 2024-03-31 at commit 6e7e315808228e03eaf8ad2e8152c087710f1d28 with flags --check-undocumented --check-timings
|
Last run on 2024-04-07 at commit 1c5ad3999afa5591ec8fcbcadf4797514c390031 with flags --check-undocumented --check-timings
|
||||||
|
|
||||||
00.json completed, all passed!
|
00.json completed, all passed!
|
||||||
01.json completed, all passed!
|
01.json completed, all passed!
|
||||||
|
@ -614,7 +614,7 @@ dd 82.json completed, all passed!
|
||||||
dd 83.json completed, all passed!
|
dd 83.json completed, all passed!
|
||||||
dd 84.json completed, all passed!
|
dd 84.json completed, all passed!
|
||||||
dd 85.json completed, all passed!
|
dd 85.json completed, all passed!
|
||||||
dd 86.json completed, all passed!
|
dd 86.json completed: 0 passed, 1000 FAILED
|
||||||
dd 87.json completed, all passed!
|
dd 87.json completed, all passed!
|
||||||
dd 88.json completed, all passed!
|
dd 88.json completed, all passed!
|
||||||
dd 89.json completed, all passed!
|
dd 89.json completed, all passed!
|
||||||
|
@ -622,7 +622,7 @@ dd 8a.json completed, all passed!
|
||||||
dd 8b.json completed, all passed!
|
dd 8b.json completed, all passed!
|
||||||
dd 8c.json completed, all passed!
|
dd 8c.json completed, all passed!
|
||||||
dd 8d.json completed, all passed!
|
dd 8d.json completed, all passed!
|
||||||
dd 8e.json completed, all passed!
|
dd 8e.json completed: 0 passed, 1000 FAILED
|
||||||
dd 8f.json completed, all passed!
|
dd 8f.json completed, all passed!
|
||||||
dd 90.json completed, all passed!
|
dd 90.json completed, all passed!
|
||||||
dd 91.json completed, all passed!
|
dd 91.json completed, all passed!
|
||||||
|
@ -630,7 +630,7 @@ dd 92.json completed, all passed!
|
||||||
dd 93.json completed, all passed!
|
dd 93.json completed, all passed!
|
||||||
dd 94.json completed, all passed!
|
dd 94.json completed, all passed!
|
||||||
dd 95.json completed, all passed!
|
dd 95.json completed, all passed!
|
||||||
dd 96.json completed, all passed!
|
dd 96.json completed: 0 passed, 1000 FAILED
|
||||||
dd 97.json completed, all passed!
|
dd 97.json completed, all passed!
|
||||||
dd 98.json completed, all passed!
|
dd 98.json completed, all passed!
|
||||||
dd 99.json completed, all passed!
|
dd 99.json completed, all passed!
|
||||||
|
@ -638,7 +638,7 @@ dd 9a.json completed, all passed!
|
||||||
dd 9b.json completed, all passed!
|
dd 9b.json completed, all passed!
|
||||||
dd 9c.json completed, all passed!
|
dd 9c.json completed, all passed!
|
||||||
dd 9d.json completed, all passed!
|
dd 9d.json completed, all passed!
|
||||||
dd 9e.json completed, all passed!
|
dd 9e.json completed: 0 passed, 1000 FAILED
|
||||||
dd 9f.json completed, all passed!
|
dd 9f.json completed, all passed!
|
||||||
dd a0.json completed, all passed!
|
dd a0.json completed, all passed!
|
||||||
dd a1.json completed, all passed!
|
dd a1.json completed, all passed!
|
||||||
|
@ -646,7 +646,7 @@ dd a2.json completed, all passed!
|
||||||
dd a3.json completed, all passed!
|
dd a3.json completed, all passed!
|
||||||
dd a4.json completed, all passed!
|
dd a4.json completed, all passed!
|
||||||
dd a5.json completed, all passed!
|
dd a5.json completed, all passed!
|
||||||
dd a6.json completed, all passed!
|
dd a6.json completed: 0 passed, 1000 FAILED
|
||||||
dd a7.json completed, all passed!
|
dd a7.json completed, all passed!
|
||||||
dd a8.json completed, all passed!
|
dd a8.json completed, all passed!
|
||||||
dd a9.json completed, all passed!
|
dd a9.json completed, all passed!
|
||||||
|
@ -654,7 +654,7 @@ dd aa.json completed, all passed!
|
||||||
dd ab.json completed, all passed!
|
dd ab.json completed, all passed!
|
||||||
dd ac.json completed, all passed!
|
dd ac.json completed, all passed!
|
||||||
dd ad.json completed, all passed!
|
dd ad.json completed, all passed!
|
||||||
dd ae.json completed, all passed!
|
dd ae.json completed: 0 passed, 1000 FAILED
|
||||||
dd af.json completed, all passed!
|
dd af.json completed, all passed!
|
||||||
dd b0.json completed, all passed!
|
dd b0.json completed, all passed!
|
||||||
dd b1.json completed, all passed!
|
dd b1.json completed, all passed!
|
||||||
|
@ -662,7 +662,7 @@ dd b2.json completed, all passed!
|
||||||
dd b3.json completed, all passed!
|
dd b3.json completed, all passed!
|
||||||
dd b4.json completed, all passed!
|
dd b4.json completed, all passed!
|
||||||
dd b5.json completed, all passed!
|
dd b5.json completed, all passed!
|
||||||
dd b6.json completed, all passed!
|
dd b6.json completed: 0 passed, 1000 FAILED
|
||||||
dd b7.json completed, all passed!
|
dd b7.json completed, all passed!
|
||||||
dd b8.json completed, all passed!
|
dd b8.json completed, all passed!
|
||||||
dd b9.json completed, all passed!
|
dd b9.json completed, all passed!
|
||||||
|
@ -670,7 +670,7 @@ dd ba.json completed, all passed!
|
||||||
dd bb.json completed, all passed!
|
dd bb.json completed, all passed!
|
||||||
dd bc.json completed, all passed!
|
dd bc.json completed, all passed!
|
||||||
dd bd.json completed, all passed!
|
dd bd.json completed, all passed!
|
||||||
dd be.json completed, all passed!
|
dd be.json completed: 0 passed, 1000 FAILED
|
||||||
dd bf.json completed, all passed!
|
dd bf.json completed, all passed!
|
||||||
dd c0.json completed, all passed!
|
dd c0.json completed, all passed!
|
||||||
dd c1.json completed, all passed!
|
dd c1.json completed, all passed!
|
||||||
|
@ -1038,7 +1038,7 @@ ed 5f.json completed, all passed!
|
||||||
ed 60.json completed: 2 passed, 998 FAILED
|
ed 60.json completed: 2 passed, 998 FAILED
|
||||||
ed 61.json completed, all passed!
|
ed 61.json completed, all passed!
|
||||||
ed 62.json completed, all passed!
|
ed 62.json completed, all passed!
|
||||||
ed 63.json completed, all passed!
|
ed 63.json completed: 0 passed, 1000 FAILED
|
||||||
ed 64.json completed, all passed!
|
ed 64.json completed, all passed!
|
||||||
ed 65.json completed, all passed!
|
ed 65.json completed, all passed!
|
||||||
ed 66.json completed, all passed!
|
ed 66.json completed, all passed!
|
||||||
|
@ -1046,7 +1046,7 @@ ed 67.json completed, all passed!
|
||||||
ed 68.json completed: 4 passed, 996 FAILED
|
ed 68.json completed: 4 passed, 996 FAILED
|
||||||
ed 69.json completed, all passed!
|
ed 69.json completed, all passed!
|
||||||
ed 6a.json completed, all passed!
|
ed 6a.json completed, all passed!
|
||||||
ed 6b.json completed, all passed!
|
ed 6b.json completed: 0 passed, 1000 FAILED
|
||||||
ed 6c.json completed, all passed!
|
ed 6c.json completed, all passed!
|
||||||
ed 6d.json completed, all passed!
|
ed 6d.json completed, all passed!
|
||||||
ed 6e.json completed, all passed!
|
ed 6e.json completed, all passed!
|
||||||
|
@ -1058,7 +1058,7 @@ ed 73.json completed, all passed!
|
||||||
ed 74.json completed, all passed!
|
ed 74.json completed, all passed!
|
||||||
ed 75.json completed, all passed!
|
ed 75.json completed, all passed!
|
||||||
ed 76.json completed, all passed!
|
ed 76.json completed, all passed!
|
||||||
ed 77.json completed, all passed!
|
ed 77.json completed: 0 passed, 1000 FAILED
|
||||||
ed 78.json completed: 7 passed, 993 FAILED
|
ed 78.json completed: 7 passed, 993 FAILED
|
||||||
ed 79.json completed, all passed!
|
ed 79.json completed, all passed!
|
||||||
ed 7a.json completed, all passed!
|
ed 7a.json completed, all passed!
|
||||||
|
@ -1066,7 +1066,7 @@ ed 7b.json completed, all passed!
|
||||||
ed 7c.json completed, all passed!
|
ed 7c.json completed, all passed!
|
||||||
ed 7d.json completed, all passed!
|
ed 7d.json completed, all passed!
|
||||||
ed 7e.json completed, all passed!
|
ed 7e.json completed, all passed!
|
||||||
ed 7f.json completed, all passed!
|
ed 7f.json completed: 0 passed, 1000 FAILED
|
||||||
ed a0.json completed, all passed!
|
ed a0.json completed, all passed!
|
||||||
ed a1.json completed: 0 passed, 1000 FAILED
|
ed a1.json completed: 0 passed, 1000 FAILED
|
||||||
ed a2.json completed: 0 passed, 1000 FAILED
|
ed a2.json completed: 0 passed, 1000 FAILED
|
||||||
|
@ -1234,7 +1234,7 @@ fd 82.json completed, all passed!
|
||||||
fd 83.json completed, all passed!
|
fd 83.json completed, all passed!
|
||||||
fd 84.json completed, all passed!
|
fd 84.json completed, all passed!
|
||||||
fd 85.json completed, all passed!
|
fd 85.json completed, all passed!
|
||||||
fd 86.json completed, all passed!
|
fd 86.json completed: 0 passed, 1000 FAILED
|
||||||
fd 87.json completed, all passed!
|
fd 87.json completed, all passed!
|
||||||
fd 88.json completed, all passed!
|
fd 88.json completed, all passed!
|
||||||
fd 89.json completed, all passed!
|
fd 89.json completed, all passed!
|
||||||
|
@ -1242,7 +1242,7 @@ fd 8a.json completed, all passed!
|
||||||
fd 8b.json completed, all passed!
|
fd 8b.json completed, all passed!
|
||||||
fd 8c.json completed, all passed!
|
fd 8c.json completed, all passed!
|
||||||
fd 8d.json completed, all passed!
|
fd 8d.json completed, all passed!
|
||||||
fd 8e.json completed, all passed!
|
fd 8e.json completed: 0 passed, 1000 FAILED
|
||||||
fd 8f.json completed, all passed!
|
fd 8f.json completed, all passed!
|
||||||
fd 90.json completed, all passed!
|
fd 90.json completed, all passed!
|
||||||
fd 91.json completed, all passed!
|
fd 91.json completed, all passed!
|
||||||
|
@ -1250,7 +1250,7 @@ fd 92.json completed, all passed!
|
||||||
fd 93.json completed, all passed!
|
fd 93.json completed, all passed!
|
||||||
fd 94.json completed, all passed!
|
fd 94.json completed, all passed!
|
||||||
fd 95.json completed, all passed!
|
fd 95.json completed, all passed!
|
||||||
fd 96.json completed, all passed!
|
fd 96.json completed: 0 passed, 1000 FAILED
|
||||||
fd 97.json completed, all passed!
|
fd 97.json completed, all passed!
|
||||||
fd 98.json completed, all passed!
|
fd 98.json completed, all passed!
|
||||||
fd 99.json completed, all passed!
|
fd 99.json completed, all passed!
|
||||||
|
@ -1258,7 +1258,7 @@ fd 9a.json completed, all passed!
|
||||||
fd 9b.json completed, all passed!
|
fd 9b.json completed, all passed!
|
||||||
fd 9c.json completed, all passed!
|
fd 9c.json completed, all passed!
|
||||||
fd 9d.json completed, all passed!
|
fd 9d.json completed, all passed!
|
||||||
fd 9e.json completed, all passed!
|
fd 9e.json completed: 0 passed, 1000 FAILED
|
||||||
fd 9f.json completed, all passed!
|
fd 9f.json completed, all passed!
|
||||||
fd a0.json completed, all passed!
|
fd a0.json completed, all passed!
|
||||||
fd a1.json completed, all passed!
|
fd a1.json completed, all passed!
|
||||||
|
@ -1266,7 +1266,7 @@ fd a2.json completed, all passed!
|
||||||
fd a3.json completed, all passed!
|
fd a3.json completed, all passed!
|
||||||
fd a4.json completed, all passed!
|
fd a4.json completed, all passed!
|
||||||
fd a5.json completed, all passed!
|
fd a5.json completed, all passed!
|
||||||
fd a6.json completed, all passed!
|
fd a6.json completed: 0 passed, 1000 FAILED
|
||||||
fd a7.json completed, all passed!
|
fd a7.json completed, all passed!
|
||||||
fd a8.json completed, all passed!
|
fd a8.json completed, all passed!
|
||||||
fd a9.json completed, all passed!
|
fd a9.json completed, all passed!
|
||||||
|
@ -1274,7 +1274,7 @@ fd aa.json completed, all passed!
|
||||||
fd ab.json completed, all passed!
|
fd ab.json completed, all passed!
|
||||||
fd ac.json completed, all passed!
|
fd ac.json completed, all passed!
|
||||||
fd ad.json completed, all passed!
|
fd ad.json completed, all passed!
|
||||||
fd ae.json completed, all passed!
|
fd ae.json completed: 0 passed, 1000 FAILED
|
||||||
fd af.json completed, all passed!
|
fd af.json completed, all passed!
|
||||||
fd b0.json completed, all passed!
|
fd b0.json completed, all passed!
|
||||||
fd b1.json completed, all passed!
|
fd b1.json completed, all passed!
|
||||||
|
@ -1282,7 +1282,7 @@ fd b2.json completed, all passed!
|
||||||
fd b3.json completed, all passed!
|
fd b3.json completed, all passed!
|
||||||
fd b4.json completed, all passed!
|
fd b4.json completed, all passed!
|
||||||
fd b5.json completed, all passed!
|
fd b5.json completed, all passed!
|
||||||
fd b6.json completed, all passed!
|
fd b6.json completed: 0 passed, 1000 FAILED
|
||||||
fd b7.json completed, all passed!
|
fd b7.json completed, all passed!
|
||||||
fd b8.json completed, all passed!
|
fd b8.json completed, all passed!
|
||||||
fd b9.json completed, all passed!
|
fd b9.json completed, all passed!
|
||||||
|
@ -1290,7 +1290,7 @@ fd ba.json completed, all passed!
|
||||||
fd bb.json completed, all passed!
|
fd bb.json completed, all passed!
|
||||||
fd bc.json completed, all passed!
|
fd bc.json completed, all passed!
|
||||||
fd bd.json completed, all passed!
|
fd bd.json completed, all passed!
|
||||||
fd be.json completed, all passed!
|
fd be.json completed: 0 passed, 1000 FAILED
|
||||||
fd bf.json completed, all passed!
|
fd bf.json completed, all passed!
|
||||||
fd c0.json completed, all passed!
|
fd c0.json completed, all passed!
|
||||||
fd c1.json completed, all passed!
|
fd c1.json completed, all passed!
|
||||||
|
@ -1611,5 +1611,5 @@ fd ff.json completed, all passed!
|
||||||
fe.json completed, all passed!
|
fe.json completed, all passed!
|
||||||
ff.json completed, all passed!
|
ff.json completed, all passed!
|
||||||
|
|
||||||
passed: 1584670, failed: 25330, total 98%
|
passed: 1564670, failed: 45330, total 97%
|
||||||
completed in 0m 8s
|
completed in 0m 9s
|
||||||
|
|
|
@ -46,6 +46,9 @@ struct Args {
|
||||||
/// Check instruction timings
|
/// Check instruction timings
|
||||||
#[clap(short = 't', long)]
|
#[clap(short = 't', long)]
|
||||||
check_timings: bool,
|
check_timings: bool,
|
||||||
|
/// Don't check I/O instructions
|
||||||
|
#[clap(short = 'i', long)]
|
||||||
|
no_check_io: bool,
|
||||||
/// Directory to the test suite to run
|
/// Directory to the test suite to run
|
||||||
#[clap(long, default_value = DEFAULT_RAD_TESTS)]
|
#[clap(long, default_value = DEFAULT_RAD_TESTS)]
|
||||||
testsuite: String,
|
testsuite: String,
|
||||||
|
@ -148,7 +151,11 @@ impl TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn init_execute_test(cputype: Z80Type, state: &TestState, ports: &[TestPort]) -> Result<(Z80<Instant>, MemoryBlock<Instant>, MemoryBlock<Instant>), Error> {
|
fn init_execute_test(
|
||||||
|
cputype: Z80Type,
|
||||||
|
state: &TestState,
|
||||||
|
ports: &[TestPort],
|
||||||
|
) -> Result<(Z80<Instant>, MemoryBlock<Instant>, MemoryBlock<Instant>), Error> {
|
||||||
// Insert basic initialization
|
// Insert basic initialization
|
||||||
let len = 0x1_0000;
|
let len = 0x1_0000;
|
||||||
let mut data = Vec::with_capacity(len);
|
let mut data = Vec::with_capacity(len);
|
||||||
|
@ -220,7 +227,8 @@ fn load_state(
|
||||||
|
|
||||||
// Load data bytes into memory
|
// Load data bytes into memory
|
||||||
for (addr, byte) in initial.ram.iter() {
|
for (addr, byte) in initial.ram.iter() {
|
||||||
memory.write_u8(Instant::START, *addr, *byte)
|
memory
|
||||||
|
.write_u8(Instant::START, *addr, *byte)
|
||||||
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,17 +287,19 @@ fn assert_state(
|
||||||
assert_value(cpu.state.iff1 as u8, expected.iff1, "iff1")?;
|
assert_value(cpu.state.iff1 as u8, expected.iff1, "iff1")?;
|
||||||
assert_value(cpu.state.iff2 as u8, expected.iff2, "iff2")?;
|
assert_value(cpu.state.iff2 as u8, expected.iff2, "iff2")?;
|
||||||
|
|
||||||
// Load data bytes into memory
|
// Compare data bytes in memory
|
||||||
for (addr, byte) in expected.ram.iter() {
|
for (addr, byte) in expected.ram.iter() {
|
||||||
let actual = memory.read_u8(Instant::START, *addr)
|
let actual = memory
|
||||||
|
.read_u8(Instant::START, *addr)
|
||||||
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
||||||
assert_value(actual, *byte, &format!("ram at {:x}", addr))?;
|
assert_value(actual, *byte, &format!("ram at {:x}", addr))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load data bytes into io space
|
// Compare data bytes in io space
|
||||||
for port in ports.iter() {
|
for port in ports.iter() {
|
||||||
if port.atype == "w" {
|
if port.atype == "w" {
|
||||||
let actual = io.read_u8(Instant::START, port.addr)
|
let actual = io
|
||||||
|
.read_u8(Instant::START, port.addr)
|
||||||
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
.map_err(|err| Error::Bus(format!("{:?}", err)))?;
|
||||||
assert_value(actual, port.value, &format!("port value at {:x}", port.addr))?;
|
assert_value(actual, port.value, &format!("port value at {:x}", port.addr))?;
|
||||||
}
|
}
|
||||||
|
@ -306,20 +316,20 @@ fn step_cpu_and_assert(
|
||||||
args: &Args,
|
args: &Args,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
//let clock_elapsed = cpu.step((memory, io))?;
|
//let clock_elapsed = cpu.step((memory, io))?;
|
||||||
let clock_elapsed = cpu.step(Instant::START, memory)
|
let clock_elapsed = cpu
|
||||||
|
.step(Instant::START, memory)
|
||||||
.map_err(|err| Error::Step(format!("{:?}", err)))?;
|
.map_err(|err| Error::Step(format!("{:?}", err)))?;
|
||||||
|
|
||||||
assert_state(cpu, memory, io, &case.final_state, args.check_extra_flags, &case.ports)?;
|
assert_state(cpu, memory, io, &case.final_state, args.check_extra_flags, &case.ports)?;
|
||||||
if args.check_timings {
|
if args.check_timings {
|
||||||
// TODO re-enable. not sure why it can't divide here
|
let cycles = clock_elapsed.as_duration() / cpu.frequency.period_duration();
|
||||||
//let cycles = clock_elapsed / cpu.frequency.period_duration();
|
if cycles != case.cycles.len() as u64 {
|
||||||
//if cycles != case.cycles.len() {
|
return Err(Error::Assertion(format!(
|
||||||
// return Err(Error::Assertion(format!(
|
"expected instruction to take {} cycles, but took {}",
|
||||||
// "expected instruction to take {} cycles, but took {}",
|
case.cycles.len(),
|
||||||
// case.cycles.len(),
|
cycles
|
||||||
// cycles
|
)));
|
||||||
// )));
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -338,8 +348,8 @@ fn run_test(case: &TestCase, args: &Args) -> Result<(), Error> {
|
||||||
if args.debug {
|
if args.debug {
|
||||||
case.dump();
|
case.dump();
|
||||||
println!();
|
println!();
|
||||||
initial_cpu.dump_state(Instant::START);
|
initial_cpu.dump_state(Instant::START, &mut memory);
|
||||||
cpu.dump_state(Instant::START);
|
cpu.dump_state(Instant::START, &mut memory);
|
||||||
}
|
}
|
||||||
println!("FAILED: {:?}", err);
|
println!("FAILED: {:?}", err);
|
||||||
}
|
}
|
||||||
|
@ -371,6 +381,10 @@ fn test_json_file(path: PathBuf, args: &Args) -> (usize, usize, String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if args.no_check_io && !case.ports.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Sort the ram memory for debugging help
|
// Sort the ram memory for debugging help
|
||||||
if args.debug {
|
if args.debug {
|
||||||
case.initial_state.ram.sort_by_key(|(addr, _)| *addr);
|
case.initial_state.ram.sort_by_key(|(addr, _)| *addr);
|
||||||
|
|
2
todo.txt
2
todo.txt
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
* fix the Z80 dumping functions
|
|
||||||
* fix the Z80 reset and bus_request signals
|
* fix the Z80 reset and bus_request signals
|
||||||
* the emulator_hal_memory should throw an error when an access will straddle the end of memory? Or should it autowrap?
|
* the emulator_hal_memory should throw an error when an access will straddle the end of memory? Or should it autowrap?
|
||||||
|
* fix the m68k dumping functions
|
||||||
|
|
||||||
* convert computie system to use the new moa-system library crate to replace the old core crate
|
* convert computie system to use the new moa-system library crate to replace the old core crate
|
||||||
* change package names to drop the 's', so moa-systems-computie becomes moa-system-computie
|
* change package names to drop the 's', so moa-systems-computie becomes moa-system-computie
|
||||||
|
|
Loading…
Reference in New Issue