|
|
1.1 root 1: /* $Header: /src386/bin/db/RCS/i8086b.c,v 1.3 93/03/11 07:45:40 bin Exp Locker: bin $
2: *
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.35
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: */
15: /*
16: * A debugger.
17: * Intel 8086.
18: *
19: * $Log: i8086b.c,v $
20: * Revision 1.3 93/03/11 07:45:40 bin
21: * Hal: post NDP update that at least
22: * can st breakpoints.
23: *
24: * Revision 1.1 92/06/10 14:36:31 bin
25: * Initial revision
26: *
27: * Revision 1.2 89/06/19 16:46:29 src
28: * Bug: 80286 virtual mode instructions not supported [ie: lgdt].
29: * Fix: Metakey 'V' added to support 3 byte virtual mode instructions. (ABC)
30: *
31: * Revision 1.1 88/10/17 04:03:49 src
32: * Initial revision
33: *
34: * Revision: 386 version 92/05/01
35: * Bernard Wald, Wald Software Consulting, Germany
36: */
37:
38: #include <stdio.h>
39: #include <sys/param.h>
40: #include <l.out.h>
41: #include "trace.h"
42: #include "i8086.h"
43:
44: /*
45: * Disassemble an Intel 80386 instruction.
46: */
47:
48: #define MAXINSTLEN 50 /* max. expanded opcode string length */
49: #define MAXDISPLCTSIZE 6 /* max. displacement size in bytes */
50: #define ESC_2_OPMAP2 0x0F /* escape to second byte of the opcode */
51:
52: /* define instruction prefix codes */
53: #define REP 0xF3
54: #define REPNE 0xF2
55: #define LOCK 0xF0
56:
57: /* define address size prefix codes */
58: #define ADDRPRE 0x67
59:
60: /* define operand size prefix codes */
61: #define OPDPRE 0x66
62:
63: /* define segment override prefix codes */
64: #define CS_PFX 0x2E
65: #define DS_PFX 0x3E
66: #define ES_PFX 0x26
67: #define FS_PFX 0x64
68: #define GS_PFX 0x65
69: #define SS_PFX 0x36
70:
71: #define EBP_SIB 5
72:
73: #define UNSIGNED 0
74: #define SIGNED 1
75:
76: #define ADDZERO 0
77: #define ADDADDR 1
78:
79: #define mod(x) (((x)>>6)&3)
80: #define modR(x) (((x)>>3)&7)
81: #define modRM(x) ((x)&7)
82: #define sibss(x) (((x)>>6)&3)
83: #define sibx(x) (((x)>>3)&7)
84: #define sibb(x) ((x)&7)
85:
86: #define ADDRINDEX(x) (x == RM32 ? 1 : 0)
87:
88: #define TOLSYM 0x100 /* print symbol if greater */
89: #define TOLHEX 0x10 /* print hexidecimal if greater */
90: /* print decimal if less */
91: static int addrflag=0; /* address size prefix flag */
92: static int opdflag=0; /* operand size prefix flag */
93: static int segflag=0; /* segment override prefix flag */
94: static char *segPreStrp; /* segment prefix str., e.g. "cs:" */
95: static unsigned char m; /* "Mod" field of ModR/M byte */
96: static unsigned char mRM; /* "R/M" field of ModR/M byte */
97: static unsigned char mReg; /* "REG" field of ModR/M byte */
98: static unsigned char modRMloaded; /* ModR/M byte part of instruction
99: has already been loaded, if set */
100: static unsigned char sb; /* "base" field of SIB byte */
101: static unsigned char sss; /* "ss" field of SIB byte */
102: static unsigned char sx; /* "index" field of SIB byte */
103: static unsigned char sibLoaded; /* SIB byte part of instruction
104: has already been loaded, if set */
105:
106: /* Function declatations */
107: char *getmodREGstr();
108: char *getmodRM16str();
109: char *getmodRM32str();
110: char *getsibstr();
111: char *getmodRMstr();
112: unsigned long getVal();
113: unsigned short getValData();
114: unsigned char check4prefix();
115: unsigned long evalValData();
116: char *getSegValStr();
117: char *getASCIIimmediateStr();
118: char *getASCIIdisplcmtStr();
119: char *getSegPreStr();
120: unsigned char c2opdsizeAdj();
121: unsigned char getnbytes();
122: unsigned char getgenRegIndex();
123:
124: char *
125: newconinst(sp, s)
126: char *sp; /* pointer to assembler nmeumonic string, which will
127: contain the expanded string to be output (to screen). */
128: int s; /* segment number */
129: {
130: unsigned char ibp[MAXDISPLCTSIZE]; /* buffer to store read-in instruction/
131: displacement machine code */
132: char is[MAXINSTLEN], *isp; /* buffer to store formatted
133: instructon string. */
134: char *tsp; /* temporary string pointer */
135: int loop, useMap2;
136:
137: /*
138: * Initialize
139: */
140: addrflag = 0;
141: opdflag = 0;
142: segflag = 0;
143: modRMloaded = 0;
144: sibLoaded = 0;
145:
146: isp = is;
147:
148: /*
149: * Check whether any prefixes are present
150: */
151: for (loop=1, useMap2=0; loop; ) {
152: if (getb(s, ibp, sizeof(char)) == 0)
153: return (NULL);
154: switch (ibp[0]) {
155: case REP: /* rep instruction prefix */
156: case REPNE: /* repne instruction prefix */
157: case LOCK: /* lock instruction prefix */
158: loop = 0; /* treat instruction prefixe like a */
159: break; /* separate instruction */
160: case ADDRPRE: /* address size prefix */
161: addrflag = 1;
162: continue;
163: case OPDPRE: /* operand size prefix */
164: opdflag = 1;
165: continue;
166: case CS_PFX: /* "cs:" segment override prefix */
167: case DS_PFX: /* "ds:" segment override prefix */
168: case ES_PFX: /* "es:" segment override prefix */
169: case FS_PFX: /* "fs:" segment override prefix */
170: case GS_PFX: /* "gs:" segment override prefix */
171: case SS_PFX: /* "ss:" segment override prefix */
172: segPreStrp = opStrMap1[ ibp[0] ]; /* store segment override */
173: segflag = 1;
174: break;
175: case ESC_2_OPMAP2: /* opcode info is in the next byte */
176: useMap2 = 1;
177: if (getb(s, ibp, sizeof(char)) == 0)
178: return (NULL);
179: loop = 0;
180: break;
181: default:
182: loop = 0;
183: }
184: }
185:
186: /*
187: * get and evaluate the formated opcode string obtained from the
188: * opStrMap1&2[]
189: */
190:
191: /* get formatted opcode string and store in is[] */
192: if ( (tsp = useMap2 ? opStrMap2[ibp[0]] : opStrMap1[ibp[0]]) == NULL ) {
193: sprintf(sp, "Invalid instruction byte = %02x (opStrMap%d)\n"
194: , ibp[0], useMap2 ? 2 : 1);
195: return( sp = (char *)strchr(sp, '\0') );
196: }
197: strcpy(isp, tsp);
198:
199: /* Expand the formatted opcode string pointed at by isp to produce an
200: assembler nmeumonic string. Make sure sp is pointing to the current
201: end-of-string after each loop. */
202: for ( ; isp[0]; isp++) {
203: switch (isp[0]) {
204: case '%':
205: if ( (isp = fmatPercent(isp, sp, s, ibp)) == NULL) {
206: printf("Invalid opcode string.\n");
207: return(NULL);
208: }
209: /* point to end of string */
210: sp = (char *)strchr(sp, '\0');
211: break;
212: case ' ':
213: *sp++ = '\t';
214: *sp = '\0';
215: break;
216: default:
217: *sp++ = isp[0];
218: *sp = '\0';
219:
220: }
221: }
222: return(sp);
223: }
224:
225:
226: /*
227: * Evalute "%c1c2" and store the expanded results in wb[]. Then, copy wb[] into
228: * sp[] and return isp pointing to the next character of the formatted
229: * instruction string.
230: *
231: * CAREFULL! - when doing string manipulations, make sure that wbp
232: * is pointing at '\0' before breaking from switch statement.
233: */
234: char *
235: fmatPercent(isp, sp, s, ibp)
236: char *isp, *sp;
237: int s;
238: unsigned char *ibp;
239: {
240: char wb[MAXINSTLEN], *wbp; /* work buffer (pointer) */
241: unsigned char c1, c2; /* 1st & 2nd char after '%' */
242: long deltaVal;
243: unsigned long val;
244: char *tsp1, *tsp2; /* temporary string pointer */
245:
246: c1 = *++isp;
247: c2 = *++isp;
248: wbp = wb;
249: wbp[0] = '\0';
250:
251: switch (c1) {
252: case 'A':
253: c2 = c2opdsizeAdj(c2);
254: val = getVal(s, ibp, c2, UNSIGNED, ADDZERO, &deltaVal);
255: wbp = getSegValStr(ibp, wbp, c2);
256: wbp = getASCIIdisplcmtStr(wbp, 'a', UNSIGNED, s, deltaVal, val);
257: break;
258: case 'C':
259: getmodRM(s, ibp, sizeof(char));
260: wbp = (char *)strcpy(wbp, ctrlReg[mReg]);
261: wbp = (char *)strchr(wbp, '\0');
262: break;
263: case 'D':
264: getmodRM(s, ibp, sizeof(char));
265: wbp = (char *)strcpy(wbp, dbgReg[mReg]);
266: wbp = (char *)strchr(wbp, '\0');
267: break;
268: case 'E':
269: case 'M':
270: case 'R':
271: if (getaddrsize() == RM16)
272: wbp = getmodRM16str(s, ibp, c2, wbp);
273: else
274: wbp = getmodRM32str(s, ibp, c2, wbp);
275: break;
276: case 'G':
277: wbp = getmodREGstr(s, ibp, c2, wbp);
278: break;
279: case 'I':
280: *wbp++ = '$';
281: c2 = c2opdsizeAdj(c2);
282: val = getVal(s, ibp, c2, SIGNED, ADDZERO, &deltaVal);
283: wbp = getSegValStr(ibp, wbp, c2);
284: wbp = getASCIIimmediateStr(wbp, 'x',
285: SIGNED, s, deltaVal, val, c2);
286: break;
287: case 'J':
288: wbp = getSegPreStr(wbp);
289: c2 = c2opdsizeAdj(c2);
290: val = getVal(s, ibp, c2, SIGNED, ADDADDR, &deltaVal);
291: wbp = getSegValStr(ibp, wbp, c2);
292: wbp = getASCIIdisplcmtStr(wbp, 'a', SIGNED, s, deltaVal, val);
293: break;
294: case 'K':
295: wbp = getSegPreStr(wbp);
296: c2 = c2opdsizeAdj(c2);
297: val = getVal(s, ibp, c2, SIGNED, ADDADDR, &deltaVal);
298: wbp = getSegValStr(ibp, wbp, c2);
299: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED, s, deltaVal, val);
300: break;
301: /* case 'M': see case 'E'
302: break; */
303: case 'O':
304: wbp = getSegPreStr(wbp);
305: c2 = getaddrsize() == RM16 ? 'w' : 'd';
306: val = getVal(s, ibp, c2, SIGNED, ADDZERO, &deltaVal);
307: wbp = getSegValStr(ibp, wbp, c2);
308: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED,
309: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val);
310: break;
311: /* case 'R': see case 'E'
312: break; */
313: case 'S':
314: getmodRM(s, ibp, sizeof(char));
315: wbp = (char *)strcpy(wbp, segReg[mReg]);
316: wbp = (char *)strchr(wbp, '\0');
317: break;
318: case 'T':
319: getmodRM(s, ibp, sizeof(char));
320: wbp = (char *)strcpy(wbp, tstReg[mReg]);
321: wbp = (char *)strchr(wbp, '\0');
322: break;
323: case 'X':
324: /* if (getaddrsize()==RM16) {
325: sprintf(wbp, "ds:(%%si)");
326: }
327: else {
328: sprintf(wbp, "ds:(%%esi)");
329: }
330: wbp = (char *)strchr(wbp, '\0');
331: break;
332: */ case 'Y':
333: /* if (getaddrsize()==RM16) {
334: sprintf(wbp, "es:(%%di)");
335: }
336: else {
337: sprintf(wbp, "es:(%%edi)");
338: }
339: wbp = (char *)strchr(wbp, '\0');
340: */ break;
341: case 'Z':
342: c2 = c2opdsizeAdj(c2);
343: switch(c2) {
344: case 'b':
345: *wbp++ = 'b';
346: break;
347: case 'd':
348: *wbp++ = 'l';
349: break;
350: case 'w':
351: *wbp++ = 'w';
352: break;
353: case 'z':
354: *wbp++ = (getopdsize()==RM16 ? 'w': 'l');
355: break;
356: }
357: wbp[0] = '\0';
358: break;
359: case 'e':
360: if (getopdsize()==OPD16) {
361: *wbp++ = '%';
362: *wbp++ = c2;
363: *wbp = '\0';
364: }
365: else {
366: *wbp++ = '%';
367: *wbp++ = 'e';
368: *wbp++ = c2;
369: *wbp = '\0';
370: }
371: break;
372: case 'g': /* just inserting the group string into isp */
373: getmodRM(s, ibp, sizeof(char));
374: if (grpStrMap[c2-'0'][mReg] == NULL) {
375: sprintf(wbp, "\nInvalid instruction byte = %02x (grpStrMap[%d][%d])\n"
376: , ibp[0], c2-'0', mReg);
377: return( wbp = (char *)strchr(wbp, '\0') );
378: }
379: tsp1 = malloc(MAXINSTLEN);
380: tsp2 = isp;
381: strcpy(tsp1, isp+1);
382: strcpy(isp+1, grpStrMap[c2-'0'][mReg]);
383: isp = (char *)strchr(isp+1, '\0');
384: strcpy(isp, tsp1);
385: isp = tsp2;
386: free(tsp1);
387: *wbp = '\0';
388: break;
389: case 'r':
390: if (getb(s, ibp, sizeof(char)) == 0)
391: return (NULL);
392: break;
393: default:
394: *wbp++ = c1;
395: *wbp++ = c2;
396: *wbp = '\0';
397: }
398:
399: sp = (char *)strcpy(sp, wb);
400:
401: return(isp);
402: }
403:
404: char *
405: getmodREGstr(s, ibp, c2, wbp)
406: int s;
407: unsigned char *ibp;
408: char c2, *wbp;
409: {
410: getmodRM(s, ibp, sizeof(char));
411: strcpy(wbp, genReg[getgenRegIndex(c2)][mReg]);
412: wbp = (char *)strchr(wbp, '\0');
413: return(wbp);
414: }
415:
416: char *
417: getmodRM16str(s, ibp, c2, wbp)
418: int s;
419: unsigned char *ibp;
420: char c2, *wbp;
421: {
422: unsigned char genRegIndex;
423: long deltaVal;
424: unsigned long val;
425:
426: getmodRM(s, ibp, sizeof(char));
427: c2 = c2opdsizeAdj(c2);
428:
429: switch(m) {
430: case 0:
431: if (mRM==6) {
432: wbp = getSegPreStr(wbp);
433: val = getVal(s, ibp, 'w', SIGNED, ADDZERO, &deltaVal);
434: wbp = getSegValStr(ibp, wbp, 'w');
435: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED,
436: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val);
437: break;
438: }
439: wbp = getSegPreStr(wbp);
440: wbp = (char *)strcpy(wbp, modRMtab16[mRM] );
441: wbp = (char *)strchr(wbp, '\0');
442: break;
443: case 1:
444: wbp = getmodRMstr(s, ibp, wbp, 'b', 'd', RM16, 1);
445: break;
446: case 2:
447: wbp = getmodRMstr(s, ibp, wbp, 'w', 'd', RM16, 1);
448: break;
449: case 3:
450: genRegIndex = getgenRegIndex(c2);
451:
452: wbp = (char *)strcpy(wbp, genReg[genRegIndex][mRM]);
453: wbp = (char *)strchr(wbp, '\0');
454: break;
455: }
456: return(wbp);
457: }
458:
459: char *
460: getmodRM32str(s, ibp, c2, wbp)
461: int s;
462: unsigned char *ibp;
463: char c2, *wbp;
464: {
465: unsigned char genRegIndex;
466: long deltaVal;
467: unsigned long val;
468:
469: getmodRM(s, ibp, sizeof(char));
470: c2 = c2opdsizeAdj(c2);
471:
472: switch(m) {
473: case 0:
474: if (mRM==4) {
475: wbp = getsibstr(s, ibp, wbp, '\0', m);
476: break;
477: }
478: if (mRM==5) {
479: wbp = getSegPreStr(wbp);
480: val = getVal(s, ibp, 'd', SIGNED, ADDZERO, &deltaVal);
481: wbp = getSegValStr(ibp, wbp, 'd');
482: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED,
483: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val);
484: break;
485: }
486: wbp = getSegPreStr(wbp);
487: wbp = (char *)strcpy(wbp, modRMtab32[mRM] );
488: wbp = (char *)strchr(wbp, '\0');
489: break;
490: case 1:
491: if (mRM==4) {
492: wbp = getsibstr(s, ibp, wbp, 'b', m);
493: break;
494: }
495: wbp = getmodRMstr(s, ibp, wbp, 'b', 'd', RM32, 1);
496: break;
497: case 2:
498: if (mRM==4) {
499: wbp = getsibstr(s, ibp, wbp, 'd', m);
500: break;
501: }
502: wbp = getmodRMstr(s, ibp, wbp, 'd', 'd', RM32, 1);
503: break;
504: case 3:
505: genRegIndex = getgenRegIndex(c2);
506:
507: wbp = (char *)strcpy(wbp, genReg[genRegIndex][mRM]);
508: wbp = (char *)strchr(wbp, '\0');
509: break;
510: }
511: return(wbp);
512: }
513:
514: char *
515: getmodRMstr(s, ibp, wbp, displctsize, form, addrsize, signedVal)
516: int s;
517: unsigned char *ibp;
518: char *wbp;
519: unsigned char displctsize, form, addrsize, signedVal;
520: {
521: long deltaVal;
522: unsigned long val;
523:
524: wbp = getSegPreStr(wbp);
525:
526: val = getVal(s, ibp, displctsize, signedVal, ADDZERO, &deltaVal);
527: wbp = getSegValStr(ibp, wbp, displctsize);
528: wbp = getASCIIdisplcmtStr(wbp, form, signedVal, s, deltaVal, val);
529:
530: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(addrsize)][mRM] );
531: wbp = (char *)strchr(wbp, '\0');
532:
533: return(wbp);
534: }
535:
536: char *
537: getsibstr(s, ibp, wbp, displctsize, m)
538: int s;
539: unsigned char *ibp;
540: char *wbp;
541: unsigned char displctsize, m;
542: {
543: long deltaVal;
544: unsigned long val;
545:
546: getsib(s, ibp, sizeof(char));
547:
548: switch(m) {
549: case 0:
550: wbp = getSegPreStr(wbp);
551: if (sb == EBP_SIB) {
552: val = getVal(s, ibp, 'd', SIGNED, ADDZERO, &deltaVal);
553: wbp = getSegValStr(ibp, wbp, 'd');
554: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val);
555: }
556: else {
557: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]);
558: wbp = (char *)strchr(wbp, '\0');
559: }
560: break;
561: case 1:
562: wbp = getSegPreStr(wbp);
563:
564: val = getVal(s, ibp, displctsize, SIGNED, ADDZERO, &deltaVal);
565: wbp = getSegValStr(ibp, wbp, displctsize);
566: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val);
567:
568: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]);
569: wbp = (char *)strchr(wbp, '\0');
570: break;
571: case 2:
572: wbp = getSegPreStr(wbp);
573:
574: val = getVal(s, ibp, displctsize, SIGNED, ADDZERO, &deltaVal);
575: wbp = getSegValStr(ibp, wbp, displctsize);
576: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val);
577:
578: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]);
579: wbp = (char *)strchr(wbp, '\0');
580: break;
581: }
582: if (sibtab[sss][sx] != NULL) {
583: wbp = (char *)strcpy(wbp, sibtab[sss][sx]);
584: wbp = (char *)strchr(wbp, '\0');
585: }
586: return(wbp);
587: }
588:
589: unsigned long
590: getVal(s, ibp, mysizeof, signedVal, addVal, deltaValp)
591: int s;
592: unsigned char *ibp;
593: unsigned char mysizeof, signedVal;
594: unsigned char addVal;
595: long *deltaValp;
596: {
597: unsigned char nbytes;
598: unsigned long val;
599:
600: if ( (nbytes = getValData(s, ibp, signedVal, mysizeof)) == 0)
601: return(ADDZERO);
602: nbytes = check4prefix(mysizeof, nbytes);
603: val = evalValData(ibp, signedVal, nbytes, addVal, deltaValp);
604: return(val);
605: }
606:
607: unsigned short
608: getValData(s, ibp, signedVal, mysizeof)
609: int s;
610: unsigned char *ibp, signedVal;
611: unsigned char mysizeof;
612: {
613: unsigned char nbytes, i;
614:
615: if ( (nbytes = getnbytes(mysizeof)) == 0 )
616: return(0);
617:
618: if ( (getb(s, ibp, nbytes)) == 0 ) {
619: printf("Unable to read opcode displacement or immediate data\n");
620: return (0);
621: }
622:
623: for (i=nbytes; i<MAXDISPLCTSIZE; i++) {
624: if (signedVal)
625: ibp[i] = (ibp[i-1] & 0x80) ? 0xFF : 0;
626: else
627: ibp[i] = 0;
628: }
629: return(nbytes);
630: }
631:
632: unsigned char
633: check4prefix(mysizeof, nbytes)
634: {
635: switch(mysizeof) {
636: case 'f': /* 32 bit pointer */
637: case 'l': /* 48 bit pointer */
638: nbytes -= 2;
639: break;
640: }
641: return(nbytes);
642: }
643:
644: unsigned long
645: evalValData(ibp, signedVal, nbytes, addVal, deltaValp)
646: unsigned char *ibp;
647: unsigned char signedVal, nbytes;
648: unsigned char addVal;
649: long *deltaValp;
650: {
651: unsigned long baseVal, val;
652:
653: if (addVal)
654: baseVal = add;
655: else baseVal = 0L;
656:
657: switch (nbytes) {
658: case DBBYTE:
659: if (signedVal) {
660: *deltaValp = *(signed char *)ibp;
661: if ((signed long)*deltaValp >= 0)
662: val = baseVal + *deltaValp;
663: else
664: val = baseVal
665: - (unsigned long)
666: (-(signed long)*deltaValp);
667: }
668: else {
669: *deltaValp = *(unsigned char *)ibp;
670: val = baseVal + *deltaValp;
671: }
672: break;
673: case DBWORD:
674: if (signedVal) {
675: *deltaValp = *(signed short *)ibp;
676: if ((signed long)*deltaValp >= 0)
677: val = baseVal + *deltaValp;
678: else
679: val = baseVal
680: - (unsigned long)
681: (-(signed long)*deltaValp);
682: }
683: else {
684: *deltaValp = *(unsigned short *)ibp;
685: val = baseVal + *deltaValp;
686: }
687: break;
688: case DBLONG:
689: *deltaValp = *(long *)ibp;
690: if (signedVal) {
691: if ((signed long)*deltaValp >= 0)
692: val = baseVal + *deltaValp;
693: else
694: val = baseVal
695: - (unsigned long)
696: (-(signed long)*deltaValp);
697: }
698: else {
699: val = baseVal + *deltaValp;
700: }
701: break;
702: }
703: return(val);
704: }
705:
706: char *
707: getSegValStr(ibp, wbp, mysizeof)
708: unsigned char *ibp;
709: char *wbp;
710: unsigned char mysizeof;
711: {
712: unsigned char nbytes;
713:
714: nbytes = getnbytes(mysizeof);
715:
716: switch(mysizeof) {
717: case 'f': /* 32 bit pointer */
718: case 'l': /* 48 bit pointer */
719: sprintf(wbp, "0x%02x%02x:", ibp[nbytes-1], ibp[nbytes-2]);
720: wbp = (char *)strchr(wbp, '\0');
721: break;
722: }
723: return(wbp);
724: }
725:
726: char *
727: getASCIIimmediateStr(wbp, form, signedVal, segn, deltaVal, val, mysizeof)
728: char *wbp;
729: unsigned char form, signedVal;
730: int segn;
731: signed long deltaVal;
732: unsigned long val;
733: unsigned char mysizeof;
734: {
735: switch (getnbytes(mysizeof)) {
736: case DBBYTE:
737: val &= 0xFF;
738: break;
739: case DBWORD:
740: val &= 0xFFFF;
741: break;
742: }
743: getASCIIdisplcmtStr(wbp, form, signedVal, segn, deltaVal, val);
744: }
745:
746: char *
747: getASCIIdisplcmtStr(wbp, form, signedVal, segn, deltaVal, val)
748: char *wbp;
749: unsigned char form, signedVal;
750: int segn;
751: signed long deltaVal;
752: unsigned long val;
753: {
754: if (signedVal && deltaVal<0)
755: deltaVal = -deltaVal;
756: switch(form) {
757: case 'a': /* print address */
758: if ( deltaVal > TOLSYM) /* print out symbol, if possible */
759: conaddr(wbp, segn, val, I);
760: else { /* Print out address in hex format */
761: *wbp = '(';
762: printaddr(wbp, val);
763: wbp = (char *)strchr(wbp, '\0');
764: *wbp = ')';
765: *wbp = '\0';
766: }
767: break;
768: case 'd': /* print decimal */
769: if (!val)
770: break;
771: /* if (deltaVal > TOLSYM) {
772: conaddr(wbp, segn, val, I);
773: }
774: else {
775: */ if (getopdsize()==OPD16) {
776: sprintf(wbp, "%d", val);
777: }
778: else {
779: sprintf(wbp, "%ld", val);
780: }
781: /* }
782: */ break;
783: case 's': /* if available, print symbol; otherwise print address */
784: conaddr(wbp, segn, val, I);
785: break;
786: case 'x': /* print hex */
787: /* if (deltaVal > TOLSYM) {
788: conaddr(wbp, segn, val, I);
789: }
790: else {
791: */ if (getopdsize()==OPD16) {
792: if (deltaVal > TOLHEX) {
793: sprintf(wbp, "0x%x", val);
794: }
795: else {
796: sprintf(wbp, "%d", val);
797: }
798: }
799: else {
800: if (deltaVal > TOLHEX) {
801: sprintf(wbp, "0x%lx", val);
802: }
803: else {
804: sprintf(wbp, "%ld", val);
805: }
806: }
807: /* }
808: */ break;
809: default:
810: if(1) printf("invalid form = %c; ", form);
811: }
812:
813: wbp = (char *)strchr(wbp, '\0');
814: return(wbp);
815: }
816:
817: printaddr(wbp, v)
818: char *wbp;
819: unsigned long v;
820: {
821: if (getopdsize()==OPD16) {
822: sprintf(wbp, "%04x", v);
823: }
824: else {
825: sprintf(wbp, "%04X", v);
826: }
827: }
828:
829: char *
830: getSegPreStr(wbp)
831: char *wbp;
832: {
833: if (segflag) {
834: strcpy(wbp, segPreStrp);
835: wbp = (char *)strchr(wbp, '\0');
836: }
837: return(wbp);
838: }
839:
840: unsigned char c2opdsizeAdj(c2)
841: unsigned char c2;
842: {
843: if (getopdsize()==RM16) {
844: switch(c2) { /* set to addr16 lengths */
845: case 'a':
846: c2 = 'w';
847: break;
848: case 'p':
849: c2 = 'f';
850: break;
851: case 'v':
852: c2 = 'w';
853: break;
854: }
855: }
856: else {
857: switch(c2) { /* set to addr32 lengths */
858: case 'a':
859: c2 = 'd';
860: break;
861: case 'p':
862: c2 = 'l';
863: break;
864: case 'v':
865: c2 = 'd';
866: break;
867: }
868: }
869: return(c2);
870: }
871:
872: unsigned char
873: getnbytes(mysizeof)
874: unsigned char mysizeof;
875: {
876: unsigned char nbytes;
877:
878: switch(mysizeof) {
879: case 'b':
880: nbytes = DBBYTE;
881: break;
882: case 'd':
883: nbytes = DBLONG;
884: break;
885: case 'f':
886: nbytes = DBPTR32;
887: break;
888: case 'l':
889: nbytes = DBPTR48;
890: break;
891: case 'w':
892: nbytes = DBWORD;
893: break;
894: case '\0':
895: nbytes = 0;
896: break;
897: default:
898: if(1) printf("invalid nbytes = %c; "
899: "a 1 byte size is chosen by default\n"
900: , mysizeof);
901: nbytes = DBBYTE;
902: }
903: return(nbytes);
904: }
905:
906: unsigned char
907: getgenRegIndex(c2)
908: unsigned char c2;
909: {
910: unsigned char genRegIndex;
911:
912: switch(c2) {
913: case 'a':
914: if (getopdsize() == OPD16)
915: genRegIndex = 1;
916: else
917: genRegIndex = 2;
918: break;
919: case 'b':
920: genRegIndex = 0;
921: break;
922: case 'd':
923: genRegIndex = 2;
924: break;
925: case 'v':
926: if (getopdsize() == OPD16)
927: genRegIndex = 1;
928: else
929: genRegIndex = 2;
930: break;
931: case 'w':
932: genRegIndex = 1;
933: break;
934: default:
935: if(1) printf("invalid c2 = %c; "
936: "a 1 byte reg is shown by default\n"
937: , c2);
938: genRegIndex = 0;
939: }
940: return(genRegIndex);
941: }
942:
943: getaddrsize()
944: {
945: return( addrflag ? 48 - hdrinfo.defsegatt : hdrinfo.defsegatt );
946: }
947:
948: getopdsize()
949: {
950: return( opdflag ? 48 - hdrinfo.defsegatt : hdrinfo.defsegatt );
951: }
952:
953: getmodRM(s, ibp, c)
954: unsigned char *ibp;
955: unsigned c;
956: {
957: if (!modRMloaded) {
958: if (getb(s, ibp, c) == 0)
959: return (NULL);
960: m = mod(ibp[0]);
961: mRM = modRM(ibp[0]);
962: mReg = modR(ibp[0]);
963: modRMloaded = 1;
964: }
965: }
966:
967: getsib(s, ibp, c)
968: unsigned char *ibp;
969: unsigned c;
970: {
971: if (!sibLoaded) {
972: if ((getb(s, ibp, c)) == 0)
973: return (NULL);
974: sss = sibss(ibp[0]);
975: sx = sibx(ibp[0]);
976: sb = sibb(ibp[0]);
977: sibLoaded = 1;
978: }
979: }
980:
981: /*
982: * Given a size character, `t1', and a type, `t2', return the appropriate
983: * format string.
984: */
985: char *
986: getform(t1, t2)
987: register int t1;
988: register int t2;
989: {
990: register char *cp;
991: register char *sp;
992:
993: if (t1=='f' || t1=='F')
994: return ("%g");
995: if (t1 == 'h')
996: t1 = 'w';
997: if ((cp=strchr(sp="bwlv", t1)) == NULL)
998: return ("?");
999: t1 = cp-sp;
1000: if ((cp=strchr(sp="duox", t2)) == NULL)
1001: return ("?");
1002: t2 = cp-sp;
1003: return (formtab[t1][t2]);
1004: }
1005:
1006: /* End of i8086b1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.