]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/dsp.cpp
Moved from ./src
[virtualjaguar] / src / dsp.cpp
index 014578bee047bce472c26e7b9db106e31b1f8fd0..f21fa692a65bf647000288776f52313f4bd2d400 100644 (file)
@@ -1,7 +1,7 @@
 //
 // DSP core
 //
-// Original source by Cal2
+// Originally by David Raingeard
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
 // Extensive cleanups/rewrites by James L. Hammons
 //
 //#define DSP_DEBUG_PL2
 //#define DSP_DEBUG_STALL
 //#define DSP_DEBUG_CC
+#define NEW_SCOREBOARD
 
 // Disassembly definitions
 
-#define DSP_DIS_ABS                                                                    // Pipelined only
+#define DSP_DIS_ABS
 #define DSP_DIS_ADD
 #define DSP_DIS_ADDC
 #define DSP_DIS_ADDQ
@@ -46,6 +47,7 @@
 #define DSP_DIS_MOVEI
 #define DSP_DIS_MOVEQ
 #define DSP_DIS_MOVEFA
+#define DSP_DIS_MOVEPC                                                         // Pipeline only!
 #define DSP_DIS_MOVETA
 #define DSP_DIS_MULT
 #define DSP_DIS_NEG
@@ -156,7 +158,11 @@ struct PipelineStage
 #define TYPE_WORD                      1
 #define TYPE_DWORD                     2
 #define PIPELINE_STALL         64                                              // Set to # of opcodes + 1
+#ifndef NEW_SCOREBOARD
 bool scoreboard[32];
+#else
+uint8 scoreboard[32];
+#endif
 uint8 plPtrFetch, plPtrRead, plPtrExec, plPtrWrite;
 PipelineStage pipeline[4];
 bool IMASKCleared = false;
@@ -278,23 +284,30 @@ static void dsp_opcode_subqt(void);
 
 uint8 dsp_opcode_cycles[64] =
 {
-       3,  3,  3,  3,  
-       3,  3,  3,  3,  
-       3,  3,  3,  3,  
-       3,  3,  3,  3,
-       3,  3,  1,  3,  
-       1, 18,  3,  3,  
-       3,  3,  3,  3,  
-       3,  3,  3,  3,
-       3,  3,  2,  2,  
-       2,  2,  3,  4,  
-       5,  4,  5,  6,  
-       6,  1,  1,  1,
-       1,  2,  2,  2,  
-       1,  1,  9,  3,  
-       3,  1,  6,  6,  
-       2,  2,  3,  3
-};
+       3,  3,  3,  3,  3,  3,  3,  3,  
+       3,  3,  3,  3,  3,  3,  3,  3,
+       3,  3,  1,  3,  1, 18,  3,  3,  
+       3,  3,  3,  3,  3,  3,  3,  3,
+       3,  3,  2,  2,  2,  2,  3,  4,  
+       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 dsp_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 (* dsp_opcode[64])() =
 {      
@@ -667,6 +680,10 @@ void DSPWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 //     WriteLog("dsp: writing %.4x at 0x%.8x\n",data,offset);
        if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000))
        {
+/*if (offset == 0xF1B2F4)
+{
+       WriteLog("DSP: %s is writing %04X at location 0xF1B2F4 (DSP_PC: %08X)...\n", whoName[who], data, dsp_pc);
+}//*/
                offset -= DSP_WORK_RAM_BASE;
                dsp_ram_8[offset] = data >> 8;
                dsp_ram_8[offset+1] = data & 0xFF;
@@ -765,6 +782,29 @@ SET32(ram2, offset, data);
 #ifdef DSP_DEBUG_IRQ
                        }
 #endif//*/
+#if 0
+                       if (/*4-8, 16*/data & 0x101F0)
+                               WriteLog("DSP: %s is enabling interrupts %s%s%s%s%s%s\n", whoName[who],
+                                       (data & 0x010 ? "CPU " : ""), (data & 0x020 ? "I2S " : ""),
+                                       (data & 0x040 ? "TIMER0 " : ""), (data & 0x080 ? "TIMER1 " : ""),
+                                       (data & 0x100 ? "EXT0 " : ""), (data & 0x10000 ? "EXT1" : ""));
+/*if (data & 0x00020) // CD BIOS DSP code...
+{
+//001AC1BA: movea.l #$1AC200, A0
+//001AC1C0: move.l  #$1AC68C, D0
+       char buffer[512];
+
+       WriteLog("\n---[DSP code at 00F1B97C]---------------------------\n");
+       uint32 j = 0xF1B97C;//0x1AC200;
+       while (j <= 0xF1BE08)//0x1AC68C)
+       {
+               uint32 oldj = j;
+               j += dasmjag(JAGUAR_DSP, buffer, j);
+//             WriteLog("\t%08X: %s\n", oldj+0xD6F77C, buffer);
+               WriteLog("\t%08X: %s\n", oldj, buffer);
+       }
+}//*/
+#endif
                        break;
                }
                case 0x04:
@@ -792,9 +832,9 @@ if (who != DSP)
                        break;
                case 0x14:
                {       
-#ifdef DSP_DEBUG
+//#ifdef DSP_DEBUG
 WriteLog("Write to DSP CTRL by %s: %08X\n", whoName[who], data);
-#endif
+//#endif
                        bool wasRunning = DSP_RUNNING;
 //                     uint32 dsp_was_running = DSP_RUNNING;
                        // Check for DSP -> CPU interrupt
@@ -988,8 +1028,15 @@ WriteLog("\tW -> %02u, %02u, %02u; r1=%08X, r2= %08X, res=%08X, wb=%u (%s)\n", p
                        }
                }
 
+#ifndef NEW_SCOREBOARD
                if (affectsScoreboard[pipeline[plPtrWrite].opcode])
                        scoreboard[pipeline[plPtrWrite].operand2] = false;
+#else
+//Yup, sequential MOVEQ # problem fixing (I hope!)...
+               if (affectsScoreboard[pipeline[plPtrWrite].opcode])
+                       if (scoreboard[pipeline[plPtrWrite].operand2])
+                               scoreboard[pipeline[plPtrWrite].operand2]--;
+#endif
        }
 
        dsp_flags |= IMASK;
@@ -1169,6 +1216,11 @@ DSPHandleIRQsNP();
 #endif
 //!!!!!!!!
        }
+
+       // Not sure if this is correct behavior, but according to JTRM,
+       // the IRQ output of JERRY is fed to this IRQ in the GPU...
+// Not sure this is right--DSP interrupts seem to be different from the JERRY interrupts!
+//     GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE);
 }
 
 void DSPInit(void)
@@ -1261,7 +1313,7 @@ void DSPDone(void)
        WriteLog("\nRegisters bank 0\n");
        for(int j=0; j<8; j++)
        {
-               WriteLog("\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
+               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],
@@ -1270,7 +1322,7 @@ void DSPDone(void)
        WriteLog("\nRegisters bank 1\n");
        for (j=0; j<8; j++)
        {
-               WriteLog("\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
+               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],
@@ -1295,6 +1347,8 @@ void DSPDone(void)
        }//*/
 
        memory_free(dsp_ram_8);
+       memory_free(dsp_reg_bank_0);
+       memory_free(dsp_reg_bank_1);
 }
 
 
@@ -1523,6 +1577,21 @@ void DSPExec(int32 cycles)
 
        while (cycles > 0 && DSP_RUNNING)
        {
+/*extern uint32 totalFrames;
+//F1B2F6: LOAD   (R14+$04), R24 [NCZ:001, R14+$04=00F20018, R24=FFFFFFFF] -> Jaguar: Unknown word read at 00F20018 by DSP (M68K PC=00E32E)
+//-> 43 + 1 + 24 -> $2B + $01 + $18 -> 101011 00001 11000 -> 1010 1100 0011 1000 -> AC38
+//C470 -> 1100 0100 0111 0000 -> 110001 00011 10000 -> 49, 3, 16 -> STORE R16, (R14+$0C)
+//F1B140:
+if (totalFrames >= 377 && GET16(dsp_ram_8, 0x0002F6) == 0xAC38 && dsp_pc == 0xF1B140)
+{
+       doDSPDis = true;
+       WriteLog("Starting disassembly at frame #%u...\n", totalFrames);
+}
+if (dsp_pc == 0xF1B092)
+       doDSPDis = false;//*/
+/*if (dsp_pc == 0xF1B140)
+       doDSPDis = true;//*/
+
                if (IMASKCleared)                                               // If IMASK was cleared,
                {
 #ifdef DSP_DEBUG_IRQ
@@ -1837,13 +1906,13 @@ static void dsp_opcode_not(void)
 {
 #ifdef DSP_DIS_NOT
        if (doDSPDis)
-               WriteLog("%06X: NOT    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);
+               WriteLog("%06X: NOT    R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", dsp_pc-2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
 #endif
        RN = ~RN;
        SET_ZN(RN);
 #ifdef DSP_DIS_NOT
        if (doDSPDis)
-               WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN);
+               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
 #endif
 }
 
@@ -2281,6 +2350,10 @@ static void dsp_opcode_mmult(void)
 
 static void dsp_opcode_abs(void)
 {
+#ifdef DSP_DIS_ABS
+       if (doDSPDis)
+               WriteLog("%06X: ABS    R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", dsp_pc-2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
+#endif
        uint32 _Rn = RN;
        uint32 res;
        
@@ -2292,6 +2365,10 @@ static void dsp_opcode_abs(void)
                res = RN = (_Rn & 0x80000000 ? -_Rn : _Rn);
                CLR_ZN; SET_Z(res);
        }
+#ifdef DSP_DIS_ABS
+       if (doDSPDis)
+               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
+#endif
 }
 
 static void dsp_opcode_div(void)
@@ -2661,6 +2738,21 @@ bool readAffected[64][2] =
        { true,  true}, { true,  true}, {false, false}, {false,  true}
 };
 
+bool isLoadStore[65] =
+{
+       false, false, false, false, false, false, false, false,
+       false, false, false, false, false, false, false, false,
+
+       false, false, false, false, false, false, false, false,
+       false, false, false, false, false, false, false, false,
+
+       false, false, false, false, false, false, false,  true,
+        true,  true, false,  true,  true,  true,  true,  true,
+
+       false,  true,  true, false, false, false, false, false,
+       false, false,  true,  true,  true,  true, false, false, false
+};
+
 void FlushDSPPipeline(void)
 {
        plPtrFetch = 3, plPtrRead = 2, plPtrExec = 1, plPtrWrite = 0;
@@ -2669,7 +2761,7 @@ void FlushDSPPipeline(void)
                pipeline[i].opcode = PIPELINE_STALL;
 
        for(int i=0; i<32; i++)
-               scoreboard[i] = false;
+               scoreboard[i] = 0;
 }
 
 //
@@ -2836,7 +2928,7 @@ because the STORE instruction writes back on stage #2 of the pipeline instead of
 If it were done properly, the STORE write back would occur *after* (well, technically,
 during) the execution of the the JUMP that follows it.
 
-!!! FIX !!!
+!!! FIX !!! [DONE]
 
 F1B08A: JR     z, F1B082 [NCZ:001] Branched!
 F1B08A: NOP    [NCZ:001]
@@ -2938,7 +3030,7 @@ F1B1FC: MOVEI  #$00F1A100, R01 [NCZ:001, R01=00F1A100] -> [NCZ:001, R01=00F1A100
 
 uint32 pcQueue1[0x400];
 uint32 pcQPtr1 = 0;
-
+static uint32 prevR1;
 //Let's try a 3 stage pipeline....
 //Looks like 3 stage is correct, otherwise bad things happen...
 void DSPExecP2(int32 cycles)
@@ -2948,8 +3040,33 @@ void DSPExecP2(int32 cycles)
 
        while (cycles > 0 && DSP_RUNNING)
        {
-if (dsp_pc == 0xF1B0A0)
+/*extern uint32 totalFrames;
+//F1B2F6: LOAD   (R14+$04), R24 [NCZ:001, R14+$04=00F20018, R24=FFFFFFFF] -> Jaguar: Unknown word read at 00F20018 by DSP (M68K PC=00E32E)
+//-> 43 + 1 + 24 -> $2B + $01 + $18 -> 101011 00001 11000 -> 1010 1100 0011 1000 -> AC38
+//C470 -> 1100 0100 0111 0000 -> 110001 00011 10000 -> 49, 3, 16 -> STORE R16, (R14+$0C)
+//F1B140:
+if (totalFrames >= 377 && GET16(dsp_ram_8, 0x0002F6) == 0xAC38 && dsp_pc == 0xF1B140)
+{
        doDSPDis = true;
+       WriteLog("Starting disassembly at frame #%u...\n", totalFrames);
+}
+if (dsp_pc == 0xF1B092)
+       doDSPDis = false;//*/
+/*if (totalFrames >= 373 && GET16(dsp_ram_8, 0x0002F6) == 0xAC38)
+       doDSPDis = true;//*/
+/*if (totalFrames >= 373 && dsp_pc == 0xF1B0A0)
+       doDSPDis = true;//*/
+/*if (dsp_pc == 0xF1B0A0)
+       doDSPDis = true;//*/
+/*if (dsp_pc == 0xF1B0D2) && dsp_reg[1] == 0x2140C)
+       doDSPDis = true;//*/
+//Two parter... (not sure how to write this)
+//if (dsp_pc == 0xF1B0D2)
+//     prevR1 = dsp_reg[1];
+
+//F1B0D2: ADDQT  #8, R01 [NCZ:000, R01=0002140C] -> [NCZ:000, R01=00021414]
+//F1B0D2: ADDQT  #8, R01 [NCZ:000, R01=0002140C] -> [NCZ:000, R01=00021414]
+
 
 pcQueue1[pcQPtr1++] = dsp_pc;
 pcQPtr1 &= 0x3FF;
@@ -3014,10 +3131,15 @@ WriteLog("\tW -> %02u, %02u, %02u; r1=%08X, r2= %08X, res=%08X, wb=%u (%s)\n", p
 //Small problem--when say LOAD or STORE (R14/5+$nn) is executed AFTER an instruction that
 //modifies R14/5, we don't check the scoreboard for R14/5 (and we need to!)... !!! FIX !!!
 //Ugly, but [DONE]
+//Another problem: Any sequential combination of LOAD and STORE operations will cause the
+//pipeline to stall, and we don't take care of that here. !!! FIX !!!
                if ((scoreboard[pipeline[plPtrRead].operand1] && readAffected[pipeline[plPtrRead].opcode][0])
                        || (scoreboard[pipeline[plPtrRead].operand2] && readAffected[pipeline[plPtrRead].opcode][1])
                        || ((pipeline[plPtrRead].opcode == 43 || pipeline[plPtrRead].opcode == 58) && scoreboard[14])
-                       || ((pipeline[plPtrRead].opcode == 44 || pipeline[plPtrRead].opcode == 59) && scoreboard[15]))
+                       || ((pipeline[plPtrRead].opcode == 44 || pipeline[plPtrRead].opcode == 59) && scoreboard[15])
+//Not sure that this is the best way to fix the LOAD/STORE problem... But it seems to
+//work--somewhat...
+                       || (isLoadStore[pipeline[plPtrRead].opcode] && isLoadStore[pipeline[plPtrExec].opcode]))
                        // We have a hit in the scoreboard, so we have to stall the pipeline...
 #ifdef DSP_DEBUG_PL2
 {
@@ -3043,7 +3165,12 @@ WriteLog("\n");
 
                        // Shouldn't we be more selective with the register scoreboarding?
                        // Yes, we should. !!! FIX !!! Kinda [DONE]
+#ifndef NEW_SCOREBOARD
                        scoreboard[pipeline[plPtrRead].operand2] = affectsScoreboard[pipeline[plPtrRead].opcode];
+#else
+//Hopefully this will fix the dual MOVEQ # problem...
+                       scoreboard[pipeline[plPtrRead].operand2] += (affectsScoreboard[pipeline[plPtrRead].opcode] ? 1 : 0);
+#endif
 
 //Advance PC here??? Yes.
                        dsp_pc += (pipeline[plPtrRead].opcode == 38 ? 6 : 2);
@@ -3061,6 +3188,8 @@ 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)
                {
+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)
 {
@@ -3082,6 +3211,11 @@ lastExec = pipeline[plPtrExec].instruction;
 //Let's not, until we do the stalling correctly...
 //But, we gotta while we're doing the comparison core...!
 //Or do we?                    cycles--;
+//Really, the whole thing is wrong. When the pipeline is correctly stuffed, most instructions
+//will execute in one clock cycle (others, like DIV, will likely not). So, the challenge is
+//to model this clock cycle behavior correctly...
+//Also, the pipeline stalls too much--mostly because the transparent writebacks at stage 3
+//don't affect the reads at stage 1...
 #ifdef DSP_DEBUG_STALL
 if (doDSPDis)
        WriteLog("[STALL... DSP_PC = %08X]\n", dsp_pc);
@@ -3123,8 +3257,15 @@ WriteLog("\n");
                                }
                        }
 
+#ifndef NEW_SCOREBOARD
                        if (affectsScoreboard[pipeline[plPtrWrite].opcode])
                                scoreboard[pipeline[plPtrWrite].operand2] = false;
+#else
+//Yup, sequential MOVEQ # problem fixing (I hope!)...
+                       if (affectsScoreboard[pipeline[plPtrWrite].opcode])
+                               if (scoreboard[pipeline[plPtrWrite].operand2])
+                                       scoreboard[pipeline[plPtrWrite].operand2]--;
+#endif
                }
 
                // Push instructions through the pipeline...
@@ -3415,7 +3556,7 @@ static void DSP_btst(void)
        NO_WRITEBACK;
 #ifdef DSP_DIS_BTST
        if (doDSPDis)
-               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
+               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRN);
 #endif
 }
 
@@ -3548,7 +3689,7 @@ char * condition[32] =
        "???", "???", "???", "F" };
        if (doDSPDis)
 //How come this is always off by 2???
-               WriteLog("%06X: JR     %s, %06X [NCZ:%u%u%u] ", DSP_PPC, condition[PIMM2], DSP_PPC+((PIMM1 & 0x10 ? 0xFFFFFFF0 | PIMM1 : PIMM1) * 2), dsp_flag_n, dsp_flag_c, dsp_flag_z);
+               WriteLog("%06X: JR     %s, %06X [NCZ:%u%u%u] ", DSP_PPC, condition[PIMM2], DSP_PPC+((PIMM1 & 0x10 ? 0xFFFFFFF0 | PIMM1 : PIMM1) * 2)+2, dsp_flag_n, dsp_flag_c, dsp_flag_z);
 #endif
        // KLUDGE: Used by BRANCH_CONDITION macro
        uint32 jaguar_flags = (dsp_flag_n << 2) | (dsp_flag_c << 1) | dsp_flag_z;
@@ -3594,8 +3735,15 @@ char * condition[32] =
                                }
                        }
 
+#ifndef NEW_SCOREBOARD
                        if (affectsScoreboard[pipeline[plPtrWrite].opcode])
                                scoreboard[pipeline[plPtrWrite].operand2] = false;
+#else
+//Yup, sequential MOVEQ # problem fixing (I hope!)...
+                       if (affectsScoreboard[pipeline[plPtrWrite].opcode])
+                               if (scoreboard[pipeline[plPtrWrite].operand2])
+                                       scoreboard[pipeline[plPtrWrite].operand2]--;
+#endif
                }
 
                // Step 2: Push instruction through pipeline & execute following instruction
@@ -3619,6 +3767,7 @@ char * condition[32] =
                        pipeline[plPtrExec].reg2 = dsp_reg[pipeline[plPtrExec].operand2];
                        pipeline[plPtrExec].writebackRegister = pipeline[plPtrExec].operand2;   // Set it to RN
                }//*/
+       dsp_pc += 2;    // For DSP_DIS_* accuracy
                DSPOpcode[pipeline[plPtrExec].opcode]();
                dsp_opcode_use[pipeline[plPtrExec].opcode]++;
                pipeline[plPtrWrite] = pipeline[plPtrExec];
@@ -3691,8 +3840,15 @@ char * condition[32] =
                                }
                        }
 
+#ifndef NEW_SCOREBOARD
                        if (affectsScoreboard[pipeline[plPtrWrite].opcode])
                                scoreboard[pipeline[plPtrWrite].operand2] = false;
+#else
+//Yup, sequential MOVEQ # problem fixing (I hope!)...
+                       if (affectsScoreboard[pipeline[plPtrWrite].opcode])
+                               if (scoreboard[pipeline[plPtrWrite].operand2])
+                                       scoreboard[pipeline[plPtrWrite].operand2]--;
+#endif
                }
 
                // Step 2: Push instruction through pipeline & execute following instruction
@@ -3717,6 +3873,7 @@ char * condition[32] =
                        pipeline[plPtrExec].reg2 = dsp_reg[pipeline[plPtrExec].operand2];
                        pipeline[plPtrExec].writebackRegister = pipeline[plPtrExec].operand2;   // Set it to RN
                }//*/
+       dsp_pc += 2;    // For DSP_DIS_* accuracy
                DSPOpcode[pipeline[plPtrExec].opcode]();
                dsp_opcode_use[pipeline[plPtrExec].opcode]++;
                pipeline[plPtrWrite] = pipeline[plPtrExec];
@@ -3929,10 +4086,18 @@ static void DSP_movei(void)
 
 static void DSP_movepc(void)
 {
+#ifdef DSP_DIS_MOVEPC
+       if (doDSPDis)
+               WriteLog("%06X: MOVE   PC, R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", DSP_PPC, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRN);
+#endif
 //Need to fix this to take into account pipelining effects... !!! FIX !!! [DONE]
 //     PRES = dsp_pc - 2;
 //Account for pipeline effects...
-       PRES = dsp_pc - (pipeline[plPtrRead].opcode == 38 ? 6 : (pipeline[plPtrRead].opcode == PIPELINE_STALL ? 0 : 2));
+       PRES = dsp_pc - 2 - (pipeline[plPtrRead].opcode == 38 ? 6 : (pipeline[plPtrRead].opcode == PIPELINE_STALL ? 0 : 2));
+#ifdef DSP_DIS_MOVEPC
+       if (doDSPDis)
+               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
+#endif
 }
 
 static void DSP_moveq(void)
@@ -4035,13 +4200,13 @@ static void DSP_not(void)
 {
 #ifdef DSP_DIS_NOT
        if (doDSPDis)
-               WriteLog("%06X: NOT    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);
+               WriteLog("%06X: NOT    R%02u [NCZ:%u%u%u, R%02u=%08X] -> ", DSP_PPC, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRN);
 #endif
        PRES = ~PRN;
        SET_ZN(PRES);
 #ifdef DSP_DIS_NOT
        if (doDSPDis)
-               WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM, PIMM2, PRES);
+               WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
 #endif
 }