5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups, endian wrongness, and bad ASM amelioration by James L. Hammons
7 // Note: Endian wrongness probably stems from the MAME origins of this emu and
8 // the braindead way in which MAME handles memory. :-)
13 #define CINT0FLAG 0x00200
14 #define CINT1FLAG 0x00400
15 #define CINT2FLAG 0x00800
16 #define CINT3FLAG 0x01000
17 #define CINT4FLAG 0x02000
18 #define CINT04FLAGS (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG)
20 extern int start_logging;
22 static void gpu_opcode_add(void);
23 static void gpu_opcode_addc(void);
24 static void gpu_opcode_addq(void);
25 static void gpu_opcode_addqt(void);
26 static void gpu_opcode_sub(void);
27 static void gpu_opcode_subc(void);
28 static void gpu_opcode_subq(void);
29 static void gpu_opcode_subqt(void);
30 static void gpu_opcode_neg(void);
31 static void gpu_opcode_and(void);
32 static void gpu_opcode_or(void);
33 static void gpu_opcode_xor(void);
34 static void gpu_opcode_not(void);
35 static void gpu_opcode_btst(void);
36 static void gpu_opcode_bset(void);
37 static void gpu_opcode_bclr(void);
38 static void gpu_opcode_mult(void);
39 static void gpu_opcode_imult(void);
40 static void gpu_opcode_imultn(void);
41 static void gpu_opcode_resmac(void);
42 static void gpu_opcode_imacn(void);
43 static void gpu_opcode_div(void);
44 static void gpu_opcode_abs(void);
45 static void gpu_opcode_sh(void);
46 static void gpu_opcode_shlq(void);
47 static void gpu_opcode_shrq(void);
48 static void gpu_opcode_sha(void);
49 static void gpu_opcode_sharq(void);
50 static void gpu_opcode_ror(void);
51 static void gpu_opcode_rorq(void);
52 static void gpu_opcode_cmp(void);
53 static void gpu_opcode_cmpq(void);
54 static void gpu_opcode_sat8(void);
55 static void gpu_opcode_sat16(void);
56 static void gpu_opcode_move(void);
57 static void gpu_opcode_moveq(void);
58 static void gpu_opcode_moveta(void);
59 static void gpu_opcode_movefa(void);
60 static void gpu_opcode_movei(void);
61 static void gpu_opcode_loadb(void);
62 static void gpu_opcode_loadw(void);
63 static void gpu_opcode_load(void);
64 static void gpu_opcode_loadp(void);
65 static void gpu_opcode_load_r14_indexed(void);
66 static void gpu_opcode_load_r15_indexed(void);
67 static void gpu_opcode_storeb(void);
68 static void gpu_opcode_storew(void);
69 static void gpu_opcode_store(void);
70 static void gpu_opcode_storep(void);
71 static void gpu_opcode_store_r14_indexed(void);
72 static void gpu_opcode_store_r15_indexed(void);
73 static void gpu_opcode_move_pc(void);
74 static void gpu_opcode_jump(void);
75 static void gpu_opcode_jr(void);
76 static void gpu_opcode_mmult(void);
77 static void gpu_opcode_mtoi(void);
78 static void gpu_opcode_normi(void);
79 static void gpu_opcode_nop(void);
80 static void gpu_opcode_load_r14_ri(void);
81 static void gpu_opcode_load_r15_ri(void);
82 static void gpu_opcode_store_r14_ri(void);
83 static void gpu_opcode_store_r15_ri(void);
84 static void gpu_opcode_sat24(void);
85 static void gpu_opcode_pack(void);
87 uint8 gpu_opcode_cycles[64] =
107 void (*gpu_opcode[64])()=
109 gpu_opcode_add, gpu_opcode_addc, gpu_opcode_addq, gpu_opcode_addqt,
110 gpu_opcode_sub, gpu_opcode_subc, gpu_opcode_subq, gpu_opcode_subqt,
111 gpu_opcode_neg, gpu_opcode_and, gpu_opcode_or, gpu_opcode_xor,
112 gpu_opcode_not, gpu_opcode_btst, gpu_opcode_bset, gpu_opcode_bclr,
113 gpu_opcode_mult, gpu_opcode_imult, gpu_opcode_imultn, gpu_opcode_resmac,
114 gpu_opcode_imacn, gpu_opcode_div, gpu_opcode_abs, gpu_opcode_sh,
115 gpu_opcode_shlq, gpu_opcode_shrq, gpu_opcode_sha, gpu_opcode_sharq,
116 gpu_opcode_ror, gpu_opcode_rorq, gpu_opcode_cmp, gpu_opcode_cmpq,
117 gpu_opcode_sat8, gpu_opcode_sat16, gpu_opcode_move, gpu_opcode_moveq,
118 gpu_opcode_moveta, gpu_opcode_movefa, gpu_opcode_movei, gpu_opcode_loadb,
119 gpu_opcode_loadw, gpu_opcode_load, gpu_opcode_loadp, gpu_opcode_load_r14_indexed,
120 gpu_opcode_load_r15_indexed, gpu_opcode_storeb, gpu_opcode_storew, gpu_opcode_store,
121 gpu_opcode_storep, gpu_opcode_store_r14_indexed, gpu_opcode_store_r15_indexed, gpu_opcode_move_pc,
122 gpu_opcode_jump, gpu_opcode_jr, gpu_opcode_mmult, gpu_opcode_mtoi,
123 gpu_opcode_normi, gpu_opcode_nop, gpu_opcode_load_r14_ri, gpu_opcode_load_r15_ri,
124 gpu_opcode_store_r14_ri, gpu_opcode_store_r15_ri, gpu_opcode_sat24, gpu_opcode_pack,
127 static uint8 * gpu_ram_8;
128 //static uint16 *gpu_ram_16;
129 //static uint32 *gpu_ram_32;
132 static uint32 gpu_pc;
133 static uint32 gpu_acc;
134 static uint32 gpu_remain;
135 static uint32 gpu_hidata;
136 static uint32 gpu_flags;
137 static uint32 gpu_matrix_control;
138 static uint32 gpu_pointer_to_matrix;
139 static uint32 gpu_data_organization;
140 static uint32 gpu_control;
141 static uint32 gpu_div_control;
142 static uint8 gpu_flag_z;
143 static uint8 gpu_flag_n;
144 static uint8 gpu_flag_c;
145 static uint8 gpu_alternate_flag_z;
146 static uint8 gpu_alternate_flag_n;
147 static uint8 gpu_alternate_flag_c;
148 static uint32 * gpu_reg;
149 static uint32 * gpu_alternate_reg;
150 static uint32 * gpu_reg_bank_0;
151 static uint32 * gpu_reg_bank_1;
153 static uint32 gpu_opcode_first_parameter;
154 static uint32 gpu_opcode_second_parameter;
156 #define GPU_RUNNING (gpu_control & 0x01)
158 #define Rm gpu_reg[gpu_opcode_first_parameter]
159 #define Rn gpu_reg[gpu_opcode_second_parameter]
160 #define alternate_Rm gpu_alternate_reg[gpu_opcode_first_parameter]
161 #define alternate_Rn gpu_alternate_reg[gpu_opcode_second_parameter]
162 #define imm_1 gpu_opcode_first_parameter
163 #define imm_2 gpu_opcode_second_parameter
165 #define set_flag_z(r) gpu_flag_z = (r==0);
166 #define set_flag_n(r) gpu_flag_n = ((r&0x80000000)>>31);
168 #define reset_flag_z() gpu_flag_z = 0;
169 #define reset_flag_n() gpu_flag_n = 0;
170 #define reset_flag_c() gpu_flag_c = 0;
172 #define CLR_Z (gpu_flag_z = 0)
173 #define CLR_ZN (gpu_flag_z = gpu_flag_n = 0)
174 #define CLR_ZNC (gpu_flag_z = gpu_flag_n = gpu_flag_c = 0)
175 #define SET_Z(r) (gpu_flag_z = ((r) == 0))
176 #define SET_N(r) (gpu_flag_n = (((UINT32)(r) >> 31) & 0x01))
177 #define SET_C_ADD(a,b) (gpu_flag_c = ((UINT32)(b) > (UINT32)(~(a))))
178 #define SET_C_SUB(a,b) (gpu_flag_c = ((UINT32)(b) > (UINT32)(a)))
179 #define SET_ZN(r) SET_N(r); SET_Z(r)
180 #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
181 #define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
183 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 };
185 uint8 * branch_condition_table = 0;
186 #define branch_condition(x) branch_condition_table[(x) + ((jaguar_flags & 7) << 5)]
188 uint32 gpu_opcode_use[64];
190 void gpu_update_register_banks(void);
192 char *gpu_opcode_str[64]=
194 "add", "addc", "addq", "addqt",
195 "sub", "subc", "subq", "subqt",
196 "neg", "and", "or", "xor",
197 "not", "btst", "bset", "bclr",
198 "mult", "imult", "imultn", "resmac",
199 "imacn", "div", "abs", "sh",
200 "shlq", "shrq", "sha", "sharq",
201 "ror", "rorq", "cmp", "cmpq",
202 "sat8", "sat16", "move", "moveq",
203 "moveta", "movefa", "movei", "loadb",
204 "loadw", "load", "loadp", "load_r14_indexed",
205 "load_r15_indexed", "storeb", "storew", "store",
206 "storep", "store_r14_indexed","store_r15_indexed","move_pc",
207 "jump", "jr", "mmult", "mtoi",
208 "normi", "nop", "load_r14_ri", "load_r15_ri",
209 "store_r14_ri", "store_r15_ri", "sat24", "pack",
212 static uint32 gpu_in_exec = 0;
213 static uint32 gpu_releaseTimeSlice_flag = 0;
216 void gpu_releaseTimeslice(void)
218 gpu_releaseTimeSlice_flag = 1;
221 uint32 gpu_get_pc(void)
226 void build_branch_condition_table(void)
228 #define ZFLAG 0x00001
229 #define CFLAG 0x00002
230 #define NFLAG 0x00004
232 if (!branch_condition_table)
234 branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(branch_condition_table[0]));
236 if (branch_condition_table)
238 for(int i=0; i<8; i++)
240 for(int j=0; j<32; j++)
250 if (i & (CFLAG << (j >> 4)))
253 if (!(i & (CFLAG << (j >> 4))))
255 branch_condition_table[i * 32 + j] = result;
263 // GPU byte access (read)
266 unsigned gpu_byte_read(unsigned int offset)
268 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
269 return gpu_ram_8[offset & 0xFFF];
270 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
272 uint32 data = gpu_long_read(offset & 0xFFFFFFFC);
274 if ((offset & 0x03) == 0)
276 else if ((offset & 0x03) == 1)
277 return (data >> 16) & 0xFF;
278 else if ((offset & 0x03) == 2)
279 return (data >> 8) & 0xFF;
280 else if ((offset & 0x03) == 3)
284 return jaguar_byte_read(offset);
288 // GPU word access (read)
291 unsigned gpu_word_read(unsigned int offset)
293 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
296 uint16 data = ((uint16)gpu_ram_8[offset] << 8) | (uint16)gpu_ram_8[offset+1];
299 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
301 // This looks and smells wrong...
302 // But it *might* be OK...
303 if (offset & 0x01) // Catch cases 1 & 3... (unaligned read)
304 return (gpu_byte_read(offset) << 8) | gpu_byte_read(offset+1);
306 uint32 data = gpu_long_read(offset & 0xFFFFFFFC);
308 if (offset & 0x02) // Cases 0 & 2...
309 return data & 0xFFFF;
314 return jaguar_word_read(offset);
318 // GPU dword access (read)
321 unsigned gpu_long_read(unsigned int offset)
324 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
327 return ((uint32)gpu_ram_8[offset] << 24) | ((uint32)gpu_ram_8[offset+1] << 16)
328 | ((uint32)gpu_ram_8[offset+2] << 8) | (uint32)gpu_ram_8[offset+3];
330 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
336 gpu_flag_c = (gpu_flag_c ? 1 : 0);
337 gpu_flag_z = (gpu_flag_z ? 1 : 0);
338 gpu_flag_n = (gpu_flag_n ? 1 : 0);
340 gpu_flags = (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
342 return gpu_flags & 0xFFFFC1FF;
344 return gpu_matrix_control;
346 return gpu_pointer_to_matrix;
348 return gpu_data_organization;
357 default: // unaligned long read
363 // to prevent any lock-ups
366 return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
370 // GPU byte access (write)
373 void gpu_byte_write(unsigned offset, unsigned data)
375 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
377 gpu_ram_8[offset & 0xFFF] = data;
378 if (gpu_in_exec == 0)
380 // s68000releaseTimeslice();
381 m68k_end_timeslice();
382 dsp_releaseTimeslice();
386 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
388 uint32 reg = offset & 0x1C;
389 int bytenum = offset & 0x03;
391 //This is definitely wrong!
392 if ((reg >= 0x1C) && (reg <= 0x1F))
393 gpu_div_control = (gpu_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
396 uint32 old_data = gpu_long_read(offset & 0xFFFFFFC);
397 bytenum = 3 - bytenum; // convention motorola !!!
398 old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
399 gpu_long_write(offset & 0xFFFFFFC, old_data);
403 // fprintf(log_get(),"gpu: writing %.2x at 0x%.8x\n",data,offset);
404 jaguar_byte_write(offset, data);
408 // GPU word access (write)
411 void gpu_word_write(unsigned offset, unsigned data)
414 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
417 gpu_ram_8[offset & 0xFFF] = (data>>8) & 0xFF;
418 gpu_ram_8[(offset+1) & 0xFFF] = data & 0xFF;
419 if (gpu_in_exec == 0)
421 // s68000releaseTimeslice();
422 m68k_end_timeslice();
423 dsp_releaseTimeslice();
427 if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
429 if (offset & 0x01) // This is supposed to weed out unaligned writes, but does nothing...
434 if ((offset & 0x1C) == 0x1C)
436 //This doesn't look right either--handles cases 1, 2, & 3 all the same!
438 gpu_div_control = (gpu_div_control&0xFFFF0000) | (data&0xFFFF);
440 gpu_div_control = (gpu_div_control&0xFFFF) | ((data&0xFFFF)<<16);
444 uint32 old_data = gpu_long_read(offset & 0xFFFFFFC);
446 old_data = (old_data & 0xFFFF0000) | (data & 0xFFFF);
448 old_data = (old_data & 0xFFFF) | ((data & 0xFFFF) << 16);
449 gpu_long_write(offset & 0xFFFFFFC, old_data);
453 // fprintf(log_get(),"gpu: writing %.4x at 0x%.8x\n",data,offset);
454 jaguar_word_write(offset, data);
458 // GPU dword access (write)
461 void gpu_long_write(unsigned offset, unsigned data)
464 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
466 gpu_ram_8[offset & 0xFFF] = (data >> 24) & 0xFF;
467 gpu_ram_8[(offset+1) & 0xFFF] = (data >> 16) & 0xFF;
468 gpu_ram_8[(offset+2) & 0xFFF] = (data >> 8) & 0xFF;
469 gpu_ram_8[(offset+3) & 0xFFF] = data & 0xFF;
472 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
479 gpu_flags=(data&(~0x08))|(gpu_flags&0x08); // update dsp_flags, but keep imask unchanged
482 gpu_flag_z = gpu_flags & 0x01;
483 gpu_flag_c = (gpu_flags>>1) & 0x01;
484 gpu_flag_n = (gpu_flags>>2) & 0x01;
485 gpu_update_register_banks();
486 gpu_control &= ~((gpu_flags & CINT04FLAGS) >> 3);
490 gpu_matrix_control = data;
493 gpu_pointer_to_matrix=data;
496 gpu_data_organization=data;
499 gpu_pc = data; /*fprintf(log_get(),"setting gpu pc to 0x%.8x\n",gpu_pc);*/
503 uint32 gpu_was_running = GPU_RUNNING;
505 data &= (~0x7C0); // disable writes to irq pending
508 fprintf(log_get(),"gpu pc is 0x%.8x\n",gpu_pc);
512 // check for GPU->CPU interrupt
515 // fprintf(log_get(),"GPU->CPU interrupt\n");
516 if (tom_irq_enabled(IRQ_GPU))
518 if ((tom_irq_enabled(IRQ_GPU)) && (jaguar_interrupt_handler_is_valid(64)))
520 tom_set_pending_gpu_int();
521 // s68000interrupt(7,64);
522 // s68000flushInterrupts();
523 m68k_set_irq(7); // Set 68000 NMI
524 gpu_releaseTimeslice();
527 uint32 addr=jaguar_word_read(((IRQ_GPU+64)<<2)+0);
529 addr|=jaguar_word_read(((IRQ_GPU+64)<<2)+2);
530 if ((addr)&&(jaguar_interrupt_handler_is_valid(IRQ_GPU+64)))
532 s68000interrupt(7,IRQ_GPU+64);
533 s68000flushInterrupts();
539 // check for CPU->GPU interrupt
542 //fprintf(log_get(),"CPU->GPU interrupt\n");
543 gpu_set_irq_line(0, 1);
544 // s68000releaseTimeslice();
545 m68k_end_timeslice();
546 dsp_releaseTimeslice();
552 //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not ");
554 gpu_control = (gpu_control & 0x107C0) | (data & (~0x107C0));
556 // if gpu wasn't running but is now running, execute a few cycles
557 #ifndef GPU_SINGLE_STEPPING
558 if ((!gpu_was_running) && (GPU_RUNNING))
561 if (gpu_control & 0x18)
563 #endif // #ifndef GPU_SINGLE_STEPPING
565 fprintf(log_get(), "Write to GPU CTRL: %08X ", data);
567 fprintf(log_get(), "-- Starting to run at %08X...", gpu_pc);
568 fprintf(log_get(), "\n");
569 #endif // #ifdef GPU_DEBUG
576 gpu_div_control = data;
578 // default: // unaligned long write
584 // fprintf(log_get(),"gpu: writing %.8x at 0x%.8x\n",data,offset);
585 jaguar_word_write(offset, (data >> 16) & 0xFFFF);
586 jaguar_word_write(offset+2, data & 0xFFFF);
589 void gpu_update_register_banks(void)
592 int bank = (gpu_flags & 0x4000);
594 // 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);
599 if ((!bank && (gpu_reg_bank_0 != gpu_reg)) || (bank && (gpu_reg_bank_1 != gpu_reg)))
601 // fprintf(log_get(),"\tswitching to bank %i\n",bank?1:0);
602 for(int i=0; i<32; i++)
605 gpu_reg[i] = gpu_alternate_reg[i];
606 gpu_alternate_reg[i] = temp;
611 gpu_flag_z = gpu_alternate_flag_z;
612 gpu_alternate_flag_z = temp;
615 gpu_flag_n = gpu_alternate_flag_n;
616 gpu_alternate_flag_n = temp;
619 gpu_flag_c = gpu_alternate_flag_c;
620 gpu_alternate_flag_c = temp;
624 gpu_reg_bank_0 = gpu_reg;
625 gpu_reg_bank_1 = gpu_alternate_reg;
629 gpu_reg_bank_0 = gpu_alternate_reg;
630 gpu_reg_bank_1 = gpu_reg;
635 // fprintf(log_get(),"\tnot switching banks\n");
639 void gpu_check_irqs(void)
641 int bits, mask, which = 0;
643 // get the active interrupt bits
644 bits = (gpu_control >> 6) & 0x1F;
645 bits |= (gpu_control >> 10) & 0x20;
647 // get the interrupt mask
648 mask = (gpu_flags >> 4) & 0x1F;
649 mask |= (gpu_flags >> 11) & 0x20;
651 // bail if nothing is available
656 // determine which interrupt
657 if (bits & 0x01) which = 0;
658 if (bits & 0x02) which = 1;
659 if (bits & 0x04) which = 2;
660 if (bits & 0x08) which = 3;
661 if (bits & 0x10) which = 4;
662 if (bits & 0x20) which = 5;
668 fprintf(log_get(),"gpu: generating irg %i\n",which);
670 // set the interrupt flag
672 gpu_update_register_banks();
674 // subqt #4,r31 ; pre-decrement stack pointer
675 // move pc,r30 ; address of interrupted code
676 // store r30,(r31) ; store return address
678 gpu_reg[30] = gpu_pc - 2;
679 gpu_long_write(gpu_reg[31], gpu_pc - 2);
681 // movei #service_address,r30 ; pointer to ISR entry
682 // jump (r30) ; jump to ISR
684 gpu_pc = gpu_work_ram_base;
685 gpu_pc += which * 0x10;
686 gpu_reg[30] = gpu_pc;
689 void gpu_set_irq_line(int irqline, int state)
692 fprintf(log_get(),"gpu: setting irg line %i\n",irqline);
693 int mask = 0x40 << irqline;
694 gpu_control &= ~mask;
705 memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work ram");
706 // gpu_ram_16=(uint16*)gpu_ram_8;
707 // gpu_ram_32=(uint32*)gpu_ram_8;
709 memory_malloc_secure((void **)&gpu_reg, 32*sizeof(int32), "GPU bank 0 regs");
710 memory_malloc_secure((void **)&gpu_alternate_reg, 32*sizeof(int32), "GPU bank 1 regs");
712 build_branch_condition_table();
720 gpu_acc = 0x00000000;
721 gpu_remain = 0x00000000;
722 gpu_hidata = 0x00000000;
723 gpu_flags = 0x00040000;
724 gpu_matrix_control = 0x00000000;
725 gpu_pointer_to_matrix = 0x00000000;
726 gpu_data_organization = 0xFFFFFFFF;
727 gpu_control = 0x00012800;
728 gpu_div_control = 0x00000000;
731 for(int i=0; i<32; i++)
733 gpu_reg[i] = 0x00000000;
734 gpu_alternate_reg[i] = 0x00000000;
737 gpu_reg_bank_0 = gpu_reg;
738 gpu_reg_bank_1 = gpu_alternate_reg;
739 // gpu_reg_bank_1 = gpu_reg;
740 // gpu_reg_bank_0 = gpu_alternate_reg;
746 gpu_alternate_flag_z = 0;
747 gpu_alternate_flag_n = 0;
748 gpu_alternate_flag_c = 0;
750 memset(gpu_ram_8, 0xFF, 0x1000);
755 uint32 gpu_read_pc(void)
760 void gpu_reset_stats(void)
762 for(uint32 i=0; i<64; i++)
763 gpu_opcode_use[i] = 0;
768 fprintf(log_get(), "GPU: stopped at PC=%08X (GPU %s running)\n", gpu_pc, GPU_RUNNING ? "was" : "wasn't");
770 // get the active interrupt bits
771 int bits = (gpu_control >> 6) & 0x1F;
772 bits |= (gpu_control >> 10) & 0x20;
774 // get the interrupt mask
775 int mask = (gpu_flags >> 4) & 0x1F;
776 mask |= (gpu_flags >> 11) & 0x20;
779 fprintf(log_get(), "GPU: ibits=0x%.8x imask=0x%.8x\n", bits, mask);
780 // fprintf(log_get(),"\nregisters bank 0\n");
781 // for (int j=0;j<8;j++)
783 // fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
784 // (j<<2)+0,gpu_reg[(j<<2)+0],
785 // (j<<2)+1,gpu_reg[(j<<2)+1],
786 // (j<<2)+2,gpu_reg[(j<<2)+2],
787 // (j<<2)+3,gpu_reg[(j<<2)+3]);
790 // fprintf(log_get(),"registers bank 1\n");
793 // fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
794 // (j<<2)+0,gpu_alternate_reg[(j<<2)+0],
795 // (j<<2)+1,gpu_alternate_reg[(j<<2)+1],
796 // (j<<2)+2,gpu_alternate_reg[(j<<2)+2],
797 // (j<<2)+3,gpu_alternate_reg[(j<<2)+3]);
800 fprintf(log_get(),"---[GPU code at 00F03000]---------------------------\n");
801 static char buffer[512];
803 for(int i=0; i<4096; i++)
806 j += dasmjag(JAGUAR_GPU, buffer, j);
807 fprintf(log_get(),"\t%08X: %s\n", oldj, buffer);
810 fprintf(log_get(), "---[GPU code at %08X]---------------------------\n", gpu_pc);
812 for(int i=0; i<4096; i++)
815 j += dasmjag(JAGUAR_GPU, buffer, j);
816 fprintf(log_get(), "\t%08X: %s\n", oldj, buffer);
819 fprintf(log_get(), "gpu opcodes use:\n");
820 for(int i=0; i<64; i++)
822 if (gpu_opcode_use[i])
823 fprintf(log_get(), "\t%s %lu\n", gpu_opcode_str[i], gpu_opcode_use[i]);
825 memory_free(gpu_ram_8);
829 // Main GPU execution core
832 void gpu_exec(int32 cycles)
837 #ifdef GPU_SINGLE_STEPPING
838 if (gpu_control & 0x18)
841 gpu_control &= ~0x10;
845 gpu_releaseTimeSlice_flag = 0;
848 while ((cycles > 0) && GPU_RUNNING)
850 gpu_flag_c = (gpu_flag_c ? 1 : 0);
851 gpu_flag_z = (gpu_flag_z ? 1 : 0);
852 gpu_flag_n = (gpu_flag_n ? 1 : 0);
854 uint16 opcode = gpu_word_read(gpu_pc);
855 /*static char buffer[512];
856 dasmjag(JAGUAR_GPU, buffer, gpu_pc);
857 fprintf(log_get(), "GPU: [%08X] %s\n", gpu_pc, buffer);*/
859 uint32 index = opcode >> 10;
860 gpu_opcode_first_parameter = (opcode >> 5) & 0x1F;
861 gpu_opcode_second_parameter = opcode & 0x1F;
864 cycles -= gpu_opcode_cycles[index];
865 gpu_opcode_use[index]++;
875 static void gpu_opcode_jump(void)
877 uint32 delayed_pc = Rm;
881 gpu_flag_c = (gpu_flag_c ? 1 : 0);
882 gpu_flag_z = (gpu_flag_z ? 1 : 0);
883 gpu_flag_n = (gpu_flag_n ? 1 : 0);
885 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
887 if (branch_condition(imm_2))
894 static void gpu_opcode_jr(void)
896 int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1;
898 int32 delayed_pc = gpu_pc + (offset * 2);
902 gpu_flag_c=gpu_flag_c?1:0;
903 gpu_flag_z=gpu_flag_z?1:0;
904 gpu_flag_n=gpu_flag_n?1:0;
906 jaguar_flags=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z;
908 if (branch_condition(imm_2))
915 static void gpu_opcode_add(void)
923 /* uint32 index = opcode >> 10;
924 gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5;
925 gpu_opcode_second_parameter = (opcode & 0x1F);
928 cycles -= gpu_opcode_cycles[index];
929 gpu_opcode_use[index]++;*/
930 /* int dreg = jaguar.op & 31;
931 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
932 UINT32 r2 = jaguar.r[dreg];
933 UINT32 res = r2 + r1;
934 jaguar.r[dreg] = res;
935 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/
937 UINT32 res = Rn + Rm;
938 CLR_ZNC; SET_ZNC_ADD(Rn, Rm, res);
944 GCC on WIN32 (more importantly mingw) doesn't know the declared
945 variables in asm until we put a _ before it.
947 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
960 : "d"(_Rm), "a"(_Rn));
972 : "d"(_Rm), "a"(_Rn));
974 #endif // #ifdef __GCCWIN32__
975 #endif // #ifndef USE_ASSEMBLY
988 #endif // #ifdef __PORT__
992 static void gpu_opcode_addc(void)
1000 /* int dreg = jaguar.op & 31;
1001 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1002 UINT32 r2 = jaguar.r[dreg];
1003 UINT32 res = r2 + r1 + ((jaguar.FLAGS >> 1) & 1);
1004 jaguar.r[dreg] = res;
1005 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/
1007 UINT32 res = Rn + Rm + gpu_flag_c;
1008 CLR_ZNC; SET_ZNC_ADD(Rn, Rm, res);
1014 GCC on WIN32 (more importantly mingw) doesn't know the declared
1015 variables in asm until we put a _ before it.
1017 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1024 cmp $0, _gpu_flag_c \n\
1030 setc _gpu_flag_c \n\
1031 setz _gpu_flag_z \n\
1032 sets _gpu_flag_n \n\
1036 : "d"(_Rm), "a"(_Rn));
1042 cmp $0, gpu_flag_c \n\
1054 : "d"(_Rm), "a"(_Rn));
1056 #endif // #ifdef __GCCWIN32__
1057 #endif // #ifndef USE_ASSEMBLY
1066 jz gpu_opcode_addc_no_carry
1068 gpu_opcode_addc_no_carry:
1079 static void gpu_opcode_addq(void)
1082 uint32 _Rm=gpu_convert_zero[imm_1];
1085 #ifndef USE_ASSEMBLY
1087 /* int dreg = jaguar.op & 31;
1088 UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1089 UINT32 r2 = jaguar.r[dreg];
1090 UINT32 res = r2 + r1;
1091 jaguar.r[dreg] = res;
1092 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/
1093 UINT32 r1 = gpu_convert_zero[imm_1];
1094 UINT32 res = Rn + r1;
1095 CLR_ZNC; SET_ZNC_ADD(Rn, r1, res);
1101 GCC on WIN32 (more importantly mingw) doesn't know the declared
1102 variables in asm until we put a _ before it.
1104 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1111 setc _gpu_flag_c \n\
1112 setz _gpu_flag_z \n\
1113 sets _gpu_flag_n \n\
1117 : "d"(_Rm), "a"(_Rn));
1129 : "d"(_Rm), "a"(_Rn));
1131 #endif // #ifdef __GCCWIN32__
1132 #endif // #ifndef USE_ASSEMBLY
1149 static void gpu_opcode_addqt(void)
1151 Rn += gpu_convert_zero[imm_1];
1154 static void gpu_opcode_sub(void)
1160 #ifndef USE_ASSEMBLY
1162 /* int dreg = jaguar.op & 31;
1163 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1164 UINT32 r2 = jaguar.r[dreg];
1165 UINT32 res = r2 - r1;
1166 jaguar.r[dreg] = res;
1167 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
1168 UINT32 res = Rn - Rm;
1169 CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res);
1175 GCC on WIN32 (more importantly mingw) doesn't know the declared
1176 variables in asm until we put a _ before it.
1178 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1185 setc _gpu_flag_c \n\
1186 setz _gpu_flag_z \n\
1187 sets _gpu_flag_n \n\
1191 : "d"(_Rm), "a"(_Rn));
1203 : "d"(_Rm), "a"(_Rn));
1205 #endif // #ifdef __GCCWIN32__
1206 #endif // #ifndef USE_ASSEMBLY
1223 static void gpu_opcode_subc(void)
1229 #ifndef USE_ASSEMBLY
1231 /* int dreg = jaguar.op & 31;
1232 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1233 UINT32 r2 = jaguar.r[dreg];
1234 UINT32 res = r2 - r1 - ((jaguar.FLAGS >> 1) & 1);
1235 jaguar.r[dreg] = res;
1236 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
1237 UINT32 res = Rn - Rm - gpu_flag_c;
1238 CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res);
1244 GCC on WIN32 (more importantly mingw) doesn't know the declared
1245 variables in asm until we put a _ before it.
1247 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1254 cmp $0, _gpu_flag_c \n\
1260 setc _gpu_flag_c \n\
1261 setz _gpu_flag_z \n\
1262 sets _gpu_flag_n \n\
1266 : "d"(_Rm), "a"(_Rn));
1272 cmp $0, gpu_flag_c \n\
1284 : "d"(_Rm), "a"(_Rn));
1286 #endif // #ifdef __GCCWIN32__
1287 #endif // #ifndef USE_ASSEMBLY
1294 jz gpu_opcode_subc_no_carry
1296 gpu_opcode_subc_no_carry:
1309 static void gpu_opcode_subq(void)
1311 uint32 _Rm=gpu_convert_zero[imm_1];
1315 #ifndef USE_ASSEMBLY
1317 /* int dreg = jaguar.op & 31;
1318 UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1319 UINT32 r2 = jaguar.r[dreg];
1320 UINT32 res = r2 - r1;
1321 jaguar.r[dreg] = res;
1322 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
1323 UINT32 r1 = gpu_convert_zero[imm_1];
1324 UINT32 res = Rn - r1;
1325 CLR_ZNC; SET_ZNC_SUB(Rn, r1, res);
1331 GCC on WIN32 (more importantly mingw) doesn't know the declared
1332 variables in asm until we put a _ before it.
1334 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1341 setc _gpu_flag_c \n\
1342 setz _gpu_flag_z \n\
1343 sets _gpu_flag_n \n\
1347 : "d"(_Rm), "a"(_Rn));
1359 : "d"(_Rm), "a"(_Rn));
1361 #endif // #ifdef __GCCWIN32__
1362 #endif // #ifndef USE_ASSEMBLY
1379 static void gpu_opcode_subqt(void)
1381 Rn -= gpu_convert_zero[imm_1];
1384 static void gpu_opcode_cmp(void)
1389 #ifndef USE_ASSEMBLY
1391 /* UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1392 UINT32 r2 = jaguar.r[jaguar.op & 31];
1393 UINT32 res = r2 - r1;
1394 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
1395 UINT32 res = Rn - Rm;
1396 CLR_ZNC; SET_ZNC_SUB(Rn, Rm, res);
1402 GCC on WIN32 (more importantly mingw) doesn't know the declared
1403 variables in asm until we put a _ before it.
1405 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1412 setc _gpu_flag_c \n\
1413 setz _gpu_flag_z \n\
1414 sets _gpu_flag_n \n\
1417 : "d"(_Rm), "a"(_Rn));
1428 : "d"(_Rm), "a"(_Rn));
1430 #endif // #ifdef __GCCWIN32__
1431 #endif // #ifndef USE_ASSEMBLY
1446 static void gpu_opcode_cmpq(void)
1448 static int32 sqtable[32] =
1449 { 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 };
1450 int32 _Rm=sqtable[imm_1&0x1f];
1453 #ifndef USE_ASSEMBLY
1455 /* UINT32 r1 = (INT8)(jaguar.op >> 2) >> 3;
1456 UINT32 r2 = jaguar.r[jaguar.op & 31];
1457 UINT32 res = r2 - r1;
1458 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
1459 UINT32 r1 = sqtable[imm_1 & 0x1F]; // I like this better -> (INT8)(jaguar.op >> 2) >> 3;
1460 UINT32 res = Rn - r1;
1461 CLR_ZNC; SET_ZNC_SUB(Rn, r1, res);
1466 GCC on WIN32 (more importantly mingw) doesn't know the declared
1467 variables in asm until we put a _ before it.
1469 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1476 setc _gpu_flag_c \n\
1477 setz _gpu_flag_z \n\
1478 sets _gpu_flag_n \n\
1481 : "d"(_Rm), "a"(_Rn));
1492 : "d"(_Rm), "a"(_Rn));
1494 #endif // #ifdef __GCCWIN32__
1495 #endif // #ifndef USE_ASSEMBLY
1510 static void gpu_opcode_and(void)
1516 #ifndef USE_ASSEMBLY
1518 /* int dreg = jaguar.op & 31;
1519 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1520 UINT32 r2 = jaguar.r[dreg];
1521 UINT32 res = r2 & r1;
1522 jaguar.r[dreg] = res;
1523 CLR_ZN; SET_ZN(res);*/
1524 UINT32 res = Rn & Rm;
1526 CLR_ZN; SET_ZN(res);
1532 GCC on WIN32 (more importantly mingw) doesn't know the declared
1533 variables in asm until we put a _ before it.
1535 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1542 setz _gpu_flag_z \n\
1543 sets _gpu_flag_n \n\
1547 : "d"(_Rm), "a"(_Rn));
1558 : "d"(_Rm), "a"(_Rn));
1560 #endif // #ifdef __GCCWIN32__
1561 #endif // #ifndef USE_ASSEMBLY
1577 static void gpu_opcode_or(void)
1583 #ifndef USE_ASSEMBLY
1585 /* int dreg = jaguar.op & 31;
1586 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1587 UINT32 r2 = jaguar.r[dreg];
1588 UINT32 res = r1 | r2;
1589 jaguar.r[dreg] = res;
1590 CLR_ZN; SET_ZN(res);*/
1591 UINT32 res = Rn | Rm;
1593 CLR_ZN; SET_ZN(res);
1598 GCC on WIN32 (more importantly mingw) doesn't know the declared
1599 variables in asm until we put a _ before it.
1601 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1608 setz _gpu_flag_z \n\
1609 sets _gpu_flag_n \n\
1613 : "d"(_Rm), "a"(_Rn));
1624 : "d"(_Rm), "a"(_Rn));
1626 #endif // #ifdef __GCCWIN32__
1627 #endif // #ifndef USE_ASSEMBLY
1643 static void gpu_opcode_xor(void)
1649 #ifndef USE_ASSEMBLY
1651 /* int dreg = jaguar.op & 31;
1652 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1653 UINT32 r2 = jaguar.r[dreg];
1654 UINT32 res = r1 ^ r2;
1655 jaguar.r[dreg] = res;
1656 CLR_ZN; SET_ZN(res);*/
1657 UINT32 res = Rn ^ Rm;
1659 CLR_ZN; SET_ZN(res);
1664 GCC on WIN32 (more importantly mingw) doesn't know the declared
1665 variables in asm until we put a _ before it.
1667 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1674 setz _gpu_flag_z \n\
1675 sets _gpu_flag_n \n\
1679 : "d"(_Rm), "a"(_Rn));
1690 : "d"(_Rm), "a"(_Rn));
1692 #endif // #ifdef __GCCWIN32__
1693 #endif // #ifndef USE_ASSEMBLY
1709 static void gpu_opcode_not(void)
1714 #ifndef USE_ASSEMBLY
1716 /* int dreg = jaguar.op & 31;
1717 UINT32 res = ~jaguar.r[dreg];
1718 jaguar.r[dreg] = res;
1719 CLR_ZN; SET_ZN(res);*/
1722 CLR_ZN; SET_ZN(res);
1727 GCC on WIN32 (more importantly mingw) doesn't know the declared
1728 variables in asm until we put a _ before it.
1730 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
1737 setz _gpu_flag_z \n\
1738 sets _gpu_flag_n \n\
1755 #endif // #ifdef __GCCWIN32__
1756 #endif // #ifndef USE_ASSEMBLY
1771 static void gpu_opcode_move_pc(void)
1776 static void gpu_opcode_sat8(void)
1778 int32 _Rn=(int32)Rn;
1780 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn);
1785 static void gpu_opcode_sat16(void)
1787 int32 _Rn=(int32)Rn;
1788 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn);
1793 static void gpu_opcode_sat24(void)
1795 int32 _Rn=(int32)Rn;
1797 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn);
1802 static void gpu_opcode_store_r14_indexed(void)
1804 gpu_long_write( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2),Rn);
1807 static void gpu_opcode_store_r15_indexed(void)
1809 gpu_long_write( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2),Rn);
1812 static void gpu_opcode_load_r14_ri(void)
1814 Rn=gpu_long_read(gpu_reg[14] + Rm);
1817 static void gpu_opcode_load_r15_ri(void)
1819 Rn=gpu_long_read(gpu_reg[15] + Rm);
1822 static void gpu_opcode_store_r14_ri(void)
1824 gpu_long_write(gpu_reg[14] + Rm,Rn);
1827 static void gpu_opcode_store_r15_ri(void)
1829 gpu_long_write(gpu_reg[15] + Rm,Rn);
1832 static void gpu_opcode_nop(void)
1836 static void gpu_opcode_pack(void)
1842 Rn =((_Rn & 0x03C00000) >> 10) |
1843 ((_Rn & 0x0001E000) >> 5) |
1844 ((_Rn & 0x000000FF));
1848 Rn =((_Rn & 0x0000F000) << 10) |
1849 ((_Rn & 0x00000F00) << 5) |
1850 ((_Rn & 0x000000FF));
1858 static void gpu_opcode_storeb(void)
1860 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
1861 gpu_long_write(Rm,Rn&0xff);
1863 jaguar_byte_write(Rm,Rn);
1866 static void gpu_opcode_storew(void)
1868 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
1869 gpu_long_write(Rm,Rn&0xffff);
1871 jaguar_word_write(Rm,Rn);
1874 static void gpu_opcode_store(void)
1876 gpu_long_write(Rm,Rn);
1879 static void gpu_opcode_storep(void)
1882 gpu_long_write(_Rm, gpu_hidata);
1883 gpu_long_write(_Rm+4, Rn);
1886 static void gpu_opcode_loadb(void)
1888 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
1889 Rn=gpu_long_read(Rm)&0xff;
1891 Rn=jaguar_byte_read(Rm);
1894 static void gpu_opcode_loadw(void)
1896 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
1897 Rn=gpu_long_read(Rm)&0xffff;
1899 Rn=jaguar_word_read(Rm);
1902 static void gpu_opcode_load(void)
1904 Rn = gpu_long_read(Rm);
1907 static void gpu_opcode_loadp(void)
1911 gpu_hidata = gpu_long_read(_Rm);
1912 Rn = gpu_long_read(_Rm+4);
1915 static void gpu_opcode_load_r14_indexed(void)
1917 Rn = gpu_long_read( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2));
1920 static void gpu_opcode_load_r15_indexed(void)
1922 Rn = gpu_long_read( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2));
1925 static void gpu_opcode_movei(void)
1927 Rn = (uint32)gpu_word_read(gpu_pc) | ((uint32)gpu_word_read(gpu_pc + 2) << 16);
1931 static void gpu_opcode_moveta(void)
1936 static void gpu_opcode_movefa(void)
1941 static void gpu_opcode_move(void)
1946 static void gpu_opcode_moveq(void)
1951 static void gpu_opcode_resmac(void)
1956 static void gpu_opcode_imult(void)
1958 uint32 res=Rn=((int16)Rn)*((int16)Rm);
1963 static void gpu_opcode_mult(void)
1965 uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn);
1970 static void gpu_opcode_bclr(void)
1976 #ifndef USE_ASSEMBLY
1978 /* int dreg = jaguar.op & 31;
1979 UINT32 r1 = (jaguar.op >> 5) & 31;
1980 UINT32 r2 = jaguar.r[dreg];
1981 UINT32 res = r2 & ~(1 << r1);
1982 jaguar.r[dreg] = res;
1983 CLR_ZN; SET_ZN(res);*/
1984 UINT32 res = Rn & ~(1 << imm_1);
1986 CLR_ZN; SET_ZN(res);
1991 GCC on WIN32 (more importantly mingw) doesn't know the declared
1992 variables in asm until we put a _ before it.
1994 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2002 setz _gpu_flag_z \n\
2003 sets _gpu_flag_n \n\
2007 : "c"(_Rm), "a"(_Rn));
2019 : "c"(_Rm), "a"(_Rn));
2021 #endif // #ifdef __GCCWIN32__
2022 #endif // #ifndef USE_ASSEMBLY
2039 static void gpu_opcode_btst(void)
2044 #ifndef USE_ASSEMBLY
2046 /* UINT32 r1 = (jaguar.op >> 5) & 31;
2047 UINT32 r2 = jaguar.r[jaguar.op & 31];
2048 CLR_Z; jaguar.FLAGS |= (~r2 >> r1) & 1;*/
2049 CLR_Z; gpu_flag_z = (~Rn >> imm_1) & 1;
2054 GCC on WIN32 (more importantly mingw) doesn't know the declared
2055 variables in asm until we put a _ before it.
2057 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2064 setnc _gpu_flag_z \n\
2067 : "c"(_Rm), "a"(_Rn));
2073 setnc gpu_flag_z \n\
2076 : "c"(_Rm), "a"(_Rn));
2078 #endif // #ifdef __GCCWIN32__
2079 #endif // #ifndef USE_ASSEMBLY
2092 static void gpu_opcode_bset(void)
2098 #ifndef USE_ASSEMBLY
2100 /* int dreg = jaguar.op & 31;
2101 UINT32 r1 = (jaguar.op >> 5) & 31;
2102 UINT32 r2 = jaguar.r[dreg];
2103 UINT32 res = r2 | (1 << r1);
2104 jaguar.r[dreg] = res;
2105 CLR_ZN; SET_ZN(res);*/
2106 UINT32 res = Rn | (1 << imm_1);
2108 CLR_ZN; SET_ZN(res);
2113 GCC on WIN32 (more importantly mingw) doesn't know the declared
2114 variables in asm until we put a _ before it.
2116 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2124 setz _gpu_flag_z \n\
2125 sets _gpu_flag_n \n\
2129 : "c"(_Rm), "a"(_Rn));
2141 : "c"(_Rm), "a"(_Rn));
2143 #endif // #ifdef __GCCWIN32__
2144 #endif // #ifndef USE_ASSEMBLY
2161 static void gpu_opcode_imacn(void)
2163 uint32 res = ((int16)Rm) * ((int16)(Rn));
2167 static void gpu_opcode_mtoi(void)
2170 uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff);
2175 static void gpu_opcode_normi(void)
2182 while ((_Rm & 0xFFC00000) == 0)
2187 while ((_Rm & 0xFF800000) != 0)
2198 static void gpu_opcode_mmult(void)
2200 int count = gpu_matrix_control & 0x0F;
2201 uint32 addr = gpu_pointer_to_matrix; // in the gpu ram
2205 if (!(gpu_matrix_control & 0x10))
2207 for (int i = 0; i < count; i++)
2211 a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff);
2213 a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff);
2215 int16 b=((int16)gpu_word_read(addr+2));
2222 for (int i = 0; i < count; i++)
2226 a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff);
2228 a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff);
2230 int16 b=((int16)gpu_word_read(addr+2));
2235 Rn = res = (int32)accum;
2241 static void gpu_opcode_abs(void)
2246 if (_Rn==0x80000000)
2252 gpu_flag_c = ((_Rn&0x80000000)>>31);
2253 res= Rn = (((int32)_Rn)<0) ? -_Rn : _Rn;
2259 static void gpu_opcode_div(void)
2266 if (gpu_div_control & 1)
2268 gpu_remain = (((uint64)_Rn) << 16) % _Rm;
2269 if (gpu_remain&0x80000000)
2271 Rn = (((uint64)_Rn) << 16) / _Rm;
2275 gpu_remain = _Rn % _Rm;
2276 if (gpu_remain&0x80000000)
2285 static void gpu_opcode_imultn(void)
2287 uint32 res = (int32)((int16)Rn * (int16)Rm);
2288 gpu_acc = (int32)res;
2293 static void gpu_opcode_neg(void)
2298 #ifndef USE_ASSEMBLY
2300 /* int dreg = jaguar.op & 31;
2301 UINT32 r2 = jaguar.r[dreg];
2303 jaguar.r[dreg] = res;
2304 CLR_ZNC; SET_ZNC_SUB(0,r2,res);*/
2306 CLR_ZNC; SET_ZNC_SUB(0, Rn, res);
2312 GCC on WIN32 (more importantly mingw) doesn't know the declared
2313 variables in asm until we put a _ before it.
2315 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2322 setc _gpu_flag_c \n\
2323 setz _gpu_flag_z \n\
2324 sets _gpu_flag_n \n\
2328 : "d"(_Rn), "a"(0));
2340 : "d"(_Rn), "a"(0));
2342 #endif // #ifdef __GCCWIN32__
2343 #endif // #ifndef USE_ASSEMBLY
2360 static void gpu_opcode_shlq(void)
2362 uint32 shift=(32-gpu_convert_zero[imm_1]);
2366 #ifndef USE_ASSEMBLY
2367 /* int dreg = jaguar.op & 31;
2368 INT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
2369 UINT32 r2 = jaguar.r[dreg];
2370 UINT32 res = r2 << (32 - r1);
2371 jaguar.r[dreg] = res;
2372 CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;*/
2374 INT32 r1 = gpu_convert_zero[imm_1];
2375 UINT32 res = Rn << (32 - r1);
2376 CLR_ZNC; SET_ZN(res); gpu_flag_c = (Rn >> 31) & 1;
2382 GCC on WIN32 (more importantly mingw) doesn't know the declared
2383 variables in asm until we put a _ before it.
2385 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2391 "testl $0x80000000, %2 \n\
2392 setnz _gpu_flag_c \n\
2395 setz _gpu_flag_z \n\
2396 sets _gpu_flag_n \n\
2400 : "c"(shift), "a"(_Rn));
2405 "testl $0x80000000, %2 \n\
2406 setnz gpu_flag_c \n\
2414 : "c"(shift), "a"(_Rn));
2416 #endif // #ifdef __GCCWIN32__
2417 #endif // #ifndef USE_ASSEMBLY
2436 static void gpu_opcode_shrq(void)
2438 uint32 shift=gpu_convert_zero[imm_1];
2443 #ifndef USE_ASSEMBLY
2444 /* int dreg = jaguar.op & 31;
2445 INT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
2446 UINT32 r2 = jaguar.r[dreg];
2447 UINT32 res = r2 >> r1;
2448 jaguar.r[dreg] = res;
2449 CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;*/
2451 INT32 r1 = gpu_convert_zero[imm_1];
2452 UINT32 res = Rn >> r1;
2453 CLR_ZNC; SET_ZN(res); gpu_flag_c = Rn & 1;
2459 GCC on WIN32 (more importantly mingw) doesn't know the declared
2460 variables in asm until we put a _ before it.
2462 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2468 "testl $0x00000001, %2 \n\
2469 setnz _gpu_flag_c \n\
2472 setz _gpu_flag_z \n\
2473 sets _gpu_flag_n \n\
2477 : "c"(shift), "a"(_Rn));
2482 "testl $0x00000001, %2 \n\
2483 setnz gpu_flag_c \n\
2491 : "c"(shift), "a"(_Rn));
2493 #endif // #ifdef __GCCWIN32__
2494 #endif // #ifndef USE_ASSEMBLY
2513 static void gpu_opcode_ror(void)
2519 #ifndef USE_ASSEMBLY
2520 //#ifndef __PORT__ // For testing...
2521 /* int dreg = jaguar.op & 31;
2522 UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31] & 31;
2523 UINT32 r2 = jaguar.r[dreg];
2524 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
2525 jaguar.r[dreg] = res;
2526 CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;*/
2528 UINT32 r1 = Rm & 0x1F;
2529 UINT32 res = (Rn >> r1) | (Rn << (32 - r1));
2530 CLR_ZNC; SET_ZN(res); gpu_flag_c = (Rn >> 31) & 1;
2536 GCC on WIN32 (more importantly mingw) doesn't know the declared
2537 variables in asm until we put a _ before it.
2539 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2545 "testl $0x80000000, %2 \n\
2546 setnz _gpu_flag_c \n\
2549 setz _gpu_flag_z \n\
2550 sets _gpu_flag_n \n\
2554 : "c"(shift), "a"(_Rn));
2559 "testl $0x80000000, %2 \n\
2560 setnz gpu_flag_c \n\
2568 : "c"(shift), "a"(_Rn));
2570 #endif // #ifdef __GCCWIN32__
2571 #endif // #ifndef USE_ASSEMBLY
2590 static void gpu_opcode_rorq(void)
2592 uint32 shift = gpu_convert_zero[imm_1 & 0x1F];
2596 #ifndef USE_ASSEMBLY
2597 /* uint32 index = opcode >> 10;
2598 gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5;
2599 gpu_opcode_second_parameter = (opcode & 0x1F);
2601 gpu_opcode[index]();
2602 cycles -= gpu_opcode_cycles[index];
2603 gpu_opcode_use[index]++;*/
2605 /* int dreg = jaguar.op & 31;
2606 UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
2607 UINT32 r2 = jaguar.r[dreg];
2608 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
2609 jaguar.r[dreg] = res;
2610 CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;*/
2612 UINT32 r1 = gpu_convert_zero[imm_1 & 0x1F];
2614 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
2616 CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
2622 GCC on WIN32 (more importantly mingw) doesn't know the declared
2623 variables in asm until we put a _ before it.
2625 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
2631 "testl $0x80000000, %2 \n\
2632 setnz _gpu_flag_c \n\
2635 setz _gpu_flag_z \n\
2636 sets _gpu_flag_n \n\
2640 : "c"(shift), "a"(_Rn));
2645 "testl $0x80000000, %2 \n\
2646 setnz gpu_flag_c \n\
2654 : "c"(shift), "a"(_Rn));
2656 #endif // #ifdef __GCCWIN32__
2657 #endif // #ifndef USE_ASSEMBLY
2672 #endif // #ifdef __PORT__
2676 static void gpu_opcode_sha(void)
2678 int32 sRm=(int32)Rm;
2684 if (shift>=32) shift=32;
2685 gpu_flag_c=(_Rn&0x80000000)>>31;
2695 if (shift>=32) shift=32;
2699 _Rn=((int32)_Rn)>>1;
2708 static void gpu_opcode_sharq(void)
2710 uint32 shift=gpu_convert_zero[imm_1];
2713 gpu_flag_c = (_Rn & 0x1);
2716 _Rn=((int32)_Rn)>>1;
2724 static void gpu_opcode_sh(void)
2726 int32 sRm=(int32)Rm;
2731 uint32 shift=(-sRm);
2732 if (shift>=32) shift=32;
2733 gpu_flag_c=(_Rn&0x80000000)>>31;
2743 if (shift>=32) shift=32;