summaryrefslogtreecommitdiff
path: root/mknes.c
diff options
context:
space:
mode:
Diffstat (limited to 'mknes.c')
-rw-r--r--mknes.c199
1 files changed, 71 insertions, 128 deletions
diff --git a/mknes.c b/mknes.c
index b5f05d3..7220450 100644
--- a/mknes.c
+++ b/mknes.c
@@ -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