93 lines
2.5 KiB
C
93 lines
2.5 KiB
C
#define VRC24_prg regByte
|
|
#define VRC24_mirroring regByte[2]
|
|
#define VRC24_misc regByte[3]
|
|
#define VRC24_chr regWord
|
|
#define VRCIRQ_latch regByte[13]
|
|
#define VRCIRQ_mode regByte[14]
|
|
#define VRCIRQ_count regByte[15]
|
|
#define VRCIRQ_cycles regWord[8]
|
|
|
|
static void VRC24_sync() {
|
|
setprg8(0x8000 ^(VRC24_misc <<13 &0x4000), VRC24_prg[0] &prgAND | prgOR &~prgAND);
|
|
setprg8(0xA000, VRC24_prg[1] &prgAND | prgOR &~prgAND);
|
|
setprg8(0xC000 ^(VRC24_misc <<13 &0x4000), 0xFE &prgAND | prgOR &~prgAND);
|
|
setprg8(0xE000, 0xFF &prgAND | prgOR &~prgAND);
|
|
setchr1(0x0000, VRC24_chr[0]);
|
|
setchr1(0x0400, VRC24_chr[1]);
|
|
setchr1(0x0800, VRC24_chr[2]);
|
|
setchr1(0x0C00, VRC24_chr[3]);
|
|
setchr1(0x1000, VRC24_chr[4]);
|
|
setchr1(0x1400, VRC24_chr[5]);
|
|
setchr1(0x1800, VRC24_chr[6]);
|
|
setchr1(0x1C00, VRC24_chr[7]);
|
|
setmirror(VRC24_mirroring &3 ^(VRC24_mirroring &2? 0: 1));
|
|
}
|
|
|
|
static DECLFW(VRC24_writeReg) {
|
|
uint8 index;
|
|
A =A &0xF000 | (mapper &2? ((A &0xA? 1: 0) | (A &0x5? 2: 0)): ((A &0x5? 1: 0) | (A &0xA? 2: 0)));
|
|
switch (A &0xF000) {
|
|
case 0x8000: case 0xA000:
|
|
VRC24_prg[A >>13 &1] =V;
|
|
sync();
|
|
break;
|
|
case 0x9000:
|
|
if (~A &2)
|
|
VRC24_mirroring =V & (mapper &1? 3: 1);
|
|
else
|
|
if (~A &1 && mapper &1)
|
|
VRC24_misc =V;
|
|
sync();
|
|
break;
|
|
case 0xF000:
|
|
if (mapper &1) switch (A &3) {
|
|
case 0: VRCIRQ_latch =VRCIRQ_latch &0xF0 | V &0x0F; break;
|
|
case 1: VRCIRQ_latch =VRCIRQ_latch &0x0F | V <<4; break;
|
|
case 2: VRCIRQ_mode =V;
|
|
if (VRCIRQ_mode &0x02) {
|
|
VRCIRQ_count =VRCIRQ_latch;
|
|
VRCIRQ_cycles =341;
|
|
}
|
|
X6502_IRQEnd(FCEU_IQEXT);
|
|
break;
|
|
case 3: VRCIRQ_mode =VRCIRQ_mode &~0x02 | VRCIRQ_mode <<1 &0x02;
|
|
X6502_IRQEnd(FCEU_IQEXT);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
index =(A -0xB000) >>11 | A >>1 &1;
|
|
if (A &1)
|
|
VRC24_chr[index] =VRC24_chr[index] & 0x0F | V <<4;
|
|
else
|
|
VRC24_chr[index] =VRC24_chr[index] &~0x0F | V &0x0F;
|
|
sync();
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void FP_FASTAPASS(1) VRCIRQ_cpuCycle(int a) {
|
|
while (a--) {
|
|
if (VRCIRQ_mode &0x02 && (VRCIRQ_mode &0x04 || (VRCIRQ_cycles -=3) <=0)) {
|
|
if (~VRCIRQ_mode &0x04) VRCIRQ_cycles +=341;
|
|
if (!++VRCIRQ_count) {
|
|
VRCIRQ_count =VRCIRQ_latch;
|
|
X6502_IRQBegin(FCEU_IQEXT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void VRC24_reset(uint8 clearRegs) {
|
|
sync =VRC24_sync;
|
|
prgAND =mapperFlags &2? 0x0F: 0x1F;
|
|
if (mapper &1) MapIRQHook =VRCIRQ_cpuCycle;
|
|
SetWriteHandler(0x8000, 0xFFFF, VRC24_writeReg);
|
|
sync();
|
|
}
|
|
|
|
#undef VRC24_prg
|
|
#undef VRC24_mirroring
|
|
#undef VRC24_misc
|
|
#undef VRC24_chr
|