1
2 /*
3 * CMPC: What happens to _S flag if the strings are identical?
4 * I suppose that it will be cleared. And is it set or cleared
5 * when the first one is a substring of the second? I suppose
6 * cleared (since _S should be (src > dst))
7 * MOVC: Why MOVCS does not exist in downward version?
8 * SHCHDB/SHCHDH: R27 is filled with the offset from the start or from the end?
9 *
10 * Strange stuff:
11 * SCHC opcodes does *not* modify _Z flag as stated in V60 manual:
12 * they do the opposite (set if not found, reset if found)
13 */
14
15 UINT32 f7aOp1, f7aOp2;
16 UINT8 f7aFlag1, f7aFlag2;
17 UINT32 f7aLenOp1, f7aLenOp2;
18 UINT8 subOp;
19
20 UINT32 f7bBamOffset1, f7bBamOffset2;
21
22 #define f7bOp1 f7aOp1
23 #define f7bFlag1 f7aFlag1
24 #define f7bOp2 f7aOp2
25 #define f7bFlag2 f7aFlag2
26 #define f7bLen f7aLenOp1
27
28 #define f7cOp1 f7aOp1
29 #define f7cOp2 f7aOp2
30 #define f7cLen f7aLenOp1
31 #define f7cFlag1 f7aFlag1
32 #define f7cFlag2 f7aFlag2
33
34 #define F7AEND() \
35 return amLength1 + amLength2 + 4;
36
37 #define F7BEND() \
38 return amLength1 + amLength2 + 3;
39
40 #define F7CEND() \
41 return amLength1 + amLength2 + 3;
42
43 #define F7BCREATEBITMASK(x) \
44 x=((1<<(x))-1)
45
46 #define F7CCREATEBITMASK(x) \
47 x=((1<<(x))-1)
48
F7aDecodeOperands(UINT32 (* DecodeOp1)(void),UINT8 dim1,UINT32 (* DecodeOp2)(void),UINT8 dim2)49 void F7aDecodeOperands(UINT32 (*DecodeOp1)(void), UINT8 dim1, UINT32 (*DecodeOp2)(void), UINT8 dim2)
50 {
51 UINT8 appb;
52 // Decode first operand
53 modDim=dim1;
54 modM=subOp&0x40;
55 modAdd=PC+2;
56 amLength1=DecodeOp1();
57 f7aFlag1=amFlag;
58 f7aOp1=amOut;
59
60 // Decode length
61 appb=OpRead8(PC+2+amLength1);
62 if (appb&0x80)
63 f7aLenOp1=v60.reg[appb&0x1F];
64 else
65 f7aLenOp1=appb;
66
67 // Decode second operand
68 modDim=dim2;
69 modM=subOp&0x20;
70 modAdd=PC+3+amLength1;
71 amLength2=DecodeOp2();
72 f7aFlag2=amFlag;
73 f7aOp2=amOut;
74
75 // Decode length
76 appb=OpRead8(PC+3+amLength1+amLength2);
77 if (appb&0x80)
78 f7aLenOp2=v60.reg[appb&0x1F];
79 else
80 f7aLenOp2=appb;
81 }
82
F7bDecodeFirstOperand(UINT32 (* DecodeOp1)(void),UINT8 dim1)83 void F7bDecodeFirstOperand(UINT32 (*DecodeOp1)(void), UINT8 dim1)
84 {
85 UINT8 appb;
86 // Decode first operand
87 modDim=dim1;
88 modM=subOp&0x40;
89 modAdd=PC+2;
90 amLength1=DecodeOp1();
91 f7bFlag1=amFlag;
92 f7bOp1=amOut;
93
94 // Decode ext
95 appb=OpRead8(PC+2+amLength1);
96 if (appb&0x80)
97 f7bLen=v60.reg[appb&0x1F];
98 else
99 f7bLen=appb;
100 }
101
102
F7bWriteSecondOperand(UINT8 dim2)103 void F7bWriteSecondOperand(UINT8 dim2)
104 {
105 modDim=dim2;
106 modM=subOp&0x20;
107 modAdd=PC+3+amLength1;
108 amLength2=WriteAM();
109 }
110
111
F7bDecodeOperands(UINT32 (* DecodeOp1)(void),UINT8 dim1,UINT32 (* DecodeOp2)(void),UINT8 dim2)112 void F7bDecodeOperands(UINT32 (*DecodeOp1)(void), UINT8 dim1, UINT32 (*DecodeOp2)(void), UINT8 dim2)
113 {
114 // Decode first operand
115 F7bDecodeFirstOperand(DecodeOp1,dim1);
116 f7bBamOffset1 = bamOffset;
117
118 // Decode second operand
119 modDim=dim2;
120 modM=subOp&0x20;
121 modAdd=PC+3+amLength1;
122 amLength2=DecodeOp2();
123 f7bFlag2=amFlag;
124 f7bOp2=amOut;
125 f7bBamOffset2 = bamOffset;
126 }
127
F7cDecodeOperands(UINT32 (* DecodeOp1)(void),UINT8 dim1,UINT32 (* DecodeOp2)(void),UINT8 dim2)128 void F7cDecodeOperands(UINT32 (*DecodeOp1)(void), UINT8 dim1, UINT32 (*DecodeOp2)(void), UINT8 dim2)
129 {
130 UINT8 appb;
131 // Decode first operand
132 modDim=dim1;
133 modM=subOp&0x40;
134 modAdd=PC+2;
135 amLength1=DecodeOp1();
136 f7cFlag1=amFlag;
137 f7cOp1=amOut;
138
139 // Decode second operand
140 modDim=dim2;
141 modM=subOp&0x20;
142 modAdd=PC+2+amLength1;
143 amLength2=DecodeOp2();
144 f7cFlag2=amFlag;
145 f7cOp2=amOut;
146
147 // Decode ext
148 appb=OpRead8(PC+2+amLength1+amLength2);
149 if (appb&0x80)
150 f7cLen=v60.reg[appb&0x1F];
151 else
152 f7cLen=appb;
153 }
154
155 #define F7CLOADOP1BYTE(appb) \
156 if (f7cFlag1) \
157 appb = (UINT8)(v60.reg[f7cOp1]&0xFF); \
158 else \
159 appb = MemRead8(f7cOp1);
160
161 #define F7CLOADOP2BYTE(appb) \
162 if (f7cFlag2) \
163 appb = (UINT8)(v60.reg[f7cOp2]&0xFF); \
164 else \
165 appb = MemRead8(f7cOp2);
166
167
168 #define F7CSTOREOP2BYTE() \
169 if (f7cFlag2) \
170 SETREG8(v60.reg[f7cOp2], appb); \
171 else \
172 MemWrite8(f7cOp2, appb);
173
174 #define F7CSTOREOP2HALF() \
175 if (f7cFlag2) \
176 SETREG16(v60.reg[f7cOp2], apph); \
177 else \
178 MemWrite16(f7cOp2, apph);
179
opCMPSTRB(UINT8 bFill,UINT8 bStop)180 UINT32 opCMPSTRB(UINT8 bFill, UINT8 bStop)
181 {
182 UINT32 i,dest;
183 UINT8 c1,c2;
184
185 F7aDecodeOperands(ReadAMAddress,0,ReadAMAddress,0);
186
187 // Filling
188 if (bFill)
189 {
190 if (f7aLenOp1 < f7aLenOp2)
191 {
192 for (i=f7aLenOp1;i<f7aLenOp2;i++)
193 MemWrite8(f7aOp1+i,(UINT8)R26);
194 }
195 else if (f7aLenOp2 < f7aLenOp1)
196 {
197 for (i=f7aLenOp2;i<f7aLenOp1;i++)
198 MemWrite8(f7aOp2+i,(UINT8)R26);
199 }
200 }
201
202 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
203
204 _Z = 0;
205 _S = 0;
206 if (bStop) _CY = 1;
207
208 for (i=0;i<dest;i++)
209 {
210 c1=MemRead8(f7aOp1+i);
211 c2=MemRead8(f7aOp2+i);
212
213 if (c1>c2)
214 {
215 _S=1; break;
216 }
217 else if (c2>c1)
218 {
219 _S=0; break;
220 }
221
222 if (bStop)
223 if (c1==(UINT8)R26 || c2==(UINT8)R26)
224 {
225 _CY=0;
226 break;
227 }
228 }
229
230 R28=f7aLenOp1+i;
231 R27=f7aLenOp2+i;
232
233 if (i==dest)
234 {
235 if (f7aLenOp1 > f7aLenOp2)
236 _S=1;
237 else if (f7aLenOp2 > f7aLenOp1)
238 _S=0;
239 else
240 _Z=1;
241 }
242
243 F7AEND();
244 }
245
opCMPSTRH(UINT8 bFill,UINT8 bStop)246 UINT32 opCMPSTRH(UINT8 bFill, UINT8 bStop)
247 {
248 UINT32 i,dest;
249 UINT16 c1,c2;
250
251 F7aDecodeOperands(ReadAMAddress,0,ReadAMAddress,0);
252
253 // Filling
254 if (bFill)
255 {
256 if (f7aLenOp1 < f7aLenOp2)
257 {
258 for (i=f7aLenOp1;i<f7aLenOp2;i++)
259 MemWrite16(f7aOp1+i*2,(UINT16)R26);
260 }
261 else if (f7aLenOp2 < f7aLenOp1)
262 {
263 for (i=f7aLenOp2;i<f7aLenOp1;i++)
264 MemWrite16(f7aOp2+i*2,(UINT16)R26);
265 }
266 }
267
268 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
269
270 _Z = 0;
271 _S = 0;
272 if (bStop) _CY = 1;
273
274 for (i=0;i<dest;i++)
275 {
276 c1=MemRead16(f7aOp1+i*2);
277 c2=MemRead16(f7aOp2+i*2);
278
279 if (c1>c2)
280 {
281 _S=1; break;
282 }
283 else if (c2>c1)
284 {
285 _S=0; break;
286 }
287
288 if (bStop)
289 if (c1==(UINT16)R26 || c2==(UINT16)R26)
290 {
291 _CY=0;
292 break;
293 }
294 }
295
296 R28=f7aLenOp1+i*2;
297 R27=f7aLenOp2+i*2;
298
299 if (i==dest)
300 {
301 if (f7aLenOp1 > f7aLenOp2)
302 _S=1;
303 else if (f7aLenOp2 > f7aLenOp1)
304 _S=0;
305 else
306 _Z=1;
307 }
308
309 F7AEND();
310 }
311
312
313
opMOVSTRUB(UINT8 bFill,UINT8 bStop)314 UINT32 opMOVSTRUB(UINT8 bFill, UINT8 bStop) /* TRUSTED (0,0) (1,0) */
315 {
316 UINT32 i,dest;
317 UINT8 c1;
318
319 // if (bStop)
320 // {
321 // int a=1;
322 // }
323
324 F7aDecodeOperands(ReadAMAddress,0,ReadAMAddress,0);
325
326 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
327
328 for (i=0;i<dest;i++)
329 {
330 MemWrite8(f7aOp2+i,(c1=MemRead8(f7aOp1+i)));
331
332 if (bStop && c1==(UINT8)R26)
333 break;
334 }
335
336 R28=f7aOp1+i;
337 R27=f7aOp2+i;
338
339 if (bFill && f7aLenOp1 < f7aLenOp2)
340 {
341 for (;i<f7aLenOp2;i++)
342 MemWrite8(f7aOp2+i,(UINT8)R26);
343
344 R27=f7aOp2+i;
345 }
346
347
348 F7AEND();
349 }
350
opMOVSTRDB(UINT8 bFill,UINT8 bStop)351 UINT32 opMOVSTRDB(UINT8 bFill, UINT8 bStop)
352 {
353 UINT32 i,dest;
354 UINT8 c1;
355
356 F7aDecodeOperands(ReadAMAddress,0,ReadAMAddress,0);
357
358 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
359
360 for (i=0;i<dest;i++)
361 {
362 MemWrite8(f7aOp2+(dest-i-1),(c1=MemRead8(f7aOp1+(dest-i-1))));
363
364 if (bStop && c1==(UINT8)R26)
365 break;
366 }
367
368 R28=f7aOp1+(f7aLenOp1-i-1);
369 R27=f7aOp2+(f7aLenOp2-i-1);
370
371 if (bFill && f7aLenOp1 < f7aLenOp2)
372 {
373 for (;i<f7aLenOp2;i++)
374 MemWrite8(f7aOp2+dest+(f7aLenOp2-i-1),(UINT8)R26);
375
376 R27=f7aOp2+(f7aLenOp2-i-1);
377 }
378
379
380 F7AEND();
381 }
382
383
opMOVSTRUH(UINT8 bFill,UINT8 bStop)384 UINT32 opMOVSTRUH(UINT8 bFill, UINT8 bStop) /* TRUSTED (0,0) (1,0) */
385 {
386 UINT32 i,dest;
387 UINT16 c1;
388
389 // if (bStop)
390 // { int a=1; }
391
392 F7aDecodeOperands(ReadAMAddress,1,ReadAMAddress,1);
393
394 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
395
396 for (i=0;i<dest;i++)
397 {
398 MemWrite16(f7aOp2+i*2,(c1=MemRead16(f7aOp1+i*2)));
399
400 if (bStop && c1==(UINT16)R26)
401 break;
402 }
403
404 R28=f7aOp1+i*2;
405 R27=f7aOp2+i*2;
406
407 if (bFill && f7aLenOp1 < f7aLenOp2)
408 {
409 for (;i<f7aLenOp2;i++)
410 MemWrite16(f7aOp2+i*2,(UINT16)R26);
411
412 R27=f7aOp2+i*2;
413 }
414
415 F7AEND();
416 }
417
opMOVSTRDH(UINT8 bFill,UINT8 bStop)418 UINT32 opMOVSTRDH(UINT8 bFill, UINT8 bStop)
419 {
420 UINT32 i,dest;
421 UINT16 c1;
422
423 // if (bFill | bStop)
424 // { int a=1; }
425
426 F7aDecodeOperands(ReadAMAddress,1,ReadAMAddress,1);
427
428 // if (f7aLenOp1 != f7aLenOp2)
429 // { int a=1; }
430
431 dest=(f7aLenOp1 < f7aLenOp2 ? f7aLenOp1 : f7aLenOp2);
432
433 for (i=0;i<dest;i++)
434 {
435 MemWrite16(f7aOp2+(dest-i-1)*2,(c1=MemRead16(f7aOp1+(dest-i-1)*2)));
436
437 if (bStop && c1==(UINT16)R26)
438 break;
439 }
440
441 R28=f7aOp1+(f7aLenOp1-i-1)*2;
442 R27=f7aOp2+(f7aLenOp2-i-1)*2;
443
444 if (bFill && f7aLenOp1 < f7aLenOp2)
445 {
446 for (;i<f7aLenOp2;i++)
447 MemWrite16(f7aOp2+(f7aLenOp2-i-1)*2,(UINT16)R26);
448
449 R27=f7aOp2+(f7aLenOp2-i-1)*2;
450 }
451
452 F7AEND();
453 }
454
opSEARCHUB(UINT8 bSearch)455 UINT32 opSEARCHUB(UINT8 bSearch)
456 {
457 UINT8 appb;
458 UINT32 i;
459
460 F7bDecodeOperands(ReadAMAddress,0,ReadAM,0);
461
462 for (i=0;i<f7bLen;i++)
463 {
464 appb = (MemRead8(f7bOp1+i)==(UINT8)f7bOp2);
465 if ((bSearch && appb) || (!bSearch && !appb))
466 break;
467 }
468
469 R28=f7bOp1+i;
470 R27=i;
471
472 // This is the opposite as stated in V60 manual...
473 if (i!=f7bLen)
474 _Z=0;
475 else
476 _Z=1;
477
478 F7BEND();
479 }
480
opSEARCHUH(UINT8 bSearch)481 UINT32 opSEARCHUH(UINT8 bSearch)
482 {
483 UINT8 appb;
484 UINT32 i;
485
486 F7bDecodeOperands(ReadAMAddress,1,ReadAM,1);
487
488 for (i=0;i<f7bLen;i++)
489 {
490 appb = (MemRead16(f7bOp1+i*2)==(UINT16)f7bOp2);
491 if ((bSearch && appb) || (!bSearch && !appb))
492 break;
493 }
494
495 R28=f7bOp1+i*2;
496 R27=i;
497
498 if (i!=f7bLen)
499 _Z=0;
500 else
501 _Z=1;
502
503 F7BEND();
504 }
505
opSEARCHDB(UINT8 bSearch)506 UINT32 opSEARCHDB(UINT8 bSearch)
507 {
508 UINT8 appb;
509 INT32 i;
510
511 F7bDecodeOperands(ReadAMAddress,0,ReadAM,0);
512
513 for (i=f7bLen;i>=0;i--)
514 {
515 appb = (MemRead8(f7bOp1+i)==(UINT8)f7bOp2);
516 if ((bSearch && appb) || (!bSearch && !appb))
517 break;
518 }
519
520 R28=f7bOp1+i;
521 R27=i;
522
523 // This is the opposite as stated in V60 manual...
524 if ((UINT32)i!=f7bLen)
525 _Z=0;
526 else
527 _Z=1;
528
529 F7BEND();
530 }
531
opSEARCHDH(UINT8 bSearch)532 UINT32 opSEARCHDH(UINT8 bSearch)
533 {
534 UINT8 appb;
535 INT32 i;
536
537 F7bDecodeOperands(ReadAMAddress,1,ReadAM,1);
538
539 for (i=f7bLen-1;i>=0;i--)
540 {
541 appb = (MemRead16(f7bOp1+i*2)==(UINT16)f7bOp2);
542 if ((bSearch && appb) || (!bSearch && !appb))
543 break;
544 }
545
546 R28=f7bOp1+i*2;
547 R27=i;
548
549 if ((UINT32)i!=f7bLen)
550 _Z=0;
551 else
552 _Z=1;
553
554 F7BEND();
555 }
556
557
opSCHCUB(void)558 UINT32 opSCHCUB(void) { return opSEARCHUB(1); }
opSCHCUH(void)559 UINT32 opSCHCUH(void) { return opSEARCHUH(1); }
opSCHCDB(void)560 UINT32 opSCHCDB(void) { return opSEARCHDB(1); }
opSCHCDH(void)561 UINT32 opSCHCDH(void) { return opSEARCHDH(1); }
opSKPCUB(void)562 UINT32 opSKPCUB(void) { return opSEARCHUB(0); }
opSKPCUH(void)563 UINT32 opSKPCUH(void) { return opSEARCHUH(0); }
opSKPCDB(void)564 UINT32 opSKPCDB(void) { return opSEARCHDB(0); }
opSKPCDH(void)565 UINT32 opSKPCDH(void) { return opSEARCHDH(0); }
566
opCMPCB(void)567 UINT32 opCMPCB(void) { return opCMPSTRB(0,0); }
opCMPCH(void)568 UINT32 opCMPCH(void) { return opCMPSTRH(0,0); }
opCMPCFB(void)569 UINT32 opCMPCFB(void) { return opCMPSTRB(1,0); }
opCMPCFH(void)570 UINT32 opCMPCFH(void) { return opCMPSTRH(1,0); }
opCMPCSB(void)571 UINT32 opCMPCSB(void) { return opCMPSTRB(0,1); }
opCMPCSH(void)572 UINT32 opCMPCSH(void) { return opCMPSTRH(0,1); }
573
opMOVCUB(void)574 UINT32 opMOVCUB(void) { return opMOVSTRUB(0,0); }
opMOVCUH(void)575 UINT32 opMOVCUH(void) { return opMOVSTRUH(0,0); }
opMOVCFUB(void)576 UINT32 opMOVCFUB(void) { return opMOVSTRUB(1,0); }
opMOVCFUH(void)577 UINT32 opMOVCFUH(void) { return opMOVSTRUH(1,0); }
opMOVCSUB(void)578 UINT32 opMOVCSUB(void) { return opMOVSTRUB(0,1); }
opMOVCSUH(void)579 UINT32 opMOVCSUH(void) { return opMOVSTRUH(0,1); }
580
opMOVCDB(void)581 UINT32 opMOVCDB(void) { return opMOVSTRDB(0,0); }
opMOVCDH(void)582 UINT32 opMOVCDH(void) { return opMOVSTRDH(0,0); }
opMOVCFDB(void)583 UINT32 opMOVCFDB(void) { return opMOVSTRDB(1,0); }
opMOVCFDH(void)584 UINT32 opMOVCFDH(void) { return opMOVSTRDH(1,0); }
585
opEXTBFZ(void)586 UINT32 opEXTBFZ(void) /* TRUSTED */
587 {
588 F7bDecodeFirstOperand(BitReadAM, 11);
589
590 F7BCREATEBITMASK(f7bLen);
591
592 modWriteValW=(f7bOp1 >> bamOffset) & f7bLen;
593
594 F7bWriteSecondOperand(2);
595
596 F7BEND();
597 }
598
opEXTBFS(void)599 UINT32 opEXTBFS(void) /* TRUSTED */
600 {
601 F7bDecodeFirstOperand(BitReadAM, 11);
602
603 F7BCREATEBITMASK(f7bLen);
604
605 modWriteValW=(f7bOp1 >> bamOffset) & f7bLen;
606 if (modWriteValW & ((f7bLen+1)>>1))
607 modWriteValW |= ~f7bLen;
608
609 F7bWriteSecondOperand(2);
610
611 F7BEND();
612 }
613
opEXTBFL(void)614 UINT32 opEXTBFL(void)
615 {
616 UINT32 appw;
617
618 F7bDecodeFirstOperand(BitReadAM, 11);
619
620 appw=f7bLen;
621 F7BCREATEBITMASK(f7bLen);
622
623 modWriteValW=(f7bOp1 >> bamOffset) & f7bLen;
624 modWriteValW<<=32-appw;
625
626 F7bWriteSecondOperand(2);
627
628 F7BEND();
629 }
630
opSCHBS(UINT32 bSearch1)631 UINT32 opSCHBS(UINT32 bSearch1)
632 {
633 UINT32 i,data;
634 UINT32 offset;
635
636 F7bDecodeFirstOperand(BitReadAMAddress,10);
637
638 // Read first UINT8
639 f7bOp1 += bamOffset/8;
640 data = MemRead8(f7bOp1);
641 offset = bamOffset&7;
642
643 // Scan bitstring
644 for (i=0;i<f7bLen;i++)
645 {
646 // Update the work register
647 R28 = f7bOp1;
648
649 // There is a 0/1 at current offset?
650 if ((bSearch1 && (data&(1<<offset))) ||
651 (!bSearch1 && !(data&(1<<offset))))
652 break;
653
654 // Next bit please
655 offset++;
656 if (offset==8)
657 {
658 // Next UINT8 please
659 offset=0;
660 f7bOp1++;
661 data = MemRead8(f7bOp1);
662 }
663 }
664
665 // Set zero if bit not found
666 _Z = (i == f7bLen);
667
668 // Write to destination the final offset
669 modWriteValW = i;
670 F7bWriteSecondOperand(2);
671
672 F7BEND();
673 }
674
opSCH0BSU(void)675 UINT32 opSCH0BSU(void) { return opSCHBS(0); }
opSCH1BSU(void)676 UINT32 opSCH1BSU(void) { return opSCHBS(1); }
677
opINSBFR(void)678 UINT32 opINSBFR(void)
679 {
680 UINT32 appw;
681 F7cDecodeOperands(ReadAM,2,BitReadAMAddress,11);
682
683 F7CCREATEBITMASK(f7cLen);
684
685 f7cOp2 += bamOffset/8;
686 appw = MemRead32(f7cOp2);
687 bamOffset &= 7;
688
689 appw &= ~(f7cLen << bamOffset);
690 appw |= (f7cLen & f7cOp1) << bamOffset;
691
692 MemWrite32(f7cOp2, appw);
693
694 F7CEND();
695 }
696
opINSBFL(void)697 UINT32 opINSBFL(void)
698 {
699 UINT32 appw;
700 F7cDecodeOperands(ReadAM,2,BitReadAMAddress,11);
701
702 f7cOp1 >>= (32-f7cLen);
703
704 F7CCREATEBITMASK(f7cLen);
705
706 f7cOp2 += bamOffset/8;
707 appw = MemRead32(f7cOp2);
708 bamOffset &= 7;
709
710 appw &= ~(f7cLen << bamOffset);
711 appw |= (f7cLen & f7cOp1) << bamOffset;
712
713 MemWrite32(f7cOp2, appw);
714
715 F7CEND();
716 }
717
opMOVBSD(void)718 UINT32 opMOVBSD(void)
719 {
720 UINT32 i;
721 UINT8 srcdata, dstdata;
722
723 F7bDecodeOperands(BitReadAMAddress,10,BitReadAMAddress,10);
724
725 // if (f7bLen!=1)
726 // { int a=1; }
727
728 f7bBamOffset1 += f7bLen-1;
729 f7bBamOffset2 += f7bLen-1;
730
731 f7bOp1 += f7bBamOffset1/8;
732 f7bOp2 += f7bBamOffset2/8;
733
734 f7bBamOffset1 &= 7;
735 f7bBamOffset2 &= 7;
736
737 srcdata = MemRead8(f7bOp1);
738 dstdata = MemRead8(f7bOp2);
739
740 for (i=0;i<f7bLen;i++)
741 {
742 // Update work registers
743 R28 = f7bOp1;
744 R27 = f7bOp2;
745
746 dstdata &= ~(1 << f7bBamOffset2);
747 dstdata |= ((srcdata >> f7bBamOffset1) & 1) << f7bBamOffset2;
748
749 if (f7bBamOffset1 == 0)
750 {
751 f7bBamOffset1 = 8;
752 f7bOp1--;
753 srcdata = MemRead8(f7bOp1);
754 }
755 if (f7bBamOffset2 == 0)
756 {
757 MemWrite8(f7bOp2, dstdata);
758 f7bBamOffset2 = 8;
759 f7bOp2--;
760 dstdata = MemRead8(f7bOp2);
761 }
762
763 f7bBamOffset1--;
764 f7bBamOffset2--;
765 }
766
767 // Flush of the final data
768 if (f7bBamOffset2 != 7)
769 MemWrite8(f7bOp2, dstdata);
770
771 F7BEND();
772 }
773
opMOVBSU(void)774 UINT32 opMOVBSU(void)
775 {
776 UINT32 i;
777 UINT8 srcdata, dstdata;
778
779 F7bDecodeOperands(BitReadAMAddress,10,BitReadAMAddress,10);
780
781 f7bOp1 += f7bBamOffset1/8;
782 f7bOp2 += f7bBamOffset2/8;
783
784 f7bBamOffset1 &= 7;
785 f7bBamOffset2 &= 7;
786
787 srcdata = MemRead8(f7bOp1);
788 dstdata = MemRead8(f7bOp2);
789
790 for (i=0;i<f7bLen;i++)
791 {
792 // Update work registers
793 R28 = f7bOp1;
794 R27 = f7bOp2;
795
796 dstdata &= ~(1 << f7bBamOffset2);
797 dstdata |= ((srcdata >> f7bBamOffset1) & 1) << f7bBamOffset2;
798
799 f7bBamOffset1++;
800 f7bBamOffset2++;
801 if (f7bBamOffset1 == 8)
802 {
803 f7bBamOffset1 = 0;
804 f7bOp1++;
805 srcdata = MemRead8(f7bOp1);
806 }
807 if (f7bBamOffset2 == 8)
808 {
809 MemWrite8(f7bOp2, dstdata);
810 f7bBamOffset2 = 0;
811 f7bOp2++;
812 dstdata = MemRead8(f7bOp2);
813 }
814 }
815
816 // Flush of the final data
817 if (f7bBamOffset2 != 0)
818 MemWrite8(f7bOp2, dstdata);
819
820 F7BEND();
821 }
822
823 // RADM 0x20f4b8 holds the time left
824
opADDDC(void)825 UINT32 opADDDC(void)
826 {
827 UINT8 appb;
828 UINT8 src, dst;
829
830 F7cDecodeOperands(ReadAM, 0, ReadAMAddress, 0);
831
832 if (f7cLen != 0)
833 {
834 logerror("ADDDC %x (pat: %x)\n", f7cOp1, f7cLen);
835 }
836
837 F7CLOADOP2BYTE(appb);
838
839 src = (appb >> 4) * 10 + (appb & 0xF);
840 dst = (UINT8)(f7cOp1 >> 4) * 10 + (UINT8)(f7cOp1 & 0xF);
841
842 appb = src + dst + (_CY?1:0);
843
844 if (appb >= 100)
845 {
846 appb -= 100;
847 _CY = 1;
848 }
849 else
850 _CY = 0;
851
852 // compute z flag:
853 // cleared if result non-zero or carry generated
854 // unchanged otherwise
855 if (appb != 0 || _CY)
856 _Z = 0;
857
858 appb = ((appb/10)<<4) | (appb % 10);
859
860 F7CSTOREOP2BYTE();
861 F7CEND();
862 }
863
opSUBDC(void)864 UINT32 opSUBDC(void)
865 {
866 INT8 appb;
867 UINT32 src, dst;
868
869 F7cDecodeOperands(ReadAM, 0, ReadAMAddress, 0);
870
871 if (f7cLen != 0)
872 {
873 logerror("SUBDC %x (pat: %x)\n", f7cOp1, f7cLen);
874 }
875
876 F7CLOADOP2BYTE(appb);
877
878 src = ((appb & 0xF0) >> 4) * 10 + (appb & 0xF);
879 dst = (UINT32)(f7cOp1 >> 4) * 10 + (UINT32)(f7cOp1 & 0xF);
880
881 // Note that this APPB must be SIGNED!
882 appb = (INT32)src - (INT32)dst - (_CY?1:0);
883
884 if (appb < 0)
885 {
886 appb += 100;
887 _CY = 1;
888 }
889 else
890 _CY = 0;
891
892 // compute z flag:
893 // cleared if result non-zero or carry generated
894 // unchanged otherwise
895 if (appb != 0 || _CY)
896 _Z = 0;
897
898 appb = ((appb/10)<<4) | (appb % 10);
899
900 F7CSTOREOP2BYTE();
901 F7CEND();
902 }
903
opSUBRDC(void)904 UINT32 opSUBRDC(void)
905 {
906 F7cDecodeOperands(ReadAM, 0, ReadAMAddress, 0);
907
908 logerror("SUBRDC %x (pat: %x)\n", f7cOp1, f7cLen);
909
910 F7CEND();
911 }
912
opCVTDPZ(void)913 UINT32 opCVTDPZ(void)
914 {
915 UINT16 apph;
916
917 F7cDecodeOperands(ReadAM, 0, ReadAMAddress, 1);
918
919 apph = (UINT16)(((f7cOp1 >> 4) & 0xF) | ((f7cOp1 & 0xF) << 8));
920 apph |= (f7cLen);
921 apph |= (f7cLen<<8);
922
923 // Z flag is unchanged if src is zero, cleared otherwise
924 if (f7cOp1 != 0) _Z = 0;
925
926 F7CSTOREOP2HALF();
927 F7CEND();
928 }
929
opCVTDZP(void)930 UINT32 opCVTDZP(void)
931 {
932 UINT8 appb;
933 F7cDecodeOperands(ReadAM, 1, ReadAMAddress, 0);
934
935 if ((f7cOp1 & 0xF0) != (f7cLen & 0xF0) || ((f7cOp1 >> 8) & 0xF0) != (f7cLen & 0xF0))
936 {
937 // Decimal exception
938 logerror("CVTD.ZP Decimal exception #1!\n");
939 }
940
941 if ((f7cOp1 & 0xF) > 9 || ((f7cOp1 >> 8) & 0xF) > 9)
942 {
943 // Decimal exception
944 logerror("CVTD.ZP Decimal exception #2!\n");
945 }
946
947 appb = (UINT8)(((f7cOp1 >> 8) & 0xF) | ((f7cOp1 & 0xF) << 4));
948 if (appb != 0) _Z = 0;
949
950 F7CSTOREOP2BYTE();
951 F7CEND();
952 }
953
op58UNHANDLED(void)954 UINT32 op58UNHANDLED(void)
955 {
956 logerror("Unhandled 58 opcode at PC: /%06x\n", PC);
957 abort();
958 }
959
op5AUNHANDLED(void)960 UINT32 op5AUNHANDLED(void)
961 {
962 logerror("Unhandled 5A opcode at PC: /%06x\n", PC);
963 abort();
964 }
965
op5BUNHANDLED(void)966 UINT32 op5BUNHANDLED(void)
967 {
968 logerror("Unhandled 5B opcode at PC: /%06x\n", PC);
969 abort();
970 }
971
op5DUNHANDLED(void)972 UINT32 op5DUNHANDLED(void)
973 {
974 logerror("Unhandled 5D opcode at PC: /%06x\n", PC);
975 abort();
976 }
977
op59UNHANDLED(void)978 UINT32 op59UNHANDLED(void)
979 {
980 logerror("Unhandled 59 opcode at PC: /%06x\n", PC);
981 abort();
982 }
983
984 UINT32 (*Op59Table[32])(void) =
985 {
986 opADDDC,
987 opSUBDC,
988 op59UNHANDLED,
989 op59UNHANDLED,
990 op59UNHANDLED,
991 op59UNHANDLED,
992 op59UNHANDLED,
993 op59UNHANDLED,
994 op59UNHANDLED,
995 op59UNHANDLED,
996 op59UNHANDLED,
997 op59UNHANDLED,
998 op59UNHANDLED,
999 op59UNHANDLED,
1000 op59UNHANDLED,
1001 op59UNHANDLED,
1002 opCVTDPZ,
1003 op59UNHANDLED,
1004 op59UNHANDLED,
1005 op59UNHANDLED,
1006 op59UNHANDLED,
1007 op59UNHANDLED,
1008 op59UNHANDLED,
1009 op59UNHANDLED,
1010 opCVTDZP,
1011 op59UNHANDLED,
1012 op59UNHANDLED,
1013 op59UNHANDLED,
1014 op59UNHANDLED,
1015 op59UNHANDLED,
1016 op59UNHANDLED,
1017 op59UNHANDLED
1018 };
1019
1020
1021 UINT32 (*Op5BTable[32])(void) =
1022 {
1023 opSCH0BSU, op5BUNHANDLED,
1024 opSCH1BSU, op5BUNHANDLED,
1025 op5BUNHANDLED,op5BUNHANDLED,
1026 op5BUNHANDLED,op5BUNHANDLED,
1027 opMOVBSU, opMOVBSD,
1028 op5BUNHANDLED,op5BUNHANDLED,
1029 op5BUNHANDLED,op5BUNHANDLED,
1030 op5BUNHANDLED,op5BUNHANDLED,
1031 op5BUNHANDLED,op5BUNHANDLED,
1032 op5BUNHANDLED,op5BUNHANDLED,
1033 op5BUNHANDLED,op5BUNHANDLED,
1034 op5BUNHANDLED,op5BUNHANDLED,
1035 op5BUNHANDLED,op5BUNHANDLED,
1036 op5BUNHANDLED,op5BUNHANDLED,
1037 op5BUNHANDLED,op5BUNHANDLED,
1038 op5BUNHANDLED,op5BUNHANDLED
1039 };
1040
1041
1042 UINT32 (*Op5DTable[32])(void) =
1043 {
1044 op5DUNHANDLED,
1045 op5DUNHANDLED,
1046 op5DUNHANDLED,
1047 op5DUNHANDLED,
1048 op5DUNHANDLED,
1049 op5DUNHANDLED,
1050 op5DUNHANDLED,
1051 op5DUNHANDLED,
1052 opEXTBFS,
1053 opEXTBFZ,
1054 opEXTBFL,
1055 op5DUNHANDLED,
1056 op5DUNHANDLED,
1057 op5DUNHANDLED,
1058 op5DUNHANDLED,
1059 op5DUNHANDLED,
1060 op5DUNHANDLED,
1061 op5DUNHANDLED,
1062 op5DUNHANDLED,
1063 op5DUNHANDLED,
1064 op5DUNHANDLED,
1065 op5DUNHANDLED,
1066 op5DUNHANDLED,
1067 op5DUNHANDLED,
1068 opINSBFR,
1069 opINSBFL,
1070 op5DUNHANDLED,
1071 op5DUNHANDLED,
1072 op5DUNHANDLED,
1073 op5DUNHANDLED,
1074 op5DUNHANDLED,
1075 op5DUNHANDLED
1076 };
1077
1078 UINT32 (*Op585ATable[32][2])(void) =
1079 {
1080 { opCMPCB , opCMPCH },
1081 { opCMPCFB , opCMPCFH },
1082 { opCMPCSB , opCMPCSH },
1083 { op58UNHANDLED, op5AUNHANDLED },
1084 { op58UNHANDLED, op5AUNHANDLED },
1085 { op58UNHANDLED, op5AUNHANDLED },
1086 { op58UNHANDLED, op5AUNHANDLED },
1087 { op58UNHANDLED, op5AUNHANDLED },
1088 { opMOVCUB , opMOVCUH },
1089 { opMOVCDB , opMOVCDH },
1090 { opMOVCFUB , opMOVCFUH },
1091 { opMOVCFDB , opMOVCFDH },
1092 { opMOVCSUB , opMOVCSUH },
1093 { op58UNHANDLED, op5AUNHANDLED },
1094 { op58UNHANDLED, op5AUNHANDLED },
1095 { op58UNHANDLED, op5AUNHANDLED },
1096 { op58UNHANDLED, op5AUNHANDLED },
1097 { op58UNHANDLED, op5AUNHANDLED },
1098 { op58UNHANDLED, op5AUNHANDLED },
1099 { op58UNHANDLED, op5AUNHANDLED },
1100 { op58UNHANDLED, op5AUNHANDLED },
1101 { op58UNHANDLED, op5AUNHANDLED },
1102 { op58UNHANDLED, op5AUNHANDLED },
1103 { op58UNHANDLED, op5AUNHANDLED },
1104 { opSCHCUB , opSCHCUH },
1105 { opSCHCDB , opSCHCDH },
1106 { opSKPCUB , opSKPCUH },
1107 { opSKPCDB , opSKPCDH },
1108 { op58UNHANDLED, op5AUNHANDLED },
1109 { op58UNHANDLED, op5AUNHANDLED },
1110 { op58UNHANDLED, op5AUNHANDLED },
1111 { op58UNHANDLED, op5AUNHANDLED }
1112 };
1113
op58(void)1114 UINT32 op58(void)
1115 {
1116 subOp = OpRead8(PC + 1);
1117
1118 return Op585ATable[subOp&0x1F][0]();
1119 }
1120
op5A(void)1121 UINT32 op5A(void)
1122 {
1123 subOp = OpRead8(PC + 1);
1124
1125 return Op585ATable[subOp&0x1F][1]();
1126 }
1127
op5B(void)1128 UINT32 op5B(void)
1129 {
1130 subOp = OpRead8(PC + 1);
1131
1132 return Op5BTable[subOp&0x1F]();
1133 }
1134
op5D(void)1135 UINT32 op5D(void)
1136 {
1137 subOp = OpRead8(PC + 1);
1138
1139 return Op5DTable[subOp&0x1F]();
1140 }
1141
op59(void)1142 UINT32 op59(void)
1143 {
1144 subOp = OpRead8(PC + 1);
1145
1146 return Op59Table[subOp&0x1F]();
1147 }
1148