+
+
+//
+// DSP comparison core...
+//
+#ifdef DSP_DEBUG_CC
+static uint16 lastExec;
+void DSPExecComp(int32 cycles)
+{
+ while (cycles > 0 && DSP_RUNNING)
+ {
+ // Load up vars for non-pipelined core
+ memcpy(dsp_ram_8, ram1, 0x2000);
+ memcpy(dsp_reg_bank_0, regs1, 32 * 4);
+ memcpy(dsp_reg_bank_1, ®s1[32], 32 * 4);
+ dsp_pc = ctrl1[0];
+ dsp_acc = ctrl1[1];
+ dsp_remain = ctrl1[2];
+ dsp_modulo = ctrl1[3];
+ dsp_flags = ctrl1[4];
+ dsp_matrix_control = ctrl1[5];
+ dsp_pointer_to_matrix = ctrl1[6];
+ dsp_data_organization = ctrl1[7];
+ dsp_control = ctrl1[8];
+ dsp_div_control = ctrl1[9];
+ IMASKCleared = ctrl1[10];
+ dsp_flag_z = ctrl1[11];
+ dsp_flag_n = ctrl1[12];
+ dsp_flag_c = ctrl1[13];
+DSPUpdateRegisterBanks();
+
+ // Decrement cycles based on non-pipelined core...
+ uint16 instr1 = DSPReadWord(dsp_pc, DSP);
+ cycles -= dsp_opcode_cycles[instr1 >> 10];
+
+//WriteLog("\tAbout to execute non-pipelined core on tick #%u (DSP_PC=%08X)...\n", (uint32)count, dsp_pc);
+ DSPExec(1); // Do *one* instruction
+
+ // Save vars
+ memcpy(ram1, dsp_ram_8, 0x2000);
+ memcpy(regs1, dsp_reg_bank_0, 32 * 4);
+ memcpy(®s1[32], dsp_reg_bank_1, 32 * 4);
+ ctrl1[0] = dsp_pc;
+ ctrl1[1] = dsp_acc;
+ ctrl1[2] = dsp_remain;
+ ctrl1[3] = dsp_modulo;
+ ctrl1[4] = dsp_flags;
+ ctrl1[5] = dsp_matrix_control;
+ ctrl1[6] = dsp_pointer_to_matrix;
+ ctrl1[7] = dsp_data_organization;
+ ctrl1[8] = dsp_control;
+ ctrl1[9] = dsp_div_control;
+ ctrl1[10] = IMASKCleared;
+ ctrl1[11] = dsp_flag_z;
+ ctrl1[12] = dsp_flag_n;
+ ctrl1[13] = dsp_flag_c;
+
+ // Load up vars for pipelined core
+ memcpy(dsp_ram_8, ram2, 0x2000);
+ memcpy(dsp_reg_bank_0, regs2, 32 * 4);
+ memcpy(dsp_reg_bank_1, ®s2[32], 32 * 4);
+ dsp_pc = ctrl2[0];
+ dsp_acc = ctrl2[1];
+ dsp_remain = ctrl2[2];
+ dsp_modulo = ctrl2[3];
+ dsp_flags = ctrl2[4];
+ dsp_matrix_control = ctrl2[5];
+ dsp_pointer_to_matrix = ctrl2[6];
+ dsp_data_organization = ctrl2[7];
+ dsp_control = ctrl2[8];
+ dsp_div_control = ctrl2[9];
+ IMASKCleared = ctrl2[10];
+ dsp_flag_z = ctrl2[11];
+ dsp_flag_n = ctrl2[12];
+ dsp_flag_c = ctrl2[13];
+DSPUpdateRegisterBanks();
+
+//WriteLog("\tAbout to execute pipelined core on tick #%u (DSP_PC=%08X)...\n", (uint32)count, dsp_pc);
+ DSPExecP2(1); // Do *one* instruction
+
+ // Save vars
+ memcpy(ram2, dsp_ram_8, 0x2000);
+ memcpy(regs2, dsp_reg_bank_0, 32 * 4);
+ memcpy(®s2[32], dsp_reg_bank_1, 32 * 4);
+ ctrl2[0] = dsp_pc;
+ ctrl2[1] = dsp_acc;
+ ctrl2[2] = dsp_remain;
+ ctrl2[3] = dsp_modulo;
+ ctrl2[4] = dsp_flags;
+ ctrl2[5] = dsp_matrix_control;
+ ctrl2[6] = dsp_pointer_to_matrix;
+ ctrl2[7] = dsp_data_organization;
+ ctrl2[8] = dsp_control;
+ ctrl2[9] = dsp_div_control;
+ ctrl2[10] = IMASKCleared;
+ ctrl2[11] = dsp_flag_z;
+ ctrl2[12] = dsp_flag_n;
+ ctrl2[13] = dsp_flag_c;
+
+ if (instr1 != lastExec)
+ {
+// WriteLog("\nCores diverged at instruction tick #%u!\nAttemping to synchronize...\n\n", count);
+
+// uint32 ppc = ctrl2[0] - (pipeline[plPtrExec].opcode == 38 ? 6 : (pipeline[plPtrExec].opcode == PIPELINE_STALL ? 0 : 2)) - (pipeline[plPtrWrite].opcode == 38 ? 6 : (pipeline[plPtrWrite].opcode == PIPELINE_STALL ? 0 : 2));
+//WriteLog("[DSP_PC1=%08X, DSP_PC2=%08X]\n", ctrl1[0], ppc);
+// if (ctrl1[0] < ppc) // P ran ahead of NP
+//How to test this crap???
+// if (1)
+ {
+ DSPExecP2(1); // Do one more instruction
+
+ // Save vars
+ memcpy(ram2, dsp_ram_8, 0x2000);
+ memcpy(regs2, dsp_reg_bank_0, 32 * 4);
+ memcpy(®s2[32], dsp_reg_bank_1, 32 * 4);
+ ctrl2[0] = dsp_pc;
+ ctrl2[1] = dsp_acc;
+ ctrl2[2] = dsp_remain;
+ ctrl2[3] = dsp_modulo;
+ ctrl2[4] = dsp_flags;
+ ctrl2[5] = dsp_matrix_control;
+ ctrl2[6] = dsp_pointer_to_matrix;
+ ctrl2[7] = dsp_data_organization;
+ ctrl2[8] = dsp_control;
+ ctrl2[9] = dsp_div_control;
+ ctrl2[10] = IMASKCleared;
+ ctrl2[11] = dsp_flag_z;
+ ctrl2[12] = dsp_flag_n;
+ ctrl2[13] = dsp_flag_c;
+ }
+// else // NP ran ahead of P
+ if (instr1 != lastExec) // Must be the other way...
+
+ {
+ // Load up vars for non-pipelined core
+ memcpy(dsp_ram_8, ram1, 0x2000);
+ memcpy(dsp_reg_bank_0, regs1, 32 * 4);
+ memcpy(dsp_reg_bank_1, ®s1[32], 32 * 4);
+ dsp_pc = ctrl1[0];
+ dsp_acc = ctrl1[1];
+ dsp_remain = ctrl1[2];
+ dsp_modulo = ctrl1[3];
+ dsp_flags = ctrl1[4];
+ dsp_matrix_control = ctrl1[5];
+ dsp_pointer_to_matrix = ctrl1[6];
+ dsp_data_organization = ctrl1[7];
+ dsp_control = ctrl1[8];
+ dsp_div_control = ctrl1[9];
+ IMASKCleared = ctrl1[10];
+ dsp_flag_z = ctrl1[11];
+ dsp_flag_n = ctrl1[12];
+ dsp_flag_c = ctrl1[13];
+DSPUpdateRegisterBanks();
+
+for(int k=0; k<2; k++)
+{
+ // Decrement cycles based on non-pipelined core...
+ instr1 = DSPReadWord(dsp_pc, DSP);
+ cycles -= dsp_opcode_cycles[instr1 >> 10];
+
+//WriteLog("\tAbout to execute non-pipelined core on tick #%u (DSP_PC=%08X)...\n", (uint32)count, dsp_pc);
+ DSPExec(1); // Do *one* instruction
+}
+
+ // Save vars
+ memcpy(ram1, dsp_ram_8, 0x2000);
+ memcpy(regs1, dsp_reg_bank_0, 32 * 4);
+ memcpy(®s1[32], dsp_reg_bank_1, 32 * 4);
+ ctrl1[0] = dsp_pc;
+ ctrl1[1] = dsp_acc;
+ ctrl1[2] = dsp_remain;
+ ctrl1[3] = dsp_modulo;
+ ctrl1[4] = dsp_flags;
+ ctrl1[5] = dsp_matrix_control;
+ ctrl1[6] = dsp_pointer_to_matrix;
+ ctrl1[7] = dsp_data_organization;
+ ctrl1[8] = dsp_control;
+ ctrl1[9] = dsp_div_control;
+ ctrl1[10] = IMASKCleared;
+ ctrl1[11] = dsp_flag_z;
+ ctrl1[12] = dsp_flag_n;
+ ctrl1[13] = dsp_flag_c;
+ }
+ }
+
+ if (instr1 != lastExec)
+ {
+ WriteLog("\nCores diverged at instruction tick #%u!\nStopped!\n\n", count);
+
+ WriteLog("Instruction for non-pipelined core: %04X\n", instr1);
+ WriteLog("Instruction for pipelined core: %04X\n", lastExec);
+
+ log_done();
+ exit(1);
+ }
+
+ count++;
+ }
+}
+#endif
+
+