2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::op_read(uint16 addr) -> uint8 {
|
2012-04-28 06:35:51 +00:00
|
|
|
if(status.oam_dma_pending) {
|
|
|
|
status.oam_dma_pending = false;
|
|
|
|
op_read(addr);
|
|
|
|
oam_dma();
|
|
|
|
}
|
|
|
|
|
|
|
|
while(status.rdy_line == 0) {
|
2013-05-05 09:21:30 +00:00
|
|
|
regs.mdr = bus.read(status.rdy_addr_valid ? status.rdy_addr_value : addr);
|
2012-04-28 06:35:51 +00:00
|
|
|
add_clocks(12);
|
|
|
|
}
|
|
|
|
|
|
|
|
regs.mdr = bus.read(addr);
|
|
|
|
add_clocks(12);
|
|
|
|
return regs.mdr;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::op_write(uint16 addr, uint8 data) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
bus.write(addr, regs.mdr = data);
|
|
|
|
add_clocks(12);
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::last_cycle() -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
status.interrupt_pending = ((status.irq_line | status.irq_apu_line) & ~regs.p.i) | status.nmi_pending;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::nmi(uint16& vector) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
if(status.nmi_pending) {
|
|
|
|
status.nmi_pending = false;
|
|
|
|
vector = 0xfffa;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::oam_dma() -> void {
|
|
|
|
for(uint n : range(256)) {
|
2012-04-28 06:35:51 +00:00
|
|
|
uint8 data = op_read((status.oam_dma_page << 8) + n);
|
|
|
|
op_write(0x2004, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::set_nmi_line(bool line) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
//edge-sensitive (0->1)
|
|
|
|
if(!status.nmi_line && line) status.nmi_pending = true;
|
|
|
|
status.nmi_line = line;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::set_irq_line(bool line) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
//level-sensitive
|
|
|
|
status.irq_line = line;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::set_irq_apu_line(bool line) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
//level-sensitive
|
|
|
|
status.irq_apu_line = line;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::set_rdy_line(bool line) -> void {
|
2012-04-28 06:35:51 +00:00
|
|
|
status.rdy_line = line;
|
|
|
|
}
|
|
|
|
|
2015-12-05 05:44:49 +00:00
|
|
|
auto CPU::set_rdy_addr(bool valid, uint16 value) -> void {
|
2013-05-05 09:21:30 +00:00
|
|
|
status.rdy_addr_valid = valid;
|
|
|
|
status.rdy_addr_value = value;
|
2012-04-28 06:35:51 +00:00
|
|
|
}
|