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