1 #include "adsp2100/adsp2100.h"
2 #include "adsp2100_intf.h"
3
4 //#define xlog(...) fprintf(stdout, "dcs: " __VA_ARGS__); fflush(stdout)
5 #define xlog(...)
6
7 #define ENABLE_TRACE 0
8
9 #define ADDR_BITS 16
10 #define PAGE_SIZE 0x100
11 #define PAGE_SHIFT 8
12 #define PAGE_MASK 0xFF
13 #define PAGE_COUNT (1 << (ADDR_BITS - PAGE_SHIFT))
14 #define PAGE_WADD (PAGE_COUNT)
15 #define ADSP_MAXHANDLER 10
16 #define PFN(x) ((x >> PAGE_SHIFT) & 0xFF)
17
18 struct Adsp2100MemoryMap
19 {
20 UINT8 *PrgMap[PAGE_COUNT * 2];
21 UINT8 *DataMap[PAGE_COUNT * 2];
22
23 pAdsp2100ReadLongHandler prgReadLong[ADSP_MAXHANDLER];
24 pAdsp2100WriteLongHandler prgWriteLong[ADSP_MAXHANDLER];
25 pAdsp2100ReadWordHandler dataReadWord[ADSP_MAXHANDLER];
26 pAdsp2100WriteWordHandler dataWriteWord[ADSP_MAXHANDLER];
27 };
28
29 static Adsp2100MemoryMap *pMemMap;
30 static adsp2100_state *pADSP;
31
32 static pAdsp2100RxCallback pRxCallback;
33 static pAdsp2100TxCallback pTxCallback;
34 static pAdsp2100TimerCallback pTimerCallback;
35
36 #if ENABLE_TRACE
37 static FILE *pTrace;
38 #endif
39
DefReadWord(unsigned int a)40 static unsigned short DefReadWord(unsigned int a) { xlog("DefReadWord %x\n", a); return 0; }
DefReadLong(unsigned int a)41 static unsigned int DefReadLong(unsigned int a) { xlog("DefReadLong %x\n", a); return 0; }
42
DefWriteWord(unsigned int a,unsigned short value)43 static void DefWriteWord(unsigned int a, unsigned short value) { xlog("DefWriteWord %x - %x\n", a, value); }
DefWriteLong(unsigned int a,unsigned int value)44 static void DefWriteLong(unsigned int a, unsigned int value) { xlog("DefWriteLog %x - %x\n", a, value); }
45
ResetMemoryMap()46 static void ResetMemoryMap()
47 {
48 for (int page = 0; page < PAGE_COUNT; page++) {
49 pMemMap->PrgMap[page] = (unsigned char*) 0;
50 pMemMap->PrgMap[PAGE_WADD + page] = (unsigned char*) 0;
51 pMemMap->DataMap[page] = (unsigned char*) 0;
52 pMemMap->DataMap[PAGE_WADD + page] = (unsigned char*) 0;
53
54 }
55
56 for (int i = 0; i < ADSP_MAXHANDLER; i++) {
57 pMemMap->prgReadLong[i] = DefReadLong;
58 pMemMap->prgWriteLong[i] = DefWriteLong;
59
60 pMemMap->dataWriteWord[i] = DefWriteWord;
61 pMemMap->dataReadWord[i] = DefReadWord;
62 }
63 }
64
RxCallback(adsp2100_state * adsp,int port)65 static int RxCallback(adsp2100_state *adsp, int port)
66 {
67 if (pRxCallback)
68 return pRxCallback(port);
69 return 0;
70 }
71
TxCallback(adsp2100_state * adsp,int port,int data)72 static void TxCallback(adsp2100_state *adsp, int port, int data)
73 {
74 if (pTxCallback)
75 pTxCallback(port, data);
76 }
77
TimerCallback(adsp2100_state * adsp,int enable)78 static void TimerCallback(adsp2100_state *adsp, int enable)
79 {
80 if (pTimerCallback)
81 pTimerCallback(enable);
82 }
83
84
Adsp2100Init()85 int Adsp2100Init()
86 {
87 pMemMap = new Adsp2100MemoryMap;
88 ResetMemoryMap();
89 pADSP = (adsp2100_state*) BurnMalloc(sizeof(adsp2100_state));
90 adsp2105_init(pADSP, NULL);
91 pADSP->sport_rx_callback = RxCallback;
92 pADSP->sport_tx_callback = TxCallback;
93 pADSP->timer_fired = TimerCallback;
94
95 pTimerCallback = NULL;
96 pTxCallback = NULL;
97 pRxCallback = NULL;
98
99 #if ENABLE_TRACE
100 pTrace = fopen("adsp21xx.txt", "w");
101 #endif
102 return 0;
103 }
104
Adsp2100Exit()105 int Adsp2100Exit()
106 {
107 adsp21xx_exit(pADSP);
108 BurnFree(pADSP);
109 delete pMemMap;
110 pMemMap = NULL;
111 #if ENABLE_TRACE
112 fclose(pTrace);
113 #endif
114 return 0;
115 }
116
Adsp2100Reset()117 void Adsp2100Reset()
118 {
119 adsp21xx_reset(pADSP);
120 }
121
Adsp2100Run(int cycles)122 int Adsp2100Run(int cycles)
123 {
124 return adsp21xx_execute(pADSP, cycles);
125 }
126
Adsp2100TotalCycles()127 int Adsp2100TotalCycles()
128 {
129 return adsp21xx_total_cycles(pADSP);
130 }
131
Adsp2100NewFrame()132 void Adsp2100NewFrame()
133 {
134 adsp21xx_new_frame(pADSP);
135 }
136
Adsp2100RunEnd()137 void Adsp2100RunEnd()
138 {
139 adsp21xx_stop_execute(pADSP);
140 }
141
Adsp2100Scan(INT32 nAction)142 void Adsp2100Scan(INT32 nAction)
143 {
144 adsp21xx_scan(pADSP, nAction);
145 }
146
Adsp2100SetRxCallback(pAdsp2100RxCallback cb)147 void Adsp2100SetRxCallback(pAdsp2100RxCallback cb)
148 {
149 pRxCallback = cb;
150 }
151
Adsp2100SetTxCallback(pAdsp2100TxCallback cb)152 void Adsp2100SetTxCallback(pAdsp2100TxCallback cb)
153 {
154 pTxCallback = cb;
155 }
156
Adsp2100SetTimerCallback(pAdsp2100TimerCallback cb)157 void Adsp2100SetTimerCallback(pAdsp2100TimerCallback cb)
158 {
159 pTimerCallback = cb;
160 }
161
Adsp2100SetIRQCallback(int (* cb)(int))162 void Adsp2100SetIRQCallback(int (*cb)(int))
163 {
164 if (pADSP)
165 pADSP->irq_callback = cb;
166 }
167
Adsp2100SetIRQLine(int line,int state)168 void Adsp2100SetIRQLine(int line, int state)
169 {
170 switch (state) {
171 case CPU_IRQSTATUS_AUTO:
172 case CPU_IRQSTATUS_HOLD:
173 adsp21xx_set_irq_line(pADSP, line, CPU_IRQSTATUS_ACK);
174 adsp21xx_set_irq_line(pADSP, line, CPU_IRQSTATUS_NONE);
175 break;
176 default:
177 adsp21xx_set_irq_line(pADSP, line, state);
178 break;
179 }
180 }
181
182
Adsp2100LoadBootROM(void * src,void * dst)183 int Adsp2100LoadBootROM(void *src, void *dst)
184 {
185 adsp2105_load_boot_data((UINT8*)src, (UINT32*)dst);
186 return 0;
187 }
188
Adsp2100MapMemory(unsigned char * pMemory,unsigned int nStart,unsigned int nEnd,int nType)189 int Adsp2100MapMemory(unsigned char* pMemory, unsigned int nStart, unsigned int nEnd, int nType)
190 {
191 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
192
193 int page = PFN(nStart);
194 for (int i = 0; i < maxPages; i++, page++) {
195
196 if (nType & MAP_READ)
197 pMemMap->PrgMap[page] = pMemory + (PAGE_SIZE * i);
198
199 if (nType & MAP_WRITE)
200 pMemMap->PrgMap[PAGE_WADD + page] = pMemory + (PAGE_SIZE * i);
201 }
202 return 0;
203 }
204
205
Adsp2100MapHandler(uintptr_t nHandler,unsigned int nStart,unsigned int nEnd,int nType)206 int Adsp2100MapHandler(uintptr_t nHandler, unsigned int nStart, unsigned int nEnd, int nType)
207 {
208 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
209
210 int page = PFN(nStart);
211 for (int i = 0; i < maxPages; i++, page++) {
212
213 if (nType & MAP_READ)
214 pMemMap->PrgMap[page] = (UINT8*) nHandler;
215
216 if (nType & MAP_WRITE)
217 pMemMap->PrgMap[PAGE_WADD + page] = (UINT8*) nHandler;
218 }
219 return 0;
220 }
221
222
223
Adsp2100MapData(unsigned char * pMemory,unsigned int nStart,unsigned int nEnd,int nType)224 int Adsp2100MapData(unsigned char* pMemory, unsigned int nStart, unsigned int nEnd, int nType)
225 {
226 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
227
228 int page = PFN(nStart);
229 for (int i = 0; i < maxPages; i++, page++) {
230
231 if (nType & MAP_READ)
232 pMemMap->DataMap[page] = pMemory + (PAGE_SIZE * i);
233
234 if (nType & MAP_WRITE)
235 pMemMap->DataMap[PAGE_WADD + page] = pMemory + (PAGE_SIZE * i);
236 }
237 return 0;
238 }
239
240
Adsp2100MapDataHandler(uintptr_t nHandler,unsigned int nStart,unsigned int nEnd,int nType)241 int Adsp2100MapDataHandler(uintptr_t nHandler, unsigned int nStart, unsigned int nEnd, int nType)
242 {
243 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
244
245 int page = PFN(nStart);
246 for (int i = 0; i < maxPages; i++, page++) {
247
248 if (nType & MAP_READ)
249 pMemMap->DataMap[page] = (UINT8*) nHandler;
250
251 if (nType & MAP_WRITE)
252 pMemMap->DataMap[PAGE_WADD + page] = (UINT8*) nHandler;
253 }
254 return 0;
255 }
256
257 // -------------------------------------------------------------------
258 // Program address space
259 // -------------------------------------------------------------------
Adsp2100SetReadLongHandler(int i,pAdsp2100ReadLongHandler pHandler)260 int Adsp2100SetReadLongHandler(int i, pAdsp2100ReadLongHandler pHandler)
261 {
262 if (i >= ADSP_MAXHANDLER)
263 return 1;
264 pMemMap->prgReadLong[i] = pHandler;
265 return 0;
266 }
267
Adsp2100SetWriteLongHandler(int i,pAdsp2100WriteLongHandler pHandler)268 int Adsp2100SetWriteLongHandler(int i, pAdsp2100WriteLongHandler pHandler)
269 {
270 if (i >= ADSP_MAXHANDLER)
271 return 1;
272 pMemMap->prgWriteLong[i] = pHandler;
273 return 0;
274 }
275
276 // -------------------------------------------------------------------
277 // Data address space
278 // -------------------------------------------------------------------
279
Adsp2100SetReadDataWordHandler(int i,pAdsp2100ReadWordHandler pHandler)280 int Adsp2100SetReadDataWordHandler(int i, pAdsp2100ReadWordHandler pHandler)
281 {
282 if (i >= ADSP_MAXHANDLER)
283 return 1;
284 pMemMap->dataReadWord[i] = pHandler;
285 return 0;
286 }
287
Adsp2100SetWriteDataWordHandler(int i,pAdsp2100WriteWordHandler pHandler)288 int Adsp2100SetWriteDataWordHandler(int i, pAdsp2100WriteWordHandler pHandler)
289 {
290 if (i >= ADSP_MAXHANDLER)
291 return 1;
292 pMemMap->dataWriteWord[i] = pHandler;
293 return 0;
294 }
295
296 // ============================================================================
297 // MEMORY ACCESSORS
298 // ============================================================================
299
300 template<typename T>
fast_read(uint8_t * ptr,unsigned adr)301 inline T fast_read(uint8_t *ptr, unsigned adr) {
302 return *((T*) ((uint8_t*) ptr + (adr & PAGE_MASK)));
303 }
304
305 template<typename T>
fast_write(uint8_t * xptr,unsigned adr,T value)306 inline void fast_write(uint8_t *xptr, unsigned adr, T value) {
307 T *ptr = ((T*) ((uint8_t*) xptr + (adr & PAGE_MASK)));
308 *ptr = value;
309 }
310
adsp21xx_data_read_word_16le(UINT32 address)311 UINT16 adsp21xx_data_read_word_16le(UINT32 address)
312 {
313 // address &= 0xFFFF;
314 address >>= 1;
315 address &= 0x3FFF;
316
317 UINT8 *pr = pMemMap->DataMap[PFN(address)];
318 if ((uintptr_t)pr >= ADSP_MAXHANDLER) {
319 return BURN_ENDIAN_SWAP_INT16(fast_read<uint16_t>(pr, address));
320 }
321 return pMemMap->dataReadWord[(uintptr_t)pr](address);
322 }
323
adsp21xx_data_write_word_16le(UINT32 address,UINT16 data)324 void adsp21xx_data_write_word_16le(UINT32 address, UINT16 data)
325 {
326 // address &= 0xFFFF;
327 address >>= 1;
328 address &= 0x3FFF;
329
330 UINT8 *pr = pMemMap->DataMap[PAGE_WADD + PFN(address)];
331 if ((uintptr_t)pr >= ADSP_MAXHANDLER) {
332 fast_write<uint16_t>(pr, address, BURN_ENDIAN_SWAP_INT16(data));
333 return;
334 }
335 pMemMap->dataWriteWord[(uintptr_t)pr](address, data);
336 }
337
338 //static UINT32 last_pc = 0xFFFFFFFF;
339 extern int adsp21xx_dasm(char *buffer, UINT8 *oprom);
adsp21xx_read_dword_32le(UINT32 address)340 UINT32 adsp21xx_read_dword_32le(UINT32 address)
341 {
342 // address &= 0xFFFF;
343 address >>= 2;
344 address &= 0x3FFF;
345
346 UINT32 value = 0;
347
348 UINT8 *pr = pMemMap->PrgMap[PFN(address)];
349 if ((uintptr_t)pr >= ADSP_MAXHANDLER) {
350 value = BURN_ENDIAN_SWAP_INT32(fast_read<uint32_t>(pr, address));
351 } else
352 value = pMemMap->prgReadLong[(uintptr_t)pr](address);
353 #if ENABLE_TRACE
354 if (last_pc != pADSP->pc) {
355 char buffer[1024];
356 adsp21xx_dasm(buffer, (UINT8*)&value);
357 fprintf(pTrace, "%04X: %s\n", address>>2, buffer);
358 last_pc = pADSP->pc;
359 }
360 #endif
361 return value;
362 }
363
adsp21xx_write_dword_32le(UINT32 address,UINT32 data)364 void adsp21xx_write_dword_32le(UINT32 address, UINT32 data)
365 {
366 // address &= 0xFFFF;
367 address >>= 2;
368 address &= 0x3FFF;
369
370 UINT8 *pr = pMemMap->PrgMap[PAGE_WADD + PFN(address)];
371 if ((uintptr_t)pr >= ADSP_MAXHANDLER) {
372 fast_write<uint32_t>(pr, address, BURN_ENDIAN_SWAP_INT32(data));
373 return;
374 }
375 pMemMap->prgWriteLong[(uintptr_t)pr](address, data);
376 }
377
378
Adsp2100GetState()379 adsp2100_state *Adsp2100GetState()
380 {
381 return pADSP;
382 }
383
384