]> Shamusworld >> Repos - virtualjaguar/blob - src/dsp.cpp
99cc887c7ffd02de4c5fb44db457d3d723bbd586
[virtualjaguar] / src / dsp.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 //////////////////////////////////////////////////////////////////////////////
4 //
5 //
6 //
7 //
8 //
9 //
10 //////////////////////////////////////////////////////////////////////////////
11
12 #include "include/dsp.h"
13
14 #define CINT0FLAG                       0x00200
15 #define CINT1FLAG                       0x00400
16 #define CINT2FLAG                       0x00800
17 #define CINT3FLAG                       0x01000
18 #define CINT4FLAG                       0x02000
19 #define CINT04FLAGS                     (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG)
20 #define CINT5FLAG                       0x20000         /* DSP only */
21
22 extern uint32 jaguar_mainRom_crc32;
23
24 static void dsp_opcode_addqmod(void);   
25 static void dsp_opcode_subqmod(void);   
26 static void dsp_opcode_mirror(void);    
27 static void dsp_opcode_sat32s(void);    
28 static void dsp_opcode_sat16s(void);    
29 static void dsp_opcode_add(void);
30 static void dsp_opcode_addc(void);
31 static void dsp_opcode_addq(void);
32 static void dsp_opcode_addqt(void);
33 static void dsp_opcode_sub(void);
34 static void dsp_opcode_subc(void);
35 static void dsp_opcode_subq(void);
36 static void dsp_opcode_subqt(void);
37 static void dsp_opcode_neg(void);
38 static void dsp_opcode_and(void);
39 static void dsp_opcode_or(void);
40 static void dsp_opcode_xor(void);
41 static void dsp_opcode_not(void);
42 static void dsp_opcode_btst(void);
43 static void dsp_opcode_bset(void);
44 static void dsp_opcode_bclr(void);
45 static void dsp_opcode_mult(void);
46 static void dsp_opcode_imult(void);
47 static void dsp_opcode_imultn(void);
48 static void dsp_opcode_resmac(void);
49 static void dsp_opcode_imacn(void);
50 static void dsp_opcode_div(void);
51 static void dsp_opcode_abs(void);
52 static void dsp_opcode_sh(void);
53 static void dsp_opcode_shlq(void);
54 static void dsp_opcode_shrq(void);
55 static void dsp_opcode_sha(void);
56 static void dsp_opcode_sharq(void);
57 static void dsp_opcode_ror(void);
58 static void dsp_opcode_rorq(void);
59 static void dsp_opcode_cmp(void);
60 static void dsp_opcode_cmpq(void);
61 static void dsp_opcode_sat8(void);
62 static void dsp_opcode_sat16(void);
63 static void dsp_opcode_move(void);
64 static void dsp_opcode_moveq(void);
65 static void dsp_opcode_moveta(void);
66 static void dsp_opcode_movefa(void);
67 static void dsp_opcode_movei(void);
68 static void dsp_opcode_loadb(void);
69 static void dsp_opcode_loadw(void);
70 static void dsp_opcode_load(void);
71 static void dsp_opcode_loadp(void);
72 static void dsp_opcode_load_r14_indexed(void);
73 static void dsp_opcode_load_r15_indexed(void);
74 static void dsp_opcode_storeb(void);
75 static void dsp_opcode_storew(void);
76 static void dsp_opcode_store(void);
77 static void dsp_opcode_storep(void);
78 static void dsp_opcode_store_r14_indexed(void);
79 static void dsp_opcode_store_r15_indexed(void);
80 static void dsp_opcode_move_pc(void);
81 static void dsp_opcode_jump(void);
82 static void dsp_opcode_jr(void);
83 static void dsp_opcode_mmult(void);
84 static void dsp_opcode_mtoi(void);
85 static void dsp_opcode_normi(void);
86 static void dsp_opcode_nop(void);
87 static void dsp_opcode_load_r14_ri(void);
88 static void dsp_opcode_load_r15_ri(void);
89 static void dsp_opcode_store_r14_ri(void);
90 static void dsp_opcode_store_r15_ri(void);
91 static void dsp_opcode_sat24(void);
92
93 uint8 dsp_opcode_cycles[64] = 
94 {
95         3,  3,  3,  3,  
96         3,  3,  3,  3,  
97         3,  3,  3,  3,  
98         3,  3,  3,  3,
99         3,  3,  1,  3,  
100         1, 18,  3,  3,  
101         3,  3,  3,  3,  
102         3,  3,  3,  3,
103         3,  3,  2,  2,  
104         2,  2,  3,  4,  
105         5,  4,  5,  6,  
106         6,  1,  1,  1,
107         1,  2,  2,  2,  
108         1,  1,  9,  3,  
109         3,  1,  6,  6,  
110         2,  2,  3,  3
111 };
112
113 void (*dsp_opcode[64])()= 
114 {       
115         dsp_opcode_add,                                 dsp_opcode_addc,                                dsp_opcode_addq,                                dsp_opcode_addqt,
116         dsp_opcode_sub,                                 dsp_opcode_subc,                                dsp_opcode_subq,                                dsp_opcode_subqt,
117         dsp_opcode_neg,                                 dsp_opcode_and,                                 dsp_opcode_or,                                  dsp_opcode_xor,
118         dsp_opcode_not,                                 dsp_opcode_btst,                                dsp_opcode_bset,                                dsp_opcode_bclr,
119         dsp_opcode_mult,                                dsp_opcode_imult,                               dsp_opcode_imultn,                              dsp_opcode_resmac,
120         dsp_opcode_imacn,                               dsp_opcode_div,                                 dsp_opcode_abs,                                 dsp_opcode_sh,
121         dsp_opcode_shlq,                                dsp_opcode_shrq,                                dsp_opcode_sha,                                 dsp_opcode_sharq,
122         dsp_opcode_ror,                                 dsp_opcode_rorq,                                dsp_opcode_cmp,                                 dsp_opcode_cmpq,
123         dsp_opcode_subqmod,                             dsp_opcode_sat16s,                              dsp_opcode_move,                                dsp_opcode_moveq,
124         dsp_opcode_moveta,                              dsp_opcode_movefa,                              dsp_opcode_movei,                               dsp_opcode_loadb,
125         dsp_opcode_loadw,                               dsp_opcode_load,                                dsp_opcode_sat32s,                              dsp_opcode_load_r14_indexed,
126         dsp_opcode_load_r15_indexed,    dsp_opcode_storeb,                              dsp_opcode_storew,                              dsp_opcode_store,
127         dsp_opcode_mirror,                              dsp_opcode_store_r14_indexed,   dsp_opcode_store_r15_indexed,   dsp_opcode_move_pc,
128         dsp_opcode_jump,                                dsp_opcode_jr,                                  dsp_opcode_mmult,                               dsp_opcode_mtoi,
129         dsp_opcode_normi,                               dsp_opcode_nop,                                 dsp_opcode_load_r14_ri,                 dsp_opcode_load_r15_ri,
130         dsp_opcode_store_r14_ri,                dsp_opcode_store_r15_ri,                dsp_opcode_nop,                                 dsp_opcode_addqmod,
131 };
132
133 uint32 dsp_opcode_use[64];
134
135 char *dsp_opcode_str[64]= 
136 {       
137         "add",                          "addc",                         "addq",                         "addqt",
138         "sub",                          "subc",                         "subq",                         "subqt",
139         "neg",                          "and",                          "or",                           "xor",
140         "not",                          "btst",                         "bset",                         "bclr",
141         "mult",                         "imult",                        "imultn",                       "resmac",
142         "imacn",                        "div",                          "abs",                          "sh",
143         "shlq",                         "shrq",                         "sha",                          "sharq",
144         "ror",                          "rorq",                         "cmp",                          "cmpq",
145         "subqmod",                      "sat16s",                       "move",                         "moveq",
146         "moveta",                       "movefa",                       "movei",                        "loadb",
147         "loadw",                        "load",                         "sat32s",                       "load_r14_indexed",
148         "load_r15_indexed",     "storeb",                       "storew",                       "store",
149         "mirror",                       "store_r14_indexed","store_r15_indexed","move_pc",
150         "jump",                         "jr",                           "mmult",                        "mtoi",
151         "normi",                        "nop",                          "load_r14_ri",          "load_r15_ri",
152         "store_r14_ri",         "store_r15_ri",         "nop",                          "addqmod",
153 };
154
155 static uint16   *mirror_table;
156 static uint8    *dsp_ram_8;
157
158
159 static uint32   dsp_pc;
160 static uint32   dsp_acc;
161 static uint32   dsp_remain;
162 static uint32   dsp_modulo;
163 static uint32   dsp_flags;
164 static uint32   dsp_matrix_control;
165 static uint32   dsp_pointer_to_matrix;
166 static uint32   dsp_data_organization;
167 static uint32   dsp_control;
168 static uint32   dsp_div_control;
169 static uint8    dsp_flag_z;
170 static uint8    dsp_flag_n;
171 static uint8    dsp_flag_c;    
172 static uint8    dsp_alternate_flag_z;
173 static uint8    dsp_alternate_flag_n;
174 static uint8    dsp_alternate_flag_c;    
175 static uint32   *dsp_reg;
176 static uint32   *dsp_alternate_reg;
177 static uint32   *dsp_reg_bank_0;
178 static uint32   *dsp_reg_bank_1;
179
180 static uint32   dsp_opcode_first_parameter;
181 static uint32   dsp_opcode_second_parameter;
182
183 #define dsp_running (dsp_control&0x01)
184
185 #define Rm dsp_reg[dsp_opcode_first_parameter]
186 #define Rn dsp_reg[dsp_opcode_second_parameter]
187 #define alternate_Rm dsp_alternate_reg[dsp_opcode_first_parameter]
188 #define alternate_Rn dsp_alternate_reg[dsp_opcode_second_parameter]
189 #define imm_1 dsp_opcode_first_parameter
190 #define imm_2 dsp_opcode_second_parameter
191
192 #define set_flag_z(r) dsp_flag_z=(r==0); 
193 #define set_flag_n(r) dsp_flag_n=(r&0x80000000);
194
195 #define reset_flag_z()  dsp_flag_z=0;
196 #define reset_flag_n()  dsp_flag_n=0;
197 #define reset_flag_c()  dsp_flag_c=0;    
198
199 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 };
200 uint8 *dsp_branch_condition_table=0;
201 #define branch_condition(x)     dsp_branch_condition_table[(x) + ((jaguar_flags & 7) << 5)]
202
203 static uint32 dsp_in_exec=0;
204 static uint32 dsp_releaseTimeSlice_flag=0;
205
206 FILE *dsp_fp;
207
208 //////////////////////////////////////////////////////////////////////////////
209 //
210 //////////////////////////////////////////////////////////////////////////////
211 //
212 //
213 //
214 //
215 //
216 //
217 //////////////////////////////////////////////////////////////////////////////
218 void dsp_reset_stats(void)
219 {
220         for (uint32 i=0;i<64;i++)
221                 dsp_opcode_use[i]=0;
222 }
223
224 //////////////////////////////////////////////////////////////////////////////
225 //
226 //////////////////////////////////////////////////////////////////////////////
227 //
228 //
229 //
230 //
231 //
232 //
233 //////////////////////////////////////////////////////////////////////////////
234 void dsp_releaseTimeslice(void)
235 {
236         dsp_releaseTimeSlice_flag=1;
237 }
238
239 //////////////////////////////////////////////////////////////////////////////
240 //
241 //////////////////////////////////////////////////////////////////////////////
242 //
243 //
244 //
245 //
246 //
247 //
248 //////////////////////////////////////////////////////////////////////////////
249 void dsp_build_branch_condition_table(void)
250 {
251         int i,j;
252         #define ZFLAG                           0x00001
253         #define CFLAG                           0x00002
254         #define NFLAG                           0x00004
255         
256         /* allocate the mirror table */
257         if (!mirror_table)
258                 mirror_table = (uint16*)malloc(65536 * sizeof(mirror_table[0]));
259
260         /* fill in the mirror table */
261         if (mirror_table)
262                 for (int i = 0; i < 65536; i++)
263                         mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) |
264                                           ((i >> 11) & 0x0004) | ((i >> 9)  & 0x0008) |
265                                           ((i >> 7)  & 0x0010) | ((i >> 5)  & 0x0020) |
266                                           ((i >> 3)  & 0x0040) | ((i >> 1)  & 0x0080) |
267                                           ((i << 1)  & 0x0100) | ((i << 3)  & 0x0200) |
268                                           ((i << 5)  & 0x0400) | ((i << 7)  & 0x0800) |
269                                           ((i << 9)  & 0x1000) | ((i << 11) & 0x2000) |
270                                           ((i << 13) & 0x4000) | ((i << 15) & 0x8000);
271
272         if (!dsp_branch_condition_table)
273         {
274                 dsp_branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(dsp_branch_condition_table[0]));
275
276                 /* fill in the condition table */
277                 if (dsp_branch_condition_table)
278                         for (i = 0; i < 8; i++)
279                                 for (j = 0; j < 32; j++)
280                                 {
281                                         int result = 1;
282                                         if (j & 1)
283                                                 if (i & ZFLAG) result = 0;
284                                         if (j & 2)
285                                                 if (!(i & ZFLAG)) result = 0;
286                                         if (j & 4)
287                                                 if (i & (CFLAG << (j >> 4))) result = 0;
288                                         if (j & 8)
289                                                 if (!(i & (CFLAG << (j >> 4)))) result = 0;
290                                         dsp_branch_condition_table[i * 32 + j] = result;
291                                 }
292         }
293 }
294 //////////////////////////////////////////////////////////////////////////////
295 //
296 //////////////////////////////////////////////////////////////////////////////
297 //
298 //
299 //
300 //
301 //
302 //
303 //////////////////////////////////////////////////////////////////////////////
304 unsigned dsp_byte_read(unsigned int offset)
305 {
306 // battlemorph
307 //      if ((offset==0xF1CFE0)||(offset==0xF1CFE2))
308 //              return(0xffff);
309         // mutant penguin
310         if ((jaguar_mainRom_crc32==0xbfd751a4)||(jaguar_mainRom_crc32==0x053efaf9))
311         {
312                 if (offset==0xF1CFE0)
313                         return(0xff);
314         }
315         if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
316                 return(dsp_ram_8[offset-dsp_work_ram_base]);
317
318         if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
319         {
320                 uint32 data=dsp_long_read(offset&0xfffffffc);
321
322                 if ((offset&0x03)==0)
323                         return(data>>24);
324                 else
325                 if ((offset&0x03)==1)
326                         return((data>>16)&0xff);
327                 else
328                 if ((offset&0x03)==2)
329                         return((data>>8)&0xff);
330                 else
331                 if ((offset&0x03)==3)
332                         return(data&0xff);
333         }
334         return(jaguar_byte_read(offset));
335
336 //////////////////////////////////////////////////////////////////////////////
337 //
338 //////////////////////////////////////////////////////////////////////////////
339 //
340 //
341 //
342 //
343 //
344 //
345 //////////////////////////////////////////////////////////////////////////////
346 unsigned dsp_word_read(unsigned int offset)
347 {
348         offset&=0xFFFFFFFE;
349         // jaguar cd bios
350         if (jaguar_mainRom_crc32==0xa74a97cd)
351         {
352                 if (offset==0xF1A114) return(0x0000);
353                 if (offset==0xF1A116) return(0x0000);
354                 if (offset==0xF1B000) return(0x1234);
355                 if (offset==0xF1B002) return(0x5678);
356         }
357 /*
358         if (jaguar_mainRom_crc32==0x7ae20823)
359         {
360                 if (offset==0xF1B9D8) return(0x0000);
361                 if (offset==0xF1B9Da) return(0x0000);
362                 if (offset==0xF1B2C0) return(0x0000);
363                 if (offset==0xF1B2C2) return(0x0000);
364         }
365 */
366         // pour permettre Ã  wolfenstein 3d de tourner sans le dsp
367 /*      if ((offset==0xF1B0D0)||(offset==0xF1B0D2))
368                 return(0);
369 */
370
371                 // pour permettre Ã  nba jam de tourner sans le dsp
372         if (jaguar_mainRom_crc32==0x4faddb18)
373         {
374                 if (offset==0xf1b2c0) return(0);
375                 if (offset==0xf1b2c2) return(0);
376                 if (offset==0xf1b240) return(0);
377                 if (offset==0xf1b242) return(0);
378                 if (offset==0xF1B340) return(0);
379                 if (offset==0xF1B342) return(0);
380                 if (offset==0xF1BAD8) return(0);
381                 if (offset==0xF1BADA) return(0);
382                 if (offset==0xF1B040) return(0);
383                 if (offset==0xF1B042) return(0);
384                 if (offset==0xF1B0C0) return(0);
385                 if (offset==0xF1B0C2) return(0);
386                 if (offset==0xF1B140) return(0);
387                 if (offset==0xF1B142) return(0);
388                 if (offset==0xF1B1C0) return(0);
389                 if (offset==0xF1B1C2) return(0);
390         }
391
392         if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
393         {
394                 offset-=dsp_work_ram_base;
395                 uint16 data=(((uint16)dsp_ram_8[offset])<<8)|((uint16)dsp_ram_8[offset+1]);
396                 return(data);
397         }
398         if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
399         {
400                 uint32 data;
401
402                 data=dsp_long_read(offset&0xfffffffc);
403
404                 if (offset&0x03)
405                         return(data&0xffff);
406                 else
407                         return(data>>16);
408         }
409         return(jaguar_word_read(offset));
410 }
411 //////////////////////////////////////////////////////////////////////////////
412 //
413 //////////////////////////////////////////////////////////////////////////////
414 //
415 //
416 //
417 //
418 //
419 //
420 //////////////////////////////////////////////////////////////////////////////
421 unsigned dsp_long_read(unsigned int offset)
422 {
423         offset&=0xFFFFFFFC;
424
425         if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
426         {
427                 offset-=dsp_work_ram_base;
428                 uint32 data= (((uint32)dsp_ram_8[offset]  )<<24)|
429                                  (((uint32)dsp_ram_8[offset+1])<<16)|
430                                          (((uint32)dsp_ram_8[offset+2])<<8 )|
431                                          ( (uint32)dsp_ram_8[offset+3]);
432                 return(data);
433         }
434         if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
435         {
436                 offset&=0x1f;
437                 switch (offset)
438                 {
439                 case 0x00:      dsp_flag_c?(dsp_flag_c=1):(dsp_flag_c=0);
440                                         dsp_flag_z?(dsp_flag_z=1):(dsp_flag_z=0);
441                                         dsp_flag_n?(dsp_flag_n=1):(dsp_flag_n=0);
442
443                                         dsp_flags=(dsp_flags&0xFFFFFFF8)|(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
444                                         
445                                         return(dsp_flags&0xFFFFC1FF);
446                 case 0x04: return(dsp_matrix_control);
447                 case 0x08: return(dsp_pointer_to_matrix);
448                 case 0x0C: return(dsp_data_organization);
449                 case 0x10: return(dsp_pc);
450                 case 0x14: return(dsp_control);
451                 case 0x18: return(dsp_modulo);
452                 case 0x1C: return(dsp_remain);
453 //              default:   // unaligned long read //__asm int 3
454                 }
455                 return(0xfffffff);
456         }
457         uint32 data=jaguar_word_read(offset);
458         data<<=16;
459         data|=jaguar_word_read(offset+2);
460         return(data);
461 }
462 //////////////////////////////////////////////////////////////////////////////
463 //
464 //////////////////////////////////////////////////////////////////////////////
465 //
466 //
467 //
468 //
469 //
470 //
471 //////////////////////////////////////////////////////////////////////////////
472 void dsp_byte_write(unsigned offset, unsigned data)
473 {
474         if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
475         {
476                 offset -= dsp_work_ram_base;
477                 dsp_ram_8[offset] = data;
478                 if (dsp_in_exec == 0)
479                 {
480 //                      s68000releaseTimeslice();
481                         m68k_end_timeslice();
482                         gpu_releaseTimeslice();
483                 }
484                 return;
485         }
486         if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
487         {
488                 uint32 reg = offset & 0x1C;
489                 int bytenum = offset & 0x03;
490                 
491                 if ((reg >= 0x1C) && (reg <= 0x1F))
492                         dsp_div_control = (dsp_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
493                 else
494                 {
495                         uint32 old_data = dsp_long_read(offset&0xFFFFFFC);
496                         bytenum = 3 - bytenum; // convention motorola !!!
497                         old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3)); 
498                         dsp_long_write(offset & 0xFFFFFFC, old_data);
499                 }
500                 return;
501         }
502 //      fprintf(log_get(),"dsp: writing %.2x at 0x%.8x\n",data,offset);
503         jaguar_byte_write(offset, data);
504 }
505 //////////////////////////////////////////////////////////////////////////////
506 //
507 //////////////////////////////////////////////////////////////////////////////
508 //
509 //
510 //
511 //
512 //
513 //
514 //////////////////////////////////////////////////////////////////////////////
515 void dsp_word_write(unsigned offset, unsigned data)
516 {
517         offset &= 0xFFFFFFFE;
518 //      fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset);
519         if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
520         {
521                 offset -= dsp_work_ram_base;
522                 dsp_ram_8[offset] = data >> 8;
523                 dsp_ram_8[offset+1] = data & 0xFF;
524                 if (dsp_in_exec == 0)
525                 {
526 //                      fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset+dsp_work_ram_base);
527 //                      s68000releaseTimeslice();
528                         m68k_end_timeslice();
529                         gpu_releaseTimeslice();
530                 }
531                 return;
532         }
533         else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
534         {
535                 if ((offset & 0x1C) == 0x1C)
536                 {
537                         if (offset & 0x03)
538                                 dsp_div_control = (dsp_div_control&0xffff0000)|(data&0xffff);
539                         else
540                                 dsp_div_control = (dsp_div_control&0xffff)|((data&0xffff)<<16);
541                 }
542                 else
543                 {
544                         uint32 old_data = dsp_long_read(offset & 0xffffffc);
545                         if (offset & 0x03)
546                                 old_data = (old_data&0xffff0000)|(data&0xffff);
547                         else
548                                 old_data = (old_data&0xffff)|((data&0xffff)<<16);
549                         dsp_long_write(offset & 0xffffffc, old_data);
550                 }
551                 return;
552         }
553         jaguar_word_write(offset, data);
554 }
555 //////////////////////////////////////////////////////////////////////////////
556 //
557 //////////////////////////////////////////////////////////////////////////////
558 //
559 //
560 //
561 //
562 //
563 //
564 //////////////////////////////////////////////////////////////////////////////
565 void dsp_long_write(unsigned offset, unsigned data)
566 {
567         offset &= 0xFFFFFFFC;
568 //      fprintf(log_get(),"dsp: writing %.8x at 0x%.8x\n",data,offset);
569         if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
570         {
571                 offset -= dsp_work_ram_base;
572                 dsp_ram_8[offset]  = data >> 24;
573                 dsp_ram_8[offset+1] = (data>>16) & 0xFF;
574                 dsp_ram_8[offset+2] = (data>>8) & 0xFF;
575                 dsp_ram_8[offset+3] = data & 0xFF;
576                 return;
577         }
578         else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
579         {
580                 offset&=0x1f;
581                 switch (offset)
582                 {
583                 case 0x00:
584                         dsp_flags = data;
585                         dsp_flag_z = dsp_flags & 0x01;
586                         dsp_flag_c = (dsp_flags>>1) & 0x01;
587                         dsp_flag_n = (dsp_flags>>2) & 0x01;
588                         dsp_update_register_banks();
589                         dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3);
590                         dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1);
591                         dsp_check_irqs();
592                         break;
593                 case 0x04:
594                         dsp_matrix_control = data;
595                         break;
596                 case 0x08:
597                         dsp_pointer_to_matrix = data;
598                         break;
599                 case 0x0C:
600                         dsp_data_organization = data;
601                         break;
602                 case 0x10:
603                         dsp_pc = data;
604                         break;
605                 case 0x14:
606                 {       
607                         uint32 dsp_was_running = dsp_running;
608                         // check for DSP->CPU interrupt
609                         if (data & 0x02)
610                         {
611 //                                                      fprintf(log_get(),"DSP->CPU interrupt\n");
612                                 if (tom_irq_enabled(IRQ_GPU) && jaguar_interrupt_handler_is_valid(64))
613                                 {
614                                         tom_set_pending_gpu_int();
615 //                                      s68000interrupt(7,64);
616 //                                      s68000flushInterrupts();
617                                         m68k_set_irq(7);                        // Set 68000 NMI...
618                                         dsp_releaseTimeslice();
619                                 }
620                                 data &= ~(0x02);
621                         }
622                         // check for CPU->DSP interrupt
623                         if (data & 0x04)
624                         {
625 //                                                      fprintf(log_get(),"CPU->DSP interrupt\n");
626                                 dsp_set_irq_line(0, 1);
627 //                              s68000releaseTimeslice();
628                                 m68k_end_timeslice();
629                                 gpu_releaseTimeslice();
630                                 data &= ~(0x04);
631                         }
632                         // single stepping
633                         if (data & 0x10)
634                         {
635                                                         //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not ");
636                         }
637                         dsp_control = data;
638
639                         // if dsp wasn't running but is now running
640                         // execute a few cycles
641 #ifndef DSP_SINGLE_STEPPING
642                         if (!dsp_was_running && dsp_running)
643                         {
644                                 dsp_exec(200);
645                         }
646 #else
647                         if (dsp_control & 0x18)
648                                 dsp_exec(1);
649 #endif
650                         break;
651                 }
652                 case 0x18:
653                         dsp_modulo = data;
654                         break;
655                 case 0x1C:
656                         dsp_div_control=data;
657                         break;
658 //              default:   // unaligned long read
659                                    //__asm int 3
660                 }
661                 return;
662         }
663         jaguar_word_write(offset, (data>>16) & 0xFFFF);
664         jaguar_word_write(offset+2, data & 0xFFFF);
665 }
666 //////////////////////////////////////////////////////////////////////////////
667 //
668 //////////////////////////////////////////////////////////////////////////////
669 //
670 //
671 //
672 //
673 //
674 //
675 //////////////////////////////////////////////////////////////////////////////
676 uint8 * jaguar_rom_load(char * path, uint32 * romSize);
677 void dsp_load_bin_at(char * path, uint32 offset)
678 {
679         uint32 romSize;
680         uint8 * rom;
681
682         rom = jaguar_rom_load(path, &romSize);
683         for(uint32 i=0; i<romSize; i++)
684                 jaguar_byte_write(offset+i, rom[i]);
685 }
686 //////////////////////////////////////////////////////////////////////////////
687 //
688 //////////////////////////////////////////////////////////////////////////////
689 //
690 //
691 //
692 //
693 //
694 //
695 //////////////////////////////////////////////////////////////////////////////
696 static int go = 0;
697 void dsp_update_register_banks(void)
698 {
699         uint32 temp;
700         int i, bank;
701
702         bank = dsp_flags&0x4000;
703
704         if (dsp_flags & 0x8) 
705                 bank = 0;
706         
707         if ((!bank && (dsp_reg_bank_0 != dsp_reg)) || (bank && (dsp_reg_bank_1 != dsp_reg)))
708         {
709                 for (i = 0; i < 32; i++)
710                 {
711                         temp = dsp_reg[i];
712                         dsp_reg[i] = dsp_alternate_reg[i];
713                         dsp_alternate_reg[i]= temp;
714                 }
715                 // switch flags
716                 temp=dsp_flag_z;
717                 dsp_flag_z=dsp_alternate_flag_z;
718                 dsp_alternate_flag_z=temp;
719
720                 temp=dsp_flag_n;
721                 dsp_flag_n=dsp_alternate_flag_n;
722                 dsp_alternate_flag_n=temp;
723
724                 temp=dsp_flag_c;
725                 dsp_flag_c=dsp_alternate_flag_c;
726                 dsp_alternate_flag_c=temp;
727         
728                 if (!bank)
729                 {
730                         dsp_reg_bank_0 = dsp_reg;
731                         dsp_reg_bank_1 = dsp_alternate_reg;
732                 }
733                 else
734                 {
735                         dsp_reg_bank_0 = dsp_alternate_reg;
736                         dsp_reg_bank_1 = dsp_reg;
737                 }
738         }
739 }
740 //////////////////////////////////////////////////////////////////////////////
741 //
742 //////////////////////////////////////////////////////////////////////////////
743 //
744 //
745 //
746 //
747 //
748 //
749 //////////////////////////////////////////////////////////////////////////////
750 void dsp_check_if_i2s_interrupt_needed(void)
751 {
752         static uint32 count=8;
753
754         int mask;
755         count--;
756         if (count>0)
757                 return;
758
759         count=4;
760         // already in an interrupt handler ?
761         if (dsp_flags & 0x8) 
762                 return;
763
764         // get the interrupt mask 
765         mask = (dsp_flags >> 4) & 0x1f;
766         mask |= (dsp_flags >> 11) & 0x20;
767
768         if (mask & 0x02)
769         {
770                 dsp_set_irq_line(1,1);
771         }
772 }
773 //////////////////////////////////////////////////////////////////////////////
774 //
775 //////////////////////////////////////////////////////////////////////////////
776 //
777 //
778 //
779 //
780 //
781 //
782 //////////////////////////////////////////////////////////////////////////////
783 void dsp_check_irqs(void)
784 {
785         int bits, mask, which = 0;
786
787         if (dsp_flags & 0x8) 
788                 return;
789
790         // get the active interrupt bits 
791         bits = (dsp_control >> 6) & 0x1f;
792         bits |= (dsp_control >> 10) & 0x20;
793
794         // get the interrupt mask 
795         mask = (dsp_flags >> 4) & 0x1f;
796         mask |= (dsp_flags >> 11) & 0x20;
797
798 //      fprintf(log_get(),"dsp: bits=%.2x mask=%.2x\n",bits,mask);
799         // bail if nothing is available
800         bits &= mask;
801
802         if (!bits)
803                 return;
804
805         // determine which interrupt 
806         if (bits & 0x01) which = 0;
807         if (bits & 0x02) which = 1;
808         if (bits & 0x04) which = 2;
809         if (bits & 0x08) which = 3;
810         if (bits & 0x10) which = 4;
811         if (bits & 0x20) which = 5;
812
813 //      fprintf(log_get(),"dsp: generating interrupt %i\n",which);
814
815         dsp_flags |= 0x08;
816         dsp_update_register_banks();
817
818         // subqt  #4,r31                ; pre-decrement stack pointer 
819         // move  pc,r30                 ; address of interrupted code 
820         // store  r30,(r31)     ; store return address
821         dsp_reg[31] -= 4;
822         dsp_reg[30]=dsp_pc;
823         dsp_long_write(dsp_reg[31], dsp_pc - 2);
824
825         // movei  #service_address,r30  ; pointer to ISR entry 
826         // jump  (r30)                                  ; jump to ISR 
827         // nop
828         dsp_pc = dsp_work_ram_base;
829         dsp_pc += which * 0x10;
830         dsp_reg[30]=dsp_pc;
831 }
832 //////////////////////////////////////////////////////////////////////////////
833 //
834 //////////////////////////////////////////////////////////////////////////////
835 //
836 //
837 //
838 //
839 //
840 //
841 //////////////////////////////////////////////////////////////////////////////
842 void dsp_set_irq_line(int irqline, int state)
843 {
844         int mask = 0x40 << irqline;
845         dsp_control &= ~mask;
846         if (state)
847         {
848                 dsp_control |= mask;
849                 dsp_check_irqs();
850         }
851 }
852 //////////////////////////////////////////////////////////////////////////////
853 //
854 //////////////////////////////////////////////////////////////////////////////
855 //
856 //
857 //
858 //
859 //
860 //
861 //////////////////////////////////////////////////////////////////////////////
862 void dsp_init(void)
863 {
864         memory_malloc_secure((void**)&dsp_ram_8,0x2000,"dsp work ram");
865         memory_malloc_secure((void**)&dsp_reg,32*sizeof(int32),"dsp bank 0 regs");
866         memory_malloc_secure((void**)&dsp_alternate_reg,32*sizeof(int32),"dsp bank 1 regs");
867         
868         dsp_build_branch_condition_table();
869
870         dsp_reset();
871 }
872 //////////////////////////////////////////////////////////////////////////////
873 //
874 //////////////////////////////////////////////////////////////////////////////
875 //
876 //
877 //
878 //
879 //
880 //
881 //////////////////////////////////////////////////////////////////////////////
882 void dsp_reset(void)
883 {
884         dsp_pc                            = 0x00f1b000;
885         dsp_acc                           = 0x00000000;
886         dsp_remain                        = 0x00000000;
887         dsp_modulo                        = 0xFFFFFFFF;
888         dsp_flags                         = 0x00040000;
889         dsp_matrix_control    = 0x00000000;
890         dsp_pointer_to_matrix = 0x00000000;
891         dsp_data_organization = 0xffffffff;
892         dsp_control                       = 0x00012800;
893         dsp_div_control           = 0x00000000;
894         dsp_in_exec                       = 0;
895
896         for (int i=0;i<32;i++)
897         {
898                 dsp_reg[i]           = 0x00000000;
899                 dsp_alternate_reg[i] = 0x00000000;
900         }
901         
902         dsp_reg_bank_0 = dsp_reg;
903         dsp_reg_bank_1 = dsp_alternate_reg;
904 //      dsp_reg_bank_1 = dsp_reg;
905 //      dsp_reg_bank_0 = dsp_alternate_reg;
906
907         reset_flag_z();
908         reset_flag_n();
909         reset_flag_c();
910
911         dsp_alternate_flag_z=0;
912         dsp_alternate_flag_n=0;
913         dsp_alternate_flag_c=0;
914
915         dsp_reset_stats();
916
917         memset(dsp_ram_8,                 0xff, 0x2000);
918 }
919 //////////////////////////////////////////////////////////////////////////////
920 //
921 //////////////////////////////////////////////////////////////////////////////
922 //
923 //
924 //
925 //
926 //
927 //      
928 //////////////////////////////////////////////////////////////////////////////
929 void dsp_done(void)
930 {
931         int i, j;
932         fprintf(log_get(),"dsp: stopped at pc=0x%.8x dsp_modulo=0x%.8x(dsp %s running)\n",dsp_pc,dsp_modulo,dsp_running?"was":"wasn't");
933         fprintf(log_get(),"dsp: %sin interrupt handler\n",(dsp_flags & 0x8)?"":"not ");
934         int bits, mask;
935
936         // get the active interrupt bits 
937         bits = (dsp_control >> 6) & 0x1f;
938         bits |= (dsp_control >> 10) & 0x20;
939
940         // get the interrupt mask 
941         mask = (dsp_flags >> 4) & 0x1f;
942         mask |= (dsp_flags >> 11) & 0x20;
943
944         fprintf(log_get(),"dsp: bits=0x%.8x mask=0x%.8x\n",bits,mask);
945         fprintf(log_get(),"\nregisters bank 0\n");
946         for (int j=0;j<8;j++)
947         {
948                 fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
949                                                   (j<<2)+0,dsp_reg[(j<<2)+0],
950                                                   (j<<2)+1,dsp_reg[(j<<2)+1],
951                                                   (j<<2)+2,dsp_reg[(j<<2)+2],
952                                                   (j<<2)+3,dsp_reg[(j<<2)+3]);
953
954         }
955 //      fprintf(log_get(),"registers bank 1\n");
956 //      for (j=0;j<8;j++)
957 //      {
958 //              fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
959 //                                                (j<<2)+0,dsp_alternate_reg[(j<<2)+0],
960 //                                                (j<<2)+1,dsp_alternate_reg[(j<<2)+1],
961 //                                                (j<<2)+2,dsp_alternate_reg[(j<<2)+2],
962 //                                                (j<<2)+3,dsp_alternate_reg[(j<<2)+3]);
963 //
964 //      }
965         static char buffer[512];
966         j=dsp_work_ram_base;
967         for (int i=0;i<4096;i++)
968         {
969                 uint32 oldj=j;
970                 j+=dasmjag(JAGUAR_DSP,buffer,j);
971 //              fprintf(log_get(),"\t0x%.8x: %s\n",oldj,buffer);
972         }
973
974 /*
975         fprintf(log_get(),"dsp opcodes use:\n");
976         for (i=0;i<64;i++)
977         {
978                 if (dsp_opcode_use[i])
979                         fprintf(log_get(),"\t%s %i\n",dsp_opcode_str[i],dsp_opcode_use[i]);
980         }
981 */
982         memory_free(dsp_ram_8);
983 }
984
985 //////////////////////////////////////////////////////////////////////////////
986 //
987 //////////////////////////////////////////////////////////////////////////////
988 //
989 //
990 //
991 //
992 //
993 //
994 //////////////////////////////////////////////////////////////////////////////
995 void dsp_exec(int32 cycles)
996 {
997         if ((cycles!=1)&&(jaguar_mainRom_crc32==0xba74c3ed))
998                 dsp_check_if_i2s_interrupt_needed();
999
1000 #ifdef DSP_SINGLE_STEPPING
1001         if (dsp_control&0x18)
1002         {
1003                 cycles=1;
1004                 dsp_control&=~0x10;
1005         }
1006 #endif
1007         dsp_check_irqs();
1008         dsp_releaseTimeSlice_flag=0;
1009         dsp_in_exec++;
1010         while ((cycles>0)&&(dsp_running))
1011         {
1012                 dsp_flag_c=(dsp_flag_c?1:0);
1013                 dsp_flag_z=(dsp_flag_z?1:0);
1014                 dsp_flag_n=(dsp_flag_n?1:0);
1015
1016
1017 /*
1018                 if (dsp_pc==0x00f1b02c)
1019                 {
1020                         if (dsp_fp)
1021                         {
1022                                 fclose(dsp_fp);
1023                                 exit(0);
1024                         }
1025                 }
1026                 else 
1027                 if (dsp_pc==0x00f1b032)
1028                 {
1029                         dsp_fp=fopen("c:\\bad.log","wrt");
1030                         if (dsp_fp==NULL)
1031                                 MessageBox(NULL,"Cannot open dsp log","",MB_OK);
1032                 }
1033                 if (dsp_fp)
1034                 {
1035                         fprintf(dsp_fp,"0x%.8x\n",dsp_pc);
1036                 }
1037                 
1038 //              if (dsp_pc==0x00f1b130)
1039 //                      dsp_load_bin_at("SCHRIFT.DAT",0x120000);
1040 */              
1041                 uint16 opcode=dsp_word_read(dsp_pc);
1042                 dsp_opcode_first_parameter=(opcode&0x3e0)>>5;
1043                 dsp_opcode_second_parameter=(opcode&0x1f);
1044                 dsp_pc+=2;
1045                 dsp_opcode[opcode>>10]();
1046                 dsp_opcode_use[opcode>>10]++;
1047                 cycles-=dsp_opcode_cycles[opcode>>10];
1048         }
1049         dsp_in_exec--;
1050 }
1051 //////////////////////////////////////////////////////////////////////////////
1052 //
1053 //////////////////////////////////////////////////////////////////////////////
1054 //
1055 //
1056 //
1057 //
1058 //
1059 //
1060 //////////////////////////////////////////////////////////////////////////////
1061 static void dsp_opcode_jump(void)
1062 {
1063         uint32 delayed_pc = Rm;
1064         uint32 jaguar_flags;
1065
1066         // normalize flags
1067         dsp_flag_c=dsp_flag_c?1:0;
1068         dsp_flag_z=dsp_flag_z?1:0;
1069         dsp_flag_n=dsp_flag_n?1:0;
1070
1071         jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
1072
1073         if (branch_condition(imm_2))
1074         {
1075                 dsp_exec(1);
1076                 dsp_pc=delayed_pc;
1077         }
1078 }
1079 //////////////////////////////////////////////////////////////////////////////
1080 //
1081 //////////////////////////////////////////////////////////////////////////////
1082 //
1083 //
1084 //
1085 //
1086 //
1087 //
1088 //////////////////////////////////////////////////////////////////////////////
1089 static void dsp_opcode_jr(void)
1090 {
1091         int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1;
1092
1093         int32 delayed_pc = dsp_pc + (offset * 2);
1094         uint32 jaguar_flags;
1095
1096         // normalize flags
1097         dsp_flag_c=dsp_flag_c?1:0;
1098         dsp_flag_z=dsp_flag_z?1:0;
1099         dsp_flag_n=dsp_flag_n?1:0;
1100         
1101         jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
1102
1103         if (branch_condition(imm_2))
1104         {
1105                 dsp_exec(1);
1106                 dsp_pc=delayed_pc;
1107         }
1108 }
1109 //////////////////////////////////////////////////////////////////////////////
1110 //
1111 //////////////////////////////////////////////////////////////////////////////
1112 //
1113 //
1114 //
1115 //
1116 //
1117 //
1118 //////////////////////////////////////////////////////////////////////////////
1119 static void dsp_opcode_add(void)
1120 {
1121         uint32 _Rm=Rm;
1122         uint32 _Rn=Rn;
1123         uint32 res;
1124 #ifdef __PORT__
1125
1126     /*
1127        GCC on WIN32 (more importantly mingw) doesn't know the declared
1128        variables in asm until we put a _ before it.
1129        
1130        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1131     */
1132     #ifdef __GCCWIN32__
1133         asm(
1134         "addl %1, %2
1135     setc  _dsp_flag_c
1136         setz  _dsp_flag_z
1137         sets  _dsp_flag_n
1138         movl %%eax, %0
1139         "
1140         : "=m"(res)
1141         : "d"(_Rm), "a"(_Rn));
1142         
1143         #else
1144         asm(
1145         "addl %1, %2
1146         setc  dsp_flag_c
1147         setz  dsp_flag_z
1148         sets  dsp_flag_n
1149         movl %%eax, %0
1150         "
1151         : "=m"(res)
1152         : "d"(_Rm), "a"(_Rn));
1153         #endif
1154         
1155 #else
1156         __asm 
1157         {
1158                 mov   edx,_Rm
1159                 mov   eax,_Rn
1160                 add   eax,edx
1161                 setc  [dsp_flag_c]
1162                 setz  [dsp_flag_z]
1163                 sets  [dsp_flag_n]
1164                 mov       res,eax
1165         };
1166 #endif
1167         Rn=res;
1168 }
1169 //////////////////////////////////////////////////////////////////////////////
1170 //
1171 //////////////////////////////////////////////////////////////////////////////
1172 //
1173 //
1174 //
1175 //
1176 //
1177 //
1178 //////////////////////////////////////////////////////////////////////////////
1179 static void dsp_opcode_addc(void)
1180 {
1181         uint32 _Rm=Rm;
1182         uint32 _Rn=Rn;
1183         uint32 res;
1184 #ifdef __PORT__
1185
1186     /*
1187        GCC on WIN32 (more importantly mingw) doesn't know the declared
1188        variables in asm until we put a _ before it.
1189        
1190        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1191        We use __GCCWIN32__ for this "bug".
1192     */
1193
1194     #ifdef __GCCWIN32__ 
1195         
1196     asm(
1197         "addl %1, %2
1198         cmp       $0, _dsp_flag_c
1199         clc
1200         jz 1f
1201         stc
1202         1:
1203         adc %1, %2
1204         setc  _dsp_flag_c
1205         setz  _dsp_flag_z
1206         sets  _dsp_flag_n
1207         movl %%eax, %0
1208         "
1209         : "=m"(res)
1210         : "d"(_Rm), "a"(_Rn));
1211         #else
1212
1213     asm(
1214         "addl %1, %2
1215         cmp       $0, dsp_flag_c
1216         clc
1217         jz 1f
1218         stc
1219         1:
1220         adc %1, %2
1221         setc  dsp_flag_c
1222         setz  dsp_flag_z
1223         sets  dsp_flag_n
1224         movl %%eax, %0
1225         "
1226         : "=m"(res)
1227         : "d"(_Rm), "a"(_Rn));
1228
1229     #endif      
1230         
1231 #else
1232         __asm 
1233         {
1234                 mov   edx,_Rm
1235                 mov   eax,_Rn
1236                 cmp       [dsp_flag_c],0
1237                 clc
1238                 jz        dsp_opcode_addc_no_carry
1239                 stc
1240 dsp_opcode_addc_no_carry:
1241                 adc   eax,edx
1242                 setc  [dsp_flag_c]
1243                 setz  [dsp_flag_z]
1244                 sets  [dsp_flag_n]
1245                 mov       res,eax
1246         };
1247 #endif
1248         Rn=res;
1249 }
1250 //////////////////////////////////////////////////////////////////////////////
1251 //
1252 //////////////////////////////////////////////////////////////////////////////
1253 //
1254 //
1255 //
1256 //
1257 //
1258 //
1259 //////////////////////////////////////////////////////////////////////////////
1260 static void dsp_opcode_addq(void)
1261 {
1262         uint32 _Rn=Rn;
1263         uint32 _Rm=dsp_convert_zero[imm_1];
1264         uint32 res;
1265         
1266 #ifdef __PORT__
1267
1268     /*
1269        GCC on WIN32 (more importantly mingw) doesn't know the declared
1270        variables in asm until we put a _ before it.
1271        
1272        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1273     */
1274
1275     #ifdef __GCCWIN32__
1276     
1277         asm(
1278         "addl %1, %2
1279         setc  _dsp_flag_c
1280         setz  _dsp_flag_z
1281         sets  _dsp_flag_n
1282         movl %%eax, %0
1283         "
1284         : "=m"(res)
1285         : "d"(_Rm), "a"(_Rn));
1286         
1287         #else
1288         
1289         asm(
1290         "addl %1, %2
1291         setc  dsp_flag_c
1292         setz  dsp_flag_z
1293         sets  dsp_flag_n
1294         movl %%eax, %0
1295         "
1296         : "=m"(res)
1297         : "d"(_Rm), "a"(_Rn));
1298
1299         #endif
1300         
1301 #else
1302         __asm 
1303         {
1304                 mov   edx,_Rm
1305                 mov   eax,_Rn
1306                 add   eax,edx
1307                 setc  [dsp_flag_c]
1308                 setz  [dsp_flag_z]
1309                 sets  [dsp_flag_n]
1310                 mov       res,eax
1311         };
1312 #endif
1313         Rn=res;
1314 }
1315 //////////////////////////////////////////////////////////////////////////////
1316 //
1317 //////////////////////////////////////////////////////////////////////////////
1318 //
1319 //
1320 //
1321 //
1322 //
1323 //
1324 //////////////////////////////////////////////////////////////////////////////
1325 static void dsp_opcode_sub(void)
1326 {
1327         uint32 _Rm=Rm;
1328         uint32 _Rn=Rn;
1329         uint32 res;
1330 #ifdef __PORT__
1331
1332     /*
1333        GCC on WIN32 (more importantly mingw) doesn't know the declared
1334        variables in asm until we put a _ before it.
1335        
1336        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1337     */
1338
1339     #ifdef __GCCWIN32__
1340     
1341         asm(
1342         "subl %1, %2
1343         setc  _dsp_flag_c
1344         setz  _dsp_flag_z
1345         sets  _dsp_flag_n
1346         movl %%eax, %0
1347         "
1348         : "=m"(res)
1349         : "d"(_Rm), "a"(_Rn));
1350         
1351         #else
1352
1353         asm(
1354         "subl %1, %2
1355         setc  dsp_flag_c
1356         setz  dsp_flag_z
1357         sets  dsp_flag_n
1358         movl %%eax, %0
1359         "
1360         : "=m"(res)
1361         : "d"(_Rm), "a"(_Rn));
1362
1363         #endif  
1364         
1365 #else
1366         __asm 
1367         {
1368                 mov   eax,_Rn
1369                 mov   edx,_Rm
1370                 sub   eax,edx
1371                 setc  [dsp_flag_c]
1372                 setz  [dsp_flag_z]
1373                 sets  [dsp_flag_n]
1374                 mov       res,eax
1375         };
1376 #endif
1377         Rn=res;
1378 }
1379 //////////////////////////////////////////////////////////////////////////////
1380 //
1381 //////////////////////////////////////////////////////////////////////////////
1382 //
1383 //
1384 //
1385 //
1386 //
1387 //
1388 //////////////////////////////////////////////////////////////////////////////
1389 static void dsp_opcode_subc(void)
1390 {
1391         uint32 _Rm=Rm;
1392         uint32 _Rn=Rn;
1393         uint32 res;
1394 #ifdef __PORT__
1395
1396     /*
1397        GCC on WIN32 (more importantly mingw) doesn't know the declared
1398        variables in asm until we put a _ before it.
1399        
1400        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1401     */
1402
1403     #ifdef __GCCWIN32__
1404
1405         asm(
1406         "addl %1, %2
1407         cmp       $0, _dsp_flag_c
1408         clc
1409         jz 1f
1410         stc
1411         1:
1412         sbb %1, %2
1413         setc  _dsp_flag_c
1414         setz  _dsp_flag_z
1415         sets  _dsp_flag_n
1416         movl %%eax, %0
1417         "
1418         : "=m"(res)
1419         : "d"(_Rm), "a"(_Rn));
1420         
1421         #else
1422
1423         asm(
1424         "addl %1, %2
1425         cmp       $0, dsp_flag_c
1426         clc
1427         jz 1f
1428         stc
1429         1:
1430         sbb %1, %2
1431         setc  dsp_flag_c
1432         setz  dsp_flag_z
1433         sets  dsp_flag_n
1434         movl %%eax, %0
1435         "
1436         : "=m"(res)
1437         : "d"(_Rm), "a"(_Rn));
1438
1439         #endif
1440         
1441 #else
1442         __asm 
1443         {
1444                 mov   edx,_Rm
1445                 mov   eax,_Rn
1446                 cmp       [dsp_flag_c],0
1447                 clc
1448                 jz        dsp_opcode_subc_no_carry
1449                 stc
1450 dsp_opcode_subc_no_carry:
1451                 sbb   eax,edx
1452                 setc  [dsp_flag_c]
1453                 setz  [dsp_flag_z]
1454                 sets  [dsp_flag_n]
1455                 mov       res,eax
1456         };
1457 #endif
1458         Rn=res;
1459 }
1460 //////////////////////////////////////////////////////////////////////////////
1461 //
1462 //////////////////////////////////////////////////////////////////////////////
1463 //
1464 //
1465 //
1466 //
1467 //
1468 //
1469 //////////////////////////////////////////////////////////////////////////////
1470 static void dsp_opcode_subq(void)
1471 {
1472         uint32 _Rm=dsp_convert_zero[imm_1];
1473         uint32 _Rn=Rn;
1474         uint32 res;
1475 #ifdef __PORT__
1476
1477     /*
1478        GCC on WIN32 (more importantly mingw) doesn't know the declared
1479        variables in asm until we put a _ before it.
1480        
1481        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1482     */
1483
1484     #ifdef __GCCWIN32__
1485
1486         asm(
1487         "subl %1, %2
1488         setc  _dsp_flag_c
1489         setz  _dsp_flag_z
1490         sets  _dsp_flag_n
1491         movl %%eax, %0
1492         "
1493         : "=m"(res)
1494         : "d"(_Rm), "a"(_Rn));
1495         
1496         #else
1497
1498         asm(
1499         "subl %1, %2
1500         setc  dsp_flag_c
1501         setz  dsp_flag_z
1502         sets  dsp_flag_n
1503         movl %%eax, %0
1504         "
1505         : "=m"(res)
1506         : "d"(_Rm), "a"(_Rn));
1507         
1508         #endif
1509 #else
1510         __asm 
1511         {
1512                 mov   eax,_Rn
1513                 mov   edx,_Rm
1514                 sub   eax,edx
1515                 setc  [dsp_flag_c]
1516                 setz  [dsp_flag_z]
1517                 sets  [dsp_flag_n]
1518                 mov       res,eax
1519         };
1520 #endif
1521         Rn=res;
1522 }
1523 //////////////////////////////////////////////////////////////////////////////
1524 //
1525 //////////////////////////////////////////////////////////////////////////////
1526 //
1527 //
1528 //
1529 //
1530 //
1531 //
1532 //////////////////////////////////////////////////////////////////////////////
1533 static void dsp_opcode_cmp(void)
1534 {
1535         uint32 _Rm=Rm;
1536         uint32 _Rn=Rn;
1537 #ifdef __PORT__
1538
1539     /*
1540        GCC on WIN32 (more importantly mingw) doesn't know the declared
1541        variables in asm until we put a _ before it.
1542        
1543        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1544     */
1545
1546     #ifdef __GCCWIN32__
1547
1548         asm(
1549         "cmpl %0, %1
1550         setc  _dsp_flag_c
1551         setz  _dsp_flag_z
1552         sets  _dsp_flag_n
1553         "
1554         :
1555         : "d"(_Rm), "a"(_Rn));
1556         
1557         #else
1558         
1559         asm(
1560         "cmpl %0, %1
1561         setc  dsp_flag_c
1562         setz  dsp_flag_z
1563         sets  dsp_flag_n
1564         "
1565         :
1566         : "d"(_Rm), "a"(_Rn));
1567         
1568         #endif
1569         
1570 #else
1571         __asm 
1572         {
1573                 mov   eax,_Rn
1574                 mov   edx,_Rm
1575                 cmp   eax,edx
1576                 setc  [dsp_flag_c]
1577                 setz  [dsp_flag_z]
1578                 sets  [dsp_flag_n]
1579         };
1580 #endif
1581 }
1582 //////////////////////////////////////////////////////////////////////////////
1583 //
1584 //////////////////////////////////////////////////////////////////////////////
1585 //
1586 //
1587 //
1588 //
1589 //
1590 //
1591 //////////////////////////////////////////////////////////////////////////////
1592 static void dsp_opcode_cmpq(void)
1593 {
1594         static int32 sqtable[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1};
1595         int32 _Rm=sqtable[imm_1&0x1f];
1596         uint32 _Rn=Rn;
1597 #ifdef __PORT__
1598
1599     /*
1600        GCC on WIN32 (more importantly mingw) doesn't know the declared
1601        variables in asm until we put a _ before it.
1602        
1603        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1604     */
1605
1606     #ifdef __GCCWIN32__
1607
1608         asm(
1609         "cmpl %0, %1
1610         setc  _dsp_flag_c
1611         setz  _dsp_flag_z
1612         sets  _dsp_flag_n
1613         "
1614         :
1615         : "d"(_Rm), "a"(_Rn));
1616         
1617         #else
1618
1619         asm(
1620         "cmpl %0, %1
1621         setc  dsp_flag_c
1622         setz  dsp_flag_z
1623         sets  dsp_flag_n
1624         "
1625         :
1626         : "d"(_Rm), "a"(_Rn));
1627         
1628         #endif
1629         
1630 #else
1631         __asm 
1632         {
1633                 mov   eax,_Rn
1634                 mov   edx,_Rm
1635                 cmp   eax,edx
1636                 setc  [dsp_flag_c]
1637                 setz  [dsp_flag_z]
1638                 sets  [dsp_flag_n]
1639         };
1640 #endif
1641 }
1642 //////////////////////////////////////////////////////////////////////////////
1643 //
1644 //////////////////////////////////////////////////////////////////////////////
1645 //
1646 //
1647 //
1648 //
1649 //
1650 //
1651 //////////////////////////////////////////////////////////////////////////////
1652 static void dsp_opcode_and(void)
1653 {
1654         uint32 _Rm=Rm;
1655         uint32 _Rn=Rn;
1656         uint32 res;
1657 #ifdef __PORT__
1658
1659     /*
1660        GCC on WIN32 (more importantly mingw) doesn't know the declared
1661        variables in asm until we put a _ before it.
1662        
1663        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1664     */
1665
1666     #ifdef __GCCWIN32__
1667
1668         asm(
1669         "andl %1, %2
1670         setz  _dsp_flag_z
1671         sets  _dsp_flag_n
1672         movl %%eax, %0
1673         "
1674         : "=m"(res)
1675         : "d"(_Rm), "a"(_Rn));
1676         
1677         #else
1678
1679         asm(
1680         "andl %1, %2
1681         setz  dsp_flag_z
1682         sets  dsp_flag_n
1683         movl %%eax, %0
1684         "
1685         : "=m"(res)
1686         : "d"(_Rm), "a"(_Rn));
1687         
1688         #endif
1689         
1690 #else
1691         __asm 
1692         {
1693                 mov   eax,_Rn
1694                 mov   edx,_Rm
1695                 and   eax,edx
1696                 setz  [dsp_flag_z]
1697                 sets  [dsp_flag_n]
1698                 mov   res,eax
1699         };
1700 #endif
1701         Rn=res;
1702 }
1703 //////////////////////////////////////////////////////////////////////////////
1704 //
1705 //////////////////////////////////////////////////////////////////////////////
1706 //
1707 //
1708 //
1709 //
1710 //
1711 //
1712 //////////////////////////////////////////////////////////////////////////////
1713 static void dsp_opcode_or(void)
1714 {
1715         uint32 _Rm=Rm;
1716         uint32 _Rn=Rn;
1717         uint32 res;
1718 #ifdef __PORT__
1719
1720     /*
1721        GCC on WIN32 (more importantly mingw) doesn't know the declared
1722        variables in asm until we put a _ before it.
1723        
1724        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1725     */
1726
1727     #ifdef __GCCWIN32__
1728
1729         asm(
1730         "orl %1, %2
1731         setz  _dsp_flag_z
1732         sets  _dsp_flag_n
1733         movl %%eax, %0
1734         "
1735         : "=m"(res)
1736         : "d"(_Rm), "a"(_Rn));
1737         
1738         #else
1739         
1740         asm(
1741         "orl %1, %2
1742         setz  dsp_flag_z
1743         sets  dsp_flag_n
1744         movl %%eax, %0
1745         "
1746         : "=m"(res)
1747         : "d"(_Rm), "a"(_Rn));
1748         
1749         #endif
1750
1751 #else
1752         __asm 
1753         {
1754                 mov   eax,_Rn
1755                 mov   edx,_Rm
1756                 or    eax,edx
1757                 setz  [dsp_flag_z]
1758                 sets  [dsp_flag_n]
1759                 mov   res,eax
1760         };
1761 #endif
1762         Rn=res;
1763 }
1764 //////////////////////////////////////////////////////////////////////////////
1765 //
1766 //////////////////////////////////////////////////////////////////////////////
1767 //
1768 //
1769 //
1770 //
1771 //
1772 //
1773 //////////////////////////////////////////////////////////////////////////////
1774 static void dsp_opcode_xor(void)
1775 {
1776         uint32 _Rm=Rm;
1777         uint32 _Rn=Rn;
1778         uint32 res;
1779 #ifdef __PORT__
1780
1781     /*
1782        GCC on WIN32 (more importantly mingw) doesn't know the declared
1783        variables in asm until we put a _ before it.
1784        
1785        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1786     */
1787
1788     #ifdef __GCCWIN32__
1789
1790         asm(
1791         "xorl %1, %2
1792         setz  _dsp_flag_z
1793         sets  _dsp_flag_n
1794         movl %%eax, %0
1795         "
1796         : "=m"(res)
1797         : "d"(_Rm), "a"(_Rn));
1798         
1799         #else
1800         
1801         asm(
1802         "xorl %1, %2
1803         setz  dsp_flag_z
1804         sets  dsp_flag_n
1805         movl %%eax, %0
1806         "
1807         : "=m"(res)
1808         : "d"(_Rm), "a"(_Rn));
1809         
1810         #endif
1811         
1812 #else
1813         __asm 
1814         {
1815                 mov   eax,_Rn
1816                 mov   edx,_Rm
1817                 xor   eax,edx
1818                 setz  [dsp_flag_z]
1819                 sets  [dsp_flag_n]
1820                 mov   res,eax
1821         };
1822 #endif
1823         Rn=res;
1824 }
1825 //////////////////////////////////////////////////////////////////////////////
1826 //
1827 //////////////////////////////////////////////////////////////////////////////
1828 //
1829 //
1830 //
1831 //
1832 //
1833 //
1834 //////////////////////////////////////////////////////////////////////////////
1835 static void dsp_opcode_not(void)
1836 {
1837         uint32 _Rn=Rn;
1838         uint32 res;
1839 #ifdef __PORT__
1840
1841     /*
1842        GCC on WIN32 (more importantly mingw) doesn't know the declared
1843        variables in asm until we put a _ before it.
1844        
1845        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1846     */
1847
1848     #ifdef __GCCWIN32__
1849
1850         asm(
1851         "notl %1
1852         setz  _dsp_flag_z
1853         sets  _dsp_flag_n
1854         movl %%eax, %0
1855         "
1856         : "=m"(res)
1857         : "a"(_Rn));
1858         
1859         #else
1860         
1861         asm(
1862         "notl %1
1863         setz  dsp_flag_z
1864         sets  dsp_flag_n
1865         movl %%eax, %0
1866         "
1867         : "=m"(res)
1868         : "a"(_Rn));
1869         
1870         #endif
1871         
1872 #else
1873         __asm 
1874         {
1875                 mov   eax,_Rn
1876                 not   eax
1877                 setz  [dsp_flag_z]
1878                 sets  [dsp_flag_n]
1879                 mov   res,eax
1880         };
1881 #endif
1882         Rn=res;
1883 }
1884 //////////////////////////////////////////////////////////////////////////////
1885 //
1886 //////////////////////////////////////////////////////////////////////////////
1887 //
1888 //
1889 //
1890 //
1891 //
1892 //
1893 //////////////////////////////////////////////////////////////////////////////
1894 static void dsp_opcode_move_pc(void)
1895 {
1896         Rn = dsp_pc-2; 
1897 }
1898 //////////////////////////////////////////////////////////////////////////////
1899 //
1900 //////////////////////////////////////////////////////////////////////////////
1901 //
1902 //
1903 //
1904 //
1905 //
1906 //
1907 //////////////////////////////////////////////////////////////////////////////
1908 static void dsp_opcode_sat8(void)
1909 {
1910         int32 _Rn=(int32)Rn;
1911
1912         uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn);
1913         set_flag_z(res);
1914         reset_flag_n();
1915 }
1916 //////////////////////////////////////////////////////////////////////////////
1917 //
1918 //////////////////////////////////////////////////////////////////////////////
1919 //
1920 //
1921 //
1922 //
1923 //
1924 //
1925 //////////////////////////////////////////////////////////////////////////////
1926 static void dsp_opcode_sat16(void)
1927 {
1928         uint32 _Rn=Rn;
1929         uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn);
1930         set_flag_z(res);
1931         reset_flag_n();
1932 }
1933 //////////////////////////////////////////////////////////////////////////////
1934 //
1935 //////////////////////////////////////////////////////////////////////////////
1936 //
1937 //
1938 //
1939 //
1940 //
1941 //
1942 //////////////////////////////////////////////////////////////////////////////
1943 static void dsp_opcode_sat24(void)
1944 {
1945         uint32 _Rn=Rn;
1946
1947         uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn);
1948         set_flag_z(res);
1949         reset_flag_n();
1950 }
1951 //////////////////////////////////////////////////////////////////////////////
1952 //
1953 //////////////////////////////////////////////////////////////////////////////
1954 //
1955 //
1956 //
1957 //
1958 //
1959 //
1960 //////////////////////////////////////////////////////////////////////////////
1961 static void dsp_opcode_store_r14_indexed(void)
1962 {
1963         dsp_long_write( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2),Rn);
1964 }
1965 //////////////////////////////////////////////////////////////////////////////
1966 //
1967 //////////////////////////////////////////////////////////////////////////////
1968 //
1969 //
1970 //
1971 //
1972 //
1973 //
1974 //////////////////////////////////////////////////////////////////////////////
1975 static void dsp_opcode_store_r15_indexed(void)
1976 {
1977         dsp_long_write( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2),Rn);
1978 }
1979 //////////////////////////////////////////////////////////////////////////////
1980 //
1981 //////////////////////////////////////////////////////////////////////////////
1982 //
1983 //
1984 //
1985 //
1986 //
1987 //
1988 //////////////////////////////////////////////////////////////////////////////
1989 static void dsp_opcode_load_r14_ri(void)
1990 {
1991         Rn=dsp_long_read(dsp_reg[14] + Rm);
1992 }
1993 //////////////////////////////////////////////////////////////////////////////
1994 //
1995 //////////////////////////////////////////////////////////////////////////////
1996 //
1997 //
1998 //
1999 //
2000 //
2001 //
2002 //////////////////////////////////////////////////////////////////////////////
2003 static void dsp_opcode_load_r15_ri(void)
2004 {
2005         Rn=dsp_long_read(dsp_reg[15] + Rm);
2006 }
2007 //////////////////////////////////////////////////////////////////////////////
2008 //
2009 //////////////////////////////////////////////////////////////////////////////
2010 //
2011 //
2012 //
2013 //
2014 //
2015 //
2016 //////////////////////////////////////////////////////////////////////////////
2017 static void dsp_opcode_store_r14_ri(void)
2018 {
2019         dsp_long_write(dsp_reg[14] + Rm,Rn);
2020 }
2021 //////////////////////////////////////////////////////////////////////////////
2022 //
2023 //////////////////////////////////////////////////////////////////////////////
2024 //
2025 //
2026 //
2027 //
2028 //
2029 //
2030 //////////////////////////////////////////////////////////////////////////////
2031 static void dsp_opcode_store_r15_ri(void)
2032 {
2033         dsp_long_write(dsp_reg[15] + Rm,Rn);
2034 }
2035 //////////////////////////////////////////////////////////////////////////////
2036 //
2037 //////////////////////////////////////////////////////////////////////////////
2038 //
2039 //
2040 //
2041 //
2042 //
2043 //
2044 //////////////////////////////////////////////////////////////////////////////
2045 static void dsp_opcode_nop(void)
2046 {
2047 }
2048 //////////////////////////////////////////////////////////////////////////////
2049 //
2050 //////////////////////////////////////////////////////////////////////////////
2051 //
2052 //
2053 //
2054 //
2055 //
2056 //
2057 //////////////////////////////////////////////////////////////////////////////
2058 static void dsp_opcode_pack(void)
2059 {
2060         uint32 _Rn=Rn;
2061
2062         if (Rm==0)
2063         {
2064                 Rn =((_Rn & 0x03C00000) >> 10) |
2065                         ((_Rn & 0x0001E000) >> 5)  |
2066                         ((_Rn & 0x000000FF));
2067         }
2068         else
2069         {
2070                 Rn =((_Rn & 0x0000F000) << 10) |
2071                         ((_Rn & 0x00000F00) << 5)  |
2072                         ((_Rn & 0x000000FF));
2073         }
2074         reset_flag_z();
2075         reset_flag_n();
2076         set_flag_z(Rn);
2077         set_flag_n(Rn);
2078 }
2079 //////////////////////////////////////////////////////////////////////////////
2080 //
2081 //////////////////////////////////////////////////////////////////////////////
2082 //
2083 //
2084 //
2085 //
2086 //
2087 //
2088 //////////////////////////////////////////////////////////////////////////////
2089 static void dsp_opcode_storeb(void)
2090 {
2091         if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
2092                 dsp_long_write(Rm,Rn&0xff);
2093         else
2094                 jaguar_byte_write(Rm,Rn);
2095 }
2096 //////////////////////////////////////////////////////////////////////////////
2097 //
2098 //////////////////////////////////////////////////////////////////////////////
2099 //
2100 //
2101 //
2102 //
2103 //
2104 //
2105 //////////////////////////////////////////////////////////////////////////////
2106 static void dsp_opcode_storew(void)
2107 {
2108         if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
2109                 dsp_long_write(Rm,Rn&0xffff);
2110         else
2111                 jaguar_word_write(Rm,Rn);
2112 }
2113 //////////////////////////////////////////////////////////////////////////////
2114 //
2115 //////////////////////////////////////////////////////////////////////////////
2116 //
2117 //
2118 //
2119 //
2120 //
2121 //
2122 //////////////////////////////////////////////////////////////////////////////
2123 static void dsp_opcode_store(void)
2124 {
2125         dsp_long_write(Rm,Rn);
2126 }
2127 //////////////////////////////////////////////////////////////////////////////
2128 //
2129 //////////////////////////////////////////////////////////////////////////////
2130 //
2131 //
2132 //
2133 //
2134 //
2135 //
2136 //////////////////////////////////////////////////////////////////////////////
2137 static void dsp_opcode_loadb(void)
2138 {
2139         if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
2140                 Rn=dsp_long_read(Rm)&0xff;
2141         else
2142                 Rn=jaguar_byte_read(Rm);
2143 }
2144 //////////////////////////////////////////////////////////////////////////////
2145 //
2146 //////////////////////////////////////////////////////////////////////////////
2147 //
2148 //
2149 //
2150 //
2151 //
2152 //
2153 //////////////////////////////////////////////////////////////////////////////
2154 static void dsp_opcode_loadw(void)
2155 {
2156         if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
2157                 Rn=dsp_long_read(Rm)&0xffff;
2158         else
2159                 Rn=jaguar_word_read(Rm);
2160 }
2161 //////////////////////////////////////////////////////////////////////////////
2162 //
2163 //////////////////////////////////////////////////////////////////////////////
2164 //
2165 //
2166 //
2167 //
2168 //
2169 //
2170 //////////////////////////////////////////////////////////////////////////////
2171 static void dsp_opcode_load(void)
2172 {
2173         Rn = dsp_long_read(Rm);
2174 }
2175 //////////////////////////////////////////////////////////////////////////////
2176 //
2177 //////////////////////////////////////////////////////////////////////////////
2178 //
2179 //
2180 //
2181 //
2182 //
2183 //
2184 //////////////////////////////////////////////////////////////////////////////
2185 static void dsp_opcode_load_r14_indexed(void)
2186 {
2187         Rn = dsp_long_read( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2));
2188 }
2189 //////////////////////////////////////////////////////////////////////////////
2190 //
2191 //////////////////////////////////////////////////////////////////////////////
2192 //
2193 //
2194 //
2195 //
2196 //
2197 //
2198 //////////////////////////////////////////////////////////////////////////////
2199 static void dsp_opcode_load_r15_indexed(void)
2200 {
2201         Rn = dsp_long_read( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2));
2202 }
2203 //////////////////////////////////////////////////////////////////////////////
2204 //
2205 //////////////////////////////////////////////////////////////////////////////
2206 //
2207 //
2208 //
2209 //
2210 //
2211 //
2212 //////////////////////////////////////////////////////////////////////////////
2213 static void dsp_opcode_movei(void)
2214 {
2215         Rn = ((uint32)dsp_word_read(dsp_pc)) + (((uint32)dsp_word_read(dsp_pc+2))<<16);
2216         dsp_pc+=4;
2217 }
2218 //////////////////////////////////////////////////////////////////////////////
2219 //
2220 //////////////////////////////////////////////////////////////////////////////
2221 //
2222 //
2223 //
2224 //
2225 //
2226 //
2227 //////////////////////////////////////////////////////////////////////////////
2228 static void dsp_opcode_moveta(void)
2229 {
2230         alternate_Rn = Rm;
2231 }
2232 //////////////////////////////////////////////////////////////////////////////
2233 //
2234 //////////////////////////////////////////////////////////////////////////////
2235 //
2236 //
2237 //
2238 //
2239 //
2240 //
2241 //////////////////////////////////////////////////////////////////////////////
2242 static void dsp_opcode_movefa(void)
2243 {
2244         Rn = alternate_Rm;
2245 }
2246 //////////////////////////////////////////////////////////////////////////////
2247 //
2248 //////////////////////////////////////////////////////////////////////////////
2249 //
2250 //
2251 //
2252 //
2253 //
2254 //
2255 //////////////////////////////////////////////////////////////////////////////
2256 static void dsp_opcode_move(void)
2257 {
2258         Rn = Rm;
2259 }
2260 //////////////////////////////////////////////////////////////////////////////
2261 //
2262 //////////////////////////////////////////////////////////////////////////////
2263 //
2264 //
2265 //
2266 //
2267 //
2268 //
2269 //////////////////////////////////////////////////////////////////////////////
2270 static void dsp_opcode_moveq(void)
2271 {
2272         Rn = imm_1;    
2273 }
2274 //////////////////////////////////////////////////////////////////////////////
2275 //
2276 //////////////////////////////////////////////////////////////////////////////
2277 //
2278 //
2279 //
2280 //
2281 //
2282 //
2283 //////////////////////////////////////////////////////////////////////////////
2284 static void dsp_opcode_resmac(void)
2285 {
2286         Rn = dsp_acc;
2287 }
2288 //////////////////////////////////////////////////////////////////////////////
2289 //
2290 //////////////////////////////////////////////////////////////////////////////
2291 //
2292 //
2293 //
2294 //
2295 //
2296 //
2297 //////////////////////////////////////////////////////////////////////////////
2298 static void dsp_opcode_imult(void)
2299 {
2300         uint32 res=Rn=((int16)Rn)*((int16)Rm);
2301         set_flag_z(res);
2302         set_flag_n(res);
2303 }
2304 //////////////////////////////////////////////////////////////////////////////
2305 //
2306 //////////////////////////////////////////////////////////////////////////////
2307 //
2308 //
2309 //
2310 //
2311 //
2312 //
2313 //////////////////////////////////////////////////////////////////////////////
2314 static void dsp_opcode_mult(void)
2315 {
2316         uint32 res=Rn =  ((uint16)Rm) * ((uint16)Rn);
2317         set_flag_z(res);
2318         set_flag_n(res);
2319 }
2320 //////////////////////////////////////////////////////////////////////////////
2321 //
2322 //////////////////////////////////////////////////////////////////////////////
2323 //
2324 //
2325 //
2326 //
2327 //
2328 //
2329 //////////////////////////////////////////////////////////////////////////////
2330 static void dsp_opcode_bclr(void)
2331 {
2332         uint32 _Rm=imm_1;
2333         uint32 _Rn=Rn;
2334         uint32 res;
2335 #ifdef __PORT__
2336
2337     /*
2338        GCC on WIN32 (more importantly mingw) doesn't know the declared
2339        variables in asm until we put a _ before it.
2340        
2341        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2342     */
2343
2344     #ifdef __GCCWIN32__
2345
2346         asm(
2347         "btrl %1, %2
2348         cmpl $0, %2
2349         setz  _dsp_flag_z
2350         sets  _dsp_flag_n
2351         movl %%eax, %0
2352         "
2353         : "=m"(res)
2354         : "c"(_Rm), "a"(_Rn));
2355         
2356         #else
2357
2358         asm(
2359         "btrl %1, %2
2360         cmpl $0, %2
2361         setz  dsp_flag_z
2362         sets  dsp_flag_n
2363         movl %%eax, %0
2364         "
2365         : "=m"(res)
2366         : "c"(_Rm), "a"(_Rn));
2367         
2368         #endif
2369         
2370         
2371 #else
2372         __asm 
2373         {
2374                 mov   eax,_Rn
2375                 mov   ecx,_Rm
2376                 btr       eax,ecx
2377                 cmp   eax,0
2378                 setz  [dsp_flag_z]
2379                 sets  [dsp_flag_n]
2380                 mov   res,eax
2381         };
2382 #endif
2383         Rn=res;
2384 }
2385 //////////////////////////////////////////////////////////////////////////////
2386 //
2387 //////////////////////////////////////////////////////////////////////////////
2388 //
2389 //
2390 //
2391 //
2392 //
2393 //
2394 //////////////////////////////////////////////////////////////////////////////
2395 static void dsp_opcode_btst(void)
2396 {
2397         uint32 _Rm=imm_1;
2398         uint32 _Rn=Rn;
2399 #ifdef __PORT__
2400
2401     /*
2402        GCC on WIN32 (more importantly mingw) doesn't know the declared
2403        variables in asm until we put a _ before it.
2404        
2405        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2406     */
2407
2408     #ifdef __GCCWIN32__
2409
2410         asm(
2411         "bt %0, %1
2412         setnc _dsp_flag_z
2413         "
2414         :
2415         : "c"(_Rm), "a"(_Rn));
2416         
2417         #else
2418         
2419         asm(
2420         "bt %0, %1
2421         setnc dsp_flag_z
2422         "
2423         :
2424         : "c"(_Rm), "a"(_Rn));
2425         
2426         #endif
2427         
2428 #else
2429         __asm 
2430         {
2431                 mov   eax,_Rn
2432                 mov   ecx,_Rm
2433                 bt        eax,ecx
2434                 setnc [dsp_flag_z]
2435         };
2436 #endif
2437 }
2438 //////////////////////////////////////////////////////////////////////////////
2439 //
2440 //////////////////////////////////////////////////////////////////////////////
2441 //
2442 //
2443 //
2444 //
2445 //
2446 //
2447 //////////////////////////////////////////////////////////////////////////////
2448 static void dsp_opcode_bset(void)
2449 {
2450         uint32 _Rm=imm_1;
2451         uint32 _Rn=Rn;
2452         uint32 res;
2453 #ifdef __PORT__
2454
2455     /*
2456        GCC on WIN32 (more importantly mingw) doesn't know the declared
2457        variables in asm until we put a _ before it.
2458        
2459        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2460     */
2461
2462     #ifdef __GCCWIN32__
2463
2464         asm(
2465         "btsl %1, %2
2466         cmpl $0, %2
2467         setz  _dsp_flag_z
2468         sets  _dsp_flag_n
2469         movl %%eax, %0
2470         "
2471         : "=m"(res)
2472         : "c"(_Rm), "a"(_Rn));
2473         
2474         #else
2475         
2476         asm(
2477         "btsl %1, %2
2478         cmpl $0, %2
2479         setz  dsp_flag_z
2480         sets  dsp_flag_n
2481         movl %%eax, %0
2482         "
2483         : "=m"(res)
2484         : "c"(_Rm), "a"(_Rn));
2485         
2486         #endif
2487         
2488 #else
2489         __asm 
2490         {
2491                 mov   eax,_Rn
2492                 mov   ecx,_Rm
2493                 bts       eax,ecx
2494                 cmp   eax,0
2495                 setz  [dsp_flag_z]
2496                 sets  [dsp_flag_n]
2497                 mov   res,eax
2498         };
2499 #endif
2500         Rn=res;
2501 }
2502 //////////////////////////////////////////////////////////////////////////////
2503 //
2504 //////////////////////////////////////////////////////////////////////////////
2505 //
2506 //
2507 //
2508 //
2509 //
2510 //
2511 //////////////////////////////////////////////////////////////////////////////
2512 static void dsp_opcode_subqt(void)
2513 {
2514         Rn -= dsp_convert_zero[imm_1];
2515 }
2516 //////////////////////////////////////////////////////////////////////////////
2517 //
2518 //////////////////////////////////////////////////////////////////////////////
2519 //
2520 //
2521 //
2522 //
2523 //
2524 //
2525 //////////////////////////////////////////////////////////////////////////////
2526 static void dsp_opcode_addqt(void)
2527 {
2528         Rn += dsp_convert_zero[imm_1];
2529 }
2530 //////////////////////////////////////////////////////////////////////////////
2531 //
2532 //////////////////////////////////////////////////////////////////////////////
2533 //
2534 //
2535 //
2536 //
2537 //
2538 //
2539 //////////////////////////////////////////////////////////////////////////////
2540 static void dsp_opcode_imacn(void)
2541 {
2542         uint32 res=((int16)Rm) * ((int16)(Rn));
2543         dsp_acc += res;
2544
2545 //////////////////////////////////////////////////////////////////////////////
2546 //
2547 //////////////////////////////////////////////////////////////////////////////
2548 //
2549 //
2550 //
2551 //
2552 //
2553 //
2554 //////////////////////////////////////////////////////////////////////////////
2555 static void dsp_opcode_mtoi(void)
2556 {
2557         uint32 _Rm=Rm;
2558         uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff);
2559         set_flag_z(res);
2560         set_flag_n(res);
2561 }
2562 //////////////////////////////////////////////////////////////////////////////
2563 //
2564 //////////////////////////////////////////////////////////////////////////////
2565 //
2566 //
2567 //
2568 //
2569 //
2570 //
2571 //////////////////////////////////////////////////////////////////////////////
2572 static void dsp_opcode_normi(void)
2573 {
2574         uint32 _Rm = Rm;
2575         uint32 res = 0;
2576
2577         if (_Rm)
2578         {
2579                 while ((_Rm & 0xffc00000) == 0)
2580                 {
2581                         _Rm <<= 1;
2582                         res--;
2583                 }
2584                 while ((_Rm & 0xff800000) != 0)
2585                 {
2586                         _Rm >>= 1;
2587                         res++;
2588                 }
2589         }
2590         Rn = res;
2591         set_flag_z(res);
2592         set_flag_n(res);
2593 }
2594 //////////////////////////////////////////////////////////////////////////////
2595 //
2596 //////////////////////////////////////////////////////////////////////////////
2597 //
2598 //
2599 //
2600 //
2601 //
2602 //
2603 //////////////////////////////////////////////////////////////////////////////
2604 static void dsp_opcode_mmult(void)
2605 {
2606         int count       = dsp_matrix_control&0x0f;
2607         uint32 addr = dsp_pointer_to_matrix; // in the gpu ram
2608         int64 accum = 0;
2609         uint32 res;
2610
2611         if (!(dsp_matrix_control & 0x10))
2612         {
2613                 for (int i = 0; i < count; i++)
2614                 { 
2615                         int16 a;
2616                         if (i&0x01)
2617                                 a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff);
2618                         else
2619                                 a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff);
2620                         int16 b=((int16)dsp_word_read(addr+2));
2621                         accum += a*b;
2622                         addr += 4;
2623                 }
2624         }
2625         else
2626         {
2627                 for (int i = 0; i < count; i++)
2628                 {
2629                         int16 a;
2630                         if (i&0x01)
2631                                 a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff);
2632                         else
2633                                 a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff);
2634                         int16 b=((int16)dsp_word_read(addr+2));
2635                         accum += a*b;
2636                         addr += 4 * count;
2637                 }
2638         }
2639         Rn = res = (int32)accum;
2640         // carry flag to do
2641         set_flag_z(res);
2642         set_flag_n(res);
2643 }
2644 //////////////////////////////////////////////////////////////////////////////
2645 //
2646 //////////////////////////////////////////////////////////////////////////////
2647 //
2648 //
2649 //
2650 //
2651 //
2652 //
2653 //////////////////////////////////////////////////////////////////////////////
2654 static void dsp_opcode_abs(void)
2655 {
2656         uint32 _Rn=Rn;
2657         uint32 res;
2658         
2659         if (_Rn==0x80000000)
2660         {
2661                 set_flag_n(1);
2662         }
2663         else
2664         {
2665                 dsp_flag_c  = ((_Rn&0x80000000)>>31);
2666                 res= Rn =  (_Rn & 0x80000000) ? -_Rn : _Rn;
2667                 reset_flag_n();
2668                 set_flag_z(res);
2669         }
2670 }
2671 //////////////////////////////////////////////////////////////////////////////
2672 //
2673 //////////////////////////////////////////////////////////////////////////////
2674 //
2675 //
2676 //
2677 //
2678 //
2679 //
2680 //////////////////////////////////////////////////////////////////////////////
2681 static void dsp_opcode_div(void)
2682 {
2683         uint32 _Rm=Rm;
2684         uint32 _Rn=Rn;
2685
2686         if (_Rm)
2687         {
2688                 if (dsp_div_control & 1)
2689                 {
2690                         dsp_remain = (((uint64)_Rn) << 16) % _Rm;
2691                         if (dsp_remain&0x80000000)
2692                                 dsp_remain-=_Rm;
2693                         Rn = (((uint64)_Rn) << 16) / _Rm;
2694                 }
2695                 else
2696                 {
2697                         dsp_remain = _Rn % _Rm;
2698                         if (dsp_remain&0x80000000)
2699                                 dsp_remain-=_Rm;
2700                         Rn/=_Rm;
2701                 }
2702         }
2703         else
2704                 Rn=0xffffffff;
2705 }
2706 //////////////////////////////////////////////////////////////////////////////
2707 //
2708 //////////////////////////////////////////////////////////////////////////////
2709 //
2710 //
2711 //
2712 //
2713 //
2714 //
2715 //////////////////////////////////////////////////////////////////////////////
2716 static void dsp_opcode_imultn(void)
2717 {
2718         uint32 res=(int32)(((int16)Rn)*((int16)Rm));
2719         dsp_acc=(int32)res;
2720         set_flag_z(res);
2721         set_flag_n(res);
2722 }
2723 //////////////////////////////////////////////////////////////////////////////
2724 //
2725 //////////////////////////////////////////////////////////////////////////////
2726 //
2727 //
2728 //
2729 //
2730 //
2731 //
2732 //////////////////////////////////////////////////////////////////////////////
2733 static void dsp_opcode_neg(void)
2734 {
2735         uint32 _Rn=Rn;
2736         uint32 res;
2737 #ifdef __PORT__
2738
2739     /*
2740        GCC on WIN32 (more importantly mingw) doesn't know the declared
2741        variables in asm until we put a _ before it.
2742        
2743        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2744     */
2745
2746     #ifdef __GCCWIN32__
2747
2748         asm(
2749         "
2750         subl %1, %2
2751         setc  _dsp_flag_c
2752         setz  _dsp_flag_z
2753         sets  _dsp_flag_n
2754         movl %%eax, %0
2755         "
2756         : "=m"(res)
2757         : "d"(_Rn), "a"(0));
2758         
2759         #else
2760
2761         asm(
2762         "
2763         subl %1, %2
2764         setc  dsp_flag_c
2765         setz  dsp_flag_z
2766         sets  dsp_flag_n
2767         movl %%eax, %0
2768         "
2769         : "=m"(res)
2770         : "d"(_Rn), "a"(0));
2771         
2772         #endif
2773         
2774 #else
2775         __asm 
2776         {
2777                 xor       eax,eax
2778                 mov   edx,_Rn
2779                 sub   eax,edx
2780                 setc  [dsp_flag_c]
2781                 setz  [dsp_flag_z]
2782                 sets  [dsp_flag_n]
2783                 mov       res,eax
2784         };
2785 #endif
2786         Rn=res;
2787 }
2788 //////////////////////////////////////////////////////////////////////////////
2789 //
2790 //////////////////////////////////////////////////////////////////////////////
2791 //
2792 //
2793 //
2794 //
2795 //
2796 //
2797 //////////////////////////////////////////////////////////////////////////////
2798 static void dsp_opcode_shlq(void)
2799 {
2800         uint32 shift=(32-dsp_convert_zero[imm_1]);
2801         uint32 _Rn=Rn;
2802         uint32 res;
2803 #ifdef __PORT__
2804
2805     /*
2806        GCC on WIN32 (more importantly mingw) doesn't know the declared
2807        variables in asm until we put a _ before it.
2808        
2809        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2810     */
2811
2812     #ifdef __GCCWIN32__
2813
2814         asm(
2815         "testl $0x80000000, %2
2816         setnz _dsp_flag_c
2817         shl %%cl, %2
2818         cmpl $0, %2
2819         setz  _dsp_flag_z
2820         sets  _dsp_flag_n
2821         movl %%eax, %0
2822         "
2823         : "=m"(res)
2824         : "c"(shift), "a"(_Rn));
2825         
2826         #else
2827         
2828         asm(
2829         "testl $0x80000000, %2
2830         setnz dsp_flag_c
2831         shl %%cl, %2
2832         cmpl $0, %2
2833         setz  dsp_flag_z
2834         sets  dsp_flag_n
2835         movl %%eax, %0
2836         "
2837         : "=m"(res)
2838         : "c"(shift), "a"(_Rn));
2839
2840         #endif  
2841         
2842 #else
2843         __asm 
2844         {
2845                 mov ecx,shift
2846                 mov eax,_Rn
2847                 test eax,0x80000000
2848                 setnz [dsp_flag_c]
2849                 shl eax,cl
2850                 cmp eax,0
2851                 setz [dsp_flag_z]
2852                 sets [dsp_flag_n]
2853                 mov res,eax
2854         }
2855 #endif
2856         Rn=res;
2857 }
2858 //////////////////////////////////////////////////////////////////////////////
2859 //
2860 //////////////////////////////////////////////////////////////////////////////
2861 //
2862 //
2863 //
2864 //
2865 //
2866 //
2867 //////////////////////////////////////////////////////////////////////////////
2868 static void dsp_opcode_shrq(void)
2869 {
2870         uint32 shift=dsp_convert_zero[imm_1];
2871         uint32 _Rn=Rn;
2872         
2873         uint32 res;
2874 #ifdef __PORT__
2875
2876     /*
2877        GCC on WIN32 (more importantly mingw) doesn't know the declared
2878        variables in asm until we put a _ before it.
2879        
2880        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2881     */
2882
2883     #ifdef __GCCWIN32__
2884
2885         asm(
2886         "testl $0x00000001, %2
2887         setnz _dsp_flag_c
2888         shr %%cl, %2
2889         cmpl $0, %2
2890         setz  _dsp_flag_z
2891         sets  _dsp_flag_n
2892         movl %%eax, %0
2893         "
2894         : "=m"(res)
2895         : "c"(shift), "a"(_Rn));
2896         
2897         #else
2898         
2899         asm(
2900         "testl $0x00000001, %2
2901         setnz dsp_flag_c
2902         shr %%cl, %2
2903         cmpl $0, %2
2904         setz  dsp_flag_z
2905         sets  dsp_flag_n
2906         movl %%eax, %0
2907         "
2908         : "=m"(res)
2909         : "c"(shift), "a"(_Rn));
2910
2911         #endif  
2912
2913 #else
2914         __asm 
2915         {
2916                 mov ecx,shift
2917                 mov eax,_Rn
2918                 test eax,0x00000001
2919                 setnz [dsp_flag_c]
2920                 shr eax,cl
2921                 cmp eax,0
2922                 setz [dsp_flag_z]
2923                 sets [dsp_flag_n]
2924                 mov res,eax
2925         }
2926 #endif
2927         Rn=res;
2928 }
2929 //////////////////////////////////////////////////////////////////////////////
2930 //
2931 //////////////////////////////////////////////////////////////////////////////
2932 //
2933 //
2934 //
2935 //
2936 //
2937 //
2938 //////////////////////////////////////////////////////////////////////////////
2939 static void dsp_opcode_ror(void)
2940 {
2941         uint32 shift=Rm;
2942         uint32 _Rn=Rn;
2943         uint32 res;
2944 #ifdef __PORT__
2945
2946     /*
2947        GCC on WIN32 (more importantly mingw) doesn't know the declared
2948        variables in asm until we put a _ before it.
2949        
2950        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2951     */
2952
2953     #ifdef __GCCWIN32__
2954
2955         asm(
2956         "testl $0x80000000, %2
2957         setnz _dsp_flag_c
2958         ror %%cl, %2
2959         cmpl $0, %2
2960         setz  _dsp_flag_z
2961         sets  _dsp_flag_n
2962         movl %%eax, %0
2963         "
2964         : "=m"(res)
2965         : "c"(shift), "a"(_Rn));
2966         
2967         #else
2968
2969         asm(
2970         "testl $0x80000000, %2
2971         setnz dsp_flag_c
2972         ror %%cl, %2
2973         cmpl $0, %2
2974         setz  dsp_flag_z
2975         sets  dsp_flag_n
2976         movl %%eax, %0
2977         "
2978         : "=m"(res)
2979         : "c"(shift), "a"(_Rn));
2980         
2981         #endif
2982         
2983 #else
2984         __asm 
2985         {
2986                 mov ecx,shift
2987                 mov eax,_Rn
2988                 test eax,0x80000000
2989                 setnz [dsp_flag_c]
2990                 ror eax,cl
2991                 cmp eax,0
2992                 setz [dsp_flag_z]
2993                 sets [dsp_flag_n]
2994                 mov res,eax
2995         }
2996 #endif
2997         Rn=res;
2998 }
2999 //////////////////////////////////////////////////////////////////////////////
3000 //
3001 //////////////////////////////////////////////////////////////////////////////
3002 //
3003 //
3004 //
3005 //
3006 //
3007 //
3008 //////////////////////////////////////////////////////////////////////////////
3009 static void dsp_opcode_rorq(void)
3010 {
3011         uint32 shift=dsp_convert_zero[imm_1&0x1f];
3012         uint32 _Rn=Rn;
3013         uint32 res;
3014 #ifdef __PORT__
3015
3016     /*
3017        GCC on WIN32 (more importantly mingw) doesn't know the declared
3018        variables in asm until we put a _ before it.
3019        
3020        So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
3021     */
3022
3023     #ifdef __GCCWIN32__
3024
3025         asm(
3026         "testl $0x80000000, %2
3027         setnz _dsp_flag_c
3028         ror %%cl, %2
3029         cmpl $0, %2
3030         setz  _dsp_flag_z
3031         sets  _dsp_flag_n
3032         movl %%eax, %0
3033         "
3034         : "=m"(res)
3035         : "c"(shift), "a"(_Rn));
3036         
3037         #else
3038         
3039         asm(
3040         "testl $0x80000000, %2
3041         setnz dsp_flag_c
3042         ror %%cl, %2
3043         cmpl $0, %2
3044         setz  dsp_flag_z
3045         sets  dsp_flag_n
3046         movl %%eax, %0
3047         "
3048         : "=m"(res)
3049         : "c"(shift), "a"(_Rn));
3050
3051         #endif
3052         
3053 #else
3054         __asm 
3055         {
3056                 mov ecx,shift
3057                 mov eax,_Rn
3058                 test eax,0x80000000
3059                 setnz [dsp_flag_c]
3060                 ror eax,cl
3061                 cmp eax,0
3062                 setz [dsp_flag_z]
3063                 sets [dsp_flag_n]
3064                 mov res,eax
3065         }
3066 #endif
3067         Rn=res;
3068 }
3069 //////////////////////////////////////////////////////////////////////////////
3070 //
3071 //////////////////////////////////////////////////////////////////////////////
3072 //
3073 //
3074 //
3075 //
3076 //
3077 //
3078 //////////////////////////////////////////////////////////////////////////////
3079 static void dsp_opcode_sha(void)
3080 {
3081         int32 sRm=(int32)Rm;
3082         uint32 _Rn=Rn;
3083
3084         if (sRm<0)
3085         {
3086                 uint32 shift=-sRm;
3087                 if (shift>=32) shift=32;
3088                 dsp_flag_c=(_Rn&0x80000000)>>31;
3089                 while (shift)
3090                 {
3091                         _Rn<<=1;
3092                         shift--;
3093                 }
3094         }
3095         else
3096         {
3097                 uint32 shift=sRm;
3098                 if (shift>=32) shift=32;
3099                 dsp_flag_c=_Rn&0x1;
3100                 while (shift)
3101                 {
3102                         _Rn=((int32)_Rn)>>1;
3103                         shift--;
3104                 }
3105         }
3106         Rn=_Rn;
3107         set_flag_z(_Rn);
3108         set_flag_n(_Rn);
3109 }
3110 //////////////////////////////////////////////////////////////////////////////
3111 //
3112 //////////////////////////////////////////////////////////////////////////////
3113 //
3114 //
3115 //
3116 //
3117 //
3118 //
3119 //////////////////////////////////////////////////////////////////////////////
3120 static void dsp_opcode_sharq(void)
3121 {
3122         uint32 shift=dsp_convert_zero[imm_1];
3123         uint32 _Rn=Rn;
3124
3125         dsp_flag_c  = (_Rn & 0x1);
3126         while (shift)
3127         {
3128                 _Rn=((int32)_Rn)>>1;
3129                 shift--;
3130         }
3131         Rn=_Rn;
3132         set_flag_z(_Rn);
3133         set_flag_n(_Rn);
3134 }
3135 //////////////////////////////////////////////////////////////////////////////
3136 //
3137 //////////////////////////////////////////////////////////////////////////////
3138 //
3139 //
3140 //
3141 //
3142 //
3143 //
3144 //////////////////////////////////////////////////////////////////////////////
3145 static void dsp_opcode_sh(void)
3146 {
3147         int32 sRm=(int32)Rm;
3148         uint32 _Rn=Rn;
3149
3150         if (sRm<0)
3151         {
3152                 uint32 shift=(-sRm);
3153                 if (shift>=32) shift=32;
3154                 dsp_flag_c=(_Rn&0x80000000)>>31;
3155                 while (shift)
3156                 {
3157                         _Rn<<=1;
3158                         shift--;
3159                 }
3160         }
3161         else
3162         {
3163                 uint32 shift=sRm;
3164                 if (shift>=32) shift=32;
3165                 dsp_flag_c=_Rn&0x1;
3166                 while (shift)
3167                 {
3168                         _Rn>>=1;
3169                         shift--;
3170                 }
3171         }
3172         Rn=_Rn;
3173         set_flag_z(_Rn);
3174         set_flag_n(_Rn);
3175 }
3176
3177 #define CLR_ZN  { dsp_flag_n=0; dsp_flag_z=0; };
3178 #define CLR_ZNC { dsp_flag_c=0; dsp_flag_n=0; dsp_flag_z=0; };
3179 #define SET_Z(r)                        (dsp_flag_z= ((r) == 0))
3180 #define SET_C_ADD(a,b)          (dsp_flag_c= ((UINT32)(b) > (UINT32)(~(a))) << 1)
3181 #define SET_C_SUB(a,b)          (dsp_flag_c= ((UINT32)(b) > (UINT32)(a)) << 1)
3182 #define SET_N(r)                        (dsp_flag_n= (((UINT32)(r) >> 29) & 4))
3183 #define SET_ZN(r)                       SET_N(r); SET_Z(r)
3184 #define SET_ZNC_ADD(a,b,r)      SET_N(r); SET_Z(r); SET_C_ADD(a,b)
3185 #define SET_ZNC_SUB(a,b,r)      SET_N(r); SET_Z(r); SET_C_SUB(a,b)
3186
3187 void dsp_opcode_addqmod(void)   
3188 {
3189         UINT32 r1 = dsp_convert_zero[imm_1];
3190         UINT32 r2 = Rn;
3191         UINT32 res = r2 + r1;
3192         res = (res & (~dsp_modulo)) | (r2 & dsp_modulo);
3193         Rn = res;
3194         CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
3195 }
3196 void dsp_opcode_subqmod(void)   
3197 {
3198         UINT32 r1 = dsp_convert_zero[imm_1];
3199         UINT32 r2 = Rn;
3200         UINT32 res = r2 - r1;
3201         res = (res & (~dsp_modulo)) | (r2 & dsp_modulo);
3202         Rn = res;
3203         
3204         SET_ZNC_SUB(r2,r1,res);
3205 }
3206 void dsp_opcode_mirror(void)    
3207 {
3208         UINT32 r1 = Rn;
3209         UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
3210         Rn = res;
3211         CLR_ZN; SET_ZN(res);
3212 }
3213 void dsp_opcode_sat32s(void)            
3214 {
3215         INT32 r2 = (UINT32)Rn;
3216         INT32 temp = dsp_acc >> 32;
3217         UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2;
3218         Rn = res;
3219         CLR_ZN; SET_ZN(res);
3220 }
3221 void dsp_opcode_sat16s(void)            
3222 {
3223         INT32 r2 = Rn;
3224         UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2;
3225         Rn = res;
3226         CLR_ZN; SET_ZN(res);
3227 }