Skip to content

Commit

Permalink
added support for more mappers and corrected another audio mute bug
Browse files Browse the repository at this point in the history
  • Loading branch information
FIX94 committed Apr 24, 2017
1 parent 273a6aa commit 069639a
Show file tree
Hide file tree
Showing 14 changed files with 603 additions and 299 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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,21,22,23,24,25,26,33,34,36,37,38,44,45,46,47,48,52,66,70,71,78,79,85,87,94,97,99,101,113,133,140,144,145,146,147,148,149,152,180,185,240 and 242.
Supported Mappers: 0,1,2,3,4,7,9,10,11,13,15,21,22,23,24,25,26,33,34,36,37,38,44,45,46,47,48,52,61,66,70,71,75,78,79,85,87,89,93,94,97,99,101,113,133,140,144,145,146,147,148,149,152,180,184,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.
You can also play FDS titles if you have the FDS BIOS named disksys.rom in the same folder as your .fds/.qd files.
Expand Down
16 changes: 16 additions & 0 deletions apu.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ void apuSet8(uint8_t reg, uint8_t val)
p1seq = pulseSeqs[val>>6];
p1Env.constant = ((val&PULSE_CONST_V) != 0);
p1Env.loop = p1haltloop = ((val&PULSE_HALT_LOOP) != 0);
if(freq1 > 8 && (freq1 < 0x7FF))
p1Sweep.mute = false; //to be safe
}
else if(reg == 1)
{
Expand All @@ -584,19 +586,25 @@ void apuSet8(uint8_t reg, uint8_t val)
p1Sweep.period = (val>>4)&7;
p1Sweep.negative = ((val&0x8) != 0);
p1Sweep.start = true;
if(freq1 > 8 && (freq1 < 0x7FF))
p1Sweep.mute = false; //to be safe
doSweepLogic(&p1Sweep, &freq1);
}
else if(reg == 2)
{
//printf("P1 time low %02x\n", val);
freq1 = ((freq1&~0xFF) | val);
if(freq1 > 8 && (freq1 < 0x7FF))
p1Sweep.mute = false; //to be safe
}
else if(reg == 3)
{
p1Cycle = 0;
if(APU_IO_Reg[0x15] & P1_ENABLE)
p1LengthCtr = lengthLookupTbl[val>>3];
freq1 = (freq1&0xFF) | ((val&7)<<8);
if(freq1 > 8 && (freq1 < 0x7FF))
p1Sweep.mute = false; //to be safe
//printf("P1 new freq %04x\n", freq1);
p1Env.start = true;
}
Expand All @@ -606,6 +614,8 @@ void apuSet8(uint8_t reg, uint8_t val)
p2seq = pulseSeqs[val>>6];
p2Env.constant = ((val&PULSE_CONST_V) != 0);
p2Env.loop = p2haltloop = ((val&PULSE_HALT_LOOP) != 0);
if(freq2 > 8 && (freq2 < 0x7FF))
p2Sweep.mute = false; //to be safe
}
else if(reg == 5)
{
Expand All @@ -615,19 +625,25 @@ void apuSet8(uint8_t reg, uint8_t val)
p2Sweep.period = (val>>4)&7;
p2Sweep.negative = ((val&0x8) != 0);
p2Sweep.start = true;
if(freq2 > 8 && (freq2 < 0x7FF))
p2Sweep.mute = false; //to be safe
doSweepLogic(&p2Sweep, &freq2);
}
else if(reg == 6)
{
//printf("P2 time low %02x\n", val);
freq2 = ((freq2&~0xFF) | val);
if(freq2 > 8 && (freq2 < 0x7FF))
p2Sweep.mute = false; //to be safe
}
else if(reg == 7)
{
p2Cycle = 0;
if(APU_IO_Reg[0x15] & P2_ENABLE)
p2LengthCtr = lengthLookupTbl[val>>3];
freq2 = (freq2&0xFF) | ((val&7)<<8);
if(freq2 > 8 && (freq2 < 0x7FF))
p2Sweep.mute = false; //to be safe
//printf("P2 new freq %04x\n", freq2);
p2Env.start = true;
}
Expand Down
10 changes: 6 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define DEBUG_KEY 0
#define DEBUG_LOAD_INFO 1

static const char *VERSION_STRING = "fixNES Alpha v0.8.1";
static const char *VERSION_STRING = "fixNES Alpha v0.8.2";

static void nesEmuDisplayFrame(void);
static void nesEmuMainLoop(void);
Expand Down Expand Up @@ -132,6 +132,11 @@ int main(int argc, char** argv)
memInit();
apuInit();
inputInit();
#if DEBUG_LOAD_INFO
printf("Read in %s\n", argv[1]);
printf("Used Mapper: %i\n", mapper);
printf("PRG: 0x%x bytes PRG RAM: 0x%x bytes CHR: 0x%x bytes\n", prgROMsize, emuPrgRAMsize, chrROMsize);
#endif
if(!mapperInit(mapper, prgROM, prgROMsize, emuPrgRAM, emuPrgRAMsize, chrROM, chrROMsize))
{
printf("Mapper init failed!\n");
Expand All @@ -146,9 +151,6 @@ int main(int argc, char** argv)
else
ppuSetNameTblHorizontal();
#if DEBUG_LOAD_INFO
printf("Read in %s\n", argv[1]);
printf("Used Mapper: %i\n", mapper);
printf("PRG: 0x%x bytes PRG RAM: 0x%x bytes CHR: 0x%x bytes\n", prgROMsize, emuPrgRAMsize, chrROMsize);
printf("Trainer: %i Saving: %i VRAM Mode: %s\n", trainer, emuSaveEnabled, (emuNesROM[6] & 1) ? "Vertical" :
((!(emuNesROM[6] & 1)) ? "Horizontal" : "4-Screen"));
#endif
Expand Down
22 changes: 14 additions & 8 deletions mapper/m4.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ static bool m4_chr_bank_flip;
static bool m4_prg_bank_flip;
static uint8_t m4_irqCtr;
static bool m4_irqEnable;
static bool m4_altirq;
static bool m4_clear;
static uint8_t m4_irqReloadVal;
static uint8_t m4_irqCooldown;
static uint8_t m4_irqStart;
Expand Down Expand Up @@ -71,6 +73,9 @@ void m4init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
m4_irqStart = 0;
m4_writeAddr = 0;
m4_irqEnable = false;
//can enable MMC3A IRQ behaviour
m4_altirq = false;
m4_clear = false;
m4_irqReloadVal = 0xFF;
m4_irqCooldown = 0;
m4_chr_bank_flip = false;
Expand Down Expand Up @@ -187,6 +192,8 @@ void m4set8(uint16_t addr, uint8_t val)
{
//printf("Reload value set to %i\n", val);
m4_irqReloadVal = val;
if(m4_altirq)
m4_clear = true;
}
else
{
Expand Down Expand Up @@ -220,19 +227,18 @@ void m4clock(uint16_t addr)
if(m4_irqCooldown == 0)
{
//printf("MMC3 Beep at %i %i\n", curLine, curDot);
if(m4_irqCtr == 0)
uint8_t oldCtr = m4_irqCtr;
if(m4_irqCtr == 0 || m4_clear)
m4_irqCtr = m4_irqReloadVal;
else
m4_irqCtr--;
if(m4_irqCtr == 0)
if((!m4_altirq || oldCtr != 0 || m4_clear) && m4_irqCtr == 0 && m4_irqEnable)
{
if(m4_irqEnable)
{
//printf("MMC3 Tick at %i %i\n", curLine, curDot);
m4_irqStart = 5; //takes a bit before trigger
m4_irqEnable = false;
}
//printf("MMC3 Tick at %i %i\n", curLine, curDot);
m4_irqStart = 5; //takes a bit before trigger
m4_irqEnable = false;
}
m4_clear = false;
}
//make sure to pass all other sprites
//before counting up again
Expand Down
86 changes: 86 additions & 0 deletions mapper/p16c4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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 <stdbool.h>
#include <inttypes.h>
#include "../ppu.h"

static uint8_t *p16c4_prgROM;
static uint8_t *p16c4_chrROM;
static uint32_t p16c4_prgROMsize;
static uint32_t p16c4_chrROMsize;
static uint32_t p16c4_firstPRGBank;
static uint32_t p16c4_curPRGBank;
static uint32_t p16c4_curCHRBank0;
static uint32_t p16c4_curCHRBank1;
static uint32_t p16c4_lastPRGBank;

static uint8_t p16c4_chrRAM[0x2000];

void p16c4init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
p16c4_prgROM = prgROMin;
p16c4_prgROMsize = prgROMsizeIn;
(void)prgRAMin;
(void)prgRAMsizeIn;
p16c4_firstPRGBank = 0;
p16c4_curPRGBank = p16c4_firstPRGBank;
p16c4_lastPRGBank = prgROMsizeIn - 0x4000;
if(chrROMsizeIn > 0)
{
p16c4_chrROM = chrROMin;
p16c4_chrROMsize = chrROMsizeIn;
}
else
{
p16c4_chrROM = p16c4_chrRAM;
p16c4_chrROMsize = 0x2000;
memset(p16c4_chrRAM,0,0x2000);
}
p16c4_curCHRBank0 = 0;
p16c4_curCHRBank1 = 0;
printf("16k PRG 4k CHR Mapper inited\n");
}

uint8_t p16c4get8(uint16_t addr, uint8_t val)
{
if(addr < 0x8000)
return val;
if(addr < 0xC000)
return p16c4_prgROM[((p16c4_curPRGBank&~0x3FFF)+(addr&0x3FFF))&(p16c4_prgROMsize-1)];
return p16c4_prgROM[((p16c4_lastPRGBank&~0x3FFF)+(addr&0x3FFF))&(p16c4_prgROMsize-1)];
}

void m184_set8(uint16_t addr, uint8_t val)
{
//printf("p16c4set8 %04x %02x\n", addr, val);
if(addr >= 0x6000 && addr < 0x8000)
{
p16c4_curCHRBank0 = ((val & 0x7)<<12)&(p16c4_chrROMsize-1);
p16c4_curCHRBank1 = (((val>>4) & 0x7)<<12)&(p16c4_chrROMsize-1);
}
else if(addr >= 0x8000)
p16c4_curPRGBank = (((val>>4) & 0x7)<<14)&(p16c4_prgROMsize-1);
}

uint8_t p16c4chrGet8(uint16_t addr)
{
if(p16c4_chrROM == p16c4_chrRAM) //Writable
return p16c4_chrROM[addr&0x1FFF];
if(addr < 0x1000) //Banked
return p16c4_chrROM[((p16c4_curCHRBank0&~0xFFF)+(addr&0xFFF))&(p16c4_chrROMsize-1)];
return p16c4_chrROM[((p16c4_curCHRBank1&~0xFFF)+(addr&0xFFF))&(p16c4_chrROMsize-1)];
}

void p16c4chrSet8(uint16_t addr, uint8_t val)
{
if(p16c4_chrROM == p16c4_chrRAM) //Writable
p16c4_chrROM[addr&0x1FFF] = val;
}
43 changes: 43 additions & 0 deletions mapper/p16c8.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static uint32_t p16c8_firstPRGBank;
static uint32_t p16c8_curPRGBank;
static uint32_t p16c8_curCHRBank;
static uint32_t p16c8_lastPRGBank;
static bool m61_p16;

static uint8_t p16c8_chrRAM[0x2000];

Expand All @@ -44,6 +45,7 @@ void p16c8init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
memset(p16c8_chrRAM,0,0x2000);
}
p16c8_curCHRBank = 0;
m61_p16 = false;
printf("16k PRG 8k CHR Mapper inited\n");
}

Expand All @@ -56,6 +58,13 @@ uint8_t p16c8get8(uint16_t addr, uint8_t val)
return p16c8_prgROM[((p16c8_lastPRGBank&~0x3FFF)+(addr&0x3FFF))&(p16c8_prgROMsize-1)];
}

uint8_t m61_get8(uint16_t addr, uint8_t val)
{
if(addr < 0x8000)
return val;
return p16c8_prgROM[((p16c8_curPRGBank&~0x3FFF)+(addr&(m61_p16?0x3FFF:0x7FFF)))&(p16c8_prgROMsize-1)];
}

uint8_t m97_get8(uint16_t addr, uint8_t val)
{
if(addr < 0x8000)
Expand All @@ -82,6 +91,19 @@ void m2_set8(uint16_t addr, uint8_t val)
p16c8_curPRGBank = ((val & 0xF)<<14)&(p16c8_prgROMsize-1);
}

void m61_set8(uint16_t addr, uint8_t val)
{
(void)val;
if(addr < 0x8000)
return;
p16c8_curPRGBank = ((((addr & 0xF)<<1)|((addr&0x20)>>5))<<14)&(p16c8_prgROMsize-1);;
m61_p16 = ((addr&0x10) != 0);
if((addr&0x80) != 0)
ppuSetNameTblHorizontal();
else
ppuSetNameTblVertical();
}

void m70_set8(uint16_t addr, uint8_t val)
{
//printf("p16c8set8 %04x %02x\n", addr, val);
Expand Down Expand Up @@ -125,6 +147,27 @@ void m78b_set8(uint16_t addr, uint8_t val)
ppuSetNameTblSingleUpper();
}

void m89_set8(uint16_t addr, uint8_t val)
{
//printf("p16c8set8 %04x %02x\n", addr, val);
if(addr < 0x8000)
return;
p16c8_curPRGBank = (((val>>4) & 7)<<14)&(p16c8_prgROMsize-1);
p16c8_curCHRBank = ((((val&0x80)>>4)|(val & 7))<<13)&(p16c8_chrROMsize-1);
if((val&0x8) == 0)
ppuSetNameTblSingleLower();
else
ppuSetNameTblSingleUpper();
}

void m93_set8(uint16_t addr, uint8_t val)
{
//printf("p16c8set8 %04x %02x\n", addr, val);
if(addr < 0x8000)
return;
p16c8_curPRGBank = (((val>>4) & 7)<<14)&(p16c8_prgROMsize-1);
}

void m94_set8(uint16_t addr, uint8_t val)
{
//printf("p16c8set8 %04x %02x\n", addr, val);
Expand Down
Loading

0 comments on commit 069639a

Please sign in to comment.