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

1.1       root        1: /*
1.1.1.2   root        2:        DSP M56001 emulation
                      3:        Dummy emulation, Hatari glue
1.1       root        4: 
1.1.1.2   root        5:        (C) 2001-2008 ARAnyM developer team
                      6:        Adaption to Hatari (C) 2008 by Thomas Huth
                      7: 
                      8:        This program is free software; you can redistribute it and/or modify
                      9:        it under the terms of the GNU General Public License as published by
                     10:        the Free Software Foundation; either version 2 of the License, or
                     11:        (at your option) any later version.
                     12: 
                     13:        This program is distributed in the hope that it will be useful,
                     14:        but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:        GNU General Public License for more details.
                     17: 
                     18:        You should have received a copy of the GNU General Public License
                     19:        along with this program; if not, write to the Free Software
                     20:        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     21: */
                     22: 
1.1       root       23: #include "main.h"
                     24: #include "sysdeps.h"
1.1.1.2   root       25: #include "newcpu.h"
1.1.1.3   root       26: #include "memorySnapShot.h"
1.1       root       27: #include "ioMem.h"
                     28: #include "dsp.h"
1.1.1.4 ! root       29: #include "crossbar.h"
        !            30: #include "configuration.h"
        !            31: 
1.1.1.3   root       32: #if ENABLE_DSP_EMU
1.1.1.4 ! root       33: #include "m68000.h"
        !            34: #include "debugdsp.h"
1.1.1.3   root       35: #include "dsp_cpu.h"
                     36: #include "dsp_disasm.h"
                     37: #endif
1.1       root       38: 
1.1.1.2   root       39: #define DEBUG 0
1.1.1.3   root       40: #if DEBUG
                     41: #define Dprintf(a) printf a
                     42: #else
                     43: #define Dprintf(a)
                     44: #endif
                     45: 
                     46: #define BITMASK(x)     ((1<<(x))-1)
1.1       root       47: 
1.1.1.3   root       48: #define DSP_HW_OFFSET  0xFFA200
                     49: 
1.1.1.4 ! root       50: 
1.1.1.3   root       51: #if ENABLE_DSP_EMU
1.1.1.2   root       52: static dsp_core_t dsp_core;
1.1.1.4 ! root       53: static dsp_core_t dsp_core_save;
        !            54: static Sint32 save_cycles;
1.1.1.2   root       55: #endif
1.1.1.3   root       56: static bool bDspDebugging;
1.1       root       57: 
1.1.1.3   root       58: bool bDspEnabled = false;
1.1.1.4 ! root       59: bool bDspHostInterruptPending = false;
        !            60: 
        !            61: 
        !            62: /**
        !            63:  * Trigger HREQ interrupt at the host CPU.
        !            64:  */
        !            65: #if ENABLE_DSP_EMU
        !            66: static void DSP_TriggerHostInterrupt(void)
        !            67: {
        !            68:        bDspHostInterruptPending = true;
        !            69: 
        !            70:        /* Note: The DSP interrupt is not wired to the MFP on a real Falcon
        !            71:         * (but to the COMBEL chip). But in Hatari we still handle it with
        !            72:         * the SPCFLAG_MFP to avoid taking care of another special flag in
        !            73:         * the CPU core! */
        !            74:        M68000_SetSpecial(SPCFLAG_MFP);
        !            75: }
        !            76: #endif
1.1       root       77: 
                     78: 
1.1.1.3   root       79: /**
                     80:  * Initialize the DSP emulation
                     81:  */
1.1       root       82: void DSP_Init(void)
                     83: {
1.1.1.3   root       84: #if ENABLE_DSP_EMU
1.1.1.4 ! root       85:        if (ConfigureParams.System.nDSPType != DSP_TYPE_EMU)
        !            86:                return;
        !            87:        dsp_core_init(&dsp_core, DSP_TriggerHostInterrupt);
1.1.1.3   root       88:        dsp56k_init_cpu(&dsp_core);
                     89:        bDspEnabled = true;
1.1.1.4 ! root       90:        save_cycles = 0;
1.1       root       91: #endif
                     92: }
                     93: 
1.1.1.3   root       94: 
                     95: /**
                     96:  * Shut down the DSP emulation
                     97:  */
1.1       root       98: void DSP_UnInit(void)
                     99: {
1.1.1.3   root      100: #if ENABLE_DSP_EMU
1.1.1.4 ! root      101:        if (ConfigureParams.System.nDSPType != DSP_TYPE_EMU)
        !           102:                return;
1.1.1.2   root      103:        dsp_core_shutdown(&dsp_core);
1.1.1.3   root      104:        bDspEnabled = false;
1.1.1.2   root      105: #endif
1.1       root      106: }
                    107: 
1.1.1.3   root      108: 
                    109: /**
                    110:  * Reset the DSP emulation
                    111:  */
1.1       root      112: void DSP_Reset(void)
                    113: {
1.1.1.3   root      114: #if ENABLE_DSP_EMU
1.1.1.2   root      115:        dsp_core_reset(&dsp_core);
1.1.1.4 ! root      116:        bDspHostInterruptPending = false;
        !           117:        save_cycles = 0;
1.1       root      118: #endif
                    119: }
                    120: 
                    121: 
1.1.1.3   root      122: /**
                    123:  * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
                    124:  */
                    125: void DSP_MemorySnapShot_Capture(bool bSave)
                    126: {
                    127: #if ENABLE_DSP_EMU
                    128:        if (!bSave)
                    129:                DSP_Reset();
                    130: 
                    131:        MemorySnapShot_Store(&bDspEnabled, sizeof(bDspEnabled));
                    132:        MemorySnapShot_Store(&dsp_core, sizeof(dsp_core));
1.1.1.4 ! root      133:        MemorySnapShot_Store(&save_cycles, sizeof(save_cycles));
1.1.1.3   root      134: #endif
                    135: }
                    136: 
                    137: /**
                    138:  * Run DSP for certain cycles
                    139:  */
                    140: void DSP_Run(int nHostCycles)
                    141: {
                    142: #if ENABLE_DSP_EMU
1.1.1.4 ! root      143:        /* Cycles emulation should be correctly tuned now */
        !           144:        Sint32 i = nHostCycles * ( DSP_FREQ / CPU_FREQ ) - save_cycles + 1;
        !           145:        Sint32 dsp_cycle = 0;
1.1.1.3   root      146: 
1.1.1.4 ! root      147:        if (dsp_core.running == 0)
        !           148:                return;
1.1.1.3   root      149: 
1.1.1.4 ! root      150:        if (unlikely(bDspDebugging)) {
        !           151:                while (i > dsp_cycle)
        !           152:                {
        !           153:                        DebugDsp_Check();
        !           154:                        dsp56k_execute_instruction();
        !           155:                        dsp_cycle += dsp_core.instr_cycle;
        !           156:                }
        !           157:        } else {
        !           158:                while (i > dsp_cycle)
        !           159:                {
        !           160:                        dsp56k_execute_instruction();
        !           161:                        dsp_cycle += dsp_core.instr_cycle;
        !           162:                }
1.1.1.3   root      163:        }
1.1.1.4 ! root      164: 
        !           165:        /* Adjust cycles for next run */ 
        !           166:        save_cycles = i - dsp_cycle;
1.1.1.3   root      167: #endif
                    168: }
                    169: 
                    170: /**
                    171:  * Enable/disable DSP debugging mode
                    172:  */
                    173: void DSP_SetDebugging(bool enabled)
                    174: {
                    175:        bDspDebugging = enabled;
                    176: }
                    177: 
                    178: /**
                    179:  * Get DSP program counter (for disassembler)
                    180:  */
                    181: Uint16 DSP_GetPC(void)
                    182: {
                    183: #if ENABLE_DSP_EMU
                    184:        if (bDspEnabled)
                    185:                return dsp_core.pc;
                    186:        else
                    187: #endif
                    188:        return 0;
                    189: }
                    190: 
                    191: 
                    192: /**
1.1.1.4 ! root      193:  * Disassemble DSP code between given addresses, return next PC address
1.1.1.3   root      194:  */
                    195: Uint32 DSP_DisasmAddress(Uint16 lowerAdr, Uint16 UpperAdr)
                    196: {
                    197: #if ENABLE_DSP_EMU
1.1.1.4 ! root      198:        Uint32 dsp_pc;
        !           199:        dsp_core_t *ptr1, *ptr2;
        !           200:        
        !           201:        ptr1 = &dsp_core;
        !           202:        ptr2 = &dsp_core_save;
1.1.1.3   root      203:        
                    204:        for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) {
1.1.1.4 ! root      205:                /* Save DSP context before executing instruction */
        !           206:                memcpy(ptr2, ptr1, sizeof(dsp_core));
        !           207: 
        !           208:                /* execute and disasm instruction */
1.1.1.3   root      209:                dsp_core.pc = dsp_pc;
                    210:                dsp_pc += dsp56k_disasm() - 1;
1.1.1.4 ! root      211:                dsp56k_execute_instruction();
        !           212:                fprintf(stderr, "%s", dsp56k_getInstructionText());
        !           213: 
        !           214:                /* Restore DSP context after executing instruction */
        !           215:                memcpy(ptr1, ptr2, sizeof(dsp_core));
1.1.1.3   root      216:        }
                    217:        return dsp_pc;
                    218: #else
                    219:        return 0;
                    220: #endif
                    221: }
                    222: 
                    223: 
                    224: /**
                    225:  * Get the value from the given (16-bit) DSP memory address / space
                    226:  * exactly the same way as in dsp_cpu.c::read_memory() (except for
                    227:  * the host/transmit peripheral register values which access has
                    228:  * side-effects). Set the mem_str to suitable string for that
                    229:  * address / space.
                    230:  * Return the value at given address. For valid values AND the return
                    231:  * value with BITMASK(24).
                    232:  */
                    233: Uint32 DSP_ReadMemory(Uint16 address, char space_id, const char **mem_str)
                    234: {
                    235: #if ENABLE_DSP_EMU
                    236:        static const char *spaces[3][4] = {
                    237:                { "X ram", "X rom", "X", "X periph" },
                    238:                { "Y ram", "Y rom", "Y", "Y periph" },
                    239:                { "P ram", "P ram", "P ext memory", "P ext memory" }
                    240:        };
                    241:        int idx, space;
                    242: 
                    243:        switch (space_id) {
                    244:        case 'X':
                    245:                space = DSP_SPACE_X;
                    246:                idx = 0;
                    247:                break;
                    248:        case 'Y':
                    249:                space = DSP_SPACE_Y;
                    250:                idx = 1;
                    251:                break;
                    252:        case 'P':
                    253:                space = DSP_SPACE_P;
                    254:                idx = 2;
                    255:                break;
                    256:        default:
                    257:                space = DSP_SPACE_X;
                    258:                idx = 0;
                    259:        }
                    260:        address &= 0xFFFF;
                    261: 
                    262:        /* Internal RAM ? */
                    263:        if (address < 0x100) {
                    264:                *mem_str = spaces[idx][0];
                    265:                return dsp_core.ramint[space][address];
                    266:        }
                    267: 
                    268:        if (space == DSP_SPACE_P) {
                    269:                /* Internal RAM ? */
                    270:                if (address < 0x200) {
                    271:                        *mem_str = spaces[idx][0];
                    272:                        return dsp_core.ramint[DSP_SPACE_P][address];
                    273:                }
                    274:                /* External RAM, mask address to available ram size */
                    275:                *mem_str = spaces[idx][2];
                    276:                return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
                    277:        }
                    278: 
                    279:        /* Internal ROM ? */
                    280:        if (address < 0x200) {
                    281:                if (dsp_core.registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) {
                    282:                        *mem_str = spaces[idx][1];
                    283:                        return dsp_core.rom[space][address];
                    284:                }
                    285:        }
                    286: 
                    287:        /* Peripheral address ? */
                    288:        if (address >= 0xffc0) {
                    289:                *mem_str = spaces[idx][3];
                    290:                /* reading host/transmit regs has side-effects,
                    291:                 * so just give the memory value.
                    292:                 */
                    293:                return dsp_core.periph[space][address-0xffc0];
                    294:        }
                    295: 
                    296:        /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
                    297:        address &= (DSP_RAMSIZE>>1) - 1;
                    298:        if (space == DSP_SPACE_X) {
                    299:                address += DSP_RAMSIZE>>1;
                    300:        }
                    301: 
                    302:        /* Falcon: External RAM, finally map X,Y to P */
                    303:        *mem_str = spaces[idx][2];
                    304:        return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
                    305: #endif
                    306:        return 0;
                    307: }
                    308: 
                    309: 
                    310: /**
                    311:  * Output memory values between given addresses in given DSP address space.
1.1.1.4 ! root      312:  * Return next DSP address value.
1.1.1.3   root      313:  */
1.1.1.4 ! root      314: Uint16 DSP_DisasmMemory(Uint16 dsp_memdump_addr, Uint16 dsp_memdump_upper, char space)
1.1.1.3   root      315: {
                    316: #if ENABLE_DSP_EMU
                    317:        Uint32 mem, mem2, value;
                    318:        const char *mem_str;
                    319: 
                    320:        for (mem = dsp_memdump_addr; mem <= dsp_memdump_upper; mem++) {
                    321:                /* special printing of host communication/transmit registers */
                    322:                if (space == 'X' && (mem == 0xffeb || mem == 0xffef)) {
                    323:                        if (mem == 0xffeb) {
                    324:                                fprintf(stderr,"X periph:%04x  HTX : %06x   RTX:%06x\n", 
                    325:                                        mem, dsp_core.dsp_host_htx, dsp_core.dsp_host_rtx);
                    326:                        }
                    327:                        else if (mem == 0xffef) {
                    328:                                fprintf(stderr,"X periph:%04x  SSI TX : %06x   SSI RX:%06x\n", 
                    329:                                        mem, dsp_core.ssi.transmit_value, dsp_core.ssi.received_value);
                    330:                        }
                    331:                        continue;
                    332:                }
                    333:                /* special printing of X & Y external RAM values */
                    334:                if ((space == 'X' || space == 'Y') &&
                    335:                    mem >= 0x200 && mem < 0xffc0) {
                    336:                        mem2 = mem & ((DSP_RAMSIZE>>1)-1);
                    337:                        if (space == 'X') {
                    338:                                mem2 += (DSP_RAMSIZE>>1);
                    339:                        }
                    340:                        fprintf(stderr,"%c:%04x (P:%04x): %06x\n", space,
                    341:                                mem, mem2, dsp_core.ramext[mem2 & (DSP_RAMSIZE-1)]);
                    342:                        continue;
                    343:                }
                    344:                value = DSP_ReadMemory(mem, space, &mem_str);
                    345:                fprintf(stderr,"%s:%04x  %06x\n", mem_str, mem, value);
                    346:        }
                    347: #endif
1.1.1.4 ! root      348:        return dsp_memdump_upper+1;
1.1.1.3   root      349: }
                    350: 
                    351: 
                    352: void DSP_DisasmRegisters(void)
                    353: {
                    354: #if ENABLE_DSP_EMU
                    355:        Uint32 i;
                    356: 
                    357:        fprintf(stderr,"A: A2: %02x  A1: %06x  A0: %06x\n",
                    358:                dsp_core.registers[DSP_REG_A2], dsp_core.registers[DSP_REG_A1], dsp_core.registers[DSP_REG_A0]);
                    359:        fprintf(stderr,"B: B2: %02x  B1: %06x  B0: %06x\n",
                    360:                dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0]);
                    361:        
                    362:        fprintf(stderr,"X: X1: %06x  X0: %06x\n", dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_X0]);
                    363:        fprintf(stderr,"Y: Y1: %06x  Y0: %06x\n", dsp_core.registers[DSP_REG_Y1], dsp_core.registers[DSP_REG_Y0]);
                    364: 
                    365:        for (i=0; i<8; i++) {
                    366:                fprintf(stderr,"R%01x: %04x   N%01x: %04x   M%01x: %04x\n", 
                    367:                        i, dsp_core.registers[DSP_REG_R0+i],
                    368:                        i, dsp_core.registers[DSP_REG_N0+i],
                    369:                        i, dsp_core.registers[DSP_REG_M0+i]);
                    370:        }
                    371: 
                    372:        fprintf(stderr,"LA: %04x   LC: %04x   PC: %04x\n", dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], dsp_core.pc);
                    373:        fprintf(stderr,"SR: %04x  OMR: %02x\n", dsp_core.registers[DSP_REG_SR], dsp_core.registers[DSP_REG_OMR]);
                    374:        fprintf(stderr,"SP: %02x    SSH: %04x  SSL: %04x\n", 
                    375:                dsp_core.registers[DSP_REG_SP], dsp_core.registers[DSP_REG_SSH], dsp_core.registers[DSP_REG_SSL]);
                    376: #endif
                    377: }
                    378: 
                    379: 
                    380: /**
                    381:  * Get given DSP register address and required bit mask.
                    382:  * Works for A0-2, B0-2, LA, LC, M0-7, N0-7, R0-7, X0-1, Y0-1, PC, SR, SP,
                    383:  * OMR, SSH & SSL registers, but note that the SP, SSH & SSL registers
                    384:  * need special handling (in DSP*SetRegister()) when they are set.
                    385:  * Return the register width in bits or zero for an error.
                    386:  */
                    387: int DSP_GetRegisterAddress(const char *regname, Uint32 **addr, Uint32 *mask)
                    388: {
                    389: #if ENABLE_DSP_EMU
                    390: #define MAX_REGNAME_LEN 4
                    391:        typedef struct {
                    392:                const char name[MAX_REGNAME_LEN];
                    393:                Uint32 *addr;
                    394:                size_t bits;
                    395:                Uint32 mask;
                    396:        } reg_addr_t;
                    397:        
                    398:        /* sorted by name so that this can be bisected */
                    399:        static const reg_addr_t registers[] = {
                    400: 
                    401:                /* 56-bit A register */
                    402:                { "A0",  &dsp_core.registers[DSP_REG_A0],  32, BITMASK(24) },
                    403:                { "A1",  &dsp_core.registers[DSP_REG_A1],  32, BITMASK(24) },
                    404:                { "A2",  &dsp_core.registers[DSP_REG_A2],  32, BITMASK(8) },
                    405: 
                    406:                /* 56-bit B register */
                    407:                { "B0",  &dsp_core.registers[DSP_REG_B0],  32, BITMASK(24) },
                    408:                { "B1",  &dsp_core.registers[DSP_REG_B1],  32, BITMASK(24) },
                    409:                { "B2",  &dsp_core.registers[DSP_REG_B2],  32, BITMASK(8) },
                    410: 
                    411:                /* 16-bit LA & LC registers */
                    412:                { "LA",  &dsp_core.registers[DSP_REG_LA],  32, BITMASK(16) },
                    413:                { "LC",  &dsp_core.registers[DSP_REG_LC],  32, BITMASK(16) },
                    414: 
                    415:                /* 16-bit M registers */
                    416:                { "M0",  &dsp_core.registers[DSP_REG_M0],  32, BITMASK(16) },
                    417:                { "M1",  &dsp_core.registers[DSP_REG_M1],  32, BITMASK(16) },
                    418:                { "M2",  &dsp_core.registers[DSP_REG_M2],  32, BITMASK(16) },
                    419:                { "M3",  &dsp_core.registers[DSP_REG_M3],  32, BITMASK(16) },
                    420:                { "M4",  &dsp_core.registers[DSP_REG_M4],  32, BITMASK(16) },
                    421:                { "M5",  &dsp_core.registers[DSP_REG_M5],  32, BITMASK(16) },
                    422:                { "M6",  &dsp_core.registers[DSP_REG_M6],  32, BITMASK(16) },
                    423:                { "M7",  &dsp_core.registers[DSP_REG_M7],  32, BITMASK(16) },
                    424: 
                    425:                /* 16-bit N registers */
                    426:                { "N0",  &dsp_core.registers[DSP_REG_N0],  32, BITMASK(16) },
                    427:                { "N1",  &dsp_core.registers[DSP_REG_N1],  32, BITMASK(16) },
                    428:                { "N2",  &dsp_core.registers[DSP_REG_N2],  32, BITMASK(16) },
                    429:                { "N3",  &dsp_core.registers[DSP_REG_N3],  32, BITMASK(16) },
                    430:                { "N4",  &dsp_core.registers[DSP_REG_N4],  32, BITMASK(16) },
                    431:                { "N5",  &dsp_core.registers[DSP_REG_N5],  32, BITMASK(16) },
                    432:                { "N6",  &dsp_core.registers[DSP_REG_N6],  32, BITMASK(16) },
                    433:                { "N7",  &dsp_core.registers[DSP_REG_N7],  32, BITMASK(16) },
                    434: 
                    435:                { "OMR", &dsp_core.registers[DSP_REG_OMR], 32, 0x5f },
                    436: 
                    437:                /* 16-bit program counter */
                    438:                { "PC",  (Uint32*)(&dsp_core.pc),  16, BITMASK(16) },
                    439: 
                    440:                /* 16-bit DSP R (address) registers */
                    441:                { "R0",  &dsp_core.registers[DSP_REG_R0],  32, BITMASK(16) },
                    442:                { "R1",  &dsp_core.registers[DSP_REG_R1],  32, BITMASK(16) },
                    443:                { "R2",  &dsp_core.registers[DSP_REG_R2],  32, BITMASK(16) },
                    444:                { "R3",  &dsp_core.registers[DSP_REG_R3],  32, BITMASK(16) },
                    445:                { "R4",  &dsp_core.registers[DSP_REG_R4],  32, BITMASK(16) },
                    446:                { "R5",  &dsp_core.registers[DSP_REG_R5],  32, BITMASK(16) },
                    447:                { "R6",  &dsp_core.registers[DSP_REG_R6],  32, BITMASK(16) },
                    448:                { "R7",  &dsp_core.registers[DSP_REG_R7],  32, BITMASK(16) },
                    449: 
                    450:                { "SSH", &dsp_core.registers[DSP_REG_SSH], 32, BITMASK(16) },
                    451:                { "SSL", &dsp_core.registers[DSP_REG_SSL], 32, BITMASK(16) },
                    452:                { "SP",  &dsp_core.registers[DSP_REG_SP],  32, BITMASK(6) },
                    453: 
                    454:                /* 16-bit status register */
                    455:                { "SR",  &dsp_core.registers[DSP_REG_SR],  32, 0xefff },
                    456: 
                    457:                /* 48-bit X register */
                    458:                { "X0",  &dsp_core.registers[DSP_REG_X0],  32, BITMASK(24) },
                    459:                { "X1",  &dsp_core.registers[DSP_REG_X1],  32, BITMASK(24) },
                    460: 
                    461:                /* 48-bit Y register */
                    462:                { "Y0",  &dsp_core.registers[DSP_REG_Y0],  32, BITMASK(24) },
                    463:                { "Y1",  &dsp_core.registers[DSP_REG_Y1],  32, BITMASK(24) }
                    464:        };
                    465:        /* left, right, middle, direction */
1.1.1.4 ! root      466:         int l, r, m, dir = 0;
        !           467:        unsigned int i, len;
1.1.1.3   root      468:        char reg[MAX_REGNAME_LEN];
                    469: 
1.1.1.4 ! root      470:        if (!bDspEnabled) {
        !           471:                return 0;
        !           472:        }
        !           473: 
1.1.1.3   root      474:        for (i = 0; i < sizeof(reg) && regname[i]; i++) {
                    475:                reg[i] = toupper(regname[i]);
                    476:        }
                    477:        if (i < 2 || regname[i]) {
                    478:                /* too short or longer than any of the names */
                    479:                return 0;
                    480:        }
1.1.1.4 ! root      481:        len = i;
        !           482:        
1.1.1.3   root      483:        /* bisect */
                    484:        l = 0;
                    485:        r = sizeof (registers) / sizeof (*registers) - 1;
                    486:        do {
                    487:                m = (l+r) >> 1;
1.1.1.4 ! root      488:                for (i = 0; i < len; i++) {
1.1.1.3   root      489:                        dir = (int)reg[i] - registers[m].name[i];
                    490:                        if (dir) {
                    491:                                break;
                    492:                        }
                    493:                }
                    494:                if (dir == 0) {
                    495:                        *addr = registers[m].addr;
                    496:                        *mask = registers[m].mask;
                    497:                        return registers[m].bits;
                    498:                }
                    499:                if (dir < 0) {
                    500:                        r = m-1;
                    501:                } else {
                    502:                        l = m+1;
                    503:                }
                    504:        } while (l <= r);
                    505: #undef MAX_REGNAME_LEN
                    506: #endif
                    507:        return 0;
                    508: }
                    509: 
                    510: 
                    511: /**
1.1.1.4 ! root      512:  * Set given DSP register value, return false if unknown register given
1.1.1.3   root      513:  */
1.1.1.4 ! root      514: bool DSP_Disasm_SetRegister(const char *arg, Uint32 value)
1.1.1.3   root      515: {
                    516: #if ENABLE_DSP_EMU
                    517:        Uint32 *addr, mask, sp_value;
                    518:        int bits;
                    519: 
                    520:        /* first check registers needing special handling... */
                    521:        if (arg[0]=='S' || arg[0]=='s') {
                    522:                if (arg[1]=='P' || arg[1]=='p') {
                    523:                        dsp_core.registers[DSP_REG_SP] = value & BITMASK(6);
                    524:                        value &= BITMASK(4); 
                    525:                        dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][value];
                    526:                        dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][value];
1.1.1.4 ! root      527:                        return true;
1.1.1.3   root      528:                }
                    529:                if (arg[1]=='S' || arg[1]=='s') {
                    530:                        sp_value = dsp_core.registers[DSP_REG_SP] & BITMASK(4);
                    531:                        if (arg[2]=='H' || arg[2]=='h') {
                    532:                                if (sp_value == 0) {
                    533:                                        dsp_core.registers[DSP_REG_SSH] = 0;
                    534:                                        dsp_core.stack[0][sp_value] = 0;
                    535:                                } else {
                    536:                                        dsp_core.registers[DSP_REG_SSH] = value & BITMASK(16);
                    537:                                        dsp_core.stack[0][sp_value] = value & BITMASK(16);
                    538:                                }
1.1.1.4 ! root      539:                                return true;
1.1.1.3   root      540:                        }
                    541:                        if (arg[2]=='L' || arg[2]=='l') {
                    542:                                if (sp_value == 0) {
                    543:                                        dsp_core.registers[DSP_REG_SSL] = 0;
                    544:                                        dsp_core.stack[1][sp_value] = 0;
                    545:                                } else {
                    546:                                        dsp_core.registers[DSP_REG_SSL] = value & BITMASK(16);
                    547:                                        dsp_core.stack[1][sp_value] = value & BITMASK(16);
                    548:                                }
1.1.1.4 ! root      549:                                return true;
1.1.1.3   root      550:                        }
                    551:                }
                    552:        }
                    553: 
                    554:        /* ...then registers where address & mask are enough */
                    555:        bits = DSP_GetRegisterAddress(arg, &addr, &mask);
                    556:        switch (bits) {
                    557:        case 32:
                    558:                *addr = value & mask;
1.1.1.4 ! root      559:                return true;
1.1.1.3   root      560:        case 16:
                    561:                *(Uint16*)addr = value & mask;
1.1.1.4 ! root      562:                return true;
1.1.1.3   root      563:        }
                    564: #endif
1.1.1.4 ! root      565:        return false;
1.1.1.3   root      566: }
                    567: 
                    568: /**
                    569:  * Read SSI transmit value
                    570:  */
                    571: Uint32 DSP_SsiReadTxValue(void)
                    572: {
                    573: #if ENABLE_DSP_EMU
                    574:        return dsp_core.ssi.transmit_value;
                    575: #else
                    576:        return 0;
                    577: #endif
                    578: }
                    579: 
                    580: /**
                    581:  * Write SSI receive value
                    582:  */
                    583: void DSP_SsiWriteRxValue(Uint32 value)
                    584: {
                    585: #if ENABLE_DSP_EMU
                    586:        dsp_core.ssi.received_value = value & 0xffffff;
                    587: #endif
                    588: }
                    589: 
                    590: /**
                    591:  * Signal SSI clock tick to DSP
                    592:  */
1.1.1.4 ! root      593: 
        !           594: void DSP_SsiReceive_SC0(void)
1.1.1.3   root      595: {
                    596: #if ENABLE_DSP_EMU
1.1.1.4 ! root      597:        dsp_core_ssi_Receive_SC0(&dsp_core);
1.1.1.3   root      598: #endif
                    599: }
                    600: 
1.1.1.4 ! root      601: void DSP_SsiTransmit_SC0(void)
1.1.1.3   root      602: {
                    603: #if ENABLE_DSP_EMU
                    604: #endif
                    605: }
                    606: 
1.1.1.4 ! root      607: void DSP_SsiReceive_SC1(Uint32 FrameCounter)
1.1       root      608: {
1.1.1.3   root      609: #if ENABLE_DSP_EMU
1.1.1.4 ! root      610:        dsp_core_ssi_Receive_SC1(&dsp_core, FrameCounter);
1.1       root      611: #endif
1.1.1.4 ! root      612: }
1.1       root      613: 
1.1.1.4 ! root      614: void DSP_SsiTransmit_SC1(void)
        !           615: {
        !           616: #if ENABLE_DSP_EMU
        !           617:        Crossbar_DmaPlayInHandShakeMode();
        !           618: #endif
1.1       root      619: }
                    620: 
1.1.1.4 ! root      621: void DSP_SsiReceive_SC2(Uint32 FrameCounter)
1.1       root      622: {
1.1.1.4 ! root      623: #if ENABLE_DSP_EMU
        !           624:        dsp_core_ssi_Receive_SC2(&dsp_core, FrameCounter);
        !           625: #endif
        !           626: }
        !           627: 
        !           628: void DSP_SsiTransmit_SC2(Uint32 frame)
        !           629: {
        !           630: #if ENABLE_DSP_EMU
        !           631:        Crossbar_DmaRecordInHandShakeMode_Frame(frame);
        !           632: #endif
1.1       root      633: }
                    634: 
1.1.1.4 ! root      635: void DSP_SsiReceive_SCK(void)
        !           636: {
        !           637: #if ENABLE_DSP_EMU
        !           638:        dsp_core_ssi_Receive_SCK(&dsp_core);
        !           639: #endif
        !           640: }
        !           641: 
        !           642: void DSP_SsiTransmit_SCK(void)
        !           643: {
        !           644: #if ENABLE_DSP_EMU
        !           645: #endif
        !           646: }
1.1.1.2   root      647: 
1.1.1.3   root      648: /**
1.1.1.4 ! root      649:  * Read access wrapper for ioMemTabFalcon (DSP Host port)
1.1.1.3   root      650:  */
1.1.1.4 ! root      651: void DSP_HandleReadAccess(void)
1.1       root      652: {
1.1.1.4 ! root      653:        Uint32 addr;
        !           654:        Uint8 value;
        !           655:        for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++)
        !           656:        {
1.1.1.3   root      657: #if ENABLE_DSP_EMU
1.1.1.4 ! root      658:                value = dsp_core_read_host(&dsp_core, addr-DSP_HW_OFFSET);
        !           659: #else
        !           660:                /* this value prevents TOS from hanging in the DSP init code */
        !           661:                value = 0xff;
1.1       root      662: #endif
1.1.1.4 ! root      663: 
        !           664:                Dprintf(("HWget_b(0x%08x)=0x%02x at 0x%08x\n", addr, value, m68k_getpc()));
        !           665:                IoMem_WriteByte(addr, value);
        !           666:        }
1.1       root      667: }
                    668: 
1.1.1.3   root      669: /**
1.1.1.4 ! root      670:  * Write access wrapper for ioMemTabFalcon (DSP Host port)
1.1.1.3   root      671:  */
1.1       root      672: void DSP_HandleWriteAccess(void)
                    673: {
1.1.1.4 ! root      674:        Uint32 addr;
        !           675:        Uint8 value;
        !           676:        for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++)
1.1       root      677:        {
1.1.1.4 ! root      678:                value = IoMem_ReadByte(addr);
        !           679:                Dprintf(("HWput_b(0x%08x,0x%02x) at 0x%08x\n", addr, value, m68k_getpc()));
        !           680: #if ENABLE_DSP_EMU
        !           681:                dsp_core_write_host(&dsp_core, addr-DSP_HW_OFFSET, value);
        !           682: #endif
1.1       root      683:        }
                    684: }

unix.superglobalmegacorp.com

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