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

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

unix.superglobalmegacorp.com

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