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