static uint8_t memory_read(struct nes_state *restrict state, uint32_t offset) { state->cycle++; ppu_tick(state); ppu_tick(state); ppu_tick(state); // state->ram[0x301] = 0x1; if(offset < 0x2000) { return state->ram[offset & 0x07ff]; } else if(offset < 0x4000) { switch(offset & 7) { case 2: return ppu_read_2002(state); case 4: return ppu_read_2004(state); case 7: return ppu_read_2007(state); default: return 0; } } else if(offset < 0x4020) { // TODO: APU and I/O reads return 0; } else if(offset >= 0x6000) { return state->mapper.read(state, offset); } else { return 0; } } static void memory_write(struct nes_state *restrict state, uint32_t offset, uint8_t value) { state->cycle++; ppu_tick(state); ppu_tick(state); ppu_tick(state); // if(offset == 0x0300) { // printf("WRITE $0300 = %02x @ PC=%04x\n", value, state->cpu.pc); // } if(offset < 0x2000) { state->ram[offset & 0x07ff] = value; } else if(offset < 0x4000) { switch(offset & 7) { case 0: ppu_write_2000(state, value); break; case 1: ppu_write_2001(state, value); break; case 3: ppu_write_2003(state, value); break; case 4: ppu_write_2004(state, value); break; case 5: ppu_write_2005(state, value); break; case 6: ppu_write_2006(state, value); break; case 7: ppu_write_2007(state, value); break; default: break; } } else if(offset == 0x4014) { ppu_dma_4014(state, value); } else if(offset < 0x4020) { // TODO: APU and I/O writes } else if(offset >= 0x6000) { state->mapper.write(state, offset, value); } } static uint8_t memory_read_dma(struct nes_state *restrict state, uint32_t offset) { // Do not tick CPU/PPU/APU — caller handles timing if(offset < 0x2000) { return state->ram[offset & 0x07ff]; } else if(offset < 0x4000) { // PPU register reads are ignored during DMA return 0; } else if(offset < 0x4020) { // APU and I/O — usually ignored or blocked during DMA return 0; } else if(offset >= 0x6000) { return state->mapper.read(state, offset); } else { return 0; } } static uint8_t memory_read_dummy(struct nes_state *restrict state, uint32_t offset) { state->cycle++; ppu_tick(state); ppu_tick(state); ppu_tick(state); if(offset < 0x2000) { return 0; } else if(offset < 0x4000) { switch(offset & 7) { case 2: return ppu_read_2002(state); case 7: return ppu_read_2007(state); default: return 0; } } else if(offset < 0x4020) { return 0; } else if(offset >= 0x6000) { return state->mapper.read(state, offset); } else { return 0; } }