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