summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mknes.c6
-rw-r--r--mknes.h1
-rw-r--r--ppu.c283
3 files changed, 51 insertions, 239 deletions
diff --git a/mknes.c b/mknes.c
index 9a91376..5fbea56 100644
--- a/mknes.c
+++ b/mknes.c
@@ -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);
diff --git a/mknes.h b/mknes.h
index b8bf87f..2d04add 100644
--- a/mknes.h
+++ b/mknes.h
@@ -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];
diff --git a/ppu.c b/ppu.c
index 02de73a..d67cff3 100644
--- a/ppu.c
+++ b/ppu.c
@@ -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;
}
}