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