@@ -233,6 +233,29 @@ void (* dsp_opcode[64])() =
233233 dsp_opcode_store_r14_ri , dsp_opcode_store_r15_ri , dsp_opcode_illegal , dsp_opcode_addqmod ,
234234};
235235
236+ uint32_t dsp_opcode_use [65 ];
237+
238+ const char * dsp_opcode_str [65 ]=
239+ {
240+ "add" , "addc" , "addq" , "addqt" ,
241+ "sub" , "subc" , "subq" , "subqt" ,
242+ "neg" , "and" , "or" , "xor" ,
243+ "not" , "btst" , "bset" , "bclr" ,
244+ "mult" , "imult" , "imultn" , "resmac" ,
245+ "imacn" , "div" , "abs" , "sh" ,
246+ "shlq" , "shrq" , "sha" , "sharq" ,
247+ "ror" , "rorq" , "cmp" , "cmpq" ,
248+ "subqmod" , "sat16s" , "move" , "moveq" ,
249+ "moveta" , "movefa" , "movei" , "loadb" ,
250+ "loadw" , "load" , "sat32s" , "load_r14_indexed" ,
251+ "load_r15_indexed" , "storeb" , "storew" , "store" ,
252+ "mirror" , "store_r14_indexed" ,"store_r15_indexed" ,"move_pc" ,
253+ "jump" , "jr" , "mmult" , "mtoi" ,
254+ "normi" , "nop" , "load_r14_ri" , "load_r15_ri" ,
255+ "store_r14_ri" , "store_r15_ri" , "illegal" , "addqmod" ,
256+ "STALL"
257+ };
258+
236259uint32_t dsp_pc ;
237260static uint64_t dsp_acc ; // 40 bit register, NOT 32!
238261static uint32_t dsp_remain ;
@@ -241,17 +264,16 @@ static uint32_t dsp_flags;
241264static uint32_t dsp_matrix_control ;
242265static uint32_t dsp_pointer_to_matrix ;
243266static uint32_t dsp_data_organization ;
244-
245- Bits32 dsp_control ;
267+ uint32_t dsp_control ;
246268static uint32_t dsp_div_control ;
247269static uint8_t dsp_flag_z , dsp_flag_n , dsp_flag_c ;
248270static uint32_t * dsp_reg = NULL , * dsp_alternate_reg = NULL ;
249271uint32_t dsp_reg_bank_0 [32 ], dsp_reg_bank_1 [32 ];
250272
251- static uint8_t dsp_opcode_first_parameter ;
252- static uint8_t dsp_opcode_second_parameter ;
273+ static uint32_t dsp_opcode_first_parameter ;
274+ static uint32_t dsp_opcode_second_parameter ;
253275
254- #define DSP_RUNNING (dsp_control.bits.b0 )
276+ #define DSP_RUNNING (dsp_control & 0x01 )
255277
256278#define RM dsp_reg[dsp_opcode_first_parameter]
257279#define RN dsp_reg[dsp_opcode_second_parameter]
@@ -282,10 +304,26 @@ static uint8_t dsp_ram_8[0x2000];
282304
283305#define BRANCH_CONDITION (x ) dsp_branch_condition_table[(x) + ((jaguar_flags & 7) << 5)]
284306
307+ static uint32_t dsp_in_exec = 0 ;
308+ static uint32_t dsp_releaseTimeSlice_flag = 0 ;
309+
285310// Private function prototypes
286311
287312void FlushDSPPipeline (void );
288313
314+
315+ void dsp_reset_stats (void )
316+ {
317+ unsigned i ;
318+ for (i = 0 ; i < 65 ; i ++ )
319+ dsp_opcode_use [i ] = 0 ;
320+ }
321+
322+ void DSPReleaseTimeslice (void )
323+ {
324+ dsp_releaseTimeSlice_flag = 1 ;
325+ }
326+
289327void dsp_build_branch_condition_table (void )
290328{
291329 unsigned i , j ;
@@ -355,24 +393,20 @@ uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/)
355393
356394uint16_t DSPReadWord (uint32_t offset , uint32_t who /*=UNKNOWN*/ )
357395{
358- Offset offsett ;
359- offsett .LONG = offset ;
360- offset = offsett .Members .offset ;
396+ offset &= 0xFFFFFFFE ;
397+
361398 if (offset >= DSP_WORK_RAM_BASE && offset <= DSP_WORK_RAM_BASE + 0x1FFF )
362399 {
363400 offset -= DSP_WORK_RAM_BASE ;
364- return GET16 (dsp_ram_8 , offset );
365- }
401+ return GET16 (dsp_ram_8 , offset );
402+ }
366403 else if ((offset >=DSP_CONTROL_RAM_BASE )&& (offset < DSP_CONTROL_RAM_BASE + 0x20 ))
367404 {
368- DSPLong data ;
369- data .LONG = DSPReadLong (offset & 0xFFFFFFFC , who );
370-
371- if (offset & 0x03 ) {
372- return data .Data .LWORD ;
373- } else {
374- return data .Data .UWORD ;
375- }
405+ uint32_t data = DSPReadLong (offset & 0xFFFFFFFC , who );
406+
407+ if (offset & 0x03 )
408+ return data & 0xFFFF ;
409+ return data >> 16 ;
376410 }
377411
378412 return JaguarReadWord (offset , who );
@@ -404,7 +438,7 @@ uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/)
404438 case 0x10 :
405439 return dsp_pc ;
406440 case 0x14 :
407- return dsp_control . WORD ;
441+ return dsp_control ;
408442 case 0x18 :
409443 return dsp_modulo ;
410444 case 0x1C :
@@ -513,8 +547,8 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
513547 dsp_flag_c = (dsp_flags >> 1 ) & 0x01 ;
514548 dsp_flag_n = (dsp_flags >> 2 ) & 0x01 ;
515549 DSPUpdateRegisterBanks ();
516- dsp_control . WORD &= ~((dsp_flags & CINT04FLAGS ) >> 3 );
517- dsp_control . WORD &= ~((dsp_flags & CINT5FLAG ) >> 1 );
550+ dsp_control &= ~((dsp_flags & CINT04FLAGS ) >> 3 );
551+ dsp_control &= ~((dsp_flags & CINT5FLAG ) >> 1 );
518552 break ;
519553 }
520554 case 0x04 :
@@ -543,6 +577,7 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
543577 if (JERRYIRQEnabled (IRQ2_DSP ))
544578 {
545579 JERRYSetPendingIRQ (IRQ2_DSP );
580+ DSPReleaseTimeslice ();
546581 m68k_set_irq (2 ); // Set 68000 IPL 2...
547582 }
548583 data &= ~CPUINT ;
@@ -551,12 +586,13 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
551586 if (data & DSPINT0 )
552587 {
553588 m68k_end_timeslice ();
589+ DSPReleaseTimeslice ();
554590 DSPSetIRQLine (DSPIRQ_CPU , ASSERT_LINE );
555591 data &= ~DSPINT0 ;
556592 }
557593 // Protect writes to VERSION and the interrupt latches...
558594 mask = VERSION | INT_LAT0 | INT_LAT1 | INT_LAT2 | INT_LAT3 | INT_LAT4 | INT_LAT5 ;
559- dsp_control . WORD = (dsp_control . WORD & mask ) | (data & ~mask );
595+ dsp_control = (dsp_control & mask ) | (data & ~mask );
560596 //CC only!
561597 //!!!!!!!!
562598
@@ -566,6 +602,8 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
566602 {
567603 if (who == M68K )
568604 m68k_end_timeslice ();
605+ else if (who == DSP )
606+ DSPReleaseTimeslice ();
569607
570608 if (!wasRunning )
571609 FlushDSPPipeline ();
@@ -608,7 +646,7 @@ void DSPHandleIRQs(void)
608646 return ;
609647
610648 // Get the active interrupt bits (latches) & interrupt mask (enables)
611- bits = ((dsp_control . WORD >> 10 ) & 0x20 ) | ((dsp_control . WORD >> 6 ) & 0x1F );
649+ bits = ((dsp_control >> 10 ) & 0x20 ) | ((dsp_control >> 6 ) & 0x1F );
612650 mask = ((dsp_flags >> 11 ) & 0x20 ) | ((dsp_flags >> 4 ) & 0x1F );
613651
614652 bits &= mask ;
@@ -695,7 +733,7 @@ void DSPHandleIRQsNP(void)
695733 return ;
696734
697735 // Get the active interrupt bits (latches) & interrupt mask (enables)
698- bits = ((dsp_control . WORD >> 10 ) & 0x20 ) | ((dsp_control . WORD >> 6 ) & 0x1F );
736+ bits = ((dsp_control >> 10 ) & 0x20 ) | ((dsp_control >> 6 ) & 0x1F );
699737 mask = ((dsp_flags >> 11 ) & 0x20 ) | ((dsp_flags >> 4 ) & 0x1F );
700738
701739 bits &= mask ;
@@ -735,11 +773,11 @@ void DSPSetIRQLine(int irqline, int state)
735773{
736774//NOTE: This doesn't take INT_LAT5 into account. !!! FIX !!!
737775 uint32_t mask = INT_LAT0 << irqline ;
738- dsp_control . WORD &= ~mask ; // Clear the latch bit
776+ dsp_control &= ~mask ; // Clear the latch bit
739777
740778 if (state )
741779 {
742- dsp_control . WORD |= mask ; // Set the latch bit
780+ dsp_control |= mask ; // Set the latch bit
743781 DSPHandleIRQsNP ();
744782 }
745783}
@@ -767,8 +805,9 @@ void DSPReset(void)
767805 dsp_matrix_control = 0x00000000 ;
768806 dsp_pointer_to_matrix = 0x00000000 ;
769807 dsp_data_organization = 0xFFFFFFFF ;
770- dsp_control . WORD = 0x00002000 ; // Report DSP version 2
808+ dsp_control = 0x00002000 ; // Report DSP version 2
771809 dsp_div_control = 0x00000000 ;
810+ dsp_in_exec = 0 ;
772811
773812 dsp_reg = dsp_reg_bank_0 ;
774813 dsp_alternate_reg = dsp_reg_bank_1 ;
@@ -779,6 +818,7 @@ void DSPReset(void)
779818 CLR_ZNC ;
780819 IMASKCleared = false;
781820 FlushDSPPipeline ();
821+ dsp_reset_stats ();
782822
783823 // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
784824 for (i = 0 ; i < 8192 ; i += 4 )
@@ -800,27 +840,31 @@ INLINE void DSPExec(int32_t cycles)
800840 dsp_control &= ~0x10 ;
801841 }
802842#endif
843+ dsp_releaseTimeSlice_flag = 0 ;
844+ dsp_in_exec ++ ;
803845
804846 while (cycles > 0 && DSP_RUNNING )
805847 {
848+ uint16_t opcode ;
849+ uint32_t index ;
850+
806851 if (IMASKCleared ) // If IMASK was cleared,
807852 {
808853 DSPHandleIRQsNP (); // See if any other interrupts are pending!
809854 IMASKCleared = false;
810855 }
811856
812- OpCode opcode ;
813- opcode .WORD = DSPReadWord (dsp_pc , DSP );
814- uint8_t index = opcode .Codes .index ;
815- uint8_t fp = opcode .Codes .first ;
816- uint8_t sp = opcode .Codes .second ;
817- dsp_opcode_first_parameter = fp ;
818- dsp_opcode_second_parameter = sp ;
819- dsp_pc += 2 ;
820- dsp_opcode [index ]();
821-
822- cycles -= dsp_opcode_cycles [index ];
857+ opcode = DSPReadWord (dsp_pc , DSP );
858+ index = opcode >> 10 ;
859+ dsp_opcode_first_parameter = (opcode >> 5 ) & 0x1F ;
860+ dsp_opcode_second_parameter = opcode & 0x1F ;
861+ dsp_pc += 2 ;
862+ dsp_opcode [index ]();
863+ dsp_opcode_use [index ]++ ;
864+ cycles -= dsp_opcode_cycles [index ];
823865 }
866+
867+ dsp_in_exec -- ;
824868}
825869
826870// DSP opcode handlers
@@ -1640,10 +1684,8 @@ void FlushDSPPipeline(void)
16401684
16411685 plPtrFetch = 3 , plPtrRead = 2 , plPtrExec = 1 , plPtrWrite = 0 ;
16421686
1643- pipeline [0 ].opcode = PIPELINE_STALL ;
1644- pipeline [1 ].opcode = PIPELINE_STALL ;
1645- pipeline [2 ].opcode = PIPELINE_STALL ;
1646- pipeline [3 ].opcode = PIPELINE_STALL ;
1687+ for (i = 0 ; i < 4 ; i ++ )
1688+ pipeline [i ].opcode = PIPELINE_STALL ;
16471689
16481690 for (i = 0 ; i < 32 ; i ++ )
16491691 scoreboard [i ] = 0 ;
@@ -1883,6 +1925,7 @@ INLINE static void DSP_jr(void)
18831925 }//*/
18841926 dsp_pc += 2 ; // For DSP_DIS_* accuracy
18851927 DSPOpcode [pipeline [plPtrExec ].opcode ]();
1928+ dsp_opcode_use [pipeline [plPtrExec ].opcode ]++ ;
18861929 pipeline [plPtrWrite ] = pipeline [plPtrExec ];
18871930
18881931 // Step 3: Flush pipeline & set new PC
@@ -1956,8 +1999,9 @@ INLINE static void DSP_jump(void)
19561999 pipeline [plPtrExec ].reg2 = dsp_reg [pipeline [plPtrExec ].operand2 ];
19572000 pipeline [plPtrExec ].writebackRegister = pipeline [plPtrExec ].operand2 ; // Set it to RN
19582001 }
1959- dsp_pc += 2 ; // For DSP_DIS_* accuracy
2002+ dsp_pc += 2 ; // For DSP_DIS_* accuracy
19602003 DSPOpcode [pipeline [plPtrExec ].opcode ]();
2004+ dsp_opcode_use [pipeline [plPtrExec ].opcode ]++ ;
19612005 pipeline [plPtrWrite ] = pipeline [plPtrExec ];
19622006
19632007 // Step 3: Flush pipeline & set new PC
@@ -2056,7 +2100,7 @@ INLINE static void DSP_mmult(void)
20562100 for (i = 0 ; i < count ; i ++ )
20572101 {
20582102 int16_t a ;
2059- int16_t b ;
2103+ int16_t b ;
20602104
20612105 if (i & 0x01 )
20622106 a = (int16_t )((dsp_alternate_reg [dsp_opcode_first_parameter + (i >>1 )]>>16 )& 0xffff );
@@ -2072,7 +2116,7 @@ INLINE static void DSP_mmult(void)
20722116 for (i = 0 ; i < count ; i ++ )
20732117 {
20742118 int16_t a ;
2075- int16_t b ;
2119+ int16_t b ;
20762120
20772121 if (i & 0x01 )
20782122 a = (int16_t )((dsp_alternate_reg [dsp_opcode_first_parameter + (i >>1 )]>>16 )& 0xffff );
@@ -2086,7 +2130,7 @@ INLINE static void DSP_mmult(void)
20862130
20872131 PRES = res = (int32_t )accum ;
20882132 // carry flag to do
2089- //NOTE: The flags are set based upon the last add/multiply done...
2133+ //NOTE: The flags are set based upon the last add/multiply done...
20902134 SET_ZN (PRES );
20912135}
20922136
@@ -2107,8 +2151,8 @@ INLINE static void DSP_movei(void)
21072151
21082152INLINE static void DSP_movepc (void )
21092153{
2110- //Need to fix this to take into account pipelining effects... !!! FIX !!! [DONE]
2111- //Account for pipeline effects...
2154+ //Need to fix this to take into account pipelining effects... !!! FIX !!! [DONE]
2155+ //Account for pipeline effects...
21122156 PRES = dsp_pc - 2 - (pipeline [plPtrRead ].opcode == 38 ? 6 : (pipeline [plPtrRead ].opcode == PIPELINE_STALL ? 0 : 2 ));
21132157}
21142158
0 commit comments