Annotation of hatari/src/falcon/dsp_cpu.c, revision 1.1.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.