diff --git a/README.md b/README.md index c245c44..29a66b9 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/apu.c b/apu.c index 4e31836..09f46af 100644 --- a/apu.c +++ b/apu.c @@ -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) { @@ -584,12 +586,16 @@ 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) { @@ -597,6 +603,8 @@ void apuSet8(uint8_t reg, uint8_t val) 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; } @@ -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) { @@ -615,12 +625,16 @@ 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) { @@ -628,6 +642,8 @@ void apuSet8(uint8_t reg, uint8_t val) 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; } diff --git a/main.c b/main.c index 2030ca1..94ea6f4 100644 --- a/main.c +++ b/main.c @@ -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); @@ -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"); @@ -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 diff --git a/mapper/m4.c b/mapper/m4.c index 14a118b..4e660fe 100644 --- a/mapper/m4.c +++ b/mapper/m4.c @@ -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; @@ -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; @@ -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 { @@ -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 diff --git a/mapper/p16c4.c b/mapper/p16c4.c new file mode 100644 index 0000000..72fa719 --- /dev/null +++ b/mapper/p16c4.c @@ -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 +#include +#include +#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; +} diff --git a/mapper/p16c8.c b/mapper/p16c8.c index c21ebff..6c33378 100644 --- a/mapper/p16c8.c +++ b/mapper/p16c8.c @@ -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]; @@ -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"); } @@ -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) @@ -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); @@ -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); diff --git a/mapper/vrc.c b/mapper/vrc.c deleted file mode 100644 index eea9351..0000000 --- a/mapper/vrc.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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 -#include -#include -#include "../ppu.h" -#include "../vrc_irq.h" - -static uint8_t *vrc_prgROM; -static uint8_t *vrc_prgRAM; -static uint8_t *vrc_chrROM; -static uint32_t vrc_prgROMsize; -static uint32_t vrc_prgRAMsize; -static uint32_t vrc_chrROMsize; -static uint32_t vrc_curPRGBank0; -static uint32_t vrc_curPRGBank1; -static uint32_t vrc_lastM1PRGBank; -static uint32_t vrc_lastPRGBank; -static uint32_t vrc_CHRBank[8]; -static uint32_t vrc_prgROMand; -static uint32_t vrc_chrROMand; -static bool vrc_prg_bank_flip; - -void vrcinit(uint8_t *prgROMin, uint32_t prgROMsizeIn, - uint8_t *prgRAMin, uint32_t prgRAMsizeIn, - uint8_t *chrROMin, uint32_t chrROMsizeIn) -{ - vrc_prgROM = prgROMin; - vrc_prgROMsize = prgROMsizeIn; - vrc_prgRAM = prgRAMin; - vrc_prgRAMsize = prgRAMsizeIn; - vrc_curPRGBank0 = 0; - vrc_curPRGBank1 = 0x2000; - vrc_lastPRGBank = (prgROMsizeIn - 0x2000); - vrc_lastM1PRGBank = vrc_lastPRGBank - 0x2000; - vrc_prgROMand = prgROMsizeIn-1; - vrc_chrROM = chrROMin; - vrc_chrROMsize = chrROMsizeIn; - vrc_chrROMand = chrROMsizeIn-1; - memset(vrc_CHRBank, 0, 8*sizeof(uint32_t)); - vrc_prg_bank_flip = false; - vrc_irq_init(); - printf("VRC Mapper inited\n"); -} - -uint8_t vrcget8(uint16_t addr, uint8_t val) -{ - if(addr >= 0x6000 && addr < 0x8000) - return vrc_prgRAM[addr&0x1FFF]; - else if(addr >= 0x8000) - { - if(addr < 0xA000) - { - if(vrc_prg_bank_flip) - return vrc_prgROM[(((vrc_lastM1PRGBank+(addr&0x1FFF)))&vrc_prgROMand)]; - else - return vrc_prgROM[(((vrc_curPRGBank0<<13)+(addr&0x1FFF))&vrc_prgROMand)]; - } - else if(addr < 0xC000) - return vrc_prgROM[(((vrc_curPRGBank1<<13)+(addr&0x1FFF))&vrc_prgROMand)]; - else if(addr < 0xE000) - { - if(vrc_prg_bank_flip) - return vrc_prgROM[(((vrc_curPRGBank0<<13)+(addr&0x1FFF))&vrc_prgROMand)]; - else - return vrc_prgROM[((vrc_lastM1PRGBank+(addr&0x1FFF))&vrc_prgROMand)]; - } - return vrc_prgROM[((vrc_lastPRGBank+(addr&0x1FFF))&vrc_prgROMand)]; - } - return val; -} - -void vrcset8(uint16_t addr, uint8_t val) -{ - //select all possible addresses - addr &= 0xF003; - if(addr == 0x8000 || addr == 0x8001 || addr == 0x8002 || addr == 0x8003) - vrc_curPRGBank0 = (val&0x1F); - else if(addr == 0x9000 || addr == 0x9001) - { - if(!ppu4Screen) - { - val &= 3; - switch(val) - { - case 0: - ppuSetNameTblVertical(); - break; - case 1: - ppuSetNameTblHorizontal(); - break; - case 2: - ppuSetNameTblSingleLower(); - break; - default: //case 3 - ppuSetNameTblSingleUpper(); - break; - } - } - } - else if(addr == 0x9002 || addr == 0x9003) - vrc_prg_bank_flip = ((val&2) != 0); - else if(addr == 0xA000 || addr == 0xA001 || addr == 0xA002 || addr == 0xA003) - vrc_curPRGBank1 = (val&0x1F); - else if(addr == 0xB000) - vrc_CHRBank[0] = (vrc_CHRBank[0]&~0xF) | (val&0xF); - else if(addr == 0xB001) - vrc_CHRBank[0] = (vrc_CHRBank[0]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xB002) - vrc_CHRBank[1] = (vrc_CHRBank[1]&~0xF) | (val&0xF); - else if(addr == 0xB003) - vrc_CHRBank[1] = (vrc_CHRBank[1]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xC000) - vrc_CHRBank[2] = (vrc_CHRBank[2]&~0xF) | (val&0xF); - else if(addr == 0xC001) - vrc_CHRBank[2] = (vrc_CHRBank[2]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xC002) - vrc_CHRBank[3] = (vrc_CHRBank[3]&~0xF) | (val&0xF); - else if(addr == 0xC003) - vrc_CHRBank[3] = (vrc_CHRBank[3]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xD000) - vrc_CHRBank[4] = (vrc_CHRBank[4]&~0xF) | (val&0xF); - else if(addr == 0xD001) - vrc_CHRBank[4] = (vrc_CHRBank[4]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xD002) - vrc_CHRBank[5] = (vrc_CHRBank[5]&~0xF) | (val&0xF); - else if(addr == 0xD003) - vrc_CHRBank[5] = (vrc_CHRBank[5]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xE000) - vrc_CHRBank[6] = (vrc_CHRBank[6]&~0xF) | (val&0xF); - else if(addr == 0xE001) - vrc_CHRBank[6] = (vrc_CHRBank[6]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xE002) - vrc_CHRBank[7] = (vrc_CHRBank[7]&~0xF) | (val&0xF); - else if(addr == 0xE003) - vrc_CHRBank[7] = (vrc_CHRBank[7]&0xF) | ((val&0x1F)<<4); - else if(addr == 0xF000) - vrc_irq_setlatchLo(val); - else if(addr == 0xF001) - vrc_irq_setlatchHi(val); - else if(addr == 0xF002) - vrc_irq_control(val); - else if(addr == 0xF003) - vrc_irq_ack(); -} - -void m21_set8(uint16_t addr, uint8_t val) -{ - if(addr < 0x6000) - return; - if(addr < 0x8000) - { - vrc_prgRAM[addr&0x1FFF] = val; - return; - } - //printf("m21_set8 %04x %02x\n", addr, val); - //VRC4 M21 Address Setup - uint8_t tmp1 = (addr>>1)&3; - uint8_t tmp2 = (addr>>6)&3; - addr &= 0xF000; addr |= (tmp1 | tmp2); - vrcset8(addr, val); -} - -void m22_set8(uint16_t addr, uint8_t val) -{ - if(addr < 0x8000) - return; - //printf("m22_set8 %04x %02x\n", addr, val); - //VRC2 only supports vertical/horizonal - if(addr == 0x9000 || addr == 0x9002) - val &= 1; - //VRC2 M22 Address Setup - uint8_t tmp = addr&3; - addr &= ~0x3; addr |= (((tmp&1)<<1) | ((tmp&2)>>1)); - vrcset8(addr, val); -} - -void m23_set8(uint16_t addr, uint8_t val) -{ - if(addr < 0x6000) - return; - if(addr < 0x8000) - { - vrc_prgRAM[addr&0x1FFF] = val; - return; - } - //printf("m23_set8 %04x %02x\n", addr, val); - //VRC2 Wai Wai World, avoid wrong mirroring - if(addr == 0x9000 && val == 0xFF) - val &= 1; //only supports vertical/horizonal - //VRC4 M23 Address Setup - uint8_t tmp = (addr>>2)&3; - addr &= ~0xC; addr |= tmp; - vrcset8(addr, val); -} - -void m25_set8(uint16_t addr, uint8_t val) -{ - if(addr < 0x6000) - return; - if(addr < 0x8000) - { - vrc_prgRAM[addr&0x1FFF] = val; - return; - } - //printf("m25_set8 %04x %02x\n", addr, val); - //VRC4 M25 Address Setup - uint8_t tmp1 = (((addr&1)<<1) | ((addr&2)>>1)); - uint8_t tmp2 = ((((addr>>2)&1)<<1) | (((addr>>2)&2)>>1)); - addr &= 0xF000; addr |= (tmp1 | tmp2); - vrcset8(addr, val); -} - -uint8_t vrcchrGet8(uint16_t addr) -{ - if(addr < 0x400) - return vrc_chrROM[(((vrc_CHRBank[0]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x800) - return vrc_chrROM[(((vrc_CHRBank[1]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0xC00) - return vrc_chrROM[(((vrc_CHRBank[2]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1000) - return vrc_chrROM[(((vrc_CHRBank[3]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1400) - return vrc_chrROM[(((vrc_CHRBank[4]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1800) - return vrc_chrROM[(((vrc_CHRBank[5]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1C00) - return vrc_chrROM[(((vrc_CHRBank[6]<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else // < 0x2000 - return vrc_chrROM[(((vrc_CHRBank[7]<<10)+(addr&0x3FF))&vrc_chrROMand)]; -} - -uint8_t m22_chrGet8(uint16_t addr) -{ - if(addr < 0x400) - return vrc_chrROM[((((vrc_CHRBank[0]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x800) - return vrc_chrROM[((((vrc_CHRBank[1]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0xC00) - return vrc_chrROM[((((vrc_CHRBank[2]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1000) - return vrc_chrROM[((((vrc_CHRBank[3]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1400) - return vrc_chrROM[((((vrc_CHRBank[4]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1800) - return vrc_chrROM[((((vrc_CHRBank[5]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else if(addr < 0x1C00) - return vrc_chrROM[((((vrc_CHRBank[6]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; - else // < 0x2000 - return vrc_chrROM[((((vrc_CHRBank[7]>>1)<<10)+(addr&0x3FF))&vrc_chrROMand)]; -} - -void vrcchrSet8(uint16_t addr, uint8_t val) -{ - (void)addr; - (void)val; -} - -void vrccycle() -{ - vrc_irq_cycle(); -} diff --git a/mapper/vrc1.c b/mapper/vrc1.c new file mode 100644 index 0000000..cff752c --- /dev/null +++ b/mapper/vrc1.c @@ -0,0 +1,107 @@ +/* + * 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 +#include +#include +#include "../ppu.h" + +static uint8_t *vrc1_prgROM; +static uint8_t *vrc1_prgRAM; +static uint8_t *vrc1_chrROM; +static uint32_t vrc1_prgROMsize; +static uint32_t vrc1_prgRAMsize; +static uint32_t vrc1_chrROMsize; +static uint32_t vrc1_curPRGBank0; +static uint32_t vrc1_curPRGBank1; +static uint32_t vrc1_curPRGBank2; +static uint32_t vrc1_lastPRGBank; +static uint32_t vrc1_curCHRBank0; +static uint32_t vrc1_curCHRBank1; +static uint32_t vrc1_prgROMand; +static uint32_t vrc1_chrROMand; +static bool vrc1_prg_bank_flip; + +void vrc1init(uint8_t *prgROMin, uint32_t prgROMsizeIn, + uint8_t *prgRAMin, uint32_t prgRAMsizeIn, + uint8_t *chrROMin, uint32_t chrROMsizeIn) +{ + vrc1_prgROM = prgROMin; + vrc1_prgROMsize = prgROMsizeIn; + vrc1_prgRAM = prgRAMin; + vrc1_prgRAMsize = prgRAMsizeIn; + vrc1_curPRGBank0 = 0; + vrc1_curPRGBank1 = 0x2000; + vrc1_curPRGBank2 = 0x4000; + vrc1_lastPRGBank = (prgROMsizeIn - 0x2000); + vrc1_prgROMand = prgROMsizeIn-1; + vrc1_chrROM = chrROMin; + vrc1_chrROMsize = chrROMsizeIn; + vrc1_chrROMand = chrROMsizeIn-1; + vrc1_curCHRBank0 = 0; + vrc1_curCHRBank1 = 0; + vrc1_prg_bank_flip = false; + printf("vrc1 Mapper inited\n"); +} + +uint8_t vrc1get8(uint16_t addr, uint8_t val) +{ + if(addr >= 0x6000 && addr < 0x8000) + return vrc1_prgRAM[addr&0x1FFF]; + else if(addr >= 0x8000) + { + if(addr < 0xA000) + return vrc1_prgROM[(((vrc1_curPRGBank0<<13)+(addr&0x1FFF))&vrc1_prgROMand)]; + else if(addr < 0xC000) + return vrc1_prgROM[(((vrc1_curPRGBank1<<13)+(addr&0x1FFF))&vrc1_prgROMand)]; + else if(addr < 0xE000) + return vrc1_prgROM[(((vrc1_curPRGBank2<<13)+(addr&0x1FFF))&vrc1_prgROMand)]; + return vrc1_prgROM[((vrc1_lastPRGBank+(addr&0x1FFF))&vrc1_prgROMand)]; + } + return val; +} + +void vrc1set8(uint16_t addr, uint8_t val) +{ + if(addr >= 0x8000 && addr < 0x9000) + vrc1_curPRGBank0 = (val&0xF); + else if(addr >= 0x9000 && addr < 0xA000) + { + if((val&0x1) != 0) + ppuSetNameTblHorizontal(); + else + ppuSetNameTblVertical(); + vrc1_curCHRBank0 &= 0xF; + if((val&0x2) != 0) + vrc1_curCHRBank0 |= 0x10; + vrc1_curCHRBank1 &= 0xF; + if((val&0x4) != 0) + vrc1_curCHRBank1 |= 0x10; + } + else if(addr >= 0xA000 && addr < 0xB000) + vrc1_curPRGBank1 = (val&0xF); + else if(addr >= 0xC000 && addr < 0xD000) + vrc1_curPRGBank2 = (val&0xF); + else if(addr >= 0xE000 && addr < 0xF000) + vrc1_curCHRBank0 = (vrc1_curCHRBank0&~0xF) | (val&0xF); + else if(addr >= 0xF000) + vrc1_curCHRBank1 = (vrc1_curCHRBank1&~0xF) | (val&0xF); +} + +uint8_t vrc1chrGet8(uint16_t addr) +{ + if(addr < 0x1000) + return vrc1_chrROM[(((vrc1_curCHRBank0<<12)+(addr&0xFFF))&vrc1_chrROMand)]; + else // < 0x2000 + return vrc1_chrROM[(((vrc1_curCHRBank1<<12)+(addr&0xFFF))&vrc1_chrROMand)]; +} + +void vrc1chrSet8(uint16_t addr, uint8_t val) +{ + (void)addr; + (void)val; +} diff --git a/mapper/vrc2_4.c b/mapper/vrc2_4.c new file mode 100644 index 0000000..1687dd4 --- /dev/null +++ b/mapper/vrc2_4.c @@ -0,0 +1,268 @@ +/* + * 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 +#include +#include +#include "../ppu.h" +#include "../vrc_irq.h" + +static uint8_t *vrc2_4_prgROM; +static uint8_t *vrc2_4_prgRAM; +static uint8_t *vrc2_4_chrROM; +static uint32_t vrc2_4_prgROMsize; +static uint32_t vrc2_4_prgRAMsize; +static uint32_t vrc2_4_chrROMsize; +static uint32_t vrc2_4_curPRGBank0; +static uint32_t vrc2_4_curPRGBank1; +static uint32_t vrc2_4_lastM1PRGBank; +static uint32_t vrc2_4_lastPRGBank; +static uint32_t vrc2_4_CHRBank[8]; +static uint32_t vrc2_4_prgROMand; +static uint32_t vrc2_4_chrROMand; +static bool vrc2_4_prg_bank_flip; + +void vrc2_4_init(uint8_t *prgROMin, uint32_t prgROMsizeIn, + uint8_t *prgRAMin, uint32_t prgRAMsizeIn, + uint8_t *chrROMin, uint32_t chrROMsizeIn) +{ + vrc2_4_prgROM = prgROMin; + vrc2_4_prgROMsize = prgROMsizeIn; + vrc2_4_prgRAM = prgRAMin; + vrc2_4_prgRAMsize = prgRAMsizeIn; + vrc2_4_curPRGBank0 = 0; + vrc2_4_curPRGBank1 = 0x2000; + vrc2_4_lastPRGBank = (prgROMsizeIn - 0x2000); + vrc2_4_lastM1PRGBank = vrc2_4_lastPRGBank - 0x2000; + vrc2_4_prgROMand = prgROMsizeIn-1; + vrc2_4_chrROM = chrROMin; + vrc2_4_chrROMsize = chrROMsizeIn; + vrc2_4_chrROMand = chrROMsizeIn-1; + memset(vrc2_4_CHRBank, 0, 8*sizeof(uint32_t)); + vrc2_4_prg_bank_flip = false; + vrc_irq_init(); + printf("vrc2/4 Mapper inited\n"); +} + +uint8_t vrc2_4_get8(uint16_t addr, uint8_t val) +{ + if(addr >= 0x6000 && addr < 0x8000) + return vrc2_4_prgRAM[addr&0x1FFF]; + else if(addr >= 0x8000) + { + if(addr < 0xA000) + { + if(vrc2_4_prg_bank_flip) + return vrc2_4_prgROM[(((vrc2_4_lastM1PRGBank+(addr&0x1FFF)))&vrc2_4_prgROMand)]; + else + return vrc2_4_prgROM[(((vrc2_4_curPRGBank0<<13)+(addr&0x1FFF))&vrc2_4_prgROMand)]; + } + else if(addr < 0xC000) + return vrc2_4_prgROM[(((vrc2_4_curPRGBank1<<13)+(addr&0x1FFF))&vrc2_4_prgROMand)]; + else if(addr < 0xE000) + { + if(vrc2_4_prg_bank_flip) + return vrc2_4_prgROM[(((vrc2_4_curPRGBank0<<13)+(addr&0x1FFF))&vrc2_4_prgROMand)]; + else + return vrc2_4_prgROM[((vrc2_4_lastM1PRGBank+(addr&0x1FFF))&vrc2_4_prgROMand)]; + } + return vrc2_4_prgROM[((vrc2_4_lastPRGBank+(addr&0x1FFF))&vrc2_4_prgROMand)]; + } + return val; +} + +void vrc2_4_set8(uint16_t addr, uint8_t val) +{ + //select all possible addresses + addr &= 0xF003; + if(addr == 0x8000 || addr == 0x8001 || addr == 0x8002 || addr == 0x8003) + vrc2_4_curPRGBank0 = (val&0x1F); + else if(addr == 0x9000 || addr == 0x9001) + { + if(!ppu4Screen) + { + val &= 3; + switch(val) + { + case 0: + ppuSetNameTblVertical(); + break; + case 1: + ppuSetNameTblHorizontal(); + break; + case 2: + ppuSetNameTblSingleLower(); + break; + default: //case 3 + ppuSetNameTblSingleUpper(); + break; + } + } + } + else if(addr == 0x9002 || addr == 0x9003) + vrc2_4_prg_bank_flip = ((val&2) != 0); + else if(addr == 0xA000 || addr == 0xA001 || addr == 0xA002 || addr == 0xA003) + vrc2_4_curPRGBank1 = (val&0x1F); + else if(addr == 0xB000) + vrc2_4_CHRBank[0] = (vrc2_4_CHRBank[0]&~0xF) | (val&0xF); + else if(addr == 0xB001) + vrc2_4_CHRBank[0] = (vrc2_4_CHRBank[0]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xB002) + vrc2_4_CHRBank[1] = (vrc2_4_CHRBank[1]&~0xF) | (val&0xF); + else if(addr == 0xB003) + vrc2_4_CHRBank[1] = (vrc2_4_CHRBank[1]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xC000) + vrc2_4_CHRBank[2] = (vrc2_4_CHRBank[2]&~0xF) | (val&0xF); + else if(addr == 0xC001) + vrc2_4_CHRBank[2] = (vrc2_4_CHRBank[2]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xC002) + vrc2_4_CHRBank[3] = (vrc2_4_CHRBank[3]&~0xF) | (val&0xF); + else if(addr == 0xC003) + vrc2_4_CHRBank[3] = (vrc2_4_CHRBank[3]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xD000) + vrc2_4_CHRBank[4] = (vrc2_4_CHRBank[4]&~0xF) | (val&0xF); + else if(addr == 0xD001) + vrc2_4_CHRBank[4] = (vrc2_4_CHRBank[4]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xD002) + vrc2_4_CHRBank[5] = (vrc2_4_CHRBank[5]&~0xF) | (val&0xF); + else if(addr == 0xD003) + vrc2_4_CHRBank[5] = (vrc2_4_CHRBank[5]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xE000) + vrc2_4_CHRBank[6] = (vrc2_4_CHRBank[6]&~0xF) | (val&0xF); + else if(addr == 0xE001) + vrc2_4_CHRBank[6] = (vrc2_4_CHRBank[6]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xE002) + vrc2_4_CHRBank[7] = (vrc2_4_CHRBank[7]&~0xF) | (val&0xF); + else if(addr == 0xE003) + vrc2_4_CHRBank[7] = (vrc2_4_CHRBank[7]&0xF) | ((val&0x1F)<<4); + else if(addr == 0xF000) + vrc_irq_setlatchLo(val); + else if(addr == 0xF001) + vrc_irq_setlatchHi(val); + else if(addr == 0xF002) + vrc_irq_control(val); + else if(addr == 0xF003) + vrc_irq_ack(); +} + +void m21_set8(uint16_t addr, uint8_t val) +{ + if(addr < 0x6000) + return; + if(addr < 0x8000) + { + vrc2_4_prgRAM[addr&0x1FFF] = val; + return; + } + //printf("m21_set8 %04x %02x\n", addr, val); + //vrc2_4_4 M21 Address Setup + uint8_t tmp1 = (addr>>1)&3; + uint8_t tmp2 = (addr>>6)&3; + addr &= 0xF000; addr |= (tmp1 | tmp2); + vrc2_4_set8(addr, val); +} + +void m22_set8(uint16_t addr, uint8_t val) +{ + if(addr < 0x8000) + return; + //printf("m22_set8 %04x %02x\n", addr, val); + //vrc2_4_2 only supports vertical/horizonal + if(addr == 0x9000 || addr == 0x9002) + val &= 1; + //vrc2_4_2 M22 Address Setup + uint8_t tmp = addr&3; + addr &= ~0x3; addr |= (((tmp&1)<<1) | ((tmp&2)>>1)); + vrc2_4_set8(addr, val); +} + +void m23_set8(uint16_t addr, uint8_t val) +{ + if(addr < 0x6000) + return; + if(addr < 0x8000) + { + vrc2_4_prgRAM[addr&0x1FFF] = val; + return; + } + //printf("m23_set8 %04x %02x\n", addr, val); + //vrc2_4_2 Wai Wai World, avoid wrong mirroring + if(addr == 0x9000 && val == 0xFF) + val &= 1; //only supports vertical/horizonal + //vrc2_4_4 M23 Address Setup + uint8_t tmp = (addr>>2)&3; + addr &= ~0xC; addr |= tmp; + vrc2_4_set8(addr, val); +} + +void m25_set8(uint16_t addr, uint8_t val) +{ + if(addr < 0x6000) + return; + if(addr < 0x8000) + { + vrc2_4_prgRAM[addr&0x1FFF] = val; + return; + } + //printf("m25_set8 %04x %02x\n", addr, val); + //vrc2_4_4 M25 Address Setup + uint8_t tmp1 = (((addr&1)<<1) | ((addr&2)>>1)); + uint8_t tmp2 = ((((addr>>2)&1)<<1) | (((addr>>2)&2)>>1)); + addr &= 0xF000; addr |= (tmp1 | tmp2); + vrc2_4_set8(addr, val); +} + +uint8_t vrc2_4_chrGet8(uint16_t addr) +{ + if(addr < 0x400) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[0]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x800) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[1]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0xC00) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[2]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1000) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[3]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1400) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[4]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1800) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[5]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1C00) + return vrc2_4_chrROM[(((vrc2_4_CHRBank[6]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else // < 0x2000 + return vrc2_4_chrROM[(((vrc2_4_CHRBank[7]<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; +} + +uint8_t m22_chrGet8(uint16_t addr) +{ + if(addr < 0x400) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[0]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x800) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[1]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0xC00) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[2]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1000) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[3]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1400) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[4]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1800) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[5]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else if(addr < 0x1C00) + return vrc2_4_chrROM[((((vrc2_4_CHRBank[6]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; + else // < 0x2000 + return vrc2_4_chrROM[((((vrc2_4_CHRBank[7]>>1)<<10)+(addr&0x3FF))&vrc2_4_chrROMand)]; +} + +void vrc2_4_chrSet8(uint16_t addr, uint8_t val) +{ + (void)addr; + (void)val; +} + +void vrc2_4_cycle() +{ + vrc_irq_cycle(); +} diff --git a/mapperList.c b/mapperList.c index 701d278..b6d9b76 100644 --- a/mapperList.c +++ b/mapperList.c @@ -16,12 +16,14 @@ #include "mapper_h/m10.h" #include "mapper_h/m13.h" #include "mapper_h/m15.h" -#include "mapper_h/p32c4.h" #include "mapper_h/m48.h" #include "mapper_h/p8c8.h" +#include "mapper_h/p16c4.h" #include "mapper_h/p16c8.h" +#include "mapper_h/p32c4.h" #include "mapper_h/p32c8.h" -#include "mapper_h/vrc.h" +#include "mapper_h/vrc1.h" +#include "mapper_h/vrc2_4.h" #include "mapper_h/vrc6.h" #include "mapper_h/vrc7.h" #include "mapper.h" @@ -49,11 +51,11 @@ mapperList_t mapperList[256] = { { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, - { vrcinit, vrcget8, m21_set8, vrcchrGet8, vrcchrSet8, vrccycle }, - { vrcinit, vrcget8, m22_set8, m22_chrGet8, vrcchrSet8, vrccycle }, - { vrcinit, vrcget8, m23_set8, vrcchrGet8, vrcchrSet8, vrccycle }, + { vrc2_4_init, vrc2_4_get8, m21_set8, vrc2_4_chrGet8, vrc2_4_chrSet8, vrc2_4_cycle }, + { vrc2_4_init, vrc2_4_get8, m22_set8, m22_chrGet8, vrc2_4_chrSet8, vrc2_4_cycle }, + { vrc2_4_init, vrc2_4_get8, m23_set8, vrc2_4_chrGet8, vrc2_4_chrSet8, vrc2_4_cycle }, { vrc6init, vrc6get8, m24_set8, vrc6chrGet8, vrc6chrSet8, vrc6cycle }, - { vrcinit, vrcget8, m25_set8, vrcchrGet8, vrcchrSet8, vrccycle }, + { vrc2_4_init, vrc2_4_get8, m25_set8, vrc2_4_chrGet8, vrc2_4_chrSet8, vrc2_4_cycle }, { vrc6init, vrc6get8, m26_set8, vrc6chrGet8, vrc6chrSet8, vrc6cycle }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, @@ -89,7 +91,7 @@ mapperList_t mapperList[256] = { { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, + { p16c8init, m61_get8, m61_set8, p16c8chrGet8, p16c8chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, @@ -103,7 +105,7 @@ mapperList_t mapperList[256] = { { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, + { vrc1init, vrc1get8, vrc1set8, vrc1chrGet8, vrc1chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { p16c8init, p16c8get8, m78a_set8, p16c8chrGet8, p16c8chrSet8, NULL }, @@ -117,11 +119,11 @@ mapperList_t mapperList[256] = { { NULL, NULL, NULL, NULL, NULL, NULL }, { p8c8init, p8c8get8, m87_set8, p8c8chrGet8, p8c8chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, + { p16c8init, p16c8get8, m89_set8, p16c8chrGet8, p16c8chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, + { p16c8init, p16c8get8, m93_set8, p16c8chrGet8, p16c8chrSet8, NULL }, { p16c8init, p16c8get8, m94_set8, p16c8chrGet8, p16c8chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, @@ -212,7 +214,7 @@ mapperList_t mapperList[256] = { { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, + { p16c4init, p16c4get8, m184_set8, p16c4chrGet8, p16c4chrSet8, NULL }, { p8c8init, p8c8get8, m185_set8, m185_chrGet8, p8c8chrSet8, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL }, diff --git a/mapper_h/p16c4.h b/mapper_h/p16c4.h new file mode 100644 index 0000000..ed3db38 --- /dev/null +++ b/mapper_h/p16c4.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +#ifndef p16c4_h_ +#define p16c4_h_ + +void p16c4init(uint8_t *prgROM, uint32_t prgROMsize, + uint8_t *prgRAM, uint32_t prgRAMsize, + uint8_t *chrROM, uint32_t chrROMsize); +uint8_t p16c4get8(uint16_t addr, uint8_t val); +void m184_set8(uint16_t addr, uint8_t val); +uint8_t p16c4chrGet8(uint16_t addr); +void p16c4chrSet8(uint16_t addr, uint8_t val); + +#endif diff --git a/mapper_h/p16c8.h b/mapper_h/p16c8.h index f7b0911..d5bbd51 100644 --- a/mapper_h/p16c8.h +++ b/mapper_h/p16c8.h @@ -12,13 +12,17 @@ void p16c8init(uint8_t *prgROM, uint32_t prgROMsize, uint8_t *prgRAM, uint32_t prgRAMsize, uint8_t *chrROM, uint32_t chrROMsize); uint8_t p16c8get8(uint16_t addr, uint8_t val); +uint8_t m61_get8(uint16_t addr, uint8_t val); uint8_t m97_get8(uint16_t addr, uint8_t val); uint8_t m180_get8(uint16_t addr, uint8_t val); void m2_set8(uint16_t addr, uint8_t val); +void m61_set8(uint16_t addr, uint8_t val); void m70_set8(uint16_t addr, uint8_t val); void m71_set8(uint16_t addr, uint8_t val); void m78a_set8(uint16_t addr, uint8_t val); void m78b_set8(uint16_t addr, uint8_t val); +void m89_set8(uint16_t addr, uint8_t val); +void m93_set8(uint16_t addr, uint8_t val); void m94_set8(uint16_t addr, uint8_t val); void m97_set8(uint16_t addr, uint8_t val); void m152_set8(uint16_t addr, uint8_t val); diff --git a/mapper_h/vrc1.h b/mapper_h/vrc1.h new file mode 100644 index 0000000..6d5a720 --- /dev/null +++ b/mapper_h/vrc1.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +#ifndef vrc1_h_ +#define vrc1_h_ + +void vrc1init(uint8_t *prgROM, uint32_t prgROMsize, + uint8_t *prgRAM, uint32_t prgRAMsize, + uint8_t *chrROM, uint32_t chrROMsize); +uint8_t vrc1get8(uint16_t addr, uint8_t val); +void vrc1set8(uint16_t addr, uint8_t val); +uint8_t vrc1chrGet8(uint16_t addr); +void vrc1chrSet8(uint16_t addr, uint8_t val); + +#endif diff --git a/mapper_h/vrc.h b/mapper_h/vrc2_4.h similarity index 64% rename from mapper_h/vrc.h rename to mapper_h/vrc2_4.h index 7cabe96..0f53c30 100644 --- a/mapper_h/vrc.h +++ b/mapper_h/vrc2_4.h @@ -5,20 +5,20 @@ * of the MIT license. See the LICENSE file for details. */ -#ifndef vrc_h_ -#define vrc_h_ +#ifndef vrc2_4_h_ +#define vrc2_4_h_ -void vrcinit(uint8_t *prgROM, uint32_t prgROMsize, +void vrc2_4_init(uint8_t *prgROM, uint32_t prgROMsize, uint8_t *prgRAM, uint32_t prgRAMsize, uint8_t *chrROM, uint32_t chrROMsize); -uint8_t vrcget8(uint16_t addr, uint8_t val); +uint8_t vrc2_4_get8(uint16_t addr, uint8_t val); void m21_set8(uint16_t addr, uint8_t val); void m22_set8(uint16_t addr, uint8_t val); void m23_set8(uint16_t addr, uint8_t val); void m25_set8(uint16_t addr, uint8_t val); -uint8_t vrcchrGet8(uint16_t addr); +uint8_t vrc2_4_chrGet8(uint16_t addr); uint8_t m22_chrGet8(uint16_t addr); -void vrcchrSet8(uint16_t addr, uint8_t val); -void vrccycle(); +void vrc2_4_chrSet8(uint16_t addr, uint8_t val); +void vrc2_4_cycle(); #endif