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