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