"cheat" around the lack of pipeline emulation, delaying bankswitches/imask clears (note: branching resets the pipeline)

This commit is contained in:
CasualPokePlayer 2022-10-04 17:58:29 -07:00
parent c547a20f8e
commit d5a47490ff
4 changed files with 59 additions and 7 deletions

Binary file not shown.

View File

@ -186,6 +186,7 @@ static uint32_t dsp_opcode_first_parameter;
static uint32_t dsp_opcode_second_parameter;
static bool IMASKCleared;
static uint32_t dsp_pipeline_countdown;
static uint32_t dsp_inhibit_interrupt;
#define DSP_RUNNING (dsp_control & 0x01)
@ -245,6 +246,8 @@ static void DSPUpdateRegisterBanks(void)
dsp_reg = dsp_reg_bank_1, dsp_alternate_reg = dsp_reg_bank_0;
else
dsp_reg = dsp_reg_bank_0, dsp_alternate_reg = dsp_reg_bank_1;
dsp_pipeline_countdown = 0;
}
//
@ -452,14 +455,23 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who)
case 0x00:
{
IMASKCleared |= (dsp_flags & IMASK) && !(data & IMASK);
dsp_flags = data & (~IMASK);
dsp_flag_z = dsp_flags & 0x01;
dsp_flag_c = (dsp_flags >> 1) & 0x01;
dsp_flag_n = (dsp_flags >> 2) & 0x01;
DSPUpdateRegisterBanks();
dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3);
dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1);
if (who == DSP)
{
if (dsp_pipeline_countdown == 0)
{
dsp_pipeline_countdown = 2;
}
}
else
{
DSPUpdateRegisterBanks();
}
break;
}
case 0x04:
@ -565,6 +577,8 @@ void DSPReset(void)
dsp_flag_z = dsp_flag_n = dsp_flag_c = 0;
IMASKCleared = false;
dsp_inhibit_interrupt = 0;
dsp_pipeline_countdown = 0;
for(uint32_t i=0; i<8192; i+=4)
*((uint32_t *)(&dsp_ram_8[i])) = rand();
@ -579,10 +593,17 @@ void DSPExec(int32_t cycles)
{
MAYBE_CALLBACK(DSPTraceCallback, dsp_pc, dsp_reg);
if (IMASKCleared && !dsp_inhibit_interrupt)
if (dsp_pipeline_countdown == 0)
{
DSPHandleIRQs();
IMASKCleared = false;
if (IMASKCleared && !dsp_inhibit_interrupt)
{
DSPHandleIRQs();
IMASKCleared = false;
}
}
else if (--dsp_pipeline_countdown == 0)
{
DSPUpdateRegisterBanks();
}
dsp_inhibit_interrupt = 0;

View File

@ -178,6 +178,7 @@ static uint32_t gpu_opcode_second_parameter;
static bool IMASKCleared;
static uint32_t gpu_inhibit_interrupt;
static uint32_t gpu_pipeline_countdown;
#define GPU_RUNNING (gpu_control & 0x01)
@ -222,6 +223,8 @@ static void GPUUpdateRegisterBanks(void)
gpu_reg = gpu_reg_bank_1, gpu_alternate_reg = gpu_reg_bank_0;
else
gpu_reg = gpu_reg_bank_0, gpu_alternate_reg = gpu_reg_bank_1;
gpu_pipeline_countdown = 0;
}
static void GPUHandleIRQs(void)
@ -460,8 +463,18 @@ void GPUWriteLong(uint32_t offset, uint32_t data, uint32_t who)
gpu_flag_z = gpu_flags & ZERO_FLAG;
gpu_flag_c = (gpu_flags & CARRY_FLAG) >> 1;
gpu_flag_n = (gpu_flags & NEGA_FLAG) >> 2;
GPUUpdateRegisterBanks();
gpu_control &= ~((gpu_flags & CINT04FLAGS) >> 3);
if (who == GPU)
{
if (gpu_pipeline_countdown == 0)
{
gpu_pipeline_countdown = 2;
}
}
else
{
GPUUpdateRegisterBanks();
}
break;
}
case 0x04:
@ -562,7 +575,8 @@ void GPUReset(void)
gpu_flag_z = gpu_flag_n = gpu_flag_c = 0;
IMASKCleared = false;
memset(gpu_ram_8, 0xFF, 0x1000);
gpu_inhibit_interrupt = 0;
gpu_pipeline_countdown = 0;
for(uint32_t i=0; i<4096; i+=4)
*((uint32_t *)(&gpu_ram_8[i])) = rand();
@ -583,6 +597,19 @@ void GPUExec(int32_t cycles)
IMASKCleared = false;
}
if (gpu_pipeline_countdown == 0)
{
if (IMASKCleared && !gpu_inhibit_interrupt)
{
GPUHandleIRQs();
IMASKCleared = false;
}
}
else if (--gpu_pipeline_countdown == 0)
{
GPUUpdateRegisterBanks();
}
gpu_inhibit_interrupt = 0;
uint16_t opcode = GPUReadWord(gpu_pc, GPU);
uint32_t index = opcode >> 10;

View File

@ -22,6 +22,7 @@
#define RISCReadWord(x, y) GPUReadWord(x, y)
#define RISCReadLong(x, y) GPUReadLong(x, y)
#define RISCWriteLong(x, y, z) GPUWriteLong(x, y, z)
#define RISCUpdateRegisterBanks GPUUpdateRegisterBanks()
#elif RISC == 2
#define RISC_OPCODE(op) static void dsp_opcode_##op(void)
#define risc_inhibit_interrupt dsp_inhibit_interrupt
@ -44,6 +45,7 @@
#define RISCReadWord(x, y) DSPReadWord(x, y)
#define RISCReadLong(x, y) DSPReadLong(x, y)
#define RISCWriteLong(x, y, z) DSPWriteLong(x, y, z)
#define RISCUpdateRegisterBanks DSPUpdateRegisterBanks()
#else
#error RISC improperly defined
#endif
@ -90,6 +92,7 @@ RISC_OPCODE(jump)
risc_inhibit_interrupt = 1;
RISCExec(1);
risc_pc = delayed_pc;
RISCUpdateRegisterBanks;
}
}
@ -104,6 +107,7 @@ RISC_OPCODE(jr)
risc_inhibit_interrupt = 1;
RISCExec(1);
risc_pc = delayed_pc;
RISCUpdateRegisterBanks;
}
}