5 static UINT8 * condition_table=0;
7 #define CONDITION(x) condition_table[(x) + ((jaguar_FLAGS & 7) << 5)]
8 static UINT16 * mirror_table;
13 /*###################################################################################################
15 **#################################################################################################*/
17 #define ROPCODE(pc) (gpu_word_read(pc))
21 static const UINT32 convert_zero[32] =
22 { 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 };
24 static uint32 cnt_opcode=0;
25 int jaguargpu_execute(int cycles)
28 /* allocate the mirror table */
31 mirror_table = (UINT16*)malloc(65536 * sizeof(mirror_table[0]));
33 /* fill in the mirror table */
35 for (i = 0; i < 65536; i++)
36 mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) |
37 ((i >> 11) & 0x0004) | ((i >> 9) & 0x0008) |
38 ((i >> 7) & 0x0010) | ((i >> 5) & 0x0020) |
39 ((i >> 3) & 0x0040) | ((i >> 1) & 0x0080) |
40 ((i << 1) & 0x0100) | ((i << 3) & 0x0200) |
41 ((i << 5) & 0x0400) | ((i << 7) & 0x0800) |
42 ((i << 9) & 0x1000) | ((i << 11) & 0x2000) |
43 ((i << 13) & 0x4000) | ((i << 15) & 0x8000);
48 condition_table = (uint8*)malloc(32 * 8 * sizeof(condition_table[0]));
50 /* fill in the condition table */
52 for (i = 0; i < 8; i++)
53 for (j = 0; j < 32; j++)
57 if (i & ZFLAG) result = 0;
59 if (!(i & ZFLAG)) result = 0;
61 if (i & (CFLAG << (j >> 4))) result = 0;
63 if (!(i & (CFLAG << (j >> 4)))) result = 0;
64 condition_table[i * 32 + j] = result;
67 /* if we're halted, we shouldn't be here */
76 gpu_flag_c=(gpu_flag_c?1:0);
77 gpu_flag_z=(gpu_flag_z?1:0);
78 gpu_flag_n=(gpu_flag_n?1:0);
80 // fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n);
83 /* instruction fetch */
84 jaguar_op = ROPCODE(gpu_pc);
87 /* parse the instruction */
88 (*gpu_op_table[jaguar_op >> 10])();
91 } while ((jaguar_icount > 0)&&(gpu_running));
93 return cycles - jaguar_icount;
95 /*###################################################################################################
97 **#################################################################################################*/
101 int dreg = jaguar_op & 31;
102 UINT32 res = gpu_reg[dreg];
104 if (res & 0x80000000)
106 gpu_reg[dreg] = res = -res;
114 int dreg = jaguar_op & 31;
115 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
116 UINT32 r2 = gpu_reg[dreg];
117 UINT32 res = r2 + r1;
119 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
122 void addc_rn_rn(void)
124 int dreg = jaguar_op & 31;
125 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
126 UINT32 r2 = gpu_reg[dreg];
127 UINT32 res = r2 + r1 + gpu_flag_c;
129 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
134 int dreg = jaguar_op & 31;
135 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
136 UINT32 r2 = gpu_reg[dreg];
137 UINT32 res = r2 + r1;
139 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
142 void addqmod_n_rn(void) /* DSP only */
144 int dreg = jaguar_op & 31;
145 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
146 UINT32 r2 = gpu_reg[dreg];
147 UINT32 res = r2 + r1;
148 res = (res & ~gpu_hidata) | (r2 & ~gpu_hidata);
150 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
153 void addqt_n_rn(void)
155 int dreg = jaguar_op & 31;
156 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
157 UINT32 r2 = gpu_reg[dreg];
158 UINT32 res = r2 + r1;
164 int dreg = jaguar_op & 31;
165 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
166 UINT32 r2 = gpu_reg[dreg];
167 UINT32 res = r2 & r1;
174 int dreg = jaguar_op & 31;
175 UINT32 r1 = (jaguar_op >> 5) & 31;
176 UINT32 r2 = gpu_reg[dreg];
177 UINT32 res = r2 & ~(1 << r1);
184 int dreg = jaguar_op & 31;
185 UINT32 r1 = (jaguar_op >> 5) & 31;
186 UINT32 r2 = gpu_reg[dreg];
187 UINT32 res = r2 | (1 << r1);
194 UINT32 r1 = (jaguar_op >> 5) & 31;
195 UINT32 r2 = gpu_reg[jaguar_op & 31];
196 CLR_Z; gpu_flag_z= (~r2 >> r1) & 1;
201 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
202 UINT32 r2 = gpu_reg[jaguar_op & 31];
203 UINT32 res = r2 - r1;
204 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
209 UINT32 r1 = (INT8)(jaguar_op >> 2) >> 3;
210 UINT32 r2 = gpu_reg[jaguar_op & 31];
211 UINT32 res = r2 - r1;
212 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
217 int dreg = jaguar_op & 31;
218 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
219 UINT32 r2 = gpu_reg[dreg];
222 if (gpu_div_control & 1)
224 gpu_reg[dreg] = ((UINT64)r2 << 16) / r1;
225 gpu_remain = ((UINT64)r2 << 16) % r1;
229 gpu_reg[dreg] = r2 / r1;
230 gpu_remain = r2 % r1;
234 gpu_reg[dreg] = 0xffffffff;
241 void imacn_rn_rn(void)
243 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
244 UINT32 r2 = gpu_reg[jaguar_op & 31];
245 gpu_acc += (INT64)((INT16)r1 * (INT16)r2);
248 void imult_rn_rn(void)
250 int dreg = jaguar_op & 31;
251 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
252 UINT32 r2 = gpu_reg[dreg];
253 UINT32 res = (INT16)r1 * (INT16)r2;
258 void imultn_rn_rn(void)
260 int dreg = jaguar_op & 31;
261 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
262 UINT32 r2 = gpu_reg[dreg];
263 UINT32 res = (INT16)r1 * (INT16)r2;
264 gpu_acc = (INT32)res;
267 jaguar_op = ROPCODE(gpu_pc);
268 while ((jaguar_op >> 10) == 20)
270 r1 = gpu_reg[(jaguar_op >> 5) & 31];
271 r2 = gpu_reg[jaguar_op & 31];
272 gpu_acc += (INT64)((INT16)r1 * (INT16)r2);
274 jaguar_op = ROPCODE(gpu_pc);
276 if ((jaguar_op >> 10) == 19)
279 gpu_reg[jaguar_op & 31] = (UINT32)gpu_acc;
287 gpu_flag_c?(gpu_flag_c=1):(gpu_flag_c=0);
288 gpu_flag_z?(gpu_flag_z=1):(gpu_flag_z=0);
289 gpu_flag_n?(gpu_flag_n=1):(gpu_flag_n=0);
291 jaguar_FLAGS=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z;
293 if (CONDITION(jaguar_op & 31))
295 INT32 r1 = (INT8)((jaguar_op >> 2) & 0xf8) >> 2;
296 UINT32 newpc = gpu_pc + r1;
297 jaguar_op = ROPCODE(gpu_pc);
298 // fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n);
300 (*gpu_op_table[jaguar_op >> 10])();
302 jaguar_icount -= 3; /* 3 wait states guaranteed */
306 void jump_cc_rn(void)
310 gpu_flag_c?(gpu_flag_c=1):(gpu_flag_c=0);
311 gpu_flag_z?(gpu_flag_z=1):(gpu_flag_z=0);
312 gpu_flag_n?(gpu_flag_n=1):(gpu_flag_n=0);
314 jaguar_FLAGS=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z;
315 if (CONDITION(jaguar_op & 31))
317 UINT8 reg = (jaguar_op >> 5) & 31;
319 /* special kludge for risky code in the cojag DSP interrupt handlers */
320 UINT32 newpc = /*(jaguar_icount == bankswitch_icount) ?*/ gpu_reg[reg];// : gpu_reg[reg];
321 jaguar_op = ROPCODE(gpu_pc);
322 // fprintf(log_get(),"%i 0x%.8x [%i %i %i]\n",cnt_opcode++,gpu_pc,gpu_flag_c,gpu_flag_z,gpu_flag_n);
324 (*gpu_op_table[jaguar_op >> 10])();
326 jaguar_icount -= 3; /* 3 wait states guaranteed */
330 void load_rn_rn(void)
332 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
333 gpu_reg[jaguar_op & 31] = gpu_long_read(r1);
336 void load_r14n_rn(void)
338 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
339 gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[14] + 4 * r1);
342 void load_r15n_rn(void)
344 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
345 gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[15] + 4 * r1);
348 void load_r14rn_rn(void)
350 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
351 gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[14] + r1);
354 void load_r15rn_rn(void)
356 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
357 gpu_reg[jaguar_op & 31] = gpu_long_read(gpu_reg[15] + r1);
360 void loadb_rn_rn(void)
362 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
363 gpu_reg[jaguar_op & 31] = gpu_byte_read(r1);
366 void loadw_rn_rn(void)
368 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
369 gpu_reg[jaguar_op & 31] = gpu_word_read(r1);
372 void loadp_rn_rn(void) /* GPU only */
374 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
375 gpu_hidata = gpu_word_read(r1);
376 gpu_reg[jaguar_op & 31] = gpu_word_read(r1+4);
379 void mirror_rn(void) /* DSP only */
381 int dreg = jaguar_op & 31;
382 UINT32 r1 = gpu_reg[dreg];
383 UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
388 void mmult_rn_rn(void)
390 int count = gpu_matrix_control & 15, i;
391 int sreg = (jaguar_op >> 5) & 31;
392 int dreg = jaguar_op & 31;
393 UINT32 addr = gpu_pointer_to_matrix;
397 if (!(gpu_matrix_control & 0x10))
399 for (i = 0; i < count; i++)
401 accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr);
407 for (i = 0; i < count; i++)
409 accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr);
413 gpu_reg[dreg] = res = (UINT32)accum;
417 void move_rn_rn(void)
419 gpu_reg[jaguar_op & 31] = gpu_reg[(jaguar_op >> 5) & 31];
422 void move_pc_rn(void)
424 gpu_reg[jaguar_op & 31] = jaguar_ppc;
427 void movefa_rn_rn(void)
429 gpu_reg[jaguar_op & 31] = gpu_alternate_reg[(jaguar_op >> 5) & 31];
432 void movei_n_rn(void)
434 UINT32 res = ROPCODE(gpu_pc) | (ROPCODE(gpu_pc + 2) << 16);
436 gpu_reg[jaguar_op & 31] = res;
439 void moveq_n_rn(void)
441 gpu_reg[jaguar_op & 31] = (jaguar_op >> 5) & 31;
444 void moveta_rn_rn(void)
446 gpu_alternate_reg[jaguar_op & 31] = gpu_reg[(jaguar_op >> 5) & 31];
449 void mtoi_rn_rn(void)
451 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
452 gpu_reg[jaguar_op & 31] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff);
455 void mult_rn_rn(void)
457 int dreg = jaguar_op & 31;
458 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
459 UINT32 r2 = gpu_reg[dreg];
460 UINT32 res = (UINT16)r1 * (UINT16)r2;
467 int dreg = jaguar_op & 31;
468 UINT32 r2 = gpu_reg[dreg];
471 CLR_ZNC; SET_ZNC_SUB(0,r2,res);
478 void normi_rn_rn(void)
480 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
482 while ((r1 & 0xffc00000) == 0)
487 while ((r1 & 0xff800000) != 0)
492 gpu_reg[jaguar_op & 31] = res;
498 int dreg = jaguar_op & 31;
499 UINT32 res = ~gpu_reg[dreg];
506 int dreg = jaguar_op & 31;
507 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
508 UINT32 r2 = gpu_reg[dreg];
509 UINT32 res = r1 | r2;
514 void pack_rn(void) /* GPU only */
516 int dreg = jaguar_op & 31;
517 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
518 UINT32 r2 = gpu_reg[dreg];
520 if (r1 == 0) /* PACK */
521 res = ((r2 >> 10) & 0xf000) | ((r2 >> 5) & 0x0f00) | (r2 & 0xff);
523 res = ((r2 & 0xf000) << 10) | ((r2 & 0x0f00) << 5) | (r2 & 0xff);
530 gpu_reg[jaguar_op & 31] = (UINT32)gpu_acc;
535 int dreg = jaguar_op & 31;
536 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31] & 31;
537 UINT32 r2 = gpu_reg[dreg];
538 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
540 CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 30) & 2;
545 int dreg = jaguar_op & 31;
546 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
547 UINT32 r2 = gpu_reg[dreg];
548 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
550 CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 >> 30) & 2;
553 void sat8_rn(void) /* GPU only */
555 int dreg = jaguar_op & 31;
556 INT32 r2 = gpu_reg[dreg];
557 UINT32 res = (r2 < 0) ? 0 : (r2 > 255) ? 255 : r2;
562 void sat16_rn(void) /* GPU only */
564 int dreg = jaguar_op & 31;
565 INT32 r2 = gpu_reg[dreg];
566 UINT32 res = (r2 < 0) ? 0 : (r2 > 65535) ? 65535 : r2;
571 void sat16s_rn(void) /* DSP only */
573 int dreg = jaguar_op & 31;
574 INT32 r2 = gpu_reg[dreg];
575 UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2;
580 void sat24_rn(void) /* GPU only */
582 int dreg = jaguar_op & 31;
583 INT32 r2 = gpu_reg[dreg];
584 UINT32 res = (r2 < 0) ? 0 : (r2 > 16777215) ? 16777215 : r2;
589 void sat32s_rn(void) /* DSP only */
591 int dreg = jaguar_op & 31;
592 INT32 r2 = (UINT32)gpu_reg[dreg];
593 INT32 temp = gpu_acc >> 32;
594 UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2;
601 int dreg = jaguar_op & 31;
602 INT32 r1 = (INT32)gpu_reg[(jaguar_op >> 5) & 31];
603 UINT32 r2 = gpu_reg[dreg];
609 res = (r1 <= -32) ? 0 : (r2 << -r1);
610 gpu_flag_c= (r2 >> 30) & 2;
614 res = (r1 >= 32) ? 0 : (r2 >> r1);
615 gpu_flag_c= (r2 << 1) & 2;
623 int dreg = jaguar_op & 31;
624 INT32 r1 = (INT32)gpu_reg[(jaguar_op >> 5) & 31];
625 UINT32 r2 = gpu_reg[dreg];
631 res = (r1 <= -32) ? 0 : (r2 << -r1);
632 gpu_flag_c= (r2 >> 30) & 2;
636 res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1);
637 gpu_flag_c= (r2 << 1) & 2;
643 void sharq_n_rn(void)
645 int dreg = jaguar_op & 31;
646 INT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
647 UINT32 r2 = gpu_reg[dreg];
648 UINT32 res = (INT32)r2 >> r1;
650 CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 << 1) & 2;
655 int dreg = jaguar_op & 31;
656 INT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
657 UINT32 r2 = gpu_reg[dreg];
658 UINT32 res = r2 << (32 - r1);
660 CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 >> 30) & 2;
665 int dreg = jaguar_op & 31;
666 INT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
667 UINT32 r2 = gpu_reg[dreg];
668 UINT32 res = r2 >> r1;
670 CLR_ZNC; SET_ZN(res); gpu_flag_c= (r2 << 1) & 2;
673 void store_rn_rn(void)
675 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
676 gpu_long_write(r1, gpu_reg[jaguar_op & 31]);
679 void store_rn_r14n(void)
681 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
682 gpu_long_write(gpu_reg[14] + r1 * 4, gpu_reg[jaguar_op & 31]);
685 void store_rn_r15n(void)
687 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
688 gpu_long_write(gpu_reg[15] + r1 * 4, gpu_reg[jaguar_op & 31]);
691 void store_rn_r14rn(void)
693 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
694 gpu_long_write(gpu_reg[14] + r1, gpu_reg[jaguar_op & 31]);
697 void store_rn_r15rn(void)
699 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
700 gpu_long_write(gpu_reg[15] + r1, gpu_reg[jaguar_op & 31]);
703 void storeb_rn_rn(void)
705 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
706 gpu_byte_write(r1, gpu_reg[jaguar_op & 31]);
709 void storew_rn_rn(void)
711 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
712 gpu_word_write(r1, gpu_reg[jaguar_op & 31]);
715 void storep_rn_rn(void) /* GPU only */
717 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
718 gpu_long_write(r1, gpu_hidata);
719 gpu_long_write(r1+4, gpu_reg[jaguar_op & 31]);
724 int dreg = jaguar_op & 31;
725 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
726 UINT32 r2 = gpu_reg[dreg];
727 // fprintf(log_get(),"r%i=0x%.8x r%i=0x%.8x\n",(jaguar_op >> 5) & 31,r1,dreg,r2);
728 UINT32 res = r2 - r1;
730 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
733 void subc_rn_rn(void)
735 int dreg = jaguar_op & 31;
736 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
737 UINT32 r2 = gpu_reg[dreg];
738 UINT32 res = r2 - r1 - gpu_flag_c;
740 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
745 int dreg = jaguar_op & 31;
746 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
747 UINT32 r2 = gpu_reg[dreg];
748 UINT32 res = r2 - r1;
750 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
753 void subqmod_n_rn(void) /* DSP only */
755 int dreg = jaguar_op & 31;
756 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
757 UINT32 r2 = gpu_reg[dreg];
758 UINT32 res = r2 - r1;
759 // res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]);
761 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
764 void subqt_n_rn(void)
766 int dreg = jaguar_op & 31;
767 UINT32 r1 = convert_zero[(jaguar_op >> 5) & 31];
768 UINT32 r2 = gpu_reg[dreg];
769 UINT32 res = r2 - r1;
775 int dreg = jaguar_op & 31;
776 UINT32 r1 = gpu_reg[(jaguar_op >> 5) & 31];
777 UINT32 r2 = gpu_reg[dreg];
778 UINT32 res = r1 ^ r2;