diff options
Diffstat (limited to 'mknes.c')
| -rw-r--r-- | mknes.c | 199 |
1 files changed, 71 insertions, 128 deletions
@@ -13,8 +13,8 @@ #define WINDOW_WIDTH 320 * 3 #define WINDOW_HEIGHT 240 * 3 -#define PRG_ROM_SIZE (512 * 1024) -#define CHR_ROM_SIZE (512 * 1024) +#define PRG_ROM_SIZE (2 * 1024 * 1024) +#define CHR_ROM_SIZE (1 * 1024 * 1024) #define PIXELS_SIZE (256 * 240) #define RAM_SIZE 0x1000 // 0x800 in reality, but for aligned alloc it must be the size of the alignment (4096) #define SRAM_SIZE 0x2000 @@ -104,62 +104,8 @@ static uint32_t frames; // debug information #include "mappers/mapper.c" #include "callbacks.c" -struct nes_state nstate; - - -static struct nes_state *allocate_nes_state(void) { - struct nes_state *state = (struct nes_state*)calloc(1, sizeof(struct nes_state)); - if(!state) return 0; - - state->prg_rom = aligned_alloc(4096, PRG_ROM_SIZE); - state->chr_rom = aligned_alloc(4096, CHR_ROM_SIZE); - state->pixels = aligned_alloc(4096, PIXELS_SIZE); - state->ram = aligned_alloc(4096, RAM_SIZE); - state->sram = aligned_alloc(4096, SRAM_SIZE); - state->ciram = aligned_alloc(4096, CIRAM_SIZE); - state->chr_ram = aligned_alloc(4096, CHR_RAM_SIZE); - memset(state->prg_rom, 0, PRG_ROM_SIZE); - memset(state->chr_rom, 0, CHR_ROM_SIZE); - memset(state->pixels, 0, PIXELS_SIZE); - memset(state->ram, 0, RAM_SIZE); - memset(state->sram, 0, SRAM_SIZE); - memset(state->ciram, 0, CIRAM_SIZE); - memset(state->chr_ram, 0, CHR_RAM_SIZE); - return state; -} - -static void free_nes_state(struct nes_state *s) { - free(s->prg_rom); - free(s->chr_rom); - free(s->pixels); - free(s->ram); - free(s->sram); - free(s->ciram); - free(s->chr_ram); - free(s); -} - - - - -static void dump_nametable_text(struct nes_state *state, const char *filename) { - FILE *f = fopen(filename, "w"); - if(!f) return; - - for(int y = 0; y < 30; y++) { - for(int x = 0; x < 32; x++) { - uint16_t addr = y * 32 + x; - uint8_t tile = state->ciram[addr]; // assuming NT0 is mapped to 0x000 - fprintf(f, "%02x ", tile); - } - fprintf(f, "\n"); - } - fclose(f); -} - - - +struct nes_state nstate; int main(int argc, char **argv) { #ifdef _WIN32 @@ -167,70 +113,72 @@ int main(int argc, char **argv) { #endif state.toggle_crt_emulation = 1; - struct nes_state *nstate = allocate_nes_state(); setbuf(stdout, 0); init_opcode_lut(); init_opcode_ud_lut(); // protect_opcode_lut(); - ppu_reset(nstate); - // ines2_load(nstate, "data/0000/10-Yard Fight (USA, Europe).nes"); - // ines2_load(nstate, "data/0000/Balloon Fight (USA).nes"); - // ines2_load(nstate, "data/0000/Excitebike (Japan, USA).nes"); - // ines2_load(nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes"); - // ines2_load(nstate, "data/0000/Kung Fu (Japan, USA).nes"); - ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).nes"); - // ines2_load(nstate, "data/Super Mario Bros. (W) (V1.0) [!].nes"); - // ines2_load(nstate, "data/Super Mario Bros. (JU) [!].nes"); - // ines2_load(nstate, "data/0000/Urban Champion (World).nes"); - // ines2_load(nstate, "data/0000/Wrecking Crew (World).nes"); - // ines2_load(nstate, "data/0000/scanline.nes"); - // ines2_load(nstate, "data/0000/Sayoonara!.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterChromaLuma.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest1.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest2.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3a.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3b.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3c.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3d.NES"); - // ines2_load(nstate, "data/0000/raster_demos/RasterTest3e.NES"); - // ines2_load(nstate, "data/0000/NEStress.NES"); - // ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).zip"); - // ines2_load(nstate, "data/0042/Super Mario Bros. + Duck Hunt (USA).zip"); - // ines2_load(nstate, "data/0000/Xevious - The Avenger (USA).zip"); - // ines2_load(nstate, "data/tv.nes"); - - // ines2_load(nstate, "data/Life Force (USA).zip"); // 2002 - - // ines2_load(nstate, "data/0003/Flipull - An Exciting Cube Game (Japan) (En).zip"); - // ines2_load(nstate, "data/0003/Friday the 13th (USA).zip"); - // ines2_load(nstate, "data/0003/Ghostbusters (Japan).zip"); - ines2_load(nstate, "data/0003/Gradius (USA).zip"); - // ines2_load(nstate, "data/0007/Battletoads (USA).zip"); - // ines2_load(nstate, "data/0007/Beetlejuice (USA).zip"); - // ines2_load(nstate, "data/0007/Cabal (USA).zip"); - - // ines2_load(nstate, "data/000b/Baby Boomer (USA) (Unl).zip"); - // ines2_load(nstate, "data/000b/Captain Comic - The Adventure (USA) (Unl).zip"); - // ines2_load(nstate, "data/000b/King Neptune's Adventure (USA) (Unl).zip"); - - // ines2_load(nstate, "data/2002/Attack Animal Gakuen (Japan).zip"); - // ines2_load(nstate, "data/2002/Ballblazer (Japan).zip"); - // ines2_load(nstate, "data/2002/Best of the Best - Championship Karate (USA).zip"); - - mapper_setup(nstate); - uint32_t lo = nstate->mapper.prg_read(nstate, 0xfffc); - uint32_t hi = nstate->mapper.prg_read(nstate, 0xfffd); - nstate->cpu.pc = (hi << 8) | lo; - -#if 0 + ppu_reset(&nstate); + // ines2_load(&nstate, "data/0000/10-Yard Fight (USA, Europe).nes"); + // ines2_load(&nstate, "data/0000/Balloon Fight (USA).nes"); + // ines2_load(&nstate, "data/0000/Excitebike (Japan, USA).nes"); + // ines2_load(&nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes"); + // ines2_load(&nstate, "data/0000/Kung Fu (Japan, USA).nes"); + ines2_load(&nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).nes"); + // ines2_load(&nstate, "data/Super Mario Bros. (W) (V1.0) [!].nes"); + // ines2_load(&nstate, "data/Super Mario Bros. (JU) [!].nes"); + // ines2_load(&nstate, "data/0000/Urban Champion (World).nes"); + // ines2_load(&nstate, "data/0000/Wrecking Crew (World).nes"); + // ines2_load(&nstate, "data/0000/scanline.nes"); + // ines2_load(&nstate, "data/0000/Sayoonara!.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterChromaLuma.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest1.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest2.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3a.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3b.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3c.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3d.NES"); + // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3e.NES"); + // ines2_load(&nstate, "data/0000/NEStress.NES"); + // ines2_load(&nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).zip"); + // ines2_load(&nstate, "data/0042/Super Mario Bros. + Duck Hunt (USA).zip"); + // ines2_load(&nstate, "data/0000/Xevious - The Avenger (USA).zip"); + // ines2_load(&nstate, "data/tv.nes"); + + ines2_load(&nstate, "data/Life Force (USA).zip"); // 2002 + + // ines2_load(&nstate, "data/0003/Flipull - An Exciting Cube Game (Japan) (En).zip"); + // ines2_load(&nstate, "data/0003/Friday the 13th (USA).zip"); + // ines2_load(&nstate, "data/0003/Ghostbusters (Japan).zip"); + // ines2_load(&nstate, "data/0003/Gradius (USA).zip"); + // ines2_load(&nstate, "data/0007/Battletoads (USA).zip"); + // ines2_load(&nstate, "data/0007/Beetlejuice (USA).zip"); + // ines2_load(&nstate, "data/0007/Cabal (USA).zip"); + + // ines2_load(&nstate, "data/000b/Baby Boomer (USA) (Unl).zip"); + // ines2_load(&nstate, "data/000b/Captain Comic - The Adventure (USA) (Unl).zip"); + // ines2_load(&nstate, "data/000b/King Neptune's Adventure (USA) (Unl).zip"); + + // ines2_load(&nstate, "data/2002/Attack Animal Gakuen (Japan).zip"); + // ines2_load(&nstate, "data/2002/Ballblazer (Japan).zip"); + // ines2_load(&nstate, "data/2002/Best of the Best - Championship Karate (USA).zip"); + + // ines2_load(&nstate, "data/Blaster Master (USA).zip"); + + + mapper_setup(&nstate); + uint32_t lo = nstate.mapper.prg_read(&nstate, 0xfffc); + uint32_t hi = nstate.mapper.prg_read(&nstate, 0xfffd); + nstate.cpu.pc = (hi << 8) | lo; + +#if 1 for(uint32_t i = 0; i < 0x5000; ++ i) { - while(!nstate->ppu.frame_ready) { + while(!nstate.ppu.frame_ready) { // PROFILE_NAMED("nes emulator"); - cpu_tick(nstate); + cpu_tick(&nstate); } - nstate->ppu.frame_ready = 0; + nstate.ppu.frame_ready = 0; frames++; } return 0; @@ -250,8 +198,8 @@ int main(int argc, char **argv) { window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "NES Emulator", 0, 0); if(window) { - glfwSetWindowUserPointer(window, (void*)nstate); - glfwSetWindowAspectRatio(window, 320, 240); // Need to set a 4:3 resolution for it to look correct! + glfwSetWindowUserPointer(window, (void*)&nstate); + glfwSetWindowAspectRatio(window, 320, 240); // Need to set a 4:3 resolution for things to look correct! glfwSetWindowSizeLimits(window, WINDOW_WIDTH, WINDOW_HEIGHT, GLFW_DONT_CARE, GLFW_DONT_CARE); glfwMakeContextCurrent(window); @@ -278,22 +226,15 @@ int main(int argc, char **argv) { timer_wait(timer); glfwPollEvents(); -// printf("Frame: %d\n", frames); - - -// static int32_t tas_frame = 0; -// nstate->input[0] = tas_input[tas_frame++]; - while(!nstate->ppu.frame_ready) { + while(!nstate.ppu.frame_ready) { // PROFILE_NAMED("nes emulator"); - cpu_tick(nstate); + cpu_tick(&nstate); } - nstate->ppu.frame_ready = 0; + nstate.ppu.frame_ready = 0; frames++; -// dump_nametable_text(nstate, "_foofbomb.txt"); - uint32_t * restrict dst = display_buffer; //buffer; - uint8_t * restrict src = nstate->pixels; + uint8_t * restrict src = nstate.pixels; for(uint32_t y = 0; y < 240; ++y) { for(uint32_t x = 0; x < 256; ++x) { uint8_t val = *src++; @@ -306,8 +247,10 @@ int main(int argc, char **argv) { render_frame(); glfwSwapBuffers(window); } -printf("total frames: %6.6d total cycles: %ld\n", frames, nstate->cpu.cycles); + + printf("total frames: %6.6d total cycles: %ld\n", frames, nstate.cpu.cycles); glfwDestroyWindow(window); + } else { fprintf(stderr, "Failed to create window\n"); } @@ -317,7 +260,7 @@ printf("total frames: %6.6d total cycles: %ld\n", frames, nstate->cpu.cycles); fprintf(stderr, "Failed to initialize GLFW\n"); } timer_destroy(timer); - free_nes_state(nstate); + // free_nes_state(&nstate); #ifdef _WIN32 timeEndPeriod(1); #endif |
