From: Shamus Hammons Date: Sat, 26 Nov 2011 09:40:05 +0000 (+0000) Subject: RISC LOAD/STORE alignment fixes. X-Git-Tag: 2.0.2~8 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f349c8a960bfff50b44eb98e7f6e0224b543208;p=virtualjaguar RISC LOAD/STORE alignment fixes. --- diff --git a/src/dsp.cpp b/src/dsp.cpp index c0fd603..1034f3c 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -11,6 +11,7 @@ // Who When What // --- ---------- ------------------------------------------------------------- // JLH 01/16/2010 Created this log ;-) +// JLH 11/26/2011 Added fixes for LOAD/STORE alignment issues // #include "dsp.h" @@ -25,6 +26,10 @@ #include "m68k.h" //#include "memory.h" + +// Seems alignment in loads & stores was off... +#define DSP_CORRECT_ALIGNMENT + //#define DSP_DEBUG //#define DSP_DEBUG_IRQ //#define DSP_DEBUG_PL2 @@ -34,6 +39,7 @@ // Disassembly definitions +#if 0 #define DSP_DIS_ABS #define DSP_DIS_ADD #define DSP_DIS_ADDC @@ -89,7 +95,7 @@ //*/ bool doDSPDis = false; //bool doDSPDis = true; - +#endif /* No dis yet: @@ -1949,7 +1955,11 @@ static void dsp_opcode_store_r14_indexed(void) if (doDSPDis) WriteLog("%06X: STORE R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", dsp_pc-2, IMM_2, dsp_convert_zero[IMM_1] << 2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, dsp_convert_zero[IMM_1] << 2, dsp_reg[14]+(dsp_convert_zero[IMM_1] << 2)); #endif +#ifdef DSP_CORRECT_ALIGNMENT + DSPWriteLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), RN, DSP); +#else DSPWriteLong(dsp_reg[14] + (dsp_convert_zero[IMM_1] << 2), RN, DSP); +#endif } static void dsp_opcode_store_r15_indexed(void) @@ -1958,7 +1968,11 @@ static void dsp_opcode_store_r15_indexed(void) if (doDSPDis) WriteLog("%06X: STORE R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", dsp_pc-2, IMM_2, dsp_convert_zero[IMM_1] << 2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, dsp_convert_zero[IMM_1] << 2, dsp_reg[15]+(dsp_convert_zero[IMM_1] << 2)); #endif +#ifdef DSP_CORRECT_ALIGNMENT + DSPWriteLong((dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), RN, DSP); +#else DSPWriteLong(dsp_reg[15] + (dsp_convert_zero[IMM_1] << 2), RN, DSP); +#endif } static void dsp_opcode_load_r14_ri(void) @@ -1967,7 +1981,11 @@ static void dsp_opcode_load_r14_ri(void) if (doDSPDis) WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM+dsp_reg[14], IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + RN = DSPReadLong((dsp_reg[14] + RM) & 0xFFFFFFFC, DSP); +#else RN = DSPReadLong(dsp_reg[14] + RM, DSP); +#endif #ifdef DSP_DIS_LOAD14R if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -1980,7 +1998,11 @@ static void dsp_opcode_load_r15_ri(void) if (doDSPDis) WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM+dsp_reg[15], IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + RN = DSPReadLong((dsp_reg[15] + RM) & 0xFFFFFFFC, DSP); +#else RN = DSPReadLong(dsp_reg[15] + RM, DSP); +#endif #ifdef DSP_DIS_LOAD15R if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -2023,10 +2045,17 @@ static void dsp_opcode_storew(void) if (doDSPDis) WriteLog("%06X: STOREW R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_pc-2, IMM_2, IMM_1, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, IMM_1, RM); #endif +#ifdef DSP_CORRECT_ALIGNMENT + if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF)) + DSPWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, DSP); + else + JaguarWriteWord(RM & 0xFFFFFFFE, RN, DSP); +#else if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF)) DSPWriteLong(RM, RN & 0xFFFF, DSP); else JaguarWriteWord(RM, RN, DSP); +#endif } static void dsp_opcode_store(void) @@ -2035,7 +2064,11 @@ static void dsp_opcode_store(void) if (doDSPDis) WriteLog("%06X: STORE R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_pc-2, IMM_2, IMM_1, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, IMM_1, RM); #endif +#ifdef DSP_CORRECT_ALIGNMENT + DSPWriteLong(RM & 0xFFFFFFFC, RN, DSP); +#else DSPWriteLong(RM, RN, DSP); +#endif } static void dsp_opcode_loadb(void) @@ -2060,10 +2093,17 @@ static void dsp_opcode_loadw(void) if (doDSPDis) WriteLog("%06X: LOADW (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF)) + RN = DSPReadLong(RM & 0xFFFFFFFE, DSP) & 0xFFFF; + else + RN = JaguarReadWord(RM & 0xFFFFFFFE, DSP); +#else if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF)) RN = DSPReadLong(RM, DSP) & 0xFFFF; else RN = JaguarReadWord(RM, DSP); +#endif #ifdef DSP_DIS_LOADW if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -2076,7 +2116,11 @@ static void dsp_opcode_load(void) if (doDSPDis) WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + RN = DSPReadLong(RM & 0xFFFFFFFC, DSP); +#else RN = DSPReadLong(RM, DSP); +#endif #ifdef DSP_DIS_LOAD if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -2089,7 +2133,11 @@ static void dsp_opcode_load_r14_indexed(void) if (doDSPDis) WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", dsp_pc-2, dsp_convert_zero[IMM_1] << 2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[IMM_1] << 2, dsp_reg[14]+(dsp_convert_zero[IMM_1] << 2), IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + RN = DSPReadLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), DSP); +#else RN = DSPReadLong(dsp_reg[14] + (dsp_convert_zero[IMM_1] << 2), DSP); +#endif #ifdef DSP_DIS_LOAD14I if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -2102,7 +2150,11 @@ static void dsp_opcode_load_r15_indexed(void) if (doDSPDis) WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", dsp_pc-2, dsp_convert_zero[IMM_1] << 2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[IMM_1] << 2, dsp_reg[15]+(dsp_convert_zero[IMM_1] << 2), IMM_2, RN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + RN = DSPReadLong((dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), DSP); +#else RN = DSPReadLong(dsp_reg[15] + (dsp_convert_zero[IMM_1] << 2), DSP); +#endif #ifdef DSP_DIS_LOAD15I if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN); @@ -3093,6 +3145,7 @@ if (dsp_pc == 0xF1B092) pcQueue1[pcQPtr1++] = dsp_pc; pcQPtr1 &= 0x3FF; +#ifdef DSP_DEBUG_PL2 if ((dsp_pc < 0xF1B000 || dsp_pc > 0xF1CFFF) && !doDSPDis) { WriteLog("DSP: PC has stepped out of bounds...\n\nBacktrace:\n\n"); @@ -3107,6 +3160,8 @@ if ((dsp_pc < 0xF1B000 || dsp_pc > 0xF1CFFF) && !doDSPDis) } WriteLog("\n"); }//*/ +#endif + if (IMASKCleared) // If IMASK was cleared, { #ifdef DSP_DEBUG_IRQ @@ -3210,9 +3265,10 @@ WriteLog("\tW -> %02u, %02u, %02u; r1=%08X, r2= %08X, res=%08X, wb=%u (%s)\n", p // Stage 2: Execute if (pipeline[plPtrExec].opcode != PIPELINE_STALL) { +#ifdef DSP_DEBUG_PL2 if (doDSPDis) WriteLog("\t[inst=%02u][R28=%08X, alt R28=%08X, REGPAGE=%s]\n", pipeline[plPtrExec].opcode, dsp_reg[28], dsp_alternate_reg[28], (dsp_flags & REGPAGE ? "set" : "not set")); -#ifdef DSP_DEBUG_PL2 + if (doDSPDis) { WriteLog("DSPExecP: About to execute opcode %s...\n", dsp_opcode_str[pipeline[plPtrExec].opcode]); @@ -3922,7 +3978,11 @@ static void DSP_load(void) if (doDSPDis) WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM, PIMM2, PRN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + PRES = DSPReadLong(PRM & 0xFFFFFFFC, DSP); +#else PRES = DSPReadLong(PRM, DSP); +#endif #ifdef DSP_DIS_LOAD if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -3951,10 +4011,17 @@ static void DSP_loadw(void) if (doDSPDis) WriteLog("%06X: LOADW (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM, PIMM2, PRN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF)) + PRES = DSPReadLong(PRM & 0xFFFFFFFE, DSP) & 0xFFFF; + else + PRES = JaguarReadWord(PRM & 0xFFFFFFFE, DSP); +#else if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF)) PRES = DSPReadLong(PRM, DSP) & 0xFFFF; else PRES = JaguarReadWord(PRM, DSP); +#endif #ifdef DSP_DIS_LOADW if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -3967,7 +4034,11 @@ static void DSP_load_r14_i(void) if (doDSPDis) WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", DSP_PPC, dsp_convert_zero[PIMM1] << 2, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[PIMM1] << 2, dsp_reg[14]+(dsp_convert_zero[PIMM1] << 2), PIMM2, PRN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + PRES = DSPReadLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2), DSP); +#else PRES = DSPReadLong(dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2), DSP); +#endif #ifdef DSP_DIS_LOAD14I if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -3980,7 +4051,11 @@ static void DSP_load_r14_r(void) if (doDSPDis) WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM+dsp_reg[14], PIMM2, PRES); #endif +#ifdef DSP_CORRECT_ALIGNMENT + PRES = DSPReadLong((dsp_reg[14] + PRM) & 0xFFFFFFFC, DSP); +#else PRES = DSPReadLong(dsp_reg[14] + PRM, DSP); +#endif #ifdef DSP_DIS_LOAD14R if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -3993,7 +4068,11 @@ static void DSP_load_r15_i(void) if (doDSPDis) WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", DSP_PPC, dsp_convert_zero[PIMM1] << 2, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[PIMM1] << 2, dsp_reg[15]+(dsp_convert_zero[PIMM1] << 2), PIMM2, PRN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + PRES = DSPReadLong((dsp_reg[15] &0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2), DSP); +#else PRES = DSPReadLong(dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2), DSP); +#endif #ifdef DSP_DIS_LOAD15I if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -4006,7 +4085,11 @@ static void DSP_load_r15_r(void) if (doDSPDis) WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM+dsp_reg[15], PIMM2, PRN); #endif +#ifdef DSP_CORRECT_ALIGNMENT + PRES = DSPReadLong((dsp_reg[15] + PRM) & 0xFFFFFFFC, DSP); +#else PRES = DSPReadLong(dsp_reg[15] + PRM, DSP); +#endif #ifdef DSP_DIS_LOAD15R if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES); @@ -4444,7 +4527,11 @@ static void DSP_store(void) #endif // DSPWriteLong(PRM, PRN, DSP); // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = PRM & 0xFFFFFFFC; +#else pipeline[plPtrExec].address = PRM; +#endif pipeline[plPtrExec].value = PRN; pipeline[plPtrExec].type = TYPE_DWORD; WRITEBACK_ADDR; @@ -4490,7 +4577,11 @@ static void DSP_storew(void) // JaguarWriteWord(PRM, PRN, DSP); // // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = PRM & 0xFFFFFFFE; +#else pipeline[plPtrExec].address = PRM; +#endif if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF)) { @@ -4513,7 +4604,11 @@ static void DSP_store_r14_i(void) #endif // DSPWriteLong(dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP); // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = (dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2); +#else pipeline[plPtrExec].address = dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2); +#endif pipeline[plPtrExec].value = PRN; pipeline[plPtrExec].type = TYPE_DWORD; WRITEBACK_ADDR; @@ -4523,7 +4618,11 @@ static void DSP_store_r14_r(void) { // DSPWriteLong(dsp_reg[14] + PRM, PRN, DSP); // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = (dsp_reg[14] + PRM) & 0xFFFFFFFC; +#else pipeline[plPtrExec].address = dsp_reg[14] + PRM; +#endif pipeline[plPtrExec].value = PRN; pipeline[plPtrExec].type = TYPE_DWORD; WRITEBACK_ADDR; @@ -4537,7 +4636,11 @@ static void DSP_store_r15_i(void) #endif // DSPWriteLong(dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP); // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = (dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2); +#else pipeline[plPtrExec].address = dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2); +#endif pipeline[plPtrExec].value = PRN; pipeline[plPtrExec].type = TYPE_DWORD; WRITEBACK_ADDR; @@ -4547,7 +4650,11 @@ static void DSP_store_r15_r(void) { // DSPWriteLong(dsp_reg[15] + PRM, PRN, DSP); // NO_WRITEBACK; +#ifdef DSP_CORRECT_ALIGNMENT + pipeline[plPtrExec].address = (dsp_reg[15] + PRM) & 0xFFFFFFFC; +#else pipeline[plPtrExec].address = dsp_reg[15] + PRM; +#endif pipeline[plPtrExec].value = PRN; pipeline[plPtrExec].type = TYPE_DWORD; WRITEBACK_ADDR; diff --git a/src/gpu.cpp b/src/gpu.cpp index 4a141c4..6ed7a38 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -13,6 +13,7 @@ // Who When What // --- ---------- ------------------------------------------------------------- // JLH 01/16/2010 Created this log ;-) +// JLH 11/26/2011 Added fixes for LOAD/STORE alignment issues // // Note: Endian wrongness probably stems from the MAME origins of this emu and @@ -35,10 +36,14 @@ //#include "memory.h" #include "tom.h" + +// Seems alignment in loads & stores was off... +#define GPU_CORRECT_ALIGNMENT //#define GPU_DEBUG // For GPU dissasembly... +#if 0 #define GPU_DIS_ABS #define GPU_DIS_ADD #define GPU_DIS_ADDC @@ -97,6 +102,8 @@ bool doGPUDis = false; //bool doGPUDis = true; //*/ +#endif + /* GPU opcodes use (BIOS flying ATARI logo): + add 357416 @@ -1725,7 +1732,11 @@ static void gpu_opcode_store_r14_indexed(void) if (doGPUDis) 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 + GPUWriteLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU); +#else GPUWriteLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), RN, GPU); +#endif } static void gpu_opcode_store_r15_indexed(void) @@ -1734,7 +1745,11 @@ static void gpu_opcode_store_r15_indexed(void) if (doGPUDis) 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 + GPUWriteLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU); +#else GPUWriteLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), RN, GPU); +#endif } static void gpu_opcode_load_r14_ri(void) @@ -1743,7 +1758,11 @@ static void gpu_opcode_load_r14_ri(void) if (doGPUDis) 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 + RN = GPUReadLong((gpu_reg[14] + RM) & 0xFFFFFFFC, GPU); +#else RN = GPUReadLong(gpu_reg[14] + RM, GPU); +#endif #ifdef GPU_DIS_LOAD14R if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); @@ -1756,7 +1775,11 @@ static void gpu_opcode_load_r15_ri(void) if (doGPUDis) 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 + RN = GPUReadLong((gpu_reg[15] + RM) & 0xFFFFFFFC, GPU); +#else RN = GPUReadLong(gpu_reg[15] + RM, GPU); +#endif #ifdef GPU_DIS_LOAD15R if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); @@ -1769,7 +1792,11 @@ static void gpu_opcode_store_r14_ri(void) if (doGPUDis) 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 + GPUWriteLong((gpu_reg[14] + RM) & 0xFFFFFFFC, RN, GPU); +#else GPUWriteLong(gpu_reg[14] + RM, RN, GPU); +#endif } static void gpu_opcode_store_r15_ri(void) @@ -1778,7 +1805,11 @@ static void gpu_opcode_store_r15_ri(void) if (doGPUDis) 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 + GPUWriteLong((gpu_reg[15] + RM) & 0xFFFFFFFC, RN, GPU); +#else GPUWriteLong(gpu_reg[15] + RM, RN, GPU); +#endif } static void gpu_opcode_nop(void) @@ -1828,10 +1859,17 @@ static void gpu_opcode_storew(void) if (doGPUDis) WriteLog("%06X: STOREW R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, 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); #endif +#ifdef GPU_CORRECT_ALIGNMENT + if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) + GPUWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, GPU); + else + JaguarWriteWord(RM & 0xFFFFFFFE, RN, GPU); +#else if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) GPUWriteLong(RM, RN & 0xFFFF, GPU); else JaguarWriteWord(RM, RN, GPU); +#endif } static void gpu_opcode_store(void) @@ -1840,13 +1878,22 @@ static void gpu_opcode_store(void) if (doGPUDis) WriteLog("%06X: STORE R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, 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); #endif +#ifdef GPU_CORRECT_ALIGNMENT + GPUWriteLong(RM & 0xFFFFFFFC, RN, GPU); +#else GPUWriteLong(RM, RN, GPU); +#endif } static void gpu_opcode_storep(void) { +#ifdef GPU_CORRECT_ALIGNMENT + GPUWriteLong((RM & 0xFFFFFFF8) + 0, gpu_hidata, GPU); + GPUWriteLong((RM & 0xFFFFFFF8) + 4, RN, GPU); +#else GPUWriteLong(RM + 0, gpu_hidata, GPU); GPUWriteLong(RM + 4, RN, GPU); +#endif } static void gpu_opcode_loadb(void) @@ -1871,23 +1918,37 @@ static void gpu_opcode_loadw(void) if (doGPUDis) WriteLog("%06X: LOADW (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 & 0xFFFFFFFE, GPU) & 0xFFFF; + else + RN = JaguarReadWord(RM & 0xFFFFFFFE, GPU); +#else if ((RM >= 0xF03000) && (RM <= 0xF03FFF)) RN = GPUReadLong(RM, GPU) & 0xFFFF; else RN = JaguarReadWord(RM, GPU); +#endif #ifdef GPU_DIS_LOADW if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", 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... static void gpu_opcode_load(void) { #ifdef GPU_DIS_LOAD if (doGPUDis) 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 + RN = GPUReadLong(RM & 0xFFFFFFFC, GPU); +#else RN = GPUReadLong(RM, GPU); +#endif #ifdef GPU_DIS_LOAD if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); @@ -1896,8 +1957,13 @@ static void gpu_opcode_load(void) static void gpu_opcode_loadp(void) { +#ifdef GPU_CORRECT_ALIGNMENT + gpu_hidata = GPUReadLong((RM & 0xFFFFFFF8) + 0, GPU); + RN = GPUReadLong((RM & 0xFFFFFFF8) + 4, GPU); +#else gpu_hidata = GPUReadLong(RM + 0, GPU); RN = GPUReadLong(RM + 4, GPU); +#endif } static void gpu_opcode_load_r14_indexed(void) @@ -1906,7 +1972,11 @@ static void gpu_opcode_load_r14_indexed(void) if (doGPUDis) 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 + RN = GPUReadLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU); +#else RN = GPUReadLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), GPU); +#endif #ifdef GPU_DIS_LOAD14I if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); @@ -1919,7 +1989,11 @@ static void gpu_opcode_load_r15_indexed(void) if (doGPUDis) 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 + RN = GPUReadLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU); +#else RN = GPUReadLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), GPU); +#endif #ifdef GPU_DIS_LOAD15I if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN); diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 0cd8411..df4c139 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -1660,7 +1660,7 @@ void JaguarInit(void) } //New timer based code stuffola... -void ScanlineCallback(void); +void HalflineCallback(void); void RenderCallback(void); void JaguarReset(void) { @@ -1686,9 +1686,8 @@ void JaguarReset(void) // New timer base code stuffola... InitializeEventList(); // SetCallbackTime(ScanlineCallback, 63.5555); - SetCallbackTime(ScanlineCallback, 31.77775); -// SetCallbackTime(RenderCallback, 33303.082); // # Scanlines * scanline time -// SetCallbackTime(RenderCallback, 16651.541); // # Scanlines * scanline time +// SetCallbackTime(ScanlineCallback, 31.77775); + SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0)); } void JaguarDone(void) @@ -1899,7 +1898,7 @@ if (effect_start) //if (start_logging) // WriteLog("About to execute OP (%u)...\n", i); - TOMExecScanline(i, render); + TOMExecHalfline(i, render); } } @@ -1953,49 +1952,27 @@ void JaguarExecuteNew(void) while (!frameDone); } -/* -BIG NOTE: NEED TO FIX THIS TO RUN ON ABSOLUTE TIMINGS BASED ON SCANLINES, - *NOT* ON THE VERTICAL PERIOD!!! - - scanlines are 64 µs in PAL - and 63.5555... µs in NTSC - -Also: 625 lines per frame in PAL, 525 in NTSC - -So... can use -#define RISC_CYCLE_IN_USEC 0.03760684198 -#define M68K_CYCLE_IN_USEC (RISC_CYCLE_IN_USEC * 2) - -#define HORIZ_PERIOD_IN_USEC_NTSC 63.555555555 -#define HORIZ_PERIOD_IN_USEC_PAL 64.0 - -#define USEC_TO_RISC_CYCLES(u) (uint32)(((u) / RISC_CYCLE_IN_USEC) + 0.5) -#define USEC_TO_M68K_CYCLES(u) (uint32)(((u) / M68K_CYCLE_IN_USEC) + 0.5) - -to figure cycles per half-line... - -USEC_TO_RISC_CYCLES(HORIZ_PERIOD_IN_USEC_NTSC) / 2 -USEC_TO_M68K_CYCLES(HORIZ_PERIOD_IN_USEC_NTSC) / 2 -USEC_TO_RISC_CYCLES(HORIZ_PERIOD_IN_USEC_PAL) / 2 -USEC_TO_M68K_CYCLES(HORIZ_PERIOD_IN_USEC_PAL) / 2 - -// Full lines here, divide by two for half-lines... -which gives the following: 1690, 845 (NTSC), 1702, 851 (PAL) -So, for a full frame, that would yield: -887250 (NTSC), 1063750 (PAL) -one second: -26617500 (NTSC), 26593750 (PAL) - -Which is off a little bit for NTSC... -#define M68K_CLOCK_RATE_PAL 13296950 -#define M68K_CLOCK_RATE_NTSC 13295453 -#define RISC_CLOCK_RATE_PAL 26593900 -#define RISC_CLOCK_RATE_NTSC 26590906 - -*/ - #define USE_CORRECT_PAL_TIMINGS -void ScanlineCallback(void) +// A lot of confusion comes from here... +// The thing to keep in mind is that the VC is advanced every HALF line, regardless +// of whether the display is interlaced or not. The only difference with an +// interlaced display is that the high bit of VC will be set when the lower +// field is being rendered. +// +// Normally, TVs will render a full frame in 1/30s (NTSC) or 1/25s (PAL) by +// rendering two fields that are slighty vertically offset from each other. +// Each field is created in 1/60s (NTSC) or 1/50s (PAL), and every other line +// is rendered in this mode so that each field, when overlaid on each other, +// will yield the final picture at the full resolution for the full frame. +// +// We execute a half frame in each timeslice (1/60s NTSC, 1/50s PAL). +// Since the number of lines in a FULL frame is 525 for NTSC, 625 for PAL, +// it will be half this number for a half frame. BUT, since we're counting +// HALF lines, we double this number and we're back at 525 for NTSC, 625 for PAL. +// +// Scanline times are 63.5555... µs in NTSC and 64 µs in PAL +// Half line times are, naturally, half of this. :-P +void HalflineCallback(void) { //OK, this is hardwired to run in NTSC, and for who knows how long. //Need to fix this so that it does a half-line in the correct amount of time @@ -2030,7 +2007,7 @@ void ScanlineCallback(void) m68k_set_irq(2); } - TOMExecScanline(vc, true); + TOMExecHalfline(vc, true); //Change this to VBB??? //Doesn't seem to matter (at least for Flip Out & I-War) @@ -2042,10 +2019,10 @@ void ScanlineCallback(void) }//*/ #ifdef USE_CORRECT_PAL_TIMINGS - SetCallbackTime(ScanlineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0)); + SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0)); #else -// SetCallbackTime(ScanlineCallback, 63.5555); - SetCallbackTime(ScanlineCallback, 31.77775); +// SetCallbackTime(HalflineCallback, 63.5555); + SetCallbackTime(HalflineCallback, 31.77775); #endif } diff --git a/src/op.cpp b/src/op.cpp index 73fc330..e10e4bb 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -133,6 +133,7 @@ void OPReset(void) void OPDone(void) { +#warning "!!! Fix OL dump so that it follows links !!!" const char * opType[8] = { "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" }; const char * ccType[8] = @@ -319,7 +320,7 @@ void DumpFixedObject(uint64 p0, uint64 p1) // Object Processor main routine // #warning "Need to fix this so that when an GPU object IRQ happens, we can pick up OP processing where we left off. !!! FIX !!!" -void OPProcessList(int scanline, bool render) +void OPProcessList(int halfline, bool render) { extern int op_start_log; // char * condition_to_str[8] = @@ -329,7 +330,7 @@ extern int op_start_log; // objectp_stop_reading_list = false; -//WriteLog("OP: Processing line #%u (OLP=%08X)...\n", scanline, op_pointer); +//WriteLog("OP: Processing line #%u (OLP=%08X)...\n", halfline, op_pointer); //op_done(); // *** BEGIN OP PROCESSOR TESTING ONLY *** @@ -342,7 +343,7 @@ int bitmapCounter = 0; uint32 opCyclesToRun = 30000; // This is a pulled-out-of-the-air value (will need to be fixed, obviously!) -// if (op_pointer) WriteLog(" new op list at 0x%.8x scanline %i\n",op_pointer,scanline); +// if (op_pointer) WriteLog(" new op list at 0x%.8x halfline %i\n",op_pointer,halfline); while (op_pointer) { // *** BEGIN OP PROCESSOR TESTING ONLY *** @@ -355,14 +356,14 @@ else // return; uint64 p0 = OPLoadPhrase(op_pointer); -//WriteLog("\t%08X type %i\n", op_pointer, (uint8)p0 & 0x07); op_pointer += 8; +//WriteLog("\t%08X type %i\n", op_pointer, (uint8)p0 & 0x07); #if 1 -if (scanline == TOMGetVDB() && op_start_log) -//if (scanline == 215 && op_start_log) -//if (scanline == 28 && op_start_log) -//if (scanline == 0) +if (halfline == TOMGetVDB() && op_start_log) +//if (halfline == 215 && op_start_log) +//if (halfline == 28 && op_start_log) +//if (halfline == 0) { WriteLog("%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF)); if ((p0 & 0x07) == OBJECT_TYPE_BITMAP) @@ -463,13 +464,13 @@ if (inhibit && op_start_log) bitmapCounter++; if (!inhibit) // For OP testing only! // *** END OP PROCESSOR TESTING ONLY *** - if (scanline >= ypos && height > 0) + if (halfline >= ypos && height > 0) { uint64 p1 = OPLoadPhrase(op_pointer); op_pointer += 8; -//WriteLog("OP: Writing scanline %d with ypos == %d...\n", scanline, ypos); +//WriteLog("OP: Writing halfline %d with ypos == %d...\n", halfline, ypos); //WriteLog("--> Writing %u BPP bitmap...\n", op_bitmap_bit_depth[(p1 >> 12) & 0x07]); -// OPProcessFixedBitmap(scanline, p0, p1, render); +// OPProcessFixedBitmap(halfline, p0, p1, render); OPProcessFixedBitmap(p0, p1, render); // OP write-backs @@ -518,19 +519,19 @@ if (!inhibit) // For OP testing only! // *** BEGIN OP PROCESSOR TESTING ONLY *** if (inhibit && op_start_log) { - WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!! (scanline=%u, ypos=%u, height=%u)\n", scanline, ypos, height); + WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!! (halfline=%u, ypos=%u, height=%u)\n", halfline, ypos, height); DumpScaledObject(p0, OPLoadPhrase(op_pointer), OPLoadPhrase(op_pointer+8)); } bitmapCounter++; if (!inhibit) // For OP testing only! // *** END OP PROCESSOR TESTING ONLY *** - if (scanline >= ypos && height > 0) + if (halfline >= ypos && height > 0) { uint64 p1 = OPLoadPhrase(op_pointer); op_pointer += 8; uint64 p2 = OPLoadPhrase(op_pointer); op_pointer += 8; -//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, scanline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); +//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, halfline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); OPProcessScaledBitmap(p0, p1, p2, render); // OP write-backs @@ -584,7 +585,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp //Here's another problem: // [hsc: 20, vsc: 20, rem: 00] // Since we're not checking for $E0 (but that's what we get from the above), we end -// up repeating this scanline unnecessarily... !!! FIX !!! [DONE, but... still not quite +// up repeating this halfline unnecessarily... !!! FIX !!! [DONE, but... still not quite // right. Either that, or the Accolade team that wrote Bubsy screwed up royal.] //Also note: $E0 = 7.0 which IS a legal vscale value... @@ -650,7 +651,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp //Do something like: //OPSuspendedByGPU = true; //Dunno if the OP keeps processing from where it was interrupted, or if it just continues -//on the next scanline... +//on the next halfline... // --> It continues from where it was interrupted! !!! FIX !!! break; } @@ -661,7 +662,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp uint32 link = (p0 >> 21) & 0x3FFFF8; // if ((ypos!=507)&&(ypos!=25)) -// WriteLog("\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],ypos>>1,link); +// WriteLog("\t%i%s%i link=0x%.8x\n",halfline,condition_to_str[cc],ypos>>1,link); switch (cc) { case CONDITION_EQUAL: @@ -692,6 +693,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp exit(0); break; default: + // Basically, if you do this, the OP does nothing. :-) WriteLog("OP: Unimplemented branch condition %i\n", cc); } break; @@ -729,6 +731,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp // and bail out/reenter to properly simulate an overloaded OP... !!! FIX !!! #warning "Better would be to count how many actual cycles it used and bail out/reenter to properly simulate an overloaded OP... !!! FIX !!!" opCyclesToRun--; + if (!opCyclesToRun) return; } diff --git a/src/tom.cpp b/src/tom.cpp index 82062bd..d02df55 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -766,13 +766,14 @@ void tom_render_16bpp_rgb_scanline(uint32 * backbuffer) // // Process a single scanline +// (this is bad terminology; each tick of the VC is actually a half-line) // -void TOMExecScanline(uint16 scanline, bool render) +void TOMExecHalfline(uint16 halfline, bool render) { bool inActiveDisplayArea = true; //Interlacing is still not handled correctly here... !!! FIX !!! - if (scanline & 0x01) // Execute OP only on even lines (non-interlaced only!) + if (halfline & 0x01) // Execute OP only on even lines (non-interlaced only!) return; //Hm, it seems that the OP needs to execute from zero, so let's try it: @@ -788,10 +789,10 @@ Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frame */ #if 1 // 16 isn't enough, and neither is 32 for raptgun. 32 fucks up Rayman -// if (scanline >= ((uint16)GET16(tomRam8, VDB) / 2) && scanline < ((uint16)GET16(tomRam8, VDE) / 2)) - if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE)) -// if (scanline >= ((uint16)GET16(tomRam8, VDB) - 16) && scanline < (uint16)GET16(tomRam8, VDE)) -// if (scanline >= 20 && scanline < (uint16)GET16(tomRam8, VDE)) +// if (halfline >= ((uint16)GET16(tomRam8, VDB) / 2) && halfline < ((uint16)GET16(tomRam8, VDE) / 2)) + if (halfline >= (uint16)GET16(tomRam8, VDB) && halfline < (uint16)GET16(tomRam8, VDE)) +// if (halfline >= ((uint16)GET16(tomRam8, VDB) - 16) && halfline < (uint16)GET16(tomRam8, VDE)) +// if (halfline >= 20 && halfline < (uint16)GET16(tomRam8, VDE)) { if (render) { @@ -803,17 +804,17 @@ Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frame for(uint32 i=0; i<720; i++) *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO; - OPProcessList(scanline, render); + OPProcessList(halfline, render); } } else inActiveDisplayArea = false; #else inActiveDisplayArea = - (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE) + (halfline >= (uint16)GET16(tomRam8, VDB) && halfline < (uint16)GET16(tomRam8, VDE) ? true : false); - if (scanline < (uint16)GET16(tomRam8, VDE)) + if (halfline < (uint16)GET16(tomRam8, VDE)) { if (render)//With JaguarExecuteNew() this is always true... { @@ -825,9 +826,9 @@ Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frame for(uint32 i=0; i<720; i++) *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO; -// OPProcessList(scanline, render); +// OPProcessList(halfline, render); //This seems to take care of it... - OPProcessList(scanline, inActiveDisplayArea); + OPProcessList(halfline, inActiveDisplayArea); } } #endif @@ -836,11 +837,11 @@ Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frame uint16 topVisible = (vjs.hardwareTypeNTSC ? TOP_VISIBLE_VC : TOP_VISIBLE_VC_PAL), bottomVisible = (vjs.hardwareTypeNTSC ? BOTTOM_VISIBLE_VC : BOTTOM_VISIBLE_VC_PAL); - uint32 * TOMCurrentLine = &(screenBuffer[((scanline - topVisible) / 2) * screenPitch]); + uint32 * TOMCurrentLine = &(screenBuffer[((halfline - topVisible) / 2) * screenPitch]); // Here's our virtualized scanline code... - if (scanline >= topVisible && scanline < bottomVisible) + if (halfline >= topVisible && halfline < bottomVisible) { if (inActiveDisplayArea) { diff --git a/src/tom.h b/src/tom.h index 59369d7..0fb1f2e 100644 --- a/src/tom.h +++ b/src/tom.h @@ -5,8 +5,6 @@ #ifndef __TOM_H__ #define __TOM_H__ -//#include "jaguar.h" -//#include "types.h" #include "memory.h" #define VIDEO_MODE_16BPP_CRY 0 @@ -27,15 +25,13 @@ uint16 TOMReadWord(uint32 offset, uint32 who = UNKNOWN); void TOMWriteByte(uint32 offset, uint8 data, uint32 who = UNKNOWN); void TOMWriteWord(uint32 offset, uint16 data, uint32 who = UNKNOWN); -void TOMExecScanline(uint16 scanline, bool render); +void TOMExecHalfline(uint16 halfline, bool render); uint32 TOMGetVideoModeWidth(void); uint32 TOMGetVideoModeHeight(void); uint8 TOMGetVideoMode(void); uint8 * TOMGetRamPointer(void); uint16 TOMGetHDB(void); uint16 TOMGetVDB(void); -//uint16 tom_get_scanline(void); -//uint32 tom_getHBlankWidthInPixels(void); int TOMIRQEnabled(int irq); uint16 TOMIRQControlReg(void);