Skip to content

Commit

Permalink
Showing 36 changed files with 1,234 additions and 233 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@
This is yet another NES Emulator which was written so I can learn about the NES, right now it is not in the most "complete" or cleanest state.
If you want to check it out for some reason I do include a windows binary in the "Releases" tab, if you want to compile it go check out the "build" files.
You will need freeglut as well as openal-soft to compile the project, it should run on most systems since it is fairly generic C code.
NTSC and PAL NES ROMs and Mappers 0,1,2,3,4,7,9 and 10 are supported right now, it also creates .sav files if the chosen game supports saving.
NTSC and PAL .nes ROMs are supported right now, it also creates .sav files if the chosen game supports saving.
Supported Mappers: 0,1,2,3,4,7,9,10,11,13,15,36,37,38,44,46,47,66,79,87,99,101,113,133,140,144,145,146,147,148,149,185,240 and 242.
To start a game, simply drag and drop its .nes file into it or call it via command line with the .nes file as argument.
If you are starting a PAL NES title then make sure it has (E) in the name to be started in PAL mode.

2 changes: 1 addition & 1 deletion build_linux.sh
Original file line number Diff line number Diff line change
@@ -2,6 +2,6 @@

#Need to replace this with a makefile

gcc main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lglut -lopenal -lGL -lGLU -lm -Wall -Wextra -O3 -s -o fixNES
gcc main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c mapperList.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lglut -lopenal -lGL -lGLU -lm -Wall -Wextra -O3 -s -o fixNES
echo "Succesfully built fixNES"

2 changes: 1 addition & 1 deletion build_windows_console.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
gcc -DWINDOWS_BUILD main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lfreeglut_static -lopenal32 -lopengl32 -lglu32 -lgdi32 -lwinmm -Wall -Wextra -O3 -s -o fixNES
gcc -DWINDOWS_BUILD main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c mapperList.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lfreeglut_static -lopenal32 -lopengl32 -lglu32 -lgdi32 -lwinmm -Wall -Wextra -O3 -s -o fixNES
pause
2 changes: 1 addition & 1 deletion build_windows_noconsole.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
gcc -DWINDOWS_BUILD main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lfreeglut_static -lopenal32 -lopengl32 -lglu32 -lgdi32 -lwinmm -Wall -Wextra -O3 -s -o fixNES -Wl,--subsystem,windows
gcc -DWINDOWS_BUILD main.c apu.c audio.c alhelpers.c cpu.c ppu.c mem.c input.c mapper.c mapperList.c fm2play.c mapper/*.c -DFREEGLUT_STATIC -lfreeglut_static -lopenal32 -lopengl32 -lglu32 -lgdi32 -lwinmm -Wall -Wextra -O3 -s -o fixNES -Wl,--subsystem,windows
pause
16 changes: 8 additions & 8 deletions cpu.c
Original file line number Diff line number Diff line change
@@ -360,16 +360,16 @@ bool cpuCycle()
if(p_irq_req == 1)
{
#if DEBUG_INTR
printf("Setting irq disable %02x %02x %d %d %d %d line %i dot %i\n", p, P_FLAG_IRQ_DISABLE, cpu_interrupt_req, apu_interrupt,
!(p & P_FLAG_IRQ_DISABLE), (p & P_FLAG_IRQ_DISABLE) == 0, curLine, curDot);
printf("Setting irq disable %02x %02x %d %d %d %d\n", p, P_FLAG_IRQ_DISABLE, cpu_interrupt_req, apu_interrupt,
!(p & P_FLAG_IRQ_DISABLE), (p & P_FLAG_IRQ_DISABLE) == 0);
#endif
p |= P_FLAG_IRQ_DISABLE;
}
else
{
#if DEBUG_INTR
printf("Clearing irq disable %02x %02x %d %d %d %d line %i dot %i\n", p, P_FLAG_IRQ_DISABLE, cpu_interrupt_req, apu_interrupt,
!(p & P_FLAG_IRQ_DISABLE), (p & P_FLAG_IRQ_DISABLE) == 0, curLine, curDot);
printf("Clearing irq disable %02x %02x %d %d %d %d\n", p, P_FLAG_IRQ_DISABLE, cpu_interrupt_req, apu_interrupt,
!(p & P_FLAG_IRQ_DISABLE), (p & P_FLAG_IRQ_DISABLE) == 0);
#endif
p &= ~P_FLAG_IRQ_DISABLE;
}
@@ -378,7 +378,7 @@ bool cpuCycle()
if(ppu_nmi_handler_req)
{
#if DEBUG_INTR
printf("NMI from p %02x pc %04x line %i dot %i ",p,pc, curLine, curDot);
printf("NMI from p %02x pc %04x ",p,pc);
#endif
p |= P_FLAG_S2;
p &= ~P_FLAG_S1;
@@ -395,7 +395,7 @@ bool cpuCycle()
else if(cpu_interrupt_req)
{
#if DEBUG_INTR
printf("INTR %d %d %d from p %02x pc %04x line %i dot %i ",interrupt,dmc_interrupt,apu_interrupt,p,pc, curLine, curDot);
printf("INTR %d %d %d from p %02x pc %04x ",interrupt,dmc_interrupt,apu_interrupt,p,pc);
#endif
intrBackup();
p |= P_FLAG_IRQ_DISABLE;
@@ -408,7 +408,6 @@ bool cpuCycle()
waitCycles+=5;
}
uint16_t instrPtr = pc;
//printf("%04x\n", instrPtr);
/*if(intrPrintUpdate == 100)
{
printf("%04x\n", instrPtr);
@@ -417,6 +416,7 @@ bool cpuCycle()
else
intrPrintUpdate++;*/
uint8_t instr = memGet8(instrPtr);
//printf("%04x %02x\n", instrPtr, instr);
uint8_t tmp, zPage;
uint16_t absAddr, val;
pc++; waitCycles++;
@@ -825,7 +825,7 @@ bool cpuCycle()
case 0x40: //RTI
memGet8(pc);
#if DEBUG_INTR
printf("RTI from p %02x pc %04x line %i dot %i ",p,pc, curLine, curDot);
printf("RTI from p %02x pc %04x ",p,pc);
#endif
//get back p from stack
s++;
8 changes: 6 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@
#define DEBUG_KEY 0
#define DEBUG_LOAD_INFO 1

static const char *VERSION_STRING = "fixNES Alpha v0.3";
static const char *VERSION_STRING = "fixNES Alpha v0.4";

static void nesEmuDisplayFrame(void);
static void nesEmuMainLoop(void);
@@ -111,7 +111,11 @@ int main(int argc, char** argv)
((ppuScreenMode == PPU_MODE_HORIZONTAL) ? "Horizontal" : "4-Screen"));
#endif
uint8_t *prgROM = emuNesROM+16;
if(trainer) prgROM += 512;
if(trainer)
{
memcpy(emuPrgRAM+0x1000,prgROM,0x200);
prgROM += 512;
}
uint8_t *chrROM = NULL;
if(chrROMsize)
{
25 changes: 2 additions & 23 deletions mapper.c
Original file line number Diff line number Diff line change
@@ -8,15 +8,8 @@
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
#include "mapper/m0.h"
#include "mapper/m1.h"
#include "mapper/m2.h"
#include "mapper/m3.h"
#include "mapper/m4.h"
#include "mapper/m7.h"
#include "mapper/m9.h"
#include "mapper/m10.h"
#include "mapper.h"
#include "mapperList.h"

get8FuncT mapperGet8;
set8FuncT mapperSet8;
@@ -25,23 +18,9 @@ chrGet8FuncT mapperChrGet8;
chrSet8FuncT mapperChrSet8;
cycleFuncT mapperCycle;

mapperList_t mapperList[11] = {
{ m0init, m0get8, m0set8, m0chrGet8, m0chrSet8, NULL },
{ m1init, m1get8, m1set8, m1chrGet8, m1chrSet8, NULL },
{ m2init, m2get8, m2set8, m2chrGet8, m2chrSet8, NULL },
{ m3init, m3get8, m3set8, m3chrGet8, m3chrSet8, NULL },
{ m4init, m4get8, m4set8, m4chrGet8, m4chrSet8, m4cycle },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ m7init, m7get8, m7set8, m7chrGet8, m7chrSet8, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ m9init, m9get8, m9set8, m9chrGet8, m9chrSet8, NULL },
{ m10init, m10get8, m10set8, m10chrGet8, m10chrSet8, NULL },
};

bool mapperInit(uint8_t mapper, uint8_t *prgROM, uint32_t prgROMsize, uint8_t *prgRAM, uint32_t prgRAMsize, uint8_t *chrROM, uint32_t chrROMsize)
{
if(mapper > 10 || mapperList[mapper].initF == NULL)
if(mapperList[mapper].initF == NULL)
{
printf("Unsupported Mapper!\n");
return false;
9 changes: 0 additions & 9 deletions mapper.h
Original file line number Diff line number Diff line change
@@ -16,15 +16,6 @@ typedef void (*chrSet8FuncT)(uint16_t, uint8_t);
typedef uint8_t* (*getChrFuncT)();
typedef void (*cycleFuncT)();

typedef struct _mapperList_t {
initFuncT initF;
get8FuncT get8F;
set8FuncT set8F;
chrGet8FuncT chrGet8F;
chrSet8FuncT chrSet8F;
cycleFuncT cycleFuncF;
} mapperList_t;

bool mapperInit(uint8_t mapper, uint8_t *prgROM, uint32_t prgROMsize, uint8_t *prgRAM, uint32_t prgRAMsize, uint8_t *chrROM, uint32_t chrROMsize);

extern get8FuncT mapperGet8;
64 changes: 0 additions & 64 deletions mapper/m0.c

This file was deleted.

19 changes: 0 additions & 19 deletions mapper/m0.h

This file was deleted.

9 changes: 5 additions & 4 deletions mapper/m1.c
Original file line number Diff line number Diff line change
@@ -65,9 +65,9 @@ void m1init(uint8_t *prgROMin, uint32_t prgROMsizeIn,

uint8_t m1get8(uint16_t addr)
{
if(addr < 0x8000)
if(addr >= 0x6000 && addr < 0x8000)
return m1_prgRAM[addr&0x1FFF];
else
else if(addr >= 0x8000)
{
if(m1_single_prg_bank)
{
@@ -86,17 +86,18 @@ uint8_t m1get8(uint16_t addr)
return m1_prgROM[(m1_curPRGBank&~0x3FFF)+(addr&0x3FFF)+m1_256KPRGBank];
}
}
return 0;
}

extern bool cpuWriteTMP;
void m1set8(uint16_t addr, uint8_t val)
{
if(addr < 0x8000)
if(addr >= 0x6000 && addr < 0x8000)
{
//printf("m1set8 %04x %02x\n", addr, val);
m1_prgRAM[addr&0x1FFF] = val;
}
else
else if(addr >= 0x8000)
{
// mmc1 regs cant be written to
// with just 1 cpu cycle delay
10 changes: 7 additions & 3 deletions mapper/m10.c
Original file line number Diff line number Diff line change
@@ -48,7 +48,9 @@ void m10init(uint8_t *prgROMin, uint32_t prgROMsizeIn,

uint8_t m10get8(uint16_t addr)
{
if(addr < 0x8000)
if(addr < 0x6000)
return 0;
else if(addr < 0x8000)
return m10_prgRAM[addr&0x1FFF];
else
{
@@ -61,7 +63,9 @@ uint8_t m10get8(uint16_t addr)
void m10set8(uint16_t addr, uint8_t val)
{
//printf("m10set8 %04x %02x\n", addr, val);
if(addr < 0x8000)
if(addr < 0x6000)
return;
else if(addr < 0x8000)
m10_prgRAM[addr&0x1FFF] = val;
else if(addr < 0xA000)
return;
@@ -74,7 +78,7 @@ void m10set8(uint16_t addr, uint8_t val)
else if(addr < 0xE000)
m10_curCHRBank10 = ((val&0x1F)<<12)&(m10_chrROMsize-1);
else if(addr < 0xF000)
m10_curCHRBank11 = ((val&0x1F)<<12);
m10_curCHRBank11 = ((val&0x1F)<<12)&(m10_chrROMsize-1);
else
{
if((val&1) == 0)
62 changes: 62 additions & 0 deletions mapper/m13.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2017 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

#include <stdio.h>
#include <inttypes.h>

static uint8_t *m13_prgROM;
static uint32_t m13_prgROMsize;
static uint32_t m13_curCHRBank;
static uint8_t m13_chrRAM[0x4000];

void m13init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
m13_prgROM = prgROMin;
m13_prgROMsize = prgROMsizeIn;
(void)prgRAMin;
(void)prgRAMsizeIn;
if(chrROMsizeIn > 0)
printf("m13 ???\n");
(void)chrROMin;
m13_curCHRBank = 0;
memset(m13_chrRAM,0,0x4000);
printf("Mapper 13 inited\n");
}

uint8_t m13get8(uint16_t addr)
{
if(addr < 0x8000)
return 0;
if(m13_prgROMsize == 0x8000)
return m13_prgROM[addr&0x7FFF];
return m13_prgROM[addr&0x3FFF];
}


void m13set8(uint16_t addr, uint8_t val)
{
if(addr < 0x8000)
return;
m13_curCHRBank = ((val & 3)<<12);
}

uint8_t m13chrGet8(uint16_t addr)
{
if(addr < 0x1000)
return m13_chrRAM[addr&0xFFF];
return m13_chrRAM[(m13_curCHRBank&~0xFFF)+(addr&0xFFF)];
}

void m13chrSet8(uint16_t addr, uint8_t val)
{
if(addr < 0x1000)
m13_chrRAM[addr&0xFFF] = val;
else
m13_chrRAM[(m13_curCHRBank&~0xFFF)+(addr&0xFFF)] = val;
}
Loading

0 comments on commit 36b1f81

Please sign in to comment.