parent
3a7753d015
commit
2b26826ab5
|
@ -87,7 +87,7 @@ static uint16 prg[11]; // 0: $5000, 1: $6000, 2: $7000, 3: $8000, 4: $9000, etc
|
|||
static uint8 chr_chip, chr_spr_ext_mode, chr_mode;
|
||||
static uint16 chr[16];
|
||||
|
||||
static uint8 NT_bank[4];
|
||||
static uint8 RNBWHackNTbank[5];
|
||||
static uint8 SPR_bank_offset;
|
||||
static uint8 SPR_bank[64];
|
||||
|
||||
|
@ -237,9 +237,8 @@ static void IRQEnd() {
|
|||
static void Rainbow2IRQ(int a) {
|
||||
|
||||
// Scanline IRQ
|
||||
int sl = newppu_get_scanline();
|
||||
int sl = newppu_get_scanline()-1;
|
||||
int dot = newppu_get_dot();
|
||||
int ppuon = (PPU[1] & 0x18);
|
||||
|
||||
S_IRQ_jitter_counter += a;
|
||||
|
||||
|
@ -248,7 +247,7 @@ static void Rainbow2IRQ(int a) {
|
|||
else
|
||||
S_IRQ_HBlank = false;
|
||||
|
||||
if (!ppuon || sl >= 241)
|
||||
if (!PPUON || sl >= 241)
|
||||
{
|
||||
// whenever rendering is off for any reason (vblank or forced disable)
|
||||
// the irq counter resets, as well as the inframe flag (easily verifiable from software)
|
||||
|
@ -497,26 +496,26 @@ static void Sync(void) {
|
|||
switch (chr_mode)
|
||||
{
|
||||
case CHR_MODE_0:
|
||||
setchr8r(cart_chr_map, chr[0] & 0xffff);
|
||||
setchr8r(cart_chr_map, chr[0] & 0x03ff);
|
||||
break;
|
||||
case CHR_MODE_1:
|
||||
setchr4r(cart_chr_map, 0x0000, chr[0] & 0xffff);
|
||||
setchr4r(cart_chr_map, 0x1000, chr[1] & 0xffff);
|
||||
setchr4r(cart_chr_map, 0x0000, chr[0] & 0x07ff);
|
||||
setchr4r(cart_chr_map, 0x1000, chr[1] & 0x07ff);
|
||||
break;
|
||||
case CHR_MODE_2:
|
||||
setchr2r(cart_chr_map, 0x0000, chr[0] & 0xffff);
|
||||
setchr2r(cart_chr_map, 0x0800, chr[1] & 0xffff);
|
||||
setchr2r(cart_chr_map, 0x1000, chr[2] & 0xffff);
|
||||
setchr2r(cart_chr_map, 0x1800, chr[3] & 0xffff);
|
||||
setchr2r(cart_chr_map, 0x0000, chr[0] & 0x0fff);
|
||||
setchr2r(cart_chr_map, 0x0800, chr[1] & 0x0fff);
|
||||
setchr2r(cart_chr_map, 0x1000, chr[2] & 0x0fff);
|
||||
setchr2r(cart_chr_map, 0x1800, chr[3] & 0x0fff);
|
||||
break;
|
||||
case CHR_MODE_3:
|
||||
for (uint8 i = 0; i < 8; i++) {
|
||||
setchr1r(cart_chr_map, i << 10, chr[i] & 0xffff);
|
||||
setchr1r(cart_chr_map, i << 10, chr[i] & 0x1fff);
|
||||
}
|
||||
break;
|
||||
case CHR_MODE_4:
|
||||
for (uint8 i = 0; i < 16; i++) {
|
||||
setchr512r(cart_chr_map, i << 9, chr[i] & 0xffff);
|
||||
setchr512r(cart_chr_map, i << 9, chr[i] & 0x3fff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -524,7 +523,7 @@ static void Sync(void) {
|
|||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
uint8 cur_NT_bank = NT_bank[i];
|
||||
uint8 cur_RNBWHackNT = RNBWHackNTbank[i];
|
||||
uint8 cur_NT_chip = RNBWHackNTcontrol[i] >> 6;
|
||||
//uint8 cur_NT_1K_dest = (RNBWHackNTcontrol[i] & 0x0C) >> 2;
|
||||
//uint8 cur_NT_ext_mode = RNBWHackNTcontrol[i] & 0x03;
|
||||
|
@ -532,20 +531,22 @@ static void Sync(void) {
|
|||
switch (cur_NT_chip)
|
||||
{
|
||||
case NT_CIRAM:
|
||||
vnapage[i] = NTARAM + 0x400 * (cur_NT_bank & 0x01);
|
||||
vnapage[i] = NTARAM + 0x400 * (cur_RNBWHackNT & 0x01);
|
||||
break;
|
||||
case NT_CHR_RAM:
|
||||
vnapage[i] = CHRRAM + 0x400 * (cur_NT_bank & 0x1f);
|
||||
vnapage[i] = CHRRAM + 0x400 * (cur_RNBWHackNT & 0x1f);
|
||||
break;
|
||||
case NT_FPGA_RAM:
|
||||
vnapage[i] = FPGA_RAM + 0x400 * (cur_NT_bank & 0x03);
|
||||
vnapage[i] = FPGA_RAM + 0x400 * (cur_RNBWHackNT & 0x03);
|
||||
break;
|
||||
case NT_CHR_ROM:
|
||||
vnapage[i] = CHR_FLASHROM + 0x400 * cur_NT_bank;
|
||||
vnapage[i] = CHR_FLASHROM + 0x400 * cur_RNBWHackNT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNBWHackSplitNTARAMPtr = FPGA_RAM + 0x400 * (RNBWHackNTbank[4] & 0x03);
|
||||
|
||||
}
|
||||
|
||||
static DECLFW(RNBW_ExpAudioWr) {
|
||||
|
@ -596,7 +597,7 @@ static DECLFR(RNBW_0x4100Rd) {
|
|||
switch (A)
|
||||
{
|
||||
case 0x4100: return (prg_ram_mode << 6) | prg_rom_mode;
|
||||
case 0x4120: return (chr_chip << 6) | (chr_spr_ext_mode << 5) | chr_mode;
|
||||
case 0x4120: return (chr_chip << 6) | (chr_spr_ext_mode << 5) | (RNBWHackSplitEnable << 4) | chr_mode;
|
||||
case 0x4151: {
|
||||
uint8 rv = (S_IRQ_HBlank ? 0x80 : 0) | (S_IRQ_in_frame ? 0x40 : 0 | (S_IRQ_pending ? 0x01 : 0));
|
||||
S_IRQ_pending = false;
|
||||
|
@ -609,21 +610,21 @@ static DECLFR(RNBW_0x4100Rd) {
|
|||
case 0x4161: return (S_IRQ_pending ? 0x80 : 0) | (C_IRQ_pending ? 0x40 : 0) | (ESP_IRQ_pending ? 0x01 : 0);
|
||||
|
||||
// ESP - WiFi
|
||||
case 0x4170:
|
||||
case 0x4190:
|
||||
{
|
||||
uint8 esp_enable_flag = esp_enable ? 0x01 : 0x00;
|
||||
uint8 irq_enable_flag = esp_irq_enable ? 0x02 : 0x00;
|
||||
UDBG("RAINBOW read flags %04x => %02xs\n", A, esp_enable_flag | irq_enable_flag);
|
||||
return esp_enable_flag | irq_enable_flag;
|
||||
}
|
||||
case 0x4171:
|
||||
case 0x4191:
|
||||
{
|
||||
uint8 esp_message_received_flag = esp_message_received() ? 0x80 : 0;
|
||||
uint8 esp_rts_flag = esp->getDataReadyIO() ? 0x40 : 0x00;
|
||||
return esp_message_received_flag | esp_rts_flag;
|
||||
}
|
||||
case 0x4172: return esp_message_sent ? 0x80 : 0;
|
||||
case 0x4175:
|
||||
case 0x4192: return esp_message_sent ? 0x80 : 0;
|
||||
case 0x4195:
|
||||
{
|
||||
uint8 retval = FPGA_RAM[0x1800 + (rx_address << 8) + rx_index];
|
||||
rx_index++;
|
||||
|
@ -637,13 +638,13 @@ static DECLFR(RNBW_0x4100Rd) {
|
|||
static DECLFW(RNBW_0x4100Wr) {
|
||||
switch (A)
|
||||
{
|
||||
// Mapper configuration
|
||||
// Mapper configuration
|
||||
case 0x4100:
|
||||
prg_rom_mode = V & 0x07;
|
||||
prg_ram_mode = (V & 0x80) >> 7;
|
||||
Sync();
|
||||
break;
|
||||
// PRG banking
|
||||
// PRG banking
|
||||
case 0x4106:
|
||||
case 0x4107:
|
||||
case 0x4108:
|
||||
|
@ -677,27 +678,30 @@ static DECLFW(RNBW_0x4100Wr) {
|
|||
Sync();
|
||||
break;
|
||||
}
|
||||
// CHR banking / chip selector / sprite extended mode
|
||||
// CHR banking / chip selector / vertical split-screen / sprite extended mode
|
||||
case 0x4120:
|
||||
chr_chip = (V & 0xC0) >> 6;
|
||||
chr_spr_ext_mode = (V & 0x20) >> 5;
|
||||
RNBWHackSplitEnable = (V & 0x10) >> 4;
|
||||
chr_mode = V & 0x07;
|
||||
Sync();
|
||||
break;
|
||||
case 0x4121:
|
||||
RNBWHackBGBankOffset = V & 0x1f;
|
||||
break;
|
||||
// Nametables bank
|
||||
case 0x4126: NT_bank[0] = V; Sync(); break;
|
||||
case 0x4127: NT_bank[1] = V; Sync(); break;
|
||||
case 0x4128: NT_bank[2] = V; Sync(); break;
|
||||
case 0x4129: NT_bank[3] = V; Sync(); break;
|
||||
// Nametables control
|
||||
// Nametables bank
|
||||
case 0x4126: RNBWHackNTbank[0] = V; Sync(); break;
|
||||
case 0x4127: RNBWHackNTbank[1] = V; Sync(); break;
|
||||
case 0x4128: RNBWHackNTbank[2] = V; Sync(); break;
|
||||
case 0x4129: RNBWHackNTbank[3] = V; Sync(); break;
|
||||
case 0x412E: RNBWHackNTbank[4] = V; Sync(); break;
|
||||
// Nametables control
|
||||
case 0x412A: RNBWHackNTcontrol[0] = V; Sync(); break;
|
||||
case 0x412B: RNBWHackNTcontrol[1] = V; Sync(); break;
|
||||
case 0x412C: RNBWHackNTcontrol[2] = V; Sync(); break;
|
||||
case 0x412D: RNBWHackNTcontrol[3] = V; Sync(); break;
|
||||
// CHR banking
|
||||
case 0x412F: RNBWHackNTcontrol[4] = V; Sync(); break;
|
||||
// CHR banking
|
||||
case 0x4130:
|
||||
case 0x4131:
|
||||
case 0x4132:
|
||||
|
@ -747,7 +751,7 @@ static DECLFW(RNBW_0x4100Wr) {
|
|||
case 0x4151: S_IRQ_enable = true; break;
|
||||
case 0x4152: S_IRQ_pending = false; S_IRQ_enable = false; break;
|
||||
case 0x4153: S_IRQ_offset = V > 169 ? 169 : V; break;
|
||||
// CPU Cycle IRQ
|
||||
// CPU Cycle IRQ
|
||||
case 0x4158: C_IRQLatch &= 0xFF00; C_IRQLatch |= V; C_IRQCount = C_IRQLatch; break;
|
||||
case 0x4159: C_IRQLatch &= 0x00FF; C_IRQLatch |= V << 8; C_IRQCount = C_IRQLatch; break;
|
||||
case 0x415A:
|
||||
|
@ -760,16 +764,35 @@ static DECLFW(RNBW_0x4100Wr) {
|
|||
C_IRQ_pending = false;
|
||||
IRQEnd();
|
||||
break;
|
||||
// ESP - WiFi
|
||||
// Window Mode
|
||||
case 0x4170:
|
||||
RNBWHackWindowXStartTile = V & 0x1f;
|
||||
break;
|
||||
case 0x4171:
|
||||
RNBWHackWindowXEndTile = V & 0x1f;
|
||||
break;
|
||||
case 0x4172:
|
||||
//RNBWHackWindowYStart = V; // TODO
|
||||
break;
|
||||
case 0x4173:
|
||||
//RNBWHackWindowYEnd = V; // TODO
|
||||
break;
|
||||
case 0x4174:
|
||||
RNBWHackSplitXScroll = V & 0x1f;
|
||||
break;
|
||||
case 0x4175:
|
||||
RNBWHackSplitYScroll = V;
|
||||
break;
|
||||
// ESP - WiFi
|
||||
case 0x4190:
|
||||
esp_enable = V & 0x01;
|
||||
esp_irq_enable = V & 0x02;
|
||||
break;
|
||||
case 0x4171:
|
||||
case 0x4191:
|
||||
if (esp_enable) clear_esp_message_received();
|
||||
else FCEU_printf("RAINBOW warning: $4170.0 is not set\n");
|
||||
else FCEU_printf("RAINBOW warning: $4190.0 is not set\n");
|
||||
break;
|
||||
case 0x4172:
|
||||
case 0x4192:
|
||||
if (esp_enable)
|
||||
{
|
||||
esp_message_sent = false;
|
||||
|
@ -781,15 +804,15 @@ static DECLFW(RNBW_0x4100Wr) {
|
|||
}
|
||||
esp_message_sent = true;
|
||||
}
|
||||
else FCEU_printf("RAINBOW warning: $4170.0 is not set\n");
|
||||
else FCEU_printf("RAINBOW warning: $4190.0 is not set\n");
|
||||
break;
|
||||
case 0x4173:
|
||||
case 0x4193:
|
||||
rx_address = V & 0x07;
|
||||
break;
|
||||
case 0x4174:
|
||||
case 0x4194:
|
||||
tx_address = V & 0x07;
|
||||
break;
|
||||
case 0x4175:
|
||||
case 0x4195:
|
||||
rx_index = V;
|
||||
break;
|
||||
case 0x41FF:
|
||||
|
@ -812,24 +835,28 @@ static DECLFW(RNBW_0x4100Wr) {
|
|||
|
||||
extern uint32 NTRefreshAddr;
|
||||
uint8 FASTCALL Rainbow2PPURead(uint32 A) {
|
||||
/*
|
||||
// if CHR-RAM, check if CHR-RAM exists, if not return data bus cache
|
||||
if (chr_chip == CHR_CHIP_RAM && CHRRAM == NULL)
|
||||
{
|
||||
if (PPU_hook) PPU_hook(A);
|
||||
return X.DB;
|
||||
}
|
||||
|
||||
// if CHR-ROM, check if CHR-ROM exists, if not return data bus cache
|
||||
if (chr_chip == CHR_CHIP_ROM && CHR_FLASHROM == NULL)
|
||||
{
|
||||
if (PPU_hook) PPU_hook(A);
|
||||
return X.DB;
|
||||
}
|
||||
*/
|
||||
if (A < 0x2000)
|
||||
int xt = NTRefreshAddr & 31;
|
||||
int yt = (NTRefreshAddr >> 5) & 31;
|
||||
int ntnum = (NTRefreshAddr >> 10) & 3;
|
||||
|
||||
bool split = false;
|
||||
int linetile;
|
||||
if(newppu)
|
||||
{
|
||||
if (ppuphase == PPUPHASE_OBJ && ScreenON)
|
||||
if (RNBWHackSplitEnable & (
|
||||
((RNBWHackWindowXStartTile <= RNBWHackWindowXEndTile) & ((xt >= RNBWHackWindowXStartTile) & (xt <= RNBWHackWindowXEndTile))) |
|
||||
((RNBWHackWindowXStartTile > RNBWHackWindowXEndTile) & ((xt >= RNBWHackWindowXStartTile) | (xt <= RNBWHackWindowXEndTile)))
|
||||
)) {
|
||||
static const int kHack = -1; //dunno if theres science to this or if it just fixes SDF (cant be bothered to think about it)
|
||||
linetile = (newppu_get_scanline() + kHack + RNBWHackSplitYScroll) / 8;
|
||||
split = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (A < 0x2000) // pattern table / CHR data
|
||||
{
|
||||
if ((ppuphase == PPUPHASE_OBJ) & (ScreenON)) // sprite fetch
|
||||
{
|
||||
if (chr_spr_ext_mode)
|
||||
if (Sprite16)
|
||||
|
@ -838,12 +865,18 @@ uint8 FASTCALL Rainbow2PPURead(uint32 A) {
|
|||
return RNBWHackVROMPtr[((SPR_bank[RNBWHackCurSprite] << 12) & RNBWHackVROMMask) + (A)];
|
||||
else
|
||||
{
|
||||
return VPage[A >> 9][A]; // FIXME
|
||||
return VPage[A >> 9][A]; // TODO: FIXME?
|
||||
}
|
||||
}
|
||||
|
||||
if (ppuphase == PPUPHASE_BG && ScreenON)
|
||||
if ((ppuphase == PPUPHASE_BG) & (ScreenON)) // tile fetch
|
||||
{
|
||||
|
||||
if(split)
|
||||
{
|
||||
return RNBWHackVROMPtr[A & 0xFFF];
|
||||
}
|
||||
|
||||
uint8 *tmp = FCEUPPU_GetCHR(A, NTRefreshAddr);
|
||||
if (tmp == NULL) return X.DB;
|
||||
else return *tmp;
|
||||
|
@ -852,14 +885,86 @@ uint8 FASTCALL Rainbow2PPURead(uint32 A) {
|
|||
// default
|
||||
return FFCEUX_PPURead_Default(A);
|
||||
}
|
||||
else
|
||||
else if (A < 0x3F00) // tiles / attributes
|
||||
{
|
||||
uint8 NT = (A >> 10) & 0x03;
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
if ((A & 0x3FF) >= 0x3C0) { // attributes
|
||||
if (split) {
|
||||
//return 0x00;
|
||||
//uint8 NT_1K_dest = (RNBWHackNTcontrol[4] & 0x0C) >> 2;
|
||||
//uint8 NT_ext_mode = RNBWHackNTcontrol[4] & 0x03;
|
||||
|
||||
//REF NT: return 0x2000 | (v << 0xB) | (h << 0xA) | (vt << 5) | ht;
|
||||
//REF AT: return 0x2000 | (v << 0xB) | (h << 0xA) | 0x3C0 | ((vt & 0x1C) << 1) | ((ht & 0x1C) >> 2);
|
||||
|
||||
// Attributes
|
||||
//return FCEUPPU_GetAttr(ntnum, xt, yt);
|
||||
|
||||
A &= ~(0x1C << 1); //mask off VT
|
||||
A |= (linetile & 0x1C) << 1; //mask on adjusted VT
|
||||
return FPGA_RAM[RNBWHackNTbank[4] * 0x400 + (A & 0x3ff)];
|
||||
} else {
|
||||
return FCEUPPU_GetAttr(ntnum, xt, yt);
|
||||
}
|
||||
} else { // tiles
|
||||
if(split) {
|
||||
// Tiles
|
||||
A &= ~((0x1F << 5) | (1 << 0xB)); //mask off VT and V
|
||||
A |= (linetile & 31) << 5; //mask on adjusted VT (V doesnt make any sense, I think)
|
||||
|
||||
//uint8 *tmp = FCEUPPU_GetCHR(A, NTRefreshAddr);
|
||||
//if (tmp == NULL) return X.DB;
|
||||
//else return *tmp;
|
||||
|
||||
return FPGA_RAM[RNBWHackNTbank[4] * 0x400 + (A & 0x3ff)];
|
||||
} else {
|
||||
return vnapage[(A >> 10) & 0x3][A & 0x3FF];
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(split)
|
||||
{
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[4] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[4] & 0x03;
|
||||
|
||||
static const int kHack = -1; //dunno if theres science to this or if it just fixes SDF (cant be bothered to think about it)
|
||||
int linetile = (newppu_get_scanline() + kHack) / 8 + RNBWHackSplitYScroll;
|
||||
|
||||
//REF NT: return 0x2000 | (v << 0xB) | (h << 0xA) | (vt << 5) | ht;
|
||||
//REF AT: return 0x2000 | (v << 0xB) | (h << 0xA) | 0x3C0 | ((vt & 0x1C) << 1) | ((ht & 0x1C) >> 2);
|
||||
|
||||
// TODO: need to handle 8x8 attributes
|
||||
if((A & 0x3FF) >= 0x3C0)
|
||||
{
|
||||
// Attributes
|
||||
return FCEUPPU_GetAttr(ntnum, xt, yt);
|
||||
|
||||
A &= ~(0x1C << 1); //mask off VT
|
||||
A |= (linetile & 0x1C) << 1; //mask on adjusted VT
|
||||
return FPGA_RAM[RNBWHackNTbank[4] * 0x400 + (A & 0x3ff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tiles
|
||||
//A &= ~((0x1F << 5) | (1 << 0xB)); //mask off VT and V
|
||||
//A |= (linetile & 31) << 5; //mask on adjusted VT (V doesnt make any sense, I think)
|
||||
|
||||
uint8 *tmp = FCEUPPU_GetCHR(A, NTRefreshAddr);
|
||||
if (tmp == NULL) return X.DB;
|
||||
else return *tmp;
|
||||
|
||||
return FPGA_RAM[RNBWHackNTbank[4] * 0x400 + (A & 0x3ff)];
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ((A & 0x3FF) >= 0x3C0)
|
||||
{
|
||||
// Attributes
|
||||
uint8 NT = (A >> 10) & 0x03;
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
|
||||
// 8x8 attributes
|
||||
if (NT_ext_mode & 0x01)
|
||||
{
|
||||
uint8 byte = FPGA_RAM[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)];
|
||||
|
@ -869,11 +974,11 @@ uint8 FASTCALL Rainbow2PPURead(uint32 A) {
|
|||
return byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
|
||||
}
|
||||
return vnapage[(A >> 10) & 0x3][A & 0x3FF];
|
||||
} else { // palette fetch
|
||||
return FFCEUX_PPURead_Default(A);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1392,14 +1497,15 @@ static void Rainbow2Reset(void) {
|
|||
// extended sprite mode disabled
|
||||
chr_chip = CHR_CHIP_ROM;
|
||||
chr_spr_ext_mode = 0;
|
||||
RNBWHackSplitEnable = 0;
|
||||
chr_mode = CHR_MODE_0;
|
||||
chr[0] = 0;
|
||||
|
||||
// Nametables - CIRAM horizontal mirroring
|
||||
NT_bank[0] = 0;
|
||||
NT_bank[1] = 0;
|
||||
NT_bank[2] = 1;
|
||||
NT_bank[3] = 1;
|
||||
RNBWHackNTbank[0] = 0;
|
||||
RNBWHackNTbank[1] = 0;
|
||||
RNBWHackNTbank[2] = 1;
|
||||
RNBWHackNTbank[3] = 1;
|
||||
RNBWHackNTcontrol[0] = 0;
|
||||
RNBWHackNTcontrol[1] = 0;
|
||||
RNBWHackNTcontrol[2] = 0;
|
||||
|
@ -1563,6 +1669,7 @@ static void Rainbow2Close(void)
|
|||
RNBWHackNTcontrol[1] = 0;
|
||||
RNBWHackNTcontrol[2] = 0;
|
||||
RNBWHackNTcontrol[3] = 0;
|
||||
RNBWHackNTcontrol[4] = 0;
|
||||
RNBWHackVROMPtr = NULL;
|
||||
RNBWHackExNTARAMPtr = NULL;
|
||||
}
|
||||
|
|
11
src/fceu.h
11
src/fceu.h
|
@ -66,13 +66,20 @@ extern int RNBWHack;
|
|||
extern uint8 *RNBWHackExNTARAMPtr;
|
||||
extern uint8 *RNBWHackVROMPtr;
|
||||
extern uint32 RNBWHackVROMMask;
|
||||
extern uint8 RNBWHackNTcontrol[4];
|
||||
extern uint8 RNBWHackNTbank[5];
|
||||
extern uint8 RNBWHackNTcontrol[5];
|
||||
extern uint8 RNBWHackBGBankOffset;
|
||||
extern uint8 RNBWHackCurSprite;
|
||||
extern uint8 RNBWHackSplitEnable;
|
||||
extern uint8 RNBWHackWindowXStartTile;
|
||||
extern uint8 RNBWHackWindowXEndTile;
|
||||
extern uint8 RNBWHackSplitXScroll;
|
||||
extern uint8 RNBWHackSplitYScroll;
|
||||
extern uint8 *RNBWHackSplitNTARAMPtr;
|
||||
|
||||
extern int PEC586Hack;
|
||||
|
||||
// VRCV extarnal shared buffers/vars
|
||||
// VRCV external shared buffers/vars
|
||||
extern int QTAIHack;
|
||||
extern uint8 QTAINTRAM[2048];
|
||||
extern uint8 qtaintramreg;
|
||||
|
|
229
src/ppu.cpp
229
src/ppu.cpp
|
@ -373,9 +373,16 @@ int RNBWHack = 0;
|
|||
uint8 *RNBWHackExNTARAMPtr = 0;
|
||||
uint8 *RNBWHackVROMPtr = 0;
|
||||
uint32 RNBWHackVROMMask = 0xff;
|
||||
uint8 RNBWHackNTcontrol[4];
|
||||
uint8 RNBWHackNTbank[5];
|
||||
uint8 RNBWHackNTcontrol[5];
|
||||
uint8 RNBWHackBGBankOffset;
|
||||
uint8 RNBWHackCurSprite;
|
||||
uint8 RNBWHackSplitEnable;
|
||||
uint8 RNBWHackWindowXStartTile;
|
||||
uint8 RNBWHackWindowXEndTile;
|
||||
uint8 RNBWHackSplitXScroll;
|
||||
uint8 RNBWHackSplitYScroll;
|
||||
uint8 *RNBWHackSplitNTARAMPtr;
|
||||
|
||||
int PEC586Hack = 0;
|
||||
|
||||
|
@ -454,16 +461,56 @@ uint8 *FCEUPPU_GetCHR(uint32 vadr, uint32 refreshaddr)
|
|||
}
|
||||
else if (RNBWHack)
|
||||
{
|
||||
uint8 NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
// uint8 xt = refreshaddr & 31;
|
||||
uint8 NT;
|
||||
/*
|
||||
static const int kHack = -1; //dunno if theres science to this or if it just fixes SDF (cant be bothered to think about it)
|
||||
int linetile = (newppu_get_scanline() + kHack + RNBWHackSplitYScroll) / 8;
|
||||
int coltile = newppu_get_dot();
|
||||
coltile = coltile / 8; // +RNBWHackSplitXScroll;
|
||||
bool split = false;
|
||||
if (RNBWHackSplitEnable & (
|
||||
( (RNBWHackWindowXStartTile <= RNBWHackWindowXEndTile) & ( (coltile >= RNBWHackWindowXStartTile) & (coltile <= RNBWHackWindowXEndTile) ) ) |
|
||||
( (RNBWHackWindowXStartTile > RNBWHackWindowXEndTile) & ( (coltile >= RNBWHackWindowXStartTile) | (coltile <= RNBWHackWindowXEndTile) ) )
|
||||
) ) {
|
||||
split = true;
|
||||
NT = 4;
|
||||
} else {
|
||||
NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
}
|
||||
*/
|
||||
NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
if (NT_ext_mode & 0x02)
|
||||
switch (NT_ext_mode)
|
||||
{
|
||||
if (RNBWHackVROMPtr == NULL) return NULL;
|
||||
case 0: // extended mode disabled
|
||||
case 1: // extended attributes
|
||||
{
|
||||
/*if (split) {
|
||||
int tmpA = vadr & 0x3ff;
|
||||
tmpA &= ~(0x1F << 5); // | (1 << 0xB)); //mask off VT and V
|
||||
tmpA |= (linetile & 31) << 5; //mask on adjusted VT (V doesnt make any sense, I think)
|
||||
return RNBWHackSplitNTARAMPtr + tmpA;
|
||||
|
||||
//vadr = (RNBWHackExNTARAMPtr[xs | (ys << 5)] << 4) + ((scanline + RNBWHackSplitYScroll) & 7);
|
||||
|
||||
}
|
||||
else*/
|
||||
return VRAMADR(vadr);
|
||||
// return vnapage[(A >> 10) & 0x3][A & 0x3FF];
|
||||
//&VPage[(vadr) >> 9][(vadr)]
|
||||
}
|
||||
case 2: // extended tiles
|
||||
case 3: // extended attributes + tiles
|
||||
{
|
||||
if (RNBWHackVROMPtr == NULL)
|
||||
return NULL;
|
||||
uint8 *C = RNBWHackVROMPtr;
|
||||
C += ((RNBWHackBGBankOffset * 0x40000) + ((RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)] & 0x3f) << 12) + (vadr & 0xfff)) & RNBWHackVROMMask;
|
||||
return C;
|
||||
}
|
||||
}
|
||||
}
|
||||
return VRAMADR(vadr);
|
||||
}
|
||||
|
@ -478,11 +525,90 @@ int FCEUPPU_GetAttr(int ntnum, int xt, int yt)
|
|||
return (MMC5HackExNTARAMPtr[refreshaddr & 0x3ff] & 0xC0) >> 6;
|
||||
else if (RNBWHack)
|
||||
{
|
||||
uint8 NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
uint8 NT;
|
||||
/*
|
||||
int linetile;
|
||||
bool split = false;
|
||||
if (RNBWHackSplitEnable & (
|
||||
((RNBWHackWindowXStartTile <= RNBWHackWindowXEndTile) & ((xt >= RNBWHackWindowXStartTile) & (xt <= RNBWHackWindowXEndTile))) |
|
||||
((RNBWHackWindowXStartTile > RNBWHackWindowXEndTile) & ((xt >= RNBWHackWindowXStartTile) | (xt <= RNBWHackWindowXEndTile)))
|
||||
)) {
|
||||
static const int kHack = -1; //dunno if theres science to this or if it just fixes SDF (cant be bothered to think about it)
|
||||
linetile = (newppu_get_scanline() + kHack + RNBWHackSplitYScroll) / 8;
|
||||
split = true;
|
||||
NT = 4;
|
||||
xt = NTRefreshAddr & 31;
|
||||
yt = (NTRefreshAddr >> 5) & 31;
|
||||
}
|
||||
else {
|
||||
NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
}
|
||||
*/
|
||||
NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
if (NT_ext_mode & 0x01)
|
||||
return (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)] & 0xC0) >> 6;
|
||||
switch (NT_ext_mode)
|
||||
{
|
||||
case 0: // extended mode disabled
|
||||
case 2: // extended tiles
|
||||
{
|
||||
return (vnapage[ntnum][attraddr] & (3 << temp)) >> temp;
|
||||
}
|
||||
case 1: // extended attributes
|
||||
{
|
||||
/*if (split) {
|
||||
int tmpA = refreshaddr & 0x3ff;
|
||||
tmpA &= ~(0x1F << 5); // | (1 << 0xB)); //mask off VT and V
|
||||
tmpA |= (linetile & 31) << 5; //mask on adjusted VT (V doesnt make any sense, I think)
|
||||
//return RNBWHackSplitNTARAMPtr + (vadr & 0x3ff);
|
||||
uint8 byte = (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + tmpA] & 0xC0);
|
||||
byte *= 0x55;
|
||||
return byte;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
uint8 byte = (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)] & 0xC0);
|
||||
byte >>= 6;
|
||||
byte *= 0x55;
|
||||
return byte;
|
||||
//}
|
||||
}
|
||||
case 3: // extended attributes + tiles
|
||||
{
|
||||
uint8 byte = (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)] & 0xC0);
|
||||
byte >>= 6;
|
||||
byte *= 0x55;
|
||||
return byte;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
uint8 NT;
|
||||
bool split = false;
|
||||
if(RNBWHackSplitEnable) {
|
||||
if(RNBWHackWindowXStartTile < RNBWHackWindowXEndTile)
|
||||
{
|
||||
if((xt >= RNBWHackWindowXStartTile) & (xt <= RNBWHackWindowXEndTile))
|
||||
split = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((xt <= RNBWHackWindowXEndTile) | (xt >= RNBWHackWindowXStartTile))
|
||||
split = true;
|
||||
}
|
||||
}
|
||||
if(split) {
|
||||
NT = 4;
|
||||
} else {
|
||||
NT = (NTRefreshAddr >> 10) & 0x03;
|
||||
}
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
if (NT_ext_mode & 0x01)
|
||||
return (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (NTRefreshAddr & 0x3ff)] & 0xC0) >> 6;
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
return (vnapage[ntnum][attraddr] & (3 << temp)) >> temp;
|
||||
}
|
||||
|
@ -1438,6 +1564,95 @@ static void RefreshLine(int lastpixel)
|
|||
}
|
||||
}
|
||||
#undef PPUT_MMC5
|
||||
|
||||
// Rainbow mapper specific code for vertical split-screen
|
||||
|
||||
#define PPUT_RNBW
|
||||
else if (RNBWHack && geniestage != 1)
|
||||
{
|
||||
for (X1 = firsttile; X1 < lasttile; X1++)
|
||||
{
|
||||
if (RNBWHackSplitEnable & (((RNBWHackWindowXStartTile <= RNBWHackWindowXEndTile) & ((X1 >= RNBWHackWindowXStartTile) & (X1 <= RNBWHackWindowXEndTile))) |
|
||||
((RNBWHackWindowXStartTile > RNBWHackWindowXEndTile) & ((X1 >= RNBWHackWindowXStartTile) | (X1 <= RNBWHackWindowXEndTile)))))
|
||||
{
|
||||
// handle vertical split-screen
|
||||
#define PPUT_RNBW_SPLIT
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[4] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[4] & 0x03;
|
||||
switch (NT_ext_mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
#include "pputile.inc"
|
||||
break;
|
||||
}
|
||||
case 1: // extended attributes
|
||||
{
|
||||
#define PPUT_RNBW_SPLIT_EXT_ATTR
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_SPLIT_EXT_ATTR
|
||||
break;
|
||||
}
|
||||
case 2: // extended tiles
|
||||
{
|
||||
#define PPUT_RNBW_SPLIT_EXT_TILE
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_SPLIT_EXT_TILE
|
||||
break;
|
||||
}
|
||||
case 3: // extended attributes + tiles
|
||||
{
|
||||
#define PPUT_RNBW_SPLIT_EXT_ATTR
|
||||
#define PPUT_RNBW_SPLIT_EXT_TILE
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_SPLIT_EXT_TILE
|
||||
#undef PPUT_RNBW_SPLIT_EXT_ATTR
|
||||
break;
|
||||
}
|
||||
#undef PPUT_RNBW_SPLIT
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle other screens
|
||||
uint8 NT = (RefreshAddr >> 10) & 0x03;
|
||||
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
|
||||
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
|
||||
switch (NT_ext_mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
#include "pputile.inc"
|
||||
break;
|
||||
}
|
||||
case 1: // extended attributes
|
||||
{
|
||||
#define PPUT_RNBW_EXT_ATTR
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_EXT_ATTR
|
||||
break;
|
||||
}
|
||||
case 2: // extended tiles
|
||||
{
|
||||
#define PPUT_RNBW_EXT_TILE
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_EXT_TILE
|
||||
break;
|
||||
}
|
||||
case 3: // extended attributes + tiles
|
||||
{
|
||||
#define PPUT_RNBW_EXT_ATTR
|
||||
#define PPUT_RNBW_EXT_TILE
|
||||
#include "pputile.inc"
|
||||
#undef PPUT_RNBW_EXT_TILE
|
||||
#undef PPUT_RNBW_EXT_ATTR
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef PPUT_RNBW
|
||||
else if (PPU_hook)
|
||||
{
|
||||
norecurse = 1;
|
||||
|
|
|
@ -5,13 +5,17 @@ uint32 vadr;
|
|||
uint8 tmpd;
|
||||
#endif
|
||||
|
||||
#ifndef PPUT_MMC5SP
|
||||
FCEU_MAYBE_UNUSED uint8 zz;
|
||||
#else
|
||||
#ifdef PPUT_MMC5SP
|
||||
uint8 xs, ys;
|
||||
xs = X1;
|
||||
ys = ((scanline >> 3) + MMC5HackSPScroll) & 0x1F;
|
||||
if (ys >= 0x1E) ys -= 0x1E;
|
||||
#elif defined(PPUT_RNBW_SPLIT)
|
||||
uint8 xs, ys;
|
||||
xs = (X1 + RNBWHackSplitXScroll) & 0x1f;
|
||||
ys = ((scanline + RNBWHackSplitYScroll) >> 3 ) & 0x1F;
|
||||
#else
|
||||
FCEU_MAYBE_UNUSED uint8 zz;
|
||||
#endif
|
||||
|
||||
if (X1 >= 2) {
|
||||
|
@ -42,6 +46,17 @@ if (X1 >= 2) {
|
|||
|
||||
#ifdef PPUT_MMC5SP
|
||||
vadr = (MMC5HackExNTARAMPtr[xs | (ys << 5)] << 4) + (vofs & 7);
|
||||
#elif defined(PPUT_RNBW_SPLIT)
|
||||
#if defined(PPUT_RNBW_SPLIT_EXT_TILE)
|
||||
// TODO need to use split config in account here
|
||||
vadr = (RNBWHackExNTARAMPtr[xs | (ys << 5)] << 4) + ((scanline + RNBWHackSplitYScroll) & 7);
|
||||
#else
|
||||
vadr = (RNBWHackExNTARAMPtr[xs | (ys << 5)] << 4) + ((scanline + RNBWHackSplitYScroll) & 7);
|
||||
#endif
|
||||
#elif defined(PPUT_RNBW_EXT_TILE)
|
||||
zz = RefreshAddr & 0x1F;
|
||||
C = vnapage[(RefreshAddr >> 10) & 3];
|
||||
vadr = (C[RefreshAddr & 0x3ff] << 4) + vofs; // Fetch name table byte.
|
||||
#else
|
||||
zz = RefreshAddr & 0x1F;
|
||||
C = vnapage[(RefreshAddr >> 10) & 3];
|
||||
|
@ -59,6 +74,15 @@ if (X1 >= 2) {
|
|||
#ifdef PPUT_MMC5SP
|
||||
cc = MMC5HackExNTARAMPtr[0x3c0 + (xs >> 2) + ((ys & 0x1C) << 1)];
|
||||
cc = ((cc >> ((xs & 2) + ((ys & 0x2) << 1))) & 3);
|
||||
#elif defined(PPUT_RNBW_SPLIT)
|
||||
#if defined(PPUT_RNBW_SPLIT_EXT_ATTR)
|
||||
cc = (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (xs | (ys << 5))] & 0xC0) >> 6;
|
||||
#else
|
||||
cc = RNBWHackExNTARAMPtr[0x3c0 + (xs >> 2) + ((ys & 0x1C) << 1)];
|
||||
cc = ((cc >> ((xs & 2) + ((ys & 0x2) << 1))) & 3);
|
||||
#endif
|
||||
#elif defined(PPUT_RNBW_EXT_ATTR)
|
||||
cc = (RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (RefreshAddr & 0x3ff)] & 0xC0) >> 6;
|
||||
#else
|
||||
#ifdef PPUT_MMC5CHR1
|
||||
cc = (MMC5HackExNTARAMPtr[RefreshAddr & 0x3ff] & 0xC0) >> 6;
|
||||
|
@ -77,6 +101,9 @@ pshift[1] <<= 8;
|
|||
#ifdef PPUT_MMC5SP
|
||||
C = MMC5HackVROMPTR + vadr;
|
||||
C += ((MMC5HackSPPage & 0x3f & MMC5HackVROMMask) << 12);
|
||||
#elif defined(PPUT_RNBW_SPLIT)
|
||||
C = RNBWHackVROMPtr + vadr;
|
||||
//C += ((RNBWHackSPPage & 0x3f & RNBWHackVROMMask) << 12);
|
||||
#else
|
||||
#ifdef PPUT_MMC5CHR1
|
||||
C = MMC5HackVROMPTR;
|
||||
|
@ -86,6 +113,11 @@ pshift[1] <<= 8;
|
|||
C = MMC5BGVRAMADR(vadr);
|
||||
#else
|
||||
|
||||
#ifdef PPUT_RNBW_EXT_TILE
|
||||
C = RNBWHackVROMPtr;
|
||||
C += ( (RNBWHackBGBankOffset * 0x40000) + (( RNBWHackExNTARAMPtr[NT_1K_dest * 0x400 + (RefreshAddr & 0x3ff)] & 0x3f ) << 12) + (vadr & 0xfff) ) & RNBWHackVROMMask;
|
||||
#endif
|
||||
|
||||
#ifdef PPU_VRC5FETCH
|
||||
if(tmpd & 0x40)
|
||||
C = CHRptr[0] + vadr;
|
||||
|
|
|
@ -1139,6 +1139,8 @@
|
|||
<ClCompile Include="..\src\boards\rainbow2.cpp">
|
||||
<Filter>boards</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\mutex.cpp" />
|
||||
<ClCompile Include="..\src\ld65dbg.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\drivers\common\args.h">
|
||||
|
@ -1654,6 +1656,9 @@
|
|||
<ClInclude Include="..\src\boards\RNBW\pping.h">
|
||||
<Filter>boards</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\debugsymboltable.h" />
|
||||
<ClInclude Include="..\src\ld65dbg.h" />
|
||||
<ClInclude Include="..\src\utils\mutex.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\src\drivers\win\res.rc">
|
||||
|
@ -1667,7 +1672,6 @@
|
|||
<None Include="..\src\drivers\win\res\ICON_2.ico">
|
||||
<Filter>drivers\win\res</Filter>
|
||||
</None>
|
||||
<None Include="..\src\pputile.inc" />
|
||||
<None Include="..\src\drivers\win\res\branch_spritesheet.bmp">
|
||||
<Filter>pix</Filter>
|
||||
</None>
|
||||
|
@ -1990,6 +1994,7 @@
|
|||
<Filter>drivers\win\res</Filter>
|
||||
</None>
|
||||
<None Include="..\src\ops.inc" />
|
||||
<None Include="..\src\pputile.inc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\src\auxlib.lua" />
|
||||
|
@ -1997,4 +2002,4 @@
|
|||
<ItemGroup>
|
||||
<Image Include="..\src\drivers\win\res\bitmap21.bmp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
Loading…
Reference in New Issue