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