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