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