summaryrefslogtreecommitdiff
path: root/ppu_registers.c
diff options
context:
space:
mode:
Diffstat (limited to 'ppu_registers.c')
-rw-r--r--ppu_registers.c107
1 files changed, 103 insertions, 4 deletions
diff --git a/ppu_registers.c b/ppu_registers.c
index c698bf2..b426f17 100644
--- a/ppu_registers.c
+++ b/ppu_registers.c
@@ -2,6 +2,69 @@ __attribute__((always_inline, hot))
static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t value) {
struct ppu_state *ppu = &state->ppu;
+ uint32_t reg = offset & 0x7;
+
+ if(reg == 0) {
+ ppu->reg_ctrl = value;
+ ppu->temp_addr = (ppu->temp_addr & 0xf3ff) | ((value & 0x03) << 10);
+ // ppu->open_bus = value;
+
+ } else if(reg == 1) {
+ ppu->reg_mask = value;
+ // ppu->open_bus = value;
+
+ } else if(reg == 3) {
+ ppu->oam_addr = value;
+ // ppu->open_bus = value;
+
+ } else if(reg == 4) {
+ ppu->oam[ppu->oam_addr++] = value;
+ // ppu->open_bus = value;
+
+ } else if(reg == 5) {
+ if(ppu->write_latch == 0) {
+ ppu->fine_x = value & 0x07;
+ ppu->temp_addr = (ppu->temp_addr & ~0x001f) | (value >> 3);
+ ppu->write_latch = 1;
+ } else {
+ ppu->temp_addr = (ppu->temp_addr & ~0x73e0) | ((value & 0x07) << 12) | ((value & 0xf8) << 2);
+ ppu->write_latch = 0;
+ }
+ // ppu->open_bus = value;
+
+ } else if(reg == 6) {
+ if(ppu->write_latch == 0) {
+ ppu->temp_addr = (ppu->temp_addr & 0x00ff) | ((value & 0x3f) << 8);
+ ppu->write_latch = 1;
+ } else {
+ ppu->temp_addr = (ppu->temp_addr & 0xff00) | value;
+ ppu->vram_addr = ppu->temp_addr;
+ ppu->write_latch = 0;
+ }
+ // ppu->open_bus = value;
+
+ } else if(reg == 7) {
+ uint32_t addr = ppu->vram_addr;
+ if(LIKELY(addr < 0x2000)) {
+ state->mapper.chr_write(state, addr, value);
+
+ } else if(LIKELY(addr < 0x3f00)) {
+ state->mapper.ciram_write(state, addr, value);
+
+ } else if(addr < 0x4000) {
+ uint32_t pal_addr = addr & 0x1f;
+ if((pal_addr & 3) == 0) {
+ pal_addr &= ~0x10;
+ }
+ ppu->palette[pal_addr] = value;
+ }
+ ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1;
+ // ppu->open_bus = value;
+ }
+
+ ppu->open_bus = value;
+
+#if 0
switch(offset & 7) {
case 0: { // 2000
ppu->reg_ctrl = value;
@@ -67,6 +130,7 @@ static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t v
ppu->open_bus = value;
} break;
}
+#endif
}
__attribute__((always_inline, hot))
@@ -74,6 +138,39 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) {
struct ppu_state *ppu = &state->ppu;
uint8_t result = ppu->open_bus;
+ uint32_t reg = offset & 0x7;
+
+ if(reg == 2) {
+ result = ppu->reg_status;
+ ppu->reg_status &= ~0x80;
+ ppu->write_latch = 0;
+
+ } else if(reg == 4) {
+ result = ppu->oam[ppu->oam_addr];
+
+ } else if(reg == 7) {
+ uint32_t addr = ppu->vram_addr;
+
+ if(LIKELY(addr < 0x2000)) {
+ result = ppu->vram_read_buffer;
+ ppu->vram_read_buffer = state->mapper.chr_read(state, addr);
+
+ } else if(LIKELY(addr < 0x3f00)) {
+ result = ppu->vram_read_buffer;
+ ppu->vram_read_buffer = state->mapper.ciram_read(state, addr);
+
+ } else if(addr < 0x4000) {
+ uint32_t pal_addr = addr & 0x1f;
+ if((pal_addr & 0x13) == 0x10) {
+ pal_addr &= ~0x10;
+ }
+ result = ppu->palette[pal_addr];
+ }
+
+ ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1;
+ }
+
+#if 0
switch(offset & 7) {
case 2: { // 2002
result = ppu->reg_status;
@@ -107,6 +204,8 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) {
ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1;
} break;
}
+# endif
+
ppu->open_bus = result;
return result;
}
@@ -118,9 +217,9 @@ static void ppu_dma_4014(struct nes_state *state, uint8_t page) {
uint32_t base = page << 8;
// Add 1 or 2 idle cycles depending on current CPU cycle
- uint8_t idle_cycles = (state->cycles & 1) ? 1 : 2;
+ uint8_t idle_cycles = (state->cpu.cycles & 1) ? 1 : 2;
for(uint8_t i = 0; i < idle_cycles; i++) {
- state->cycles++;
+ state->cpu.cycles++;
ppu_tick(state);
// apu_tick(state);
}
@@ -128,12 +227,12 @@ static void ppu_dma_4014(struct nes_state *state, uint8_t page) {
for(uint32_t i = 0; i < 256; i++) {
uint32_t addr = base + i;
- state->cycles++;
+ state->cpu.cycles++;
ppu_tick(state);
// apu_tick(state);
uint8_t value = memory_read_dma(state, addr);
- state->cycles++;
+ state->cpu.cycles++;
ppu_tick(state);
// apu_tick(state);