Minor refactors and bug fixes
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Has been cancelled
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Has been cancelled
- Bit instruction now sets Z flag correctly - DMA is no longer handled by cpu.rs
This commit is contained in:
131
src/cpu.rs
131
src/cpu.rs
@@ -1,7 +1,7 @@
|
||||
use std::fmt::Write;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{debug::DebugLog, mem::CpuMem};
|
||||
use crate::{Break, debug::DebugLog, mem::CpuMem};
|
||||
|
||||
bitfield::bitfield! {
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
@@ -634,7 +634,9 @@ impl Cpu {
|
||||
if self.status.carry() {
|
||||
let page = self.jmp_rel(off);
|
||||
log!(" : - JMP ${:04X}", self.pc);
|
||||
if page { return ExecState::PageCross };
|
||||
if page {
|
||||
return ExecState::PageCross;
|
||||
};
|
||||
}
|
||||
}),
|
||||
0xF0 => inst!("BEQ", self.status.zero(), |off| {
|
||||
@@ -642,7 +644,9 @@ impl Cpu {
|
||||
if self.status.zero() {
|
||||
let page = self.jmp_rel(off);
|
||||
log!(" : - JMP ${:04X}", self.pc);
|
||||
if page { return ExecState::PageCross };
|
||||
if page {
|
||||
return ExecState::PageCross;
|
||||
};
|
||||
}
|
||||
}),
|
||||
0x30 => inst!("BMI", self.status.negative(), |off| {
|
||||
@@ -650,7 +654,9 @@ impl Cpu {
|
||||
if self.status.negative() {
|
||||
let page = self.jmp_rel(off);
|
||||
log!(" : - JMP ${:04X}", self.pc);
|
||||
if page { return ExecState::PageCross };
|
||||
if page {
|
||||
return ExecState::PageCross;
|
||||
};
|
||||
}
|
||||
}),
|
||||
0xD0 => inst!("BNE", !self.status.zero(), |off| {
|
||||
@@ -658,7 +664,9 @@ impl Cpu {
|
||||
if !self.status.zero() {
|
||||
let page = self.jmp_rel(off);
|
||||
log!(" : - JMP ${:04X}", self.pc);
|
||||
if page { return ExecState::PageCross };
|
||||
if page {
|
||||
return ExecState::PageCross;
|
||||
};
|
||||
}
|
||||
}),
|
||||
0x10 => inst!("BPL", !self.status.negative(), |off| {
|
||||
@@ -666,7 +674,9 @@ impl Cpu {
|
||||
if !self.status.negative() {
|
||||
let page = self.jmp_rel(off);
|
||||
log!(" : - JMP ${:04X}", self.pc);
|
||||
if page { return ExecState::PageCross };
|
||||
if page {
|
||||
return ExecState::PageCross;
|
||||
};
|
||||
}
|
||||
}),
|
||||
0x4C => inst!("JMP abs", 0, |low, high| {
|
||||
@@ -1509,14 +1519,14 @@ impl Cpu {
|
||||
}),
|
||||
0x24 => inst!("BIT zp", 1, |off| {
|
||||
let val = self.read_abs(mem, off, 0);
|
||||
self.status.set_zero(val == 0);
|
||||
self.status.set_zero(val & self.a == 0);
|
||||
self.status.set_overflow(val & 0x40 == 0x40);
|
||||
self.status.set_negative(val & 0x80 == 0x80);
|
||||
log!("{addr:04X}: BIT ${:02X} | {:02X}", off, val);
|
||||
}),
|
||||
0x2C => inst!("BIT abs", 1, |low, high| {
|
||||
let val = self.read_abs(mem, low, high);
|
||||
self.status.set_zero(val == 0);
|
||||
self.status.set_zero(val & self.a == 0);
|
||||
self.status.set_overflow(val & 0x40 == 0x40);
|
||||
self.status.set_negative(val & 0x80 == 0x80);
|
||||
log!("{addr:04X}: BIT ${:02X}{:02X} | {:02X}", high, low, val);
|
||||
@@ -1723,7 +1733,7 @@ impl Cpu {
|
||||
}
|
||||
}
|
||||
|
||||
fn clock_cpu(&mut self, mem: &mut CpuMem<'_>, nmi: bool, irq: bool) {
|
||||
pub fn clock_cpu(&mut self, mem: &mut CpuMem<'_>, nmi: bool, irq: bool, br: &Break) -> bool {
|
||||
self.clock_state = match self.clock_state {
|
||||
ClockState::HoldNmi { cycles } => {
|
||||
if cycles == 0 {
|
||||
@@ -1750,6 +1760,10 @@ impl Cpu {
|
||||
}
|
||||
}
|
||||
ClockState::ReadInstruction => {
|
||||
if br.cpu_exec {
|
||||
println!("Returning early from clock_cpu");
|
||||
return true;
|
||||
}
|
||||
let addr = self.pc;
|
||||
let instruction = mem.read(self.pc);
|
||||
if instruction != 0x02 {
|
||||
@@ -1900,59 +1914,13 @@ impl Cpu {
|
||||
}
|
||||
// self.irq_pending = self.ppu.irq_waiting() || self.apu.irq_waiting();
|
||||
self.irq_pending = irq;
|
||||
false
|
||||
}
|
||||
|
||||
pub fn cpu_cycle(
|
||||
&mut self,
|
||||
mem: &mut CpuMem<'_>,
|
||||
dma: &mut DmaState,
|
||||
nmi: bool,
|
||||
irq: bool,
|
||||
) {
|
||||
match *dma {
|
||||
DmaState::Passive => self.clock_cpu(mem, nmi, irq),
|
||||
// TODO: Validate that this takes the correct number of cycles (513 or 514 cycles)
|
||||
DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: Some(read),
|
||||
} => {
|
||||
mem.write(0x2004, read);
|
||||
// self.ppu.write_reg(4, read);
|
||||
debug!("OAM DMA write {:02X}", read);
|
||||
if rem == 0 {
|
||||
*dma = DmaState::Passive;
|
||||
} else {
|
||||
*dma = DmaState::Running {
|
||||
cpu_addr: cpu_addr + 1,
|
||||
rem: rem - 1,
|
||||
read: None,
|
||||
};
|
||||
}
|
||||
}
|
||||
DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: None,
|
||||
} => {
|
||||
let read = mem.read(cpu_addr);
|
||||
debug!("OAM DMA read {:04X} {:02X}", cpu_addr, read);
|
||||
*dma = DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: Some(read),
|
||||
};
|
||||
}
|
||||
}
|
||||
// if [0x8031, 0x8014].contains(&self.cpu.pc) {
|
||||
// self.dbg_int = true;
|
||||
// }
|
||||
}
|
||||
pub fn cpu_cycle_update(&mut self) {
|
||||
if !self.halted {
|
||||
self.cycle += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn executed(&self) -> bool {
|
||||
@@ -1978,6 +1946,7 @@ impl Cpu {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DmaState {
|
||||
Passive,
|
||||
Idle(u16),
|
||||
Running {
|
||||
cpu_addr: u16,
|
||||
rem: u8,
|
||||
@@ -1995,6 +1964,56 @@ impl DmaState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cycle(self, mem: &mut CpuMem<'_>, cpu: &mut Cpu) -> Option<Self> {
|
||||
match self {
|
||||
DmaState::Passive => None,
|
||||
DmaState::Idle(cpu_addr) => Some(DmaState::Running {
|
||||
cpu_addr,
|
||||
rem: 0xFF,
|
||||
read: None,
|
||||
}),
|
||||
DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: Some(read),
|
||||
} => {
|
||||
mem.write(0x2004, read);
|
||||
// self.ppu.write_reg(4, read);
|
||||
writeln!(&mut cpu.debug_log, "OAM DMA write {:02X}", read).unwrap();
|
||||
if rem == 0 {
|
||||
Some(DmaState::Passive)
|
||||
} else {
|
||||
Some(DmaState::Running {
|
||||
cpu_addr: cpu_addr + 1,
|
||||
rem: rem - 1,
|
||||
read: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: None,
|
||||
} => {
|
||||
if cpu.cycle % 2 != 1 {
|
||||
return Some(self);
|
||||
}
|
||||
let read = mem.read(cpu_addr);
|
||||
writeln!(
|
||||
&mut cpu.debug_log,
|
||||
"OAM DMA read {:04X} {:02X}",
|
||||
cpu_addr, read
|
||||
)
|
||||
.unwrap();
|
||||
Some(DmaState::Running {
|
||||
cpu_addr,
|
||||
rem,
|
||||
read: Some(read),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CycleResult {
|
||||
|
||||
Reference in New Issue
Block a user