fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1355 lines 25 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/atarist/cmd.c * 7 * Created: 2011-03-17 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2011-2019 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 "atarist.h" 25#include "cmd.h" 26#include "dma.h" 27 28#include <string.h> 29 30#include <lib/console.h> 31#include <lib/log.h> 32#include <lib/monitor.h> 33#include <lib/msgdsk.h> 34#include <lib/sysdep.h> 35 36 37#ifndef DEBUG_BIOS 38#define DEBUG_BIOS 0 39#endif 40 41 42mon_cmd_t par_cmd[] = { 43 { "c", "[cnt]", "clock" }, 44 { "gb", "[addr..]", "run with breakpoints at addr" }, 45 { "ge", "[exception]", "run until exception" }, 46 { "g", "", "run" }, 47 { "halt", "[val]", "set halt state [2]" }, 48 { "hm", "", "print help on messages" }, 49 { "p", "[cnt]", "execute cnt instructions, skip calls [1]" }, 50 { "reset", "", "reset" }, 51 { "rte", "", "execute to next rte" }, 52 { "r", "reg [val]", "get or set a register" }, 53 { "s", "[what]", "print status (acia0|acia1|cpu|disks|dma|mem|mfp|psg|video)" }, 54 { "t", "[cnt]", "execute cnt instructions [1]" }, 55 { "u", "[w][[-]addr [cnt]]", "disassemble" }, 56 { "uw", "[addr [cnt]]", "disassemble as constant words" } 57}; 58 59unsigned par_cmd_cnt = sizeof (par_cmd) / sizeof (par_cmd[0]); 60 61 62static 63void st_dasm_str (char *dst, e68_dasm_t *op, int opcode) 64{ 65 unsigned i, n; 66 char tmp[272]; 67 const char *ins; 68 69 strcpy (dst, ""); 70 71 if (opcode) { 72 for (i = 0; i < op->irn; i++) { 73 sprintf (tmp, "%04X ", (unsigned) op->ir[i]); 74 strcat (dst, tmp); 75 } 76 77 for (i = op->irn; i < 4; i++) { 78 strcat (dst, " "); 79 } 80 } 81 82 if (op->flags & E68_DFLAG_PRIV) { 83 strcat (dst, "*"); 84 } 85 else if (op->flags & E68_DFLAG_CALL) { 86 strcat (dst, ">"); 87 } 88 else if (op->flags & E68_DFLAG_RTS) { 89 strcat (dst, "<"); 90 } 91 else { 92 strcat (dst, " "); 93 } 94 95 ins = op->op; 96 97 switch (op->argn) { 98 case 0: 99 sprintf (tmp, "%s", ins); 100 break; 101 102 case 1: 103 sprintf (tmp, "%-8s %s", ins, op->arg1); 104 break; 105 106 case 2: 107 sprintf (tmp, "%-8s %s, %s", ins, op->arg1, op->arg2); 108 break; 109 110 case 3: 111 sprintf (tmp, "%-8s %s, %s, %s", 112 ins, op->arg1, op->arg2, op->arg3 113 ); 114 break; 115 116 default: 117 strcpy (tmp, "---"); 118 break; 119 } 120 121 strcat (dst, tmp); 122 123 if (op->comm[0] != 0) { 124 n = strlen (dst); 125 126 dst += n; 127 128 while (n < 50) { 129 *(dst++) = ' '; 130 n += 1; 131 } 132 133 strcpy (dst, "; "); 134 strcat (dst, op->comm); 135 } 136} 137 138void st_print_state_cpu (atari_st_t *sim) 139{ 140 e68000_t *c; 141 e68_dasm_t op; 142 char str[256]; 143 144 pce_prt_sep ("68000"); 145 146 c = sim->cpu; 147 148 pce_printf ("SR=%04X [%c%c %c%c%c%c%c] EX=%02X(%-4s) TA=%04X IL=%X/%X\n", 149 (unsigned) e68_get_sr (c), 150 (e68_get_sr_t (c)) ? 'T' : '-', 151 (e68_get_sr_s (c)) ? 'S' : '-', 152 (e68_get_sr_x (c)) ? 'X' : '-', 153 (e68_get_sr_n (c)) ? 'N' : '-', 154 (e68_get_sr_z (c)) ? 'Z' : '-', 155 (e68_get_sr_v (c)) ? 'V' : '-', 156 (e68_get_sr_c (c)) ? 'C' : '-', 157 e68_get_exception (c), 158 e68_get_exception_name (c), 159 e68_get_last_trap_a (c), 160 e68_get_ipl (c), 161 e68_get_iml (c) 162 ); 163 164 pce_printf ("D0=%08lX D4=%08lX A0=%08lX A4=%08lX PC=%08lX PC1=%08lX\n", 165 (unsigned long) e68_get_dreg32 (c, 0), 166 (unsigned long) e68_get_dreg32 (c, 4), 167 (unsigned long) e68_get_areg32 (c, 0), 168 (unsigned long) e68_get_areg32 (c, 4), 169 (unsigned long) e68_get_pc (c), 170 (unsigned long) e68_get_last_pc (c, 0) 171 ); 172 173 pce_printf ("D1=%08lX D5=%08lX A1=%08lX A5=%08lX PPC=%08lX PC2=%08lX\n", 174 (unsigned long) e68_get_dreg32 (c, 1), 175 (unsigned long) e68_get_dreg32 (c, 5), 176 (unsigned long) e68_get_areg32 (c, 1), 177 (unsigned long) e68_get_areg32 (c, 5), 178 e68_get_ir_pc (c), 179 (unsigned long) e68_get_last_pc (c, 1) 180 ); 181 182 pce_printf ("D2=%08lX D6=%08lX A2=%08lX A6=%08lX USP=%08lX PC3=%08lX\n", 183 (unsigned long) e68_get_dreg32 (c, 2), 184 (unsigned long) e68_get_dreg32 (c, 6), 185 (unsigned long) e68_get_areg32 (c, 2), 186 (unsigned long) e68_get_areg32 (c, 6), 187 (unsigned long) e68_get_usp (c), 188 (unsigned long) e68_get_last_pc (c, 2) 189 ); 190 191 pce_printf ("D3=%08lX D7=%08lX A3=%08lX A7=%08lX SSP=%08lX PC4=%08lX\n", 192 (unsigned long) e68_get_dreg32 (c, 3), 193 (unsigned long) e68_get_dreg32 (c, 7), 194 (unsigned long) e68_get_areg32 (c, 3), 195 (unsigned long) e68_get_areg32 (c, 7), 196 (unsigned long) e68_get_ssp (c), 197 (unsigned long) e68_get_last_pc (c, 3) 198 ); 199 200 e68_dasm_mem (c, &op, e68_get_pc (c)); 201 st_dasm_str (str, &op, 1); 202 203 pce_printf ("%08lX %s\n", (unsigned long) e68_get_pc (c), str); 204} 205 206static 207void st_print_state_cpu_short (e68000_t *c) 208{ 209 e68_dasm_t op; 210 char str[256]; 211 212 e68_dasm_mem (c, &op, e68_get_pc (c)); 213 st_dasm_str (str, &op, 0); 214 215 pce_printf ("D0=%08lX A0=%08lX A6=%08lX A7=%08lX SR=%04X[%c%c%c%c%c%c%c] %06lX %s\n", 216 (unsigned long) e68_get_dreg32 (c, 0), 217 (unsigned long) e68_get_areg32 (c, 0), 218 (unsigned long) e68_get_areg32 (c, 6), 219 (unsigned long) e68_get_areg32 (c, 7), 220 (unsigned) e68_get_sr (c), 221 (e68_get_sr_t (c)) ? 'T' : '-', 222 (e68_get_sr_s (c)) ? 'S' : '-', 223 (e68_get_sr_c (c)) ? 'C' : '-', 224 (e68_get_sr_v (c)) ? 'V' : '-', 225 (e68_get_sr_z (c)) ? 'Z' : '-', 226 (e68_get_sr_n (c)) ? 'N' : '-', 227 (e68_get_sr_x (c)) ? 'X' : '-', 228 (unsigned long) e68_get_pc (c), str 229 ); 230} 231 232static 233void st_print_state_mfp_timer (e68901_timer_t *tmr, const char *label) 234{ 235 pce_printf ("TM-%s: CR=%02X DR=%02X/%02X DIV=%04X CLK=%04X OUT=%d (%u/%u)\n", 236 label, 237 tmr->cr, tmr->dr[0], tmr->dr[1], 238 tmr->clk_div_set, tmr->clk_val / tmr->clk_div_inp, 239 tmr->out != 0, tmr->clk_val, tmr->clk_div 240 ); 241} 242 243static 244void st_print_state_mfp (atari_st_t *sim) 245{ 246 e68901_t *mfp; 247 248 static char parity[4] = { 'N', 'N', 'O', 'E' }; 249 250 mfp = &sim->mfp; 251 252 pce_prt_sep ("68901-MFP"); 253 254 pce_printf ("GPIP: INP=%02X/%02X OUT=%02X AER=%02X DDR=%02X\n", 255 mfp->gpip_inp, mfp->gpip_xor, mfp->gpip_val, mfp->gpip_aer, mfp->gpip_ddr 256 ); 257 258 pce_printf ("INTR: IRR=%04X/%04X IER=%04X IPR=%04X IMR=%04X ISR=%04X IVR=%02X VEC=%02X IRQ=%d\n", 259 mfp->irr1, mfp->irr2, mfp->ier, mfp->ipr, mfp->imr, mfp->isr, mfp->ivr, mfp->vec, mfp->irq_val 260 ); 261 262 pce_printf ("UART: PAR=%u%c%u UCR=%02X RSR=%02X RDR=%02X TSR=%02X TDR=%02X RCLK=%u/%u SCLK=%u/%u\n", 263 8 - ((mfp->ucr >> 5) & 3), 264 parity[(mfp->ucr >> 1) & 3], 265 (((mfp->ucr >> 3) & 3) + 1) / 2, 266 mfp->ucr, mfp->rsr[0], mfp->rdr[0], mfp->tsr[0], mfp->tdr[0], 267 mfp->recv_clk_cnt, mfp->recv_clk_max, 268 mfp->send_clk_cnt, mfp->send_clk_max 269 ); 270 271 st_print_state_mfp_timer (mfp->timer + 0, "A"); 272 st_print_state_mfp_timer (mfp->timer + 1, "B"); 273 st_print_state_mfp_timer (mfp->timer + 2, "C"); 274 st_print_state_mfp_timer (mfp->timer + 3, "D"); 275} 276 277static 278void st_print_state_acia (atari_st_t *sim, unsigned idx) 279{ 280 e6850_t *acia; 281 282 if (idx == 0) { 283 acia = &sim->acia0; 284 pce_prt_sep ("6850-ACIA-0"); 285 } 286 else { 287 acia = &sim->acia1; 288 pce_prt_sep ("6850-ACIA-1"); 289 } 290 291 pce_printf ("CR=%02X SR=%02X TDR=%02X RDR=%02X IRQ=%d\n", 292 acia->cr, acia->sr, acia->tdr, acia->rdr, acia->irq_val 293 ); 294} 295 296static 297void st_print_state_dma (atari_st_t *sim) 298{ 299 st_dma_t *dma; 300 301 dma = &sim->dma; 302 303 pce_prt_sep ("DMA"); 304 305 pce_printf ("MODE=%04X STATUS=%04X ADDR=%06lX MASK=%06lX\n", 306 dma->mode, dma->status, dma->addr, dma->mask 307 ); 308} 309 310static 311void st_print_state_mem (atari_st_t *sim) 312{ 313 pce_prt_sep ("MEM"); 314 mem_prt_state (sim->mem, stdout); 315} 316 317static 318void st_print_state_psg (atari_st_t *sim) 319{ 320 st_psg_t *psg; 321 322 pce_prt_sep ("PSG"); 323 324 psg = &sim->psg; 325 326 pce_printf ("R%02X=%02X PA=%u\n", 0, psg->reg[0], 327 ((psg->reg[1] << 8) | (psg->reg[0])) & 0x3ff 328 ); 329 330 pce_printf ("R%02X=%02X\n", 1, psg->reg[1]); 331 332 pce_printf ("R%02X=%02X PB=%u\n", 2, psg->reg[2], 333 ((psg->reg[3] << 8) | (psg->reg[2])) & 0x3ff 334 ); 335 336 pce_printf ("R%02X=%02X\n", 3, psg->reg[3]); 337 338 pce_printf ("R%02X=%02X PC=%u\n", 4, psg->reg[4], 339 ((psg->reg[5] << 8) | (psg->reg[4])) & 0x3ff 340 ); 341 342 pce_printf ("R%02X=%02X\n", 5, psg->reg[5]); 343 344 pce_printf ("R%02X=%02X PN=%u\n", 6, psg->reg[6], 345 psg->reg[6] & 0x1f 346 ); 347 348 pce_printf ("R%02X=%02X N=%c%c%c T=%c%c%c\n", 7, psg->reg[7], 349 (psg->reg[7] & 8) ? 'a' : 'A', 350 (psg->reg[7] & 16) ? 'b' : 'B', 351 (psg->reg[7] & 32) ? 'c' : 'C', 352 (psg->reg[7] & 1) ? 'a' : 'A', 353 (psg->reg[7] & 2) ? 'b' : 'B', 354 (psg->reg[7] & 4) ? 'c' : 'C' 355 ); 356 357 pce_printf ("R%02X=%02X VA=%u %c\n", 8, psg->reg[8], 358 psg->reg[8] & 0x0f, 359 (psg->reg[8] & 0x10) ? 'M' : '-' 360 ); 361 362 pce_printf ("R%02X=%02X VB=%u %c\n", 9, psg->reg[9], 363 psg->reg[9] & 0x0f, 364 (psg->reg[9] & 0x10) ? 'M' : '-' 365 ); 366 367 pce_printf ("R%02X=%02X VC=%u %c\n", 10, psg->reg[10], 368 psg->reg[10] & 0x0f, 369 (psg->reg[10] & 0x10) ? 'M' : '-' 370 ); 371 372 pce_printf ("R%02X=%02X PE=%u\n", 11, psg->reg[11], 373 ((psg->reg[12] << 8) | (psg->reg[11])) & 0xffff 374 ); 375 376 pce_printf ("R%02X=%02X\n", 12, psg->reg[12]); 377 378 pce_printf ("R%02X=%02X ENV=%X\n", 13, psg->reg[13], 379 psg->reg[13] & 0x0f 380 ); 381 382 pce_printf ("R%02X=%02X\n", 14, psg->reg[14]); 383 pce_printf ("R%02X=%02X\n", 15, psg->reg[15]); 384} 385 386static 387void st_print_state_video (atari_st_t *sim) 388{ 389 unsigned i; 390 st_video_t *vid; 391 392 vid = sim->video; 393 394 pce_prt_sep ("VIDEO"); 395 396 pce_printf ("B=%06lX A=%06lX HB=%-3d VB=%-3d\n", 397 vid->base, vid->addr, vid->hb_val != 0, vid->vb_val != 0 398 ); 399 400 pce_printf ("X=%-3u HB1=%-3u HB2=%-3u %lu Hz\n", 401 vid->clk, vid->hb1, vid->hb2, 402 (8000000UL + vid->hb2 / 2) / vid->hb2 403 ); 404 405 pce_printf ("Y=%-3u VB1=%-3u VB2=%-3u %lu Hz\n", 406 vid->line, vid->vb1, vid->vb2, 407 (8000000UL + (vid->hb2 * vid->vb2) / 2) / (vid->hb2 * vid->vb2) 408 ); 409 410 for (i = 0; i < 8; i++) { 411 pce_printf ("PAL%X=%04X [%02X %02X %02X] PAL%X=%04X [%02X %02X %02X]\n", 412 i, vid->palette[i], 413 vid->pal_col[i][0], vid->pal_col[i][1], vid->pal_col[i][2], 414 i + 8, vid->palette[i + 8], 415 vid->pal_col[i + 8][0], vid->pal_col[i + 8][1], vid->pal_col[i + 8][2] 416 ); 417 } 418} 419 420static 421void st_print_state (atari_st_t *sim, const char *str) 422{ 423 cmd_t cmd; 424 425 cmd_set_str (&cmd, str); 426 427 if (cmd_match_eol (&cmd)) { 428 return; 429 } 430 431 while (!cmd_match_eol (&cmd)) { 432 if (cmd_match (&cmd, "cpu")) { 433 st_print_state_cpu (sim); 434 } 435 else if (cmd_match (&cmd, "disks")) { 436 dsks_print_info (sim->dsks); 437 } 438 else if (cmd_match (&cmd, "dma")) { 439 st_print_state_dma (sim); 440 } 441 else if (cmd_match (&cmd, "mem")) { 442 st_print_state_mem (sim); 443 } 444 else if (cmd_match (&cmd, "acia0")) { 445 st_print_state_acia (sim, 0); 446 } 447 else if (cmd_match (&cmd, "acia1")) { 448 st_print_state_acia (sim, 1); 449 } 450 else if (cmd_match (&cmd, "mfp")) { 451 st_print_state_mfp (sim); 452 } 453 else if (cmd_match (&cmd, "psg")) { 454 st_print_state_psg (sim); 455 } 456 else if (cmd_match (&cmd, "video")) { 457 st_print_state_video (sim); 458 } 459 else { 460 pce_printf ("unknown component (%s)\n", cmd_get_str (&cmd)); 461 return; 462 } 463 } 464} 465 466 467/* 468 * Check if a breakpoint has triggered 469 */ 470static 471int st_check_break (atari_st_t *sim) 472{ 473 unsigned long pc; 474 475 pc = e68_get_pc (sim->cpu) & 0x00ffffff; 476 477 if (bps_check (&sim->bps, 0, pc, stdout)) { 478 return (1); 479 } 480 481 if (sim->brk) { 482 return (1); 483 } 484 485 return (0); 486} 487 488/* 489 * Execute one instruction 490 */ 491static 492int st_exec (atari_st_t *sim) 493{ 494 unsigned long old; 495 496 old = e68_get_opcnt (sim->cpu); 497 498 while (e68_get_opcnt (sim->cpu) == old) { 499 st_clock (sim, 1); 500 501 if (st_check_break (sim)) { 502 return (1); 503 } 504 } 505 506 return (0); 507} 508 509/* 510 * Execute until a specific PC is reached 511 */ 512static 513int st_exec_to (atari_st_t *sim, unsigned long addr) 514{ 515 while (e68_get_pc (sim->cpu) != addr) { 516 st_clock (sim, 1); 517 518 if (st_check_break (sim)) { 519 return (1); 520 } 521 } 522 523 return (0); 524} 525 526/* 527 * Run the simulation 528 */ 529void st_run (atari_st_t *sim) 530{ 531 pce_start (&sim->brk); 532 533 st_clock_discontinuity (sim); 534 535 while (1) { 536 st_clock (par_sim, 0); 537 538 if (sim->brk) { 539 break; 540 } 541 542 while (sim->pause) { 543 pce_usleep (50UL * 1000UL); 544 trm_check (sim->trm); 545 } 546 } 547 548 pce_stop(); 549} 550 551 552static 553void st_log_trap_bios (atari_st_t *sim, unsigned iw) 554{ 555 unsigned i; 556 unsigned short par[8]; 557 558#if (DEBUG_BIOS == 0) 559 return; 560#endif 561 562 for (i = 0; i < 8; i++) { 563 par[i] = mem_get_uint16_be (sim->mem, e68_get_areg32 (sim->cpu, 7) + 2 * i); 564 } 565 566 switch (par[0]) { 567 case 1: 568 //st_log_deb ("bios_constat (%u)\n", par[1]); 569 break; 570 571 case 2: 572 st_log_deb ("bios_conin (%u)\n", par[1]); 573 break; 574 575 case 3: 576 st_log_deb ("bios_conout (%u, %u)\n", par[1], par[2]); 577 break; 578 579 case 4: 580 st_log_deb ("bios_rwabs (%u, 0x%08lx, %u, %u, %u)\n", 581 par[1], ((unsigned long) par[2] << 16) | par[3], 582 par[4], par[5], par[6] 583 ); 584 break; 585 586 case 5: 587 st_log_deb ("bios_setexc (%u, %lu)\n", 588 par[1], ((unsigned long) par[2] << 16) | par[3] 589 ); 590 break; 591 592 case 9: 593 st_log_deb ("bios_media_change (%u)\n", par[1]); 594 break; 595 596 default: 597 st_log_deb ("bios (%u, %u, %u, %u)\n", par[0], par[1], par[2], par[3]); 598 break; 599 } 600} 601 602static 603void st_log_exception (void *ext, unsigned tn) 604{ 605 unsigned iw; 606 atari_st_t *sim = ext; 607 608 iw = e68_get_mem16 (sim->cpu, e68_get_last_pc (sim->cpu, 0)); 609 610 switch (tn) { 611 case 0x00: 612 st_reset (sim); 613 return; 614 615 case 0x02: /* BUSE */ 616 return; 617 618 case 0x04: /* ILLG */ 619 case 0x09: /* TRACE */ 620 case 0x0a: /* AXXX */ 621 case 0x0b: /* FXXX */ 622 return; 623 624 case 0x1a: /* AVEC 2 */ 625 case 0x1c: /* AVEC 4 */ 626 case 0x1e: /* AVEC 6 */ 627 return; 628 629 case 0x20: /* trap */ 630 case 0x21: 631 case 0x22: 632 case 0x27: 633 case 0x28: 634 case 0x29: 635 case 0x2a: 636 case 0x2b: 637 case 0x2c: 638 case 0x2e: 639 case 0x2f: 640 return; 641 642 case 0x2d: 643 st_log_trap_bios (sim, iw); 644 return; 645 646 case 0x06: 647 case 0x08: 648 case 0x42: /* MFP RS232 CTS */ 649 case 0x44: /* MFP Timer D */ 650 case 0x45: /* MFP Timer C */ 651 case 0x46: /* MFP I4 (ACIA0) */ 652 case 0x48: /* HB counter */ 653 case 0x49: /* USART send data */ 654 case 0x4a: /* USART send error */ 655 case 0x4b: /* USART recv data */ 656 case 0x4c: /* USART recv error */ 657 case 0x4d: /* MFP Timer A */ 658 return; 659 } 660 661 pce_log (MSG_DEB, 662 "%08lX: exception %02X (%s) IW=%04X\n", 663 (unsigned long) e68_get_last_pc (sim->cpu, 0), 664 tn, e68_get_exception_name (sim->cpu), iw 665 ); 666} 667 668 669/* 670 * c - clock 671 */ 672static 673void st_cmd_c (cmd_t *cmd, atari_st_t *sim) 674{ 675 unsigned long cnt; 676 677 cnt = 1; 678 679 cmd_match_uint32 (cmd, &cnt); 680 681 if (!cmd_match_end (cmd)) { 682 return; 683 } 684 685 while (cnt > 0) { 686 st_clock (sim, 1); 687 cnt -= 1; 688 } 689 690 st_print_state_cpu (sim); 691} 692 693/* 694 * gb - run with breakpoints 695 */ 696static 697void st_cmd_g_b (cmd_t *cmd, atari_st_t *sim) 698{ 699 unsigned long addr; 700 breakpoint_t *bp; 701 702 while (cmd_match_uint32 (cmd, &addr)) { 703 bp = bp_addr_new (addr); 704 bps_bp_add (&sim->bps, bp); 705 } 706 707 if (!cmd_match_end (cmd)) { 708 return; 709 } 710 711 pce_start (&sim->brk); 712 713 st_clock_discontinuity (sim); 714 715 while (1) { 716 if (st_exec (sim)) { 717 break; 718 } 719 } 720 721 pce_stop(); 722} 723 724/* 725 * ge - run until an exception is raised 726 */ 727static 728void st_cmd_g_e (cmd_t *cmd, atari_st_t *sim) 729{ 730 unsigned short tn; 731 unsigned cnt; 732 733 if (!cmd_match_uint16 (cmd, &tn)) { 734 tn = 0xffff; 735 } 736 737 if (!cmd_match_end (cmd)) { 738 return; 739 } 740 741 cnt = e68_get_exception_cnt (sim->cpu); 742 743 pce_start (&sim->brk); 744 745 st_clock_discontinuity (sim); 746 747 while (1) { 748 st_exec (sim); 749 750 if (st_check_break (sim)) { 751 break; 752 } 753 754 if (e68_get_exception_cnt (sim->cpu) == cnt) { 755 continue; 756 } 757 758 if (tn == 0xffff) { 759 pce_printf ("exception %02X (%s)\n", 760 e68_get_exception (sim->cpu), 761 e68_get_exception_name (sim->cpu) 762 ); 763 break; 764 } 765 else { 766 if (e68_get_exception (sim->cpu) == tn) { 767 pce_printf ("exception %02X (%s)\n", 768 e68_get_exception (sim->cpu), 769 e68_get_exception_name (sim->cpu) 770 ); 771 break; 772 } 773 } 774 775 } 776 777 pce_stop(); 778} 779 780/* 781 * g - run 782 */ 783static 784void st_cmd_g (cmd_t *cmd, atari_st_t *sim) 785{ 786 if (cmd_match (cmd, "b")) { 787 st_cmd_g_b (cmd, sim); 788 return; 789 } 790 else if (cmd_match (cmd, "e")) { 791 st_cmd_g_e (cmd, sim); 792 return; 793 } 794 795 if (!cmd_match_end (cmd)) { 796 return; 797 } 798 799 st_run (sim); 800} 801 802/* 803 * halt - halt the cpu 804 */ 805static 806void st_cmd_halt (cmd_t *cmd, atari_st_t *sim) 807{ 808 unsigned short val; 809 810 if (cmd_match_uint16 (cmd, &val) == 0) { 811 val = 2; 812 } 813 814 if (!cmd_match_end (cmd)) { 815 return; 816 } 817 818 e68_set_halt (sim->cpu, val); 819 820 st_print_state_cpu (sim); 821} 822 823/* 824 * hm - help on messages 825 */ 826static 827void st_cmd_hm (cmd_t *cmd) 828{ 829 pce_puts ( 830 "emu.exit\n" 831 "emu.stop\n" 832 "emu.pause \"0\" | \"1\"\n" 833 "emu.pause.toggle\n" 834 "emu.reset\n" 835 "\n" 836 "emu.cpu.model \"68000\" | \"68010\" | \"68020\"\n" 837 "emu.cpu.speed <factor>\n" 838 "emu.cpu.speed.step <adjustment>\n" 839 "\n" 840 "emu.midi.file <fname>\n" 841 "\n" 842 "emu.fdc.ro <drive>\n" 843 "emu.fdc.rw <drive>\n" 844 "\n" 845 "emu.par.driver <driver>\n" 846 "emu.par.file <filename>\n" 847 "\n" 848 "emu.psg.aym.file <filename>\n" 849 "emu.psg.aym.res <usec>\n" 850 "emu.psg.driver <driver>\n" 851 "emu.psg.lowpass <freq>\n" 852 "\n" 853 "emu.ser.driver <driver>\n" 854 "emu.ser.file <filename>\n" 855 "\n" 856 "emu.viking \"0\" | \"1\"\n" 857 "emu.viking.toggle\n" 858 "\n" 859 "term.fullscreen \"0\" | \"1\"\n" 860 "term.fullscreen.toggle\n" 861 "term.grab\n" 862 "term.release\n" 863 "term.screenshot [<filename>]\n" 864 "term.title <title>\n" 865 "\n" 866 ); 867 868 msg_dsk_print_help(); 869} 870 871/* 872 * p - step 873 */ 874static 875void st_cmd_p (cmd_t *cmd, atari_st_t *sim) 876{ 877 unsigned ecnt; 878 unsigned long cnt; 879 e68_dasm_t da; 880 881 cnt = 1; 882 883 while (cmd_match (cmd, "p")) { 884 cnt += 1; 885 } 886 887 cmd_match_uint32 (cmd, &cnt); 888 889 if (!cmd_match_end (cmd)) { 890 return; 891 } 892 893 pce_start (&sim->brk); 894 895 st_clock_discontinuity (sim); 896 897 while (cnt > 0) { 898 e68_dasm_mem (sim->cpu, &da, e68_get_pc (sim->cpu)); 899 900 if (da.flags & E68_DFLAG_CALL) { 901 if (st_exec_to (sim, e68_get_pc (sim->cpu) + 2 * da.irn)) { 902 break; 903 } 904 } 905 else { 906 ecnt = e68_get_exception_cnt (sim->cpu); 907 908 if (st_exec (sim)) { 909 break; 910 } 911 912 if (e68_get_exception_cnt (sim->cpu) != ecnt) { 913 if (st_exec_to (sim, sim->cpu->except_addr)) { 914 break; 915 } 916 } 917 } 918 919 cnt -= 1; 920 } 921 922 pce_stop(); 923 924 st_print_state_cpu (sim); 925} 926 927/* 928 * n - run to following instruction 929 */ 930static 931void st_cmd_n (cmd_t *cmd, atari_st_t *sim) 932{ 933 unsigned long cnt; 934 e68_dasm_t da; 935 936 cnt = 1; 937 938 while (cmd_match (cmd, "n")) { 939 cnt += 1; 940 } 941 942 cmd_match_uint32 (cmd, &cnt); 943 944 if (!cmd_match_end (cmd)) { 945 return; 946 } 947 948 pce_start (&sim->brk); 949 950 st_clock_discontinuity (sim); 951 952 while (cnt > 0) { 953 e68_dasm_mem (sim->cpu, &da, e68_get_pc (sim->cpu)); 954 955 if (st_exec_to (sim, e68_get_pc (sim->cpu) + 2 * da.irn)) { 956 break; 957 } 958 959 cnt -= 1; 960 } 961 962 pce_stop(); 963 964 st_print_state_cpu (sim); 965} 966 967/* 968 * reset - reset the simulation 969 */ 970static 971void st_cmd_reset (cmd_t *cmd, atari_st_t *sim) 972{ 973 if (!cmd_match_end (cmd)) { 974 return; 975 } 976 977 st_reset (sim); 978 979 st_print_state_cpu (sim); 980} 981 982/* 983 * rte - execute until rte 984 */ 985static 986void st_cmd_rte (cmd_t *cmd, atari_st_t *sim) 987{ 988 e68_dasm_t dis; 989 990 if (!cmd_match_end (cmd)) { 991 return; 992 } 993 994 pce_start (&sim->brk); 995 996 while (1) { 997 st_exec (sim); 998 999 if (st_check_break (sim)) { 1000 break; 1001 } 1002 1003 e68_dasm_mem (sim->cpu, &dis, e68_get_pc (sim->cpu)); 1004 1005 if (dis.flags & E68_DFLAG_RTE) { 1006 st_print_state_cpu (sim); 1007 break; 1008 } 1009 } 1010 1011 pce_stop(); 1012} 1013 1014/* 1015 * r - display or set register contents 1016 */ 1017static 1018void st_cmd_r (cmd_t *cmd, atari_st_t *sim) 1019{ 1020 unsigned long val; 1021 char sym[256]; 1022 1023 if (cmd_match_eol (cmd)) { 1024 st_print_state_cpu (sim); 1025 return; 1026 } 1027 1028 if (!cmd_match_ident (cmd, sym, 256)) { 1029 cmd_error (cmd, "missing register\n"); 1030 return; 1031 } 1032 1033 if (e68_get_reg (sim->cpu, sym, &val)) { 1034 pce_printf ("bad register (%s)\n", sym); 1035 return; 1036 } 1037 1038 if (cmd_match_eol (cmd)) { 1039 pce_printf ("%08lX\n", val); 1040 return; 1041 } 1042 1043 if (!cmd_match_uint32 (cmd, &val)) { 1044 cmd_error (cmd, "missing value\n"); 1045 return; 1046 } 1047 1048 if (!cmd_match_end (cmd)) { 1049 return; 1050 } 1051 1052 e68_set_reg (sim->cpu, sym, val); 1053 1054 st_print_state_cpu (sim); 1055} 1056 1057/* 1058 * s - print state 1059 */ 1060static 1061void st_cmd_s (cmd_t *cmd, atari_st_t *sim) 1062{ 1063 if (cmd_match_eol (cmd)) { 1064 st_print_state_cpu (sim); 1065 return; 1066 } 1067 1068 st_print_state (sim, cmd_get_str (cmd)); 1069} 1070 1071/* 1072 * t - execute one instruction 1073 */ 1074static 1075void st_cmd_t (cmd_t *cmd, atari_st_t *sim) 1076{ 1077 unsigned long i, n, k; 1078 1079 n = 1; 1080 k = 0; 1081 1082 while (cmd_match (cmd, "t")) { 1083 n += 1; 1084 } 1085 1086 cmd_match_uint32 (cmd, &n); 1087 cmd_match_uint32 (cmd, &k); 1088 1089 if (!cmd_match_end (cmd)) { 1090 return; 1091 } 1092 1093 pce_start (&sim->brk); 1094 1095 st_clock_discontinuity (sim); 1096 1097 for (i = 0; i < n; i++) { 1098 if ((n > 1) && (i >= k)) { 1099 st_print_state_cpu_short (sim->cpu); 1100 } 1101 1102 st_exec (sim); 1103 } 1104 1105 pce_stop(); 1106 1107 st_print_state_cpu (sim); 1108} 1109 1110/* 1111 * u- - disassemble to address 1112 */ 1113static 1114void st_cmd_u_to (cmd_t *cmd, atari_st_t *sim, unsigned long addr) 1115{ 1116 unsigned long cnt; 1117 unsigned ins_i, ins_j, ins_n; 1118 unsigned sync; 1119 unsigned long pc; 1120 unsigned long insn[256]; 1121 e68_dasm_t op; 1122 char str[256]; 1123 1124 cnt = 16; 1125 1126 if (cmd_match_uint32 (cmd, &addr)) { 1127 cmd_match_uint32 (cmd, &cnt); 1128 } 1129 1130 if (!cmd_match_end (cmd)) { 1131 return; 1132 } 1133 1134 if (cnt > 256) { 1135 cnt = 256; 1136 } 1137 1138 ins_i = 0; 1139 ins_j = 0; 1140 ins_n = 0; 1141 sync = 5; 1142 1143 pc = (addr - 12 * cnt) & ~1UL; 1144 1145 while (pc <= addr) { 1146 if (sync == 0) { 1147 insn[ins_j] = pc; 1148 ins_j = (ins_j + 1) % 256; 1149 if (ins_j == ins_i) { 1150 ins_i = (ins_i + 1) % 256; 1151 } 1152 else { 1153 ins_n += 1; 1154 } 1155 } 1156 else { 1157 sync -= 1; 1158 } 1159 1160 e68_dasm_mem (sim->cpu, &op, pc); 1161 1162 pc += 2 * op.irn; 1163 } 1164 1165 if (ins_n > cnt) { 1166 ins_i = (ins_i + (ins_n - cnt)) % 256; 1167 } 1168 1169 while (ins_i != ins_j) { 1170 pc = insn[ins_i]; 1171 1172 e68_dasm_mem (sim->cpu, &op, pc); 1173 st_dasm_str (str, &op, 1); 1174 1175 pce_printf ("%08lX %s\n", pc, str); 1176 1177 ins_i = (ins_i + 1) % 256; 1178 } 1179 1180 1181} 1182 1183/* 1184 * uw - disassemble as constant words 1185 */ 1186static 1187void st_cmd_u_w (cmd_t *cmd, atari_st_t *sim) 1188{ 1189 unsigned i, col; 1190 unsigned long addr, cnt; 1191 e68_dasm_t op; 1192 char str[256]; 1193 1194 if (cmd_match_uint32 (cmd, &addr) == 0) { 1195 addr = 0; 1196 } 1197 1198 if (cmd_match_uint32 (cmd, &cnt) == 0) { 1199 cnt = 256; 1200 } 1201 1202 if (!cmd_match_end (cmd)) { 1203 return; 1204 } 1205 1206 while (1) { 1207 e68_dasm_mem (sim->cpu, &op, addr); 1208 st_dasm_str (str, &op, 0); 1209 1210 pce_printf (".word 0x%04x", op.ir[0]); 1211 1212 for (i = 1; i < op.irn; i++) { 1213 pce_printf (", 0x%04x", op.ir[i]); 1214 } 1215 1216 col = 4 + 8 * op.irn; 1217 1218 while (col < 32) { 1219 pce_printf ("\t"); 1220 col = (col + 8) & ~7; 1221 } 1222 1223 pce_printf ("\t/* %06lX %s */\n", addr, str); 1224 1225 if (op.flags & E68_DFLAG_RTS) { 1226 pce_printf ("\n"); 1227 } 1228 1229 if (cnt <= (2 * op.irn)) { 1230 break; 1231 } 1232 1233 addr += 2 * op.irn; 1234 cnt -= 2 * op.irn; 1235 } 1236} 1237 1238/* 1239 * u - disassemble 1240 */ 1241static 1242void st_cmd_u (cmd_t *cmd, atari_st_t *sim) 1243{ 1244 unsigned i; 1245 unsigned long addr, cnt; 1246 static unsigned int first = 1; 1247 static unsigned long saddr = 0; 1248 e68_dasm_t op; 1249 char str[256]; 1250 1251 if (cmd_match (cmd, "w")) { 1252 st_cmd_u_w (cmd, sim); 1253 return; 1254 } 1255 1256 if (first) { 1257 first = 0; 1258 saddr = e68_get_pc (sim->cpu); 1259 } 1260 1261 addr = saddr; 1262 cnt = 16; 1263 1264 if (cmd_match (cmd, "-")) { 1265 st_cmd_u_to (cmd, sim, addr); 1266 return; 1267 } 1268 1269 if (cmd_match_uint32 (cmd, &addr)) { 1270 cmd_match_uint32 (cmd, &cnt); 1271 } 1272 1273 if (!cmd_match_end (cmd)) { 1274 return; 1275 } 1276 1277 for (i = 0; i < cnt; i++) { 1278 e68_dasm_mem (sim->cpu, &op, addr); 1279 st_dasm_str (str, &op, 1); 1280 1281 pce_printf ("%08lX %s\n", addr, str); 1282 1283 addr += 2 * op.irn; 1284 } 1285 1286 saddr = addr; 1287} 1288 1289int st_cmd (atari_st_t *sim, cmd_t *cmd) 1290{ 1291 if (sim->trm != NULL) { 1292 trm_check (sim->trm); 1293 } 1294 1295 if (cmd_match (cmd, "b")) { 1296 cmd_do_b (cmd, &sim->bps); 1297 } 1298 else if (cmd_match (cmd, "c")) { 1299 st_cmd_c (cmd, sim); 1300 } 1301 else if (cmd_match (cmd, "g")) { 1302 st_cmd_g (cmd, sim); 1303 } 1304 else if (cmd_match (cmd, "halt")) { 1305 st_cmd_halt (cmd, sim); 1306 } 1307 else if (cmd_match (cmd, "hm")) { 1308 st_cmd_hm (cmd); 1309 } 1310 else if (cmd_match (cmd, "p")) { 1311 st_cmd_p (cmd, sim); 1312 } 1313 else if (cmd_match (cmd, "n")) { 1314 st_cmd_n (cmd, sim); 1315 } 1316 else if (cmd_match (cmd, "reset")) { 1317 st_cmd_reset (cmd, sim); 1318 } 1319 else if (cmd_match (cmd, "rte")) { 1320 st_cmd_rte (cmd, sim); 1321 } 1322 else if (cmd_match (cmd, "r")) { 1323 st_cmd_r (cmd, sim); 1324 } 1325 else if (cmd_match (cmd, "s")) { 1326 st_cmd_s (cmd, sim); 1327 } 1328 else if (cmd_match (cmd, "t")) { 1329 st_cmd_t (cmd, sim); 1330 } 1331 else if (cmd_match (cmd, "u")) { 1332 st_cmd_u (cmd, sim); 1333 } 1334 else { 1335 return (1); 1336 } 1337 1338 if (sim->trm != NULL) { 1339 trm_set_msg_trm (sim->trm, "term.release", "1"); 1340 } 1341 1342 return (0); 1343} 1344 1345void st_cmd_init (atari_st_t *sim, monitor_t *mon) 1346{ 1347 mon_cmd_add (mon, par_cmd, sizeof (par_cmd) / sizeof (par_cmd[0])); 1348 mon_cmd_add_bp (mon); 1349 1350 sim->cpu->log_ext = sim; 1351 sim->cpu->log_opcode = NULL; 1352 sim->cpu->log_undef = NULL; 1353 sim->cpu->log_exception = st_log_exception; 1354 sim->cpu->log_mem = NULL; 1355}