]> Shamusworld >> Repos - virtualjaguar/blob - src/gpu2.cpp
9496b703b19b29dcbabb222b65f1f1dba379375c
[virtualjaguar] / src / gpu2.cpp
1 //
2 // Alternate GPU core... Testing purposes only!
3 //
4
5 //#include "gpu.h"
6
7 // Random stuff from GPU.CPP
8
9 /*static uint8 * gpu_ram_8;
10 extern uint32 gpu_pc;
11 static uint32 gpu_acc;
12 static uint32 gpu_remain;
13 static uint32 gpu_hidata;
14 static uint32 gpu_flags;
15 static uint32 gpu_matrix_control;
16 static uint32 gpu_pointer_to_matrix;
17 static uint32 gpu_data_organization;
18 static uint32 gpu_control;
19 static uint32 gpu_div_control;
20 static uint8 gpu_flag_z, gpu_flag_n, gpu_flag_c;
21 static uint8 gpu_alternate_flag_z, gpu_alternate_flag_n, gpu_alternate_flag_c;
22 static uint32 * gpu_reg;
23 static uint32 * gpu_alternate_reg;
24 static uint32 * gpu_reg_bank_0;
25 static uint32 * gpu_reg_bank_1;
26
27 static uint32 gpu_opcode_first_parameter;
28 static uint32 gpu_opcode_second_parameter;*/
29
30 //
31
32 const INT32 qtable[32] = 
33 { 32, 1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
34   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
35
36 const INT32 sqtable[32] = 
37 { 0,   1,   2,   3,   4,   5,   6,   7,  8,  9,  10, 11, 12, 13, 14, 15,
38   -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1 };
39
40 const UINT8 gpu_opcode_times[64] =
41 {  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
42    3, 3, 1, 3, 1,18, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
43    3, 3, 2, 2, 2, 2, 3, 6, 6, 4, 6, 6, 6, 1, 1, 1,
44    1, 2, 2, 2, 1, 1,20, 3, 3, 1, 6, 6, 2, 2, 3, 3 };
45
46 UINT8 jump_condition[32][8];
47
48 void gpu2_init(void)
49 {
50         memset(jump_condition, 0, 32 * 8 * sizeof(UINT8));
51
52         for(int j=0; j<32; j++)
53         {
54                 for(int i=0; i<8; i++)
55                 {
56                         UINT8 r = 1;
57                         if(j & 0x1) {
58                                 if(i & 0x1)
59                                         r = 0;
60                         }
61                         if(j & 0x2) {
62                                 if(!(i & 0x1))
63                                         r = 0;
64                         }
65                         if(j & 0x4) {
66                                 if(i & (0x2 << (j >> 4)))
67                                         r = 0;
68                         }
69                         if(j & 0x8) {
70                                 if(!(i & (0x2 << (j >> 4))))
71                                         r = 0;
72                         }
73                         jump_condition[j][i] = r;
74                 }
75         }
76 }
77
78 //              case 22:  // ABS
79 void opcode_abs(void)
80 {
81                                 int d = RN;
82                                 if(d & 0x80000000) {
83                                         d = abs(d);
84                                         gpu_flag_c = 1;
85                                 } else {
86                                         gpu_flag_c = 0;
87                                 }
88                                 RN = d;
89                                 gpu_flag_z = d == 0 ? 1 : 0;
90                                 gpu_flag_n = 0;
91 }
92
93 //              case 0:   // ADD
94 void opcode_add(void)
95 {
96                                 int s = RM;
97                                 int d = RN;
98                                 INT64 r = s + d;
99                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
100                                 RN = r;
101                                 gpu_flag_z = RN == 0 ? 1 : 0;
102                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
103 }
104 //                      break;
105 //              case 1:   // ADDC
106 void opcode_addc(void)
107 {
108                                 int s = RM;
109                                 int d = RN;
110                                 int c = gpu_flag_c;
111                                 INT64 r = s + d + c;
112                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
113                                 RN = r;
114                                 gpu_flag_z = RN == 0 ? 1 : 0;
115                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
116 }
117 //                  break;
118 //              case 2:   // ADDQ
119 void opcode_addq(void)
120 {
121                                 int s = qtable[IMM_1];
122                                 int d = RN;
123                                 INT64 r = s + d;
124                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
125                                 RN = r;
126                                 gpu_flag_z = RN == 0 ? 1 : 0;
127                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
128 }
129 //                  break;
130 //              case 3:   // ADDQT
131 void opcode_addqt(void)
132 {
133                                 RN += qtable[IMM_1];
134 }
135 //                      break;
136 //              case 9:   // AND
137 void opcode_and(void)
138 {
139                                 RN &= RM;
140                                 gpu_flag_z = RN == 0 ? 1 : 0;
141                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
142 }
143 //                      break;
144 //              case 15:  // BLCR
145 void opcode_bclr(void)
146 {
147                                 RN &= ~(1 << IMM_1);
148                                 gpu_flag_z = RN == 0 ? 1 : 0;
149                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
150 }
151 //                  break;
152 //              case 14:  // BSET
153 void opcode_bset(void)
154 {
155                                 RN |= 1 << IMM_1;
156                                 gpu_flag_z = RN == 0 ? 1 : 0;
157                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
158 }
159 //                      break;
160 //              case 13:  // BTST
161 void opcode_btst(void)
162 {
163                                 gpu_flag_z = RN & (1 << IMM_1) ? 0 : 1;
164 }
165 //                  break;
166 //              case 30:  // CMP
167 void opcode_cmp(void)
168 {
169                                 int s = RM;
170                                 int d = RN;
171                                 gpu_flag_c = (unsigned int)d < (unsigned int)s;
172                                 d -= s;
173                                 gpu_flag_z = d == 0 ? 1 : 0;
174                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
175 }
176 //                      break;
177 //              case 31:  // CMPQ
178 void opcode_cmpq(void)
179 {
180                                 int s = sqtable[IMM_1];
181                                 int d = RN;
182                                 gpu_flag_c = (unsigned int)d < (unsigned int)s;
183                                 d -= s;
184                                 gpu_flag_z = d == 0 ? 1 : 0;
185                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
186 }
187 //                      break;
188 //              case 21:  // DIV
189 void opcode_div(void)
190 {
191                                 if(RM != 0) {
192                                         if(gpu_div_control == 0) {
193                                                 UINT32 q = RN;
194                                                 UINT32 d = RM;
195                                                 UINT32 r = q / d;
196                                                 UINT32 r2 = q % d;
197                                                 RN = r;
198                                                 gpu_remain = r2;
199                                         } else {
200                                                 UINT64 q = (UINT64)(RN)<<16;
201                                                 UINT64 d = (UINT64)(RM);
202                                                 UINT32 r = (UINT64)(q / d);
203                                                 UINT32 r2 = (UINT64)(q % d);
204                                                 RN = r;
205                                                 gpu_remain = r2;
206                                         }
207                                 }
208 }
209 //                      break;
210 //              case 20:  // IMACN   
211 void opcode_imacn(void)
212 {
213                                 short s = RM;
214                                 short d = RN;
215                                 int r = s * d;
216                                 gpu_acc += r;
217 }
218 //                      break;
219 //              case 17:  // IMULT
220 void opcode_imult(void)
221 {
222                                 short s = RM;
223                                 short d = RN;
224                                 int r = s * d;
225                                 RN = r;
226                                 gpu_flag_z = r == 0 ? 1 : 0;
227                                 gpu_flag_n = r & 0x80000000 ? 1 : 0;
228 }
229 //                      break;
230 //              case 18:  // IMULTN
231 void opcode_imultn(void)
232 {
233                                 short s = RM;
234                                 short d = RN;
235                                 int r = s * d;
236                                 gpu_acc = r;
237                                 gpu_flag_z = r == 0 ? 1 : 0;
238                                 gpu_flag_n = r & 0x80000000 ? 1 : 0;
239 }
240 //                      break;
241 //        case 53:  // JR;
242 void opcode_jr(void)
243 {
244                         UINT32 dw = (gpu_flag_z & 0x1) | ((gpu_flag_n & 0x1) << 2) | ((gpu_flag_c & 0x1) << 1);
245                         if (jump_condition[IMM_2][dw])
246                         {
247 if (gpu_start_log)
248         fprintf(log_get(), "    --> JR: Branch taken. ");
249                                 signed int offset = IMM_1 & 0x10 ? (0xFFFFFFF0 | (IMM_1 & 0xF)) : (IMM_1 & 0xF);
250                                 UINT32 delayed_jump_address = gpu_pc + 2 + (offset * 2);
251 //                              delayed_jump = 1;
252                                 gpu_pc += 2;
253                                 gpu_exec(1);
254 //                              gpu_pc = delayed_jump_address;
255                                 gpu_pc = delayed_jump_address - 2;
256                         }
257 }
258 //                      break;
259 //              case 52:  // JUMP
260 void opcode_jump(void)
261 {
262                         UINT32 dw = (gpu_flag_z & 0x1) | ((gpu_flag_n & 0x1) << 2) | ((gpu_flag_c & 0x1) << 1);
263                         if (jump_condition[IMM_2][dw])
264                         {
265 if (gpu_start_log)
266         fprintf(log_get(), "    --> JUMP: Branch taken. ");
267                                 UINT32 delayed_jump_address = RM & 0xFFFFFE;
268 //                              delayed_jump = 1;
269                                 gpu_pc += 2;
270                                 gpu_exec(1);
271 //                              gpu_pc = delayed_jump_address;
272                                 gpu_pc = delayed_jump_address - 2;
273                         }
274 }
275 //                      break;
276 //              case 41:  // LOAD
277 void opcode_load(void)
278 {
279                                 UINT32 address = RM;
280                                 if(address >= 0xF03000 && address < 0xF04000) {
281 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
282                                         RN = gpu_long_read(address);
283                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
284 //                                      RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16);
285                                         RN = gpu_long_read(address-0x8000);
286                                 } else {
287 //                                      RN = ReadMem32(address);
288                                         RN = jaguar_long_read(address);
289                                 }
290 }
291 //                      break;
292 //              case 43:  // LOAD (R14+m)
293 void opcode_load_r14_indexed(void)
294 {
295                                 UINT32 address = gpu_reg[14] + (qtable[IMM_1] << 2);
296                                 if(address >= 0xF03000 && address < 0xF04000) {
297 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
298                                         RN = gpu_long_read(address);
299                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
300 //                                      RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16);
301                                         RN = gpu_long_read(address-0x8000);
302                                 } else {
303 //                                      RN = ReadMem32(address);
304                                         RN = jaguar_long_read(address);
305                                 }
306 }
307 //                      break;
308 //              case 44:  // LOAD (R15+m)
309 void opcode_load_r15_indexed(void)
310 {
311                                 UINT32 address = gpu_reg[15] + (qtable[IMM_1] << 2);
312                                 if(address >= 0xF03000 && address < 0xF04000) {
313 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
314                                         RN = gpu_long_read(address);
315                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
316 //                                      RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16);
317                                         RN = gpu_long_read(address-0x8000);
318                                 } else {
319 //                                      RN = ReadMem32(address);
320                                         RN = jaguar_long_read(address);
321                                 }
322 }
323 //                      break; 
324 //              case 58:  // LOAD (R14+Rm)
325 void opcode_load_r14_ri(void)
326 {
327                                 UINT32 address = gpu_reg[14] + RM;
328                                 if(address >= 0xF03000 && address < 0xF04000) {
329 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
330                                         RN = gpu_long_read(address);
331                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
332 //                                      RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16);
333                                         RN = gpu_long_read(address-0x8000);
334                                 } else {
335 //                                      RN = ReadMem32(address);
336                                         RN = jaguar_long_read(address);
337                                 }
338 }
339 //                      break;
340 //              case 59:  // LOAD (R15+Rm)
341 void opcode_load_r15_ri(void)
342 {
343                                 UINT32 address = gpu_reg[15] + RM;
344                                 if(address >= 0xF03000 && address < 0xF04000) {
345 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
346                                         RN = gpu_long_read(address);
347                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
348 //                                      RN = _rotl(*(UINT32*)(&MEM[address-0x8000]),16);
349                                         RN = gpu_long_read(address-0x8000);
350                                 } else {
351 //                                      RN = ReadMem32(address);
352                                         RN = jaguar_long_read(address);
353                                 }
354 }
355 //                      break;
356 //              case 39:  // LOADB
357 void opcode_loadb(void)
358 {
359                         if(RM >= 0xF03000 && RM < 0xF04000) {
360 //                              RN = ReadMem32(RM);
361                                 RN = gpu_long_read(RM);
362                         } else {
363 //                              RN = ReadMem8(RM);
364                                 RN = jaguar_byte_read(RM);
365                         }
366 }
367 //                      break;
368 //              case 40:  // LOADW
369 void opcode_loadw(void)
370 {
371                         if(RM >= 0xF03000 && RM < 0xF04000) {
372 //                              RN = ReadMem32(RM);
373                                 RN = gpu_long_read(RM);
374                         } else {
375 //                              RN = ReadMem16(RM);
376                                 RN = jaguar_word_read(RM);
377                         }
378 }
379 //                      break;
380 //              case 42:  // LOADP
381 void opcode_loadp(void)
382 {
383                         if(RM >= 0xF03000 && RM < 0xF04000) {
384 //                              RN = ReadMem32(RM);
385                                 RN = gpu_long_read(RM);
386                         } else {
387 //                              RN = ReadMem32(RM);
388 //                              gpu_hidata = ReadMem32(RM+4);
389                                 RN = gpu_long_read(RM);
390                                 gpu_hidata = gpu_long_read(RM + 4);
391                         }
392 }
393 //                      break;
394 //              case 34:  // MOVE
395 void opcode_move(void)
396 {
397                                 RN = RM;
398 }
399 //                      break;
400 //              case 51:  // MOVE PC,Rn
401 void opcode_move_pc(void)
402 {
403                                 RN = gpu_pc;
404 }
405 //                      break;
406 //              case 37:  // MOVEFA
407 void opcode_movefa(void)
408 {
409                                 RN = gpu_alternate_reg[IMM_1];
410 }
411 //                      break;
412 //              case 38:  // MOVEI
413 void opcode_movei(void)
414 {
415         // This instruction is followed by 32-bit value in LSW / MSW format...
416 //      RN = (uint32)gpu_word_read(gpu_pc) | ((uint32)gpu_word_read(gpu_pc + 2) << 16);
417 //      gpu_pc += 4;
418 //                                      RN = _rotl(*(UINT32*)(&MEM[address]),16);
419 //                              RN = *(UINT32*)(&MEM[gpu_pc+2]);
420                                 RN = _rotl(gpu_long_read(gpu_pc + 2), 16);
421                                 gpu_pc += 4;
422 }
423 //                      break;
424 //        case 35:  // MOVEQ
425 void opcode_moveq(void)
426 {
427                                 RN = IMM_1;
428 }
429 //                      break;
430 //              case 36:  // MOVETA
431 void opcode_moveta(void)
432 {
433                                 gpu_alternate_reg[IMM_2] = RM;
434 }
435 //                      break;
436 //              case 55:  // MTOI
437 void opcode_mtoi(void)
438 {
439                                 int d = RN & 0x7FFFFF;
440                                 if(RN & 0x80000000) {
441                                         d |= 0xFF800000;
442                                 }
443                                 RN = d;
444                                 gpu_flag_z = d == 0 ? 1 : 0;
445                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
446 }
447 //                      break;
448 //              case 16:  // MULT
449 void opcode_mult(void)
450 {
451                                 unsigned short s = RM;
452                                 unsigned short d = RN;
453                                 int r = s * d;
454                                 RN = r;
455                                 gpu_flag_z = r == 0 ? 1 : 0;
456                                 gpu_flag_n = r & 0x80000000 ? 1 : 0;
457 }
458 //                      break;
459 //              case 54:  // MMULT
460 void opcode_mmult(void)
461 {
462                                 int size = gpu_matrix_control & 0xF;
463                                 int address = gpu_pointer_to_matrix;
464                                 int add;
465                                 if (gpu_matrix_control & 0x10)
466                                         add = size * 4;
467                                 else
468                                         add = 4;
469                                 int result = 0;
470                                 for(int i=0; i<size; i++)
471                                 {
472                                         short m, r;
473 //                                      m = ReadMem16(address+2);
474                                         m = gpu_word_read(address + 2);
475                                         if (i & 0x1)
476                                                 r = gpu_alternate_reg[IMM_1+(i>>1)] >> 16;
477                                         else
478                                                 r = (gpu_alternate_reg[IMM_1+(i>>1)] & 0xFFFF);
479                                         result += (int)(r * m);
480 /*                                      int mult = r*m;
481                                         __asm {
482                                                 mov eax,[result]
483                                                 mov edx,[mult]
484                                                 add eax,edx
485                                                 setc [gpu_flag_c]
486                                                 mov [result],eax
487                                         }*/
488
489                                         address += add;
490                                 }
491                                 RN = result;
492                                 gpu_flag_n = (result < 0) ? 1 : 0;
493                                 gpu_flag_z = (result == 0) ? 1 : 0;
494 }
495 //                      break;
496 //              case 8:   // NEG
497 void opcode_neg(void)
498 {
499                                 int s = 0;
500                                 int d = RN;
501                                 gpu_flag_c = d - s < d;
502                                 d = s - d;
503                                 RN = d;
504                                 gpu_flag_z = d == 0 ? 1 : 0;
505                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
506 }
507 //                      break;
508 //              case 57:  // NOP
509 void opcode_nop(void)
510 {
511 }
512 //                      break;
513 //              case 56:  // NORMI
514 void opcode_normi(void)
515 {
516                                 /*unsigned int d = RN;
517                                 int r = 0;
518                                 while ((d & 0xffc00000) == 0)
519                                 {
520                                         d <<= 1;
521                                         r--;
522                                 }
523                                 while ((d & 0xff800000) != 0)
524                                 {
525                                         d >>= 1;
526                                         r++;
527                                 }
528                                 RN = r;
529                                 gpu_flag_z = r == 0 ? 1 : 0;
530                                 gpu_flag_n = r & 0x80000000 ? 1 : 0;*/
531                                 RN = 0;
532 }
533 //                      break;
534 //              case 12:  // NOT
535 void opcode_not(void)
536 {
537                                 int d = RN;
538                                 d ^= 0xFFFFFFFF;
539                                 RN = d;
540                                 gpu_flag_z = d == 0 ? 1 : 0;
541                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
542 }
543 //                      break;
544 //              case 10:  // OR
545 void opcode_or(void)
546 {
547                                 int s = RM;
548                                 int d = RN;
549                                 d |= s;
550                                 RN = d;
551                                 gpu_flag_z = d == 0 ? 1 : 0;
552                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
553 }
554 //                      break;
555 //              case 63:  // PACK / UNPACK
556 void opcode_pack(void)
557 {
558                                 if (IMM_1 == 0)
559                                 {
560                                         int c1 = (RN & 0x3C00000) >> 10;
561                                         int c2 = (RN & 0x1E000) >> 5;
562                                         int y = (RN & 0xFF);
563                                         RN = c1 | c2 | y;
564                                 }
565                                 else
566                                 {
567                                         int c1 = (RN & 0xF000) << 10;
568                                         int c2 = (RN & 0xF00) << 5;
569                                         int y = (RN & 0xFF);
570                                         RN = c1 | c2 | y;
571                                 }
572 }
573 //                      break;
574 //              case 19:  // RESMAC
575 void opcode_resmac(void)
576 {
577                                 RN = gpu_acc;
578 }
579 //                      break;
580 //              case 28:  // ROR
581 void opcode_ror(void)
582 {
583                                 unsigned int d = RN;
584                                 int shift = RM;
585                                 gpu_flag_c = d & 0x80000000 ? 1 : 0;
586                                 d = _rotr(d, shift);
587                                 RN = d;
588                                 gpu_flag_z = d == 0 ? 1 : 0;
589                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
590 }
591 //                      break;
592 //              case 29:  // RORQ
593 void opcode_rorq(void)
594 {
595                                 unsigned int d = RN;
596                                 int shift = qtable[IMM_1];
597                                 gpu_flag_c = d & 0x80000000 ? 1 : 0;
598                                 d = _rotr(d, shift);
599                                 RN = d;
600                                 gpu_flag_z = d == 0 ? 1 : 0;
601                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
602 }
603 //                      break;
604 //              case 32:  // SAT8
605 void opcode_sat8(void)
606 {
607                                 int d = RN;
608                                 if(d < 0)
609                                         d = 0;
610                                 if(d > 255)
611                                         d = 255;
612                                 RN = d;
613                                 gpu_flag_z = d == 0 ? 1 : 0;
614                                 gpu_flag_n = 0;
615 }
616 //                      break;
617 //              case 33:  // SAT16
618 void opcode_sat16(void)
619 {
620                                 int d = RN;
621                                 if(d < 0)
622                                         d = 0;
623                                 if(d > 65535)
624                                         d = 65535;
625                                 RN = d;
626                                 gpu_flag_z = d == 0 ? 1 : 0;
627                                 gpu_flag_n = 0;
628 }
629 //                      break;
630 //              case 62:  // SAT24
631 void opcode_sat24(void)
632 {
633                                 int d = RN;
634                                 if (d < 0)
635                                         d = 0;
636                                 if (d > 16777215)
637                                         d = 16777215;
638                                 RN = d;
639                                 gpu_flag_z = d == 0 ? 1 : 0;
640                                 gpu_flag_n = 0;
641 }
642 //                      break;
643 //              case 23:  // SH
644 void opcode_sh(void)
645 {
646                                 int shift = RM;
647                                 if (shift & 0x80000000)
648                                 {
649                                         gpu_flag_c = RN & 0x80000000 ? 1 : 0;
650                                         UINT32 d = RN;
651                                         d <<= 0-shift;
652                                         RN = d;
653                                         gpu_flag_z = RN == 0 ? 1 : 0;
654                                         gpu_flag_n = RN & 0x80000000 ? 1 : 0;
655                                 }
656                                 else
657                                 {
658                                         gpu_flag_c = RN & 0x1 ? 1 : 0;
659                                         UINT32 d = RN;
660                                         d >>= shift;
661                                         RN = d;
662                                         gpu_flag_z = RN == 0 ? 1 : 0;
663                                         gpu_flag_n = RN & 0x80000000 ? 1 : 0;
664                                 }
665 }
666 //                      break;
667 //              case 26:  // SHA
668 void opcode_sha(void)
669 {
670                                 int shift = RM;
671                                 if(shift & 0x80000000) {
672                                         gpu_flag_c = RN & 0x80000000 ? 1 : 0;
673                                         INT32 d = RN;
674                                         d <<= 0-shift;
675                                         RN = d;
676                                         gpu_flag_z = RN == 0 ? 1 : 0;
677                                         gpu_flag_n = RN & 0x80000000 ? 1 : 0;
678                                 } else {
679                                         gpu_flag_c = RN & 0x1 ? 1 : 0;
680                                         INT32 d = RN;
681                                         d >>= shift;
682                                         RN = d;
683                                         gpu_flag_z = RN == 0 ? 1 : 0;
684                                         gpu_flag_n = RN & 0x80000000 ? 1 : 0;
685                                 }
686 }
687 //                      break;
688 //              case 27:  // SHARQ
689 void opcode_sharq(void)
690 {
691                                 INT32 d = RN;
692                                 int shift = qtable[IMM_1];
693                                 gpu_flag_c = d & 0x1 ? 1 : 0;
694                                 d >>= shift;
695                                 RN = d;
696                                 gpu_flag_z = d == 0 ? 1 : 0;
697                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
698 }
699 //                      break;
700 //              case 24:  // SHLQ
701 void opcode_shlq(void)
702 {
703                                 UINT32 d = RN;
704                                 int shift = 32 - IMM_1;
705                                 gpu_flag_c = d & 0x80000000 ? 1 : 0;
706                                 d <<= shift;
707                                 RN = d;
708                                 gpu_flag_z = d == 0 ? 1 : 0;
709                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
710 }
711 //                      break;
712  //       case 25:  // SHRQ
713 void opcode_shrq(void)
714 {
715                                 UINT32 d = RN;
716                                 int shift = qtable[IMM_1];
717                                 gpu_flag_c = d & 0x1 ? 1 : 0;
718                                 d >>= shift;
719                                 RN = d;
720                                 gpu_flag_z = d == 0 ? 1 : 0;
721                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
722 }
723 //                      break;
724 //              case 47:  // STORE
725 void opcode_store(void)
726 {
727                                 UINT32 address = RM;
728                                 if(address >= 0xF03000 && address < 0xF04000) {
729 //                                      *(UINT32*)(&MEM[address]) = _rotl(RN,16);
730                                         gpu_long_write(address, RN);
731                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
732 //                                      *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16);
733                                         gpu_long_write(address-0x8000, RN);
734                                 } else {
735 //                                      WriteMem32(address,RN);
736                                         jaguar_long_write(address, RN);
737                                 }
738 }
739 //                      break;
740 //              case 49:  // STORE (R14+m)
741 void opcode_store_r14_indexed(void)
742 {
743                                 UINT32 address = gpu_reg[14] + (qtable[IMM_1] << 2);
744                                 if(address >= 0xF03000 && address < 0xF04000) {
745 //                                      *(UINT32*)(&MEM[address]) = _rotl(RN,16);
746                                         gpu_long_write(address, RN);
747                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
748 //                                      *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16);
749                                         gpu_long_write(address-0x8000, RN);
750                                 } else {
751 //                                      WriteMem32(address,RN);
752                                         jaguar_long_write(address, RN);
753                                 }
754 }
755 //                      break;
756 //              case 50:  // STORE (R15+m)
757 void opcode_store_r15_indexed(void)
758 {
759                                 UINT32 address = gpu_reg[15] + (qtable[IMM_1] << 2);
760                                 if(address >= 0xF03000 && address < 0xF04000) {
761 //                                      *(UINT32*)(&MEM[address]) = _rotl(RN,16);
762                                         gpu_long_write(address, RN);
763                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
764 //                                      *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16);
765                                         gpu_long_write(address-0x8000, RN);
766                                 } else {
767 //                                      WriteMem32(address,RN);
768                                         jaguar_long_write(address, RN);
769                                 }
770 }
771 //                      break;
772 //              case 60:  // STORE (R14+Rm)
773 void opcode_store_r14_ri(void)
774 {
775                                 UINT32 address = gpu_reg[14] + RM;
776                                 if(address >= 0xF03000 && address < 0xF04000) {
777 //                                      *(UINT32*)(&MEM[address]) = _rotl(RN,16);
778                                         gpu_long_write(address, RN);
779                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
780 //                                      *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16);
781                                         gpu_long_write(address-0x8000, RN);
782                                 } else {
783 //                                      WriteMem32(address,RN);
784                                         jaguar_long_write(address, RN);
785                                 }
786 }
787 //                      break;
788 //              case 61:  // STORE (R15+Rm)
789 void opcode_store_r15_ri(void)
790 {
791                                 UINT32 address = gpu_reg[15] + RM;
792                                 if(address >= 0xF03000 && address < 0xF04000) {
793 //                                      *(UINT32*)(&MEM[address]) = _rotl(RN,16);
794                                         gpu_long_write(address, RN);
795                                 } else if(address >= 0xF0B000 && address < 0xF0C000) {
796 //                                      *(UINT32*)(&MEM[address-0x8000]) = _rotl(RN,16);
797                                         gpu_long_write(address-0x8000, RN);
798                                 } else {
799 //                                      WriteMem32(address,RN);
800                                         jaguar_long_write(address, RN);
801                                 }
802 }
803 //                      break;
804 //              case 45:  // STOREB
805 void opcode_storeb(void)
806 {
807                         if(RM>0xF03000 && RM<0xF04000) {
808 //                              WriteMem32(RM,RN);
809                                 gpu_long_write(RM, RN);
810                         } else {
811 //                              WriteMem8(RM,(UINT8)RN);
812                                 jaguar_byte_write(RM, (UINT8)RN);
813                         }
814 }
815 //                      break;
816 //              case 46:  // STOREW
817 void opcode_storew(void)
818 {
819                         if(RM>0xF03000 && RM<0xF04000) {
820 //                              WriteMem32(RM,RN);
821                                 gpu_long_write(RM, RN);
822                         } else {
823 //                              WriteMem16(RM,(WORD)RN);
824                                 jaguar_word_write(RM, (UINT16)RN);
825                         }
826 }
827 //                      break;
828 //              case 48:  // STOREP
829 void opcode_storep(void)
830 {
831                         if (RM>0xF03000 && RM<0xF04000)
832                         {
833 //                              WriteMem32(RM,RN);
834                                 gpu_long_write(RM, RN);
835                         }
836                         else
837                         {
838 //                              WriteMem32(RM,RN);
839 //                              WriteMem32(RM+4,gpu_hidata);
840                                 jaguar_long_write(RM, RN);
841                                 jaguar_long_write(RM + 4, gpu_hidata);
842                         }
843 }
844 //                      break;
845 //              case 4:   // SUB
846 void opcode_sub(void)
847 {
848                                 int s = RM;
849                                 int d = RN;
850                                 INT64 r = d - s;
851                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
852                                 RN = r;
853                                 gpu_flag_z = RN == 0 ? 1 : 0;
854                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
855 }
856 //                      break;
857 //              case 5:   // SUBC
858 void opcode_subc(void)
859 {
860                                 int s = RM;
861                                 int d = RN;
862                                 int c = gpu_flag_c;
863                                 INT64 r = d - s - c;
864                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
865                                 RN = r;
866                                 gpu_flag_z = RN == 0 ? 1 : 0;
867                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
868 }
869 //                      break;
870 //              case 6:   // SUBQ
871 void opcode_subq(void)
872 {
873                                 int s = qtable[IMM_1];
874                                 int d = RN;
875                                 INT64 r = d - s;
876                                 gpu_flag_c = r & 0x100000000 ? 1 : 0;
877                                 RN = r;
878                                 gpu_flag_z = RN == 0 ? 1 : 0;
879                                 gpu_flag_n = RN & 0x80000000 ? 1 : 0;
880 }
881 //                      break;
882 //              case 7:   // SUBQT
883 void opcode_subqt(void)
884 {
885                                 RN -= qtable[IMM_1];
886 }
887 //                      break;
888 //              case 11:  // XOR
889 void opcode_xor(void)
890 {
891                                 int s = RM;
892                                 int d = RN;
893                                 d ^= s;
894                                 RN = d;
895                                 gpu_flag_z = d == 0 ? 1 : 0;
896                                 gpu_flag_n = d & 0x80000000 ? 1 : 0;
897 }