|
- #include <stdio.h>
-
- #include "nes.h"
- #include "mapper.h"
-
-
- uint8_t nes_mem_read(nes* sys, uint16_t addr) {
- uint8_t val = 0;
-
- if (addr < nes_mem_ppu_start) {
- addr = (addr - nes_mem_ram_start) & (nes_mem_ram_size - 1);
- val = sys->ram[addr];
-
- } else if (addr < nes_mem_apu_start) {
- addr = (addr - nes_mem_ppu_start) & (nes_ppu_map_size - 1);
- val = nes_ppu_read(&sys->ppu, nes_mem_ppu_start + addr);
-
- } else if ( nes_input_1_reg == addr ||
- nes_input_2_reg == addr) {
- val = nes_input_read(&sys->input, addr);
-
- } else if (addr < nes_mem_exp_start) {
- val = nes_apu_read(&sys->apu, addr);
-
- } else {
- val = nes_map_read(sys->cart.mapper, addr);
- }
-
- return val;
- }
-
- void nes_mem_write(nes* sys, uint16_t addr, uint8_t val) {
- if (addr < nes_mem_ppu_start) {
- addr = (addr - nes_mem_ram_start) & (nes_mem_ram_size - 1);
- sys->ram[addr] = val;
-
- } else if (addr < nes_mem_apu_start) {
- addr = (addr - nes_mem_ppu_start) & (nes_ppu_map_size - 1);
- nes_ppu_write(&sys->ppu, nes_mem_ppu_start + addr, val);
-
- } else if (nes_ppu_dma_reg == addr) {
- OAM_LOG("PPU: OAM DMA $%02x00 > $%02x\n", val, sys->ppu.oam_addr);
- uint8_t* buf = (uint8_t*)sys->ppu.oam;
- for (int i = 0; i < nes_ppu_oam_size; ++i) {
- buf[(uint8_t)(i + sys->ppu.oam_addr)] =
- nes_mem_read(sys, ((uint16_t)val << 8) + i);
- }
- sys->cpu.cycle += 513U;
- // Other subsystem cycles are driven by CPU cycles
-
- } else if (addr == nes_input_set_reg) {
- nes_input_write(&sys->input, addr, val);
-
- } else if (addr < nes_mem_exp_start) {
- nes_apu_write(&sys->apu, addr, val);
-
- } else {
- nes_map_write(sys->cart.mapper, addr, val);
- }
- }
-
- static void nes_irq(void* sys, int active) {
- e6502_set_irq(&((nes*)sys)->cpu, active);
- }
-
- int nes_init(nes* sys, int audio_freq) {
- e6502_init(&sys->cpu, (e6502_Read*)nes_mem_read,
- (e6502_Write*)nes_mem_write, sys);
- nes_map_set_irq(sys->cart.mapper, nes_irq, sys);
- nes_ppu_init(&sys->ppu, &sys->cart);
- return nes_apu_init(
- &sys->apu,
- nes_clock_master_num / nes_clock_master_den,
- audio_freq,
- (uint8_t(*)(void*, uint16_t))nes_mem_read,
- sys
- );
- }
-
- void nes_reset(nes* sys) {
- e6502_reset(&sys->cpu);
- nes_ppu_reset(&sys->ppu);
- nes_apu_reset(&sys->apu);
- }
-
- nes_ppu_Result nes_step(nes* sys, int* run) {
- nes_ppu_Result result = ppu_Result_Halt;
-
- int cpu_run = e6502_step(&sys->cpu);
-
- if (cpu_run > 0) {
- int master_cycles = cpu_run * nes_clock_cpu_div;
-
- nes_apu_Result aresult = nes_apu_run(&sys->apu,
- master_cycles);
-
- // TODO: Does this conflict with MMC3?
- e6502_set_irq(&sys->cpu, aresult == apu_Result_IRQ);
-
- int ppu_cycles = master_cycles / nes_clock_ppu_div;
- result = nes_ppu_run(&sys->ppu, ppu_cycles);
-
- if (result == ppu_Result_VBlank_On) {
- e6502_set_nmi(&sys->cpu, 1);
- } else if (result == ppu_Result_VBlank_Off) {
- e6502_set_nmi(&sys->cpu, 0);
- }
-
- if (run) *run = master_cycles;
- }
-
- return result;
- }
|