fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1164 lines 21 kB view raw
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}