1 //////////////////////////////////////////////////////////////////////////////
\r
3 //////////////////////////////////////////////////////////////////////////////
\r
10 //////////////////////////////////////////////////////////////////////////////
\r
12 #include "include/dsp.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
20 #define CINT5FLAG 0x20000 /* DSP only */
\r
22 extern uint32 jaguar_mainRom_crc32;
\r
24 static void dsp_opcode_addqmod(void);
\r
25 static void dsp_opcode_subqmod(void);
\r
26 static void dsp_opcode_mirror(void);
\r
27 static void dsp_opcode_sat32s(void);
\r
28 static void dsp_opcode_sat16s(void);
\r
29 static void dsp_opcode_add(void);
\r
30 static void dsp_opcode_addc(void);
\r
31 static void dsp_opcode_addq(void);
\r
32 static void dsp_opcode_addqt(void);
\r
33 static void dsp_opcode_sub(void);
\r
34 static void dsp_opcode_subc(void);
\r
35 static void dsp_opcode_subq(void);
\r
36 static void dsp_opcode_subqt(void);
\r
37 static void dsp_opcode_neg(void);
\r
38 static void dsp_opcode_and(void);
\r
39 static void dsp_opcode_or(void);
\r
40 static void dsp_opcode_xor(void);
\r
41 static void dsp_opcode_not(void);
\r
42 static void dsp_opcode_btst(void);
\r
43 static void dsp_opcode_bset(void);
\r
44 static void dsp_opcode_bclr(void);
\r
45 static void dsp_opcode_mult(void);
\r
46 static void dsp_opcode_imult(void);
\r
47 static void dsp_opcode_imultn(void);
\r
48 static void dsp_opcode_resmac(void);
\r
49 static void dsp_opcode_imacn(void);
\r
50 static void dsp_opcode_div(void);
\r
51 static void dsp_opcode_abs(void);
\r
52 static void dsp_opcode_sh(void);
\r
53 static void dsp_opcode_shlq(void);
\r
54 static void dsp_opcode_shrq(void);
\r
55 static void dsp_opcode_sha(void);
\r
56 static void dsp_opcode_sharq(void);
\r
57 static void dsp_opcode_ror(void);
\r
58 static void dsp_opcode_rorq(void);
\r
59 static void dsp_opcode_cmp(void);
\r
60 static void dsp_opcode_cmpq(void);
\r
61 static void dsp_opcode_sat8(void);
\r
62 static void dsp_opcode_sat16(void);
\r
63 static void dsp_opcode_move(void);
\r
64 static void dsp_opcode_moveq(void);
\r
65 static void dsp_opcode_moveta(void);
\r
66 static void dsp_opcode_movefa(void);
\r
67 static void dsp_opcode_movei(void);
\r
68 static void dsp_opcode_loadb(void);
\r
69 static void dsp_opcode_loadw(void);
\r
70 static void dsp_opcode_load(void);
\r
71 static void dsp_opcode_loadp(void);
\r
72 static void dsp_opcode_load_r14_indexed(void);
\r
73 static void dsp_opcode_load_r15_indexed(void);
\r
74 static void dsp_opcode_storeb(void);
\r
75 static void dsp_opcode_storew(void);
\r
76 static void dsp_opcode_store(void);
\r
77 static void dsp_opcode_storep(void);
\r
78 static void dsp_opcode_store_r14_indexed(void);
\r
79 static void dsp_opcode_store_r15_indexed(void);
\r
80 static void dsp_opcode_move_pc(void);
\r
81 static void dsp_opcode_jump(void);
\r
82 static void dsp_opcode_jr(void);
\r
83 static void dsp_opcode_mmult(void);
\r
84 static void dsp_opcode_mtoi(void);
\r
85 static void dsp_opcode_normi(void);
\r
86 static void dsp_opcode_nop(void);
\r
87 static void dsp_opcode_load_r14_ri(void);
\r
88 static void dsp_opcode_load_r15_ri(void);
\r
89 static void dsp_opcode_store_r14_ri(void);
\r
90 static void dsp_opcode_store_r15_ri(void);
\r
91 static void dsp_opcode_sat24(void);
\r
93 uint8 dsp_opcode_cycles[64] =
\r
113 void (*dsp_opcode[64])()=
\r
115 dsp_opcode_add, dsp_opcode_addc, dsp_opcode_addq, dsp_opcode_addqt,
\r
116 dsp_opcode_sub, dsp_opcode_subc, dsp_opcode_subq, dsp_opcode_subqt,
\r
117 dsp_opcode_neg, dsp_opcode_and, dsp_opcode_or, dsp_opcode_xor,
\r
118 dsp_opcode_not, dsp_opcode_btst, dsp_opcode_bset, dsp_opcode_bclr,
\r
119 dsp_opcode_mult, dsp_opcode_imult, dsp_opcode_imultn, dsp_opcode_resmac,
\r
120 dsp_opcode_imacn, dsp_opcode_div, dsp_opcode_abs, dsp_opcode_sh,
\r
121 dsp_opcode_shlq, dsp_opcode_shrq, dsp_opcode_sha, dsp_opcode_sharq,
\r
122 dsp_opcode_ror, dsp_opcode_rorq, dsp_opcode_cmp, dsp_opcode_cmpq,
\r
123 dsp_opcode_subqmod, dsp_opcode_sat16s, dsp_opcode_move, dsp_opcode_moveq,
\r
124 dsp_opcode_moveta, dsp_opcode_movefa, dsp_opcode_movei, dsp_opcode_loadb,
\r
125 dsp_opcode_loadw, dsp_opcode_load, dsp_opcode_sat32s, dsp_opcode_load_r14_indexed,
\r
126 dsp_opcode_load_r15_indexed, dsp_opcode_storeb, dsp_opcode_storew, dsp_opcode_store,
\r
127 dsp_opcode_mirror, dsp_opcode_store_r14_indexed, dsp_opcode_store_r15_indexed, dsp_opcode_move_pc,
\r
128 dsp_opcode_jump, dsp_opcode_jr, dsp_opcode_mmult, dsp_opcode_mtoi,
\r
129 dsp_opcode_normi, dsp_opcode_nop, dsp_opcode_load_r14_ri, dsp_opcode_load_r15_ri,
\r
130 dsp_opcode_store_r14_ri, dsp_opcode_store_r15_ri, dsp_opcode_nop, dsp_opcode_addqmod,
\r
133 uint32 dsp_opcode_use[64];
\r
135 char *dsp_opcode_str[64]=
\r
137 "add", "addc", "addq", "addqt",
\r
138 "sub", "subc", "subq", "subqt",
\r
139 "neg", "and", "or", "xor",
\r
140 "not", "btst", "bset", "bclr",
\r
141 "mult", "imult", "imultn", "resmac",
\r
142 "imacn", "div", "abs", "sh",
\r
143 "shlq", "shrq", "sha", "sharq",
\r
144 "ror", "rorq", "cmp", "cmpq",
\r
145 "subqmod", "sat16s", "move", "moveq",
\r
146 "moveta", "movefa", "movei", "loadb",
\r
147 "loadw", "load", "sat32s", "load_r14_indexed",
\r
148 "load_r15_indexed", "storeb", "storew", "store",
\r
149 "mirror", "store_r14_indexed","store_r15_indexed","move_pc",
\r
150 "jump", "jr", "mmult", "mtoi",
\r
151 "normi", "nop", "load_r14_ri", "load_r15_ri",
\r
152 "store_r14_ri", "store_r15_ri", "nop", "addqmod",
\r
155 static uint16 *mirror_table;
\r
156 static uint8 *dsp_ram_8;
\r
159 static uint32 dsp_pc;
\r
160 static uint32 dsp_acc;
\r
161 static uint32 dsp_remain;
\r
162 static uint32 dsp_modulo;
\r
163 static uint32 dsp_flags;
\r
164 static uint32 dsp_matrix_control;
\r
165 static uint32 dsp_pointer_to_matrix;
\r
166 static uint32 dsp_data_organization;
\r
167 static uint32 dsp_control;
\r
168 static uint32 dsp_div_control;
\r
169 static uint8 dsp_flag_z;
\r
170 static uint8 dsp_flag_n;
\r
171 static uint8 dsp_flag_c;
\r
172 static uint8 dsp_alternate_flag_z;
\r
173 static uint8 dsp_alternate_flag_n;
\r
174 static uint8 dsp_alternate_flag_c;
\r
175 static uint32 *dsp_reg;
\r
176 static uint32 *dsp_alternate_reg;
\r
177 static uint32 *dsp_reg_bank_0;
\r
178 static uint32 *dsp_reg_bank_1;
\r
180 static uint32 dsp_opcode_first_parameter;
\r
181 static uint32 dsp_opcode_second_parameter;
\r
183 #define dsp_running (dsp_control&0x01)
\r
185 #define Rm dsp_reg[dsp_opcode_first_parameter]
\r
186 #define Rn dsp_reg[dsp_opcode_second_parameter]
\r
187 #define alternate_Rm dsp_alternate_reg[dsp_opcode_first_parameter]
\r
188 #define alternate_Rn dsp_alternate_reg[dsp_opcode_second_parameter]
\r
189 #define imm_1 dsp_opcode_first_parameter
\r
190 #define imm_2 dsp_opcode_second_parameter
\r
192 #define set_flag_z(r) dsp_flag_z=(r==0);
\r
193 #define set_flag_n(r) dsp_flag_n=(r&0x80000000);
\r
195 #define reset_flag_z() dsp_flag_z=0;
\r
196 #define reset_flag_n() dsp_flag_n=0;
\r
197 #define reset_flag_c() dsp_flag_c=0;
\r
199 uint32 dsp_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
200 uint8 *dsp_branch_condition_table=0;
\r
201 #define branch_condition(x) dsp_branch_condition_table[(x) + ((jaguar_flags & 7) << 5)]
\r
203 static uint32 dsp_in_exec=0;
\r
204 static uint32 dsp_releaseTimeSlice_flag=0;
\r
208 //////////////////////////////////////////////////////////////////////////////
\r
210 //////////////////////////////////////////////////////////////////////////////
\r
217 //////////////////////////////////////////////////////////////////////////////
\r
218 void dsp_reset_stats(void)
\r
220 for (uint32 i=0;i<64;i++)
\r
221 dsp_opcode_use[i]=0;
\r
224 //////////////////////////////////////////////////////////////////////////////
\r
226 //////////////////////////////////////////////////////////////////////////////
\r
233 //////////////////////////////////////////////////////////////////////////////
\r
234 void dsp_releaseTimeslice(void)
\r
236 dsp_releaseTimeSlice_flag=1;
\r
239 //////////////////////////////////////////////////////////////////////////////
\r
241 //////////////////////////////////////////////////////////////////////////////
\r
248 //////////////////////////////////////////////////////////////////////////////
\r
249 void dsp_build_branch_condition_table(void)
\r
252 #define ZFLAG 0x00001
\r
253 #define CFLAG 0x00002
\r
254 #define NFLAG 0x00004
\r
256 /* allocate the mirror table */
\r
258 mirror_table = (uint16*)malloc(65536 * sizeof(mirror_table[0]));
\r
260 /* fill in the mirror table */
\r
262 for (int i = 0; i < 65536; i++)
\r
263 mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) |
\r
264 ((i >> 11) & 0x0004) | ((i >> 9) & 0x0008) |
\r
265 ((i >> 7) & 0x0010) | ((i >> 5) & 0x0020) |
\r
266 ((i >> 3) & 0x0040) | ((i >> 1) & 0x0080) |
\r
267 ((i << 1) & 0x0100) | ((i << 3) & 0x0200) |
\r
268 ((i << 5) & 0x0400) | ((i << 7) & 0x0800) |
\r
269 ((i << 9) & 0x1000) | ((i << 11) & 0x2000) |
\r
270 ((i << 13) & 0x4000) | ((i << 15) & 0x8000);
\r
272 if (!dsp_branch_condition_table)
\r
274 dsp_branch_condition_table = (uint8*)malloc(32 * 8 * sizeof(dsp_branch_condition_table[0]));
\r
276 /* fill in the condition table */
\r
277 if (dsp_branch_condition_table)
\r
278 for (i = 0; i < 8; i++)
\r
279 for (j = 0; j < 32; j++)
\r
283 if (i & ZFLAG) result = 0;
\r
285 if (!(i & ZFLAG)) result = 0;
\r
287 if (i & (CFLAG << (j >> 4))) result = 0;
\r
289 if (!(i & (CFLAG << (j >> 4)))) result = 0;
\r
290 dsp_branch_condition_table[i * 32 + j] = result;
\r
294 //////////////////////////////////////////////////////////////////////////////
\r
296 //////////////////////////////////////////////////////////////////////////////
\r
303 //////////////////////////////////////////////////////////////////////////////
\r
304 unsigned dsp_byte_read(unsigned int offset)
\r
307 // if ((offset==0xF1CFE0)||(offset==0xF1CFE2))
\r
310 if ((jaguar_mainRom_crc32==0xbfd751a4)||(jaguar_mainRom_crc32==0x053efaf9))
\r
312 if (offset==0xF1CFE0)
\r
315 if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
\r
316 return(dsp_ram_8[offset-dsp_work_ram_base]);
\r
318 if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
\r
320 uint32 data=dsp_long_read(offset&0xfffffffc);
\r
322 if ((offset&0x03)==0)
\r
325 if ((offset&0x03)==1)
\r
326 return((data>>16)&0xff);
\r
328 if ((offset&0x03)==2)
\r
329 return((data>>8)&0xff);
\r
331 if ((offset&0x03)==3)
\r
334 return(jaguar_byte_read(offset));
\r
336 //////////////////////////////////////////////////////////////////////////////
\r
338 //////////////////////////////////////////////////////////////////////////////
\r
345 //////////////////////////////////////////////////////////////////////////////
\r
346 unsigned dsp_word_read(unsigned int offset)
\r
348 offset&=0xFFFFFFFE;
\r
350 if (jaguar_mainRom_crc32==0xa74a97cd)
\r
352 if (offset==0xF1A114) return(0x0000);
\r
353 if (offset==0xF1A116) return(0x0000);
\r
354 if (offset==0xF1B000) return(0x1234);
\r
355 if (offset==0xF1B002) return(0x5678);
\r
358 if (jaguar_mainRom_crc32==0x7ae20823)
\r
360 if (offset==0xF1B9D8) return(0x0000);
\r
361 if (offset==0xF1B9Da) return(0x0000);
\r
362 if (offset==0xF1B2C0) return(0x0000);
\r
363 if (offset==0xF1B2C2) return(0x0000);
\r
366 // pour permettre à wolfenstein 3d de tourner sans le dsp
\r
367 /* if ((offset==0xF1B0D0)||(offset==0xF1B0D2))
\r
371 // pour permettre à nba jam de tourner sans le dsp
\r
372 if (jaguar_mainRom_crc32==0x4faddb18)
\r
374 if (offset==0xf1b2c0) return(0);
\r
375 if (offset==0xf1b2c2) return(0);
\r
376 if (offset==0xf1b240) return(0);
\r
377 if (offset==0xf1b242) return(0);
\r
378 if (offset==0xF1B340) return(0);
\r
379 if (offset==0xF1B342) return(0);
\r
380 if (offset==0xF1BAD8) return(0);
\r
381 if (offset==0xF1BADA) return(0);
\r
382 if (offset==0xF1B040) return(0);
\r
383 if (offset==0xF1B042) return(0);
\r
384 if (offset==0xF1B0C0) return(0);
\r
385 if (offset==0xF1B0C2) return(0);
\r
386 if (offset==0xF1B140) return(0);
\r
387 if (offset==0xF1B142) return(0);
\r
388 if (offset==0xF1B1C0) return(0);
\r
389 if (offset==0xF1B1C2) return(0);
\r
392 if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
\r
394 offset-=dsp_work_ram_base;
\r
395 uint16 data=(((uint16)dsp_ram_8[offset])<<8)|((uint16)dsp_ram_8[offset+1]);
\r
398 if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
\r
402 data=dsp_long_read(offset&0xfffffffc);
\r
405 return(data&0xffff);
\r
409 return(jaguar_word_read(offset));
\r
411 //////////////////////////////////////////////////////////////////////////////
\r
413 //////////////////////////////////////////////////////////////////////////////
\r
420 //////////////////////////////////////////////////////////////////////////////
\r
421 unsigned dsp_long_read(unsigned int offset)
\r
423 offset&=0xFFFFFFFC;
\r
425 if ((offset>=dsp_work_ram_base)&&(offset<dsp_work_ram_base+0x2000))
\r
427 offset-=dsp_work_ram_base;
\r
428 uint32 data= (((uint32)dsp_ram_8[offset] )<<24)|
\r
429 (((uint32)dsp_ram_8[offset+1])<<16)|
\r
430 (((uint32)dsp_ram_8[offset+2])<<8 )|
\r
431 ( (uint32)dsp_ram_8[offset+3]);
\r
434 if ((offset>=dsp_control_ram_base)&&(offset<dsp_control_ram_base+0x20))
\r
439 case 0x00: dsp_flag_c?(dsp_flag_c=1):(dsp_flag_c=0);
\r
440 dsp_flag_z?(dsp_flag_z=1):(dsp_flag_z=0);
\r
441 dsp_flag_n?(dsp_flag_n=1):(dsp_flag_n=0);
\r
443 dsp_flags=(dsp_flags&0xFFFFFFF8)|(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
\r
445 return(dsp_flags&0xFFFFC1FF);
\r
446 case 0x04: return(dsp_matrix_control);
\r
447 case 0x08: return(dsp_pointer_to_matrix);
\r
448 case 0x0C: return(dsp_data_organization);
\r
449 case 0x10: return(dsp_pc);
\r
450 case 0x14: return(dsp_control);
\r
451 case 0x18: return(dsp_modulo);
\r
452 case 0x1C: return(dsp_remain);
\r
453 // default: // unaligned long read //__asm int 3
\r
457 uint32 data=jaguar_word_read(offset);
\r
459 data|=jaguar_word_read(offset+2);
\r
462 //////////////////////////////////////////////////////////////////////////////
\r
464 //////////////////////////////////////////////////////////////////////////////
\r
471 //////////////////////////////////////////////////////////////////////////////
\r
472 void dsp_byte_write(unsigned offset, unsigned data)
\r
474 if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
\r
476 offset -= dsp_work_ram_base;
\r
477 dsp_ram_8[offset] = data;
\r
478 if (dsp_in_exec == 0)
\r
480 // s68000releaseTimeslice();
\r
481 m68k_end_timeslice();
\r
482 gpu_releaseTimeslice();
\r
486 if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
\r
488 uint32 reg = offset & 0x1C;
\r
489 int bytenum = offset & 0x03;
\r
491 if ((reg >= 0x1C) && (reg <= 0x1F))
\r
492 dsp_div_control = (dsp_div_control & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
\r
495 uint32 old_data = dsp_long_read(offset&0xFFFFFFC);
\r
496 bytenum = 3 - bytenum; // convention motorola !!!
\r
497 old_data = (old_data & (~(0xFF << (bytenum << 3)))) | (data << (bytenum << 3));
\r
498 dsp_long_write(offset & 0xFFFFFFC, old_data);
\r
502 // fprintf(log_get(),"dsp: writing %.2x at 0x%.8x\n",data,offset);
\r
503 jaguar_byte_write(offset, data);
\r
505 //////////////////////////////////////////////////////////////////////////////
\r
507 //////////////////////////////////////////////////////////////////////////////
\r
514 //////////////////////////////////////////////////////////////////////////////
\r
515 void dsp_word_write(unsigned offset, unsigned data)
\r
517 offset &= 0xFFFFFFFE;
\r
518 // fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset);
\r
519 if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
\r
521 offset -= dsp_work_ram_base;
\r
522 dsp_ram_8[offset] = data >> 8;
\r
523 dsp_ram_8[offset+1] = data & 0xFF;
\r
524 if (dsp_in_exec == 0)
\r
526 // fprintf(log_get(),"dsp: writing %.4x at 0x%.8x\n",data,offset+dsp_work_ram_base);
\r
527 // s68000releaseTimeslice();
\r
528 m68k_end_timeslice();
\r
529 gpu_releaseTimeslice();
\r
533 else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
\r
535 if ((offset & 0x1C) == 0x1C)
\r
538 dsp_div_control = (dsp_div_control&0xffff0000)|(data&0xffff);
\r
540 dsp_div_control = (dsp_div_control&0xffff)|((data&0xffff)<<16);
\r
544 uint32 old_data = dsp_long_read(offset & 0xffffffc);
\r
546 old_data = (old_data&0xffff0000)|(data&0xffff);
\r
548 old_data = (old_data&0xffff)|((data&0xffff)<<16);
\r
549 dsp_long_write(offset & 0xffffffc, old_data);
\r
553 jaguar_word_write(offset, data);
\r
555 //////////////////////////////////////////////////////////////////////////////
\r
557 //////////////////////////////////////////////////////////////////////////////
\r
564 //////////////////////////////////////////////////////////////////////////////
\r
565 void dsp_long_write(unsigned offset, unsigned data)
\r
567 offset &= 0xFFFFFFFC;
\r
568 // fprintf(log_get(),"dsp: writing %.8x at 0x%.8x\n",data,offset);
\r
569 if ((offset >= dsp_work_ram_base) && (offset < dsp_work_ram_base+0x2000))
\r
571 offset -= dsp_work_ram_base;
\r
572 dsp_ram_8[offset] = data >> 24;
\r
573 dsp_ram_8[offset+1] = (data>>16) & 0xFF;
\r
574 dsp_ram_8[offset+2] = (data>>8) & 0xFF;
\r
575 dsp_ram_8[offset+3] = data & 0xFF;
\r
578 else if ((offset >= dsp_control_ram_base) && (offset < dsp_control_ram_base+0x20))
\r
585 dsp_flag_z = dsp_flags & 0x01;
\r
586 dsp_flag_c = (dsp_flags>>1) & 0x01;
\r
587 dsp_flag_n = (dsp_flags>>2) & 0x01;
\r
588 dsp_update_register_banks();
\r
589 dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3);
\r
590 dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1);
\r
594 dsp_matrix_control = data;
\r
597 dsp_pointer_to_matrix = data;
\r
600 dsp_data_organization = data;
\r
607 uint32 dsp_was_running = dsp_running;
\r
608 // check for DSP->CPU interrupt
\r
611 // fprintf(log_get(),"DSP->CPU interrupt\n");
\r
612 if (tom_irq_enabled(IRQ_GPU) && jaguar_interrupt_handler_is_valid(64))
\r
614 tom_set_pending_gpu_int();
\r
615 // s68000interrupt(7,64);
\r
616 // s68000flushInterrupts();
\r
617 m68k_set_irq(7); // Set 68000 NMI...
\r
618 dsp_releaseTimeslice();
\r
622 // check for CPU->DSP interrupt
\r
625 // fprintf(log_get(),"CPU->DSP interrupt\n");
\r
626 dsp_set_irq_line(0, 1);
\r
627 // s68000releaseTimeslice();
\r
628 m68k_end_timeslice();
\r
629 gpu_releaseTimeslice();
\r
635 //fprintf(log_get(),"asked to perform a single step (single step is %senabled)\n",(data&0x8)?"":"not ");
\r
637 dsp_control = data;
\r
639 // if dsp wasn't running but is now running
\r
640 // execute a few cycles
\r
641 #ifndef DSP_SINGLE_STEPPING
\r
642 if (!dsp_was_running && dsp_running)
\r
647 if (dsp_control & 0x18)
\r
656 dsp_div_control=data;
\r
658 // default: // unaligned long read
\r
663 jaguar_word_write(offset, (data>>16) & 0xFFFF);
\r
664 jaguar_word_write(offset+2, data & 0xFFFF);
\r
666 //////////////////////////////////////////////////////////////////////////////
\r
668 //////////////////////////////////////////////////////////////////////////////
\r
675 //////////////////////////////////////////////////////////////////////////////
\r
676 uint8 * jaguar_rom_load(char * path, uint32 * romSize);
\r
677 void dsp_load_bin_at(char * path, uint32 offset)
\r
682 rom = jaguar_rom_load(path, &romSize);
\r
683 for(uint32 i=0; i<romSize; i++)
\r
684 jaguar_byte_write(offset+i, rom[i]);
\r
686 //////////////////////////////////////////////////////////////////////////////
\r
688 //////////////////////////////////////////////////////////////////////////////
\r
695 //////////////////////////////////////////////////////////////////////////////
\r
697 void dsp_update_register_banks(void)
\r
702 bank = dsp_flags&0x4000;
\r
704 if (dsp_flags & 0x8)
\r
707 if ((!bank && (dsp_reg_bank_0 != dsp_reg)) || (bank && (dsp_reg_bank_1 != dsp_reg)))
\r
709 for (i = 0; i < 32; i++)
\r
712 dsp_reg[i] = dsp_alternate_reg[i];
\r
713 dsp_alternate_reg[i]= temp;
\r
717 dsp_flag_z=dsp_alternate_flag_z;
\r
718 dsp_alternate_flag_z=temp;
\r
721 dsp_flag_n=dsp_alternate_flag_n;
\r
722 dsp_alternate_flag_n=temp;
\r
725 dsp_flag_c=dsp_alternate_flag_c;
\r
726 dsp_alternate_flag_c=temp;
\r
730 dsp_reg_bank_0 = dsp_reg;
\r
731 dsp_reg_bank_1 = dsp_alternate_reg;
\r
735 dsp_reg_bank_0 = dsp_alternate_reg;
\r
736 dsp_reg_bank_1 = dsp_reg;
\r
740 //////////////////////////////////////////////////////////////////////////////
\r
742 //////////////////////////////////////////////////////////////////////////////
\r
749 //////////////////////////////////////////////////////////////////////////////
\r
750 void dsp_check_if_i2s_interrupt_needed(void)
\r
752 static uint32 count=8;
\r
760 // already in an interrupt handler ?
\r
761 if (dsp_flags & 0x8)
\r
764 // get the interrupt mask
\r
765 mask = (dsp_flags >> 4) & 0x1f;
\r
766 mask |= (dsp_flags >> 11) & 0x20;
\r
770 dsp_set_irq_line(1,1);
\r
773 //////////////////////////////////////////////////////////////////////////////
\r
775 //////////////////////////////////////////////////////////////////////////////
\r
782 //////////////////////////////////////////////////////////////////////////////
\r
783 void dsp_check_irqs(void)
\r
785 int bits, mask, which = 0;
\r
787 if (dsp_flags & 0x8)
\r
790 // get the active interrupt bits
\r
791 bits = (dsp_control >> 6) & 0x1f;
\r
792 bits |= (dsp_control >> 10) & 0x20;
\r
794 // get the interrupt mask
\r
795 mask = (dsp_flags >> 4) & 0x1f;
\r
796 mask |= (dsp_flags >> 11) & 0x20;
\r
798 // fprintf(log_get(),"dsp: bits=%.2x mask=%.2x\n",bits,mask);
\r
799 // bail if nothing is available
\r
805 // determine which interrupt
\r
806 if (bits & 0x01) which = 0;
\r
807 if (bits & 0x02) which = 1;
\r
808 if (bits & 0x04) which = 2;
\r
809 if (bits & 0x08) which = 3;
\r
810 if (bits & 0x10) which = 4;
\r
811 if (bits & 0x20) which = 5;
\r
813 // fprintf(log_get(),"dsp: generating interrupt %i\n",which);
\r
816 dsp_update_register_banks();
\r
818 // subqt #4,r31 ; pre-decrement stack pointer
\r
819 // move pc,r30 ; address of interrupted code
\r
820 // store r30,(r31) ; store return address
\r
822 dsp_reg[30]=dsp_pc;
\r
823 dsp_long_write(dsp_reg[31], dsp_pc - 2);
\r
825 // movei #service_address,r30 ; pointer to ISR entry
\r
826 // jump (r30) ; jump to ISR
\r
828 dsp_pc = dsp_work_ram_base;
\r
829 dsp_pc += which * 0x10;
\r
830 dsp_reg[30]=dsp_pc;
\r
832 //////////////////////////////////////////////////////////////////////////////
\r
834 //////////////////////////////////////////////////////////////////////////////
\r
841 //////////////////////////////////////////////////////////////////////////////
\r
842 void dsp_set_irq_line(int irqline, int state)
\r
844 int mask = 0x40 << irqline;
\r
845 dsp_control &= ~mask;
\r
848 dsp_control |= mask;
\r
852 //////////////////////////////////////////////////////////////////////////////
\r
854 //////////////////////////////////////////////////////////////////////////////
\r
861 //////////////////////////////////////////////////////////////////////////////
\r
862 void dsp_init(void)
\r
864 memory_malloc_secure((void**)&dsp_ram_8,0x2000,"dsp work ram");
\r
865 memory_malloc_secure((void**)&dsp_reg,32*sizeof(int32),"dsp bank 0 regs");
\r
866 memory_malloc_secure((void**)&dsp_alternate_reg,32*sizeof(int32),"dsp bank 1 regs");
\r
868 dsp_build_branch_condition_table();
\r
872 //////////////////////////////////////////////////////////////////////////////
\r
874 //////////////////////////////////////////////////////////////////////////////
\r
881 //////////////////////////////////////////////////////////////////////////////
\r
882 void dsp_reset(void)
\r
884 dsp_pc = 0x00f1b000;
\r
885 dsp_acc = 0x00000000;
\r
886 dsp_remain = 0x00000000;
\r
887 dsp_modulo = 0xFFFFFFFF;
\r
888 dsp_flags = 0x00040000;
\r
889 dsp_matrix_control = 0x00000000;
\r
890 dsp_pointer_to_matrix = 0x00000000;
\r
891 dsp_data_organization = 0xffffffff;
\r
892 dsp_control = 0x00012800;
\r
893 dsp_div_control = 0x00000000;
\r
896 for (int i=0;i<32;i++)
\r
898 dsp_reg[i] = 0x00000000;
\r
899 dsp_alternate_reg[i] = 0x00000000;
\r
902 dsp_reg_bank_0 = dsp_reg;
\r
903 dsp_reg_bank_1 = dsp_alternate_reg;
\r
904 // dsp_reg_bank_1 = dsp_reg;
\r
905 // dsp_reg_bank_0 = dsp_alternate_reg;
\r
911 dsp_alternate_flag_z=0;
\r
912 dsp_alternate_flag_n=0;
\r
913 dsp_alternate_flag_c=0;
\r
917 memset(dsp_ram_8, 0xff, 0x2000);
\r
919 //////////////////////////////////////////////////////////////////////////////
\r
921 //////////////////////////////////////////////////////////////////////////////
\r
928 //////////////////////////////////////////////////////////////////////////////
\r
929 void dsp_done(void)
\r
932 fprintf(log_get(),"dsp: stopped at pc=0x%.8x dsp_modulo=0x%.8x(dsp %s running)\n",dsp_pc,dsp_modulo,dsp_running?"was":"wasn't");
\r
933 fprintf(log_get(),"dsp: %sin interrupt handler\n",(dsp_flags & 0x8)?"":"not ");
\r
936 // get the active interrupt bits
\r
937 bits = (dsp_control >> 6) & 0x1f;
\r
938 bits |= (dsp_control >> 10) & 0x20;
\r
940 // get the interrupt mask
\r
941 mask = (dsp_flags >> 4) & 0x1f;
\r
942 mask |= (dsp_flags >> 11) & 0x20;
\r
944 fprintf(log_get(),"dsp: bits=0x%.8x mask=0x%.8x\n",bits,mask);
\r
945 fprintf(log_get(),"\nregisters bank 0\n");
\r
946 for (int j=0;j<8;j++)
\r
948 fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
\r
949 (j<<2)+0,dsp_reg[(j<<2)+0],
\r
950 (j<<2)+1,dsp_reg[(j<<2)+1],
\r
951 (j<<2)+2,dsp_reg[(j<<2)+2],
\r
952 (j<<2)+3,dsp_reg[(j<<2)+3]);
\r
955 // fprintf(log_get(),"registers bank 1\n");
\r
956 // for (j=0;j<8;j++)
\r
958 // fprintf(log_get(),"\tr%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x r%2i=0x%.8x\n",
\r
959 // (j<<2)+0,dsp_alternate_reg[(j<<2)+0],
\r
960 // (j<<2)+1,dsp_alternate_reg[(j<<2)+1],
\r
961 // (j<<2)+2,dsp_alternate_reg[(j<<2)+2],
\r
962 // (j<<2)+3,dsp_alternate_reg[(j<<2)+3]);
\r
965 static char buffer[512];
\r
966 j=dsp_work_ram_base;
\r
967 for (int i=0;i<4096;i++)
\r
970 j+=dasmjag(JAGUAR_DSP,buffer,j);
\r
971 // fprintf(log_get(),"\t0x%.8x: %s\n",oldj,buffer);
\r
975 fprintf(log_get(),"dsp opcodes use:\n");
\r
978 if (dsp_opcode_use[i])
\r
979 fprintf(log_get(),"\t%s %i\n",dsp_opcode_str[i],dsp_opcode_use[i]);
\r
982 memory_free(dsp_ram_8);
\r
985 //////////////////////////////////////////////////////////////////////////////
\r
987 //////////////////////////////////////////////////////////////////////////////
\r
994 //////////////////////////////////////////////////////////////////////////////
\r
995 void dsp_exec(int32 cycles)
\r
997 if ((cycles!=1)&&(jaguar_mainRom_crc32==0xba74c3ed))
\r
998 dsp_check_if_i2s_interrupt_needed();
\r
1000 #ifdef DSP_SINGLE_STEPPING
\r
1001 if (dsp_control&0x18)
\r
1004 dsp_control&=~0x10;
\r
1008 dsp_releaseTimeSlice_flag=0;
\r
1010 while ((cycles>0)&&(dsp_running))
\r
1012 dsp_flag_c=(dsp_flag_c?1:0);
\r
1013 dsp_flag_z=(dsp_flag_z?1:0);
\r
1014 dsp_flag_n=(dsp_flag_n?1:0);
\r
1018 if (dsp_pc==0x00f1b02c)
\r
1027 if (dsp_pc==0x00f1b032)
\r
1029 dsp_fp=fopen("c:\\bad.log","wrt");
\r
1031 MessageBox(NULL,"Cannot open dsp log","",MB_OK);
\r
1035 fprintf(dsp_fp,"0x%.8x\n",dsp_pc);
\r
1038 // if (dsp_pc==0x00f1b130)
\r
1039 // dsp_load_bin_at("SCHRIFT.DAT",0x120000);
\r
1041 uint16 opcode=dsp_word_read(dsp_pc);
\r
1042 dsp_opcode_first_parameter=(opcode&0x3e0)>>5;
\r
1043 dsp_opcode_second_parameter=(opcode&0x1f);
\r
1045 dsp_opcode[opcode>>10]();
\r
1046 dsp_opcode_use[opcode>>10]++;
\r
1047 cycles-=dsp_opcode_cycles[opcode>>10];
\r
1051 //////////////////////////////////////////////////////////////////////////////
\r
1053 //////////////////////////////////////////////////////////////////////////////
\r
1060 //////////////////////////////////////////////////////////////////////////////
\r
1061 static void dsp_opcode_jump(void)
\r
1063 uint32 delayed_pc = Rm;
\r
1064 uint32 jaguar_flags;
\r
1066 // normalize flags
\r
1067 dsp_flag_c=dsp_flag_c?1:0;
\r
1068 dsp_flag_z=dsp_flag_z?1:0;
\r
1069 dsp_flag_n=dsp_flag_n?1:0;
\r
1071 jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
\r
1073 if (branch_condition(imm_2))
\r
1076 dsp_pc=delayed_pc;
\r
1079 //////////////////////////////////////////////////////////////////////////////
\r
1081 //////////////////////////////////////////////////////////////////////////////
\r
1088 //////////////////////////////////////////////////////////////////////////////
\r
1089 static void dsp_opcode_jr(void)
\r
1091 int32 offset=(imm_1&0x10) ? (0xFFFFFFF0|imm_1) : imm_1;
\r
1093 int32 delayed_pc = dsp_pc + (offset * 2);
\r
1094 uint32 jaguar_flags;
\r
1096 // normalize flags
\r
1097 dsp_flag_c=dsp_flag_c?1:0;
\r
1098 dsp_flag_z=dsp_flag_z?1:0;
\r
1099 dsp_flag_n=dsp_flag_n?1:0;
\r
1101 jaguar_flags=(dsp_flag_n<<2)|(dsp_flag_c<<1)|dsp_flag_z;
\r
1103 if (branch_condition(imm_2))
\r
1106 dsp_pc=delayed_pc;
\r
1109 //////////////////////////////////////////////////////////////////////////////
\r
1111 //////////////////////////////////////////////////////////////////////////////
\r
1118 //////////////////////////////////////////////////////////////////////////////
\r
1119 static void dsp_opcode_add(void)
\r
1127 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1128 variables in asm until we put a _ before it.
\r
1130 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1132 #ifdef __GCCWIN32__
\r
1141 : "d"(_Rm), "a"(_Rn));
\r
1152 : "d"(_Rm), "a"(_Rn));
\r
1169 //////////////////////////////////////////////////////////////////////////////
\r
1171 //////////////////////////////////////////////////////////////////////////////
\r
1178 //////////////////////////////////////////////////////////////////////////////
\r
1179 static void dsp_opcode_addc(void)
\r
1187 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1188 variables in asm until we put a _ before it.
\r
1190 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1191 We use __GCCWIN32__ for this "bug".
\r
1194 #ifdef __GCCWIN32__
\r
1198 cmp $0, _dsp_flag_c
\r
1210 : "d"(_Rm), "a"(_Rn));
\r
1215 cmp $0, dsp_flag_c
\r
1227 : "d"(_Rm), "a"(_Rn));
\r
1236 cmp [dsp_flag_c],0
\r
1238 jz dsp_opcode_addc_no_carry
\r
1240 dsp_opcode_addc_no_carry:
\r
1250 //////////////////////////////////////////////////////////////////////////////
\r
1252 //////////////////////////////////////////////////////////////////////////////
\r
1259 //////////////////////////////////////////////////////////////////////////////
\r
1260 static void dsp_opcode_addq(void)
\r
1263 uint32 _Rm=dsp_convert_zero[imm_1];
\r
1269 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1270 variables in asm until we put a _ before it.
\r
1272 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1275 #ifdef __GCCWIN32__
\r
1285 : "d"(_Rm), "a"(_Rn));
\r
1297 : "d"(_Rm), "a"(_Rn));
\r
1315 //////////////////////////////////////////////////////////////////////////////
\r
1317 //////////////////////////////////////////////////////////////////////////////
\r
1324 //////////////////////////////////////////////////////////////////////////////
\r
1325 static void dsp_opcode_sub(void)
\r
1333 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1334 variables in asm until we put a _ before it.
\r
1336 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1339 #ifdef __GCCWIN32__
\r
1349 : "d"(_Rm), "a"(_Rn));
\r
1361 : "d"(_Rm), "a"(_Rn));
\r
1379 //////////////////////////////////////////////////////////////////////////////
\r
1381 //////////////////////////////////////////////////////////////////////////////
\r
1388 //////////////////////////////////////////////////////////////////////////////
\r
1389 static void dsp_opcode_subc(void)
\r
1397 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1398 variables in asm until we put a _ before it.
\r
1400 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1403 #ifdef __GCCWIN32__
\r
1407 cmp $0, _dsp_flag_c
\r
1419 : "d"(_Rm), "a"(_Rn));
\r
1425 cmp $0, dsp_flag_c
\r
1437 : "d"(_Rm), "a"(_Rn));
\r
1446 cmp [dsp_flag_c],0
\r
1448 jz dsp_opcode_subc_no_carry
\r
1450 dsp_opcode_subc_no_carry:
\r
1460 //////////////////////////////////////////////////////////////////////////////
\r
1462 //////////////////////////////////////////////////////////////////////////////
\r
1469 //////////////////////////////////////////////////////////////////////////////
\r
1470 static void dsp_opcode_subq(void)
\r
1472 uint32 _Rm=dsp_convert_zero[imm_1];
\r
1478 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1479 variables in asm until we put a _ before it.
\r
1481 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1484 #ifdef __GCCWIN32__
\r
1494 : "d"(_Rm), "a"(_Rn));
\r
1506 : "d"(_Rm), "a"(_Rn));
\r
1523 //////////////////////////////////////////////////////////////////////////////
\r
1525 //////////////////////////////////////////////////////////////////////////////
\r
1532 //////////////////////////////////////////////////////////////////////////////
\r
1533 static void dsp_opcode_cmp(void)
\r
1540 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1541 variables in asm until we put a _ before it.
\r
1543 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1546 #ifdef __GCCWIN32__
\r
1555 : "d"(_Rm), "a"(_Rn));
\r
1566 : "d"(_Rm), "a"(_Rn));
\r
1582 //////////////////////////////////////////////////////////////////////////////
\r
1584 //////////////////////////////////////////////////////////////////////////////
\r
1591 //////////////////////////////////////////////////////////////////////////////
\r
1592 static void dsp_opcode_cmpq(void)
\r
1594 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
1595 int32 _Rm=sqtable[imm_1&0x1f];
\r
1600 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1601 variables in asm until we put a _ before it.
\r
1603 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1606 #ifdef __GCCWIN32__
\r
1615 : "d"(_Rm), "a"(_Rn));
\r
1626 : "d"(_Rm), "a"(_Rn));
\r
1642 //////////////////////////////////////////////////////////////////////////////
\r
1644 //////////////////////////////////////////////////////////////////////////////
\r
1651 //////////////////////////////////////////////////////////////////////////////
\r
1652 static void dsp_opcode_and(void)
\r
1660 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1661 variables in asm until we put a _ before it.
\r
1663 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1666 #ifdef __GCCWIN32__
\r
1675 : "d"(_Rm), "a"(_Rn));
\r
1686 : "d"(_Rm), "a"(_Rn));
\r
1703 //////////////////////////////////////////////////////////////////////////////
\r
1705 //////////////////////////////////////////////////////////////////////////////
\r
1712 //////////////////////////////////////////////////////////////////////////////
\r
1713 static void dsp_opcode_or(void)
\r
1721 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1722 variables in asm until we put a _ before it.
\r
1724 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1727 #ifdef __GCCWIN32__
\r
1736 : "d"(_Rm), "a"(_Rn));
\r
1747 : "d"(_Rm), "a"(_Rn));
\r
1764 //////////////////////////////////////////////////////////////////////////////
\r
1766 //////////////////////////////////////////////////////////////////////////////
\r
1773 //////////////////////////////////////////////////////////////////////////////
\r
1774 static void dsp_opcode_xor(void)
\r
1782 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1783 variables in asm until we put a _ before it.
\r
1785 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1788 #ifdef __GCCWIN32__
\r
1797 : "d"(_Rm), "a"(_Rn));
\r
1808 : "d"(_Rm), "a"(_Rn));
\r
1825 //////////////////////////////////////////////////////////////////////////////
\r
1827 //////////////////////////////////////////////////////////////////////////////
\r
1834 //////////////////////////////////////////////////////////////////////////////
\r
1835 static void dsp_opcode_not(void)
\r
1842 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
1843 variables in asm until we put a _ before it.
\r
1845 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
1848 #ifdef __GCCWIN32__
\r
1884 //////////////////////////////////////////////////////////////////////////////
\r
1886 //////////////////////////////////////////////////////////////////////////////
\r
1893 //////////////////////////////////////////////////////////////////////////////
\r
1894 static void dsp_opcode_move_pc(void)
\r
1898 //////////////////////////////////////////////////////////////////////////////
\r
1900 //////////////////////////////////////////////////////////////////////////////
\r
1907 //////////////////////////////////////////////////////////////////////////////
\r
1908 static void dsp_opcode_sat8(void)
\r
1910 int32 _Rn=(int32)Rn;
\r
1912 uint32 res= Rn = (_Rn<0) ? 0 : (_Rn > 0xff ? 0xff : _Rn);
\r
1916 //////////////////////////////////////////////////////////////////////////////
\r
1918 //////////////////////////////////////////////////////////////////////////////
\r
1925 //////////////////////////////////////////////////////////////////////////////
\r
1926 static void dsp_opcode_sat16(void)
\r
1929 uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFF ? 0xFFFF : _Rn);
\r
1933 //////////////////////////////////////////////////////////////////////////////
\r
1935 //////////////////////////////////////////////////////////////////////////////
\r
1942 //////////////////////////////////////////////////////////////////////////////
\r
1943 static void dsp_opcode_sat24(void)
\r
1947 uint32 res= Rn = (_Rn&0x80000000) ? 0 : (_Rn > 0xFFFFFF ? 0xFFFFFF : _Rn);
\r
1951 //////////////////////////////////////////////////////////////////////////////
\r
1953 //////////////////////////////////////////////////////////////////////////////
\r
1960 //////////////////////////////////////////////////////////////////////////////
\r
1961 static void dsp_opcode_store_r14_indexed(void)
\r
1963 dsp_long_write( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2),Rn);
\r
1965 //////////////////////////////////////////////////////////////////////////////
\r
1967 //////////////////////////////////////////////////////////////////////////////
\r
1974 //////////////////////////////////////////////////////////////////////////////
\r
1975 static void dsp_opcode_store_r15_indexed(void)
\r
1977 dsp_long_write( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2),Rn);
\r
1979 //////////////////////////////////////////////////////////////////////////////
\r
1981 //////////////////////////////////////////////////////////////////////////////
\r
1988 //////////////////////////////////////////////////////////////////////////////
\r
1989 static void dsp_opcode_load_r14_ri(void)
\r
1991 Rn=dsp_long_read(dsp_reg[14] + Rm);
\r
1993 //////////////////////////////////////////////////////////////////////////////
\r
1995 //////////////////////////////////////////////////////////////////////////////
\r
2002 //////////////////////////////////////////////////////////////////////////////
\r
2003 static void dsp_opcode_load_r15_ri(void)
\r
2005 Rn=dsp_long_read(dsp_reg[15] + Rm);
\r
2007 //////////////////////////////////////////////////////////////////////////////
\r
2009 //////////////////////////////////////////////////////////////////////////////
\r
2016 //////////////////////////////////////////////////////////////////////////////
\r
2017 static void dsp_opcode_store_r14_ri(void)
\r
2019 dsp_long_write(dsp_reg[14] + Rm,Rn);
\r
2021 //////////////////////////////////////////////////////////////////////////////
\r
2023 //////////////////////////////////////////////////////////////////////////////
\r
2030 //////////////////////////////////////////////////////////////////////////////
\r
2031 static void dsp_opcode_store_r15_ri(void)
\r
2033 dsp_long_write(dsp_reg[15] + Rm,Rn);
\r
2035 //////////////////////////////////////////////////////////////////////////////
\r
2037 //////////////////////////////////////////////////////////////////////////////
\r
2044 //////////////////////////////////////////////////////////////////////////////
\r
2045 static void dsp_opcode_nop(void)
\r
2048 //////////////////////////////////////////////////////////////////////////////
\r
2050 //////////////////////////////////////////////////////////////////////////////
\r
2057 //////////////////////////////////////////////////////////////////////////////
\r
2058 static void dsp_opcode_pack(void)
\r
2064 Rn =((_Rn & 0x03C00000) >> 10) |
\r
2065 ((_Rn & 0x0001E000) >> 5) |
\r
2066 ((_Rn & 0x000000FF));
\r
2070 Rn =((_Rn & 0x0000F000) << 10) |
\r
2071 ((_Rn & 0x00000F00) << 5) |
\r
2072 ((_Rn & 0x000000FF));
\r
2079 //////////////////////////////////////////////////////////////////////////////
\r
2081 //////////////////////////////////////////////////////////////////////////////
\r
2088 //////////////////////////////////////////////////////////////////////////////
\r
2089 static void dsp_opcode_storeb(void)
\r
2091 if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
\r
2092 dsp_long_write(Rm,Rn&0xff);
\r
2094 jaguar_byte_write(Rm,Rn);
\r
2096 //////////////////////////////////////////////////////////////////////////////
\r
2098 //////////////////////////////////////////////////////////////////////////////
\r
2105 //////////////////////////////////////////////////////////////////////////////
\r
2106 static void dsp_opcode_storew(void)
\r
2108 if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
\r
2109 dsp_long_write(Rm,Rn&0xffff);
\r
2111 jaguar_word_write(Rm,Rn);
\r
2113 //////////////////////////////////////////////////////////////////////////////
\r
2115 //////////////////////////////////////////////////////////////////////////////
\r
2122 //////////////////////////////////////////////////////////////////////////////
\r
2123 static void dsp_opcode_store(void)
\r
2125 dsp_long_write(Rm,Rn);
\r
2127 //////////////////////////////////////////////////////////////////////////////
\r
2129 //////////////////////////////////////////////////////////////////////////////
\r
2136 //////////////////////////////////////////////////////////////////////////////
\r
2137 static void dsp_opcode_loadb(void)
\r
2139 if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
\r
2140 Rn=dsp_long_read(Rm)&0xff;
\r
2142 Rn=jaguar_byte_read(Rm);
\r
2144 //////////////////////////////////////////////////////////////////////////////
\r
2146 //////////////////////////////////////////////////////////////////////////////
\r
2153 //////////////////////////////////////////////////////////////////////////////
\r
2154 static void dsp_opcode_loadw(void)
\r
2156 if ((Rm >= dsp_work_ram_base) && (Rm < (dsp_work_ram_base+0x2000)))
\r
2157 Rn=dsp_long_read(Rm)&0xffff;
\r
2159 Rn=jaguar_word_read(Rm);
\r
2161 //////////////////////////////////////////////////////////////////////////////
\r
2163 //////////////////////////////////////////////////////////////////////////////
\r
2170 //////////////////////////////////////////////////////////////////////////////
\r
2171 static void dsp_opcode_load(void)
\r
2173 Rn = dsp_long_read(Rm);
\r
2175 //////////////////////////////////////////////////////////////////////////////
\r
2177 //////////////////////////////////////////////////////////////////////////////
\r
2184 //////////////////////////////////////////////////////////////////////////////
\r
2185 static void dsp_opcode_load_r14_indexed(void)
\r
2187 Rn = dsp_long_read( dsp_reg[14] + (dsp_convert_zero[imm_1] << 2));
\r
2189 //////////////////////////////////////////////////////////////////////////////
\r
2191 //////////////////////////////////////////////////////////////////////////////
\r
2198 //////////////////////////////////////////////////////////////////////////////
\r
2199 static void dsp_opcode_load_r15_indexed(void)
\r
2201 Rn = dsp_long_read( dsp_reg[15] + (dsp_convert_zero[imm_1] << 2));
\r
2203 //////////////////////////////////////////////////////////////////////////////
\r
2205 //////////////////////////////////////////////////////////////////////////////
\r
2212 //////////////////////////////////////////////////////////////////////////////
\r
2213 static void dsp_opcode_movei(void)
\r
2215 Rn = ((uint32)dsp_word_read(dsp_pc)) + (((uint32)dsp_word_read(dsp_pc+2))<<16);
\r
2218 //////////////////////////////////////////////////////////////////////////////
\r
2220 //////////////////////////////////////////////////////////////////////////////
\r
2227 //////////////////////////////////////////////////////////////////////////////
\r
2228 static void dsp_opcode_moveta(void)
\r
2230 alternate_Rn = Rm;
\r
2232 //////////////////////////////////////////////////////////////////////////////
\r
2234 //////////////////////////////////////////////////////////////////////////////
\r
2241 //////////////////////////////////////////////////////////////////////////////
\r
2242 static void dsp_opcode_movefa(void)
\r
2244 Rn = alternate_Rm;
\r
2246 //////////////////////////////////////////////////////////////////////////////
\r
2248 //////////////////////////////////////////////////////////////////////////////
\r
2255 //////////////////////////////////////////////////////////////////////////////
\r
2256 static void dsp_opcode_move(void)
\r
2260 //////////////////////////////////////////////////////////////////////////////
\r
2262 //////////////////////////////////////////////////////////////////////////////
\r
2269 //////////////////////////////////////////////////////////////////////////////
\r
2270 static void dsp_opcode_moveq(void)
\r
2274 //////////////////////////////////////////////////////////////////////////////
\r
2276 //////////////////////////////////////////////////////////////////////////////
\r
2283 //////////////////////////////////////////////////////////////////////////////
\r
2284 static void dsp_opcode_resmac(void)
\r
2288 //////////////////////////////////////////////////////////////////////////////
\r
2290 //////////////////////////////////////////////////////////////////////////////
\r
2297 //////////////////////////////////////////////////////////////////////////////
\r
2298 static void dsp_opcode_imult(void)
\r
2300 uint32 res=Rn=((int16)Rn)*((int16)Rm);
\r
2304 //////////////////////////////////////////////////////////////////////////////
\r
2306 //////////////////////////////////////////////////////////////////////////////
\r
2313 //////////////////////////////////////////////////////////////////////////////
\r
2314 static void dsp_opcode_mult(void)
\r
2316 uint32 res=Rn = ((uint16)Rm) * ((uint16)Rn);
\r
2320 //////////////////////////////////////////////////////////////////////////////
\r
2322 //////////////////////////////////////////////////////////////////////////////
\r
2329 //////////////////////////////////////////////////////////////////////////////
\r
2330 static void dsp_opcode_bclr(void)
\r
2338 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2339 variables in asm until we put a _ before it.
\r
2341 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2344 #ifdef __GCCWIN32__
\r
2354 : "c"(_Rm), "a"(_Rn));
\r
2366 : "c"(_Rm), "a"(_Rn));
\r
2385 //////////////////////////////////////////////////////////////////////////////
\r
2387 //////////////////////////////////////////////////////////////////////////////
\r
2394 //////////////////////////////////////////////////////////////////////////////
\r
2395 static void dsp_opcode_btst(void)
\r
2402 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2403 variables in asm until we put a _ before it.
\r
2405 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2408 #ifdef __GCCWIN32__
\r
2415 : "c"(_Rm), "a"(_Rn));
\r
2424 : "c"(_Rm), "a"(_Rn));
\r
2434 setnc [dsp_flag_z]
\r
2438 //////////////////////////////////////////////////////////////////////////////
\r
2440 //////////////////////////////////////////////////////////////////////////////
\r
2447 //////////////////////////////////////////////////////////////////////////////
\r
2448 static void dsp_opcode_bset(void)
\r
2456 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2457 variables in asm until we put a _ before it.
\r
2459 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2462 #ifdef __GCCWIN32__
\r
2472 : "c"(_Rm), "a"(_Rn));
\r
2484 : "c"(_Rm), "a"(_Rn));
\r
2502 //////////////////////////////////////////////////////////////////////////////
\r
2504 //////////////////////////////////////////////////////////////////////////////
\r
2511 //////////////////////////////////////////////////////////////////////////////
\r
2512 static void dsp_opcode_subqt(void)
\r
2514 Rn -= dsp_convert_zero[imm_1];
\r
2516 //////////////////////////////////////////////////////////////////////////////
\r
2518 //////////////////////////////////////////////////////////////////////////////
\r
2525 //////////////////////////////////////////////////////////////////////////////
\r
2526 static void dsp_opcode_addqt(void)
\r
2528 Rn += dsp_convert_zero[imm_1];
\r
2530 //////////////////////////////////////////////////////////////////////////////
\r
2532 //////////////////////////////////////////////////////////////////////////////
\r
2539 //////////////////////////////////////////////////////////////////////////////
\r
2540 static void dsp_opcode_imacn(void)
\r
2542 uint32 res=((int16)Rm) * ((int16)(Rn));
\r
2545 //////////////////////////////////////////////////////////////////////////////
\r
2547 //////////////////////////////////////////////////////////////////////////////
\r
2554 //////////////////////////////////////////////////////////////////////////////
\r
2555 static void dsp_opcode_mtoi(void)
\r
2558 uint32 res=Rn=(((INT32)_Rm >> 8) & 0xff800000) | (_Rm & 0x007fffff);
\r
2562 //////////////////////////////////////////////////////////////////////////////
\r
2564 //////////////////////////////////////////////////////////////////////////////
\r
2571 //////////////////////////////////////////////////////////////////////////////
\r
2572 static void dsp_opcode_normi(void)
\r
2579 while ((_Rm & 0xffc00000) == 0)
\r
2584 while ((_Rm & 0xff800000) != 0)
\r
2594 //////////////////////////////////////////////////////////////////////////////
\r
2596 //////////////////////////////////////////////////////////////////////////////
\r
2603 //////////////////////////////////////////////////////////////////////////////
\r
2604 static void dsp_opcode_mmult(void)
\r
2606 int count = dsp_matrix_control&0x0f;
\r
2607 uint32 addr = dsp_pointer_to_matrix; // in the gpu ram
\r
2611 if (!(dsp_matrix_control & 0x10))
\r
2613 for (int i = 0; i < count; i++)
\r
2617 a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff);
\r
2619 a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff);
\r
2620 int16 b=((int16)dsp_word_read(addr+2));
\r
2627 for (int i = 0; i < count; i++)
\r
2631 a=(int16)((dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]>>16)&0xffff);
\r
2633 a=(int16)(dsp_alternate_reg[dsp_opcode_first_parameter + (i>>1)]&0xffff);
\r
2634 int16 b=((int16)dsp_word_read(addr+2));
\r
2636 addr += 4 * count;
\r
2639 Rn = res = (int32)accum;
\r
2640 // carry flag to do
\r
2644 //////////////////////////////////////////////////////////////////////////////
\r
2646 //////////////////////////////////////////////////////////////////////////////
\r
2653 //////////////////////////////////////////////////////////////////////////////
\r
2654 static void dsp_opcode_abs(void)
\r
2659 if (_Rn==0x80000000)
\r
2665 dsp_flag_c = ((_Rn&0x80000000)>>31);
\r
2666 res= Rn = (_Rn & 0x80000000) ? -_Rn : _Rn;
\r
2671 //////////////////////////////////////////////////////////////////////////////
\r
2673 //////////////////////////////////////////////////////////////////////////////
\r
2680 //////////////////////////////////////////////////////////////////////////////
\r
2681 static void dsp_opcode_div(void)
\r
2688 if (dsp_div_control & 1)
\r
2690 dsp_remain = (((uint64)_Rn) << 16) % _Rm;
\r
2691 if (dsp_remain&0x80000000)
\r
2693 Rn = (((uint64)_Rn) << 16) / _Rm;
\r
2697 dsp_remain = _Rn % _Rm;
\r
2698 if (dsp_remain&0x80000000)
\r
2706 //////////////////////////////////////////////////////////////////////////////
\r
2708 //////////////////////////////////////////////////////////////////////////////
\r
2715 //////////////////////////////////////////////////////////////////////////////
\r
2716 static void dsp_opcode_imultn(void)
\r
2718 uint32 res=(int32)(((int16)Rn)*((int16)Rm));
\r
2719 dsp_acc=(int32)res;
\r
2723 //////////////////////////////////////////////////////////////////////////////
\r
2725 //////////////////////////////////////////////////////////////////////////////
\r
2732 //////////////////////////////////////////////////////////////////////////////
\r
2733 static void dsp_opcode_neg(void)
\r
2740 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2741 variables in asm until we put a _ before it.
\r
2743 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2746 #ifdef __GCCWIN32__
\r
2757 : "d"(_Rn), "a"(0));
\r
2770 : "d"(_Rn), "a"(0));
\r
2788 //////////////////////////////////////////////////////////////////////////////
\r
2790 //////////////////////////////////////////////////////////////////////////////
\r
2797 //////////////////////////////////////////////////////////////////////////////
\r
2798 static void dsp_opcode_shlq(void)
\r
2800 uint32 shift=(32-dsp_convert_zero[imm_1]);
\r
2806 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2807 variables in asm until we put a _ before it.
\r
2809 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2812 #ifdef __GCCWIN32__
\r
2815 "testl $0x80000000, %2
\r
2824 : "c"(shift), "a"(_Rn));
\r
2829 "testl $0x80000000, %2
\r
2838 : "c"(shift), "a"(_Rn));
\r
2847 test eax,0x80000000
\r
2848 setnz [dsp_flag_c]
\r
2858 //////////////////////////////////////////////////////////////////////////////
\r
2860 //////////////////////////////////////////////////////////////////////////////
\r
2867 //////////////////////////////////////////////////////////////////////////////
\r
2868 static void dsp_opcode_shrq(void)
\r
2870 uint32 shift=dsp_convert_zero[imm_1];
\r
2877 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2878 variables in asm until we put a _ before it.
\r
2880 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2883 #ifdef __GCCWIN32__
\r
2886 "testl $0x00000001, %2
\r
2895 : "c"(shift), "a"(_Rn));
\r
2900 "testl $0x00000001, %2
\r
2909 : "c"(shift), "a"(_Rn));
\r
2918 test eax,0x00000001
\r
2919 setnz [dsp_flag_c]
\r
2929 //////////////////////////////////////////////////////////////////////////////
\r
2931 //////////////////////////////////////////////////////////////////////////////
\r
2938 //////////////////////////////////////////////////////////////////////////////
\r
2939 static void dsp_opcode_ror(void)
\r
2947 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
2948 variables in asm until we put a _ before it.
\r
2950 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
2953 #ifdef __GCCWIN32__
\r
2956 "testl $0x80000000, %2
\r
2965 : "c"(shift), "a"(_Rn));
\r
2970 "testl $0x80000000, %2
\r
2979 : "c"(shift), "a"(_Rn));
\r
2988 test eax,0x80000000
\r
2989 setnz [dsp_flag_c]
\r
2999 //////////////////////////////////////////////////////////////////////////////
\r
3001 //////////////////////////////////////////////////////////////////////////////
\r
3008 //////////////////////////////////////////////////////////////////////////////
\r
3009 static void dsp_opcode_rorq(void)
\r
3011 uint32 shift=dsp_convert_zero[imm_1&0x1f];
\r
3017 GCC on WIN32 (more importantly mingw) doesn't know the declared
\r
3018 variables in asm until we put a _ before it.
\r
3020 So the declaration dsp_flag_c needs to be _dsp_flag_c on mingw.
\r
3023 #ifdef __GCCWIN32__
\r
3026 "testl $0x80000000, %2
\r
3035 : "c"(shift), "a"(_Rn));
\r
3040 "testl $0x80000000, %2
\r
3049 : "c"(shift), "a"(_Rn));
\r
3058 test eax,0x80000000
\r
3059 setnz [dsp_flag_c]
\r
3069 //////////////////////////////////////////////////////////////////////////////
\r
3071 //////////////////////////////////////////////////////////////////////////////
\r
3078 //////////////////////////////////////////////////////////////////////////////
\r
3079 static void dsp_opcode_sha(void)
\r
3081 int32 sRm=(int32)Rm;
\r
3086 uint32 shift=-sRm;
\r
3087 if (shift>=32) shift=32;
\r
3088 dsp_flag_c=(_Rn&0x80000000)>>31;
\r
3098 if (shift>=32) shift=32;
\r
3099 dsp_flag_c=_Rn&0x1;
\r
3102 _Rn=((int32)_Rn)>>1;
\r
3110 //////////////////////////////////////////////////////////////////////////////
\r
3112 //////////////////////////////////////////////////////////////////////////////
\r
3119 //////////////////////////////////////////////////////////////////////////////
\r
3120 static void dsp_opcode_sharq(void)
\r
3122 uint32 shift=dsp_convert_zero[imm_1];
\r
3125 dsp_flag_c = (_Rn & 0x1);
\r
3128 _Rn=((int32)_Rn)>>1;
\r
3135 //////////////////////////////////////////////////////////////////////////////
\r
3137 //////////////////////////////////////////////////////////////////////////////
\r
3144 //////////////////////////////////////////////////////////////////////////////
\r
3145 static void dsp_opcode_sh(void)
\r
3147 int32 sRm=(int32)Rm;
\r
3152 uint32 shift=(-sRm);
\r
3153 if (shift>=32) shift=32;
\r
3154 dsp_flag_c=(_Rn&0x80000000)>>31;
\r
3164 if (shift>=32) shift=32;
\r
3165 dsp_flag_c=_Rn&0x1;
\r
3177 #define CLR_ZN { dsp_flag_n=0; dsp_flag_z=0; };
\r
3178 #define CLR_ZNC { dsp_flag_c=0; dsp_flag_n=0; dsp_flag_z=0; };
\r
3179 #define SET_Z(r) (dsp_flag_z= ((r) == 0))
\r
3180 #define SET_C_ADD(a,b) (dsp_flag_c= ((UINT32)(b) > (UINT32)(~(a))) << 1)
\r
3181 #define SET_C_SUB(a,b) (dsp_flag_c= ((UINT32)(b) > (UINT32)(a)) << 1)
\r
3182 #define SET_N(r) (dsp_flag_n= (((UINT32)(r) >> 29) & 4))
\r
3183 #define SET_ZN(r) SET_N(r); SET_Z(r)
\r
3184 #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
\r
3185 #define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
\r
3187 void dsp_opcode_addqmod(void)
\r
3189 UINT32 r1 = dsp_convert_zero[imm_1];
\r
3191 UINT32 res = r2 + r1;
\r
3192 res = (res & (~dsp_modulo)) | (r2 & dsp_modulo);
\r
3194 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
\r
3196 void dsp_opcode_subqmod(void)
\r
3198 UINT32 r1 = dsp_convert_zero[imm_1];
\r
3200 UINT32 res = r2 - r1;
\r
3201 res = (res & (~dsp_modulo)) | (r2 & dsp_modulo);
\r
3204 SET_ZNC_SUB(r2,r1,res);
\r
3206 void dsp_opcode_mirror(void)
\r
3209 UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
\r
3211 CLR_ZN; SET_ZN(res);
\r
3213 void dsp_opcode_sat32s(void)
\r
3215 INT32 r2 = (UINT32)Rn;
\r
3216 INT32 temp = dsp_acc >> 32;
\r
3217 UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2;
\r
3219 CLR_ZN; SET_ZN(res);
\r
3221 void dsp_opcode_sat16s(void)
\r
3224 UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2;
\r
3226 CLR_ZN; SET_ZN(res);
\r