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

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

unix.superglobalmegacorp.com

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