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

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

unix.superglobalmegacorp.com

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