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