Skip to content

Commit

Permalink
build 20170819
Browse files Browse the repository at this point in the history
[+] Fix crash on SNA loading while running GBC/NES
[+] Fix MOS6502 SBC/ADC commands
[+] Fix NES APU sweep
  • Loading branch information
samstyle committed Aug 19, 2017
1 parent 10594ee commit 11db261
Show file tree
Hide file tree
Showing 13 changed files with 514 additions and 249 deletions.
2 changes: 1 addition & 1 deletion Release
@@ -1 +1 @@
0.6.20170816
0.6.20170819
35 changes: 20 additions & 15 deletions src/libxpeccy/cartridge.c
Expand Up @@ -258,14 +258,12 @@ unsigned char slt_nes_all_rd(xCartridge* slot, int mt, unsigned short adr, int r
unsigned char res = 0xff;
switch (mt) {
case SLT_PRG:
radr &= slot->memMask;
if (slot->data)
res = slot->data[radr];
res = slot->data[radr & slot->memMask];
break;
case SLT_CHR:
radr &= slot->chrMask;
if (slot->chrrom)
res = slot->chrrom[radr];
res = slot->chrrom[radr & slot->chrMask];
break;
case SLT_RAM:
radr &= 0x1fff;
Expand Down Expand Up @@ -391,7 +389,7 @@ void slt_nes_m002_wr(xCartridge* slot, int mt, unsigned short adr, int radr, uns
slot->memMap[3] = slot->prglast;
}

// maper 003 : no PRG banking, up to 256 8K CHR banks
// maper 003 (CNROM) : no PRG banking, up to 256 8K CHR banks

void slt_nes_m003_wr(xCartridge* slot, int mt, unsigned short adr, int radr, unsigned char val) {
if (mt != SLT_PRG) return;
Expand Down Expand Up @@ -433,8 +431,8 @@ void slt_nes_mmc3_wr(xCartridge* slot, int mt, unsigned short adr, int radr, uns
case 3: slot->chrMap[5] = val; break; // 1K CHR @ 1400 (0400)
case 4: slot->chrMap[6] = val; break; // 1K CHR @ 1800 (0800)
case 5: slot->chrMap[7] = val; break; // 1K CHR @ 1c00 (0c00)
case 6: slot->memMap[0] = val & 0x3f; break; // 8K PRG @ 8000 (C000)
case 7: slot->memMap[1] = val & 0x3f; break; // 8K PRG @ A000
case 6: slot->memMap[0] = val; break; // 8K PRG @ 8000 (C000)
case 7: slot->memMap[1] = val; break; // 8K PRG @ A000
}
case 0xa000:
slot->ntmask = (val & 1) ? 0x3bff : 0x37ff; // nametable mirroring
Expand All @@ -458,16 +456,19 @@ void slt_nes_mmc3_wr(xCartridge* slot, int mt, unsigned short adr, int radr, uns

int slt_nes_mmc3_adr(xCartridge* slot, int mt, unsigned short adr) {
int radr = -1;
int bnk;
switch (mt) {
case SLT_PRG:
if ((slot->reg00 & 0x40) && !(adr & 0x2000)) // 8000..9fff <-> c000..dfff
adr ^= 0x4000;
radr = (slot->memMap[(adr >> 13) & 3] << 13) | (adr & 0x1fff);
bnk = (adr >> 13) & 3;
if ((slot->reg00 & 0x40) && !(bnk & 1)) // 8000..9fff (bnk:0) <-> c000..dfff (bnk:2)
bnk ^= 2;
radr = (slot->memMap[bnk] << 13) | (adr & 0x1fff);
break;
case SLT_CHR:
bnk = (adr >> 10) & 7;
if (slot->reg00 & 0x80)
adr ^= 0x1000; // 0000..0fff <-> 1000..1fff
radr = (slot->chrMap[(adr >> 10) & 7] << 10) | (adr & 0x03ff);
bnk ^= 4; // 0000..0fff (bnk:0..3) <-> 1000..1fff (bnk:4..7)
radr = (slot->chrMap[bnk] << 10) | (adr & 0x03ff);
break;
case SLT_RAM:
radr = adr & 0x1fff;
Expand All @@ -480,12 +481,12 @@ int slt_nes_mmc3_adr(xCartridge* slot, int mt, unsigned short adr) {

void slt_nes_m007_wr(xCartridge* slot, int mt, unsigned short adr, int radr, unsigned char val) {
if (mt != SLT_PRG) return;
int tmp = (val << 2) & 0x1c; //
int tmp = (val << 2) & 0x1c;
slot->memMap[0] = tmp;
slot->memMap[1] = tmp + 1;
slot->memMap[2] = tmp + 2;
slot->memMap[3] = tmp + 3;
slot->ntorsk = (val & 0x40) ? 0x0400 : 0x0000;
slot->ntorsk = (val & 0x40) ? ((slot->ntmask & 0xc00) ^ 0xc00) : 0x0000;
}

// maper 071 : 2x16K PRG
Expand All @@ -495,6 +496,8 @@ void slt_nes_m071_wr(xCartridge* slot, int mt, unsigned short adr, int radr, uns
if ((adr & 0xe000) == 0xc000) {
slot->memMap[0] = (val << 1);
slot->memMap[1] = (val << 1) + 1;
slot->memMap[2] = slot->prglast - 1;
slot->memMap[3] = slot->prglast;
}
}
}
Expand Down Expand Up @@ -588,7 +591,7 @@ unsigned char sltRead(xCartridge* slt, int mt, unsigned short adr) {
res = slt->core->rd(slt, mt, adr, radr);
if (mt != SLT_PRG) return res;
if (!slt->brkMap) return res;
if (slt->brkMap[radr] & MEM_BRK_RD)
if (slt->brkMap[radr & slt->memMask] & MEM_BRK_RD)
slt->brk = 1;
return res;
}
Expand All @@ -598,5 +601,7 @@ void sltWrite(xCartridge* slt, int mt, unsigned short adr, unsigned char val) {
if (!slt->core->wr) return;
int radr = slt->core->adr(slt, mt, adr);
slt->core->wr(slt, mt, adr, radr, val);
if (slt->brkMap[radr & slt->memMask] & MEM_BRK_WR)
slt->brk = 1;
}

8 changes: 4 additions & 4 deletions src/libxpeccy/cartridge.h
Expand Up @@ -80,16 +80,16 @@ struct xCartridge {
unsigned char reg03;
unsigned char icnt; // irq counter (nes mmc3)

unsigned char* data; // onboard rom (malloc) = nes prg-rom
unsigned char* brkMap;
int memMask;
unsigned char* chrrom; // nes chr rom (malloc)
int chrMask;
unsigned short ntmask; // nes nametables mirroring control (AND)
unsigned short ntorsk; // same (OR)
unsigned char ram[0x8000]; // onboard ram (32K max)
unsigned short ramMask;
unsigned char ram[0x8000]; // onboard ram (32K max)
xCardCallback* core;
unsigned char* data; // onboard rom (malloc) = nes prg-rom
unsigned char* brkMap;
unsigned char* chrrom; // nes chr rom (malloc)
};

xCartridge* sltCreate();
Expand Down
52 changes: 20 additions & 32 deletions src/libxpeccy/cpu/MOS6502/6502_macro.h
Expand Up @@ -34,50 +34,38 @@

// math
// NOTE: ADD set C flag if overflow occured, clears if not
// NOTE: BCD mode (flag MFD) doesn't affect NES
#define MADC(_op) \
cpu->e = (cpu->f & MFC) ? 1 : 0;\
cpu->tmpw = cpu->a + _op + cpu->e;\
cpu->f &= ~(MFV | MFC | MFZ | MFN);\
if (!(cpu->tmpw & 0xff)) cpu->f |= MFZ;\
if (cpu->f & MFD) {\
cpu->l = (cpu->a & 0x0f) + (_op & 0x0f) + cpu->e;\
cpu->h = (cpu->a >> 4) + (_op >> 4) + ((cpu->l >> 4) & 1);\
if (cpu->l > 9) cpu->l += 6;\
if (!cpu->ltw) cpu->f |= MFZ;\
if (cpu->h & 8) cpu->f |= MFN;\
if ((((cpu->h << 4) ^ cpu->a) & 0x80) && !((cpu->a ^ _op) & 0x80)) cpu->f |= MFV;\
if (cpu->h > 9) cpu->h += 6;\
if (cpu->h > 15) cpu->f |= MFC;\
cpu->a = ((cpu->h & 0x0f) << 4) | (cpu->l & 0x0f);\
if ((cpu->a & 0x0f) + (_op & 0x0f) + cpu->e > 9) cpu->tmpw += 6;\
if (cpu->tmpw & 0x80) cpu->f |= MFN;\
if (!((cpu->a ^ _op) & 0x80) && ((cpu->a ^ cpu->tmpw) & 0x80)) cpu->f |= MFV;\
if (cpu->tmpw > 0x99) cpu->tmpw += 0x60;\
if (cpu->tmpw > 0x99) cpu->f |= MFC;\
} else {\
cpu->tmpb = (cpu->a & 0x7f) + (_op & 0x7f) + cpu->e;\
cpu->a = cpu->ltw;\
if (cpu->tmpw & 0x100) cpu->f |= MFC;\
if (!cpu->a) cpu->f |= MFZ;\
if (cpu->a & 0x80) cpu->f |= MFN;\
if (cpu->tmpb & 0x80) cpu->f |= MFV;\
}
if (cpu->tmpw & 0x80) cpu->f |= MFN;\
if (!((cpu->a ^ _op) & 0x80) && ((cpu->a ^ cpu->tmpw) & 0x80)) cpu->f |= MFV;\
if (cpu->tmpw & 0xff00) cpu->f |= MFC;\
}\
cpu->a = cpu->tmpw & 0xff;

#define MSBC(_op) \
cpu->e = (cpu->f & MFC) ? 0 : 1;\
cpu->tmpw = cpu->a - _op - cpu->e;\
cpu->f &= ~(MFV | MFC | MFZ | MFN);\
if (((cpu->tmpw ^ _op) & 0x80) && ((cpu->a ^ _op) & 0x80)) cpu->f |= MFV;\
if (cpu->tmpw & 0x80) cpu->f |= MFN;\
if (!(cpu->tmpw & 0xff)) cpu->f |= MFZ;\
if (((cpu->tmpw ^ cpu->a) & 0x80) && ((cpu->a ^ _op) & 0x80)) cpu->f |= MFV;\
if (cpu->f & MFD) {\
cpu->l = (cpu->a & 15) - (_op & 15) - cpu->e;\
if (cpu->l & 16) cpu->l -= 6;\
cpu->h = (cpu->a >> 4) - (_op >> 4) - ((cpu->l & 16) ? 1 : 0);\
if (cpu->h & 15) cpu->h -= 6;\
if (cpu->tmpw < 0x100) cpu->f |= MFC;\
if (!cpu->ltw) cpu->f |= MFZ;\
if (cpu->tmpw & 0x80) cpu->f |= MFN;\
cpu->a = ((cpu->h & 0x0f) << 4) | (cpu->l & 0x0f);\
} else {\
cpu->tmpb = (cpu->a & 0x7f) - (_op & 0x7f) - cpu->e;\
cpu->a = cpu->ltw;\
if (cpu->tmpw < 0x100) cpu->f |= MFC;\
if (!cpu->a) cpu->f |= MFZ;\
if (cpu->a & 0x80) cpu->f |= MFN;\
}
if (((cpu->a & 0x0f) - cpu->e) < (_op & 0x0f)) cpu->tmpw -= 6;\
if (cpu->tmpw > 0x99) cpu->tmpw -= 0x60;\
}\
if (cpu->tmpw < 0x100) cpu->f |= MFC;\
cpu->a = cpu->tmpw & 0xff;

// shift

Expand Down
31 changes: 17 additions & 14 deletions src/libxpeccy/filetypes/nes.c
Expand Up @@ -64,54 +64,57 @@ int loadNes(Computer* comp, const char* name) {
break;
}

printf("\nmaper %X\n", maper);
printf("\nMapper #%.3X\n", maper);
xCardCallback* core = sltFindMaper(maper | 0x100);
if (core->id == MAP_UNKNOWN) {
res = ERR_NES_MAPPER;
} else {
slot->core = core;

printf("PRGROM:%i\n", hd.nprg);
int tsiz = 1;
while (tsiz < (hd.nprg << 14)) {tsiz <<= 1;} // up to 2^n - 1
slot->data = realloc(slot->data, tsiz); // PRG-ROM / 16K
slot->brkMap = realloc(slot->brkMap, tsiz);
memset(slot->brkMap, 0x00, tsiz);
while (tsiz < (hd.nprg << 14)) // up to 2^n
tsiz <<= 1;
slot->data = realloc(slot->data, tsiz); // PRGROM
slot->brkMap = realloc(slot->brkMap, tsiz); // PRGROM breakpoints map
memset(slot->brkMap, 0x00, tsiz); // init
slot->memMask = tsiz - 1;
slot->prglast = slot->memMask >> 13;
printf("memMask:%X last8K:%X\n",slot->memMask, slot->prglast);
printf("PRGROM:%.3i x 16K = %X (%i x 8K)\n", hd.nprg, slot->memMask, slot->prglast + 1);
fread(slot->data, hd.nprg << 14, 1, file);

printf("CHRROM:%i\n",hd.nchr);
if (hd.nchr == 0) { // no CHR-ROM
if (slot->chrrom)
free(slot->chrrom);
slot->chrrom = NULL;
slot->chrMask = 0;
} else { // CHR-ROM must be mapped @ 1st 8K of PPU memory
tsiz = 1;
while (tsiz < (hd.nchr << 13)) {tsiz <<= 1;}
slot->chrrom = realloc(slot->chrrom, tsiz); // CHR-ROM / 8K
slot->chrMask = tsiz - 1;
fread(slot->chrrom, hd.nchr << 13, 1, file);
}
printf("CHRROM:%.3i x 8K = %X\n",hd.nchr, slot->chrMask);

slot->memMap[0] = 0x00; // 0x8000 : 1st page
slot->memMap[0] = 0x00; // 0x8000 : page 0
slot->memMap[1] = 0x01;
slot->memMap[2] = slot->prglast - 1; // 0xc000 : last page
slot->memMap[3] = slot->prglast;
for (int i = 0; i < 8; i++)
for (int i = 0; i < 8; i++) // 0x0000 : CHR 8x1K pages
slot->chrMap[i] = i;

// printf("memMask %X; %i %i\n", slot->memMask, slot->memMap[0], slot->memMap[1]);

if (hd.flag6 & 8) {
comp->slot->ntmask = 0x3fff; // full 4-screen nametable
} else if (hd.flag6 & 1) {
comp->slot->ntmask = 0x37ff; // down screens (2800, 2c00) = upper screens (2000, 2400) : ignore bit 11
comp->slot->ntmask = 0x37ff; // down screens (2800, 2c00) = upper screens (2000, 2400) : VA11
} else {
comp->slot->ntmask = 0x3bff; // right sceens (2400, 2c00) = left sceens (2000, 2800) : ignore bit 10
comp->slot->ntmask = 0x3bff; // right sceens (2400, 2c00) = left sceens (2000, 2800) : VA10
}
comp->slot->ntorsk = 0x0000;
slot->ramen = 1;
slot->ramwe = 1;
slot->irqen = 0;
slot->irq = 0;

comp->nes.pal = pal ? 1 : 0;
compUpdateTimings(comp);
Expand Down
3 changes: 2 additions & 1 deletion src/libxpeccy/filetypes/sna.c
Expand Up @@ -70,7 +70,8 @@ int loadSNA_f(Computer* comp, FILE* file, size_t fileSize) {
adr |= fgetc(file) << 8;
comp->cpu->pc = adr;
tmp = fgetc(file);
comp->hw->out(comp,0x7ffd,tmp,0);
if (comp->hw->out)
comp->hw->out(comp,0x7ffd,tmp,0);
tmp2 = fgetc(file);
comp->dos = (tmp2 & 1) ? 1 : 0;
for (tmp2 = 0; tmp2 < 8; tmp2++) {
Expand Down

0 comments on commit 11db261

Please sign in to comment.