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