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