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