Annotation of hatari/src/falcon/dsp_cpu.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.