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