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