"Fossies" - the Fresh Open Source Software Archive

Member "pcemu/debugger.c" (22 Jan 2001, 24675 Bytes) of package /linux/privat/old/pcemu-1.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "debugger.c" see the Fossies "Dox" file reference documentation.

    1 /****************************************************************************
    2 *                                                                           *
    3 *                            Third Year Project                             *
    4 *                                                                           *
    5 *                            An IBM PC Emulator                             *
    6 *                          For Unix and X Windows                           *
    7 *                                                                           *
    8 *                             By David Hedley                               *
    9 *                                                                           *
   10 *                                                                           *
   11 * This program is Copyrighted.  Consult the file COPYRIGHT for more details *
   12 *                                                                           *
   13 ****************************************************************************/
   14 
   15 #ifdef DEBUGGER
   16 
   17 #include "global.h"
   18 
   19 #include <stdio.h>
   20 #include <stdlib.h>
   21 #include <string.h>
   22 #include <signal.h>
   23 #include <ctype.h>
   24 
   25 #include "debugger.h"
   26 #include "cpu.h"
   27 #include "disasm.h"
   28 #include "vgahard.h"
   29 
   30 volatile int running;
   31 volatile int breakpoint;
   32 volatile int debug_abort;
   33 static BYTE *bpoint;
   34 
   35 static int numbase = 16;
   36 
   37 #define mylower(c) ((c >= 'A' && c <= 'Z') ? c-'A'+'a' : c)
   38 
   39 static BYTE instruction_byte;
   40 
   41 static char wordp[] = "word ptr ";
   42 static char bytep[] = "byte ptr ";
   43 static char blank[] = "";
   44 
   45 void print_regs(void)
   46 {
   47     printf("\nAX=%02X%02X  BX=%02X%02X  CX=%02X%02X  DX=%02X%02X  "
   48            "SP=%02X%02X  BP=%02X%02X  SI=%02X%02X  DI=%02X%02X\n",
   49            *bregs[AH],*bregs[AL],*bregs[BH],*bregs[BL],*bregs[CH],
   50            *bregs[CL],*bregs[DH],*bregs[DL], *bregs[SPH],*bregs[SPL],
   51            *bregs[BPH],*bregs[BPL],*bregs[SIH],*bregs[SIL],*bregs[DIH],
   52            *bregs[DIL]);
   53     printf("DS=%04X  ES=%04X  SS=%04X  CS=%04X  IP=%04X %s %s %s "
   54            "%s %s %s %s %s %s\n",sregs[DS],sregs[ES],sregs[SS],sregs[CS],
   55            ip, OF ? "OV" : "NV", DF ? "DN" : "UP", IF ? "EI" : "DI",
   56            SF ? "NG" : "PL", ZF ? "ZR" : "NZ",AF ? "AC" : "NA",
   57            PF ? "PE" : "PO", CF ? "CY" : "NC",TF ? "TR" : "NT" );
   58 }
   59 
   60 
   61 static char *get_byte_reg(unsigned ModRM)
   62 {
   63     return byte_reg[(ModRM & 0x38) >> 3];
   64 }
   65 
   66 static char *get_word_reg(unsigned ModRM)
   67 {
   68     return word_reg[(ModRM & 0x38) >> 3];
   69 }
   70 
   71 static char *get_seg_reg(unsigned ModRM)
   72 {
   73     return seg_reg[(ModRM & 0x38) >> 3];
   74 }
   75 
   76 static unsigned get_d8(BYTE *seg, unsigned *off)
   77 {
   78     return GetMemInc(seg, (*off));
   79 }
   80 
   81 static unsigned get_d16(BYTE *seg, unsigned *off)
   82 {
   83     unsigned num = GetMemInc(seg, (*off));
   84     num += GetMemInc(seg, (*off)) << 8;
   85     return num;
   86 }
   87 
   88 static char *get_mem(unsigned ModRM, BYTE *seg, unsigned *off, char **reg, char *msg)
   89 {
   90     static char buffer[100];
   91     int num;
   92     char ch;
   93 
   94     switch(ModRM & 0xc0)
   95     {
   96     case 0x00:
   97         if ((ModRM & 0x07) != 6)
   98             sprintf(buffer,"%s[%s]", msg, index_reg[ModRM & 0x07]);
   99         else
  100             sprintf(buffer,"%s[%04X]", msg, get_d16(seg, off));
  101         break;
  102     case 0x40:
  103         if ((num = (INT8)get_d8(seg, off)) < 0)
  104         {
  105             ch = '-';
  106             num = -num;
  107         }
  108         else
  109             ch = '+';
  110         sprintf(buffer,"%s[%s%c%02X]", msg, index_reg[ModRM & 0x07], ch, num);
  111         break;
  112     case 0x80:
  113         if ((num = (INT16)get_d16(seg, off)) < 0)
  114         {
  115             ch = '-';
  116             num = -num;
  117         }
  118         else
  119             ch = '+';
  120         sprintf(buffer,"%s[%s%c%04X]", msg, index_reg[ModRM & 0x07], ch, num);
  121         break;
  122     case 0xc0:
  123         strcpy(buffer, reg[ModRM & 0x07]);
  124         break;
  125     }
  126 
  127     return buffer;
  128 }
  129 
  130 static WORD get_disp(BYTE *seg, unsigned *off)
  131 {
  132     unsigned disp = GetMemInc(seg, (*off));
  133 
  134     return (WORD)(*off + (INT32)((INT8)disp));
  135 }
  136 
  137 static WORD get_disp16(BYTE *seg, unsigned *off)
  138 {
  139     unsigned disp = GetMemInc(seg, (*off));
  140     disp += GetMemInc(seg, (*off)) << 8;
  141 
  142     return (WORD)(*off + (INT32)((INT16)disp));
  143 }
  144 
  145 static void print_instruction(BYTE *seg, unsigned off, int *tab, char *buf)
  146 {
  147     unsigned ModRM = GetMemB(seg,off);
  148     sprintf(buf, "%-6s ", itext[tab[(ModRM & 0x38) >> 3]]);
  149 }
  150     
  151 static unsigned decode_br8(BYTE *seg, unsigned off, char *buf)
  152 {
  153     unsigned ModRM = GetMemInc(seg, off);
  154     sprintf(buf, "%s,%s", get_mem(ModRM, seg, &off, byte_reg, blank), get_byte_reg(ModRM));
  155     return off;
  156 }
  157 
  158 static unsigned decode_r8b(BYTE *seg, unsigned off, char *buf)
  159 {
  160     unsigned ModRM = GetMemInc(seg,off);
  161     sprintf(buf,"%s,%s", get_byte_reg(ModRM), get_mem(ModRM, seg, &off, byte_reg, blank));
  162     return off;
  163 }
  164 
  165 static unsigned decode_wr16(BYTE *seg, unsigned off, char *buf)
  166 {
  167     unsigned ModRM = GetMemInc(seg,off);
  168     sprintf(buf, "%s,%s", get_mem(ModRM, seg, &off, word_reg, blank), get_word_reg(ModRM));
  169     return off;
  170 }
  171 
  172 static unsigned decode_r16w(BYTE *seg, unsigned off, char *buf)
  173 {
  174     unsigned ModRM = GetMemInc(seg,off);
  175     sprintf(buf,"%s,%s", get_word_reg(ModRM), get_mem(ModRM, seg, &off, word_reg, blank));
  176     return off;
  177 }
  178 
  179 static unsigned decode_ald8(BYTE *seg, unsigned off, char *buf)
  180 {
  181     sprintf(buf,"al,%02X",get_d8(seg, &off));
  182     return off;
  183 }
  184 
  185 static unsigned decode_axd16(BYTE *seg, unsigned off, char *buf)
  186 {
  187     sprintf(buf,"ax,%04X",get_d16(seg, &off));
  188     return off;
  189 }
  190 
  191 static unsigned decode_pushpopseg(BYTE *seg, unsigned off, char *buf)
  192 {
  193     strcpy(buf, get_seg_reg(instruction_byte));
  194     return off;
  195 }
  196 
  197 static unsigned decode_databyte(BYTE *seg, unsigned off, char *buf)
  198 {
  199     sprintf(buf,"%02X", instruction_byte);
  200     return off;
  201 }
  202 
  203 static unsigned decode_wordreg(BYTE *seg, unsigned off, char *buf)
  204 {
  205     strcat(buf, word_reg[instruction_byte & 0x7]);
  206     return off;
  207 }
  208 
  209 
  210 static unsigned decode_cond_jump(BYTE *seg, unsigned off, char *buf)
  211 {
  212     sprintf(buf,"%-5s %04X", condition[instruction_byte & 0xf], get_disp(seg, &off));
  213     return off;
  214 }
  215 
  216 static unsigned decode_bd8(BYTE *seg, unsigned off, char *buf)
  217 {
  218     unsigned ModRM = GetMemInc(seg, off);
  219     char *mem = get_mem(ModRM, seg, &off, byte_reg, bytep);
  220     sprintf(buf,"%s,%02X", mem, get_d8(seg, &off));
  221     return off;
  222 }
  223 
  224 static unsigned decode_wd16(BYTE *seg, unsigned off, char *buf)
  225 {
  226     unsigned ModRM = GetMemInc(seg, off);
  227     char *mem = get_mem(ModRM, seg, &off, word_reg, wordp);
  228     sprintf(buf,"%s,%04X", mem, get_d16(seg, &off));
  229     return off;
  230 }
  231 
  232 static unsigned decode_wd8(BYTE *seg, unsigned off, char *buf)
  233 {
  234     unsigned ModRM = GetMemInc(seg, off);
  235     char *mem = get_mem(ModRM, seg, &off, word_reg, wordp);
  236     sprintf(buf,"%s,%02X", mem, get_d8(seg, &off));
  237     return off;
  238 }
  239 
  240 static unsigned decode_ws(BYTE *seg, unsigned off, char *buf)
  241 {
  242     unsigned ModRM = GetMemInc(seg, off);
  243     sprintf(buf,"%s,%s", get_mem(ModRM, seg, &off, word_reg, blank), get_seg_reg(ModRM));
  244     return off;
  245 }
  246 
  247 static unsigned decode_sw(BYTE *seg, unsigned off, char *buf)
  248 {
  249     unsigned ModRM = GetMemInc(seg, off);
  250     sprintf(buf,"%s,%s", get_seg_reg(ModRM), get_mem(ModRM, seg, &off, word_reg, blank));
  251     return off;
  252 }
  253 
  254 static unsigned decode_w(BYTE *seg, unsigned off, char *buf)
  255 {
  256     unsigned ModRM = GetMemInc(seg, off);
  257     strcpy(buf, get_mem(ModRM, seg, &off, word_reg, wordp));
  258     return off;
  259 }
  260 
  261 static unsigned decode_b(BYTE *seg, unsigned off, char *buf)
  262 {
  263     unsigned ModRM = GetMemInc(seg, off);
  264     strcpy(buf, get_mem(ModRM, seg, &off, byte_reg, bytep));
  265     return off;
  266 }
  267 
  268 static unsigned decode_xchgax(BYTE *seg, unsigned off, char *buf)
  269 {
  270     sprintf(buf, "ax,%s", word_reg[instruction_byte & 0x7]);
  271     return off;
  272 }
  273 
  274 static unsigned decode_far(BYTE *seg, unsigned off, char *buf)
  275 {
  276     unsigned offset = get_d16(seg, &off);
  277 
  278     sprintf(buf,"%04X:%04X", get_d16(seg, &off), offset);
  279     return off;
  280 }
  281 
  282 static unsigned decode_almem(BYTE *seg, unsigned off, char *buf)
  283 {
  284     sprintf(buf,"al,[%04X]", get_d16(seg, &off));
  285     return off;
  286 }
  287 
  288 static unsigned decode_axmem(BYTE *seg, unsigned off, char *buf)
  289 {
  290     sprintf(buf,"ax,[%04X]", get_d16(seg, &off));
  291     return off;
  292 }
  293 
  294 static unsigned decode_memal(BYTE *seg, unsigned off, char *buf)
  295 {
  296     sprintf(buf,"[%04X],al", get_d16(seg, &off));
  297     return off;
  298 }
  299 
  300 static unsigned decode_memax(BYTE *seg, unsigned off, char *buf)
  301 {
  302     sprintf(buf,"[%04X],ax", get_d16(seg, &off));
  303     return off;
  304 }
  305 
  306 static unsigned decode_string(BYTE *seg, unsigned off, char *buf)
  307 {
  308     if (instruction_byte & 0x01)
  309         strcat(buf,"w");
  310     else
  311         strcat(buf,"b");
  312 
  313     return off;
  314 }
  315 
  316 static unsigned decode_rd(BYTE *seg, unsigned off, char *buf)
  317 {
  318     if ((instruction_byte & 0xf) > 7)
  319         sprintf(buf,"%s,%04X", word_reg[instruction_byte & 0x7], get_d16(seg, &off));
  320     else
  321         sprintf(buf,"%s,%02X", byte_reg[instruction_byte & 0x7], get_d8(seg, &off));
  322 
  323     return off;
  324 }
  325 
  326 static unsigned decode_d16(BYTE *seg, unsigned off, char *buf)
  327 {
  328     sprintf(buf,"%04X", get_d16(seg, &off));
  329     return off;
  330 }
  331 
  332 static unsigned decode_int3(BYTE *seg, unsigned off, char *buf)
  333 {
  334     strcpy(buf, "3");
  335     return off;
  336 }
  337 
  338 static unsigned decode_d8(BYTE *seg, unsigned off, char *buf)
  339 {
  340     sprintf(buf,"%02X", get_d8(seg, &off));
  341     return off;
  342 }
  343 
  344 static unsigned decode_bbit1(BYTE *seg, unsigned off, char *buf)
  345 {
  346     unsigned ModRM = GetMemInc(seg, off);
  347     sprintf(buf,"%s,1", get_mem(ModRM, seg, &off, byte_reg, bytep));
  348     return off;
  349 }
  350 
  351 static unsigned decode_wbit1(BYTE *seg, unsigned off, char *buf)
  352 {
  353     unsigned ModRM = GetMemInc(seg, off);
  354     sprintf(buf,"%s,1", get_mem(ModRM, seg, &off, word_reg, wordp));
  355     return off;
  356 }
  357 
  358 static unsigned decode_bbitcl(BYTE *seg, unsigned off, char *buf)
  359 {
  360     unsigned ModRM = GetMemInc(seg, off);
  361     sprintf(buf,"%s,cl", get_mem(ModRM, seg, &off, byte_reg, bytep));
  362     return off;
  363 }
  364 
  365 static unsigned decode_wbitcl(BYTE *seg, unsigned off, char *buf)
  366 {
  367     unsigned ModRM = GetMemInc(seg, off);
  368     sprintf(buf,"%s,cl", get_mem(ModRM, seg, &off, word_reg, wordp));
  369     return off;
  370 }
  371 
  372 static unsigned decode_disp(BYTE *seg, unsigned off, char *buf)
  373 {
  374     sprintf(buf,"%04X", get_disp(seg, &off));
  375     return off;
  376 }
  377 
  378 static unsigned decode_escape(BYTE *seg, unsigned off, char *buf)
  379 {
  380     unsigned ModRM  = GetMemInc(seg, off);
  381     sprintf(buf,"%d,%s", instruction_byte & 0x7,
  382             get_mem(ModRM, seg, &off, nul_reg, blank));
  383     return off;
  384 }
  385 
  386 static unsigned decode_adjust(BYTE *seg, unsigned off, char *buf)
  387 {
  388     unsigned num = GetMemInc(seg, off);
  389 
  390     if (num != 10)
  391         sprintf(buf, "%02X", num);
  392     return off;
  393 }
  394 
  395 static unsigned decode_d8al(BYTE *seg, unsigned off, char *buf)
  396 {
  397     sprintf(buf, "%02X,al", get_d8(seg, &off));
  398     return off;
  399 }
  400 
  401 static unsigned decode_d8ax(BYTE *seg, unsigned off, char *buf)
  402 {
  403     sprintf(buf, "%02X,ax", get_d8(seg, &off));
  404     return off;
  405 }
  406 
  407 static unsigned decode_axd8(BYTE *seg, unsigned off, char *buf)
  408 {
  409     sprintf(buf, "ax,%02X", get_d8(seg, &off));
  410     return off;
  411 }
  412 
  413 static unsigned decode_far_ind(BYTE *seg, unsigned off, char *buf)
  414 {
  415     unsigned ModRM = GetMemInc(seg, off);
  416     sprintf(buf, "far %s", get_mem(ModRM, seg, &off, word_reg, blank));
  417     return off;
  418 }
  419 
  420 static unsigned decode_portdx(BYTE *seg, unsigned off, char *buf)
  421 {
  422     switch (instruction_byte)
  423     {
  424     case 0xec:
  425         strcpy(buf,"al,dx"); break;
  426     case 0xed:
  427         strcpy(buf,"ax,dx"); break;
  428     case 0xee:
  429         strcpy(buf,"dx,al"); break;
  430     case 0xef:
  431         strcpy(buf,"dx,ax"); break;
  432     }
  433      
  434     return off;
  435 }
  436 
  437 static unsigned decode_disp16(BYTE *seg, unsigned off, char *buf)
  438 {
  439     sprintf(buf, "%04X", get_disp16(seg, &off));
  440     return off;
  441 }
  442 
  443 static unsigned decode_f6(BYTE *seg, unsigned off, char *buf)
  444 {
  445     unsigned ModRM = GetMemB(seg, off);
  446     if ((ModRM & 0x38) == 0x00)
  447         return decode_bd8(seg, off, buf);
  448 
  449     return decode_b(seg, off, buf);
  450 }
  451 
  452 static unsigned decode_f7(BYTE *seg, unsigned off, char *buf)
  453 {
  454     unsigned ModRM = GetMemB(seg, off);
  455     if ((ModRM & 0x38) == 0x00)
  456         return decode_wd16(seg, off, buf);
  457 
  458     return decode_w(seg, off, buf);
  459 }
  460 
  461 static unsigned decode_ff(BYTE *seg, unsigned off, char *buf)
  462 {
  463     unsigned ModRM = (GetMemB(seg, off) & 0x38) >> 3;
  464 
  465     if (ModRM == 3 || ModRM == 5)
  466         return decode_far_ind(seg, off, buf);
  467 
  468     return decode_w(seg, off, buf);
  469 }
  470 
  471 static unsigned decode_bioscall(BYTE *seg, unsigned off, char *buf)
  472 {
  473     unsigned addr;
  474 
  475     if (GetMemB(seg, off) == 0xf1)
  476     {
  477         off = (WORD)(off + 1);
  478         addr = GetMemInc(seg, off);
  479         addr += GetMemInc(seg, off) << 8;
  480         addr += GetMemInc(seg, off) << 16;
  481         addr += GetMemInc(seg, off) << 24;
  482         sprintf(buf, "bios   %08X",addr);
  483     }
  484     else
  485         sprintf(buf, "db     F1");
  486 
  487     return off;
  488 }
  489 
  490 static unsigned disasm(unsigned seg, unsigned off, char *buffer)
  491 {
  492     BYTE *segp = &memory[(seg << 4)];
  493     struct Disasm *d;
  494 
  495     instruction_byte = GetMemInc(segp, off);
  496     d = &disasm_table[instruction_byte];
  497 
  498     if (d->supp != NULL)
  499         print_instruction(segp, off, d->supp, buffer);
  500     else
  501         sprintf(buffer, (d->flags & DF_NOSPACE) ? "%s" : "%-6s ",
  502                 itext[d->text]);
  503 
  504     if (d->type != NULL)
  505         off = (d->type)(segp, off, &buffer[strlen(buffer)]);
  506 
  507     return off;
  508 }
  509 
  510 static unsigned disassemble(unsigned seg, unsigned off, int count)
  511 {
  512     char buffer1[80];
  513     char buffer2[80];
  514     char buffer3[3];
  515     unsigned newoff;
  516 
  517     for (; !debug_abort && count > 0; count--)
  518     {
  519         do
  520         {
  521             printf("%04X:%04X ", seg, off);
  522             buffer1[0] = '\0';
  523             newoff = disasm(seg, off, buffer1);
  524             buffer2[0] = '\0';
  525             for (; off < newoff; off++)
  526             {
  527                 sprintf(buffer3,"%02X", GetMemB(&memory[seg << 4], off));
  528                 strcat(buffer2,buffer3);
  529             }
  530             printf("%-14s%s\n", buffer2,buffer1);
  531         } while (disasm_table[instruction_byte].flags & DF_PREFIX);
  532     }
  533     return off;
  534 }
  535 
  536 static unsigned hexdump(unsigned seg, unsigned off, unsigned count)
  537 {
  538     char bytes[3*16+1];
  539     char ascii[16+1];
  540     char *byteptr, *asciiptr;
  541     unsigned startpos,i;
  542     BYTE *segp;
  543     BYTE ch;
  544 
  545     segp = &memory[seg << 4];
  546 
  547     while (!debug_abort && count > 0)
  548     {
  549         startpos = off & 0xf;
  550 
  551         byteptr = bytes;
  552         asciiptr = ascii;
  553 
  554         printf("%04X:%04X ", seg, off & 0xfff0);
  555 
  556         for (i = off & 0x0f; count>0 && i<0x10; i++, off=(WORD)(off+1),count--)
  557         {
  558             ch = GetMemB(segp, off);
  559             sprintf(byteptr, "%c%02X", i == 8 ? '-' : ' ', ch);
  560             sprintf(asciiptr, "%c", ch < 32 || ch > 126 ? '.' : ch);
  561             byteptr += 3;
  562             asciiptr++;
  563             if ((WORD)(off+1) < off)
  564             {
  565                 debug_abort = TRUE;
  566                 break;
  567             }
  568         }
  569 
  570         for (i = 0; i < startpos; i++)
  571             printf("   ");
  572         printf("%s", bytes);
  573         if (off & 0xf)
  574             for (i = 16-(off & 0xf); i > 0; i--)
  575                 printf("   ");
  576         for (i = 0; i < startpos; i++)
  577             printf(" ");
  578         printf("   %s\n", ascii);
  579 
  580     }
  581 
  582     return off;
  583 }
  584 
  585 static int get_number(char *s)
  586 {
  587     int i;
  588     char *endptr;
  589     long int num;
  590     
  591     for (i = 0; i < 8; i++)
  592         if (strcmp(word_reg[i],s) == 0)
  593             return ChangeE(wregs[i]);
  594 
  595     for (i = 0; i < 4; i++)
  596         if (strcmp(seg_reg[i],s) == 0)
  597             return sregs[i];
  598 
  599     if (strcmp("ip",s) == 0)
  600         return ip;
  601 
  602     num = strtol(s, &endptr, numbase);
  603 
  604     if (num > 65535 || num < -32768 || *endptr != '\0')
  605     {
  606         printf("Invalid number\n");
  607         return -1;
  608     }
  609     if (num < 0)
  610         num = (WORD)num;
  611 
  612     return num;
  613 }
  614     
  615 
  616 static int get_address(char *s, unsigned *seg, unsigned *off)
  617 {
  618     char *offset;
  619     int num;
  620 
  621     offset = strchr(s,':');
  622 
  623     if (offset != NULL)
  624     {
  625         *offset = '\0';
  626         num = get_number(s);
  627         if (num >= 0)
  628         {
  629             *seg = (unsigned)num;
  630             num = get_number(offset+1);
  631             if (num >= 0)
  632                 *off = (unsigned)num;
  633             else
  634                 return -1;
  635         }
  636         else
  637             return -1;
  638     }
  639     else
  640     {
  641         num = get_number(s);
  642         if (num >= 0)
  643             *off = (unsigned)num;
  644         else
  645             return -1;
  646     }
  647     return 0;
  648 }
  649 
  650 static char *strlwr(char *s)
  651 {
  652     for (; *s; s++)
  653         *s = mylower(*s);
  654         
  655     return s;
  656 }
  657 
  658 static int read_number(void)
  659 {
  660     char inpbuf[80];
  661     char buffer[80];
  662 
  663     fgets(inpbuf, sizeof inpbuf, stdin);
  664 
  665     if (sscanf(inpbuf," %s \n", buffer) <= 0)
  666         return -1;
  667 
  668     return get_number(buffer);
  669 }
  670 
  671 static void change_reg(char *reg)
  672 {
  673     int i;
  674     int num;
  675 
  676     for (i = 0; i < 8; i++)
  677         if (strcmp(word_reg[i],reg) == 0)
  678         {
  679             printf("%s = %04X\n:",word_reg[i], ChangeE(wregs[i]));
  680             num = read_number();
  681             if (num >= 0)
  682                 wregs[i] = ChangeE(num);
  683             return;
  684         }
  685 
  686     for (i = 0; i < 4; i++)
  687         if (strcmp(seg_reg[i],reg) == 0)
  688         {
  689             printf("%s = %04X\n:",seg_reg[i], sregs[i]);
  690             num = read_number();
  691             if (num >= 0)
  692             {
  693                 sregs[i] = num;
  694                 switch(i)
  695                 {
  696                 case ES:
  697                     c_es = SegToMemPtr(ES); break;
  698                 case CS:
  699                     c_cs = SegToMemPtr(CS); break;
  700                 case SS:
  701                     c_ss = SegToMemPtr(SS); break;
  702                 case DS:
  703                     c_ds = SegToMemPtr(DS); break;
  704                 }
  705             }
  706             return;
  707         }
  708 
  709     if (strcmp("ip",reg) == 0)
  710     {
  711         printf("ip = %04X\n:", ip);
  712         num = read_number();
  713         if (num >= 0)
  714             ip = (WORD)num;
  715         return;
  716     }
  717     printf("Invalid register\n");
  718 }
  719 
  720 
  721 static void enter_bytes(unsigned seg, unsigned off)
  722 {
  723     BYTE *b;
  724     int num;
  725     
  726     while (!debug_abort)
  727     {
  728         b = &memory[(seg << 4)+off];
  729 
  730         printf("%04X:%04X  %02X   ", seg, off, *b);
  731         num = read_number();
  732         if (num >= 0)
  733             *b = num & 0xff;
  734 
  735         off = (WORD)(off+1);
  736     }
  737 }                
  738 
  739 
  740 static void process_input(void)
  741 {
  742     char buffer[1024];
  743     char command;
  744     char param1[1024];
  745     char param2[1024];
  746     int num;
  747     unsigned ucurrent_seg, ucurrent_off;
  748     unsigned dcurrent_seg, dcurrent_off;
  749     unsigned ecurrent_seg, ecurrent_off;
  750     unsigned next_ip;
  751     int count;
  752     unsigned temp;
  753 
  754     ucurrent_seg = sregs[CS];
  755     ucurrent_off = ip;
  756     ecurrent_seg = dcurrent_seg = sregs[DS];
  757     ecurrent_off = dcurrent_off = 0;
  758 
  759     print_regs();
  760     next_ip = disassemble(sregs[CS], ip, 1);
  761 
  762     for(;;)
  763     {
  764 
  765 #ifdef __hpux
  766         sigset_t newmask, oldmask;
  767 #endif
  768         fputc('-', stdout);
  769         fflush(stdout);
  770         fflush(stdin);
  771 
  772 #ifdef __hpux
  773         sigfillset(&newmask);
  774         sigprocmask(SIG_SETMASK, &newmask, &oldmask);
  775 #endif
  776 
  777         if (fgets(buffer, sizeof buffer, stdin) == NULL)
  778             exit_emu();
  779 
  780 #ifdef __hpux
  781         sigprocmask(SIG_SETMASK, &oldmask, NULL);
  782 #endif
  783 
  784         debug_abort = FALSE;
  785         
  786         strlwr(buffer);
  787         num = sscanf(buffer," %c %s %s \n", &command, param1, param2);
  788         
  789         if (num >= 1)
  790         {
  791             switch(command)
  792             {
  793             case 'x':
  794                 printf("memory = %p\n", memory);
  795                 printf("c_es = %p / %04X\n", c_es, (c_es-memory) >> 4);
  796                 printf("c_cs = %p / %04X\n", c_cs, (c_cs-memory) >> 4);
  797                 printf("c_ds = %p / %04X\n", c_ds, (c_ds-memory) >> 4);
  798                 printf("c_ss = %p / %04X\n", c_ss, (c_ss-memory) >> 4);
  799                 printf("c_stack = %p / %04X\n", c_stack, (c_stack-memory) >> 4);
  800                 break;
  801             case 'q':
  802                 exit_emu();
  803                 break;
  804             case 'g':
  805                 if (num == 1)
  806                 {
  807                     running = TRUE;
  808                     return;
  809                 }
  810                 else
  811                 {
  812                     unsigned seg,off;
  813                     seg = sregs[CS];
  814                     if (get_address(param1,&seg,&off) >= 0)
  815                     {
  816                         breakpoint = TRUE;
  817                         bpoint = &memory[(seg << 4) + off];
  818                         return;
  819                     }
  820                 }
  821                 break;
  822             case 't':
  823                 return;
  824             case 'r':
  825                 if (num == 1)
  826                 {
  827                     print_regs();
  828                     next_ip = disassemble(sregs[CS],ip,1);
  829                     ucurrent_seg = sregs[CS];
  830                     ucurrent_off = ip;
  831                 }
  832                 else
  833                     change_reg(param1);
  834                 break;
  835             case 'p':
  836                 for (temp = ip;; temp = (WORD)(temp+1))
  837                 {
  838                     num = memory[(sregs[CS] << 4) + temp];
  839                     if (num==0x26 || num==0x2e || num==0x36 || num==0x3e)
  840                         continue;
  841                     else
  842                         break;
  843                 }
  844                 switch(num)
  845                 {         
  846                 case 0xff:
  847                     num = memory[(sregs[CS] << 4) + (WORD)(temp+1)];
  848                     switch (num & 0x38)
  849                     {
  850                     case 0x10:
  851                     case 0x18:
  852                         break;
  853                     default:
  854                         return;
  855                     }
  856                     /* FALL THROUGH */
  857                 case 0x9a:
  858                 case 0xcc:
  859                 case 0xcd:
  860                 case 0xce:
  861                 case 0xe0:
  862                 case 0xe1:
  863                 case 0xe2:
  864                 case 0xe8:
  865                     running = FALSE;
  866                     breakpoint = TRUE;
  867                     bpoint = &c_cs[next_ip];
  868                     break;
  869                 }
  870                 return;
  871             case 's':
  872                 pcemu_refresh();
  873                 break;
  874             case 'u':
  875                 count = 16;
  876                 if (num > 1)
  877                 {
  878                     ucurrent_seg = sregs[CS];
  879                     if (get_address(param1,&ucurrent_seg, &ucurrent_off) < 0)
  880                         break;
  881                     if (num > 2)
  882                     {
  883                         count = get_number(param2);
  884                         if (count < 0)
  885                             break;
  886                     }
  887                 }
  888                 ucurrent_off = disassemble(ucurrent_seg, ucurrent_off, count);
  889                 break;
  890             case 'd':
  891                 count = ((dcurrent_off + 16*8) & 0xfff0)-dcurrent_off;
  892                 if (num > 1)
  893                 {
  894                     dcurrent_seg = sregs[DS];
  895                     if (get_address(param1,&dcurrent_seg, &dcurrent_off) < 0)
  896                         break;
  897                     if (num > 2)
  898                     {
  899                         count = get_number(param2);
  900                         if (count < 0)
  901                             break;
  902                     }
  903                     else
  904                         count = ((dcurrent_off + 16*8) & 0xfff0)-dcurrent_off;
  905                 }
  906                 dcurrent_off = hexdump(dcurrent_seg, dcurrent_off, count);
  907                 break;
  908             case 'e':
  909                 if (num > 1)
  910                 {
  911                     ecurrent_seg = sregs[DS];
  912                     if (get_address(param1,&ecurrent_seg, &ecurrent_off) < 0)
  913                         break;
  914 
  915                     enter_bytes(ecurrent_seg, ecurrent_off);
  916                 }
  917                 break;
  918             case 'b':
  919                 if (num == 2 && (param1[0] == 'd' || param1[0] == 'h'))
  920                     numbase = param1[0] == 'd' ? 0 : 16;
  921                 else
  922                     printf("Parameter must be either 'd' or 'h'\n");
  923                 break;
  924             default:
  925                 printf("Unrecognised command\n");
  926                 break;
  927             }
  928         }
  929     }
  930 }
  931 
  932 int debug_breakin(int sig)
  933 {
  934     signal(sig, (void *)debug_breakin);
  935     running = breakpoint = FALSE;
  936     
  937     if (in_debug)
  938         debug_abort = TRUE;
  939     return 0;
  940 }
  941 
  942 void call_debugger(int where)
  943 {
  944     if (where == D_INT)
  945     {
  946 /*        printf("Interrupt!\n"); */
  947         return;
  948     }
  949 
  950     if (running)
  951         return;
  952 
  953     if (breakpoint)
  954     {
  955         if (&c_cs[ip] != bpoint)
  956             return;
  957     }
  958 
  959     in_debug = TRUE;
  960     running = breakpoint = FALSE;
  961     CalcAll();
  962     process_input();
  963     in_debug = FALSE;
  964 }
  965 
  966 #endif
  967 
  968 
  969