[9] | 1 | /*
|
---|
| 2 | * mdbdis86.c for mdb.c - 8086-386 and 8087 disassembler
|
---|
| 3 | * From Bruce Evans db
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | #include "mdb.h"
|
---|
| 7 | #include <stddef.h>
|
---|
| 8 | #include <stdio.h>
|
---|
| 9 | #include <sys/types.h>
|
---|
| 10 | #include "proto.h"
|
---|
| 11 |
|
---|
| 12 | struct address_s
|
---|
| 13 | {
|
---|
| 14 | off_t off;
|
---|
| 15 | off_t base;
|
---|
| 16 | };
|
---|
| 17 |
|
---|
| 18 | PRIVATE int bits32;
|
---|
| 19 | PRIVATE struct address_s uptr;
|
---|
| 20 |
|
---|
| 21 | FORWARD _PROTOTYPE( u8_t get8, (void) );
|
---|
| 22 | FORWARD _PROTOTYPE( u16_t get16, (void) );
|
---|
| 23 | FORWARD _PROTOTYPE( u32_t get32, (void) );
|
---|
| 24 | FORWARD _PROTOTYPE( u8_t peek_byte, (off_t addr) );
|
---|
| 25 | FORWARD _PROTOTYPE( u16_t peek_word, (off_t addr) );
|
---|
| 26 | FORWARD _PROTOTYPE( int puti, (void) );
|
---|
| 27 | FORWARD _PROTOTYPE( int outsegaddr, (struct address_s *addr) );
|
---|
| 28 | FORWARD _PROTOTYPE( int outssegaddr, (struct address_s *addr) );
|
---|
| 29 | FORWARD _PROTOTYPE( int show1instruction , (void));
|
---|
| 30 |
|
---|
| 31 | /************************* UNASM ******************************/
|
---|
| 32 |
|
---|
| 33 |
|
---|
| 34 | #define LINDIRECT '['
|
---|
| 35 | #define RINDIRECT ']'
|
---|
| 36 |
|
---|
| 37 | #define BASE_MASK 0x07
|
---|
| 38 | #define INDEX_MASK 0x38
|
---|
| 39 | #define INDEX_SHIFT 3
|
---|
| 40 | #define MOD_MASK 0xC0 /* mod reg r/m is mmrrrRRR */
|
---|
| 41 | #define REG_MOD 0xC0
|
---|
| 42 | #define MEM0_MOD 0x00
|
---|
| 43 | #define MEM1_MOD 0x40
|
---|
| 44 | #define MEM2_MOD 0x80
|
---|
| 45 | #define REG_MASK 0x38
|
---|
| 46 | #define REG_SHIFT 3
|
---|
| 47 | #define RM_MASK 0x07
|
---|
| 48 | #define RM_SHIFT 0
|
---|
| 49 | #define SS_MASK 0xC0
|
---|
| 50 | #define SS_SHIFT 6
|
---|
| 51 |
|
---|
| 52 | #define SIGNBIT 0x02 /* opcode bits xxxxxxsw for immediates */
|
---|
| 53 | #define WORDBIT 0x01
|
---|
| 54 | #define TOREGBIT 0x02 /* opcode bit for non-immediates */
|
---|
| 55 |
|
---|
| 56 | #define MAX_SIGNED_CHAR 0x7F /* will assume 2's complement */
|
---|
| 57 | #define MAX_UNSIGNED_CHAR 0xFF
|
---|
| 58 |
|
---|
| 59 | typedef unsigned opcode_pt; /* promote to unsigned and not int */
|
---|
| 60 |
|
---|
| 61 | typedef int reg_pt;
|
---|
| 62 | typedef int su16_t;
|
---|
| 63 | typedef int su8_pt;
|
---|
| 64 |
|
---|
| 65 | FORWARD _PROTOTYPE( su8_pt get8s , (void));
|
---|
| 66 | FORWARD _PROTOTYPE( void getmodregrm , (void));
|
---|
| 67 | FORWARD _PROTOTYPE( void i_00_to_3f , (opcode_pt opc ));
|
---|
| 68 | FORWARD _PROTOTYPE( void i_40_to_5f , (opcode_pt opc ));
|
---|
| 69 | FORWARD _PROTOTYPE( void i_60_to_6f , (opcode_pt opc ));
|
---|
| 70 | FORWARD _PROTOTYPE( void i_70_to_7f , (opcode_pt opc ));
|
---|
| 71 | FORWARD _PROTOTYPE( void i_80 , (opcode_pt opc ));
|
---|
| 72 | FORWARD _PROTOTYPE( void i_88 , (opcode_pt opc ));
|
---|
| 73 | FORWARD _PROTOTYPE( void i_90 , (opcode_pt opc ));
|
---|
| 74 | FORWARD _PROTOTYPE( void i_98 , (opcode_pt opc ));
|
---|
| 75 | FORWARD _PROTOTYPE( void i_a0 , (opcode_pt opc ));
|
---|
| 76 | FORWARD _PROTOTYPE( void i_a8 , (opcode_pt opc ));
|
---|
| 77 | FORWARD _PROTOTYPE( void i_b0 , (opcode_pt opc ));
|
---|
| 78 | FORWARD _PROTOTYPE( void i_b8 , (opcode_pt opc ));
|
---|
| 79 | FORWARD _PROTOTYPE( void i_c0 , (opcode_pt opc ));
|
---|
| 80 | FORWARD _PROTOTYPE( void i_c8 , (opcode_pt opc ));
|
---|
| 81 | FORWARD _PROTOTYPE( void i_d0 , (opcode_pt opc ));
|
---|
| 82 | FORWARD _PROTOTYPE( void i_d8 , (opcode_pt opc ));
|
---|
| 83 | FORWARD _PROTOTYPE( void i_e0 , (opcode_pt opc ));
|
---|
| 84 | FORWARD _PROTOTYPE( void i_e8 , (opcode_pt opc ));
|
---|
| 85 | FORWARD _PROTOTYPE( void i_f0 , (opcode_pt opc ));
|
---|
| 86 | FORWARD _PROTOTYPE( void i_f8 , (opcode_pt opc ));
|
---|
| 87 | FORWARD _PROTOTYPE( void outad , (opcode_pt opc ));
|
---|
| 88 | FORWARD _PROTOTYPE( void outad1 , (opcode_pt opc ));
|
---|
| 89 | FORWARD _PROTOTYPE( void outalorx , (opcode_pt opc ));
|
---|
| 90 | FORWARD _PROTOTYPE( void outax , (void));
|
---|
| 91 | FORWARD _PROTOTYPE( void outbptr , (void));
|
---|
| 92 | FORWARD _PROTOTYPE( void outbwptr , (opcode_pt opc ));
|
---|
| 93 | FORWARD _PROTOTYPE( void outea , (opcode_pt wordflags ));
|
---|
| 94 | FORWARD _PROTOTYPE( void outf1 , (void));
|
---|
| 95 | FORWARD _PROTOTYPE( void out32offset , (void));
|
---|
| 96 | FORWARD _PROTOTYPE( void outfishy , (void));
|
---|
| 97 | FORWARD _PROTOTYPE( void outgetaddr , (void));
|
---|
| 98 | FORWARD _PROTOTYPE( void outimmed , (opcode_pt signwordflag ));
|
---|
| 99 | FORWARD _PROTOTYPE( void outpc , (off_t pc ));
|
---|
| 100 | FORWARD _PROTOTYPE( void outsegpc , (void));
|
---|
| 101 | FORWARD _PROTOTYPE( void oututstr , (char *s ));
|
---|
| 102 | FORWARD _PROTOTYPE( void outword , (void));
|
---|
| 103 | FORWARD _PROTOTYPE( void outwptr , (void));
|
---|
| 104 | FORWARD _PROTOTYPE( void outwsize , (void));
|
---|
| 105 | FORWARD _PROTOTYPE( void pagef , (void));
|
---|
| 106 | FORWARD _PROTOTYPE( void shift , (opcode_pt opc ));
|
---|
| 107 | FORWARD _PROTOTYPE( void checkmemory , (void));
|
---|
| 108 | FORWARD _PROTOTYPE( void CL , (void));
|
---|
| 109 | FORWARD _PROTOTYPE( void Eb , (void));
|
---|
| 110 | FORWARD _PROTOTYPE( void Ev , (void));
|
---|
| 111 | FORWARD _PROTOTYPE( void EvGv , (void));
|
---|
| 112 | FORWARD _PROTOTYPE( void EvIb , (void));
|
---|
| 113 | FORWARD _PROTOTYPE( void Ew , (void));
|
---|
| 114 | FORWARD _PROTOTYPE( void EwRw , (void));
|
---|
| 115 | FORWARD _PROTOTYPE( void Gv , (void));
|
---|
| 116 | FORWARD _PROTOTYPE( void Gv1 , (void));
|
---|
| 117 | FORWARD _PROTOTYPE( void GvEv , (void));
|
---|
| 118 | FORWARD _PROTOTYPE( void GvEw , (void));
|
---|
| 119 | FORWARD _PROTOTYPE( void GvM , (void));
|
---|
| 120 | FORWARD _PROTOTYPE( void GvMa , (void));
|
---|
| 121 | FORWARD _PROTOTYPE( void GvMp , (void));
|
---|
| 122 | FORWARD _PROTOTYPE( void Ib , (void));
|
---|
| 123 | FORWARD _PROTOTYPE( void Iw , (void));
|
---|
| 124 | FORWARD _PROTOTYPE( void Iv , (void));
|
---|
| 125 | FORWARD _PROTOTYPE( void Jb , (void));
|
---|
| 126 | FORWARD _PROTOTYPE( void Jv , (void));
|
---|
| 127 | FORWARD _PROTOTYPE( void Ms , (void));
|
---|
| 128 |
|
---|
| 129 | _PROTOTYPE( typedef void (*pfv_t),(opcode_pt opc ));
|
---|
| 130 |
|
---|
| 131 | PRIVATE pfv_t optable[] =
|
---|
| 132 | {
|
---|
| 133 | i_00_to_3f,
|
---|
| 134 | i_00_to_3f,
|
---|
| 135 | i_00_to_3f,
|
---|
| 136 | i_00_to_3f,
|
---|
| 137 | i_00_to_3f,
|
---|
| 138 | i_00_to_3f,
|
---|
| 139 | i_00_to_3f,
|
---|
| 140 | i_00_to_3f,
|
---|
| 141 | i_40_to_5f,
|
---|
| 142 | i_40_to_5f,
|
---|
| 143 | i_40_to_5f,
|
---|
| 144 | i_40_to_5f,
|
---|
| 145 | i_60_to_6f,
|
---|
| 146 | i_60_to_6f,
|
---|
| 147 | i_70_to_7f,
|
---|
| 148 | i_70_to_7f,
|
---|
| 149 | i_80,
|
---|
| 150 | i_88,
|
---|
| 151 | i_90,
|
---|
| 152 | i_98,
|
---|
| 153 | i_a0,
|
---|
| 154 | i_a8,
|
---|
| 155 | i_b0,
|
---|
| 156 | i_b8,
|
---|
| 157 | i_c0,
|
---|
| 158 | i_c8,
|
---|
| 159 | i_d0,
|
---|
| 160 | i_d8,
|
---|
| 161 | i_e0,
|
---|
| 162 | i_e8,
|
---|
| 163 | i_f0,
|
---|
| 164 | i_f8,
|
---|
| 165 | };
|
---|
| 166 |
|
---|
| 167 | PRIVATE char fishy[] = "???";
|
---|
| 168 | PRIVATE char movtab[] = "mov\t";
|
---|
| 169 |
|
---|
| 170 | PRIVATE char *genreg[] =
|
---|
| 171 | {
|
---|
| 172 | "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
|
---|
| 173 | "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
|
---|
| 174 | "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
---|
| 175 | };
|
---|
| 176 |
|
---|
| 177 | PRIVATE char *segreg[] =
|
---|
| 178 | {
|
---|
| 179 | "es", "cs", "ss", "ds", "fs", "gs", "?s", "?s",
|
---|
| 180 | };
|
---|
| 181 |
|
---|
| 182 | PRIVATE char *indreg[] =
|
---|
| 183 | {
|
---|
| 184 | "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx",
|
---|
| 185 | };
|
---|
| 186 |
|
---|
| 187 | PRIVATE char *str_00_to_3f[] =
|
---|
| 188 | {
|
---|
| 189 | /* index by (opcode >> 3) & 7 */
|
---|
| 190 | "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp",
|
---|
| 191 | };
|
---|
| 192 |
|
---|
| 193 | PRIVATE char *sstr_00_to_3f[] =
|
---|
| 194 | {
|
---|
| 195 | /* index ((opc>>2) & 0x0E) + (opc & 7) - 6 */
|
---|
| 196 | "push\tes", "pop\tes", "push\tcs", "pop\tcs",
|
---|
| 197 | "push\tss", "pop\tss", "push\tds", "pop\tds",
|
---|
| 198 | "es:", "daa", "cs:", "das", "ss:", "aaa", "ds:", "aas",
|
---|
| 199 | };
|
---|
| 200 |
|
---|
| 201 | PRIVATE char *sstr_0f[] =
|
---|
| 202 | {
|
---|
| 203 | "push\tfs", "pop\tfs", fishy, "bt\t", "shld\t", "shld\t", fishy, fishy,
|
---|
| 204 | "push\tgs", "pop\tgs", fishy, "bts\t", "shrd\t", "shrd\t", fishy, "imul\t",
|
---|
| 205 | fishy, fishy, "lss\t", "btr\t", "lfs\t", "lgs\t", "movzx\t", "movzx\t",
|
---|
| 206 | fishy, fishy, "", "btc\t", "bsf\t", "bsr\t", "movsx\t", "movsx\t",
|
---|
| 207 | };
|
---|
| 208 |
|
---|
| 209 | PRIVATE char *ssstr_0f[] =
|
---|
| 210 | {
|
---|
| 211 | "sldt\t", "str\t", "lldt\t", "ltr\t", "verr\t", "verw\t", fishy, fishy,
|
---|
| 212 | "sgdt\t", "sidt\t", "lgdt\t", "lidt\t", "smsw\t", fishy, "lmsw\t", fishy,
|
---|
| 213 | fishy, fishy, fishy, fishy, "bt\t", "bts\t", "btr\t", "btc\t",
|
---|
| 214 | };
|
---|
| 215 |
|
---|
| 216 | PRIVATE char *str_40_to_5f[] =
|
---|
| 217 | {
|
---|
| 218 | /* index by (opcode >> 3) & 3 */
|
---|
| 219 | "inc\t", "dec\t", "push\t", "pop\t",
|
---|
| 220 | };
|
---|
| 221 |
|
---|
| 222 | PRIVATE char *str_60_to_6f[] =
|
---|
| 223 | {
|
---|
| 224 | "pusha", "popa", "bound\t", "arpl\t", "fs:", "gs:", "os:", "as:",
|
---|
| 225 | "push\t", "imul\t", "push\t", "imul\t", "insb", "ins", "outsb", "outs",
|
---|
| 226 | };
|
---|
| 227 |
|
---|
| 228 | PRIVATE char *str_flags[] =
|
---|
| 229 | {
|
---|
| 230 | /* opcodes 0x70 to 0x7F, and 0x0F80 to 0x0F9F */
|
---|
| 231 | "o", "no", "b", "nb", "z", "nz", "be", "a",
|
---|
| 232 | "s", "ns", "pe", "po", "l", "ge", "le", "g",
|
---|
| 233 | };
|
---|
| 234 |
|
---|
| 235 | PRIVATE char *str_98[] =
|
---|
| 236 | {
|
---|
| 237 | "cbw", "cwd", "call\t", "wait", "pushf", "popf", "sahf", "lahf",
|
---|
| 238 | "cwde", "cdq", "call\t", "wait", "pushfd", "popfd", "sahf", "lahf",
|
---|
| 239 | };
|
---|
| 240 |
|
---|
| 241 | PRIVATE char *str_a0[] =
|
---|
| 242 | {
|
---|
| 243 | movtab, movtab, movtab, movtab, "movsb", "movs", "cmpsb", "cmps",
|
---|
| 244 | };
|
---|
| 245 |
|
---|
| 246 | PRIVATE char *str_a8[] =
|
---|
| 247 | {
|
---|
| 248 | "test\t", "test\t", "stosb", "stos", "lodsb", "lods", "scasb", "scas",
|
---|
| 249 | };
|
---|
| 250 |
|
---|
| 251 | PRIVATE char *str_c0[] =
|
---|
| 252 | {
|
---|
| 253 | "", "", "ret\t", "ret", "les\t", "lds\t", movtab, movtab,
|
---|
| 254 | };
|
---|
| 255 |
|
---|
| 256 | PRIVATE char *str_c8[] =
|
---|
| 257 | {
|
---|
| 258 | "enter\t", "leave", "retf\t", "retf", "int\t3", "int\t", "into", "iret",
|
---|
| 259 | };
|
---|
| 260 |
|
---|
| 261 | PRIVATE char *str_d0[] =
|
---|
| 262 | {
|
---|
| 263 | "aam", "aad", "db\td6", "xlat",
|
---|
| 264 | };
|
---|
| 265 |
|
---|
| 266 | PRIVATE char *sstr_d0[] =
|
---|
| 267 | {
|
---|
| 268 | "rol", "ror", "rcl", "rcr", "shl", "shr", fishy, "sar",
|
---|
| 269 | };
|
---|
| 270 |
|
---|
| 271 | PRIVATE char *str_d8[] =
|
---|
| 272 | {
|
---|
| 273 | "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
|
---|
| 274 | "fld", NULL, "fst", "fstp", "fldenv", "fldcw", "fstenv", "fstcw",
|
---|
| 275 | "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr",
|
---|
| 276 | "fild", NULL, "fist", "fistp", NULL, "fld", NULL, "fstp",
|
---|
| 277 | "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
|
---|
| 278 | "fld", NULL, "fst", "fstp", "frstor", NULL, "fsave", "fstsw",
|
---|
| 279 | "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr",
|
---|
| 280 | "fild", NULL, "fist", "fistp", "fbld", "fild", "fbstp", "fistp",
|
---|
| 281 | };
|
---|
| 282 |
|
---|
| 283 | PRIVATE char *str1_d8[] =
|
---|
| 284 | {
|
---|
| 285 | "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
|
---|
| 286 | "fld", "fxch", "\0\0", NULL, "\0\10", "\0\20", "\0\30", "\0\40",
|
---|
| 287 | NULL, NULL, NULL, NULL, NULL, "\0\50", NULL, NULL,
|
---|
| 288 | NULL, NULL, NULL, NULL, "\0\60", NULL, NULL, NULL,
|
---|
| 289 | "fadd", "fmul", NULL, NULL, "fsubr", "fsub", "fdivr", "fdiv",
|
---|
| 290 | "ffree", NULL, "fst", "fstp", "fucom", "fucomp", NULL, NULL,
|
---|
| 291 | "faddp", "fmulp", NULL, "\0\70", "fsubrp", "fsubp", "fdivrp", "fdivp",
|
---|
| 292 | NULL, NULL, NULL, NULL, "\0\100", NULL, NULL, NULL,
|
---|
| 293 | };
|
---|
| 294 |
|
---|
| 295 | PRIVATE unsigned char size_d8[] =
|
---|
| 296 | {
|
---|
| 297 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 14-28, 2, 14-28, 2,
|
---|
| 298 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 0, 10, 0, 10,
|
---|
| 299 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 94-108, 0, 94-108, 2,
|
---|
| 300 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 10, 8, 10, 8,
|
---|
| 301 | };
|
---|
| 302 |
|
---|
| 303 | PRIVATE char *sstr_d8[] =
|
---|
| 304 | {
|
---|
| 305 | "fnop", NULL, NULL, NULL, /* D9D0 */
|
---|
| 306 | NULL, NULL, NULL, NULL,
|
---|
| 307 | "fchs", "fabs", NULL, NULL, /* D9E0 */
|
---|
| 308 | "ftst", "fxam", NULL, NULL,
|
---|
| 309 | "fld1", "fldl2t", "fldl2e", "fldpi", /* D9E8 */
|
---|
| 310 | "fldlg2", "fldln2", "fldz", NULL,
|
---|
| 311 | "f2xm1", "fyl2x", "fptan", "fpatan", /* D9F0 */
|
---|
| 312 | "fxtract", "fprem1", "fdecstp", "fincstp",
|
---|
| 313 | "fprem", "fyl2xp1", "fsqrt", "fsincos", /* D9F8 */
|
---|
| 314 | "frndint", "fscale", "fsin", "fcos",
|
---|
| 315 | NULL, "fucompp", NULL, NULL, /* DAE8 */
|
---|
| 316 | NULL, NULL, NULL, NULL,
|
---|
| 317 | "feni", "fdisi", "fclex", "finit", /* DBE0 */
|
---|
| 318 | "fsetpm", NULL, NULL, NULL,
|
---|
| 319 | NULL, "fcompp", NULL, NULL, /* DED8 */
|
---|
| 320 | NULL, NULL, NULL, NULL,
|
---|
| 321 | NULL, NULL, NULL, NULL, /* DFE0 */
|
---|
| 322 | "fstsw\tax", NULL, NULL, NULL,
|
---|
| 323 | };
|
---|
| 324 |
|
---|
| 325 | PRIVATE char *str_e0[] =
|
---|
| 326 | {
|
---|
| 327 | "loopnz\t", "loopz\t", "loop\t", "jcxz\t",
|
---|
| 328 | "in\t", "in\t", "out\t", "out\t",
|
---|
| 329 | };
|
---|
| 330 |
|
---|
| 331 | PRIVATE char *str_e8[] =
|
---|
| 332 | {
|
---|
| 333 | "call\t", "jmp\t", "jmp\t", "jmp\t",
|
---|
| 334 | "in\t", "in\t", "out\t", "out\t",
|
---|
| 335 | };
|
---|
| 336 |
|
---|
| 337 | PRIVATE char *str_f0[] =
|
---|
| 338 | {
|
---|
| 339 | "lock\t", "db\tf1", "repnz\t", "repz\t",
|
---|
| 340 | "hlt", "cmc",
|
---|
| 341 | /* other 2 from sstr_f0 */
|
---|
| 342 | };
|
---|
| 343 |
|
---|
| 344 | PRIVATE char *sstr_f0[] =
|
---|
| 345 | {
|
---|
| 346 | "test\t", fishy, "not\t", "neg\t",
|
---|
| 347 | "mul\t", "imul\t", "div\t", "idiv\t",
|
---|
| 348 | };
|
---|
| 349 |
|
---|
| 350 | PRIVATE char *str_f8[] =
|
---|
| 351 | {
|
---|
| 352 | "clc", "stc", "cli", "sti",
|
---|
| 353 | "cld", "std",
|
---|
| 354 | /* other 2 from sstr_f8 */
|
---|
| 355 | };
|
---|
| 356 |
|
---|
| 357 | PRIVATE char *sstr_f8[] =
|
---|
| 358 | {
|
---|
| 359 | "inc\t", "dec\t", "call\t", "call\tfar ",
|
---|
| 360 | "jmp\t", "jmp\tfar ", "push\t", "???\t",
|
---|
| 361 | };
|
---|
| 362 |
|
---|
| 363 | PRIVATE int data_seg; /* data segment (munged name for asld) */
|
---|
| 364 | PRIVATE unsigned hasize; /* half address size in bits */
|
---|
| 365 | PRIVATE unsigned hdefsize;
|
---|
| 366 | PRIVATE unsigned hosize; /* half operand size in bits */
|
---|
| 367 | /* for easy index into reg tables */
|
---|
| 368 | PRIVATE opcode_pt mod;
|
---|
| 369 | PRIVATE off_t offtable[2];
|
---|
| 370 | PRIVATE off_t *offptr;
|
---|
| 371 | PRIVATE off_t *off1ptr;
|
---|
| 372 | PRIVATE opcode_pt reg;
|
---|
| 373 | PRIVATE opcode_pt rm;
|
---|
| 374 |
|
---|
| 375 | PRIVATE su8_pt get8s()
|
---|
| 376 | {
|
---|
| 377 | u8_t got;
|
---|
| 378 |
|
---|
| 379 | if ((got = get8()) > MAX_SIGNED_CHAR)
|
---|
| 380 | got -= (MAX_UNSIGNED_CHAR + 1);
|
---|
| 381 | return got;
|
---|
| 382 | }
|
---|
| 383 |
|
---|
| 384 | PRIVATE void getmodregrm()
|
---|
| 385 | {
|
---|
| 386 | opcode_pt modregrm;
|
---|
| 387 |
|
---|
| 388 | modregrm = get8();
|
---|
| 389 | mod = modregrm & MOD_MASK;
|
---|
| 390 | reg = (modregrm & REG_MASK) >> REG_SHIFT;
|
---|
| 391 | rm = (modregrm & RM_MASK) >> RM_SHIFT;
|
---|
| 392 | }
|
---|
| 393 |
|
---|
| 394 | PRIVATE void i_00_to_3f(opc)
|
---|
| 395 | opcode_pt opc;
|
---|
| 396 | {
|
---|
| 397 | opcode_pt sub;
|
---|
| 398 |
|
---|
| 399 | if (opc == 15)
|
---|
| 400 | pagef();
|
---|
| 401 | else if ((sub = opc & 7) >= 6)
|
---|
| 402 | {
|
---|
| 403 | outustr((sstr_00_to_3f - 6)[((opc >> 2) & 0x0E) + sub]);
|
---|
| 404 | if (!(opc & 1))
|
---|
| 405 | data_seg = opc;
|
---|
| 406 | }
|
---|
| 407 | else
|
---|
| 408 | {
|
---|
| 409 | oututstr(str_00_to_3f[(opc >> 3) & 7]);
|
---|
| 410 | if (sub == 4)
|
---|
| 411 | {
|
---|
| 412 | outustr(genreg[0]);
|
---|
| 413 | outcomma();
|
---|
| 414 | Ib();
|
---|
| 415 | }
|
---|
| 416 | else if (sub == 5)
|
---|
| 417 | {
|
---|
| 418 | outax();
|
---|
| 419 | outcomma();
|
---|
| 420 | Iv();
|
---|
| 421 | }
|
---|
| 422 | else
|
---|
| 423 | outad(sub);
|
---|
| 424 | }
|
---|
| 425 | }
|
---|
| 426 |
|
---|
| 427 | PRIVATE void i_40_to_5f(opc)
|
---|
| 428 | opcode_pt opc;
|
---|
| 429 | {
|
---|
| 430 | outustr(str_40_to_5f[(opc >> 3) & 3]);
|
---|
| 431 | outustr(genreg[hosize + (opc & 7)]);
|
---|
| 432 | }
|
---|
| 433 |
|
---|
| 434 | PRIVATE void i_60_to_6f(opc)
|
---|
| 435 | opcode_pt opc;
|
---|
| 436 | {
|
---|
| 437 | /* most for 386, some for 286 */
|
---|
| 438 |
|
---|
| 439 | outustr((str_60_to_6f - 0x60)[opc]);
|
---|
| 440 | switch (opc)
|
---|
| 441 | {
|
---|
| 442 | case 0x60:
|
---|
| 443 | case 0x61:
|
---|
| 444 | if (hosize == 16)
|
---|
| 445 | outwsize();
|
---|
| 446 | break;
|
---|
| 447 | case 0x62:
|
---|
| 448 | GvMa();
|
---|
| 449 | break;
|
---|
| 450 | case 0x63:
|
---|
| 451 | EwRw();
|
---|
| 452 | break;
|
---|
| 453 | case 0x64:
|
---|
| 454 | case 0x65:
|
---|
| 455 | data_seg = opc;
|
---|
| 456 | break;
|
---|
| 457 | case 0x66:
|
---|
| 458 | hosize = (16 + 8) - hdefsize;
|
---|
| 459 | break;
|
---|
| 460 | case 0x67:
|
---|
| 461 | hasize = (16 + 8) - hdefsize;
|
---|
| 462 | break;
|
---|
| 463 | case 0x68:
|
---|
| 464 | outword();
|
---|
| 465 | Iv();
|
---|
| 466 | break;
|
---|
| 467 | case 0x6A:
|
---|
| 468 | outword();
|
---|
| 469 | outimmed(SIGNBIT | WORDBIT);
|
---|
| 470 | break;
|
---|
| 471 | case 0x69:
|
---|
| 472 | GvEv();
|
---|
| 473 | outcomma();
|
---|
| 474 | Iv();
|
---|
| 475 | break;
|
---|
| 476 | case 0x6B:
|
---|
| 477 | GvEv();
|
---|
| 478 | outcomma();
|
---|
| 479 | outimmed(SIGNBIT | WORDBIT);
|
---|
| 480 | break;
|
---|
| 481 | case 0x6D:
|
---|
| 482 | case 0x6F:
|
---|
| 483 | outwsize();
|
---|
| 484 | break;
|
---|
| 485 | }
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | PRIVATE void i_70_to_7f(opc)
|
---|
| 489 | opcode_pt opc;
|
---|
| 490 | {
|
---|
| 491 | outustr("j");
|
---|
| 492 | oututstr((str_flags - 0x70)[opc]);
|
---|
| 493 | Jb();
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | PRIVATE void i_80(opc)
|
---|
| 497 | opcode_pt opc;
|
---|
| 498 | {
|
---|
| 499 | if (opc >= 4)
|
---|
| 500 | {
|
---|
| 501 | outustr(opc >= 6 ? "xchg\t" : "test\t");
|
---|
| 502 | outad(opc);
|
---|
| 503 | }
|
---|
| 504 | else
|
---|
| 505 | {
|
---|
| 506 | getmodregrm();
|
---|
| 507 | oututstr(str_00_to_3f[reg]);
|
---|
| 508 | outbwptr(opc);
|
---|
| 509 | outea(opc);
|
---|
| 510 | outcomma();
|
---|
| 511 | outimmed(opc);
|
---|
| 512 | #ifdef SIGNED_LOGICALS
|
---|
| 513 | if (opc & SIGNBIT && (reg == 1 || reg == 4 || reg == 6))
|
---|
| 514 | /* and, or and xor with signe extension are not documented in some
|
---|
| 515 | * 8086 and 80286 manuals, but make sense and work
|
---|
| 516 | */
|
---|
| 517 | outfishy();
|
---|
| 518 | #endif
|
---|
| 519 | }
|
---|
| 520 | }
|
---|
| 521 |
|
---|
| 522 | PRIVATE void i_88(opc)
|
---|
| 523 | opcode_pt opc;
|
---|
| 524 | {
|
---|
| 525 | if (opc < 4)
|
---|
| 526 | {
|
---|
| 527 | outustr(movtab);
|
---|
| 528 | outad(opc);
|
---|
| 529 | }
|
---|
| 530 | else if (opc == 5)
|
---|
| 531 | {
|
---|
| 532 | oututstr("lea");
|
---|
| 533 | GvM();
|
---|
| 534 | }
|
---|
| 535 | else if (opc == 7)
|
---|
| 536 | {
|
---|
| 537 | oututstr("pop");
|
---|
| 538 | getmodregrm();
|
---|
| 539 | outwptr();
|
---|
| 540 | Ev();
|
---|
| 541 | if (reg != 0)
|
---|
| 542 | outfishy();
|
---|
| 543 | }
|
---|
| 544 | else
|
---|
| 545 | {
|
---|
| 546 | getmodregrm();
|
---|
| 547 | outustr(movtab);
|
---|
| 548 | if (!(opc & TOREGBIT))
|
---|
| 549 | {
|
---|
| 550 | Ev();
|
---|
| 551 | outcomma();
|
---|
| 552 | }
|
---|
| 553 | outustr(segreg[reg]);
|
---|
| 554 | if (opc & TOREGBIT)
|
---|
| 555 | {
|
---|
| 556 | outcomma();
|
---|
| 557 | Ev();
|
---|
| 558 | }
|
---|
| 559 | }
|
---|
| 560 | }
|
---|
| 561 |
|
---|
| 562 | PRIVATE void i_90(opc)
|
---|
| 563 | opcode_pt opc;
|
---|
| 564 | {
|
---|
| 565 | if (opc == 0)
|
---|
| 566 | outustr("nop");
|
---|
| 567 | else
|
---|
| 568 | {
|
---|
| 569 | outustr("xchg\t");
|
---|
| 570 | outax();
|
---|
| 571 | outcomma();
|
---|
| 572 | outustr(genreg[hosize + opc]);
|
---|
| 573 | }
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | PRIVATE void i_98(opc)
|
---|
| 577 | opcode_pt opc;
|
---|
| 578 | {
|
---|
| 579 | outustr((str_98 - 8)[opc + hosize]);
|
---|
| 580 | if (opc == 2)
|
---|
| 581 | outsegpc();
|
---|
| 582 | }
|
---|
| 583 |
|
---|
| 584 | PRIVATE void i_a0(opc)
|
---|
| 585 | opcode_pt opc;
|
---|
| 586 | {
|
---|
| 587 | outustr(str_a0[opc]);
|
---|
| 588 | if (opc < 4)
|
---|
| 589 | {
|
---|
| 590 | mod = MEM0_MOD; /* fake */
|
---|
| 591 | reg = 0; /* fake ax */
|
---|
| 592 | if (hasize == 16)
|
---|
| 593 | rm = 5; /* fake [d16] */
|
---|
| 594 | else
|
---|
| 595 | rm = 6; /* fake [d32] */
|
---|
| 596 | outad1(opc ^ TOREGBIT);
|
---|
| 597 | }
|
---|
| 598 | else if (opc & 1)
|
---|
| 599 | outwsize();
|
---|
| 600 | }
|
---|
| 601 |
|
---|
| 602 | PRIVATE void i_a8(opc)
|
---|
| 603 | opcode_pt opc;
|
---|
| 604 | {
|
---|
| 605 | outustr(str_a8[opc]);
|
---|
| 606 | if (opc < 2)
|
---|
| 607 | {
|
---|
| 608 | outalorx(opc);
|
---|
| 609 | outcomma();
|
---|
| 610 | outimmed(opc);
|
---|
| 611 | }
|
---|
| 612 | else if (opc & 1)
|
---|
| 613 | outwsize();
|
---|
| 614 | }
|
---|
| 615 |
|
---|
| 616 | PRIVATE void i_b0(opc)
|
---|
| 617 | opcode_pt opc;
|
---|
| 618 | {
|
---|
| 619 | outustr(movtab);
|
---|
| 620 | outustr(genreg[opc]);
|
---|
| 621 | outcomma();
|
---|
| 622 | Ib();
|
---|
| 623 | }
|
---|
| 624 |
|
---|
| 625 | PRIVATE void i_b8(opc)
|
---|
| 626 | opcode_pt opc;
|
---|
| 627 | {
|
---|
| 628 | outustr(movtab);
|
---|
| 629 | outustr(genreg[hosize + opc]);
|
---|
| 630 | outcomma();
|
---|
| 631 | Iv();
|
---|
| 632 | }
|
---|
| 633 |
|
---|
| 634 | PRIVATE void i_c0(opc)
|
---|
| 635 | opcode_pt opc;
|
---|
| 636 | {
|
---|
| 637 | outustr(str_c0[opc]);
|
---|
| 638 | if (opc >= 6)
|
---|
| 639 | {
|
---|
| 640 | getmodregrm();
|
---|
| 641 | outbwptr(opc);
|
---|
| 642 | outea(opc);
|
---|
| 643 | outcomma();
|
---|
| 644 | outimmed(opc & WORDBIT);
|
---|
| 645 | if (reg != 0)
|
---|
| 646 | /* not completely decoded (like DEBUG) */
|
---|
| 647 | outfishy();
|
---|
| 648 | }
|
---|
| 649 | else if (opc >= 4)
|
---|
| 650 | GvMp();
|
---|
| 651 | else if (opc == 2)
|
---|
| 652 | Iv();
|
---|
| 653 | else if (opc < 2)
|
---|
| 654 | shift(opc);
|
---|
| 655 | }
|
---|
| 656 |
|
---|
| 657 | PRIVATE void i_c8(opc)
|
---|
| 658 | opcode_pt opc;
|
---|
| 659 | {
|
---|
| 660 | outustr(str_c8[opc]);
|
---|
| 661 | if (opc == 0)
|
---|
| 662 | {
|
---|
| 663 | Iw();
|
---|
| 664 | outcomma();
|
---|
| 665 | Ib();
|
---|
| 666 | }
|
---|
| 667 | if (opc == 2)
|
---|
| 668 | Iv();
|
---|
| 669 | else if (opc == 5)
|
---|
| 670 | Ib();
|
---|
| 671 | else if (opc == 7 && hosize == 16)
|
---|
| 672 | outwsize();
|
---|
| 673 | }
|
---|
| 674 |
|
---|
| 675 | PRIVATE void i_d0(opc)
|
---|
| 676 | opcode_pt opc;
|
---|
| 677 | {
|
---|
| 678 | opcode_pt aabyte;
|
---|
| 679 |
|
---|
| 680 | if (opc < 4)
|
---|
| 681 | shift(opc | 0xD0);
|
---|
| 682 | else
|
---|
| 683 | {
|
---|
| 684 | outustr((str_d0 - 4)[opc]);
|
---|
| 685 | if (opc < 6 && (aabyte = get8()) != 0x0A)
|
---|
| 686 | {
|
---|
| 687 | outtab();
|
---|
| 688 | outh8(aabyte);
|
---|
| 689 | outfishy();
|
---|
| 690 | }
|
---|
| 691 | }
|
---|
| 692 | }
|
---|
| 693 |
|
---|
| 694 | PRIVATE void i_d8(opc)
|
---|
| 695 | opcode_pt opc;
|
---|
| 696 | {
|
---|
| 697 | opcode_pt esc;
|
---|
| 698 | char *str;
|
---|
| 699 |
|
---|
| 700 | getmodregrm();
|
---|
| 701 | esc = (opc << 3) | reg;
|
---|
| 702 | if ((str = (mod == REG_MOD ? str1_d8 : str_d8)[esc]) == NULL)
|
---|
| 703 | {
|
---|
| 704 | escape:
|
---|
| 705 | oututstr("esc");
|
---|
| 706 | outh8(esc);
|
---|
| 707 | outcomma();
|
---|
| 708 | outea(0);
|
---|
| 709 | return;
|
---|
| 710 | }
|
---|
| 711 | if (*str == 0)
|
---|
| 712 | {
|
---|
| 713 | str = sstr_d8[str[1] + rm];
|
---|
| 714 | if (str == NULL)
|
---|
| 715 | goto escape;
|
---|
| 716 | outustr(str);
|
---|
| 717 | return;
|
---|
| 718 | }
|
---|
| 719 | outustr(str);
|
---|
| 720 | outtab();
|
---|
| 721 | if (mod == REG_MOD)
|
---|
| 722 | {
|
---|
| 723 | if (opc == 0 && reg != 2 && reg != 3)
|
---|
| 724 | outustr("st,");
|
---|
| 725 | outf1();
|
---|
| 726 | if (opc == 4 || opc == 6)
|
---|
| 727 | outustr(",st");
|
---|
| 728 | return;
|
---|
| 729 | }
|
---|
| 730 | switch(size_d8[esc])
|
---|
| 731 | {
|
---|
| 732 | case 4:
|
---|
| 733 | outustr("d");
|
---|
| 734 | case 2:
|
---|
| 735 | outwptr();
|
---|
| 736 | break;
|
---|
| 737 | case 8:
|
---|
| 738 | outustr("q");
|
---|
| 739 | outwptr();
|
---|
| 740 | break;
|
---|
| 741 | case 10:
|
---|
| 742 | outustr("t");
|
---|
| 743 | outbptr();
|
---|
| 744 | break;
|
---|
| 745 | }
|
---|
| 746 | outea(opc);
|
---|
| 747 | }
|
---|
| 748 |
|
---|
| 749 | PRIVATE void i_e0(opc)
|
---|
| 750 | opcode_pt opc;
|
---|
| 751 | {
|
---|
| 752 | outustr(str_e0[opc]);
|
---|
| 753 | if (opc < 4)
|
---|
| 754 | Jb();
|
---|
| 755 | else if (opc < 6)
|
---|
| 756 | {
|
---|
| 757 | outalorx(opc);
|
---|
| 758 | outcomma();
|
---|
| 759 | Ib();
|
---|
| 760 | }
|
---|
| 761 | else
|
---|
| 762 | {
|
---|
| 763 | Ib();
|
---|
| 764 | outcomma();
|
---|
| 765 | outalorx(opc);
|
---|
| 766 | }
|
---|
| 767 | }
|
---|
| 768 |
|
---|
| 769 | PRIVATE void i_e8(opc)
|
---|
| 770 | opcode_pt opc;
|
---|
| 771 | {
|
---|
| 772 | outustr(str_e8[opc]);
|
---|
| 773 | if (opc < 2)
|
---|
| 774 | Jv();
|
---|
| 775 | else if (opc == 2)
|
---|
| 776 | outsegpc();
|
---|
| 777 | else if (opc == 3)
|
---|
| 778 | Jb();
|
---|
| 779 | else
|
---|
| 780 | {
|
---|
| 781 | if (opc & TOREGBIT)
|
---|
| 782 | {
|
---|
| 783 | outustr(genreg[10]);
|
---|
| 784 | outcomma();
|
---|
| 785 | outalorx(opc);
|
---|
| 786 | }
|
---|
| 787 | else
|
---|
| 788 | {
|
---|
| 789 | outalorx(opc);
|
---|
| 790 | outcomma();
|
---|
| 791 | outustr(genreg[10]);
|
---|
| 792 | }
|
---|
| 793 | }
|
---|
| 794 | }
|
---|
| 795 |
|
---|
| 796 | PRIVATE void i_f0(opc)
|
---|
| 797 | opcode_pt opc;
|
---|
| 798 | {
|
---|
| 799 | if (opc < 6)
|
---|
| 800 | outustr(str_f0[opc]);
|
---|
| 801 | else
|
---|
| 802 | {
|
---|
| 803 | getmodregrm();
|
---|
| 804 | outustr(sstr_f0[reg]);
|
---|
| 805 | outbwptr(opc);
|
---|
| 806 | outea(opc);
|
---|
| 807 | if (reg == 0)
|
---|
| 808 | {
|
---|
| 809 | outcomma();
|
---|
| 810 | outimmed(opc & WORDBIT);
|
---|
| 811 | }
|
---|
| 812 | }
|
---|
| 813 | }
|
---|
| 814 |
|
---|
| 815 | PRIVATE void i_f8(opc)
|
---|
| 816 | opcode_pt opc;
|
---|
| 817 | {
|
---|
| 818 | if (opc < 6)
|
---|
| 819 | outustr(str_f8[opc]);
|
---|
| 820 | else
|
---|
| 821 | {
|
---|
| 822 | getmodregrm();
|
---|
| 823 | if (opc == 6 && reg >= 2)
|
---|
| 824 | outustr("fishy\t");
|
---|
| 825 | else
|
---|
| 826 | outustr(sstr_f8[reg]);
|
---|
| 827 | outbwptr(opc);
|
---|
| 828 | outea(opc);
|
---|
| 829 | }
|
---|
| 830 | }
|
---|
| 831 |
|
---|
| 832 | PRIVATE void outad(opc)
|
---|
| 833 | opcode_pt opc;
|
---|
| 834 | {
|
---|
| 835 | getmodregrm();
|
---|
| 836 | outad1(opc);
|
---|
| 837 | }
|
---|
| 838 |
|
---|
| 839 | PRIVATE void outad1(opc)
|
---|
| 840 | opcode_pt opc;
|
---|
| 841 | {
|
---|
| 842 | if (!(opc & TOREGBIT))
|
---|
| 843 | {
|
---|
| 844 | outea(opc);
|
---|
| 845 | outcomma();
|
---|
| 846 | }
|
---|
| 847 | if (opc & WORDBIT)
|
---|
| 848 | Gv1();
|
---|
| 849 | else
|
---|
| 850 | outustr(genreg[reg]);
|
---|
| 851 | if (opc & TOREGBIT)
|
---|
| 852 | {
|
---|
| 853 | outcomma();
|
---|
| 854 | outea(opc);
|
---|
| 855 | }
|
---|
| 856 | }
|
---|
| 857 |
|
---|
| 858 | PRIVATE void outalorx(opc)
|
---|
| 859 | opcode_pt opc;
|
---|
| 860 | {
|
---|
| 861 | if (opc & WORDBIT)
|
---|
| 862 | outax();
|
---|
| 863 | else
|
---|
| 864 | outustr(genreg[0]);
|
---|
| 865 | }
|
---|
| 866 |
|
---|
| 867 | PRIVATE void outax()
|
---|
| 868 | {
|
---|
| 869 | outustr(genreg[hosize]);
|
---|
| 870 | }
|
---|
| 871 |
|
---|
| 872 | PRIVATE void outbptr()
|
---|
| 873 | {
|
---|
| 874 | outustr("byte ptr ");
|
---|
| 875 | }
|
---|
| 876 |
|
---|
| 877 | PRIVATE void outbwptr(opc)
|
---|
| 878 | opcode_pt opc;
|
---|
| 879 | {
|
---|
| 880 | if (mod != REG_MOD)
|
---|
| 881 | {
|
---|
| 882 | if (opc & WORDBIT)
|
---|
| 883 | outwptr();
|
---|
| 884 | else
|
---|
| 885 | outbptr();
|
---|
| 886 | }
|
---|
| 887 | }
|
---|
| 888 |
|
---|
| 889 | PRIVATE void outea(wordflags)
|
---|
| 890 | opcode_pt wordflags;
|
---|
| 891 | {
|
---|
| 892 | reg_pt base;
|
---|
| 893 | reg_pt index;
|
---|
| 894 | opcode_pt ss;
|
---|
| 895 | opcode_pt ssindexbase;
|
---|
| 896 |
|
---|
| 897 | if (mod == REG_MOD)
|
---|
| 898 | outustr(genreg[hosize * (wordflags & WORDBIT) + rm]);
|
---|
| 899 | else
|
---|
| 900 | {
|
---|
| 901 | outbyte(LINDIRECT);
|
---|
| 902 | if (hasize == 16)
|
---|
| 903 | {
|
---|
| 904 | if (rm == 4)
|
---|
| 905 | {
|
---|
| 906 | base = (ssindexbase = get8()) & BASE_MASK;
|
---|
| 907 | if (mod == MEM0_MOD && base == 5)
|
---|
| 908 | outgetaddr();
|
---|
| 909 | else
|
---|
| 910 | outustr((genreg + 16)[base]);
|
---|
| 911 | ss = (ssindexbase & SS_MASK) >> SS_SHIFT;
|
---|
| 912 | if ((index = (ssindexbase & INDEX_MASK) >> INDEX_SHIFT) != 4)
|
---|
| 913 | {
|
---|
| 914 | outbyte('+');
|
---|
| 915 | outustr((genreg + 16)[index]);
|
---|
| 916 | outstr("\0\0\0*2\0*4\0*8\0" + (3 * ss));
|
---|
| 917 | }
|
---|
| 918 | }
|
---|
| 919 | else if (mod == MEM0_MOD && rm == 5)
|
---|
| 920 | outgetaddr();
|
---|
| 921 | else
|
---|
| 922 | outustr((genreg + 16)[rm]);
|
---|
| 923 | }
|
---|
| 924 | else if (mod == MEM0_MOD && rm == 6)
|
---|
| 925 | outgetaddr();
|
---|
| 926 | else
|
---|
| 927 | outustr(indreg[rm]);
|
---|
| 928 | if (mod == MEM1_MOD)
|
---|
| 929 | /* fake sign extension to get +- */
|
---|
| 930 | outimmed(SIGNBIT | WORDBIT);
|
---|
| 931 | else if (mod == MEM2_MOD)
|
---|
| 932 | {
|
---|
| 933 | outbyte('+');
|
---|
| 934 | #if (_WORD_SIZE == 4)
|
---|
| 935 | out32offset();
|
---|
| 936 | #else
|
---|
| 937 | outgetaddr();
|
---|
| 938 | #endif
|
---|
| 939 | }
|
---|
| 940 | outbyte(RINDIRECT);
|
---|
| 941 | if (hasize == 16 && rm == 4 && index == 4 && ss != 0)
|
---|
| 942 | outfishy();
|
---|
| 943 | }
|
---|
| 944 | }
|
---|
| 945 |
|
---|
| 946 | PRIVATE void outf1()
|
---|
| 947 | {
|
---|
| 948 | outustr("st(");
|
---|
| 949 | outbyte((int) (rm + '0'));
|
---|
| 950 | outbyte(')');
|
---|
| 951 | }
|
---|
| 952 |
|
---|
| 953 | #if (_WORD_SIZE == 4)
|
---|
| 954 |
|
---|
| 955 | PRIVATE void out32offset()
|
---|
| 956 | {
|
---|
| 957 | off_t off;
|
---|
| 958 |
|
---|
| 959 | if (hasize == 16)
|
---|
| 960 | off = get32();
|
---|
| 961 | else
|
---|
| 962 | outfishy();
|
---|
| 963 |
|
---|
| 964 | outh32(off);
|
---|
| 965 | }
|
---|
| 966 | #endif
|
---|
| 967 |
|
---|
| 968 | PRIVATE void outfishy()
|
---|
| 969 | {
|
---|
| 970 | outustr("\t???");
|
---|
| 971 | }
|
---|
| 972 |
|
---|
| 973 | PRIVATE void outgetaddr()
|
---|
| 974 | {
|
---|
| 975 | off_t off;
|
---|
| 976 |
|
---|
| 977 | if (hasize == 16)
|
---|
| 978 | off = get32();
|
---|
| 979 | else
|
---|
| 980 | off = get16();
|
---|
| 981 |
|
---|
| 982 | if ( finds_data(off,data_seg) )
|
---|
| 983 | *offptr++ = off;
|
---|
| 984 | else if (hasize == 16)
|
---|
| 985 | outh32(off);
|
---|
| 986 | else
|
---|
| 987 | outh16((u16_t) off);
|
---|
| 988 | }
|
---|
| 989 |
|
---|
| 990 | PRIVATE void outimmed(signwordflag)
|
---|
| 991 | opcode_pt signwordflag;
|
---|
| 992 | {
|
---|
| 993 | su8_pt byte;
|
---|
| 994 |
|
---|
| 995 | if (signwordflag & WORDBIT)
|
---|
| 996 | {
|
---|
| 997 | if (signwordflag & SIGNBIT)
|
---|
| 998 | {
|
---|
| 999 | if ((byte = get8s()) < 0)
|
---|
| 1000 | {
|
---|
| 1001 | outbyte('-');
|
---|
| 1002 | byte = -byte;
|
---|
| 1003 | }
|
---|
| 1004 | else
|
---|
| 1005 | outbyte('+');
|
---|
| 1006 | outh8((u8_t) byte);
|
---|
| 1007 | }
|
---|
| 1008 | else
|
---|
| 1009 | Iv();
|
---|
| 1010 | }
|
---|
| 1011 | else
|
---|
| 1012 | Ib();
|
---|
| 1013 | }
|
---|
| 1014 |
|
---|
| 1015 | PRIVATE void outpc(pc)
|
---|
| 1016 | off_t pc;
|
---|
| 1017 | {
|
---|
| 1018 | if (hosize == 8)
|
---|
| 1019 | pc = (u16_t) pc;
|
---|
| 1020 |
|
---|
| 1021 | if ( finds_pc(pc) )
|
---|
| 1022 | *offptr++ = pc;
|
---|
| 1023 | else if (hosize == 16)
|
---|
| 1024 | outh32(pc);
|
---|
| 1025 | else
|
---|
| 1026 | outh16((u16_t) pc);
|
---|
| 1027 | }
|
---|
| 1028 |
|
---|
| 1029 | PRIVATE void outsegpc()
|
---|
| 1030 | {
|
---|
| 1031 | off_t oldbase;
|
---|
| 1032 | off_t pc;
|
---|
| 1033 |
|
---|
| 1034 | if (hosize == 16)
|
---|
| 1035 | pc = get32();
|
---|
| 1036 | else
|
---|
| 1037 | pc = get16();
|
---|
| 1038 | oldbase = uptr.base;
|
---|
| 1039 | outh16((u16_t) (uptr.base = get16())); /* fake seg for lookup of pc */
|
---|
| 1040 | /* TODO - convert to offset in protected mode */
|
---|
| 1041 | outbyte(':');
|
---|
| 1042 | outpc(pc);
|
---|
| 1043 | uptr.base = oldbase;
|
---|
| 1044 | }
|
---|
| 1045 |
|
---|
| 1046 | PRIVATE void oututstr(s)
|
---|
| 1047 | char *s;
|
---|
| 1048 | {
|
---|
| 1049 | outustr(s);
|
---|
| 1050 | outtab();
|
---|
| 1051 | }
|
---|
| 1052 |
|
---|
| 1053 | PRIVATE void outword()
|
---|
| 1054 | {
|
---|
| 1055 | outustr("dword " + ((16 - hosize) >> 3));
|
---|
| 1056 | }
|
---|
| 1057 |
|
---|
| 1058 | PRIVATE void outwptr()
|
---|
| 1059 | {
|
---|
| 1060 | outword();
|
---|
| 1061 | outustr("ptr ");
|
---|
| 1062 | }
|
---|
| 1063 |
|
---|
| 1064 | PRIVATE void outwsize()
|
---|
| 1065 | {
|
---|
| 1066 | if (hosize == 16)
|
---|
| 1067 | outustr("d");
|
---|
| 1068 | else
|
---|
| 1069 | outustr("w");
|
---|
| 1070 | }
|
---|
| 1071 |
|
---|
| 1072 | PRIVATE void pagef()
|
---|
| 1073 | {
|
---|
| 1074 | opcode_pt opc;
|
---|
| 1075 | int regbad;
|
---|
| 1076 |
|
---|
| 1077 | if ((opc = get8()) <= 1 || opc == 0xBA)
|
---|
| 1078 | {
|
---|
| 1079 | if (opc == 0xBA)
|
---|
| 1080 | opc = 16;
|
---|
| 1081 | else
|
---|
| 1082 | opc *= 8;
|
---|
| 1083 | getmodregrm();
|
---|
| 1084 | outustr(ssstr_0f[opc += reg]);
|
---|
| 1085 | if (opc < 6 || opc == 12 || opc == 14)
|
---|
| 1086 | Ew();
|
---|
| 1087 | else if (opc >= 8 && opc < 13)
|
---|
| 1088 | Ms();
|
---|
| 1089 | else if (opc >= 20)
|
---|
| 1090 | {
|
---|
| 1091 | outbwptr(WORDBIT);
|
---|
| 1092 | EvIb();
|
---|
| 1093 | }
|
---|
| 1094 | }
|
---|
| 1095 | else if (opc < 4)
|
---|
| 1096 | {
|
---|
| 1097 | oututstr("lar\0lsl" + 4 * (opc - 2));
|
---|
| 1098 | GvEw();
|
---|
| 1099 | }
|
---|
| 1100 | else if (opc == 5)
|
---|
| 1101 | {
|
---|
| 1102 | outustr("loadall");
|
---|
| 1103 | outfishy();
|
---|
| 1104 | }
|
---|
| 1105 | else if (opc == 6)
|
---|
| 1106 | outustr("clts");
|
---|
| 1107 | else if (opc < 0x20)
|
---|
| 1108 | outstr(fishy);
|
---|
| 1109 | else if (opc < 0x27 && opc != 0x25)
|
---|
| 1110 | {
|
---|
| 1111 | outustr(movtab);
|
---|
| 1112 | getmodregrm();
|
---|
| 1113 | hosize = 16;
|
---|
| 1114 | if (!(opc & TOREGBIT))
|
---|
| 1115 | {
|
---|
| 1116 | Ev(); /* Rd() since hosize is 16 */
|
---|
| 1117 | outcomma();
|
---|
| 1118 | }
|
---|
| 1119 | regbad = FALSE;
|
---|
| 1120 | if (opc & 1)
|
---|
| 1121 | {
|
---|
| 1122 | outustr("dr");
|
---|
| 1123 | if (reg == 4 || reg == 5)
|
---|
| 1124 | regbad = TRUE;
|
---|
| 1125 | }
|
---|
| 1126 | else if (opc < 0x24)
|
---|
| 1127 | {
|
---|
| 1128 | outustr("cr");
|
---|
| 1129 | if (reg >= 4 || reg == 1)
|
---|
| 1130 | regbad = TRUE;
|
---|
| 1131 | }
|
---|
| 1132 | else
|
---|
| 1133 | {
|
---|
| 1134 | outustr("tr");
|
---|
| 1135 | if (reg < 6)
|
---|
| 1136 | regbad = TRUE;
|
---|
| 1137 | }
|
---|
| 1138 | outbyte((int) (reg + '0'));
|
---|
| 1139 | if (opc & TOREGBIT)
|
---|
| 1140 | {
|
---|
| 1141 | outcomma();
|
---|
| 1142 | Ev();
|
---|
| 1143 | }
|
---|
| 1144 | if (regbad || mod != REG_MOD)
|
---|
| 1145 | outfishy();
|
---|
| 1146 | }
|
---|
| 1147 | else if (opc < 0x80)
|
---|
| 1148 | outstr(fishy);
|
---|
| 1149 | else if (opc < 0x90)
|
---|
| 1150 | {
|
---|
| 1151 | outustr("j");
|
---|
| 1152 | oututstr((str_flags - 0x80)[opc]);
|
---|
| 1153 | Jv();
|
---|
| 1154 | }
|
---|
| 1155 | else if (opc < 0xA0)
|
---|
| 1156 | {
|
---|
| 1157 | outustr("set");
|
---|
| 1158 | oututstr((str_flags - 0x90)[opc]);
|
---|
| 1159 | getmodregrm();
|
---|
| 1160 | outbwptr(0);
|
---|
| 1161 | Eb();
|
---|
| 1162 | }
|
---|
| 1163 | else if (opc < 0xC0)
|
---|
| 1164 | {
|
---|
| 1165 | outustr((sstr_0f - 0xA0)[opc]);
|
---|
| 1166 | switch (opc)
|
---|
| 1167 | {
|
---|
| 1168 | case 0xA3:
|
---|
| 1169 | case 0xAB:
|
---|
| 1170 | case 0xB3:
|
---|
| 1171 | case 0xBB:
|
---|
| 1172 | EvGv();
|
---|
| 1173 | break;
|
---|
| 1174 | case 0xA4:
|
---|
| 1175 | case 0xAC:
|
---|
| 1176 | EvGv();
|
---|
| 1177 | outcomma();
|
---|
| 1178 | Ib();
|
---|
| 1179 | break;
|
---|
| 1180 | case 0xA5:
|
---|
| 1181 | case 0xAD:
|
---|
| 1182 | EvGv();
|
---|
| 1183 | outcomma();
|
---|
| 1184 | CL();
|
---|
| 1185 | break;
|
---|
| 1186 | case 0xAF:
|
---|
| 1187 | case 0xBC:
|
---|
| 1188 | case 0xBD:
|
---|
| 1189 | GvEv();
|
---|
| 1190 | break;
|
---|
| 1191 | case 0xB2:
|
---|
| 1192 | case 0xB4:
|
---|
| 1193 | case 0xB5:
|
---|
| 1194 | GvMp();
|
---|
| 1195 | break;
|
---|
| 1196 | case 0xB6:
|
---|
| 1197 | case 0xBE:
|
---|
| 1198 | Gv();
|
---|
| 1199 | outcomma();
|
---|
| 1200 | outbwptr(opc);
|
---|
| 1201 | Eb();
|
---|
| 1202 | break;
|
---|
| 1203 | case 0xB7:
|
---|
| 1204 | case 0xBF:
|
---|
| 1205 | Gv();
|
---|
| 1206 | outcomma();
|
---|
| 1207 | hosize = 8; /* done in Ew(), but too late */
|
---|
| 1208 | outbwptr(opc);
|
---|
| 1209 | Ew();
|
---|
| 1210 | break;
|
---|
| 1211 | }
|
---|
| 1212 | }
|
---|
| 1213 | else
|
---|
| 1214 | outstr(fishy);
|
---|
| 1215 | }
|
---|
| 1216 |
|
---|
| 1217 | PRIVATE int puti()
|
---|
| 1218 | {
|
---|
| 1219 | static int hadprefix;
|
---|
| 1220 | opcode_pt opcode;
|
---|
| 1221 |
|
---|
| 1222 | more:
|
---|
| 1223 | offptr = offtable;
|
---|
| 1224 | opcode = get8();
|
---|
| 1225 | if (!hadprefix)
|
---|
| 1226 | {
|
---|
| 1227 | data_seg = DSEG;
|
---|
| 1228 | hdefsize = 8;
|
---|
| 1229 | if (bits32)
|
---|
| 1230 | hdefsize = 16;
|
---|
| 1231 | hosize =
|
---|
| 1232 | hasize = hdefsize;
|
---|
| 1233 | }
|
---|
| 1234 | (*optable[opcode >> 3])(opcode < 0x80 ? opcode : opcode & 7);
|
---|
| 1235 | if (offptr > offtable)
|
---|
| 1236 | {
|
---|
| 1237 | if (stringtab() >= 31)
|
---|
| 1238 | {
|
---|
| 1239 | outspace();
|
---|
| 1240 | outspace();
|
---|
| 1241 | }
|
---|
| 1242 | else
|
---|
| 1243 | while (stringtab() < 32)
|
---|
| 1244 | outtab();
|
---|
| 1245 | outbyte(';');
|
---|
| 1246 | for (off1ptr = offtable; off1ptr < offptr; ++off1ptr)
|
---|
| 1247 | {
|
---|
| 1248 | outspace();
|
---|
| 1249 | if (*off1ptr < 0x10000)
|
---|
| 1250 | outh16((u16_t) *off1ptr);
|
---|
| 1251 | else
|
---|
| 1252 | outh32(*off1ptr);
|
---|
| 1253 | }
|
---|
| 1254 | offptr = offtable;
|
---|
| 1255 | }
|
---|
| 1256 | if ((opcode & 0xE7) == 0x26 ||
|
---|
| 1257 | opcode >= 0x64 && opcode < 0x68 ||
|
---|
| 1258 | opcode == 0xF0 || opcode == 0xF2 || opcode == 0xF3)
|
---|
| 1259 | /* not finished instruction for 0x26, 0x2E, 0x36, 0x3E seg overrides
|
---|
| 1260 | * and 0x64, 0x65 386 seg overrides
|
---|
| 1261 | * and 0x66, 0x67 386 size prefixes
|
---|
| 1262 | * and 0xF0 lock, 0xF2 repne, 0xF3 rep
|
---|
| 1263 | */
|
---|
| 1264 | {
|
---|
| 1265 | hadprefix = TRUE;
|
---|
| 1266 | goto more; /* TODO - print prefixes better */
|
---|
| 1267 | return FALSE;
|
---|
| 1268 | }
|
---|
| 1269 | hadprefix = FALSE;
|
---|
| 1270 | return TRUE;
|
---|
| 1271 | }
|
---|
| 1272 |
|
---|
| 1273 | PRIVATE void shift(opc)
|
---|
| 1274 | opcode_pt opc;
|
---|
| 1275 | {
|
---|
| 1276 | getmodregrm();
|
---|
| 1277 | oututstr(sstr_d0[reg]);
|
---|
| 1278 | outbwptr(opc);
|
---|
| 1279 | outea(opc);
|
---|
| 1280 | outcomma();
|
---|
| 1281 | if (opc < 0xD0)
|
---|
| 1282 | Ib();
|
---|
| 1283 | else if (opc & 2)
|
---|
| 1284 | CL();
|
---|
| 1285 | else
|
---|
| 1286 | outbyte('1');
|
---|
| 1287 | }
|
---|
| 1288 |
|
---|
| 1289 | PRIVATE void checkmemory()
|
---|
| 1290 | {
|
---|
| 1291 | if (mod == REG_MOD)
|
---|
| 1292 | outfishy();
|
---|
| 1293 | }
|
---|
| 1294 |
|
---|
| 1295 | PRIVATE void CL()
|
---|
| 1296 | {
|
---|
| 1297 | outustr(genreg[1]);
|
---|
| 1298 | }
|
---|
| 1299 |
|
---|
| 1300 | PRIVATE void Eb()
|
---|
| 1301 | {
|
---|
| 1302 | outea(0);
|
---|
| 1303 | }
|
---|
| 1304 |
|
---|
| 1305 | PRIVATE void Ev()
|
---|
| 1306 | {
|
---|
| 1307 | outea(WORDBIT);
|
---|
| 1308 | }
|
---|
| 1309 |
|
---|
| 1310 | PRIVATE void EvGv()
|
---|
| 1311 | {
|
---|
| 1312 | getmodregrm();
|
---|
| 1313 | Ev();
|
---|
| 1314 | outcomma();
|
---|
| 1315 | Gv1();
|
---|
| 1316 | }
|
---|
| 1317 |
|
---|
| 1318 | PRIVATE void EvIb()
|
---|
| 1319 | {
|
---|
| 1320 | Ev();
|
---|
| 1321 | outcomma();
|
---|
| 1322 | Ib();
|
---|
| 1323 | }
|
---|
| 1324 |
|
---|
| 1325 | PRIVATE void Ew()
|
---|
| 1326 | {
|
---|
| 1327 | hosize = 8;
|
---|
| 1328 | Ev();
|
---|
| 1329 | }
|
---|
| 1330 |
|
---|
| 1331 | PRIVATE void EwRw()
|
---|
| 1332 | {
|
---|
| 1333 | hosize = 8;
|
---|
| 1334 | EvGv();
|
---|
| 1335 | }
|
---|
| 1336 |
|
---|
| 1337 | PRIVATE void Gv()
|
---|
| 1338 | {
|
---|
| 1339 | getmodregrm();
|
---|
| 1340 | Gv1();
|
---|
| 1341 | }
|
---|
| 1342 |
|
---|
| 1343 | PRIVATE void Gv1()
|
---|
| 1344 | {
|
---|
| 1345 | outustr(genreg[hosize + reg]);
|
---|
| 1346 | }
|
---|
| 1347 |
|
---|
| 1348 | PRIVATE void GvEv()
|
---|
| 1349 | {
|
---|
| 1350 | Gv();
|
---|
| 1351 | outcomma();
|
---|
| 1352 | Ev();
|
---|
| 1353 | }
|
---|
| 1354 |
|
---|
| 1355 | PRIVATE void GvEw()
|
---|
| 1356 | {
|
---|
| 1357 | Gv();
|
---|
| 1358 | outcomma();
|
---|
| 1359 | Ew();
|
---|
| 1360 | }
|
---|
| 1361 |
|
---|
| 1362 | PRIVATE void GvM()
|
---|
| 1363 | {
|
---|
| 1364 | GvEv();
|
---|
| 1365 | checkmemory();
|
---|
| 1366 | }
|
---|
| 1367 |
|
---|
| 1368 | PRIVATE void GvMa()
|
---|
| 1369 | {
|
---|
| 1370 | GvM();
|
---|
| 1371 | }
|
---|
| 1372 |
|
---|
| 1373 | PRIVATE void GvMp()
|
---|
| 1374 | {
|
---|
| 1375 | GvM();
|
---|
| 1376 | }
|
---|
| 1377 |
|
---|
| 1378 | PRIVATE void Ib()
|
---|
| 1379 | {
|
---|
| 1380 | outh8(get8());
|
---|
| 1381 | }
|
---|
| 1382 |
|
---|
| 1383 | PRIVATE void Iw()
|
---|
| 1384 | {
|
---|
| 1385 | outh16(get16());
|
---|
| 1386 | }
|
---|
| 1387 |
|
---|
| 1388 | PRIVATE void Iv()
|
---|
| 1389 | {
|
---|
| 1390 | if (hosize == 16)
|
---|
| 1391 | outh32(get32());
|
---|
| 1392 | else
|
---|
| 1393 | Iw();
|
---|
| 1394 | }
|
---|
| 1395 |
|
---|
| 1396 | PRIVATE void Jb()
|
---|
| 1397 | {
|
---|
| 1398 | off_t pcjump;
|
---|
| 1399 |
|
---|
| 1400 | pcjump = get8s();
|
---|
| 1401 | outpc(pcjump + uptr.off);
|
---|
| 1402 | }
|
---|
| 1403 |
|
---|
| 1404 | PRIVATE void Jv()
|
---|
| 1405 | {
|
---|
| 1406 | off_t pcjump;
|
---|
| 1407 |
|
---|
| 1408 | if (hosize == 16)
|
---|
| 1409 | pcjump = get32();
|
---|
| 1410 | else
|
---|
| 1411 | pcjump = (su16_t) get16();
|
---|
| 1412 | outpc(pcjump + uptr.off);
|
---|
| 1413 | }
|
---|
| 1414 |
|
---|
| 1415 | PRIVATE void Ms()
|
---|
| 1416 | {
|
---|
| 1417 | Ev();
|
---|
| 1418 | checkmemory();
|
---|
| 1419 | }
|
---|
| 1420 |
|
---|
| 1421 | /********************* DASM ******************************/
|
---|
| 1422 |
|
---|
| 1423 | PUBLIC long dasm( addr, count, symflg )
|
---|
| 1424 | long addr;
|
---|
| 1425 | int count;
|
---|
| 1426 | int symflg;
|
---|
| 1427 | {
|
---|
| 1428 | #if (_WORD_SIZE == 4)
|
---|
| 1429 | bits32 = TRUE; /* Set mode */
|
---|
| 1430 | #else
|
---|
| 1431 | bits32 = FALSE;
|
---|
| 1432 | #endif
|
---|
| 1433 | uptr.off = addr;
|
---|
| 1434 | uptr.base = 0; /* not known */
|
---|
| 1435 | while ( count-- != 0 && show1instruction() )
|
---|
| 1436 | ;
|
---|
| 1437 | }
|
---|
| 1438 |
|
---|
| 1439 |
|
---|
| 1440 | PRIVATE int show1instruction()
|
---|
| 1441 | {
|
---|
| 1442 | register int column;
|
---|
| 1443 | int idone;
|
---|
| 1444 | static char line[81];
|
---|
| 1445 | int maxcol;
|
---|
| 1446 | struct address_s newuptr;
|
---|
| 1447 | struct address_s olduptr;
|
---|
| 1448 |
|
---|
| 1449 | outbyte('\r');
|
---|
| 1450 | do
|
---|
| 1451 | {
|
---|
| 1452 | if ( text_symbol(uptr.off) ) {
|
---|
| 1453 | outbyte(':');
|
---|
| 1454 | outbyte('\n');
|
---|
| 1455 | }
|
---|
| 1456 | olduptr = uptr;
|
---|
| 1457 | openstring(line);
|
---|
| 1458 | idone = puti();
|
---|
| 1459 | line[stringpos()] = 0;
|
---|
| 1460 | closestring();
|
---|
| 1461 | newuptr = uptr;
|
---|
| 1462 | uptr = olduptr;
|
---|
| 1463 | column = outssegaddr(&uptr);
|
---|
| 1464 | while (uptr.off != newuptr.off)
|
---|
| 1465 | {
|
---|
| 1466 | outh8(get8());
|
---|
| 1467 | column += 2;
|
---|
| 1468 | }
|
---|
| 1469 | maxcol = bits32 ? 24 : 16;
|
---|
| 1470 | while (column < maxcol)
|
---|
| 1471 | {
|
---|
| 1472 | outtab();
|
---|
| 1473 | column += 8;
|
---|
| 1474 | }
|
---|
| 1475 | outtab();
|
---|
| 1476 | outstr(line);
|
---|
| 1477 | outbyte('\n');
|
---|
| 1478 | }
|
---|
| 1479 | while (!idone); /* eat all prefixes */
|
---|
| 1480 | return TRUE;
|
---|
| 1481 | }
|
---|
| 1482 |
|
---|
| 1483 |
|
---|
| 1484 | PRIVATE u8_t get8()
|
---|
| 1485 | {
|
---|
| 1486 | /* get 8 bits current instruction pointer and advance pointer */
|
---|
| 1487 |
|
---|
| 1488 | u8_t temp;
|
---|
| 1489 |
|
---|
| 1490 | temp = peek_byte(uptr.off + uptr.base);
|
---|
| 1491 | ++uptr.off;
|
---|
| 1492 | return temp;
|
---|
| 1493 | }
|
---|
| 1494 |
|
---|
| 1495 | PRIVATE u16_t get16()
|
---|
| 1496 | {
|
---|
| 1497 | /* get 16 bits from current instruction pointer and advance pointer */
|
---|
| 1498 |
|
---|
| 1499 | u16_t temp;
|
---|
| 1500 |
|
---|
| 1501 | temp = peek_word(uptr.off + uptr.base);
|
---|
| 1502 | uptr.off += 2;
|
---|
| 1503 | return temp;
|
---|
| 1504 | }
|
---|
| 1505 |
|
---|
| 1506 | PRIVATE u32_t get32()
|
---|
| 1507 | {
|
---|
| 1508 | /* get 32 bits from current instruction pointer and advance pointer */
|
---|
| 1509 |
|
---|
| 1510 | u32_t temp;
|
---|
| 1511 |
|
---|
| 1512 | temp = peek_dword(uptr.off + uptr.base);
|
---|
| 1513 | uptr.off += 4;
|
---|
| 1514 | return temp;
|
---|
| 1515 | }
|
---|
| 1516 |
|
---|
| 1517 |
|
---|
| 1518 | PRIVATE int outsegaddr(addr)
|
---|
| 1519 | struct address_s *addr;
|
---|
| 1520 | {
|
---|
| 1521 | /* print segmented address */
|
---|
| 1522 |
|
---|
| 1523 | int bytes_printed;
|
---|
| 1524 |
|
---|
| 1525 | bytes_printed = 2;
|
---|
| 1526 | bytes_printed = outsegreg(addr->base);
|
---|
| 1527 | if (bytes_printed > 4)
|
---|
| 1528 | outbyte('+');
|
---|
| 1529 | else
|
---|
| 1530 | outbyte(':');
|
---|
| 1531 | ++bytes_printed;
|
---|
| 1532 | if (addr->off >= 0x10000)
|
---|
| 1533 | {
|
---|
| 1534 | outh32(addr->off);
|
---|
| 1535 | return bytes_printed + 8;
|
---|
| 1536 | }
|
---|
| 1537 | outh16((u16_t) addr->off);
|
---|
| 1538 | return bytes_printed + 4;
|
---|
| 1539 | }
|
---|
| 1540 |
|
---|
| 1541 | PRIVATE int outssegaddr(addr)
|
---|
| 1542 | struct address_s *addr;
|
---|
| 1543 | {
|
---|
| 1544 | /* print 32 bit segmented address and 2 spaces */
|
---|
| 1545 |
|
---|
| 1546 | int bytes_printed;
|
---|
| 1547 |
|
---|
| 1548 | bytes_printed = outsegaddr(addr);
|
---|
| 1549 | outspace();
|
---|
| 1550 | outspace();
|
---|
| 1551 | return bytes_printed + 2;
|
---|
| 1552 | }
|
---|
| 1553 |
|
---|
| 1554 | PRIVATE u8_t peek_byte(addr)
|
---|
| 1555 | off_t addr;
|
---|
| 1556 | {
|
---|
| 1557 | return (u8_t) peek_dword(addr) & 0xFF; /* 8 bits only */
|
---|
| 1558 | }
|
---|
| 1559 |
|
---|
| 1560 | PRIVATE u16_t peek_word(addr)
|
---|
| 1561 | off_t addr;
|
---|
| 1562 | {
|
---|
| 1563 | return (u16_t) peek_dword(addr);
|
---|
| 1564 | }
|
---|