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