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

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

unix.superglobalmegacorp.com

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