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

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

unix.superglobalmegacorp.com

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