home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / emulator / unix / z80pack / z80sim / simctl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-11  |  22.9 KB  |  1,054 lines

  1. /*
  2.  * Z80SIM  -  a    Z80-CPU    simulator
  3.  *
  4.  * Copyright (C) 1987-92 by Udo Munk
  5.  *
  6.  * This modul contains the user interface, a full qualified ICE,
  7.  * for the Z80-CPU simulation. This modul is released to the public domain,
  8.  * and may be modified by user.
  9.  *
  10.  * History:
  11.  * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
  12.  * 11-JAN-89 Release 1.1
  13.  * 08-FEB-89 Release 1.2
  14.  * 13-MAR-89 Release 1.3
  15.  * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
  16.  * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
  17.  * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
  18.  *             and some optimization
  19.  * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0
  20.  */
  21.  
  22. /*
  23.  *    This modul is an ICE type user interface to debug Z80 programs
  24.  *    on a host system.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #if defined(COHERENT) && !defined(_I386)
  29. #include <sys/fcntl.h>
  30. #else
  31. #include <fcntl.h>
  32. #endif
  33. #ifndef COHERENT
  34. #include <memory.h>
  35. #endif
  36. #include <ctype.h>
  37. #include <signal.h>
  38. #include "sim.h"
  39. #include "simglb.h"
  40.  
  41. /*
  42.  *    The function "mon()" is the dialog user interface, called
  43.  *    from the simulation just after program start.
  44.  */
  45. mon()
  46. {
  47.     register int eoj = 1;
  48.     static char cmd[LENCMD];
  49.  
  50.     if (x_flag) {
  51.         if (do_getfile(xfn) == 0)
  52.             do_go("");
  53.     }
  54.     while (eoj) {
  55.         next:
  56.         printf(">>> ");
  57.         fflush(stdout);
  58.         if (fgets(cmd, LENCMD, stdin) == NULL) {
  59.             putchar('\n');
  60.             goto next;
  61.         }
  62.         switch (*cmd) {
  63.         case '\n':
  64.             do_step();
  65.             break;
  66.         case 't':
  67.             do_trace(cmd + 1);
  68.             break;
  69.         case 'g':
  70.             do_go(cmd + 1);
  71.             break;
  72.         case 'd':
  73.             do_dump(cmd + 1);
  74.             break;
  75. #if !defined(COHERENT) || defined(_I386)
  76.         case 'l':
  77.             do_list(cmd + 1);
  78.             break;
  79. #endif
  80.         case 'm':
  81.             do_modify(cmd +    1);
  82.             break;
  83.         case 'f':
  84.             do_fill(cmd + 1);
  85.             break;
  86. #if !defined(COHERENT) || defined(_I386)
  87.         case 'v':
  88.             do_move(cmd + 1);
  89.             break;
  90. #endif
  91.         case 'x':
  92.             do_reg(cmd + 1);
  93.             break;
  94.         case 'p':
  95.             do_port(cmd + 1);
  96.             break;
  97.         case 'b':
  98.             do_break(cmd + 1);
  99.             break;
  100.         case 'h':
  101.             do_hist(cmd + 1);
  102.             break;
  103.         case 'z':
  104.             do_count(cmd + 1);
  105.             break;
  106. #if !defined(COHERENT) || defined(_I386)
  107.         case 'c':
  108.             do_clock();
  109.             break;
  110. #endif
  111.         case 's':
  112.             do_show();
  113.             break;
  114.         case '?':
  115.             do_help();
  116.             break;
  117.         case 'r':
  118.             do_getfile(cmd + 1);
  119.             break;
  120.         case '!':
  121.             do_unix(cmd + 1);
  122.             break;
  123.         case 'q':
  124.             eoj = 0;
  125.             break;
  126.         default:
  127.             puts("what??");
  128.             break;
  129.         }
  130.     }
  131. }
  132.  
  133. /*
  134.  *    Execute a single step
  135.  */
  136. static do_step()
  137. {
  138. #if !defined(COHERENT) || defined(_I386)
  139.     BYTE *p;
  140. #endif
  141.  
  142.     cpu_state = SINGLE_STEP;
  143.     cpu_error = NONE;
  144.     cpu();
  145.     if (cpu_error == OPHALT)
  146.         handel_break();
  147.     cpu_err_msg();
  148.     print_head();
  149.     print_reg();
  150. #if !defined(COHERENT) || defined(_I386)
  151.     p = PC;
  152.     disass(&p, p - ram);
  153. #endif
  154. }
  155.  
  156. /*
  157.  *    Execute several steps with trace output
  158.  */
  159. static do_trace(s)
  160. register char *s;
  161. {
  162.     register int count, i;
  163.  
  164.     while (isspace(*s))
  165.         s++;
  166.     if (*s == '\0')
  167.         count =    20;
  168.     else
  169.         count =    atoi(s);
  170.     cpu_state = SINGLE_STEP;
  171.     cpu_error = NONE;
  172.     print_head();
  173.     print_reg();
  174.     for (i = 0; i <    count; i++) {
  175.         cpu();
  176.         print_reg();
  177.         if (cpu_error) {
  178.             if (cpu_error == OPHALT) {
  179.                 if (!handel_break()) {
  180.                     break;
  181.                 }
  182.             } else
  183.                 break;
  184.         }
  185.     }
  186.     cpu_err_msg();
  187. }
  188.  
  189. /*
  190.  *    Run the CPU emulation endless
  191.  */
  192. static do_go(s)
  193. register char *s;
  194. {
  195.     while (isspace(*s))
  196.         s++;
  197.     if (isxdigit(*s))
  198.         PC = ram + exatoi(s);
  199.     cont:
  200.     cpu_state = CONTIN_RUN;
  201.     cpu_error = NONE;
  202.     cpu();
  203.     if (cpu_error == OPHALT)
  204.         if (handel_break())
  205.             if (!cpu_error)
  206.                 goto cont;
  207.     cpu_err_msg();
  208.     print_head();
  209.     print_reg();
  210. }
  211.  
  212. /*
  213.  *    Handling of software breakpoints (HALT opcode):
  214.  *    Behandlung von Software    Breakpoints (HALT Op-Code)
  215.  *    Output:    0 breakpoint or other HALT opcode reached (stop)
  216.  *        1 breakpoint reached, passcounter not reached (continue)
  217.  */
  218. static handel_break()
  219. {
  220. #ifdef SBSIZE
  221.     register int i;
  222.     int break_address;
  223.  
  224.     for (i = 0; i <    SBSIZE;    i++)    /* search for breakpoint */
  225.         if (soft[i].sb_adr == PC - ram - 1)
  226.             goto was_softbreak;
  227.     return(0);
  228.     was_softbreak:
  229. #ifdef HISIZE
  230.     h_next--;            /* correct history */
  231.     if (h_next < 0)
  232.         h_next = 0;
  233. #endif
  234.     break_address =    PC - ram - 1;    /* store adr of breakpoint */
  235.     cpu_error = NONE;        /* HALT    was a breakpoint */
  236.     PC--;                /* substitute HALT opcode by */
  237.     *PC = soft[i].sb_oldopc;    /* original opcode */
  238.     cpu_state = SINGLE_STEP;    /* and execute it */
  239.     cpu();
  240.     *(ram +    soft[i].sb_adr)    = 0x76;    /* restore HALT    opcode again */
  241.     soft[i].sb_passcount++;        /* increment passcounter */
  242.     if (soft[i].sb_passcount != soft[i].sb_pass)
  243.         return(1);        /* pass    not reached, continue */
  244.     printf("Software breakpoint %d reached at %04x\n", i, break_address);
  245.     soft[i].sb_passcount = 0;    /* reset passcounter */
  246.     return(0);            /* pass    reached, stop */
  247. #endif
  248. }
  249.  
  250. /*
  251.  *    Memory dump
  252.  */
  253. static do_dump(s)
  254. register char *s;
  255. {
  256.     register int i,    j;
  257.     BYTE c;
  258.  
  259.     while (isspace(*s))
  260.         s++;
  261.     if (isxdigit(*s)) {
  262. #if defined(COHERENT) && !defined(_I386)
  263.         if (exatoi(s) < 0) {
  264.             puts(adr_err);
  265.             return;
  266.         }
  267. #endif
  268.         wrk_ram    = ram +    exatoi(s) - exatoi(s) %    16;
  269.     }
  270.     printf("Adr    ");
  271.     for (i = 0; i <    16; i++)
  272.         printf("%02x ",    i);
  273.     puts(" ASCII");
  274.     for (i = 0; i <    16; i++) {
  275.         printf("%04x - ", wrk_ram - ram);
  276.         for (j = 0; j <    16; j++) {
  277.             printf("%02x ",    *wrk_ram);
  278.             wrk_ram++;
  279. #if !defined(COHERENT) || defined(_I386)
  280.             if (wrk_ram > ram + 65535)
  281. #else
  282.             if (wrk_ram > ram + 32767)
  283. #endif
  284.                 wrk_ram    = ram;
  285.         }
  286.         putchar('\t');
  287.         for (j = -16; j    < 0; j++)
  288.             printf("%c",((c    = *(wrk_ram+j))>=' ' &&    c<=0x7f) ? c : '.');
  289.         putchar('\n');
  290.     }
  291. }
  292.  
  293. #if !defined(COHERENT) || defined(_I386)
  294. /*
  295.  *    Disassemble
  296.  */
  297. static do_list(s)
  298. register char *s;
  299. {
  300.     register int i;
  301.  
  302.     while (isspace(*s))
  303.         s++;
  304.     if (isxdigit(*s))
  305.         wrk_ram    = ram +    exatoi(s);
  306.     for (i = 0; i <    10; i++) {
  307.         printf("%04x - ", wrk_ram - ram);
  308.         disass(&wrk_ram, wrk_ram - ram);
  309.         if (wrk_ram > ram + 65535)
  310.             wrk_ram    = ram;
  311.     }
  312. }
  313. #endif
  314.  
  315. /*
  316.  *    Memory modify
  317.  */
  318. static do_modify(s)
  319. register char *s;
  320. {
  321.     static char nv[LENCMD];
  322.  
  323.     while (isspace(*s))
  324.         s++;
  325.     if (isxdigit(*s)) {
  326. #if defined(COHERENT) && !defined(_I386)
  327.         if (exatoi(s) < 0) {
  328.             puts(adr_err);
  329.             return;
  330.         }
  331. #endif
  332.         wrk_ram    = ram +    exatoi(s);
  333.     }
  334.     for (;;) {
  335.         printf("%04x = %02x : ", wrk_ram - ram,    *wrk_ram);
  336.         fgets(nv, sizeof(nv), stdin);
  337.         if (nv[0] == '\n') {
  338.             wrk_ram++;
  339. #if !defined(COHERENT) || defined(_I386)
  340.             if (wrk_ram > ram + 32767)
  341. #else
  342.             if (wrk_ram > ram + 65535)
  343. #endif
  344.                 wrk_ram    = ram;
  345.             continue;
  346.         }
  347.         if (!isxdigit(nv[0]))
  348.             break;
  349.         *wrk_ram++ = exatoi(nv);
  350. #if !defined(COHERENT) || defined(_I386)
  351.         if (wrk_ram > ram + 32767)
  352. #else
  353.         if (wrk_ram > ram + 65535)
  354. #endif
  355.             wrk_ram    = ram;
  356.     }
  357. }
  358.  
  359. /*
  360.  *    Memory fill
  361.  */
  362. static do_fill(s)
  363. register char *s;
  364. {
  365.     register BYTE *p;
  366.     register int i;
  367.     register BYTE val;
  368.  
  369.     while (isspace(*s))
  370.         s++;
  371. #if defined(COHERENT) && !defined(_I386)
  372.     if (exatoi(s) < 0) {
  373.         puts(adr_err);
  374.         return;
  375.     }
  376. #endif
  377.     p = ram    + exatoi(s);
  378.     while (*s != ',' && *s != '\0')
  379.         s++;
  380.     if (*s)
  381.         i = exatoi(++s);
  382.     while (*s != ',' && *s != '\0')
  383.         s++;
  384.     if (*s)
  385.         val = exatoi(++s);
  386.     while (i--) {
  387.         *p++ = val;
  388. #if !defined(COHERENT) || defined(_I386)
  389.         if (p > ram + 32767)
  390. #else
  391.         if (p >    ram + 65535)
  392. #endif
  393.             p = ram;
  394.     }
  395. }
  396.  
  397. #if !defined(COHERENT) || defined(_I386)
  398. /*
  399.  *    Memory move
  400.  */
  401. static do_move(s)
  402. register char *s;
  403. {
  404.     register BYTE *p1, *p2;
  405.     register int count;
  406.  
  407.     while (isspace(*s))
  408.         s++;
  409.     p1 = ram + exatoi(s);
  410.     while (*s != ',' && *s != '\0')
  411.         s++;
  412.     if (*s)
  413.         p2 = ram + exatoi(++s);
  414.     while (*s != ',' && *s != '\0')
  415.         s++;
  416.     if (*s)
  417.         count =    exatoi(++s);
  418.     while (count--)    {
  419.         *p2++ =    *p1++;
  420.         if (p1 > ram + 65535)
  421.             p1 = ram;
  422.         if (p2 > ram + 65535)
  423.             p2 = ram;
  424.     }
  425. }
  426. #endif
  427.  
  428. /*
  429.  *    Port modify
  430.  */
  431. static do_port(s)
  432. register char *s;
  433. {
  434.     register BYTE port;
  435.     static char nv[LENCMD];
  436.     extern BYTE io_out(), io_in();
  437.  
  438.     while (isspace(*s))
  439.         s++;
  440.     port = exatoi(s);
  441.     printf("%02x = %02x : ", port, io_in(port));
  442.     fgets(nv, sizeof(nv), stdin);
  443.     if (isxdigit(*nv))
  444.         io_out(port, (BYTE) exatoi(nv));
  445. }
  446.  
  447. /*
  448.  *    Register modify
  449.  */
  450. static do_reg(s)
  451. register char *s;
  452. {
  453.     static char nv[LENCMD];
  454.  
  455.     while (isspace(*s))
  456.         s++;
  457.     if (*s == '\0')    {
  458.         print_head();
  459.         print_reg();
  460.     } else {
  461.         if (strncmp(s, "bc'", 3) == 0) {
  462.             printf("BC' = %04x : ",    B_ * 256 + C_);
  463.             fgets(nv, sizeof(nv), stdin);
  464.             B_ = (exatoi(nv) & 0xffff) / 256;
  465.             C_ = (exatoi(nv) & 0xffff) % 256;
  466.         } else if (strncmp(s, "de'", 3)    == 0) {
  467.             printf("DE' = %04x : ",    D_ * 256 + E_);
  468.             fgets(nv, sizeof(nv), stdin);
  469.             D_ = (exatoi(nv) & 0xffff) / 256;
  470.             E_ = (exatoi(nv) & 0xffff) % 256;
  471.         } else if (strncmp(s, "hl'", 3)    == 0) {
  472.             printf("HL' = %04x : ",    H_ * 256 + L_);
  473.             fgets(nv, sizeof(nv), stdin);
  474.             H_ = (exatoi(nv) & 0xffff) / 256;
  475.             L_ = (exatoi(nv) & 0xffff) % 256;
  476.         } else if (strncmp(s, "pc", 2) == 0) {
  477.             printf("PC = %04x : ", PC - ram);
  478.             fgets(nv, sizeof(nv), stdin);
  479.             PC = ram + (exatoi(nv) & 0xffff);
  480.         } else if (strncmp(s, "bc", 2) == 0) {
  481.             printf("BC = %04x : ", B * 256 + C);
  482.             fgets(nv, sizeof(nv), stdin);
  483.             B = (exatoi(nv)    & 0xffff) / 256;
  484.             C = (exatoi(nv)    & 0xffff) % 256;
  485.         } else if (strncmp(s, "de", 2) == 0) {
  486.             printf("DE = %04x : ", D * 256 + E);
  487.             fgets(nv, sizeof(nv), stdin);
  488.             D = (exatoi(nv)    & 0xffff) / 256;
  489.             E = (exatoi(nv)    & 0xffff) % 256;
  490.         } else if (strncmp(s, "hl", 2) == 0) {
  491.             printf("HL = %04x : ", H * 256 + L);
  492.             fgets(nv, sizeof(nv), stdin);
  493.             H = (exatoi(nv)    & 0xffff) / 256;
  494.             L = (exatoi(nv)    & 0xffff) % 256;
  495.         } else if (strncmp(s, "ix", 2) == 0) {
  496.             printf("IX = %04x : ", IX);
  497.             fgets(nv, sizeof(nv), stdin);
  498.             IX = exatoi(nv)    & 0xffff;
  499.         } else if (strncmp(s, "iy", 2) == 0) {
  500.             printf("IY = %04x : ", IY);
  501.             fgets(nv, sizeof(nv), stdin);
  502.             IY = exatoi(nv)    & 0xffff;
  503.         } else if (strncmp(s, "sp", 2) == 0) {
  504.             printf("SP = %04x : ", STACK - ram);
  505.             fgets(nv, sizeof(nv), stdin);
  506.             STACK =    ram + (exatoi(nv) & 0xffff);
  507.         } else if (strncmp(s, "fs", 2) == 0) {
  508.             printf("S-FLAG = %c : ", (F & S_FLAG) ?    '1' : '0');
  509.             fgets(nv, sizeof(nv), stdin);
  510.             F = (exatoi(nv)) ? (F |    S_FLAG)    : (F & ~S_FLAG);
  511.         } else if (strncmp(s, "fz", 2) == 0) {
  512.             printf("Z-FLAG = %c : ", (F & Z_FLAG) ?    '1' : '0');
  513.             fgets(nv, sizeof(nv), stdin);
  514.             F = (exatoi(nv)) ? (F |    Z_FLAG)    : (F & ~Z_FLAG);
  515.         } else if (strncmp(s, "fh", 2) == 0) {
  516.             printf("H-FLAG = %c : ", (F & H_FLAG) ?    '1' : '0');
  517.             fgets(nv, sizeof(nv), stdin);
  518.             F = (exatoi(nv)) ? (F |    H_FLAG)    : (F & ~H_FLAG);
  519.         } else if (strncmp(s, "fp", 2) == 0) {
  520.             printf("P-FLAG = %c : ", (F & P_FLAG) ?    '1' : '0');
  521.             fgets(nv, sizeof(nv), stdin);
  522.             F = (exatoi(nv)) ? (F |    P_FLAG)    : (F & ~P_FLAG);
  523.         } else if (strncmp(s, "fn", 2) == 0) {
  524.             printf("N-FLAG = %c : ", (F & N_FLAG) ?    '1' : '0');
  525.             fgets(nv, sizeof(nv), stdin);
  526.             F = (exatoi(nv)) ? (F |    N_FLAG)    : (F & ~N_FLAG);
  527.         } else if (strncmp(s, "fc", 2) == 0) {
  528.             printf("C-FLAG = %c : ", (F & C_FLAG) ?    '1' : '0');
  529.             fgets(nv, sizeof(nv), stdin);
  530.             F = (exatoi(nv)) ? (F |    C_FLAG)    : (F & ~C_FLAG);
  531.         } else if (strncmp(s, "a'", 2) == 0) {
  532.             printf("A' = %02x : ", A_);
  533.             fgets(nv, sizeof(nv), stdin);
  534.             A_ = exatoi(nv)    & 0xff;
  535.         } else if (strncmp(s, "f'", 2) == 0) {
  536.             printf("F' = %02x : ", F_);
  537.             fgets(nv, sizeof(nv), stdin);
  538.             F_ = exatoi(nv)    & 0xff;
  539.         } else if (strncmp(s, "b'", 2) == 0) {
  540.             printf("B' = %02x : ", B_);
  541.             fgets(nv, sizeof(nv), stdin);
  542.             B_ = exatoi(nv)    & 0xff;
  543.         } else if (strncmp(s, "c'", 2) == 0) {
  544.             printf("C' = %02x : ", C_);
  545.             fgets(nv, sizeof(nv), stdin);
  546.             C_ = exatoi(nv)    & 0xff;
  547.         } else if (strncmp(s, "d'", 2) == 0) {
  548.             printf("D' = %02x : ", D_);
  549.             fgets(nv, sizeof(nv), stdin);
  550.             D_ = exatoi(nv)    & 0xff;
  551.         } else if (strncmp(s, "e'", 2) == 0) {
  552.             printf("E' = %02x : ", E_);
  553.             fgets(nv, sizeof(nv), stdin);
  554.             E_ = exatoi(nv)    & 0xff;
  555.         } else if (strncmp(s, "h'", 2) == 0) {
  556.             printf("H' = %02x : ", H_);
  557.             fgets(nv, sizeof(nv), stdin);
  558.             H_ = exatoi(nv)    & 0xff;
  559.         } else if (strncmp(s, "l'", 2) == 0) {
  560.             printf("L' = %02x : ", L_);
  561.             fgets(nv, sizeof(nv), stdin);
  562.             L_ = exatoi(nv)    & 0xff;
  563.         } else if (strncmp(s, "i", 1) == 0) {
  564.             printf("I = %02x : ", I);
  565.             fgets(nv, sizeof(nv), stdin);
  566.             I = exatoi(nv) & 0xff;
  567.         } else if (strncmp(s, "a", 1) == 0) {
  568.             printf("A = %02x : ", A);
  569.             fgets(nv, sizeof(nv), stdin);
  570.             A = exatoi(nv) & 0xff;
  571.         } else if (strncmp(s, "f", 1) == 0) {
  572.             printf("F = %02x : ", F);
  573.             fgets(nv, sizeof(nv), stdin);
  574.             F = exatoi(nv) & 0xff;
  575.         } else if (strncmp(s, "b", 1) == 0) {
  576.             printf("B = %02x : ", B);
  577.             fgets(nv, sizeof(nv), stdin);
  578.             B = exatoi(nv) & 0xff;
  579.         } else if (strncmp(s, "c", 1) == 0) {
  580.             printf("C = %02x : ", C);
  581.             fgets(nv, sizeof(nv), stdin);
  582.             C = exatoi(nv) & 0xff;
  583.         } else if (strncmp(s, "d", 1) == 0) {
  584.             printf("D = %02x : ", D);
  585.             fgets(nv, sizeof(nv), stdin);
  586.             D = exatoi(nv) & 0xff;
  587.         } else if (strncmp(s, "e", 1) == 0) {
  588.             printf("E = %02x : ", E);
  589.             fgets(nv, sizeof(nv), stdin);
  590.             E = exatoi(nv) & 0xff;
  591.         } else if (strncmp(s, "h", 1) == 0) {
  592.             printf("H = %02x : ", H);
  593.             fgets(nv, sizeof(nv), stdin);
  594.             H = exatoi(nv) & 0xff;
  595.         } else if (strncmp(s, "l", 1) == 0) {
  596.             printf("L = %02x : ", L);
  597.             fgets(nv, sizeof(nv), stdin);
  598.             L = exatoi(nv) & 0xff;
  599.         } else
  600.             printf("can't change register %s\n", nv);
  601.         print_head();
  602.         print_reg();
  603.     }
  604. }
  605.  
  606. /*
  607.  *    Output header for the CPU registers
  608.  */
  609. static print_head()
  610. {
  611.     printf("\nPC   A  SZHPNC I  IFF BC   DE   HL   A'F' B'C' D'E' H'L' IX   IY   SP\n");
  612. }
  613.  
  614. /*
  615.  *    Output all CPU registers
  616.  */
  617. static print_reg()
  618. {
  619.     printf("%04x %02x ", PC    - ram, A);
  620.     printf("%c", F & S_FLAG    ? '1' :    '0');
  621.     printf("%c", F & Z_FLAG    ? '1' :    '0');
  622.     printf("%c", F & H_FLAG    ? '1' :    '0');
  623.     printf("%c", F & P_FLAG    ? '1' :    '0');
  624.     printf("%c", F & N_FLAG    ? '1' :    '0');
  625.     printf("%c", F & C_FLAG    ? '1' :    '0');
  626.     printf(" %02x ", I);
  627.     printf("%c", IFF & 1 ? '1' : '0');
  628.     printf("%c", IFF & 2 ? '1' : '0');
  629.     printf("  %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %04x %04x %04x\n",
  630.          B, C, D, E, H,    L, A_, F_, B_, C_, D_, E_, H_, L_, IX, IY, STACK - ram);
  631. }
  632.  
  633. /*
  634.  *    Software breakpoints
  635.  */
  636. static do_break(s)
  637. register char *s;
  638. {
  639. #ifndef    SBSIZE
  640.     puts("Sorry, no breakpoints available");
  641.     puts("Please recompile with SBSIZE defined in sim.h");
  642. #else
  643.     register int i;
  644.  
  645.     if (!break_flag) {
  646.         puts("Can't use softbreaks with -h option.");
  647.         return;
  648.     }
  649.     if (*s == '\n')    {
  650.         puts("No Addr Pass  Counter");
  651.         for (i = 0; i <    SBSIZE;    i++)
  652.             if (soft[i].sb_pass)
  653.                 printf("%02d %04x %05d %05d\n",    i,
  654.                 soft[i].sb_adr,soft[i].sb_pass,soft[i].sb_passcount);
  655.         return;
  656.     }
  657.     if (isxdigit(*s)) {
  658.         i = atoi(s++);
  659.         if (i >= SBSIZE) {
  660.             printf("breakpoint %d not available\n",    i);
  661.             return;
  662.         }
  663.     } else {
  664.         i = sb_next++;
  665.         if (sb_next == SBSIZE)
  666.             sb_next    = 0;
  667.     }
  668.     while (isspace(*s))
  669.         s++;
  670.     if (*s == 'c') {
  671.         *(ram +    soft[i].sb_adr)    = soft[i].sb_oldopc;
  672.         memset((char *)    &soft[i], 0, sizeof(struct softbreak));
  673.         return;
  674.     }
  675. #if defined(COHERENT) && !defined(_I386)
  676.     if (exatoi(s) < 0) {
  677.         puts(adr_err);
  678.         return;
  679.     }
  680. #endif
  681.     if (soft[i].sb_pass)
  682.         *(ram +    soft[i].sb_adr)    = soft[i].sb_oldopc;
  683.     soft[i].sb_adr = exatoi(s);
  684.     soft[i].sb_oldopc = *(ram + soft[i].sb_adr);
  685.     *(ram +    soft[i].sb_adr)    = 0x76;
  686.     while (!iscntrl(*s) && !ispunct(*s))
  687.         s++;
  688.     if (*s != ',')
  689.         soft[i].sb_pass    = 1;
  690.     else
  691.         soft[i].sb_pass    = exatoi(++s);
  692.     soft[i].sb_passcount = 0;
  693. #endif
  694. }
  695.  
  696. /*
  697.  *    History
  698.  */
  699. static do_hist(s)
  700. register char *s;
  701. {
  702. #ifndef    HISIZE
  703.     puts("Sorry, no history available");
  704.     puts("Please recompile with HISIZE defined in sim.h");
  705. #else
  706.     register int i,    l, b, e, c, sa;
  707.  
  708.     while (isspace(*s))
  709.         s++;
  710.     switch (*s) {
  711.     case 'c':
  712.         memset((char *)    his, 0,    sizeof(struct history) * HISIZE);
  713.         h_next = 0;
  714.         h_flag = 0;
  715.         break;
  716.     default:
  717.         if ((h_next == 0) && (h_flag ==    0)) {
  718.             puts("History memory is empty");
  719.             break;
  720.         }
  721.         e = h_next;
  722.         b = (h_flag) ? h_next +    1 : 0;
  723.         l = 0;
  724.         while (isspace(*s))
  725.             s++;
  726.         if (*s)
  727.             sa = exatoi(s);
  728.         else
  729.             sa = -1;
  730.         for (i = b; i != e; i++) {
  731.             if (i == HISIZE)
  732.                 i = 0;
  733.             if (sa != -1)
  734.                 if (his[i].h_adr < sa)
  735.                     continue;
  736.                 else
  737.                     sa = -1;
  738.             printf("%04x AF=%04x BC=%04x DE=%04x HL=%04x IX=%04x IY=%04x SP=%04x\n",
  739.                    his[i].h_adr, his[i].h_af, his[i].h_bc,
  740.                    his[i].h_de, his[i].h_hl, his[i].h_ix,
  741.                    his[i].h_iy, his[i].h_sp);
  742.             l++;
  743.             if (l == 20) {
  744.                 l = 0;
  745.                 printf("q = quit, else continue: ");
  746.                 c = getkey();
  747.                 putchar('\n');
  748.                 if (toupper(c) == 'Q')
  749.                     break;
  750.             }
  751.         }
  752.         break;
  753.     }
  754. #endif
  755. }
  756.  
  757. /*
  758.  *    Runtime measurement by counting the executed T states
  759.  */
  760. static do_count(s)
  761. register char *s;
  762. {
  763. #ifndef    WANT_TIM
  764.     puts("Sorry, no t-state count available");
  765.     puts("Please recompile with WANT_TIM defined in sim.h");
  766. #else
  767.     while (isspace(*s))
  768.         s++;
  769.     if (*s == '\0')    {
  770.         puts("start  stop  status  T-states");
  771.         printf("%04x   %04x    %s   %lu\n",
  772.         t_start    - ram, t_end - ram, t_flag ? "on ": "off", t_states);
  773.     } else {
  774.         t_start    = ram +    exatoi(s);
  775.         while (*s != ',' && *s != '\0')
  776.             s++;
  777.         if (*s)
  778.             t_end =    ram + exatoi(++s);
  779.         t_states = 0L;
  780.         t_flag = 0;
  781.     }
  782. #endif
  783. }
  784.  
  785. #if !defined(COHERENT) || defined(_I386)
  786. /*
  787.  *    Calculate the clock frequency of the emulated CPU:
  788.  *    into memory locations 0000H to 0002H the following
  789.  *    code will be stored:
  790.  *        LOOP: JP LOOP
  791.  *    It uses 10 T states for each execution. A 3 secound
  792.  *    timer is started and then the CPU. For every opcode
  793.  *    fetch the R register is incremented by one and after
  794.  *    the timer is down and stopps the emulation, the clock
  795.  *    speed of the CPU is calculated with:
  796.  *        f = R /    300000
  797.  */
  798. static do_clock()
  799. {
  800.     static BYTE save[3];
  801.     int timeout();
  802.     unsigned alarm();
  803.  
  804.     save[0]    = *(ram    + 0x0000);    /* save memory locations */
  805.     save[1]    = *(ram    + 0x0001);    /* 0000H - 0002H */
  806.     save[2]    = *(ram    + 0x0002);
  807.     *(ram +    0x0000)    = 0xc3;        /* store opcode JP 0000H at address */
  808.     *(ram +    0x0001)    = 0x00;        /* 0000H */
  809.     *(ram +    0x0002)    = 0x00;
  810.     PC = ram + 0x0000;        /* set PC to this code */
  811.     R = 0L;                /* clear refresh register */
  812.     cpu_state = CONTIN_RUN;        /* initialize CPU */
  813.     cpu_error = NONE;
  814.     signal(SIGALRM,    timeout);    /* initialize timer interrupt handler */
  815.     alarm(3);            /* start 3 secound timer */
  816.     cpu();                /* start CPU */
  817.     *(ram +    0x0000)    = save[0];    /* restore memory locations */
  818.     *(ram +    0x0001)    = save[1];    /* 0000H - 0002H */
  819.     *(ram +    0x0002)    = save[2];
  820.     if (cpu_error == NONE)
  821.         printf("clock frequency = %5.2f Mhz\n",    ((float) R) / 300000.0);
  822.     else
  823.         puts("Interrupted by user");
  824. }
  825.  
  826. /*
  827.  *    This function is the signal handler for the timer interrupt.
  828.  *    The CPU emulation is stopped here.
  829.  */
  830. static timeout()
  831. {
  832.     cpu_state = STOPPED;
  833. }
  834. #endif
  835.  
  836. /*
  837.  *    Output informations about compiling options
  838.  */
  839. static do_show()
  840. {
  841.     register int i;
  842.  
  843.     printf("Release: %s\n",    RELEASE);
  844. #ifdef HISIZE
  845.     i = HISIZE;
  846. #else
  847.     i = 0;
  848. #endif
  849.     printf("No. of entrys in history memory: %d\n",    i);
  850. #ifdef SBSIZE
  851.     i = SBSIZE;
  852. #else
  853.     i = 0;
  854. #endif
  855.     printf("No. of software breakpoints: %d\n", i);
  856. #ifdef WANT_SPC
  857.     i = 1;
  858. #else
  859.     i = 0;
  860. #endif
  861.     printf("Stackpointer turn around %schecked\n", i ? "" :    "not ");
  862. #ifdef WANT_PCC
  863.     i = 1;
  864. #else
  865.     i = 0;
  866. #endif
  867.     printf("Programcounter turn around %schecked\n", i ? ""    : "not ");
  868. #ifdef WANT_TIM
  869.     i = 1;
  870. #else
  871.     i = 0;
  872. #endif
  873.     printf("T-State counting %spossible\n",    i ? "" : "im");
  874. #ifdef CNTL_C
  875.     i = 1;
  876. #else
  877.     i = 0;
  878. #endif
  879.     printf("CPU simulation %sstopped on cntl-c\n", i ? "" :    "not ");
  880. #ifdef CNTL_BS
  881.     i = 1;
  882. #else
  883.     i = 0;
  884. #endif
  885.     printf("CPU simulation %sstopped on cntl-\\\n",    i ? "" : "not ");
  886. }
  887.  
  888. /*
  889.  *    Read a file into the memory of the emulated CPU.
  890.  *    The following file formats are supported:
  891.  *
  892.  *        binary images with Mostek header
  893.  */
  894. static do_getfile(s)
  895. register char *s;
  896. {
  897.     char fn[LENCMD];
  898.     BYTE fileb[5];
  899.     register char *pfn = fn;
  900.     int fd;
  901.     long lseek();
  902.  
  903.     while (isspace(*s))
  904.         s++;
  905.     while (*s != ',' && *s != '\n' && *s !=    '\0')
  906.         *pfn++ = *s++;
  907.     *pfn = '\0';
  908.     if (strlen(fn) == 0) {
  909.         puts("no input file given");
  910.         return 1;
  911.     }
  912.     if ((fd    = open(fn, O_RDONLY)) == -1) {
  913.         printf("can't open file %s\n", fn);
  914.         return 1;
  915.     }
  916.     if (*s == ',')
  917.         wrk_ram    = ram +    exatoi(++s);
  918.     else
  919.         wrk_ram    = NULL;
  920.     read(fd, (char *) fileb, 5); /*    read first 5 bytes of file */
  921.     if (*fileb == (BYTE) 0xff) {      /* Mostek header ? */
  922.         lseek(fd, 0l, 0);
  923.         return (load_mos(fd, fn));
  924.     }
  925.     else {
  926.         printf("unkown format, can't load file %s\n", fn);
  927.         close(fd);
  928.         return 1;
  929.     }
  930. }
  931.  
  932. /*
  933.  *    Loader for binary images with Mostek header.
  934.  *    Format of the first 3 bytes:
  935.  *
  936.  *    0xff ll    lh
  937.  *
  938.  *    ll = load address low
  939.  *    lh = load address high
  940.  */
  941. static load_mos(fd, fn)
  942. int fd;
  943. char *fn;
  944. {
  945.     BYTE fileb[3];
  946.     unsigned count,    readed;
  947.     int rc = 0;
  948.  
  949.     read(fd, (char *) fileb, 3);    /* read load address */
  950.     if (wrk_ram == NULL)        /* and set if not given */
  951.         wrk_ram    = ram +    (fileb[2] * 256    + fileb[1]);
  952. #if !defined(COHERENT) || defined(_I386)
  953.     count =    ram + 32767 - wrk_ram;
  954.     if ((readed = read(fd, (char *)    wrk_ram, count)) == count) {
  955.         puts("Too much to load, stopped at 0x7fff");
  956.         rc = 1;
  957.     }
  958. #else
  959.     count =    ram + 65535 - wrk_ram;
  960.     if ((readed = read(fd, (char *)    wrk_ram, count)) == count) {
  961.         puts("Too much to load, stopped at 0xffff");
  962.         rc = 1;
  963.     }
  964. #endif
  965.     close(fd);
  966.     printf("Loader statistics for file %s:\n", fn);
  967.     printf("START : %04x\n", wrk_ram - ram);
  968.     printf("END   : %04x\n", wrk_ram - ram + readed    - 1);
  969.     printf("LOADED: %04x\n", readed);
  970.     PC = wrk_ram;
  971.     return rc;
  972. }
  973.  
  974. /*
  975.  *    Call system function from simulator
  976.  */
  977. static do_unix(s)
  978. register char *s;
  979. {
  980.     int_off();
  981.     system(s);
  982.     int_on();
  983. }
  984.  
  985. /*
  986.  *    Output help text
  987.  */
  988. static do_help()
  989. {
  990.     puts("r filename[,address]      read object into memory");
  991.     puts("d [address]               dump memory");
  992. #if !defined(COHERENT) || defined(_I386)
  993.     puts("l [address]               list memory");
  994. #endif
  995.     puts("m [address]               modify memory");
  996.     puts("f address,count,value     fill memory");
  997. #if !defined(COHERENT) || defined(_I386)
  998.     puts("v from,to,count           move memory");
  999. #endif
  1000.     puts("p address                 show/modify port");
  1001.     puts("g [address]               run program");
  1002.     puts("t [count]                 trace program");
  1003.     puts("return                    single step program");
  1004.     puts("x [register]              show/modify register");
  1005.     puts("x f<flag>                 modify flag");
  1006.     puts("b[no] address[,pass]      set soft breakpoint");
  1007.     puts("b                         show soft breakpoints");
  1008.     puts("b[no] c                   clear soft breakpoint");
  1009.     puts("h [address]               show history");
  1010.     puts("h c                       clear history");
  1011.     puts("z start,stop              set trigger adr for t-state count");
  1012.     puts("z                         show t-state count");
  1013. #if !defined(COHERENT) || defined(_I386)
  1014.     puts("c                         measure clock frequency");
  1015. #endif
  1016.     puts("s                         show settings");
  1017.     puts("! command                 execute UNIX command");
  1018.     puts("q                         quit");
  1019. }
  1020.  
  1021. /*
  1022.  *    Error handler after CPU is stopped
  1023.  */
  1024. static cpu_err_msg()
  1025. {
  1026.     switch (cpu_error) {
  1027.     case NONE:
  1028.         break;
  1029.     case OPHALT:
  1030.         printf("HALT Op-Code reached at %04x\n", PC-ram-1);
  1031.         break;
  1032.     case IOTRAP:
  1033.         printf("I/O Trap at %04x\n", PC-ram);
  1034.         break;
  1035.     case OPTRAP1:
  1036.         printf("Op-code trap at %04x %02x\n", PC-1-ram,    *(PC-1));
  1037.         break;
  1038.     case OPTRAP2:
  1039.         printf("Op-code trap at %04x %02x %02x\n", PC-2-ram,
  1040.                *(PC-2),    *(PC-1));
  1041.         break;
  1042.     case OPTRAP4:
  1043.         printf("Op-code trap at %04x %02x %02x %02x %02x\n",
  1044.         PC-4-ram, *(PC-4), *(PC-3), *(PC-2), *(PC-1));
  1045.         break;
  1046.     case USERINT:
  1047.         puts("User Interrupt");
  1048.         break;
  1049.     default:
  1050.         printf("Unknown error %d\n", cpu_error);
  1051.         break;
  1052.     }
  1053. }
  1054.