Skip to content

Commit

Permalink
added .nsf playback support! just drag and drop .nsf in and change tr…
Browse files Browse the repository at this point in the history
…acks by pressing left/right in the window
  • Loading branch information
FIX94 committed Feb 10, 2017
1 parent 36b1f81 commit b751d05
Show file tree
Hide file tree
Showing 14 changed files with 396 additions and 108 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ This is yet another NES Emulator which was written so I can learn about the NES,
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 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.
Supported Mappers: 0,1,2,3,4,7,9,10,11,13,15,36,37,38,44,46,47,66,71,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.
If you are starting a PAL NES title then make sure it has (E) in the name to be started in PAL mode.
You can also listen to .nsf files by dragging them in, changing tracks works by pressing left/right.

Controls right now are keyboard only and do the following:
Y/Z is A
Expand Down
4 changes: 2 additions & 2 deletions apu.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ void apuSet8(uint8_t reg, uint8_t val)
}
else if(reg == 3)
{
//p1Cycle = 0;
p1Cycle = 0;
if(APU_IO_Reg[0x15] & P1_ENABLE)
p1LengthCtr = lengthLookupTbl[val>>3];
freq1 = (freq1&0xFF) | ((val&7)<<8);
Expand Down Expand Up @@ -553,7 +553,7 @@ void apuSet8(uint8_t reg, uint8_t val)
}
else if(reg == 7)
{
//p2Cycle = 0;
p2Cycle = 0;
if(APU_IO_Reg[0x15] & P2_ENABLE)
p2LengthCtr = lengthLookupTbl[val>>3];
freq2 = (freq2&0xFF) | ((val&7)<<8);
Expand Down
37 changes: 37 additions & 0 deletions cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <inttypes.h>
#include "mem.h"
#include "ppu.h"
#include "apu.h"

#define P_FLAG_CARRY (1<<0)
#define P_FLAG_ZERO (1<<1)
Expand Down Expand Up @@ -1913,3 +1914,39 @@ uint16_t cpuGetPc()
{
return pc;
}

void cpuPlayNSF(uint16_t addr)
{
//used in NSF mapper to detect init/play return
uint16_t initRet = 0x4567-1;
memSet8(0x100+s,initRet>>8);
s--;
memSet8(0x100+s,initRet&0xFF);
s--;
pc = addr;
//printf("Playback at %04x\n", addr);
}

void cpuInitNSF(uint16_t addr, uint8_t newA, uint8_t newX)
{
//full reset
cpuInit();
ppuInit();
memInit();
apuInit();
//do init
reset = false;
interrupt = false;
dmc_interrupt = false;
apu_interrupt = false;
p = (P_FLAG_IRQ_DISABLE | P_FLAG_S1 | P_FLAG_S2);
a = newA;
x = newX;
y = 0;
s = 0xFD;
waitCycles = 0;
//initial "play" addr is init
apuSet8(0x15,0xF);
apuSet8(0x17,0x40);
cpuPlayNSF(addr);
}
2 changes: 2 additions & 0 deletions cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#define _cpu_h_

void cpuInit();
void cpuInitNSF(uint16_t addr, uint8_t newA, uint8_t newX);
void cpuPlayNSF(uint16_t addr);
bool cpuCycle();
void cpuIncWaitCycles(uint32_t inc);
uint16_t cpuGetPc();
Expand Down
51 changes: 39 additions & 12 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define DEBUG_KEY 0
#define DEBUG_LOAD_INFO 1

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

static void nesEmuDisplayFrame(void);
static void nesEmuMainLoop(void);
Expand All @@ -48,6 +48,7 @@ bool nesPause = false;
bool ppuDebugPauseFrame = false;
bool doOverscan = true;
bool nesPAL = false;
bool nesEmuNSFPlayback = false;

static bool inPause = false;
static bool inOverscanToggle = false;
Expand All @@ -71,6 +72,7 @@ static const int visibleImg = VISIBLE_DOTS*VISIBLE_LINES*4;
static int scaleFactor = 2;
static bool emuSaveEnabled = false;
static int emuApuClockCycles;
static int emuApuClock;

//from input.c
extern uint8_t inValReads[8];
Expand Down Expand Up @@ -146,19 +148,45 @@ int main(int argc, char** argv)
}
if(argc == 5 && (strstr(argv[2],".fm2") != NULL || strstr(argv[2],".FM2") != NULL))
fm2playInit(argv[2], atoi(argv[3]), !!atoi(argv[4]));
#if WINDOWS_BUILD
emuFrameStart = GetTickCount();
#endif
textureImage = malloc(visibleImg);
memset(textureImage,0,visibleImg);
//make sure image is visible
int i;
for(i = 0; i < visibleImg; i+=4)
textureImage[i+3] = 0xFF;
}
else if(argc >= 2 && (strstr(argv[1],".nsf") != NULL || strstr(argv[1],".NSF") != NULL))
{
FILE *nesF = fopen(argv[1],"rb");
if(!nesF) return EXIT_SUCCESS;
fseek(nesF,0,SEEK_END);
size_t fsize = ftell(nesF);
rewind(nesF);
emuNesROM = malloc(fsize);
fread(emuNesROM,1,fsize,nesF);
fclose(nesF);
emuPrgRAMsize = 0x2000;
emuPrgRAM = malloc(emuPrgRAMsize);
cpuInit();
ppuInit();
memInit();
apuInit();
inputInit();
if(!mapperInitNSF(emuNesROM, fsize, emuPrgRAM, emuPrgRAMsize))
{
printf("NSF init failed!\n");
free(emuNesROM);
return EXIT_SUCCESS;
}
nesEmuNSFPlayback = true;
}
if(emuNesROM == NULL)
return EXIT_SUCCESS;
#if WINDOWS_BUILD
emuFrameStart = GetTickCount();
#endif
textureImage = malloc(visibleImg);
memset(textureImage,0,visibleImg);
//make sure image is visible
int i;
for(i = 0; i < visibleImg; i+=4)
textureImage[i+3] = 0xFF;
emuApuClockCycles = nesPAL ? 8313 : 7457;
emuApuClock = emuApuClockCycles - (nesPAL ? 1066 : 1137);
glutInit(&argc, argv);
glutInitWindowSize(VISIBLE_DOTS*scaleFactor, VISIBLE_LINES*scaleFactor);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
Expand Down Expand Up @@ -226,7 +254,6 @@ bool emuSkipVsync = false;

//static int mCycles = 0;
static bool emuApuDoCycle = false;
static int emuApuClock = 0;
//do one scanline per idle loop
#define MAIN_LOOP_RUNS 341
static int mainClock = 0, mainLoopPos = MAIN_LOOP_RUNS;
Expand Down Expand Up @@ -280,7 +307,7 @@ static void nesEmuMainLoop(void)
else
ppuExtraCycles++;
}
if(ppuDrawDone())
if(!nesEmuNSFPlayback && ppuDrawDone())
{
//printf("%i\n",mCycles);
//mCycles = 0;
Expand Down
12 changes: 12 additions & 0 deletions mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <inttypes.h>
#include "mapper.h"
#include "mapperList.h"
#include "mapper_h/nsf.h"

get8FuncT mapperGet8;
set8FuncT mapperSet8;
Expand All @@ -33,3 +34,14 @@ bool mapperInit(uint8_t mapper, uint8_t *prgROM, uint32_t prgROMsize, uint8_t *p
mapperCycle = mapperList[mapper].cycleFuncF;
return true;
}

bool mapperInitNSF(uint8_t *nsfBIN, uint32_t nsfBINsize, uint8_t *prgRAM, uint32_t prgRAMsize)
{
nsfinit(nsfBIN, nsfBINsize, prgRAM, prgRAMsize);
mapperGet8 = nsfget8;
mapperSet8 = nsfset8;
mapperChrGet8 = nsfchrGet8;
mapperChrSet8 = nsfchrSet8;
mapperCycle = nsfcycle;
return true;
}
1 change: 1 addition & 0 deletions mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef uint8_t* (*getChrFuncT)();
typedef void (*cycleFuncT)();

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

extern get8FuncT mapperGet8;
extern set8FuncT mapperSet8;
Expand Down
69 changes: 0 additions & 69 deletions mapper/m2.c

This file was deleted.

Loading

0 comments on commit b751d05

Please sign in to comment.