1 /*
2  * MUL* and MULU* do not set OV correctly
3  * DIVX: the second operand should be treated as dword instead of word
4  * GETATE, GETPTE and GETRA should not be used
5  * UPDPSW: _CY and _OV must be cleared or unchanged? I suppose
6  *   cleared, like TEST being done on the mask operand.
7  * MOVT: I cannot understand exactly what happens to the result
8  *   when an overflow occurs
9  *
10  * Unimplemented opcodes:
11  * ROTC, UPDATE, UPDPTE
12  */
13 
14 static UINT32 f12Op1, f12Op2;
15 static UINT8 f12Flag1, f12Flag2;
16 
17 
18 /*
19  *  Macro to access data in operands decoded with ReadAMAddress()
20  */
21 
22 #define F12LOADOPBYTE(num)			  \
23 	if (f12Flag##num)								\
24 		appb = (UINT8)v60.reg[f12Op##num];  \
25 	else														\
26 		appb = MemRead8(f12Op##num);
27 
28 #define F12LOADOPHALF(num)			  \
29 	if (f12Flag##num)								\
30 		apph = (UINT16)v60.reg[f12Op##num];  \
31 	else														\
32 		apph = MemRead16(f12Op##num);
33 
34 #define F12LOADOPWORD(num)			  \
35 	if (f12Flag##num)								\
36 		appw = v60.reg[f12Op##num];  \
37 	else														\
38 		appw = MemRead32(f12Op##num);
39 
40 #define F12STOREOPBYTE(num)				\
41 	if (f12Flag##num)								\
42 		SETREG8(v60.reg[f12Op##num], appb);	\
43 	else														\
44 		MemWrite8(f12Op##num,appb);
45 
46 #define F12STOREOPHALF(num)				\
47 	if (f12Flag##num)								\
48 		SETREG16(v60.reg[f12Op##num], apph);	\
49 	else														\
50 		MemWrite16(f12Op##num,apph);
51 
52 #define F12STOREOPWORD(num)				\
53 	if (f12Flag##num)								\
54 		v60.reg[f12Op##num] = appw;	\
55 	else														\
56 		MemWrite32(f12Op##num,appw);
57 
58 #define F12LOADOP1BYTE()  F12LOADOPBYTE(1)
59 #define F12LOADOP1HALF()  F12LOADOPHALF(1)
60 #define F12LOADOP1WORD()  F12LOADOPWORD(1)
61 
62 #define F12LOADOP2BYTE()  F12LOADOPBYTE(2)
63 #define F12LOADOP2HALF()  F12LOADOPHALF(2)
64 #define F12LOADOP2WORD()  F12LOADOPWORD(2)
65 
66 #define F12STOREOP1BYTE()  F12STOREOPBYTE(1)
67 #define F12STOREOP1HALF()  F12STOREOPHALF(1)
68 #define F12STOREOP1WORD()  F12STOREOPWORD(1)
69 
70 #define F12STOREOP2BYTE()  F12STOREOPBYTE(2)
71 #define F12STOREOP2HALF()  F12STOREOPHALF(2)
72 #define F12STOREOP2WORD()  F12STOREOPWORD(2)
73 
74 
75 
76 #define F12END()									\
77 	return amLength1 + amLength2 + 2;
78 
79 static UINT8 if12;
80 
81 // Decode the first operand of the instruction and prepare
82 // writing to the second operand.
F12DecodeFirstOperand(UINT32 (* DecodeOp1)(void),UINT8 dim1)83 static void F12DecodeFirstOperand(UINT32 (*DecodeOp1)(void), UINT8 dim1)
84 {
85 	if12 = OpRead8(PC + 1);
86 
87 	// Check if F1 or F2
88 	if (if12 & 0x80)
89 	{
90 		modDim = dim1;
91 		modM = if12 & 0x40;
92 		modAdd = PC + 2;
93 		amLength1 = DecodeOp1();
94 		f12Op1 = amOut;
95 		f12Flag1 = amFlag;
96 	}
97 	else
98 	{
99 		// Check D flag
100 		if (if12 & 0x20)
101 		{
102 			modDim = dim1;
103 			modM = if12 & 0x40;
104 			modAdd = PC + 2;
105 			amLength1 = DecodeOp1();
106 			f12Op1 = amOut;
107 			f12Flag1 = amFlag;
108 		}
109 		else
110 		{
111 			if (DecodeOp1==ReadAM)
112 			{
113 				switch (dim1)
114 				{
115 				case 0:
116 					f12Op1 = (UINT8)v60.reg[if12 & 0x1F];
117 					break;
118 				case 1:
119 					f12Op1 = (UINT16)v60.reg[if12 & 0x1F];
120 					break;
121 				case 2:
122 					f12Op1 = v60.reg[if12 & 0x1F];
123 					break;
124 				}
125 
126 				f12Flag1 = 0;
127 			}
128 			else
129 			{
130 				f12Flag1 = 1;
131 				f12Op1 = if12 & 0x1F;
132 			}
133 
134 			amLength1 = 0;
135 		}
136 	}
137 }
138 
F12WriteSecondOperand(UINT8 dim2)139 static void F12WriteSecondOperand(UINT8 dim2)
140 {
141 	modDim = dim2;
142 
143 	// Check if F1 or F2
144 	if (if12 & 0x80)
145 	{
146 		modM = if12 & 0x20;
147 		modAdd = PC + 2 + amLength1;
148 		modDim = dim2;
149 		amLength2 = WriteAM();
150 	}
151 	else
152 	{
153 		// Check D flag
154 		if (if12 & 0x20)
155 		{
156 			switch (dim2)
157 			{
158 			case 0:
159 				SETREG8(v60.reg[if12 & 0x1F], modWriteValB);
160 				break;
161 			case 1:
162 				SETREG16(v60.reg[if12 & 0x1F], modWriteValH);
163 				break;
164 			case 2:
165 				v60.reg[if12 & 0x1F] = modWriteValW;
166 				break;
167 			}
168 
169 			amLength2 = 0;
170 		}
171 		else
172 		{
173 			modM = if12 & 0x40;
174 			modAdd = PC + 2;
175 			modDim = dim2;
176 			amLength2 = WriteAM();
177 		}
178 	}
179 }
180 
181 
182 
183 // Decode both format 1/2 operands
F12DecodeOperands(UINT32 (* DecodeOp1)(void),UINT8 dim1,UINT32 (* DecodeOp2)(void),UINT8 dim2)184 static void F12DecodeOperands(UINT32 (*DecodeOp1)(void), UINT8 dim1, UINT32 (*DecodeOp2)(void), UINT8 dim2)
185 {
186 	UINT8 _if12 = OpRead8(PC + 1);
187 
188 	// Check if F1 or F2
189 	if (_if12 & 0x80)
190 	{
191 		modDim = dim1;
192 		modM = _if12 & 0x40;
193 		modAdd = PC + 2;
194 		amLength1 = DecodeOp1();
195 		f12Op1 = amOut;
196 		f12Flag1 = amFlag;
197 
198 		modDim = dim2;
199 		modM = _if12 & 0x20;
200 		modAdd = PC + 2 + amLength1;
201 		amLength2 = DecodeOp2();
202 		f12Op2 = amOut;
203 		f12Flag2 = amFlag;
204 	}
205 	else
206 	{
207 		// Check D flag
208 		if (_if12 & 0x20)
209 		{
210 			if (DecodeOp2==ReadAMAddress)
211 			{
212 				f12Op2 = _if12 & 0x1F;
213 				f12Flag2 = 1;
214 			}
215 			else
216 			{
217 				switch (dim2)
218 				{
219 				case 0:
220 					f12Op2 = (UINT8)v60.reg[_if12 & 0x1F];
221 					break;
222 				case 1:
223 					f12Op2 = (UINT16)v60.reg[_if12 & 0x1F];
224 					break;
225 				case 2:
226 					f12Op2 = v60.reg[_if12 & 0x1F];
227 					break;
228 				}
229 			}
230 
231 			amLength2 = 0;
232 
233 			modDim = dim1;
234 			modM = _if12 & 0x40;
235 			modAdd = PC + 2;
236 			amLength1 = DecodeOp1();
237 			f12Op1 = amOut;
238 			f12Flag1 = amFlag;
239 		}
240 		else
241 		{
242 			if (DecodeOp1==ReadAMAddress)
243 			{
244 				f12Op1 = _if12 & 0x1F;
245 				f12Flag1 = 1;
246 			}
247 			else
248 			{
249 				switch (dim1)
250 				{
251 				case 0:
252 					f12Op1 = (UINT8)v60.reg[_if12 & 0x1F];
253 					break;
254 				case 1:
255 					f12Op1 = (UINT16)v60.reg[_if12 & 0x1F];
256 					break;
257 				case 2:
258 					f12Op1 = v60.reg[_if12 & 0x1F];
259 					break;
260 				}
261 			}
262 			amLength1 = 0;
263 
264 			modDim = dim2;
265 			modM = _if12 & 0x40;
266 			modAdd = PC + 2 + amLength1;
267 			amLength2 = DecodeOp2();
268 			f12Op2 = amOut;
269 			f12Flag2 = amFlag;
270 		}
271 	}
272 }
273 
opADDB(void)274 static UINT32 opADDB(void) /* TRUSTED (C too!)*/
275 {
276 	UINT8 appb;
277 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
278 
279 	F12LOADOP2BYTE();
280 
281 	ADDB(appb, (UINT8)f12Op1);
282 
283 	F12STOREOP2BYTE();
284 	F12END();
285 }
286 
opADDH(void)287 static UINT32 opADDH(void) /* TRUSTED (C too!)*/
288 {
289 	UINT16 apph;
290 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
291 
292 	F12LOADOP2HALF();
293 
294 	ADDW(apph, (UINT16)f12Op1);
295 
296 	F12STOREOP2HALF();
297 	F12END();
298 }
299 
opADDW(void)300 static UINT32 opADDW(void) /* TRUSTED (C too!) */
301 {
302 	UINT32 appw;
303 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
304 
305 	F12LOADOP2WORD();
306 
307 	ADDL(appw, (UINT32)f12Op1);
308 
309 	F12STOREOP2WORD();
310 	F12END();
311 }
312 
opADDCB(void)313 static UINT32 opADDCB(void)
314 {
315 	UINT8 appb, temp;
316 
317 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
318 
319 	F12LOADOP2BYTE();
320 
321 	temp = ((UINT8)f12Op1 + (_CY?1:0));
322 	ADDB(appb, temp);
323 
324 	F12STOREOP2BYTE();
325 	F12END();
326 }
327 
opADDCH(void)328 static UINT32 opADDCH(void)
329 {
330 	UINT16 apph, temp;
331 
332 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
333 
334 	F12LOADOP2HALF();
335 
336 	temp = ((UINT16)f12Op1 + (_CY?1:0));
337 	ADDW(apph, temp);
338 
339 	F12STOREOP2HALF();
340 	F12END();
341 }
342 
opADDCW(void)343 static UINT32 opADDCW(void)
344 {
345 	UINT32 appw, temp;
346 
347 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
348 
349 	F12LOADOP2WORD();
350 
351 	temp = f12Op1 + (_CY?1:0);
352 	ADDL(appw, temp);
353 
354 	F12STOREOP2WORD();
355 	F12END();
356 }
357 
opANDB(void)358 static UINT32 opANDB(void) /* TRUSTED */
359 {
360 	UINT8 appb;
361 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
362 
363 	F12LOADOP2BYTE();
364 
365 	appb &= f12Op1;
366 	_OV = 0;
367 	_S = ((appb&0x80)!=0);
368 	_Z = (appb==0);
369 
370 	F12STOREOP2BYTE();
371 	F12END();
372 }
373 
opANDH(void)374 static UINT32 opANDH(void) /* TRUSTED */
375 {
376 	UINT16 apph;
377 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
378 
379 	F12LOADOP2HALF();
380 
381 	apph &= f12Op1;
382 	_OV = 0;
383 	_S = ((apph&0x8000)!=0);
384 	_Z = (apph==0);
385 
386 	F12STOREOP2HALF();
387 	F12END();
388 }
389 
opANDW(void)390 static UINT32 opANDW(void) /* TRUSTED */
391 {
392 	UINT32 appw;
393 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
394 
395 	F12LOADOP2WORD();
396 
397 	appw &= f12Op1;
398 	_OV = 0;
399 	_S = ((appw&0x80000000)!=0);
400 	_Z = (appw==0);
401 
402 	F12STOREOP2WORD();
403 	F12END();
404 }
405 
opCALL(void)406 static UINT32 opCALL(void) /* TRUSTED */
407 {
408 	F12DecodeOperands(ReadAMAddress,0,ReadAMAddress,2);
409 
410 	SP -= 4;
411 	MemWrite32(SP, AP);
412 	AP = f12Op2;
413 
414 	SP -= 4;
415 	MemWrite32(SP, PC + amLength1 + amLength2 + 2);
416 	PC = f12Op1;
417 	ChangePC(PC);
418 
419 	return 0;
420 }
421 
opCHKAR(void)422 static UINT32 opCHKAR(void)
423 {
424 	F12DecodeOperands(ReadAM,0,ReadAM,0);
425 
426 	// No MMU and memory permissions yet @@@
427 	_Z = 1;
428 	_CY = 0;
429 	_S = 0;
430 
431 	F12END();
432 }
433 
opCHKAW(void)434 static UINT32 opCHKAW(void)
435 {
436 	F12DecodeOperands(ReadAM,0,ReadAM,0);
437 
438 	// No MMU and memory permissions yet @@@
439 	_Z = 1;
440 	_CY = 0;
441 	_S = 0;
442 
443 	F12END();
444 }
445 
opCHKAE(void)446 static UINT32 opCHKAE(void)
447 {
448 	F12DecodeOperands(ReadAM,0,ReadAM,0);
449 
450 	// No MMU and memory permissions yet @@@
451 	_Z = 1;
452 	_CY = 0;
453 	_S = 0;
454 
455 	F12END();
456 }
457 
opCHLVL(void)458 static UINT32 opCHLVL(void)
459 {
460 	UINT32 oldPSW;
461 
462 	F12DecodeOperands(ReadAM,0,ReadAM,0);
463 
464 	if (f12Op1>3)
465 	{
466 		//fatalerror("Illegal data field on opCHLVL, PC=%x", PC);
467 	}
468 
469 	oldPSW = v60_update_psw_for_exception(0, f12Op1);
470 
471 	SP -= 4;
472 	MemWrite32(SP,f12Op2);
473 
474 	SP -= 4;
475 	MemWrite32(SP,EXCEPTION_CODE_AND_SIZE(0x1800 + f12Op1*0x100, 8));
476 
477 	SP -= 4;
478 	MemWrite32(SP,oldPSW);
479 
480 	SP -= 4;
481 	MemWrite32(SP,PC + amLength1 + amLength2 + 2);
482 
483 	PC = GETINTVECT(24+f12Op1);
484 	ChangePC(PC);
485 
486 	return 0;
487 }
488 
opCLR1(void)489 static UINT32 opCLR1(void) /* TRUSTED */
490 {
491 	UINT32 appw;
492 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
493 
494 	F12LOADOP2WORD();
495 
496 	_CY = ((appw & (1<<f12Op1))!=0);
497 	_Z = !(_CY);
498 
499 	appw &= ~(1<<f12Op1);
500 
501 	F12STOREOP2WORD();
502 	F12END();
503 }
504 
opCMPB(void)505 static UINT32 opCMPB(void) /* TRUSTED (C too!) */
506 {
507 	UINT8 appb;
508 	F12DecodeOperands(ReadAM,0,ReadAM,0);
509 
510 	appb = (UINT8)f12Op2;
511 	SUBB(appb, (UINT8)f12Op1);
512 
513 	F12END();
514 }
515 
opCMPH(void)516 static UINT32 opCMPH(void) /* TRUSTED (C too!) */
517 {
518 	UINT16 apph;
519 	F12DecodeOperands(ReadAM,1,ReadAM,1);
520 
521 	apph = (UINT16)f12Op2;
522 	SUBW(apph, (UINT16)f12Op1);
523 
524 	F12END();
525 }
526 
527 
opCMPW(void)528 static UINT32 opCMPW(void) /* TRUSTED (C too!)*/
529 {
530 	F12DecodeOperands(ReadAM,2,ReadAM,2);
531 
532 	SUBL(f12Op2, (UINT32)f12Op1);
533 
534 	F12END();
535 }
536 
opDIVB(void)537 static UINT32 opDIVB(void) /* TRUSTED */
538 {
539 	UINT8 appb;
540 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
541 
542 	F12LOADOP2BYTE();
543 
544 	_OV = ((appb == 0x80) && (f12Op1==0xFF));
545 	if (f12Op1 && !_OV)
546 		appb= (INT8)appb / (INT8)f12Op1;
547 	_Z = (appb == 0);
548 	_S = ((appb & 0x80)!=0);
549 
550 	F12STOREOP2BYTE();
551 	F12END();
552 }
553 
opDIVH(void)554 static UINT32 opDIVH(void) /* TRUSTED */
555 {
556 	UINT16 apph;
557 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
558 
559 	F12LOADOP2HALF();
560 
561 	_OV = ((apph == 0x8000) && (f12Op1==0xFFFF));
562 	if (f12Op1 && !_OV)
563 		apph = (INT16)apph / (INT16)f12Op1;
564 	_Z = (apph == 0);
565 	_S = ((apph & 0x8000)!=0);
566 
567 	F12STOREOP2HALF();
568 	F12END();
569 }
570 
opDIVW(void)571 static UINT32 opDIVW(void) /* TRUSTED */
572 {
573 	UINT32 appw;
574 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
575 
576 	F12LOADOP2WORD();
577 
578 	_OV = ((appw == 0x80000000) && (f12Op1==0xFFFFFFFF));
579 	if (f12Op1 && !_OV)
580 		appw = (INT32)appw / (INT32)f12Op1;
581 	_Z = (appw == 0);
582 	_S = ((appw & 0x80000000)!=0);
583 
584 	F12STOREOP2WORD();
585 	F12END();
586 }
587 
opDIVX(void)588 static UINT32 opDIVX(void)
589 {
590 	UINT32 a,b;
591 	INT64 dv;
592 
593 	F12DecodeOperands(ReadAM,2,ReadAMAddress,3);
594 
595 	if (f12Flag2)
596 	{
597 		a=v60.reg[f12Op2&0x1F];
598 		b=v60.reg[(f12Op2&0x1F)+1];
599 	}
600 	else
601 	{
602 		a=MemRead32(f12Op2);
603 		b=MemRead32(f12Op2+4);
604 	}
605 
606 	dv = ((UINT64)b<<32) | ((UINT64)a);
607 
608 	a = dv / (INT64)((INT32)f12Op1);
609 	b = dv % (INT64)((INT32)f12Op1);
610 
611 	_S = ((a & 0x80000000)!=0);
612 	_Z = (a == 0);
613 
614 	if (f12Flag2)
615 	{
616 		v60.reg[f12Op2&0x1F]=a;
617 		v60.reg[(f12Op2&0x1F)+1]=b;
618 	}
619 	else
620 	{
621 		MemWrite32(f12Op2,a);
622 		MemWrite32(f12Op2+4,b);
623 	}
624 
625 	F12END();
626 }
627 
opDIVUX(void)628 static UINT32 opDIVUX(void)
629 {
630 	UINT32 a,b;
631 	UINT64 dv;
632 
633 	F12DecodeOperands(ReadAM,2,ReadAMAddress,3);
634 
635 	if (f12Flag2)
636 	{
637 		a=v60.reg[f12Op2&0x1F];
638 		b=v60.reg[(f12Op2&0x1F)+1];
639 	}
640 	else
641 	{
642 		a=MemRead32(f12Op2);
643 		b=MemRead32(f12Op2+4);
644 	}
645 
646 	dv = (UINT64)(((UINT64)b<<32) | (UINT64)a);
647 	a = (UINT32)(dv / (UINT64)f12Op1);
648 	b = (UINT32)(dv % (UINT64)f12Op1);
649 
650 	_S = ((a & 0x80000000) != 0);
651 	_Z = (a == 0);
652 
653 	if (f12Flag2)
654 	{
655 		v60.reg[f12Op2&0x1F]=a;
656 		v60.reg[(f12Op2&0x1F)+1]=b;
657 	}
658 	else
659 	{
660 		MemWrite32(f12Op2,a);
661 		MemWrite32(f12Op2+4,b);
662 	}
663 
664 	F12END();
665 }
666 
667 
opDIVUB(void)668 static UINT32 opDIVUB(void) /* TRUSTED */
669 {
670 	UINT8 appb;
671 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
672 
673 	F12LOADOP2BYTE();
674 
675 	_OV = 0;
676 	if (f12Op1)	appb /= (UINT8)f12Op1;
677 	_Z = (appb == 0);
678 	_S = ((appb & 0x80)!=0);
679 
680 	F12STOREOP2BYTE();
681 	F12END();
682 }
683 
opDIVUH(void)684 static UINT32 opDIVUH(void) /* TRUSTED */
685 {
686 	UINT16 apph;
687 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
688 
689 	F12LOADOP2HALF();
690 
691 	_OV = 0;
692 	if (f12Op1)	apph /= (UINT16)f12Op1;
693 	_Z = (apph == 0);
694 	_S = ((apph & 0x8000)!=0);
695 
696 	F12STOREOP2HALF();
697 	F12END();
698 }
699 
opDIVUW(void)700 static UINT32 opDIVUW(void) /* TRUSTED */
701 {
702 	UINT32 appw;
703 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
704 
705 	F12LOADOP2WORD();
706 
707 	_OV = 0;
708 	if (f12Op1)	appw /= f12Op1;
709 	_Z = (appw == 0);
710 	_S = ((appw & 0x80000000)!=0);
711 
712 	F12STOREOP2WORD();
713 	F12END();
714 }
715 
opINB(void)716 static UINT32 opINB(void)
717 {
718 	F12DecodeFirstOperand(ReadAMAddress,0);
719 	modWriteValB=PortRead8(f12Op1);
720 
721 	if ( v60.stall_io )
722 	{
723 		v60.stall_io = 0;
724 		return 0;
725 	}
726 
727 	F12WriteSecondOperand(0);
728 	F12END();
729 }
730 
opINH(void)731 static UINT32 opINH(void)
732 {
733 	F12DecodeFirstOperand(ReadAMAddress,1);
734 	modWriteValH=PortRead16(f12Op1);
735 
736 	if ( v60.stall_io )
737 	{
738 		v60.stall_io = 0;
739 		return 0;
740 	}
741 
742 	F12WriteSecondOperand(1);
743 	F12END();
744 }
745 
opINW(void)746 static UINT32 opINW(void)
747 {
748 	F12DecodeFirstOperand(ReadAMAddress,2);
749 	modWriteValW=PortRead32(f12Op1);
750 
751 	if ( v60.stall_io )
752 	{
753 		v60.stall_io = 0;
754 		return 0;
755 	}
756 
757 	F12WriteSecondOperand(2);
758 	F12END();
759 }
760 
opLDPR(void)761 static UINT32 opLDPR(void)
762 {
763 	F12DecodeOperands(ReadAMAddress,2,ReadAM,2);
764 	if (f12Op2 <= 28)
765 	{
766 	  if (f12Flag1 &&(!(OpRead8(PC + 1)&0x80 && OpRead8(PC + 2)==0xf4 ) ))
767 			v60.reg[f12Op2 + 36] = v60.reg[f12Op1];
768 		else
769 			v60.reg[f12Op2 + 36] = f12Op1;
770 	}
771 	else
772 	{
773 		//fatalerror("Invalid operand on LDPR PC=%x", PC);
774 	}
775 	F12END();
776 }
777 
opLDTASK(void)778 static UINT32 opLDTASK(void)
779 {
780 	int i;
781 	F12DecodeOperands(ReadAMAddress,2,ReadAM,2);
782 
783 	v60WritePSW(v60ReadPSW() & 0xefffffff);
784 
785 	TR = f12Op2;
786 
787 	TKCW = MemRead32(f12Op2);
788 	f12Op2 += 4;
789 	if(SYCW & 0x100) {
790 		L0SP = MemRead32(f12Op2);
791 		f12Op2 += 4;
792 	}
793 	if(SYCW & 0x200) {
794 		L1SP = MemRead32(f12Op2);
795 		f12Op2 += 4;
796 	}
797 	if(SYCW & 0x400) {
798 		L2SP = MemRead32(f12Op2);
799 		f12Op2 += 4;
800 	}
801 	if(SYCW & 0x800) {
802 		L3SP = MemRead32(f12Op2);
803 		f12Op2 += 4;
804 	}
805 
806 	v60ReloadStack();
807 
808 	// 31 registers supported, _not_ 32
809 	for(i=0; i<31; i++)
810 		if(f12Op1 & (1<<i)) {
811 			v60.reg[i] = MemRead32(f12Op2);
812 			f12Op2 += 4;
813 		}
814 
815 	// #### Ignore the virtual addressing crap.
816 
817 	F12END();
818 }
819 
opMOVD(void)820 static UINT32 opMOVD(void) /* TRUSTED */
821 {
822 	UINT32 a,b;
823 
824 	F12DecodeOperands(ReadAMAddress,3,ReadAMAddress,3);
825 
826 	if (f12Flag1)
827 	{
828 		a=v60.reg[f12Op1&0x1F];
829 		b=v60.reg[(f12Op1&0x1F)+1];
830 	}
831 	else
832 	{
833 		a=MemRead32(f12Op1);
834 		b=MemRead32(f12Op1+4);
835 	}
836 
837 	if (f12Flag2)
838 	{
839 		v60.reg[f12Op2&0x1F]=a;
840 		v60.reg[(f12Op2&0x1F)+1]=b;
841 	}
842 	else
843 	{
844 		MemWrite32(f12Op2,a);
845 		MemWrite32(f12Op2+4,b);
846 	}
847 
848 	F12END();
849 }
850 
opMOVB(void)851 static UINT32 opMOVB(void) /* TRUSTED */
852 {
853 	F12DecodeFirstOperand(ReadAM,0);
854 	modWriteValB = (UINT8)f12Op1;
855 	F12WriteSecondOperand(0);
856 	F12END();
857 }
858 
opMOVH(void)859 static UINT32 opMOVH(void) /* TRUSTED */
860 {
861 	F12DecodeFirstOperand(ReadAM,1);
862 	modWriteValH = (UINT16)f12Op1;
863 	F12WriteSecondOperand(1);
864 	F12END();
865 }
866 
opMOVW(void)867 static UINT32 opMOVW(void) /* TRUSTED */
868 {
869 	F12DecodeFirstOperand(ReadAM,2);
870 	modWriteValW = f12Op1;
871 	F12WriteSecondOperand(2);
872 	F12END();
873 }
874 
opMOVEAB(void)875 static UINT32 opMOVEAB(void) /* TRUSTED */
876 {
877 	F12DecodeFirstOperand(ReadAMAddress,0);
878 	modWriteValW = f12Op1;
879 	F12WriteSecondOperand(2);
880 	F12END();
881 }
882 
opMOVEAH(void)883 static UINT32 opMOVEAH(void) /* TRUSTED */
884 {
885 	F12DecodeFirstOperand(ReadAMAddress,1);
886 	modWriteValW = f12Op1;
887 	F12WriteSecondOperand(2);
888 	F12END();
889 }
890 
opMOVEAW(void)891 static UINT32 opMOVEAW(void) /* TRUSTED */
892 {
893 	F12DecodeFirstOperand(ReadAMAddress,2);
894 	modWriteValW = f12Op1;
895 	F12WriteSecondOperand(2);
896 	F12END();
897 }
898 
opMOVSBH(void)899 static UINT32 opMOVSBH(void) /* TRUSTED */
900 {
901 	F12DecodeFirstOperand(ReadAM,0);
902 	modWriteValH = (INT8)(f12Op1&0xFF);
903 	F12WriteSecondOperand(1);
904 	F12END();
905 }
906 
opMOVSBW(void)907 static UINT32 opMOVSBW(void) /* TRUSTED */
908 {
909 	F12DecodeFirstOperand(ReadAM,0);
910 	modWriteValW = (INT8)(f12Op1&0xFF);
911 	F12WriteSecondOperand(2);
912 	F12END();
913 }
914 
opMOVSHW(void)915 static UINT32 opMOVSHW(void) /* TRUSTED */
916 {
917 	F12DecodeFirstOperand(ReadAM,1);
918 	modWriteValW = (INT16)(f12Op1&0xFFFF);
919 	F12WriteSecondOperand(2);
920 	F12END();
921 }
922 
opMOVTHB(void)923 static UINT32 opMOVTHB(void)
924 {
925 	F12DecodeFirstOperand(ReadAM,1);
926 	modWriteValB = (UINT8)(f12Op1&0xFF);
927 
928 	// Check for overflow: the truncated bits must match the sign
929 	//  of the result, otherwise overflow
930 	if (((modWriteValB&0x80)==0x80 && ((f12Op1&0xFF00)==0xFF00)) ||
931 		  ((modWriteValB&0x80)==0 && ((f12Op1&0xFF00)==0x0000)))
932 		_OV = 0;
933 	else
934 		_OV = 1;
935 
936 	F12WriteSecondOperand(0);
937 	F12END();
938 }
939 
opMOVTWB(void)940 static UINT32 opMOVTWB(void)
941 {
942 	F12DecodeFirstOperand(ReadAM,2);
943 	modWriteValB = (UINT8)(f12Op1&0xFF);
944 
945 	// Check for overflow: the truncated bits must match the sign
946 	//  of the result, otherwise overflow
947 	if (((modWriteValB&0x80)==0x80 && ((f12Op1&0xFFFFFF00)==0xFFFFFF00)) ||
948 		  ((modWriteValB&0x80)==0 && ((f12Op1&0xFFFFFF00)==0x00000000)))
949 		_OV = 0;
950 	else
951 		_OV = 1;
952 
953 	F12WriteSecondOperand(0);
954 	F12END();
955 }
956 
opMOVTWH(void)957 static UINT32 opMOVTWH(void)
958 {
959 	F12DecodeFirstOperand(ReadAM,2);
960 	modWriteValH = (UINT16)(f12Op1&0xFFFF);
961 
962 	// Check for overflow: the truncated bits must match the sign
963 	//  of the result, otherwise overflow
964 	if (((modWriteValH&0x8000)==0x8000 && ((f12Op1&0xFFFF0000)==0xFFFF0000)) ||
965 		  ((modWriteValH&0x8000)==0 && ((f12Op1&0xFFFF0000)==0x00000000)))
966 		_OV = 0;
967 	else
968 		_OV = 1;
969 
970 	F12WriteSecondOperand(1);
971 	F12END();
972 }
973 
974 
opMOVZBH(void)975 static UINT32 opMOVZBH(void) /* TRUSTED */
976 {
977 	F12DecodeFirstOperand(ReadAM,0);
978 	modWriteValH = (UINT16)f12Op1;
979 	F12WriteSecondOperand(1);
980 	F12END();
981 }
982 
opMOVZBW(void)983 static UINT32 opMOVZBW(void) /* TRUSTED */
984 {
985 	F12DecodeFirstOperand(ReadAM,0);
986 	modWriteValW = f12Op1;
987 	F12WriteSecondOperand(2);
988 	F12END();
989 }
990 
opMOVZHW(void)991 static UINT32 opMOVZHW(void) /* TRUSTED */
992 {
993 	F12DecodeFirstOperand(ReadAM,1);
994 	modWriteValW = f12Op1;
995 	F12WriteSecondOperand(2);
996 	F12END();
997 }
998 
opMULB(void)999 static UINT32 opMULB(void)
1000 {
1001 	UINT8 appb;
1002 	UINT32 tmp;
1003 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1004 
1005 	F12LOADOP2BYTE();
1006 
1007 	tmp=(INT8)appb * (INT32)(INT8)f12Op1;
1008 	appb = tmp;
1009 	_Z = (appb == 0);
1010 	_S = ((appb & 0x80)!=0);
1011 	_OV = ((tmp >> 8)!=0);
1012 
1013 	F12STOREOP2BYTE();
1014 	F12END();
1015 }
1016 
opMULH(void)1017 static UINT32 opMULH(void)
1018 {
1019 	UINT16 apph;
1020 	UINT32 tmp;
1021 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
1022 
1023 	F12LOADOP2HALF();
1024 
1025 	tmp=(INT16)apph * (INT32)(INT16)f12Op1;
1026 	apph = tmp;
1027 	_Z = (apph == 0);
1028 	_S = ((apph & 0x8000)!=0);
1029 	_OV = ((tmp >> 16)!=0);
1030 
1031 	F12STOREOP2HALF();
1032 	F12END();
1033 }
1034 
opMULW(void)1035 static UINT32 opMULW(void)
1036 {
1037 	UINT32 appw;
1038 	UINT64 tmp;
1039 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1040 
1041 	F12LOADOP2WORD();
1042 
1043 	tmp=(INT32)appw * (INT64)(INT32)f12Op1;
1044 	appw = tmp;
1045 	_Z = (appw == 0);
1046 	_S = ((appw & 0x80000000)!=0);
1047 	_OV = ((tmp >> 32) != 0);
1048 
1049 	F12STOREOP2WORD();
1050 	F12END();
1051 }
1052 
opMULUB(void)1053 static UINT32 opMULUB(void)
1054 {
1055 	UINT8 appb;
1056 	UINT32 tmp;
1057 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1058 
1059 	F12LOADOP2BYTE();
1060 
1061 	tmp = appb * (UINT8)f12Op1;
1062 	appb = tmp;
1063 	_Z = (appb == 0);
1064 	_S = ((appb & 0x80)!=0);
1065 	_OV = ((tmp >> 8)!=0);
1066 
1067 	F12STOREOP2BYTE();
1068 	F12END();
1069 }
1070 
opMULUH(void)1071 static UINT32 opMULUH(void)
1072 {
1073 	UINT16 apph;
1074 	UINT32 tmp;
1075 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
1076 
1077 	F12LOADOP2HALF();
1078 
1079 	tmp=apph * (UINT16)f12Op1;
1080 	apph = tmp;
1081 	_Z = (apph == 0);
1082 	_S = ((apph & 0x8000)!=0);
1083 	_OV = ((tmp >> 16)!=0);
1084 
1085 	F12STOREOP2HALF();
1086 	F12END();
1087 }
1088 
opMULUW(void)1089 static UINT32 opMULUW(void)
1090 {
1091 	UINT32 appw;
1092 	UINT64 tmp;
1093 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1094 
1095 	F12LOADOP2WORD();
1096 
1097 	tmp=(UINT64)appw * (UINT64)f12Op1;
1098 	appw = tmp;
1099 	_Z = (appw == 0);
1100 	_S = ((appw & 0x80000000)!=0);
1101 	_OV = ((tmp >> 32)!=0);
1102 
1103 	F12STOREOP2WORD();
1104 	F12END();
1105 }
1106 
opNEGB(void)1107 static UINT32 opNEGB(void) /* TRUSTED  (C too!)*/
1108 {
1109 	F12DecodeFirstOperand(ReadAM,0);
1110 
1111 	modWriteValB = 0;
1112 	SUBB(modWriteValB, (INT8)f12Op1);
1113 	_CY = modWriteValB ? 1 : 0;
1114 
1115 	F12WriteSecondOperand(0);
1116 	F12END();
1117 }
1118 
opNEGH(void)1119 static UINT32 opNEGH(void) /* TRUSTED  (C too!)*/
1120 {
1121 	F12DecodeFirstOperand(ReadAM,1);
1122 
1123 	modWriteValH = 0;
1124 	SUBW(modWriteValH, (INT16)f12Op1);
1125 	_CY = modWriteValH ? 1 : 0;
1126 
1127 	F12WriteSecondOperand(1);
1128 	F12END();
1129 }
1130 
opNEGW(void)1131 static UINT32 opNEGW(void) /* TRUSTED  (C too!)*/
1132 {
1133 	F12DecodeFirstOperand(ReadAM,2);
1134 
1135 	modWriteValW = 0;
1136 	SUBL(modWriteValW, (INT32)f12Op1);
1137 	_CY = modWriteValW ? 1 : 0;
1138 
1139 	F12WriteSecondOperand(2);
1140 	F12END();
1141 }
1142 
opNOTB(void)1143 static UINT32 opNOTB(void) /* TRUSTED */
1144 {
1145 	F12DecodeFirstOperand(ReadAM,0);
1146 	modWriteValB=~f12Op1;
1147 
1148 	_OV=0;
1149 	_S=((modWriteValB&0x80)!=0);
1150 	_Z=(modWriteValB==0);
1151 
1152 	F12WriteSecondOperand(0);
1153 	F12END();
1154 }
1155 
opNOTH(void)1156 static UINT32 opNOTH(void) /* TRUSTED */
1157 {
1158 	F12DecodeFirstOperand(ReadAM,1);
1159 	modWriteValH=~f12Op1;
1160 
1161 	_OV=0;
1162 	_S=((modWriteValH&0x8000)!=0);
1163 	_Z=(modWriteValH==0);
1164 
1165 	F12WriteSecondOperand(1);
1166 	F12END();
1167 }
1168 
opNOTW(void)1169 static UINT32 opNOTW(void) /* TRUSTED */
1170 {
1171 	F12DecodeFirstOperand(ReadAM,2);
1172 	modWriteValW=~f12Op1;
1173 
1174 	_OV=0;
1175 	_S=((modWriteValW&0x80000000)!=0);
1176 	_Z=(modWriteValW==0);
1177 
1178 	F12WriteSecondOperand(2);
1179 	F12END();
1180 }
1181 
opNOT1(void)1182 static UINT32 opNOT1(void) /* TRUSTED */
1183 {
1184 	UINT32 appw;
1185 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1186 
1187 	F12LOADOP2WORD();
1188 
1189 	_CY = ((appw & (1<<f12Op1))!=0);
1190 	_Z = !(_CY);
1191 
1192 	if (_CY)
1193 		appw &= ~(1<<f12Op1);
1194 	else
1195 		appw |= (1<<f12Op1);
1196 
1197 	F12STOREOP2WORD();
1198 	F12END();
1199 }
1200 
opORB(void)1201 static UINT32 opORB(void) /* TRUSTED  (C too!)*/
1202 {
1203 	UINT8 appb;
1204 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1205 
1206 	F12LOADOP2BYTE();
1207 
1208 	ORB(appb, (UINT8)f12Op1);
1209 
1210 	F12STOREOP2BYTE();
1211 	F12END();
1212 }
1213 
opORH(void)1214 static UINT32 opORH(void) /* TRUSTED (C too!)*/
1215 {
1216 	UINT16 apph;
1217 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
1218 
1219 	F12LOADOP2HALF();
1220 
1221 	ORW(apph, (UINT16)f12Op1);
1222 
1223 	F12STOREOP2HALF();
1224 	F12END();
1225 }
1226 
opORW(void)1227 static UINT32 opORW(void) /* TRUSTED (C too!) */
1228 {
1229 	UINT32 appw;
1230 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1231 
1232 	F12LOADOP2WORD();
1233 
1234 	ORL(appw, (UINT32)f12Op1);
1235 
1236 	F12STOREOP2WORD();
1237 	F12END();
1238 }
1239 
opOUTB(void)1240 static UINT32 opOUTB(void)
1241 {
1242 	F12DecodeOperands(ReadAM,0,ReadAMAddress,2);
1243 	PortWrite8(f12Op2,(UINT8)f12Op1);
1244 	F12END();
1245 }
1246 
opOUTH(void)1247 static UINT32 opOUTH(void)
1248 {
1249 	F12DecodeOperands(ReadAM,1,ReadAMAddress,2);
1250 	PortWrite16(f12Op2,(UINT16)f12Op1);
1251 	F12END();
1252 }
1253 
opOUTW(void)1254 static UINT32 opOUTW(void)
1255 {
1256 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1257 	PortWrite32(f12Op2,f12Op1);
1258 	F12END();
1259 }
1260 
opREMB(void)1261 static UINT32 opREMB(void)
1262 {
1263 	UINT8 appb;
1264 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1265 
1266 	F12LOADOP2BYTE();
1267 
1268 	_OV = 0;
1269 	if (f12Op1)
1270 		appb= (INT8)appb % (INT8)f12Op1;
1271 	_Z = (appb == 0);
1272 	_S = ((appb & 0x80)!=0);
1273 
1274 	F12STOREOP2BYTE();
1275 	F12END();
1276 }
1277 
opREMH(void)1278 static UINT32 opREMH(void)
1279 {
1280 	UINT16 apph;
1281 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
1282 
1283 	F12LOADOP2HALF();
1284 
1285 	_OV = 0;
1286 	if (f12Op1)
1287 		apph=(INT16)apph % (INT16)f12Op1;
1288 	_Z = (apph == 0);
1289 	_S = ((apph & 0x8000)!=0);
1290 
1291 	F12STOREOP2HALF();
1292 	F12END();
1293 }
1294 
opREMW(void)1295 static UINT32 opREMW(void)
1296 {
1297 	UINT32 appw;
1298 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1299 
1300 	F12LOADOP2WORD();
1301 
1302 	_OV = 0;
1303 	if (f12Op1)
1304 		appw=(INT32)appw % (INT32)f12Op1;
1305 	_Z = (appw == 0);
1306 	_S = ((appw & 0x80000000)!=0);
1307 
1308 	F12STOREOP2WORD();
1309 	F12END();
1310 }
1311 
opREMUB(void)1312 static UINT32 opREMUB(void)
1313 {
1314 	UINT8 appb;
1315 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1316 
1317 	F12LOADOP2BYTE();
1318 
1319 	_OV = 0;
1320 	if (f12Op1)
1321 		appb %= (UINT8)f12Op1;
1322 	_Z = (appb == 0);
1323 	_S = ((appb & 0x80)!=0);
1324 
1325 	F12STOREOP2BYTE();
1326 	F12END();
1327 }
1328 
opREMUH(void)1329 static UINT32 opREMUH(void)
1330 {
1331 	UINT16 apph;
1332 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
1333 
1334 	F12LOADOP2HALF();
1335 
1336 	_OV = 0;
1337 	if (f12Op1)
1338 		apph %= (UINT16)f12Op1;
1339 	_Z = (apph == 0);
1340 	_S = ((apph & 0x8000)!=0);
1341 
1342 	F12STOREOP2HALF();
1343 	F12END();
1344 }
1345 
opREMUW(void)1346 static UINT32 opREMUW(void)
1347 {
1348 	UINT32 appw;
1349 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1350 
1351 	F12LOADOP2WORD();
1352 
1353 	_OV = 0;
1354 	if (f12Op1)
1355 		appw %= f12Op1;
1356 	_Z = (appw == 0);
1357 	_S = ((appw & 0x80000000)!=0);
1358 
1359 	F12STOREOP2WORD();
1360 	F12END();
1361 }
1362 
opROTB(void)1363 static UINT32 opROTB(void) /* TRUSTED */
1364 {
1365 	UINT8 appb;
1366 	INT8 i,count;
1367 
1368 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1369 
1370 	F12LOADOP2BYTE();
1371 
1372 	count=(INT8)(f12Op1&0xFF);
1373 	if (count>0)
1374 	{
1375 		for (i=0;i<count;i++)
1376 			appb = (appb<<1) | ((appb&0x80) >> 7);
1377 
1378 		_CY=(appb&0x1)!=0;
1379 	}
1380 	else if (count<0)
1381 	{
1382 		count=-count;
1383 		for (i=0;i<count;i++)
1384 			appb = (appb>>1) | ((appb&0x1) << 7);
1385 
1386 		_CY=(appb&0x80)!=0;
1387 	}
1388 	else
1389 		_CY=0;
1390 
1391 	_OV=0;
1392 	_S=(appb&0x80)!=0;
1393 	_Z=(appb==0);
1394 
1395 	F12STOREOP2BYTE();
1396 	F12END();
1397 }
1398 
opROTH(void)1399 static UINT32 opROTH(void) /* TRUSTED */
1400 {
1401 	UINT16 apph;
1402 	INT8 i,count;
1403 
1404 	F12DecodeOperands(ReadAM,0,ReadAMAddress,1);
1405 
1406 	F12LOADOP2HALF();
1407 
1408 	count=(INT8)(f12Op1&0xFF);
1409 	if (count>0)
1410 	{
1411 		for (i=0;i<count;i++)
1412 			apph = (apph<<1) | ((apph&0x8000) >> 15);
1413 
1414 		_CY=(apph&0x1)!=0;
1415 	}
1416 	else if (count<0)
1417 	{
1418 		count=-count;
1419 		for (i=0;i<count;i++)
1420 			apph = (apph>>1) | ((apph&0x1) << 15);
1421 
1422 		_CY=(apph&0x8000)!=0;
1423 	}
1424 	else
1425 		_CY=0;
1426 
1427 	_OV=0;
1428 	_S=(apph&0x8000)!=0;
1429 	_Z=(apph==0);
1430 
1431 	F12STOREOP2HALF();
1432 	F12END();
1433 }
1434 
opROTW(void)1435 static UINT32 opROTW(void) /* TRUSTED */
1436 {
1437 	UINT32 appw;
1438 	INT8 i,count;
1439 
1440 	F12DecodeOperands(ReadAM,0,ReadAMAddress,2);
1441 
1442 	F12LOADOP2WORD();
1443 
1444 	count=(INT8)(f12Op1&0xFF);
1445 	if (count>0)
1446 	{
1447 		for (i=0;i<count;i++)
1448 			appw = (appw<<1) | ((appw&0x80000000) >> 31);
1449 
1450 		_CY=(appw&0x1)!=0;
1451 	}
1452 	else if (count<0)
1453 	{
1454 		count=-count;
1455 		for (i=0;i<count;i++)
1456 			appw = (appw>>1) | ((appw&0x1) << 31);
1457 
1458 		_CY=(appw&0x80000000)!=0;
1459 	}
1460 	else
1461 		_CY=0;
1462 
1463 	_OV=0;
1464 	_S=(appw&0x80000000)!=0;
1465 	_Z=(appw==0);
1466 
1467 	F12STOREOP2WORD();
1468 	F12END();
1469 }
1470 
opROTCB(void)1471 static UINT32 opROTCB(void) /* TRUSTED */
1472 {
1473 	UINT8 appb;
1474 	INT8 i,cy,count;
1475 
1476 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1477 
1478 	F12LOADOP2BYTE();
1479 	NORMALIZEFLAGS();
1480 
1481 	count=(INT8)(f12Op1&0xFF);
1482 	if (count>0)
1483 	{
1484 		for (i=0;i<count;i++)
1485 		{
1486 			cy = _CY;
1487 			_CY = (UINT8)((appb & 0x80) >> 7);
1488 			appb = (appb<<1) | cy;
1489 		}
1490 	}
1491 	else if (count<0)
1492 	{
1493 		count=-count;
1494 		for (i=0;i<count;i++)
1495 		{
1496 			cy = _CY;
1497 			_CY = (appb & 1);
1498 			appb = (appb>>1) | (cy << 7);
1499 		}
1500 	}
1501 	else
1502 		_CY = 0;
1503 
1504 	_OV=0;
1505 	_S=(appb&0x80)!=0;
1506 	_Z=(appb==0);
1507 
1508 	F12STOREOP2BYTE();
1509 	F12END();
1510 }
1511 
opROTCH(void)1512 static UINT32 opROTCH(void) /* TRUSTED */
1513 {
1514 	UINT16 apph;
1515 	INT8 i,cy,count;
1516 
1517 	F12DecodeOperands(ReadAM,0,ReadAMAddress,1);
1518 
1519 	F12LOADOP2HALF();
1520 	NORMALIZEFLAGS();
1521 
1522 	count=(INT8)(f12Op1&0xFF);
1523 	if (count>0)
1524 	{
1525 		for (i=0;i<count;i++)
1526 		{
1527 			cy = _CY;
1528 			_CY = (UINT8)((apph & 0x8000) >> 15);
1529 			apph = (apph<<1) | cy;
1530 		}
1531 	}
1532 	else if (count<0)
1533 	{
1534 		count=-count;
1535 		for (i=0;i<count;i++)
1536 		{
1537 			cy = _CY;
1538 			_CY = (UINT8)(apph & 1);
1539 			apph = (apph>>1) | ((UINT16)cy << 15);
1540 		}
1541 	}
1542 	else
1543 		_CY = 0;
1544 
1545 	_OV=0;
1546 	_S=(apph&0x8000)!=0;
1547 	_Z=(apph==0);
1548 
1549 	F12STOREOP2HALF();
1550 	F12END();
1551 }
1552 
opROTCW(void)1553 static UINT32 opROTCW(void) /* TRUSTED */
1554 {
1555 	UINT32 appw;
1556 	INT8 i,cy,count;
1557 
1558 	F12DecodeOperands(ReadAM,0,ReadAMAddress,2);
1559 
1560 	F12LOADOP2WORD();
1561 	NORMALIZEFLAGS();
1562 
1563 	count=(INT8)(f12Op1&0xFF);
1564 	if (count>0)
1565 	{
1566 		for (i=0;i<count;i++)
1567 		{
1568 			cy = _CY;
1569 			_CY = (UINT8)((appw & 0x80000000) >> 31);
1570 			appw = (appw<<1) | cy;
1571 		}
1572 	}
1573 	else if (count<0)
1574 	{
1575 		count=-count;
1576 		for (i=0;i<count;i++)
1577 		{
1578 			cy = _CY;
1579 			_CY = (UINT8)(appw & 1);
1580 			appw = (appw>>1) | ((UINT32)cy << 31);
1581 		}
1582 	}
1583 	else
1584 		_CY=0;
1585 
1586 	_OV=0;
1587 	_S=(appw&0x80000000)!=0;
1588 	_Z=(appw==0);
1589 
1590 	F12STOREOP2WORD();
1591 	F12END();
1592 }
1593 
opRVBIT(void)1594 static UINT32 opRVBIT(void)
1595 {
1596 	F12DecodeFirstOperand(ReadAM,0);
1597 
1598 	modWriteValB =(UINT8)
1599 								(((f12Op1 & (1<<0)) << 7) |
1600 								 ((f12Op1 & (1<<1)) << 5) |
1601 								 ((f12Op1 & (1<<2)) << 3) |
1602 								 ((f12Op1 & (1<<3)) << 1) |
1603 								 ((f12Op1 & (1<<4)) >> 1) |
1604 								 ((f12Op1 & (1<<5)) >> 3) |
1605 								 ((f12Op1 & (1<<6)) >> 5) |
1606 								 ((f12Op1 & (1<<7)) >> 7));
1607 
1608 	F12WriteSecondOperand(0);
1609 	F12END();
1610 }
1611 
opRVBYT(void)1612 static UINT32 opRVBYT(void) /* TRUSTED */
1613 {
1614 	F12DecodeFirstOperand(ReadAM,2);
1615 
1616 	modWriteValW = ((f12Op1 & 0x000000FF) << 24) |
1617 								 ((f12Op1 & 0x0000FF00) << 8)  |
1618 								 ((f12Op1 & 0x00FF0000) >> 8)  |
1619 								 ((f12Op1 & 0xFF000000) >> 24);
1620 
1621 	F12WriteSecondOperand(2);
1622 	F12END();
1623 }
1624 
opSET1(void)1625 static UINT32 opSET1(void) /* TRUSTED */
1626 {
1627 	UINT32 appw;
1628 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
1629 
1630 	F12LOADOP2WORD();
1631 
1632 	_CY = ((appw & (1<<f12Op1))!=0);
1633 	_Z = !(_CY);
1634 
1635 	appw |= (1<<f12Op1);
1636 
1637 	F12STOREOP2WORD();
1638 	F12END();
1639 }
1640 
1641 
opSETF(void)1642 static UINT32 opSETF(void)
1643 {
1644 	F12DecodeFirstOperand(ReadAM,0);
1645 
1646 	// Normalize the flags
1647 	NORMALIZEFLAGS();
1648 
1649 	switch (f12Op1 & 0xF)
1650 	{
1651 	case 0:
1652 		if (!_OV) modWriteValB=0;
1653 		else modWriteValB=1;
1654 		break;
1655 	case 1:
1656 		if (_OV) modWriteValB=0;
1657 		else modWriteValB=1;
1658 		break;
1659 	case 2:
1660 		if (!_CY) modWriteValB=0;
1661 		else modWriteValB=1;
1662 		break;
1663 	case 3:
1664 		if (_CY) modWriteValB=0;
1665 		else modWriteValB=1;
1666 		break;
1667 	case 4:
1668 		if (!_Z) modWriteValB=0;
1669 		else modWriteValB=1;
1670 		break;
1671 	case 5:
1672 		if (_Z) modWriteValB=0;
1673 		else modWriteValB=1;
1674 		break;
1675 	case 6:
1676 		if (!(_CY | _Z)) modWriteValB=0;
1677 		else modWriteValB=1;
1678 		break;
1679 	case 7:
1680 		if ((_CY | _Z)) modWriteValB=0;
1681 		else modWriteValB=1;
1682 		break;
1683 	case 8:
1684 		if (!_S) modWriteValB=0;
1685 		else modWriteValB=1;
1686 		break;
1687 	case 9:
1688 		if (_S) modWriteValB=0;
1689 		else modWriteValB=1;
1690 		break;
1691 	case 10:
1692 		modWriteValB=1;
1693 		break;
1694 	case 11:
1695 		modWriteValB=0;
1696 		break;
1697 	case 12:
1698 		if (!(_S^_OV)) modWriteValB=0;
1699 		else modWriteValB=1;
1700 		break;
1701 	case 13:
1702 		if ((_S^_OV)) modWriteValB=0;
1703 		else modWriteValB=1;
1704 		break;
1705 	case 14:
1706 		if (!((_S^_OV)|_Z)) modWriteValB=0;
1707 		else modWriteValB=1;
1708 		break;
1709 	case 15:
1710 		if (((_S^_OV)|_Z)) modWriteValB=0;
1711 		else modWriteValB=1;
1712 		break;
1713 	}
1714 
1715 	F12WriteSecondOperand(0);
1716 
1717 	F12END();
1718 }
1719 
1720 /*
1721 #define SHIFTLEFT_OY(val, count, bitsize) \
1722 {\
1723     UINT32 tmp = ((val) >> (bitsize-1)) & 1; \
1724     tmp <<= count; \
1725     tmp -= 1; \
1726     tmp <<= (bitsize - (count)); \
1727     _OV = (((val) & tmp) != tmp); \
1728     _CY = (((val) & (1 << (count-1))) != 0); \
1729 }
1730 */
1731 
1732 // During the shift, the overflow is set if the sign bit changes at any point during the shift
1733 #define SHIFTLEFT_OV(val, count, bitsize) \
1734 {\
1735 	UINT32 tmp; \
1736 	if (count == 32) \
1737 		tmp = 0xFFFFFFFF; \
1738 	else \
1739 		tmp = ((1 << (count)) - 1); \
1740 	tmp <<= (bitsize - (count)); \
1741 	if (((val) >> (bitsize-1)) & 1) \
1742 		_OV = (((val) & tmp) != tmp); \
1743 	else \
1744 		_OV = (((val) & tmp) != 0); \
1745 }
1746 
1747 #define SHIFTLEFT_CY(val, count, bitsize) \
1748 	_CY = (UINT8)(((val) >> (bitsize - count)) & 1);
1749 
1750 
1751 
1752 #define SHIFTARITHMETICRIGHT_OV(val, count, bitsize) \
1753 	_OV = 0;
1754 
1755 #define SHIFTARITHMETICRIGHT_CY(val, count, bitsize) \
1756 	_CY = (UINT8)(((val) >> (count-1)) & 1);
1757 
1758 
1759 
opSHAB(void)1760 static UINT32 opSHAB(void)
1761 {
1762 	UINT8 appb;
1763 	INT8 count;
1764 
1765 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1766 
1767 	F12LOADOP2BYTE();
1768 
1769 	count=(INT8)(f12Op1&0xFF);
1770 
1771 	// Special case: destination unchanged, flags set
1772 	if (count == 0)
1773 	{
1774 		_CY = _OV = 0;
1775 		SetSZPF_Byte(appb);
1776 	}
1777 	else if (count>0)
1778 	{
1779 		SHIFTLEFT_OV(appb, count, 8);
1780 
1781 		// @@@ Undefined what happens to CY when count >= bitsize
1782 		SHIFTLEFT_CY(appb, count, 8);
1783 
1784 		// do the actual shift...
1785 		if (count >= 8)
1786 			appb = 0;
1787 		else
1788 			appb <<= count;
1789 
1790 		// and set zero and sign
1791 		SetSZPF_Byte(appb);
1792 	}
1793 	else
1794 	{
1795 		count = -count;
1796 
1797 		SHIFTARITHMETICRIGHT_OV(appb, count, 8);
1798 		SHIFTARITHMETICRIGHT_CY(appb, count, 8);
1799 
1800 		if (count >= 8)
1801 			appb = (appb & 0x80) ? 0xFF : 0;
1802 		else
1803 			appb = ((INT8)appb) >> count;
1804 
1805 		SetSZPF_Byte(appb);
1806 	}
1807 
1808 //  mame_printf_debug("SHAB: %x _CY: %d _Z: %d _OV: %d _S: %d\n", appb, _CY, _Z, _OV, _S);
1809 
1810 	F12STOREOP2BYTE();
1811 	F12END();
1812 }
1813 
opSHAH(void)1814 static UINT32 opSHAH(void)
1815 {
1816 	UINT16 apph;
1817 	INT8 count;
1818 
1819 	F12DecodeOperands(ReadAM,0,ReadAMAddress,1);
1820 
1821 	F12LOADOP2HALF();
1822 
1823 	count=(INT8)(f12Op1&0xFF);
1824 
1825 	// Special case: destination unchanged, flags set
1826 	if (count == 0)
1827 	{
1828 		_CY = _OV = 0;
1829 		SetSZPF_Word(apph);
1830 	}
1831 	else if (count>0)
1832 	{
1833 		SHIFTLEFT_OV(apph, count, 16);
1834 
1835 		// @@@ Undefined what happens to CY when count >= bitsize
1836 		SHIFTLEFT_CY(apph, count, 16);
1837 
1838 		// do the actual shift...
1839 		if (count >= 16)
1840 			apph = 0;
1841 		else
1842 			apph <<= count;
1843 
1844 		// and set zero and sign
1845 		SetSZPF_Word(apph);
1846 	}
1847 	else
1848 	{
1849 		count = -count;
1850 
1851 		SHIFTARITHMETICRIGHT_OV(apph, count, 16);
1852 		SHIFTARITHMETICRIGHT_CY(apph, count, 16);
1853 
1854 		if (count >= 16)
1855 			apph = (apph & 0x8000) ? 0xFFFF : 0;
1856 		else
1857 			apph = ((INT16)apph) >> count;
1858 
1859 		SetSZPF_Word(apph);
1860 	}
1861 
1862 //  mame_printf_debug("SHAH: %x >> %d = %x _CY: %d _Z: %d _OV: %d _S: %d\n", oldval, count, apph, _CY, _Z, _OV, _S);
1863 
1864 	F12STOREOP2HALF();
1865 	F12END();
1866 }
1867 
opSHAW(void)1868 static UINT32 opSHAW(void)
1869 {
1870 	UINT32 appw;
1871 	INT8 count;
1872 
1873 	F12DecodeOperands(ReadAM,0,ReadAMAddress,2);
1874 
1875 	F12LOADOP2WORD();
1876 
1877 	count=(INT8)(f12Op1&0xFF);
1878 
1879 	// Special case: destination unchanged, flags set
1880 	if (count == 0)
1881 	{
1882 		_CY = _OV = 0;
1883 		SetSZPF_Long(appw);
1884 	}
1885 	else if (count>0)
1886 	{
1887 		SHIFTLEFT_OV(appw, count, 32);
1888 
1889 		// @@@ Undefined what happens to CY when count >= bitsize
1890 		SHIFTLEFT_CY(appw, count, 32);
1891 
1892 		// do the actual shift...
1893 		if (count >= 32)
1894 			appw = 0;
1895 		else
1896 			appw <<= count;
1897 
1898 		// and set zero and sign
1899 		SetSZPF_Long(appw);
1900 	}
1901 	else
1902 	{
1903 		count = -count;
1904 
1905 		SHIFTARITHMETICRIGHT_OV(appw, count, 32);
1906 		SHIFTARITHMETICRIGHT_CY(appw, count, 32);
1907 
1908 		if (count >= 32)
1909 			appw = (appw & 0x80000000) ? 0xFFFFFFFF : 0;
1910 		else
1911 			appw = ((INT32)appw) >> count;
1912 
1913 		SetSZPF_Long(appw);
1914 	}
1915 
1916 //  mame_printf_debug("SHAW: %x >> %d = %x _CY: %d _Z: %d _OV: %d _S: %d\n", oldval, count, appw, _CY, _Z, _OV, _S);
1917 
1918 	F12STOREOP2WORD();
1919 	F12END();
1920 }
1921 
1922 
opSHLB(void)1923 static UINT32 opSHLB(void) /* TRUSTED */
1924 {
1925 	UINT8 appb;
1926 	INT8 count;
1927 	UINT32 tmp;
1928 
1929 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
1930 
1931 	F12LOADOP2BYTE();
1932 
1933 	count=(INT8)(f12Op1&0xFF);
1934 	if (count>0)
1935 	{
1936 		// left shift flags:
1937 		// carry gets the last bit shifted out,
1938 		// overflow is always CLEARed
1939 
1940 		_OV = 0;	// default to no overflow
1941 
1942 		// now handle carry
1943 		tmp = appb & 0xff;
1944 		tmp <<= count;
1945 		SetCFB(tmp);	// set carry properly
1946 
1947 		// do the actual shift...
1948 		appb <<= count;
1949 
1950 		// and set zero and sign
1951 		SetSZPF_Byte(appb);
1952 	}
1953 	else
1954 	{
1955 		if (count == 0)
1956 		{
1957 			// special case: clear carry and overflow, do nothing else
1958 			_CY = _OV = 0;
1959 			SetSZPF_Byte(appb);	// doc. is unclear if this is true...
1960 		}
1961 		else
1962 		{
1963 			// right shift flags:
1964 			// carry = last bit shifted out
1965 			// overflow always cleared
1966 			tmp = appb & 0xff;
1967 			tmp >>= ((-count)-1);
1968 			_CY = (UINT8)(tmp & 0x1);
1969 			_OV = 0;
1970 
1971 			appb >>= -count;
1972 			SetSZPF_Byte(appb);
1973 		}
1974 	}
1975 
1976 //  mame_printf_debug("SHLB: %x _CY: %d _Z: %d _OV: %d _S: %d\n", appb, _CY, _Z, _OV, _S);
1977 
1978 	F12STOREOP2BYTE();
1979 	F12END();
1980 }
1981 
opSHLH(void)1982 static UINT32 opSHLH(void) /* TRUSTED */
1983 {
1984 	UINT16 apph;
1985 	INT8 count;
1986 	UINT32 tmp;
1987 
1988 	F12DecodeOperands(ReadAM,0,ReadAMAddress,1);
1989 
1990 	F12LOADOP2HALF();
1991 
1992 	count=(INT8)(f12Op1&0xFF);
1993 //  mame_printf_debug("apph: %x count: %d  ", apph, count);
1994 	if (count>0)
1995 	{
1996 		// left shift flags:
1997 		// carry gets the last bit shifted out,
1998 		// overflow is always CLEARed
1999 
2000 		_OV = 0;
2001 
2002 		// now handle carry
2003 		tmp = apph & 0xffff;
2004 		tmp <<= count;
2005 		SetCFW(tmp);	// set carry properly
2006 
2007 		// do the actual shift...
2008 		apph <<= count;
2009 
2010 		// and set zero and sign
2011 		SetSZPF_Word(apph);
2012 	}
2013 	else
2014 	{
2015 		if (count == 0)
2016 		{
2017 			// special case: clear carry and overflow, do nothing else
2018 			_CY = _OV = 0;
2019 			SetSZPF_Word(apph);	// doc. is unclear if this is true...
2020 		}
2021 		else
2022 		{
2023 			// right shift flags:
2024 			// carry = last bit shifted out
2025 			// overflow always cleared
2026 			tmp = apph & 0xffff;
2027 			tmp >>= ((-count)-1);
2028 			_CY = (UINT8)(tmp & 0x1);
2029 			_OV = 0;
2030 
2031 			apph >>= -count;
2032 			SetSZPF_Word(apph);
2033 		}
2034 	}
2035 
2036 //  mame_printf_debug("SHLH: %x _CY: %d _Z: %d _OV: %d _S: %d\n", apph, _CY, _Z, _OV, _S);
2037 
2038 	F12STOREOP2HALF();
2039 	F12END();
2040 }
2041 
opSHLW(void)2042 static UINT32 opSHLW(void) /* TRUSTED */
2043 {
2044 	UINT32 appw;
2045 	INT8 count;
2046 	UINT64 tmp;
2047 
2048 	F12DecodeOperands(ReadAM,0,ReadAMAddress,2);
2049 
2050 	F12LOADOP2WORD();
2051 
2052 	count=(INT8)(f12Op1&0xFF);
2053 	if (count>0)
2054 	{
2055 		// left shift flags:
2056 		// carry gets the last bit shifted out,
2057 		// overflow is always CLEARed
2058 
2059 		_OV = 0;
2060 
2061 		// now handle carry
2062 		tmp = appw & 0xffffffff;
2063 		tmp <<= count;
2064 		SetCFL(tmp);	// set carry properly
2065 
2066 		// do the actual shift...
2067 		appw <<= count;
2068 
2069 		// and set zero and sign
2070 		SetSZPF_Long(appw);
2071 	}
2072 	else
2073 	{
2074 		if (count == 0)
2075 		{
2076 			// special case: clear carry and overflow, do nothing else
2077 			_CY = _OV = 0;
2078 			SetSZPF_Long(appw);	// doc. is unclear if this is true...
2079 		}
2080 		else
2081 		{
2082 			// right shift flags:
2083 			// carry = last bit shifted out
2084 			// overflow always cleared
2085 			tmp = (UINT64)(appw & 0xffffffff);
2086 			tmp >>= ((-count)-1);
2087 			_CY = (UINT8)(tmp & 0x1);
2088 			_OV = 0;
2089 
2090 			appw >>= -count;
2091 			SetSZPF_Long(appw);
2092 		}
2093 	}
2094 
2095 //  mame_printf_debug("SHLW: %x _CY: %d _Z: %d _OV: %d _S: %d\n", appw, _CY, _Z, _OV, _S);
2096 
2097 	F12STOREOP2WORD();
2098 	F12END();
2099 }
2100 
opSTPR(void)2101 static UINT32 opSTPR(void)
2102 {
2103 	F12DecodeFirstOperand(ReadAM,2);
2104 	if (f12Op1 <= 28)
2105 		modWriteValW = v60.reg[f12Op1 + 36];
2106 	else
2107 	{
2108 		//fatalerror("Invalid operand on STPR PC=%x", PC);
2109 	}
2110 	F12WriteSecondOperand(2);
2111 	F12END();
2112 }
2113 
2114 
opSUBB(void)2115 static UINT32 opSUBB(void) /* TRUSTED (C too!) */
2116 {
2117 	UINT8 appb;
2118 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
2119 
2120 	F12LOADOP2BYTE();
2121 
2122 	SUBB(appb, (UINT8)f12Op1);
2123 
2124 	F12STOREOP2BYTE();
2125 	F12END();
2126 }
2127 
opSUBH(void)2128 static UINT32 opSUBH(void) /* TRUSTED (C too!) */
2129 {
2130 	UINT16 apph;
2131 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
2132 
2133 	F12LOADOP2HALF();
2134 
2135 	SUBW(apph, (UINT16)f12Op1);
2136 
2137 	F12STOREOP2HALF();
2138 	F12END();
2139 }
2140 
opSUBW(void)2141 static UINT32 opSUBW(void) /* TRUSTED (C too!) */
2142 {
2143 	UINT32 appw;
2144 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
2145 
2146 	F12LOADOP2WORD();
2147 
2148 	SUBL(appw, (UINT32)f12Op1);
2149 
2150 	F12STOREOP2WORD();
2151 	F12END();
2152 }
2153 
2154 
opSUBCB(void)2155 static UINT32 opSUBCB(void)
2156 {
2157 	UINT8 appb;
2158 	UINT8 src;
2159 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
2160 
2161 	F12LOADOP2BYTE();
2162 
2163 	src = (UINT8)f12Op1 + (_CY?1:0);
2164 	SUBB(appb, src);
2165 
2166 	F12STOREOP2BYTE();
2167 	F12END();
2168 }
2169 
opSUBCH(void)2170 static UINT32 opSUBCH(void)
2171 {
2172 	UINT16 apph;
2173 	UINT16 src;
2174 
2175 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
2176 
2177 	F12LOADOP2HALF();
2178 
2179 	src = (UINT16)f12Op1 + (_CY?1:0);
2180 	SUBW(apph, src);
2181 
2182 	F12STOREOP2HALF();
2183 	F12END();
2184 }
2185 
opSUBCW(void)2186 static UINT32 opSUBCW(void)
2187 {
2188 	UINT32 appw;
2189 	UINT32 src;
2190 
2191 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
2192 
2193 	F12LOADOP2WORD();
2194 
2195 	src = (UINT32)f12Op1 + (_CY?1:0);
2196 	SUBL(appw, src);
2197 
2198 	F12STOREOP2WORD();
2199 	F12END();
2200 }
2201 
opTEST1(void)2202 static UINT32 opTEST1(void)
2203 {
2204 	F12DecodeOperands(ReadAM,2,ReadAM,2);
2205 
2206 	_CY = ((f12Op2 & (1<<f12Op1))!=0);
2207 	_Z = !(_CY);
2208 
2209 	F12END();
2210 }
2211 
opUPDPSWW(void)2212 static UINT32 opUPDPSWW(void)
2213 {
2214 	F12DecodeOperands(ReadAM,2,ReadAM,2);
2215 
2216 	/* can only modify condition code and control fields */
2217 	f12Op2 &= 0xFFFFFF;
2218 	f12Op1 &= 0xFFFFFF;
2219 	v60WritePSW((v60ReadPSW() & (~f12Op2)) | (f12Op1 & f12Op2));
2220 
2221 	F12END();
2222 }
2223 
opUPDPSWH(void)2224 static UINT32 opUPDPSWH(void)
2225 {
2226 	F12DecodeOperands(ReadAM,2,ReadAM,2);
2227 
2228 	/* can only modify condition code fields */
2229 	f12Op2 &= 0xFFFF;
2230 	f12Op1 &= 0xFFFF;
2231 	v60WritePSW((v60ReadPSW() & (~f12Op2)) | (f12Op1 & f12Op2));
2232 
2233 	F12END();
2234 }
2235 
opXCHB(void)2236 static UINT32 opXCHB(void) /* TRUSTED */
2237 {
2238 	UINT8 appb, temp;
2239 
2240 	F12DecodeOperands(ReadAMAddress,0,ReadAMAddress,0);
2241 
2242 	F12LOADOP1BYTE();
2243 	temp=appb;
2244 	F12LOADOP2BYTE();
2245 	F12STOREOP1BYTE();
2246 	appb=temp;
2247 	F12STOREOP2BYTE();
2248 
2249 	F12END()
2250 }
2251 
opXCHH(void)2252 static UINT32 opXCHH(void) /* TRUSTED */
2253 {
2254 	UINT16 apph, temp;
2255 
2256 	F12DecodeOperands(ReadAMAddress,1,ReadAMAddress,1);
2257 
2258 	F12LOADOP1HALF();
2259 	temp=apph;
2260 	F12LOADOP2HALF();
2261 	F12STOREOP1HALF();
2262 	apph=temp;
2263 	F12STOREOP2HALF();
2264 
2265 	F12END()
2266 }
2267 
opXCHW(void)2268 static UINT32 opXCHW(void) /* TRUSTED */
2269 {
2270 	UINT32 appw, temp;
2271 
2272 	F12DecodeOperands(ReadAMAddress,2,ReadAMAddress,2);
2273 
2274 	F12LOADOP1WORD();
2275 	temp=appw;
2276 	F12LOADOP2WORD();
2277 	F12STOREOP1WORD();
2278 	appw=temp;
2279 	F12STOREOP2WORD();
2280 
2281 	F12END()
2282 }
2283 
opXORB(void)2284 static UINT32 opXORB(void) /* TRUSTED (C too!) */
2285 {
2286 	UINT8 appb;
2287 	F12DecodeOperands(ReadAM,0,ReadAMAddress,0);
2288 
2289 	F12LOADOP2BYTE();
2290 
2291 	XORB(appb, (UINT8)f12Op1);
2292 
2293 	F12STOREOP2BYTE();
2294 	F12END();
2295 }
2296 
opXORH(void)2297 static UINT32 opXORH(void) /* TRUSTED (C too!) */
2298 {
2299 	UINT16 apph;
2300 	F12DecodeOperands(ReadAM,1,ReadAMAddress,1);
2301 
2302 	F12LOADOP2HALF();
2303 
2304 	XORW(apph, (UINT16)f12Op1);
2305 
2306 	F12STOREOP2HALF();
2307 	F12END();
2308 }
2309 
opXORW(void)2310 static UINT32 opXORW(void) /* TRUSTED (C too!) */
2311 {
2312 	UINT32 appw;
2313 	F12DecodeOperands(ReadAM,2,ReadAMAddress,2);
2314 
2315 	F12LOADOP2WORD();
2316 
2317 	XORL(appw, (UINT32)f12Op1);
2318 
2319 	F12STOREOP2WORD();
2320 	F12END();
2321 }
2322 
opMULX(void)2323 static UINT32 opMULX(void)
2324 {
2325 	INT32 a,b;
2326 	INT64 res;
2327 
2328 	F12DecodeOperands(ReadAM,2,ReadAMAddress,3);
2329 
2330 	if (f12Flag2)
2331 	{
2332 		a=v60.reg[f12Op2&0x1F];
2333 	}
2334 	else
2335 	{
2336 		a=MemRead32(f12Op2);
2337 	}
2338 
2339 	res = (INT64)a * (INT64)(INT32)f12Op1;
2340 
2341 	b = (INT32)((res >> 32)&0xffffffff);
2342 	a = (INT32)(res&0xffffffff);
2343 
2344 	_S = ((b & 0x80000000) != 0);
2345 	_Z = (a == 0 && b == 0);
2346 
2347 	if (f12Flag2)
2348 	{
2349 		v60.reg[f12Op2&0x1F]=a;
2350 		v60.reg[(f12Op2&0x1F)+1]=b;
2351 	}
2352 	else
2353 	{
2354 		MemWrite32(f12Op2,a);
2355 		MemWrite32(f12Op2+4,b);
2356 	}
2357 
2358 	F12END();
2359 }
2360 
opMULUX(void)2361 static UINT32 opMULUX(void)
2362 {
2363 	INT32 a,b;
2364 	UINT64 res;
2365 
2366 	F12DecodeOperands(ReadAM,2,ReadAMAddress,3);
2367 
2368 	if (f12Flag2)
2369 	{
2370 		a=v60.reg[f12Op2&0x1F];
2371 	}
2372 	else
2373 	{
2374 		a=MemRead32(f12Op2);
2375 	}
2376 
2377 	res = (UINT64)a * (UINT64)f12Op1;
2378 	b = (INT32)((res >> 32)&0xffffffff);
2379 	a = (INT32)(res&0xffffffff);
2380 
2381 	_S = ((b & 0x80000000) != 0);
2382 	_Z = (a == 0 && b == 0);
2383 
2384 	if (f12Flag2)
2385 	{
2386 		v60.reg[f12Op2&0x1F]=a;
2387 		v60.reg[(f12Op2&0x1F)+1]=b;
2388 	}
2389 	else
2390 	{
2391 		MemWrite32(f12Op2,a);
2392 		MemWrite32(f12Op2+4,b);
2393 	}
2394 
2395 	F12END();
2396 }
2397