Emulate hardware bug

This commit is contained in:
Balt 2024-04-03 17:23:30 +00:00
parent 6419f63453
commit a52d53a8d4
3 changed files with 12 additions and 14 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "r6502" name = "r6502"
version = "1.0.7" version = "1.1.0"
authors = ["baltdev"] authors = ["baltdev"]
edition = "2021" edition = "2021"
description = "A simple MOS 6502 emulator." description = "A simple MOS 6502 emulator."

View File

@ -42,21 +42,17 @@ where
} }
} }
/// Default implementor of [`ReadCallback`] for [`Emulator`]. /// Default implementor of [`ReadCallback`] and [`WriteCallback`] for [`Emulator`].
#[derive(Debug, Copy, Clone, PartialEq, Eq, core::hash::Hash, Ord, PartialOrd)] #[derive(Debug, Copy, Clone, PartialEq, Eq, core::hash::Hash, Ord, PartialOrd)]
pub struct DefaultReadCallback; pub struct DefaultCallbacks;
impl ReadCallback for DefaultReadCallback { impl ReadCallback for DefaultCallbacks {
fn callback(&mut self, state: &mut State, address: u16) -> u8 { fn callback(&mut self, state: &mut State, address: u16) -> u8 {
state.memory[address as usize] state.memory[address as usize]
} }
} }
/// Default implementor of [`WriteCallback`] for [`Emulator`]. impl WriteCallback for DefaultCallbacks {
#[derive(Debug, Copy, Clone, PartialEq, Eq, core::hash::Hash, Ord, PartialOrd)]
pub struct DefaultWriteCallback;
impl WriteCallback for DefaultWriteCallback {
fn callback(&mut self, state: &mut State, address: u16, byte: u8) { fn callback(&mut self, state: &mut State, address: u16, byte: u8) {
state.memory[address as usize] = byte; state.memory[address as usize] = byte;
} }
@ -209,12 +205,12 @@ impl<R: ReadCallback, W: WriteCallback> Emulator<R, W> {
} }
} }
impl Default for Emulator<DefaultReadCallback, DefaultWriteCallback> { impl Default for Emulator<DefaultCallbacks, DefaultCallbacks> {
fn default() -> Self { fn default() -> Self {
Self { Self {
state: State::default(), state: State::default(),
read_callback: DefaultReadCallback, read_callback: DefaultCallbacks,
write_callback: DefaultWriteCallback, write_callback: DefaultCallbacks,
} }
} }
} }
@ -251,7 +247,9 @@ impl<R: ReadCallback, W: WriteCallback> Emulator<R, W> {
.wrapping_add_signed(i16::from(offset)), .wrapping_add_signed(i16::from(offset)),
AbsoluteIndirect(addr) => { AbsoluteIndirect(addr) => {
let high = self.read(addr); let high = self.read(addr);
let low = self.read(addr.wrapping_add(1)); // Emulate hardware bug: low byte is wrapped around page only
let addr_low = (addr as u8).wrapping_add(1);
let low = self.read(addr & 0xFF00 | (addr_low as u16));
u16::from_le_bytes([high, low]) u16::from_le_bytes([high, low])
} }
AbsoluteX(addr) => addr.wrapping_add(u16::from(self.state.x_register)), AbsoluteX(addr) => addr.wrapping_add(u16::from(self.state.x_register)),

View File

@ -9,7 +9,7 @@ pub mod instructions;
pub mod state; pub mod state;
pub use emulation::{ pub use emulation::{
DefaultReadCallback, DefaultWriteCallback, Emulator, FunctionReadCallback, DefaultCallbacks, Emulator, FunctionReadCallback,
FunctionWriteCallback, ReadCallback, WriteCallback, FunctionWriteCallback, ReadCallback, WriteCallback,
}; };
pub use instructions::{AddressMode, Instruction, Opcode}; pub use instructions::{AddressMode, Instruction, Opcode};