commit
ddf760c6b6
|
@ -16,6 +16,9 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PEC-586 FC based computer series by DUNDA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
|
|
@ -17,20 +17,24 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* VRC-5 (CAI Shogakko no Sansu)
|
||||
* VRC-V (CAI Shogakko no Sansu)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
#define CAI_DEBUG
|
||||
//#define CAI_DEBUG
|
||||
|
||||
static writefunc old2006wrap;
|
||||
static writefunc old2007wrap;
|
||||
static uint8 QTAINTRAM[2048];
|
||||
static uint16 qtaintramofs;
|
||||
// main tiles RAM is 8K in size, but unless other non-CHR ROM type carts,
|
||||
// this one accesses the $0000 and $1000 pages based on extra NT RAM on board
|
||||
// which is similar to MMC5 but much simpler because there are no additional
|
||||
// bankings here.
|
||||
// extra NT RAM handling is in PPU code now.
|
||||
|
||||
static uint16 CHRSIZE = 8192;
|
||||
// there are two separate WRAMs 8K each, on main system cartridge (not battery
|
||||
// backed), and one on the daughter cart (with battery). both are accessed
|
||||
// via the same registers with additional selector flags.
|
||||
static uint16 WRAMSIZE = 8192 + 8192;
|
||||
static uint8 *CHRRAM = NULL;
|
||||
static uint8 *WRAM = NULL;
|
||||
|
@ -38,72 +42,91 @@ static uint8 *WRAM = NULL;
|
|||
static uint8 IRQa, K4IRQ;
|
||||
static uint32 IRQLatch, IRQCount;
|
||||
|
||||
static uint8 conv_tbl[128][4] = {
|
||||
{ 0x40, 0x40, 0x40, 0x40 },
|
||||
{ 0x41, 0x41, 0x41, 0x41 },
|
||||
{ 0x42, 0x42, 0x42, 0x42 },
|
||||
{ 0x43, 0x43, 0x43, 0x43 },
|
||||
{ 0x44, 0x44, 0x44, 0x44 },
|
||||
{ 0x45, 0x45, 0x45, 0x45 },
|
||||
{ 0x46, 0x46, 0x46, 0x46 },
|
||||
{ 0x47, 0x47, 0x47, 0x47 },
|
||||
{ 0x40, 0x40, 0x40, 0x40 },
|
||||
{ 0x41, 0x41, 0x41, 0x41 },
|
||||
{ 0x42, 0x42, 0x42, 0x42 },
|
||||
{ 0x43, 0x43, 0x43, 0x43 },
|
||||
{ 0x44, 0x44, 0x44, 0x44 },
|
||||
{ 0x45, 0x45, 0x45, 0x45 },
|
||||
{ 0x46, 0x46, 0x46, 0x46 },
|
||||
{ 0x47, 0x47, 0x47, 0x47 },
|
||||
{ 0x40, 0x40, 0x48, 0x44 },
|
||||
{ 0x41, 0x41, 0x49, 0x45 },
|
||||
{ 0x42, 0x42, 0x4A, 0x46 },
|
||||
{ 0x43, 0x43, 0x4B, 0x47 },
|
||||
{ 0x44, 0x40, 0x48, 0x44 },
|
||||
{ 0x45, 0x41, 0x49, 0x45 },
|
||||
{ 0x46, 0x42, 0x4A, 0x46 },
|
||||
{ 0x47, 0x43, 0x4B, 0x47 },
|
||||
{ 0x40, 0x50, 0x58, 0x60 },
|
||||
{ 0x41, 0x51, 0x59, 0x61 },
|
||||
{ 0x42, 0x52, 0x5A, 0x62 },
|
||||
{ 0x43, 0x53, 0x5B, 0x63 },
|
||||
{ 0x44, 0x54, 0x5C, 0x64 },
|
||||
{ 0x45, 0x55, 0x5D, 0x65 },
|
||||
{ 0x46, 0x56, 0x5E, 0x66 },
|
||||
{ 0x47, 0x57, 0x5F, 0x67 },
|
||||
{ 0x40, 0x68, 0x70, 0x78 },
|
||||
{ 0x41, 0x69, 0x71, 0x79 },
|
||||
{ 0x42, 0x6A, 0x72, 0x7A },
|
||||
{ 0x43, 0x6B, 0x73, 0x7B },
|
||||
{ 0x44, 0x6C, 0x74, 0x7C },
|
||||
{ 0x45, 0x6D, 0x75, 0x7D },
|
||||
{ 0x46, 0x6E, 0x76, 0x7E },
|
||||
{ 0x47, 0x6F, 0x77, 0x7F },
|
||||
{ 0x40, 0x40, 0x48, 0x50 },
|
||||
{ 0x41, 0x41, 0x49, 0x51 },
|
||||
{ 0x42, 0x42, 0x4A, 0x52 },
|
||||
{ 0x43, 0x43, 0x4B, 0x53 },
|
||||
{ 0x44, 0x44, 0x4C, 0x54 },
|
||||
{ 0x45, 0x45, 0x4D, 0x55 },
|
||||
{ 0x46, 0x46, 0x4E, 0x56 },
|
||||
{ 0x47, 0x47, 0x4F, 0x57 },
|
||||
{ 0x40, 0x58, 0x60, 0x68 },
|
||||
{ 0x41, 0x59, 0x61, 0x69 },
|
||||
{ 0x42, 0x5A, 0x62, 0x6A },
|
||||
{ 0x43, 0x5B, 0x63, 0x6B },
|
||||
{ 0x44, 0x5C, 0x64, 0x6C },
|
||||
{ 0x45, 0x5D, 0x65, 0x6D },
|
||||
{ 0x46, 0x5E, 0x66, 0x6E },
|
||||
{ 0x47, 0x5F, 0x67, 0x6F },
|
||||
{ 0x40, 0x70, 0x78, 0x74 },
|
||||
{ 0x41, 0x71, 0x79, 0x75 },
|
||||
{ 0x42, 0x72, 0x7A, 0x76 },
|
||||
{ 0x43, 0x73, 0x7B, 0x77 },
|
||||
{ 0x44, 0x74, 0x7C, 0x74 },
|
||||
{ 0x45, 0x75, 0x7D, 0x75 },
|
||||
{ 0x46, 0x76, 0x7E, 0x76 },
|
||||
{ 0x47, 0x77, 0x7F, 0x77 },
|
||||
// some kind of 16-bit text encoding (actually 14-bit) used in game resources
|
||||
// may be converted by the hardware into the tile indexes for internal CHR ROM
|
||||
// not sure whey they made it hardware, because most of calculations are just
|
||||
// bit shifting. the main purpose of this table is to calculate actual CHR ROM
|
||||
// bank for every character. there is a some kind of regularity, so this table
|
||||
// may be calculated in software easily.
|
||||
|
||||
// table read out from hardware registers as is
|
||||
|
||||
///*
|
||||
static uint8 conv_tbl[4][8] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x40, 0x10, 0x28, 0x00, 0x18, 0x30 },
|
||||
{ 0x00, 0x00, 0x48, 0x18, 0x30, 0x08, 0x20, 0x38 },
|
||||
{ 0x00, 0x00, 0x80, 0x20, 0x38, 0x10, 0x28, 0xB0 }
|
||||
};
|
||||
//*/
|
||||
/*
|
||||
static uint8 conv_tbl[64][4] = {
|
||||
{ 0x40, 0x40, 0x40, 0x40 }, // 00 | A - 40 41 42 43 44 45 46 47
|
||||
{ 0x41, 0x41, 0x41, 0x41 }, // 02 | B - 48 49 4A 4B 4C 4D 4E 4F
|
||||
{ 0x42, 0x42, 0x42, 0x42 }, // 04 | C - 50 51 52 53 54 55 56 57
|
||||
{ 0x43, 0x43, 0x43, 0x43 }, // 06 | D - 58 59 5A 5B 5C 5D 5E 5F
|
||||
{ 0x44, 0x44, 0x44, 0x44 }, // 08 | E - 60 61 62 63 64 65 66 67
|
||||
{ 0x45, 0x45, 0x45, 0x45 }, // 0A | F - 68 69 6A 6B 6C 6D 6E 6F
|
||||
{ 0x46, 0x46, 0x46, 0x46 }, // 0C | G - 70 71 72 73 74 75 76 77
|
||||
{ 0x47, 0x47, 0x47, 0x47 }, // 0E | H - 78 79 7A 7B 7C 7D 7E 7F
|
||||
{ 0x40, 0x40, 0x40, 0x40 }, // 10 |
|
||||
{ 0x41, 0x41, 0x41, 0x41 }, // 12 +----------------------------
|
||||
{ 0x42, 0x42, 0x42, 0x42 }, // 14 | A A A A
|
||||
{ 0x43, 0x43, 0x43, 0x43 }, // 16 | A A A A
|
||||
{ 0x44, 0x44, 0x44, 0x44 }, // 18 | A A' B' A"
|
||||
{ 0x45, 0x45, 0x45, 0x45 }, // 1A | A C D E
|
||||
{ 0x46, 0x46, 0x46, 0x46 }, // 1C | A F G H
|
||||
{ 0x47, 0x47, 0x47, 0x47 }, // 1E | A A B C
|
||||
{ 0x40, 0x40, 0x48, 0x44 }, // 20 | A D E F
|
||||
{ 0x41, 0x41, 0x49, 0x45 }, // 22 | A G H G"
|
||||
{ 0x42, 0x42, 0x4A, 0x46 }, // 24 +----------------------------
|
||||
{ 0x43, 0x43, 0x4B, 0x47 }, // 26 | A' - 40 41 42 43 40 41 42 43
|
||||
{ 0x44, 0x40, 0x48, 0x44 }, // 28 | A" - 44 45 46 47 44 45 46 47
|
||||
{ 0x45, 0x41, 0x49, 0x45 }, // 2A | B' - 48 49 4A 4B 48 49 4A 4B
|
||||
{ 0x46, 0x42, 0x4A, 0x46 }, // 2C | G" - 74 75 76 77 74 75 76 77
|
||||
{ 0x47, 0x43, 0x4B, 0x47 }, // 2E
|
||||
{ 0x40, 0x50, 0x58, 0x60 }, // 30
|
||||
{ 0x41, 0x51, 0x59, 0x61 }, // 32
|
||||
{ 0x42, 0x52, 0x5A, 0x62 }, // 34
|
||||
{ 0x43, 0x53, 0x5B, 0x63 }, // 36
|
||||
{ 0x44, 0x54, 0x5C, 0x64 }, // 38
|
||||
{ 0x45, 0x55, 0x5D, 0x65 }, // 3A
|
||||
{ 0x46, 0x56, 0x5E, 0x66 }, // 3C
|
||||
{ 0x47, 0x57, 0x5F, 0x67 }, // 3E
|
||||
{ 0x40, 0x68, 0x70, 0x78 }, // 40
|
||||
{ 0x41, 0x69, 0x71, 0x79 }, // 42
|
||||
{ 0x42, 0x6A, 0x72, 0x7A }, // 44
|
||||
{ 0x43, 0x6B, 0x73, 0x7B }, // 46
|
||||
{ 0x44, 0x6C, 0x74, 0x7C }, // 48
|
||||
{ 0x45, 0x6D, 0x75, 0x7D }, // 4A
|
||||
{ 0x46, 0x6E, 0x76, 0x7E }, // 4C
|
||||
{ 0x47, 0x6F, 0x77, 0x7F }, // 4E
|
||||
{ 0x40, 0x40, 0x48, 0x50 }, // 50
|
||||
{ 0x41, 0x41, 0x49, 0x51 }, // 52
|
||||
{ 0x42, 0x42, 0x4A, 0x52 }, // 54
|
||||
{ 0x43, 0x43, 0x4B, 0x53 }, // 56
|
||||
{ 0x44, 0x44, 0x4C, 0x54 }, // 58
|
||||
{ 0x45, 0x45, 0x4D, 0x55 }, // 5A
|
||||
{ 0x46, 0x46, 0x4E, 0x56 }, // 5C
|
||||
{ 0x47, 0x47, 0x4F, 0x57 }, // 5E
|
||||
{ 0x40, 0x58, 0x60, 0x68 }, // 60
|
||||
{ 0x41, 0x59, 0x61, 0x69 }, // 62
|
||||
{ 0x42, 0x5A, 0x62, 0x6A }, // 64
|
||||
{ 0x43, 0x5B, 0x63, 0x6B }, // 66
|
||||
{ 0x44, 0x5C, 0x64, 0x6C }, // 68
|
||||
{ 0x45, 0x5D, 0x65, 0x6D }, // 6A
|
||||
{ 0x46, 0x5E, 0x66, 0x6E }, // 6C
|
||||
{ 0x47, 0x5F, 0x67, 0x6F }, // 6E
|
||||
{ 0x40, 0x70, 0x78, 0x74 }, // 70
|
||||
{ 0x41, 0x71, 0x79, 0x75 }, // 72
|
||||
{ 0x42, 0x72, 0x7A, 0x76 }, // 74
|
||||
{ 0x43, 0x73, 0x7B, 0x77 }, // 76
|
||||
{ 0x44, 0x74, 0x7C, 0x74 }, // 78
|
||||
{ 0x45, 0x75, 0x7D, 0x75 }, // 7A
|
||||
{ 0x46, 0x76, 0x7E, 0x76 }, // 7C
|
||||
{ 0x47, 0x77, 0x7F, 0x77 }, // 7E
|
||||
};
|
||||
*/
|
||||
|
||||
static uint8 regs[16];
|
||||
static SFORMAT StateRegs[] =
|
||||
|
@ -118,88 +141,65 @@ static SFORMAT StateRegs[] =
|
|||
|
||||
static void chrSync(void) {
|
||||
setchr4r(0x10, 0x0000, regs[5] & 1);
|
||||
// one more hack to make visible some screens in common. will be replaced with proper code later
|
||||
setchr4r(0x10, 0x1000, QTAINTRAM[0] & 1);
|
||||
// setchr4r(0x10, 0x1000, 1);
|
||||
// 30.06.19 CaH4e3 there is much more complicated behaviour with second banking register, you may actually
|
||||
// view the content of the internal character CHR rom via this window, but it is useless because hardware
|
||||
// does not use this area to access the internal ROM. not sure why they did this, but I see no need to
|
||||
// emulate this behaviour carefully, unless I find something that I missed...
|
||||
setchr4r(0x10, 0x1000, 1);
|
||||
}
|
||||
|
||||
static void Sync(void) {
|
||||
chrSync();
|
||||
setprg4r(0x10, 0x6000, (regs[0] & 1) | (regs[0] >> 2));
|
||||
setprg4r(0x10, 0x7000, (regs[1] & 1) | (regs[1] >> 2));
|
||||
#ifdef CAI_DEBUG
|
||||
setprg8(0x8000, regs[2]);
|
||||
setprg8(0xA000, regs[3]);
|
||||
setprg8(0xC000, regs[4]);
|
||||
setprg8(0xE000, ~0);
|
||||
#else
|
||||
setprg8r((regs[2] >> 6) & 1, 0x8000, (regs[2] & 0x3F));
|
||||
setprg8r((regs[3] >> 6) & 1, 0xA000, (regs[3] & 0x3F));
|
||||
setprg8r((regs[4] >> 6) & 1, 0xC000, (regs[4] & 0x3F));
|
||||
setprg8r(1, 0xE000, ~0);
|
||||
#endif
|
||||
setprg4r(0x10, 0x6000, (regs[0] & 1) | (regs[0] >> 2)); // two 4K banks are identical, either internal or excernal
|
||||
setprg4r(0x10, 0x7000, (regs[1] & 1) | (regs[1] >> 2)); // SRAMs may be mapped in any bank independently
|
||||
if (PRGsize[0] == 1024 * 1024) {// hacky hacky way to run it as iNES rom for debugging purposes
|
||||
setprg8(0x8000, regs[2]);
|
||||
setprg8(0xA000, regs[3]);
|
||||
setprg8(0xC000, regs[4]);
|
||||
setprg8(0xE000, ~0);
|
||||
} else {
|
||||
setprg8r((regs[2] >> 6) & 1, 0x8000, (regs[2] & 0x3F));
|
||||
setprg8r((regs[3] >> 6) & 1, 0xA000, (regs[3] & 0x3F));
|
||||
setprg8r((regs[4] >> 6) & 1, 0xC000, (regs[4] & 0x3F));
|
||||
setprg8r(1, 0xE000, ~0); // always sees the last bank of the external cart, so can't be booted without it.
|
||||
}
|
||||
setmirror(((regs[0xA]&2)>>1)^1);
|
||||
}
|
||||
|
||||
static DECLFW(QTAiWrite) {
|
||||
regs[(A & 0x0F00) >> 8] = V;
|
||||
regs[(A & 0x0F00) >> 8] = V; // IRQ pretty the same as in other VRC mappers by Konami
|
||||
switch (A) {
|
||||
case 0xd600: {
|
||||
IRQLatch &= 0xFF00;
|
||||
IRQLatch |= V;
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("irq latch lo=%02x\n", V);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 0xd700: {
|
||||
IRQLatch &= 0x00FF;
|
||||
IRQLatch |= V << 8;
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("irq latch hi=%02x\n", V);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 0xd900: {
|
||||
IRQCount = IRQLatch;
|
||||
IRQa = V & 2;
|
||||
K4IRQ = V & 1;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("irq reload\n", V);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 0xd800: {
|
||||
IRQa = K4IRQ;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("irq stop\n", V);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("write %04x:%04x %d, %d\n", A, V, scanline, timestamp);
|
||||
#endif
|
||||
case 0xd600: IRQLatch &= 0xFF00; IRQLatch |= V; break;
|
||||
case 0xd700: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break;
|
||||
case 0xd900: IRQCount = IRQLatch; IRQa = V & 2; K4IRQ = V & 1; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||
case 0xd800: IRQa = K4IRQ; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||
case 0xda00: qtaintramreg = regs[0xA] & 3; break; // register shadow to share it with ppu
|
||||
}
|
||||
Sync();
|
||||
}
|
||||
|
||||
#ifdef CAI_DEBUG
|
||||
static DECLFR(DebugExtNT) {
|
||||
return QTAINTRAM[A & 0x07FF];
|
||||
}
|
||||
#endif
|
||||
|
||||
static DECLFR(QTAiRead) {
|
||||
// OH = conv_tbl[DD00 >> 1][DC00 >> 6]
|
||||
// OL = ((DC00 & 0x3F) << 2) + DB00
|
||||
if (A == 0xDD00)
|
||||
return conv_tbl[regs[0xD] >> 1][regs[0xC] >> 6];
|
||||
else if (A == 0xDC00)
|
||||
return ((regs[0xC] & 0x3F) << 2) + regs[0xB];
|
||||
else
|
||||
|
||||
// uint8 res1 = conv_tbl[(regs[0xD] & 0x7F) >> 1][(regs[0xC] >> 5) & 3];
|
||||
// uint8 res2 = ((regs[0xD] & 1) << 7) | ((regs[0xC] & 0x1F) << 2) | (regs[0xB] & 3);
|
||||
|
||||
uint8 tabl = conv_tbl[(regs[0xC] >> 5) & 3][(regs[0xD] & 0x7F) >> 4];
|
||||
uint8 res1 = 0x40 | (tabl & 0x3F) | ((regs[0xD] >> 1) & 7);
|
||||
uint8 res2 = ((regs[0xD] & 1) << 7) | ((regs[0xC] & 0x1F) << 2) | (regs[0xB] & 3);
|
||||
|
||||
if (tabl & 0x40)
|
||||
res1 &= 0xFB;
|
||||
else if (tabl & 0x80)
|
||||
res1 |= 0x04;
|
||||
|
||||
if (A == 0xDD00) {
|
||||
return res1;
|
||||
} else if (A == 0xDC00) {
|
||||
#ifdef CAI_DEBUG
|
||||
FCEU_printf("%02x:%02x+%d -> %02x:%02x\n", regs[0xD], regs[0xC], regs[0xB], res1, res2);
|
||||
#endif
|
||||
return res2;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -213,38 +213,7 @@ static void VRC5IRQ(int a) {
|
|||
}
|
||||
}
|
||||
|
||||
// debug hack. mapper does not track ppu address himseld, instead the regular ppu offset is used
|
||||
// these handlers must be moved in ppu code in order to be emulated properly.
|
||||
//
|
||||
static DECLFW(QTAi2006Wrap) {
|
||||
if (regs[0xA] & 1)
|
||||
qtaintramofs = (qtaintramofs << 8) | V;
|
||||
else
|
||||
old2006wrap(0x2006, V);
|
||||
}
|
||||
|
||||
static DECLFW(QTAi2007Wrap) {
|
||||
if (regs[0xA] & 1) {
|
||||
QTAINTRAM[qtaintramofs & 0x07FF] = V;
|
||||
qtaintramofs++;
|
||||
} else
|
||||
old2007wrap(0x2007, V);
|
||||
}
|
||||
|
||||
static void QTAiPower(void) {
|
||||
|
||||
QTAIHack = 1;
|
||||
qtaintramofs = 0;
|
||||
|
||||
old2006wrap = GetWriteHandler(0x2006);
|
||||
old2007wrap = GetWriteHandler(0x2007);
|
||||
SetWriteHandler(0x2006, 0x2006, QTAi2006Wrap);
|
||||
SetWriteHandler(0x2007, 0x2007, QTAi2007Wrap);
|
||||
|
||||
#ifdef CAI_DEBUG
|
||||
SetReadHandler(0x5000, 0x5FFF, DebugExtNT);
|
||||
#endif
|
||||
|
||||
SetReadHandler(0x6000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x6000, 0x7FFF, CartBW);
|
||||
SetWriteHandler(0x8000, 0xFFFF, QTAiWrite);
|
||||
|
@ -268,6 +237,8 @@ static void StateRestore(int version) {
|
|||
}
|
||||
|
||||
void QTAi_Init(CartInfo *info) {
|
||||
QTAIHack = 1;
|
||||
|
||||
info->Power = QTAiPower;
|
||||
info->Close = QTAiClose;
|
||||
GameStateRestore = StateRestore;
|
||||
|
@ -284,7 +255,10 @@ void QTAi_Init(CartInfo *info) {
|
|||
|
||||
if (info->battery) {
|
||||
info->SaveGame[0] = WRAM;
|
||||
info->SaveGameLen[0] = WRAMSIZE - 4096;
|
||||
// note, only extrnal cart's SRAM is battery backed, the the part on the main cartridge is just
|
||||
// an additional work ram. so we may save only half here, but I forgot what part is saved lol, will
|
||||
// find out later.
|
||||
info->SaveGameLen[0] = WRAMSIZE;
|
||||
}
|
||||
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
|
|
10
src/fceu.h
10
src/fceu.h
|
@ -46,9 +46,11 @@ void FCEUI_RewindToLastAutosave(void);
|
|||
char *FCEUI_GetAboutString();
|
||||
|
||||
extern uint64 timestampbase;
|
||||
|
||||
// MMC5 external shared buffers/vars
|
||||
extern int MMC5Hack;
|
||||
extern uint32 MMC5HackVROMMask;
|
||||
extern uint8 *MMC5HackExNTARAMPtr;
|
||||
extern int MMC5Hack, PEC586Hack, QTAIHack;
|
||||
extern uint8 *MMC5HackVROMPTR;
|
||||
extern uint8 MMC5HackCHRMode;
|
||||
extern uint8 MMC5HackSPMode;
|
||||
|
@ -56,6 +58,12 @@ extern uint8 MMC50x5130;
|
|||
extern uint8 MMC5HackSPScroll;
|
||||
extern uint8 MMC5HackSPPage;
|
||||
|
||||
extern int PEC586Hack;
|
||||
|
||||
// VRCV extarnal shared buffers/vars
|
||||
extern int QTAIHack;
|
||||
extern uint8 QTAINTRAM[2048];
|
||||
extern uint8 qtaintramreg;
|
||||
|
||||
#define GAME_MEM_BLOCK_SIZE 131072
|
||||
|
||||
|
|
44
src/ppu.cpp
44
src/ppu.cpp
|
@ -330,7 +330,7 @@ int fceuindbg = 0;
|
|||
//0xFF shall indicate to use palette[0]
|
||||
uint8 gNoBGFillColor = 0xFF;
|
||||
|
||||
int MMC5Hack = 0, PEC586Hack = 0, QTAIHack = 0;
|
||||
int MMC5Hack = 0;
|
||||
uint32 MMC5HackVROMMask = 0;
|
||||
uint8 *MMC5HackExNTARAMPtr = 0;
|
||||
uint8 *MMC5HackVROMPTR = 0;
|
||||
|
@ -340,6 +340,12 @@ uint8 MMC50x5130 = 0;
|
|||
uint8 MMC5HackSPScroll = 0;
|
||||
uint8 MMC5HackSPPage = 0;
|
||||
|
||||
int PEC586Hack = 0;
|
||||
|
||||
int QTAIHack = 0;
|
||||
uint8 QTAINTRAM[2048];
|
||||
uint8 qtaintramreg;
|
||||
|
||||
uint8 VRAMBuffer = 0, PPUGenLatch = 0;
|
||||
uint8 *vnapage[4];
|
||||
uint8 PPUNTARAM = 0;
|
||||
|
@ -426,8 +432,12 @@ inline void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
|||
if (PPUCHRRAM & (1 << (tmp >> 10)))
|
||||
VPage[tmp >> 10][tmp] = V;
|
||||
} else if (tmp < 0x3F00) {
|
||||
if (PPUNTARAM & (1 << ((tmp & 0xF00) >> 10)))
|
||||
vnapage[((tmp & 0xF00) >> 10)][tmp & 0x3FF] = V;
|
||||
if (QTAIHack && (qtaintramreg & 1)) {
|
||||
QTAINTRAM[((((tmp & 0xF00) >> 10) >> ((qtaintramreg >> 1)) & 1) << 10) | (tmp & 0x3FF)] = V;
|
||||
} else {
|
||||
if (PPUNTARAM & (1 << ((tmp & 0xF00) >> 10)))
|
||||
vnapage[((tmp & 0xF00) >> 10)][tmp & 0x3FF] = V;
|
||||
}
|
||||
} else {
|
||||
if (!(tmp & 3)) {
|
||||
if (!(tmp & 0xC)) {
|
||||
|
@ -955,8 +965,12 @@ static DECLFW(B2007) {
|
|||
if (PPUCHRRAM & (1 << (tmp >> 10)))
|
||||
VPage[tmp >> 10][tmp] = V;
|
||||
} else if (tmp < 0x3F00) {
|
||||
if (PPUNTARAM & (1 << ((tmp & 0xF00) >> 10)))
|
||||
vnapage[((tmp & 0xF00) >> 10)][tmp & 0x3FF] = V;
|
||||
if (QTAIHack && (qtaintramreg & 1)) {
|
||||
QTAINTRAM[((((tmp & 0xF00) >> 10) >> ((qtaintramreg >> 1)) & 1) << 10) | (tmp & 0x3FF)] = V;
|
||||
} else {
|
||||
if (PPUNTARAM & (1 << ((tmp & 0xF00) >> 10)))
|
||||
vnapage[((tmp & 0xF00) >> 10)][tmp & 0x3FF] = V;
|
||||
}
|
||||
} else {
|
||||
if (!(tmp & 3)) {
|
||||
if (!(tmp & 0xC))
|
||||
|
@ -1196,6 +1210,12 @@ static void RefreshLine(int lastpixel) {
|
|||
#include "pputile.inc"
|
||||
}
|
||||
#undef PPU_BGFETCH
|
||||
} if (QTAIHack) {
|
||||
#define PPU_VRC5FETCH
|
||||
for (X1 = firsttile; X1 < lasttile; X1++) {
|
||||
#include "pputile.inc"
|
||||
}
|
||||
#undef PPU_VRC5FETCH
|
||||
} else {
|
||||
for (X1 = firsttile; X1 < lasttile; X1++) {
|
||||
#include "pputile.inc"
|
||||
|
@ -1959,12 +1979,16 @@ void runppu(int x) {
|
|||
//todo - consider making this a 3 or 4 slot fifo to keep from touching so much memory
|
||||
struct BGData {
|
||||
struct Record {
|
||||
uint8 nt, pecnt, at, pt[2];
|
||||
uint8 nt, pecnt, at, pt[2], qtnt;
|
||||
|
||||
INLINE void Read() {
|
||||
NTRefreshAddr = RefreshAddr = ppur.get_ntread();
|
||||
if (PEC586Hack)
|
||||
ppur.s = (RefreshAddr & 0x200) >> 9;
|
||||
else if (QTAIHack) {
|
||||
qtnt = QTAINTRAM[((((RefreshAddr >> 10) & 3) >> ((qtaintramreg >> 1)) & 1) << 10) | (RefreshAddr & 0x3FF)];
|
||||
ppur.s = qtnt & 0x3F;
|
||||
}
|
||||
pecnt = (RefreshAddr & 1) << 3;
|
||||
nt = CALL_PPUREAD(RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
|
@ -1990,12 +2014,16 @@ struct BGData {
|
|||
ppur.par = nt;
|
||||
RefreshAddr = ppur.get_ptread();
|
||||
if (PEC586Hack) {
|
||||
if (ScreenON)
|
||||
RENDER_LOG(RefreshAddr | pecnt);
|
||||
pt[0] = CALL_PPUREAD(RefreshAddr | pecnt);
|
||||
runppu(kFetchTime);
|
||||
pt[1] = CALL_PPUREAD(RefreshAddr | pecnt);
|
||||
runppu(kFetchTime);
|
||||
} else if (QTAIHack && (qtnt & 0x40)) {
|
||||
pt[0] = *(CHRptr[0] + RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
RefreshAddr |= 8;
|
||||
pt[1] = *(CHRptr[0] + RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
} else {
|
||||
if (ScreenON)
|
||||
RENDER_LOG(RefreshAddr);
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
uint8 *C;
|
||||
register uint8 cc;
|
||||
uint32 vadr;
|
||||
#ifdef PPU_VRC5FETCH
|
||||
uint8 tmpd;
|
||||
#endif
|
||||
|
||||
#ifndef PPUT_MMC5SP
|
||||
register uint8 zz;
|
||||
|
@ -42,7 +45,11 @@ if (X1 >= 2) {
|
|||
#else
|
||||
zz = RefreshAddr & 0x1F;
|
||||
C = vnapage[(RefreshAddr >> 10) & 3];
|
||||
vadr = (C[RefreshAddr & 0x3ff] << 4) + vofs; // Fetch name table byte.
|
||||
#ifdef PPU_VRC5FETCH
|
||||
tmpd = QTAINTRAM[((((RefreshAddr >> 10) & 3) >> ((qtaintramreg >> 1)) & 1) << 10) | (RefreshAddr & 0x3FF)];
|
||||
vofs = ((tmpd & 0x3F) << 12) | ((RefreshAddr >> 12) & 7); // recalculate VROM offset
|
||||
#endif
|
||||
vadr = (C[RefreshAddr & 0x3ff] << 4) + vofs; // Fetch name table byte.
|
||||
#endif
|
||||
|
||||
#ifdef PPUT_HOOK
|
||||
|
@ -78,7 +85,16 @@ pshift[1] <<= 8;
|
|||
#elif defined(PPUT_MMC5)
|
||||
C = MMC5BGVRAMADR(vadr);
|
||||
#else
|
||||
|
||||
#ifdef PPU_VRC5FETCH
|
||||
if(tmpd & 0x40)
|
||||
C = CHRptr[0] + vadr;
|
||||
else
|
||||
C = VRAMADR(vadr);
|
||||
#else
|
||||
C = VRAMADR(vadr);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue