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 
print_regs(void)45 static 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 
get_byte_reg(unsigned ModRM)61 static char *get_byte_reg(unsigned ModRM)
62 {
63     return byte_reg[(ModRM & 0x38) >> 3];
64 }
65 
get_word_reg(unsigned ModRM)66 static char *get_word_reg(unsigned ModRM)
67 {
68     return word_reg[(ModRM & 0x38) >> 3];
69 }
70 
get_seg_reg(unsigned ModRM)71 static char *get_seg_reg(unsigned ModRM)
72 {
73     return seg_reg[(ModRM & 0x38) >> 3];
74 }
75 
get_d8(BYTE * seg,unsigned * off)76 static unsigned get_d8(BYTE *seg, unsigned *off)
77 {
78     return GetMemInc(seg, (*off));
79 }
80 
get_d16(BYTE * seg,unsigned * off)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 
get_mem(unsigned ModRM,BYTE * seg,unsigned * off,char ** reg,char * msg)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 
get_disp(BYTE * seg,unsigned * off)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 
get_disp16(BYTE * seg,unsigned * off)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 
print_instruction(BYTE * seg,unsigned off,int * tab,char * buf)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 
decode_br8(BYTE * seg,unsigned off,char * buf)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 
decode_r8b(BYTE * seg,unsigned off,char * buf)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 
decode_wr16(BYTE * seg,unsigned off,char * buf)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 
decode_r16w(BYTE * seg,unsigned off,char * buf)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 
decode_ald8(BYTE * seg,unsigned off,char * buf)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 
decode_axd16(BYTE * seg,unsigned off,char * buf)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 
decode_pushpopseg(BYTE * seg,unsigned off,char * buf)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 
decode_databyte(BYTE * seg,unsigned off,char * buf)197 static unsigned decode_databyte(BYTE *seg, unsigned off, char *buf)
198 {
199     sprintf(buf,"%02X", instruction_byte);
200     return off;
201 }
202 
decode_wordreg(BYTE * seg,unsigned off,char * buf)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 
decode_cond_jump(BYTE * seg,unsigned off,char * buf)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 
decode_bd8(BYTE * seg,unsigned off,char * buf)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 
decode_wd16(BYTE * seg,unsigned off,char * buf)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 
decode_wd8(BYTE * seg,unsigned off,char * buf)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 
decode_ws(BYTE * seg,unsigned off,char * buf)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 
decode_sw(BYTE * seg,unsigned off,char * buf)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 
decode_w(BYTE * seg,unsigned off,char * buf)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 
decode_b(BYTE * seg,unsigned off,char * buf)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 
decode_xchgax(BYTE * seg,unsigned off,char * buf)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 
decode_far(BYTE * seg,unsigned off,char * buf)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 
decode_almem(BYTE * seg,unsigned off,char * buf)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 
decode_axmem(BYTE * seg,unsigned off,char * buf)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 
decode_memal(BYTE * seg,unsigned off,char * buf)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 
decode_memax(BYTE * seg,unsigned off,char * buf)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 
decode_string(BYTE * seg,unsigned off,char * buf)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 
decode_rd(BYTE * seg,unsigned off,char * buf)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 
decode_d16(BYTE * seg,unsigned off,char * buf)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 
decode_int3(BYTE * seg,unsigned off,char * buf)332 static unsigned decode_int3(BYTE *seg, unsigned off, char *buf)
333 {
334     strcpy(buf, "3");
335     return off;
336 }
337 
decode_d8(BYTE * seg,unsigned off,char * buf)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 
decode_bbit1(BYTE * seg,unsigned off,char * buf)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 
decode_wbit1(BYTE * seg,unsigned off,char * buf)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 
decode_bbitcl(BYTE * seg,unsigned off,char * buf)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 
decode_wbitcl(BYTE * seg,unsigned off,char * buf)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 
decode_disp(BYTE * seg,unsigned off,char * buf)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 
decode_escape(BYTE * seg,unsigned off,char * buf)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 
decode_adjust(BYTE * seg,unsigned off,char * buf)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 
decode_d8al(BYTE * seg,unsigned off,char * buf)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 
decode_d8ax(BYTE * seg,unsigned off,char * buf)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 
decode_axd8(BYTE * seg,unsigned off,char * buf)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 
decode_far_ind(BYTE * seg,unsigned off,char * buf)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 
decode_portdx(BYTE * seg,unsigned off,char * buf)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 
decode_disp16(BYTE * seg,unsigned off,char * buf)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 
decode_f6(BYTE * seg,unsigned off,char * buf)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 
decode_f7(BYTE * seg,unsigned off,char * buf)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 
decode_ff(BYTE * seg,unsigned off,char * buf)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 
decode_bioscall(BYTE * seg,unsigned off,char * buf)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 
disasm(unsigned seg,unsigned off,char * buffer)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 
disassemble(unsigned seg,unsigned off,int count)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 
hexdump(unsigned seg,unsigned off,unsigned count)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 
get_number(char * s)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 
get_address(char * s,unsigned * seg,unsigned * off)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 
strlwr(char * s)650 static char *strlwr(char *s)
651 {
652     for (; *s; s++)
653         *s = mylower(*s);
654 
655     return s;
656 }
657 
read_number(void)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 
change_reg(char * reg)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 
enter_bytes(unsigned seg,unsigned off)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 
process_input(void)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                 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 
debug_breakin(int sig)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 
call_debugger(int where)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 
970