fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1406 lines 27 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/rc759/cmd.c * 7 * Created: 2012-06-29 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2012-2025 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 "rc759.h" 25 26#include <stdio.h> 27#include <string.h> 28 29#include <lib/brkpt.h> 30#include <lib/cmd.h> 31#include <lib/console.h> 32#include <lib/log.h> 33#include <lib/monitor.h> 34#include <lib/msgdsk.h> 35#include <lib/sysdep.h> 36 37 38static mon_cmd_t par_cmd[] = { 39 { "c", "[cnt]", "clock the simulation [1]" }, 40 { "gb", "[addr...]", "run with breakpoints" }, 41 { "g", "far", "run until CS changes" }, 42 { "g", "", "run" }, 43 { "hm", "", "print help on messages" }, 44 { "i", "[b|w] port", "input a byte or word from a port" }, 45 { "key", "[[+|-]key...]", "simulate pressing or releasing keys" }, 46 { "log", "int l", "list interrupt log expressions" }, 47 { "log", "int n [expr]", "set interrupt n log expression to expr" }, 48 { "nv", "get addr [cnt]", "read bytes from nvram" }, 49 { "nv", "set addr [val...]", "write bytes to nvram" }, 50 { "nv", "sum", "fix the nvram checksum" }, 51 { "o", "[b|w] port val", "output a byte or word to a port" }, 52 { "pq", "[c|f|s]", "prefetch queue clear/fill/status" }, 53 { "p", "[cnt]", "execute cnt instructions, without trace in calls [1]" }, 54 { "r", "[reg val]", "set a register" }, 55 { "s", "[what]", "print status (cpu|disks|icu|mem||ppi|pic|rc759|tcu|time)" }, 56 { "t", "[cnt]", "execute cnt instructions [1]" }, 57 { "u", "[addr [cnt [mode]]]", "disassemble" } 58}; 59 60 61static 62void disasm_str (char *dst, e86_disasm_t *op) 63{ 64 unsigned i; 65 unsigned dst_i; 66 67 dst_i = 2; 68 sprintf (dst, "%02X", op->dat[0]); 69 70 for (i = 1; i < op->dat_n; i++) { 71 sprintf (dst + dst_i, " %02X", op->dat[i]); 72 dst_i += 3; 73 } 74 75 dst[dst_i++] = ' '; 76 while (dst_i < 20) { 77 dst[dst_i++] = ' '; 78 } 79 80 if ((op->flags & ~(E86_DFLAGS_CALL | E86_DFLAGS_LOOP)) != 0) { 81 unsigned flg; 82 83 flg = op->flags; 84 85 dst[dst_i++] = '['; 86 87 if (flg & E86_DFLAGS_186) { 88 dst_i += sprintf (dst + dst_i, "186"); 89 flg &= ~E86_DFLAGS_186; 90 } 91 92 if (flg != 0) { 93 if (flg != op->flags) { 94 dst[dst_i++] = ' '; 95 } 96 dst_i += sprintf (dst + dst_i, " %04X", flg); 97 } 98 dst[dst_i++] = ']'; 99 dst[dst_i++] = ' '; 100 } 101 102 strcpy (dst + dst_i, op->op); 103 while (dst[dst_i] != 0) { 104 dst_i += 1; 105 } 106 107 if (op->arg_n > 0) { 108 dst[dst_i++] = ' '; 109 while (dst_i < 26) { 110 dst[dst_i++] = ' '; 111 } 112 } 113 114 if (op->arg_n == 1) { 115 dst_i += sprintf (dst + dst_i, "%s", op->arg1); 116 } 117 else if (op->arg_n == 2) { 118 dst_i += sprintf (dst + dst_i, "%s, %s", op->arg1, op->arg2); 119 } 120 121 dst[dst_i] = 0; 122} 123 124static 125void prt_uint8_bin (unsigned char val) 126{ 127 unsigned i; 128 unsigned char m; 129 char str[16]; 130 131 m = 0x80; 132 133 for (i = 0; i < 8; i++) { 134 str[i] = (val & m) ? '1' : '0'; 135 m = m >> 1; 136 } 137 138 str[8] = 0; 139 140 pce_puts (str); 141} 142 143static 144void print_state_icu (e80186_icu_t *icu) 145{ 146 unsigned i; 147 unsigned char inp, irr, imr, isr; 148 149 const char *names[] = { 150 "TMR", NULL, "DMA0", "DMA1", "INT0", "INT1", "INT2", "INT3" 151 }; 152 153 inp = icu->inp; 154 irr = e80186_icu_get_irr (icu); 155 imr = e80186_icu_get_imr (icu); 156 isr = e80186_icu_get_isr (icu); 157 158 pce_prt_sep ("80186-ICU"); 159 160 pce_puts ("INP="); 161 prt_uint8_bin (inp); 162 pce_puts (" IRR="); 163 prt_uint8_bin (irr); 164 pce_puts (" IMR="); 165 prt_uint8_bin (imr); 166 pce_puts (" ISR="); 167 prt_uint8_bin (isr); 168 pce_puts ("\n"); 169 170 pce_printf ("PMR=%04X PST=%04X INT=%d\n", 171 e80186_icu_get_pmr (icu), 172 e80186_icu_get_pollst (icu), 173 icu->intr_val 174 ); 175 176 for (i = 0; i < 8; i++) { 177 pce_printf ("%4s[%u]: CTL=%04X CNT=%04lX I=%u R=%u M=%u S=%u\n", 178 (names[i] != NULL) ? names[i] : "-", i, 179 e80186_icu_get_icon (icu, i), 180 icu->int_cnt[i], 181 inp & 1, irr & 1, imr & 1, isr & 1 182 ); 183 184 inp >>= 1; 185 irr >>= 1; 186 imr >>= 1; 187 isr >>= 1; 188 } 189} 190 191static 192void print_state_tcu (e80186_tcu_t *tcu) 193{ 194 unsigned i; 195 unsigned short ctl; 196 197 pce_prt_sep ("80186-TCU"); 198 199 for (i = 0; i < 3; i++) { 200 ctl = e80186_tcu_get_control (tcu, i); 201 202 pce_printf ( 203 "%cC%d: CTL=%04X CNT=%04X MAXA=%04X MAXB=%04X\n", 204 (ctl & 0x8000) ? '*' : ' ', 205 i, 206 ctl, 207 e80186_tcu_get_count (tcu, i), 208 e80186_tcu_get_max_count_a (tcu, i), 209 e80186_tcu_get_max_count_b (tcu, i) 210 ); 211 } 212} 213 214static 215void print_state_ppi (e8255_t *ppi) 216{ 217 pce_prt_sep ("8255-PPI"); 218 219 pce_printf ( 220 "MOD=%02X MODA=%u MODB=%u", 221 ppi->mode, ppi->group_a_mode, ppi->group_b_mode 222 ); 223 224 if (ppi->port[0].inp != 0) { 225 pce_printf (" A=I[%02X]", e8255_get_inp (ppi, 0)); 226 } 227 else { 228 pce_printf (" A=O[%02X]", e8255_get_out (ppi, 0)); 229 } 230 231 if (ppi->port[1].inp != 0) { 232 pce_printf (" B=I[%02X]", e8255_get_inp (ppi, 1)); 233 } 234 else { 235 pce_printf (" B=O[%02X]", e8255_get_out (ppi, 1)); 236 } 237 238 switch (ppi->port[2].inp) { 239 case 0xff: 240 pce_printf (" C=I[%02X]", e8255_get_inp (ppi, 2)); 241 break; 242 243 case 0x00: 244 pce_printf (" C=O[%02X]", e8255_get_out (ppi, 2)); 245 break; 246 247 case 0x0f: 248 pce_printf (" CH=O[%X] CL=I[%X]", 249 (e8255_get_out (ppi, 2) >> 4) & 0x0f, 250 e8255_get_inp (ppi, 2) & 0x0f 251 ); 252 break; 253 254 case 0xf0: 255 pce_printf (" CH=I[%X] CL=O[%X]", 256 (e8255_get_inp (ppi, 2) >> 4) & 0x0f, 257 e8255_get_out (ppi, 2) & 0x0f 258 ); 259 break; 260 } 261 262 pce_puts ("\n"); 263} 264 265static 266void print_state_dma (e80186_dma_t *dma) 267{ 268 unsigned i; 269 270 pce_prt_sep ("80186-DMA"); 271 272 for (i = 0; i < 2; i++) { 273 pce_printf ("%u: CTL=%04X CNT=%04X SRC=%05lX DST=%05lX\n", 274 i, 275 e80186_dma_get_control (dma, i), 276 e80186_dma_get_count (dma, i), 277 e80186_dma_get_src (dma, i), 278 e80186_dma_get_dst (dma, i) 279 ); 280 } 281} 282 283static 284void print_state_pic (e8259_t *pic) 285{ 286 unsigned i; 287 288 pce_prt_sep ("8259A-PIC"); 289 290 pce_puts ("INP="); 291 prt_uint8_bin (pic->irq_inp); 292 pce_puts ("\n"); 293 294 pce_puts ("IRR="); 295 prt_uint8_bin (e8259_get_irr (pic)); 296 pce_printf (" PRIO=%u\n", pic->priority); 297 298 pce_puts ("IMR="); 299 prt_uint8_bin (e8259_get_imr (pic)); 300 pce_printf (" INTR=%d\n", pic->intr_val != 0); 301 302 pce_puts ("ISR="); 303 prt_uint8_bin (e8259_get_isr (pic)); 304 pce_puts ("\n"); 305 306 pce_printf ("ICW=[%02X %02X %02X %02X] OCW=[%02X %02X %02X]\n", 307 e8259_get_icw (pic, 0), e8259_get_icw (pic, 1), e8259_get_icw (pic, 2), 308 e8259_get_icw (pic, 3), 309 e8259_get_ocw (pic, 0), e8259_get_ocw (pic, 1), e8259_get_ocw (pic, 2) 310 ); 311 312 pce_printf ("N0=%04lX", pic->irq_cnt[0]); 313 for (i = 1; i < 8; i++) { 314 pce_printf (" N%u=%04lX", i, pic->irq_cnt[i]); 315 } 316 317 pce_puts ("\n"); 318} 319 320static 321void print_state_fdc (rc759_fdc_t *fdc) 322{ 323 unsigned i; 324 wd179x_drive_t *drv; 325 326 pce_prt_sep ("179X-FDC"); 327 328 pce_printf ("FCR=%02X RSV=%02X\n", 329 rc759_fdc_get_fcr (fdc), rc759_fdc_get_reserve (fdc) 330 ); 331 332 pce_printf ("STATUS=%02X CMD=%02X\n", 333 fdc->wd179x.status, fdc->wd179x.cmd 334 ); 335 336 for (i = 0; i < 2; i++) { 337 drv = &fdc->wd179x.drive[i]; 338 339 pce_printf ("DRIVE %u: SEL=%d RDY=%d M=%d C=%02X H=%X POS=%lu CNT=%lu\n", 340 i, 341 fdc->wd179x.drv->d == i, drv->ready != 0, drv->motor != 0, 342 (unsigned) drv->c, (unsigned) drv->h, 343 (unsigned long) drv->trkbuf_idx, (unsigned long) drv->trkbuf_cnt 344 ); 345 } 346} 347 348static 349void print_state_video (e82730_t *crt) 350{ 351 unsigned i; 352 353 pce_prt_sep ("82730-CRTC"); 354 355 pce_printf ("CBP: %08lX\n", crt->cbp); 356 pce_printf ("GRAPH: %-4d MONO: %d SINT: %-4d\n", crt->graphic != 0, crt->monochrome != 0, crt->sint_val != 0); 357 pce_printf ("STAT: %04X IMSK: %04X\n", crt->status, crt->intmask); 358 pce_printf ("ALF: %-4d LSSW: %-4d\n", crt->auto_lf != 0, crt->list_switch != 0); 359 pce_printf ("FATTR: %04X\n", crt->field_attrib); 360 361 362 pce_printf ("Mode:\n"); 363 pce_printf ("\tline length: %u\n", crt->mode_line_length); 364 pce_printf ("\th field start: %u\n", crt->mode_hfldstrt); 365 pce_printf ("\th field stop: %u\n", crt->mode_hfldstp); 366 pce_printf ("\tframe length: %u\n", crt->mode_frame_length); 367 pce_printf ("\tv field start: %u\n", crt->mode_vfldstrt); 368 pce_printf ("\tv field stop: %u\n", crt->mode_vfldstp); 369 pce_printf ("\tlines per row: %u\n", crt->mode_lines_per_row); 370 pce_printf ("\tframe int count: %u\n", crt->frame_int_count[0]); 371 372 for (i = 0; i < 2; i++) { 373 pce_printf ("CURSOR %u: X=%02X Y=%02X OE=%d RVV=%d BE=%d FREQ=%u DUTY=%u START=%02X STOP=%02X\n", 374 i + 1, 375 crt->cursor_x[i], 376 crt->cursor_y[i], 377 crt->cursor_enable[i], 378 crt->cursor_reverse[i], 379 crt->cursor_blink[i], 380 crt->cursor_max, 381 crt->cursor_duty, 382 crt->cursor_start[i], 383 crt->cursor_stop[i] 384 ); 385 } 386} 387 388void print_state_cpu (e8086_t *c) 389{ 390 static char ft[2] = { '-', '+' }; 391 392 pce_prt_sep ("80186"); 393 394 pce_printf ( 395 "AX=%04X BX=%04X CX=%04X DX=%04X " 396 "SP=%04X BP=%04X SI=%04X DI=%04X INT=%02X%c\n", 397 e86_get_ax (c), e86_get_bx (c), e86_get_cx (c), e86_get_dx (c), 398 e86_get_sp (c), e86_get_bp (c), e86_get_si (c), e86_get_di (c), 399 par_sim->current_int & 0xff, 400 (par_sim->current_int & 0x100) ? '*' : ' ' 401 ); 402 403 pce_printf ("CS=%04X DS=%04X ES=%04X SS=%04X IP=%04X F =%04X", 404 e86_get_cs (c), e86_get_ds (c), e86_get_es (c), e86_get_ss (c), 405 e86_get_ip (c), c->flg 406 ); 407 408 pce_printf (" I%c D%c O%c S%c Z%c A%c P%c C%c\n", 409 ft[e86_get_if (c)], ft[e86_get_df (c)], 410 ft[e86_get_of (c)], ft[e86_get_sf (c)], 411 ft[e86_get_zf (c)], ft[e86_get_af (c)], 412 ft[e86_get_pf (c)], ft[e86_get_cf (c)] 413 ); 414 415 if (e86_get_halt (c)) { 416 pce_printf ("HALT=1\n"); 417 } 418} 419 420static 421void print_state_mem (rc759_t *sim) 422{ 423 pce_prt_sep ("RC759 MEM"); 424 mem_prt_state (sim->mem, stdout); 425} 426 427static 428void print_state_ports (rc759_t *sim) 429{ 430 pce_prt_sep ("RC759 PORTS"); 431 mem_prt_state (sim->iop, stdout); 432} 433 434static 435void print_state_rc759 (rc759_t *sim) 436{ 437 print_state_ppi (&sim->ppi); 438 print_state_tcu (&sim->tcu); 439 print_state_pic (&sim->pic); 440 print_state_dma (&sim->dma); 441 print_state_cpu (sim->cpu); 442} 443 444static 445void print_state (rc759_t *sim) 446{ 447 e86_disasm_t op; 448 char str[256]; 449 450 e86_disasm_cur (sim->cpu, &op); 451 disasm_str (str, &op); 452 453 print_state_cpu (sim->cpu); 454 455 pce_printf ("%04X:%04X %s\n", 456 (unsigned) e86_get_cs (sim->cpu), 457 (unsigned) e86_get_ip (sim->cpu), 458 str 459 ); 460} 461 462static 463int rc759_check_break (rc759_t *sim) 464{ 465 unsigned short seg, ofs; 466 467 seg = e86_get_cs (sim->cpu); 468 ofs = e86_get_ip (sim->cpu); 469 470 if (bps_check (&sim->bps, seg, ofs, stdout)) { 471 return (1); 472 } 473 474 if (sim->brk) { 475 return (1); 476 } 477 478 return (0); 479} 480 481static 482void rc759_exec (rc759_t *sim) 483{ 484 unsigned old; 485 486 sim->current_int &= 0xff; 487 488 old = e86_get_opcnt (sim->cpu); 489 490 while (e86_get_opcnt (sim->cpu) == old) { 491 rc759_clock (sim, 1); 492 493 if (sim->brk) { 494 break; 495 } 496 } 497} 498 499void rc759_run (rc759_t *sim) 500{ 501 pce_start (&sim->brk); 502 503 rc759_clock_discontinuity (sim); 504 505 while (sim->brk == 0) { 506 if (sim->pause == 0) { 507 rc759_clock (sim, 0); 508 } 509 else { 510 pce_usleep (100000); 511 trm_check (sim->trm); 512 } 513 } 514 515 sim->current_int &= 0xff; 516 517 pce_stop(); 518} 519 520static 521void pce_op_int (void *ext, unsigned char n) 522{ 523 rc759_t *sim; 524 525 sim = ext; 526 527 sim->current_int = n | 0x100; 528 529 if (rc759_intlog_check (sim, n)) { 530 pce_printf ("%04X:%04X: int %02X" 531 " [AX=%04X BX=%04X CX=%04X DX=%04X DS=%04X ES=%04X]\n", 532 e86_get_cs (sim->cpu), e86_get_cur_ip (sim->cpu), 533 n, 534 e86_get_ax (sim->cpu), e86_get_bx (sim->cpu), 535 e86_get_cx (sim->cpu), e86_get_dx (sim->cpu), 536 e86_get_ds (sim->cpu), e86_get_es (sim->cpu) 537 ); 538 } 539} 540 541static 542void pce_op_undef (void *ext, unsigned char op1, unsigned char op2) 543{ 544 rc759_t *sim; 545 546 sim = ext; 547 548 pce_log (MSG_DEB, "%04X:%04X: undefined operation [%02X %02x]\n", 549 e86_get_cs (sim->cpu), e86_get_ip (sim->cpu), op1, op2 550 ); 551 552 pce_usleep (100000UL); 553 554 trm_check (sim->trm); 555} 556 557 558static 559void rc759_cmd_c (cmd_t *cmd, rc759_t *sim) 560{ 561 unsigned long cnt; 562 563 cnt = 1; 564 565 cmd_match_uint32 (cmd, &cnt); 566 567 if (!cmd_match_end (cmd)) { 568 return; 569 } 570 571 rc759_clock_discontinuity (sim); 572 573 while (cnt > 0) { 574 rc759_clock (sim, 1); 575 cnt -= 1; 576 } 577 578 print_state (sim); 579} 580 581static 582void rc759_cmd_g_b (cmd_t *cmd, rc759_t *sim) 583{ 584 unsigned long seg, ofs; 585 breakpoint_t *bp; 586 587 while (cmd_match_uint32 (cmd, &seg)) { 588 if (cmd_match (cmd, ":")) { 589 if (!cmd_match_uint32 (cmd, &ofs)) { 590 cmd_error (cmd, "expecting offset"); 591 return; 592 } 593 594 bp = bp_segofs_new (seg, ofs); 595 } 596 else { 597 bp = bp_addr_new (seg); 598 } 599 600 bps_bp_add (&sim->bps, bp); 601 } 602 603 if (!cmd_match_end (cmd)) { 604 return; 605 } 606 607 pce_start (&sim->brk); 608 609 rc759_clock_discontinuity (sim); 610 611 while (1) { 612 rc759_exec (sim); 613 614 if (rc759_check_break (sim)) { 615 break; 616 } 617 } 618 619 pce_stop(); 620} 621 622static 623void rc759_cmd_g_far (cmd_t *cmd, rc759_t *sim) 624{ 625 unsigned short seg; 626 627 if (!cmd_match_end (cmd)) { 628 return; 629 } 630 631 seg = e86_get_cs (sim->cpu); 632 633 pce_start (&sim->brk); 634 635 rc759_clock_discontinuity (sim); 636 637 while (1) { 638 rc759_exec (sim); 639 640 if (e86_get_cs (sim->cpu) != seg) { 641 print_state (sim); 642 break; 643 } 644 645 if (rc759_check_break (sim)) { 646 break; 647 } 648 } 649 650 pce_stop(); 651} 652 653static 654void rc759_cmd_g (cmd_t *cmd, rc759_t *sim) 655{ 656 if (cmd_match (cmd, "b")) { 657 rc759_cmd_g_b (cmd, sim); 658 } 659 else if (cmd_match (cmd, "far")) { 660 rc759_cmd_g_far (cmd, sim); 661 } 662 else { 663 if (!cmd_match_end (cmd)) { 664 return; 665 } 666 667 rc759_run (sim); 668 } 669} 670 671static 672void rc759_cmd_hm (cmd_t *cmd) 673{ 674 pce_puts ( 675 "emu.config.save <filename>\n" 676 "emu.exit\n" 677 "emu.stop\n" 678 "emu.pause \"0\" | \"1\"\n" 679 "emu.pause.toggle\n" 680 "emu.reset\n" 681 "\n" 682 "emu.cpu.speed <factor>\n" 683 "emu.cpu.speed.step <adjustment>\n" 684 "\n" 685 "emu.parport1.driver <driver>\n" 686 "emu.parport1.file <filename>\n" 687 "emu.parport2.driver <driver>\n" 688 "emu.parport2.file <filename>\n" 689 "\n" 690 "emu.term.fullscreen \"0\" | \"1\"\n" 691 "emu.term.fullscreen.toggle\n" 692 "emu.term.grab\n" 693 "emu.term.release\n" 694 "emu.term.screenshot [<filename>]\n" 695 "emu.term.title <title>\n" 696 "\n" 697 ); 698 699 msg_dsk_print_help(); 700} 701 702static 703void rc759_cmd_i (cmd_t *cmd, rc759_t *sim) 704{ 705 int word; 706 unsigned short port; 707 708 if (cmd_match (cmd, "w")) { 709 word = 1; 710 } 711 else if (cmd_match (cmd, "b")) { 712 word = 0; 713 } 714 else { 715 word = 0; 716 } 717 718 if (!cmd_match_uint16 (cmd, &port)) { 719 cmd_error (cmd, "need a port address"); 720 return; 721 } 722 723 if (!cmd_match_end (cmd)) { 724 return; 725 } 726 727 if (word) { 728 pce_printf ("%04X: %04X\n", port, e86_get_prt16 (sim->cpu, port)); 729 } 730 else { 731 pce_printf ("%04X: %02X\n", port, e86_get_prt8 (sim->cpu, port)); 732 } 733} 734 735static 736void rc759_cmd_key (cmd_t *cmd, rc759_t *sim) 737{ 738 unsigned i; 739 unsigned event; 740 pce_key_t key; 741 char str[256]; 742 743 while (cmd_match_str (cmd, str, 256)) { 744 i = 0; 745 746 event = PCE_KEY_EVENT_DOWN; 747 748 if (str[0] == '+') { 749 i += 1; 750 } 751 else if (str[0] == '-') { 752 i += 1; 753 event = PCE_KEY_EVENT_UP; 754 } 755 756 key = pce_key_from_string (str + i); 757 758 if (key == PCE_KEY_NONE) { 759 pce_printf ("unknown key: %s\n", str); 760 } 761 else { 762 pce_printf ("key: %s%s\n", 763 (event == PCE_KEY_EVENT_DOWN) ? "+" : "-", 764 str + i 765 ); 766 767 rc759_kbd_set_key (&sim->kbd, event, key); 768 } 769 } 770 771 if (!cmd_match_end (cmd)) { 772 return; 773 } 774} 775 776static 777void rc759_cmd_log_int_l (cmd_t *cmd, rc759_t *sim) 778{ 779 unsigned i; 780 const char *str; 781 782 for (i = 0; i < 256; i++) { 783 str = rc759_intlog_get (sim, i); 784 785 if (str != NULL) { 786 pce_printf ("%02X: %s\n", i, str); 787 } 788 } 789} 790 791static 792void rc759_cmd_log_int (cmd_t *cmd, rc759_t *sim) 793{ 794 unsigned short n; 795 char buf[256]; 796 797 if (cmd_match_eol (cmd)) { 798 rc759_cmd_log_int_l (cmd, sim); 799 return; 800 } 801 802 if (cmd_match (cmd, "l")) { 803 rc759_cmd_log_int_l (cmd, sim); 804 return; 805 } 806 807 if (!cmd_match_uint16 (cmd, &n)) { 808 cmd_error (cmd, "need an interrupt number"); 809 return; 810 } 811 812 if (cmd_match_eol (cmd)) { 813 rc759_intlog_set (sim, n, NULL); 814 pce_printf ("%02X: <deleted>\n", n); 815 return; 816 } 817 818 if (!cmd_match_str (cmd, buf, 256)) { 819 cmd_error (cmd, "need an expression"); 820 return; 821 } 822 823 pce_printf ("%02X: %s\n", n, buf); 824 825 rc759_intlog_set (sim, n, buf); 826} 827 828static 829void rc759_cmd_log (cmd_t *cmd, rc759_t *sim) 830{ 831 if (cmd_match (cmd, "int")) { 832 rc759_cmd_log_int (cmd, sim); 833 } 834 else { 835 cmd_error (cmd, "log what?"); 836 } 837} 838 839static 840int rc759_cmd_nv_match_addr (cmd_t *cmd, unsigned short *addr) 841{ 842 if (cmd_match (cmd, "boot")) { 843 *addr = 0x19; 844 } 845 else if (cmd_match (cmd, "color")) { 846 *addr = 0x16; 847 } 848 else if (cmd_match (cmd, "cursor")) { 849 *addr = 0x13; 850 } 851 else if (cmd_match (cmd, "mdelay")) { 852 *addr = 0x14; 853 } 854 else if (cmd_match (cmd, "mdisk")) { 855 *addr = 0x1b; 856 } 857 else if (cmd_match (cmd, "scroll")) { 858 *addr = 0x12; 859 } 860 else if (cmd_match (cmd, "year")) { 861 *addr = 0x18; 862 } 863 else if (cmd_match_uint16 (cmd, addr)) { 864 ; 865 } 866 else { 867 cmd_error (cmd, "need an address"); 868 return (0); 869 } 870 871 return (1); 872} 873 874static 875void rc759_cmd_nvget (cmd_t *cmd, rc759_t *sim) 876{ 877 unsigned short addr, cnt, val; 878 879 if (!rc759_cmd_nv_match_addr (cmd, &addr)) { 880 return; 881 } 882 883 if (!cmd_match_uint16 (cmd, &cnt)) { 884 cnt = 1; 885 } 886 887 while (cnt--) { 888 val = rc759_nvm_get_uint8 (&sim->nvm, addr); 889 pce_printf ("NVM: %03X -> %02X\n", addr, val); 890 addr += 1; 891 } 892 893 cmd_match_end (cmd); 894} 895 896static 897void rc759_cmd_nvset (cmd_t *cmd, rc759_t *sim) 898{ 899 unsigned short addr, val; 900 901 if (!rc759_cmd_nv_match_addr (cmd, &addr)) { 902 return; 903 } 904 905 while (cmd_match_uint16 (cmd, &val)) { 906 pce_printf ("NVM: %03X <- %02X\n", addr, val); 907 rc759_nvm_set_uint8 (&sim->nvm, addr, val); 908 addr += 1; 909 } 910 911 cmd_match_end (cmd); 912} 913 914static 915void rc759_cmd_nvsum (cmd_t *cmd, rc759_t *sim) 916{ 917 unsigned v1, v2; 918 919 v1 = rc759_nvm_get_uint8 (&sim->nvm, 0); 920 rc759_nvm_fix_checksum (&sim->nvm); 921 v2 = rc759_nvm_get_uint8 (&sim->nvm, 0); 922 923 if (v1 != v2) { 924 pce_printf ("NVM: %03X <- %02X\n", 0, v2); 925 } 926 else { 927 pce_printf ("NVM: %03X -> %02X\n", 0, v1); 928 } 929 930 cmd_match_end (cmd); 931} 932 933static 934void rc759_cmd_nv (cmd_t *cmd, rc759_t *sim) 935{ 936 if (cmd_match (cmd, "set")) { 937 rc759_cmd_nvset (cmd, sim); 938 } 939 else if (cmd_match (cmd, "get")) { 940 rc759_cmd_nvget (cmd, sim); 941 } 942 else if (cmd_match (cmd, "sum")) { 943 rc759_cmd_nvsum (cmd, sim); 944 } 945 else { 946 cmd_error (cmd, "nv: unknown command"); 947 } 948} 949 950static 951void rc759_cmd_o (cmd_t *cmd, rc759_t *sim) 952{ 953 int word; 954 unsigned short port, val; 955 956 if (cmd_match (cmd, "w")) { 957 word = 1; 958 } 959 else if (cmd_match (cmd, "b")) { 960 word = 0; 961 } 962 else { 963 word = 0; 964 } 965 966 if (!cmd_match_uint16 (cmd, &port)) { 967 cmd_error (cmd, "need a port address"); 968 return; 969 } 970 971 if (!cmd_match_uint16 (cmd, &val)) { 972 cmd_error (cmd, "need a value"); 973 return; 974 } 975 976 if (!cmd_match_end (cmd)) { 977 return; 978 } 979 980 if (word) { 981 e86_set_prt16 (sim->cpu, port, val); 982 } 983 else { 984 e86_set_prt8 (sim->cpu, port, val); 985 } 986} 987 988static 989void rc759_cmd_pqc (cmd_t *cmd, rc759_t *sim) 990{ 991 if (!cmd_match_end (cmd)) { 992 return; 993 } 994 995 e86_pq_init (sim->cpu); 996} 997 998static 999void rc759_cmd_pqs (cmd_t *cmd, rc759_t *sim) 1000{ 1001 unsigned i; 1002 1003 if (!cmd_match_end (cmd)) { 1004 return; 1005 } 1006 1007 pce_puts ("PQ:"); 1008 1009 for (i = 0; i < sim->cpu->pq_cnt; i++) { 1010 pce_printf (" %02X", sim->cpu->pq[i]); 1011 } 1012 1013 pce_puts ("\n"); 1014} 1015 1016static 1017void rc759_cmd_pqf (cmd_t *cmd, rc759_t *sim) 1018{ 1019 if (!cmd_match_end (cmd)) { 1020 return; 1021 } 1022 1023 e86_pq_fill (sim->cpu); 1024} 1025 1026static 1027void rc759_cmd_pq (cmd_t *cmd, rc759_t *sim) 1028{ 1029 if (cmd_match (cmd, "c")) { 1030 rc759_cmd_pqc (cmd, sim); 1031 } 1032 else if (cmd_match (cmd, "f")) { 1033 rc759_cmd_pqf (cmd, sim); 1034 } 1035 else if (cmd_match (cmd, "s")) { 1036 rc759_cmd_pqs (cmd, sim); 1037 } 1038 else if (cmd_match_eol (cmd)) { 1039 rc759_cmd_pqs (cmd, sim); 1040 } 1041 else { 1042 cmd_error (cmd, "pq: unknown command (%s)\n"); 1043 } 1044} 1045 1046static 1047void rc759_cmd_p (cmd_t *cmd, rc759_t *sim) 1048{ 1049 unsigned short seg, ofs; 1050 unsigned long i, n; 1051 int brk; 1052 e86_disasm_t op; 1053 1054 n = 1; 1055 1056 cmd_match_uint32 (cmd, &n); 1057 1058 if (!cmd_match_end (cmd)) { 1059 return; 1060 } 1061 1062 brk = 0; 1063 1064 pce_start (&sim->brk); 1065 1066 sim->current_int &= 0xff; 1067 1068 rc759_clock_discontinuity (sim); 1069 1070 for (i = 0; i < n; i++) { 1071 e86_disasm_cur (sim->cpu, &op); 1072 1073 seg = e86_get_cs (sim->cpu); 1074 ofs = e86_get_ip (sim->cpu); 1075 1076 while ((e86_get_cs (sim->cpu) == seg) && (e86_get_ip (sim->cpu) == ofs)) { 1077 rc759_clock (sim, 1); 1078 1079 if (rc759_check_break (sim)) { 1080 brk = 1; 1081 break; 1082 } 1083 } 1084 1085 if (brk) { 1086 break; 1087 } 1088 1089 if (op.flags & (E86_DFLAGS_CALL | E86_DFLAGS_LOOP)) { 1090 unsigned short ofs2 = ofs + op.dat_n; 1091 1092 while ((e86_get_cs (sim->cpu) != seg) || (e86_get_ip (sim->cpu) != ofs2)) { 1093 rc759_clock (sim, 1); 1094 1095 if (rc759_check_break (sim)) { 1096 brk = 1; 1097 break; 1098 } 1099 } 1100 } 1101 1102 if (brk) { 1103 break; 1104 } 1105 1106 if (rc759_check_break (sim)) { 1107 break; 1108 } 1109 } 1110 1111 pce_stop(); 1112 1113 print_state (sim); 1114} 1115 1116static 1117void rc759_cmd_r (cmd_t *cmd, rc759_t *sim) 1118{ 1119 unsigned long val; 1120 char sym[256]; 1121 1122 if (cmd_match_eol (cmd)) { 1123 print_state_cpu (sim->cpu); 1124 return; 1125 } 1126 1127 if (!cmd_match_ident (cmd, sym, 256)) { 1128 pce_printf ("missing register\n"); 1129 return; 1130 } 1131 1132 if (e86_get_reg (sim->cpu, sym, &val)) { 1133 pce_printf ("bad register (%s)\n", sym); 1134 return; 1135 } 1136 1137 if (cmd_match_eol (cmd)) { 1138 pce_printf ("%04lX\n", val); 1139 return; 1140 } 1141 1142 if (!cmd_match_uint32 (cmd, &val)) { 1143 pce_printf ("missing value\n"); 1144 return; 1145 } 1146 1147 if (!cmd_match_end (cmd)) { 1148 return; 1149 } 1150 1151 e86_set_reg (sim->cpu, sym, val); 1152 1153 print_state (sim); 1154} 1155 1156static 1157void rc759_cmd_set (cmd_t *cmd, rc759_t *sim) 1158{ 1159 unsigned short val; 1160 char str[256]; 1161 1162 if (!cmd_match_str (cmd, str, 256)) { 1163 cmd_error (cmd, "missing signal\n"); 1164 return; 1165 } 1166 1167 if (!cmd_match_uint16 (cmd, &val)) { 1168 cmd_error (cmd, "missing value\n"); 1169 return; 1170 } 1171 1172 if (strcmp (str, "pic.irq0") == 0) { 1173 e8259_set_irq0 (&sim->pic, val); 1174 } 1175 else if (strcmp (str, "pic.irq1") == 0) { 1176 e8259_set_irq1 (&sim->pic, val); 1177 } 1178 else if (strcmp (str, "pic.irq2") == 0) { 1179 e8259_set_irq2 (&sim->pic, val); 1180 } 1181 else if (strcmp (str, "pic.irq3") == 0) { 1182 e8259_set_irq3 (&sim->pic, val); 1183 } 1184 else if (strcmp (str, "pic.irq4") == 0) { 1185 e8259_set_irq4 (&sim->pic, val); 1186 } 1187 else if (strcmp (str, "pic.irq5") == 0) { 1188 e8259_set_irq5 (&sim->pic, val); 1189 } 1190 else if (strcmp (str, "pic.irq6") == 0) { 1191 e8259_set_irq6 (&sim->pic, val); 1192 } 1193 else if (strcmp (str, "pic.irq7") == 0) { 1194 e8259_set_irq7 (&sim->pic, val); 1195 } 1196 else { 1197 pce_printf ("unknown signal (%s)\n", str); 1198 } 1199 1200 cmd_match_end (cmd); 1201} 1202 1203static 1204void rc759_cmd_s (cmd_t *cmd, rc759_t *sim) 1205{ 1206 if (cmd_match_eol (cmd)) { 1207 print_state (sim); 1208 return; 1209 } 1210 1211 while (!cmd_match_eol (cmd)) { 1212 if (cmd_match (cmd, "rc759")) { 1213 print_state_rc759 (sim); 1214 } 1215 else if (cmd_match (cmd, "cpu")) { 1216 print_state_cpu (sim->cpu); 1217 } 1218 else if (cmd_match (cmd, "disks")) { 1219 dsks_print_info (sim->dsks); 1220 } 1221 else if (cmd_match (cmd, "dma")) { 1222 print_state_dma (&sim->dma); 1223 } 1224 else if (cmd_match (cmd, "fdc")) { 1225 print_state_fdc (&sim->fdc); 1226 } 1227 else if (cmd_match (cmd, "icu")) { 1228 print_state_icu (&sim->icu); 1229 } 1230 else if (cmd_match (cmd, "mem")) { 1231 print_state_mem (sim); 1232 } 1233 else if (cmd_match (cmd, "ports")) { 1234 print_state_ports (sim); 1235 } 1236 else if (cmd_match (cmd, "pic")) { 1237 print_state_pic (&sim->pic); 1238 } 1239 else if (cmd_match (cmd, "ppi")) { 1240 print_state_ppi (&sim->ppi); 1241 } 1242 else if (cmd_match (cmd, "tcu")) { 1243 print_state_tcu (&sim->tcu); 1244 } 1245 else if (cmd_match (cmd, "video")) { 1246 print_state_video (&sim->crt); 1247 } 1248 else { 1249 cmd_error (cmd, "unknown component (%s)\n"); 1250 return; 1251 } 1252 } 1253} 1254 1255static 1256void rc759_cmd_t (cmd_t *cmd, rc759_t *sim) 1257{ 1258 unsigned long i, n; 1259 1260 n = 1; 1261 1262 cmd_match_uint32 (cmd, &n); 1263 1264 if (!cmd_match_end (cmd)) { 1265 return; 1266 } 1267 1268 pce_start (&sim->brk); 1269 1270 rc759_clock_discontinuity (sim); 1271 1272 for (i = 0; i < n; i++) { 1273 rc759_exec (sim); 1274 1275 if (rc759_check_break (sim)) { 1276 break; 1277 } 1278 } 1279 1280 pce_stop(); 1281 1282 print_state (sim); 1283} 1284 1285static 1286void rc759_cmd_u (cmd_t *cmd, rc759_t *sim) 1287{ 1288 unsigned short seg, ofs, cnt, mode; 1289 static unsigned int first = 1; 1290 static unsigned short sseg = 0; 1291 static unsigned short sofs = 0; 1292 e86_disasm_t op; 1293 char str[256]; 1294 1295 if (first) { 1296 first = 0; 1297 sseg = e86_get_cs (sim->cpu); 1298 sofs = e86_get_ip (sim->cpu); 1299 } 1300 1301 seg = sseg; 1302 ofs = sofs; 1303 cnt = 16; 1304 mode = 0; 1305 1306 if (cmd_match_uint16_16 (cmd, &seg, &ofs)) { 1307 cmd_match_uint16 (cmd, &cnt); 1308 } 1309 1310 cmd_match_uint16 (cmd, &mode); 1311 1312 if (!cmd_match_end (cmd)) { 1313 return; 1314 } 1315 1316 while (cnt > 0) { 1317 e86_disasm_mem (sim->cpu, &op, seg, ofs); 1318 disasm_str (str, &op); 1319 1320 pce_printf ("%04X:%04X %s\n", seg, ofs, str); 1321 1322 ofs = (ofs + op.dat_n) & 0xffff; 1323 1324 if (mode == 0) { 1325 cnt -= 1; 1326 } 1327 else { 1328 cnt = (cnt < op.dat_n) ? 0 : (cnt - op.dat_n); 1329 } 1330 } 1331 1332 sseg = seg; 1333 sofs = ofs; 1334} 1335 1336int rc759_cmd (rc759_t *sim, cmd_t *cmd) 1337{ 1338 if (sim->trm != NULL) { 1339 trm_check (sim->trm); 1340 } 1341 1342 if (cmd_match (cmd, "b")) { 1343 cmd_do_b (cmd, &sim->bps); 1344 } 1345 else if (cmd_match (cmd, "c")) { 1346 rc759_cmd_c (cmd, sim); 1347 } 1348 else if (cmd_match (cmd, "g")) { 1349 rc759_cmd_g (cmd, sim); 1350 } 1351 else if (cmd_match (cmd, "hm")) { 1352 rc759_cmd_hm (cmd); 1353 } 1354 else if (cmd_match (cmd, "i")) { 1355 rc759_cmd_i (cmd, sim); 1356 } 1357 else if (cmd_match (cmd, "key")) { 1358 rc759_cmd_key (cmd, sim); 1359 } 1360 else if (cmd_match (cmd, "log")) { 1361 rc759_cmd_log (cmd, sim); 1362 } 1363 else if (cmd_match (cmd, "nv")) { 1364 rc759_cmd_nv (cmd, sim); 1365 } 1366 else if (cmd_match (cmd, "o")) { 1367 rc759_cmd_o (cmd, sim); 1368 } 1369 else if (cmd_match (cmd, "pq")) { 1370 rc759_cmd_pq (cmd, sim); 1371 } 1372 else if (cmd_match (cmd, "p")) { 1373 rc759_cmd_p (cmd, sim); 1374 } 1375 else if (cmd_match (cmd, "r")) { 1376 rc759_cmd_r (cmd, sim); 1377 } 1378 else if (cmd_match (cmd, "set")) { 1379 rc759_cmd_set (cmd, sim); 1380 } 1381 else if (cmd_match (cmd, "s")) { 1382 rc759_cmd_s (cmd, sim); 1383 } 1384 else if (cmd_match (cmd, "t")) { 1385 rc759_cmd_t (cmd, sim); 1386 } 1387 else if (cmd_match (cmd, "u")) { 1388 rc759_cmd_u (cmd, sim); 1389 } 1390 else { 1391 return (1); 1392 } 1393 1394 return (0); 1395} 1396 1397void rc759_cmd_init (rc759_t *sim, monitor_t *mon) 1398{ 1399 mon_cmd_add (mon, par_cmd, sizeof (par_cmd) / sizeof (par_cmd[0])); 1400 mon_cmd_add_bp (mon); 1401 1402 sim->cpu->op_ext = sim; 1403 1404 sim->cpu->op_int = pce_op_int; 1405 sim->cpu->op_undef = pce_op_undef; 1406}