// a bit before writing a result. I.e., if the result of an operation leaves a zero in
// the carry flag, you don't have to zero gpu_flag_c before you can write that zero!
static uint8 gpu_flag_z, gpu_flag_n, gpu_flag_c;
-static uint32 gpu_reg_bank_0[32];
-static uint32 gpu_reg_bank_1[32];
+uint32 gpu_reg_bank_0[32];
+uint32 gpu_reg_bank_1[32];
static uint32 * gpu_reg;
static uint32 * gpu_alternate_reg;
uint32 GPUReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
- WriteLog("GPU: ReadLong--Attempt to read from GPU register file by %s!\n", whoName[who]);
+ {
+ WriteLog("GPU: ReadLong--Attempt to read from GPU register file (%X) by %s!\n", offset, whoName[who]);
+ uint32 reg = (offset & 0xFC) >> 2;
+ return (reg < 32 ? gpu_reg_bank_0[reg] : gpu_reg_bank_1[reg - 32]);
+ }
// if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE + 0x1000))
if ((offset >= GPU_WORK_RAM_BASE) && (offset <= GPU_WORK_RAM_BASE + 0x0FFC))
{
//WriteLog("[GPU W16:%08X,%04X]", offset, data);
uint32 old_data = GPUReadLong(offset & 0xFFFFFFC, who);
+
if (offset & 0x02)
old_data = (old_data & 0xFFFF0000) | (data & 0xFFFF);
else
old_data = (old_data & 0x0000FFFF) | ((data & 0xFFFF) << 16);
+
GPUWriteLong(offset & 0xFFFFFFC, old_data, who);
}
+
return;
}
else if ((offset == GPU_WORK_RAM_BASE + 0x0FFF) || (GPU_CONTROL_RAM_BASE + 0x1F))
case 0x00:
{
bool IMASKCleared = (gpu_flags & IMASK) && !(data & IMASK);
- gpu_flags = data;
+ // NOTE: According to the JTRM, writing a 1 to IMASK has no effect; only the
+ // IRQ logic can set it. So we mask it out here to prevent problems...
+ gpu_flags = data & (~IMASK);
gpu_flag_z = gpu_flags & ZERO_FLAG;
gpu_flag_c = (gpu_flags & CARRY_FLAG) >> 1;
gpu_flag_n = (gpu_flags & NEGA_FLAG) >> 2;
{
//WriteLog("asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not ");
}
+
gpu_control = (gpu_control & 0xF7C0) | (data & (~0xF7C0));
// if gpu wasn't running but is now running, execute a few cycles