]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/gpu.cpp
added missing #include (D'oh!)
[virtualjaguar] / src / gpu.cpp
index 464350cf9fbb7453e6da89be7a1563658ffeaad0..681cbcf1fa558c1fa53fdb70f0ce6ab06bf12c7a 100644 (file)
@@ -1,7 +1,7 @@
 //
 // GPU Core
 //
-// by Cal2
+// Originally by David Raingeard (Cal2)
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
 // Cleanups, endian wrongness, and bad ASM amelioration by James L. Hammons
 // Note: Endian wrongness probably stems from the MAME origins of this emu and
@@ -223,7 +223,8 @@ static void gpu_opcode_store_r15_ri(void);
 static void gpu_opcode_sat24(void);
 static void gpu_opcode_pack(void);
 
-uint8 gpu_opcode_cycles[64] = 
+// This is wrong, since it doesn't take pipeline effects into account. !!! FIX !!!
+/*uint8 gpu_opcode_cycles[64] = 
 {
        3,  3,  3,  3,  3,  3,  3,  3,
        3,  3,  3,  3,  3,  3,  3,  3,
@@ -233,6 +234,21 @@ uint8 gpu_opcode_cycles[64] =
        5,  4,  5,  6,  6,  1,  1,  1,
        1,  2,  2,  2,  1,  1,  9,  3,
        3,  1,  6,  6,  2,  2,  3,  3
+};//*/
+//Here's a QnD kludge...
+//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!)...
+uint8 gpu_opcode_cycles[64] = 
+{
+       1,  1,  1,  1,  1,  1,  1,  1,
+       1,  1,  1,  1,  1,  1,  1,  1,
+       1,  1,  1,  1,  1,  9,  1,  1,
+       1,  1,  1,  1,  1,  1,  1,  1,
+       1,  1,  1,  1,  1,  1,  1,  2,
+       2,  2,  2,  3,  3,  1,  1,  1,
+       1,  1,  1,  1,  1,  1,  4,  1,
+       1,  1,  3,  3,  1,  1,  1,  1
 };
 
 void (*gpu_opcode[64])()= 
@@ -435,9 +451,9 @@ uint16 GPUReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
                        return data >> 16;
        }
 
-//TEMP--Mirror of F03000?
-if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
-WriteLog("[GPUR16] --> Possible GPU RAM mirror access by %s!", whoName[who]);
+//TEMP--Mirror of F03000? No. Writes only...
+//if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
+//WriteLog("[GPUR16] --> Possible GPU RAM mirror access by %s!", whoName[who]);
 
        return JaguarReadWord(offset, who);
 }
@@ -493,9 +509,9 @@ uint32 GPUReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
                        return 0;
                }
        }
-//TEMP--Mirror of F03000?
-if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
-       WriteLog("[GPUR32] --> Possible GPU RAM mirror access by %s!\n", whoName[who]);
+//TEMP--Mirror of F03000? No. Writes only...
+//if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
+//     WriteLog("[GPUR32] --> Possible GPU RAM mirror access by %s!\n", whoName[who]);
 /*if (offset >= 0xF1D000 && offset <= 0xF1DFFF)
        WriteLog("[GPUR32] --> Reading from Wavetable ROM!\n");//*/
 
@@ -558,6 +574,10 @@ void GPUWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 /*             offset &= 0xFFF;
                SET16(gpu_ram_8, offset, data);//*/
 
+/*if (offset >= 0xF03214 && offset < 0xF0321F)
+       WriteLog("GPU: Writing WORD (%04X) to GPU RAM (%08X)...\n", data, offset);//*/
+
+
 //This is the same stupid worthless code that was in the DSP!!! AARRRGGGGHHHHH!!!!!!
 /*             if (!gpu_in_exec)
                {
@@ -630,12 +650,8 @@ void GPUWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/)
                }
 #endif // GPU_DEBUG
 
-/*             gpu_ram_8[offset & 0xFFF] = (data >> 24) & 0xFF,
-               gpu_ram_8[(offset+1) & 0xFFF] = (data >> 16) & 0xFF,
-               gpu_ram_8[(offset+2) & 0xFFF] = (data >> 8) & 0xFF,
-               gpu_ram_8[(offset+3) & 0xFFF] = data & 0xFF;//*/
                offset &= 0xFFF;
-               SET32(gpu_ram_8, offset, data);//*/
+               SET32(gpu_ram_8, offset, data);
                return;
        }
 //     else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
@@ -853,6 +869,7 @@ if (GPU_RUNNING && effect_start5 && gpu_pc == 0xF035D8)
 
 //     JaguarWriteWord(offset, (data >> 16) & 0xFFFF, who);
 //     JaguarWriteWord(offset+2, data & 0xFFFF, who);
+// We're a 32-bit processor, we can do a long write...!
        JaguarWriteLong(offset, data, who);
 }
 
@@ -940,8 +957,6 @@ void GPUSetIRQLine(int irqline, int state)
 void gpu_init(void)
 {
        memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work RAM");
-//     memory_malloc_secure((void **)&gpu_reg, 32*sizeof(int32), "GPU bank 0 regs");
-//     memory_malloc_secure((void **)&gpu_alternate_reg, 32*sizeof(int32), "GPU bank 1 regs");
        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");
 
@@ -1060,6 +1075,8 @@ void gpu_done(void)
        WriteLog("\n");
 
        memory_free(gpu_ram_8);
+       memory_free(gpu_reg_bank_0);
+       memory_free(gpu_reg_bank_1);
 }
 
 //
@@ -1086,6 +1103,35 @@ void gpu_exec(int32 cycles)
 
        while (cycles > 0 && GPU_RUNNING)
        {
+if (gpu_ram_8[0x054] == 0x98 && gpu_ram_8[0x055] == 0x0A && gpu_ram_8[0x056] == 0x03
+       && gpu_ram_8[0x057] == 0x00 && gpu_ram_8[0x058] == 0x00 && gpu_ram_8[0x059] == 0x00)
+{
+       if (gpu_pc == 0xF03000)
+       {
+               extern uint32 starCount;
+               starCount = 0;
+/*             WriteLog("GPU: Starting starfield generator... Dump of [R03=%08X]:\n", gpu_reg_bank_0[03]);
+               uint32 base = gpu_reg_bank_0[3];
+               for(uint32 i=0; i<0x100; i+=16)
+               {
+                       WriteLog("%02X: ", i);
+                       for(uint32 j=0; j<16; j++)
+                       {
+                               WriteLog("%02X ", JaguarReadByte(base + i + j));
+                       }
+                       WriteLog("\n");
+               }*/
+       }
+//     if (gpu_pc == 0xF03)
+       {
+       }
+}//*/
+/*if (gpu_pc == 0xF03B9E && gpu_reg_bank_0[01] == 0)
+{
+       GPUDumpRegisters();
+       WriteLog("GPU: Starting disassembly log...\n");
+       doGPUDis = true;
+}//*/
 /*if (gpu_pc == 0xF0359A)
 {
        doGPUDis = true;
@@ -1465,14 +1511,25 @@ static void gpu_opcode_subc(void)
        UINT32 res = RN - RM - gpu_flag_c;
        UINT32 borrow = gpu_flag_c;
 //     SET_ZNC_SUB(RN, RM, res); //???BUG??? YES!!!
-       SET_ZNC_SUB(RN - borrow, RM, res);
+//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;
 #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
@@ -1593,7 +1650,7 @@ static void gpu_opcode_move_pc(void)
 {
 #ifdef GPU_DIS_MOVEPC
        if (doGPUDis)
-               WriteLog("%06X: MOVE   PC, R%02u [NCZ:%u%u%u, PC=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_pc-2, IMM_2, RN);
+               WriteLog("%06X: MOVE   PC, R%02u [NCZ:%u%u%u, PC=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_pc-2, IMM_2, RN);
 #endif
        // Should be previous PC--this might not always be previous instruction!
        // Then again, this will point right at the *current* instruction, i.e., MOVE PC,R!