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