updated IRQs + added ZPCM + added reset detection

- IRQ cleanup
- added PPU IRQ m2 jitter counter
- added HBlank flag
- ZPCM added (not working as intended...)
- $fffc/$fffd reset detection
This commit is contained in:
contact@brokestudio.fr 2023-08-01 10:01:13 +02:00
parent 9f5c92d6e0
commit 4a0fc7ae18
2 changed files with 216 additions and 237 deletions

View File

@ -111,19 +111,22 @@ static int CHRRAMSIZE = 0; // max 512 KiB
extern uint8 *ExtraNTARAM;
static uint8 RNBWbattery = 0;
static uint8 reset_step = 0;
// Scanline IRQ
static uint8 S_IRQcontrol, S_IRQlatch, S_IRQoffset; // matches hardware register
static bool S_IRQ_enable, S_IRQ_pending, S_IRQ_in_frame, S_IRQ_HBlank;
static uint8 S_IRQ_latch, S_IRQ_offset, S_IRQ_jitter_counter;
// additional flags to emulate hardware correctly
static float S_IRQdotcount;
static uint8 S_IRQready, S_IRQlastSLtriggered;
static float S_IRQ_dot_count;
static uint8 S_IRQ_ready, S_IRQ_last_SL_triggered;
// CPU Cycle IRQ
static bool C_IRQe, C_IRQr, C_IRQp;
static bool C_IRQ_enable, C_IRQ_reset, C_IRQ_pending;
static int32 C_IRQLatch, C_IRQCount;
// ESP message IRQ
static uint8 ESP_IRQp;
static uint8 ESP_IRQ_pending;
static uint8 flash_mode[2];
static uint8 flash_sequence[2];
@ -153,20 +156,23 @@ static SFORMAT Rainbow2StateRegs[] =
{ prg, 11, "PRG" },
{ chr, 16, "CHR" },
{ &S_IRQcontrol, 1, "SICO" },
{ &S_IRQlatch, 1, "SILA" },
{ &S_IRQoffset, 1, "SIOF" },
{ &S_IRQdotcount, 4, "SIDC" },
{ &S_IRQready, 1, "SIRE" },
{ &S_IRQlastSLtriggered, 1, "SITR" },
{ &S_IRQ_enable, 1, "PPUE" },
{ &S_IRQ_pending, 1, "PPUP" },
{ &S_IRQ_in_frame, 1, "PPUF" },
{ &S_IRQ_HBlank, 1, "PPUH" },
{ &S_IRQ_latch, 1, "PPUL" },
{ &S_IRQ_offset, 1, "PPUO" },
{ &S_IRQ_dot_count, 4, "PPUD" },
{ &S_IRQ_ready, 1, "PPUR" },
{ &S_IRQ_last_SL_triggered, 1, "PPUT" },
{ &C_IRQe, 1, "CPUA" },
{ &C_IRQp, 1, "CPUP" },
{ &C_IRQr, 1, "CPUR" },
{ &C_IRQ_enable, 1, "CPUE" },
{ &C_IRQ_pending, 1, "CPUP" },
{ &C_IRQ_reset, 1, "CPUR" },
{ &C_IRQLatch, 4, "CPUL" },
{ &C_IRQCount, 4, "CPUC" },
{ &ESP_IRQp, 1, "ESPP" },
{ &ESP_IRQ_pending, 1, "ESPP" },
{ 0 }
};
@ -178,10 +184,12 @@ static int32 cvbc[3];
static int32 vcount[3];
static int32 dcount[2];
static uint8 ZPCM[3];
static SFORMAT SStateRegs[] =
{
{ vpsg1, 8, "PSG1" },
{ vpsg2, 4, "PSG2" },
{ vpsg1, 8, "PSG1" }, // SQ 1+2
{ vpsg2, 4, "PSG2" }, // SAW
{ 0 }
};
@ -216,7 +224,7 @@ static void clear_esp_message_received() {
}
static void IRQEnd() {
if (!C_IRQp && !(S_IRQcontrol & 0x80) && !ESP_IRQp)
if (!C_IRQ_pending & !S_IRQ_pending & !ESP_IRQ_pending)
{
X6502_IRQEnd(FCEU_IQEXT);
}
@ -229,64 +237,72 @@ static void Rainbow2IRQ(int a) {
int dot = newppu_get_dot();
int ppuon = (PPU[1] & 0x18);
S_IRQ_jitter_counter += a;
if (dot >= 256)
S_IRQ_HBlank = true;
else
S_IRQ_HBlank = false;
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)
S_IRQcontrol &= ~0x40; // in-frame flag cleared
S_IRQcontrol &= ~0x80; // pending IRQ flag cleared
S_IRQready = 0;
S_IRQlastSLtriggered = 255;
S_IRQ_in_frame = false; // in-frame flag cleared
S_IRQ_pending = false; // pending IRQ flag cleared
S_IRQ_ready = 0;
S_IRQ_last_SL_triggered = 255;
IRQEnd();
}
else
{
if (!(S_IRQcontrol & 0x40))
if (!S_IRQ_in_frame)
{
S_IRQcontrol |= 0x40;
S_IRQcontrol &= ~0x80;
S_IRQ_in_frame = true;
S_IRQ_pending = false;
IRQEnd();
}
// this is kind of hacky but result is pretty close to hardware
if ((sl == S_IRQlatch) & !S_IRQready & !(S_IRQcontrol & 0x80) & (sl != S_IRQlastSLtriggered))
if ((sl == S_IRQ_latch) & (S_IRQ_ready == 0) & !S_IRQ_pending & (sl != S_IRQ_last_SL_triggered))
{
S_IRQready = 1;
S_IRQdotcount = (float)dot;
if (PAL) S_IRQdotcount -= a * 3.2;
else S_IRQdotcount -= (float)a * 3;
S_IRQ_ready = 1;
S_IRQ_dot_count = (float)dot;
if (PAL) S_IRQ_dot_count -= a * 3.2;
else S_IRQ_dot_count -= (float)a * 3;
}
if ((S_IRQready == 1) & !(S_IRQcontrol & 0x80))
if ((S_IRQ_ready == 1) & !S_IRQ_pending)
{
if (PAL) S_IRQdotcount += (float)a * 3.2;
else S_IRQdotcount += (float)a * 3;
if (PAL) S_IRQ_dot_count += (float)a * 3.2;
else S_IRQ_dot_count += (float)a * 3;
int dotTarget = (S_IRQoffset * 2);
int dotTarget = (S_IRQ_offset * 2);
if (PAL) dotTarget += 20;
else dotTarget += 24;
if (((int)S_IRQdotcount) >= dotTarget)
if (((int)S_IRQ_dot_count) >= dotTarget)
{
S_IRQready = 2;
S_IRQlastSLtriggered = S_IRQlatch;
S_IRQ_ready = 2;
S_IRQ_last_SL_triggered = S_IRQ_latch;
}
}
if ((S_IRQcontrol & 0x01) && !(S_IRQcontrol & 0x80) && (S_IRQready == 2))
if (S_IRQ_enable & !S_IRQ_pending & (S_IRQ_ready == 2))
{
X6502_IRQBegin(FCEU_IQEXT);
S_IRQcontrol |= 0x80;
S_IRQready = 0;
S_IRQ_pending = true;
S_IRQ_ready = 0;
S_IRQ_jitter_counter = 0;
}
}
// Cycle Counter IRQ
if (C_IRQe) {
if (C_IRQ_enable) {
C_IRQCount -= a;
if (C_IRQCount <= 0) {
C_IRQe = C_IRQr;
C_IRQp = true;
C_IRQ_enable = C_IRQ_reset;
C_IRQ_pending = true;
C_IRQCount = C_IRQLatch;
X6502_IRQBegin(FCEU_IQEXT);
}
@ -298,11 +314,11 @@ static void Rainbow2IRQ(int a) {
if (esp_message_received())
{
X6502_IRQBegin(FCEU_IQEXT);
ESP_IRQp = 1;
ESP_IRQ_pending = 1;
}
else
{
ESP_IRQp = 0;
ESP_IRQ_pending = 0;
}
}
@ -310,9 +326,6 @@ static void Rainbow2IRQ(int a) {
}
static void Sync(void) {
//static uint8 *address;
//uint32 start;
//uint32 offset;
uint8 cart_chr_map;
// $8000-$ffff
@ -455,21 +468,21 @@ static void Sync(void) {
// CHR
switch (chr_chip)
{
case CHR_CHIP_ROM:
RNBWHackVROMPtr = CHR_FLASHROM;
RNBWHackVROMMask = CHR_FLASHROMSIZE - 1;
break;
case CHR_CHIP_RAM:
RNBWHackVROMPtr = CHRRAM;
RNBWHackVROMMask = CHRRAMSIZE - 1;
break;
case CHR_CHIP_FPGA_RAM:
RNBWHackVROMPtr = FPGA_RAM;
RNBWHackVROMMask = FPGA_RAMSIZE - 1;
break;
case CHR_CHIP_ROM:
RNBWHackVROMPtr = CHR_FLASHROM;
RNBWHackVROMMask = CHR_FLASHROMSIZE - 1;
break;
case CHR_CHIP_RAM:
RNBWHackVROMPtr = CHRRAM;
RNBWHackVROMMask = CHRRAMSIZE - 1;
break;
case CHR_CHIP_FPGA_RAM:
RNBWHackVROMPtr = FPGA_RAM;
RNBWHackVROMMask = FPGA_RAMSIZE - 1;
break;
}
if(chr_chip == CHR_CHIP_FPGA_RAM)
if (chr_chip == CHR_CHIP_FPGA_RAM)
{
setchr4r(0x12, 0x0000, 0);
setchr4r(0x12, 0x1000, 0);
@ -532,125 +545,45 @@ static void Sync(void) {
}
static DECLFW(RNBW_ExpAudioWr) {
uint8 i;
if (A >= 0x41A0 && A <= 0x41A2)
{
vpsg1[A & 3] = V;
i = A & 3; // 0, 1, 2
vpsg1[i] = V;
if (sfun[0])
sfun[0]();
}
else if (A >= 0x41A3 && A <= 0x41A5)
{
vpsg1[4 | ((A - 3) & 3)] = V;
i = 4 | ((A - 3) & 3); // 4, 5, 6
vpsg1[i] = V;
if (sfun[1])
sfun[1]();
}
else if (A >= 0x41A6 && A <= 0x41A8)
{
vpsg2[(A - 6) & 3] = V;
i = (A - 6) & 3; // 0, 1, 2
vpsg2[i] = V;
if (sfun[2])
sfun[2]();
}
}
static DECLFW(WRAM_0x6000Wr)
{
// $6000-$7fff
// 8K
if (prg_ram_mode == PRG_RAM_MODE_0)
{
if (((prg[1] & 0xC000) >> 14) == 3)
CartBW(A, V); // FPGA_RAM
else if ((((prg[1] & 0xC000) >> 14) == 2) && WRAM)
CartBW(A, V); // WRAM
else if (((prg[1] & 0x8000) >> 15) == 0)
CartBW(A, V); // PRG-ROM
}
// 4K
if (prg_ram_mode == PRG_RAM_MODE_1)
{
if ((A >= 0x6000) & (A < 0x7000))
{
if (((prg[1] & 0xC000) >> 14) == 3)
CartBW(A, V); // FPGA_RAM
else if ((((prg[1] & 0xC000) >> 14) == 2) && WRAM)
CartBW(A, V); // WRAM
else if (((prg[1] & 0x8000) >> 15) == 0)
CartBW(A, V); // PRG-ROM
}
if ((A >= 0x7000) & (A < 0x8000))
{
if (((prg[2] & 0xC000) >> 14) == 3)
CartBW(A, V); // FPGA_RAM
else if ((((prg[2] & 0xC000) >> 14) == 2) && WRAM)
CartBW(A, V); // WRAM
else if (((prg[2] & 0x8000) >> 15) == 0)
CartBW(A, V); // PRG-ROM
}
}
static DECLFR(RNBW_0x4011Rd) {
uint8 ZPCM_val = ((ZPCM[0] + ZPCM[1] + ZPCM[2]) & 0x3f) << 2;
return ZPCM_val;
}
static DECLFR(WRAM_0x6000Rd)
{
// $6000-$7fff
// 8K
if (prg_ram_mode == PRG_RAM_MODE_0)
static DECLFR(RNBW_RstPowRd) {
if (A == 0xFFFC) reset_step = 1;
else if (A == 0xFFFD & reset_step == 1)
{
if (((prg[1] & 0xC000) >> 14) == 3)
return CartBR(A); // FPGA_RAM
else if ((((prg[1] & 0xC000) >> 14) == 2) && WRAM)
return CartBR(A); // WRAM
else if (((prg[1] & 0x8000) >> 15) == 0)
return CartBR(A); // PRG-ROM
Rainbow2Reset();
reset_step = 0;
}
// 4K
if (prg_ram_mode == PRG_RAM_MODE_1)
{
if ((A >= 0x6000) & (A < 0x7000))
{
if (((prg[1] & 0xC000) >> 14) == 3)
return CartBR(A); // FPGA_RAM
else if ((((prg[1] & 0xC000) >> 14) == 2) && WRAM)
return CartBR(A); // WRAM
else if (((prg[1] & 0x8000) >> 15) == 0)
return CartBR(A); // PRG-ROM
}
if ((A >= 0x7000) & (A < 0x8000))
{
if (((prg[2] & 0xC000) >> 14) == 3)
return CartBR(A); // FPGA_RAM
else if ((((prg[2] & 0xC000) >> 14) == 2) && WRAM)
return CartBR(A); // WRAM
else if (((prg[2] & 0x8000) >> 15) == 0)
return CartBR(A); // PRG-ROM
}
}
return X.DB;
}
static DECLFW(WRAM_0x5000Wr)
{
CartBW(A, V);
}
static DECLFR(WRAM_0x5000Rd)
{
else reset_step = 0;
return CartBR(A);
}
static DECLFW(FPGA_0x4800Wr)
{
CartBW(A, V);
//FPGA_RAM[(A & 0x7ff) + 0x1800] = V;
}
static DECLFR(FPGA_0x4800Rd)
{
return CartBR(A);
//return FPGA_RAM[(A & 0x7ff) + 0x1800];
}
static DECLFR(RNBW_0x4100Rd) {
switch (A)
@ -658,12 +591,15 @@ static DECLFR(RNBW_0x4100Rd) {
case 0x4100: return (prg_ram_mode << 6) | prg_rom_mode;
case 0x4120: return (chr_chip << 6) | (chr_spr_ext_mode << 5) | chr_mode;
case 0x4151: {
S_IRQcontrol &= ~0x80;
S_IRQready = 0;
uint8 rv = (S_IRQ_HBlank ? 0x80 : 0) | (S_IRQ_in_frame ? 0x40 : 0 | (S_IRQ_pending ? 0x01 : 0));
S_IRQ_pending = false;
S_IRQ_ready = 0;
IRQEnd();
return CartBR(A);
return rv;
}
case 0x4154: return S_IRQ_jitter_counter;
case 0x4160: return MAPPER_VERSION;
case 0x4161: return (S_IRQ_pending ? 0x80 : 0) | (C_IRQ_pending ? 0x40 : 0) | (ESP_IRQ_pending ? 0x01 : 0);
// ESP - WiFi
case 0x4170:
@ -712,7 +648,7 @@ static DECLFW(RNBW_0x4100Wr) {
case 0x410E:
case 0x410F:
{
int bank = ( A & 0x0f ) - 5;
int bank = (A & 0x0f) - 5;
prg[bank] = (prg[bank] & 0x00ff) | (V << 8);
Sync();
break;
@ -729,12 +665,12 @@ static DECLFW(RNBW_0x4100Wr) {
case 0x411E:
case 0x411F:
{
int bank = ( A & 0x0f ) - 5;
int bank = (A & 0x0f) - 5;
prg[bank] = (prg[bank] & 0xff00) | V;
Sync();
break;
}
// CHR banking / chip selector / sprite extended mode
// CHR banking / chip selector / sprite extended mode
case 0x4120:
chr_chip = (V & 0xC0) >> 6;
chr_spr_ext_mode = (V & 0x20) >> 5;
@ -799,22 +735,22 @@ static DECLFW(RNBW_0x4100Wr) {
Sync();
break;
}
// Scanline IRQ
case 0x4150: S_IRQlatch = V; break;
case 0x4151: S_IRQcontrol |= 1; break;
case 0x4152: S_IRQcontrol &= 0x7E; break;
case 0x4153: S_IRQoffset = V > 169 ? 169 : V; break;
// Scanline IRQ
case 0x4150: S_IRQ_latch = V; break;
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
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:
C_IRQe = V & 0x01;
C_IRQr = (V & 0x02) >> 1;
if (C_IRQe)
C_IRQ_enable = V & 0x01;
C_IRQ_reset = (V & 0x02) >> 1;
if (C_IRQ_enable)
C_IRQCount = C_IRQLatch;
break;
case 0x415B:
C_IRQp = false;
C_IRQ_pending = false;
IRQEnd();
break;
// ESP - WiFi
@ -869,27 +805,27 @@ 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-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 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)
{
if (ppuphase == PPUPHASE_OBJ && ScreenON)
{
if (chr_spr_ext_mode)
if(Sprite16)
if (Sprite16)
return RNBWHackVROMPtr[((SPR_bank[RNBWHackCurSprite] << 13) & RNBWHackVROMMask) + (A)]; // TODO: test + fix
else
return RNBWHackVROMPtr[((SPR_bank[RNBWHackCurSprite] << 12) & RNBWHackVROMMask) + (A)];
@ -914,7 +850,7 @@ uint8 FASTCALL Rainbow2PPURead(uint32 A) {
uint8 NT = (A >> 10) & 0x03;
uint8 NT_1K_dest = (RNBWHackNTcontrol[NT] & 0x0C) >> 2;
uint8 NT_ext_mode = RNBWHackNTcontrol[NT] & 0x03;
if(( A & 0x3FF ) >= 0x3C0)
if ((A & 0x3FF) >= 0x3C0)
{
// Attributes
if (NT_ext_mode & 0x01)
@ -1184,14 +1120,14 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
case 1024: // S29AL008
if (S29AL008_TOP && sector_index == 15)
{
if (flash_addr >= 0xF0000 && flash_addr <= 0xF7FFF) { sector_offset = 0xF0000; sector_size = 32; }
if (flash_addr >= 0xF0000 && flash_addr <= 0xF7FFF) { sector_offset = 0xF0000; sector_size = 32; }
else if (flash_addr >= 0xF8000 && flash_addr <= 0xF9FFF) { sector_offset = 0xF8000; sector_size = 8; }
else if (flash_addr >= 0xFA000 && flash_addr <= 0xFBFFF) { sector_offset = 0xFA000; sector_size = 8; }
else if (flash_addr >= 0xFC000 && flash_addr <= 0xFFFFF) { sector_offset = 0xFC000; sector_size = 16; }
}
else if (!S29AL008_TOP && sector_index == 0)
{
if (flash_addr >= 0x00000 && flash_addr <= 0x03FFF) { sector_offset = 0x00000; sector_size = 16; }
if (flash_addr >= 0x00000 && flash_addr <= 0x03FFF) { sector_offset = 0x00000; sector_size = 16; }
else if (flash_addr >= 0x04000 && flash_addr <= 0x05FFF) { sector_offset = 0x04000; sector_size = 8; }
else if (flash_addr >= 0x06000 && flash_addr <= 0x07FFF) { sector_offset = 0x06000; sector_size = 8; }
else if (flash_addr >= 0x08000 && flash_addr <= 0x0FFFF) { sector_offset = 0x08000; sector_size = 32; }
@ -1200,14 +1136,14 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
case 2048: // S29AL016
if (S29AL016_TOP && sector_index == 31)
{
if (flash_addr >= 0x1F0000 && flash_addr <= 0x1F7FFF) { sector_offset = 0xF0000; sector_size = 32; }
if (flash_addr >= 0x1F0000 && flash_addr <= 0x1F7FFF) { sector_offset = 0xF0000; sector_size = 32; }
else if (flash_addr >= 0x1F8000 && flash_addr <= 0x1F9FFF) { sector_offset = 0xF8000; sector_size = 8; }
else if (flash_addr >= 0x1FA000 && flash_addr <= 0x1FBFFF) { sector_offset = 0xFA000; sector_size = 8; }
else if (flash_addr >= 0x1FC000 && flash_addr <= 0x1FFFFF) { sector_offset = 0xFC000; sector_size = 16; }
}
else if (!S29AL016_TOP && sector_index == 0)
{
if (flash_addr >= 0x00000 && flash_addr <= 0x03FFF) { sector_offset = 0x00000; sector_size = 16; }
if (flash_addr >= 0x00000 && flash_addr <= 0x03FFF) { sector_offset = 0x00000; sector_size = 16; }
else if (flash_addr >= 0x04000 && flash_addr <= 0x05FFF) { sector_offset = 0x04000; sector_size = 8; }
else if (flash_addr >= 0x06000 && flash_addr <= 0x07FFF) { sector_offset = 0x06000; sector_size = 8; }
else if (flash_addr >= 0x08000 && flash_addr <= 0x0FFFF) { sector_offset = 0x08000; sector_size = 32; }
@ -1216,7 +1152,7 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
case 4096: // S29JL032
if (S29JL032_TOP && sector_index == 63)
{
if (flash_addr >= 0x3F0000 && flash_addr <= 0x3F1FFF) { sector_offset = 0x3F0000; sector_size = 8; }
if (flash_addr >= 0x3F0000 && flash_addr <= 0x3F1FFF) { sector_offset = 0x3F0000; sector_size = 8; }
else if (flash_addr >= 0x3F2000 && flash_addr <= 0x3F3FFF) { sector_offset = 0x3F2000; sector_size = 8; }
else if (flash_addr >= 0x3F4000 && flash_addr <= 0x3F5FFF) { sector_offset = 0x3F4000; sector_size = 8; }
else if (flash_addr >= 0x3F6000 && flash_addr <= 0x3F7FFF) { sector_offset = 0x3F6000; sector_size = 8; }
@ -1228,7 +1164,7 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
}
else if (!S29JL032_TOP && sector_index == 0)
{
if (flash_addr >= 0x000000 && flash_addr <= 0x001FFF) { sector_offset = 0x000000; sector_size = 8; }
if (flash_addr >= 0x000000 && flash_addr <= 0x001FFF) { sector_offset = 0x000000; sector_size = 8; }
else if (flash_addr >= 0x002000 && flash_addr <= 0x003FFF) { sector_offset = 0x002000; sector_size = 8; }
else if (flash_addr >= 0x004000 && flash_addr <= 0x005FFF) { sector_offset = 0x004000; sector_size = 8; }
else if (flash_addr >= 0x006000 && flash_addr <= 0x007FFF) { sector_offset = 0x006000; sector_size = 8; }
@ -1241,7 +1177,7 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
case 8192: // S29GL064S
if (!S29GL064S_TOP && sector_index == 0)
{
if (flash_addr >= 0x000000 && flash_addr <= 0x001FFF) { sector_offset = 0x000000; sector_size = 8; }
if (flash_addr >= 0x000000 && flash_addr <= 0x001FFF) { sector_offset = 0x000000; sector_size = 8; }
else if (flash_addr >= 0x002000 && flash_addr <= 0x003FFF) { sector_offset = 0x002000; sector_size = 8; }
else if (flash_addr >= 0x004000 && flash_addr <= 0x005FFF) { sector_offset = 0x004000; sector_size = 8; }
else if (flash_addr >= 0x006000 && flash_addr <= 0x007FFF) { sector_offset = 0x006000; sector_size = 8; }
@ -1252,7 +1188,7 @@ void Rainbow2Flash(uint8 chip, uint32 flash_addr, uint8 V) {
}
else if (S29GL064S_TOP && sector_index == 127)
{
if (flash_addr >= 0x7F0000 && flash_addr <= 0x7F1FFF) { sector_offset = 0x7F0000; sector_size = 8; }
if (flash_addr >= 0x7F0000 && flash_addr <= 0x7F1FFF) { sector_offset = 0x7F0000; sector_size = 8; }
else if (flash_addr >= 0x7F2000 && flash_addr <= 0x7F3FFF) { sector_offset = 0x7F2000; sector_size = 8; }
else if (flash_addr >= 0x7F4000 && flash_addr <= 0x7F5FFF) { sector_offset = 0x7F4000; sector_size = 8; }
else if (flash_addr >= 0x7F6000 && flash_addr <= 0x7F7FFF) { sector_offset = 0x7F6000; sector_size = 8; }
@ -1306,7 +1242,7 @@ static DECLFW(RNBW_0x6000Wr) {
prg_idx = ((A >> 12) & 0x07) - 6;
if (((prg[prg_idx] & 0x8000) >> 14) != 0)
return CartBW(A, V); // FPGA_RAM or WRAM
// PRG-ROM
flash_addr &= 0x1FFF;
flash_addr |= (prg[prg_idx] & 0x7FFF) << 13;
@ -1368,7 +1304,7 @@ static DECLFW(RNBW_0x6000Wr) {
prg_idx = ((A >> 12) & 0x06) + 3;
if ((prg[prg_idx] >> 14) != 0)
return CartBW(A, V); // WRAM
// PRG-ROM
flash_addr &= 0x1FFF;
flash_addr |= (prg[prg_idx] & 0x7FFF) << 13;
@ -1377,10 +1313,10 @@ static DECLFW(RNBW_0x6000Wr) {
case PRG_ROM_MODE_4:
// 8 x 4K
prg_idx = ((A >> 12) & 0x07) + 3;
if ((prg[prg_idx] >> 14) != 0)
return CartBW(A, V); // WRAM
// PRG-ROM
flash_addr &= 0x0FFF;
flash_addr |= (prg[prg_idx] & 0x7FFF) << 13;
@ -1394,15 +1330,15 @@ static DECLFW(RNBW_0x6000Wr) {
}
static void Rainbow2PPUWrite(uint32 A, uint8 V) {
/*
// if CHR-RAM but CHR-RAM does not exist then return
if (chr_chip == CHR_CHIP_RAM && CHRRAM == NULL)
return;
/*
// if CHR-RAM but CHR-RAM does not exist then return
if (chr_chip == CHR_CHIP_RAM && CHRRAM == NULL)
return;
// if CHR-ROM but CHR-ROM does not exist then return
if (chr_chip == CHR_CHIP_ROM && CHR_FLASHROM == NULL)
return;
else*/
// if CHR-ROM but CHR-ROM does not exist then return
if (chr_chip == CHR_CHIP_ROM && CHR_FLASHROM == NULL)
return;
else*/
{
uint32 flash_addr = A;
if (A < 0x2000)
@ -1438,6 +1374,9 @@ static void Rainbow2PPUWrite(uint32 A, uint8 V) {
}
static void Rainbow2Reset(void) {
// reset
reset_step = 0;
// PRG - 32K banks mapped to first PRG-ROM bank
prg_rom_mode = PRG_ROM_MODE_0;
prg[3] = 0;
@ -1460,11 +1399,16 @@ static void Rainbow2Reset(void) {
RNBWHackNTcontrol[3] = 0;
// Scanline IRQ
S_IRQcontrol = 0;
S_IRQoffset = 135;
S_IRQ_enable = false;
S_IRQ_pending = false;
S_IRQ_in_frame = false;
S_IRQ_HBlank = false;
S_IRQ_offset = 135;
// CPU Cycle IRQ
C_IRQe = C_IRQp = C_IRQr = 0;
C_IRQ_enable = false;
C_IRQ_pending = false;
C_IRQ_reset = false;
// Audio Output
audio_output = 1;
@ -1476,31 +1420,39 @@ static void Rainbow2Reset(void) {
//rx_address = 0;
//tx_address = 0;
//rx_index = 0;
ESP_IRQp = 0;
ESP_IRQ_pending = 0;
Sync();
}
static void Rainbow2Power(void) {
// mapper init
if(MiscROMS) bootrom = 1;
if (MiscROMS) bootrom = 1;
else bootrom = 0;
Rainbow2Reset();
Rainbow2Reset();
SetReadHandler(0x4800, 0xFFFF, CartBR);
SetWriteHandler(0x4800, 0x7FFF, CartBW);
/*
if (WRAM)
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
FCEU_CheatAddRAM(FPGA_RAMSIZE >> 10, 0x5000, FPGA_RAM);
FCEU_CheatAddRAM(0x1800 >> 10, 0x4800, FPGA_RAM);
*/
// reset-power vectors
SetReadHandler(0xFFFC, 0xFFFF, RNBW_RstPowRd);
//
SetReadHandler(0x4800, 0xFFFB, CartBR);
SetWriteHandler(0x4800, 0x5FFF, CartBW);
/*
if (WRAM)
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
FCEU_CheatAddRAM(FPGA_RAMSIZE >> 10, 0x5000, FPGA_RAM);
FCEU_CheatAddRAM(0x1800 >> 10, 0x4800, FPGA_RAM);
*/
// mapper registers (writes)
SetWriteHandler(0x4100, 0x47ff, RNBW_0x4100Wr);
// mapper registers (reads)
SetReadHandler(0x4100, 0x47ff, RNBW_0x4100Rd);
// audio expansion (reads)
SetReadHandler(0x4011, 0x4011, RNBW_0x4011Rd);
// audio expansion registers (writes)
SetWriteHandler(0x41A0, 0x41A8, RNBW_ExpAudioWr);
@ -1512,8 +1464,7 @@ static void Rainbow2Power(void) {
flash_id[CHIP_TYPE_PRG] = false;
flash_id[CHIP_TYPE_CHR] = false;
SetWriteHandler(0x6000, 0xFFFF, RNBW_0x6000Wr);
// fill WRAM/FPGA_RAM/CHRRAM/DUMMY_CHRRAM/DUMMY_CHRROM with random values
if (WRAM && !RNBWbattery)
FCEU_MemoryRand(WRAM, WRAMSIZE, false);
@ -1635,7 +1586,9 @@ static INLINE void DoSQV(int x) {
if (vpsg1[x << 2] & 0x80)
{
for (V = start; V < end; V++)
{
Wave[V >> 4] += amp;
}
}
else
{
@ -1643,7 +1596,9 @@ static INLINE void DoSQV(int x) {
int32 freq = ((vpsg1[(x << 2) | 0x1] | ((vpsg1[(x << 2) | 0x2] & 15) << 8)) + 1) << 17;
for (V = start; V < end; V++) {
if (dcount[x] > thresh)
{
Wave[V >> 4] += amp;
}
vcount[x] -= nesincsize;
while (vcount[x] <= 0) {
vcount[x] += freq;
@ -1708,32 +1663,51 @@ static void DoSawV(void) {
}
static INLINE void DoSQVHQ(int x) {
int32 V;
int32 amp = ((vpsg1[x << 2] & 15) << 8) * 6 / 8;
int volume = vpsg1[x << 2] & 15;
int duty = (vpsg1[x << 2] >> 4) & 7;
bool ignore_duty = vpsg1[x << 2] & 0x80;
int freq_lo = vpsg1[(x << 2) | 0x1];
int freq_hi = vpsg1[(x << 2) | 0x2] & 15;
bool enable = vpsg1[(x << 2) | 0x2] & 0x80;
if ((vpsg1[(x << 2) | 0x2] & 0x80) && (audio_output & 0x03))
int32 V;
int32 amp = (volume << 8) * 6 / 8;
if (enable)
{
if (vpsg1[x << 2] & 0x80)
if (ignore_duty)
{
for (V = cvbc[x]; V < (int)SOUNDTS; V++)
WaveHi[V] += amp;
{
if (audio_output & 0x03) WaveHi[V] += amp;
ZPCM[x] = volume;
}
}
else
{
int32 thresh = (vpsg1[x << 2] >> 4) & 7;
int32 thresh = duty;
for (V = cvbc[x]; V < (int)SOUNDTS; V++) {
if (dcount[x] > thresh)
WaveHi[V] += amp;
{
if (audio_output & 0x03) WaveHi[V] += amp;
ZPCM[x] = volume;
}
vcount[x]--;
if (vcount[x] <= 0)
{
vcount[x] = (vpsg1[(x << 2) | 0x1] | ((vpsg1[(x << 2) | 0x2] & 15) << 8)) + 1;
vcount[x] = (freq_lo | (freq_hi << 8)) + 1;
dcount[x] = (dcount[x] + 1) & 15;
}
}
}
}
else
{
ZPCM[x] = 0;
}
cvbc[x] = SOUNDTS;
return;
}
static void DoSQV1HQ(void) {
@ -1749,10 +1723,11 @@ static void DoSawVHQ(void) {
static int32 phaseacc = 0;
int32 V;
if ((vpsg2[2] & 0x80) && (audio_output & 0x03))
if (vpsg2[2] & 0x80)
{
for (V = cvbc[2]; V < (int)SOUNDTS; V++) {
WaveHi[V] += (((phaseacc >> 3) & 0x1f) << 8) * 6 / 8;
ZPCM[2] = (phaseacc >> 3) & 0x1f;
if (audio_output & 0x03) WaveHi[V] += (((phaseacc >> 3) & 0x1f) << 8) * 6 / 8;
vcount[2]--;
if (vcount[2] <= 0)
{
@ -1766,6 +1741,10 @@ static void DoSawVHQ(void) {
}
}
}
else
{
ZPCM[2] = 0;
}
cvbc[2] = SOUNDTS;
}
@ -1963,7 +1942,7 @@ void RAINBOW2_Init(CartInfo *info) {
}
SetupCartCHRMapping(0x10, CHR_FLASHROM, CHR_FLASHROMSIZE, 0);
}
else
else
{
// create dummy CHR-ROM to avoid crash when trying to use CHR-ROM for pattern tables
// when no CHR-ROM is specified in the ROM header

View File

@ -23,8 +23,8 @@ static uint8 const NO_WORKING_FILE = 0xff;
static uint8 const NUM_FILE_PATHS = 3;
static uint8 const NUM_FILES = 64;
static uint64 const ESP_FLASH_SIZE = 0x200000; // 2MiB - 0x200000
static uint64 const SD_CARD_SIZE = 0x80000000; // 2GiB - 0x80000000
static uint64 const ESP_FLASH_SIZE = 0x200000; // 2MiB
static uint64 const SD_CARD_SIZE = 0x80000000; // 2GiB
static uint8 const NUM_NETWORKS = 3;
static uint8 const NUM_FAKE_NETWORKS = 5;