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

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

unix.superglobalmegacorp.com

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