1 //////////////////////////////////////////////////////////////////////////////
\r
3 //////////////////////////////////////////////////////////////////////////////
\r
10 //////////////////////////////////////////////////////////////////////////////
\r
12 #include "include/gpu.h"
\r
14 #define CINT0FLAG 0x00200
\r
15 #define CINT1FLAG 0x00400
\r
16 #define CINT2FLAG 0x00800
\r
17 #define CINT3FLAG 0x01000
\r
18 #define CINT4FLAG 0x02000
\r
19 #define CINT04FLAGS (CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG)
\r
21 extern int start_logging;
\r
24 static void gpu_opcode_add(void);
\r
25 static void gpu_opcode_addc(void);
\r
26 static void gpu_opcode_addq(void);
\r
27 static void gpu_opcode_addqt(void);
\r
28 static void gpu_opcode_sub(void);
\r
29 static void gpu_opcode_subc(void);
\r
30 static void gpu_opcode_subq(void);
\r
31 static void gpu_opcode_subqt(void);
\r
32 static void gpu_opcode_neg(void);
\r
33 static void gpu_opcode_and(void);
\r
34 static void gpu_opcode_or(void);
\r
35 static void gpu_opcode_xor(void);
\r
36 static void gpu_opcode_not(void);
\r
37 static void gpu_opcode_btst(void);
\r
38 static void gpu_opcode_bset(void);
\r
39 static void gpu_opcode_bclr(void);
\r
40 static void gpu_opcode_mult(void);
\r
41 static void gpu_opcode_imult(void);
\r
42 static void gpu_opcode_imultn(void);
\r
43 static void gpu_opcode_resmac(void);
\r
44 static void gpu_opcode_imacn(void);
\r
45 static void gpu_opcode_div(void);
\r
46 static void gpu_opcode_abs(void);
\r
47 static void gpu_opcode_sh(void);
\r
48 static void gpu_opcode_shlq(void);
\r
49 static void gpu_opcode_shrq(void);
\r
50 static void gpu_opcode_sha(void);
\r
51 static void gpu_opcode_sharq(void);
\r
52 static void gpu_opcode_ror(void);
\r
53 static void gpu_opcode_rorq(void);
\r
54 static void gpu_opcode_cmp(void);
\r
55 static void gpu_opcode_cmpq(void);
\r
56 static void gpu_opcode_sat8(void);
\r
57 static void gpu_opcode_sat16(void);
\r
58 static void gpu_opcode_move(void);
\r
59 static void gpu_opcode_moveq(void);
\r
60 static void gpu_opcode_moveta(void);
\r
61 static void gpu_opcode_movefa(void);
\r
62 static void gpu_opcode_movei(void);
\r
63 static void gpu_opcode_loadb(void);
\r
64 static void gpu_opcode_loadw(void);
\r
65 static void gpu_opcode_load(void);
\r
66 static void gpu_opcode_loadp(void);
\r
67 static void gpu_opcode_load_r14_indexed(void);
\r
68 static void gpu_opcode_load_r15_indexed(void);
\r
69 static void gpu_opcode_storeb(void);
\r
70 static void gpu_opcode_storew(void);
\r
71 static void gpu_opcode_store(void);
\r
72 static void gpu_opcode_storep(void);
\r
73 static void gpu_opcode_store_r14_indexed(void);
\r
74 static void gpu_opcode_store_r15_indexed(void);
\r
75 static void gpu_opcode_move_pc(void);
\r
76 static void gpu_opcode_jump(void);
\r
77 static void gpu_opcode_jr(void);
\r
78 static void gpu_opcode_mmult(void);
\r
79 static void gpu_opcode_mtoi(void);
\r
80 static void gpu_opcode_normi(void);
\r
81 static void gpu_opcode_nop(void);
\r
82 static void gpu_opcode_load_r14_ri(void);
\r
83 static void gpu_opcode_load_r15_ri(void);
\r
84 static void gpu_opcode_store_r14_ri(void);
\r
85 static void gpu_opcode_store_r15_ri(void);
\r
86 static void gpu_opcode_sat24(void);
\r
87 static void gpu_opcode_pack(void);
\r
89 uint8 gpu_opcode_cycles[64] =
\r
109 void (*gpu_opcode[64])()=
\r
111 gpu_opcode_add, gpu_opcode_addc, gpu_opcode_addq, gpu_opcode_addqt,
\r
112 gpu_opcode_sub, gpu_opcode_subc, gpu_opcode_subq, gpu_opcode_subqt,
\r
113 gpu_opcode_neg, gpu_opcode_and, gpu_opcode_or, gpu_opcode_xor,
\r
114 gpu_opcode_not, gpu_opcode_btst, gpu_opcode_bset, gpu_opcode_bclr,
\r
115 gpu_opcode_mult, gpu_opcode_imult, gpu_opcode_imultn, gpu_opcode_resmac,
\r
116 gpu_opcode_imacn, gpu_opcode_div, gpu_opcode_abs, gpu_opcode_sh,
\r
117 gpu_opcode_shlq, gpu_opcode_shrq, gpu_opcode_sha, gpu_opcode_sharq,
\r
118 gpu_opcode_ror, gpu_opcode_rorq, gpu_opcode_cmp, gpu_opcode_cmpq,
\r
119 gpu_opcode_sat8, gpu_opcode_sat16, gpu_opcode_move, gpu_opcode_moveq,
\r
120 gpu_opcode_moveta, gpu_opcode_movefa, gpu_opcode_movei, gpu_opcode_loadb,
\r
121 gpu_opcode_loadw, gpu_opcode_load, gpu_opcode_loadp, gpu_opcode_load_r14_indexed,
\r
122 gpu_opcode_load_r15_indexed, gpu_opcode_storeb, gpu_opcode_storew, gpu_opcode_store,
\r
123 gpu_opcode_storep, gpu_opcode_store_r14_indexed, gpu_opcode_store_r15_indexed, gpu_opcode_move_pc,
\r
124 gpu_opcode_jump, gpu_opcode_jr, gpu_opcode_mmult, gpu_opcode_mtoi,
\r
125 gpu_opcode_normi, gpu_opcode_nop, gpu_opcode_load_r14_ri, gpu_opcode_load_r15_ri,
\r
126 gpu_opcode_store_r14_ri, gpu_opcode_store_r15_ri, gpu_opcode_sat24, gpu_opcode_pack,
\r
129 static uint8 * gpu_ram_8;
\r
130 //static uint16 *gpu_ram_16;
\r
131 //static uint32 *gpu_ram_32;
\r
134 static uint32 gpu_pc;
\r
135 static uint32 gpu_acc;
\r
136 static uint32 gpu_remain;
\r
137 static uint32 gpu_hidata;
\r
138 static uint32 gpu_flags;
\r
139 static uint32 gpu_matrix_control;
\r
140 static uint32 gpu_pointer_to_matrix;
\r
141 static uint32 gpu_data_organization;
\r
142 static uint32 gpu_control;
\r
143 static uint32 gpu_div_control;
\r
144 static uint8 gpu_flag_z;
\r
145 static uint8 gpu_flag_n;
\r
146 static uint8 gpu_flag_c;
\r
147 static uint8 gpu_alternate_flag_z;
\r
148 static uint8 gpu_alternate_flag_n;
\r
149 static uint8 gpu_alternate_flag_c;
\r
150 static uint32 * gpu_reg;
\r
151 static uint32 * gpu_alternate_reg;
\r
152 static uint32 * gpu_reg_bank_0;
\r
153 static uint32 * gpu_reg_bank_1;
\r
155 static uint32 gpu_opcode_first_parameter;
\r
156 static uint32 gpu_opcode_second_parameter;
\r
158 #define gpu_running (gpu_control&0x01)
\r
160 #define Rm gpu_reg[gpu_opcode_first_parameter]
\r
161 #define Rn gpu_reg[gpu_opcode_second_parameter]
\r
162 #define alternate_Rm gpu_alternate_reg[gpu_opcode_first_parameter]
\r
163 #define alternate_Rn gpu_alternate_reg[gpu_opcode_second_parameter]
\r
164 #define imm_1 gpu_opcode_first_parameter
\r
165 #define imm_2 gpu_opcode_second_parameter
\r
167 #define set_flag_z(r) gpu_flag_z=(r==0);
\r
168 #define set_flag_n(r) gpu_flag_n=((r&0x80000000)>>31);
\r
170 #define reset_flag_z() gpu_flag_z=0;
\r
171 #define reset_flag_n() gpu_flag_n=0;
\r
172 #define reset_flag_c() gpu_flag_c=0;
\r
174 uint32 gpu_convert_zero[32] = { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
\r
176 uint8 * branch_condition_table = 0;
\r
177 #define branch_condition(x) branch_condition_table[(x) + ((jaguar_flags & 7) << 5)]
\r
179 uint32 gpu_opcode_use[64];
\r
181 void gpu_update_register_banks(void);
\r
183 char *gpu_opcode_str[64]=
\r
185 "add", "addc", "addq", "addqt",
\r
186 "sub", "subc", "subq", "subqt",
\r
187 "neg", "and", "or", "xor",
\r
188 "not", "btst", "bset", "bclr",
\r
189 "mult", "imult", "imultn", "resmac",
\r
190 "imacn", "div", "abs", "sh",
\r
191 "shlq", "shrq", "sha", "sharq",
\r
192 "ror", "rorq", "cmp", "cmpq",
\r
193 "sat8", "sat16", "move", "moveq",
\r
194 "moveta", "movefa", "movei", "loadb",
\r
195 "loadw", "load", "loadp", "load_r14_indexed",
\r
196 "load_r15_indexed", "storeb", "storew", "store",
\r
197 "storep", "store_r14_indexed","store_r15_indexed","move_pc",
\r
198 "jump", "jr", "mmult", "mtoi",
\r
199 "normi", "nop", "load_r14_ri", "load_r15_ri",
\r
200 "store_r14_ri", "store_r15_ri", "sat24", "pack",
\r
203 static uint32 gpu_in_exec = 0;
\r
204 static uint32 gpu_releaseTimeSlice_flag = 0;
\r
206 //////////////////////////////////////////////////////////////////////////////
\r
208 //////////////////////////////////////////////////////////////////////////////
\r
215 //////////////////////////////////////////////////////////////////////////////
\r
216 void gpu_releaseTimeslice(void)
\r
218 gpu_releaseTimeSlice_flag = 1;
\r
220 //////////////////////////////////////////////////////////////////////////////
\r
222 //////////////////////////////////////////////////////////////////////////////
\r
229 //////////////////////////////////////////////////////////////////////////////
\r
230 uint32 gpu_get_pc(void)
\r
234 //////////////////////////////////////////////////////////////////////////////
\r
236 //////////////////////////////////////////////////////////////////////////////
\r
243 //////////////////////////////////////////////////////////////////////////////
\r
244 void build_branch_condition_table(void)
\r
246 #define ZFLAG 0x00001
\r
247 #define CFLAG 0x00002
\r
248 #define NFLAG 0x00004
\r
250 if (!branch_condition_table)
\r
252 branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(branch_condition_table[0]));
\r
254 if (branch_condition_table)
\r
256 for(int i=0; i<8; i++)
\r
258 for(int j=0; j<32; j++)
\r
268 if (i & (CFLAG << (j >> 4)))
\r
271 if (!(i & (CFLAG << (j >> 4))))
\r
273 branch_condition_table[i * 32 + j] = result;
\r
281 // GPU byte access (read)
\r
284 unsigned gpu_byte_read(unsigned int offset)
\r
286 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
287 return gpu_ram_8[offset & 0xFFF];
\r
288 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
290 uint32 data = gpu_long_read(offset & 0xFFFFFFFC);
\r
292 if ((offset & 0x03) == 0)
\r
294 else if ((offset & 0x03) == 1)
\r
295 return (data >> 16) & 0xFF;
\r
296 else if ((offset & 0x03) == 2)
\r
297 return (data >> 8) & 0xFF;
\r
298 else if ((offset & 0x03) == 3)
\r
299 return data & 0xFF;
\r
302 return jaguar_byte_read(offset);
\r
306 // GPU word access (read)
\r
309 unsigned gpu_word_read(unsigned int offset)
\r
311 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
314 uint16 data = (((uint16)gpu_ram_8[offset]) << 8) | (uint16)gpu_ram_8[offset+1];
\r
317 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
319 // This looks and smells wrong...
\r
320 // But it *might* be OK...
\r
321 if (offset & 0x01) // Catch cases 1 & 3... (unaligned read)
\r
322 return (gpu_byte_read(offset) << 8) | gpu_byte_read(offset+1);
\r
324 uint32 data = gpu_long_read(offset & 0xFFFFFFFC);
\r
326 if (offset & 0x02) // Cases 0 & 2...
\r
327 return data & 0xFFFF;
\r
332 return jaguar_word_read(offset);
\r
336 // GPU dword access (read)
\r
339 unsigned gpu_long_read(unsigned int offset)
\r
342 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
345 return ((uint32)gpu_ram_8[offset] << 24) | ((uint32)gpu_ram_8[offset+1] << 16)
\r
346 | ((uint32)gpu_ram_8[offset+2] << 8) | (uint32)gpu_ram_8[offset+3];
\r
348 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
354 gpu_flag_c = (gpu_flag_c ? 1 : 0);
\r
355 gpu_flag_z = (gpu_flag_z ? 1 : 0);
\r
356 gpu_flag_n = (gpu_flag_n ? 1 : 0);
\r
358 gpu_flags = (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
\r
360 return gpu_flags & 0xFFFFC1FF;
\r
362 return gpu_matrix_control;
\r
364 return gpu_pointer_to_matrix;
\r
366 return gpu_data_organization;
\r
370 return gpu_control;
\r
375 default: // unaligned long read
\r
381 // to prevent any lock-ups
\r
384 return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
\r
388 // GPU byte access (write)
\r
391 void gpu_byte_write(unsigned offset, unsigned data)
\r
393 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
395 gpu_ram_8[offset & 0xFFF] = data;
\r
396 if (gpu_in_exec == 0)
\r
398 // s68000releaseTimeslice();
\r
399 m68k_end_timeslice();
\r
400 dsp_releaseTimeslice();
\r
404 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
406 uint32 reg = offset & 0x1C;
\r
407 int bytenum = offset & 0x03;
\r
409 //This is definitely wrong!
\r
410 if ((reg >= 0x1C) && (reg <= 0x1F))
\r
411 gpu_div_control = (gpu_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
\r
414 uint32 old_data = gpu_long_read(offset & 0xFFFFFFC);
\r
415 bytenum = 3 - bytenum; // convention motorola !!!
\r
416 old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
\r
417 gpu_long_write(offset & 0xFFFFFFC, old_data);
\r
421 // fprintf(log_get(),"gpu: writing %.2x at 0x%.8x\n",data,offset);
\r
422 jaguar_byte_write(offset, data);
\r
426 // GPU word access (write)
\r
429 void gpu_word_write(unsigned offset, unsigned data)
\r
432 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
435 gpu_ram_8[offset & 0xFFF] = (data>>8) & 0xFF;
\r
436 gpu_ram_8[(offset+1) & 0xFFF] = data & 0xFF;
\r
437 if (gpu_in_exec == 0)
\r
439 // s68000releaseTimeslice();
\r
440 m68k_end_timeslice();
\r
441 dsp_releaseTimeslice();
\r
445 if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
447 if (offset & 0x01) // This is supposed to weed out unaligned writes, but does nothing...
\r
452 if ((offset & 0x1C) == 0x1C)
\r
454 //This doesn't look right either--handles cases 1, 2, & 3 all the same!
\r
456 gpu_div_control = (gpu_div_control&0xFFFF0000) | (data&0xFFFF);
\r
458 gpu_div_control = (gpu_div_control&0xFFFF) | ((data&0xFFFF)<<16);
\r
462 uint32 old_data = gpu_long_read(offset & 0xFFFFFFC);
\r
464 old_data = (old_data & 0xFFFF0000) | (data & 0xFFFF);
\r
466 old_data = (old_data & 0xFFFF) | ((data & 0xFFFF) << 16);
\r
467 gpu_long_write(offset & 0xFFFFFFC, old_data);
\r
471 // fprintf(log_get(),"gpu: writing %.4x at 0x%.8x\n",data,offset);
\r
472 jaguar_word_write(offset, data);
\r
476 // GPU dword access (write)
\r
479 void gpu_long_write(unsigned offset, unsigned data)
\r
482 if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
\r
484 gpu_ram_8[offset & 0xFFF] = (data >> 24) & 0xFF;
\r
485 gpu_ram_8[(offset+1) & 0xFFF] = (data >> 16) & 0xFF;
\r
486 gpu_ram_8[(offset+2) & 0xFFF] = (data >> 8) & 0xFF;
\r
487 gpu_ram_8[(offset+3) & 0xFFF] = data & 0xFF;
\r
490 else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
\r
497 gpu_flags=(data&(~0x08))|(gpu_flags&0x08); // update dsp_flags, but keep imask unchanged
\r
500 gpu_flag_z = gpu_flags & 0x01;
\r
501 gpu_flag_c = (gpu_flags>>1) & 0x01;
\r
502 gpu_flag_n = (gpu_flags>>2) & 0x01;
\r
503 gpu_update_register_banks();
\r
504 gpu_control &= ~((gpu_flags & CINT04FLAGS) >> 3);
\r
508 gpu_matrix_control = data;
\r
511 gpu_pointer_to_matrix=data;
\r
514 gpu_data_organization=data;
\r
517 gpu_pc = data; /*fprintf(log_get(),"setting gpu pc to 0x%.8x\n",gpu_pc);*/
\r
521 uint32 gpu_was_running = gpu_running;
\r
523 data &= (~0x7C0); // disable writes to irq pending
\r
526 fprintf(log_get(),"gpu pc is 0x%.8x\n",gpu_pc);
\r
530 // check for GPU->CPU interrupt
\r
533 // fprintf(log_get(),"GPU->CPU interrupt\n");
\r
534 if (tom_irq_enabled(IRQ_GPU))
\r
536 if ((tom_irq_enabled(IRQ_GPU)) && (jaguar_interrupt_handler_is_valid(64)))
\r
538 tom_set_pending_gpu_int();
\r
539 // s68000interrupt(7,64);
\r
540 // s68000flushInterrupts();
\r
541 m68k_set_irq(7); // Set 68000 NMI
\r
542 gpu_releaseTimeslice();
\r
545 uint32 addr=jaguar_word_read(((IRQ_GPU+64)<<2)+0);
\r
547 addr|=jaguar_word_read(((IRQ_GPU+64)<<2)+2);
\r
548 if ((addr)&&(jaguar_interrupt_handler_is_valid(IRQ_GPU+64)))
\r
550 s68000interrupt(7,IRQ_GPU+64);
\r
551 s68000flushInterrupts();
\r
557 // check for CPU->GPU interrupt
\r
560 //fprintf(log_get(),"CPU->GPU interrupt\n");
\r
561 gpu_set_irq_line(0, 1);
\r
562 // s68000releaseTimeslice();
\r
563 m68k_end_timeslice();
\r
564 dsp_releaseTimeslice();
\r
570 //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not ");
\r
572 gpu_control = (gpu_control & 0x107C0) | (data & (~0x107C0));
\r
574 // if gpu wasn't running but is now running, execute a few cycles
\r
575 #ifndef GPU_SINGLE_STEPPING
\r
576 if ((!gpu_was_running) && (gpu_running))
\r
579 if (gpu_control & 0x18)
\r
588 gpu_div_control = data;
\r
590 // default: // unaligned long write
\r
596 // fprintf(log_get(),"gpu: writing %.8x at 0x%.8x\n",data,offset);
\r
597 jaguar_word_write(offset, (data >> 16) & 0xFFFF);
\r
598 jaguar_word_write(offset+2, data & 0xFFFF);
\r
600 //////////////////////////////////////////////////////////////////////////////
\r
602 //////////////////////////////////////////////////////////////////////////////
\r
609 //////////////////////////////////////////////////////////////////////////////
\r
610 void gpu_update_register_banks(void)
\r
613 int bank = (gpu_flags & 0x4000);
\r
615 // fprintf(log_get(),"gpu_update_register_banks at gpu pc 0x%.8x bank=%i iflag=%i\n",gpu_pc,bank?1:0,(gpu_flags&0x8)?1:0);
\r
617 if (gpu_flags & 0x8)
\r
620 if ((!bank && (gpu_reg_bank_0 != gpu_reg)) || (bank && (gpu_reg_bank_1 != gpu_reg)))
\r
622 // fprintf(log_get(),"\tswitching to bank %i\n",bank?1:0);
\r
623 for(int i=0; i<32; i++)
\r
626 gpu_reg[i] = gpu_alternate_reg[i];
\r
627 gpu_alternate_reg[i] = temp;
\r
632 gpu_flag_z = gpu_alternate_flag_z;
\r
633 gpu_alternate_flag_z = temp;
\r
636 gpu_flag_n = gpu_alternate_flag_n;
\r
637 gpu_alternate_flag_n = temp;
\r
640 gpu_flag_c = gpu_alternate_flag_c;
\r
641 gpu_alternate_flag_c = temp;
\r
645 gpu_reg_bank_0 = gpu_reg;
\r
646 gpu_reg_bank_1 = gpu_alternate_reg;
\r
650 gpu_reg_bank_0 = gpu_alternate_reg;
\r
651 gpu_reg_bank_1 = gpu_reg;
\r
656 // fprintf(log_get(),"\tnot switching banks\n");
\r
659 //////////////////////////////////////////////////////////////////////////////
\r
661 //////////////////////////////////////////////////////////////////////////////
\r
668 //////////////////////////////////////////////////////////////////////////////
\r
669 void gpu_check_irqs(void)
\r
671 int bits, mask, which = 0;
\r
673 // get the active interrupt bits
\r
674 bits = (gpu_control >> 6) & 0x1F;
\r
675 bits |= (gpu_control >> 10) & 0x20;
\r
677 // get the interrupt mask
\r
678 mask = (gpu_flags >> 4) & 0x1F;
\r
679 mask |= (gpu_flags >> 11) & 0x20;
\r
681 // bail if nothing is available
\r
686 // determine which interrupt
\r
687 if (bits & 0x01) which = 0;
\r
688 if (bits & 0x02) which = 1;
\r
689 if (bits & 0x04) which = 2;
\r
690 if (bits & 0x08) which = 3;
\r
691 if (bits & 0x10) which = 4;
\r
692 if (bits & 0x20) which = 5;
\r
694 if (gpu_flags & 0x8)
\r
698 fprintf(log_get(),"gpu: generating irg %i\n",which);
\r
700 // set the interrupt flag
\r
702 gpu_update_register_banks();
\r
704 // subqt #4,r31 ; pre-decrement stack pointer
\r
705 // move pc,r30 ; address of interrupted code
\r
706 // store r30,(r31) ; store return address
\r
708 gpu_reg[30] = gpu_pc - 2;
\r
709 gpu_long_write(gpu_reg[31], gpu_pc - 2);
\r
711 // movei #service_address,r30 ; pointer to ISR entry
\r
712 // jump (r30) ; jump to ISR
\r
714 gpu_pc = gpu_work_ram_base;
\r
715 gpu_pc += which * 0x10;
\r
716 gpu_reg[30] = gpu_pc;
\r
718 //////////////////////////////////////////////////////////////////////////////
\r
720 //////////////////////////////////////////////////////////////////////////////
\r
727 //////////////////////////////////////////////////////////////////////////////
\r
728 void gpu_set_irq_line(int irqline, int state)
\r
731 fprintf(log_get(),"gpu: setting irg line %i\n",irqline);
\r
732 int mask = 0x40 << irqline;
\r
733 gpu_control &= ~mask;
\r
737 gpu_control |= mask;
\r
741 //////////////////////////////////////////////////////////////////////////////
\r
743 //////////////////////////////////////////////////////////////////////////////
\r
750 //////////////////////////////////////////////////////////////////////////////
\r
751 void gpu_init(void)
\r
753 memory_malloc_secure((void **)&gpu_ram_8, 0x1000, "GPU work ram");
\r
754 // gpu_ram_16=(uint16*)gpu_ram_8;
\r
755 // gpu_ram_32=(uint32*)gpu_ram_8;
\r
757 memory_malloc_secure((void **)&gpu_reg, 32*sizeof(int32), "GPU bank 0 regs");
\r
758 memory_malloc_secure((void **)&gpu_alternate_reg, 32*sizeof(int32), "GPU bank 1 regs");
\r
760 build_branch_condition_table();
\r
764 //////////////////////////////////////////////////////////////////////////////
\r
766 //////////////////////////////////////////////////////////////////////////////
\r
773 //////////////////////////////////////////////////////////////////////////////
\r
774 void gpu_reset(void)
\r
776 gpu_pc = 0x00F03000;
\r
777 gpu_acc = 0x00000000;
\r
778 gpu_remain = 0x00000000;
\r
779 gpu_hidata = 0x00000000;
\r
780 gpu_flags = 0x00040000;
\r
781 gpu_matrix_control = 0x00000000;
\r
782 gpu_pointer_to_matrix = 0x00000000;
\r
783 gpu_data_organization = 0xFFFFFFFF;
\r
784 gpu_control = 0x00012800;
\r
785 gpu_div_control = 0x00000000;
\r
788 for(int i=0; i<32; i++)
\r
790 gpu_reg[i] = 0x00000000;
\r
791 gpu_alternate_reg[i] = 0x00000000;
\r
794 gpu_reg_bank_0 = gpu_reg;
\r
795 gpu_reg_bank_1 = gpu_alternate_reg;
\r
796 // gpu_reg_bank_1 = gpu_reg;
\r
797 // gpu_reg_bank_0 = gpu_alternate_reg;
\r
803 gpu_alternate_flag_z = 0;
\r
804 gpu_alternate_flag_n = 0;
\r
805 gpu_alternate_flag_c = 0;
\r
807 memset(gpu_ram_8, 0xFF, 0x1000);
\r
811 //////////////////////////////////////////////////////////////////////////////
\r
813 //////////////////////////////////////////////////////////////////////////////
\r
820 //////////////////////////////////////////////////////////////////////////////
\r
821 uint32 gpu_read_pc(void)
\r
825 //////////////////////////////////////////////////////////////////////////////
\r
827 //////////////////////////////////////////////////////////////////////////////
\r
834 //////////////////////////////////////////////////////////////////////////////
\r
835 void gpu_reset_stats(void)
\r
837 for(uint32 i=0; i<64; i++)
\r
838 gpu_opcode_use[i] = 0;
\r
840 //////////////////////////////////////////////////////////////////////////////
\r
842 //////////////////////////////////////////////////////////////////////////////
\r
849 //////////////////////////////////////////////////////////////////////////////
\r
850 void gpu_done(void)
\r
853 fprintf(log_get(),"gpu: stopped at pc=0x%.8x (gpu %s running)\n",gpu_pc,gpu_running?"was":"wasn't");
\r
856 // get the active interrupt bits
\r
857 bits = (gpu_control >> 6) & 0x1F;
\r
858 bits |= (gpu_control >> 10) & 0x20;
\r
860 // get the interrupt mask
\r
861 mask = (gpu_flags >> 4) & 0x1F;
\r
862 mask |= (gpu_flags >> 11) & 0x20;
\r
865 fprintf(log_get(),"gpu: bits=0x%.8x mask=0x%.8x\n",bits,mask);
\r
866 // fprintf(log_get(),"\nregisters bank 0\n");
\r
867 // for (int j=0;j<8;j++)
\r
869 // fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
\r
870 // (j<<2)+0,gpu_reg[(j<<2)+0],
\r
871 // (j<<2)+1,gpu_reg[(j<<2)+1],
\r
872 // (j<<2)+2,gpu_reg[(j<<2)+2],
\r
873 // (j<<2)+3,gpu_reg[(j<<2)+3]);
\r
876 // fprintf(log_get(),"registers bank 1\n");
\r
877 // for (j=0;j<8;j++)
\r
879 // fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
\r
880 // (j<<2)+0,gpu_alternate_reg[(j<<2)+0],
\r
881 // (j<<2)+1,gpu_alternate_reg[(j<<2)+1],
\r
882 // (j<<2)+2,gpu_alternate_reg[(j<<2)+2],
\r
883 // (j<<2)+3,gpu_alternate_reg[(j<<2)+3]);
\r
886 // fprintf(log_get(),"---[GPU code at 0x00f03000]---------------------------\n");
\r
887 static char buffer[512];
\r
889 for(int i=0; i<4096; i++)
\r
892 j += dasmjag(JAGUAR_GPU, buffer, j);
\r
893 fprintf(log_get(),"\t%08X: %s\n", oldj, buffer);
\r
896 fprintf(log_get(), "---[GPU code at %08X]---------------------------\n", gpu_pc);
\r
898 for(i=0; i<4096; i++)
\r
901 j += dasmjag(JAGUAR_GPU, buffer, j);
\r
902 fprintf(log_get(), "\t%08X: %s\n", oldj, buffer);
\r
905 fprintf(log_get(), "gpu opcodes use:\n");
\r
906 for(i=0; i<64; i++)
\r
908 if (gpu_opcode_use[i])
\r
909 fprintf(log_get(), "\t%s %lu\n", gpu_opcode_str[i], gpu_opcode_use[i]);
\r
911 memory_free(gpu_ram_8);
\r
913 //////////////////////////////////////////////////////////////////////////////
\r
915 //////////////////////////////////////////////////////////////////////////////
\r
922 //////////////////////////////////////////////////////////////////////////////
\r
923 void gpu_exec(int32 cycles)
\r
928 #ifdef GPU_SINGLE_STEPPING
\r
929 if (gpu_control & 0x18)
\r
932 gpu_control &= ~0x10;
\r
936 gpu_releaseTimeSlice_flag = 0;
\r
939 while ((cycles > 0) && gpu_running)
\r
941 gpu_flag_c = (gpu_flag_c ? 1 : 0);
\r
942 gpu_flag_z = (gpu_flag_z ? 1 : 0);
\r
943 gpu_flag_n = (gpu_flag_n ? 1 : 0);
\r
945 uint16 opcode = gpu_word_read(gpu_pc);
\r
947 uint32 index = opcode >> 10;
\r
948 gpu_opcode_first_parameter = (opcode & 0x3E0) >> 5;
\r
949 gpu_opcode_second_parameter = (opcode & 0x1F);
\r
951 gpu_opcode[index]();
\r
952 cycles -= gpu_opcode_cycles[index];
\r
953 gpu_opcode_use[index]++;
\r
958 //////////////////////////////////////////////////////////////////////////////
\r
960 //////////////////////////////////////////////////////////////////////////////
\r
967 //////////////////////////////////////////////////////////////////////////////
\r
968 static void gpu_opcode_jump(void)
\r
970 uint32 delayed_pc = Rm;
\r
971 uint32 jaguar_flags;
\r
974 gpu_flag_c = (gpu_flag_c ? 1 : 0);
\r
975 gpu_flag_z = (gpu_flag_z ? 1 : 0);
\r
976 gpu_flag_n = (gpu_flag_n ? 1 : 0);
\r
978 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
\r
980 if (branch_condition(imm_2))
\r
983 gpu_pc = delayed_pc;
\r
986 //////////////////////////////////////////////////////////////////////////////
\r
988 //////////////////////////////////////////////////////////////////////////////
\r
995 //////////////////////////////////////////////////////////////////////////////
\r
996 static void gpu_opcode_jr(void)
\r
998 int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1;
\r
1000 int32 delayed_pc = gpu_pc + (offset * 2);
\r
1001 uint32 jaguar_flags;
\r
1003 // normalize flags
\r
1004 gpu_flag_c=gpu_flag_c?1:0;
\r
1005 gpu_flag_z=gpu_flag_z?1:0;
\r
1006 gpu_flag_n=gpu_flag_n?1:0;
\r
1008 jaguar_flags=(gpu_flag_n<<2)|(gpu_flag_c<<1)|gpu_flag_z;
\r
1010 if (branch_condition(imm_2))
\r
1013 gpu_pc=delayed_pc;
\r
1016 //////////////////////////////////////////////////////////////////////////////
\r
1018 //////////////////////////////////////////////////////////////////////////////
\r
1025 //////////////////////////////////////////////////////////////////////////////
\r
1026 static void gpu_opcode_add(void)
\r
1034 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1035 variables in asm until we put a _ before it.
\r
1037 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1040 #ifdef __GCCWIN32__
\r
1044 setc _gpu_flag_c \n\
\r
1045 setz _gpu_flag_z \n\
\r
1046 sets _gpu_flag_n \n\
\r
1047 movl %%eax, %0 \n\
\r
1050 : "d"(_Rm), "a"(_Rn));
\r
1056 setc gpu_flag_c \n\
\r
1057 setz gpu_flag_z \n\
\r
1058 sets gpu_flag_n \n\
\r
1059 movl %%eax, %0 \n\
\r
1062 : "d"(_Rm), "a"(_Rn));
\r
1080 //////////////////////////////////////////////////////////////////////////////
\r
1082 //////////////////////////////////////////////////////////////////////////////
\r
1089 //////////////////////////////////////////////////////////////////////////////
\r
1090 static void gpu_opcode_addc(void)
\r
1098 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1099 variables in asm until we put a _ before it.
\r
1101 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1104 #ifdef __GCCWIN32__
\r
1108 cmp $0, _gpu_flag_c \n\
\r
1114 setc _gpu_flag_c \n\
\r
1115 setz _gpu_flag_z \n\
\r
1116 sets _gpu_flag_n \n\
\r
1117 movl %%eax, %0 \n\
\r
1120 : "d"(_Rm), "a"(_Rn));
\r
1126 cmp $0, gpu_flag_c \n\
\r
1132 setc gpu_flag_c \n\
\r
1133 setz gpu_flag_z \n\
\r
1134 sets gpu_flag_n \n\
\r
1135 movl %%eax, %0 \n\
\r
1138 : "d"(_Rm), "a"(_Rn));
\r
1147 cmp [gpu_flag_c],0
\r
1149 jz gpu_opcode_addc_no_carry
\r
1151 gpu_opcode_addc_no_carry:
\r
1161 //////////////////////////////////////////////////////////////////////////////
\r
1163 //////////////////////////////////////////////////////////////////////////////
\r
1170 //////////////////////////////////////////////////////////////////////////////
\r
1171 static void gpu_opcode_addq(void)
\r
1174 uint32 _Rm=gpu_convert_zero[imm_1];
\r
1179 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1180 variables in asm until we put a _ before it.
\r
1182 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1185 #ifdef __GCCWIN32__
\r
1189 setc _gpu_flag_c \n\
\r
1190 setz _gpu_flag_z \n\
\r
1191 sets _gpu_flag_n \n\
\r
1192 movl %%eax, %0 \n\
\r
1195 : "d"(_Rm), "a"(_Rn));
\r
1201 setc gpu_flag_c \n\
\r
1202 setz gpu_flag_z \n\
\r
1203 sets gpu_flag_n \n\
\r
1204 movl %%eax, %0 \n\
\r
1207 : "d"(_Rm), "a"(_Rn));
\r
1225 //////////////////////////////////////////////////////////////////////////////
\r
1227 //////////////////////////////////////////////////////////////////////////////
\r
1234 //////////////////////////////////////////////////////////////////////////////
\r
1235 static void gpu_opcode_addqt(void)
\r
1237 Rn += gpu_convert_zero[imm_1];
\r
1239 //////////////////////////////////////////////////////////////////////////////
\r
1241 //////////////////////////////////////////////////////////////////////////////
\r
1248 //////////////////////////////////////////////////////////////////////////////
\r
1249 static void gpu_opcode_sub(void)
\r
1257 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1258 variables in asm until we put a _ before it.
\r
1260 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1263 #ifdef __GCCWIN32__
\r
1267 setc _gpu_flag_c \n\
\r
1268 setz _gpu_flag_z \n\
\r
1269 sets _gpu_flag_n \n\
\r
1270 movl %%eax, %0 \n\
\r
1273 : "d"(_Rm), "a"(_Rn));
\r
1279 setc gpu_flag_c \n\
\r
1280 setz gpu_flag_z \n\
\r
1281 sets gpu_flag_n \n\
\r
1282 movl %%eax, %0 \n\
\r
1285 : "d"(_Rm), "a"(_Rn));
\r
1303 //////////////////////////////////////////////////////////////////////////////
\r
1305 //////////////////////////////////////////////////////////////////////////////
\r
1312 //////////////////////////////////////////////////////////////////////////////
\r
1313 static void gpu_opcode_subc(void)
\r
1321 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1322 variables in asm until we put a _ before it.
\r
1324 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1327 #ifdef __GCCWIN32__
\r
1331 cmp $0, _gpu_flag_c \n\
\r
1337 setc _gpu_flag_c \n\
\r
1338 setz _gpu_flag_z \n\
\r
1339 sets _gpu_flag_n \n\
\r
1340 movl %%eax, %0 \n\
\r
1343 : "d"(_Rm), "a"(_Rn));
\r
1349 cmp $0, gpu_flag_c \n\
\r
1355 setc gpu_flag_c \n\
\r
1356 setz gpu_flag_z \n\
\r
1357 sets gpu_flag_n \n\
\r
1358 movl %%eax, %0 \n\
\r
1361 : "d"(_Rm), "a"(_Rn));
\r
1368 cmp [gpu_flag_c],0
\r
1370 jz gpu_opcode_subc_no_carry
\r
1372 gpu_opcode_subc_no_carry:
\r
1384 //////////////////////////////////////////////////////////////////////////////
\r
1386 //////////////////////////////////////////////////////////////////////////////
\r
1393 //////////////////////////////////////////////////////////////////////////////
\r
1394 static void gpu_opcode_subq(void)
\r
1396 uint32 _Rm=gpu_convert_zero[imm_1];
\r
1402 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1403 variables in asm until we put a _ before it.
\r
1405 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1408 #ifdef __GCCWIN32__
\r
1412 setc _gpu_flag_c \n\
\r
1413 setz _gpu_flag_z \n\
\r
1414 sets _gpu_flag_n \n\
\r
1415 movl %%eax, %0 \n\
\r
1418 : "d"(_Rm), "a"(_Rn));
\r
1424 setc gpu_flag_c \n\
\r
1425 setz gpu_flag_z \n\
\r
1426 sets gpu_flag_n \n\
\r
1427 movl %%eax, %0 \n\
\r
1430 : "d"(_Rm), "a"(_Rn));
\r
1448 //////////////////////////////////////////////////////////////////////////////
\r
1450 //////////////////////////////////////////////////////////////////////////////
\r
1457 //////////////////////////////////////////////////////////////////////////////
\r
1458 static void gpu_opcode_subqt(void)
\r
1460 Rn -= gpu_convert_zero[imm_1];
\r
1462 //////////////////////////////////////////////////////////////////////////////
\r
1464 //////////////////////////////////////////////////////////////////////////////
\r
1471 //////////////////////////////////////////////////////////////////////////////
\r
1472 static void gpu_opcode_cmp(void)
\r
1479 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1480 variables in asm until we put a _ before it.
\r
1482 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1485 #ifdef __GCCWIN32__
\r
1489 setc _gpu_flag_c \n\
\r
1490 setz _gpu_flag_z \n\
\r
1491 sets _gpu_flag_n \n\
\r
1494 : "d"(_Rm), "a"(_Rn));
\r
1500 setc gpu_flag_c \n\
\r
1501 setz gpu_flag_z \n\
\r
1502 sets gpu_flag_n \n\
\r
1505 : "d"(_Rm), "a"(_Rn));
\r
1521 //////////////////////////////////////////////////////////////////////////////
\r
1523 //////////////////////////////////////////////////////////////////////////////
\r
1530 //////////////////////////////////////////////////////////////////////////////
\r
1531 static void gpu_opcode_cmpq(void)
\r
1533 static int32 sqtable[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1};
\r
1534 int32 _Rm=sqtable[imm_1&0x1f];
\r
1539 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1540 variables in asm until we put a _ before it.
\r
1542 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1545 #ifdef __GCCWIN32__
\r
1549 setc _gpu_flag_c \n\
\r
1550 setz _gpu_flag_z \n\
\r
1551 sets _gpu_flag_n \n\
\r
1554 : "d"(_Rm), "a"(_Rn));
\r
1560 setc gpu_flag_c \n\
\r
1561 setz gpu_flag_z \n\
\r
1562 sets gpu_flag_n \n\
\r
1565 : "d"(_Rm), "a"(_Rn));
\r
1580 //////////////////////////////////////////////////////////////////////////////
\r
1582 //////////////////////////////////////////////////////////////////////////////
\r
1589 //////////////////////////////////////////////////////////////////////////////
\r
1590 static void gpu_opcode_and(void)
\r
1598 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1599 variables in asm until we put a _ before it.
\r
1601 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1604 #ifdef __GCCWIN32__
\r
1608 setz _gpu_flag_z \n\
\r
1609 sets _gpu_flag_n \n\
\r
1610 movl %%eax, %0 \n\
\r
1613 : "d"(_Rm), "a"(_Rn));
\r
1619 setz gpu_flag_z \n\
\r
1620 sets gpu_flag_n \n\
\r
1621 movl %%eax, %0 \n\
\r
1624 : "d"(_Rm), "a"(_Rn));
\r
1640 //////////////////////////////////////////////////////////////////////////////
\r
1642 //////////////////////////////////////////////////////////////////////////////
\r
1649 //////////////////////////////////////////////////////////////////////////////
\r
1650 static void gpu_opcode_or(void)
\r
1658 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1659 variables in asm until we put a _ before it.
\r
1661 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1664 #ifdef __GCCWIN32__
\r
1668 setz _gpu_flag_z \n\
\r
1669 sets _gpu_flag_n \n\
\r
1670 movl %%eax, %0 \n\
\r
1673 : "d"(_Rm), "a"(_Rn));
\r
1679 setz gpu_flag_z \n\
\r
1680 sets gpu_flag_n \n\
\r
1681 movl %%eax, %0 \n\
\r
1684 : "d"(_Rm), "a"(_Rn));
\r
1700 //////////////////////////////////////////////////////////////////////////////
\r
1702 //////////////////////////////////////////////////////////////////////////////
\r
1709 //////////////////////////////////////////////////////////////////////////////
\r
1710 static void gpu_opcode_xor(void)
\r
1718 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1719 variables in asm until we put a _ before it.
\r
1721 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1724 #ifdef __GCCWIN32__
\r
1728 setz _gpu_flag_z \n\
\r
1729 sets _gpu_flag_n \n\
\r
1730 movl %%eax, %0 \n\
\r
1733 : "d"(_Rm), "a"(_Rn));
\r
1739 setz gpu_flag_z \n\
\r
1740 sets gpu_flag_n \n\
\r
1741 movl %%eax, %0 \n\
\r
1744 : "d"(_Rm), "a"(_Rn));
\r
1760 //////////////////////////////////////////////////////////////////////////////
\r
1762 //////////////////////////////////////////////////////////////////////////////
\r
1769 //////////////////////////////////////////////////////////////////////////////
\r
1770 static void gpu_opcode_not(void)
\r
1777 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1778 variables in asm until we put a _ before it.
\r
1780 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1783 #ifdef __GCCWIN32__
\r
1787 setz _gpu_flag_z \n\
\r
1788 sets _gpu_flag_n \n\
\r
1789 movl %%eax, %0 \n\
\r
1798 setz gpu_flag_z \n\
\r
1799 sets gpu_flag_n \n\
\r
1800 movl %%eax, %0 \n\
\r
1818 //////////////////////////////////////////////////////////////////////////////
\r
1820 //////////////////////////////////////////////////////////////////////////////
\r
1827 //////////////////////////////////////////////////////////////////////////////
\r
1828 static void gpu_opcode_move_pc(void)
\r
1832 //////////////////////////////////////////////////////////////////////////////
\r
1834 //////////////////////////////////////////////////////////////////////////////
\r
1841 //////////////////////////////////////////////////////////////////////////////
\r
1842 static void gpu_opcode_sat8(void)
\r
1844 int32 _Rn=(int32)Rn;
\r
1846 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn);
\r
1850 //////////////////////////////////////////////////////////////////////////////
\r
1852 //////////////////////////////////////////////////////////////////////////////
\r
1859 //////////////////////////////////////////////////////////////////////////////
\r
1860 static void gpu_opcode_sat16(void)
\r
1862 int32 _Rn=(int32)Rn;
\r
1863 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn);
\r
1867 //////////////////////////////////////////////////////////////////////////////
\r
1869 //////////////////////////////////////////////////////////////////////////////
\r
1876 //////////////////////////////////////////////////////////////////////////////
\r
1877 static void gpu_opcode_sat24(void)
\r
1879 int32 _Rn=(int32)Rn;
\r
1881 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn);
\r
1885 //////////////////////////////////////////////////////////////////////////////
\r
1887 //////////////////////////////////////////////////////////////////////////////
\r
1894 //////////////////////////////////////////////////////////////////////////////
\r
1895 static void gpu_opcode_store_r14_indexed(void)
\r
1897 gpu_long_write( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2),Rn);
\r
1899 //////////////////////////////////////////////////////////////////////////////
\r
1901 //////////////////////////////////////////////////////////////////////////////
\r
1908 //////////////////////////////////////////////////////////////////////////////
\r
1909 static void gpu_opcode_store_r15_indexed(void)
\r
1911 gpu_long_write( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2),Rn);
\r
1913 //////////////////////////////////////////////////////////////////////////////
\r
1915 //////////////////////////////////////////////////////////////////////////////
\r
1922 //////////////////////////////////////////////////////////////////////////////
\r
1923 static void gpu_opcode_load_r14_ri(void)
\r
1925 Rn=gpu_long_read(gpu_reg[14] + Rm);
\r
1927 //////////////////////////////////////////////////////////////////////////////
\r
1929 //////////////////////////////////////////////////////////////////////////////
\r
1936 //////////////////////////////////////////////////////////////////////////////
\r
1937 static void gpu_opcode_load_r15_ri(void)
\r
1939 Rn=gpu_long_read(gpu_reg[15] + Rm);
\r
1941 //////////////////////////////////////////////////////////////////////////////
\r
1943 //////////////////////////////////////////////////////////////////////////////
\r
1950 //////////////////////////////////////////////////////////////////////////////
\r
1951 static void gpu_opcode_store_r14_ri(void)
\r
1953 gpu_long_write(gpu_reg[14] + Rm,Rn);
\r
1955 //////////////////////////////////////////////////////////////////////////////
\r
1957 //////////////////////////////////////////////////////////////////////////////
\r
1964 //////////////////////////////////////////////////////////////////////////////
\r
1965 static void gpu_opcode_store_r15_ri(void)
\r
1967 gpu_long_write(gpu_reg[15] + Rm,Rn);
\r
1969 //////////////////////////////////////////////////////////////////////////////
\r
1971 //////////////////////////////////////////////////////////////////////////////
\r
1978 //////////////////////////////////////////////////////////////////////////////
\r
1979 static void gpu_opcode_nop(void)
\r
1982 //////////////////////////////////////////////////////////////////////////////
\r
1984 //////////////////////////////////////////////////////////////////////////////
\r
1991 //////////////////////////////////////////////////////////////////////////////
\r
1992 static void gpu_opcode_pack(void)
\r
1998 Rn =((_Rn & 0x03C00000) >> 10) |
\r
1999 ((_Rn & 0x0001E000) >> 5) |
\r
2000 ((_Rn & 0x000000FF));
\r
2004 Rn =((_Rn & 0x0000F000) << 10) |
\r
2005 ((_Rn & 0x00000F00) << 5) |
\r
2006 ((_Rn & 0x000000FF));
\r
2013 //////////////////////////////////////////////////////////////////////////////
\r
2015 //////////////////////////////////////////////////////////////////////////////
\r
2022 //////////////////////////////////////////////////////////////////////////////
\r
2023 static void gpu_opcode_storeb(void)
\r
2025 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
\r
2026 gpu_long_write(Rm,Rn&0xff);
\r
2028 jaguar_byte_write(Rm,Rn);
\r
2030 //////////////////////////////////////////////////////////////////////////////
\r
2032 //////////////////////////////////////////////////////////////////////////////
\r
2039 //////////////////////////////////////////////////////////////////////////////
\r
2040 static void gpu_opcode_storew(void)
\r
2042 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
\r
2043 gpu_long_write(Rm,Rn&0xffff);
\r
2045 jaguar_word_write(Rm,Rn);
\r
2047 //////////////////////////////////////////////////////////////////////////////
\r
2049 //////////////////////////////////////////////////////////////////////////////
\r
2056 //////////////////////////////////////////////////////////////////////////////
\r
2057 static void gpu_opcode_store(void)
\r
2059 gpu_long_write(Rm,Rn);
\r
2061 //////////////////////////////////////////////////////////////////////////////
\r
2063 //////////////////////////////////////////////////////////////////////////////
\r
2070 //////////////////////////////////////////////////////////////////////////////
\r
2071 static void gpu_opcode_storep(void)
\r
2074 gpu_long_write(_Rm, gpu_hidata);
\r
2075 gpu_long_write(_Rm+4, Rn);
\r
2077 //////////////////////////////////////////////////////////////////////////////
\r
2079 //////////////////////////////////////////////////////////////////////////////
\r
2086 //////////////////////////////////////////////////////////////////////////////
\r
2087 static void gpu_opcode_loadb(void)
\r
2089 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
\r
2090 Rn=gpu_long_read(Rm)&0xff;
\r
2092 Rn=jaguar_byte_read(Rm);
\r
2094 //////////////////////////////////////////////////////////////////////////////
\r
2096 //////////////////////////////////////////////////////////////////////////////
\r
2103 //////////////////////////////////////////////////////////////////////////////
\r
2104 static void gpu_opcode_loadw(void)
\r
2106 if ((Rm >= 0xF03000) && (Rm < 0xF04000))
\r
2107 Rn=gpu_long_read(Rm)&0xffff;
\r
2109 Rn=jaguar_word_read(Rm);
\r
2111 //////////////////////////////////////////////////////////////////////////////
\r
2113 //////////////////////////////////////////////////////////////////////////////
\r
2120 //////////////////////////////////////////////////////////////////////////////
\r
2121 static void gpu_opcode_load(void)
\r
2123 Rn = gpu_long_read(Rm);
\r
2125 //////////////////////////////////////////////////////////////////////////////
\r
2127 //////////////////////////////////////////////////////////////////////////////
\r
2134 //////////////////////////////////////////////////////////////////////////////
\r
2135 static void gpu_opcode_loadp(void)
\r
2139 gpu_hidata = gpu_long_read(_Rm);
\r
2140 Rn = gpu_long_read(_Rm+4);
\r
2142 //////////////////////////////////////////////////////////////////////////////
\r
2144 //////////////////////////////////////////////////////////////////////////////
\r
2151 //////////////////////////////////////////////////////////////////////////////
\r
2152 static void gpu_opcode_load_r14_indexed(void)
\r
2154 Rn = gpu_long_read( gpu_reg[14] + (gpu_convert_zero[imm_1] << 2));
\r
2156 //////////////////////////////////////////////////////////////////////////////
\r
2158 //////////////////////////////////////////////////////////////////////////////
\r
2165 //////////////////////////////////////////////////////////////////////////////
\r
2166 static void gpu_opcode_load_r15_indexed(void)
\r
2168 Rn = gpu_long_read( gpu_reg[15] + (gpu_convert_zero[imm_1] << 2));
\r
2170 //////////////////////////////////////////////////////////////////////////////
\r
2172 //////////////////////////////////////////////////////////////////////////////
\r
2179 //////////////////////////////////////////////////////////////////////////////
\r
2180 static void gpu_opcode_movei(void)
\r
2182 Rn = ((uint32)gpu_word_read(gpu_pc)) + (((uint32)gpu_word_read(gpu_pc+2))<<16);
\r
2185 //////////////////////////////////////////////////////////////////////////////
\r
2187 //////////////////////////////////////////////////////////////////////////////
\r
2194 //////////////////////////////////////////////////////////////////////////////
\r
2195 static void gpu_opcode_moveta(void)
\r
2197 alternate_Rn = Rm;
\r
2199 //////////////////////////////////////////////////////////////////////////////
\r
2201 //////////////////////////////////////////////////////////////////////////////
\r
2208 //////////////////////////////////////////////////////////////////////////////
\r
2209 static void gpu_opcode_movefa(void)
\r
2211 Rn = alternate_Rm;
\r
2213 //////////////////////////////////////////////////////////////////////////////
\r
2215 //////////////////////////////////////////////////////////////////////////////
\r
2222 //////////////////////////////////////////////////////////////////////////////
\r
2223 static void gpu_opcode_move(void)
\r
2227 //////////////////////////////////////////////////////////////////////////////
\r
2229 //////////////////////////////////////////////////////////////////////////////
\r
2236 //////////////////////////////////////////////////////////////////////////////
\r
2237 static void gpu_opcode_moveq(void)
\r
2241 //////////////////////////////////////////////////////////////////////////////
\r
2243 //////////////////////////////////////////////////////////////////////////////
\r
2250 //////////////////////////////////////////////////////////////////////////////
\r
2251 static void gpu_opcode_resmac(void)
\r
2255 //////////////////////////////////////////////////////////////////////////////
\r
2257 //////////////////////////////////////////////////////////////////////////////
\r
2264 //////////////////////////////////////////////////////////////////////////////
\r
2265 static void gpu_opcode_imult(void)
\r
2267 uint32 res=Rn=((int16)Rn)*((int16)Rm);
\r
2271 //////////////////////////////////////////////////////////////////////////////
\r
2273 //////////////////////////////////////////////////////////////////////////////
\r
2280 //////////////////////////////////////////////////////////////////////////////
\r
2281 static void gpu_opcode_mult(void)
\r
2283 uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn);
\r
2287 //////////////////////////////////////////////////////////////////////////////
\r
2289 //////////////////////////////////////////////////////////////////////////////
\r
2296 //////////////////////////////////////////////////////////////////////////////
\r
2297 static void gpu_opcode_bclr(void)
\r
2305 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2306 variables in asm until we put a _ before it.
\r
2308 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2311 #ifdef __GCCWIN32__
\r
2316 setz _gpu_flag_z \n\
\r
2317 sets _gpu_flag_n \n\
\r
2318 movl %%eax, %0 \n\
\r
2321 : "c"(_Rm), "a"(_Rn));
\r
2328 setz gpu_flag_z \n\
\r
2329 sets gpu_flag_n \n\
\r
2330 movl %%eax, %0 \n\
\r
2333 : "c"(_Rm), "a"(_Rn));
\r
2351 //////////////////////////////////////////////////////////////////////////////
\r
2353 //////////////////////////////////////////////////////////////////////////////
\r
2360 //////////////////////////////////////////////////////////////////////////////
\r
2361 static void gpu_opcode_btst(void)
\r
2368 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2369 variables in asm until we put a _ before it.
\r
2371 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2374 #ifdef __GCCWIN32__
\r
2378 setnc _gpu_flag_z \n\
\r
2381 : "c"(_Rm), "a"(_Rn));
\r
2387 setnc gpu_flag_z \n\
\r
2390 : "c"(_Rm), "a"(_Rn));
\r
2399 setnc [gpu_flag_z]
\r
2403 //////////////////////////////////////////////////////////////////////////////
\r
2405 //////////////////////////////////////////////////////////////////////////////
\r
2412 //////////////////////////////////////////////////////////////////////////////
\r
2413 static void gpu_opcode_bset(void)
\r
2421 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2422 variables in asm until we put a _ before it.
\r
2424 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2427 #ifdef __GCCWIN32__
\r
2432 setz _gpu_flag_z \n\
\r
2433 sets _gpu_flag_n \n\
\r
2434 movl %%eax, %0 \n\
\r
2437 : "c"(_Rm), "a"(_Rn));
\r
2444 setz gpu_flag_z \n\
\r
2445 sets gpu_flag_n \n\
\r
2446 movl %%eax, %0 \n\
\r
2449 : "c"(_Rm), "a"(_Rn));
\r
2467 //////////////////////////////////////////////////////////////////////////////
\r
2469 //////////////////////////////////////////////////////////////////////////////
\r
2476 //////////////////////////////////////////////////////////////////////////////
\r
2477 static void gpu_opcode_imacn(void)
\r
2479 uint32 res = ((int16)Rm) * ((int16)(Rn));
\r
2482 //////////////////////////////////////////////////////////////////////////////
\r
2484 //////////////////////////////////////////////////////////////////////////////
\r
2491 //////////////////////////////////////////////////////////////////////////////
\r
2492 static void gpu_opcode_mtoi(void)
\r
2495 uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff);
\r
2499 //////////////////////////////////////////////////////////////////////////////
\r
2501 //////////////////////////////////////////////////////////////////////////////
\r
2508 //////////////////////////////////////////////////////////////////////////////
\r
2509 static void gpu_opcode_normi(void)
\r
2516 while ((_Rm & 0xffc00000) == 0)
\r
2521 while ((_Rm & 0xff800000) != 0)
\r
2531 //////////////////////////////////////////////////////////////////////////////
\r
2533 //////////////////////////////////////////////////////////////////////////////
\r
2540 //////////////////////////////////////////////////////////////////////////////
\r
2541 static void gpu_opcode_mmult(void)
\r
2543 int count = gpu_matrix_control&0x0f;
\r
2544 uint32 addr = gpu_pointer_to_matrix; // in the gpu ram
\r
2548 if (!(gpu_matrix_control & 0x10))
\r
2550 for (int i = 0; i < count; i++)
\r
2554 a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff);
\r
2556 a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff);
\r
2558 int16 b=((int16)gpu_word_read(addr+2));
\r
2565 for (int i = 0; i < count; i++)
\r
2569 a=(int16)((gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]>>16)&0xffff);
\r
2571 a=(int16)(gpu_alternate_reg[gpu_opcode_first_parameter + (i>>1)]&0xffff);
\r
2573 int16 b=((int16)gpu_word_read(addr+2));
\r
2575 addr += 4 * count;
\r
2578 Rn = res = (int32)accum;
\r
2579 // carry flag to do
\r
2583 //////////////////////////////////////////////////////////////////////////////
\r
2585 //////////////////////////////////////////////////////////////////////////////
\r
2592 //////////////////////////////////////////////////////////////////////////////
\r
2593 static void gpu_opcode_abs(void)
\r
2598 if (_Rn==0x80000000)
\r
2604 gpu_flag_c = ((_Rn&0x80000000)>>31);
\r
2605 res= Rn = (((int32)_Rn)<0) ? -_Rn : _Rn;
\r
2610 //////////////////////////////////////////////////////////////////////////////
\r
2612 //////////////////////////////////////////////////////////////////////////////
\r
2619 //////////////////////////////////////////////////////////////////////////////
\r
2620 static void gpu_opcode_div(void)
\r
2627 if (gpu_div_control & 1)
\r
2629 gpu_remain = (((uint64)_Rn) << 16) % _Rm;
\r
2630 if (gpu_remain&0x80000000)
\r
2632 Rn = (((uint64)_Rn) << 16) / _Rm;
\r
2636 gpu_remain = _Rn % _Rm;
\r
2637 if (gpu_remain&0x80000000)
\r
2645 //////////////////////////////////////////////////////////////////////////////
\r
2647 //////////////////////////////////////////////////////////////////////////////
\r
2654 //////////////////////////////////////////////////////////////////////////////
\r
2655 static void gpu_opcode_imultn(void)
\r
2657 uint32 res = (int32)((int16)Rn * (int16)Rm);
\r
2658 gpu_acc = (int32)res;
\r
2662 //////////////////////////////////////////////////////////////////////////////
\r
2664 //////////////////////////////////////////////////////////////////////////////
\r
2671 //////////////////////////////////////////////////////////////////////////////
\r
2672 static void gpu_opcode_neg(void)
\r
2679 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2680 variables in asm until we put a _ before it.
\r
2682 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2685 #ifdef __GCCWIN32__
\r
2689 setc _gpu_flag_c \n\
\r
2690 setz _gpu_flag_z \n\
\r
2691 sets _gpu_flag_n \n\
\r
2692 movl %%eax, %0 \n\
\r
2695 : "d"(_Rn), "a"(0));
\r
2701 setc gpu_flag_c \n\
\r
2702 setz gpu_flag_z \n\
\r
2703 sets gpu_flag_n \n\
\r
2704 movl %%eax, %0 \n\
\r
2707 : "d"(_Rn), "a"(0));
\r
2724 //////////////////////////////////////////////////////////////////////////////
\r
2726 //////////////////////////////////////////////////////////////////////////////
\r
2733 //////////////////////////////////////////////////////////////////////////////
\r
2734 static void gpu_opcode_shlq(void)
\r
2736 uint32 shift=(32-gpu_convert_zero[imm_1]);
\r
2742 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2743 variables in asm until we put a _ before it.
\r
2745 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2748 #ifdef __GCCWIN32__
\r
2751 "testl $0x80000000, %2 \n\
\r
2752 setnz _gpu_flag_c \n\
\r
2755 setz _gpu_flag_z \n\
\r
2756 sets _gpu_flag_n \n\
\r
2757 movl %%eax, %0 \n\
\r
2760 : "c"(shift), "a"(_Rn));
\r
2765 "testl $0x80000000, %2 \n\
\r
2766 setnz gpu_flag_c \n\
\r
2769 setz gpu_flag_z \n\
\r
2770 sets gpu_flag_n \n\
\r
2771 movl %%eax, %0 \n\
\r
2774 : "c"(shift), "a"(_Rn));
\r
2783 test eax,0x80000000
\r
2784 setnz [gpu_flag_c]
\r
2794 //////////////////////////////////////////////////////////////////////////////
\r
2796 //////////////////////////////////////////////////////////////////////////////
\r
2803 //////////////////////////////////////////////////////////////////////////////
\r
2804 static void gpu_opcode_shrq(void)
\r
2806 uint32 shift=gpu_convert_zero[imm_1];
\r
2813 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2814 variables in asm until we put a _ before it.
\r
2816 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2819 #ifdef __GCCWIN32__
\r
2822 "testl $0x00000001, %2 \n\
\r
2823 setnz _gpu_flag_c \n\
\r
2826 setz _gpu_flag_z \n\
\r
2827 sets _gpu_flag_n \n\
\r
2828 movl %%eax, %0 \n\
\r
2831 : "c"(shift), "a"(_Rn));
\r
2836 "testl $0x00000001, %2 \n\
\r
2837 setnz gpu_flag_c \n\
\r
2840 setz gpu_flag_z \n\
\r
2841 sets gpu_flag_n \n\
\r
2842 movl %%eax, %0 \n\
\r
2845 : "c"(shift), "a"(_Rn));
\r
2853 test eax,0x00000001
\r
2854 setnz [gpu_flag_c]
\r
2864 //////////////////////////////////////////////////////////////////////////////
\r
2866 //////////////////////////////////////////////////////////////////////////////
\r
2873 //////////////////////////////////////////////////////////////////////////////
\r
2874 static void gpu_opcode_ror(void)
\r
2882 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2883 variables in asm until we put a _ before it.
\r
2885 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2888 #ifdef __GCCWIN32__
\r
2891 "testl $0x80000000, %2 \n\
\r
2892 setnz _gpu_flag_c \n\
\r
2895 setz _gpu_flag_z \n\
\r
2896 sets _gpu_flag_n \n\
\r
2897 movl %%eax, %0 \n\
\r
2900 : "c"(shift), "a"(_Rn));
\r
2905 "testl $0x80000000, %2 \n\
\r
2906 setnz gpu_flag_c \n\
\r
2909 setz gpu_flag_z \n\
\r
2910 sets gpu_flag_n \n\
\r
2911 movl %%eax, %0 \n\
\r
2914 : "c"(shift), "a"(_Rn));
\r
2923 test eax,0x80000000
\r
2924 setnz [gpu_flag_c]
\r
2934 //////////////////////////////////////////////////////////////////////////////
\r
2936 //////////////////////////////////////////////////////////////////////////////
\r
2943 //////////////////////////////////////////////////////////////////////////////
\r
2944 static void gpu_opcode_rorq(void)
\r
2946 uint32 shift = gpu_convert_zero[imm_1 & 0x1F];
\r
2952 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2953 variables in asm until we put a _ before it.
\r
2955 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2958 #ifdef __GCCWIN32__
\r
2961 "testl $0x80000000, %2 \n\
\r
2962 setnz _gpu_flag_c \n\
\r
2965 setz _gpu_flag_z \n\
\r
2966 sets _gpu_flag_n \n\
\r
2967 movl %%eax, %0 \n\
\r
2970 : "c"(shift), "a"(_Rn));
\r
2975 "testl $0x80000000, %2 \n\
\r
2976 setnz gpu_flag_c \n\
\r
2979 setz gpu_flag_z \n\
\r
2980 sets gpu_flag_n \n\
\r
2981 movl %%eax, %0 \n\
\r
2984 : "c"(shift), "a"(_Rn));
\r
2986 #endif // #ifdef __GCCWIN32__
\r
2993 test eax,0x80000000
\r
2994 setnz [gpu_flag_c]
\r
3001 #endif // #ifdef __PORT__
\r
3004 //////////////////////////////////////////////////////////////////////////////
\r
3006 //////////////////////////////////////////////////////////////////////////////
\r
3013 //////////////////////////////////////////////////////////////////////////////
\r
3014 static void gpu_opcode_sha(void)
\r
3016 int32 sRm=(int32)Rm;
\r
3021 uint32 shift=-sRm;
\r
3022 if (shift>=32) shift=32;
\r
3023 gpu_flag_c=(_Rn&0x80000000)>>31;
\r
3033 if (shift>=32) shift=32;
\r
3034 gpu_flag_c=_Rn&0x1;
\r
3037 _Rn=((int32)_Rn)>>1;
\r
3045 //////////////////////////////////////////////////////////////////////////////
\r
3047 //////////////////////////////////////////////////////////////////////////////
\r
3054 //////////////////////////////////////////////////////////////////////////////
\r
3055 static void gpu_opcode_sharq(void)
\r
3057 uint32 shift=gpu_convert_zero[imm_1];
\r
3060 gpu_flag_c = (_Rn & 0x1);
\r
3063 _Rn=((int32)_Rn)>>1;
\r
3070 //////////////////////////////////////////////////////////////////////////////
\r
3072 //////////////////////////////////////////////////////////////////////////////
\r
3079 //////////////////////////////////////////////////////////////////////////////
\r
3080 static void gpu_opcode_sh(void)
\r
3082 int32 sRm=(int32)Rm;
\r
3087 uint32 shift=(-sRm);
\r
3088 if (shift>=32) shift=32;
\r
3089 gpu_flag_c=(_Rn&0x80000000)>>31;
\r
3099 if (shift>=32) shift=32;
\r
3100 gpu_flag_c=_Rn&0x1;
\r