|
|
1.1 root 1: /*
1.1.1.2 root 2: DSP M56001 emulation
3: Instructions interpreter, execution thread
4:
5: (C) 2003-2008 ARAnyM developer team
6:
7: This program is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2 of the License, or
10: (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20: */
21:
22: #ifdef HAVE_CONFIG_H
23: #include "config.h"
24: #endif
25:
26: #include "dsp_core.h"
1.1 root 27: #include "dsp_cpu.h"
28: #ifdef DSP_DISASM
29: #include "dsp_disasm.h"
30: #endif
31:
32: #define DEBUG 0
33:
34: /* More disasm infos, if wanted */
1.1.1.2 root 35: #define DSP_DISASM_INST 0 /* Instructions */
36: #define DSP_DISASM_REG 0 /* Registers changes */
37: #define DSP_DISASM_MEM 0 /* Memory changes */
38: #define DSP_DISASM_INTER 0 /* Interrupts */
39: #define DSP_DISASM_STATE 0 /* State change */
1.1 root 40:
1.1.1.2 root 41: #define DSP_COUNT_IPS 0 /* Count instruction per seconds */
42:
43: #if defined(DSP_DISASM) && (DSP_DISASM_MEM==1)
44: # define write_memory(x,y,z) write_memory_disasm(x,y,z)
45: #else
46: # define write_memory(x,y,z) write_memory_raw(x,y,z)
47: #endif
1.1 root 48:
49: /**********************************
50: * Defines
51: **********************************/
52:
53: #define BITMASK(x) ((1<<(x))-1)
54:
55: /**********************************
56: * Variables
57: **********************************/
58:
59: /* Length of current instruction */
1.1.1.2 root 60: static Uint32 cur_inst_len; /* =0:jump, >0:increment */
1.1 root 61:
62: /* Current instruction */
1.1.1.2 root 63: static Uint32 cur_inst;
1.1 root 64:
65: /* Parallel move temp data */
1.1.1.2 root 66: typedef union {
67: Uint32 *host_pointer;
68: Uint32 dsp_address;
1.1 root 69: } parmove_dest_u;
70:
1.1.1.2 root 71: static Uint32 tmp_parmove_src[2][3]; /* What to read */
1.1 root 72: static parmove_dest_u tmp_parmove_dest[2][3]; /* Where to write */
1.1.1.2 root 73: static Uint32 tmp_parmove_start[2]; /* From where to read/write */
74: static Uint32 tmp_parmove_len[2]; /* How many to read/write */
75: static Uint32 tmp_parmove_type[2]; /* 0=register, 1=memory */
76: static Uint32 tmp_parmove_space[2]; /* Memory space to write to */
1.1 root 77:
78: /* PC on Rep instruction ? */
1.1.1.2 root 79: static Uint32 pc_on_rep;
1.1 root 80:
81: /**********************************
82: * Functions
83: **********************************/
84:
85: typedef void (*dsp_emul_t)(void);
86:
87: static void dsp_execute_instruction(void);
88: static void dsp_postexecute_update_pc(void);
89: static void dsp_postexecute_interrupts(void);
90:
1.1.1.2 root 91: static void dsp_ccr_extension(Uint32 *reg0, Uint32 *reg1);
92: static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1);
93: static void dsp_ccr_negative(Uint32 *reg0);
94: static void dsp_ccr_zero(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2);
95:
96: static Uint32 read_memory(int space, Uint16 address);
97: static void write_memory_raw(int space, Uint32 address, Uint32 value);
98: #if defined(DSP_DISASM) && (DSP_DISASM_MEM==1)
99: static Uint32 read_memory_disasm(int space, Uint16 address);
100: static void write_memory_disasm(int space, Uint32 address, Uint32 value);
1.1 root 101: #endif
102:
1.1.1.2 root 103: static void dsp_stack_push(Uint32 curpc, Uint32 cursr);
104: static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr);
1.1 root 105:
106: static void opcode8h_0(void);
107: static void opcode8h_1(void);
108: static void opcode8h_4(void);
109: static void opcode8h_6(void);
110: static void opcode8h_8(void);
111: static void opcode8h_a(void);
112: static void opcode8h_b(void);
113:
1.1.1.2 root 114: static void dsp_update_rn(Uint32 numreg, Sint16 modifier);
115: static void dsp_update_rn_bitreverse(Uint32 numreg);
116: static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier);
117: static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr);
118: static int dsp_calc_cc(Uint32 cc_code);
1.1 root 119:
120: static void dsp_undefined(void);
121:
122: /* Instructions without parallel moves */
123: static void dsp_andi(void);
124: static void dsp_bchg(void);
125: static void dsp_bclr(void);
126: static void dsp_bset(void);
127: static void dsp_btst(void);
128: static void dsp_div(void);
129: static void dsp_do(void);
130: static void dsp_enddo(void);
131: static void dsp_illegal(void);
132: static void dsp_jcc(void);
133: static void dsp_jclr(void);
134: static void dsp_jmp(void);
135: static void dsp_jscc(void);
136: static void dsp_jsclr(void);
137: static void dsp_jset(void);
138: static void dsp_jsr(void);
139: static void dsp_jsset(void);
140: static void dsp_lua(void);
141: static void dsp_movec(void);
142: static void dsp_movem(void);
143: static void dsp_movep(void);
144: static void dsp_nop(void);
145: static void dsp_norm(void);
146: static void dsp_ori(void);
147: static void dsp_rep(void);
148: static void dsp_reset(void);
149: static void dsp_rti(void);
150: static void dsp_rts(void);
151: static void dsp_stop(void);
152: static void dsp_swi(void);
153: static void dsp_tcc(void);
154: static void dsp_wait(void);
155:
1.1.1.3 ! root 156: static void dsp_do_ea(void);
! 157: static void dsp_do_aa(void);
! 158: static void dsp_do_imm(void);
! 159: static void dsp_do_reg(void);
! 160: static void dsp_rep_aa(void);
! 161: static void dsp_rep_ea(void);
! 162: static void dsp_rep_imm(void);
! 163: static void dsp_rep_reg(void);
! 164: static void dsp_movec_aa(void);
! 165: static void dsp_movec_ea(void);
! 166: static void dsp_movec_imm(void);
! 167: static void dsp_movec_reg(void);
1.1 root 168: static void dsp_movep_0(void);
169: static void dsp_movep_1(void);
170: static void dsp_movep_2(void);
171:
172: /* Parallel move analyzer */
173: static void dsp_parmove_read(void);
174: static void dsp_parmove_write(void);
175:
1.1.1.2 root 176: static int dsp_pm_read_accu24(int numreg, Uint32 *dest);
1.1 root 177: static void dsp_pm_writereg(int numreg, int position);
178:
179: static void dsp_pm_0(void);
180: static void dsp_pm_1(void);
181: static void dsp_pm_2(void);
182: static void dsp_pm_2_2(void);
183: static void dsp_pm_3(void);
184: static void dsp_pm_4(void);
1.1.1.2 root 185: static void dsp_pm_4x(int immediat, Uint32 l_addr);
1.1 root 186: static void dsp_pm_5(void);
187: static void dsp_pm_8(void);
188:
189: /* 56bits arithmetic */
1.1.1.2 root 190: static Uint16 dsp_abs56(Uint32 *dest);
191: static Uint16 dsp_asl56(Uint32 *dest);
192: static Uint16 dsp_asr56(Uint32 *dest);
193: static Uint16 dsp_add56(Uint32 *source, Uint32 *dest);
194: static Uint16 dsp_sub56(Uint32 *source, Uint32 *dest);
195: static void dsp_mul56(Uint32 source1, Uint32 source2, Uint32 *dest);
196: static void dsp_rnd56(Uint32 *dest);
1.1 root 197:
198: /* Instructions with parallel moves */
199: static void dsp_abs(void);
200: static void dsp_adc(void);
201: static void dsp_add(void);
202: static void dsp_addl(void);
203: static void dsp_addr(void);
204: static void dsp_and(void);
205: static void dsp_asl(void);
206: static void dsp_asr(void);
207: static void dsp_clr(void);
208: static void dsp_cmp(void);
209: static void dsp_cmpm(void);
210: static void dsp_eor(void);
211: static void dsp_lsl(void);
212: static void dsp_lsr(void);
213: static void dsp_mac(void);
214: static void dsp_macr(void);
215: static void dsp_move(void);
216: static void dsp_mpy(void);
217: static void dsp_mpyr(void);
218: static void dsp_neg(void);
219: static void dsp_not(void);
220: static void dsp_or(void);
221: static void dsp_rnd(void);
222: static void dsp_rol(void);
223: static void dsp_ror(void);
224: static void dsp_sbc(void);
225: static void dsp_sub(void);
226: static void dsp_subl(void);
227: static void dsp_subr(void);
228: static void dsp_tfr(void);
229: static void dsp_tst(void);
230:
231: static void dsp_move_pm(void);
232:
233: static dsp_emul_t opcodes8h[16]={
234: opcode8h_0,
235: opcode8h_1,
236: dsp_tcc,
237: dsp_tcc,
238: opcode8h_4,
239: dsp_movec,
240: opcode8h_6,
241: dsp_movem,
242: opcode8h_8,
243: opcode8h_8,
244: opcode8h_a,
245: opcode8h_b,
246: dsp_jmp,
247: dsp_jsr,
248: dsp_jcc,
249: dsp_jscc
250: };
251:
252: static dsp_emul_t opcodes_0809[16]={
253: dsp_move_pm,
254: dsp_move_pm,
255: dsp_move_pm,
256: dsp_move_pm,
257:
258: dsp_movep,
259: dsp_movep,
260: dsp_movep,
261: dsp_movep,
262:
263: dsp_move_pm,
264: dsp_move_pm,
265: dsp_move_pm,
266: dsp_move_pm,
267:
268: dsp_movep,
269: dsp_movep,
270: dsp_movep,
271: dsp_movep
272: };
273:
274: static dsp_emul_t opcodes_0a[32]={
275: /* 00 000 */ dsp_bclr,
276: /* 00 001 */ dsp_bset,
277: /* 00 010 */ dsp_bclr,
278: /* 00 011 */ dsp_bset,
279: /* 00 100 */ dsp_jclr,
280: /* 00 101 */ dsp_jset,
281: /* 00 110 */ dsp_jclr,
282: /* 00 111 */ dsp_jset,
283:
284: /* 01 000 */ dsp_bclr,
285: /* 01 001 */ dsp_bset,
286: /* 01 010 */ dsp_bclr,
287: /* 01 011 */ dsp_bset,
288: /* 01 100 */ dsp_jclr,
289: /* 01 101 */ dsp_jset,
290: /* 01 110 */ dsp_jclr,
291: /* 01 111 */ dsp_jset,
292:
293: /* 10 000 */ dsp_bclr,
294: /* 10 001 */ dsp_bset,
295: /* 10 010 */ dsp_bclr,
296: /* 10 011 */ dsp_bset,
297: /* 10 100 */ dsp_jclr,
298: /* 10 101 */ dsp_jset,
299: /* 10 110 */ dsp_jclr,
300: /* 10 111 */ dsp_jset,
301:
302: /* 11 000 */ dsp_jclr,
303: /* 11 001 */ dsp_jset,
304: /* 11 010 */ dsp_bclr,
305: /* 11 011 */ dsp_bset,
306: /* 11 100 */ dsp_jmp,
307: /* 11 101 */ dsp_jcc,
308: /* 11 110 */ dsp_undefined,
309: /* 11 111 */ dsp_undefined
310: };
311:
312: static dsp_emul_t opcodes_0b[32]={
313: /* 00 000 */ dsp_bchg,
314: /* 00 001 */ dsp_btst,
315: /* 00 010 */ dsp_bchg,
316: /* 00 011 */ dsp_btst,
317: /* 00 100 */ dsp_jsclr,
318: /* 00 101 */ dsp_jsset,
319: /* 00 110 */ dsp_jsclr,
320: /* 00 111 */ dsp_jsset,
321:
322: /* 01 000 */ dsp_bchg,
323: /* 01 001 */ dsp_btst,
324: /* 01 010 */ dsp_bchg,
325: /* 01 011 */ dsp_btst,
326: /* 01 100 */ dsp_jsclr,
327: /* 01 101 */ dsp_jsset,
328: /* 01 110 */ dsp_jsclr,
329: /* 01 111 */ dsp_jsset,
330:
331: /* 10 000 */ dsp_bchg,
332: /* 10 001 */ dsp_btst,
333: /* 10 010 */ dsp_bchg,
334: /* 10 011 */ dsp_btst,
335: /* 10 100 */ dsp_jsclr,
336: /* 10 101 */ dsp_jsset,
337: /* 10 110 */ dsp_jsclr,
338: /* 10 111 */ dsp_jsset,
339:
340: /* 11 000 */ dsp_jsclr,
341: /* 11 001 */ dsp_jsclr,
342: /* 11 010 */ dsp_bchg,
343: /* 11 011 */ dsp_btst,
344: /* 11 100 */ dsp_jsr,
345: /* 11 101 */ dsp_jscc,
346: /* 11 110 */ dsp_undefined,
347: /* 11 111 */ dsp_undefined
348: };
349:
350: static dsp_emul_t opcodes_parmove[16]={
351: dsp_pm_0,
352: dsp_pm_1,
353: dsp_pm_2,
354: dsp_pm_3,
355: dsp_pm_4,
356: dsp_pm_5,
357: dsp_pm_5,
358: dsp_pm_5,
359:
360: dsp_pm_8,
361: dsp_pm_8,
362: dsp_pm_8,
363: dsp_pm_8,
364: dsp_pm_8,
365: dsp_pm_8,
366: dsp_pm_8,
367: dsp_pm_8
368: };
369:
370: static dsp_emul_t opcodes_alu003f[64]={
371: /* 0x00 - 0x0f */
372: dsp_move,
373: dsp_tfr,
374: dsp_addr,
375: dsp_tst,
376: dsp_undefined,
377: dsp_cmp,
378: dsp_subr,
379: dsp_cmpm,
380: dsp_undefined,
381: dsp_tfr,
382: dsp_addr,
383: dsp_tst,
384: dsp_undefined,
385: dsp_cmp,
386: dsp_subr,
387: dsp_cmpm,
388:
389: /* 0x10 - 0x1f */
390: dsp_add,
391: dsp_rnd,
392: dsp_addl,
393: dsp_clr,
394: dsp_sub,
395: dsp_undefined,
396: dsp_subl,
397: dsp_not,
398: dsp_add,
399: dsp_rnd,
400: dsp_addl,
401: dsp_clr,
402: dsp_sub,
403: dsp_undefined,
404: dsp_subl,
405: dsp_not,
406:
407: /* 0x20 - 0x2f */
408: dsp_add,
409: dsp_adc,
410: dsp_asr,
411: dsp_lsr,
412: dsp_sub,
413: dsp_sbc,
414: dsp_abs,
415: dsp_ror,
416: dsp_add,
417: dsp_adc,
418: dsp_asr,
419: dsp_lsr,
420: dsp_sub,
421: dsp_sbc,
422: dsp_abs,
423: dsp_ror,
424:
425: /* 0x30 - 0x3f */
426: dsp_add,
427: dsp_adc,
428: dsp_asl,
429: dsp_lsl,
430: dsp_sub,
431: dsp_sbc,
432: dsp_neg,
433: dsp_rol,
434: dsp_add,
435: dsp_adc,
436: dsp_asl,
437: dsp_lsl,
438: dsp_sub,
439: dsp_sbc,
440: dsp_neg,
441: dsp_rol
442: };
443:
444: static dsp_emul_t opcodes_alu407f[16]={
445: dsp_add,
446: dsp_tfr,
447: dsp_or,
448: dsp_eor,
449: dsp_sub,
450: dsp_cmp,
451: dsp_and,
452: dsp_cmpm,
453: dsp_add,
454: dsp_tfr,
455: dsp_or,
456: dsp_eor,
457: dsp_sub,
458: dsp_cmp,
459: dsp_and,
460: dsp_cmpm
461: };
462:
463: static dsp_emul_t opcodes_alu80ff[4]={
464: dsp_mpy,
465: dsp_mpyr,
466: dsp_mac,
467: dsp_macr
468: };
469:
1.1.1.3 ! root 470: static dsp_emul_t opcodes_do[8]={
! 471: dsp_do_aa,
! 472: dsp_do_imm,
! 473: dsp_do_ea,
! 474: dsp_do_imm,
1.1 root 475:
476: dsp_undefined,
1.1.1.3 ! root 477: dsp_do_imm,
! 478: dsp_do_reg,
! 479: dsp_do_imm
1.1 root 480: };
481:
1.1.1.3 ! root 482: static dsp_emul_t opcodes_rep[8]={
! 483: dsp_rep_aa,
! 484: dsp_rep_imm,
! 485: dsp_rep_ea,
! 486: dsp_rep_imm,
1.1 root 487:
488: dsp_undefined,
1.1.1.3 ! root 489: dsp_rep_imm,
! 490: dsp_rep_reg,
! 491: dsp_rep_imm
1.1 root 492: };
493:
1.1.1.3 ! root 494: static dsp_emul_t opcodes_movec[8]={
1.1 root 495: dsp_undefined,
496: dsp_undefined,
497: dsp_undefined,
1.1.1.3 ! root 498: dsp_movec_reg,
1.1 root 499:
1.1.1.3 ! root 500: dsp_movec_aa,
! 501: dsp_movec_imm,
! 502: dsp_movec_ea,
! 503: dsp_movec_imm
1.1 root 504: };
505:
506: static dsp_emul_t opcodes_movep[4]={
507: dsp_movep_0,
508: dsp_movep_1,
509: dsp_movep_2,
510: dsp_movep_2
511: };
512:
513: static int registers_lmove[8][2]={
514: {DSP_REG_A1,DSP_REG_A0}, /* A10 */
515: {DSP_REG_B1,DSP_REG_B0}, /* B10 */
516: {DSP_REG_X1,DSP_REG_X0}, /* X */
517: {DSP_REG_Y1,DSP_REG_Y0}, /* Y */
518: {DSP_REG_A,DSP_REG_A}, /* A */
519: {DSP_REG_B,DSP_REG_B}, /* B */
520: {DSP_REG_A,DSP_REG_B}, /* AB */
521: {DSP_REG_B,DSP_REG_A} /* BA */
522: };
523:
524: static int registers_tcc[16][2]={
525: {DSP_REG_B,DSP_REG_A},
526: {DSP_REG_A,DSP_REG_B},
527: {DSP_REG_NULL,DSP_REG_NULL},
528: {DSP_REG_NULL,DSP_REG_NULL},
529:
530: {DSP_REG_NULL,DSP_REG_NULL},
531: {DSP_REG_NULL,DSP_REG_NULL},
532: {DSP_REG_NULL,DSP_REG_NULL},
533: {DSP_REG_NULL,DSP_REG_NULL},
534:
535: {DSP_REG_X0,DSP_REG_A},
536: {DSP_REG_X0,DSP_REG_B},
537: {DSP_REG_Y0,DSP_REG_A},
538: {DSP_REG_Y0,DSP_REG_B},
1.1.1.2 root 539:
540: {DSP_REG_X1,DSP_REG_A},
541: {DSP_REG_X1,DSP_REG_B},
1.1 root 542: {DSP_REG_Y1,DSP_REG_A},
543: {DSP_REG_Y1,DSP_REG_B}
544: };
545:
546: static int registers_mpy[8][2]={
547: {DSP_REG_X0,DSP_REG_X0},
548: {DSP_REG_Y0,DSP_REG_Y0},
549: {DSP_REG_X1,DSP_REG_X0},
550: {DSP_REG_Y1,DSP_REG_Y0},
551:
552: {DSP_REG_X0,DSP_REG_Y1},
553: {DSP_REG_Y0,DSP_REG_X0},
554: {DSP_REG_X1,DSP_REG_Y0},
555: {DSP_REG_Y1,DSP_REG_X1}
556: };
557:
558: static int registers_mask[64]={
559: 0, 0, 0, 0,
560: 24, 24, 24, 24,
561: 24, 24, 8, 8,
562: 24, 24, 24, 24,
563:
564: 16, 16, 16, 16,
565: 16, 16, 16, 16,
566: 16, 16, 16, 16,
567: 16, 16, 16, 16,
568:
569: 16, 16, 16, 16,
570: 16, 16, 16, 16,
571: 0, 0, 0, 0,
572: 0, 0, 0, 0,
573:
574: 0, 0, 0, 0,
575: 0, 0, 0, 0,
576: 0, 16, 8, 6,
577: 6, 6, 16, 16
578: };
579:
580: /**********************************
581: * Emulator kernel
582: **********************************/
583:
1.1.1.2 root 584: /* Yep, feel lazy, so put it there */
585: static dsp_core_t *dsp_core;
586:
587: int dsp56k_do_execute(void *th_dsp_core)
1.1 root 588: {
1.1.1.2 root 589: Uint32 start_time, num_inst;
590:
591: dsp_core = th_dsp_core;
592: #ifdef DSP_DISASM
593: dsp56k_disasm_init(dsp_core);
594: #endif
1.1 root 595:
1.1.1.2 root 596: #if DSP_DISASM_STATE
597: fprintf(stderr, "Dsp: WAIT_BOOTSTRAP\n");
598: #endif
599: SDL_SemWait(dsp_core->semaphore);
600:
601: start_time = SDL_GetTicks();
602: num_inst = 0;
603: while(dsp_core->running) {
1.1 root 604: dsp_execute_instruction();
1.1.1.2 root 605: #if DSP_COUNT_IPS
606: ++num_inst;
607: if ((num_inst & 63) == 0) {
608: /* Evaluate time after <N> instructions have been executed to avoid asking too frequently */
609: Uint32 cur_time = SDL_GetTicks();
610: if (cur_time-start_time>1000) {
611: fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time));
612: start_time=cur_time;
613: num_inst=0;
614: }
615: }
616: #endif
1.1 root 617: }
618:
1.1.1.2 root 619: #if DSP_DISASM_STATE
620: fprintf(stderr, "Dsp: SHUTDOWN\n");
621: #endif
1.1 root 622: return 0;
623: }
624:
625: static void dsp_execute_instruction(void)
626: {
1.1.1.2 root 627: Uint32 value;
1.1 root 628:
629: #ifdef DSP_DISASM
630: #if DSP_DISASM_REG
631: dsp56k_disasm_reg_read();
632: #endif
633: #if DSP_DISASM_INST
634: dsp56k_disasm();
635: #endif
636: #endif
637:
638: /* Decode and execute current instruction */
1.1.1.2 root 639: cur_inst = read_memory(DSP_SPACE_P, dsp_core->pc);
1.1 root 640: cur_inst_len = 1;
641:
642: value = (cur_inst >> 16) & BITMASK(8);
643: if (value< 0x10) {
644: opcodes8h[value]();
645: } else {
646: dsp_parmove_read();
647: value = cur_inst & BITMASK(8);
648: if (value < 0x40) {
649: opcodes_alu003f[value]();
650: } else if (value < 0x80) {
651: value &= BITMASK(4);
652: opcodes_alu407f[value]();
653: } else {
654: value &= BITMASK(2);
655: opcodes_alu80ff[value]();
656: }
657: dsp_parmove_write();
658: }
659:
660: /* Don't update the PC if we are halted */
1.1.1.2 root 661: /*if (dsp_core->state == DSP_RUNNING)*/ {
1.1 root 662: dsp_postexecute_update_pc();
663: }
664:
665: /* Interrupts ? */
666: dsp_postexecute_interrupts();
667:
668: #ifdef DSP_DISASM
669: #if DSP_DISASM_REG
670: dsp56k_disasm_reg_compare();
671: #endif
672: #endif
673: }
674:
675: /**********************************
676: * Update the PC
677: **********************************/
678:
679: static void dsp_postexecute_update_pc(void)
680: {
681: /* When running a REP, PC must stay on the current instruction */
1.1.1.2 root 682: if (dsp_core->loop_rep) {
1.1 root 683: /* Is PC on the instruction to repeat ? */
684: if (pc_on_rep==0) {
1.1.1.2 root 685: --dsp_core->registers[DSP_REG_LC];
686: dsp_core->registers[DSP_REG_LC] &= BITMASK(16);
1.1 root 687:
1.1.1.2 root 688: if (dsp_core->registers[DSP_REG_LC] > 0) {
1.1 root 689: cur_inst_len=0; /* Stay on this instruction */
690: } else {
1.1.1.2 root 691: dsp_core->loop_rep = 0;
692: dsp_core->registers[DSP_REG_LC] = dsp_core->registers[DSP_REG_LCSAVE];
1.1 root 693: }
1.1.1.2 root 694: #ifdef DSP_DISASM
695: dsp56k_disasm_force_reg_changed(DSP_REG_LC);
696: #endif
1.1 root 697: } else {
698: /* Init LC at right value */
1.1.1.2 root 699: if (dsp_core->registers[DSP_REG_LC] == 0) {
700: dsp_core->registers[DSP_REG_LC] = 0x010000;
701: #ifdef DSP_DISASM
702: dsp56k_disasm_force_reg_changed(DSP_REG_LC);
703: #endif
1.1 root 704: }
705: pc_on_rep = 0;
706: }
707: }
708:
709: /* Normal execution, go to next instruction */
710: if (cur_inst_len>0) {
1.1.1.2 root 711: dsp_core->pc += cur_inst_len;
1.1 root 712: }
713:
714: /* When running a DO loop, we test the end of loop with the */
715: /* updated PC, pointing to last instruction of the loop */
1.1.1.2 root 716: if (dsp_core->registers[DSP_REG_SR] & (1<<DSP_SR_LF)) {
1.1 root 717:
718: /* Did we execute the last instruction in loop ? */
1.1.1.2 root 719: if (dsp_core->pc == dsp_core->registers[DSP_REG_LA]+1) {
720: --dsp_core->registers[DSP_REG_LC];
721: dsp_core->registers[DSP_REG_LC] &= BITMASK(16);
1.1 root 722:
1.1.1.2 root 723: if (dsp_core->registers[DSP_REG_LC]==0) {
1.1 root 724: /* end of loop */
1.1.1.2 root 725: Uint32 newpc;
1.1 root 726:
1.1.1.2 root 727: dsp_stack_pop(&newpc, &dsp_core->registers[DSP_REG_SR]);
728: dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]);
1.1 root 729: } else {
730: /* Loop one more time */
1.1.1.2 root 731: dsp_core->pc = dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]];
1.1 root 732: }
1.1.1.2 root 733: #ifdef DSP_DISASM
734: dsp56k_disasm_force_reg_changed(DSP_REG_LC);
735: #endif
1.1 root 736: }
737: }
738: }
739:
740: /**********************************
741: * Interrupts
742: **********************************/
743:
744: static void dsp_postexecute_interrupts(void)
745: {
1.1.1.2 root 746: Uint32 ipl, ipl_hi;
1.1 root 747:
1.1.1.2 root 748: ipl = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2);
749: ipl_hi = (dsp_core->periph[DSP_SPACE_X][DSP_IPR]>>10) & BITMASK(2);
1.1 root 750:
751: /* Trace, level 3 */
1.1.1.2 root 752: if (dsp_core->registers[DSP_REG_SR] & (1<<DSP_SR_T)) {
1.1 root 753: /* Raise interrupt p:0x0004 */
754: #if DSP_DISASM_INTER
1.1.1.2 root 755: fprintf(stderr, "Dsp: Interrupt: Trace\n");
1.1 root 756: #endif
757: }
758:
759: /* Host interface interrupts */
760: if ((ipl_hi>0) && ((ipl_hi-1)>=ipl)) {
761:
762: /* Host transmit */
763: if (
1.1.1.2 root 764: (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HTIE)) &&
765: ((dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HTDE))==0)
1.1 root 766: ) {
767: /* Raise interrupt p:0x0022 */
768: #if DSP_DISASM_INTER
1.1.1.2 root 769: fprintf(stderr, "Dsp: Interrupt: Host transmit\n");
1.1 root 770: #endif
771: }
772:
773: /* Host receive */
774: if (
1.1.1.2 root 775: (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HRIE)) &&
776: ((dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HRDF)))
1.1 root 777: ) {
778: /* Raise interrupt p:0x0020 */
779: #if DSP_DISASM_INTER
1.1.1.2 root 780: fprintf(stderr, "Dsp: Interrupt: Host receive\n");
1.1 root 781: #endif
782: }
783:
784: /* Host command */
785: if (
1.1.1.2 root 786: (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HCIE)) &&
787: (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HCP))
1.1 root 788: ) {
789: /* Raise interrupt p:((hostport[CPU_HOST_CVR] & 31)<<1) */
790: #if DSP_DISASM_INTER
1.1.1.2 root 791: fprintf(stderr, "Dsp: Interrupt: Host command\n");
1.1 root 792: #endif
793: }
794: }
795: }
796:
797: /**********************************
798: * Set/clear ccr bits
799: **********************************/
800:
801: /* reg0 has bits 55..48 */
802: /* reg1 has bits 47..24 */
803: /* reg2 has bits 23..0 */
804:
1.1.1.2 root 805: static void dsp_ccr_extension(Uint32 *reg0, Uint32 *reg1)
1.1 root 806: {
1.1.1.2 root 807: Uint32 scaling, value, numbits;
808: int sr_extension = 1<<DSP_SR_E;
1.1 root 809:
1.1.1.2 root 810: scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2);
1.1 root 811: value = (*reg0) & 0xff;
812: numbits = 8;
813: switch(scaling) {
814: case 0:
815: value <<=1;
816: value |= ((*reg1)>>23) & 1;
817: numbits=9;
818: break;
819: case 1:
820: break;
821: case 2:
822: value <<=2;
823: value |= ((*reg1)>>22) & 3;
824: numbits=10;
825: break;
826: default:
827: return;
828: break;
829: }
1.1.1.2 root 830: if ((value==0) || (value==(Uint32)BITMASK(numbits))) {
831: sr_extension = 0;
832: }
1.1 root 833:
1.1.1.2 root 834: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_E);
835: dsp_core->registers[DSP_REG_SR] |= sr_extension;
1.1 root 836: }
837:
1.1.1.2 root 838: static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1)
1.1 root 839: {
1.1.1.2 root 840: Uint32 scaling, value;
1.1 root 841:
1.1.1.2 root 842: scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2);
1.1 root 843:
844: switch(scaling) {
845: case 0:
846: value = ((*reg1)>>22) & 3;
847: break;
848: case 1:
849: value = ((*reg0)<<1) & 2;
850: value |= ((*reg1)>>23) & 1;
851: break;
852: case 2:
853: value = ((*reg1)>>21) & 3;
854: break;
855: default:
856: return;
857: break;
858: }
859:
1.1.1.2 root 860: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_U);
861: dsp_core->registers[DSP_REG_SR] |= ((value==0) || (value==BITMASK(2)))<<DSP_SR_U;
1.1 root 862: }
863:
1.1.1.2 root 864: static void dsp_ccr_negative(Uint32 *reg0)
1.1 root 865: {
1.1.1.2 root 866: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_N);
867: dsp_core->registers[DSP_REG_SR] |= (((*reg0)>>7) & 1)<<DSP_SR_N;
1.1 root 868: }
869:
1.1.1.2 root 870: static void dsp_ccr_zero(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2)
1.1 root 871: {
1.1.1.2 root 872: Uint32 zeroed;
1.1 root 873:
874: zeroed=1;
875: if (((*reg2) & BITMASK(24))!=0) {
876: zeroed=0;
877: } else if (((*reg1) & BITMASK(24))!=0) {
878: zeroed=0;
879: } else if (((*reg0) & BITMASK(8))!=0) {
880: zeroed=0;
881: }
882:
1.1.1.2 root 883: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_Z);
884: dsp_core->registers[DSP_REG_SR] |= zeroed<<DSP_SR_Z;
1.1 root 885: }
886:
887: /**********************************
888: * Read/Write memory functions
889: **********************************/
890:
1.1.1.2 root 891: #if defined(DSP_DISASM) && (DSP_DISASM_MEM==1)
892: static Uint32 read_memory_disasm(int space, Uint16 address)
1.1 root 893: {
894: address &= BITMASK(16);
895:
896: switch(space) {
897: case DSP_SPACE_X:
898: case DSP_SPACE_Y:
1.1.1.2 root 899: /* Internal RAM? */
900: if (address<0x100) {
901: return dsp_core->ramint[space][address] & BITMASK(24);
902: }
903: /* Internal ROM? */
904: if ((dsp_core->registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) &&
905: (address<0x200)) {
906: return dsp_core->rom[space][address] & BITMASK(24);
1.1 root 907: }
908: /* Peripheral address ? */
909: if (address >= 0xffc0) {
1.1.1.2 root 910: return dsp_core->periph[space][address-0xffc0] & BITMASK(24);
1.1 root 911: }
1.1.1.2 root 912: /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
913: if (space == DSP_SPACE_X) {
914: address += DSP_RAMSIZE>>1;
915: }
916: /* Falcon: External RAM, map X,Y to P */
917: space = DSP_SPACE_P;
918: break;
1.1 root 919: case DSP_SPACE_P:
1.1.1.2 root 920: /* Internal RAM? */
921: if (address<0x200) {
922: return dsp_core->ramint[space][address] & BITMASK(24);
1.1 root 923: }
924: break;
925: }
926:
1.1.1.2 root 927: /* External RAM, mask address to available ram size */
928: return dsp_core->ram[space][address & (DSP_RAMSIZE-1)] & BITMASK(24);
1.1 root 929: }
930: #endif
931:
1.1.1.2 root 932: static Uint32 read_memory(int space, Uint16 address)
1.1 root 933: {
934: address &= BITMASK(16);
935:
936: switch(space) {
937: case DSP_SPACE_X:
938: case DSP_SPACE_Y:
1.1.1.2 root 939: /* Internal RAM ?*/
940: if (address<0x100) {
941: return dsp_core->ramint[space][address] & BITMASK(24);
942: }
943: /* Internal ROM ?*/
944: if ((dsp_core->registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) &&
945: (address<0x200)) {
946: return dsp_core->rom[space][address] & BITMASK(24);
1.1 root 947: }
948: /* Peripheral address ? */
949: if (address >= 0xffc0) {
1.1.1.2 root 950: Uint32 value;
1.1 root 951:
1.1.1.2 root 952: SDL_LockMutex(dsp_core->mutex);
1.1 root 953: if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HRX)) {
1.1.1.2 root 954: dsp_core_hostport_dspread(dsp_core);
1.1 root 955: }
1.1.1.2 root 956: value = dsp_core->periph[space][address-0xffc0] & BITMASK(24);
957: SDL_UnlockMutex(dsp_core->mutex);
1.1 root 958:
1.1.1.2 root 959: return value;
1.1 root 960: }
1.1.1.2 root 961: /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
962: if (space == DSP_SPACE_X) {
963: address += DSP_RAMSIZE>>1;
964: }
965: /* Falcon: External RAM, map X,Y to P */
966: space = DSP_SPACE_P;
967: break;
1.1 root 968: case DSP_SPACE_P:
1.1.1.2 root 969: /* Internal RAM ?*/
970: if (address<0x200) {
971: return dsp_core->ramint[space][address] & BITMASK(24);
1.1 root 972: }
973: break;
974: }
975:
1.1.1.2 root 976: /* External RAM, mask address to available ram size */
977: return dsp_core->ram[space][address & (DSP_RAMSIZE-1)] & BITMASK(24);
1.1 root 978: }
979:
1.1.1.2 root 980: /* Note: MACRO write_memory defined to either write_memory_raw or write_memory_disasm */
981: static void write_memory_raw(int space, Uint32 address, Uint32 value)
1.1 root 982: {
983: address &= BITMASK(16);
984: value &= BITMASK(24);
985:
986: switch(space) {
987: case DSP_SPACE_X:
1.1.1.2 root 988: /* Internal RAM ? */
989: if (address<0x100) {
990: dsp_core->ramint[space][address] = value;
991: return;
992: }
993: /* Internal ROM ?*/
994: if ((dsp_core->registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) &&
995: (address<0x200)) {
996: /* Can not write to ROM space */
997: return;
1.1 root 998: }
999: /* Peripheral space ? */
1000: if ((address >= 0xffc0) && (address <= 0xffff)) {
1.1.1.2 root 1001: SDL_LockMutex(dsp_core->mutex);
1.1 root 1002: switch(address-0xffc0) {
1003: case DSP_HOST_HTX:
1.1.1.2 root 1004: dsp_core->periph[space][DSP_HOST_HTX] = value;
1005:
1006: dsp_core_hostport_dspwrite(dsp_core);
1.1 root 1007: break;
1008: case DSP_HOST_HCR:
1.1.1.2 root 1009: dsp_core->periph[space][DSP_HOST_HCR] = value;
1.1 root 1010: /* Set HF3 and HF2 accordingly on the host side */
1.1.1.2 root 1011: dsp_core->hostport[CPU_HOST_ISR] &=
1.1 root 1012: BITMASK(8)-((1<<CPU_HOST_ISR_HF3)|(1<<CPU_HOST_ISR_HF2));
1.1.1.2 root 1013: dsp_core->hostport[CPU_HOST_ISR] |=
1014: dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & ((1<<CPU_HOST_ISR_HF3)|(1<<CPU_HOST_ISR_HF2));
1.1 root 1015: break;
1016: case DSP_HOST_HSR:
1017: /* Read only */
1018: break;
1019: default:
1.1.1.2 root 1020: dsp_core->periph[space][address-0xffc0] = value;
1.1 root 1021: break;
1022: }
1.1.1.2 root 1023: SDL_UnlockMutex(dsp_core->mutex);
1.1 root 1024: return;
1025: }
1.1.1.2 root 1026: /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
1027: if (space == DSP_SPACE_X) {
1028: address += DSP_RAMSIZE>>1;
1.1 root 1029: }
1.1.1.2 root 1030: /* Falcon: External RAM, map X to P */
1031: space = DSP_SPACE_P;
1.1 root 1032: break;
1033: case DSP_SPACE_Y:
1.1.1.2 root 1034: /* Internal RAM ? */
1035: if (address<0x100) {
1036: dsp_core->ramint[space][address] = value;
1037: return;
1.1 root 1038: }
1.1.1.2 root 1039: /* Internal ROM ?*/
1040: if ((dsp_core->registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) &&
1041: (address<0x200)) {
1042: /* Can not write to ROM space */
1.1 root 1043: return;
1044: }
1.1.1.2 root 1045: /* Peripheral space ? */
1046: if ((address >= 0xffc0) && (address <= 0xffff)) {
1047: dsp_core->periph[space][address-0xffc0] = value;
1048: return;
1.1 root 1049: }
1.1.1.2 root 1050: /* Falcon: External RAM, map Y to P */
1051: space = DSP_SPACE_P;
1.1 root 1052: break;
1053: case DSP_SPACE_P:
1.1.1.2 root 1054: /* Internal RAM ?*/
1055: if (address<0x200) {
1056: dsp_core->ramint[space][address] = value;
1.1 root 1057: return;
1058: }
1059: break;
1060: }
1061:
1.1.1.2 root 1062: /* External RAM, mask address to available ram size */
1063: dsp_core->ram[space][address & (DSP_RAMSIZE-1)] = value;
1064: }
1065:
1066: #if defined(DSP_DISASM) && (DSP_DISASM_MEM==1)
1067: static void write_memory_disasm(int space, Uint32 address, Uint32 value)
1068: {
1069: address &= BITMASK(16);
1070: value &= BITMASK(24);
1071:
1072: Uint32 curvalue = read_memory_disasm(space, address);
1073:
1074: write_memory_raw(space,address,value);
1075:
1.1 root 1076: switch(space) {
1077: case DSP_SPACE_P:
1078: fprintf(stderr,"Dsp: Mem: p:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address));
1079: break;
1080: case DSP_SPACE_X:
1081: fprintf(stderr,"Dsp: Mem: x:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address));
1082: break;
1083: case DSP_SPACE_Y:
1084: fprintf(stderr,"Dsp: Mem: y:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address));
1085: break;
1086: }
1087: }
1.1.1.2 root 1088: #endif
1.1 root 1089:
1090: /**********************************
1091: * Stack push/pop
1092: **********************************/
1093:
1.1.1.2 root 1094: static void dsp_stack_push(Uint32 curpc, Uint32 cursr)
1.1 root 1095: {
1.1.1.2 root 1096: if (dsp_core->registers[DSP_REG_SP]==0x0f) {
1.1 root 1097: /* Stack full, raise interrupt */
1098: #if DSP_DISASM_STATE
1.1.1.2 root 1099: fprintf(stderr, "Dsp: Stack error (overflow)\n");
1.1 root 1100: #endif
1.1.1.2 root 1101: SDL_SemWait(dsp_core->semaphore);
1.1 root 1102: return;
1103: }
1104:
1.1.1.2 root 1105: dsp_core->registers[DSP_REG_SP]++;
1106: dsp_core->registers[DSP_REG_SSH]++;
1107: dsp_core->registers[DSP_REG_SSL]++;
1.1 root 1108:
1.1.1.2 root 1109: dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]]=curpc;
1110: dsp_core->stack[1][dsp_core->registers[DSP_REG_SSL]]=cursr;
1.1 root 1111: }
1112:
1.1.1.2 root 1113: static void dsp_stack_pop(Uint32 *newpc, Uint32 *newsr)
1.1 root 1114: {
1.1.1.2 root 1115: if (dsp_core->registers[DSP_REG_SP]==0x00) {
1.1 root 1116: /* Stack empty, raise interrupt */
1117: #if DSP_DISASM_STATE
1.1.1.2 root 1118: fprintf(stderr, "Dsp: Stack error (underflow)\n");
1.1 root 1119: #endif
1.1.1.2 root 1120: SDL_SemWait(dsp_core->semaphore);
1.1 root 1121: return;
1122: }
1123:
1.1.1.2 root 1124: *newpc = dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]];
1125: *newsr = dsp_core->stack[1][dsp_core->registers[DSP_REG_SSL]];
1.1 root 1126:
1.1.1.2 root 1127: --dsp_core->registers[DSP_REG_SP];
1128: --dsp_core->registers[DSP_REG_SSH];
1129: --dsp_core->registers[DSP_REG_SSL];
1.1 root 1130: }
1131:
1132: /**********************************
1133: * Effective address calculation
1134: **********************************/
1135:
1.1.1.2 root 1136: static void dsp_update_rn(Uint32 numreg, Sint16 modifier)
1.1 root 1137: {
1.1.1.2 root 1138: Sint16 value;
1139: Uint16 m_reg;
1.1 root 1140:
1.1.1.2 root 1141: m_reg = (Uint16) dsp_core->registers[DSP_REG_M0+numreg];
1.1 root 1142: if (m_reg == 0) {
1143: /* Bit reversed carry update */
1144: dsp_update_rn_bitreverse(numreg);
1145: } else if ((m_reg>=1) && (m_reg<=32767)) {
1146: /* Modulo update */
1147: dsp_update_rn_modulo(numreg, modifier);
1148: } else if (m_reg == 65535) {
1149: /* Linear addressing mode */
1.1.1.2 root 1150: value = (Sint16) dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1151: value += modifier;
1.1.1.2 root 1152: dsp_core->registers[DSP_REG_R0+numreg] = ((Uint32) value) & BITMASK(16);
1.1 root 1153: } else {
1154: /* Undefined */
1155: }
1156: }
1157:
1.1.1.2 root 1158: static void dsp_update_rn_bitreverse(Uint32 numreg)
1.1 root 1159: {
1160: int revbits, i;
1.1.1.2 root 1161: Uint32 value, r_reg;
1.1 root 1162:
1163: /* Check how many bits to reverse */
1.1.1.2 root 1164: value = dsp_core->registers[DSP_REG_N0+numreg];
1.1 root 1165: for (revbits=0;revbits<16;revbits++) {
1166: if (value & (1<<revbits)) {
1167: break;
1168: }
1169: }
1170: revbits++;
1171:
1172: /* Reverse Rn bits */
1.1.1.2 root 1173: r_reg = dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1174: value = r_reg & (BITMASK(16)-BITMASK(revbits));
1175: for (i=0;i<revbits;i++) {
1176: if (r_reg & (1<<i)) {
1177: value |= 1<<(revbits-i-1);
1178: }
1179: }
1180:
1181: /* Increment */
1182: value++;
1183: value &= BITMASK(revbits);
1184:
1185: /* Reverse Rn bits */
1186: r_reg &= (BITMASK(16)-BITMASK(revbits));
1187: r_reg |= value;
1188:
1189: value = r_reg & (BITMASK(16)-BITMASK(revbits));
1190: for (i=0;i<revbits;i++) {
1191: if (r_reg & (1<<i)) {
1192: value |= 1<<(revbits-i-1);
1193: }
1194: }
1195:
1.1.1.2 root 1196: dsp_core->registers[DSP_REG_R0+numreg] = value;
1.1 root 1197: }
1198:
1.1.1.2 root 1199: static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier)
1.1 root 1200: {
1.1.1.2 root 1201: Uint16 bufsize, modulo, lobound, hibound, bufmask;
1202: Sint16 r_reg;
1.1 root 1203:
1.1.1.2 root 1204: modulo = (dsp_core->registers[DSP_REG_M0+numreg]+1) & BITMASK(16);
1.1 root 1205: bufsize = 1;
1.1.1.2 root 1206: bufmask = BITMASK(16);
1.1 root 1207: while (bufsize < modulo) {
1208: bufsize <<= 1;
1.1.1.2 root 1209: bufmask <<= 1;
1.1 root 1210: }
1.1.1.2 root 1211: bufmask &= BITMASK(16);
1.1 root 1212:
1.1.1.2 root 1213: lobound = dsp_core->registers[DSP_REG_R0+numreg] & bufmask;
1214: hibound = lobound + modulo - 1;
1.1 root 1215:
1.1.1.2 root 1216: r_reg = (Sint16) (dsp_core->registers[DSP_REG_R0+numreg] & BITMASK(16));
1217: while (modifier>=bufsize) {
1218: r_reg += bufsize;
1219: modifier -= bufsize;
1220: }
1221: while (modifier<=-bufsize) {
1222: r_reg -= bufsize;
1223: modifier += bufsize;
1224: }
1.1 root 1225: r_reg += modifier;
1226: if (r_reg>hibound) {
1.1.1.2 root 1227: r_reg -= modulo;
1.1 root 1228: } else if (r_reg<lobound) {
1.1.1.2 root 1229: r_reg += modulo;
1.1 root 1230: }
1231:
1.1.1.2 root 1232: dsp_core->registers[DSP_REG_R0+numreg] = ((Uint32) r_reg) & BITMASK(16);
1.1 root 1233: }
1234:
1.1.1.2 root 1235: static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr)
1.1 root 1236: {
1.1.1.2 root 1237: Uint32 value, numreg, curreg;
1.1 root 1238:
1239: value = (ea_mode >> 3) & BITMASK(3);
1240: numreg = ea_mode & BITMASK(3);
1241: switch (value) {
1242: case 0:
1243: /* (Rx)-Nx */
1.1.1.2 root 1244: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1245: dsp_update_rn(numreg, -dsp_core->registers[DSP_REG_N0+numreg]);
1.1 root 1246: break;
1247: case 1:
1248: /* (Rx)+Nx */
1.1.1.2 root 1249: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1250: dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]);
1.1 root 1251: break;
1252: case 2:
1253: /* (Rx)- */
1.1.1.2 root 1254: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1255: dsp_update_rn(numreg, -1);
1256: break;
1257: case 3:
1258: /* (Rx)+ */
1.1.1.2 root 1259: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1260: dsp_update_rn(numreg, +1);
1261: break;
1262: case 4:
1263: /* (Rx) */
1.1.1.2 root 1264: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1265: break;
1266: case 5:
1267: /* (Rx+Nx) */
1.1.1.2 root 1268: curreg = dsp_core->registers[DSP_REG_R0+numreg];
1269: dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]);
1270: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1271: dsp_core->registers[DSP_REG_R0+numreg] = curreg;
1.1 root 1272: break;
1273: case 6:
1274: /* aa */
1.1.1.2 root 1275: *dst_addr = read_memory(DSP_SPACE_P,dsp_core->pc+1);
1.1 root 1276: cur_inst_len++;
1277: if (numreg != 0) {
1278: return 1; /* immediate value */
1279: }
1280: break;
1281: case 7:
1282: /* -(Rx) */
1283: dsp_update_rn(numreg, -1);
1.1.1.2 root 1284: *dst_addr = dsp_core->registers[DSP_REG_R0+numreg];
1.1 root 1285: break;
1286: }
1287: /* address */
1288: return 0;
1289: }
1290:
1291: /**********************************
1292: * Condition code test
1293: **********************************/
1294:
1295: #define DSP_SR_NV 8 /* N xor V */
1296: #define DSP_SR_ZUE 9 /* Z or ((not U) and (not E)) */
1297: #define DSP_SR_ZNV 10 /* Z or (N xor V) */
1298:
1299: #define CCR_BIT(x,y) \
1300: (((x) >> (y)) & 1)
1301:
1302: static int cc_code_map[8]={
1303: DSP_SR_C,
1304: DSP_SR_NV,
1305: DSP_SR_Z,
1306: DSP_SR_N,
1307: DSP_SR_ZUE,
1308: DSP_SR_E,
1309: DSP_SR_L,
1310: DSP_SR_ZNV
1311: };
1312:
1.1.1.2 root 1313: static int dsp_calc_cc(Uint32 cc_code)
1.1 root 1314: {
1.1.1.2 root 1315: Uint16 value;
1.1 root 1316:
1.1.1.2 root 1317: value = dsp_core->registers[DSP_REG_SR] & BITMASK(8);
1.1 root 1318: value |= (CCR_BIT(value,DSP_SR_N) ^ CCR_BIT(value, DSP_SR_V))<<DSP_SR_NV;
1.1.1.2 root 1319: value |= ((CCR_BIT(value,DSP_SR_Z) | ((~CCR_BIT(value,DSP_SR_U)) & (~CCR_BIT(value,DSP_SR_E)))) & 1)<<DSP_SR_ZUE;
1.1 root 1320: value |= (CCR_BIT(value,DSP_SR_Z) | CCR_BIT(value, DSP_SR_NV))<<DSP_SR_ZNV;
1321:
1.1.1.2 root 1322: return (Uint32)(CCR_BIT(value,cc_code_map[cc_code & BITMASK(3)]))==((cc_code>>3) & 1);
1.1 root 1323: }
1324:
1325: /**********************************
1326: * Highbyte opcodes dispatchers
1327: **********************************/
1328:
1329: static void opcode8h_0(void)
1330: {
1331: if (cur_inst <= 0x00008c) {
1332: switch(cur_inst) {
1333: case 0x000000:
1334: dsp_nop();
1335: break;
1336: case 0x000004:
1337: dsp_rti();
1338: break;
1339: case 0x000005:
1340: dsp_illegal();
1341: break;
1342: case 0x000006:
1343: dsp_swi();
1344: break;
1345: case 0x00000c:
1346: dsp_rts();
1347: break;
1348: case 0x000084:
1349: dsp_reset();
1350: break;
1351: case 0x000086:
1352: dsp_wait();
1353: break;
1354: case 0x000087:
1355: dsp_stop();
1356: break;
1357: case 0x00008c:
1358: dsp_enddo();
1359: break;
1360: }
1361: } else {
1362: switch (cur_inst & 0xf8) {
1363: case 0x0000b8:
1364: dsp_andi();
1365: break;
1366: case 0x0000f8:
1367: dsp_ori();
1368: break;
1369: }
1370: }
1371: }
1372:
1373: static void opcode8h_1(void)
1374: {
1.1.1.3 ! root 1375: switch(cur_inst & 0xfff000) {
! 1376: case 0x018000:
1.1 root 1377: dsp_div();
1378: break;
1.1.1.3 ! root 1379: case 0x01d000:
1.1 root 1380: dsp_norm();
1381: break;
1382: }
1383: }
1384:
1385: static void opcode8h_4(void)
1386: {
1387: switch((cur_inst>>5) & BITMASK(3)) {
1388: case 0:
1389: dsp_lua();
1390: break;
1391: case 5:
1392: dsp_movec();
1393: break;
1394: }
1395: }
1396:
1397: static void opcode8h_6(void)
1398: {
1399: if (cur_inst & (1<<5)) {
1400: dsp_rep();
1401: } else {
1402: dsp_do();
1403: }
1404: }
1405:
1406: static void opcode8h_8(void)
1407: {
1.1.1.2 root 1408: Uint32 value;
1.1 root 1409:
1410: value = (cur_inst >> 12) & BITMASK(4);
1411: opcodes_0809[value]();
1412: }
1413:
1414: static void opcode8h_a(void)
1415: {
1.1.1.2 root 1416: Uint32 value;
1.1 root 1417:
1418: value = (cur_inst >> 11) & (BITMASK(2)<<3);
1419: value |= (cur_inst >> 5) & BITMASK(3);
1420:
1421: opcodes_0a[value]();
1422: }
1423:
1424: static void opcode8h_b(void)
1425: {
1.1.1.2 root 1426: Uint32 value;
1.1 root 1427:
1428: value = (cur_inst >> 11) & (BITMASK(2)<<3);
1429: value |= (cur_inst >> 5) & BITMASK(3);
1430:
1431: opcodes_0b[value]();
1432: }
1433:
1434: /**********************************
1435: * Non-parallel moves instructions
1436: **********************************/
1437:
1438: static void dsp_undefined(void)
1439: {
1440: cur_inst_len = 0;
1.1.1.2 root 1441: fprintf(stderr, "Dsp: 0x%04x: 0x%06x unknown instruction\n",dsp_core->pc, cur_inst);
1.1 root 1442: }
1443:
1444: static void dsp_andi(void)
1445: {
1.1.1.2 root 1446: Uint32 regnum, value;
1.1 root 1447:
1448: value = (cur_inst >> 8) & BITMASK(8);
1449: regnum = cur_inst & BITMASK(2);
1450: switch(regnum) {
1451: case 0:
1452: /* mr */
1.1.1.2 root 1453: dsp_core->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8);
1.1 root 1454: break;
1455: case 1:
1456: /* ccr */
1.1.1.2 root 1457: dsp_core->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value;
1.1 root 1458: break;
1459: case 2:
1460: /* omr */
1.1.1.2 root 1461: dsp_core->registers[DSP_REG_OMR] &= value;
1.1 root 1462: break;
1463: }
1464: }
1465:
1466: static void dsp_bchg(void)
1467: {
1.1.1.2 root 1468: Uint32 memspace, addr, value, numreg, newcarry, numbit, srcreg;
1.1 root 1469:
1470: memspace = (cur_inst>>6) & 1;
1471: value = (cur_inst>>8) & BITMASK(6);
1472: numbit = cur_inst & BITMASK(5);
1473: newcarry = 0;
1474:
1475: switch((cur_inst>>14) & BITMASK(2)) {
1476: case 0:
1477: /* bchg #n,x:aa */
1478: /* bchg #n,y:aa */
1479: addr = value;
1480: value = read_memory(memspace, addr);
1481: newcarry = (value>>numbit) & 1;
1482: if (newcarry) {
1483: value -= (1<<numbit);
1484: } else {
1485: value += (1<<numbit);
1486: }
1487: write_memory(memspace, addr, value);
1488: break;
1489: case 1:
1490: /* bchg #n,x:ea */
1491: /* bchg #n,y:ea */
1492: dsp_calc_ea(value, &addr);
1493: value = read_memory(memspace, addr);
1494: newcarry = (value>>numbit) & 1;
1495: if (newcarry) {
1496: value -= (1<<numbit);
1497: } else {
1498: value += (1<<numbit);
1499: }
1500: write_memory(memspace, addr, value);
1501: break;
1502: case 2:
1503: /* bchg #n,x:pp */
1504: /* bchg #n,y:pp */
1505: addr = 0xffc0 + value;
1506: value = read_memory(memspace, addr);
1507: newcarry = (value>>numbit) & 1;
1508: if (newcarry) {
1509: value -= (1<<numbit);
1510: } else {
1511: value += (1<<numbit);
1512: }
1513: write_memory(memspace, addr, value);
1514: break;
1515: case 3:
1516: /* bchg #n,R */
1.1.1.2 root 1517: srcreg = numreg = value;
1.1 root 1518: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
1519: numreg = DSP_REG_A1+(numreg & 1);
1520: }
1.1.1.2 root 1521: value = dsp_core->registers[numreg];
1.1 root 1522: newcarry = (value>>numbit) & 1;
1523: if (newcarry) {
1524: value -= (1<<numbit);
1525: } else {
1526: value += (1<<numbit);
1527: }
1.1.1.2 root 1528: dsp_core->registers[numreg] = value;
1529: if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) {
1530: dsp_core->registers[DSP_REG_A2+(srcreg & 1)]= (newcarry ? 0x00 : 0xff);
1.1 root 1531: }
1532: break;
1533: }
1534:
1535: /* Set carry */
1.1.1.2 root 1536: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_C);
1537: dsp_core->registers[DSP_REG_SR] |= newcarry<<DSP_SR_C;
1.1 root 1538: }
1539:
1540: static void dsp_bclr(void)
1541: {
1.1.1.2 root 1542: Uint32 memspace, addr, value, numreg, newcarry, numbit, srcreg;
1.1 root 1543:
1544: memspace = (cur_inst>>6) & 1;
1545: value = (cur_inst>>8) & BITMASK(6);
1546: numbit = cur_inst & BITMASK(5);
1547: newcarry = 0;
1548:
1549: switch((cur_inst>>14) & BITMASK(2)) {
1550: case 0:
1551: /* bclr #n,x:aa */
1552: /* bclr #n,y:aa */
1553: addr = value;
1554: value = read_memory(memspace, addr);
1555: newcarry = (value>>numbit) & 1;
1556: value &= 0xffffffff-(1<<numbit);
1557: write_memory(memspace, addr, value);
1558: break;
1559: case 1:
1560: /* bclr #n,x:ea */
1561: /* bclr #n,y:ea */
1562: dsp_calc_ea(value, &addr);
1563: value = read_memory(memspace, addr);
1564: newcarry = (value>>numbit) & 1;
1565: value &= 0xffffffff-(1<<numbit);
1566: write_memory(memspace, addr, value);
1567: break;
1568: case 2:
1569: /* bclr #n,x:pp */
1570: /* bclr #n,y:pp */
1571: addr = 0xffc0 + value;
1572: value = read_memory(memspace, addr);
1573: newcarry = (value>>numbit) & 1;
1574: value &= 0xffffffff-(1<<numbit);
1575: write_memory(memspace, addr, value);
1576: break;
1577: case 3:
1578: /* bclr #n,R */
1.1.1.2 root 1579: srcreg = numreg = value;
1.1 root 1580: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
1581: numreg = DSP_REG_A1+(numreg & 1);
1582: }
1.1.1.2 root 1583: value = dsp_core->registers[numreg];
1.1 root 1584: newcarry = (value>>numbit) & 1;
1585: value &= 0xffffffff-(1<<numbit);
1.1.1.2 root 1586: dsp_core->registers[numreg] = value;
1587: if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) {
1588: dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0x00;
1.1 root 1589: }
1590: break;
1591: }
1592:
1593: /* Set carry */
1.1.1.2 root 1594: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_C);
1595: dsp_core->registers[DSP_REG_SR] |= newcarry<<DSP_SR_C;
1.1 root 1596: }
1597:
1598: static void dsp_bset(void)
1599: {
1.1.1.2 root 1600: Uint32 memspace, addr, value, numreg, newcarry, numbit, srcreg;
1.1 root 1601:
1602: memspace = (cur_inst>>6) & 1;
1603: value = (cur_inst>>8) & BITMASK(6);
1604: numbit = cur_inst & BITMASK(5);
1605: newcarry = 0;
1606:
1607: switch((cur_inst>>14) & BITMASK(2)) {
1608: case 0:
1609: /* bset #n,x:aa */
1610: /* bset #n,y:aa */
1611: addr = value;
1612: value = read_memory(memspace, addr);
1613: newcarry = (value>>numbit) & 1;
1614: value |= (1<<numbit);
1615: write_memory(memspace, addr, value);
1616: break;
1617: case 1:
1618: /* bset #n,x:ea */
1619: /* bset #n,y:ea */
1620: dsp_calc_ea(value, &addr);
1621: value = read_memory(memspace, addr);
1622: newcarry = (value>>numbit) & 1;
1623: value |= (1<<numbit);
1624: write_memory(memspace, addr, value);
1625: break;
1626: case 2:
1627: /* bset #n,x:pp */
1628: /* bset #n,y:pp */
1629: addr = 0xffc0 + value;
1630: value = read_memory(memspace, addr);
1631: newcarry = (value>>numbit) & 1;
1632: value |= (1<<numbit);
1633: write_memory(memspace, addr, value);
1634: break;
1635: case 3:
1636: /* bset #n,R */
1.1.1.2 root 1637: srcreg = numreg = value;
1.1 root 1638: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
1639: numreg = DSP_REG_A1+(numreg & 1);
1640: }
1.1.1.2 root 1641: value = dsp_core->registers[numreg];
1.1 root 1642: newcarry = (value>>numbit) & 1;
1643: value |= (1<<numbit);
1.1.1.2 root 1644: dsp_core->registers[numreg] = value;
1645: if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) {
1646: dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0xff;
1.1 root 1647: }
1648: break;
1649: }
1650:
1651: /* Set carry */
1.1.1.2 root 1652: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_C);
1653: dsp_core->registers[DSP_REG_SR] |= newcarry<<DSP_SR_C;
1.1 root 1654: }
1655:
1656: static void dsp_btst(void)
1657: {
1.1.1.2 root 1658: Uint32 memspace, addr, value, numreg, newcarry, numbit;
1.1 root 1659:
1660: memspace = (cur_inst>>6) & 1;
1661: value = (cur_inst>>8) & BITMASK(6);
1662: numbit = cur_inst & BITMASK(5);
1663: newcarry = 0;
1664:
1665: switch((cur_inst>>14) & BITMASK(2)) {
1666: case 0:
1667: /* btst #n,x:aa */
1668: /* btst #n,y:aa */
1669: addr = value;
1670: value = read_memory(memspace, addr);
1671: newcarry = (value>>numbit) & 1;
1672: break;
1673: case 1:
1674: /* btst #n,x:ea */
1675: /* btst #n,y:ea */
1676: dsp_calc_ea(value, &addr);
1677: value = read_memory(memspace, addr);
1678: newcarry = (value>>numbit) & 1;
1679: break;
1680: case 2:
1681: /* btst #n,x:pp */
1682: /* btst #n,y:pp */
1683: addr = 0xffc0 + value;
1684: value = read_memory(memspace, addr);
1685: newcarry = (value>>numbit) & 1;
1686: break;
1687: case 3:
1688: /* btst #n,R */
1689: numreg = value;
1690: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
1691: numreg = DSP_REG_A1+(numreg & 1);
1692: }
1.1.1.2 root 1693: value = dsp_core->registers[numreg];
1.1 root 1694: newcarry = (value>>numbit) & 1;
1695: break;
1696: }
1697:
1698: /* Set carry */
1.1.1.2 root 1699: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_C);
1700: dsp_core->registers[DSP_REG_SR] |= newcarry<<DSP_SR_C;
1.1 root 1701: }
1702:
1703: static void dsp_div(void)
1704: {
1.1.1.2 root 1705: Uint32 srcreg, destreg, source[3], dest[3];
1706: Uint16 newsr;
1.1 root 1707:
1708: srcreg = DSP_REG_NULL;
1709: switch((cur_inst>>4) & BITMASK(2)) {
1710: case 0: srcreg = DSP_REG_X0; break;
1711: case 1: srcreg = DSP_REG_Y0; break;
1712: case 2: srcreg = DSP_REG_X1; break;
1713: case 3: srcreg = DSP_REG_Y1; break;
1714: }
1715: destreg = DSP_REG_A+((cur_inst>>3) & 1);
1716:
1.1.1.2 root 1717: source[0] = 0;
1.1.1.3 ! root 1718: source[1] = dsp_core->registers[srcreg];
! 1719: if (source[1] & (1<<23)) {
! 1720: source[0] = 0xff;
! 1721: }
! 1722: source[2] = 0;
1.1.1.2 root 1723:
1724: dest[0] = dsp_core->registers[DSP_REG_A2+(destreg & 1)];
1725: dest[1] = dsp_core->registers[DSP_REG_A1+(destreg & 1)];
1726: dest[2] = dsp_core->registers[DSP_REG_A0+(destreg & 1)];
1.1 root 1727:
1.1.1.2 root 1728: if (((dest[0]>>7) & 1) ^ ((source[1]>>23) & 1)) {
1.1 root 1729: /* D += S */
1.1.1.2 root 1730: newsr = dsp_asl56(dest);
1731: dsp_add56(source, dest);
1.1 root 1732: } else {
1733: /* D -= S */
1.1.1.2 root 1734: newsr = dsp_asl56(dest);
1735: dsp_sub56(source, dest);
1.1 root 1736: }
1737:
1.1.1.2 root 1738: dest[2] |= (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1;
1.1 root 1739:
1.1.1.2 root 1740: dsp_core->registers[DSP_REG_A2+(destreg & 1)] = dest[0];
1741: dsp_core->registers[DSP_REG_A1+(destreg & 1)] = dest[1];
1742: dsp_core->registers[DSP_REG_A0+(destreg & 1)] = dest[2];
1743:
1744: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_V));
1745: dsp_core->registers[DSP_REG_SR] |= (1-((dest[0]>>7) & 1))<<DSP_SR_C;
1746: dsp_core->registers[DSP_REG_SR] |= newsr & (1<<DSP_SR_L);
1747: dsp_core->registers[DSP_REG_SR] |= newsr & (1<<DSP_SR_V);
1.1 root 1748: }
1749:
1.1.1.3 ! root 1750: /*
! 1751: DO instruction parameter encoding
! 1752:
! 1753: xxxxxxxx 00xxxxxx 0xxxxxxx aa
! 1754: xxxxxxxx 01xxxxxx 0xxxxxxx ea
! 1755: xxxxxxxx YYxxxxxx 1xxxxxxx imm
! 1756: xxxxxxxx 11xxxxxx 0xxxxxxx reg
! 1757: */
! 1758:
1.1 root 1759: static void dsp_do(void)
1760: {
1.1.1.2 root 1761: Uint32 value;
1.1 root 1762:
1.1.1.2 root 1763: dsp_stack_push(dsp_core->registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC]);
1.1 root 1764:
1.1.1.2 root 1765: dsp_core->registers[DSP_REG_LA] = read_memory(DSP_SPACE_P, dsp_core->pc+1) & BITMASK(16);
1.1 root 1766: cur_inst_len++;
1767:
1.1.1.2 root 1768: dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]);
1.1 root 1769:
1.1.1.2 root 1770: dsp_core->registers[DSP_REG_SR] |= (1<<DSP_SR_LF);
1.1 root 1771:
1.1.1.3 ! root 1772: value = ((cur_inst>>14) & BITMASK(2))<<1;
! 1773: value |= (cur_inst>>7) & 1;
1.1 root 1774:
1775: opcodes_do[value]();
1776: }
1777:
1.1.1.3 ! root 1778: static void dsp_do_aa(void)
1.1 root 1779: {
1.1.1.2 root 1780: Uint32 memspace, addr;
1.1 root 1781:
1782: /* x:aa */
1783: /* y:aa */
1784:
1785: memspace = (cur_inst>>6) & 1;
1786: addr = (cur_inst>>8) & BITMASK(6);
1.1.1.2 root 1787: dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16);
1.1 root 1788: }
1789:
1.1.1.3 ! root 1790: static void dsp_do_imm(void)
1.1 root 1791: {
1792: /* #xx */
1.1.1.3 ! root 1793:
! 1794: dsp_core->registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8))
! 1795: + ((cur_inst & BITMASK(4))<<8);
1.1 root 1796: }
1797:
1.1.1.3 ! root 1798: static void dsp_do_ea(void)
1.1 root 1799: {
1.1.1.2 root 1800: Uint32 memspace, ea_mode, addr;
1.1 root 1801:
1802: /* x:ea */
1803: /* y:ea */
1804:
1805: memspace = (cur_inst>>6) & 1;
1806: ea_mode = (cur_inst>>8) & BITMASK(6);
1807: dsp_calc_ea(ea_mode, &addr);
1.1.1.2 root 1808: dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16);
1.1 root 1809: }
1810:
1.1.1.3 ! root 1811: static void dsp_do_reg(void)
1.1 root 1812: {
1.1.1.2 root 1813: Uint32 numreg;
1.1 root 1814:
1815: /* S */
1816:
1817: numreg = (cur_inst>>8) & BITMASK(6);
1818: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
1.1.1.2 root 1819: dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]);
1.1 root 1820: } else {
1.1.1.2 root 1821: dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg];
1.1 root 1822: }
1.1.1.2 root 1823: dsp_core->registers[DSP_REG_LC] &= BITMASK(16);
1.1 root 1824: }
1825:
1826: static void dsp_enddo(void)
1827: {
1.1.1.2 root 1828: Uint32 newpc;
1.1 root 1829:
1.1.1.2 root 1830: dsp_stack_pop(&newpc, &dsp_core->registers[DSP_REG_SR]);
1831: dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]);
1.1 root 1832: }
1833:
1834: static void dsp_illegal(void)
1835: {
1836: /* Raise interrupt p:0x003e */
1837: #if DSP_DISASM_INTER
1.1.1.2 root 1838: fprintf(stderr, "Dsp: Interrupt: Illegal\n");
1.1 root 1839: #endif
1840: }
1841:
1842: static void dsp_jcc(void)
1843: {
1.1.1.2 root 1844: Uint32 newpc, cc_code;
1.1 root 1845:
1846: cc_code = 0;
1847: switch((cur_inst >> 16) & BITMASK(8)) {
1848: case 0x0a:
1849: dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc);
1850: cc_code=cur_inst & BITMASK(4);
1851: break;
1852: case 0x0e:
1853: newpc = cur_inst & BITMASK(12);
1854: cc_code=(cur_inst>>12) & BITMASK(4);
1855: break;
1856: }
1857:
1858: if (dsp_calc_cc(cc_code)) {
1.1.1.2 root 1859: dsp_core->pc = newpc;
1.1 root 1860: cur_inst_len = 0;
1861: }
1862: }
1863:
1864: static void dsp_jclr(void)
1865: {
1.1.1.2 root 1866: Uint32 memspace, addr, value, numreg, newpc, numbit;
1.1 root 1867:
1868: memspace = (cur_inst>>6) & 1;
1869: value = (cur_inst>>8) & BITMASK(6);
1870: numbit = cur_inst & BITMASK(5);
1871:
1872: switch((cur_inst>>14) & BITMASK(2)) {
1873: case 0:
1874: /* jclr #n,x:aa,p:xx */
1875: /* jclr #n,y:aa,p:xx */
1876: addr = value;
1877: value = read_memory(memspace, addr);
1878: break;
1879: case 1:
1880: /* jclr #n,x:ea,p:xx */
1881: /* jclr #n,y:ea,p:xx */
1882: dsp_calc_ea(value, &addr);
1883: value = read_memory(memspace, addr);
1884: break;
1885: case 2:
1886: /* jclr #n,x:pp,p:xx */
1887: /* jclr #n,y:pp,p:xx */
1888: addr = 0xffc0 + value;
1889: value = read_memory(memspace, addr);
1890: break;
1891: case 3:
1892: /* jclr #n,R,p:xx */
1893: numreg = value;
1.1.1.2 root 1894: value = dsp_core->registers[numreg];
1.1 root 1895: addr = 0xffff0000; /* invalid address */
1896: memspace = 0xffff0000; /* invalid memspace */
1897: break;
1898: }
1899:
1.1.1.2 root 1900: ++cur_inst_len;
1.1 root 1901:
1902: if ((value & (1<<numbit))==0) {
1.1.1.2 root 1903: int pollingLoop, i;
1.1 root 1904:
1.1.1.2 root 1905: newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1);
1.1 root 1906:
1.1.1.2 root 1907: /* Polling loop if jump to same PC as current JCLR instruction */
1908: pollingLoop = (newpc == dsp_core->pc);
1909: if (!pollingLoop && (newpc<dsp_core->pc)) {
1910: /* or if only NOPs from jump address to current JCLR instruction */
1911: pollingLoop = 1;
1912: for (i=newpc; i<dsp_core->pc; i++) {
1913: if (read_memory(DSP_SPACE_P, i) != 0) {
1914: pollingLoop=0;
1915: break;
1916: }
1917: }
1918: }
1919: if (!pollingLoop && (newpc+2 == dsp_core->pc)) {
1920: /* or programs that re-set host port operation (Papa was a bladerunner/Eko) */
1921: pollingLoop = (read_memory(DSP_SPACE_P, newpc) == 0x08f4a0) /* movep #0x000001,x:0xffe0 */
1922: && (read_memory(DSP_SPACE_P, newpc+1) == 0x000001);
1923: }
1924:
1925: if (pollingLoop) {
1.1 root 1926: /* Are we waiting for host port ? */
1927: if ((memspace==DSP_SPACE_X) && (addr==0xffc0+DSP_HOST_HSR)) {
1928: /* Wait for host to write */
1929: if (numbit==DSP_HOST_HSR_HRDF) {
1930: #if DSP_DISASM_STATE
1.1.1.2 root 1931: fprintf(stderr, "Dsp: WAIT_HOSTWRITE\n");
1.1 root 1932: #endif
1.1.1.2 root 1933: SDL_SemWait(dsp_core->semaphore);
1.1 root 1934: }
1935:
1936: /* Wait for host to read */
1937: if (numbit==DSP_HOST_HSR_HTDE) {
1938: #if DSP_DISASM_STATE
1.1.1.2 root 1939: fprintf(stderr, "Dsp: WAIT_HOSTREAD\n");
1.1 root 1940: #endif
1.1.1.2 root 1941: SDL_SemWait(dsp_core->semaphore);
1.1 root 1942: }
1943: }
1944: }
1945:
1.1.1.2 root 1946: dsp_core->pc = newpc;
1.1 root 1947: cur_inst_len = 0;
1948: return;
1949: }
1950: }
1951:
1952: static void dsp_jmp(void)
1953: {
1.1.1.2 root 1954: Uint32 newpc;
1.1 root 1955:
1956: switch((cur_inst >> 16) & BITMASK(8)) {
1957: case 0x0a:
1958: dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc);
1959: break;
1960: case 0x0c:
1961: newpc = cur_inst & BITMASK(12);
1962: break;
1963: }
1964:
1965: cur_inst_len = 0;
1966:
1967: /* Infinite loop ? */
1.1.1.2 root 1968: if (newpc == dsp_core->pc) {
1.1 root 1969: #if DSP_DISASM_STATE
1.1.1.2 root 1970: fprintf(stderr, "Dsp: JMP instruction, infinite loop\n");
1.1 root 1971: #endif
1.1.1.2 root 1972: SDL_SemWait(dsp_core->semaphore);
1.1 root 1973: return;
1974: }
1975:
1.1.1.2 root 1976: dsp_core->pc = newpc;
1.1 root 1977: }
1978:
1979: static void dsp_jscc(void)
1980: {
1.1.1.2 root 1981: Uint32 newpc, cc_code;
1.1 root 1982:
1983: cc_code = 0;
1984: switch((cur_inst >> 16) & BITMASK(8)) {
1985: case 0x0b:
1986: dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc);
1987: cc_code=cur_inst & BITMASK(4);
1988: break;
1989: case 0x0f:
1990: newpc = cur_inst & BITMASK(12);
1991: cc_code=(cur_inst>>12) & BITMASK(4);
1992: break;
1993: }
1994:
1995: if (dsp_calc_cc(cc_code)) {
1.1.1.2 root 1996: dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]);
1.1 root 1997:
1.1.1.2 root 1998: dsp_core->pc = newpc;
1.1 root 1999: cur_inst_len = 0;
2000: }
2001: }
2002:
2003: static void dsp_jsclr(void)
2004: {
1.1.1.2 root 2005: Uint32 memspace, addr, value, numreg, newpc, numbit;
1.1 root 2006:
2007: memspace = (cur_inst>>6) & 1;
2008: value = (cur_inst>>8) & BITMASK(6);
2009: numbit = cur_inst & BITMASK(5);
2010:
2011: switch((cur_inst>>14) & BITMASK(2)) {
2012: case 0:
2013: /* jsclr #n,x:aa,p:xx */
2014: /* jsclr #n,y:aa,p:xx */
2015: addr = value;
2016: value = read_memory(memspace, addr);
2017: break;
2018: case 1:
2019: /* jsclr #n,x:ea,p:xx */
2020: /* jsclr #n,y:ea,p:xx */
2021: dsp_calc_ea(value, &addr);
2022: value = read_memory(memspace, addr);
2023: break;
2024: case 2:
2025: /* jsclr #n,x:pp,p:xx */
2026: /* jsclr #n,y:pp,p:xx */
2027: addr = 0xffc0 + value;
2028: value = read_memory(memspace, addr);
2029: break;
2030: case 3:
2031: /* jsclr #n,R,p:xx */
2032: numreg = value;
1.1.1.2 root 2033: value = dsp_core->registers[numreg];
1.1 root 2034: break;
2035: }
2036:
1.1.1.2 root 2037: ++cur_inst_len;
1.1 root 2038: if ((value & (1<<numbit))==0) {
1.1.1.2 root 2039: dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]);
1.1 root 2040:
1.1.1.2 root 2041: newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1);
2042: dsp_core->pc = newpc;
1.1 root 2043: cur_inst_len = 0;
2044: }
2045: }
2046:
2047: static void dsp_jset(void)
2048: {
1.1.1.2 root 2049: Uint32 memspace, addr, value, numreg, numbit;
2050: Uint32 newpc;
1.1 root 2051:
2052: memspace = (cur_inst>>6) & 1;
2053: value = (cur_inst>>8) & BITMASK(6);
2054: numbit = cur_inst & BITMASK(5);
2055:
2056: switch((cur_inst>>14) & BITMASK(2)) {
2057: case 0:
2058: /* jset #n,x:aa,p:xx */
2059: /* jset #n,y:aa,p:xx */
2060: addr = value;
2061: value = read_memory(memspace, addr);
2062: break;
2063: case 1:
2064: /* jset #n,x:ea,p:xx */
2065: /* jset #n,y:ea,p:xx */
2066: dsp_calc_ea(value, &addr);
2067: value = read_memory(memspace, addr);
2068: break;
2069: case 2:
2070: /* jset #n,x:pp,p:xx */
2071: /* jset #n,y:pp,p:xx */
2072: addr = 0xffc0 + value;
2073: value = read_memory(memspace, addr);
2074: break;
2075: case 3:
2076: /* jset #n,R,p:xx */
2077: numreg = value;
1.1.1.2 root 2078: value = dsp_core->registers[numreg];
1.1 root 2079: break;
2080: }
2081:
1.1.1.2 root 2082: ++cur_inst_len;
1.1 root 2083: if (value & (1<<numbit)) {
1.1.1.2 root 2084: newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1);
1.1 root 2085:
1.1.1.2 root 2086: dsp_core->pc = newpc;
1.1 root 2087: cur_inst_len=0;
2088: }
2089: }
2090:
2091: static void dsp_jsr(void)
2092: {
1.1.1.2 root 2093: Uint32 newpc;
1.1 root 2094:
2095: if (((cur_inst>>12) & BITMASK(4))==0) {
2096: newpc = cur_inst & BITMASK(12);
2097: } else {
2098: dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc);
2099: }
2100:
1.1.1.2 root 2101: dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]);
1.1 root 2102:
1.1.1.2 root 2103: dsp_core->pc = newpc;
1.1 root 2104: cur_inst_len = 0;
2105: }
2106:
2107: static void dsp_jsset(void)
2108: {
1.1.1.2 root 2109: Uint32 memspace, addr, value, numreg, newpc, numbit;
1.1 root 2110:
2111: memspace = (cur_inst>>6) & 1;
2112: value = (cur_inst>>8) & BITMASK(6);
2113: numbit = cur_inst & BITMASK(5);
2114:
2115: switch((cur_inst>>14) & BITMASK(2)) {
2116: case 0:
2117: /* jsset #n,x:aa,p:xx */
2118: /* jsset #n,y:aa,p:xx */
2119: addr = value;
2120: value = read_memory(memspace, addr);
2121: break;
2122: case 1:
2123: /* jsset #n,x:ea,p:xx */
2124: /* jsset #n,y:ea,p:xx */
2125: dsp_calc_ea(value, &addr);
2126: value = read_memory(memspace, addr);
2127: break;
2128: case 2:
2129: /* jsset #n,x:pp,p:xx */
2130: /* jsset #n,y:pp,p:xx */
2131: addr = 0xffc0 + value;
2132: value = read_memory(memspace, addr);
2133: break;
2134: case 3:
2135: /* jsset #n,R,p:xx */
2136: numreg = value;
1.1.1.2 root 2137: value = dsp_core->registers[numreg];
1.1 root 2138: break;
2139: }
2140:
1.1.1.2 root 2141: ++cur_inst_len;
1.1 root 2142: if (value & (1<<numbit)) {
1.1.1.2 root 2143: dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]);
1.1 root 2144:
1.1.1.2 root 2145: newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1);
2146: dsp_core->pc = newpc;
1.1 root 2147: cur_inst_len = 0;
2148: }
2149: }
2150:
2151: static void dsp_lua(void)
2152: {
1.1.1.2 root 2153: Uint32 value, srcreg, dstreg, srcsave, srcnew;
2154:
1.1 root 2155: srcreg = (cur_inst>>8) & BITMASK(3);
1.1.1.2 root 2156:
2157: srcsave = dsp_core->registers[DSP_REG_R0+srcreg];
2158: dsp_calc_ea((cur_inst>>8) & BITMASK(5), &value);
2159: srcnew = dsp_core->registers[DSP_REG_R0+srcreg];
2160: dsp_core->registers[DSP_REG_R0+srcreg] = srcsave;
2161:
1.1 root 2162: dstreg = cur_inst & BITMASK(3);
2163:
2164: if (cur_inst & (1<<3)) {
1.1.1.2 root 2165: dsp_core->registers[DSP_REG_N0+dstreg] = srcnew;
1.1 root 2166: } else {
1.1.1.2 root 2167: dsp_core->registers[DSP_REG_R0+dstreg] = srcnew;
1.1 root 2168: }
2169: }
2170:
1.1.1.3 ! root 2171: /*
! 2172: MOVEC instruction parameter encoding
! 2173:
! 2174: xxxxxxx0 x1xxxxxx 1xxxxxxx reg
! 2175: xxxxxxx1 x0xxxxxx 0xxxxxxx aa
! 2176: xxxxxxx1 x1xxxxxx 0xxxxxxx ea
! 2177: xxxxxxx1 xYxxxxxx 1xxxxxxx #xx
! 2178: */
1.1 root 2179: static void dsp_movec(void)
2180: {
1.1.1.2 root 2181: Uint32 value;
1.1.1.3 ! root 2182:
! 2183: value = ((cur_inst>>16) & 1)<<2;
! 2184: value |= ((cur_inst>>14) & 1)<<1;
! 2185: value |= (cur_inst>>7) & 1;
1.1 root 2186:
2187: opcodes_movec[value]();
2188: }
2189:
1.1.1.3 ! root 2190: static void dsp_movec_reg(void)
1.1 root 2191: {
1.1.1.2 root 2192: Uint32 numreg1, numreg2, value;
1.1 root 2193:
2194: /* S1,D2 */
2195: /* S2,D1 */
2196:
2197: numreg2 = (cur_inst>>8) & BITMASK(6);
2198: numreg1 = (cur_inst & BITMASK(5))|0x20;
2199:
2200: if (cur_inst & (1<<15)) {
2201: /* Write D1 */
2202:
2203: if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) {
1.1.1.2 root 2204: dsp_pm_read_accu24(numreg2, &dsp_core->registers[numreg1]);
1.1 root 2205: } else {
1.1.1.2 root 2206: dsp_core->registers[numreg1] = dsp_core->registers[numreg2];
1.1 root 2207: }
1.1.1.2 root 2208: dsp_core->registers[numreg1] &= BITMASK(registers_mask[numreg1]);
1.1 root 2209: } else {
2210: /* Read S1 */
2211:
2212: if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) {
1.1.1.2 root 2213: value = dsp_core->registers[numreg1];
2214: dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0;
1.1 root 2215: if (value & (1<<23)) {
1.1.1.2 root 2216: dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0xff;
1.1 root 2217: }
1.1.1.2 root 2218: dsp_core->registers[DSP_REG_A1+(numreg2 & 1)] = value & BITMASK(24);
2219: dsp_core->registers[DSP_REG_A0+(numreg2 & 1)] = 0;
1.1 root 2220: } else {
1.1.1.2 root 2221: dsp_core->registers[numreg2] = dsp_core->registers[numreg1];
2222: dsp_core->registers[numreg2] &= BITMASK(registers_mask[numreg2]);
1.1 root 2223: }
2224: }
2225: }
2226:
1.1.1.3 ! root 2227: static void dsp_movec_aa(void)
1.1 root 2228: {
1.1.1.2 root 2229: Uint32 numreg, addr, memspace;
1.1 root 2230:
2231: /* x:aa,D1 */
2232: /* S1,x:aa */
2233: /* y:aa,D1 */
2234: /* S1,y:aa */
2235:
2236: numreg = (cur_inst & BITMASK(5))|0x20;
2237: addr = (cur_inst>>8) & BITMASK(6);
2238: memspace = (cur_inst>>6) & 1;
2239:
2240: if (cur_inst & (1<<15)) {
2241: /* Write D1 */
2242:
1.1.1.2 root 2243: dsp_core->registers[numreg] = read_memory(memspace, addr);
2244: dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]);
1.1 root 2245: } else {
2246: /* Read S1 */
2247:
1.1.1.2 root 2248: write_memory(memspace, addr, dsp_core->registers[numreg]);
1.1 root 2249: }
2250: }
2251:
1.1.1.3 ! root 2252: static void dsp_movec_imm(void)
1.1 root 2253: {
1.1.1.2 root 2254: Uint32 numreg;
1.1 root 2255:
2256: /* #xx,D1 */
2257:
2258: numreg = (cur_inst & BITMASK(5))|0x20;
1.1.1.2 root 2259: dsp_core->registers[numreg] = (cur_inst>>8) & BITMASK(8);
1.1 root 2260: }
2261:
1.1.1.3 ! root 2262: static void dsp_movec_ea(void)
1.1 root 2263: {
1.1.1.2 root 2264: Uint32 numreg, addr, memspace, ea_mode;
1.1 root 2265: int retour;
2266:
2267: /* x:ea,D1 */
2268: /* S1,x:ea */
2269: /* y:ea,D1 */
2270: /* S1,y:ea */
2271: /* #xxxx,D1 */
2272:
2273: numreg = (cur_inst & BITMASK(5))|0x20;
2274: ea_mode = (cur_inst>>8) & BITMASK(6);
2275: memspace = (cur_inst>>6) & 1;
2276:
2277: if (cur_inst & (1<<15)) {
2278: /* Write D1 */
2279:
2280: retour = dsp_calc_ea(ea_mode, &addr);
2281: if (retour) {
1.1.1.2 root 2282: dsp_core->registers[numreg] = addr;
1.1 root 2283: } else {
1.1.1.2 root 2284: dsp_core->registers[numreg] = read_memory(memspace, addr);
1.1 root 2285: }
1.1.1.2 root 2286: dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]);
1.1 root 2287: } else {
2288: /* Read S1 */
2289:
2290: retour = dsp_calc_ea(ea_mode, &addr);
2291:
1.1.1.2 root 2292: write_memory(memspace, addr, dsp_core->registers[numreg]);
1.1 root 2293: }
2294: }
2295:
2296: static void dsp_movem(void)
2297: {
1.1.1.2 root 2298: Uint32 numreg, addr, ea_mode, value;
1.1 root 2299:
2300: numreg = cur_inst & BITMASK(6);
2301:
2302: if (cur_inst & (1<<14)) {
2303: /* S,p:ea */
2304: /* p:ea,D */
2305:
2306: ea_mode = (cur_inst>>8) & BITMASK(6);
2307: dsp_calc_ea(ea_mode, &addr);
2308: } else {
2309: /* S,p:aa */
2310: /* p:aa,D */
2311:
2312: addr = (cur_inst>>8) & BITMASK(6);
2313: }
2314:
2315: if (cur_inst & (1<<15)) {
2316: /* Write D */
2317:
2318: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
2319: value = read_memory(DSP_SPACE_P, addr);
1.1.1.2 root 2320: dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0;
1.1 root 2321: if (value & (1<<23)) {
1.1.1.2 root 2322: dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0xff;
1.1 root 2323: }
1.1.1.2 root 2324: dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24);
2325: dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0;
1.1 root 2326: } else {
1.1.1.2 root 2327: dsp_core->registers[numreg] = read_memory(DSP_SPACE_P, addr);
2328: dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]);
1.1 root 2329: }
2330: } else {
2331: /* Read S */
2332:
2333: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
2334: dsp_pm_read_accu24(numreg, &value);
2335: } else {
1.1.1.2 root 2336: value = dsp_core->registers[numreg];
1.1 root 2337: }
2338: write_memory(DSP_SPACE_P, addr, value);
2339: }
2340: }
2341:
2342: static void dsp_movep(void)
2343: {
1.1.1.2 root 2344: Uint32 value;
1.1 root 2345:
2346: value = (cur_inst>>6) & BITMASK(2);
2347:
2348: opcodes_movep[value]();
2349: }
2350:
2351: static void dsp_movep_0(void)
2352: {
2353: /* S,x:pp */
2354: /* x:pp,D */
2355: /* S,y:pp */
2356: /* y:pp,D */
2357:
1.1.1.2 root 2358: Uint32 addr, memspace, numreg, value;
1.1 root 2359:
2360: addr = 0xffc0 + (cur_inst & BITMASK(6));
2361: memspace = (cur_inst>>16) & 1;
2362: numreg = (cur_inst>>8) & BITMASK(6);
2363:
2364: if (cur_inst & (1<<15)) {
2365: /* Write pp */
2366:
2367: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
2368: dsp_pm_read_accu24(numreg, &value);
2369: } else {
1.1.1.2 root 2370: value = dsp_core->registers[numreg];
1.1 root 2371: }
2372: write_memory(memspace, addr, value);
2373: } else {
2374: /* Read pp */
2375:
2376: value = read_memory(memspace, addr);
2377:
2378: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
1.1.1.2 root 2379: dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0;
1.1 root 2380: if (value & (1<<23)) {
1.1.1.2 root 2381: dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0xff;
1.1 root 2382: }
1.1.1.2 root 2383: dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24);
2384: dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0;
1.1 root 2385: } else {
1.1.1.2 root 2386: dsp_core->registers[numreg] = value;
2387: dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]);
1.1 root 2388: }
2389: }
2390: }
2391:
2392: static void dsp_movep_1(void)
2393: {
2394: /* p:ea,x:pp */
2395: /* x:pp,p:ea */
2396: /* p:ea,y:pp */
2397: /* y:pp,p:ea */
2398:
1.1.1.2 root 2399: Uint32 xyaddr, memspace, paddr;
1.1 root 2400:
2401: xyaddr = 0xffc0 + (cur_inst & BITMASK(6));
2402: dsp_calc_ea((cur_inst>>8) & BITMASK(6), &paddr);
2403: memspace = (cur_inst>>16) & 1;
2404:
2405: if (cur_inst & (1<<15)) {
2406: /* Write pp */
2407: write_memory(memspace, xyaddr, read_memory(DSP_SPACE_P, paddr));
2408: } else {
2409: /* Read pp */
2410: write_memory(DSP_SPACE_P, paddr, read_memory(memspace, xyaddr));
2411: }
2412: }
2413:
2414: static void dsp_movep_2(void)
2415: {
2416: /* x:ea,x:pp */
2417: /* y:ea,x:pp */
2418: /* #xxxxxx,x:pp */
2419: /* x:pp,x:ea */
2420: /* x:pp,y:pp */
2421: /* x:ea,y:pp */
2422: /* y:ea,y:pp */
2423: /* #xxxxxx,y:pp */
2424: /* y:pp,y:ea */
2425: /* y:pp,x:ea */
2426:
1.1.1.2 root 2427: Uint32 addr, peraddr, easpace, perspace, ea_mode;
1.1 root 2428: int retour;
2429:
2430: peraddr = 0xffc0 + (cur_inst & BITMASK(6));
2431: perspace = (cur_inst>>16) & 1;
2432:
2433: ea_mode = (cur_inst>>8) & BITMASK(6);
2434: easpace = (cur_inst>>6) & 1;
2435: retour = dsp_calc_ea(ea_mode, &addr);
2436:
2437: if (cur_inst & (1<<15)) {
2438: /* Write pp */
2439:
2440: if (retour) {
2441: write_memory(perspace, peraddr, addr);
2442: } else {
2443: write_memory(perspace, peraddr, read_memory(easpace, addr));
2444: }
2445: } else {
2446: /* Read pp */
2447:
2448: write_memory(easpace, addr, read_memory(perspace, peraddr));
2449: }
2450: }
2451:
2452: static void dsp_norm(void)
2453: {
1.1.1.2 root 2454: Uint32 cursr,cur_e, cur_euz, dest[3], numreg, rreg;
2455: Uint16 newsr;
1.1 root 2456:
1.1.1.2 root 2457: cursr = dsp_core->registers[DSP_REG_SR];
1.1 root 2458: cur_e = (cursr>>DSP_SR_E) & 1; /* E */
2459: cur_euz = ~cur_e; /* (not E) and U and (not Z) */
2460: cur_euz &= (cursr>>DSP_SR_U) & 1;
2461: cur_euz &= ~((cursr>>DSP_SR_Z) & 1);
2462: cur_euz &= 1;
2463:
2464: numreg = (cur_inst>>3) & 1;
1.1.1.2 root 2465: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
2466: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
2467: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 2468: rreg = DSP_REG_R0+((cur_inst>>8) & BITMASK(3));
2469:
2470: if (cur_euz) {
2471: newsr = dsp_asl56(dest);
1.1.1.2 root 2472: --dsp_core->registers[rreg];
2473: dsp_core->registers[rreg] &= BITMASK(16);
1.1 root 2474: } else if (cur_e) {
2475: newsr = dsp_asr56(dest);
1.1.1.2 root 2476: ++dsp_core->registers[rreg];
2477: dsp_core->registers[rreg] &= BITMASK(16);
1.1 root 2478: } else {
2479: newsr = 0;
2480: }
2481:
1.1.1.2 root 2482: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
2483: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
2484: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
2485:
2486: dsp_ccr_extension(&dest[0], &dest[1]);
2487: dsp_ccr_unnormalized(&dest[0], &dest[1]);
2488: dsp_ccr_negative(&dest[0]);
1.1 root 2489: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
2490:
1.1.1.2 root 2491: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
2492: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 2493: }
2494:
2495: static void dsp_ori(void)
2496: {
1.1.1.2 root 2497: Uint32 regnum, value;
1.1 root 2498:
2499: value = (cur_inst >> 8) & BITMASK(8);
2500: regnum = cur_inst & BITMASK(2);
2501: switch(regnum) {
2502: case 0:
2503: /* mr */
1.1.1.2 root 2504: dsp_core->registers[DSP_REG_SR] |= value<<8;
1.1 root 2505: break;
2506: case 1:
2507: /* ccr */
1.1.1.2 root 2508: dsp_core->registers[DSP_REG_SR] |= value;
1.1 root 2509: break;
2510: case 2:
2511: /* omr */
1.1.1.2 root 2512: dsp_core->registers[DSP_REG_OMR] |= value;
1.1 root 2513: break;
2514: }
2515: }
2516:
1.1.1.3 ! root 2517: /*
! 2518: REP instruction parameter encoding
! 2519:
! 2520: xxxxxxxx 00xxxxxx 0xxxxxxx aa
! 2521: xxxxxxxx 01xxxxxx 0xxxxxxx ea
! 2522: xxxxxxxx YYxxxxxx 1xxxxxxx imm
! 2523: xxxxxxxx 11xxxxxx 0xxxxxxx reg
! 2524: */
! 2525:
1.1 root 2526: static void dsp_rep(void)
2527: {
1.1.1.2 root 2528: Uint32 value;
1.1 root 2529:
1.1.1.2 root 2530: dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC];
1.1 root 2531:
1.1.1.3 ! root 2532: value = ((cur_inst>>14) & BITMASK(2))<<1;
! 2533: value |= (cur_inst>>7) & 1;
1.1 root 2534:
2535: opcodes_rep[value]();
2536: pc_on_rep = 1; /* Not decrement LC at first time */
1.1.1.2 root 2537: dsp_core->loop_rep = 1; /* We are now running rep */
1.1 root 2538: }
2539:
1.1.1.3 ! root 2540: static void dsp_rep_aa(void)
1.1 root 2541: {
2542: /* x:aa */
2543: /* y:aa */
2544:
1.1.1.2 root 2545: dsp_core->registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6));
1.1 root 2546: }
2547:
1.1.1.3 ! root 2548: static void dsp_rep_imm(void)
1.1 root 2549: {
2550: /* #xxx */
2551:
1.1.1.3 ! root 2552: dsp_core->registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8))
! 2553: + ((cur_inst & BITMASK(4))<<8);
1.1 root 2554: }
2555:
1.1.1.3 ! root 2556: static void dsp_rep_ea(void)
1.1 root 2557: {
1.1.1.2 root 2558: Uint32 value;
1.1 root 2559:
2560: /* x:ea */
2561: /* y:ea */
2562:
2563: dsp_calc_ea((cur_inst>>8) & BITMASK(6),&value);
1.1.1.2 root 2564: dsp_core->registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value);
1.1 root 2565: }
2566:
1.1.1.3 ! root 2567: static void dsp_rep_reg(void)
1.1 root 2568: {
1.1.1.2 root 2569: Uint32 numreg;
1.1 root 2570:
2571: /* R */
2572:
2573: numreg = (cur_inst>>8) & BITMASK(6);
2574: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
1.1.1.2 root 2575: dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]);
1.1 root 2576: } else {
1.1.1.2 root 2577: dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg];
1.1 root 2578: }
1.1.1.2 root 2579: dsp_core->registers[DSP_REG_LC] &= BITMASK(16);
1.1 root 2580: }
2581:
2582: static void dsp_reset(void)
2583: {
2584: /* Reset external peripherals */
2585: }
2586:
2587: static void dsp_rti(void)
2588: {
1.1.1.2 root 2589: Uint32 newpc = 0, newsr = 0;
1.1 root 2590:
2591: dsp_stack_pop(&newpc, &newsr);
2592:
1.1.1.2 root 2593: dsp_core->pc = newpc;
2594: dsp_core->registers[DSP_REG_SR] = newsr;
1.1 root 2595:
2596: cur_inst_len = 0;
2597: }
2598:
2599: static void dsp_rts(void)
2600: {
1.1.1.2 root 2601: Uint32 newpc = 0, newsr;
1.1 root 2602:
2603: dsp_stack_pop(&newpc, &newsr);
2604:
1.1.1.2 root 2605: dsp_core->pc = newpc;
1.1 root 2606: cur_inst_len = 0;
2607: }
2608:
2609: static void dsp_stop(void)
2610: {
1.1.1.2 root 2611: #if DSP_DISASM_STATE
2612: fprintf(stderr, "Dsp: STOP instruction\n");
2613: #endif
2614: SDL_SemWait(dsp_core->semaphore);
1.1 root 2615: }
2616:
2617: static void dsp_swi(void)
2618: {
2619: /* Raise interrupt p:0x0006 */
2620: #if DSP_DISASM_INTER
1.1.1.2 root 2621: fprintf(stderr, "Dsp: Interrupt: Swi\n");
1.1 root 2622: #endif
2623: }
2624:
2625: static void dsp_tcc(void)
2626: {
1.1.1.2 root 2627: Uint32 cc_code, regsrc1, regdest1, value;
2628: Uint32 regsrc2, regdest2;
1.1 root 2629:
2630: cc_code = (cur_inst>>12) & BITMASK(4);
2631:
2632: if (dsp_calc_cc(cc_code)) {
2633: regsrc1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][0];
1.1.1.2 root 2634: regdest1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][1];
1.1 root 2635:
2636: /* Read S1 */
2637: if ((regsrc1 == DSP_REG_A) || (regsrc1 == DSP_REG_B)) {
1.1.1.2 root 2638: tmp_parmove_src[0][0]=dsp_core->registers[DSP_REG_A2+(regsrc1 & 1)];
2639: tmp_parmove_src[0][1]=dsp_core->registers[DSP_REG_A1+(regsrc1 & 1)];
2640: tmp_parmove_src[0][2]=dsp_core->registers[DSP_REG_A0+(regsrc1 & 1)];
1.1 root 2641: } else {
1.1.1.2 root 2642: value = dsp_core->registers[regsrc1];
1.1 root 2643: tmp_parmove_src[0][0]=0;
2644: if (value & (1<<23)) {
2645: tmp_parmove_src[0][0]=0x0000ff;
2646: }
2647: tmp_parmove_src[0][1]=value;
2648: tmp_parmove_src[0][2]=0;
2649: }
2650:
2651: /* Write D1 */
1.1.1.2 root 2652: dsp_core->registers[DSP_REG_A2+(regdest1 & 1)]=tmp_parmove_src[0][0];
2653: dsp_core->registers[DSP_REG_A1+(regdest1 & 1)]=tmp_parmove_src[0][1];
2654: dsp_core->registers[DSP_REG_A0+(regdest1 & 1)]=tmp_parmove_src[0][2];
1.1 root 2655:
2656: /* S2,D2 transfer */
2657: if (cur_inst & (1<<16)) {
1.1.1.2 root 2658: regsrc2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3));
2659: regdest2 = DSP_REG_R0+(cur_inst & BITMASK(3));
1.1 root 2660:
1.1.1.2 root 2661: dsp_core->registers[regdest2] = dsp_core->registers[regsrc2];
1.1 root 2662: }
2663: }
2664: }
2665:
2666: static void dsp_wait(void)
2667: {
1.1.1.2 root 2668: #if DSP_DISASM_STATE
2669: fprintf(stderr, "Dsp: WAIT instruction\n");
2670: #endif
2671: SDL_SemWait(dsp_core->semaphore);
1.1 root 2672: }
2673:
2674: /**********************************
2675: * Parallel moves instructions dispatcher
2676: **********************************/
2677:
2678: static void dsp_parmove_read(void)
2679: {
1.1.1.2 root 2680: Uint32 value;
1.1 root 2681:
2682: tmp_parmove_len[0] = tmp_parmove_len[1] = 0;
2683:
2684: /* Calculate needed parallel moves */
2685: value = (cur_inst >> 20) & BITMASK(4);
2686:
2687: /* Do parallel move read */
2688: opcodes_parmove[value]();
2689: }
2690:
2691: static void dsp_parmove_write(void)
2692: {
1.1.1.2 root 2693: Uint32 i,j;
1.1 root 2694:
2695: for(i=0;i<2;i++) {
2696: if (tmp_parmove_len[i]==0) {
2697: continue;
2698: }
2699:
2700: /* Do parallel move write */
2701: for (
2702: j=tmp_parmove_start[i];
2703: j<tmp_parmove_start[i]+tmp_parmove_len[i];
2704: j++
2705: ) {
2706: if (tmp_parmove_type[i]) {
2707: /* Write to memory */
2708: write_memory(tmp_parmove_space[i], tmp_parmove_dest[i][j].dsp_address, tmp_parmove_src[i][j]);
2709: } else {
1.1.1.2 root 2710: Uint32 *dest;
1.1 root 2711:
2712: /* Write to register */
2713: dest=tmp_parmove_dest[i][j].host_pointer;
2714: *dest = tmp_parmove_src[i][j];
2715: }
2716: }
2717: }
2718: }
2719:
1.1.1.2 root 2720: static int dsp_pm_read_accu24(int numreg, Uint32 *dest)
1.1 root 2721: {
1.1.1.2 root 2722: Uint32 scaling, value, numbits;
2723: int got_limited=0;
1.1 root 2724:
2725: /* Read an accumulator, stores it limited */
2726:
1.1.1.2 root 2727: scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2);
1.1 root 2728: numreg &= 1;
2729:
2730: /* scaling==1 */
1.1.1.2 root 2731: value = dsp_core->registers[DSP_REG_A2+numreg] & 0xff;
1.1 root 2732: numbits = 8;
2733:
2734: switch(scaling) {
2735: case 0:
2736: value <<=1;
1.1.1.2 root 2737: value |= (dsp_core->registers[DSP_REG_A1+numreg]>>23) & 1;
1.1 root 2738: numbits=9;
2739: break;
2740: case 2:
2741: value <<=2;
1.1.1.2 root 2742: value |= (dsp_core->registers[DSP_REG_A1+numreg]>>22) & 3;
1.1 root 2743: numbits=10;
2744: break;
2745: }
2746:
1.1.1.2 root 2747: if ((value==0) || (value==(Uint32)(BITMASK(numbits)))) {
1.1 root 2748: /* No limiting */
1.1.1.2 root 2749: *dest=dsp_core->registers[DSP_REG_A1+numreg];
2750: } else if (dsp_core->registers[DSP_REG_A2+numreg] & (1<<7)) {
1.1 root 2751: /* Limited to maximum negative value */
2752: *dest=0x00800000;
1.1.1.2 root 2753: dsp_core->registers[DSP_REG_SR] |= (1<<DSP_SR_L);
2754: got_limited=1;
1.1 root 2755: } else {
2756: /* Limited to maximal positive value */
2757: *dest=0x007fffff;
1.1.1.2 root 2758: dsp_core->registers[DSP_REG_SR] |= (1<<DSP_SR_L);
2759: got_limited=1;
1.1 root 2760: }
1.1.1.2 root 2761:
2762: return got_limited;
1.1 root 2763: }
2764:
2765: static void dsp_pm_writereg(int numreg, int position)
2766: {
2767: if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
1.1.1.2 root 2768: tmp_parmove_dest[position][0].host_pointer=&dsp_core->registers[DSP_REG_A2+(numreg & 1)];
2769: tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[DSP_REG_A1+(numreg & 1)];
2770: tmp_parmove_dest[position][2].host_pointer=&dsp_core->registers[DSP_REG_A0+(numreg & 1)];
1.1 root 2771:
2772: tmp_parmove_start[position]=0;
2773: tmp_parmove_len[position]=3;
2774: } else {
1.1.1.2 root 2775: tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[numreg];
1.1 root 2776:
2777: tmp_parmove_start[position]=1;
2778: tmp_parmove_len[position]=1;
2779: }
2780: }
2781:
2782: static void dsp_pm_0(void)
2783: {
1.1.1.2 root 2784: Uint32 memspace, dummy, numreg, value;
1.1 root 2785: /*
2786: 0000 100d 00mm mrrr S,x:ea x0,D
2787: 0000 100d 10mm mrrr S,y:ea y0,D
2788: */
2789: memspace = (cur_inst>>15) & 1;
2790: numreg = (cur_inst>>16) & 1;
2791: dsp_calc_ea((cur_inst>>8) & BITMASK(6), &dummy);
2792:
2793: /* [A|B] to [x|y]:ea */
2794: dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]);
2795: tmp_parmove_dest[0][1].dsp_address=dummy;
2796:
2797: tmp_parmove_start[0] = 1;
2798: tmp_parmove_len[0] = 1;
2799:
2800: tmp_parmove_type[0]=1;
2801: tmp_parmove_space[0]=memspace;
2802:
2803: /* [x|y]0 to [A|B] */
1.1.1.2 root 2804: value = dsp_core->registers[DSP_REG_X0+(memspace<<1)];
1.1 root 2805: if (value & (1<<23)) {
2806: tmp_parmove_src[1][0]=0x0000ff;
2807: } else {
2808: tmp_parmove_src[1][0]=0x000000;
2809: }
2810: tmp_parmove_src[1][1]=value;
2811: tmp_parmove_src[1][2]=0x000000;
1.1.1.2 root 2812: tmp_parmove_dest[1][0].host_pointer=&dsp_core->registers[DSP_REG_A2+numreg];
2813: tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[DSP_REG_A1+numreg];
2814: tmp_parmove_dest[1][2].host_pointer=&dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 2815:
2816: tmp_parmove_start[1] = 0;
2817: tmp_parmove_len[1] = 3;
2818: }
2819:
2820: static void dsp_pm_1(void)
2821: {
1.1.1.2 root 2822: Uint32 memspace, numreg, value, xy_addr, retour;
1.1 root 2823: /*
2824: 0001 ffdf w0mm mrrr x:ea,D1 S2,D2
2825: S1,x:ea S2,D2
2826: #xxxxxx,D1 S2,D2
2827: 0001 deff w1mm mrrr S1,D1 y:ea,D2
2828: S1,D1 S2,y:ea
2829: S1,D1 #xxxxxx,D2
2830: */
2831: value = (cur_inst>>8) & BITMASK(6);
2832:
2833: retour = dsp_calc_ea(value, &xy_addr);
2834:
2835: memspace = (cur_inst>>14) & 1;
2836: numreg = DSP_REG_NULL;
2837:
2838: if (memspace) {
2839: /* Y: */
2840: switch((cur_inst>>16) & BITMASK(2)) {
2841: case 0: numreg = DSP_REG_Y0; break;
2842: case 1: numreg = DSP_REG_Y1; break;
2843: case 2: numreg = DSP_REG_A; break;
2844: case 3: numreg = DSP_REG_B; break;
2845: }
2846: } else {
2847: /* X: */
2848: switch((cur_inst>>18) & BITMASK(2)) {
2849: case 0: numreg = DSP_REG_X0; break;
2850: case 1: numreg = DSP_REG_X1; break;
2851: case 2: numreg = DSP_REG_A; break;
2852: case 3: numreg = DSP_REG_B; break;
2853: }
2854: }
2855:
2856: if (cur_inst & (1<<15)) {
2857: /* Write D1 */
2858:
2859: if (retour) {
2860: value = xy_addr;
2861: } else {
2862: value = read_memory(memspace, xy_addr);
2863: }
2864: tmp_parmove_src[0][0]= 0x000000;
2865: if (value & (1<<23)) {
2866: tmp_parmove_src[0][0]= 0x0000ff;
2867: }
2868: tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]);
2869: tmp_parmove_src[0][2]= 0x000000;
2870:
2871: dsp_pm_writereg(numreg, 0);
2872: tmp_parmove_type[0]=0;
2873: } else {
2874: /* Read S1 */
2875:
2876: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
2877: dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]);
2878: } else {
1.1.1.2 root 2879: tmp_parmove_src[0][1]=dsp_core->registers[numreg];
1.1 root 2880: }
2881:
2882: tmp_parmove_dest[0][1].dsp_address=xy_addr;
2883:
2884: tmp_parmove_start[0]=1;
2885: tmp_parmove_len[0]=1;
2886:
2887: tmp_parmove_type[0]=1;
2888: tmp_parmove_space[0]=memspace;
2889: }
2890:
2891: /* S2 */
2892: if (memspace) {
2893: /* Y: */
2894: numreg = DSP_REG_A + ((cur_inst>>19) & 1);
2895: } else {
2896: /* X: */
2897: numreg = DSP_REG_A + ((cur_inst>>17) & 1);
2898: }
2899: dsp_pm_read_accu24(numreg, &tmp_parmove_src[1][1]);
2900:
2901: /* D2 */
2902: if (memspace) {
2903: /* Y: */
1.1.1.2 root 2904: numreg = DSP_REG_X0 + ((cur_inst>>18) & 1);
1.1 root 2905: } else {
2906: /* X: */
1.1.1.2 root 2907: numreg = DSP_REG_Y0 + ((cur_inst>>16) & 1);
1.1 root 2908: }
2909: tmp_parmove_src[1][1] &= BITMASK(registers_mask[numreg]);
1.1.1.2 root 2910: tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[numreg];
1.1 root 2911:
1.1.1.2 root 2912: tmp_parmove_start[1]=1;
2913: tmp_parmove_len[1]=1;
1.1 root 2914:
1.1.1.2 root 2915: tmp_parmove_type[1]=0;
1.1 root 2916: }
2917:
2918: static void dsp_pm_2(void)
2919: {
1.1.1.2 root 2920: Uint32 dummy;
1.1 root 2921: /*
2922: 0010 0000 0000 0000 nop
2923: 0010 0000 010m mrrr R update
2924: 0010 00ee eeed dddd S,D
2925: 001d dddd iiii iiii #xx,D
2926: */
2927: if (((cur_inst >> 8) & 0xffff) == 0x2000) {
2928: return;
2929: }
2930:
2931: if (((cur_inst >> 8) & 0xffe0) == 0x2040) {
2932: dsp_calc_ea((cur_inst>>8) & BITMASK(5), &dummy);
2933: return;
2934: }
2935:
2936: if (((cur_inst >> 8) & 0xfc00) == 0x2000) {
2937: dsp_pm_2_2();
2938: return;
2939: }
2940:
2941: dsp_pm_3();
2942: }
2943:
2944: static void dsp_pm_2_2(void)
2945: {
2946: /*
2947: 0010 00ee eeed dddd S,D
2948: */
1.1.1.2 root 2949: Uint32 srcreg, dstreg;
1.1 root 2950:
2951: srcreg = (cur_inst >> 13) & BITMASK(5);
2952: dstreg = (cur_inst >> 8) & BITMASK(5);
2953:
2954: tmp_parmove_src[0][0]=
2955: tmp_parmove_src[0][1]=
2956: tmp_parmove_src[0][2]= 0x000000;
2957:
2958: if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) {
1.1.1.2 root 2959: /* Accu to register or accu: limited 24 bits */
2960: dsp_pm_read_accu24(srcreg, &tmp_parmove_src[0][1]);
2961: if (tmp_parmove_src[0][1] & (1<<23)) {
2962: tmp_parmove_src[0][0]=0x0000ff;
1.1 root 2963: }
2964: } else {
2965: if ((dstreg == DSP_REG_A) || (dstreg == DSP_REG_B)) {
2966: /* Register to accu: sign extended to 56 bits */
1.1.1.2 root 2967: tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[srcreg]);
1.1 root 2968: if (tmp_parmove_src[0][1] & (1<<23)) {
2969: tmp_parmove_src[0][0]=0x0000ff;
2970: }
2971: } else {
2972: /* Register to register: n bits */
1.1.1.2 root 2973: tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[srcreg]);
1.1 root 2974: }
2975: }
2976:
2977: dsp_pm_writereg(dstreg, 0);
2978: tmp_parmove_type[0]=0;
2979: }
2980:
2981: static void dsp_pm_3(void)
2982: {
1.1.1.2 root 2983: Uint32 dest, srcvalue;
1.1 root 2984: /*
2985: 001d dddd iiii iiii #xx,R
2986: */
2987: dest = (cur_inst >> 16) & BITMASK(5);
2988: srcvalue = (cur_inst >> 8) & BITMASK(8);
2989:
2990: switch(dest) {
2991: case DSP_REG_X0:
2992: case DSP_REG_X1:
2993: case DSP_REG_Y0:
2994: case DSP_REG_Y1:
2995: case DSP_REG_A:
2996: case DSP_REG_B:
2997: srcvalue <<= 16;
2998: break;
2999: }
3000:
3001: tmp_parmove_src[0][0]=0x000000;
3002: if ((dest == DSP_REG_A) || (dest == DSP_REG_B)) {
3003: if (srcvalue & (1<<23)) {
3004: tmp_parmove_src[0][0]=0x0000ff;
3005: }
3006: }
3007: tmp_parmove_src[0][1]=srcvalue & BITMASK(registers_mask[dest]);
3008: tmp_parmove_src[0][2]=0x000000;
3009:
3010: dsp_pm_writereg(dest, 0);
3011: tmp_parmove_type[0]=0;
3012: }
3013:
3014: static void dsp_pm_4(void)
3015: {
1.1.1.2 root 3016: Uint32 l_addr, value;
1.1 root 3017: int retour;
3018: /*
3019: 0100 l0ll w0aa aaaa l:aa,D
3020: S,l:aa
3021: 0100 l0ll w1mm mrrr l:ea,D
3022: S,l:ea
3023: 01dd 0ddd w0aa aaaa x:aa,D
3024: S,x:aa
3025: 01dd 0ddd w1mm mrrr x:ea,D
3026: S,x:ea
3027: #xxxxxx,D
3028: 01dd 1ddd w0aa aaaa y:aa,D
3029: S,y:aa
3030: 01dd 1ddd w1mm mrrr y:ea,D
3031: S,y:ea
3032: #xxxxxx,D
3033: */
3034: value = (cur_inst>>16) & BITMASK(3);
3035: value |= (cur_inst>>17) & (BITMASK(2)<<3);
3036:
3037: if ((value>>2)==0) {
3038: value = (cur_inst>>8) & BITMASK(6);
3039: if (cur_inst & (1<<14)) {
3040: retour = dsp_calc_ea(value, &l_addr);
3041: } else {
3042: l_addr = value;
3043: retour = 0;
3044: }
3045: dsp_pm_4x(retour, l_addr);
3046: return;
3047: }
3048:
3049: dsp_pm_5();
3050: }
3051:
1.1.1.2 root 3052: static void dsp_pm_4x(int immediat, Uint32 l_addr)
1.1 root 3053: {
1.1.1.2 root 3054: Uint32 value, numreg, numreg2;
3055: immediat = 0; /* UNUSED */
1.1 root 3056: /*
3057: 0100 l0ll w0aa aaaa l:aa,D
3058: S,l:aa
3059: 0100 l0ll w1mm mrrr l:ea,D
3060: S,l:ea
3061: */
3062: l_addr &= BITMASK(16);
3063: numreg = (cur_inst>>16) & BITMASK(2);
3064: numreg |= (cur_inst>>17) & (1<<2);
3065:
3066: if (cur_inst & (1<<15)) {
3067: /* Write D */
3068:
1.1.1.2 root 3069: /* Sources */
1.1 root 3070: value = read_memory(DSP_SPACE_X,l_addr);
1.1.1.2 root 3071: tmp_parmove_src[0][0] = (value & (1<<23) ? 0xff : 0);
1.1 root 3072: tmp_parmove_src[0][1] = value & BITMASK(registers_mask[registers_lmove[numreg][0]]);
3073: tmp_parmove_src[0][2] = 0x000000;
3074: value = read_memory(DSP_SPACE_Y,l_addr);
3075:
1.1.1.2 root 3076: if (registers_lmove[numreg][0]==registers_lmove[numreg][1]) {
3077: /* Write to 56bit accumulator, setup a single transfer as 56 bit */
3078: tmp_parmove_src[0][2] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]);
1.1 root 3079: } else {
1.1.1.2 root 3080: /* Writes to 24bit registers, setup second 24 bit transfer */
3081: tmp_parmove_src[1][0] = (value & (1<<23) ? 0xff : 0);
3082: tmp_parmove_src[1][1] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]);
3083: tmp_parmove_src[1][2] = 0x000000;
1.1 root 3084: }
3085:
1.1.1.2 root 3086: /* Destinations */
3087: dsp_pm_writereg(registers_lmove[numreg][0], 0);
1.1 root 3088: tmp_parmove_type[0]=0;
3089:
1.1.1.2 root 3090: if (registers_lmove[numreg][0]!=registers_lmove[numreg][1]) {
3091: /* Two 24 or 56 bits registers */
3092: dsp_pm_writereg(registers_lmove[numreg][1], 1);
3093: tmp_parmove_type[1]=0;
1.1 root 3094: }
3095: } else {
3096: /* Read S */
3097:
1.1.1.2 root 3098: /* Sources */
3099: if (numreg<4) {
3100: /* Two 24 bits tranfers */
3101: tmp_parmove_src[0][1] = dsp_core->registers[registers_lmove[numreg][0]];
3102: tmp_parmove_src[1][1] = dsp_core->registers[registers_lmove[numreg][1]];
3103: } else if (numreg<6) {
3104: /* Single accumulator transfer */
3105: numreg2 = registers_lmove[numreg][0];
3106: if (dsp_pm_read_accu24(numreg2, &tmp_parmove_src[0][1])) {
3107: /* Was limited, set lower part */
3108: tmp_parmove_src[1][1] = (tmp_parmove_src[0][1] & (1<<23) ? 0 : 0xffffff);
3109: } else {
3110: /* Not limited */
3111: tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_A0+(numreg2 & 1)];
3112: }
1.1 root 3113: } else {
1.1.1.2 root 3114: /* Two accumulators tranfers */
3115: dsp_pm_read_accu24(registers_lmove[numreg][0], &tmp_parmove_src[0][1]);
3116: dsp_pm_read_accu24(registers_lmove[numreg][1], &tmp_parmove_src[1][1]);
1.1 root 3117: }
1.1.1.2 root 3118:
1.1 root 3119: /* D1 */
3120: tmp_parmove_dest[0][1].dsp_address=l_addr;
3121: tmp_parmove_start[0]=1;
3122: tmp_parmove_len[0]=1;
3123:
3124: tmp_parmove_type[0]=1;
3125: tmp_parmove_space[0]=DSP_SPACE_X;
3126:
3127: /* D2 */
3128: tmp_parmove_dest[1][1].dsp_address=l_addr;
3129: tmp_parmove_start[1]=1;
3130: tmp_parmove_len[1]=1;
3131:
3132: tmp_parmove_type[1]=1;
3133: tmp_parmove_space[1]=DSP_SPACE_Y;
3134: }
3135: }
3136:
3137: static void dsp_pm_5(void)
3138: {
1.1.1.2 root 3139: Uint32 memspace, numreg, value, xy_addr, retour;
1.1 root 3140: /*
3141: 01dd 0ddd w0aa aaaa x:aa,D
3142: S,x:aa
3143: 01dd 0ddd w1mm mrrr x:ea,D
3144: S,x:ea
3145: #xxxxxx,D
3146: 01dd 1ddd w0aa aaaa y:aa,D
3147: S,y:aa
3148: 01dd 1ddd w1mm mrrr y:ea,D
3149: S,y:ea
3150: #xxxxxx,D
3151: */
3152:
3153: value = (cur_inst>>8) & BITMASK(6);
3154:
3155: if (cur_inst & (1<<14)) {
3156: retour = dsp_calc_ea(value, &xy_addr);
3157: } else {
3158: xy_addr = value;
3159: retour = 0;
3160: }
3161:
3162: memspace = (cur_inst>>19) & 1;
3163: numreg = (cur_inst>>16) & BITMASK(3);
3164: numreg |= (cur_inst>>17) & (BITMASK(2)<<3);
3165:
3166: if (cur_inst & (1<<15)) {
3167: /* Write D */
3168:
3169: if (retour) {
3170: value = xy_addr;
3171: } else {
3172: value = read_memory(memspace, xy_addr);
3173: }
3174: tmp_parmove_src[0][0]= 0x000000;
3175: if (value & (1<<23)) {
3176: tmp_parmove_src[0][0]= 0x0000ff;
3177: }
3178: tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]);
3179: tmp_parmove_src[0][2]= 0x000000;
3180:
3181: dsp_pm_writereg(numreg, 0);
3182: tmp_parmove_type[0]=0;
3183: } else {
3184: /* Read S */
3185:
3186: if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
3187: dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]);
3188: } else {
1.1.1.2 root 3189: tmp_parmove_src[0][1]=dsp_core->registers[numreg];
1.1 root 3190: }
3191:
3192: tmp_parmove_dest[0][1].dsp_address=xy_addr;
3193:
3194: tmp_parmove_start[0]=1;
3195: tmp_parmove_len[0]=1;
3196:
3197: tmp_parmove_type[0]=1;
3198: tmp_parmove_space[0]=memspace;
3199: }
3200: }
3201:
3202: static void dsp_pm_8(void)
3203: {
1.1.1.2 root 3204: Uint32 ea1, ea2;
3205: Uint32 numreg1, numreg2;
3206: Uint32 value, dummy1, dummy2;
1.1 root 3207: /*
3208: 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2
3209: x:ea,D1 S2,y:ea
3210: S1,x:ea y:ea,D2
3211: S1,x:ea S2,y:ea
3212: */
3213: numreg1 = numreg2 = DSP_REG_NULL;
3214:
3215: ea1 = (cur_inst>>8) & BITMASK(5);
3216: if ((ea1>>3) == 0) {
3217: ea1 |= (1<<5);
3218: }
3219: ea2 = (cur_inst>>13) & BITMASK(2);
3220: ea2 |= (cur_inst>>17) & (BITMASK(2)<<3);
3221: if ((ea1 & (1<<2))==0) {
3222: ea2 |= 1<<2;
3223: }
3224: if ((ea2>>3) == 0) {
3225: ea2 |= (1<<5);
3226: }
3227:
3228: dsp_calc_ea(ea1, &dummy1);
3229: dsp_calc_ea(ea2, &dummy2);
3230:
3231: switch((cur_inst>>18) & BITMASK(2)) {
3232: case 0: numreg1=DSP_REG_X0; break;
3233: case 1: numreg1=DSP_REG_X1; break;
3234: case 2: numreg1=DSP_REG_A; break;
3235: case 3: numreg1=DSP_REG_B; break;
3236: }
3237: switch((cur_inst>>16) & BITMASK(2)) {
3238: case 0: numreg2=DSP_REG_Y0; break;
3239: case 1: numreg2=DSP_REG_Y1; break;
3240: case 2: numreg2=DSP_REG_A; break;
3241: case 3: numreg2=DSP_REG_B; break;
3242: }
3243:
3244: if (cur_inst & (1<<15)) {
3245: /* Write D1 */
3246:
3247: value = read_memory(DSP_SPACE_X, dummy1);
3248: tmp_parmove_src[0][0]= 0x000000;
3249: if (value & (1<<23)) {
3250: tmp_parmove_src[0][0]= 0x0000ff;
3251: }
3252: tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg1]);
3253: tmp_parmove_src[0][2]= 0x000000;
3254:
3255: dsp_pm_writereg(numreg1, 0);
3256: tmp_parmove_type[0]=0;
3257: } else {
3258: /* Read S1 */
3259:
3260: if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) {
3261: dsp_pm_read_accu24(numreg1, &tmp_parmove_src[0][1]);
3262: } else {
1.1.1.2 root 3263: tmp_parmove_src[0][1]=dsp_core->registers[numreg1];
1.1 root 3264: }
3265:
3266: tmp_parmove_dest[0][1].dsp_address=dummy1;
3267:
3268: tmp_parmove_start[0]=1;
3269: tmp_parmove_len[0]=1;
3270:
3271: tmp_parmove_type[0]=1;
3272: tmp_parmove_space[0]=DSP_SPACE_X;
3273: }
3274:
3275: if (cur_inst & (1<<22)) {
3276: /* Write D2 */
3277:
3278: value = read_memory(DSP_SPACE_Y, dummy2);
3279: tmp_parmove_src[1][0]= 0x000000;
3280: if (value & (1<<23)) {
3281: tmp_parmove_src[1][0]= 0x0000ff;
3282: }
3283: tmp_parmove_src[1][1]= value & BITMASK(registers_mask[numreg2]);
3284: tmp_parmove_src[1][2]= 0x000000;
3285:
3286: dsp_pm_writereg(numreg2, 1);
3287: tmp_parmove_type[1]=0;
3288: } else {
3289: /* Read S2 */
3290: if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) {
3291: dsp_pm_read_accu24(numreg1, &tmp_parmove_src[1][1]);
3292: } else {
1.1.1.2 root 3293: tmp_parmove_src[1][1]=dsp_core->registers[numreg1];
1.1 root 3294: }
3295:
3296: tmp_parmove_dest[1][1].dsp_address=dummy2;
3297:
3298: tmp_parmove_start[1]=1;
3299: tmp_parmove_len[1]=1;
3300:
3301: tmp_parmove_type[1]=1;
3302: tmp_parmove_space[1]=DSP_SPACE_Y;
3303: }
3304: }
3305:
3306: /**********************************
3307: * 56bit arithmetic
3308: **********************************/
3309:
3310: /* source,dest[0] is 55:48 */
3311: /* source,dest[1] is 47:24 */
3312: /* source,dest[2] is 23:00 */
3313:
1.1.1.2 root 3314: static Uint16 dsp_abs56(Uint32 *dest)
1.1 root 3315: {
1.1.1.2 root 3316: Uint32 zerodest[3];
3317: Uint16 newsr;
1.1 root 3318:
3319: /* D=|D| */
3320:
3321: if (dest[0] & (1<<7)) {
3322: zerodest[0] = zerodest[1] = zerodest[2] = 0;
3323:
3324: newsr = dsp_sub56(dest, zerodest);
3325:
3326: dest[0] = zerodest[0];
3327: dest[1] = zerodest[1];
3328: dest[2] = zerodest[2];
3329: } else {
3330: newsr = 0;
3331: }
3332:
3333: return newsr;
3334: }
3335:
1.1.1.2 root 3336: static Uint16 dsp_asl56(Uint32 *dest)
1.1 root 3337: {
1.1.1.2 root 3338: Uint16 overflow, carry;
1.1 root 3339:
3340: /* Shift left dest 1 bit: D<<=1 */
3341:
3342: carry = (dest[0]>>7) & 1;
3343:
3344: dest[0] <<= 1;
3345: dest[0] |= (dest[1]>>23) & 1;
3346: dest[0] &= BITMASK(8);
3347:
3348: dest[1] <<= 1;
3349: dest[1] |= (dest[2]>>23) & 1;
3350: dest[1] &= BITMASK(24);
3351:
3352: dest[2] <<= 1;
3353: dest[2] &= BITMASK(24);
3354:
3355: overflow = (carry != ((dest[0]>>7) & 1));
3356:
3357: return (overflow<<DSP_SR_L)|(overflow<<DSP_SR_V)|(carry<<DSP_SR_C);
3358: }
3359:
1.1.1.2 root 3360: static Uint16 dsp_asr56(Uint32 *dest)
1.1 root 3361: {
1.1.1.2 root 3362: Uint16 carry;
1.1 root 3363:
3364: /* Shift right dest 1 bit: D>>=1 */
3365:
3366: carry = dest[2] & 1;
3367:
3368: dest[2] >>= 1;
3369: dest[2] &= BITMASK(23);
3370: dest[2] |= (dest[1] & 1)<<23;
3371:
3372: dest[1] >>= 1;
3373: dest[1] &= BITMASK(23);
3374: dest[1] |= (dest[0] & 1)<<23;
3375:
3376: dest[0] >>= 1;
3377: dest[0] &= BITMASK(7);
3378: dest[0] |= (dest[0] & (1<<6))<<1;
3379:
3380: return (carry<<DSP_SR_C);
3381: }
3382:
1.1.1.2 root 3383: static Uint16 dsp_add56(Uint32 *source, Uint32 *dest)
1.1 root 3384: {
1.1.1.2 root 3385: Uint16 overflow, carry;
1.1 root 3386:
3387: /* Add source to dest: D = D+S */
1.1.1.2 root 3388: dest[2] += source[2];
3389: dest[1] += source[1]+((dest[2]>>24) & 1);
3390: dest[0] += source[0]+((dest[1]>>24) & 1);
1.1 root 3391:
3392: /* overflow if we go below -256.0 or above +256.0 */
1.1.1.2 root 3393: overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff));
1.1 root 3394:
1.1.1.2 root 3395: /* set carry from the virtual 56th bit */
3396: carry = (dest[0]>>8) & 1;
1.1 root 3397:
3398: dest[2] &= BITMASK(24);
3399: dest[1] &= BITMASK(24);
3400: dest[0] &= BITMASK(8);
3401:
3402: return (overflow<<DSP_SR_L)|(overflow<<DSP_SR_V)|(carry<<DSP_SR_C);
3403: }
3404:
1.1.1.2 root 3405: static Uint16 dsp_sub56(Uint32 *source, Uint32 *dest)
1.1 root 3406: {
1.1.1.2 root 3407: Uint16 overflow, carry;
1.1 root 3408:
3409: /* Substract source from dest: D = D-S */
1.1.1.2 root 3410: dest[2] -= source[2];
3411: dest[1] -= source[1]+((dest[2]>>24) & 1);
3412: dest[0] -= source[0]+((dest[1]>>24) & 1);
1.1 root 3413:
3414: /* overflow if we go below -256.0 or above +256.0 */
1.1.1.2 root 3415: overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff));
1.1 root 3416:
1.1.1.2 root 3417: /* set carry from the virtual 56th bit */
3418: carry = (dest[0]>>8) & 1;
1.1 root 3419:
3420: dest[2] &= BITMASK(24);
3421: dest[1] &= BITMASK(24);
3422: dest[0] &= BITMASK(8);
3423:
3424: return (overflow<<DSP_SR_L)|(overflow<<DSP_SR_V)|(carry<<DSP_SR_C);
3425: }
3426:
1.1.1.2 root 3427: static void dsp_mul56(Uint32 source1, Uint32 source2, Uint32 *dest)
1.1 root 3428: {
1.1.1.2 root 3429: Uint32 negresult; /* Negate the result ? */
3430: Uint32 part[4], zerodest[3], value;
1.1 root 3431:
3432: /* Multiply: D = S1*S2 */
3433: negresult = 0;
3434: if (source1 & (1<<23)) {
3435: negresult ^= 1;
3436: source1 = (1<<24) - (source1 & BITMASK(24));
3437: }
3438: if (source2 & (1<<23)) {
3439: negresult ^= 1;
3440: source2 = (1<<24) - (source2 & BITMASK(24));
3441: }
3442:
3443: /* bits 0-11 * bits 0-11 */
3444: part[0]=(source1 & BITMASK(12))*(source2 & BITMASK(12));
3445: /* bits 12-23 * bits 0-11 */
3446: part[1]=((source1>>12) & BITMASK(12))*(source2 & BITMASK(12));
3447: /* bits 0-11 * bits 12-23 */
3448: part[2]=(source1 & BITMASK(12))*((source2>>12) & BITMASK(12));
3449: /* bits 12-23 * bits 12-23 */
3450: part[3]=((source1>>12) & BITMASK(12))*((source2>>12) & BITMASK(12));
3451:
3452: /* Calc dest 2 */
3453: dest[2] = part[0];
3454: dest[2] += (part[1] & BITMASK(12)) << 12;
3455: dest[2] += (part[2] & BITMASK(12)) << 12;
3456:
3457: /* Calc dest 1 */
3458: dest[1] = (part[1]>>12) & BITMASK(12);
3459: dest[1] += (part[2]>>12) & BITMASK(12);
3460: dest[1] += part[3];
3461:
3462: /* Calc dest 0 */
3463: dest[0] = 0;
3464:
3465: /* Add carries */
3466: value = (dest[2]>>24) & BITMASK(8);
3467: if (value) {
3468: dest[1] += value;
3469: dest[2] &= BITMASK(24);
3470: }
3471: value = (dest[1]>>24) & BITMASK(8);
3472: if (value) {
3473: dest[0] += value;
3474: dest[1] &= BITMASK(24);
3475: }
3476:
3477: /* Get rid of extra sign bit */
3478: dsp_asl56(dest);
3479:
3480: if (negresult) {
3481: zerodest[0] = zerodest[1] = zerodest[2] = 0;
3482:
3483: dsp_sub56(dest, zerodest);
3484:
3485: dest[0] = zerodest[0];
3486: dest[1] = zerodest[1];
3487: dest[2] = zerodest[2];
3488: }
3489: }
3490:
1.1.1.2 root 3491: static void dsp_rnd56(Uint32 *dest)
1.1 root 3492: {
1.1.1.2 root 3493: Uint32 value;
1.1 root 3494:
3495: /* Round D */
3496:
3497: value = dest[2] & BITMASK(24);
3498: if (value==0x800000) {
3499: if (dest[1] & 1) {
3500: ++dest[1];
3501: if ((dest[1]>>24) & BITMASK(8)) {
3502: ++dest[0];
3503: dest[0] &= BITMASK(8);
3504: dest[1] &= BITMASK(24);
3505: }
3506: }
3507: } else if (value>0x800000) {
3508: ++dest[1];
3509: if ((dest[1]>>24) & BITMASK(8)) {
3510: ++dest[0];
3511: dest[0] &= BITMASK(8);
3512: dest[1] &= BITMASK(24);
3513: }
3514: }
3515:
3516: dest[2]=0;
3517: }
3518:
3519: /**********************************
3520: * Parallel moves instructions
3521: **********************************/
3522:
3523: static void dsp_abs(void)
3524: {
1.1.1.2 root 3525: Uint32 numreg, dest[3], overflowed;
1.1 root 3526:
3527: numreg = (cur_inst>>3) & 1;
3528:
1.1.1.2 root 3529: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
3530: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
3531: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 3532:
3533: overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80));
3534:
3535: dsp_abs56(dest);
3536:
1.1.1.2 root 3537: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
3538: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
3539: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
3540:
3541: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
3542: dsp_core->registers[DSP_REG_SR] |= (overflowed<<DSP_SR_L)|(overflowed<<DSP_SR_V);
3543:
3544: dsp_ccr_extension(&dest[0], &dest[1]);
3545: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3546: dsp_ccr_negative(&dest[0]);
1.1 root 3547: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3548: }
3549:
3550: static void dsp_adc(void)
3551: {
1.1.1.2 root 3552: Uint32 srcreg, destreg, source[3], dest[3], curcarry;
3553: Uint16 newsr;
1.1 root 3554:
1.1.1.2 root 3555: curcarry = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1;
1.1 root 3556:
3557: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 3558: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
3559: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
3560: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 3561:
3562: srcreg = (cur_inst>>4) & 1;
1.1.1.2 root 3563: if (srcreg == 0) { /* X */
3564: source[1] = dsp_core->registers[DSP_REG_X1];
3565: source[2] = dsp_core->registers[DSP_REG_X0];
3566: source[0] = 0;
3567: if (source[1] & (1<<23)) {
3568: source[0] = 0x0000ff;
3569: }
3570: }
3571: else { /* Y */
3572: source[1] = dsp_core->registers[DSP_REG_Y1];
3573: source[2] = dsp_core->registers[DSP_REG_Y0];
3574: source[0] = 0;
3575: if (source[1] & (1<<23)) {
3576: source[0] = 0x0000ff;
3577: }
1.1 root 3578: }
3579:
3580: newsr = dsp_add56(source, dest);
3581:
3582: if (curcarry) {
3583: source[0]=0;
3584: source[1]=0;
3585: source[2]=1;
3586: newsr |= dsp_add56(source, dest);
3587: }
3588:
1.1.1.2 root 3589: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
3590: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
3591: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
3592:
3593: dsp_ccr_extension(&dest[0], &dest[1]);
3594: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3595: dsp_ccr_negative(&dest[0]);
1.1 root 3596: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3597:
1.1.1.2 root 3598: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3599: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3600: }
3601:
3602: static void dsp_add(void)
3603: {
1.1.1.2 root 3604: Uint32 srcreg, destreg, source[3], dest[3];
3605: Uint16 newsr;
1.1 root 3606:
3607: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 3608: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
3609: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
3610: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 3611:
3612: srcreg = (cur_inst>>4) & BITMASK(3);
3613: switch(srcreg) {
3614: case 1: /* A or B */
3615: srcreg = destreg ^ 1;
1.1.1.2 root 3616: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
3617: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
3618: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 3619: break;
3620: case 2: /* X */
1.1.1.2 root 3621: source[1] = dsp_core->registers[DSP_REG_X1];
3622: source[2] = dsp_core->registers[DSP_REG_X0];
1.1 root 3623: source[0] = 0;
3624: if (source[1] & (1<<23)) {
3625: source[0] = 0x0000ff;
3626: }
3627: break;
3628: case 3: /* Y */
1.1.1.2 root 3629: source[1] = dsp_core->registers[DSP_REG_Y1];
3630: source[2] = dsp_core->registers[DSP_REG_Y0];
1.1 root 3631: source[0] = 0;
3632: if (source[1] & (1<<23)) {
3633: source[0] = 0x0000ff;
3634: }
3635: break;
3636: case 4: /* X0 */
3637: source[2] = 0;
1.1.1.2 root 3638: source[1] = dsp_core->registers[DSP_REG_X0];
1.1 root 3639: source[0] = 0;
3640: if (source[1] & (1<<23)) {
3641: source[0] = 0x0000ff;
3642: }
3643: break;
3644: case 5: /* Y0 */
3645: source[2] = 0;
1.1.1.2 root 3646: source[1] = dsp_core->registers[DSP_REG_Y0];
1.1 root 3647: source[0] = 0;
3648: if (source[1] & (1<<23)) {
3649: source[0] = 0x0000ff;
3650: }
3651: break;
3652: case 6: /* X1 */
3653: source[2] = 0;
1.1.1.2 root 3654: source[1] = dsp_core->registers[DSP_REG_X1];
1.1 root 3655: source[0] = 0;
3656: if (source[1] & (1<<23)) {
3657: source[0] = 0x0000ff;
3658: }
3659: break;
3660: case 7: /* Y1 */
3661: source[2] = 0;
1.1.1.2 root 3662: source[1] = dsp_core->registers[DSP_REG_Y1];
1.1 root 3663: source[0] = 0;
3664: if (source[1] & (1<<23)) {
3665: source[0] = 0x0000ff;
3666: }
3667: break;
1.1.1.2 root 3668: default:
3669: fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__);
3670: return;
1.1 root 3671: }
3672:
3673: newsr = dsp_add56(source, dest);
3674:
1.1.1.2 root 3675: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
3676: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
3677: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
3678:
3679: dsp_ccr_extension(&dest[0], &dest[1]);
3680: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3681: dsp_ccr_negative(&dest[0]);
1.1 root 3682: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3683:
1.1.1.2 root 3684: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3685: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3686: }
3687:
3688: static void dsp_addl(void)
3689: {
1.1.1.2 root 3690: Uint32 numreg, source[3], dest[3];
3691: Uint16 newsr;
1.1 root 3692:
3693: numreg = (cur_inst>>3) & 1;
3694:
1.1.1.2 root 3695: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
3696: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
3697: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 3698: newsr = dsp_asl56(dest);
3699:
1.1.1.2 root 3700: source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)];
3701: source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)];
3702: source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)];
1.1 root 3703: newsr |= dsp_add56(source, dest);
3704:
1.1.1.2 root 3705: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
3706: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
3707: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
3708:
3709: dsp_ccr_extension(&dest[0], &dest[1]);
3710: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3711: dsp_ccr_negative(&dest[0]);
1.1 root 3712: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3713:
1.1.1.2 root 3714: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3715: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3716: }
3717:
3718: static void dsp_addr(void)
3719: {
1.1.1.2 root 3720: Uint32 numreg, source[3], dest[3];
3721: Uint16 newsr;
1.1 root 3722:
3723: numreg = (cur_inst>>3) & 1;
3724:
1.1.1.2 root 3725: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
3726: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
3727: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 3728: newsr = dsp_asr56(dest);
3729:
1.1.1.2 root 3730: source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)];
3731: source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)];
3732: source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)];
1.1 root 3733: newsr |= dsp_add56(source, dest);
3734:
1.1.1.2 root 3735: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
3736: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
3737: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
3738:
3739: dsp_ccr_extension(&dest[0], &dest[1]);
3740: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3741: dsp_ccr_negative(&dest[0]);
1.1 root 3742: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3743:
1.1.1.2 root 3744: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3745: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3746: }
3747:
3748: static void dsp_and(void)
3749: {
1.1.1.2 root 3750: Uint32 srcreg, dstreg;
1.1 root 3751:
1.1.1.2 root 3752: switch((cur_inst>>4) & BITMASK(2)) {
3753: case 1:
3754: srcreg=DSP_REG_Y0;
3755: break;
3756: case 2:
3757: srcreg=DSP_REG_X1;
3758: break;
3759: case 3:
3760: srcreg=DSP_REG_Y1;
3761: break;
3762: case 0:
3763: default:
3764: srcreg=DSP_REG_X0;
3765: }
1.1 root 3766: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
3767:
1.1.1.2 root 3768: dsp_core->registers[dstreg] &= dsp_core->registers[srcreg];
3769: dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */
1.1 root 3770:
1.1.1.2 root 3771: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
3772: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
3773: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 3774: }
3775:
3776: static void dsp_asl(void)
3777: {
1.1.1.2 root 3778: Uint32 numreg, dest[3];
3779: Uint16 newsr;
1.1 root 3780:
3781: numreg = (cur_inst>>3) & 1;
3782:
1.1.1.2 root 3783: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
3784: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
3785: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 3786:
3787: newsr = dsp_asl56(dest);
3788:
1.1.1.2 root 3789: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
3790: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
3791: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
3792:
3793: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_V));
3794: dsp_core->registers[DSP_REG_SR] |= newsr;
3795:
3796: dsp_ccr_extension(&dest[0], &dest[1]);
3797: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3798: dsp_ccr_negative(&dest[0]);
1.1 root 3799: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3800: }
3801:
3802: static void dsp_asr(void)
3803: {
1.1.1.2 root 3804: Uint32 numreg, newsr, dest[3];
1.1 root 3805:
3806: numreg = (cur_inst>>3) & 1;
3807:
1.1.1.2 root 3808: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
3809: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
3810: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 3811:
3812: newsr = dsp_asr56(dest);
3813:
1.1.1.2 root 3814: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
3815: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
3816: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
3817:
3818: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_V));
3819: dsp_core->registers[DSP_REG_SR] |= newsr;
3820:
3821: dsp_ccr_extension(&dest[0], &dest[1]);
3822: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3823: dsp_ccr_negative(&dest[0]);
1.1 root 3824: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3825: }
3826:
3827: static void dsp_clr(void)
3828: {
1.1.1.2 root 3829: Uint32 numreg;
1.1 root 3830:
3831: numreg = (cur_inst>>3) & 1;
3832:
1.1.1.2 root 3833: dsp_core->registers[DSP_REG_A2+numreg]=0;
3834: dsp_core->registers[DSP_REG_A1+numreg]=0;
3835: dsp_core->registers[DSP_REG_A0+numreg]=0;
1.1 root 3836:
1.1.1.2 root 3837: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_E)|(1<<DSP_SR_N)|(1<<DSP_SR_V));
3838: dsp_core->registers[DSP_REG_SR] |= (1<<DSP_SR_U)|(1<<DSP_SR_Z);
1.1 root 3839: }
3840:
3841: static void dsp_cmp(void)
3842: {
1.1.1.2 root 3843: Uint32 srcreg, destreg, source[3], dest[3];
3844: Uint16 newsr;
1.1 root 3845:
3846: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 3847: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
3848: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
3849: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 3850:
3851: srcreg = (cur_inst>>4) & BITMASK(3);
3852: switch(srcreg) {
3853: case 0: /* A or B */
3854: srcreg = destreg ^ 1;
1.1.1.2 root 3855: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
3856: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
3857: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 3858: break;
3859: case 4: /* X0 */
3860: source[2] = 0;
1.1.1.2 root 3861: source[1] = dsp_core->registers[DSP_REG_X0];
1.1 root 3862: source[0] = 0;
3863: if (source[1] & (1<<23)) {
3864: source[0] = 0x0000ff;
3865: }
3866: break;
3867: case 5: /* Y0 */
3868: source[2] = 0;
1.1.1.2 root 3869: source[1] = dsp_core->registers[DSP_REG_Y0];
1.1 root 3870: source[0] = 0;
3871: if (source[1] & (1<<23)) {
3872: source[0] = 0x0000ff;
3873: }
3874: break;
3875: case 6: /* X1 */
3876: source[2] = 0;
1.1.1.2 root 3877: source[1] = dsp_core->registers[DSP_REG_X1];
1.1 root 3878: source[0] = 0;
3879: if (source[1] & (1<<23)) {
3880: source[0] = 0x0000ff;
3881: }
3882: break;
3883: case 7: /* Y1 */
3884: source[2] = 0;
1.1.1.2 root 3885: source[1] = dsp_core->registers[DSP_REG_Y1];
1.1 root 3886: source[0] = 0;
3887: if (source[1] & (1<<23)) {
3888: source[0] = 0x0000ff;
3889: }
3890: break;
1.1.1.2 root 3891: default:
3892: fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__);
3893: return;
1.1 root 3894: }
3895:
3896: newsr = dsp_sub56(source, dest);
3897:
1.1.1.2 root 3898: dsp_ccr_extension(&dest[0], &dest[1]);
3899: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3900: dsp_ccr_negative(&dest[0]);
1.1 root 3901: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3902:
1.1.1.2 root 3903: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3904: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3905: }
3906:
3907: static void dsp_cmpm(void)
3908: {
1.1.1.2 root 3909: Uint32 srcreg, destreg, source[3], dest[3];
3910: Uint16 newsr;
1.1 root 3911:
3912: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 3913: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
3914: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
3915: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 3916: dsp_abs56(dest);
3917:
3918: srcreg = (cur_inst>>4) & BITMASK(3);
3919: switch(srcreg) {
3920: case 0: /* A or B */
3921: srcreg = destreg ^ 1;
1.1.1.2 root 3922: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
3923: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
3924: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 3925: break;
3926: case 4: /* X0 */
3927: source[2] = 0;
1.1.1.2 root 3928: source[1] = dsp_core->registers[DSP_REG_X0];
1.1 root 3929: source[0] = 0;
3930: if (source[1] & (1<<23)) {
3931: source[0] = 0x0000ff;
3932: }
3933: break;
3934: case 5: /* Y0 */
3935: source[2] = 0;
1.1.1.2 root 3936: source[1] = dsp_core->registers[DSP_REG_Y0];
1.1 root 3937: source[0] = 0;
3938: if (source[1] & (1<<23)) {
3939: source[0] = 0x0000ff;
3940: }
3941: break;
3942: case 6: /* X1 */
3943: source[2] = 0;
1.1.1.2 root 3944: source[1] = dsp_core->registers[DSP_REG_X1];
1.1 root 3945: source[0] = 0;
3946: if (source[1] & (1<<23)) {
3947: source[0] = 0x0000ff;
3948: }
3949: break;
3950: case 7: /* Y1 */
3951: source[2] = 0;
1.1.1.2 root 3952: source[1] = dsp_core->registers[DSP_REG_Y1];
1.1 root 3953: source[0] = 0;
3954: if (source[1] & (1<<23)) {
3955: source[0] = 0x0000ff;
3956: }
3957: break;
1.1.1.2 root 3958: default:
3959: fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__);
3960: return;
1.1 root 3961: }
3962:
3963: dsp_abs56(source);
3964: newsr = dsp_sub56(source, dest);
3965:
1.1.1.2 root 3966: dsp_ccr_extension(&dest[0], &dest[1]);
3967: dsp_ccr_unnormalized(&dest[0], &dest[1]);
3968: dsp_ccr_negative(&dest[0]);
1.1 root 3969: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
3970:
1.1.1.2 root 3971: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
3972: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 3973: }
3974:
3975: static void dsp_eor(void)
3976: {
1.1.1.2 root 3977: Uint32 srcreg, dstreg;
1.1 root 3978:
1.1.1.2 root 3979: switch((cur_inst>>4) & BITMASK(2)) {
3980: case 1:
3981: srcreg=DSP_REG_Y0;
3982: break;
3983: case 2:
3984: srcreg=DSP_REG_X1;
3985: break;
3986: case 3:
3987: srcreg=DSP_REG_Y1;
3988: break;
3989: case 0:
3990: default:
3991: srcreg=DSP_REG_X0;
3992: }
1.1 root 3993: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
3994:
1.1.1.2 root 3995: dsp_core->registers[dstreg] ^= dsp_core->registers[srcreg];
3996: dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */
1.1 root 3997:
1.1.1.2 root 3998: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
3999: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
4000: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 4001: }
4002:
4003: static void dsp_lsl(void)
4004: {
1.1.1.2 root 4005: Uint32 numreg, newcarry;
1.1 root 4006:
1.1.1.2 root 4007: numreg = DSP_REG_A1+((cur_inst>>3) & 1);
1.1 root 4008:
1.1.1.2 root 4009: newcarry = (dsp_core->registers[numreg]>>23) & 1;
1.1 root 4010:
1.1.1.2 root 4011: dsp_core->registers[numreg] <<= 1;
4012: dsp_core->registers[numreg] &= BITMASK(24);
1.1 root 4013:
1.1.1.2 root 4014: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4015: dsp_core->registers[DSP_REG_SR] |= newcarry;
4016: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[numreg]>>23) & 1)<<DSP_SR_N;
4017: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<<DSP_SR_Z;
1.1 root 4018: }
4019:
4020: static void dsp_lsr(void)
4021: {
1.1.1.2 root 4022: Uint32 numreg, newcarry;
1.1 root 4023:
1.1.1.2 root 4024: numreg = DSP_REG_A1+((cur_inst>>3) & 1);
1.1 root 4025:
1.1.1.2 root 4026: newcarry = dsp_core->registers[numreg] & 1;
1.1 root 4027:
1.1.1.2 root 4028: dsp_core->registers[numreg] >>= 1;
4029: /*dsp_core->registers[numreg] &= BITMASK(24);*/
1.1 root 4030:
1.1.1.2 root 4031: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4032: dsp_core->registers[DSP_REG_SR] |= newcarry;
4033: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<<DSP_SR_Z;
1.1 root 4034: }
4035:
4036: static void dsp_mac(void)
4037: {
1.1.1.2 root 4038: Uint32 srcreg1, srcreg2, destreg, value, source[3], dest[3];
4039: Uint16 newsr;
1.1 root 4040:
4041: value = (cur_inst>>4) & BITMASK(3);
4042: srcreg1 = registers_mpy[value][0];
4043: srcreg2 = registers_mpy[value][1];
4044:
1.1.1.2 root 4045: dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source);
1.1 root 4046:
4047: if (cur_inst & (1<<2)) {
4048: dest[0] = dest[1] = dest[2] = 0;
4049:
4050: dsp_sub56(source, dest);
4051:
4052: source[0] = dest[0];
4053: source[1] = dest[1];
4054: source[2] = dest[2];
4055: }
4056:
4057: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 4058: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
4059: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
4060: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 4061: newsr = dsp_add56(source, dest);
4062:
1.1.1.2 root 4063: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4064: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4065: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
4066:
4067: dsp_ccr_extension(&dest[0], &dest[1]);
4068: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4069: dsp_ccr_negative(&dest[0]);
1.1 root 4070: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4071:
1.1.1.2 root 4072: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
4073: dsp_core->registers[DSP_REG_SR] |= newsr & 0xfe;
1.1 root 4074: }
4075:
4076: static void dsp_macr(void)
4077: {
1.1.1.2 root 4078: Uint32 srcreg1, srcreg2, destreg, value, source[3], dest[3];
4079: Uint16 newsr;
1.1 root 4080:
4081: value = (cur_inst>>4) & BITMASK(3);
4082: srcreg1 = registers_mpy[value][0];
4083: srcreg2 = registers_mpy[value][1];
4084:
1.1.1.2 root 4085: dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source);
1.1 root 4086:
4087: if (cur_inst & (1<<2)) {
4088: dest[0] = dest[1] = dest[2] = 0;
4089:
4090: dsp_sub56(source, dest);
4091:
4092: source[0] = dest[0];
4093: source[1] = dest[1];
4094: source[2] = dest[2];
4095: }
4096:
4097: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 4098: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
4099: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
4100: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 4101: newsr = dsp_add56(source, dest);
4102:
4103: dsp_rnd56(dest);
4104:
1.1.1.2 root 4105: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4106: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4107: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
4108:
4109: dsp_ccr_extension(&dest[0], &dest[1]);
4110: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4111: dsp_ccr_negative(&dest[0]);
1.1 root 4112: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4113:
1.1.1.2 root 4114: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
4115: dsp_core->registers[DSP_REG_SR] |= newsr & 0xfe;
1.1 root 4116: }
4117:
4118: static void dsp_move(void)
4119: {
4120: /* move instruction inside alu opcodes
4121: taken care of by parallel move dispatcher */
4122: }
4123:
4124: static void dsp_move_pm(void)
4125: {
4126: /* move instruction outside alu opcodes */
4127: dsp_parmove_read();
4128: dsp_parmove_write();
4129: }
4130:
4131: static void dsp_mpy(void)
4132: {
1.1.1.2 root 4133: Uint32 srcreg1, srcreg2, destreg, value, dest[3], source[3];
1.1 root 4134:
4135: value = (cur_inst>>4) & BITMASK(3);
4136: srcreg1 = registers_mpy[value][0];
4137: srcreg2 = registers_mpy[value][1];
4138:
1.1.1.2 root 4139: dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source);
1.1 root 4140:
4141: destreg = (cur_inst>>3) & 1;
4142: if (cur_inst & (1<<2)) {
4143: dest[0] = dest[1] = dest[2] = 0;
4144:
4145: dsp_sub56(source, dest);
4146:
1.1.1.2 root 4147: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4148: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4149: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
1.1 root 4150: } else {
1.1.1.2 root 4151: dsp_core->registers[DSP_REG_A2+destreg] = source[0];
4152: dsp_core->registers[DSP_REG_A1+destreg] = source[1];
4153: dsp_core->registers[DSP_REG_A0+destreg] = source[2];
1.1 root 4154: }
4155:
1.1.1.2 root 4156: dsp_ccr_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]);
4157: dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]);
4158: dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]);
4159: dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]);
1.1 root 4160:
1.1.1.2 root 4161: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
1.1 root 4162: }
4163:
4164: static void dsp_mpyr(void)
4165: {
1.1.1.2 root 4166: Uint32 srcreg1, srcreg2, destreg, value, dest[3], source[3];
1.1 root 4167:
4168: value = (cur_inst>>4) & BITMASK(3);
4169: srcreg1 = registers_mpy[value][0];
4170: srcreg2 = registers_mpy[value][1];
4171:
1.1.1.2 root 4172: dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source);
1.1 root 4173:
4174: destreg = (cur_inst>>3) & 1;
4175: if (cur_inst & (1<<2)) {
4176: dest[0] = dest[1] = dest[2] = 0;
4177:
4178: dsp_sub56(source, dest);
4179: } else {
4180: dest[0] = source[0];
4181: dest[1] = source[1];
4182: dest[2] = source[2];
4183: }
4184:
4185: dsp_rnd56(dest);
4186:
1.1.1.2 root 4187: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4188: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4189: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
4190:
4191: dsp_ccr_extension(&dest[0], &dest[1]);
4192: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4193: dsp_ccr_negative(&dest[0]);
1.1 root 4194: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4195:
1.1.1.2 root 4196: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
1.1 root 4197: }
4198:
4199: static void dsp_neg(void)
4200: {
1.1.1.2 root 4201: Uint32 srcreg, source[3], dest[3], overflowed;
1.1 root 4202:
4203: srcreg = (cur_inst>>3) & 1;
1.1.1.2 root 4204: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
4205: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
4206: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 4207:
4208: overflowed = ((source[2]==0) && (source[1]==0) && (source[0]==0x80));
4209:
4210: dest[0] = dest[1] = dest[2] = 0;
4211:
4212: dsp_sub56(source, dest);
4213:
1.1.1.2 root 4214: dsp_core->registers[DSP_REG_A2+srcreg] = dest[0];
4215: dsp_core->registers[DSP_REG_A1+srcreg] = dest[1];
4216: dsp_core->registers[DSP_REG_A0+srcreg] = dest[2];
4217:
4218: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
4219: dsp_core->registers[DSP_REG_SR] |= (overflowed<<DSP_SR_L)|(overflowed<<DSP_SR_V);
4220:
4221: dsp_ccr_extension(&dest[0], &dest[1]);
4222: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4223: dsp_ccr_negative(&dest[0]);
1.1 root 4224: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4225: }
4226:
4227: static void dsp_nop(void)
4228: {
4229: }
4230:
4231: static void dsp_not(void)
4232: {
1.1.1.2 root 4233: Uint32 dstreg;
1.1 root 4234:
4235: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
4236:
1.1.1.2 root 4237: dsp_core->registers[dstreg] = ~dsp_core->registers[dstreg];
4238: dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */
1.1 root 4239:
1.1.1.2 root 4240: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4241: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
4242: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 4243: }
4244:
4245: static void dsp_or(void)
4246: {
1.1.1.2 root 4247: Uint32 srcreg, dstreg;
1.1 root 4248:
1.1.1.2 root 4249: switch((cur_inst>>4) & BITMASK(2)) {
4250: case 1:
4251: srcreg=DSP_REG_Y0;
4252: break;
4253: case 2:
4254: srcreg=DSP_REG_X1;
4255: break;
4256: case 3:
4257: srcreg=DSP_REG_Y1;
4258: break;
4259: case 0:
4260: default:
4261: srcreg=DSP_REG_X0;
4262: }
1.1 root 4263: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
4264:
1.1.1.2 root 4265: dsp_core->registers[dstreg] |= dsp_core->registers[srcreg];
4266: dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */
1.1 root 4267:
1.1.1.2 root 4268: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4269: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
4270: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 4271: }
4272:
4273: static void dsp_rnd(void)
4274: {
1.1.1.2 root 4275: Uint32 numreg, dest[3];
1.1 root 4276:
4277: numreg = (cur_inst>>3) & 1;
4278:
1.1.1.2 root 4279: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
4280: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
4281: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 4282:
4283: dsp_rnd56(dest);
4284:
1.1.1.2 root 4285: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
4286: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
4287: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
4288:
4289: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
4290:
4291: dsp_ccr_extension(&dest[0], &dest[1]);
4292: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4293: dsp_ccr_negative(&dest[0]);
1.1 root 4294: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4295: }
4296:
4297: static void dsp_rol(void)
4298: {
1.1.1.2 root 4299: Uint32 dstreg, newcarry;
1.1 root 4300:
4301: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
4302:
1.1.1.2 root 4303: newcarry = (dsp_core->registers[dstreg]>>23) & 1;
1.1 root 4304:
1.1.1.2 root 4305: dsp_core->registers[dstreg] <<= 1;
4306: dsp_core->registers[dstreg] |= newcarry;
4307: dsp_core->registers[dstreg] &= BITMASK(24);
4308:
4309: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4310: dsp_core->registers[DSP_REG_SR] |= newcarry;
4311: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
4312: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 4313: }
4314:
4315: static void dsp_ror(void)
4316: {
1.1.1.2 root 4317: Uint32 dstreg, newcarry;
1.1 root 4318:
4319: dstreg = DSP_REG_A1+((cur_inst>>3) & 1);
4320:
1.1.1.2 root 4321: newcarry = dsp_core->registers[dstreg] & 1;
1.1 root 4322:
1.1.1.2 root 4323: dsp_core->registers[dstreg] >>= 1;
4324: dsp_core->registers[dstreg] |= newcarry<<23;
4325: dsp_core->registers[dstreg] &= BITMASK(24);
4326:
4327: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_C)|(1<<DSP_SR_N)|(1<<DSP_SR_Z)|(1<<DSP_SR_V));
4328: dsp_core->registers[DSP_REG_SR] |= newcarry;
4329: dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<<DSP_SR_N;
4330: dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<<DSP_SR_Z;
1.1 root 4331: }
4332:
4333: static void dsp_sbc(void)
4334: {
1.1.1.2 root 4335: Uint32 srcreg, destreg, source[3], dest[3], curcarry;
4336: Uint16 newsr;
1.1 root 4337:
1.1.1.2 root 4338: curcarry = (dsp_core->registers[DSP_REG_SR]>>(DSP_SR_C)) & 1;
1.1 root 4339:
4340: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 4341: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
4342: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
4343: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 4344:
4345: srcreg = (cur_inst>>4) & 1;
1.1.1.2 root 4346: if (srcreg == 0) { /* X */
4347: source[1] = dsp_core->registers[DSP_REG_X1];
4348: source[2] = dsp_core->registers[DSP_REG_X0];
4349: source[0] = 0;
4350: if (source[1] & (1<<23)) {
4351: source[0] = 0x0000ff;
4352: }
4353: }
4354: else { /* Y */
4355: source[1] = dsp_core->registers[DSP_REG_Y1];
4356: source[2] = dsp_core->registers[DSP_REG_Y0];
4357: source[0] = 0;
4358: if (source[1] & (1<<23)) {
4359: source[0] = 0x0000ff;
4360: }
1.1 root 4361: }
4362:
4363: newsr = dsp_sub56(source, dest);
4364:
4365: if (curcarry) {
4366: source[0]=0;
4367: source[1]=0;
4368: source[2]=1;
4369: newsr |= dsp_sub56(source, dest);
4370: }
4371:
1.1.1.2 root 4372: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4373: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4374: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
4375:
4376: dsp_ccr_extension(&dest[0], &dest[1]);
4377: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4378: dsp_ccr_negative(&dest[0]);
1.1 root 4379: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4380:
1.1.1.2 root 4381: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
4382: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 4383: }
4384:
4385: static void dsp_sub(void)
4386: {
1.1.1.2 root 4387: Uint32 srcreg, destreg, source[3], dest[3];
4388: Uint16 newsr;
1.1 root 4389:
4390: destreg = (cur_inst>>3) & 1;
1.1.1.2 root 4391: dest[0] = dsp_core->registers[DSP_REG_A2+destreg];
4392: dest[1] = dsp_core->registers[DSP_REG_A1+destreg];
4393: dest[2] = dsp_core->registers[DSP_REG_A0+destreg];
1.1 root 4394:
4395: srcreg = (cur_inst>>4) & BITMASK(3);
4396: switch(srcreg) {
4397: case 1: /* A or B */
4398: srcreg = destreg ^ 1;
1.1.1.2 root 4399: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
4400: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
4401: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 4402: break;
4403: case 2: /* X */
1.1.1.2 root 4404: source[1] = dsp_core->registers[DSP_REG_X1];
4405: source[2] = dsp_core->registers[DSP_REG_X0];
1.1 root 4406: source[0] = 0;
4407: if (source[1] & (1<<23)) {
4408: source[0] = 0x0000ff;
4409: }
4410: break;
4411: case 3: /* Y */
1.1.1.2 root 4412: source[1] = dsp_core->registers[DSP_REG_Y1];
4413: source[2] = dsp_core->registers[DSP_REG_Y0];
1.1 root 4414: source[0] = 0;
4415: if (source[1] & (1<<23)) {
4416: source[0] = 0x0000ff;
4417: }
4418: break;
4419: case 4: /* X0 */
4420: source[2] = 0;
1.1.1.2 root 4421: source[1] = dsp_core->registers[DSP_REG_X0];
1.1 root 4422: source[0] = 0;
4423: if (source[1] & (1<<23)) {
4424: source[0] = 0x0000ff;
4425: }
4426: break;
4427: case 5: /* Y0 */
4428: source[2] = 0;
1.1.1.2 root 4429: source[1] = dsp_core->registers[DSP_REG_Y0];
1.1 root 4430: source[0] = 0;
4431: if (source[1] & (1<<23)) {
4432: source[0] = 0x0000ff;
4433: }
4434: break;
4435: case 6: /* X1 */
4436: source[2] = 0;
1.1.1.2 root 4437: source[1] = dsp_core->registers[DSP_REG_X1];
1.1 root 4438: source[0] = 0;
4439: if (source[1] & (1<<23)) {
4440: source[0] = 0x0000ff;
4441: }
4442: break;
4443: case 7: /* Y1 */
4444: source[2] = 0;
1.1.1.2 root 4445: source[1] = dsp_core->registers[DSP_REG_Y1];
1.1 root 4446: source[0] = 0;
4447: if (source[1] & (1<<23)) {
4448: source[0] = 0x0000ff;
4449: }
4450: break;
1.1.1.2 root 4451: default:
4452: fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__);
4453: return;
1.1 root 4454: }
4455:
4456: newsr = dsp_sub56(source, dest);
4457:
1.1.1.2 root 4458: dsp_core->registers[DSP_REG_A2+destreg] = dest[0];
4459: dsp_core->registers[DSP_REG_A1+destreg] = dest[1];
4460: dsp_core->registers[DSP_REG_A0+destreg] = dest[2];
4461:
4462: dsp_ccr_extension(&dest[0], &dest[1]);
4463: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4464: dsp_ccr_negative(&dest[0]);
1.1 root 4465: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4466:
1.1.1.2 root 4467: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
4468: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 4469: }
4470:
4471: static void dsp_subl(void)
4472: {
1.1.1.2 root 4473: Uint32 numreg, source[3], dest[3];
4474: Uint16 newsr;
1.1 root 4475:
4476: numreg = (cur_inst>>3) & 1;
4477:
1.1.1.2 root 4478: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
4479: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
4480: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 4481: newsr = dsp_asl56(dest);
4482:
1.1.1.2 root 4483: source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)];
4484: source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)];
4485: source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)];
1.1 root 4486: newsr |= dsp_sub56(source, dest);
4487:
1.1.1.2 root 4488: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
4489: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
4490: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
4491:
4492: dsp_ccr_extension(&dest[0], &dest[1]);
4493: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4494: dsp_ccr_negative(&dest[0]);
1.1 root 4495: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4496:
1.1.1.2 root 4497: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
4498: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 4499: }
4500:
4501: static void dsp_subr(void)
4502: {
1.1.1.2 root 4503: Uint32 numreg, source[3], dest[3];
4504: Uint16 newsr;
1.1 root 4505:
4506: numreg = (cur_inst>>3) & 1;
4507:
1.1.1.2 root 4508: dest[0] = dsp_core->registers[DSP_REG_A2+numreg];
4509: dest[1] = dsp_core->registers[DSP_REG_A1+numreg];
4510: dest[2] = dsp_core->registers[DSP_REG_A0+numreg];
1.1 root 4511: newsr = dsp_asr56(dest);
4512:
1.1.1.2 root 4513: source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)];
4514: source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)];
4515: source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)];
1.1 root 4516: newsr |= dsp_sub56(source, dest);
4517:
1.1.1.2 root 4518: dsp_core->registers[DSP_REG_A2+numreg] = dest[0];
4519: dsp_core->registers[DSP_REG_A1+numreg] = dest[1];
4520: dsp_core->registers[DSP_REG_A0+numreg] = dest[2];
4521:
4522: dsp_ccr_extension(&dest[0], &dest[1]);
4523: dsp_ccr_unnormalized(&dest[0], &dest[1]);
4524: dsp_ccr_negative(&dest[0]);
1.1 root 4525: dsp_ccr_zero(&dest[0], &dest[1], &dest[2]);
4526:
1.1.1.2 root 4527: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
4528: dsp_core->registers[DSP_REG_SR] |= newsr;
1.1 root 4529: }
4530:
4531: static void dsp_tfr(void)
4532: {
1.1.1.2 root 4533: Uint32 srcreg, destreg, source[3];
1.1 root 4534:
4535: destreg = (cur_inst>>3) & 1;
4536:
4537: srcreg = (cur_inst>>4) & BITMASK(3);
4538: switch(srcreg) {
4539: case 0: /* A or B */
4540: srcreg = destreg ^ 1;
1.1.1.2 root 4541: source[0] = dsp_core->registers[DSP_REG_A2+srcreg];
4542: source[1] = dsp_core->registers[DSP_REG_A1+srcreg];
4543: source[2] = dsp_core->registers[DSP_REG_A0+srcreg];
1.1 root 4544: break;
4545: case 4: /* X0 */
4546: source[2] = 0;
1.1.1.2 root 4547: source[1] = dsp_core->registers[DSP_REG_X0];
1.1 root 4548: source[0] = 0;
4549: if (source[1] & (1<<23)) {
4550: source[0] = 0x0000ff;
4551: }
4552: break;
4553: case 5: /* Y0 */
4554: source[2] = 0;
1.1.1.2 root 4555: source[1] = dsp_core->registers[DSP_REG_Y0];
1.1 root 4556: source[0] = 0;
4557: if (source[1] & (1<<23)) {
4558: source[0] = 0x0000ff;
4559: }
4560: break;
4561: case 6: /* X1 */
4562: source[2] = 0;
1.1.1.2 root 4563: source[1] = dsp_core->registers[DSP_REG_X1];
1.1 root 4564: source[0] = 0;
4565: if (source[1] & (1<<23)) {
4566: source[0] = 0x0000ff;
4567: }
4568: break;
4569: case 7: /* Y1 */
4570: source[2] = 0;
1.1.1.2 root 4571: source[1] = dsp_core->registers[DSP_REG_Y1];
1.1 root 4572: source[0] = 0;
4573: if (source[1] & (1<<23)) {
4574: source[0] = 0x0000ff;
4575: }
4576: break;
4577: default:
4578: return;
4579: }
4580:
1.1.1.2 root 4581: dsp_core->registers[DSP_REG_A2+destreg] = source[0];
4582: dsp_core->registers[DSP_REG_A1+destreg] = source[1];
4583: dsp_core->registers[DSP_REG_A0+destreg] = source[2];
1.1 root 4584: }
4585:
4586: static void dsp_tst(void)
4587: {
1.1.1.2 root 4588: Uint32 destreg;
1.1 root 4589:
4590: destreg = (cur_inst>>3) & 1;
4591:
1.1.1.2 root 4592: dsp_ccr_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]);
4593: dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]);
4594: dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]);
4595: dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]);
1.1 root 4596:
1.1.1.2 root 4597: dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
1.1 root 4598: }
4599:
1.1.1.2 root 4600: /*
4601: vim:ts=4:sw=4:
4602: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.