fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/macplus/cmd_68k.c *
7 * Created: 2007-04-15 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2007-2023 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "cmd_68k.h"
25#include "macplus.h"
26#include "traps.h"
27
28#include <string.h>
29
30#include <cpu/e68000/e68000.h>
31
32#include <lib/brkpt.h>
33#include <lib/cmd.h>
34#include <lib/console.h>
35#include <lib/log.h>
36#include <lib/msgdsk.h>
37#include <lib/monitor.h>
38#include <lib/sysdep.h>
39
40
41mon_cmd_t par_cmd[] = {
42 { "c", "[cnt]", "clock" },
43 { "gb", "[addr..]", "run with breakpoints at addr" },
44 { "ge", "[exception]", "run until exception" },
45 { "g", "", "run" },
46 { "halt", "[val]", "set halt state [2]" },
47 { "p", "[cnt]", "execute cnt instructions, skip calls [1]" },
48 { "reset", "", "reset" },
49 { "rte", "", "execute to next rte" },
50 { "r", "reg [val]", "get or set a register" },
51 { "s", "[what]", "print status (cpu|disks|iwm|mem|scc|via)" },
52 { "t", "[cnt]", "execute cnt instructions [1]" },
53 { "u", "[gas] [[-]addr [cnt]]", "disassemble" }
54};
55
56unsigned par_cmd_cnt = sizeof (par_cmd) / sizeof (par_cmd[0]);
57
58
59static
60void mac_dasm_str (char *dst, e68_dasm_t *op)
61{
62 unsigned i, n;
63 char tmp[512];
64 const char *ins;
65
66 strcpy (dst, "");
67
68 for (i = 0; i < op->irn; i++) {
69 sprintf (tmp, "%04X ", (unsigned) op->ir[i]);
70 strcat (dst, tmp);
71 }
72
73 for (i = op->irn; i < 4; i++) {
74 strcat (dst, " ");
75 }
76
77 if (op->flags & E68_DFLAG_PRIV) {
78 strcat (dst, "*");
79 }
80 else if (op->flags & E68_DFLAG_CALL) {
81 strcat (dst, ">");
82 }
83 else if (op->flags & E68_DFLAG_RTS) {
84 strcat (dst, "<");
85 }
86 else {
87 strcat (dst, " ");
88 }
89
90 ins = mac_get_trap_name (op->ir[0]);
91
92 if (ins == NULL) {
93 ins = op->op;
94 }
95
96 switch (op->argn) {
97 case 0:
98 sprintf (tmp, "%s", ins);
99 break;
100
101 case 1:
102 sprintf (tmp, "%-8s %s", ins, op->arg1);
103 break;
104
105 case 2:
106 sprintf (tmp, "%-8s %s, %s", ins, op->arg1, op->arg2);
107 break;
108
109 case 3:
110 sprintf (tmp, "%-8s %s, %s, %s",
111 ins, op->arg1, op->arg2, op->arg3
112 );
113 break;
114
115 default:
116 strcpy (tmp, "---");
117 break;
118 }
119
120 strcat (dst, tmp);
121
122 if (op->comm[0] != 0) {
123 n = strlen (dst);
124
125 dst += n;
126
127 while (n < 50) {
128 *(dst++) = ' ';
129 n += 1;
130 }
131
132 strcpy (dst, "; ");
133 strcat (dst, op->comm);
134 }
135}
136
137static
138void mac_prt_state_cpu (e68000_t *c)
139{
140 unsigned long opcnt, clkcnt;
141 unsigned long delay;
142 e68_dasm_t op;
143 char str[256];
144
145 pce_prt_sep ("68000");
146
147 opcnt = e68_get_opcnt (c);
148 clkcnt = e68_get_clkcnt (c);
149 delay = e68_get_delay (c);
150
151 pce_printf ("CLK=%lx OP=%lx DLY=%lu CPI=%.4f\n",
152 clkcnt, opcnt, delay,
153 (opcnt > 0) ? ((double) (clkcnt + delay) / (double) opcnt) : 1.0
154 );
155
156 pce_printf (" SR=%04X[%c%c] CC=%02X[%c%c%c%c%c] EX=%02X(%-4s) TRP=%04X IML=%X IPL=%X\n",
157 (unsigned) e68_get_sr (c),
158 (e68_get_sr_t (c)) ? 'T' : '-',
159 (e68_get_sr_s (c)) ? 'S' : '-',
160 (unsigned) e68_get_ccr (c),
161 (e68_get_sr_c (c)) ? 'C' : '-',
162 (e68_get_sr_v (c)) ? 'V' : '-',
163 (e68_get_sr_z (c)) ? 'Z' : '-',
164 (e68_get_sr_n (c)) ? 'N' : '-',
165 (e68_get_sr_x (c)) ? 'X' : '-',
166 e68_get_exception (c),
167 e68_get_exception_name (c),
168 e68_get_last_trap_a (c),
169 e68_get_iml (c),
170 e68_get_ipl (c)
171 );
172
173 pce_printf (" D0=%08lX D4=%08lX A0=%08lX A4=%08lX PC=%08lX\n",
174 (unsigned long) e68_get_dreg32 (c, 0),
175 (unsigned long) e68_get_dreg32 (c, 4),
176 (unsigned long) e68_get_areg32 (c, 0),
177 (unsigned long) e68_get_areg32 (c, 4),
178 (unsigned long) e68_get_pc (c)
179 );
180
181 pce_printf (" D1=%08lX D5=%08lX A1=%08lX A5=%08lX LPC=%08lX\n",
182 (unsigned long) e68_get_dreg32 (c, 1),
183 (unsigned long) e68_get_dreg32 (c, 5),
184 (unsigned long) e68_get_areg32 (c, 1),
185 (unsigned long) e68_get_areg32 (c, 5),
186 e68_get_last_pc (c, 0)
187 );
188
189 pce_printf (" D2=%08lX D6=%08lX A2=%08lX A6=%08lX USP=%08lX\n",
190 (unsigned long) e68_get_dreg32 (c, 2),
191 (unsigned long) e68_get_dreg32 (c, 6),
192 (unsigned long) e68_get_areg32 (c, 2),
193 (unsigned long) e68_get_areg32 (c, 6),
194 (unsigned long) e68_get_usp (c)
195 );
196
197 pce_printf (" D3=%08lX D7=%08lX A3=%08lX A7=%08lX SSP=%08lX\n",
198 (unsigned long) e68_get_dreg32 (c, 3),
199 (unsigned long) e68_get_dreg32 (c, 7),
200 (unsigned long) e68_get_areg32 (c, 3),
201 (unsigned long) e68_get_areg32 (c, 7),
202 (unsigned long) e68_get_ssp (c)
203 );
204
205 e68_dasm_mem (c, &op, e68_get_pc (c));
206 mac_dasm_str (str, &op);
207
208 pce_printf ("%08lX %s\n", (unsigned long) e68_get_pc (c), str);
209}
210
211static
212void mac_prt_state_scc (macplus_t *sim)
213{
214 unsigned i;
215 e8530_t *scc;
216 e8530_chn_t *chn;
217
218 static const char p[4] = { 'N', 'O', 'E', ' ' };
219 static const char *s[5] = { "0", "", "1", "1.5", "2" };
220
221 scc = &sim->scc;
222
223 pce_prt_sep ("8530-SCC");
224
225 pce_printf ("IRQ=%u\n", scc->irq_val);
226
227 for (i = 0; i < 2; i++) {
228 chn = scc->chn + i;
229 pce_printf ("CHN%u=%u%c%u%s\n",
230 i, chn->bps, p[chn->parity & 3], chn->bpc, s[chn->stop]
231 );
232 }
233
234 for (i = 0; i < 16; i++) {
235 pce_printf (
236 "WR%02uA=%02X RR%02uA=%02X WR%02uB=%02X RR%02uB=%02X\n",
237 i, scc->chn[0].wr[i],
238 i, scc->chn[0].rr[i],
239 i, scc->chn[1].wr[i],
240 i, scc->chn[1].rr[i]
241 );
242 }
243}
244
245static
246void mac_prt_state_via (macplus_t *sim)
247{
248 e6522_t *via;
249
250 via = &sim->via;
251
252 pce_prt_sep ("6522-VIA");
253
254 pce_printf (" PCR=%02X ACR=%02X IFR=%02X IER=%02X IRQ=%u\n",
255 via->pcr, via->acr, via->ifr, via->ier, via->irq_val
256 );
257
258 pce_printf ("DDRA=%02X DDRB=%02X CA1=%X T1L=%04X SHFT=%02X/%u\n",
259 via->ddra, via->ddrb, via->ca1_inp,
260 via->t1_latch, via->shift_val, via->shift_cnt
261 );
262
263 pce_printf (" IRA=%02X IRB=%02X CA2=%X %cT1V=%04X\n",
264 via->ira, via->irb, via->ca2_inp,
265 via->t1_hot ? '*' : ' ', via->t1_val
266 );
267
268 pce_printf (" ORA=%02X ORB=%02X CB1=%X T2L=%04X\n",
269 via->ora, via->orb, 0,
270 via->t2_latch
271 );
272
273 pce_printf (" PA=%02X PB=%02X CB2=%X %cT2V=%04X\n",
274 sim->via_port_a, sim->via_port_b, 0,
275 via->t2_hot ? '*' : ' ', via->t2_val
276 );
277}
278
279static
280void mac_print_state_iwm (macplus_t *sim)
281{
282 unsigned i;
283 mac_iwm_drive_t *drv;
284 mac_iwm_t *iwm;
285
286 pce_prt_sep ("IWM");
287
288 iwm = &sim->iwm;
289
290 pce_printf ("DSEL=%02X HSEL=%02X LINE=%02X WR=%d\n",
291 iwm->drive_sel, iwm->head_sel, iwm->lines, iwm->writing
292 );
293
294 pce_printf ("STAT=%02X MODE=%02X HDSK=%02X\n",
295 iwm->status, iwm->mode, iwm->handshake
296 );
297
298 pce_printf ("SCNT=%u SHFT=%02X RBUF=%02X\n",
299 iwm->shift_cnt, iwm->shift, iwm->read_buf
300 );
301
302 for (i = 0; i < 2; i++) {
303 drv = &sim->iwm.drv[i];
304
305 pce_printf ("D%u: DSK=%d MOT=%d MOD=%c%c TRK=%2u/%u POS=%lu/%lu\n",
306 i + 1, drv->disk_inserted, drv->motor_on,
307 drv->dirty ? 'D' : '-',
308 drv->track_dirty ? 'T' : '-',
309 drv->cur_cyl, drv->cur_head,
310 drv->cur_track_pos, drv->cur_track_len
311 );
312 }
313}
314
315static
316void mac_prt_state_mem (macplus_t *sim)
317{
318 pce_prt_sep ("MEM");
319 mem_prt_state (sim->mem, stdout);
320}
321
322void mac_prt_state (macplus_t *sim, const char *str)
323{
324 cmd_t cmd;
325
326 cmd_set_str (&cmd, str);
327
328 if (cmd_match_eol (&cmd)) {
329 return;
330 }
331
332 while (!cmd_match_eol (&cmd)) {
333 if (cmd_match (&cmd, "cpu")) {
334 mac_prt_state_cpu (sim->cpu);
335 }
336 else if (cmd_match (&cmd, "disks")) {
337 dsks_print_info (sim->dsks);
338 }
339 else if (cmd_match (&cmd, "iwm")) {
340 mac_print_state_iwm (sim);
341 }
342 else if (cmd_match (&cmd, "mem")) {
343 mac_prt_state_mem (sim);
344 }
345 else if (cmd_match (&cmd, "scc")) {
346 mac_prt_state_scc (sim);
347 }
348 else if (cmd_match (&cmd, "via")) {
349 mac_prt_state_via (sim);
350 }
351 else {
352 pce_printf ("unknown component (%s)\n", cmd_get_str (&cmd));
353 return;
354 }
355 }
356}
357
358
359/*
360 * Check if a breakpoint has triggered
361 */
362static
363int mac_check_break (macplus_t *sim)
364{
365 unsigned long pc;
366
367 pc = e68_get_pc (sim->cpu) & 0x00ffffff;
368
369 if (bps_check (&sim->bps, 0, pc, stdout)) {
370 return (1);
371 }
372
373 if (sim->brk) {
374 return (1);
375 }
376
377 return (0);
378}
379
380/*
381 * Execute one instruction
382 */
383static
384int mac_exec (macplus_t *sim)
385{
386 unsigned long old;
387
388 old = e68_get_opcnt (sim->cpu);
389
390 while (e68_get_opcnt (sim->cpu) == old) {
391 mac_clock (sim, 0);
392
393 if (mac_check_break (sim)) {
394 return (1);
395 }
396 }
397
398 return (0);
399}
400
401/*
402 * Execute until a specific PC is reached
403 */
404static
405int mac_exec_to (macplus_t *sim, unsigned long addr)
406{
407 while (e68_get_pc (sim->cpu) != addr) {
408 mac_clock (sim, 0);
409
410 if (mac_check_break (sim)) {
411 return (1);
412 }
413 }
414
415 return (0);
416}
417
418/*
419 * Run the simulation
420 */
421void mac_run (macplus_t *sim)
422{
423 pce_start (&sim->brk);
424 mac_clock_discontinuity (sim);
425
426 while (1) {
427 mac_clock (par_sim, 0);
428 mac_clock (par_sim, 0);
429
430 if (sim->brk) {
431 break;
432 }
433
434 while (sim->pause) {
435 pce_usleep (50UL * 1000UL);
436 trm_check (sim->trm);
437 }
438 }
439
440 pce_stop();
441}
442
443
444#if 0
445static
446void mac_log_opcode (void *ext, unsigned long ir)
447{
448 macplus_t *sim = ext;
449}
450#endif
451
452static
453void mac_log_undef (void *ext, unsigned long ir)
454{
455 unsigned long pc;
456 macplus_t *sim = ext;
457
458 pc = e68_get_last_pc (sim->cpu, 0);
459
460 pce_log (MSG_DEB,
461 "%08lX: undefined operation: %04lX [%04X %04X %04X %04X %04X]\n",
462 pc, ir,
463 (unsigned) e68_get_mem16 (sim->cpu, pc),
464 (unsigned) e68_get_mem16 (sim->cpu, pc + 2),
465 (unsigned) e68_get_mem16 (sim->cpu, pc + 4),
466 (unsigned) e68_get_mem16 (sim->cpu, pc + 6),
467 (unsigned) e68_get_mem16 (sim->cpu, pc + 8)
468 );
469
470 /* mac_set_msg (sim, "emu.stop", NULL); */
471}
472
473static
474void mac_log_exception (void *ext, unsigned tn)
475{
476 unsigned iw;
477 macplus_t *sim = ext;
478
479 iw = e68_get_mem16 (sim->cpu, e68_get_last_pc (sim->cpu, 0));
480
481 switch (tn) {
482 case 0x00:
483 mac_reset (sim);
484 return;
485
486 case 0x0a:
487 mac_sony_patch (&sim->sony);
488 return;
489
490 case 0x19:
491 case 0x1a:
492 return;
493
494 case 0x20: /* trap */
495 return;
496
497 case 0x27:
498 case 0x28:
499 case 0x29:
500 case 0x2a:
501 case 0x2b:
502 case 0x2c:
503 case 0x2e:
504 return;
505 }
506
507 pce_log (MSG_DEB,
508 "%08lX: exception %02X (%s) IW=%04X\n",
509 (unsigned long) e68_get_last_pc (sim->cpu, 0),
510 tn, e68_get_exception_name (sim->cpu), iw
511 );
512}
513
514void mac_log_mem (void *ext, unsigned long addr, unsigned type)
515{
516#if 0
517 macplus_t *sim = ext;
518
519 addr &= 0x00ffffff;
520#endif
521}
522
523
524/*
525 * c - clock
526 */
527static
528void mac_cmd_c (cmd_t *cmd, macplus_t *sim)
529{
530 unsigned long cnt;
531
532 cnt = 1;
533
534 cmd_match_uint32 (cmd, &cnt);
535
536 if (!cmd_match_end (cmd)) {
537 return;
538 }
539
540 while (cnt > 0) {
541 mac_clock (sim, 1);
542 cnt -= 1;
543 }
544
545 mac_prt_state_cpu (sim->cpu);
546}
547
548/*
549 * gb - run with breakpoints
550 */
551static
552void mac_cmd_g_b (cmd_t *cmd, macplus_t *sim)
553{
554 unsigned long addr;
555 breakpoint_t *bp;
556
557 while (cmd_match_uint32 (cmd, &addr)) {
558 bp = bp_addr_new (addr);
559 bps_bp_add (&sim->bps, bp);
560 }
561
562 if (!cmd_match_end (cmd)) {
563 return;
564 }
565
566 pce_start (&sim->brk);
567 mac_clock_discontinuity (sim);
568
569 while (1) {
570 if (mac_exec (sim)) {
571 break;
572 }
573 }
574
575 pce_stop();
576}
577
578/*
579 * ge - run until an exception is raised
580 */
581static
582void mac_cmd_g_e (cmd_t *cmd, macplus_t *sim)
583{
584 unsigned cnt;
585 unsigned short tn;
586
587 if (!cmd_match_uint16 (cmd, &tn)) {
588 tn = 0xffff;
589 }
590
591 if (!cmd_match_end (cmd)) {
592 return;
593 }
594
595 cnt = e68_get_exception_cnt (sim->cpu);
596
597 pce_start (&sim->brk);
598 mac_clock_discontinuity (sim);
599
600 while (1) {
601 mac_exec (sim);
602
603 if (mac_check_break (sim)) {
604 break;
605 }
606
607 if (e68_get_exception_cnt (sim->cpu) == cnt) {
608 continue;
609 }
610
611 if (tn == 0xffff) {
612 pce_printf ("exception %02X (%s)\n",
613 e68_get_exception (sim->cpu),
614 e68_get_exception_name (sim->cpu)
615 );
616 break;
617 }
618 else {
619 if (e68_get_exception (sim->cpu) == tn) {
620 pce_printf ("exception %02X (%s)\n",
621 e68_get_exception (sim->cpu),
622 e68_get_exception_name (sim->cpu)
623 );
624 break;
625 }
626 }
627
628 }
629
630 pce_stop();
631}
632
633/*
634 * g - run
635 */
636static
637void mac_cmd_g (cmd_t *cmd, macplus_t *sim)
638{
639 if (cmd_match (cmd, "b")) {
640 mac_cmd_g_b (cmd, sim);
641 return;
642 }
643 else if (cmd_match (cmd, "e")) {
644 mac_cmd_g_e (cmd, sim);
645 return;
646 }
647
648 if (!cmd_match_end (cmd)) {
649 return;
650 }
651
652 mac_run (sim);
653}
654
655/*
656 * halt - halt the cpu
657 */
658static
659void mac_cmd_halt (cmd_t *cmd, macplus_t *sim)
660{
661 unsigned short val;
662
663 if (cmd_match_uint16 (cmd, &val) == 0) {
664 val = 2;
665 }
666
667 if (!cmd_match_end (cmd)) {
668 return;
669 }
670
671 e68_set_halt (sim->cpu, val);
672
673 mac_prt_state_cpu (sim->cpu);
674}
675
676static
677void mac_cmd_hm (cmd_t *cmd)
678{
679 pce_puts (
680 "emu.exit\n"
681 "emu.pause \"0\" | \"1\"\n"
682 "emu.pause.toggle\n"
683 "emu.realtime \"0\" | \"1\"\n"
684 "emu.realtime.toggle\n"
685 "emu.reset\n"
686 "emu.stop\n"
687 "\n"
688 "emu.cpu.model \"68000\" | \"68010\" | \"68020\"\n"
689 "emu.cpu.speed <factor>\n"
690 "emu.cpu.speed.step <adjustment>\n"
691 "\n"
692 "emu.mac.insert <drive>\n"
693 "\n"
694 "emu.ser1.driver <driver>\n"
695 "emu.ser1.file <filename>\n"
696 "emu.ser1.multi <count>\n"
697 "emu.ser2.driver <driver>\n"
698 "emu.ser2.file <filename>\n"
699 "emu.ser2.multi <count>\n"
700 "\n"
701 "emu.term.fullscreen \"0\" | \"1\"\n"
702 "emu.term.fullscreen.toggle\n"
703 "emu.term.grab\n"
704 "emu.term.release\n"
705 "emu.term.screenshot [<filename>]\n"
706 "emu.term.title <title>\n"
707 "\n"
708 "emu.video.brightness <val>\n"
709 "\n"
710 );
711
712 msg_dsk_print_help();
713}
714
715/*
716 * p - step
717 */
718static
719void mac_cmd_p (cmd_t *cmd, macplus_t *sim)
720{
721 unsigned ecnt;
722 unsigned long cnt;
723 e68_dasm_t da;
724
725 cnt = 1;
726
727 while (cmd_match (cmd, "p")) {
728 cnt += 1;
729 }
730
731 cmd_match_uint32 (cmd, &cnt);
732
733 if (!cmd_match_end (cmd)) {
734 return;
735 }
736
737 ecnt = e68_get_exception_cnt (sim->cpu);
738
739 pce_start (&sim->brk);
740 mac_clock_discontinuity (sim);
741
742 while (cnt > 0) {
743 e68_dasm_mem (sim->cpu, &da, e68_get_pc (sim->cpu));
744
745 if (da.flags & E68_DFLAG_CALL) {
746 if (mac_exec_to (sim, e68_get_pc (sim->cpu) + 2 * da.irn)) {
747 break;
748 }
749 }
750 else {
751 if (mac_exec (sim)) {
752 break;
753 }
754
755 if (e68_get_exception_cnt (sim->cpu) != ecnt) {
756 if (mac_exec_to (sim, sim->cpu->except_addr)) {
757 break;
758 }
759 }
760 }
761
762 cnt -= 1;
763 }
764
765 pce_stop();
766
767 mac_prt_state_cpu (sim->cpu);
768}
769
770/*
771 * reset - reset the simulation
772 */
773static
774void mac_cmd_reset (cmd_t *cmd, macplus_t *sim)
775{
776 if (!cmd_match_end (cmd)) {
777 return;
778 }
779
780 mac_reset (sim);
781
782 mac_prt_state_cpu (sim->cpu);
783}
784
785/*
786 * rte - execute until rte
787 */
788static
789void mac_cmd_rte (cmd_t *cmd, macplus_t *sim)
790{
791 e68_dasm_t dis;
792
793 if (!cmd_match_end (cmd)) {
794 return;
795 }
796
797 pce_start (&sim->brk);
798 mac_clock_discontinuity (sim);
799
800 while (1) {
801 mac_exec (sim);
802
803 if (mac_check_break (sim)) {
804 break;
805 }
806
807 e68_dasm_mem (sim->cpu, &dis, e68_get_pc (sim->cpu));
808
809 if (dis.flags & E68_DFLAG_RTE) {
810 mac_prt_state_cpu (sim->cpu);
811 break;
812 }
813 }
814
815 pce_stop();
816}
817
818/*
819 * r - display or set register contents
820 */
821static
822void mac_cmd_r (cmd_t *cmd, macplus_t *sim)
823{
824 unsigned long val;
825 char sym[256];
826
827 if (cmd_match_eol (cmd)) {
828 mac_prt_state_cpu (sim->cpu);
829 return;
830 }
831
832 if (!cmd_match_ident (cmd, sym, 256)) {
833 cmd_error (cmd, "missing register\n");
834 return;
835 }
836
837 if (e68_get_reg (sim->cpu, sym, &val)) {
838 pce_printf ("bad register (%s)\n", sym);
839 return;
840 }
841
842 if (cmd_match_eol (cmd)) {
843 pce_printf ("%08lX\n", val);
844 return;
845 }
846
847 if (!cmd_match_uint32 (cmd, &val)) {
848 cmd_error (cmd, "missing value\n");
849 return;
850 }
851
852 if (!cmd_match_end (cmd)) {
853 return;
854 }
855
856 e68_set_reg (sim->cpu, sym, val);
857
858 mac_prt_state_cpu (sim->cpu);
859}
860
861/*
862 * s - print state
863 */
864static
865void mac_cmd_s (cmd_t *cmd, macplus_t *sim)
866{
867 if (cmd_match_eol (cmd)) {
868 mac_prt_state_cpu (sim->cpu);
869 return;
870 }
871
872 mac_prt_state (sim, cmd_get_str (cmd));
873}
874
875/*
876 * t - execute one instruction
877 */
878static
879void mac_cmd_t (cmd_t *cmd, macplus_t *sim)
880{
881 unsigned long i, n;
882
883 n = 1;
884
885 while (cmd_match (cmd, "t")) {
886 n += 1;
887 }
888
889 cmd_match_uint32 (cmd, &n);
890
891 if (!cmd_match_end (cmd)) {
892 return;
893 }
894
895 pce_start (&sim->brk);
896 mac_clock_discontinuity (sim);
897
898 for (i = 0; i < n; i++) {
899 mac_exec (sim);
900 }
901
902 pce_stop();
903
904 mac_prt_state_cpu (sim->cpu);
905}
906
907/*
908 * u- - disassemble to address
909 */
910static
911void mac_cmd_u_to (cmd_t *cmd, macplus_t *sim, unsigned long addr)
912{
913 unsigned long cnt;
914 unsigned ins_i, ins_j, ins_n;
915 unsigned sync;
916 unsigned long pc;
917 unsigned long insn[256];
918 e68_dasm_t op;
919 char str[256];
920
921 cnt = 16;
922
923 if (cmd_match_uint32 (cmd, &addr)) {
924 cmd_match_uint32 (cmd, &cnt);
925 }
926
927 if (!cmd_match_end (cmd)) {
928 return;
929 }
930
931 if (cnt > 256) {
932 cnt = 256;
933 }
934
935 ins_i = 0;
936 ins_j = 0;
937 ins_n = 0;
938 sync = 5;
939
940 pc = (addr - 12 * cnt) & ~1UL;
941
942 while (pc <= addr) {
943 if (sync == 0) {
944 insn[ins_j] = pc;
945 ins_j = (ins_j + 1) % 256;
946 if (ins_j == ins_i) {
947 ins_i = (ins_i + 1) % 256;
948 }
949 else {
950 ins_n += 1;
951 }
952 }
953 else {
954 sync -= 1;
955 }
956
957 e68_dasm_mem (sim->cpu, &op, pc);
958
959 pc += 2 * op.irn;
960 }
961
962 if (ins_n > cnt) {
963 ins_i = (ins_i + (ins_n - cnt)) % 256;
964 }
965
966 while (ins_i != ins_j) {
967 pc = insn[ins_i];
968
969 e68_dasm_mem (sim->cpu, &op, pc);
970 mac_dasm_str (str, &op);
971
972 pce_printf ("%08lX %s\n", pc, str);
973
974 ins_i = (ins_i + 1) % 256;
975 }
976
977
978}
979
980/*
981 * u gas - disassemble for gas
982 */
983static
984void mac_cmd_u_gas (cmd_t *cmd, macplus_t *sim)
985{
986 unsigned i;
987 unsigned long addr1, addr2;
988 const char *ins;
989 e68_dasm_t op;
990
991 addr1 = 0;
992 addr2 = 0;
993
994 if (cmd_match_uint32 (cmd, &addr1)) {
995 addr2 = addr1;
996 cmd_match_uint32 (cmd, &addr2);
997 }
998
999 if (!cmd_match_end (cmd)) {
1000 return;
1001 }
1002
1003 pce_printf ("\t.text\n");
1004
1005 while (addr1 < addr2) {
1006 e68_dasm_mem (sim->cpu, &op, addr1);
1007
1008 pce_printf ("\tdc.w\t0x%04x", (unsigned) op.ir[0]);
1009
1010 for (i = 1; i < op.irn; i++) {
1011 pce_printf (", 0x%04x", (unsigned) op.ir[i]);
1012 }
1013
1014 for (i = op.irn; i < 4; i++) {
1015 pce_printf ("\t");
1016 }
1017
1018 pce_printf ("\t| %06lX ", op.pc);
1019
1020 ins = mac_get_trap_name (op.ir[0]);
1021
1022 if (ins == NULL) {
1023 ins = op.op;
1024 }
1025
1026 pce_printf ((op.argn > 0) ? "%-8s" : "%s", ins);
1027
1028 if (op.argn >= 1) {
1029 pce_printf ("%s", op.arg1);
1030 }
1031
1032 if (op.argn >= 2) {
1033 pce_printf (", %s", op.arg2);
1034 }
1035
1036 if (op.argn >= 3) {
1037 pce_printf (", %s", op.arg3);
1038 }
1039
1040 pce_printf ("\n");
1041
1042 if (op.flags & E68_DFLAG_RTS) {
1043 pce_printf ("\n");
1044 }
1045
1046 addr1 += 2 * op.irn;
1047 }
1048}
1049
1050/*
1051 * u - disassemble
1052 */
1053static
1054void mac_cmd_u (cmd_t *cmd, macplus_t *sim)
1055{
1056 unsigned i;
1057 unsigned long addr, cnt;
1058 static unsigned int first = 1;
1059 static unsigned long saddr = 0;
1060 e68_dasm_t op;
1061 char str[256];
1062
1063 if (cmd_match (cmd, "gas")) {
1064 mac_cmd_u_gas (cmd, sim);
1065 return;
1066 }
1067
1068 if (first) {
1069 first = 0;
1070 saddr = e68_get_pc (sim->cpu);
1071 }
1072
1073 addr = saddr;
1074 cnt = 16;
1075
1076 if (cmd_match (cmd, "-")) {
1077 mac_cmd_u_to (cmd, sim, addr);
1078 return;
1079 }
1080
1081 if (cmd_match_uint32 (cmd, &addr)) {
1082 cmd_match_uint32 (cmd, &cnt);
1083 }
1084
1085 if (!cmd_match_end (cmd)) {
1086 return;
1087 }
1088
1089 for (i = 0; i < cnt; i++) {
1090 e68_dasm_mem (sim->cpu, &op, addr);
1091 mac_dasm_str (str, &op);
1092
1093 pce_printf ("%08lX %s\n", addr, str);
1094
1095 addr += 2 * op.irn;
1096 }
1097
1098 saddr = addr;
1099}
1100
1101int mac_cmd (macplus_t *sim, cmd_t *cmd)
1102{
1103 if (sim->trm != NULL) {
1104 trm_check (sim->trm);
1105 }
1106
1107 if (cmd_match (cmd, "b")) {
1108 cmd_do_b (cmd, &sim->bps);
1109 }
1110 else if (cmd_match (cmd, "c")) {
1111 mac_cmd_c (cmd, sim);
1112 }
1113 else if (cmd_match (cmd, "g")) {
1114 mac_cmd_g (cmd, sim);
1115 }
1116 else if (cmd_match (cmd, "halt")) {
1117 mac_cmd_halt (cmd, sim);
1118 }
1119 else if (cmd_match (cmd, "hm")) {
1120 mac_cmd_hm (cmd);
1121 }
1122 else if (cmd_match (cmd, "p")) {
1123 mac_cmd_p (cmd, sim);
1124 }
1125 else if (cmd_match (cmd, "reset")) {
1126 mac_cmd_reset (cmd, sim);
1127 }
1128 else if (cmd_match (cmd, "rte")) {
1129 mac_cmd_rte (cmd, sim);
1130 }
1131 else if (cmd_match (cmd, "r")) {
1132 mac_cmd_r (cmd, sim);
1133 }
1134 else if (cmd_match (cmd, "s")) {
1135 mac_cmd_s (cmd, sim);
1136 }
1137 else if (cmd_match (cmd, "t")) {
1138 mac_cmd_t (cmd, sim);
1139 }
1140 else if (cmd_match (cmd, "u")) {
1141 mac_cmd_u (cmd, sim);
1142 }
1143 else {
1144 return (1);
1145 }
1146
1147 if (sim->trm != NULL) {
1148 trm_set_msg_trm (sim->trm, "term.release", "1");
1149 }
1150
1151 return (0);
1152}
1153
1154void mac_cmd_init (macplus_t *sim, monitor_t *mon)
1155{
1156 mon_cmd_add (mon, par_cmd, sizeof (par_cmd) / sizeof (par_cmd[0]));
1157 mon_cmd_add_bp (mon);
1158
1159 sim->cpu->log_ext = sim;
1160 sim->cpu->log_opcode = NULL;
1161 sim->cpu->log_undef = mac_log_undef;
1162 sim->cpu->log_exception = mac_log_exception;
1163 sim->cpu->log_mem = mac_log_mem;
1164}