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

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"
1.1.1.6   root       31: #include "cycInt.h"
1.1.1.9 ! root       32: #include "m68000.h"
1.1.1.4   root       33: 
1.1.1.3   root       34: #if ENABLE_DSP_EMU
1.1.1.4   root       35: #include "debugdsp.h"
1.1.1.3   root       36: #include "dsp_cpu.h"
                     37: #include "dsp_disasm.h"
                     38: #endif
1.1       root       39: 
1.1.1.2   root       40: #define DEBUG 0
1.1.1.3   root       41: #if DEBUG
                     42: #define Dprintf(a) printf a
                     43: #else
                     44: #define Dprintf(a)
                     45: #endif
                     46: 
                     47: #define DSP_HW_OFFSET  0xFFA200
                     48: 
1.1.1.4   root       49: 
1.1.1.3   root       50: #if ENABLE_DSP_EMU
1.1.1.7   root       51: static const char* x_ext_memory_addr_name[] = {
                     52:        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
                     53:        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
                     54:        "PBC", "PCC", "PBDDR", "PCDDR", "PBD", "PCD", "", "",
                     55:        "HCR", "HSR", "", "HRX/HTX", "CRA", "CRB", "SSISR/TSR", "RX/TX",
                     56:        "SCR", "SSR", "SCCR", "STXA", "SRX/STX", "SRX/STX", "SRX/STX", "",
1.1.1.9 ! root       57:        "", "", "", "", "", "", "BCR", "IPR"
1.1.1.7   root       58: };
                     59: 
1.1.1.9 ! root       60: static Sint32 save_cycles;
        !            61: #endif
        !            62: 
        !            63: static bool bDspDebugging;
        !            64: 
        !            65: bool bDspEnabled = false;
        !            66: bool bDspHostInterruptPending = false;
        !            67: 
1.1.1.4   root       68: 
                     69: /**
                     70:  * Trigger HREQ interrupt at the host CPU.
                     71:  */
                     72: #if ENABLE_DSP_EMU
                     73: static void DSP_TriggerHostInterrupt(void)
                     74: {
                     75:        bDspHostInterruptPending = true;
1.1.1.9 ! root       76:        M68000_SetSpecial(SPCFLAG_DSP);
        !            77: }
        !            78: #endif
1.1.1.4   root       79: 
1.1.1.9 ! root       80: 
        !            81: /**
        !            82:  * This function is called from the CPU emulation part when SPCFLAG_DSP is set.
        !            83:  * If the DSP's IRQ signal is set, we check that SR allows a level 6 interrupt,
        !            84:  * and if so, we call M68000_Exception.
        !            85:  */
        !            86: #if ENABLE_DSP_EMU
        !            87: bool   DSP_ProcessIRQ(void)
        !            88: {
        !            89:        if (bDspHostInterruptPending && regs.intmask < 6)
        !            90:        {
        !            91:                M68000_Exception(IoMem_ReadByte(0xffa203)*4, M68000_EXC_SRC_INT_DSP);
        !            92:                bDspHostInterruptPending = false;
        !            93:                M68000_UnsetSpecial(SPCFLAG_DSP);
        !            94:                return true;
        !            95:        }
        !            96: 
        !            97:        return false;
1.1.1.4   root       98: }
                     99: #endif
1.1       root      100: 
                    101: 
1.1.1.3   root      102: /**
                    103:  * Initialize the DSP emulation
                    104:  */
1.1       root      105: void DSP_Init(void)
                    106: {
1.1.1.3   root      107: #if ENABLE_DSP_EMU
1.1.1.5   root      108:        if (bDspEnabled || ConfigureParams.System.nDSPType != DSP_TYPE_EMU)
1.1.1.4   root      109:                return;
1.1.1.5   root      110:        dsp_core_init(DSP_TriggerHostInterrupt);
                    111:        dsp56k_init_cpu();
1.1.1.3   root      112:        bDspEnabled = true;
1.1.1.4   root      113:        save_cycles = 0;
1.1       root      114: #endif
                    115: }
                    116: 
1.1.1.3   root      117: 
                    118: /**
                    119:  * Shut down the DSP emulation
                    120:  */
1.1       root      121: void DSP_UnInit(void)
                    122: {
1.1.1.3   root      123: #if ENABLE_DSP_EMU
1.1.1.5   root      124:        if (!bDspEnabled)
1.1.1.4   root      125:                return;
1.1.1.5   root      126:        dsp_core_shutdown();
1.1.1.3   root      127:        bDspEnabled = false;
1.1.1.2   root      128: #endif
1.1       root      129: }
                    130: 
1.1.1.3   root      131: 
                    132: /**
                    133:  * Reset the DSP emulation
                    134:  */
1.1       root      135: void DSP_Reset(void)
                    136: {
1.1.1.3   root      137: #if ENABLE_DSP_EMU
1.1.1.5   root      138:        dsp_core_reset();
1.1.1.4   root      139:        bDspHostInterruptPending = false;
                    140:        save_cycles = 0;
1.1       root      141: #endif
                    142: }
                    143: 
                    144: 
1.1.1.3   root      145: /**
                    146:  * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
                    147:  */
                    148: void DSP_MemorySnapShot_Capture(bool bSave)
                    149: {
                    150: #if ENABLE_DSP_EMU
                    151:        if (!bSave)
                    152:                DSP_Reset();
                    153: 
                    154:        MemorySnapShot_Store(&bDspEnabled, sizeof(bDspEnabled));
                    155:        MemorySnapShot_Store(&dsp_core, sizeof(dsp_core));
1.1.1.4   root      156:        MemorySnapShot_Store(&save_cycles, sizeof(save_cycles));
1.1.1.3   root      157: #endif
                    158: }
                    159: 
                    160: /**
                    161:  * Run DSP for certain cycles
                    162:  */
                    163: void DSP_Run(int nHostCycles)
                    164: {
                    165: #if ENABLE_DSP_EMU
1.1.1.5   root      166:         save_cycles += nHostCycles * 2;
1.1.1.3   root      167: 
1.1.1.5   root      168:         if (dsp_core.running == 0)
                    169:                 return;
1.1.1.3   root      170: 
1.1.1.5   root      171:         if (save_cycles <= 0)
                    172:                 return;
                    173: 
                    174:         if (unlikely(bDspDebugging)) {
                    175:                 while (save_cycles > 0)
                    176:                 {
                    177:                         dsp56k_execute_instruction();
                    178:                         save_cycles -= dsp_core.instr_cycle;
1.1.1.9 ! root      179:                         DebugDsp_Check();
1.1.1.5   root      180:                 }
                    181:         } else {
                    182:                //      fprintf(stderr, "--> %d\n", save_cycles);
                    183:                 while (save_cycles > 0)
                    184:                 {
                    185:                         dsp56k_execute_instruction();
                    186:                         save_cycles -= dsp_core.instr_cycle;
                    187:                 }
                    188:         }
1.1.1.4   root      189: 
1.1.1.3   root      190: #endif
1.1.1.5   root      191: } 
1.1.1.3   root      192: 
                    193: /**
                    194:  * Enable/disable DSP debugging mode
                    195:  */
                    196: void DSP_SetDebugging(bool enabled)
                    197: {
                    198:        bDspDebugging = enabled;
                    199: }
                    200: 
                    201: /**
1.1.1.5   root      202:  * Get DSP program counter (for debugging)
1.1.1.3   root      203:  */
                    204: Uint16 DSP_GetPC(void)
                    205: {
                    206: #if ENABLE_DSP_EMU
                    207:        if (bDspEnabled)
                    208:                return dsp_core.pc;
                    209:        else
                    210: #endif
                    211:        return 0;
                    212: }
                    213: 
1.1.1.5   root      214: /**
1.1.1.9 ! root      215:  * Get next DSP PC without output (for debugging)
        !           216:  */
        !           217: Uint16 DSP_GetNextPC(Uint16 pc)
        !           218: {
        !           219: #if ENABLE_DSP_EMU
        !           220:        /* code is reduced copy from dsp56k_execute_one_disasm_instruction() */
        !           221:        dsp_core_t dsp_core_save;
        !           222:        Uint16 instruction_length;
        !           223: 
        !           224:        if (!bDspEnabled)
        !           225:                return 0;
        !           226: 
        !           227:        /* Save DSP context */
        !           228:        memcpy(&dsp_core_save, &dsp_core, sizeof(dsp_core));
        !           229: 
        !           230:        /* Disasm instruction */
        !           231:        dsp_core.pc = pc;
        !           232:        /* why dsp56k_execute_one_disasm_instruction() does "-1"
        !           233:         * for this value, that doesn't seem right???
        !           234:         */
        !           235:        instruction_length = dsp56k_disasm(DSP_DISASM_MODE);
        !           236: 
        !           237:        /* Restore DSP context */
        !           238:        memcpy(&dsp_core, &dsp_core_save, sizeof(dsp_core));
        !           239: 
        !           240:        return pc + instruction_length;
        !           241: #else
        !           242:        return 0;
        !           243: #endif
        !           244: }
        !           245: 
        !           246: /**
1.1.1.5   root      247:  * Get current DSP instruction cycles (for profiling)
                    248:  */
                    249: Uint16 DSP_GetInstrCycles(void)
                    250: {
                    251: #if ENABLE_DSP_EMU
                    252:        if (bDspEnabled)
                    253:                return dsp_core.instr_cycle;
                    254:        else
                    255: #endif
                    256:        return 0;
                    257: }
                    258: 
1.1.1.3   root      259: 
                    260: /**
1.1.1.4   root      261:  * Disassemble DSP code between given addresses, return next PC address
1.1.1.3   root      262:  */
1.1.1.9 ! root      263: Uint16 DSP_DisasmAddress(FILE *out, Uint16 lowerAdr, Uint16 UpperAdr)
1.1.1.3   root      264: {
                    265: #if ENABLE_DSP_EMU
1.1.1.8   root      266:        Uint16 dsp_pc;
1.1.1.4   root      267: 
1.1.1.5   root      268:        for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) {
1.1.1.9 ! root      269:                dsp_pc += dsp56k_execute_one_disasm_instruction(out, dsp_pc);
1.1.1.3   root      270:        }
                    271:        return dsp_pc;
                    272: #else
                    273:        return 0;
                    274: #endif
                    275: }
                    276: 
                    277: 
                    278: /**
                    279:  * Get the value from the given (16-bit) DSP memory address / space
                    280:  * exactly the same way as in dsp_cpu.c::read_memory() (except for
                    281:  * the host/transmit peripheral register values which access has
                    282:  * side-effects). Set the mem_str to suitable string for that
                    283:  * address / space.
                    284:  * Return the value at given address. For valid values AND the return
                    285:  * value with BITMASK(24).
                    286:  */
                    287: Uint32 DSP_ReadMemory(Uint16 address, char space_id, const char **mem_str)
                    288: {
                    289: #if ENABLE_DSP_EMU
                    290:        static const char *spaces[3][4] = {
                    291:                { "X ram", "X rom", "X", "X periph" },
                    292:                { "Y ram", "Y rom", "Y", "Y periph" },
                    293:                { "P ram", "P ram", "P ext memory", "P ext memory" }
                    294:        };
                    295:        int idx, space;
                    296: 
                    297:        switch (space_id) {
                    298:        case 'X':
                    299:                space = DSP_SPACE_X;
                    300:                idx = 0;
                    301:                break;
                    302:        case 'Y':
                    303:                space = DSP_SPACE_Y;
                    304:                idx = 1;
                    305:                break;
                    306:        case 'P':
                    307:                space = DSP_SPACE_P;
                    308:                idx = 2;
                    309:                break;
                    310:        default:
                    311:                space = DSP_SPACE_X;
                    312:                idx = 0;
                    313:        }
                    314:        address &= 0xFFFF;
                    315: 
                    316:        /* Internal RAM ? */
                    317:        if (address < 0x100) {
                    318:                *mem_str = spaces[idx][0];
                    319:                return dsp_core.ramint[space][address];
                    320:        }
                    321: 
                    322:        if (space == DSP_SPACE_P) {
                    323:                /* Internal RAM ? */
                    324:                if (address < 0x200) {
                    325:                        *mem_str = spaces[idx][0];
                    326:                        return dsp_core.ramint[DSP_SPACE_P][address];
                    327:                }
                    328:                /* External RAM, mask address to available ram size */
                    329:                *mem_str = spaces[idx][2];
                    330:                return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
                    331:        }
                    332: 
                    333:        /* Internal ROM ? */
                    334:        if (address < 0x200) {
                    335:                if (dsp_core.registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) {
                    336:                        *mem_str = spaces[idx][1];
                    337:                        return dsp_core.rom[space][address];
                    338:                }
                    339:        }
                    340: 
                    341:        /* Peripheral address ? */
                    342:        if (address >= 0xffc0) {
                    343:                *mem_str = spaces[idx][3];
                    344:                /* reading host/transmit regs has side-effects,
                    345:                 * so just give the memory value.
                    346:                 */
                    347:                return dsp_core.periph[space][address-0xffc0];
                    348:        }
                    349: 
                    350:        /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
                    351:        address &= (DSP_RAMSIZE>>1) - 1;
                    352:        if (space == DSP_SPACE_X) {
                    353:                address += DSP_RAMSIZE>>1;
                    354:        }
                    355: 
                    356:        /* Falcon: External RAM, finally map X,Y to P */
                    357:        *mem_str = spaces[idx][2];
                    358:        return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
                    359: #endif
                    360:        return 0;
                    361: }
                    362: 
                    363: 
                    364: /**
                    365:  * Output memory values between given addresses in given DSP address space.
1.1.1.4   root      366:  * Return next DSP address value.
1.1.1.3   root      367:  */
1.1.1.4   root      368: Uint16 DSP_DisasmMemory(Uint16 dsp_memdump_addr, Uint16 dsp_memdump_upper, char space)
1.1.1.3   root      369: {
                    370: #if ENABLE_DSP_EMU
                    371:        Uint32 mem, mem2, value;
                    372:        const char *mem_str;
                    373: 
                    374:        for (mem = dsp_memdump_addr; mem <= dsp_memdump_upper; mem++) {
                    375:                /* special printing of host communication/transmit registers */
1.1.1.7   root      376:                if (space == 'X' && mem >= 0xffc0) {
1.1.1.3   root      377:                        if (mem == 0xffeb) {
                    378:                                fprintf(stderr,"X periph:%04x  HTX : %06x   RTX:%06x\n", 
                    379:                                        mem, dsp_core.dsp_host_htx, dsp_core.dsp_host_rtx);
                    380:                        }
                    381:                        else if (mem == 0xffef) {
                    382:                                fprintf(stderr,"X periph:%04x  SSI TX : %06x   SSI RX:%06x\n", 
                    383:                                        mem, dsp_core.ssi.transmit_value, dsp_core.ssi.received_value);
                    384:                        }
1.1.1.7   root      385:                        else {
                    386:                                value = DSP_ReadMemory(mem, space, &mem_str);
                    387:                                fprintf(stderr,"%s:%04x  %06x\t%s\n", mem_str, mem, value, x_ext_memory_addr_name[mem-0xffc0]);
                    388:                        }
1.1.1.3   root      389:                        continue;
                    390:                }
                    391:                /* special printing of X & Y external RAM values */
                    392:                if ((space == 'X' || space == 'Y') &&
                    393:                    mem >= 0x200 && mem < 0xffc0) {
                    394:                        mem2 = mem & ((DSP_RAMSIZE>>1)-1);
                    395:                        if (space == 'X') {
                    396:                                mem2 += (DSP_RAMSIZE>>1);
                    397:                        }
                    398:                        fprintf(stderr,"%c:%04x (P:%04x): %06x\n", space,
                    399:                                mem, mem2, dsp_core.ramext[mem2 & (DSP_RAMSIZE-1)]);
                    400:                        continue;
                    401:                }
                    402:                value = DSP_ReadMemory(mem, space, &mem_str);
                    403:                fprintf(stderr,"%s:%04x  %06x\n", mem_str, mem, value);
                    404:        }
                    405: #endif
1.1.1.4   root      406:        return dsp_memdump_upper+1;
1.1.1.3   root      407: }
                    408: 
1.1.1.9 ! root      409: /**
        !           410:  * Show information on DSP core state which isn't
        !           411:  * shown by any of the other commands (dd, dm, dr).
        !           412:  */
        !           413: void DSP_Info(Uint32 dummy)
        !           414: {
        !           415: #if ENABLE_DSP_EMU
        !           416:        int i, j;
        !           417:        const char *stackname[] = { "SSH", "SSL" };
        !           418: 
        !           419:        fputs("DSP core information:\n", stderr);
        !           420: 
        !           421:        for (i = 0; i < ARRAYSIZE(stackname); i++) {
        !           422:                fprintf(stderr, "- %s stack:", stackname[i]);
        !           423:                for (j = 0; j < ARRAYSIZE(dsp_core.stack[0]); j++) {
        !           424:                        fprintf(stderr, " %04hx", dsp_core.stack[i][j]);
        !           425:                }
        !           426:                fputs("\n", stderr);
        !           427:        }
        !           428: 
        !           429:        fprintf(stderr, "- Interrupt IPL:");
        !           430:        for (i = 0; i < ARRAYSIZE(dsp_core.interrupt_ipl); i++) {
        !           431:                fprintf(stderr, " %04hx", dsp_core.interrupt_ipl[i]);
        !           432:        }
        !           433:        fputs("\n", stderr);
        !           434: 
        !           435:        fprintf(stderr, "- Pending ints: ");
        !           436:        for (i = 0; i < ARRAYSIZE(dsp_core.interrupt_isPending); i++) {
        !           437:                fprintf(stderr, " %04hx", dsp_core.interrupt_isPending[i]);
        !           438:        }
        !           439:        fputs("\n", stderr);
        !           440: 
        !           441:        fprintf(stderr, "- Hostport:");
        !           442:        for (i = 0; i < ARRAYSIZE(dsp_core.hostport); i++) {
        !           443:                fprintf(stderr, " %02x", dsp_core.hostport[i]);
        !           444:        }
        !           445:        fputs("\n", stderr);
        !           446: #endif
        !           447: }
1.1.1.3   root      448: 
1.1.1.9 ! root      449: /**
        !           450:  * Show DSP register contents
        !           451:  */
1.1.1.3   root      452: void DSP_DisasmRegisters(void)
                    453: {
                    454: #if ENABLE_DSP_EMU
                    455:        Uint32 i;
                    456: 
                    457:        fprintf(stderr,"A: A2: %02x  A1: %06x  A0: %06x\n",
                    458:                dsp_core.registers[DSP_REG_A2], dsp_core.registers[DSP_REG_A1], dsp_core.registers[DSP_REG_A0]);
                    459:        fprintf(stderr,"B: B2: %02x  B1: %06x  B0: %06x\n",
                    460:                dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0]);
                    461:        
                    462:        fprintf(stderr,"X: X1: %06x  X0: %06x\n", dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_X0]);
                    463:        fprintf(stderr,"Y: Y1: %06x  Y0: %06x\n", dsp_core.registers[DSP_REG_Y1], dsp_core.registers[DSP_REG_Y0]);
                    464: 
                    465:        for (i=0; i<8; i++) {
                    466:                fprintf(stderr,"R%01x: %04x   N%01x: %04x   M%01x: %04x\n", 
                    467:                        i, dsp_core.registers[DSP_REG_R0+i],
                    468:                        i, dsp_core.registers[DSP_REG_N0+i],
                    469:                        i, dsp_core.registers[DSP_REG_M0+i]);
                    470:        }
                    471: 
                    472:        fprintf(stderr,"LA: %04x   LC: %04x   PC: %04x\n", dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], dsp_core.pc);
                    473:        fprintf(stderr,"SR: %04x  OMR: %02x\n", dsp_core.registers[DSP_REG_SR], dsp_core.registers[DSP_REG_OMR]);
                    474:        fprintf(stderr,"SP: %02x    SSH: %04x  SSL: %04x\n", 
                    475:                dsp_core.registers[DSP_REG_SP], dsp_core.registers[DSP_REG_SSH], dsp_core.registers[DSP_REG_SSL]);
                    476: #endif
                    477: }
                    478: 
                    479: 
                    480: /**
                    481:  * Get given DSP register address and required bit mask.
                    482:  * Works for A0-2, B0-2, LA, LC, M0-7, N0-7, R0-7, X0-1, Y0-1, PC, SR, SP,
                    483:  * OMR, SSH & SSL registers, but note that the SP, SSH & SSL registers
                    484:  * need special handling (in DSP*SetRegister()) when they are set.
                    485:  * Return the register width in bits or zero for an error.
                    486:  */
                    487: int DSP_GetRegisterAddress(const char *regname, Uint32 **addr, Uint32 *mask)
                    488: {
                    489: #if ENABLE_DSP_EMU
                    490: #define MAX_REGNAME_LEN 4
                    491:        typedef struct {
                    492:                const char name[MAX_REGNAME_LEN];
                    493:                Uint32 *addr;
                    494:                size_t bits;
                    495:                Uint32 mask;
                    496:        } reg_addr_t;
                    497:        
                    498:        /* sorted by name so that this can be bisected */
                    499:        static const reg_addr_t registers[] = {
                    500: 
                    501:                /* 56-bit A register */
                    502:                { "A0",  &dsp_core.registers[DSP_REG_A0],  32, BITMASK(24) },
                    503:                { "A1",  &dsp_core.registers[DSP_REG_A1],  32, BITMASK(24) },
                    504:                { "A2",  &dsp_core.registers[DSP_REG_A2],  32, BITMASK(8) },
                    505: 
                    506:                /* 56-bit B register */
                    507:                { "B0",  &dsp_core.registers[DSP_REG_B0],  32, BITMASK(24) },
                    508:                { "B1",  &dsp_core.registers[DSP_REG_B1],  32, BITMASK(24) },
                    509:                { "B2",  &dsp_core.registers[DSP_REG_B2],  32, BITMASK(8) },
                    510: 
                    511:                /* 16-bit LA & LC registers */
                    512:                { "LA",  &dsp_core.registers[DSP_REG_LA],  32, BITMASK(16) },
                    513:                { "LC",  &dsp_core.registers[DSP_REG_LC],  32, BITMASK(16) },
                    514: 
                    515:                /* 16-bit M registers */
                    516:                { "M0",  &dsp_core.registers[DSP_REG_M0],  32, BITMASK(16) },
                    517:                { "M1",  &dsp_core.registers[DSP_REG_M1],  32, BITMASK(16) },
                    518:                { "M2",  &dsp_core.registers[DSP_REG_M2],  32, BITMASK(16) },
                    519:                { "M3",  &dsp_core.registers[DSP_REG_M3],  32, BITMASK(16) },
                    520:                { "M4",  &dsp_core.registers[DSP_REG_M4],  32, BITMASK(16) },
                    521:                { "M5",  &dsp_core.registers[DSP_REG_M5],  32, BITMASK(16) },
                    522:                { "M6",  &dsp_core.registers[DSP_REG_M6],  32, BITMASK(16) },
                    523:                { "M7",  &dsp_core.registers[DSP_REG_M7],  32, BITMASK(16) },
                    524: 
                    525:                /* 16-bit N registers */
                    526:                { "N0",  &dsp_core.registers[DSP_REG_N0],  32, BITMASK(16) },
                    527:                { "N1",  &dsp_core.registers[DSP_REG_N1],  32, BITMASK(16) },
                    528:                { "N2",  &dsp_core.registers[DSP_REG_N2],  32, BITMASK(16) },
                    529:                { "N3",  &dsp_core.registers[DSP_REG_N3],  32, BITMASK(16) },
                    530:                { "N4",  &dsp_core.registers[DSP_REG_N4],  32, BITMASK(16) },
                    531:                { "N5",  &dsp_core.registers[DSP_REG_N5],  32, BITMASK(16) },
                    532:                { "N6",  &dsp_core.registers[DSP_REG_N6],  32, BITMASK(16) },
                    533:                { "N7",  &dsp_core.registers[DSP_REG_N7],  32, BITMASK(16) },
                    534: 
                    535:                { "OMR", &dsp_core.registers[DSP_REG_OMR], 32, 0x5f },
                    536: 
                    537:                /* 16-bit program counter */
                    538:                { "PC",  (Uint32*)(&dsp_core.pc),  16, BITMASK(16) },
                    539: 
                    540:                /* 16-bit DSP R (address) registers */
                    541:                { "R0",  &dsp_core.registers[DSP_REG_R0],  32, BITMASK(16) },
                    542:                { "R1",  &dsp_core.registers[DSP_REG_R1],  32, BITMASK(16) },
                    543:                { "R2",  &dsp_core.registers[DSP_REG_R2],  32, BITMASK(16) },
                    544:                { "R3",  &dsp_core.registers[DSP_REG_R3],  32, BITMASK(16) },
                    545:                { "R4",  &dsp_core.registers[DSP_REG_R4],  32, BITMASK(16) },
                    546:                { "R5",  &dsp_core.registers[DSP_REG_R5],  32, BITMASK(16) },
                    547:                { "R6",  &dsp_core.registers[DSP_REG_R6],  32, BITMASK(16) },
                    548:                { "R7",  &dsp_core.registers[DSP_REG_R7],  32, BITMASK(16) },
                    549: 
                    550:                { "SSH", &dsp_core.registers[DSP_REG_SSH], 32, BITMASK(16) },
                    551:                { "SSL", &dsp_core.registers[DSP_REG_SSL], 32, BITMASK(16) },
                    552:                { "SP",  &dsp_core.registers[DSP_REG_SP],  32, BITMASK(6) },
                    553: 
                    554:                /* 16-bit status register */
                    555:                { "SR",  &dsp_core.registers[DSP_REG_SR],  32, 0xefff },
                    556: 
                    557:                /* 48-bit X register */
                    558:                { "X0",  &dsp_core.registers[DSP_REG_X0],  32, BITMASK(24) },
                    559:                { "X1",  &dsp_core.registers[DSP_REG_X1],  32, BITMASK(24) },
                    560: 
                    561:                /* 48-bit Y register */
                    562:                { "Y0",  &dsp_core.registers[DSP_REG_Y0],  32, BITMASK(24) },
                    563:                { "Y1",  &dsp_core.registers[DSP_REG_Y1],  32, BITMASK(24) }
                    564:        };
                    565:        /* left, right, middle, direction */
1.1.1.4   root      566:         int l, r, m, dir = 0;
                    567:        unsigned int i, len;
1.1.1.3   root      568:        char reg[MAX_REGNAME_LEN];
                    569: 
1.1.1.4   root      570:        if (!bDspEnabled) {
                    571:                return 0;
                    572:        }
                    573: 
1.1.1.3   root      574:        for (i = 0; i < sizeof(reg) && regname[i]; i++) {
                    575:                reg[i] = toupper(regname[i]);
                    576:        }
                    577:        if (i < 2 || regname[i]) {
                    578:                /* too short or longer than any of the names */
                    579:                return 0;
                    580:        }
1.1.1.4   root      581:        len = i;
                    582:        
1.1.1.3   root      583:        /* bisect */
                    584:        l = 0;
1.1.1.9 ! root      585:        r = ARRAYSIZE(registers) - 1;
1.1.1.3   root      586:        do {
                    587:                m = (l+r) >> 1;
1.1.1.4   root      588:                for (i = 0; i < len; i++) {
1.1.1.3   root      589:                        dir = (int)reg[i] - registers[m].name[i];
                    590:                        if (dir) {
                    591:                                break;
                    592:                        }
                    593:                }
                    594:                if (dir == 0) {
                    595:                        *addr = registers[m].addr;
                    596:                        *mask = registers[m].mask;
                    597:                        return registers[m].bits;
                    598:                }
                    599:                if (dir < 0) {
                    600:                        r = m-1;
                    601:                } else {
                    602:                        l = m+1;
                    603:                }
                    604:        } while (l <= r);
                    605: #undef MAX_REGNAME_LEN
                    606: #endif
                    607:        return 0;
                    608: }
                    609: 
                    610: 
                    611: /**
1.1.1.4   root      612:  * Set given DSP register value, return false if unknown register given
1.1.1.3   root      613:  */
1.1.1.4   root      614: bool DSP_Disasm_SetRegister(const char *arg, Uint32 value)
1.1.1.3   root      615: {
                    616: #if ENABLE_DSP_EMU
                    617:        Uint32 *addr, mask, sp_value;
                    618:        int bits;
                    619: 
                    620:        /* first check registers needing special handling... */
                    621:        if (arg[0]=='S' || arg[0]=='s') {
                    622:                if (arg[1]=='P' || arg[1]=='p') {
                    623:                        dsp_core.registers[DSP_REG_SP] = value & BITMASK(6);
                    624:                        value &= BITMASK(4); 
                    625:                        dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][value];
                    626:                        dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][value];
1.1.1.4   root      627:                        return true;
1.1.1.3   root      628:                }
                    629:                if (arg[1]=='S' || arg[1]=='s') {
                    630:                        sp_value = dsp_core.registers[DSP_REG_SP] & BITMASK(4);
                    631:                        if (arg[2]=='H' || arg[2]=='h') {
                    632:                                if (sp_value == 0) {
                    633:                                        dsp_core.registers[DSP_REG_SSH] = 0;
                    634:                                        dsp_core.stack[0][sp_value] = 0;
                    635:                                } else {
                    636:                                        dsp_core.registers[DSP_REG_SSH] = value & BITMASK(16);
                    637:                                        dsp_core.stack[0][sp_value] = value & BITMASK(16);
                    638:                                }
1.1.1.4   root      639:                                return true;
1.1.1.3   root      640:                        }
                    641:                        if (arg[2]=='L' || arg[2]=='l') {
                    642:                                if (sp_value == 0) {
                    643:                                        dsp_core.registers[DSP_REG_SSL] = 0;
                    644:                                        dsp_core.stack[1][sp_value] = 0;
                    645:                                } else {
                    646:                                        dsp_core.registers[DSP_REG_SSL] = value & BITMASK(16);
                    647:                                        dsp_core.stack[1][sp_value] = value & BITMASK(16);
                    648:                                }
1.1.1.4   root      649:                                return true;
1.1.1.3   root      650:                        }
                    651:                }
                    652:        }
                    653: 
                    654:        /* ...then registers where address & mask are enough */
                    655:        bits = DSP_GetRegisterAddress(arg, &addr, &mask);
                    656:        switch (bits) {
                    657:        case 32:
                    658:                *addr = value & mask;
1.1.1.4   root      659:                return true;
1.1.1.3   root      660:        case 16:
                    661:                *(Uint16*)addr = value & mask;
1.1.1.4   root      662:                return true;
1.1.1.3   root      663:        }
                    664: #endif
1.1.1.4   root      665:        return false;
1.1.1.3   root      666: }
                    667: 
                    668: /**
                    669:  * Read SSI transmit value
                    670:  */
                    671: Uint32 DSP_SsiReadTxValue(void)
                    672: {
                    673: #if ENABLE_DSP_EMU
                    674:        return dsp_core.ssi.transmit_value;
                    675: #else
                    676:        return 0;
                    677: #endif
                    678: }
                    679: 
                    680: /**
                    681:  * Write SSI receive value
                    682:  */
                    683: void DSP_SsiWriteRxValue(Uint32 value)
                    684: {
                    685: #if ENABLE_DSP_EMU
                    686:        dsp_core.ssi.received_value = value & 0xffffff;
                    687: #endif
                    688: }
                    689: 
                    690: /**
                    691:  * Signal SSI clock tick to DSP
                    692:  */
1.1.1.4   root      693: 
                    694: void DSP_SsiReceive_SC0(void)
1.1.1.3   root      695: {
                    696: #if ENABLE_DSP_EMU
1.1.1.5   root      697:        dsp_core_ssi_Receive_SC0();
1.1.1.3   root      698: #endif
                    699: }
                    700: 
1.1.1.4   root      701: void DSP_SsiTransmit_SC0(void)
1.1.1.3   root      702: {
                    703: #if ENABLE_DSP_EMU
                    704: #endif
                    705: }
                    706: 
1.1.1.4   root      707: void DSP_SsiReceive_SC1(Uint32 FrameCounter)
1.1       root      708: {
1.1.1.3   root      709: #if ENABLE_DSP_EMU
1.1.1.5   root      710:        dsp_core_ssi_Receive_SC1(FrameCounter);
1.1       root      711: #endif
1.1.1.4   root      712: }
1.1       root      713: 
1.1.1.4   root      714: void DSP_SsiTransmit_SC1(void)
                    715: {
                    716: #if ENABLE_DSP_EMU
                    717:        Crossbar_DmaPlayInHandShakeMode();
                    718: #endif
1.1       root      719: }
                    720: 
1.1.1.4   root      721: void DSP_SsiReceive_SC2(Uint32 FrameCounter)
1.1       root      722: {
1.1.1.4   root      723: #if ENABLE_DSP_EMU
1.1.1.5   root      724:        dsp_core_ssi_Receive_SC2(FrameCounter);
1.1.1.4   root      725: #endif
                    726: }
                    727: 
                    728: void DSP_SsiTransmit_SC2(Uint32 frame)
                    729: {
                    730: #if ENABLE_DSP_EMU
                    731:        Crossbar_DmaRecordInHandShakeMode_Frame(frame);
                    732: #endif
1.1       root      733: }
                    734: 
1.1.1.4   root      735: void DSP_SsiReceive_SCK(void)
                    736: {
                    737: #if ENABLE_DSP_EMU
1.1.1.5   root      738:        dsp_core_ssi_Receive_SCK();
1.1.1.4   root      739: #endif
                    740: }
                    741: 
                    742: void DSP_SsiTransmit_SCK(void)
                    743: {
                    744: #if ENABLE_DSP_EMU
                    745: #endif
                    746: }
1.1.1.2   root      747: 
1.1.1.3   root      748: /**
1.1.1.4   root      749:  * Read access wrapper for ioMemTabFalcon (DSP Host port)
1.1.1.6   root      750:  * DSP Host interface port is accessed by the 68030 in Byte mode.
                    751:  * A move.w value,$ffA206 results in 2 bus access for the 68030.
1.1.1.3   root      752:  */
1.1.1.4   root      753: void DSP_HandleReadAccess(void)
1.1       root      754: {
1.1.1.4   root      755:        Uint32 addr;
                    756:        Uint8 value;
1.1.1.6   root      757:        bool multi_access = false; 
                    758:        
1.1.1.4   root      759:        for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++)
                    760:        {
1.1.1.3   root      761: #if ENABLE_DSP_EMU
1.1.1.5   root      762:                value = dsp_core_read_host(addr-DSP_HW_OFFSET);
1.1.1.4   root      763: #else
                    764:                /* this value prevents TOS from hanging in the DSP init code */
                    765:                value = 0xff;
1.1       root      766: #endif
1.1.1.9 ! root      767:                if (multi_access == true)
        !           768:                        M68000_AddCycles(4);
        !           769:                multi_access = true;
1.1.1.4   root      770: 
                    771:                Dprintf(("HWget_b(0x%08x)=0x%02x at 0x%08x\n", addr, value, m68k_getpc()));
                    772:                IoMem_WriteByte(addr, value);
                    773:        }
1.1       root      774: }
                    775: 
1.1.1.3   root      776: /**
1.1.1.4   root      777:  * Write access wrapper for ioMemTabFalcon (DSP Host port)
1.1.1.6   root      778:  * DSP Host interface port is accessed by the 68030 in Byte mode.
                    779:  * A move.w value,$ffA206 results in 2 bus access for the 68030.
1.1.1.3   root      780:  */
1.1       root      781: void DSP_HandleWriteAccess(void)
                    782: {
1.1.1.4   root      783:        Uint32 addr;
1.1.1.6   root      784:        bool multi_access = false; 
                    785: 
1.1.1.4   root      786:        for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++)
1.1       root      787:        {
1.1.1.4   root      788: #if ENABLE_DSP_EMU
1.1.1.9 ! root      789:                Uint8 value = IoMem_ReadByte(addr);
        !           790:                Dprintf(("HWput_b(0x%08x,0x%02x) at 0x%08x\n", addr, value, m68k_getpc()));
1.1.1.5   root      791:                dsp_core_write_host(addr-DSP_HW_OFFSET, value);
1.1.1.9 ! root      792: #endif
1.1.1.6   root      793:                if (multi_access == true)
                    794:                        M68000_AddCycles(4);
                    795:                multi_access = true;
1.1       root      796:        }
                    797: }

unix.superglobalmegacorp.com

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