diff options
| -rw-r--r-- | mknes.c | 6 | ||||
| -rw-r--r-- | mknes.h | 1 | ||||
| -rw-r--r-- | ppu.c | 283 |
3 files changed, 51 insertions, 239 deletions
@@ -116,7 +116,7 @@ int main(int argc, char **argv) { // ines2_load(&nstate, "data/nrom/Excitebike (Japan, USA).nes"); // ines2_load(&nstate, "data/nrom/Ice Climber (USA, Europe, Korea).nes"); // ines2_load(&nstate, "data/nrom/Kung Fu (Japan, USA).nes"); - // ines2_load(&nstate, "data/nrom/Super Mario Bros. (World) (HVC-SM).nes"); + ines2_load(&nstate, "data/nrom/Super Mario Bros. (World) (HVC-SM).nes"); // ines2_load(&nstate, "data/nrom/Urban Champion (World).nes"); // ines2_load(&nstate, "data/nrom/Wrecking Crew (World).nes"); // ines2_load(&nstate, "data/nrom/scanline.nes"); @@ -132,7 +132,7 @@ int main(int argc, char **argv) { // ines2_load(&nstate, "data/nrom/raster_demos/RasterTest3e.NES"); // ines2_load(&nstate, "data/nrom/NEStress.NES"); // ines2_load(&nstate, "data/tv.nes"); - ines2_load(&nstate, "data/Super Mario Bros. (World) (HVC-SM).zip"); + // ines2_load(&nstate, "data/Super Mario Bros. (World) (HVC-SM).zip"); // ines2_load(&nstate, "data/Super Mario Bros. + Duck Hunt (USA).zip"); mapper_setup(&nstate); @@ -173,7 +173,7 @@ int main(int argc, char **argv) { } } - set_decay(20); + set_decay(40); timer_start(timer); @@ -33,6 +33,7 @@ struct ppu_state { uint8_t bg_next_tile_msb; uint8_t oam_addr; uint8_t oam_data; + uint8_t even_frame; uint8_t pixels[256 * 240] __attribute__((aligned(64))); uint8_t oam[256]; @@ -266,92 +266,75 @@ __attribute__((hot, flatten)) static void ppu_tick(struct nes_state *state) { struct ppu_state *ppu = &state->ppu; + uint32_t dot = ppu->dot; + uint32_t scanline = ppu->scanline; + uint8_t rendering = (ppu->reg_mask & 0x18); + for(uint32_t ppu_loops = 0; ppu_loops < 3; ++ppu_loops) { - uint32_t dot = ppu->dot; - uint32_t scanline = ppu->scanline; - uint8_t rendering = (ppu->reg_mask & 0x18); + if(LIKELY(rendering)) { -#if 1 -if(rendering) { - switch(scanline) { - case 0 ... 239: { - // if(rendering && (dot >= 1 && dot <= 256)) { - // } + if(ppu->even_frame && dot == 0) { + // call mapper_tick here. + ppu->dot++; + } - switch(dot) { - case 1 ... 256: - ppu_render_pixel(state); + if(scanline < 240 && dot >= 1 && dot <= 256) { + ppu_render_pixel(state); + } + if((dot >= 1 && dot <= 256) || (dot >= 321 && dot <= 336)) { - if(dot == 256) { - if((ppu->vram_addr & 0x7000) != 0x7000) { - ppu->vram_addr += 0x1000; + if(ppu->reg_mask & 0x10) { + for(uint32_t i = 0; i < ppu->sprite_count; i++) { + if(ppu->sprite_positions[i] > 0) { + ppu->sprite_positions[i]--; } else { - ppu->vram_addr &= ~0x7000; - uint32_t y = (ppu->vram_addr & 0x03e0) >> 5; - if(y == 29) { - y = 0; - ppu->vram_addr ^= 0x0800; - } else if(y == 31) { - y = 0; - } else { - y++; - } - ppu->vram_addr = (ppu->vram_addr & ~0x03e0) | (y << 5); + ppu->sprite_shift_lo[i] <<= 1; + ppu->sprite_shift_hi[i] <<= 1; } } + } - __attribute__((fallthrough)); - case 321 ... 336: { - - if(rendering && ((dot >= 1 && dot <= 256) || (dot >= 321 && dot <= 336))) { - if(ppu->reg_mask & 0x10) { - for(uint32_t i = 0; i < ppu->sprite_count; i++) { - if(ppu->sprite_positions[i] > 0) { - ppu->sprite_positions[i]--; - } else { - ppu->sprite_shift_lo[i] <<= 1; - ppu->sprite_shift_hi[i] <<= 1; - } - } - } + ppu->bg_shift_pattern_low <<= 1; + ppu->bg_shift_pattern_high <<= 1; + ppu->bg_shift_attrib_low <<= 1; + ppu->bg_shift_attrib_high <<= 1; + } - ppu->bg_shift_pattern_low <<= 1; - ppu->bg_shift_pattern_high <<= 1; - ppu->bg_shift_attrib_low <<= 1; - ppu->bg_shift_attrib_high <<= 1; - } + if(scanline < 240 || scanline == 261) { + if((dot >= 1 && dot <= 256) || (dot >= 321 && dot <= 336)) { switch(dot % 8) { case 1: { uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff); ppu->bg_next_tile_id = state->mapper.ciram_read(state, nt_addr); - } break; + break; + } case 3: { - uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | - ((ppu->vram_addr >> 4) & 0x38) | - ((ppu->vram_addr >> 2) & 0x07); + uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07); uint8_t attr = state->mapper.ciram_read(state, attr_addr & 0x0fff); uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2); ppu->bg_next_tile_attrib = (attr >> shift) & 3; - } break; + break; + } case 5: { uint32_t base = (ppu->reg_ctrl & 0x10) ? 0x1000 : 0x0000; uint32_t tile = ppu->bg_next_tile_id; uint32_t fine_y = (ppu->vram_addr >> 12) & 7; uint32_t addr_lsb = (base + tile * 16 + fine_y) & 0x1fff; ppu->bg_next_tile_lsb = state->mapper.chr_read(state, addr_lsb); - } break; + break; + } case 7: { uint32_t base = (ppu->reg_ctrl & 0x10) ? 0x1000 : 0x0000; uint32_t tile = ppu->bg_next_tile_id; uint32_t fine_y = (ppu->vram_addr >> 12) & 7; uint32_t addr_msb = (base + tile * 16 + fine_y + 8) & 0x1fff; - ppu->bg_next_tile_msb = state->mapper.chr_read(state, addr_msb); - - } break; + ppu->bg_next_tile_msb = state->mapper.chr_read(state, addr_msb); + break; + } case 0: { ppu->bg_shift_pattern_low = (ppu->bg_shift_pattern_low & 0xff00) | ppu->bg_next_tile_lsb; ppu->bg_shift_pattern_high = (ppu->bg_shift_pattern_high & 0xff00) | ppu->bg_next_tile_msb; @@ -366,148 +349,12 @@ if(rendering) { } else { ppu->vram_addr++; } - } break; - } - } break; - - case 257: { - ppu->vram_addr = (ppu->vram_addr & ~0x041f) | (ppu->temp_addr & 0x041f); - ppu_evaluate_sprites(state); - break; - } - - case 340: { - ppu_fetch_sprite_patterns(state); - break; - } - } - } break; - - // case 241: { - // if(dot == 1) { - // ppu->reg_status |= 0x80; - // if(ppu->reg_ctrl & 0x80) { - // state->nmi_pending = 1; - // } - // } - // } break; - - // case 261: { - // if(dot == 1) { - // ppu->reg_status &= ~0x80; - // ppu->reg_status &= ~0x40; - // ppu->sprite_zero_hit_possible = 0; - // } - - // if(dot >= 280 && dot <= 304) { - // ppu->vram_addr = (ppu->vram_addr & ~0x7be0) | (ppu->temp_addr & 0x7be0); - // } - - // if(dot == 340) { - // ppu_fetch_sprite_patterns(state); - // } - // } break; - - // // Handle the frame rendering - // if(++dot > 340) { - // dot = 0; - // scanline++; - // if(scanline > 261) { - // scanline = 0; - // ppu->frame_ready = 1; - // } - // } - - // ppu->dot = dot; - // ppu->scanline = scanline; - } -} - -#else - - // if(ppu->even_frame && (ppu->reg_mask & 0x18)) { - // // skip this dot - // // call mapper_tick here. - // ppu->dot++; - // } - - - if(rendering && scanline < 240 && dot >= 1 && dot <= 256) { - ppu_render_pixel(state); - } - - if(rendering && ((dot >= 1 && dot <= 256) || (dot >= 321 && dot <= 336))) { - - if(ppu->reg_mask & 0x10) { - for(uint32_t i = 0; i < ppu->sprite_count; i++) { - if(ppu->sprite_positions[i] > 0) { - ppu->sprite_positions[i]--; - } else { - ppu->sprite_shift_lo[i] <<= 1; - ppu->sprite_shift_hi[i] <<= 1; - } - } - } - - ppu->bg_shift_pattern_low <<= 1; - ppu->bg_shift_pattern_high <<= 1; - ppu->bg_shift_attrib_low <<= 1; - ppu->bg_shift_attrib_high <<= 1; - } - - if(scanline < 240 || scanline == 261) { - if(rendering && ((dot >= 1 && dot <= 256) || (dot >= 321 && dot <= 336))) { - switch(dot % 8) { - case 1: { - uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff); - ppu->bg_next_tile_id = state->mapper.ciram_read(state, nt_addr); - break; - } - case 3: { - uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07); - uint8_t attr = state->mapper.ciram_read(state, attr_addr & 0x0fff); - uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2); - ppu->bg_next_tile_attrib = (attr >> shift) & 3; - break; - } - case 5: { - uint32_t base = (ppu->reg_ctrl & 0x10) ? 0x1000 : 0x0000; - uint32_t tile = ppu->bg_next_tile_id; - uint32_t fine_y = (ppu->vram_addr >> 12) & 7; - uint32_t addr_lsb = (base + tile * 16 + fine_y) & 0x1fff; - ppu->bg_next_tile_lsb = state->mapper.chr_read(state, addr_lsb); - break; - } - case 7: { - uint32_t base = (ppu->reg_ctrl & 0x10) ? 0x1000 : 0x0000; - uint32_t tile = ppu->bg_next_tile_id; - uint32_t fine_y = (ppu->vram_addr >> 12) & 7; - uint32_t addr_msb = (base + tile * 16 + fine_y + 8) & 0x1fff; - ppu->bg_next_tile_msb = state->mapper.chr_read(state, addr_msb); - break; - } - case 0: { - ppu->bg_shift_pattern_low = (ppu->bg_shift_pattern_low & 0xff00) | ppu->bg_next_tile_lsb; - ppu->bg_shift_pattern_high = (ppu->bg_shift_pattern_high & 0xff00) | ppu->bg_next_tile_msb; - - uint8_t a = ppu->bg_next_tile_attrib; - ppu->bg_shift_attrib_low = (ppu->bg_shift_attrib_low & 0xff00) | ((a & 1) ? 0xff : 0x00); - ppu->bg_shift_attrib_high = (ppu->bg_shift_attrib_high & 0xff00) | ((a & 2) ? 0xff : 0x00); - - if((ppu->vram_addr & 0x001f) == 31) { - ppu->vram_addr &= ~0x001f; - ppu->vram_addr ^= 0x0400; - } else { - ppu->vram_addr++; + break; } - - break; } } - } - if(rendering) { if(dot == 256) { if((ppu->vram_addr & 0x7000) != 0x7000) { ppu->vram_addr += 0x1000; @@ -543,56 +390,19 @@ if(rendering) { } } } -#endif - - - -// TEST SWITCH CODE - switch(scanline) { - case 241: { - if(dot == 1) { - ppu->reg_status |= 0x80; - if(ppu->reg_ctrl & 0x80) { - state->nmi_pending = 1; - } + if(UNLIKELY(scanline == 241) && dot == 1) { + ppu->reg_status |= 0x80; + if(ppu->reg_ctrl & 0x80) { + state->nmi_pending = 1; } - break; } - case 261: { - if(dot == 1) { - ppu->reg_status &= ~0x80; - ppu->reg_status &= ~0x40; - ppu->sprite_zero_hit_possible = 0; - } - - if(dot >= 280 && dot <= 304) { - ppu->vram_addr = (ppu->vram_addr & ~0x7be0) | (ppu->temp_addr & 0x7be0); - } - - if(dot == 340) { - ppu_fetch_sprite_patterns(state); - } - break; + if(UNLIKELY(scanline == 261) && dot == 1) { + ppu->reg_status &= ~0x80; + ppu->reg_status &= ~0x40; + ppu->sprite_zero_hit_possible = 0; } - } - - -// TEST SWITCH CODE - - // if(UNLIKELY(scanline == 241) && dot == 1) { - // ppu->reg_status |= 0x80; - // if(ppu->reg_ctrl & 0x80) { - // state->nmi_pending = 1; - // } - // } - - // if(UNLIKELY(scanline == 261) && dot == 1) { - // ppu->reg_status &= ~0x80; - // ppu->reg_status &= ~0x40; - // ppu->sprite_zero_hit_possible = 0; - // } dot++; if(dot > 340) { @@ -601,6 +411,7 @@ if(rendering) { if(scanline > 261) { scanline = 0; ppu->frame_ready = 1; + ppu->even_frame = !ppu->even_frame; } } |
