|
|
1.1 ! root 1: /* ! 2: DSP M56001 emulation ! 3: Dummy emulation, Hatari glue ! 4: ! 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: ! 23: #include <ctype.h> ! 24: ! 25: #include "main.h" ! 26: #include "sysdeps.h" ! 27: #include "newcpu.h" ! 28: #include "ioMem.h" ! 29: #include "dsp.h" ! 30: #include "configuration.h" ! 31: #include "cycInt.h" ! 32: #include "statusbar.h" ! 33: #include "m68000.h" ! 34: #include "sysReg.h" ! 35: #include "dma.h" ! 36: ! 37: #if ENABLE_DSP_EMU ! 38: #include "dsp_cpu.h" ! 39: #include "dsp_disasm.h" ! 40: #endif ! 41: ! 42: #define DEBUG 0 ! 43: #if DEBUG ! 44: #define Dprintf(a) printf a ! 45: #else ! 46: #define Dprintf(a) ! 47: #endif ! 48: ! 49: #define LOG_DSP_LEVEL LOG_DEBUG ! 50: ! 51: #define DSP_HW_OFFSET 0xFFA200 ! 52: ! 53: ! 54: #if ENABLE_DSP_EMU ! 55: static const char* x_ext_memory_addr_name[] = { ! 56: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ! 57: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ! 58: "PBC", "PCC", "PBDDR", "PCDDR", "PBD", "PCD", "", "", ! 59: "HCR", "HSR", "", "HRX/HTX", "CRA", "CRB", "SSISR/TSR", "RX/TX", ! 60: "SCR", "SSR", "SCCR", "STXA", "SRX/STX", "SRX/STX", "SRX/STX", "", ! 61: "", "", "", "", "", "", "BCR", "IPR" ! 62: }; ! 63: ! 64: static Sint32 save_cycles; ! 65: #endif ! 66: ! 67: static bool bDspDebugging; ! 68: ! 69: bool bDspEnabled = false; ! 70: bool bDspEmulated = false; ! 71: bool bDspHostInterruptPending = false; ! 72: ! 73: ! 74: /** ! 75: * Handle TXD interrupt at host CPU ! 76: */ ! 77: #if ENABLE_DSP_EMU ! 78: void DSP_HandleTXD(int set) { ! 79: if (set) { ! 80: Log_Printf(LOG_WARN, "[DSP] Set TXD interrupt"); ! 81: //set_dsp_interrupt(SET_INT); ! 82: } else { ! 83: Log_Printf(LOG_WARN, "[DSP] Release TXD interrupt"); ! 84: //set_dsp_interrupt(RELEASE_INT); ! 85: } ! 86: } ! 87: #endif ! 88: ! 89: ! 90: /** ! 91: * Handle HREQ at the host CPU. ! 92: */ ! 93: #if ENABLE_DSP_EMU ! 94: static void DSP_HandleHREQ(int set) ! 95: { ! 96: if (dsp_core.dma_mode) { ! 97: set_dsp_interrupt(RELEASE_INT); ! 98: if (set) { ! 99: dsp_core.dma_request = 1; ! 100: } else { ! 101: dsp_core.dma_request = 0; ! 102: } ! 103: } else { ! 104: dsp_core.dma_request = 0; ! 105: if (set) { ! 106: Log_Printf(LOG_DSP_LEVEL, "[DSP] Set HREQ interrupt"); ! 107: set_dsp_interrupt(SET_INT); ! 108: } else { ! 109: Log_Printf(LOG_DSP_LEVEL, "[DSP] Release HREQ interrupt"); ! 110: set_dsp_interrupt(RELEASE_INT); ! 111: } ! 112: } ! 113: } ! 114: #endif ! 115: ! 116: ! 117: /** ! 118: * Host DSP DMA interface ! 119: */ ! 120: ! 121: /** ! 122: * Set DSP IRQB at the end of a DMA block. ! 123: */ ! 124: void DSP_SetIRQB(void) ! 125: { ! 126: #if ENABLE_DSP_EMU ! 127: if (dsp_intr_at_block_end) { ! 128: dsp_set_interrupt(DSP_INTER_IRQB, 1); ! 129: } ! 130: #endif ! 131: } ! 132: ! 133: ! 134: /** ! 135: * Handling DMA transfers. ! 136: */ ! 137: #if ENABLE_DSP_EMU ! 138: static void DSP_HandleDMA(void) ! 139: { ! 140: if (dsp_core.dma_mode && dsp_core.dma_request && dma_dsp_ready()) { ! 141: /* Set the counter according to selected DMA mode */ ! 142: if (dsp_core.dma_address_counter==0) { ! 143: dsp_core.dma_address_counter = 4-dsp_core.dma_mode; ! 144: /* Handle unpacked mode on Turbo systems */ ! 145: if (dsp_dma_unpacked && ConfigureParams.System.bTurbo) { ! 146: dsp_core.dma_address_counter = 4; ! 147: } ! 148: } ! 149: dsp_core.dma_address_counter--; ! 150: ! 151: /* Read or write via DMA */ ! 152: if (dsp_core.dma_direction==(1<<CPU_HOST_ICR_TREQ)) { ! 153: dsp_core_write_host(CPU_HOST_TRXL-dsp_core.dma_address_counter, dma_dsp_read_memory()); ! 154: } else { ! 155: dma_dsp_write_memory(dsp_core_read_host(CPU_HOST_TRXL-dsp_core.dma_address_counter)); ! 156: } ! 157: ! 158: /* Handle unpacked mode on non-Turbo systems */ ! 159: if (dsp_dma_unpacked && dsp_core.dma_address_counter==0 && !ConfigureParams.System.bTurbo) { ! 160: if (dsp_core.dma_direction==(1<<CPU_HOST_ICR_TREQ)) { ! 161: dsp_core_write_host(CPU_HOST_TRX0, dma_dsp_read_memory()); ! 162: } else { ! 163: dma_dsp_write_memory(dsp_core_read_host(CPU_HOST_TRX0)); ! 164: } ! 165: return; ! 166: } ! 167: } ! 168: } ! 169: #endif ! 170: ! 171: ! 172: /** ! 173: * This function is called from the CPU emulation part when SPCFLAG_DSP is set. ! 174: * If the DSP's IRQ signal is set, we check that SR allows a level 6 interrupt, ! 175: * and if so, we call M68000_Exception. ! 176: */ ! 177: #if ENABLE_DSP_EMU ! 178: bool DSP_ProcessIRQ(void) ! 179: { ! 180: if (bDspHostInterruptPending && regs.intmask < 6) ! 181: { ! 182: M68000_Exception(IoMem_ReadByte(0xffa203)*4, M68000_EXC_SRC_INT_DSP); ! 183: bDspHostInterruptPending = false; ! 184: // M68000_UnsetSpecial(SPCFLAG_DSP); ! 185: return true; ! 186: } ! 187: ! 188: return false; ! 189: } ! 190: #endif ! 191: ! 192: ! 193: /** ! 194: * Initialize the DSP emulation ! 195: */ ! 196: void DSP_Init(void) ! 197: { ! 198: #if ENABLE_DSP_EMU ! 199: if (bDspEnabled) ! 200: return; ! 201: dsp_core_init(DSP_HandleHREQ); ! 202: dsp56k_init_cpu(); ! 203: bDspEnabled = true; ! 204: save_cycles = 0; ! 205: #endif ! 206: } ! 207: ! 208: ! 209: /** ! 210: * Shut down the DSP emulation ! 211: */ ! 212: void DSP_UnInit(void) ! 213: { ! 214: #if ENABLE_DSP_EMU ! 215: if (!bDspEnabled) ! 216: return; ! 217: dsp_core_shutdown(); ! 218: bDspEnabled = false; ! 219: #endif ! 220: } ! 221: ! 222: ! 223: /** ! 224: * Reset the DSP emulation ! 225: */ ! 226: void DSP_Reset(void) ! 227: { ! 228: #if ENABLE_DSP_EMU ! 229: //LogTraceFlags = TRACE_DSP_ALL; ! 230: if (ConfigureParams.System.bDSPMemoryExpansion) { ! 231: DSP_RAMSIZE = DSP_RAMSIZE_96kB; ! 232: } else { ! 233: DSP_RAMSIZE = DSP_RAMSIZE_24kB; ! 234: } ! 235: if (ConfigureParams.System.nDSPType==DSP_TYPE_EMU) { ! 236: bDspEmulated = true; ! 237: } else { ! 238: bDspEmulated = false; ! 239: } ! 240: Statusbar_SetDspLed(false); ! 241: ! 242: dsp_core_reset(); ! 243: save_cycles = 0; ! 244: #endif ! 245: } ! 246: ! 247: ! 248: /** ! 249: * Start the DSP emulation ! 250: */ ! 251: void DSP_Start(Uint8 mode) ! 252: { ! 253: if (!bDspEmulated) { ! 254: return; ! 255: } ! 256: #if ENABLE_DSP_EMU ! 257: dsp_core_start(mode); ! 258: save_cycles = 0; ! 259: #endif ! 260: } ! 261: ! 262: /** ! 263: * Run DSP for certain cycles ! 264: */ ! 265: void DSP_Run(int nHostCycles) ! 266: { ! 267: #if ENABLE_DSP_EMU ! 268: if (dsp_core.running == 0) ! 269: return; ! 270: ! 271: save_cycles += nHostCycles * 2; ! 272: ! 273: if (save_cycles <= 0) ! 274: return; ! 275: ! 276: while (save_cycles > 0) ! 277: { ! 278: dsp56k_execute_instruction(); ! 279: save_cycles -= dsp_core.instr_cycle; ! 280: } ! 281: ! 282: DSP_HandleDMA(); ! 283: #endif ! 284: } ! 285: ! 286: /** ! 287: * Enable/disable DSP debugging mode ! 288: */ ! 289: void DSP_SetDebugging(bool enabled) ! 290: { ! 291: bDspDebugging = enabled; ! 292: } ! 293: ! 294: /** ! 295: * Get DSP program counter (for debugging) ! 296: */ ! 297: Uint16 DSP_GetPC(void) ! 298: { ! 299: #if ENABLE_DSP_EMU ! 300: if (bDspEnabled) ! 301: return dsp_core.pc; ! 302: else ! 303: #endif ! 304: return 0; ! 305: } ! 306: ! 307: /** ! 308: * Get next DSP PC without output (for debugging) ! 309: */ ! 310: Uint16 DSP_GetNextPC(Uint16 pc) ! 311: { ! 312: #if ENABLE_DSP_EMU ! 313: /* code is reduced copy from dsp56k_execute_one_disasm_instruction() */ ! 314: dsp_core_t dsp_core_save; ! 315: Uint16 instruction_length; ! 316: ! 317: if (!bDspEnabled) ! 318: return 0; ! 319: ! 320: /* Save DSP context */ ! 321: memcpy(&dsp_core_save, &dsp_core, sizeof(dsp_core)); ! 322: ! 323: /* Disasm instruction */ ! 324: dsp_core.pc = pc; ! 325: /* why dsp56k_execute_one_disasm_instruction() does "-1" ! 326: * for this value, that doesn't seem right??? ! 327: */ ! 328: instruction_length = dsp56k_disasm(DSP_DISASM_MODE); ! 329: ! 330: /* Restore DSP context */ ! 331: memcpy(&dsp_core, &dsp_core_save, sizeof(dsp_core)); ! 332: ! 333: return pc + instruction_length; ! 334: #else ! 335: return 0; ! 336: #endif ! 337: } ! 338: ! 339: /** ! 340: * Get current DSP instruction cycles (for profiling) ! 341: */ ! 342: Uint16 DSP_GetInstrCycles(void) ! 343: { ! 344: #if ENABLE_DSP_EMU ! 345: if (bDspEnabled) ! 346: return dsp_core.instr_cycle; ! 347: else ! 348: #endif ! 349: return 0; ! 350: } ! 351: ! 352: ! 353: /** ! 354: * Disassemble DSP code between given addresses, return next PC address ! 355: */ ! 356: Uint16 DSP_DisasmAddress(FILE *out, Uint16 lowerAdr, Uint16 UpperAdr) ! 357: { ! 358: #if ENABLE_DSP_EMU ! 359: Uint16 dsp_pc; ! 360: ! 361: for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) { ! 362: dsp_pc += dsp56k_execute_one_disasm_instruction(out, dsp_pc); ! 363: } ! 364: return dsp_pc; ! 365: #else ! 366: return 0; ! 367: #endif ! 368: } ! 369: ! 370: ! 371: /** ! 372: * Get the value from the given (16-bit) DSP memory address / space ! 373: * exactly the same way as in dsp_cpu.c::read_memory() (except for ! 374: * the host/transmit peripheral register values which access has ! 375: * side-effects). Set the mem_str to suitable string for that ! 376: * address / space. ! 377: * Return the value at given address. For valid values AND the return ! 378: * value with BITMASK(24). ! 379: */ ! 380: Uint32 DSP_ReadMemory(Uint16 address, char space_id, const char **mem_str) ! 381: { ! 382: #if ENABLE_DSP_EMU ! 383: static const char *spaces[3][4] = { ! 384: { "X ram", "X rom", "X", "X periph" }, ! 385: { "Y ram", "Y rom", "Y", "Y periph" }, ! 386: { "P ram", "P ram", "P ext memory", "P ext memory" } ! 387: }; ! 388: int idx, space; ! 389: ! 390: switch (space_id) { ! 391: case 'X': ! 392: space = DSP_SPACE_X; ! 393: idx = 0; ! 394: break; ! 395: case 'Y': ! 396: space = DSP_SPACE_Y; ! 397: idx = 1; ! 398: break; ! 399: case 'P': ! 400: space = DSP_SPACE_P; ! 401: idx = 2; ! 402: break; ! 403: default: ! 404: space = DSP_SPACE_X; ! 405: idx = 0; ! 406: } ! 407: address &= 0xFFFF; ! 408: ! 409: /* Internal RAM ? */ ! 410: if (address < 0x100) { ! 411: *mem_str = spaces[idx][0]; ! 412: return dsp_core.ramint[space][address]; ! 413: } ! 414: ! 415: if (space == DSP_SPACE_P) { ! 416: /* Internal RAM ? */ ! 417: if (address < 0x200) { ! 418: *mem_str = spaces[idx][0]; ! 419: return dsp_core.ramint[DSP_SPACE_P][address]; ! 420: } ! 421: /* External RAM, mask address to available ram size */ ! 422: *mem_str = spaces[idx][2]; ! 423: return dsp_core.ramext[address & (DSP_RAMSIZE-1)]; ! 424: } ! 425: ! 426: /* Internal ROM ? */ ! 427: if (address < 0x200) { ! 428: if (dsp_core.registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) { ! 429: *mem_str = spaces[idx][1]; ! 430: return dsp_core.rom[space][address]; ! 431: } ! 432: } ! 433: ! 434: /* Peripheral address ? */ ! 435: if (address >= 0xffc0) { ! 436: *mem_str = spaces[idx][3]; ! 437: /* reading host/transmit regs has side-effects, ! 438: * so just give the memory value. ! 439: */ ! 440: return dsp_core.periph[space][address-0xffc0]; ! 441: } ! 442: ! 443: /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ ! 444: address &= (DSP_RAMSIZE>>1) - 1; ! 445: if (space == DSP_SPACE_X) { ! 446: address += DSP_RAMSIZE>>1; ! 447: } ! 448: ! 449: /* Falcon: External RAM, finally map X,Y to P */ ! 450: *mem_str = spaces[idx][2]; ! 451: return dsp_core.ramext[address & (DSP_RAMSIZE-1)]; ! 452: #endif ! 453: return 0; ! 454: } ! 455: ! 456: ! 457: /** ! 458: * Output memory values between given addresses in given DSP address space. ! 459: * Return next DSP address value. ! 460: */ ! 461: Uint16 DSP_DisasmMemory(Uint16 dsp_memdump_addr, Uint16 dsp_memdump_upper, char space) ! 462: { ! 463: #if ENABLE_DSP_EMU ! 464: Uint32 mem, mem2, value; ! 465: const char *mem_str; ! 466: ! 467: for (mem = dsp_memdump_addr; mem <= dsp_memdump_upper; mem++) { ! 468: /* special printing of host communication/transmit registers */ ! 469: if (space == 'X' && mem >= 0xffc0) { ! 470: if (mem == 0xffeb) { ! 471: fprintf(stderr,"X periph:%04x HTX : %06x RTX:%06x\n", ! 472: mem, dsp_core.dsp_host_htx, dsp_core.dsp_host_rtx); ! 473: } ! 474: else if (mem == 0xffef) { ! 475: fprintf(stderr,"X periph:%04x SSI TX : %06x SSI RX:%06x\n", ! 476: mem, dsp_core.ssi.transmit_value, dsp_core.ssi.received_value); ! 477: } ! 478: else { ! 479: value = DSP_ReadMemory(mem, space, &mem_str); ! 480: fprintf(stderr,"%s:%04x %06x\t%s\n", mem_str, mem, value, x_ext_memory_addr_name[mem-0xffc0]); ! 481: } ! 482: continue; ! 483: } ! 484: /* special printing of X & Y external RAM values */ ! 485: if ((space == 'X' || space == 'Y') && ! 486: mem >= 0x200 && mem < 0xffc0) { ! 487: mem2 = mem & ((DSP_RAMSIZE>>1)-1); ! 488: if (space == 'X') { ! 489: mem2 += (DSP_RAMSIZE>>1); ! 490: } ! 491: fprintf(stderr,"%c:%04x (P:%04x): %06x\n", space, ! 492: mem, mem2, dsp_core.ramext[mem2 & (DSP_RAMSIZE-1)]); ! 493: continue; ! 494: } ! 495: value = DSP_ReadMemory(mem, space, &mem_str); ! 496: fprintf(stderr,"%s:%04x %06x\n", mem_str, mem, value); ! 497: } ! 498: #endif ! 499: return dsp_memdump_upper+1; ! 500: } ! 501: ! 502: /** ! 503: * Show information on DSP core state which isn't ! 504: * shown by any of the other commands (dd, dm, dr). ! 505: */ ! 506: void DSP_Info(Uint32 dummy) ! 507: { ! 508: #if ENABLE_DSP_EMU ! 509: int i, j; ! 510: const char *stackname[] = { "SSH", "SSL" }; ! 511: ! 512: fputs("DSP core information:\n", stderr); ! 513: ! 514: for (i = 0; i < ARRAYSIZE(stackname); i++) { ! 515: fprintf(stderr, "- %s stack:", stackname[i]); ! 516: for (j = 0; j < ARRAYSIZE(dsp_core.stack[0]); j++) { ! 517: fprintf(stderr, " %04hx", dsp_core.stack[i][j]); ! 518: } ! 519: fputs("\n", stderr); ! 520: } ! 521: ! 522: fprintf(stderr, "- Interrupts:\n"); ! 523: for (i = 0; i < 32; i++) { ! 524: fprintf(stderr, "%s: ", dsp_interrupt_name[i]); ! 525: if ((1<<i) & dsp_core.interrupt_status & (dsp_core.interrupt_mask|DSP_INTER_NMI_MASK)) { ! 526: fprintf(stderr, "Pending "); ! 527: } ! 528: if ((1<<i) & DSP_INTER_NMI_MASK) { ! 529: fprintf(stderr, "at level 3"); ! 530: } else { ! 531: for (j = 2; j>=0; j--) { ! 532: if ((1<<i) & dsp_core.interrupt_mask_level[j]) { ! 533: fprintf(stderr, "at level %i", j); ! 534: } ! 535: } ! 536: } ! 537: fputs("\n", stderr); ! 538: } ! 539: fprintf(stderr, "- Hostport:"); ! 540: for (i = 0; i < ARRAYSIZE(dsp_core.hostport); i++) { ! 541: fprintf(stderr, " %02x", dsp_core.hostport[i]); ! 542: } ! 543: fputs("\n", stderr); ! 544: #endif ! 545: } ! 546: ! 547: /** ! 548: * Show DSP register contents ! 549: */ ! 550: void DSP_DisasmRegisters(void) ! 551: { ! 552: #if ENABLE_DSP_EMU ! 553: Uint32 i; ! 554: ! 555: fprintf(stderr,"A: A2: %02x A1: %06x A0: %06x\n", ! 556: dsp_core.registers[DSP_REG_A2], dsp_core.registers[DSP_REG_A1], dsp_core.registers[DSP_REG_A0]); ! 557: fprintf(stderr,"B: B2: %02x B1: %06x B0: %06x\n", ! 558: dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0]); ! 559: ! 560: fprintf(stderr,"X: X1: %06x X0: %06x\n", dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_X0]); ! 561: fprintf(stderr,"Y: Y1: %06x Y0: %06x\n", dsp_core.registers[DSP_REG_Y1], dsp_core.registers[DSP_REG_Y0]); ! 562: ! 563: for (i=0; i<8; i++) { ! 564: fprintf(stderr,"R%01x: %04x N%01x: %04x M%01x: %04x\n", ! 565: i, dsp_core.registers[DSP_REG_R0+i], ! 566: i, dsp_core.registers[DSP_REG_N0+i], ! 567: i, dsp_core.registers[DSP_REG_M0+i]); ! 568: } ! 569: ! 570: fprintf(stderr,"LA: %04x LC: %04x PC: %04x\n", dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], dsp_core.pc); ! 571: fprintf(stderr,"SR: %04x OMR: %02x\n", dsp_core.registers[DSP_REG_SR], dsp_core.registers[DSP_REG_OMR]); ! 572: fprintf(stderr,"SP: %02x SSH: %04x SSL: %04x\n", ! 573: dsp_core.registers[DSP_REG_SP], dsp_core.registers[DSP_REG_SSH], dsp_core.registers[DSP_REG_SSL]); ! 574: #endif ! 575: } ! 576: ! 577: ! 578: /** ! 579: * Get given DSP register address and required bit mask. ! 580: * Works for A0-2, B0-2, LA, LC, M0-7, N0-7, R0-7, X0-1, Y0-1, PC, SR, SP, ! 581: * OMR, SSH & SSL registers, but note that the SP, SSH & SSL registers ! 582: * need special handling (in DSP*SetRegister()) when they are set. ! 583: * Return the register width in bits or zero for an error. ! 584: */ ! 585: int DSP_GetRegisterAddress(const char *regname, Uint32 **addr, Uint32 *mask) ! 586: { ! 587: #if ENABLE_DSP_EMU ! 588: #define MAX_REGNAME_LEN 4 ! 589: typedef struct { ! 590: const char name[MAX_REGNAME_LEN]; ! 591: Uint32 *addr; ! 592: size_t bits; ! 593: Uint32 mask; ! 594: } reg_addr_t; ! 595: ! 596: /* sorted by name so that this can be bisected */ ! 597: static const reg_addr_t registers[] = { ! 598: ! 599: /* 56-bit A register */ ! 600: { "A0", &dsp_core.registers[DSP_REG_A0], 32, BITMASK(24) }, ! 601: { "A1", &dsp_core.registers[DSP_REG_A1], 32, BITMASK(24) }, ! 602: { "A2", &dsp_core.registers[DSP_REG_A2], 32, BITMASK(8) }, ! 603: ! 604: /* 56-bit B register */ ! 605: { "B0", &dsp_core.registers[DSP_REG_B0], 32, BITMASK(24) }, ! 606: { "B1", &dsp_core.registers[DSP_REG_B1], 32, BITMASK(24) }, ! 607: { "B2", &dsp_core.registers[DSP_REG_B2], 32, BITMASK(8) }, ! 608: ! 609: /* 16-bit LA & LC registers */ ! 610: { "LA", &dsp_core.registers[DSP_REG_LA], 32, BITMASK(16) }, ! 611: { "LC", &dsp_core.registers[DSP_REG_LC], 32, BITMASK(16) }, ! 612: ! 613: /* 16-bit M registers */ ! 614: { "M0", &dsp_core.registers[DSP_REG_M0], 32, BITMASK(16) }, ! 615: { "M1", &dsp_core.registers[DSP_REG_M1], 32, BITMASK(16) }, ! 616: { "M2", &dsp_core.registers[DSP_REG_M2], 32, BITMASK(16) }, ! 617: { "M3", &dsp_core.registers[DSP_REG_M3], 32, BITMASK(16) }, ! 618: { "M4", &dsp_core.registers[DSP_REG_M4], 32, BITMASK(16) }, ! 619: { "M5", &dsp_core.registers[DSP_REG_M5], 32, BITMASK(16) }, ! 620: { "M6", &dsp_core.registers[DSP_REG_M6], 32, BITMASK(16) }, ! 621: { "M7", &dsp_core.registers[DSP_REG_M7], 32, BITMASK(16) }, ! 622: ! 623: /* 16-bit N registers */ ! 624: { "N0", &dsp_core.registers[DSP_REG_N0], 32, BITMASK(16) }, ! 625: { "N1", &dsp_core.registers[DSP_REG_N1], 32, BITMASK(16) }, ! 626: { "N2", &dsp_core.registers[DSP_REG_N2], 32, BITMASK(16) }, ! 627: { "N3", &dsp_core.registers[DSP_REG_N3], 32, BITMASK(16) }, ! 628: { "N4", &dsp_core.registers[DSP_REG_N4], 32, BITMASK(16) }, ! 629: { "N5", &dsp_core.registers[DSP_REG_N5], 32, BITMASK(16) }, ! 630: { "N6", &dsp_core.registers[DSP_REG_N6], 32, BITMASK(16) }, ! 631: { "N7", &dsp_core.registers[DSP_REG_N7], 32, BITMASK(16) }, ! 632: ! 633: { "OMR", &dsp_core.registers[DSP_REG_OMR], 32, 0x5f }, ! 634: ! 635: /* 16-bit program counter */ ! 636: { "PC", (Uint32*)(&dsp_core.pc), 16, BITMASK(16) }, ! 637: ! 638: /* 16-bit DSP R (address) registers */ ! 639: { "R0", &dsp_core.registers[DSP_REG_R0], 32, BITMASK(16) }, ! 640: { "R1", &dsp_core.registers[DSP_REG_R1], 32, BITMASK(16) }, ! 641: { "R2", &dsp_core.registers[DSP_REG_R2], 32, BITMASK(16) }, ! 642: { "R3", &dsp_core.registers[DSP_REG_R3], 32, BITMASK(16) }, ! 643: { "R4", &dsp_core.registers[DSP_REG_R4], 32, BITMASK(16) }, ! 644: { "R5", &dsp_core.registers[DSP_REG_R5], 32, BITMASK(16) }, ! 645: { "R6", &dsp_core.registers[DSP_REG_R6], 32, BITMASK(16) }, ! 646: { "R7", &dsp_core.registers[DSP_REG_R7], 32, BITMASK(16) }, ! 647: ! 648: { "SSH", &dsp_core.registers[DSP_REG_SSH], 32, BITMASK(16) }, ! 649: { "SSL", &dsp_core.registers[DSP_REG_SSL], 32, BITMASK(16) }, ! 650: { "SP", &dsp_core.registers[DSP_REG_SP], 32, BITMASK(6) }, ! 651: ! 652: /* 16-bit status register */ ! 653: { "SR", &dsp_core.registers[DSP_REG_SR], 32, 0xefff }, ! 654: ! 655: /* 48-bit X register */ ! 656: { "X0", &dsp_core.registers[DSP_REG_X0], 32, BITMASK(24) }, ! 657: { "X1", &dsp_core.registers[DSP_REG_X1], 32, BITMASK(24) }, ! 658: ! 659: /* 48-bit Y register */ ! 660: { "Y0", &dsp_core.registers[DSP_REG_Y0], 32, BITMASK(24) }, ! 661: { "Y1", &dsp_core.registers[DSP_REG_Y1], 32, BITMASK(24) } ! 662: }; ! 663: /* left, right, middle, direction */ ! 664: int l, r, m, dir = 0; ! 665: unsigned int i, len; ! 666: char reg[MAX_REGNAME_LEN]; ! 667: ! 668: if (!bDspEnabled) { ! 669: return 0; ! 670: } ! 671: ! 672: for (i = 0; i < sizeof(reg) && regname[i]; i++) { ! 673: reg[i] = toupper((unsigned char)regname[i]); ! 674: } ! 675: if (i < 2 || regname[i]) { ! 676: /* too short or longer than any of the names */ ! 677: return 0; ! 678: } ! 679: len = i; ! 680: ! 681: /* bisect */ ! 682: l = 0; ! 683: r = ARRAYSIZE(registers) - 1; ! 684: do { ! 685: m = (l+r) >> 1; ! 686: for (i = 0; i < len; i++) { ! 687: dir = (int)reg[i] - registers[m].name[i]; ! 688: if (dir) { ! 689: break; ! 690: } ! 691: } ! 692: if (dir == 0) { ! 693: *addr = registers[m].addr; ! 694: *mask = registers[m].mask; ! 695: return registers[m].bits; ! 696: } ! 697: if (dir < 0) { ! 698: r = m-1; ! 699: } else { ! 700: l = m+1; ! 701: } ! 702: } while (l <= r); ! 703: #undef MAX_REGNAME_LEN ! 704: #endif ! 705: return 0; ! 706: } ! 707: ! 708: ! 709: /** ! 710: * Set given DSP register value, return false if unknown register given ! 711: */ ! 712: bool DSP_Disasm_SetRegister(const char *arg, Uint32 value) ! 713: { ! 714: #if ENABLE_DSP_EMU ! 715: Uint32 *addr, mask, sp_value; ! 716: int bits; ! 717: ! 718: /* first check registers needing special handling... */ ! 719: if (arg[0]=='S' || arg[0]=='s') { ! 720: if (arg[1]=='P' || arg[1]=='p') { ! 721: dsp_core.registers[DSP_REG_SP] = value & BITMASK(6); ! 722: value &= BITMASK(4); ! 723: dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][value]; ! 724: dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][value]; ! 725: return true; ! 726: } ! 727: if (arg[1]=='S' || arg[1]=='s') { ! 728: sp_value = dsp_core.registers[DSP_REG_SP] & BITMASK(4); ! 729: if (arg[2]=='H' || arg[2]=='h') { ! 730: if (sp_value == 0) { ! 731: dsp_core.registers[DSP_REG_SSH] = 0; ! 732: dsp_core.stack[0][sp_value] = 0; ! 733: } else { ! 734: dsp_core.registers[DSP_REG_SSH] = value & BITMASK(16); ! 735: dsp_core.stack[0][sp_value] = value & BITMASK(16); ! 736: } ! 737: return true; ! 738: } ! 739: if (arg[2]=='L' || arg[2]=='l') { ! 740: if (sp_value == 0) { ! 741: dsp_core.registers[DSP_REG_SSL] = 0; ! 742: dsp_core.stack[1][sp_value] = 0; ! 743: } else { ! 744: dsp_core.registers[DSP_REG_SSL] = value & BITMASK(16); ! 745: dsp_core.stack[1][sp_value] = value & BITMASK(16); ! 746: } ! 747: return true; ! 748: } ! 749: } ! 750: } ! 751: ! 752: /* ...then registers where address & mask are enough */ ! 753: bits = DSP_GetRegisterAddress(arg, &addr, &mask); ! 754: switch (bits) { ! 755: case 32: ! 756: *addr = value & mask; ! 757: return true; ! 758: case 16: ! 759: *(Uint16*)addr = value & mask; ! 760: return true; ! 761: } ! 762: #endif ! 763: return false; ! 764: } ! 765: ! 766: /** ! 767: * Read SSI transmit value ! 768: */ ! 769: Uint32 DSP_SsiReadTxValue(void) ! 770: { ! 771: #if ENABLE_DSP_EMU ! 772: return dsp_core.ssi.transmit_value; ! 773: #else ! 774: return 0; ! 775: #endif ! 776: } ! 777: ! 778: /** ! 779: * Write SSI receive value ! 780: */ ! 781: void DSP_SsiWriteRxValue(Uint32 value) ! 782: { ! 783: #if ENABLE_DSP_EMU ! 784: dsp_core.ssi.received_value = value & 0xffffff; ! 785: #endif ! 786: } ! 787: ! 788: /** ! 789: * Signal SSI clock tick to DSP ! 790: */ ! 791: ! 792: void DSP_SsiReceive_SC0(void) ! 793: { ! 794: #if ENABLE_DSP_EMU ! 795: dsp_core_ssi_Receive_SC0(); ! 796: #endif ! 797: } ! 798: ! 799: void DSP_SsiTransmit_SC0(void) ! 800: { ! 801: #if ENABLE_DSP_EMU ! 802: #endif ! 803: } ! 804: ! 805: void DSP_SsiReceive_SC1(Uint32 FrameCounter) ! 806: { ! 807: #if ENABLE_DSP_EMU ! 808: dsp_core_ssi_Receive_SC1(FrameCounter); ! 809: #endif ! 810: } ! 811: ! 812: void DSP_SsiTransmit_SC1(void) ! 813: { ! 814: #if ENABLE_DSP_EMU ! 815: // Crossbar_DmaPlayInHandShakeMode(); ! 816: #endif ! 817: } ! 818: ! 819: void DSP_SsiReceive_SC2(Uint32 FrameCounter) ! 820: { ! 821: #if ENABLE_DSP_EMU ! 822: dsp_core_ssi_Receive_SC2(FrameCounter); ! 823: #endif ! 824: } ! 825: ! 826: void DSP_SsiTransmit_SC2(Uint32 frame) ! 827: { ! 828: #if ENABLE_DSP_EMU ! 829: // Crossbar_DmaRecordInHandShakeMode_Frame(frame); ! 830: #endif ! 831: } ! 832: ! 833: void DSP_SsiReceive_SCK(void) ! 834: { ! 835: #if ENABLE_DSP_EMU ! 836: dsp_core_ssi_Receive_SCK(); ! 837: #endif ! 838: } ! 839: ! 840: void DSP_SsiTransmit_SCK(void) ! 841: { ! 842: #if ENABLE_DSP_EMU ! 843: #endif ! 844: } ! 845: ! 846: /** ! 847: * Read access wrapper for ioMemTabFalcon (DSP Host port) ! 848: * DSP Host interface port is accessed by the 68030 in Byte mode. ! 849: * A move.w value,$ffA206 results in 2 bus access for the 68030. ! 850: */ ! 851: void DSP_HandleReadAccess(void) ! 852: { ! 853: Uint32 addr; ! 854: Uint8 value; ! 855: bool multi_access = false; ! 856: ! 857: for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++) ! 858: { ! 859: #if ENABLE_DSP_EMU ! 860: value = dsp_core_read_host(addr-DSP_HW_OFFSET); ! 861: #else ! 862: /* this value prevents TOS from hanging in the DSP init code */ ! 863: value = 0xff; ! 864: #endif ! 865: if (multi_access == true) ! 866: M68000_AddCycles(4); ! 867: multi_access = true; ! 868: ! 869: Dprintf(("HWget_b(0x%08x)=0x%02x at 0x%08x\n", addr, value, m68k_getpc())); ! 870: IoMem_WriteByte(addr, value); ! 871: } ! 872: } ! 873: ! 874: /** ! 875: * Write access wrapper for ioMemTabFalcon (DSP Host port) ! 876: * DSP Host interface port is accessed by the 68030 in Byte mode. ! 877: * A move.w value,$ffA206 results in 2 bus access for the 68030. ! 878: */ ! 879: void DSP_HandleWriteAccess(void) ! 880: { ! 881: Uint32 addr; ! 882: bool multi_access = false; ! 883: ! 884: for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++) ! 885: { ! 886: #if ENABLE_DSP_EMU ! 887: Uint8 value = IoMem_ReadByte(addr); ! 888: Dprintf(("HWput_b(0x%08x,0x%02x) at 0x%08x\n", addr, value, m68k_getpc())); ! 889: dsp_core_write_host(addr-DSP_HW_OFFSET, value); ! 890: #endif ! 891: if (multi_access == true) ! 892: M68000_AddCycles(4); ! 893: multi_access = true; ! 894: } ! 895: } ! 896: ! 897: ! 898: ! 899: /* Previous Register Access */ ! 900: #define LOG_DSP_REG_LEVEL LOG_DEBUG ! 901: ! 902: #define IO_SEG_MASK 0x1FFFF ! 903: ! 904: /* Register bits */ ! 905: ! 906: #define ICR_INIT 0x80 ! 907: #define ICR_HM1 0x40 ! 908: #define ICR_HM0 0x20 ! 909: #define ICR_HF1 0x10 ! 910: #define ICR_HF0 0x08 ! 911: #define ICR_TREQ 0x02 ! 912: #define ICR_RREQ 0x01 ! 913: ! 914: #define CVR_HC 0x80 ! 915: #define CVR_HV 0x1F ! 916: ! 917: #define ISR_HREQ 0x80 ! 918: #define ISR_DMA 0x40 ! 919: #define ISR_HF3 0x10 ! 920: #define ISR_HF2 0x08 ! 921: #define ISR_TRDY 0x04 ! 922: #define ISR_TXDE 0x02 ! 923: #define ISR_RXDF 0x01 ! 924: ! 925: ! 926: void DSP_ICR_Read(void) { // 0x02008000 ! 927: #if ENABLE_DSP_EMU ! 928: if (bDspEmulated) ! 929: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_ICR); ! 930: else ! 931: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x7F; ! 932: #else ! 933: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x7F; ! 934: #endif ! 935: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] ICR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 936: } ! 937: ! 938: void DSP_ICR_Write(void) { ! 939: #if ENABLE_DSP_EMU ! 940: if (bDspEmulated) ! 941: dsp_core_write_host(CPU_HOST_ICR, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 942: #endif ! 943: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] ICR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 944: } ! 945: ! 946: void DSP_CVR_Read(void) { // 0x02008001 ! 947: #if ENABLE_DSP_EMU ! 948: if (bDspEmulated) ! 949: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_CVR); ! 950: else ! 951: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 952: #else ! 953: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 954: #endif ! 955: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] CVR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 956: } ! 957: ! 958: void DSP_CVR_Write(void) { ! 959: #if ENABLE_DSP_EMU ! 960: if (bDspEmulated) ! 961: dsp_core_write_host(CPU_HOST_CVR, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 962: #endif ! 963: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] CVR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 964: } ! 965: ! 966: void DSP_ISR_Read(void) { // 0x02008002 ! 967: #if ENABLE_DSP_EMU ! 968: if (bDspEmulated) ! 969: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_ISR); ! 970: else ! 971: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 972: #else ! 973: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 974: #endif ! 975: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] ISR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 976: } ! 977: ! 978: void DSP_ISR_Write(void) { ! 979: #if ENABLE_DSP_EMU ! 980: if (bDspEmulated) ! 981: dsp_core_write_host(CPU_HOST_ISR, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 982: #endif ! 983: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] ISR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 984: } ! 985: ! 986: void DSP_IVR_Read(void) { // 0x02008003 ! 987: #if ENABLE_DSP_EMU ! 988: if (bDspEmulated) ! 989: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_IVR); ! 990: else ! 991: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 992: #else ! 993: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0xFF; ! 994: #endif ! 995: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] IVR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 996: } ! 997: ! 998: void DSP_IVR_Write(void) { ! 999: #if ENABLE_DSP_EMU ! 1000: if (bDspEmulated) ! 1001: dsp_core_write_host(CPU_HOST_IVR, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 1002: #endif ! 1003: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] IVR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1004: } ! 1005: ! 1006: void DSP_Data0_Read(void) { // 0x02008004 ! 1007: #if ENABLE_DSP_EMU ! 1008: if (bDspEmulated) ! 1009: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_TRX0); ! 1010: else ! 1011: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1012: #else ! 1013: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1014: #endif ! 1015: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data0 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1016: } ! 1017: ! 1018: void DSP_Data0_Write(void) { ! 1019: #if ENABLE_DSP_EMU ! 1020: if (bDspEmulated) ! 1021: dsp_core_write_host(CPU_HOST_TRX0, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 1022: #endif ! 1023: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data0 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1024: } ! 1025: ! 1026: void DSP_Data1_Read(void) { // 0x02008005 ! 1027: #if ENABLE_DSP_EMU ! 1028: if (bDspEmulated) ! 1029: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_TRXH); ! 1030: else ! 1031: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1032: #else ! 1033: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1034: #endif ! 1035: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data1 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1036: } ! 1037: ! 1038: void DSP_Data1_Write(void) { ! 1039: #if ENABLE_DSP_EMU ! 1040: if (bDspEmulated) ! 1041: dsp_core_write_host(CPU_HOST_TRXH, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 1042: #endif ! 1043: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data1 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1044: } ! 1045: ! 1046: void DSP_Data2_Read(void) { // 0x02008006 ! 1047: #if ENABLE_DSP_EMU ! 1048: if (bDspEmulated) ! 1049: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_TRXM); ! 1050: else ! 1051: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1052: #else ! 1053: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1054: #endif ! 1055: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data2 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1056: } ! 1057: ! 1058: void DSP_Data2_Write(void) { ! 1059: #if ENABLE_DSP_EMU ! 1060: if (bDspEmulated) ! 1061: dsp_core_write_host(CPU_HOST_TRXM, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 1062: #endif ! 1063: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1064: } ! 1065: ! 1066: void DSP_Data3_Read(void) { // 0x02008007 ! 1067: #if ENABLE_DSP_EMU ! 1068: if (bDspEmulated) ! 1069: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dsp_core_read_host(CPU_HOST_TRXL); ! 1070: else ! 1071: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1072: #else ! 1073: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00; ! 1074: #endif ! 1075: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data3 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1076: } ! 1077: ! 1078: void DSP_Data3_Write(void) { ! 1079: #if ENABLE_DSP_EMU ! 1080: if (bDspEmulated) ! 1081: dsp_core_write_host(CPU_HOST_TRXL, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]); ! 1082: #endif ! 1083: Log_Printf(LOG_DSP_REG_LEVEL,"[DSP] Data3 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); ! 1084: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.