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