X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdsp.cpp;h=8853f946ad519f4d7862d96c1a152c2bf5a2d6a0;hb=240a6df48aebb5e17f82452c32e770cdfe9b5d5e;hp=0218a7d92bbfa2db1f8f49bb58a9971cace38728;hpb=d1e404e2f488610a99f844783dca15a7525c3813;p=virtualjaguar diff --git a/src/dsp.cpp b/src/dsp.cpp index 0218a7d..8853f94 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -457,12 +457,14 @@ void dsp_reset_stats(void) dsp_opcode_use[i] = 0; } + void DSPReleaseTimeslice(void) { //This does absolutely nothing!!! !!! FIX !!! dsp_releaseTimeSlice_flag = 1; } + void dsp_build_branch_condition_table(void) { // Fill in the mirror table @@ -502,6 +504,7 @@ void dsp_build_branch_condition_table(void) } } + uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -522,22 +525,20 @@ uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { uint32_t data = DSPReadLong(offset & 0xFFFFFFFC, who); - if ((offset&0x03)==0) - return(data>>24); - else - if ((offset&0x03)==1) - return((data>>16)&0xff); - else - if ((offset&0x03)==2) - return((data>>8)&0xff); - else - if ((offset&0x03)==3) - return(data&0xff); + if ((offset & 0x03) == 0) + return (data >> 24); + else if ((offset & 0x03) == 1) + return ((data >> 16) & 0xFF); + else if ((offset & 0x03) == 2) + return ((data >> 8) & 0xFF); + else if ((offset & 0x03) == 3) + return (data & 0xFF); } return JaguarReadByte(offset, who); } + uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -565,6 +566,7 @@ uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadWord(offset, who); } + uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -609,12 +611,13 @@ uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadLong(offset, who); } + void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) WriteLog("DSP: WriteByte--Attempt to write to DSP register file by %s!\n", whoName[who]); - if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE + 0x2000)) { offset -= DSP_WORK_RAM_BASE; dsp_ram_8[offset] = data; @@ -626,7 +629,7 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) }*/ return; } - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { uint32_t reg = offset & 0x1C; int bytenum = offset & 0x03; @@ -645,9 +648,11 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) } // WriteLog("dsp: writing %.2x at 0x%.8x\n",data,offset); //Should this *ever* happen??? Shouldn't we be saying "unknown" here??? +// Well, yes, it can. There are 3 MMU users after all: 68K, GPU & DSP...! JaguarWriteByte(offset, data, who); } + void DSPWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -709,6 +714,7 @@ SET16(ram2, offset, data); JaguarWriteWord(offset, data, who); } + //bool badWrite = false; void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) { @@ -889,6 +895,7 @@ WriteLog("DSP: Modulo data %08X written by %s.\n", data, whoName[who]); JaguarWriteLong(offset, data, who); } + // // Update the DSP register file pointers depending on REGPAGE bit // @@ -909,6 +916,7 @@ void DSPUpdateRegisterBanks(void) #endif } + // // Check for and handle any asserted DSP IRQs // @@ -1054,6 +1062,7 @@ ctrl2[0] = regs2[30] = dsp_pc; FlushDSPPipeline(); } + // // Non-pipelined version... // @@ -1159,6 +1168,7 @@ ctrl1[0] = regs1[30] = dsp_pc; //!!!!!!!! } + // // Set the specified DSP IRQ line to a given state // @@ -1193,11 +1203,13 @@ DSPHandleIRQsNP(); // GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE); } + bool DSPIsRunning(void) { return (DSP_RUNNING ? true : false); } + void DSPInit(void) { // memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "DSP work RAM"); @@ -1208,6 +1220,7 @@ void DSPInit(void) DSPReset(); } + void DSPReset(void) { dsp_pc = 0x00F1B000; @@ -1238,6 +1251,7 @@ void DSPReset(void) *((uint32_t *)(&dsp_ram_8[i])) = rand(); } + void DSPDumpDisassembly(void) { char buffer[512]; @@ -1253,6 +1267,7 @@ void DSPDumpDisassembly(void) } } + void DSPDumpRegisters(void) { //Shoud add modulus, etc to dump here... @@ -1280,62 +1295,56 @@ void DSPDumpRegisters(void) } } + void DSPDone(void) { - int i, j; + WriteLog("\n\n---------------------------------------------------------------------\n"); + WriteLog("DSP I/O Registers\n"); + WriteLog("---------------------------------------------------------------------\n"); + WriteLog("F1%04X (D_FLAGS): $%06X\n", 0xA100, (dsp_flags & 0xFFFFFFF8) | (dsp_flag_n << 2) | (dsp_flag_c << 1) | dsp_flag_z); + WriteLog("F1%04X (D_MTXC): $%04X\n", 0xA104, dsp_matrix_control); + WriteLog("F1%04X (D_MTXA): $%04X\n", 0xA108, dsp_pointer_to_matrix); + WriteLog("F1%04X (D_END): $%02X\n", 0xA10C, dsp_data_organization); + WriteLog("F1%04X (D_PC): $%06X\n", 0xA110, dsp_pc); + WriteLog("F1%04X (D_CTRL): $%06X\n", 0xA114, dsp_control); + WriteLog("F1%04X (D_MOD): $%08X\n", 0xA118, dsp_modulo); + WriteLog("F1%04X (D_REMAIN): $%08X\n", 0xA11C, dsp_remain); + WriteLog("F1%04X (D_DIVCTRL): $%02X\n", 0xA11C, dsp_div_control); + WriteLog("F1%04X (D_MACHI): $%02X\n", 0xA120, (dsp_acc >> 32) & 0xFF); + WriteLog("---------------------------------------------------------------------\n\n\n"); + WriteLog("DSP: Stopped at PC=%08X dsp_modulo=%08X (dsp was%s running)\n", dsp_pc, dsp_modulo, (DSP_RUNNING ? "" : "n't")); WriteLog("DSP: %sin interrupt handler\n", (dsp_flags & IMASK ? "" : "not ")); - // get the active interrupt bits + // Get the active interrupt bits int bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F); - // get the interrupt mask + // Get the interrupt mask int mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F); WriteLog("DSP: pending=$%X enabled=$%X (%s%s%s%s%s%s)\n", bits, mask, (mask & 0x01 ? "CPU " : ""), (mask & 0x02 ? "I2S " : ""), (mask & 0x04 ? "Timer0 " : ""), (mask & 0x08 ? "Timer1 " : ""), (mask & 0x10 ? "Ext0 " : ""), (mask & 0x20 ? "Ext1" : "")); - WriteLog("\nRegisters bank 0\n"); - - 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]); - } - - WriteLog("\nRegisters bank 1\n"); - - for (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]); - } - + DSPDumpRegisters(); WriteLog("\n"); static char buffer[512]; - j = DSP_WORK_RAM_BASE; + int j = DSP_WORK_RAM_BASE; while (j <= 0xF1CFFF) { uint32_t oldj = j; j += dasmjag(JAGUAR_DSP, buffer, j); WriteLog("\t%08X: %s\n", oldj, buffer); - }//*/ + } WriteLog("DSP opcodes use:\n"); - for (i=0;i<64;i++) + for(int i=0; i<64; i++) { if (dsp_opcode_use[i]) WriteLog("\t%s %i\n", dsp_opcode_str[i], dsp_opcode_use[i]); - }//*/ + } } @@ -2455,29 +2464,6 @@ static void dsp_opcode_abs(void) static void dsp_opcode_div(void) { #if 0 - uint32_t _Rm=RM; - uint32_t _Rn=RN; - - if (_Rm) - { - if (dsp_div_control & 1) - { - dsp_remain = (((uint64_t)_Rn) << 16) % _Rm; - if (dsp_remain&0x80000000) - dsp_remain-=_Rm; - RN = (((uint64_t)_Rn) << 16) / _Rm; - } - else - { - dsp_remain = _Rn % _Rm; - if (dsp_remain&0x80000000) - dsp_remain-=_Rm; - RN/=_Rm; - } - } - else - RN=0xffffffff; -#else if (RM) { if (dsp_div_control & 0x01) // 16.16 division @@ -2493,15 +2479,34 @@ static void dsp_opcode_div(void) RN = RN / RM; } -// What we really should do here is figure out why this condition -// happens in the real divide unit and emulate *that* behavior. -#if 0 - if ((gpu_remain - RM) & 0x80000000) // If the result would have been negative... - gpu_remain -= RM; // Then make it negative! -#endif } else + { + // This is what happens according to SCPCD. NYAN! RN = 0xFFFFFFFF; + dsp_remain = 0; + } +#else + // Real algorithm, courtesy of SCPCD: NYAN! + uint32_t q = RN; + uint32_t r = 0; + + // If 16.16 division, stuff top 16 bits of RN into remainder and put the + // bottom 16 of RN in top 16 of quotient + if (dsp_div_control & 0x01) + q <<= 16, r = RN >> 16; + + for(int i=0; i<32; i++) + { +// uint32_t sign = (r >> 31) & 0x01; + uint32_t sign = r & 0x80000000; + r = (r << 1) | ((q >> 31) & 0x01); + r += (sign ? RM : -RM); + q = (q << 1) | (((~r) >> 31) & 0x01); + } + + RN = q; + dsp_remain = r; #endif }