36515e107c9f1de3be7e64069cfcc0d7bffb5eb3
[picodrive.git] / Pico / carthw / svp / compiler.c
1 // 187 blocks, 12072 bytes
2 // 14 IRAM blocks
3
4 #include "../../PicoInt.h"
5
6 #define TCACHE_SIZE (256*1024)
7 static unsigned int *block_table[0x5090/2];
8 static unsigned int *block_table_iram[15][0x800/2];
9 static unsigned int *tcache = NULL;
10 static unsigned int *tcache_ptr = NULL;
11
12 static int had_jump = 0;
13 static int nblocks = 0;
14 static int iram_context = 0;
15
16 #define EMBED_INTERPRETER
17 #define ssp1601_reset ssp1601_reset_local
18 #define ssp1601_run ssp1601_run_local
19
20 static unsigned int interp_get_pc(void);
21
22 #define GET_PC interp_get_pc
23 #define GET_PPC_OFFS() (interp_get_pc()*2 - 2)
24 #define SET_PC(d) { had_jump = 1; rPC = d; }            /* must return to dispatcher after this */
25 //#define GET_PC() (PC - (unsigned short *)svp->iram_rom)
26 //#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2)
27 //#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d
28
29 #include "ssp16.c"
30
31 // -----------------------------------------------------
32
33 // ld d, s
34 static void op00(unsigned int op, unsigned int imm)
35 {
36         unsigned int tmpv;
37         if (op == 0) return; // nop
38         if (op == ((SSP_A<<4)|SSP_P)) { // A <- P
39                 // not sure. MAME claims that only hi word is transfered.
40                 read_P(); // update P
41                 rA32 = rP.v;
42         }
43         else
44         {
45                 tmpv = REG_READ(op & 0x0f);
46                 REG_WRITE((op & 0xf0) >> 4, tmpv);
47         }
48 }
49
50 // ld d, (ri)
51 static void op01(unsigned int op, unsigned int imm)
52 {
53         unsigned int tmpv;
54         tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
55 }
56
57 // ld (ri), s
58 static void op02(unsigned int op, unsigned int imm)
59 {
60         unsigned int tmpv;
61         tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv);
62 }
63
64 // ldi d, imm
65 static void op04(unsigned int op, unsigned int imm)
66 {
67         REG_WRITE((op & 0xf0) >> 4, imm);
68 }
69
70 // ld d, ((ri))
71 static void op05(unsigned int op, unsigned int imm)
72 {
73         unsigned int tmpv;
74         tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
75 }
76
77 // ldi (ri), imm
78 static void op06(unsigned int op, unsigned int imm)
79 {
80         ptr1_write(op, imm);
81 }
82
83 // ld adr, a
84 static void op07(unsigned int op, unsigned int imm)
85 {
86         ssp->RAM[op & 0x1ff] = rA;
87 }
88
89 // ld d, ri
90 static void op09(unsigned int op, unsigned int imm)
91 {
92         unsigned int tmpv;
93         tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv);
94 }
95
96 // ld ri, s
97 static void op0a(unsigned int op, unsigned int imm)
98 {
99         rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4);
100 }
101
102 // ldi ri, simm (also op0d op0e op0f)
103 static void op0c(unsigned int op, unsigned int imm)
104 {
105         rIJ[(op>>8)&7] = op;
106 }
107
108 // call cond, addr
109 static void op24(unsigned int op, unsigned int imm)
110 {
111         int cond = 0;
112         do {
113                 COND_CHECK
114                 if (cond) { int new_PC = imm; write_STACK(GET_PC()); write_PC(new_PC); }
115         }
116         while (0);
117 }
118
119 // ld d, (a)
120 static void op25(unsigned int op, unsigned int imm)
121 {
122         unsigned int tmpv;
123         tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv);
124 }
125
126 // bra cond, addr
127 static void op26(unsigned int op, unsigned int imm)
128 {
129         do
130         {
131                 int cond = 0;
132                 COND_CHECK
133                 if (cond) write_PC(imm);
134         }
135         while(0);
136 }
137
138 // mod cond, op
139 static void op48(unsigned int op, unsigned int imm)
140 {
141         do
142         {
143                 int cond = 0;
144                 COND_CHECK
145                 if (cond) {
146                         switch (op & 7) {
147                                 case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic)
148                                 case 3: rA32 <<= 1; break; // shl
149                                 case 6: rA32 = -(signed int)rA32; break; // neg
150                                 case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs
151                                 default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x",
152                                                          op&7, GET_PPC_OFFS());
153                         }
154                         UPD_ACC_ZN // ?
155                 }
156         }
157         while(0);
158 }
159
160 // mpys?
161 static void op1b(unsigned int op, unsigned int imm)
162 {
163         read_P(); // update P
164         rA32 -= rP.v;                   // maybe only upper word?
165         UPD_ACC_ZN                      // there checking flags after this
166         rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
167         rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
168 }
169
170 // mpya (rj), (ri), b
171 static void op4b(unsigned int op, unsigned int imm)
172 {
173         read_P(); // update P
174         rA32 += rP.v; // confirmed to be 32bit
175         UPD_ACC_ZN // ?
176         rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
177         rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
178 }
179
180 // mld (rj), (ri), b
181 static void op5b(unsigned int op, unsigned int imm)
182 {
183         rA32 = 0;
184         rST &= 0x0fff; // ?
185         rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
186         rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
187 }
188
189 // OP a, s
190 static void op10(unsigned int op, unsigned int imm)
191 {
192         do
193         {
194                 unsigned int tmpv;
195                 OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv);
196         }
197         while(0);
198 }
199
200 static void op30(unsigned int op, unsigned int imm)
201 {
202         do
203         {
204                 unsigned int tmpv;
205                 OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv);
206         }
207         while(0);
208 }
209
210 static void op40(unsigned int op, unsigned int imm)
211 {
212         do
213         {
214                 unsigned int tmpv;
215                 OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv);
216         }
217         while(0);
218 }
219
220 static void op50(unsigned int op, unsigned int imm)
221 {
222         do
223         {
224                 unsigned int tmpv;
225                 OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv);
226         }
227         while(0);
228 }
229
230 static void op60(unsigned int op, unsigned int imm)
231 {
232         do
233         {
234                 unsigned int tmpv;
235                 OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv);
236         }
237         while(0);
238 }
239
240 static void op70(unsigned int op, unsigned int imm)
241 {
242         do
243         {
244                 unsigned int tmpv;
245                 OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv);
246         }
247         while(0);
248 }
249
250 // OP a, (ri)
251 static void op11(unsigned int op, unsigned int imm)
252 {
253         unsigned int tmpv;
254         tmpv = ptr1_read(op); OP_SUBA(tmpv);
255 }
256
257 static void op31(unsigned int op, unsigned int imm)
258 {
259         unsigned int tmpv;
260         tmpv = ptr1_read(op); OP_CMPA(tmpv);
261 }
262
263 static void op41(unsigned int op, unsigned int imm)
264 {
265         unsigned int tmpv;
266         tmpv = ptr1_read(op); OP_ADDA(tmpv);
267 }
268
269 static void op51(unsigned int op, unsigned int imm)
270 {
271         unsigned int tmpv;
272         tmpv = ptr1_read(op); OP_ANDA(tmpv);
273 }
274
275 static void op61(unsigned int op, unsigned int imm)
276 {
277         unsigned int tmpv;
278         tmpv = ptr1_read(op); OP_ORA (tmpv);
279 }
280
281 static void op71(unsigned int op, unsigned int imm)
282 {
283         unsigned int tmpv;
284         tmpv = ptr1_read(op); OP_EORA(tmpv);
285 }
286
287 // OP a, adr
288 static void op03(unsigned int op, unsigned int imm)
289 {
290         unsigned int tmpv;
291         tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv);
292 }
293
294 static void op13(unsigned int op, unsigned int imm)
295 {
296         unsigned int tmpv;
297         tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv);
298 }
299
300 static void op33(unsigned int op, unsigned int imm)
301 {
302         unsigned int tmpv;
303         tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv);
304 }
305
306 static void op43(unsigned int op, unsigned int imm)
307 {
308         unsigned int tmpv;
309         tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv);
310 }
311
312 static void op53(unsigned int op, unsigned int imm)
313 {
314         unsigned int tmpv;
315         tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv);
316 }
317
318 static void op63(unsigned int op, unsigned int imm)
319 {
320         unsigned int tmpv;
321         tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv);
322 }
323
324 static void op73(unsigned int op, unsigned int imm)
325 {
326         unsigned int tmpv;
327         tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv);
328 }
329
330 // OP a, imm
331 static void op14(unsigned int op, unsigned int imm)
332 {
333         OP_SUBA(imm);
334 }
335
336 static void op34(unsigned int op, unsigned int imm)
337 {
338         OP_CMPA(imm);
339 }
340
341 static void op44(unsigned int op, unsigned int imm)
342 {
343         OP_ADDA(imm);
344 }
345
346 static void op54(unsigned int op, unsigned int imm)
347 {
348         OP_ANDA(imm);
349 }
350
351 static void op64(unsigned int op, unsigned int imm)
352 {
353         OP_ORA (imm);
354 }
355
356 static void op74(unsigned int op, unsigned int imm)
357 {
358         OP_EORA(imm);
359 }
360
361 // OP a, ((ri))
362 static void op15(unsigned int op, unsigned int imm)
363 {
364         unsigned int tmpv;
365         tmpv = ptr2_read(op); OP_SUBA(tmpv);
366 }
367
368 static void op35(unsigned int op, unsigned int imm)
369 {
370         unsigned int tmpv;
371         tmpv = ptr2_read(op); OP_CMPA(tmpv);
372 }
373
374 static void op45(unsigned int op, unsigned int imm)
375 {
376         unsigned int tmpv;
377         tmpv = ptr2_read(op); OP_ADDA(tmpv);
378 }
379
380 static void op55(unsigned int op, unsigned int imm)
381 {
382         unsigned int tmpv;
383         tmpv = ptr2_read(op); OP_ANDA(tmpv);
384 }
385
386 static void op65(unsigned int op, unsigned int imm)
387 {
388         unsigned int tmpv;
389         tmpv = ptr2_read(op); OP_ORA (tmpv);
390 }
391
392 static void op75(unsigned int op, unsigned int imm)
393 {
394         unsigned int tmpv;
395         tmpv = ptr2_read(op); OP_EORA(tmpv);
396 }
397
398 // OP a, ri
399 static void op19(unsigned int op, unsigned int imm)
400 {
401         unsigned int tmpv;
402         tmpv = rIJ[IJind]; OP_SUBA(tmpv);
403 }
404
405 static void op39(unsigned int op, unsigned int imm)
406 {
407         unsigned int tmpv;
408         tmpv = rIJ[IJind]; OP_CMPA(tmpv);
409 }
410
411 static void op49(unsigned int op, unsigned int imm)
412 {
413         unsigned int tmpv;
414         tmpv = rIJ[IJind]; OP_ADDA(tmpv);
415 }
416
417 static void op59(unsigned int op, unsigned int imm)
418 {
419         unsigned int tmpv;
420         tmpv = rIJ[IJind]; OP_ANDA(tmpv);
421 }
422
423 static void op69(unsigned int op, unsigned int imm)
424 {
425         unsigned int tmpv;
426         tmpv = rIJ[IJind]; OP_ORA (tmpv);
427 }
428
429 static void op79(unsigned int op, unsigned int imm)
430 {
431         unsigned int tmpv;
432         tmpv = rIJ[IJind]; OP_EORA(tmpv);
433 }
434
435 // OP simm
436 static void op1c(unsigned int op, unsigned int imm)
437 {
438         OP_SUBA(op & 0xff);
439 }
440
441 static void op3c(unsigned int op, unsigned int imm)
442 {
443         OP_CMPA(op & 0xff);
444 }
445
446 static void op4c(unsigned int op, unsigned int imm)
447 {
448         OP_ADDA(op & 0xff);
449 }
450
451 static void op5c(unsigned int op, unsigned int imm)
452 {
453         OP_ANDA(op & 0xff);
454 }
455
456 static void op6c(unsigned int op, unsigned int imm)
457 {
458         OP_ORA (op & 0xff);
459 }
460
461 static void op7c(unsigned int op, unsigned int imm)
462 {
463         OP_EORA(op & 0xff);
464 }
465
466 typedef void (in_func)(unsigned int op, unsigned int imm);
467
468 static in_func *in_funcs[0x80] =
469 {
470         op00, op01, op02, op03, op04, op05, op06, op07,
471         NULL, op09, op0a, NULL, op0c, op0c, op0c, op0c,
472         op10, op11, NULL, op13, op14, op15, NULL, NULL,
473         NULL, op19, NULL, op1b, op1c, NULL, NULL, NULL,
474         NULL, NULL, NULL, NULL, op24, op25, op26, NULL,
475         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
476         op30, op31, NULL, op33, op34, op35, NULL, NULL,
477         NULL, op39, NULL, NULL, op3c, NULL, NULL, NULL,
478         op40, op41, NULL, op43, op44, op45, NULL, NULL,
479         op48, op49, NULL, op4b, op4c, NULL, NULL, NULL,
480         op50, op51, NULL, op53, op54, op55, NULL, NULL,
481         NULL, op59, NULL, op5b, op5c, NULL, NULL, NULL,
482         op60, op61, NULL, op63, op64, op65, NULL, NULL,
483         NULL, op69, NULL, NULL, op6c, NULL, NULL, NULL,
484         op70, op71, NULL, op73, op74, op75, NULL, NULL,
485         NULL, op79, NULL, NULL, op7c, NULL, NULL, NULL,
486 };
487
488 // -----------------------------------------------------
489
490 static unsigned int crctable[256] =
491 {
492  0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
493  0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
494  0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
495  0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
496  0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
497  0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
498  0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
499  0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
500  0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
501  0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
502  0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
503  0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
504  0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
505  0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
506  0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
507  0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
508  0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
509  0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
510  0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
511  0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
512  0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
513  0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
514  0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
515  0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
516  0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
517  0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
518  0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
519  0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
520  0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
521  0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
522  0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
523  0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
524  0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
525  0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
526  0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
527  0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
528  0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
529  0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
530  0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
531  0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
532  0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
533  0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
534  0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
535  0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
536  0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
537  0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
538  0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
539  0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
540  0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
541  0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
542  0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
543  0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
544  0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
545  0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
546  0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
547  0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
548  0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
549  0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
550  0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
551  0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
552  0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
553  0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
554  0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
555  0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
556 };
557
558 static u32 chksum_crc32 (unsigned char *block, unsigned int length)
559 {
560    register u32 crc;
561    unsigned long i;
562
563    crc = 0xFFFFFFFF;
564    for (i = 0; i < length; i++)
565    {
566       crc = ((crc >> 8) & 0x00FFFFFF) ^ crctable[(crc ^ *block++) & 0xFF];
567    }
568    return (crc ^ 0xFFFFFFFF);
569 }
570
571 //static int iram_crcs[32] = { 0, };
572
573 // -----------------------------------------------------
574
575 static unsigned char iram_context_map[] =
576 {
577          0, 0, 0, 0, 1, 0, 0, 0, // 04
578          0, 0, 0, 0, 0, 0, 2, 0, // 0e
579          0, 0, 0, 0, 0, 3, 0, 4, // 15 17
580          5, 0, 0, 6, 0, 7, 0, 0, // 18 1b 1d
581          8, 9, 0, 0, 0,10, 0, 0, // 20 21 25
582          0, 0, 0, 0, 0, 0, 0, 0,
583          0, 0,11, 0, 0,12, 0, 0, // 32 35
584         13,14, 0, 0, 0, 0, 0, 0  // 38 39
585 };
586
587 static unsigned int checksums[] =
588 {
589         0,
590         0xfa9ddfb2,
591         0x229c80b6,
592         0x3af0c3d3,
593         0x98fc4552,
594         0x5ecacdbc,
595         0xa6931962,
596         0x53930b10,
597         0x69524552,
598         0xcb1ccdaf,
599         0x995068c7,
600         0x48b97f4d,
601         0xe8c61b74,
602         0xafa2e81a,
603         0x4e3e071a
604 };
605
606
607 static int get_iram_context(void)
608 {
609         unsigned char *ir = (unsigned char *)svp->iram_rom;
610         int val1, val = ir[0x083^1] + ir[0x4FA^1] + ir[0x5F7^1] + ir[0x47B^1];
611         int crc = chksum_crc32(svp->iram_rom, 0x800);
612         val1 = iram_context_map[(val>>1)&0x3f];
613
614         if (crc != checksums[val1] || val1 == 0) {
615                 printf("val: %02x PC=%04x\n", (val>>1)&0x3f, rPC);
616                 elprintf(EL_ANOMALY, "bad crc: %08x vs %08x", crc, checksums[val1]);
617                 //debug_dump2file(name, svp->iram_rom, 0x800);
618                 exit(1);
619         }
620         elprintf(EL_ANOMALY, "iram_context: %02i", val1);
621         return val1;
622 }
623
624 #define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
625
626 static u32 interp_get_pc(void)
627 {
628 #if 0
629         unsigned short *pc1 = PC;
630         int i;
631
632         while (pc1[-1] != 0xfe01) pc1--;                // goto current block start
633
634         if (rPC >= 0x800/2)
635         {
636                 for (i = 0; i < 0x5090/2; i++)
637                         if (block_table[i] == pc1) break;
638                 if (i == 0x5090/2) goto fail;
639         }
640         else
641         {
642                 for (i = 0; i < 0x800/2; i++)
643                         if (block_table_iram[iram_context][i] == pc1) break;
644                 if (i == 0x800/2) goto fail;
645         }
646
647         return i + (PC - pc1);
648 fail:
649         printf("block not found!\n");
650         exit(1);
651 #else
652         return rPC;
653 #endif
654 }
655
656 static void *translate_block(int pc)
657 {
658         unsigned int op, op1, icount = 0;
659         void *ret;
660
661         ret = tcache_ptr;
662
663         //printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<1);
664         for (;;)
665         {
666                 icount++;
667                 op = PROGRAM(pc++);
668                 op1 = op >> 9;
669                 // need immediate?
670                 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) {
671                         op |= PROGRAM(pc++) << 16; // immediate
672                 }
673                 *tcache_ptr++ = op;
674                 *tcache_ptr = (unsigned int) in_funcs[op1];
675                 if (*tcache_ptr == 0) {
676                         printf("NULL func! op=%08x (%02x)\n", op, op1);
677                         exit(1);
678                 }
679                 tcache_ptr++;
680                 if (op1 == 0x24 || op1 == 0x26 || // call, bra
681                         ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
682                                 (op & 0xf0) == 0x60)) { // ld PC
683                         break;
684                 }
685         }
686         *tcache_ptr++ = 0xfe01;
687         *tcache_ptr++ = 0xfe01; // end of block
688         //printf("  %i inst\n", icount);
689
690         if (tcache_ptr - tcache > TCACHE_SIZE/4) {
691                 printf("tcache overflow!\n");
692                 fflush(stdout);
693                 exit(1);
694         }
695
696         // stats
697         nblocks++;
698         //if (pc >= 0x400)
699         printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4);
700
701         return ret;
702 }
703
704
705
706 // -----------------------------------------------------
707
708 int ssp1601_dyn_init(void)
709 {
710         tcache = tcache_ptr = malloc(TCACHE_SIZE);
711         memset(tcache, 0, sizeof(TCACHE_SIZE));
712         memset(block_table, 0, sizeof(block_table));
713         memset(block_table_iram, 0, sizeof(block_table_iram));
714         *tcache_ptr++ = 0xfe01;
715         *tcache_ptr++ = 0xfe01;
716
717         return 0;
718 }
719
720
721 void ssp1601_dyn_reset(ssp1601_t *ssp)
722 {
723         ssp1601_reset_local(ssp);
724 }
725
726
727 static void ssp1601_run2(unsigned int *iPC)
728 {
729         in_func *func;
730         unsigned int op, op1, imm;
731         while (*iPC != 0xfe01)
732         {
733                 rPC++;
734                 op = *iPC & 0xffff;
735                 imm = *iPC++ >> 16;
736                 op1 = op >> 9;
737                 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) rPC++;
738                 PC = ((unsigned short *)&op) + 1; /* needed for interpreter */
739
740                 func = (in_func *) *iPC++;
741                 func(op, imm);
742                 g_cycles--;
743         }
744 }
745
746
747 void ssp1601_dyn_run(int cycles)
748 {
749         while (cycles > 0)
750         {
751                 unsigned int *iPC;
752                 //int pc_old = rPC;
753                 if (rPC < 0x800/2)
754                 {
755                         if (iram_dirty) {
756                                 iram_context = get_iram_context();
757                                 iram_dirty--;
758                         }
759                         if (block_table_iram[iram_context][rPC] == NULL)
760                                 block_table_iram[iram_context][rPC] = translate_block(rPC);
761                         iPC = block_table_iram[iram_context][rPC];
762                 }
763                 else
764                 {
765                         if (block_table[rPC] == NULL)
766                                 block_table[rPC] = translate_block(rPC);
767                         iPC = block_table[rPC];
768                 }
769
770                 had_jump = 0;
771
772                 //printf("enter @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
773                 g_cycles = 0;
774                 ssp1601_run2(iPC);
775                 cycles += g_cycles;
776 /*
777                 if (!had_jump) {
778                         // no jumps
779                         if (pc_old < 0x800/2)
780                                 rPC += (PC - block_table_iram[iram_context][pc_old]) - 1;
781                         else
782                                 rPC += (PC - block_table[pc_old]) - 1;
783                 }
784 */
785                 //printf("end   @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
786 /*
787                 if (pc_old < 0x400) {
788                         // flush IRAM cache
789                         tcache_ptr = block_table[pc_old];
790                         block_table[pc_old] = NULL;
791                         nblocks--;
792                 }
793                 if (pc_old >= 0x400 && rPC < 0x400)
794                 {
795                         int i, crc = chksum_crc32(svp->iram_rom, 0x800);
796                         for (i = 0; i < 32; i++)
797                                 if (iram_crcs[i] == crc) break;
798                         if (i == 32) {
799                                 char name[32];
800                                 for (i = 0; i < 32 && iram_crcs[i]; i++);
801                                 iram_crcs[i] = crc;
802                                 printf("%i IRAMs\n", i+1);
803                                 sprintf(name, "ir%08x.bin", crc);
804                                 debug_dump2file(name, svp->iram_rom, 0x800);
805                         }
806                         printf("CRC %08x %08x\n", crc, iram_id);
807                 }
808 */
809         }
810 //      debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);
811 //      exit(1);
812 }
813