static void gpu_opcode_pack(void);
// This is wrong, since it doesn't take pipeline effects into account. !!! FIX !!!
static void gpu_opcode_pack(void);
// This is wrong, since it doesn't take pipeline effects into account. !!! FIX !!!
//This is wrong, wrong, WRONG, but it seems to work for the time being...
//(That is, it fixes Flip Out which relies on GPU timing rather than semaphores. Bad developers! Bad!)
//What's needed here is a way to take pipeline effects into account (including pipeline stalls!)...
//This is wrong, wrong, WRONG, but it seems to work for the time being...
//(That is, it fixes Flip Out which relies on GPU timing rather than semaphores. Bad developers! Bad!)
//What's needed here is a way to take pipeline effects into account (including pipeline stalls!)...
gpu_opcode_store_r14_ri, gpu_opcode_store_r15_ri, gpu_opcode_sat24, gpu_opcode_pack,
};
gpu_opcode_store_r14_ri, gpu_opcode_store_r15_ri, gpu_opcode_sat24, gpu_opcode_pack,
};
-static uint8 gpu_ram_8[0x1000];
-uint32 gpu_pc;
-static uint32 gpu_acc;
-static uint32 gpu_remain;
-static uint32 gpu_hidata;
-static uint32 gpu_flags;
-static uint32 gpu_matrix_control;
-static uint32 gpu_pointer_to_matrix;
-static uint32 gpu_data_organization;
-static uint32 gpu_control;
-static uint32 gpu_div_control;
+static uint8_t gpu_ram_8[0x1000];
+uint32_t gpu_pc;
+static uint32_t gpu_acc;
+static uint32_t gpu_remain;
+static uint32_t gpu_hidata;
+static uint32_t gpu_flags;
+static uint32_t gpu_matrix_control;
+static uint32_t gpu_pointer_to_matrix;
+static uint32_t gpu_data_organization;
+static uint32_t gpu_control;
+static uint32_t gpu_div_control;
// There is a distinct advantage to having these separated out--there's no need to clear
// 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!
// There is a distinct advantage to having these separated out--there's no need to clear
// 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];
-static uint32 * gpu_reg;
-static uint32 * gpu_alternate_reg;
+static uint8_t gpu_flag_z, gpu_flag_n, gpu_flag_c;
+uint32_t gpu_reg_bank_0[32];
+uint32_t gpu_reg_bank_1[32];
+static uint32_t * gpu_reg;
+static uint32_t * gpu_alternate_reg;
-static uint32 gpu_instruction;
-static uint32 gpu_opcode_first_parameter;
-static uint32 gpu_opcode_second_parameter;
+static uint32_t gpu_instruction;
+static uint32_t gpu_opcode_first_parameter;
+static uint32_t gpu_opcode_second_parameter;
#define CLR_ZN (gpu_flag_z = gpu_flag_n = 0)
#define CLR_ZNC (gpu_flag_z = gpu_flag_n = gpu_flag_c = 0)
#define SET_Z(r) (gpu_flag_z = ((r) == 0))
#define CLR_ZN (gpu_flag_z = gpu_flag_n = 0)
#define CLR_ZNC (gpu_flag_z = gpu_flag_n = gpu_flag_c = 0)
#define SET_Z(r) (gpu_flag_z = ((r) == 0))
-#define SET_N(r) (gpu_flag_n = (((uint32)(r) >> 31) & 0x01))
-#define SET_C_ADD(a,b) (gpu_flag_c = ((uint32)(b) > (uint32)(~(a))))
-#define SET_C_SUB(a,b) (gpu_flag_c = ((uint32)(b) > (uint32)(a)))
+#define SET_N(r) (gpu_flag_n = (((uint32_t)(r) >> 31) & 0x01))
+#define SET_C_ADD(a,b) (gpu_flag_c = ((uint32_t)(b) > (uint32_t)(~(a))))
+#define SET_C_SUB(a,b) (gpu_flag_c = ((uint32_t)(b) > (uint32_t)(a)))
#define SET_ZN(r) SET_N(r); SET_Z(r)
#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
#define SET_ZN(r) SET_N(r); SET_Z(r)
#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
{ 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
{ 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
"store_r14_ri", "store_r15_ri", "sat24", "pack",
};
"store_r14_ri", "store_r15_ri", "sat24", "pack",
};
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: ReadByte--Attempt to read from GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: ReadByte--Attempt to read from GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: ReadWord--Attempt to read from GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: ReadWord--Attempt to read from GPU register file by %s!\n", whoName[who]);
if (offset & 0x01) // Catch cases 1 & 3... (unaligned read)
return (GPUReadByte(offset, who) << 8) | GPUReadByte(offset+1, who);
if (offset & 0x01) // Catch cases 1 & 3... (unaligned read)
return (GPUReadByte(offset, who) << 8) | GPUReadByte(offset+1, who);
- 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_t 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))
{
offset &= 0xFFF;
// if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE + 0x1000))
if ((offset >= GPU_WORK_RAM_BASE) && (offset <= GPU_WORK_RAM_BASE + 0x0FFC))
{
offset &= 0xFFF;
- return ((uint32)gpu_ram_8[offset] << 24) | ((uint32)gpu_ram_8[offset+1] << 16)
- | ((uint32)gpu_ram_8[offset+2] << 8) | (uint32)gpu_ram_8[offset+3];//*/
+ return ((uint32_t)gpu_ram_8[offset] << 24) | ((uint32_t)gpu_ram_8[offset+1] << 16)
+ | ((uint32_t)gpu_ram_8[offset+2] << 8) | (uint32_t)gpu_ram_8[offset+3];//*/
// return GET32(gpu_ram_8, offset);
}
// else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
// return GET32(gpu_ram_8, offset);
}
// else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteByte--Attempt to write to GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteByte--Attempt to write to GPU register file by %s!\n", whoName[who]);
bytenum = 3 - bytenum; // convention motorola !!!
old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
GPUWriteLong(offset & 0xFFFFFFC, old_data, who);
bytenum = 3 - bytenum; // convention motorola !!!
old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
GPUWriteLong(offset & 0xFFFFFFC, old_data, who);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteWord--Attempt to write to GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteWord--Attempt to write to GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteLong--Attempt to write to GPU register file by %s!\n", whoName[who]);
{
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("GPU: WriteLong--Attempt to write to GPU register file by %s!\n", whoName[who]);
gpu_flag_z = gpu_flags & ZERO_FLAG;
gpu_flag_c = (gpu_flags & CARRY_FLAG) >> 1;
gpu_flag_n = (gpu_flags & NEGA_FLAG) >> 2;
gpu_flag_z = gpu_flags & ZERO_FLAG;
gpu_flag_c = (gpu_flags & CARRY_FLAG) >> 1;
gpu_flag_n = (gpu_flags & NEGA_FLAG) >> 2;
gpu_control = (gpu_control & 0xF7C0) | (data & (~0xF7C0));
// if gpu wasn't running but is now running, execute a few cycles
gpu_control = (gpu_control & 0xF7C0) | (data & (~0xF7C0));
// if gpu wasn't running but is now running, execute a few cycles
WriteLog("\nDump of $6528: %u items.\n\n", numItems);
for(int i=0; i<numItems*3*4; i+=3*4)
{
WriteLog("\t%04X: %08X %08X %08X -> ", 0x6528+i, JaguarReadLong(0x6528+i),
JaguarReadLong(0x6528+i+4), JaguarReadLong(0x6528+i+8));
WriteLog("\nDump of $6528: %u items.\n\n", numItems);
for(int i=0; i<numItems*3*4; i+=3*4)
{
WriteLog("\t%04X: %08X %08X %08X -> ", 0x6528+i, JaguarReadLong(0x6528+i),
JaguarReadLong(0x6528+i+4), JaguarReadLong(0x6528+i+8));
//This isn't working the way it should! !!! FIX !!!
//Err, actually, it is.
// NOW, it works right! Problem solved!!! It's a blitter bug!
//This isn't working the way it should! !!! FIX !!!
//Err, actually, it is.
// NOW, it works right! Problem solved!!! It's a blitter bug!
-// memory_malloc_secure((void **)&gpu_reg_bank_0, 32 * sizeof(int32), "GPU bank 0 regs");
-// memory_malloc_secure((void **)&gpu_reg_bank_1, 32 * sizeof(int32), "GPU bank 1 regs");
+// memory_malloc_secure((void **)&gpu_reg_bank_0, 32 * sizeof(int32_t), "GPU bank 0 regs");
+// memory_malloc_secure((void **)&gpu_reg_bank_1, 32 * sizeof(int32_t), "GPU bank 1 regs");
j += dasmjag(JAGUAR_GPU, buffer, j);
WriteLog("\t%08X: %s\n", oldj, buffer);
}
j += dasmjag(JAGUAR_GPU, buffer, j);
WriteLog("\t%08X: %s\n", oldj, buffer);
}
WriteLog("GPU: Stopped at PC=%08X (GPU %s running)\n", (unsigned int)gpu_pc, GPU_RUNNING ? "was" : "wasn't");
// Get the interrupt latch & enable bits
WriteLog("GPU: Stopped at PC=%08X (GPU %s running)\n", (unsigned int)gpu_pc, GPU_RUNNING ? "was" : "wasn't");
// Get the interrupt latch & enable bits
WriteLog("GPU: Latch bits = %02X, enable bits = %02X\n", bits, mask);
GPUDumpRegisters();
WriteLog("GPU: Latch bits = %02X, enable bits = %02X\n", bits, mask);
GPUDumpRegisters();
/* gpu_flag_c = (gpu_flag_c ? 1 : 0);
gpu_flag_z = (gpu_flag_z ? 1 : 0);
gpu_flag_n = (gpu_flag_n ? 1 : 0);*/
/* gpu_flag_c = (gpu_flag_c ? 1 : 0);
gpu_flag_z = (gpu_flag_z ? 1 : 0);
gpu_flag_n = (gpu_flag_n ? 1 : 0);*/
- uint16 opcode = GPUReadWord(gpu_pc, GPU);
- uint32 index = opcode >> 10;
+ uint16_t opcode = GPUReadWord(gpu_pc, GPU);
+ uint32_t index = opcode >> 10;
gpu_instruction = opcode; // Added for GPU #3...
gpu_opcode_first_parameter = (opcode >> 5) & 0x1F;
gpu_opcode_second_parameter = opcode & 0x1F;
gpu_instruction = opcode; // Added for GPU #3...
gpu_opcode_first_parameter = (opcode >> 5) & 0x1F;
gpu_opcode_second_parameter = opcode & 0x1F;
gpu_flag_z = (gpu_flag_z ? 1 : 0);
gpu_flag_n = (gpu_flag_n ? 1 : 0);*/
// KLUDGE: Used by BRANCH_CONDITION
gpu_flag_z = (gpu_flag_z ? 1 : 0);
gpu_flag_n = (gpu_flag_n ? 1 : 0);*/
// KLUDGE: Used by BRANCH_CONDITION
gpu_flag_c = (gpu_flag_c ? 1 : 0);
gpu_flag_z = (gpu_flag_z ? 1 : 0);*/
// KLUDGE: Used by BRANCH_CONDITION
gpu_flag_c = (gpu_flag_c ? 1 : 0);
gpu_flag_z = (gpu_flag_z ? 1 : 0);*/
// KLUDGE: Used by BRANCH_CONDITION
static void gpu_opcode_add(void)
{
#ifdef GPU_DIS_ADD
if (doGPUDis)
WriteLog("%06X: ADD R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_add(void)
{
#ifdef GPU_DIS_ADD
if (doGPUDis)
WriteLog("%06X: ADD R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
WriteLog("%06X: ADDC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
/* int dreg = jaguar.op & 31;
WriteLog("%06X: ADDC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
/* int dreg = jaguar.op & 31;
- uint32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
- uint32 r2 = jaguar.r[dreg];
- uint32 res = r2 + r1 + ((jaguar.FLAGS >> 1) & 1);
+ uint32_t r1 = jaguar.r[(jaguar.op >> 5) & 31];
+ uint32_t r2 = jaguar.r[dreg];
+ uint32_t res = r2 + r1 + ((jaguar.FLAGS >> 1) & 1);
// SET_ZNC_ADD(RN, RM, res); //???BUG??? Yes!
SET_ZNC_ADD(RN + carry, RM, res);
// SET_ZNC_ADD(RN, RM + carry, res);
// SET_ZNC_ADD(RN, RM, res); //???BUG??? Yes!
SET_ZNC_ADD(RN + carry, RM, res);
// SET_ZNC_ADD(RN, RM + carry, res);
static void gpu_opcode_addq(void)
{
#ifdef GPU_DIS_ADDQ
if (doGPUDis)
WriteLog("%06X: ADDQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_addq(void)
{
#ifdef GPU_DIS_ADDQ
if (doGPUDis)
WriteLog("%06X: ADDQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_sub(void)
{
#ifdef GPU_DIS_SUB
if (doGPUDis)
WriteLog("%06X: SUB R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_sub(void)
{
#ifdef GPU_DIS_SUB
if (doGPUDis)
WriteLog("%06X: SUB R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_subc(void)
{
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_subc(void)
{
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
- uint32 res = RN - RM - gpu_flag_c;
- uint32 borrow = gpu_flag_c;
-// SET_ZNC_SUB(RN, RM, res); //???BUG??? YES!!!
-//No matter how you do it, there is a problem. With below, it's 0-0 with carry,
-//and the one below it it's FFFFFFFF - FFFFFFFF with carry... !!! FIX !!!
-// SET_ZNC_SUB(RN - borrow, RM, res);
- SET_ZNC_SUB(RN, RM + borrow, res);
- RN = res;
+ // This is how the GPU ALU does it--Two's complement with inverted carry
+ uint64_t res = (uint64_t)RN + (uint64_t)(RM ^ 0xFFFFFFFF) + (gpu_flag_c ^ 1);
+ // Carry out of the result is inverted too
+ gpu_flag_c = ((res >> 32) & 0x01) ^ 1;
+ RN = (res & 0xFFFFFFFF);
+ SET_ZN(RN);
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
}
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
}
-/*
-N = 5, M = 3, 3 - 5 = -2, C = 1... Or, in our case:
-N = 0, M = 1, 0 - 1 = -1, C = 0!
-#define SET_C_SUB(a,b) (gpu_flag_c = ((uint32)(b) > (uint32)(a)))
-#define SET_ZN(r) SET_N(r); SET_Z(r)
-#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
-#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
-*/
static void gpu_opcode_subq(void)
{
#ifdef GPU_DIS_SUBQ
if (doGPUDis)
WriteLog("%06X: SUBQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_subq(void)
{
#ifdef GPU_DIS_SUBQ
if (doGPUDis)
WriteLog("%06X: SUBQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_cmp(void)
{
#ifdef GPU_DIS_CMP
if (doGPUDis)
WriteLog("%06X: CMP R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_cmp(void)
{
#ifdef GPU_DIS_CMP
if (doGPUDis)
WriteLog("%06X: CMP R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1 };
#ifdef GPU_DIS_CMPQ
if (doGPUDis)
WriteLog("%06X: CMPQ #%d, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, sqtable[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1 };
#ifdef GPU_DIS_CMPQ
if (doGPUDis)
WriteLog("%06X: CMPQ #%d, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, sqtable[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_sat8(void)
{
#ifdef GPU_DIS_SAT8
if (doGPUDis)
WriteLog("%06X: SAT8 R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_sat8(void)
{
#ifdef GPU_DIS_SAT8
if (doGPUDis)
WriteLog("%06X: SAT8 R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
WriteLog("%06X: STORE R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2));
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: STORE R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2));
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
WriteLog("%06X: STORE R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2));
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: STORE R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2));
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[14], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[14], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if (address >= 0xF03000 && address <= 0xF03FFF)
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[15], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[15], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if (address >= 0xF03000 && address <= 0xF03FFF)
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
WriteLog("%06X: STORE R%02u, (R14+R%02u) [NCZ:%u%u%u, R%02u=%08X, R14+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[14]);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: STORE R%02u, (R14+R%02u) [NCZ:%u%u%u, R%02u=%08X, R14+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[14]);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
WriteLog("%06X: STORE R%02u, (R15+R%02u) [NCZ:%u%u%u, R%02u=%08X, R15+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[15]);
#endif
#ifdef GPU_CORRECT_ALIGNMENT_STORE
WriteLog("%06X: STORE R%02u, (R15+R%02u) [NCZ:%u%u%u, R%02u=%08X, R15+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[15]);
#endif
#ifdef GPU_CORRECT_ALIGNMENT_STORE
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
if (address >= 0xF03000 && address <= 0xF03FFF)
GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
static void gpu_opcode_pack(void)
{
#ifdef GPU_DIS_PACK
if (doGPUDis)
WriteLog("%06X: %s R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, (!IMM_1 ? "PACK " : "UNPACK"), IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_pack(void)
{
#ifdef GPU_DIS_PACK
if (doGPUDis)
WriteLog("%06X: %s R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, (!IMM_1 ? "PACK " : "UNPACK"), IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
// According to the docs, & "Do The Same", this address is long aligned...
// So let's try it:
// And it works!!! Need to fix all instances...
// Also, Power Drive Rally seems to contradict the idea that only LOADs in
// the $F03000-$F03FFF range are aligned...
#warning "!!! Alignment issues, need to find definitive final word on this !!!"
// According to the docs, & "Do The Same", this address is long aligned...
// So let's try it:
// And it works!!! Need to fix all instances...
// Also, Power Drive Rally seems to contradict the idea that only LOADs in
// the $F03000-$F03FFF range are aligned...
#warning "!!! Alignment issues, need to find definitive final word on this !!!"
+/*
+Preliminary testing on real hardware seems to confirm that something strange goes on
+with unaligned reads in main memory. When the address is off by 1, the result is the
+same as the long address with the top byte replaced by something. So if the read is
+from $401, and $400 has 12 34 56 78, the value read will be $nn345678, where nn is a currently unknown vlaue.
+When the address is off by 2, the result would be $nnnn5678, where nnnn is unknown.
+When the address is off by 3, the result would be $nnnnnn78, where nnnnnn is unknown.
+It may be that the "unknown" values come from the prefetch queue, but not sure how
+to test that. They seem to be stable, though, which would indicate such a mechanism.
+Sometimes, however, the off by 2 case returns $12345678!
+*/
WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
// if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(RM & 0xFFFFFFFC, GPU);
// if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(RM & 0xFFFFFFFC, GPU);
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
- WriteLog("%06X: MOVEI #$%08X, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, (uint32)GPUReadWord(gpu_pc) | ((uint32)GPUReadWord(gpu_pc + 2) << 16), IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
+ WriteLog("%06X: MOVEI #$%08X, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, (uint32_t)GPUReadWord(gpu_pc) | ((uint32_t)GPUReadWord(gpu_pc + 2) << 16), IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
static void gpu_opcode_imult(void)
{
#ifdef GPU_DIS_IMULT
if (doGPUDis)
WriteLog("%06X: IMULT R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_imult(void)
{
#ifdef GPU_DIS_IMULT
if (doGPUDis)
WriteLog("%06X: IMULT R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_mult(void)
{
#ifdef GPU_DIS_MULT
if (doGPUDis)
WriteLog("%06X: MULT R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_mult(void)
{
#ifdef GPU_DIS_MULT
if (doGPUDis)
WriteLog("%06X: MULT R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_bclr(void)
{
#ifdef GPU_DIS_BCLR
if (doGPUDis)
WriteLog("%06X: BCLR #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_bclr(void)
{
#ifdef GPU_DIS_BCLR
if (doGPUDis)
WriteLog("%06X: BCLR #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_bset(void)
{
#ifdef GPU_DIS_BSET
if (doGPUDis)
WriteLog("%06X: BSET #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_bset(void)
{
#ifdef GPU_DIS_BSET
if (doGPUDis)
WriteLog("%06X: BSET #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_div(void) // RN / RM
{
#ifdef GPU_DIS_DIV
if (doGPUDis)
WriteLog("%06X: DIV R%02u, R%02u (%s) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, (gpu_div_control & 0x01 ? "16.16" : "32"), gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_div(void) // RN / RM
{
#ifdef GPU_DIS_DIV
if (doGPUDis)
WriteLog("%06X: DIV R%02u, R%02u (%s) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, (gpu_div_control & 0x01 ? "16.16" : "32"), gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
-// NOTE: remainder is NOT calculated correctly here!
-// The original tried to get it right by checking to see if the
-// remainder was negative, but that's too late...
-// The code there should do it now, but I'm not 100% sure...
-
-/* uint32 _RM=RM;
- uint32 _RN=RN;
+ // If 16.16 division, stuff top 16 bits of RN into remainder and put the
+ // bottom 16 of RN in top 16 of quotient
+ if (gpu_div_control & 0x01)
+ q <<= 16, r = RN >> 16;
- if (gpu_div_control & 1)
- {
- gpu_remain = (((uint64)_RN) << 16) % _RM;
- if (gpu_remain&0x80000000)
- gpu_remain-=_RM;
- RN = (((uint64)_RN) << 16) / _RM;
- }
- else
- {
- gpu_remain = _RN % _RM;
- if (gpu_remain&0x80000000)
- gpu_remain-=_RM;
- RN/=_RM;
- }
+// uint32_t sign = (r >> 31) & 0x01;
+ uint32_t sign = r & 0x80000000;
+ r = (r << 1) | ((q >> 31) & 0x01);
+ r += (sign ? RM : -RM);
+ q = (q << 1) | (((~r) >> 31) & 0x01);
#ifdef GPU_DIS_DIV
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] Remainder: %08X\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN, gpu_remain);
#endif
}
#ifdef GPU_DIS_DIV
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] Remainder: %08X\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN, gpu_remain);
#endif
}
static void gpu_opcode_neg(void)
{
#ifdef GPU_DIS_NEG
if (doGPUDis)
WriteLog("%06X: NEG R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_neg(void)
{
#ifdef GPU_DIS_NEG
if (doGPUDis)
WriteLog("%06X: NEG R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_shrq(void)
{
#ifdef GPU_DIS_SHRQ
if (doGPUDis)
WriteLog("%06X: SHRQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_shrq(void)
{
#ifdef GPU_DIS_SHRQ
if (doGPUDis)
WriteLog("%06X: SHRQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_ror(void)
{
#ifdef GPU_DIS_ROR
if (doGPUDis)
WriteLog("%06X: ROR R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_ror(void)
{
#ifdef GPU_DIS_ROR
if (doGPUDis)
WriteLog("%06X: ROR R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_rorq(void)
{
#ifdef GPU_DIS_RORQ
if (doGPUDis)
WriteLog("%06X: RORQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_rorq(void)
{
#ifdef GPU_DIS_RORQ
if (doGPUDis)
WriteLog("%06X: RORQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
if (doGPUDis)
WriteLog("%06X: SHA R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
if (doGPUDis)
WriteLog("%06X: SHA R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
static void gpu_opcode_sharq(void)
{
#ifdef GPU_DIS_SHARQ
if (doGPUDis)
WriteLog("%06X: SHARQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
static void gpu_opcode_sharq(void)
{
#ifdef GPU_DIS_SHARQ
if (doGPUDis)
WriteLog("%06X: SHARQ #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1], IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif