1 // license:BSD-3-Clause
2 // copyright-holders:Zsolt Vasvari
3 /*
4 * A TMS34010 disassembler
5 *
6 * This code written by Zsolt Vasvari for the MAME project
7 *
8 */
9
10 #include "emu.h"
11 #include "34010dsm.h"
12
r16(offs_t & pos,const data_buffer & opcodes)13 uint16_t tms34010_disassembler::r16(offs_t &pos, const data_buffer &opcodes)
14 {
15 uint16_t r = opcodes.r16(pos);
16 pos += 16;
17 return r;
18 }
19
r32(offs_t & pos,const data_buffer & opcodes)20 uint32_t tms34010_disassembler::r32(offs_t &pos, const data_buffer &opcodes)
21 {
22 uint32_t r = opcodes.r32(pos);
23 pos += 32;
24 return r;
25 }
26
print_reg(std::ostream & stream,uint8_t reg)27 void tms34010_disassembler::print_reg(std::ostream &stream, uint8_t reg)
28 {
29 if (reg != 0x0f)
30 {
31 util::stream_format(stream, "%c%d", rf, reg);
32 }
33 else
34 {
35 stream << "SP";
36 }
37 }
38
print_src_reg(std::ostream & stream)39 void tms34010_disassembler::print_src_reg(std::ostream &stream)
40 {
41 print_reg(stream, rs);
42 }
43
print_des_reg(std::ostream & stream)44 void tms34010_disassembler::print_des_reg(std::ostream &stream)
45 {
46 print_reg(stream, rd);
47 }
48
print_src_des_reg(std::ostream & stream)49 void tms34010_disassembler::print_src_des_reg(std::ostream &stream)
50 {
51 print_src_reg(stream);
52 stream << ",";
53 print_des_reg(stream);
54 }
55
print_word_parm(std::ostream & stream,offs_t & pos,const data_buffer & params)56 void tms34010_disassembler::print_word_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms)
57 {
58 util::stream_format(stream, "%Xh", r16(pos, params));
59 }
60
print_word_parm_1s_comp(std::ostream & stream,offs_t & pos,const data_buffer & params)61 void tms34010_disassembler::print_word_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms)
62 {
63 util::stream_format(stream, "%Xh", u16(~r16(pos, params)));
64 }
65
print_long_parm(std::ostream & stream,offs_t & pos,const data_buffer & params)66 void tms34010_disassembler::print_long_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms)
67 {
68 util::stream_format(stream, "%Xh", r32(pos, params));
69 }
70
print_long_parm_1s_comp(std::ostream & stream,offs_t & pos,const data_buffer & params)71 void tms34010_disassembler::print_long_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms)
72 {
73 util::stream_format(stream, "%Xh", u32(~r32(pos, params)));
74 }
75
print_constant(std::ostream & stream)76 void tms34010_disassembler::print_constant(std::ostream &stream)
77 {
78 uint8_t constant = (op >> 5) & 0x1f;
79
80 util::stream_format(stream, "%Xh", constant);
81 }
82
print_constant_1_32(std::ostream & stream)83 void tms34010_disassembler::print_constant_1_32(std::ostream &stream)
84 {
85 uint8_t constant = (op >> 5) & 0x1f;
86 if (!constant) constant = 0x20;
87
88 util::stream_format(stream, "%Xh", constant);
89 }
90
print_constant_1s_comp(std::ostream & stream)91 void tms34010_disassembler::print_constant_1s_comp(std::ostream &stream)
92 {
93 uint8_t constant = (~op >> 5) & 0x1f;
94
95 util::stream_format(stream, "%Xh", constant);
96 }
97
print_constant_2s_comp(std::ostream & stream)98 void tms34010_disassembler::print_constant_2s_comp(std::ostream &stream)
99 {
100 uint8_t constant = 32 - ((op >> 5) & 0x1f);
101
102 util::stream_format(stream, "%Xh", constant);
103 }
104
print_relative(std::ostream & stream,offs_t pc,offs_t & pos,const data_buffer & params)105 void tms34010_disassembler::print_relative(std::ostream &stream, offs_t pc, offs_t &pos, const data_buffer ¶ms)
106 {
107 int16_t ls = (int16_t)r16(pos, params);
108
109 util::stream_format(stream, "%Xh", pc + 32 + (ls << 4));
110 }
111
print_relative_8bit(std::ostream & stream,offs_t pc)112 void tms34010_disassembler::print_relative_8bit(std::ostream &stream, offs_t pc)
113 {
114 int8_t ls = (int8_t)op;
115
116 util::stream_format(stream, "%Xh", pc + 16 + (ls << 4));
117 }
118
print_relative_5bit(std::ostream & stream,offs_t pc)119 void tms34010_disassembler::print_relative_5bit(std::ostream &stream, offs_t pc)
120 {
121 int8_t ls = (int8_t)((op >> 5) & 0x1f);
122 if (op & 0x0400) ls = -ls;
123
124 util::stream_format(stream, "%Xh", pc + 16 + (ls << 4));
125 }
126
print_field(std::ostream & stream)127 void tms34010_disassembler::print_field(std::ostream &stream)
128 {
129 util::stream_format(stream, "%c", (op & 0x200) ? '1' : '0');
130 }
131
print_condition_code(std::ostream & stream)132 void tms34010_disassembler::print_condition_code(std::ostream &stream)
133 {
134 switch (op & 0x0f00)
135 {
136 case 0x0000: stream << " "; break; /* This is really UC (Unconditional) */
137 case 0x0100: stream << "P "; break;
138 case 0x0200: stream << "LS"; break;
139 case 0x0300: stream << "HI"; break;
140 case 0x0400: stream << "LT"; break;
141 case 0x0500: stream << "GE"; break;
142 case 0x0600: stream << "LE"; break;
143 case 0x0700: stream << "GT"; break;
144 case 0x0800: stream << "C "; break;
145 case 0x0900: stream << "NC"; break;
146 case 0x0a00: stream << "EQ"; break;
147 case 0x0b00: stream << "NE"; break;
148 case 0x0c00: stream << "V "; break;
149 case 0x0d00: stream << "NV"; break;
150 case 0x0e00: stream << "N "; break;
151 case 0x0f00: stream << "NN"; break;
152 }
153 }
154
print_reg_list_range(std::ostream & stream,int8_t first,int8_t last)155 void tms34010_disassembler::print_reg_list_range(std::ostream &stream, int8_t first, int8_t last)
156 {
157 if ((first != -1 ) && (first != last))
158 {
159 if ((last - first) == 1)
160 stream << ",";
161 else
162 stream << "-";
163 print_reg(stream, last);
164 }
165 }
166
print_reg_list(std::ostream & stream,uint16_t rev,offs_t & pos,const data_buffer & params)167 void tms34010_disassembler::print_reg_list(std::ostream &stream, uint16_t rev, offs_t &pos, const data_buffer ¶ms)
168 {
169 uint8_t i;
170 int8_t first = -1, last = 0;
171
172 uint16_t l = r16(pos, params);
173
174 for (i = 0; i < 16; i++)
175 {
176 int moved;
177
178 if (rev)
179 {
180 moved = l & 0x8000;
181 l <<= 1;
182 }
183 else
184 {
185 moved = l & 0x01;
186 l >>= 1;
187 }
188
189 if (moved)
190 {
191 if (first == -1)
192 {
193 stream << ",";
194 print_reg(stream, i);
195 first = i;
196 }
197 last = i;
198 }
199 else
200 {
201 print_reg_list_range(stream, first, last);
202 first = -1;
203 }
204 }
205
206 print_reg_list_range(stream, first, last);
207 }
208
209
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)210 offs_t tms34010_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
211 {
212 int flags = 0;
213 uint8_t bad = 0;
214 uint16_t subop;
215 offs_t pos = pc;
216
217 op = r16(pos, opcodes);
218
219 subop = (op & 0x01e0);
220 rs = (op >> 5) & 0x0f; /* Source register */
221 rd = op & 0x0f; /* Destination register */
222 rf = ((op & 0x10) ? 'B' : 'A'); /* Register file */
223
224 switch (op & 0xfe00)
225 {
226 case 0x0000:
227 switch (subop)
228 {
229 case 0x0020:
230 util::stream_format(stream, "REV ");
231 print_des_reg(stream);
232 break;
233
234 case 0x0040:
235 if (m_is_34020)
236 util::stream_format(stream, "IDLE ");
237 else
238 bad = 1;
239 break;
240
241 case 0x0080:
242 if (m_is_34020)
243 util::stream_format(stream, "MWAIT ");
244 else
245 bad = 1;
246 break;
247
248 case 0x00e0:
249 if (m_is_34020)
250 util::stream_format(stream, "BLMOVE %d,%d", (op >> 1) & 1, op & 1);
251 else
252 bad = 1;
253 break;
254
255 case 0x0100:
256 util::stream_format(stream, "EMU ");
257 break;
258
259 case 0x0120:
260 util::stream_format(stream, "EXGPC ");
261 print_des_reg(stream);
262 break;
263
264 case 0x0140:
265 util::stream_format(stream, "GETPC ");
266 print_des_reg(stream);
267 break;
268
269 case 0x0160:
270 util::stream_format(stream, "JUMP ");
271 print_des_reg(stream);
272 break;
273
274 case 0x0180:
275 util::stream_format(stream, "GETST ");
276 print_des_reg(stream);
277 break;
278
279 case 0x01a0:
280 util::stream_format(stream, "PUTST ");
281 print_des_reg(stream);
282 break;
283
284 case 0x01c0:
285 util::stream_format(stream, "POPST ");
286 break;
287
288 case 0x01e0:
289 util::stream_format(stream, "PUSHST ");
290 break;
291
292 default:
293 bad = 1;
294 }
295 break;
296
297
298 case 0x0200:
299 switch (subop)
300 {
301 case 0x0040:
302 if (m_is_34020)
303 util::stream_format(stream, "SETCSP ");
304 else
305 bad = 1;
306 break;
307
308 case 0x0060:
309 if (m_is_34020)
310 util::stream_format(stream, "SETCDP ");
311 else
312 bad = 1;
313 break;
314
315 case 0x0080:
316 if (m_is_34020)
317 {
318 util::stream_format(stream, "RPIX ");
319 print_des_reg(stream);
320 }
321 else
322 bad = 1;
323 break;
324
325 case 0x00a0:
326 if (m_is_34020)
327 {
328 util::stream_format(stream, "EXGPS ");
329 print_des_reg(stream);
330 }
331 else
332 bad = 1;
333 break;
334
335 case 0x00c0:
336 if (m_is_34020)
337 {
338 util::stream_format(stream, "GETPS ");
339 print_des_reg(stream);
340 }
341 else
342 bad = 1;
343 break;
344
345 case 0x00e0:
346 if (m_is_34020)
347 util::stream_format(stream, "SETCMP ");
348 else
349 bad = 1;
350 break;
351
352 case 0x0100:
353 util::stream_format(stream, "NOP ");
354 break;
355
356 case 0x0120:
357 util::stream_format(stream, "CLRC ");
358 break;
359
360 case 0x0140:
361 util::stream_format(stream, "MOVB @");
362 print_long_parm(stream, pos, params);
363 stream << ",@";
364 print_long_parm(stream, pos, params);
365 break;
366
367 case 0x0160:
368 util::stream_format(stream, "DINT ");
369 break;
370
371 case 0x0180:
372 util::stream_format(stream, "ABS ");
373 print_des_reg(stream);
374 break;
375
376 case 0x01a0:
377 util::stream_format(stream, "NEG ");
378 print_des_reg(stream);
379 break;
380
381 case 0x01c0:
382 util::stream_format(stream, "NEGB ");
383 print_des_reg(stream);
384 break;
385
386 case 0x01e0:
387 util::stream_format(stream, "NOT ");
388 print_des_reg(stream);
389 break;
390
391 default:
392 bad = 1;
393 }
394 break;
395
396
397 case 0x0400:
398 case 0x0600:
399 switch (subop)
400 {
401 case 0x0000:
402 if (m_is_34020 && (op & 0xfe00) == 0x0600)
403 {
404 uint32_t x = r32(pos, params);
405 util::stream_format(stream, "CEXEC %d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
406 }
407 else
408 bad = 1;
409 break;
410
411 case 0x0020:
412 if (m_is_34020 && (op & 0xfe00) == 0x0600)
413 {
414 uint32_t x = r32(pos, params);
415 util::stream_format(stream, "CMOVGC ");
416 print_des_reg(stream);
417 util::stream_format(stream, ",%06X,%d", (x >> 8) & 0x1fffff, (x >> 29) & 7);
418 }
419 else
420 bad = 1;
421 break;
422
423 case 0x0040:
424 if (m_is_34020 && (op & 0xfe00) == 0x0600)
425 {
426 uint32_t x = r32(pos, params);
427 util::stream_format(stream, "CMOVGC ");
428 print_des_reg(stream);
429 stream << ",";
430 rf = (x & 0x10) ? 'B' : 'A';
431 print_reg(stream, x & 0x0f);
432 util::stream_format(stream, ",%d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
433 }
434 else
435 bad = 1;
436 break;
437
438 case 0x0060:
439 if (m_is_34020 && (op & 0xfe00) == 0x0600)
440 {
441 uint32_t x = r32(pos, params);
442
443 if (op == 0x0660 && (x & 0xff) == 0x01)
444 {
445 util::stream_format(stream, "CMOVCS ");
446 util::stream_format(stream, ",%06X,%d", (x >> 8) & 0x1fffff, (x >> 29) & 7);
447 }
448 else
449 {
450 util::stream_format(stream, "CMOVCG ");
451 print_des_reg(stream);
452 stream << ",";
453 rf = (x & 0x10) ? 'B' : 'A';
454 print_reg(stream, x & 0x0f);
455 util::stream_format(stream, ",%d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
456 }
457 }
458 else
459 bad = 1;
460 break;
461
462 case 0x0080:
463 if (m_is_34020 && (op & 0xfe00) == 0x0600)
464 {
465 uint32_t x = r32(pos, params);
466 util::stream_format(stream, "CMOVMC *");
467 rf = (x & 0x10) ? 'B' : 'A';
468 print_reg(stream, x & 0x0f);
469 util::stream_format(stream, "+,%d,%d,%06X,%d", op & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
470 }
471 else
472 bad = 1;
473 break;
474
475 case 0x00a0:
476 if (m_is_34020 && (op & 0xfe00) == 0x0600)
477 {
478 uint32_t x = r32(pos, params);
479 util::stream_format(stream, "CMOVCM *");
480 print_des_reg(stream);
481 util::stream_format(stream, "+,%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
482 }
483 else
484 bad = 1;
485 break;
486
487 case 0x00c0:
488 if (m_is_34020 && (op & 0xfe00) == 0x0600)
489 {
490 uint32_t x = r32(pos, params);
491 util::stream_format(stream, "CMOVCM *-");
492 print_des_reg(stream);
493 util::stream_format(stream, ",%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
494 }
495 else
496 bad = 1;
497 break;
498
499 case 0x00e0:
500 if (m_is_34020 && (op & 0xfe00) == 0x0600)
501 {
502 uint32_t x = r32(pos, params);
503 util::stream_format(stream, "CMOVMC *");
504 rf = (x & 0x10) ? 'B' : 'A';
505 print_reg(stream, x & 0x0f);
506 stream << "+,";
507 rf = (op & 0x10) ? 'B' : 'A';
508 print_reg(stream, op & 0x0f);
509 util::stream_format(stream, ",%d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
510 }
511 else
512 bad = 1;
513 break;
514
515 case 0x0100:
516 util::stream_format(stream, "SEXT ");
517 print_des_reg(stream);
518 stream << ",";
519 print_field(stream);
520 break;
521
522 case 0x0120:
523 util::stream_format(stream, "ZEXT ");
524 print_des_reg(stream);
525 stream << ",";
526 print_field(stream);
527 break;
528
529 case 0x0140:
530 case 0x0160:
531 util::stream_format(stream, "SETF %Xh,%X,",
532 (op & 0x1f) ? op & 0x1f : 0x20,
533 (op >> 5) & 1);
534 print_field(stream);
535 break;
536
537 case 0x0180:
538 util::stream_format(stream, "MOVE ");
539 print_des_reg(stream);
540 stream << ",@";
541 print_long_parm(stream, pos, params);
542 stream << ",";
543 print_field(stream);
544 break;
545
546 case 0x01a0:
547 util::stream_format(stream, "MOVE @");
548 print_long_parm(stream, pos, params);
549 stream << ",";
550 print_des_reg(stream);
551 stream << ",";
552 print_field(stream);
553 break;
554
555 case 0x01c0:
556 util::stream_format(stream, "MOVE @");
557 print_long_parm(stream, pos, params);
558 stream << ",@";
559 print_long_parm(stream, pos, params);
560 stream << ",";
561 print_field(stream);
562 break;
563
564 case 0x01e0:
565 if (op & 0x200)
566 {
567 util::stream_format(stream, "MOVE @");
568 print_long_parm(stream, pos, params);
569 stream << ",";
570 print_des_reg(stream);
571 }
572 else
573 {
574 util::stream_format(stream, "MOVB ");
575 print_des_reg(stream);
576 stream << ",@";
577 print_long_parm(stream, pos, params);
578 }
579 break;
580
581 default:
582 bad = 1;
583 }
584 break;
585
586
587 case 0x0800:
588 switch (subop)
589 {
590 case 0x0000:
591 if (m_is_34020)
592 {
593 util::stream_format(stream, "TRAPL ");
594 flags = STEP_OVER;
595 }
596 else
597 bad = 1;
598 break;
599
600 case 0x0020:
601 if (m_is_34020)
602 {
603 uint32_t x = r32(pos, params);
604 util::stream_format(stream, "CMOVMC *-");
605 rf = (x & 0x10) ? 'B' : 'A';
606 print_reg(stream, x & 0x0f);
607 util::stream_format(stream, ",%d,%d,%06X,%d", op & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7);
608 }
609 else
610 bad = 1;
611 break;
612
613 case 0x0040:
614 if (m_is_34020)
615 util::stream_format(stream, "VBLT B,L");
616 else
617 bad = 1;
618 break;
619
620 case 0x0060:
621 if (m_is_34020)
622 {
623 util::stream_format(stream, "RETM ");
624 flags = STEP_OUT;
625 }
626 else
627 bad = 1;
628 break;
629
630 case 0x00e0:
631 if (m_is_34020)
632 util::stream_format(stream, "CLIP ");
633 else
634 bad = 1;
635 break;
636
637 case 0x0100:
638 util::stream_format(stream, "TRAP %Xh", op & 0x1f);
639 flags = STEP_OVER;
640 break;
641
642 case 0x0120:
643 util::stream_format(stream, "CALL ");
644 print_des_reg(stream);
645 flags = STEP_OVER;
646 break;
647
648 case 0x0140:
649 util::stream_format(stream, "RETI ");
650 flags = STEP_OUT;
651 break;
652
653 case 0x0160:
654 util::stream_format(stream, "RETS ");
655 flags = STEP_OUT;
656 if (op & 0x1f)
657 {
658 util::stream_format(stream, "%Xh", op & 0x1f);
659 }
660 break;
661
662 case 0x0180:
663 util::stream_format(stream, "MMTM ");
664 print_des_reg(stream);
665 print_reg_list(stream, 1, pos, params);
666 break;
667
668 case 0x01a0:
669 util::stream_format(stream, "MMFM ");
670 print_des_reg(stream);
671 print_reg_list(stream, 0, pos, params);
672 break;
673
674 case 0x01c0:
675 util::stream_format(stream, "MOVI ");
676 print_word_parm(stream, pos, params);
677 stream << ",";
678 print_des_reg(stream);
679 break;
680
681 case 0x01e0:
682 util::stream_format(stream, "MOVI ");
683 print_long_parm(stream, pos, params);
684 stream << ",";
685 print_des_reg(stream);
686 break;
687
688 default:
689 bad = 1;
690 }
691 break;
692
693
694 case 0x0a00:
695 switch (subop)
696 {
697 case 0x0000:
698 if (m_is_34020)
699 util::stream_format(stream, "VLCOL ");
700 else
701 bad = 1;
702 break;
703
704 case 0x0020:
705 if (m_is_34020)
706 util::stream_format(stream, "PFILL XY");
707 else
708 bad = 1;
709 break;
710
711 case 0x0040:
712 if (m_is_34020)
713 util::stream_format(stream, "VFILL L");
714 else
715 bad = 1;
716 break;
717
718 case 0x0060:
719 if (m_is_34020)
720 {
721 util::stream_format(stream, "CVMXYL ");
722 print_des_reg(stream);
723 }
724 else
725 bad = 1;
726 break;
727
728 case 0x0080:
729 if (m_is_34020)
730 {
731 util::stream_format(stream, "CVDXYL ");
732 print_des_reg(stream);
733 }
734 else
735 bad = 1;
736 break;
737
738 case 0x00a0:
739 if (m_is_34020)
740 util::stream_format(stream, "FPIXEQ ");
741 else
742 bad = 1;
743 break;
744
745 case 0x00c0:
746 if (m_is_34020)
747 util::stream_format(stream, "FPIXNE ");
748 else
749 bad = 1;
750 break;
751
752 case 0x0100:
753 util::stream_format(stream, "ADDI ");
754 print_word_parm(stream, pos, params);
755 stream << ",";
756 print_des_reg(stream);
757 break;
758
759 case 0x0120:
760 util::stream_format(stream, "ADDI ");
761 print_long_parm(stream, pos, params);
762 stream << ",";
763 print_des_reg(stream);
764 break;
765
766 case 0x0140:
767 util::stream_format(stream, "CMPI ");
768 print_word_parm_1s_comp(stream, pos, params);
769 stream << ",";
770 print_des_reg(stream);
771 break;
772
773 case 0x0160:
774 util::stream_format(stream, "CMPI ");
775 print_long_parm_1s_comp(stream, pos, params);
776 stream << ",";
777 print_des_reg(stream);
778 break;
779
780 case 0x0180:
781 util::stream_format(stream, "ANDI ");
782 print_long_parm_1s_comp(stream, pos, params);
783 stream << ",";
784 print_des_reg(stream);
785 break;
786
787 case 0x01a0:
788 util::stream_format(stream, "ORI ");
789 print_long_parm(stream, pos, params);
790 stream << ",";
791 print_des_reg(stream);
792 break;
793
794 case 0x01c0:
795 util::stream_format(stream, "XORI ");
796 print_long_parm(stream, pos, params);
797 stream << ",";
798 print_des_reg(stream);
799 break;
800
801 case 0x01e0:
802 util::stream_format(stream, "SUBI ");
803 print_word_parm_1s_comp(stream, pos, params);
804 stream << ",";
805 print_des_reg(stream);
806 break;
807
808 default:
809 bad = 1;
810 }
811 break;
812
813
814 case 0x0c00:
815 switch (subop)
816 {
817 case 0x0000:
818 if (m_is_34020)
819 {
820 util::stream_format(stream, "ADDXYI ");
821 print_long_parm(stream, pos, params);
822 stream << ",";
823 print_des_reg(stream);
824 }
825 else
826 bad = 1;
827 break;
828
829 case 0x0040:
830 if (m_is_34020)
831 util::stream_format(stream, "LINIT ");
832 else
833 bad = 1;
834 break;
835
836 case 0x0100:
837 util::stream_format(stream, "SUBI ");
838 print_long_parm_1s_comp(stream, pos, params);
839 stream << ",";
840 print_des_reg(stream);
841 break;
842
843 case 0x0120:
844 util::stream_format(stream, "CALLR ");
845 print_relative(stream, pc, pos, params);
846 flags = STEP_OVER;
847 break;
848
849 case 0x0140:
850 util::stream_format(stream, "CALLA ");
851 print_long_parm(stream, pos, params);
852 flags = STEP_OVER;
853 break;
854
855 case 0x0160:
856 util::stream_format(stream, "EINT ");
857 break;
858
859 case 0x0180:
860 util::stream_format(stream, "DSJ ");
861 print_des_reg(stream);
862 stream << ",";
863 print_relative(stream, pc, pos, params);
864 flags = STEP_OVER;
865 break;
866
867 case 0x01a0:
868 util::stream_format(stream, "DSJEQ ");
869 print_des_reg(stream);
870 stream << ",";
871 print_relative(stream, pc, pos, params);
872 flags = STEP_OVER;
873 break;
874
875 case 0x01c0:
876 util::stream_format(stream, "DSJNE ");
877 print_des_reg(stream);
878 stream << ",";
879 print_relative(stream, pc, pos, params);
880 flags = STEP_OVER;
881 break;
882
883 case 0x01e0:
884 util::stream_format(stream, "SETC ");
885 break;
886
887 default:
888 bad = 1;
889 }
890 break;
891
892
893 case 0x0e00:
894 flags = STEP_OVER;
895 switch (subop)
896 {
897 case 0x0000:
898 if (m_is_34020)
899 util::stream_format(stream, "PIXBLT L,M,L");
900 else
901 bad = 1;
902 break;
903
904 case 0x00e0:
905 if (m_is_34020)
906 util::stream_format(stream, "TFILL XY");
907 else
908 bad = 1;
909 break;
910
911 case 0x0100:
912 util::stream_format(stream, "PIXBLT L,L");
913 break;
914
915 case 0x0120:
916 util::stream_format(stream, "PIXBLT L,XY");
917 break;
918
919 case 0x0140:
920 util::stream_format(stream, "PIXBLT XY,L");
921 break;
922
923 case 0x0160:
924 util::stream_format(stream, "PIXBLT XY,XY");
925 break;
926
927 case 0x0180:
928 util::stream_format(stream, "PIXBLT B,L");
929 break;
930
931 case 0x01a0:
932 util::stream_format(stream, "PIXBLT B,XY");
933 break;
934
935 case 0x01c0:
936 util::stream_format(stream, "FILL L");
937 break;
938
939 case 0x01e0:
940 util::stream_format(stream, "FILL XY");
941 break;
942
943 default:
944 bad = 1;
945 }
946 break;
947
948
949 case 0x1000:
950 case 0x1200:
951 if ((op & 0x03e0) != 0x0020)
952 {
953 util::stream_format(stream, "ADDK ");
954 print_constant_1_32(stream);
955 stream << ",";
956 }
957 else
958 {
959 util::stream_format(stream, "INC ");
960 }
961 print_des_reg(stream);
962
963 break;
964
965
966 case 0x1400:
967 case 0x1600:
968 if ((op & 0x03e0) != 0x0020)
969 {
970 util::stream_format(stream, "SUBK ");
971 print_constant_1_32(stream);
972 stream << ",";
973 }
974 else
975 {
976 util::stream_format(stream, "DEC ");
977 }
978 print_des_reg(stream);
979
980 break;
981
982
983 case 0x1800:
984 case 0x1a00:
985 util::stream_format(stream, "MOVK ");
986 print_constant_1_32(stream);
987 stream << ",";
988 print_des_reg(stream);
989 break;
990
991
992 case 0x1c00:
993 case 0x1e00:
994 util::stream_format(stream, "BTST ");
995 print_constant_1s_comp(stream);
996 stream << ",";
997 print_des_reg(stream);
998 break;
999
1000
1001 case 0x2000:
1002 case 0x2200:
1003 util::stream_format(stream, "SLA ");
1004 print_constant(stream);
1005 stream << ",";
1006 print_des_reg(stream);
1007 break;
1008
1009
1010 case 0x2400:
1011 case 0x2600:
1012 util::stream_format(stream, "SLL ");
1013 print_constant(stream);
1014 stream << ",";
1015 print_des_reg(stream);
1016 break;
1017
1018
1019 case 0x2800:
1020 case 0x2a00:
1021 util::stream_format(stream, "SRA ");
1022 print_constant_2s_comp(stream);
1023 stream << ",";
1024 print_des_reg(stream);
1025 break;
1026
1027
1028 case 0x2c00:
1029 case 0x2e00:
1030 util::stream_format(stream, "SRL ");
1031 print_constant_2s_comp(stream);
1032 stream << ",";
1033 print_des_reg(stream);
1034 break;
1035
1036
1037 case 0x3000:
1038 case 0x3200:
1039 util::stream_format(stream, "RL ");
1040 print_constant(stream);
1041 stream << ",";
1042 print_des_reg(stream);
1043 break;
1044
1045 case 0x3400:
1046 case 0x3600:
1047 if (m_is_34020)
1048 {
1049 util::stream_format(stream, "CMPK ");
1050 print_constant_1_32(stream);
1051 stream << ",";
1052 print_des_reg(stream);
1053 }
1054 else
1055 bad = 1;
1056 break;
1057
1058 case 0x3800:
1059 case 0x3a00:
1060 case 0x3c00:
1061 case 0x3e00:
1062 util::stream_format(stream, "DSJS ");
1063 print_des_reg(stream);
1064 stream << ",";
1065 print_relative_5bit(stream, pc);
1066 flags = STEP_OVER;
1067 break;
1068
1069
1070 case 0x4000:
1071 util::stream_format(stream, "ADD ");
1072 print_src_des_reg(stream);
1073 break;
1074
1075
1076 case 0x4200:
1077 util::stream_format(stream, "ADDC ");
1078 print_src_des_reg(stream);
1079 break;
1080
1081
1082 case 0x4400:
1083 util::stream_format(stream, "SUB ");
1084 print_src_des_reg(stream);
1085 break;
1086
1087
1088 case 0x4600:
1089 util::stream_format(stream, "SUBB ");
1090 print_src_des_reg(stream);
1091 break;
1092
1093
1094 case 0x4800:
1095 util::stream_format(stream, "CMP ");
1096 print_src_des_reg(stream);
1097 break;
1098
1099
1100 case 0x4a00:
1101 util::stream_format(stream, "BTST ");
1102 print_src_des_reg(stream);
1103 break;
1104
1105
1106 case 0x4c00:
1107 case 0x4e00:
1108 util::stream_format(stream, "MOVE ");
1109
1110 if (!(op & 0x0200))
1111 {
1112 print_src_des_reg(stream);
1113 }
1114 else
1115 {
1116 print_src_reg(stream);
1117 stream << ",";
1118
1119 if (rf == 'A')
1120 {
1121 rf = 'B';
1122 }
1123 else
1124 {
1125 rf = 'A';
1126 }
1127
1128 print_des_reg(stream);
1129 }
1130 break;
1131
1132
1133 case 0x5000:
1134 util::stream_format(stream, "AND ");
1135 print_src_des_reg(stream);
1136 break;
1137
1138
1139 case 0x5200:
1140 util::stream_format(stream, "ANDN ");
1141 print_src_des_reg(stream);
1142 break;
1143
1144
1145 case 0x5400:
1146 util::stream_format(stream, "OR ");
1147 print_src_des_reg(stream);
1148 break;
1149
1150
1151 case 0x5600:
1152 if (rs != rd)
1153 {
1154 util::stream_format(stream, "XOR ");
1155 print_src_des_reg(stream);
1156 }
1157 else
1158 {
1159 util::stream_format(stream, "CLR ");
1160 print_des_reg(stream);
1161 }
1162 break;
1163
1164
1165 case 0x5800:
1166 util::stream_format(stream, "DIVS ");
1167 print_src_des_reg(stream);
1168 break;
1169
1170
1171 case 0x5a00:
1172 util::stream_format(stream, "DIVU ");
1173 print_src_des_reg(stream);
1174 break;
1175
1176
1177 case 0x5c00:
1178 util::stream_format(stream, "MPYS ");
1179 print_src_des_reg(stream);
1180 break;
1181
1182
1183 case 0x5e00:
1184 util::stream_format(stream, "MPYU ");
1185 print_src_des_reg(stream);
1186 break;
1187
1188
1189 case 0x6000:
1190 util::stream_format(stream, "SLA ");
1191 print_src_des_reg(stream);
1192 break;
1193
1194
1195 case 0x6200:
1196 util::stream_format(stream, "SLL ");
1197 print_src_des_reg(stream);
1198 break;
1199
1200
1201 case 0x6400:
1202 util::stream_format(stream, "SRA ");
1203 print_src_des_reg(stream);
1204 break;
1205
1206
1207 case 0x6600:
1208 util::stream_format(stream, "SRL ");
1209 print_src_des_reg(stream);
1210 break;
1211
1212
1213 case 0x6800:
1214 util::stream_format(stream, "RL ");
1215 print_src_des_reg(stream);
1216 break;
1217
1218
1219 case 0x6a00:
1220 util::stream_format(stream, "LMO ");
1221 print_src_des_reg(stream);
1222 break;
1223
1224
1225 case 0x6c00:
1226 util::stream_format(stream, "MODS ");
1227 print_src_des_reg(stream);
1228 break;
1229
1230
1231 case 0x6e00:
1232 util::stream_format(stream, "MODU ");
1233 print_src_des_reg(stream);
1234 break;
1235
1236
1237 case 0x7a00:
1238 if (m_is_34020)
1239 {
1240 util::stream_format(stream, "RMO ");
1241 print_src_des_reg(stream);
1242 }
1243 else
1244 bad = 1;
1245 break;
1246
1247 case 0x7e00:
1248 if (m_is_34020)
1249 {
1250 util::stream_format(stream, "SWAPF *");
1251 print_src_des_reg(stream);
1252 stream << ",0";
1253 }
1254 else
1255 bad = 1;
1256 break;
1257
1258
1259 case 0x8000:
1260 case 0x8200:
1261 util::stream_format(stream, "MOVE ");
1262 print_src_reg(stream);
1263 stream << ",*";
1264 print_des_reg(stream);
1265 stream << ",";
1266 print_field(stream);
1267 break;
1268
1269
1270 case 0x8400:
1271 case 0x8600:
1272 util::stream_format(stream, "MOVE *");
1273 print_src_des_reg(stream);
1274 stream << ",";
1275 print_field(stream);
1276 break;
1277
1278
1279 case 0x8800:
1280 case 0x8a00:
1281 util::stream_format(stream, "MOVE *");
1282 print_src_reg(stream);
1283 stream << ",*";
1284 print_des_reg(stream);
1285 stream << ",";
1286 print_field(stream);
1287 break;
1288
1289
1290 case 0x8c00:
1291 util::stream_format(stream, "MOVB ");
1292 print_src_reg(stream);
1293 stream << ",*";
1294 print_des_reg(stream);
1295 break;
1296
1297
1298 case 0x8e00:
1299 util::stream_format(stream, "MOVB *");
1300 print_src_des_reg(stream);
1301 break;
1302
1303
1304 case 0x9000:
1305 case 0x9200:
1306 util::stream_format(stream, "MOVE ");
1307 print_src_reg(stream);
1308 stream << ",*";
1309 print_des_reg(stream);
1310 stream << "+,";
1311 print_field(stream);
1312 break;
1313
1314
1315 case 0x9400:
1316 case 0x9600:
1317 util::stream_format(stream, "MOVE *");
1318 print_src_reg(stream);
1319 stream << "+,";
1320 print_des_reg(stream);
1321 stream << ",";
1322 print_field(stream);
1323 break;
1324
1325
1326 case 0x9800:
1327 case 0x9a00:
1328 util::stream_format(stream, "MOVE *");
1329 print_src_reg(stream);
1330 stream << "+,*";
1331 print_des_reg(stream);
1332 stream << "+,";
1333 print_field(stream);
1334 break;
1335
1336
1337 case 0x9c00:
1338 util::stream_format(stream, "MOVB *");
1339 print_src_reg(stream);
1340 stream << ",*";
1341 print_des_reg(stream);
1342 break;
1343
1344
1345 case 0xa000:
1346 case 0xa200:
1347 util::stream_format(stream, "MOVE ");
1348 print_src_reg(stream);
1349 stream << ",-*";
1350 print_des_reg(stream);
1351 stream << ",";
1352 print_field(stream);
1353 break;
1354
1355
1356 case 0xa400:
1357 case 0xa600:
1358 util::stream_format(stream, "MOVE -*");
1359 print_src_des_reg(stream);
1360 stream << ",";
1361 print_field(stream);
1362 break;
1363
1364
1365 case 0xa800:
1366 case 0xaa00:
1367 util::stream_format(stream, "MOVE -*");
1368 print_src_reg(stream);
1369 stream << ",-*";
1370 print_des_reg(stream);
1371 stream << ",";
1372 print_field(stream);
1373 break;
1374
1375
1376 case 0xac00:
1377 util::stream_format(stream, "MOVB ");
1378 print_src_reg(stream);
1379 stream << ",*";
1380 print_des_reg(stream);
1381 stream << "(";
1382 print_word_parm(stream, pos, params);
1383 stream << ")";
1384 break;
1385
1386
1387 case 0xae00:
1388 util::stream_format(stream, "MOVB *");
1389 print_src_reg(stream);
1390 stream << "(";
1391 print_word_parm(stream, pos, params);
1392 stream << "),";
1393 print_des_reg(stream);
1394 break;
1395
1396
1397 case 0xb000:
1398 case 0xb200:
1399 util::stream_format(stream, "MOVE ");
1400 print_src_reg(stream);
1401 stream << ",*";
1402 print_des_reg(stream);
1403 stream << "(";
1404 print_word_parm(stream, pos, params);
1405 stream << "),";
1406 print_field(stream);
1407 break;
1408
1409
1410 case 0xb400:
1411 case 0xb600:
1412 util::stream_format(stream, "MOVE *");
1413 print_src_reg(stream);
1414 stream << "(";
1415 print_word_parm(stream, pos, params);
1416 stream << "),";
1417 print_des_reg(stream);
1418 stream << ",";
1419 print_field(stream);
1420 break;
1421
1422
1423 case 0xb800:
1424 case 0xba00:
1425 util::stream_format(stream, "MOVE *");
1426 print_src_reg(stream);
1427 stream << "(";
1428 print_word_parm(stream, pos, params);
1429 stream << "),*";
1430 print_des_reg(stream);
1431 stream << "(";
1432 print_word_parm(stream, pos, params);
1433 stream << "),";
1434 print_field(stream);
1435 break;
1436
1437
1438 case 0xbc00:
1439 util::stream_format(stream, "MOVB *");
1440 print_src_reg(stream);
1441 stream << "(";
1442 print_word_parm(stream, pos, params);
1443 stream << "),*";
1444 print_des_reg(stream);
1445 stream << "(";
1446 print_word_parm(stream, pos, params);
1447 stream << ")";
1448 break;
1449
1450
1451 case 0xc000:
1452 case 0xc200:
1453 case 0xc400:
1454 case 0xc600:
1455 case 0xc800:
1456 case 0xca00:
1457 case 0xcc00:
1458 case 0xce00:
1459 if ((op & 0x00ff) == 0x80)
1460 {
1461 util::stream_format(stream, "JA");
1462 }
1463 else
1464 {
1465 util::stream_format(stream, "JR");
1466 }
1467
1468 print_condition_code(stream);
1469 stream << " ";
1470
1471 switch (op & 0x00ff)
1472 {
1473 case 0x00:
1474 print_relative(stream, pc, pos, params);
1475 break;
1476
1477 case 0x80:
1478 print_long_parm(stream, pos, params);
1479 break;
1480
1481 default:
1482 print_relative_8bit(stream, pc);
1483 }
1484 break;
1485
1486
1487 case 0xd000:
1488 case 0xd200:
1489 util::stream_format(stream, "MOVE *");
1490 print_src_reg(stream);
1491 stream << "(";
1492 print_word_parm(stream, pos, params);
1493 stream << "),*";
1494 print_des_reg(stream);
1495 stream << "+,";
1496 print_field(stream);
1497 break;
1498
1499
1500 case 0xd400:
1501 case 0xd600:
1502 switch (subop)
1503 {
1504 case 0x0000:
1505 util::stream_format(stream, "MOVE @");
1506 print_long_parm(stream, pos, params);
1507 stream << ",*";
1508 print_des_reg(stream);
1509 stream << "+,";
1510 print_field(stream);
1511 break;
1512
1513 case 0x0100:
1514 util::stream_format(stream, "EXGF ");
1515 print_des_reg(stream);
1516 stream << ",";
1517 print_field(stream);
1518 break;
1519
1520 default:
1521 bad = 1;
1522 }
1523 break;
1524
1525 case 0xd800:
1526 if (m_is_34020)
1527 {
1528 uint32_t x = r16(pos, params);
1529 util::stream_format(stream, "CEXEC %d,%06X,%d", op & 1, ((x << 5) & 0x1fffe0) | ((op >> 1) & 0x1f), (x >> 13) & 7);
1530 }
1531 else
1532 bad = 1;
1533 break;
1534
1535
1536 case 0xde00:
1537 switch (subop)
1538 {
1539 case 0x0000:
1540 if (m_is_34020)
1541 util::stream_format(stream, "FLINE 0");
1542 else
1543 bad = 1;
1544 break;
1545
1546 case 0x0080:
1547 if (m_is_34020)
1548 util::stream_format(stream, "FLINE 1");
1549 else
1550 bad = 1;
1551 break;
1552
1553 case 0x0100:
1554 util::stream_format(stream, "LINE 0");
1555 break;
1556
1557 case 0x0180:
1558 util::stream_format(stream, "LINE 1");
1559 break;
1560
1561 default:
1562 bad = 1;
1563 }
1564 break;
1565
1566 case 0xe000:
1567 util::stream_format(stream, "ADDXY ");
1568 print_src_des_reg(stream);
1569 break;
1570
1571
1572 case 0xe200:
1573 util::stream_format(stream, "SUBXY ");
1574 print_src_des_reg(stream);
1575 break;
1576
1577
1578 case 0xe400:
1579 util::stream_format(stream, "CMPXY ");
1580 print_src_des_reg(stream);
1581 break;
1582
1583
1584 case 0xe600:
1585 util::stream_format(stream, "CPW ");
1586 print_src_des_reg(stream);
1587 break;
1588
1589
1590 case 0xe800:
1591 util::stream_format(stream, "CVXYL ");
1592 print_src_des_reg(stream);
1593 break;
1594
1595
1596 case 0xea00:
1597 if (m_is_34020)
1598 {
1599 util::stream_format(stream, "CVSXYL ");
1600 print_src_des_reg(stream);
1601 }
1602 else
1603 bad = 1;
1604 break;
1605
1606
1607 case 0xec00:
1608 util::stream_format(stream, "MOVX ");
1609 print_src_des_reg(stream);
1610 break;
1611
1612
1613 case 0xee00:
1614 util::stream_format(stream, "MOVY ");
1615 print_src_des_reg(stream);
1616 break;
1617
1618
1619 case 0xf000:
1620 util::stream_format(stream, "PIXT ");
1621 print_src_reg(stream);
1622 stream << ",*";
1623 print_des_reg(stream);
1624 stream << ",XY";
1625 break;
1626
1627
1628 case 0xf200:
1629 util::stream_format(stream, "PIXT *");
1630 print_src_reg(stream);
1631 stream << ",XY,";
1632 print_des_reg(stream);
1633 break;
1634
1635
1636 case 0xf400:
1637 util::stream_format(stream, "PIXT *");
1638 print_src_reg(stream);
1639 stream << ",XY,*";
1640 print_des_reg(stream);
1641 stream << ",XY";
1642 break;
1643
1644
1645 case 0xf600:
1646 util::stream_format(stream, "DRAV ");
1647 print_src_des_reg(stream);
1648 break;
1649
1650
1651 case 0xf800:
1652 util::stream_format(stream, "PIXT ");
1653 print_src_reg(stream);
1654 stream << ",*";
1655 print_des_reg(stream);
1656 break;
1657
1658
1659 case 0xfa00:
1660 util::stream_format(stream, "PIXT *");
1661 print_src_des_reg(stream);
1662 break;
1663
1664
1665 case 0xfc00:
1666 util::stream_format(stream, "PIXT *");
1667 print_src_reg(stream);
1668 stream << ",*";
1669 print_des_reg(stream);
1670 break;
1671
1672 default:
1673 bad = 1;
1674 }
1675
1676 if (bad)
1677 {
1678 util::stream_format(stream, "DW %04Xh", op & 0xffff);
1679 }
1680
1681 return (pos - pc) | flags | SUPPORTED;
1682 }
1683
opcode_alignment() const1684 uint32_t tms34010_disassembler::opcode_alignment() const
1685 {
1686 return 16;
1687 }
1688
tms34010_disassembler(bool is_34020)1689 tms34010_disassembler::tms34010_disassembler(bool is_34020) : m_is_34020(is_34020)
1690 {
1691 }
1692