]> Shamusworld >> Repos - virtualjaguar/commitdiff
Fix to M68K core vs. DSP thread sync problem.
authorShamus Hammons <jlhamm@acm.org>
Thu, 7 Feb 2013 23:59:36 +0000 (17:59 -0600)
committerShamus Hammons <jlhamm@acm.org>
Thu, 7 Feb 2013 23:59:36 +0000 (17:59 -0600)
Seems there were some M68K core calls coming from the DSP thread that
caused problems with IRQ handling on the latter. There's a kludge in for
now that should solve that problem but there may be even more like it
lurking in the shadows. :-/

14 files changed:
Makefile
src/dsp.cpp
src/dsp.h
src/file.cpp
src/gpu.cpp
src/gpu.h
src/gui/debug/cpubrowser.cpp
src/gui/mainwin.cpp
src/jagdasm.cpp
src/jaguar.cpp
src/joystick.cpp
src/log.cpp
src/m68000/m68kinterface.c
src/m68000/m68kinterface.h

index 88763de9fa39c411a2866dce3ddbed1aab9b0ed2..edc1d20c7e035efa03b8b33546cd9912fd39b65d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -42,10 +42,10 @@ obj:
 
 prepare: obj
        @echo -e "\033[01;33m***\033[00;32m Preparing to compile Virtual Jaguar...\033[00m"
-       @echo "#define VJ_RELEASE_VERSION \"v2.1.0\"" > src/version.h
-       @echo "#define VJ_RELEASE_SUBVERSION \"Final\"" >> src/version.h
-#      @echo "#define VJ_RELEASE_VERSION \"GIT `git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -`\"" > src/version.h
-#      @echo "#define VJ_RELEASE_SUBVERSION \"2.1.0 Prerelease\"" >> src/version.h
+#      @echo "#define VJ_RELEASE_VERSION \"v2.1.1\"" > src/version.h
+#      @echo "#define VJ_RELEASE_SUBVERSION \"Final\"" >> src/version.h
+       @echo "#define VJ_RELEASE_VERSION \"GIT `git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -`\"" > src/version.h
+       @echo "#define VJ_RELEASE_SUBVERSION \"2.1.1 Prerelease\"" >> src/version.h
 
 virtualjaguar: sources libs makefile-qt
        @echo -e "\033[01;33m***\033[00;32m Making Virtual Jaguar GUI...\033[00m"
index 7a0553f292b6c432a8daaa80b56c51daf88e7ef5..f39449b5016fb4336c05d8813383dd8038806c11 100644 (file)
@@ -99,6 +99,9 @@
 bool doDSPDis = false;
 //bool doDSPDis = true;
 #endif
+bool doDSPDis = false;
+//#define DSP_DIS_JR
+//#define DSP_DIS_JUMP
 
 /*
 No dis yet:
@@ -306,6 +309,7 @@ static void dsp_opcode_subc(void);
 static void dsp_opcode_subq(void);
 static void dsp_opcode_subqmod(void);
 static void dsp_opcode_subqt(void);
+static void dsp_opcode_illegal(void);
 
 uint8 dsp_opcode_cycles[64] =
 {
@@ -351,7 +355,7 @@ void (* dsp_opcode[64])() =
        dsp_opcode_mirror,                              dsp_opcode_store_r14_indexed,   dsp_opcode_store_r15_indexed,   dsp_opcode_move_pc,
        dsp_opcode_jump,                                dsp_opcode_jr,                                  dsp_opcode_mmult,                               dsp_opcode_mtoi,
        dsp_opcode_normi,                               dsp_opcode_nop,                                 dsp_opcode_load_r14_ri,                 dsp_opcode_load_r15_ri,
-       dsp_opcode_store_r14_ri,                dsp_opcode_store_r15_ri,                dsp_opcode_nop,                                 dsp_opcode_addqmod,
+       dsp_opcode_store_r14_ri,                dsp_opcode_store_r15_ri,                dsp_opcode_illegal,                             dsp_opcode_addqmod,
 };
 
 uint32 dsp_opcode_use[65];
@@ -389,7 +393,7 @@ uint32 dsp_control;
 static uint32 dsp_div_control;
 static uint8 dsp_flag_z, dsp_flag_n, dsp_flag_c;
 static uint32 * dsp_reg = NULL, * dsp_alternate_reg = NULL;
-static uint32 dsp_reg_bank_0[32], dsp_reg_bank_1[32];
+uint32 dsp_reg_bank_0[32], dsp_reg_bank_1[32];
 
 static uint32 dsp_opcode_first_parameter;
 static uint32 dsp_opcode_second_parameter;
@@ -418,6 +422,7 @@ uint32 dsp_convert_zero[32] = {
        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
 };
+
 uint8 dsp_branch_condition_table[32 * 8];
 static uint16 mirror_table[65536];
 static uint8 dsp_ram_8[0x2000];
@@ -537,48 +542,6 @@ uint16 DSPReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
                WriteLog("DSP: ReadWord--Attempt to read from DSP register file by %s!\n", whoName[who]);
        //???
        offset &= 0xFFFFFFFE;
-       // jaguar cd bios
-/*     if (jaguar_mainRom_crc32==0xa74a97cd)
-       {
-               if (offset==0xF1A114) return(0x0000);
-               if (offset==0xF1A116) return(0x0000);
-               if (offset==0xF1B000) return(0x1234);
-               if (offset==0xF1B002) return(0x5678);
-       }*/
-/*
-       if (jaguar_mainRom_crc32==0x7ae20823)
-       {
-               if (offset==0xF1B9D8) return(0x0000);
-               if (offset==0xF1B9Da) return(0x0000);
-               if (offset==0xF1B2C0) return(0x0000);
-               if (offset==0xF1B2C2) return(0x0000);
-       }
-*/
-       // pour permettre � wolfenstein 3d de tourner sans le dsp
-/*     if ((offset==0xF1B0D0)||(offset==0xF1B0D2))
-               return(0);
-*/
-
-               // pour permettre � nba jam de tourner sans le dsp
-/*     if (jaguar_mainRom_crc32==0x4faddb18)
-       {
-               if (offset==0xf1b2c0) return(0);
-               if (offset==0xf1b2c2) return(0);
-               if (offset==0xf1b240) return(0);
-               if (offset==0xf1b242) return(0);
-               if (offset==0xF1B340) return(0);
-               if (offset==0xF1B342) return(0);
-               if (offset==0xF1BAD8) return(0);
-               if (offset==0xF1BADA) return(0);
-               if (offset==0xF1B040) return(0);
-               if (offset==0xF1B042) return(0);
-               if (offset==0xF1B0C0) return(0);
-               if (offset==0xF1B0C2) return(0);
-               if (offset==0xF1B140) return(0);
-               if (offset==0xF1B142) return(0);
-               if (offset==0xF1B1C0) return(0);
-               if (offset==0xF1B1C2) return(0);
-       }*/
 
        if (offset >= DSP_WORK_RAM_BASE && offset <= DSP_WORK_RAM_BASE+0x1FFF)
        {
@@ -979,6 +942,7 @@ WriteLog("\n");
                        break;
                }
                case 0x18:
+WriteLog("DSP: Modulo data %08X written by %s.\n", data, whoName[who]);
                        dsp_modulo = data;
                        break;
                case 0x1C:
@@ -1012,6 +976,10 @@ 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;
+
+#ifdef DSP_DEBUG_IRQ
+       WriteLog("DSP: Register bank #%s active.\n", (bank ? "1" : "0"));
+#endif
 }
 
 //
@@ -1033,6 +1001,7 @@ void DSPHandleIRQs(void)
                return;
 
        int which = 0;                                                                  // Determine which interrupt
+
        if (bits & 0x01)
                which = 0;
        if (bits & 0x02)
@@ -1212,18 +1181,24 @@ DSPUpdateRegisterBanks();
        if (bits & 0x20)
                which = 5;
 
-#ifdef DSP_DEBUG_IRQ
-       WriteLog("DSP: Generating interrupt #%i...", which);
-#endif
-
-       dsp_flags |= IMASK;
+       dsp_flags |= IMASK;             // Force Bank #0
 //CC only!
 #ifdef DSP_DEBUG_CC
 ctrl1[4] = dsp_flags;
 #endif
 //!!!!!!!!
+#ifdef DSP_DEBUG_IRQ
+       WriteLog("DSP: Bank 0: R30=%08X, R31=%08X\n", dsp_reg_bank_0[30], dsp_reg_bank_0[31]);
+       WriteLog("DSP: Bank 1: R30=%08X, R31=%08X\n", dsp_reg_bank_1[30], dsp_reg_bank_1[31]);
+#endif
        DSPUpdateRegisterBanks();
 #ifdef DSP_DEBUG_IRQ
+       WriteLog("DSP: Bank 0: R30=%08X, R31=%08X\n", dsp_reg_bank_0[30], dsp_reg_bank_0[31]);
+       WriteLog("DSP: Bank 1: R30=%08X, R31=%08X\n", dsp_reg_bank_1[30], dsp_reg_bank_1[31]);
+#endif
+
+#ifdef DSP_DEBUG_IRQ
+       WriteLog("DSP: Generating interrupt #%i...", which);
        WriteLog(" [PC will return to %08X, R31 = %08X]\n", dsp_pc, dsp_reg[31]);
 #endif
 
@@ -1231,12 +1206,15 @@ ctrl1[4] = dsp_flags;
        // move   pc,r30                ; address of interrupted code
        // store  r30,(r31)     ; store return address
        dsp_reg[31] -= 4;
+       dsp_reg[30] = dsp_pc - 2; // -2 because we've executed the instruction already
+
 //CC only!
 #ifdef DSP_DEBUG_CC
 regs1[31] -= 4;
 #endif
 //!!!!!!!!
-       DSPWriteLong(dsp_reg[31], dsp_pc - 2, DSP);
+//     DSPWriteLong(dsp_reg[31], dsp_pc - 2, DSP);
+       DSPWriteLong(dsp_reg[31], dsp_reg[30], DSP);
 //CC only!
 #ifdef DSP_DEBUG_CC
 SET32(ram1, regs1[31] - 0xF1B000, dsp_pc - 2);
@@ -1271,7 +1249,9 @@ ctrl1[8] = ctrl2[8] = dsp_control;
        if (state)
        {
                dsp_control |= mask;                                            // Set the latch bit
-               DSPHandleIRQs();
+#warning !!! No checking done to see if we're using pipelined DSP or not !!!
+//             DSPHandleIRQs();
+               DSPHandleIRQsNP();
 //CC only!
 #ifdef DSP_DEBUG_CC
 ctrl1[8] = ctrl2[8] = dsp_control;
@@ -1358,10 +1338,10 @@ void DSPDumpRegisters(void)
        for(int j=0; j<8; j++)
        {
                WriteLog("\tR%02i = %08X R%02i = %08X R%02i = %08X R%02i = %08X\n",
-                                                 (j << 2) + 0, dsp_reg_bank_0[(j << 2) + 0],
-                                                 (j << 2) + 1, dsp_reg_bank_0[(j << 2) + 1],
-                                                 (j << 2) + 2, dsp_reg_bank_0[(j << 2) + 2],
-                                                 (j << 2) + 3, dsp_reg_bank_0[(j << 2) + 3]);
+                       (j << 2) + 0, dsp_reg_bank_0[(j << 2) + 0],
+                       (j << 2) + 1, dsp_reg_bank_0[(j << 2) + 1],
+                       (j << 2) + 2, dsp_reg_bank_0[(j << 2) + 2],
+                       (j << 2) + 3, dsp_reg_bank_0[(j << 2) + 3]);
        }
 
        WriteLog("Registers bank 1\n");
@@ -1369,10 +1349,10 @@ void DSPDumpRegisters(void)
        for(int j=0; j<8; j++)
        {
                WriteLog("\tR%02i = %08X R%02i = %08X R%02i = %08X R%02i = %08X\n",
-                                                 (j << 2) + 0, dsp_reg_bank_1[(j << 2) + 0],
-                                                 (j << 2) + 1, dsp_reg_bank_1[(j << 2) + 1],
-                                                 (j << 2) + 2, dsp_reg_bank_1[(j << 2) + 2],
-                                                 (j << 2) + 3, dsp_reg_bank_1[(j << 2) + 3]);
+                       (j << 2) + 0, dsp_reg_bank_1[(j << 2) + 0],
+                       (j << 2) + 1, dsp_reg_bank_1[(j << 2) + 1],
+                       (j << 2) + 2, dsp_reg_bank_1[(j << 2) + 2],
+                       (j << 2) + 3, dsp_reg_bank_1[(j << 2) + 3]);
        }
 }
 
@@ -1432,15 +1412,6 @@ void DSPDone(void)
                if (dsp_opcode_use[i])
                        WriteLog("\t%s %i\n", dsp_opcode_str[i], dsp_opcode_use[i]);
        }//*/
-
-//     memory_free(dsp_ram_8);
-//     memory_free(dsp_reg_bank_0);
-//     memory_free(dsp_reg_bank_1);
-//     if (dsp_branch_condition_table)
-//             free(dsp_branch_condition_table);
-
-//     if (mirror_table)
-//             free(mirror_table);
 }
 
 
@@ -1652,9 +1623,6 @@ for(int k=0; k<2; k++)
 //static uint32 pcQueue[32], ptrPCQ = 0;
 void DSPExec(int32 cycles)
 {
-/*HACKS!!! ->  if (cycles != 1 && jaguar_mainRom_crc32 == 0xba74c3ed)
-               dsp_check_if_i2s_interrupt_needed();*/
-
 #ifdef DSP_SINGLE_STEPPING
        if (dsp_control & 0x18)
        {
@@ -1687,7 +1655,7 @@ if (dsp_pc == 0xF1B092)
                if (IMASKCleared)                                               // If IMASK was cleared,
                {
 #ifdef DSP_DEBUG_IRQ
-                       WriteLog("DSP: Finished interrupt.\n");
+                       WriteLog("DSP: Finished interrupt. PC=$%06X\n", dsp_pc);
 #endif
                        DSPHandleIRQsNP();                                      // See if any other interrupts are pending!
                        IMASKCleared = false;
@@ -2572,6 +2540,7 @@ static void dsp_opcode_shlq(void)
        if (doDSPDis)
                WriteLog("%06X: SHLQ   #%u, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", dsp_pc-2, 32 - IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
 #endif
+       // NB: This instruction is the *only* one that does (32 - immediate data).
        int32 r1 = 32 - IMM_1;
        uint32 res = RN << r1;
        SET_ZN(res); dsp_flag_c = (RN >> 31) & 1;
@@ -2761,6 +2730,12 @@ void dsp_opcode_sat16s(void)
        SET_ZN(res);
 }
 
+void dsp_opcode_illegal(void)
+{
+       // Don't know what it does, but it does *something*...
+       WriteLog("%06X: illegal %u, %u [NCZ:%u%u%u]\n", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z);
+}
+
 //
 // New pipelined DSP core
 //
index 67e52991bea17c643efe82a5049c7998201296d2..935c6e699366a9586d992bf17093ef25bd981c32 100644 (file)
--- a/src/dsp.h
+++ b/src/dsp.h
@@ -35,6 +35,7 @@ void DSPExecComp(int32 cycles);
 // Exported vars
 
 extern bool doDSPDis;
+extern uint32 dsp_reg_bank_0[], dsp_reg_bank_1[];
 
 // DSP interrupt numbers (in $F1A100, bits 4-8 & 16)
 
index dff0c55a062154366ee50b68191c0ebdfb397a3f..ac81a06dd2d1b1409cc855c86b4cde52fc8ea576 100644 (file)
@@ -223,6 +223,11 @@ WriteLog("FILE: Cartridge run address is reported as $%X...\n", jaguarRunAddress
                        memcpy(jagMemSpace + loadAddress, buffer + 0x2E, jaguarROMSize - 0x2E);
                        delete[] buffer;
                        jaguarRunAddress = runAddress;
+
+// Hmm. Is this kludge necessary?
+SET32(jaguarMainRAM, 0x10, 0x00001000);                // Set Exception #4 (Illegal Instruction)
+SET16(jaguarMainRAM, 0x1000, 0x60FE);          // Here: bra Here
+
                        return true;
 //             }
 //             else // Special WTFOMGBBQ type here...
index 09a664d6cce2fc07ab32393f8d0af80fc485dddc..e5855fea7eda560f68fcdc186f74b781febaf36d 100644 (file)
@@ -323,8 +323,8 @@ static uint32 gpu_div_control;
 // 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;
 
index 97ba4b33a3a7fdf804d27d3751bee3e864f75a5a..9d3260f778af10067c9ee25f6f7fa110df6781a6 100644 (file)
--- a/src/gpu.h
+++ b/src/gpu.h
@@ -35,4 +35,8 @@ uint32 GPUReadPC(void);
 
 enum { GPUIRQ_CPU = 0, GPUIRQ_DSP, GPUIRQ_TIMER, GPUIRQ_OBJECT, GPUIRQ_BLITTER };
 
+// Exported vars
+
+extern uint32 gpu_reg_bank_0[], gpu_reg_bank_1[];
+
 #endif // __GPU_H__
index 9951c648a458ae5f147350b935a9544115c21964..62d6d0a250ebe8a958806d7443069db2113a0a84 100644 (file)
@@ -46,7 +46,7 @@ CPUBrowserWindow::CPUBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt:
 
 void CPUBrowserWindow::RefreshContents(void)
 {
-       char string[1024], buf[64];
+       char string[2048];
        QString s;
 
        // 68K
@@ -87,10 +87,86 @@ void CPUBrowserWindow::RefreshContents(void)
        sprintf(string, "GPU PC: %06X&nbsp;&nbsp;FLAGS: %08X<br><br>", GPUReadLong(0xF02010), GPUReadLong(0xF02000));
        s += QString(string);
 
+       sprintf(string, "Bank 0:<br>"
+               "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
+               "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
+               "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
+               "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
+               "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
+               "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
+               "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
+               "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
+               gpu_reg_bank_0[0], gpu_reg_bank_0[1], gpu_reg_bank_0[2], gpu_reg_bank_0[3],
+               gpu_reg_bank_0[4], gpu_reg_bank_0[5], gpu_reg_bank_0[6], gpu_reg_bank_0[7],
+               gpu_reg_bank_0[8], gpu_reg_bank_0[9], gpu_reg_bank_0[10], gpu_reg_bank_0[11],
+               gpu_reg_bank_0[12], gpu_reg_bank_0[13], gpu_reg_bank_0[14], gpu_reg_bank_0[15],
+               gpu_reg_bank_0[16], gpu_reg_bank_0[17], gpu_reg_bank_0[18], gpu_reg_bank_0[19],
+               gpu_reg_bank_0[20], gpu_reg_bank_0[21], gpu_reg_bank_0[22], gpu_reg_bank_0[23],
+               gpu_reg_bank_0[24], gpu_reg_bank_0[25], gpu_reg_bank_0[26], gpu_reg_bank_0[27],
+               gpu_reg_bank_0[28], gpu_reg_bank_0[29], gpu_reg_bank_0[30], gpu_reg_bank_0[31]);
+       s += QString(string);
+
+       sprintf(string, "Bank 1:<br>"
+               "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
+               "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
+               "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
+               "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
+               "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
+               "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
+               "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
+               "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
+               gpu_reg_bank_1[0], gpu_reg_bank_1[1], gpu_reg_bank_1[2], gpu_reg_bank_1[3],
+               gpu_reg_bank_1[4], gpu_reg_bank_1[5], gpu_reg_bank_1[6], gpu_reg_bank_1[7],
+               gpu_reg_bank_1[8], gpu_reg_bank_1[9], gpu_reg_bank_1[10], gpu_reg_bank_1[11],
+               gpu_reg_bank_1[12], gpu_reg_bank_1[13], gpu_reg_bank_1[14], gpu_reg_bank_1[15],
+               gpu_reg_bank_1[16], gpu_reg_bank_1[17], gpu_reg_bank_1[18], gpu_reg_bank_1[19],
+               gpu_reg_bank_1[20], gpu_reg_bank_1[21], gpu_reg_bank_1[22], gpu_reg_bank_1[23],
+               gpu_reg_bank_1[24], gpu_reg_bank_1[25], gpu_reg_bank_1[26], gpu_reg_bank_1[27],
+               gpu_reg_bank_1[28], gpu_reg_bank_1[29], gpu_reg_bank_1[30], gpu_reg_bank_1[31]);
+       s += QString(string);
+
        // DSP
        sprintf(string, "DSP PC: %06X&nbsp;&nbsp;FLAGS: %08X<br><br>", DSPReadLong(0xF1A110), DSPReadLong(0xF1A100));
        s += QString(string);
 
+       sprintf(string, "Bank 0:<br>"
+               "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
+               "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
+               "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
+               "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
+               "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
+               "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
+               "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
+               "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
+               dsp_reg_bank_0[0], dsp_reg_bank_0[1], dsp_reg_bank_0[2], dsp_reg_bank_0[3],
+               dsp_reg_bank_0[4], dsp_reg_bank_0[5], dsp_reg_bank_0[6], dsp_reg_bank_0[7],
+               dsp_reg_bank_0[8], dsp_reg_bank_0[9], dsp_reg_bank_0[10], dsp_reg_bank_0[11],
+               dsp_reg_bank_0[12], dsp_reg_bank_0[13], dsp_reg_bank_0[14], dsp_reg_bank_0[15],
+               dsp_reg_bank_0[16], dsp_reg_bank_0[17], dsp_reg_bank_0[18], dsp_reg_bank_0[19],
+               dsp_reg_bank_0[20], dsp_reg_bank_0[21], dsp_reg_bank_0[22], dsp_reg_bank_0[23],
+               dsp_reg_bank_0[24], dsp_reg_bank_0[25], dsp_reg_bank_0[26], dsp_reg_bank_0[27],
+               dsp_reg_bank_0[28], dsp_reg_bank_0[29], dsp_reg_bank_0[30], dsp_reg_bank_0[31]);
+       s += QString(string);
+
+       sprintf(string, "Bank 1:<br>"
+               "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
+               "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
+               "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
+               "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
+               "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
+               "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
+               "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
+               "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br>",
+               dsp_reg_bank_1[0], dsp_reg_bank_1[1], dsp_reg_bank_1[2], dsp_reg_bank_1[3],
+               dsp_reg_bank_1[4], dsp_reg_bank_1[5], dsp_reg_bank_1[6], dsp_reg_bank_1[7],
+               dsp_reg_bank_1[8], dsp_reg_bank_1[9], dsp_reg_bank_1[10], dsp_reg_bank_1[11],
+               dsp_reg_bank_1[12], dsp_reg_bank_1[13], dsp_reg_bank_1[14], dsp_reg_bank_1[15],
+               dsp_reg_bank_1[16], dsp_reg_bank_1[17], dsp_reg_bank_1[18], dsp_reg_bank_1[19],
+               dsp_reg_bank_1[20], dsp_reg_bank_1[21], dsp_reg_bank_1[22], dsp_reg_bank_1[23],
+               dsp_reg_bank_1[24], dsp_reg_bank_1[25], dsp_reg_bank_1[26], dsp_reg_bank_1[27],
+               dsp_reg_bank_1[28], dsp_reg_bank_1[29], dsp_reg_bank_1[30], dsp_reg_bank_1[31]);
+       s += QString(string);
+
        text->clear();
        text->setText(s);
 }
index 1c990faec8337d5a7c038907150cbce48a524a51..1dbafa0a3975a3324c35604b2cbe13e063e31c57 100644 (file)
@@ -403,12 +403,22 @@ void MainWin::closeEvent(QCloseEvent * event)
 
 void MainWin::keyPressEvent(QKeyEvent * e)
 {
+       // From jaguar.cpp
+       extern bool startM68KTracing;
+
        // We ignore the Alt key for now, since it causes problems with the GUI
        if (e->key() == Qt::Key_Alt)
        {
                e->accept();
                return;
        }
+       else if (e->key() == Qt::Key_F11)
+       {
+               startM68KTracing = true;
+               e->accept();
+               return;
+       }
+
 /*
        if (e->key() == Qt::Key_F9)
        {
index e2730495534e289c483e32f9d1a34a436bf5febf..71c531a2b59dd9f1e93c4a6e83954591621eed82 100644 (file)
@@ -114,7 +114,7 @@ unsigned dasmjag(int dsp_type, char * bufferOut, unsigned pc)
                case 21:        sprintf(buffer, "DIV     R%02d,R%02d", reg1, reg2);                             break;
                case 22:        sprintf(buffer, "ABS     R%02d", reg2);                                                 break;
                case 23:        sprintf(buffer, "SH      R%02d,R%02d", reg1, reg2);                             break;
-               case 24:        sprintf(buffer, "SHLQ    $%X,R%02d", 32 - convert_zero[reg1], reg2);    break;
+               case 24:        sprintf(buffer, "SHLQ    $%X,R%02d", 32 - reg1, reg2);  break;
                case 25:        sprintf(buffer, "SHRQ    $%X,R%02d", convert_zero[reg1], reg2); break;
                case 26:        sprintf(buffer, "SHA     R%02d,R%02d", reg1, reg2);                             break;
                case 27:        sprintf(buffer, "SHARQ   $%X,R%02d", convert_zero[reg1], reg2); break;
@@ -171,7 +171,7 @@ unsigned dasmjag(int dsp_type, char * bufferOut, unsigned pc)
                case 62:        if (dsp_type == JAGUAR_GPU)
                                                sprintf(buffer, "SAT24   R%02d", reg2);
                                        else
-                                               sprintf(buffer, "illegal");
+                                               sprintf(buffer, "illegal [%d,%d]", reg1, reg2);
                                        break;
                case 63:        if (dsp_type == JAGUAR_GPU)
                                                sprintf(buffer, (reg1 ? "UNPACK  R%02d" : "PACK    R%02d"), reg2);
index f930c9a31e5b2a6965457b7dacc3d4956dd10758..5f23f1b4da8306ef7c3351baa079e2d3d27e26ad 100644 (file)
 //Do this in makefile??? Yes! Could, but it's easier to define here...
 //#define LOG_UNMAPPED_MEMORY_ACCESSES
 //#define ABORT_ON_UNMAPPED_MEMORY_ACCESS
-#define ABORT_ON_ILLEGAL_INSTRUCTIONS
+//#define ABORT_ON_ILLEGAL_INSTRUCTIONS
 //#define ABORT_ON_OFFICIAL_ILLEGAL_INSTRUCTION
 #define CPU_DEBUG_MEMORY
 //#define LOG_CD_BIOS_CALLS
+#define CPU_DEBUG_TRACING
 
 // Private function prototypes
 
@@ -78,6 +79,7 @@ uint32 returnAddr[4000], raPtr = 0xFFFFFFFF;
 
 uint32 pcQueue[0x400];
 uint32 pcQPtr = 0;
+bool startM68KTracing = false;
 
 //
 // Callback function to detect illegal instructions
@@ -121,6 +123,17 @@ if (inRoutine)
        instSeen++;
 #endif
 
+// For code tracing...
+#ifdef CPU_DEBUG_TRACING
+       if (startM68KTracing)
+       {
+               static char buffer[2048];
+
+               m68k_disassemble(buffer, m68kPC, 0);
+               WriteLog("%06X: %s\n", m68kPC, buffer);
+       }
+#endif
+
 // For tracebacks...
 // Ideally, we'd save all the registers as well...
        pcQueue[pcQPtr++] = m68kPC;
@@ -270,7 +283,7 @@ if (m68kPC == 0x802058) start = true;
                        m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
                        m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2));
        }//*/
-       if (m68kPC == 0x82E1A)
+/*     if (m68kPC == 0x82E1A)
        {
                static char buffer[2048];
                m68k_disassemble(buffer, m68kPC, 0);//M68K_CPU_TYPE_68000);
@@ -279,7 +292,7 @@ if (m68kPC == 0x802058) start = true;
                        m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
                        m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2));
        }//*/
-       if (m68kPC == 0x82E58)
+/*     if (m68kPC == 0x82E58)
                WriteLog("--> [Routine end]\n");
        if (m68kPC == 0x80004)
        {
@@ -929,6 +942,13 @@ handler:
 #endif
 int irq_ack_handler(int level)
 {
+#ifdef CPU_DEBUG_TRACING
+       if (startM68KTracing)
+       {
+               WriteLog("irq_ack_handler: M68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC));
+       }
+#endif
+
        // Tracing the IPL lines on the Jaguar schematic yields the following:
        // IPL1 is connected to INTL on TOM (OUT to 68K)
        // IPL0-2 are also tied to Vcc via 4.7K resistors!
index 14b5ff784a8f737cd49b67daee9c06c36d996595..208b58b2be51cb5ecbfca18f5206312c2455772e 100644 (file)
@@ -283,6 +283,8 @@ void JoystickExec(void)
                joypad_0_buttons[BUTTON_D] = 0;
 #endif
 
+// This is handled by the GUI layer, as it should
+#if 0
        // Joystick support [nwagenaar]
 
     if (vjs.useJoystick)
@@ -310,6 +312,7 @@ void JoystickExec(void)
 
        // Needed to ensure that the events queue is empty [nwagenaar]
     SDL_PumpEvents();
+#endif
 }
 
 void JoystickReset(void)
index 2782c930160ad1e8b3a042981ff90d8d8bf0d7b0..4f6619d9b20412fd05b2d83f7eb1e6844a174a3c 100644 (file)
@@ -22,7 +22,8 @@
 #include <stdarg.h>
 #include "types.h"
 
-#define MAX_LOG_SIZE           10000000                                // Maximum size of log file (10 MB)
+//#define MAX_LOG_SIZE         10000000                                // Maximum size of log file (10 MB)
+#define MAX_LOG_SIZE           100000000                               // Maximum size of log file (100 MB)
 
 static FILE * log_stream = NULL;
 static uint32 logSize = 0;
index bdaa0c4d7e2074774ab2616c6d6e6b6d56bbe472..528d7e7ae1f66a54c7c6da34d1cb44e1b5487df7 100644 (file)
 //
 
 #include "m68kinterface.h"
+//#include <pthread.h>
 #include "cpudefs.h"
 #include "inlines.h"
 #include "cpuextra.h"
 #include "readcpu.h"
 
-
 // Exception Vectors handled by emulation
 #define EXCEPTION_BUS_ERROR                2 /* This one is not emulated! */
 #define EXCEPTION_ADDRESS_ERROR            3 /* This one is partially emulated (doesn't stack a proper frame yet) */
@@ -54,11 +54,17 @@ STATIC_INLINE uint32_t m68ki_init_exception(void);
 STATIC_INLINE void m68ki_stack_frame_3word(uint32_t pc, uint32_t sr);
 unsigned long IllegalOpcode(uint32_t opcode);
 void BuildCPUFunctionTable(void);
+void m68k_set_irq2(unsigned int intLevel);
 
 // Local "Global" vars
 static int32_t initialCycles;
 cpuop_func * cpuFunctionTable[65536];
 
+// By virtue of the fact that m68k_set_irq() can be called asychronously by
+// another thread, we need something along the lines of this:
+static int checkForIRQToHandle = 0;
+//static pthread_mutex_t executionLock = PTHREAD_MUTEX_INITIALIZER;
+static int IRQLevelToHandle = 0;
 
 #if 0
 #define ADD_CYCLES(A)    m68ki_remaining_cycles += (A)
@@ -311,6 +317,16 @@ if (inRoutine)
 //94C0: 6A02                     BPL.B $94C4
 //94C2: 2452                     MOVEA.L       (A2), A2                        ; <--- HERE
 //94C4: 4283                     CLR.L D3
+#endif
+//             pthread_mutex_lock(&executionLock);
+               if (checkForIRQToHandle)
+               {
+                       checkForIRQToHandle = 0;
+                       m68k_set_irq2(IRQLevelToHandle);
+               }
+
+#ifdef M68K_HOOK_FUNCTION
+               M68KInstructionHook();
 #endif
                uint32_t opcode = get_iword(0);
 //if ((opcode & 0xFFF8) == 0x31C0)
@@ -319,14 +335,12 @@ if (inRoutine)
 //}
                int32_t cycles = (int32_t)(*cpuFunctionTable[opcode])(opcode);
                regs.remainingCycles -= cycles;
+//             pthread_mutex_unlock(&executionLock);
+
 //printf("Executed opcode $%04X (%i cycles)...\n", opcode, cycles);
 #endif
        }
-#if 0
-       while (GET_CYCLES() > 0);
-#else
        while (regs.remainingCycles > 0);
-#endif
 
 #if 0
        /* set previous PC to current PC for the next entry into the loop */
@@ -348,20 +362,21 @@ if (inRoutine)
 }
 
 
-/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
 void m68k_set_irq(unsigned int intLevel)
 {
-#if 0
-       uint old_level = CPU_INT_LEVEL;
-       CPU_INT_LEVEL = int_level << 8;
+       // Since this can be called asynchronously, we need to fix it so that it
+       // doesn't fuck up the main execution loop.
+       IRQLevelToHandle = intLevel;
+       checkForIRQToHandle = 1;
+}
+
+
+/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
+void m68k_set_irq2(unsigned int intLevel)
+{
+//     pthread_mutex_lock(&executionLock);
+//             printf("m68k_set_irq: Could not get the lock!!!\n");
 
-       /* A transition from < 7 to 7 always interrupts (NMI) */
-       /* Note: Level 7 can also level trigger like a normal IRQ */
-       if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
-               m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */
-       else
-               m68ki_check_interrupts(); /* Level triggered (IRQ) */
-#else
        int oldLevel = regs.intLevel;
        regs.intLevel = intLevel;
 
@@ -371,7 +386,8 @@ void m68k_set_irq(unsigned int intLevel)
                m68ki_exception_interrupt(7);           // Edge triggered level 7 (NMI)
        else
                m68ki_check_interrupts();                       // Level triggered (IRQ)
-#endif
+
+//     pthread_mutex_unlock(&executionLock);
 }
 
 
@@ -485,9 +501,24 @@ void m68ki_exception_interrupt(uint32_t intLevel)
        // Set the interrupt mask to the level of the one being serviced
        regs.intmask = intLevel;
 
+#if 0
+extern int startM68KTracing;
+if (startM68KTracing)
+{
+       printf("IRQ: old PC=%06X, ", regs.pc);
+}
+#endif
+
        // Get the new PC
        uint32_t newPC = m68k_read_memory_32(vector << 2);
 
+#if 0
+if (startM68KTracing)
+{
+       printf("new PC=%06X, vector=%u, ", newPC, vector);
+}
+#endif
+
        // If vector is uninitialized, call the uninitialized interrupt vector
        if (newPC == 0)
                newPC = m68k_read_memory_32(EXCEPTION_UNINITIALIZED_INTERRUPT << 2);
@@ -496,6 +527,12 @@ void m68ki_exception_interrupt(uint32_t intLevel)
        m68ki_stack_frame_3word(regs.pc, sr);
 
        m68k_setpc(newPC);
+#if 0
+if (startM68KTracing)
+{
+       printf("(PC=%06X)\n", regs.pc);
+}
+#endif
 
        // Defer cycle counting until later
        regs.interruptCycles += 56;     // NOT ACCURATE-- !!! FIX !!!
@@ -605,10 +642,16 @@ unsigned int m68k_disassemble(char * str_buff, unsigned int pc, unsigned int cpu
 
 int m68k_cycles_run(void) {}              /* Number of cycles run so far */
 int m68k_cycles_remaining(void) {}        /* Number of cycles left */
-void m68k_modify_timeslice(int cycles) {} /* Modify cycles left */
+//void m68k_modify_timeslice(int cycles) {} /* Modify cycles left */
 //void m68k_end_timeslice(void) {}          /* End timeslice now */
 
 
+void m68k_modify_timeslice(int cycles)
+{
+       regs.remainingCycles = cycles;
+}
+
+
 void m68k_end_timeslice(void)
 {
 #if 0
index f96bf680dc9c5565575d770be7d5165b9ee9d4b5..613bb11c68baed8ad0ddec5d46ed58b2da415656 100644 (file)
@@ -90,6 +90,13 @@ int irq_ack_handler(int);
 
 // Convenience functions
 
+// Uncomment this to have the emulated CPU call a hook function after every instruction
+// NB: This must be implemented by the user!
+#define M68K_HOOK_FUNCTION
+#ifdef M68K_HOOK_FUNCTION
+void M68KInstructionHook(void);
+#endif
+
 /* Peek at the internals of a CPU context.  This can either be a context
  * retrieved using m68k_get_context() or the currently running context.
  * If context is NULL, the currently running CPU context will be used.