1 /***************************************************************************
2 
3     TMS34010: Portable Texas Instruments TMS34010 emulator
4 
5     Copyright Alex Pasadyn/Zsolt Vasvari
6     Parts based on code by Aaron Giles
7 
8 ***************************************************************************/
9 
10 /* Combine two 32-bit integers into a 64-bit integer */
11 #define COMBINE_64_32_32(A,B)     ((((UINT64)(A))<<32) | (UINT32)(B))
12 #define COMBINE_U64_U32_U32(A,B)  COMBINE_64_32_32(A,B)
13 #define DIV_64_64_32(A,B)	  ((A)/(B))
14 #define DIV_U64_U64_U32(A,B)  ((A)/(UINT32)(B))
15 #define MOD_32_64_32(A,B)	  ((A)%(B))
16 #define MOD_U32_U64_U32(A,B)  ((A)%(UINT32)(B))
17 #define HI32_32_64(A)		  (((UINT64)(A)) >> 32)
18 #define HI32_U32_U64(A)		  HI32_32_64(A)
19 #define LO32_32_64(A)		  ((A) & 0xffffffff)
20 #define LO32_U32_U64(A)		  LO32_32_64(A)
21 #define MUL_64_32_32(A,B)	  ((A)*(INT64)(B))
22 #define MUL_U64_U32_U32(A,B)  ((A)*(UINT64)(UINT32)(B))
23 
24 
25 /***************************************************************************
26     MISC MACROS
27 ***************************************************************************/
28 
29 #define ZEXTEND(val,width) if (width) (val) &= ((UINT32)0xffffffff >> (32 - (width)))
30 #define SEXTEND(val,width) if (width) (val) = (INT32)((val) << (32 - (width))) >> (32 - (width))
31 
32 #define SXYTOL(val)	((((INT16)(val).y * state.convsp) + ((INT16)(val).x << state.pixelshift)) + OFFSET)
33 #define DXYTOL(val)	((((INT16)(val).y * state.convdp) + ((INT16)(val).x << state.pixelshift)) + OFFSET)
34 #define MXYTOL(val)	((((INT16)(val).y * state.convmp) + ((INT16)(val).x << state.pixelshift)) + OFFSET)
35 
36 #define COUNT_CYCLES(x)	do { tms34010_ICount -= x; check_timer(x); } while (0)
37 #define COUNT_UNKNOWN_CYCLES(x) COUNT_CYCLES(x)
38 
39 #define CORRECT_ODD_PC(x)	do { if (PC & 0x0f) logerror("%s to PC=%08X\n", x, PC); PC &= ~0x0f; } while (0)
40 
41 
42 
43 /***************************************************************************
44     FLAG HANDLING MACROS
45 ***************************************************************************/
46 
47 #define SIGN(val)			((val) & 0x80000000)
48 
49 #define CLR_Z					state.st &= ~STBIT_Z
50 #define CLR_V					state.st &= ~STBIT_V
51 #define CLR_C					state.st &= ~STBIT_C
52 #define CLR_N					state.st &= ~STBIT_N
53 #define CLR_NZ					state.st &= ~(STBIT_N | STBIT_Z)
54 #define CLR_CZ					state.st &= ~(STBIT_C | STBIT_Z)
55 #define CLR_ZV					state.st &= ~(STBIT_Z | STBIT_V)
56 #define CLR_NZV					state.st &= ~(STBIT_N | STBIT_Z | STBIT_V)
57 #define CLR_NCZ					state.st &= ~(STBIT_N | STBIT_C | STBIT_Z)
58 #define CLR_NCZV				state.st &= ~(STBIT_N | STBIT_C | STBIT_Z | STBIT_V)
59 
60 #define SET_V_BIT_LO(val,bit)	state.st |= ((val) << (28 - (bit))) & STBIT_V
61 #define SET_V_BIT_HI(val,bit)	state.st |= ((val) >> ((bit) - 28)) & STBIT_V
62 #define SET_V_LOG(val)			state.st |= (val) << 28
63 #define SET_Z_BIT_LO(val,bit)	state.st |= ((val) << (29 - (bit))) & STBIT_Z
64 #define SET_Z_BIT_HI(val,bit)	state.st |= ((val) >> ((bit) - 29)) & STBIT_Z
65 #define SET_Z_LOG(val)			state.st |= (val) << 29
66 #define SET_C_BIT_LO(val,bit)	state.st |= ((val) << (30 - (bit))) & STBIT_C
67 #define SET_C_BIT_HI(val,bit)	state.st |= ((val) >> ((bit) - 30)) & STBIT_C
68 #define SET_C_LOG(val)			state.st |= (val) << 30
69 #define SET_N_BIT(val,bit)		state.st |= ((val) << (31 - (bit))) & STBIT_N
70 #define SET_N_LOG(val)			state.st |= (val) << 31
71 
72 #define SET_Z_VAL(val)			SET_Z_LOG((val) == 0)
73 #define SET_N_VAL(val)			SET_N_BIT(val, 31)
74 #define SET_NZ_VAL(val)			SET_Z_VAL(val); SET_N_VAL(val)
75 #define SET_V_SUB(a,b,r)		SET_V_BIT_HI(((a) ^ (b)) & ((a) ^ (r)), 31)
76 #define SET_V_ADD(a,b,r)		SET_V_BIT_HI(~((a) ^ (b)) & ((a) ^ (r)), 31)
77 #define SET_C_SUB(a,b)			SET_C_LOG((UINT32)(b) > (UINT32)(a))
78 #define SET_C_ADD(a,b)			SET_C_LOG((UINT32)~(a) < (UINT32)(b))
79 #define SET_NZV_SUB(a,b,r)		SET_NZ_VAL(r); SET_V_SUB(a,b,r)
80 #define SET_NZCV_SUB(a,b,r)		SET_NZV_SUB(a,b,r); SET_C_SUB(a,b)
81 #define SET_NZCV_ADD(a,b,r)		SET_NZ_VAL(r); SET_V_ADD(a,b,r); SET_C_ADD(a,b)
82 
83 static const UINT8 fw_inc[32] = { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
84 
85 
86 /***************************************************************************
87     UNIMPLEMENTED INSTRUCTION
88 ***************************************************************************/
89 
unimpl(void)90 static void unimpl(void)
91 {
92 	bprintf(0, _T("CPU: %d  unimpl @ %x\n"), TMS34010GetActive(), TMS34010GetPC());
93 #if 1
94 	/* kludge for Super High Impact -- this doesn't seem to cause */
95 	/* an illegal opcode exception */
96 	if (cpu_readop16(TOBYTE(PC - 0x10)) == 0x0007)
97 		return;
98 
99 	/* 9 Ball Shootout calls to FFDF7468, expecting it */
100 	/* to execute the next instruction from FFDF7470 */
101 	/* but the instruction at FFDF7460 is an 0x0001 */
102 	if (cpu_readop16(TOBYTE(PC - 0x10)) == 0x0001)
103 		return;
104 
105 	PUSH(PC);
106 	PUSH(GET_ST());
107 	RESET_ST();
108 	PC = RLONG(0xfffffc20);
109 	change_pc(TOBYTE(PC));
110   	COUNT_UNKNOWN_CYCLES(16);
111 
112 	/* extra check to prevent bad things */
113 	if (PC == 0 || opcode_table[cpu_readop16(TOBYTE(PC)) >> 4] == unimpl)
114 	{
115 //		cpunum_set_input_line(state.screen->machine, cpu_getactivecpu(), INPUT_LINE_HALT, ASSERT_LINE);
116 		//		debugger_break(state.screen->machine);
117 		bprintf(0, _T("unimpl halts?\n"));
118 	}
119 #endif
120 }
121 
122 
123 
124 /***************************************************************************
125     X/Y OPERATIONS
126 ***************************************************************************/
127 
128 #define ADD_XY(R)								\
129 {												\
130 	XY  a =  R##REG_XY(SRCREG);					\
131 	XY *b = &R##REG_XY(DSTREG);					\
132 	CLR_NCZV;									\
133 	b->x += a.x;								\
134 	b->y += a.y;								\
135 	SET_N_LOG(b->x == 0);						\
136 	SET_C_BIT_LO(b->y, 15);						\
137 	SET_Z_LOG(b->y == 0);						\
138 	SET_V_BIT_LO(b->x, 15);						\
139   	COUNT_CYCLES(1);							\
140 }
add_xy_a(void)141 static void add_xy_a(void) { ADD_XY(A); }
add_xy_b(void)142 static void add_xy_b(void) { ADD_XY(B); }
143 
144 #define SUB_XY(R)								\
145 {												\
146 	XY  a =  R##REG_XY(SRCREG);					\
147 	XY *b = &R##REG_XY(DSTREG);					\
148 	CLR_NCZV;									\
149 	SET_N_LOG(a.x == b->x);						\
150 	SET_C_LOG(a.y > b->y);						\
151 	SET_Z_LOG(a.y == b->y);						\
152 	SET_V_LOG(a.x > b->x);						\
153 	b->x -= a.x;								\
154 	b->y -= a.y;								\
155   	COUNT_CYCLES(1);							\
156 }
sub_xy_a(void)157 static void sub_xy_a(void) { SUB_XY(A); }
sub_xy_b(void)158 static void sub_xy_b(void) { SUB_XY(B); }
159 
160 #define CMP_XY(R)								\
161 {												\
162 	INT16 res;									\
163 	XY a = R##REG_XY(DSTREG);					\
164 	XY b = R##REG_XY(SRCREG);					\
165 	CLR_NCZV;									\
166 	res = a.x-b.x;								\
167 	SET_N_LOG(res == 0);						\
168 	SET_V_BIT_LO(res, 15);						\
169 	res = a.y-b.y;								\
170 	SET_Z_LOG(res == 0);						\
171 	SET_C_BIT_LO(res, 15);						\
172   	COUNT_CYCLES(1);							\
173 }
cmp_xy_a(void)174 static void cmp_xy_a(void) { CMP_XY(A); }
cmp_xy_b(void)175 static void cmp_xy_b(void) { CMP_XY(B); }
176 
177 #define CPW(R)									\
178 {												\
179 	INT32 res = 0;								\
180 	INT16 x = R##REG_X(SRCREG);					\
181 	INT16 y = R##REG_Y(SRCREG);					\
182 												\
183 	CLR_V;										\
184 	res |= ((WSTART_X > x) ? 0x20  : 0);		\
185 	res |= ((x > WEND_X)   ? 0x40  : 0);		\
186 	res |= ((WSTART_Y > y) ? 0x80  : 0);		\
187 	res |= ((y > WEND_Y)   ? 0x100 : 0);		\
188 	R##REG(DSTREG) = res;						\
189 	SET_V_LOG(res != 0);						\
190   	COUNT_CYCLES(1);							\
191 }
cpw_a(void)192 static void cpw_a(void) { CPW(A); }
cpw_b(void)193 static void cpw_b(void) { CPW(B); }
194 
195 #define CVXYL(R)									\
196 {													\
197     R##REG(DSTREG) = DXYTOL(R##REG_XY(SRCREG));		\
198   	COUNT_CYCLES(3);								\
199 }
cvxyl_a(void)200 static void cvxyl_a(void) { CVXYL(A); }
cvxyl_b(void)201 static void cvxyl_b(void) { CVXYL(B); }
202 
203 #define MOVX(R)										\
204 {													\
205 	R##REG(DSTREG) = (R##REG(DSTREG) & 0xffff0000) | (UINT16)R##REG(SRCREG);	\
206   	COUNT_CYCLES(1);																	\
207 }
movx_a(void)208 static void movx_a(void) { MOVX(A); }
movx_b(void)209 static void movx_b(void) { MOVX(B); }
210 
211 #define MOVY(R)										\
212 {													\
213 	R##REG(DSTREG) = (R##REG(SRCREG) & 0xffff0000) | (UINT16)R##REG(DSTREG);	\
214   	COUNT_CYCLES(1);																	\
215 }
movy_a(void)216 static void movy_a(void) { MOVY(A); }
movy_b(void)217 static void movy_b(void) { MOVY(B); }
218 
219 
220 
221 /***************************************************************************
222     PIXEL TRANSFER OPERATIONS
223 ***************************************************************************/
224 
225 #define PIXT_RI(R)			                        \
226 {							 						\
227 	WPIXEL(R##REG(DSTREG),R##REG(SRCREG));	\
228   	COUNT_UNKNOWN_CYCLES(2);						\
229 }
pixt_ri_a(void)230 static void pixt_ri_a(void) { PIXT_RI(A); }
pixt_ri_b(void)231 static void pixt_ri_b(void) { PIXT_RI(B); }
232 
233 #define PIXT_RIXY(R)		                       									\
234 {																					\
235 	if (WINDOW_CHECKING != 0)														\
236 	{																				\
237 		CLR_V;																		\
238 		if (R##REG_X(DSTREG) < WSTART_X || R##REG_X(DSTREG) > WEND_X ||				\
239 			R##REG_Y(DSTREG) < WSTART_Y || R##REG_Y(DSTREG) > WEND_Y)				\
240 		{																			\
241 			SET_V_LOG(1);															\
242 			goto skip;																\
243 		}																			\
244 		if (WINDOW_CHECKING == 1) goto skip;										\
245 	}																				\
246 	WPIXEL(DXYTOL(R##REG_XY(DSTREG)),R##REG(SRCREG));								\
247 skip: 																				\
248   	COUNT_UNKNOWN_CYCLES(4);														\
249 }
pixt_rixy_a(void)250 static void pixt_rixy_a(void) { PIXT_RIXY(A); }
pixt_rixy_b(void)251 static void pixt_rixy_b(void) { PIXT_RIXY(B); }
252 
253 #define PIXT_IR(R)			                        \
254 {													\
255 	INT32 temp = RPIXEL(R##REG(SRCREG));			\
256 	CLR_V;											\
257 	R##REG(DSTREG) = temp;						 	\
258 	SET_V_LOG(temp != 0);							\
259 	COUNT_CYCLES(4);								\
260 }
pixt_ir_a(void)261 static void pixt_ir_a(void) { PIXT_IR(A); }
pixt_ir_b(void)262 static void pixt_ir_b(void) { PIXT_IR(B); }
263 
264 #define PIXT_II(R)			                       	\
265 {													\
266 	WPIXEL(R##REG(DSTREG),RPIXEL(R##REG(SRCREG)));	\
267   	COUNT_UNKNOWN_CYCLES(4);						\
268 }
pixt_ii_a(void)269 static void pixt_ii_a(void) { PIXT_II(A); }
pixt_ii_b(void)270 static void pixt_ii_b(void) { PIXT_II(B); }
271 
272 #define PIXT_IXYR(R)			              		\
273 {													\
274 	INT32 temp = RPIXEL(SXYTOL(R##REG_XY(SRCREG)));	\
275 	CLR_V;											\
276 	R##REG(DSTREG) = temp;						 	\
277 	SET_V_LOG(temp != 0);							\
278 	COUNT_CYCLES(6);								\
279 }
pixt_ixyr_a(void)280 static void pixt_ixyr_a(void) { PIXT_IXYR(A); }
pixt_ixyr_b(void)281 static void pixt_ixyr_b(void) { PIXT_IXYR(B); }
282 
283 #define PIXT_IXYIXY(R)			              			      						\
284 {																					\
285 	if (WINDOW_CHECKING != 0)														\
286 	{																				\
287 		CLR_V;																		\
288 		if (R##REG_X(DSTREG) < WSTART_X || R##REG_X(DSTREG) > WEND_X ||				\
289 			R##REG_Y(DSTREG) < WSTART_Y || R##REG_Y(DSTREG) > WEND_Y)				\
290 		{																			\
291 			SET_V_LOG(1);															\
292 			goto skip;																\
293 		}																			\
294 		if (WINDOW_CHECKING == 1) goto skip;										\
295 	}																				\
296 	WPIXEL(DXYTOL(R##REG_XY(DSTREG)),RPIXEL(SXYTOL(R##REG_XY(SRCREG))));			\
297 skip: 																				\
298   	COUNT_UNKNOWN_CYCLES(7);														\
299 }
pixt_ixyixy_a(void)300 static void pixt_ixyixy_a(void) { PIXT_IXYIXY(A); }
pixt_ixyixy_b(void)301 static void pixt_ixyixy_b(void) { PIXT_IXYIXY(B); }
302 
303 #define DRAV(R)			              			      								\
304 {																					\
305 	if (WINDOW_CHECKING != 0)														\
306 	{																				\
307 		CLR_V;																		\
308 		if (R##REG_X(DSTREG) < WSTART_X || R##REG_X(DSTREG) > WEND_X ||				\
309 			R##REG_Y(DSTREG) < WSTART_Y || R##REG_Y(DSTREG) > WEND_Y)				\
310 		{																			\
311 			SET_V_LOG(1);															\
312 			goto skip;																\
313 		}																			\
314 		if (WINDOW_CHECKING == 1) goto skip;										\
315 	}																				\
316 	WPIXEL(DXYTOL(R##REG_XY(DSTREG)),COLOR1);										\
317 skip: 																				\
318 	R##REG_X(DSTREG) += R##REG_X(SRCREG);											\
319 	R##REG_Y(DSTREG) += R##REG_Y(SRCREG);											\
320   	COUNT_UNKNOWN_CYCLES(4);														\
321 }
drav_a(void)322 static void drav_a(void) { DRAV(A); }
drav_b(void)323 static void drav_b(void) { DRAV(B); }
324 
325 
326 
327 /***************************************************************************
328     ARITHMETIC OPERATIONS
329 ***************************************************************************/
330 
331 #define ABS(R)			              			      		\
332 {															\
333 	INT32 *rd = &R##REG(DSTREG);							\
334 	INT32 r = 0 - *rd;										\
335 	CLR_NZV;												\
336 	if (r > 0) *rd = r;										\
337 	SET_NZ_VAL(r);											\
338 	SET_V_LOG(r == (INT32)0x80000000);						\
339 	COUNT_CYCLES(1);										\
340 }
abs_a(void)341 static void abs_a(void) { ABS(A); }
abs_b(void)342 static void abs_b(void) { ABS(B); }
343 
344 #define ADD(R)			              			      		\
345 {							 								\
346 	INT32 a = R##REG(SRCREG);								\
347 	INT32 *rd = &R##REG(DSTREG);							\
348 	INT32 b = *rd;											\
349 	INT32 r = a + b;										\
350 	CLR_NCZV;												\
351 	*rd = r;												\
352 	SET_NZCV_ADD(a,b,r);									\
353 	COUNT_CYCLES(1);										\
354 }
add_a(void)355 static void add_a(void) { ADD(A); }
add_b(void)356 static void add_b(void) { ADD(B); }
357 
358 #define ADDC(R)			              			      		\
359 {			  												\
360 	/* I'm not sure to which side the carry is added to, should */	\
361 	/* verify it against the examples */					\
362 	INT32 a = R##REG(SRCREG);								\
363 	INT32 *rd = &R##REG(DSTREG);							\
364 	INT32 b = *rd;											\
365 	INT32 r = a + b + (C_FLAG ? 1 : 0);						\
366 	CLR_NCZV;												\
367 	*rd = r;												\
368 	SET_NZCV_ADD(a,b,r);									\
369 	COUNT_CYCLES(1);										\
370 }
addc_a(void)371 static void addc_a(void) { ADDC(A); }
addc_b(void)372 static void addc_b(void) { ADDC(B); }
373 
374 #define ADDI_W(R)			              			      	\
375 {			  												\
376 	INT32 a = PARAM_WORD();									\
377 	INT32 *rd = &R##REG(DSTREG);							\
378 	INT32 b = *rd;											\
379 	INT32 r = a + b;										\
380 	CLR_NCZV;												\
381 	*rd = r;												\
382 	SET_NZCV_ADD(a,b,r);									\
383 	COUNT_CYCLES(2);										\
384 }
addi_w_a(void)385 static void addi_w_a(void) { ADDI_W(A); }
addi_w_b(void)386 static void addi_w_b(void) { ADDI_W(B); }
387 
388 #define ADDI_L(R)			              			      	\
389 {			  												\
390 	INT32 a = PARAM_LONG();									\
391 	INT32 *rd = &R##REG(DSTREG);							\
392 	INT32 b = *rd;											\
393 	INT32 r = a + b;										\
394 	CLR_NCZV;												\
395 	*rd = r;												\
396 	SET_NZCV_ADD(a,b,r);									\
397 	COUNT_CYCLES(3);										\
398 }
addi_l_a(void)399 static void addi_l_a(void) { ADDI_L(A); }
addi_l_b(void)400 static void addi_l_b(void) { ADDI_L(B); }
401 
402 #define ADDK(R)				              			      	\
403 {			  												\
404 	INT32 a = fw_inc[PARAM_K];								\
405 	INT32 *rd = &R##REG(DSTREG);							\
406 	INT32 b = *rd;											\
407 	INT32 r = a + b;										\
408 	CLR_NCZV;												\
409 	*rd = r;												\
410 	SET_NZCV_ADD(a,b,r);									\
411 	COUNT_CYCLES(1);										\
412 }
addk_a(void)413 static void addk_a(void) { ADDK(A); }
addk_b(void)414 static void addk_b(void) { ADDK(B); }
415 
416 #define AND(R)				              			      	\
417 {			  												\
418 	INT32 *rd = &R##REG(DSTREG);							\
419 	CLR_Z;													\
420 	*rd &= R##REG(SRCREG);									\
421 	SET_Z_VAL(*rd);											\
422 	COUNT_CYCLES(1);										\
423 }
and_a(void)424 static void and_a(void) { AND(A); }
and_b(void)425 static void and_b(void) { AND(B); }
426 
427 #define ANDI(R)				              			      	\
428 {			  												\
429 	INT32 *rd = &R##REG(DSTREG);							\
430 	CLR_Z;													\
431 	*rd &= ~PARAM_LONG();									\
432 	SET_Z_VAL(*rd);											\
433 	COUNT_CYCLES(3);										\
434 }
andi_a(void)435 static void andi_a(void) { ANDI(A); }
andi_b(void)436 static void andi_b(void) { ANDI(B); }
437 
438 #define ANDN(R)				              			      	\
439 {			  												\
440 	INT32 *rd = &R##REG(DSTREG);							\
441 	CLR_Z;													\
442 	*rd &= ~R##REG(SRCREG);									\
443 	SET_Z_VAL(*rd);											\
444 	COUNT_CYCLES(1);										\
445 }
andn_a(void)446 static void andn_a(void) { ANDN(A); }
andn_b(void)447 static void andn_b(void) { ANDN(B); }
448 
449 #define BTST_K(R)				              			    \
450 {							 								\
451 	int bit = 31 - PARAM_K;									\
452 	CLR_Z;													\
453 	if (bit <= 29)											\
454 		SET_Z_BIT_LO(~R##REG(DSTREG), bit);					\
455 	else													\
456 		SET_Z_BIT_HI(~R##REG(DSTREG), bit);					\
457 	COUNT_CYCLES(1);										\
458 }
btst_k_a(void)459 static void btst_k_a(void) { BTST_K(A); }
btst_k_b(void)460 static void btst_k_b(void) { BTST_K(B); }
461 
462 #define BTST_R(R)				              			    \
463 {															\
464 	int bit = R##REG(SRCREG) & 0x1f;						\
465 	CLR_Z;													\
466 	if (bit <= 29)											\
467 		SET_Z_BIT_LO(~R##REG(DSTREG), bit);					\
468 	else													\
469 		SET_Z_BIT_HI(~R##REG(DSTREG), bit);					\
470 	COUNT_CYCLES(2);										\
471 }
btst_r_a(void)472 static void btst_r_a(void) { BTST_R(A); }
btst_r_b(void)473 static void btst_r_b(void) { BTST_R(B); }
474 
clrc(void)475 static void clrc(void)
476 {
477 	CLR_C;
478 	COUNT_CYCLES(1);
479 }
480 
481 #define CMP(R)				       		       			    \
482 {															\
483 	INT32 *rs = &R##REG(SRCREG);							\
484 	INT32 *rd = &R##REG(DSTREG);							\
485 	INT32 r = *rd - *rs;									\
486 	CLR_NCZV;												\
487 	SET_NZCV_SUB(*rd,*rs,r);								\
488 	COUNT_CYCLES(1);										\
489 }
cmp_a(void)490 static void cmp_a(void) { CMP(A); }
cmp_b(void)491 static void cmp_b(void) { CMP(B); }
492 
493 #define CMPI_W(R)			       		       			    \
494 {															\
495 	INT32 *rd = &R##REG(DSTREG);							\
496 	INT32 t = (INT16)~PARAM_WORD();							\
497 	INT32 r = *rd - t;										\
498 	CLR_NCZV;												\
499 	SET_NZCV_SUB(*rd,t,r);									\
500 	COUNT_CYCLES(2);										\
501 }
cmpi_w_a(void)502 static void cmpi_w_a(void) { CMPI_W(A); }
cmpi_w_b(void)503 static void cmpi_w_b(void) { CMPI_W(B); }
504 
505 #define CMPI_L(R)			       		       			    \
506 {															\
507 	INT32 *rd = &R##REG(DSTREG);							\
508 	INT32 t = ~PARAM_LONG();								\
509 	INT32 r = *rd - t;										\
510 	CLR_NCZV;												\
511 	SET_NZCV_SUB(*rd,t,r);									\
512 	COUNT_CYCLES(3);										\
513 }
cmpi_l_a(void)514 static void cmpi_l_a(void) { CMPI_L(A); }
cmpi_l_b(void)515 static void cmpi_l_b(void) { CMPI_L(B); }
516 
dint(void)517 static void dint(void)
518 {
519 	state.st &= ~STBIT_IE;
520 	COUNT_CYCLES(3);
521 }
522 
523 #define DIVS(R)			       		       			   		\
524 {															\
525 	INT32 *rs  = &R##REG(SRCREG);							\
526 	INT32 *rd1 = &R##REG(DSTREG);							\
527 	CLR_NZV;												\
528 	if (!(DSTREG & 1))										\
529 	{														\
530 		if (!*rs)											\
531 		{													\
532 			SET_V_LOG(1);									\
533 		}													\
534 		else												\
535 		{													\
536 			INT32 *rd2 = &R##REG(DSTREG+1);					\
537 			INT64 dividend  = COMBINE_64_32_32(*rd1, *rd2); \
538 			INT64 quotient  = DIV_64_64_32(dividend, *rs); 	\
539 			INT32 remainder = MOD_32_64_32(dividend, *rs); 	\
540 			UINT32 signbits = (INT32)quotient >> 31;	 	\
541 			if (HI32_32_64(quotient) != signbits)			\
542 			{												\
543 				SET_V_LOG(1);								\
544 			}												\
545 			else											\
546 			{												\
547 				*rd1 = quotient;							\
548 				*rd2 = remainder;							\
549 				SET_NZ_VAL(*rd1);							\
550 			}												\
551 		}													\
552 		COUNT_CYCLES(40);									\
553 	}														\
554 	else													\
555 	{														\
556 		if (!*rs)											\
557 		{													\
558 			SET_V_LOG(1);									\
559 		}													\
560 		else												\
561 		{													\
562 			*rd1 /= *rs;									\
563 			SET_NZ_VAL(*rd1);								\
564 		}													\
565 		COUNT_CYCLES(39);									\
566 	}														\
567 }
divs_a(void)568 static void divs_a(void) { DIVS(A); }
divs_b(void)569 static void divs_b(void) { DIVS(B); }
570 
571 #define DIVU(R)			       		       			   		\
572 {										  					\
573 	INT32 *rs  = &R##REG(SRCREG);							\
574 	INT32 *rd1 = &R##REG(DSTREG);							\
575 	CLR_ZV;													\
576 	if (!(DSTREG & 1))										\
577 	{														\
578 		if (!*rs)											\
579 		{													\
580 			SET_V_LOG(1);									\
581 		}													\
582 		else												\
583 		{													\
584 			INT32 *rd2 = &R##REG(DSTREG+1);					\
585 			UINT64 dividend  = COMBINE_U64_U32_U32(*rd1, *rd2);	\
586 			UINT64 quotient  = DIV_U64_U64_U32(dividend, *rs);	\
587 			UINT32 remainder = MOD_U32_U64_U32(dividend, *rs); 	\
588 			if (HI32_U32_U64(quotient) != 0)				\
589 			{												\
590 				SET_V_LOG(1);								\
591 			}												\
592 			else											\
593 			{												\
594 				*rd1 = quotient;							\
595 				*rd2 = remainder;							\
596 				SET_Z_VAL(*rd1);							\
597 			}												\
598 		}													\
599 	}														\
600 	else													\
601 	{														\
602 		if (!*rs)											\
603 		{													\
604 			SET_V_LOG(1);									\
605 		}													\
606 		else												\
607 		{													\
608 			*rd1 = (UINT32)*rd1 / (UINT32)*rs;			  	\
609 			SET_Z_VAL(*rd1);								\
610 		}													\
611 	}														\
612 	COUNT_CYCLES(37);										\
613 }
divu_a(void)614 static void divu_a(void) { DIVU(A); }
divu_b(void)615 static void divu_b(void) { DIVU(B); }
616 
eint(void)617 static void eint(void)
618 {
619 	state.st |= STBIT_IE;
620 	check_interrupt();
621 	COUNT_CYCLES(3);
622 }
623 
624 #define EXGF(F,R)			       		       			    	\
625 {																\
626 	UINT8 shift = F ? 6 : 0;									\
627 	INT32 *rd = &R##REG(DSTREG);								\
628 	UINT32 temp = (state.st >> shift) & 0x3f;					\
629 	state.st &= ~(0x3f << shift);								\
630 	state.st |= (*rd & 0x3f) << shift;							\
631 	*rd = temp;													\
632 	COUNT_CYCLES(1);											\
633 }
exgf0_a(void)634 static void exgf0_a(void) { EXGF(0,A); }
exgf0_b(void)635 static void exgf0_b(void) { EXGF(0,B); }
exgf1_a(void)636 static void exgf1_a(void) { EXGF(1,A); }
exgf1_b(void)637 static void exgf1_b(void) { EXGF(1,B); }
638 
639 #define LMO(R)			       		       			    		\
640 {																\
641 	UINT32 res = 0;												\
642 	UINT32 rs  = R##REG(SRCREG);								\
643 	 INT32 *rd = &R##REG(DSTREG);								\
644 	CLR_Z;														\
645 	SET_Z_VAL(rs);												\
646 	if (rs)														\
647 	{															\
648 		while (!(rs & 0x80000000))								\
649 		{														\
650 			res++;												\
651 			rs <<= 1;											\
652 		}														\
653 	}															\
654 	*rd = res;													\
655 	COUNT_CYCLES(1);											\
656 }
lmo_a(void)657 static void lmo_a(void) { LMO(A); }
lmo_b(void)658 static void lmo_b(void) { LMO(B); }
659 
660 #define MMFM(R)			       		       			    		\
661 {																\
662 	INT32 i;													\
663 	UINT16 l = (UINT16) PARAM_WORD();							\
664 	COUNT_CYCLES(3);											\
665 	{															\
666 		INT32 rd = DSTREG;										\
667 		for (i = 15; i >= 0 ; i--)								\
668 		{														\
669 			if (l & 0x8000)										\
670 			{													\
671 				R##REG(i) = RLONG(R##REG(rd));					\
672 				R##REG(rd) += 0x20;								\
673 				COUNT_CYCLES(4);								\
674 			}													\
675 			l <<= 1;											\
676 		}														\
677 	}															\
678 }
mmfm_a(void)679 static void mmfm_a(void) { MMFM(A); }
mmfm_b(void)680 static void mmfm_b(void) { MMFM(B); }
681 
682 #define MMTM(R)			       		       			    		\
683 {			  													\
684 	UINT32 i;													\
685 	UINT16 l = (UINT16) PARAM_WORD();							\
686 	COUNT_CYCLES(2);											\
687 	{															\
688 		INT32 rd = DSTREG;										\
689 		if (state.is_34020)										\
690 		{														\
691 			CLR_N;												\
692 			SET_N_VAL(R##REG(rd) ^ 0x80000000);					\
693 		}														\
694 		for (i = 0; i  < 16; i++)								\
695 		{														\
696 			if (l & 0x8000)										\
697 			{													\
698 				R##REG(rd) -= 0x20;								\
699 				WLONG(R##REG(rd),R##REG(i));					\
700 				COUNT_CYCLES(4);								\
701 			}													\
702 			l <<= 1;											\
703 		}														\
704 	}															\
705 }
mmtm_a(void)706 static void mmtm_a(void) { MMTM(A); }
mmtm_b(void)707 static void mmtm_b(void) { MMTM(B); }
708 
709 #define MODS(R)			       		       			    		\
710 {				  												\
711 	INT32 *rs = &R##REG(SRCREG);								\
712 	INT32 *rd = &R##REG(DSTREG);								\
713 	CLR_NZV;													\
714 	if (*rs != 0)												\
715 	{															\
716 		*rd %= *rs;												\
717 		SET_NZ_VAL(*rd);										\
718 	}															\
719 	else														\
720 		SET_V_LOG(1);											\
721 	COUNT_CYCLES(40);											\
722 }
mods_a(void)723 static void mods_a(void) { MODS(A); }
mods_b(void)724 static void mods_b(void) { MODS(B); }
725 
726 #define MODU(R)			       		       			    		\
727 {				  												\
728 	INT32 *rs = &R##REG(SRCREG);								\
729 	INT32 *rd = &R##REG(DSTREG);								\
730 	CLR_ZV;														\
731 	if (*rs != 0)												\
732 	{															\
733 		*rd = (UINT32)*rd % (UINT32)*rs;						\
734 		SET_Z_VAL(*rd);											\
735 	}															\
736 	else														\
737 		SET_V_LOG(1);											\
738 	COUNT_CYCLES(35);											\
739 }
modu_a(void)740 static void modu_a(void) { MODU(A); }
modu_b(void)741 static void modu_b(void) { MODU(B); }
742 
743 #define MPYS(R)			       		       			    		\
744 {																\
745 	INT32 *rd1 = &R##REG(DSTREG);								\
746 	INT32 m1 = R##REG(SRCREG);									\
747 	INT64 product;												\
748 																\
749 	SEXTEND(m1, FW(1));											\
750 	CLR_NZ;														\
751 	product = MUL_64_32_32(m1, *rd1);							\
752 	SET_Z_LOG(product == 0);									\
753 	SET_N_BIT(product >> 32, 31);								\
754 																\
755 	*rd1             = HI32_32_64(product);						\
756 	R##REG(DSTREG|1) = LO32_32_64(product);						\
757 																\
758 	COUNT_CYCLES(20);											\
759 }
mpys_a(void)760 static void mpys_a(void) { MPYS(A); }
mpys_b(void)761 static void mpys_b(void) { MPYS(B); }
762 
763 #define MPYU(R)			       		       			    		\
764 {																\
765 	INT32 *rd1 = &R##REG(DSTREG);								\
766 	UINT32 m1 = R##REG(SRCREG);									\
767 	UINT64 product;												\
768 																\
769 	ZEXTEND(m1, FW(1));											\
770 	CLR_Z;														\
771 	product = MUL_U64_U32_U32(m1, *rd1);						\
772 	SET_Z_LOG(product == 0);									\
773 																\
774 	*rd1             = HI32_32_64(product);						\
775 	R##REG(DSTREG|1) = LO32_32_64(product);						\
776 																\
777 	COUNT_CYCLES(21);											\
778 }
mpyu_a(void)779 static void mpyu_a(void) { MPYU(A); }
mpyu_b(void)780 static void mpyu_b(void) { MPYU(B); }
781 
782 #define NEG(R)			       		       			    		\
783 {			  													\
784 	INT32 *rd = &R##REG(DSTREG);								\
785 	INT32 r = 0 - *rd;											\
786 	CLR_NCZV;													\
787 	SET_NZCV_SUB(0,*rd,r);										\
788 	*rd = r;													\
789 	COUNT_CYCLES(1);											\
790 }
neg_a(void)791 static void neg_a(void) { NEG(A); }
neg_b(void)792 static void neg_b(void) { NEG(B); }
793 
794 #define NEGB(R)			       		       			    		\
795 {			  													\
796 	INT32 *rd = &R##REG(DSTREG);								\
797 	INT32 t = *rd + (C_FLAG ? 1 : 0);							\
798 	INT32 r = 0 - t;											\
799 	CLR_NCZV;													\
800 	SET_NZCV_SUB(0,t,r);										\
801 	*rd = r;													\
802 	COUNT_CYCLES(1);											\
803 }
negb_a(void)804 static void negb_a(void) { NEGB(A); }
negb_b(void)805 static void negb_b(void) { NEGB(B); }
806 
nop(void)807 static void nop(void)
808 {
809 	COUNT_CYCLES(1);
810 }
811 
812 #define NOT(R)			       		       			    		\
813 {								 								\
814 	INT32 *rd = &R##REG(DSTREG);								\
815 	CLR_Z;														\
816 	*rd = ~(*rd);												\
817 	SET_Z_VAL(*rd);												\
818 	COUNT_CYCLES(1);											\
819 }
not_a(void)820 static void not_a(void) { NOT(A); }
not_b(void)821 static void not_b(void) { NOT(B); }
822 
823 #define OR(R)			       		       			    		\
824 {			  													\
825 	INT32 *rd = &R##REG(DSTREG);								\
826 	CLR_Z;														\
827 	*rd |= R##REG(SRCREG);										\
828 	SET_Z_VAL(*rd);												\
829 	COUNT_CYCLES(1);											\
830 }
or_a(void)831 static void or_a(void) { OR(A); }
or_b(void)832 static void or_b(void) { OR(B); }
833 
834 #define ORI(R)			       		       			    		\
835 {			  													\
836 	INT32 *rd = &R##REG(DSTREG);								\
837 	CLR_Z;														\
838 	*rd |= PARAM_LONG();										\
839 	SET_Z_VAL(*rd);												\
840 	COUNT_CYCLES(3);											\
841 }
ori_a(void)842 static void ori_a(void) { ORI(A); }
ori_b(void)843 static void ori_b(void) { ORI(B); }
844 
setc(void)845 static void setc(void)
846 {
847 	SET_C_LOG(1);
848 	COUNT_CYCLES(1);
849 }
850 
851 #define SETF(F)													\
852 {																\
853 	UINT8 shift = F ? 6 : 0;									\
854 	state.st &= ~(0x3f << shift);								\
855 	state.st |= (state.op & 0x3f) << shift;						\
856 	COUNT_CYCLES(1+F);											\
857 }
setf0(void)858 static void setf0(void) { SETF(0); }
setf1(void)859 static void setf1(void) { SETF(1); }
860 
861 #define SEXT(F,R)												\
862 {							   									\
863 	INT32 *rd = &R##REG(DSTREG);								\
864 	CLR_NZ;														\
865 	SEXTEND(*rd,FW(F));											\
866 	SET_NZ_VAL(*rd);											\
867 	COUNT_CYCLES(3);											\
868 }
sext0_a(void)869 static void sext0_a(void) { SEXT(0,A); }
sext0_b(void)870 static void sext0_b(void) { SEXT(0,B); }
sext1_a(void)871 static void sext1_a(void) { SEXT(1,A); }
sext1_b(void)872 static void sext1_b(void) { SEXT(1,B); }
873 
874 #define RL(R,K)			       		       			    		\
875 {			 													\
876 	INT32 *rd = &R##REG(DSTREG);								\
877 	INT32 res = *rd;											\
878 	INT32 k = (K);												\
879 	CLR_CZ;														\
880 	if (k)														\
881 	{															\
882 		res<<=(k-1);											\
883 		SET_C_BIT_HI(res, 31);									\
884 		res<<=1;												\
885 		res |= (((UINT32)*rd)>>((-k)&0x1f));					\
886 		*rd = res;												\
887 	}															\
888 	SET_Z_VAL(res);												\
889 	COUNT_CYCLES(1);											\
890 }
rl_k_a(void)891 static void rl_k_a(void) { RL(A,PARAM_K); }
rl_k_b(void)892 static void rl_k_b(void) { RL(B,PARAM_K); }
rl_r_a(void)893 static void rl_r_a(void) { RL(A,AREG(SRCREG)&0x1f); }
rl_r_b(void)894 static void rl_r_b(void) { RL(B,BREG(SRCREG)&0x1f); }
895 
896 #define SLA(R,K)												\
897 {				 												\
898 	 INT32 *rd = &R##REG(DSTREG);								\
899 	UINT32 res = *rd;											\
900 	 INT32 k = K;												\
901 	CLR_NCZV;													\
902 	if (k)														\
903 	{															\
904 		UINT32 mask = (0xffffffff<<(31-k))&0x7fffffff;			\
905 		UINT32 res2 = SIGN(res) ? res^mask : res;				\
906 		SET_V_LOG((res2 & mask) != 0);							\
907 																\
908 		res<<=(k-1);											\
909 		SET_C_BIT_HI(res, 31);									\
910 		res<<=1;												\
911 		*rd = res;												\
912 	}															\
913 	SET_NZ_VAL(res);											\
914 	COUNT_CYCLES(3);											\
915 }
sla_k_a(void)916 static void sla_k_a(void) { SLA(A,PARAM_K); }
sla_k_b(void)917 static void sla_k_b(void) { SLA(B,PARAM_K); }
sla_r_a(void)918 static void sla_r_a(void) { SLA(A,AREG(SRCREG)&0x1f); }
sla_r_b(void)919 static void sla_r_b(void) { SLA(B,BREG(SRCREG)&0x1f); }
920 
921 #define SLL(R,K)												\
922 {			 													\
923 	 INT32 *rd = &R##REG(DSTREG);								\
924 	UINT32 res = *rd;											\
925 	 INT32 k = K;												\
926 	CLR_CZ;														\
927 	if (k)														\
928 	{															\
929 		res<<=(k-1);											\
930 		SET_C_BIT_HI(res, 31);									\
931 		res<<=1;												\
932 		*rd = res;												\
933 	}															\
934 	SET_Z_VAL(res);												\
935 	COUNT_CYCLES(1);											\
936 }
sll_k_a(void)937 static void sll_k_a(void) { SLL(A,PARAM_K); }
sll_k_b(void)938 static void sll_k_b(void) { SLL(B,PARAM_K); }
sll_r_a(void)939 static void sll_r_a(void) { SLL(A,AREG(SRCREG)&0x1f); }
sll_r_b(void)940 static void sll_r_b(void) { SLL(B,BREG(SRCREG)&0x1f); }
941 
942 #define SRA(R,K)												\
943 {			  													\
944 	INT32 *rd = &R##REG(DSTREG);								\
945 	INT32 res = *rd;											\
946 	INT32 k = (-(K)) & 0x1f;									\
947 	CLR_NCZ;													\
948 	if (k)														\
949 	{															\
950 		res>>=(k-1);											\
951 		SET_C_BIT_LO(res, 0);									\
952 		res>>=1;												\
953 		*rd = res;												\
954 	}															\
955 	SET_NZ_VAL(res);											\
956 	COUNT_CYCLES(1);											\
957 }
sra_k_a(void)958 static void sra_k_a(void) { SRA(A,PARAM_K); }
sra_k_b(void)959 static void sra_k_b(void) { SRA(B,PARAM_K); }
sra_r_a(void)960 static void sra_r_a(void) { SRA(A,AREG(SRCREG)); }
sra_r_b(void)961 static void sra_r_b(void) { SRA(B,BREG(SRCREG)); }
962 
963 #define SRL(R,K)												\
964 {			  													\
965 	 INT32 *rd = &R##REG(DSTREG);								\
966 	UINT32 res = *rd;											\
967 	 INT32 k = (-(K)) & 0x1f;									\
968 	CLR_CZ;														\
969 	if (k)														\
970 	{															\
971 		res>>=(k-1);											\
972 		SET_C_BIT_LO(res, 0);									\
973 		res>>=1;												\
974 		*rd = res;												\
975 	}															\
976 	SET_Z_VAL(res);												\
977 	COUNT_CYCLES(1);											\
978 }
srl_k_a(void)979 static void srl_k_a(void) { SRL(A,PARAM_K); }
srl_k_b(void)980 static void srl_k_b(void) { SRL(B,PARAM_K); }
srl_r_a(void)981 static void srl_r_a(void) { SRL(A,AREG(SRCREG)); }
srl_r_b(void)982 static void srl_r_b(void) { SRL(B,BREG(SRCREG)); }
983 
984 #define SUB(R)			       		       			    		\
985 {			  													\
986 	INT32 *rs = &R##REG(SRCREG);								\
987 	INT32 *rd = &R##REG(DSTREG);								\
988 	INT32 r = *rd - *rs;										\
989 	CLR_NCZV;													\
990 	SET_NZCV_SUB(*rd,*rs,r);									\
991 	*rd = r;													\
992 	COUNT_CYCLES(1);											\
993 }
sub_a(void)994 static void sub_a(void) { SUB(A); }
sub_b(void)995 static void sub_b(void) { SUB(B); }
996 
997 #define SUBB(R)			       		       			    		\
998 {			  													\
999 	INT32 *rd = &R##REG(DSTREG);								\
1000 	INT32 t = R##REG(SRCREG);									\
1001 	INT32 r = *rd - t - (C_FLAG ? 1 : 0);						\
1002 	CLR_NCZV;													\
1003 	SET_NZCV_SUB(*rd,t,r);										\
1004 	*rd = r;													\
1005 	COUNT_CYCLES(1);											\
1006 }
subb_a(void)1007 static void subb_a(void) { SUBB(A); }
subb_b(void)1008 static void subb_b(void) { SUBB(B); }
1009 
1010 #define SUBI_W(R)			       		       			    	\
1011 {			  													\
1012 	INT32 *rd = &R##REG(DSTREG);								\
1013 	INT32 r;													\
1014 	INT32 t = ~PARAM_WORD();									\
1015 	CLR_NCZV;													\
1016 	r = *rd - t;												\
1017 	SET_NZCV_SUB(*rd,t,r);										\
1018 	*rd = r;													\
1019 	COUNT_CYCLES(2);											\
1020 }
subi_w_a(void)1021 static void subi_w_a(void) { SUBI_W(A); }
subi_w_b(void)1022 static void subi_w_b(void) { SUBI_W(B); }
1023 
1024 #define SUBI_L(R)			       		       			    	\
1025 {			  													\
1026 	INT32 *rd = &R##REG(DSTREG);								\
1027 	INT32 t = ~PARAM_LONG();									\
1028 	INT32 r = *rd - t;											\
1029 	CLR_NCZV;													\
1030 	SET_NZCV_SUB(*rd,t,r);										\
1031 	*rd = r;													\
1032 	COUNT_CYCLES(3);											\
1033 }
subi_l_a(void)1034 static void subi_l_a(void) { SUBI_L(A); }
subi_l_b(void)1035 static void subi_l_b(void) { SUBI_L(B); }
1036 
1037 #define SUBK(R)			       		       			    		\
1038 {			  													\
1039 	INT32 *rd = &R##REG(DSTREG);								\
1040 	INT32 t = fw_inc[PARAM_K];									\
1041 	INT32 r = *rd - t;											\
1042 	CLR_NCZV;													\
1043 	SET_NZCV_SUB(*rd,t,r);										\
1044 	*rd = r;													\
1045 	COUNT_CYCLES(1);											\
1046 }
subk_a(void)1047 static void subk_a(void) { SUBK(A); }
subk_b(void)1048 static void subk_b(void) { SUBK(B); }
1049 
1050 #define XOR(R)			       		       			    		\
1051 {			  													\
1052 	INT32 *rd = &R##REG(DSTREG);								\
1053 	CLR_Z;														\
1054 	*rd ^= R##REG(SRCREG);										\
1055 	SET_Z_VAL(*rd);												\
1056 	COUNT_CYCLES(1);											\
1057 }
xor_a(void)1058 static void xor_a(void) { XOR(A); }
xor_b(void)1059 static void xor_b(void) { XOR(B); }
1060 
1061 #define XORI(R)			       		       			    		\
1062 {			  													\
1063 	INT32 *rd = &R##REG(DSTREG);								\
1064 	CLR_Z;														\
1065 	*rd ^= PARAM_LONG();										\
1066 	SET_Z_VAL(*rd);												\
1067 	COUNT_CYCLES(3);											\
1068 }
xori_a(void)1069 static void xori_a(void) { XORI(A); }
xori_b(void)1070 static void xori_b(void) { XORI(B); }
1071 
1072 #define ZEXT(F,R)												\
1073 {																\
1074 	INT32 *rd = &R##REG(DSTREG);								\
1075 	CLR_Z;														\
1076 	ZEXTEND(*rd,FW(F));											\
1077 	SET_Z_VAL(*rd);												\
1078 	COUNT_CYCLES(1);											\
1079 }
zext0_a(void)1080 static void zext0_a(void) { ZEXT(0,A); }
zext0_b(void)1081 static void zext0_b(void) { ZEXT(0,B); }
zext1_a(void)1082 static void zext1_a(void) { ZEXT(1,A); }
zext1_b(void)1083 static void zext1_b(void) { ZEXT(1,B); }
1084 
1085 
1086 
1087 /***************************************************************************
1088     MOVE INSTRUCTIONS
1089 ***************************************************************************/
1090 
1091 #define MOVI_W(R)		       		       			    		\
1092 {			  													\
1093 	INT32 *rd = &R##REG(DSTREG);								\
1094 	CLR_NZV;													\
1095 	*rd=PARAM_WORD();											\
1096 	SET_NZ_VAL(*rd);											\
1097 	COUNT_CYCLES(2);											\
1098 }
movi_w_a(void)1099 static void movi_w_a(void) { MOVI_W(A); }
movi_w_b(void)1100 static void movi_w_b(void) { MOVI_W(B); }
1101 
1102 #define MOVI_L(R)		       		       			    		\
1103 {			  													\
1104 	INT32 *rd = &R##REG(DSTREG);								\
1105 	CLR_NZV;													\
1106 	*rd=PARAM_LONG();											\
1107 	SET_NZ_VAL(*rd);											\
1108 	COUNT_CYCLES(3);											\
1109 }
movi_l_a(void)1110 static void movi_l_a(void) { MOVI_L(A); }
movi_l_b(void)1111 static void movi_l_b(void) { MOVI_L(B); }
1112 
1113 #define MOVK(R)		       		       			    			\
1114 {																\
1115 	INT32 k = PARAM_K; if (!k) k = 32;							\
1116 	R##REG(DSTREG) = k;											\
1117 	COUNT_CYCLES(1);											\
1118 }
movk_a(void)1119 static void movk_a(void) { MOVK(A); }
movk_b(void)1120 static void movk_b(void) { MOVK(B); }
1121 
1122 #define MOVB_RN(R)		       		       			    		\
1123 {																\
1124 	WBYTE(R##REG(DSTREG),R##REG(SRCREG));						\
1125 	COUNT_CYCLES(1);											\
1126 }
movb_rn_a(void)1127 static void movb_rn_a(void) { MOVB_RN(A); }
movb_rn_b(void)1128 static void movb_rn_b(void) { MOVB_RN(B); }
1129 
1130 #define MOVB_NR(R)		       		       			    		\
1131 {			  													\
1132 	INT32 *rd = &R##REG(DSTREG);								\
1133 	CLR_NZV;													\
1134 	*rd = (INT8)RBYTE(R##REG(SRCREG));							\
1135 	SET_NZ_VAL(*rd);											\
1136 	COUNT_CYCLES(3);											\
1137 }
movb_nr_a(void)1138 static void movb_nr_a(void) { MOVB_NR(A); }
movb_nr_b(void)1139 static void movb_nr_b(void) { MOVB_NR(B); }
1140 
1141 #define MOVB_NN(R)												\
1142 {																\
1143 	WBYTE(R##REG(DSTREG),(UINT32)(UINT8)RBYTE(R##REG(SRCREG)));	\
1144 	COUNT_CYCLES(3);											\
1145 }
movb_nn_a(void)1146 static void movb_nn_a(void) { MOVB_NN(A); }
movb_nn_b(void)1147 static void movb_nn_b(void) { MOVB_NN(B); }
1148 
1149 #define MOVB_R_NO(R)	       		       			    		\
1150 {							  									\
1151 	INT32 o = PARAM_WORD();										\
1152 	WBYTE(R##REG(DSTREG)+o,R##REG(SRCREG));						\
1153 	COUNT_CYCLES(3);											\
1154 }
movb_r_no_a(void)1155 static void movb_r_no_a(void) { MOVB_R_NO(A); }
movb_r_no_b(void)1156 static void movb_r_no_b(void) { MOVB_R_NO(B); }
1157 
1158 #define MOVB_NO_R(R)	       		       			    		\
1159 {			  													\
1160 	INT32 *rd = &R##REG(DSTREG);								\
1161 	INT32 o = PARAM_WORD();										\
1162 	CLR_NZV;													\
1163 	*rd = (INT8)RBYTE(R##REG(SRCREG)+o);						\
1164 	SET_NZ_VAL(*rd);											\
1165 	COUNT_CYCLES(5);											\
1166 }
movb_no_r_a(void)1167 static void movb_no_r_a(void) { MOVB_NO_R(A); }
movb_no_r_b(void)1168 static void movb_no_r_b(void) { MOVB_NO_R(B); }
1169 
1170 #define MOVB_NO_NO(R)	       		       			    		\
1171 {																\
1172 	INT32 o1 = PARAM_WORD();									\
1173 	INT32 o2 = PARAM_WORD();									\
1174 	WBYTE(R##REG(DSTREG)+o2,(UINT32)(UINT8)RBYTE(R##REG(SRCREG)+o1));	\
1175 	COUNT_CYCLES(5);											\
1176 }
movb_no_no_a(void)1177 static void movb_no_no_a(void) { MOVB_NO_NO(A); }
movb_no_no_b(void)1178 static void movb_no_no_b(void) { MOVB_NO_NO(B); }
1179 
1180 #define MOVB_RA(R)	       		       			    			\
1181 {																\
1182 	WBYTE(PARAM_LONG(),R##REG(DSTREG));							\
1183 	COUNT_CYCLES(1);											\
1184 }
movb_ra_a(void)1185 static void movb_ra_a(void) { MOVB_RA(A); }
movb_ra_b(void)1186 static void movb_ra_b(void) { MOVB_RA(B); }
1187 
1188 #define MOVB_AR(R)	       		       			    			\
1189 {			  													\
1190 	INT32 *rd = &R##REG(DSTREG);								\
1191 	CLR_NZV;													\
1192 	*rd = (INT8)RBYTE(PARAM_LONG());							\
1193 	SET_NZ_VAL(*rd);											\
1194 	COUNT_CYCLES(5);											\
1195 }
movb_ar_a(void)1196 static void movb_ar_a(void) { MOVB_AR(A); }
movb_ar_b(void)1197 static void movb_ar_b(void) { MOVB_AR(B); }
1198 
movb_aa(void)1199 static void movb_aa(void)
1200 {
1201 	UINT32 bitaddrs=PARAM_LONG();
1202 	WBYTE(PARAM_LONG(),(UINT32)(UINT8)RBYTE(bitaddrs));
1203 	COUNT_CYCLES(6);
1204 }
1205 
1206 #define MOVE_RR(RS,RD)	       		       			    		\
1207 {																\
1208 	INT32 *rd = &RD##REG(DSTREG);								\
1209 	CLR_NZV;													\
1210 	*rd = RS##REG(SRCREG);										\
1211 	SET_NZ_VAL(*rd);											\
1212 	COUNT_CYCLES(1);											\
1213 }
move_rr_a(void)1214 static void move_rr_a (void) { MOVE_RR(A,A); }
move_rr_b(void)1215 static void move_rr_b (void) { MOVE_RR(B,B); }
move_rr_ax(void)1216 static void move_rr_ax(void) { MOVE_RR(A,B); }
move_rr_bx(void)1217 static void move_rr_bx(void) { MOVE_RR(B,A); }
1218 
1219 #define MOVE_RN(F,R)	       		       			    		\
1220 {																\
1221 	WFIELD##F(R##REG(DSTREG),R##REG(SRCREG));					\
1222 	COUNT_CYCLES(1);											\
1223 }
move0_rn_a(void)1224 static void move0_rn_a (void) { MOVE_RN(0,A); }
move0_rn_b(void)1225 static void move0_rn_b (void) { MOVE_RN(0,B); }
move1_rn_a(void)1226 static void move1_rn_a (void) { MOVE_RN(1,A); }
move1_rn_b(void)1227 static void move1_rn_b (void) { MOVE_RN(1,B); }
1228 
1229 #define MOVE_R_DN(F,R)	       		       			    		\
1230 {																\
1231 	INT32 *rd = &R##REG(DSTREG);								\
1232 	*rd-=fw_inc[FW(F)];											\
1233 	WFIELD##F(*rd,R##REG(SRCREG));								\
1234 	COUNT_CYCLES(2);											\
1235 }
move0_r_dn_a(void)1236 static void move0_r_dn_a (void) { MOVE_R_DN(0,A); }
move0_r_dn_b(void)1237 static void move0_r_dn_b (void) { MOVE_R_DN(0,B); }
move1_r_dn_a(void)1238 static void move1_r_dn_a (void) { MOVE_R_DN(1,A); }
move1_r_dn_b(void)1239 static void move1_r_dn_b (void) { MOVE_R_DN(1,B); }
1240 
1241 #define MOVE_R_NI(F,R)	       		       			    		\
1242 {			  													\
1243 	INT32 *rd = &R##REG(DSTREG);								\
1244     WFIELD##F(*rd,R##REG(SRCREG));								\
1245     *rd+=fw_inc[FW(F)];											\
1246 	COUNT_CYCLES(1);											\
1247 }
move0_r_ni_a(void)1248 static void move0_r_ni_a (void) { MOVE_R_NI(0,A); }
move0_r_ni_b(void)1249 static void move0_r_ni_b (void) { MOVE_R_NI(0,B); }
move1_r_ni_a(void)1250 static void move1_r_ni_a (void) { MOVE_R_NI(1,A); }
move1_r_ni_b(void)1251 static void move1_r_ni_b (void) { MOVE_R_NI(1,B); }
1252 
1253 #define MOVE_NR(F,R)	       		       			    		\
1254 {																\
1255 	INT32 *rd = &R##REG(DSTREG);								\
1256 	CLR_NZV;													\
1257 	*rd = RFIELD##F(R##REG(SRCREG));							\
1258 	SET_NZ_VAL(*rd);											\
1259 	COUNT_CYCLES(3);											\
1260 }
move0_nr_a(void)1261 static void move0_nr_a (void) { MOVE_NR(0,A); }
move0_nr_b(void)1262 static void move0_nr_b (void) { MOVE_NR(0,B); }
move1_nr_a(void)1263 static void move1_nr_a (void) { MOVE_NR(1,A); }
move1_nr_b(void)1264 static void move1_nr_b (void) { MOVE_NR(1,B); }
1265 
1266 #define MOVE_DN_R(F,R)	       		       			    		\
1267 {			  													\
1268 	INT32 *rd = &R##REG(DSTREG);								\
1269 	INT32 *rs = &R##REG(SRCREG);								\
1270 	CLR_NZV;													\
1271 	*rs-=fw_inc[FW(F)];											\
1272 	*rd = RFIELD##F(*rs);										\
1273 	SET_NZ_VAL(*rd);											\
1274 	COUNT_CYCLES(4);											\
1275 }
move0_dn_r_a(void)1276 static void move0_dn_r_a (void) { MOVE_DN_R(0,A); }
move0_dn_r_b(void)1277 static void move0_dn_r_b (void) { MOVE_DN_R(0,B); }
move1_dn_r_a(void)1278 static void move1_dn_r_a (void) { MOVE_DN_R(1,A); }
move1_dn_r_b(void)1279 static void move1_dn_r_b (void) { MOVE_DN_R(1,B); }
1280 
1281 #define MOVE_NI_R(F,R)	       		       			    		\
1282 {			  													\
1283 	INT32 *rd = &R##REG(DSTREG);								\
1284 	INT32 *rs = &R##REG(SRCREG);								\
1285 	INT32 data = RFIELD##F(*rs);								\
1286 	CLR_NZV;													\
1287 	*rs+=fw_inc[FW(F)];											\
1288 	*rd = data;													\
1289 	SET_NZ_VAL(*rd);											\
1290 	COUNT_CYCLES(3);											\
1291 }
move0_ni_r_a(void)1292 static void move0_ni_r_a (void) { MOVE_NI_R(0,A); }
move0_ni_r_b(void)1293 static void move0_ni_r_b (void) { MOVE_NI_R(0,B); }
move1_ni_r_a(void)1294 static void move1_ni_r_a (void) { MOVE_NI_R(1,A); }
move1_ni_r_b(void)1295 static void move1_ni_r_b (void) { MOVE_NI_R(1,B); }
1296 
1297 #define MOVE_NN(F,R)	       		       			    		\
1298 {										  						\
1299 	WFIELD##F(R##REG(DSTREG),RFIELD##F(R##REG(SRCREG)));		\
1300 	COUNT_CYCLES(3);											\
1301 }
move0_nn_a(void)1302 static void move0_nn_a (void) { MOVE_NN(0,A); }
move0_nn_b(void)1303 static void move0_nn_b (void) { MOVE_NN(0,B); }
move1_nn_a(void)1304 static void move1_nn_a (void) { MOVE_NN(1,A); }
move1_nn_b(void)1305 static void move1_nn_b (void) { MOVE_NN(1,B); }
1306 
1307 #define MOVE_DN_DN(F,R)	       		       			    		\
1308 {			  													\
1309 	INT32 *rd = &R##REG(DSTREG);								\
1310 	INT32 *rs = &R##REG(SRCREG);								\
1311 	INT32 data;													\
1312 	*rs-=fw_inc[FW(F)];											\
1313 	data = RFIELD##F(*rs);										\
1314 	*rd-=fw_inc[FW(F)];											\
1315 	WFIELD##F(*rd,data);										\
1316 	COUNT_CYCLES(4);											\
1317 }
move0_dn_dn_a(void)1318 static void move0_dn_dn_a (void) { MOVE_DN_DN(0,A); }
move0_dn_dn_b(void)1319 static void move0_dn_dn_b (void) { MOVE_DN_DN(0,B); }
move1_dn_dn_a(void)1320 static void move1_dn_dn_a (void) { MOVE_DN_DN(1,A); }
move1_dn_dn_b(void)1321 static void move1_dn_dn_b (void) { MOVE_DN_DN(1,B); }
1322 
1323 #define MOVE_NI_NI(F,R)	       		       			    		\
1324 {			  													\
1325 	INT32 *rd = &R##REG(DSTREG);								\
1326 	INT32 *rs = &R##REG(SRCREG);								\
1327 	INT32 data = RFIELD##F(*rs);								\
1328 	*rs+=fw_inc[FW(F)];											\
1329 	WFIELD##F(*rd,data);										\
1330 	*rd+=fw_inc[FW(F)];											\
1331 	COUNT_CYCLES(4);											\
1332 }
move0_ni_ni_a(void)1333 static void move0_ni_ni_a (void) { MOVE_NI_NI(0,A); }
move0_ni_ni_b(void)1334 static void move0_ni_ni_b (void) { MOVE_NI_NI(0,B); }
move1_ni_ni_a(void)1335 static void move1_ni_ni_a (void) { MOVE_NI_NI(1,A); }
move1_ni_ni_b(void)1336 static void move1_ni_ni_b (void) { MOVE_NI_NI(1,B); }
1337 
1338 #define MOVE_R_NO(F,R)	       		       			    		\
1339 {								  								\
1340 	INT32 o = PARAM_WORD();										\
1341 	WFIELD##F(R##REG(DSTREG)+o,R##REG(SRCREG));					\
1342 	COUNT_CYCLES(3);											\
1343 }
move0_r_no_a(void)1344 static void move0_r_no_a (void) { MOVE_R_NO(0,A); }
move0_r_no_b(void)1345 static void move0_r_no_b (void) { MOVE_R_NO(0,B); }
move1_r_no_a(void)1346 static void move1_r_no_a (void) { MOVE_R_NO(1,A); }
move1_r_no_b(void)1347 static void move1_r_no_b (void) { MOVE_R_NO(1,B); }
1348 
1349 #define MOVE_NO_R(F,R)	       		       			    		\
1350 {			  													\
1351 	INT32 *rd = &R##REG(DSTREG);								\
1352 	INT32 o = PARAM_WORD();										\
1353 	CLR_NZV;													\
1354 	*rd = RFIELD##F(R##REG(SRCREG)+o);							\
1355 	SET_NZ_VAL(*rd);											\
1356 	COUNT_CYCLES(5);											\
1357 }
move0_no_r_a(void)1358 static void move0_no_r_a (void) { MOVE_NO_R(0,A); }
move0_no_r_b(void)1359 static void move0_no_r_b (void) { MOVE_NO_R(0,B); }
move1_no_r_a(void)1360 static void move1_no_r_a (void) { MOVE_NO_R(1,A); }
move1_no_r_b(void)1361 static void move1_no_r_b (void) { MOVE_NO_R(1,B); }
1362 
1363 #define MOVE_NO_NI(F,R)	       		       			    		\
1364 {			  													\
1365 	INT32 *rd = &R##REG(DSTREG);								\
1366 	INT32 o = PARAM_WORD();										\
1367 	INT32 data = RFIELD##F(R##REG(SRCREG)+o);					\
1368 	WFIELD##F(*rd,data);										\
1369 	*rd+=fw_inc[FW(F)];											\
1370 	COUNT_CYCLES(5);											\
1371 }
move0_no_ni_a(void)1372 static void move0_no_ni_a (void) { MOVE_NO_NI(0,A); }
move0_no_ni_b(void)1373 static void move0_no_ni_b (void) { MOVE_NO_NI(0,B); }
move1_no_ni_a(void)1374 static void move1_no_ni_a (void) { MOVE_NO_NI(1,A); }
move1_no_ni_b(void)1375 static void move1_no_ni_b (void) { MOVE_NO_NI(1,B); }
1376 
1377 #define MOVE_NO_NO(F,R)	       		       			    		\
1378 {				 												\
1379 	INT32 o1 = PARAM_WORD();									\
1380 	INT32 o2 = PARAM_WORD();									\
1381 	INT32 data = RFIELD##F(R##REG(SRCREG)+o1);					\
1382 	WFIELD##F(R##REG(DSTREG)+o2,data);							\
1383 	COUNT_CYCLES(5);											\
1384 }
move0_no_no_a(void)1385 static void move0_no_no_a (void) { MOVE_NO_NO(0,A); }
move0_no_no_b(void)1386 static void move0_no_no_b (void) { MOVE_NO_NO(0,B); }
move1_no_no_a(void)1387 static void move1_no_no_a (void) { MOVE_NO_NO(1,A); }
move1_no_no_b(void)1388 static void move1_no_no_b (void) { MOVE_NO_NO(1,B); }
1389 
1390 #define MOVE_RA(F,R)	       		       			    		\
1391 {							  									\
1392 	WFIELD##F(PARAM_LONG(),R##REG(DSTREG));						\
1393 	COUNT_CYCLES(3);											\
1394 }
move0_ra_a(void)1395 static void move0_ra_a (void) { MOVE_RA(0,A); }
move0_ra_b(void)1396 static void move0_ra_b (void) { MOVE_RA(0,B); }
move1_ra_a(void)1397 static void move1_ra_a (void) { MOVE_RA(1,A); }
move1_ra_b(void)1398 static void move1_ra_b (void) { MOVE_RA(1,B); }
1399 
1400 #define MOVE_AR(F,R)	       		       			    		\
1401 {			  													\
1402 	INT32 *rd = &R##REG(DSTREG);								\
1403 	CLR_NZV;													\
1404 	*rd = RFIELD##F(PARAM_LONG());								\
1405 	SET_NZ_VAL(*rd);											\
1406 	COUNT_CYCLES(5);											\
1407 }
move0_ar_a(void)1408 static void move0_ar_a (void) { MOVE_AR(0,A); }
move0_ar_b(void)1409 static void move0_ar_b (void) { MOVE_AR(0,B); }
move1_ar_a(void)1410 static void move1_ar_a (void) { MOVE_AR(1,A); }
move1_ar_b(void)1411 static void move1_ar_b (void) { MOVE_AR(1,B); }
1412 
1413 #define MOVE_A_NI(F,R)	       		       			    		\
1414 {			  													\
1415 	INT32 *rd = &R##REG(DSTREG);								\
1416     WFIELD##F(*rd,RFIELD##F(PARAM_LONG()));						\
1417     *rd+=fw_inc[FW(F)];											\
1418 	COUNT_CYCLES(5);											\
1419 }
move0_a_ni_a(void)1420 static void move0_a_ni_a (void) { MOVE_A_NI(0,A); }
move0_a_ni_b(void)1421 static void move0_a_ni_b (void) { MOVE_A_NI(0,B); }
move1_a_ni_a(void)1422 static void move1_a_ni_a (void) { MOVE_A_NI(1,A); }
move1_a_ni_b(void)1423 static void move1_a_ni_b (void) { MOVE_A_NI(1,B); }
1424 
1425 #define MOVE_AA(F)		       		       			    		\
1426 {																\
1427 	UINT32 bitaddrs=PARAM_LONG();								\
1428 	WFIELD##F(PARAM_LONG(),RFIELD##F(bitaddrs));				\
1429 	COUNT_CYCLES(7);											\
1430 }
move0_aa(void)1431 static void move0_aa (void) { MOVE_AA(0); }
move1_aa(void)1432 static void move1_aa (void) { MOVE_AA(1); }
1433 
1434 
1435 
1436 /***************************************************************************
1437     PROGRAM CONTROL INSTRUCTIONS
1438 ***************************************************************************/
1439 
1440 #define CALL(R)													\
1441 {																\
1442 	PUSH(PC);													\
1443 	PC = R##REG(DSTREG);										\
1444 	CORRECT_ODD_PC("CALL");										\
1445 	change_pc(TOBYTE(PC));										\
1446 	COUNT_CYCLES(3);											\
1447 }
call_a(void)1448 static void call_a (void) { CALL(A); }
call_b(void)1449 static void call_b (void) { CALL(B); }
1450 
callr(void)1451 static void callr(void)
1452 {
1453 	PUSH(PC+0x10);
1454 	PC += (PARAM_WORD_NO_INC()<<4)+0x10;
1455 	COUNT_CYCLES(3);
1456 }
1457 
calla(void)1458 static void calla(void)
1459 {
1460 	PUSH(PC+0x20);
1461 	PC = PARAM_LONG_NO_INC();
1462 	CORRECT_ODD_PC("CALLA");
1463 	change_pc(TOBYTE(PC));
1464 	COUNT_CYCLES(4);
1465 }
1466 
1467 #define DSJ(R)													\
1468 {																\
1469 	if (--R##REG(DSTREG))										\
1470 	{															\
1471 		PC += (PARAM_WORD_NO_INC()<<4)+0x10;					\
1472 		COUNT_CYCLES(3);										\
1473 	}															\
1474 	else														\
1475 	{															\
1476 		SKIP_WORD;												\
1477 		COUNT_CYCLES(2);										\
1478 	}															\
1479 }
dsj_a(void)1480 static void dsj_a (void) { DSJ(A); }
dsj_b(void)1481 static void dsj_b (void) { DSJ(B); }
1482 
1483 #define DSJEQ(R)												\
1484 {																\
1485 	if (Z_FLAG)													\
1486 	{															\
1487 		if (--R##REG(DSTREG))									\
1488 		{														\
1489 			PC += (PARAM_WORD_NO_INC()<<4)+0x10;				\
1490 			COUNT_CYCLES(3);									\
1491 		}														\
1492 		else													\
1493 		{														\
1494 			SKIP_WORD;											\
1495 			COUNT_CYCLES(2);									\
1496 		}														\
1497 	}															\
1498 	else														\
1499 	{															\
1500 		SKIP_WORD;												\
1501 		COUNT_CYCLES(2);										\
1502 	}															\
1503 }
dsjeq_a(void)1504 static void dsjeq_a (void) { DSJEQ(A); }
dsjeq_b(void)1505 static void dsjeq_b (void) { DSJEQ(B); }
1506 
1507 #define DSJNE(R)												\
1508 {																\
1509 	if (!Z_FLAG)												\
1510 	{															\
1511 		if (--R##REG(DSTREG))									\
1512 		{														\
1513 			PC += (PARAM_WORD_NO_INC()<<4)+0x10;				\
1514 			COUNT_CYCLES(3);									\
1515 		}														\
1516 		else													\
1517 		{														\
1518 			SKIP_WORD;											\
1519 			COUNT_CYCLES(2);									\
1520 		}														\
1521 	}															\
1522 	else														\
1523 	{															\
1524 		SKIP_WORD;												\
1525 		COUNT_CYCLES(2);										\
1526 	}															\
1527 }
dsjne_a(void)1528 static void dsjne_a (void) { DSJNE(A); }
dsjne_b(void)1529 static void dsjne_b (void) { DSJNE(B); }
1530 
1531 #define DSJS(R)													\
1532 {									   							\
1533 	if (state.op & 0x0400)										\
1534 	{															\
1535 		if (--R##REG(DSTREG))									\
1536 		{														\
1537 			PC -= ((PARAM_K)<<4);								\
1538 			COUNT_CYCLES(2);									\
1539 		}														\
1540 		else													\
1541 			COUNT_CYCLES(3);									\
1542 	}															\
1543 	else														\
1544 	{															\
1545 		if (--R##REG(DSTREG))									\
1546 		{														\
1547 			PC += ((PARAM_K)<<4);								\
1548 			COUNT_CYCLES(2);									\
1549 		}														\
1550 		else													\
1551 			COUNT_CYCLES(3);									\
1552 	}															\
1553 }
dsjs_a(void)1554 static void dsjs_a (void) { DSJS(A); }
dsjs_b(void)1555 static void dsjs_b (void) { DSJS(B); }
1556 
emu(void)1557 static void emu(void)
1558 {
1559 	/* in RUN state, this instruction is a NOP */
1560 	COUNT_CYCLES(6);
1561 }
1562 
1563 #define EXGPC(R)												\
1564 {			  													\
1565 	INT32 *rd = &R##REG(DSTREG);								\
1566 	INT32 temppc = *rd;											\
1567 	*rd = PC;													\
1568 	PC = temppc;												\
1569 	CORRECT_ODD_PC("EXGPC");									\
1570 	change_pc(TOBYTE(PC));										\
1571 	COUNT_CYCLES(2);											\
1572 }
exgpc_a(void)1573 static void exgpc_a (void) { EXGPC(A); }
exgpc_b(void)1574 static void exgpc_b (void) { EXGPC(B); }
1575 
1576 #define GETPC(R)												\
1577 {																\
1578 	R##REG(DSTREG) = PC;										\
1579 	COUNT_CYCLES(1);											\
1580 }
getpc_a(void)1581 static void getpc_a (void) { GETPC(A); }
getpc_b(void)1582 static void getpc_b (void) { GETPC(B); }
1583 
1584 #define GETST(R)												\
1585 {			  													\
1586 	R##REG(DSTREG) = GET_ST();									\
1587 	COUNT_CYCLES(1);											\
1588 }
getst_a(void)1589 static void getst_a (void) { GETST(A); }
getst_b(void)1590 static void getst_b (void) { GETST(B); }
1591 
1592 #define j_xx_8(TAKE)			  								\
1593 {	   															\
1594 	if (DSTREG)													\
1595 	{															\
1596 		if (TAKE)												\
1597 		{														\
1598 			PC += (PARAM_REL8 << 4);							\
1599 			COUNT_CYCLES(2);									\
1600 		}														\
1601 		else													\
1602 			COUNT_CYCLES(1);									\
1603 	}															\
1604 	else														\
1605 	{															\
1606 		if (TAKE)												\
1607 		{														\
1608 			PC = PARAM_LONG_NO_INC();							\
1609 			CORRECT_ODD_PC("J_XX_8");							\
1610 			change_pc(TOBYTE(PC));								\
1611 			COUNT_CYCLES(3);									\
1612 		}														\
1613 		else													\
1614 		{														\
1615 			SKIP_LONG;											\
1616 			COUNT_CYCLES(4);									\
1617 		}														\
1618 	}															\
1619 }
1620 
1621 #define j_xx_0(TAKE)											\
1622 {																\
1623 	if (DSTREG)												\
1624 	{															\
1625 		if (TAKE)												\
1626 		{														\
1627 			PC += (PARAM_REL8 << 4);							\
1628 			COUNT_CYCLES(2);									\
1629 		}														\
1630 		else													\
1631 			COUNT_CYCLES(1);									\
1632 	}															\
1633 	else														\
1634 	{															\
1635 		if (TAKE)												\
1636 		{														\
1637 			PC += (PARAM_WORD_NO_INC()<<4)+0x10;				\
1638 			COUNT_CYCLES(3);									\
1639 		}														\
1640 		else													\
1641 		{														\
1642 			SKIP_WORD;											\
1643 			COUNT_CYCLES(2);									\
1644 		}														\
1645 	}															\
1646 }
1647 
1648 #define j_xx_x(TAKE)											\
1649 {																\
1650 	if (TAKE)													\
1651 	{															\
1652 		PC += (PARAM_REL8 << 4);								\
1653 		COUNT_CYCLES(2);										\
1654 	}															\
1655 	else														\
1656 		COUNT_CYCLES(1);										\
1657 }
1658 
j_UC_0(void)1659 static void j_UC_0(void)
1660 {
1661 	j_xx_0(1);
1662 }
j_UC_8(void)1663 static void j_UC_8(void)
1664 {
1665 	j_xx_8(1);
1666 }
j_UC_x(void)1667 static void j_UC_x(void)
1668 {
1669 	j_xx_x(1);
1670 }
j_P_0(void)1671 static void j_P_0(void)
1672 {
1673 	j_xx_0(!N_FLAG && !Z_FLAG);
1674 }
j_P_8(void)1675 static void j_P_8(void)
1676 {
1677 	j_xx_8(!N_FLAG && !Z_FLAG);
1678 }
j_P_x(void)1679 static void j_P_x(void)
1680 {
1681 	j_xx_x(!N_FLAG && !Z_FLAG);
1682 }
j_LS_0(void)1683 static void j_LS_0(void)
1684 {
1685 	j_xx_0(C_FLAG || Z_FLAG);
1686 }
j_LS_8(void)1687 static void j_LS_8(void)
1688 {
1689 	j_xx_8(C_FLAG || Z_FLAG);
1690 }
j_LS_x(void)1691 static void j_LS_x(void)
1692 {
1693 	j_xx_x(C_FLAG || Z_FLAG);
1694 }
j_HI_0(void)1695 static void j_HI_0(void)
1696 {
1697 	j_xx_0(!C_FLAG && !Z_FLAG);
1698 }
j_HI_8(void)1699 static void j_HI_8(void)
1700 {
1701 	j_xx_8(!C_FLAG && !Z_FLAG);
1702 }
j_HI_x(void)1703 static void j_HI_x(void)
1704 {
1705 	j_xx_x(!C_FLAG && !Z_FLAG);
1706 }
j_LT_0(void)1707 static void j_LT_0(void)
1708 {
1709 	j_xx_0((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
1710 }
j_LT_8(void)1711 static void j_LT_8(void)
1712 {
1713 	j_xx_8((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
1714 }
j_LT_x(void)1715 static void j_LT_x(void)
1716 {
1717 	j_xx_x((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
1718 }
j_GE_0(void)1719 static void j_GE_0(void)
1720 {
1721 	j_xx_0((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
1722 }
j_GE_8(void)1723 static void j_GE_8(void)
1724 {
1725 	j_xx_8((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
1726 }
j_GE_x(void)1727 static void j_GE_x(void)
1728 {
1729 	j_xx_x((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
1730 }
j_LE_0(void)1731 static void j_LE_0(void)
1732 {
1733 	j_xx_0((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || Z_FLAG);
1734 }
j_LE_8(void)1735 static void j_LE_8(void)
1736 {
1737 	j_xx_8((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || Z_FLAG);
1738 }
j_LE_x(void)1739 static void j_LE_x(void)
1740 {
1741 	j_xx_x((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || Z_FLAG);
1742 }
j_GT_0(void)1743 static void j_GT_0(void)
1744 {
1745 	j_xx_0((N_FLAG && V_FLAG && !Z_FLAG) || (!N_FLAG && !V_FLAG && !Z_FLAG));
1746 }
j_GT_8(void)1747 static void j_GT_8(void)
1748 {
1749 	j_xx_8((N_FLAG && V_FLAG && !Z_FLAG) || (!N_FLAG && !V_FLAG && !Z_FLAG));
1750 }
j_GT_x(void)1751 static void j_GT_x(void)
1752 {
1753 	j_xx_x((N_FLAG && V_FLAG && !Z_FLAG) || (!N_FLAG && !V_FLAG && !Z_FLAG));
1754 }
j_C_0(void)1755 static void j_C_0(void)
1756 {
1757 	j_xx_0(C_FLAG);
1758 }
j_C_8(void)1759 static void j_C_8(void)
1760 {
1761 	j_xx_8(C_FLAG);
1762 }
j_C_x(void)1763 static void j_C_x(void)
1764 {
1765 	j_xx_x(C_FLAG);
1766 }
j_NC_0(void)1767 static void j_NC_0(void)
1768 {
1769 	j_xx_0(!C_FLAG);
1770 }
j_NC_8(void)1771 static void j_NC_8(void)
1772 {
1773 	j_xx_8(!C_FLAG);
1774 }
j_NC_x(void)1775 static void j_NC_x(void)
1776 {
1777 	j_xx_x(!C_FLAG);
1778 }
j_EQ_0(void)1779 static void j_EQ_0(void)
1780 {
1781 	j_xx_0(Z_FLAG);
1782 }
j_EQ_8(void)1783 static void j_EQ_8(void)
1784 {
1785 	j_xx_8(Z_FLAG);
1786 }
j_EQ_x(void)1787 static void j_EQ_x(void)
1788 {
1789 	j_xx_x(Z_FLAG);
1790 }
j_NE_0(void)1791 static void j_NE_0(void)
1792 {
1793 	j_xx_0(!Z_FLAG);
1794 }
j_NE_8(void)1795 static void j_NE_8(void)
1796 {
1797 	j_xx_8(!Z_FLAG);
1798 }
j_NE_x(void)1799 static void j_NE_x(void)
1800 {
1801 	j_xx_x(!Z_FLAG);
1802 }
j_V_0(void)1803 static void j_V_0(void)
1804 {
1805 	j_xx_0(V_FLAG);
1806 }
j_V_8(void)1807 static void j_V_8(void)
1808 {
1809 	j_xx_8(V_FLAG);
1810 }
j_V_x(void)1811 static void j_V_x(void)
1812 {
1813 	j_xx_x(V_FLAG);
1814 }
j_NV_0(void)1815 static void j_NV_0(void)
1816 {
1817 	j_xx_0(!V_FLAG);
1818 }
j_NV_8(void)1819 static void j_NV_8(void)
1820 {
1821 	j_xx_8(!V_FLAG);
1822 }
j_NV_x(void)1823 static void j_NV_x(void)
1824 {
1825 	j_xx_x(!V_FLAG);
1826 }
j_N_0(void)1827 static void j_N_0(void)
1828 {
1829 	j_xx_0(N_FLAG);
1830 }
j_N_8(void)1831 static void j_N_8(void)
1832 {
1833 	j_xx_8(N_FLAG);
1834 }
j_N_x(void)1835 static void j_N_x(void)
1836 {
1837 	j_xx_x(N_FLAG);
1838 }
j_NN_0(void)1839 static void j_NN_0(void)
1840 {
1841 	j_xx_0(!N_FLAG);
1842 }
j_NN_8(void)1843 static void j_NN_8(void)
1844 {
1845 	j_xx_8(!N_FLAG);
1846 }
j_NN_x(void)1847 static void j_NN_x(void)
1848 {
1849 	j_xx_x(!N_FLAG);
1850 }
1851 
1852 #define JUMP(R)													\
1853 {																\
1854 	PC = R##REG(DSTREG);										\
1855 	CORRECT_ODD_PC("JUMP");										\
1856 	change_pc(TOBYTE(PC));										\
1857 	COUNT_CYCLES(2);											\
1858 }
jump_a(void)1859 static void jump_a (void) { JUMP(A); }
jump_b(void)1860 static void jump_b (void) { JUMP(B); }
1861 
popst(void)1862 static void popst(void)
1863 {
1864 	SET_ST(POP());
1865 	COUNT_CYCLES(8);
1866 }
1867 
pushst(void)1868 static void pushst(void)
1869 {
1870 	PUSH(GET_ST());
1871 	COUNT_CYCLES(2);
1872 }
1873 
1874 #define PUTST(R)												\
1875 {																\
1876 	SET_ST(R##REG(DSTREG));										\
1877 	COUNT_CYCLES(3);											\
1878 }
putst_a(void)1879 static void putst_a (void) { PUTST(A); }
putst_b(void)1880 static void putst_b (void) { PUTST(B); }
1881 
reti(void)1882 static void reti(void)
1883 {
1884 	INT32 st = POP();
1885 	PC = POP();
1886 	CORRECT_ODD_PC("RETI");
1887 	change_pc(TOBYTE(PC));
1888 	SET_ST(st);
1889 	COUNT_CYCLES(11);
1890 }
1891 
rets(void)1892 static void rets(void)
1893 {
1894 	UINT32 offs;
1895 	PC = POP();
1896 	CORRECT_ODD_PC("RETS");
1897 	change_pc(TOBYTE(PC));
1898 	offs = PARAM_N;
1899 	if (offs)
1900 	{
1901 		SP+=(offs<<4);
1902 	}
1903 	COUNT_CYCLES(7);
1904 }
1905 
1906 #define REV(R)													\
1907 {																\
1908     R##REG(DSTREG) = 0x0008;									\
1909 	COUNT_CYCLES(1);											\
1910 }
rev_a(void)1911 static void rev_a (void) { REV(A); }
rev_b(void)1912 static void rev_b (void) { REV(B); }
1913 
trap(void)1914 static void trap(void)
1915 {
1916 	UINT32 t = PARAM_N;
1917 	if (t)
1918 	{
1919 		PUSH(PC);
1920 		PUSH(GET_ST());
1921 	}
1922 	RESET_ST();
1923 	PC = RLONG(0xffffffe0-(t<<5));
1924 	CORRECT_ODD_PC("TRAP");
1925 	change_pc(TOBYTE(PC));
1926 	COUNT_CYCLES(16);
1927 }
1928 
1929 
1930 
1931 /***************************************************************************
1932     34020 INSTRUCTIONS
1933 ***************************************************************************/
1934 
1935 /************************************
1936 
1937 New 34020 ops:
1938 
1939     0000 1100 000R dddd = ADDXYI IL,Rd
1940     iiii iiii iiii iiii
1941     iiii iiii iiii iiii
1942 
1943     0000 0000 1111 00SD = BLMOVE S,D
1944 
1945     0000 0110 0000 0000 = CEXEC S,c,ID,L
1946     cccc cccc S000 0000
1947     iiic cccc cccc cccc
1948 
1949     1101 1000 0ccc cccS = CEXEC S,c,ID
1950     iiic cccc cccc cccc
1951 
1952     0000 1000 1111 0010 = CLIP
1953 
1954     0000 0110 011R dddd = CMOVCG Rd1,Rd2,S,c,ID
1955     cccc cccc S00R dddd
1956     iiic cccc cccc cccc
1957 
1958     0000 0110 101R dddd = CMOVCM *Rd+,n,S,c,ID
1959     cccc cccc S00n nnnn
1960     iiic cccc cccc cccc
1961 
1962     0000 0110 110R dddd = CMOVCM -*Rd,n,S,c,ID
1963     cccc cccc S00n nnnn
1964     iiic cccc cccc cccc
1965 
1966     0000 0110 0110 0000 = CMOVCS c,ID
1967     cccc cccc 0000 0001
1968     iiic cccc cccc cccc
1969 
1970     0000 0110 001R ssss = CMOVGC Rs,c,ID
1971     cccc cccc 0000 0000
1972     iiic cccc cccc cccc
1973 
1974     0000 0110 010R ssss = CMOVGC Rs1,Rs2,S,c,ID
1975     cccc cccc S00R ssss
1976     iiic cccc cccc cccc
1977 
1978     0000 0110 100n nnnn = CMOVMC *Rs+,n,S,c,ID
1979     cccc cccc S00R ssss
1980     iiic cccc cccc cccc
1981 
1982     0000 1000 001n nnnn = CMOVMC -*Rs,n,S,c,ID
1983     cccc cccc S00R ssss
1984     iiic cccc cccc cccc
1985 
1986     0000 0110 111R dddd = CMOVMC *Rs+,Rd,S,c,ID
1987     cccc cccc S00R ssss
1988     iiic cccc cccc cccc
1989 
1990     0011 01kk kkkR dddd = CMPK k,Rd
1991 
1992     0000 1010 100R dddd = CVDXYL Rd
1993 
1994     0000 1010 011R dddd = CVMXYL Rd
1995 
1996     1110 101s sssR dddd = CVSXYL Rs,Rd
1997 
1998     0000 0010 101R dddd = EXGPS Rd
1999 
2000     1101 1110 Z001 1010 = FLINE Z
2001 
2002     0000 1010 1011 1011 = FPIXEQ
2003 
2004     0000 1010 1101 1011 = FPIXNE
2005 
2006     0000 0010 110R dddd = GETPS Rd
2007 
2008     0000 0000 0100 0000 = IDLE
2009 
2010     0000 1100 0101 0111 = LINIT
2011 
2012     0000 0000 1000 0000 = MWAIT
2013 
2014     0000 1010 0011 0111 = PFILL XY
2015 
2016     0000 1110 0001 0111 = PIXBLT L,M,L
2017 
2018     0000 1000 0110 0000 = RETM
2019 
2020     0111 101s sssR dddd = RMO Rs,Rd
2021 
2022     0000 0010 100R dddd = RPIX Rd
2023 
2024     0000 0010 0111 0011 = SETCDP
2025 
2026     0000 0010 1111 1011 = SETCMP
2027 
2028     0000 0010 0101 0001 = SETCSP
2029 
2030     0111 111s sssR dddd = SWAPF *Rs,Rd,0
2031 
2032     0000 1110 1111 1010 = TFILL XY
2033 
2034     0000 1000 0000 1111 = TRAPL
2035 
2036     0000 1000 0101 0111 = VBLT B,L
2037 
2038     0000 1010 0101 0111 = VFILL L
2039 
2040     0000 1010 0000 0000 = VLCOL
2041 
2042 ************************************/
2043 
2044 
2045 #define ADD_XYI(R)								\
2046 {												\
2047 	UINT32 a = PARAM_LONG();					\
2048 	XY *b = &R##REG_XY(DSTREG);					\
2049 	CLR_NCZV;									\
2050 	b->x += (INT16)(a & 0xffff);				\
2051 	b->y += ((INT32)a >> 16);					\
2052 	SET_N_LOG(b->x == 0);						\
2053 	SET_C_BIT_LO(b->y, 15);						\
2054 	SET_Z_LOG(b->y == 0);						\
2055 	SET_V_BIT_LO(b->x, 15);						\
2056   	COUNT_CYCLES(1);							\
2057 }
addxyi_a(void)2058 static void addxyi_a(void)
2059 {
2060 	if (!state.is_34020) { unimpl(); return; }
2061 	ADD_XYI(A);
2062 }
addxyi_b(void)2063 static void addxyi_b(void)
2064 {
2065 	if (!state.is_34020) { unimpl(); return; }
2066 	ADD_XYI(B);
2067 }
2068 
blmove(void)2069 static void blmove(void)
2070 {
2071 	offs_t src = BREG(0);
2072 	offs_t dst = BREG(2);
2073 	offs_t bits = BREG(7);
2074 
2075 	if (!state.is_34020) { unimpl(); return; }
2076 
2077 	/* src and dst are aligned */
2078 	if (!(src & 0x0f) && !(dst & 0x0f))
2079 	{
2080 		while (bits >= 16 && tms34010_ICount > 0)
2081 		{
2082 			TMS34010_WRMEM_WORD(TOBYTE(dst), TMS34010_RDMEM_WORD(TOBYTE(src)));
2083 			src += 0x10;
2084 			dst += 0x10;
2085 			bits -= 0x10;
2086 			//tms34010_ICount -= 2;
2087 			COUNT_CYCLES(2);
2088 		}
2089 		if (bits != 0 && tms34010_ICount > 0)
2090 		{
2091 			(*tms34010_wfield_functions[bits])(dst, (*tms34010_rfield_functions[bits])(src));
2092 			dst += bits;
2093 			src += bits;
2094 			bits = 0;
2095 			//tms34010_ICount -= 2;
2096 			COUNT_CYCLES(2);
2097 		}
2098 	}
2099 
2100 	/* src is aligned, dst is not */
2101 	else if (!(src & 0x0f))
2102 	{
2103 		logerror("020:BLMOVE with aligned src and unaligned dst\n");
2104 	}
2105 
2106 	/* dst is aligned, src is not */
2107 	else if (!(dst & 0x0f))
2108 	{
2109 		logerror("020:BLMOVE with unaligned src and aligned dst\n");
2110 	}
2111 
2112 	/* neither are aligned */
2113 	else
2114 	{
2115 		logerror("020:BLMOVE with completely unaligned src and dst\n");
2116 	}
2117 
2118 	/* update the final results */
2119 	BREG(0) = src;
2120 	BREG(2) = dst;
2121 	BREG(7) = bits;
2122 
2123 	/* if we're not done yet, back up the PC */
2124 	if (bits != 0)
2125 		PC -= 0x10;
2126 }
2127 
cexec_l(void)2128 static void cexec_l(void)
2129 {
2130 	if (!state.is_34020) { unimpl(); return; }
2131 	logerror("020:cexec_l\n");
2132 }
2133 
cexec_s(void)2134 static void cexec_s(void)
2135 {
2136 	if (!state.is_34020) { unimpl(); return; }
2137 	logerror("020:cexec_s\n");
2138 }
2139 
clip(void)2140 static void clip(void)
2141 {
2142 	if (!state.is_34020) { unimpl(); return; }
2143 	logerror("020:clip\n");
2144 }
2145 
cmovcg_a(void)2146 static void cmovcg_a(void)
2147 {
2148 	if (!state.is_34020) { unimpl(); return; }
2149 	logerror("020:cmovcg_a\n");
2150 }
2151 
cmovcg_b(void)2152 static void cmovcg_b(void)
2153 {
2154 	if (!state.is_34020) { unimpl(); return; }
2155 	logerror("020:cmovcg_b\n");
2156 }
2157 
cmovcm_f(void)2158 static void cmovcm_f(void)
2159 {
2160 	if (!state.is_34020) { unimpl(); return; }
2161 	logerror("020:cmovcm_f\n");
2162 }
2163 
cmovcm_b(void)2164 static void cmovcm_b(void)
2165 {
2166 	if (!state.is_34020) { unimpl(); return; }
2167 	logerror("020:cmovcm_b\n");
2168 }
2169 
cmovgc_a(void)2170 static void cmovgc_a(void)
2171 {
2172 	if (!state.is_34020) { unimpl(); return; }
2173 	logerror("020:cmovgc_a\n");
2174 }
2175 
cmovgc_b(void)2176 static void cmovgc_b(void)
2177 {
2178 	if (!state.is_34020) { unimpl(); return; }
2179 	logerror("020:cmovgc_b\n");
2180 }
2181 
cmovgc_a_s(void)2182 static void cmovgc_a_s(void)
2183 {
2184 	if (!state.is_34020) { unimpl(); return; }
2185 	logerror("020:cmovgc_a_s\n");
2186 }
2187 
cmovgc_b_s(void)2188 static void cmovgc_b_s(void)
2189 {
2190 	if (!state.is_34020) { unimpl(); return; }
2191 	logerror("020:cmovgc_b_s\n");
2192 }
2193 
cmovmc_f(void)2194 static void cmovmc_f(void)
2195 {
2196 	if (!state.is_34020) { unimpl(); return; }
2197 	logerror("020:cmovmc_f\n");
2198 }
2199 
cmovmc_f_va(void)2200 static void cmovmc_f_va(void)
2201 {
2202 	if (!state.is_34020) { unimpl(); return; }
2203 	logerror("020:cmovmc_f_va\n");
2204 }
2205 
cmovmc_f_vb(void)2206 static void cmovmc_f_vb(void)
2207 {
2208 	if (!state.is_34020) { unimpl(); return; }
2209 	logerror("020:cmovmc_f_vb\n");
2210 }
2211 
cmovmc_b(void)2212 static void cmovmc_b(void)
2213 {
2214 	if (!state.is_34020) { unimpl(); return; }
2215 	logerror("020:cmovmc_b\n");
2216 }
2217 
2218 #define CMPK(R)				       		       			    \
2219 {															\
2220 	INT32 r;												\
2221 	INT32 *rd = &R##REG(DSTREG);							\
2222 	INT32 t = PARAM_K; if (!t) t = 32;						\
2223 	CLR_NCZV;												\
2224 	r = *rd - t;											\
2225 	SET_NZCV_SUB(*rd,t,r);									\
2226 	COUNT_CYCLES(1);										\
2227 }
cmp_k_a(void)2228 static void cmp_k_a(void)
2229 {
2230 	if (!state.is_34020) { unimpl(); return; }
2231 	CMPK(A);
2232 }
cmp_k_b(void)2233 static void cmp_k_b(void)
2234 {
2235 	if (!state.is_34020) { unimpl(); return; }
2236 	CMPK(B);
2237 }
2238 
cvdxyl_a(void)2239 static void cvdxyl_a(void)
2240 {
2241 	if (!state.is_34020) { unimpl(); return; }
2242 	logerror("020:cvdxyl_a\n");
2243 }
2244 
cvdxyl_b(void)2245 static void cvdxyl_b(void)
2246 {
2247 	if (!state.is_34020) { unimpl(); return; }
2248 	logerror("020:cvdxyl_b\n");
2249 }
2250 
cvmxyl_a(void)2251 static void cvmxyl_a(void)
2252 {
2253 	if (!state.is_34020) { unimpl(); return; }
2254 	logerror("020:cvmxyl_a\n");
2255 }
2256 
cvmxyl_b(void)2257 static void cvmxyl_b(void)
2258 {
2259 	if (!state.is_34020) { unimpl(); return; }
2260 	logerror("020:cvmxyl_b\n");
2261 }
2262 
cvsxyl_a(void)2263 static void cvsxyl_a(void)
2264 {
2265 	if (!state.is_34020) { unimpl(); return; }
2266 	logerror("020:cvsxyl_a\n");
2267 }
2268 
cvsxyl_b(void)2269 static void cvsxyl_b(void)
2270 {
2271 	if (!state.is_34020) { unimpl(); return; }
2272 	logerror("020:cvsxyl_b\n");
2273 }
2274 
exgps_a(void)2275 static void exgps_a(void)
2276 {
2277 	if (!state.is_34020) { unimpl(); return; }
2278 	logerror("020:exgps_a\n");
2279 }
2280 
exgps_b(void)2281 static void exgps_b(void)
2282 {
2283 	if (!state.is_34020) { unimpl(); return; }
2284 	logerror("020:exgps_b\n");
2285 }
2286 
fline(void)2287 static void fline(void)
2288 {
2289 	if (!state.is_34020) { unimpl(); return; }
2290 	logerror("020:fline\n");
2291 }
2292 
fpixeq(void)2293 static void fpixeq(void)
2294 {
2295 	if (!state.is_34020) { unimpl(); return; }
2296 	logerror("020:fpixeq\n");
2297 }
2298 
fpixne(void)2299 static void fpixne(void)
2300 {
2301 	if (!state.is_34020) { unimpl(); return; }
2302 	logerror("020:fpixne\n");
2303 }
2304 
getps_a(void)2305 static void getps_a(void)
2306 {
2307 	if (!state.is_34020) { unimpl(); return; }
2308 	logerror("020:getps_a\n");
2309 }
2310 
getps_b(void)2311 static void getps_b(void)
2312 {
2313 	if (!state.is_34020) { unimpl(); return; }
2314 	logerror("020:getps_b\n");
2315 }
2316 
idle(void)2317 static void idle(void)
2318 {
2319 	if (!state.is_34020) { unimpl(); return; }
2320 	logerror("020:idle\n");
2321 }
2322 
linit(void)2323 static void linit(void)
2324 {
2325 	if (!state.is_34020) { unimpl(); return; }
2326 	logerror("020:linit\n");
2327 }
2328 
mwait(void)2329 static void mwait(void)
2330 {
2331 	if (!state.is_34020) { unimpl(); return; }
2332 }
2333 
pfill_xy(void)2334 static void pfill_xy(void)
2335 {
2336 	if (!state.is_34020) { unimpl(); return; }
2337 	logerror("020:pfill_xy\n");
2338 }
2339 
pixblt_l_m_l(void)2340 static void pixblt_l_m_l(void)
2341 {
2342 	if (!state.is_34020) { unimpl(); return; }
2343 	logerror("020:pixblt_l_m_l\n");
2344 }
2345 
retm(void)2346 static void retm(void)
2347 {
2348 	if (!state.is_34020) { unimpl(); return; }
2349 	logerror("020:retm\n");
2350 }
2351 
2352 #define RMO(R)			       		       			    		\
2353 {																\
2354 	UINT32 res = 0;												\
2355 	UINT32 rs  = R##REG(SRCREG);								\
2356 	 INT32 *rd = &R##REG(DSTREG);								\
2357 	CLR_Z;														\
2358 	SET_Z_VAL(rs);												\
2359 	if (rs)														\
2360 	{															\
2361 		while (!(rs & 0x00000001))								\
2362 		{														\
2363 			res++;												\
2364 			rs >>= 1;											\
2365 		}														\
2366 	}															\
2367 	*rd = res;													\
2368 	COUNT_CYCLES(1);											\
2369 }
2370 
rmo_a(void)2371 static void rmo_a(void) { RMO(A); }
rmo_b(void)2372 static void rmo_b(void) { RMO(B); }
2373 
2374 #define RPIX(R)									\
2375 {												\
2376 	UINT32 v = R##REG(DSTREG);					\
2377 	switch (state.pixelshift)					\
2378 	{											\
2379 		case 0:									\
2380 			v = (v & 1) ? 0xffffffff : 0x00000000;\
2381 		  	COUNT_CYCLES(8);					\
2382 		  	break;								\
2383 		case 1:									\
2384 			v &= 3;								\
2385 			v |= v << 2;						\
2386 			v |= v << 4;						\
2387 			v |= v << 8;						\
2388 			v |= v << 16;						\
2389 			COUNT_CYCLES(7);					\
2390 			break;								\
2391 		case 2:									\
2392 			v &= 0x0f;							\
2393 			v |= v << 4;						\
2394 			v |= v << 8;						\
2395 			v |= v << 16;						\
2396 			COUNT_CYCLES(6);					\
2397 			break;								\
2398 		case 3:									\
2399 			v &= 0xff;							\
2400 			v |= v << 8;						\
2401 			v |= v << 16;						\
2402 			COUNT_CYCLES(5);					\
2403 			break;								\
2404 		case 4:									\
2405 			v &= 0xffff;						\
2406 			v |= v << 16;						\
2407 			COUNT_CYCLES(4);					\
2408 			break;								\
2409 		case 5:									\
2410 			COUNT_CYCLES(2);					\
2411 			break;								\
2412 	}											\
2413 	R##REG(DSTREG) = v;							\
2414 }
2415 
rpix_a(void)2416 static void rpix_a(void)
2417 {
2418 	if (!state.is_34020) { unimpl(); return; }
2419 	RPIX(A);
2420 }
2421 
rpix_b(void)2422 static void rpix_b(void)
2423 {
2424 	if (!state.is_34020) { unimpl(); return; }
2425 	RPIX(B);
2426 }
2427 
setcdp(void)2428 static void setcdp(void)
2429 {
2430 	if (!state.is_34020) { unimpl(); return; }
2431 	logerror("020:setcdp\n");
2432 }
2433 
setcmp(void)2434 static void setcmp(void)
2435 {
2436 	if (!state.is_34020) { unimpl(); return; }
2437 	logerror("020:setcmp\n");
2438 }
2439 
setcsp(void)2440 static void setcsp(void)
2441 {
2442 	if (!state.is_34020) { unimpl(); return; }
2443 	logerror("020:setcsp\n");
2444 }
2445 
swapf_a(void)2446 static void swapf_a(void)
2447 {
2448 	if (!state.is_34020) { unimpl(); return; }
2449 	logerror("020:swapf_a\n");
2450 }
2451 
swapf_b(void)2452 static void swapf_b(void)
2453 {
2454 	if (!state.is_34020) { unimpl(); return; }
2455 	logerror("020:swapf_b\n");
2456 }
2457 
tfill_xy(void)2458 static void tfill_xy(void)
2459 {
2460 	if (!state.is_34020) { unimpl(); return; }
2461 	logerror("020:tfill_xy\n");
2462 }
2463 
trapl(void)2464 static void trapl(void)
2465 {
2466 	if (!state.is_34020) { unimpl(); return; }
2467 	logerror("020:trapl\n");
2468 }
2469 
vblt_b_l(void)2470 static void vblt_b_l(void)
2471 {
2472 	if (!state.is_34020) { unimpl(); return; }
2473 	logerror("020:vblt_b_l\n");
2474 }
2475 
vfill_l(void)2476 static void vfill_l(void)
2477 {
2478 	if (!state.is_34020) { unimpl(); return; }
2479 	logerror("020:vfill_l\n");
2480 }
2481 
vlcol(void)2482 static void vlcol(void)
2483 {
2484 	if (!state.is_34020) { unimpl(); return; }
2485 	logerror("020:vlcol\n");
2486 }
2487