fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 2185 lines 42 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/cpu/e8086/disasm.c * 7 * Created: 2002-05-20 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2002-2017 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <string.h> 24 25#include "e8086.h" 26#include "internal.h" 27 28 29/************************************************************************** 30 * Disassembler functions 31 **************************************************************************/ 32 33 34static void e86_disasm_op (e86_disasm_t *op, unsigned char *src); 35 36 37static 38char *d_tab_reg8[8] = { 39 "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH" 40}; 41 42static 43char *d_tab_reg16[8] = { 44 "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI" 45}; 46 47static 48char *d_tab_sreg[4] = { 49 "ES", "CS", "SS", "DS" 50}; 51 52static 53const char *d_tab_segpre[5] = { 54 "", "ES:", "CS:", "SS:", "DS:" 55}; 56 57typedef struct { 58 unsigned cnt; 59 const char *arg; 60} d_tab_ea_t; 61 62static 63d_tab_ea_t d_tab_ea[24] = { 64 { 0, "BX+SI" }, 65 { 0, "BX+DI" }, 66 { 0, "BP+SI" }, 67 { 0, "BP+DI" }, 68 { 0, "SI" }, 69 { 0, "DI" }, 70 { 2, NULL }, 71 { 0, "BX" }, 72 { 1, "BX+SI" }, 73 { 1, "BX+DI" }, 74 { 1, "BP+SI" }, 75 { 1, "BP+DI" }, 76 { 1, "SI" }, 77 { 1, "DI" }, 78 { 1, "BP" }, 79 { 1, "BX" }, 80 { 2, "BX+SI" }, 81 { 2, "BX+DI" }, 82 { 2, "BP+SI" }, 83 { 2, "BP+DI" }, 84 { 2, "SI" }, 85 { 2, "DI" }, 86 { 2, "BP" }, 87 { 2, "BX" } 88}; 89 90 91static 92void disasm_reg8 (char *dst, unsigned r) 93{ 94 strcpy (dst, d_tab_reg8[r & 7]); 95} 96 97static 98void disasm_reg16 (char *dst, unsigned r) 99{ 100 strcpy (dst, d_tab_reg16[r & 7]); 101} 102 103static 104void disasm_sreg (char *dst, unsigned r) 105{ 106 strcpy (dst, d_tab_sreg[r & 3]); 107} 108 109static 110void disasm_uint16 (char *dst, unsigned short v) 111{ 112 sprintf (dst, "%04X", v); 113} 114 115static 116void disasm_imm8 (char *dst, const unsigned char *src) 117{ 118 sprintf (dst, "%02X", src[0]); 119} 120 121static 122void disasm_simm8 (char *dst, const unsigned char *src) 123{ 124 if (src[0] < 0x80) { 125 sprintf (dst, "+%02X", src[0]); 126 } 127 else { 128 sprintf (dst, "-%02X", (~src[0] + 1) & 0xff); 129 } 130} 131 132static 133void disasm_imm16 (char *dst, const unsigned char *src) 134{ 135 sprintf (dst, "%04X", e86_mk_uint16 (src[0], src[1])); 136} 137 138static 139void disasm_imm32 (char *dst, const unsigned char *src) 140{ 141 sprintf (dst, "%04X:%04X", 142 e86_mk_uint16 (src[2], src[3]), 143 e86_mk_uint16 (src[0], src[1]) 144 ); 145} 146 147static 148void disasm_addr16 (e86_disasm_t *op, char *dst, const unsigned char *src) 149{ 150 sprintf (dst, "[%s%04X]", 151 d_tab_segpre[op->seg], 152 e86_mk_uint16 (src[0], src[1]) 153 ); 154 155 op->seg = 0; 156} 157 158static 159void disasm_addr16_index (e86_disasm_t *op, char *dst, const char *reg) 160{ 161 sprintf (dst, "[%s%s]", d_tab_segpre[op->seg], reg); 162} 163 164static 165unsigned disasm_ea (e86_disasm_t *op, char *str, const unsigned char *src, int s16) 166{ 167 unsigned val; 168 unsigned ea; 169 d_tab_ea_t *eat; 170 const char *seg; 171 172 if ((src[0] & 0xc0) == 0xc0) { 173 if (s16) { 174 disasm_reg16 (str, src[0] & 7); 175 } 176 else { 177 disasm_reg8 (str, src[0] & 7); 178 } 179 180 return (1); 181 } 182 183 ea = (src[0] & 7) | ((src[0] & 0xc0) >> 3); 184 eat = &d_tab_ea[ea]; 185 186 seg = d_tab_segpre[op->seg]; 187 188 op->seg = 0; 189 190 strcpy (str, s16 ? "WORD " : "BYTE "); 191 str += strlen (str); 192 193 if (eat->arg == NULL) { 194 sprintf (str, "[%s%04X]", seg, 195 e86_mk_uint16 (src[1], src[2]) 196 ); 197 return (3); 198 } 199 200 switch (eat->cnt) { 201 case 0: 202 sprintf (str, "[%s%s]", seg, eat->arg); 203 break; 204 205 case 1: 206 sprintf (str, "[%s%s%c%02X]", seg, eat->arg, 207 (src[1] & 0x80) ? '-' : '+', 208 ((src[1] & 0x80) ? (~src[1] + 1) : src[1]) & 0xff 209 ); 210 break; 211 212 case 2: 213 val = e86_mk_uint16 (src[1], src[2]); 214 215 sprintf (str, "[%s%s%c%04X]", seg, eat->arg, 216 (val & 0x8000) ? '-' : '+', 217 ((val & 0x8000) ? (~val + 1) : val) & 0xffff 218 ); 219 break; 220 221 default: 222 strcpy (str, "<bad>"); 223 break; 224 } 225 226 return (eat->cnt + 1); 227} 228 229static 230unsigned disasm_ea8 (e86_disasm_t *op, char *str, const unsigned char *src) 231{ 232 return (disasm_ea (op, str, src, 0)); 233} 234 235static 236unsigned disasm_ea16 (e86_disasm_t *op, char *str, const unsigned char *src) 237{ 238 return (disasm_ea (op, str, src, 1)); 239} 240 241 242static 243void dop_ud (e86_disasm_t *op, unsigned char *src) 244{ 245 op->dat_n = 1; 246 op->arg_n = 1; 247 248 strcpy (op->op, "DB"); 249 disasm_imm8 (op->arg1, src); 250} 251 252static 253void dop_const (e86_disasm_t *op, const char *sop, unsigned cnt) 254{ 255 op->dat_n = cnt; 256 op->arg_n = 0; 257 258 strcpy (op->op, sop); 259} 260 261static 262void dop_ea8_reg8 (e86_disasm_t *op, unsigned char *src, char *sop) 263{ 264 unsigned cnt; 265 266 strcpy (op->op, sop); 267 cnt = disasm_ea8 (op, op->arg1, src + 1); 268 disasm_reg8 (op->arg2, (src[1] >> 3) & 7); 269 270 op->dat_n = 1 + cnt; 271 op->arg_n = 2; 272} 273 274static 275void dop_ea16_reg16 (e86_disasm_t *op, unsigned char *src, char *sop) 276{ 277 unsigned cnt; 278 279 strcpy (op->op, sop); 280 cnt = disasm_ea16 (op, op->arg1, src + 1); 281 disasm_reg16 (op->arg2, (src[1] >> 3) & 7); 282 283 op->dat_n = 1 + cnt; 284 op->arg_n = 2; 285} 286 287static 288void dop_reg8_ea8 (e86_disasm_t *op, unsigned char *src, char *sop) 289{ 290 unsigned cnt; 291 292 strcpy (op->op, sop); 293 disasm_reg8 (op->arg1, (src[1] >> 3) & 7); 294 cnt = disasm_ea8 (op, op->arg2, src + 1); 295 296 op->dat_n = 1 + cnt; 297 op->arg_n = 2; 298} 299 300static 301void dop_reg16_ea16 (e86_disasm_t *op, unsigned char *src, char *sop) 302{ 303 unsigned cnt; 304 305 strcpy (op->op, sop); 306 disasm_reg16 (op->arg1, (src[1] >> 3) & 7); 307 cnt = disasm_ea16 (op, op->arg2, src + 1); 308 309 op->dat_n = 1 + cnt; 310 op->arg_n = 2; 311} 312 313static 314void dop_ea8 (e86_disasm_t *op, unsigned char *src, char *sop) 315{ 316 unsigned cnt; 317 318 strcpy (op->op, sop); 319 cnt = disasm_ea8 (op, op->arg1, src + 1); 320 321 op->dat_n = 1 + cnt; 322 op->arg_n = 1; 323} 324 325static 326void dop_ea16 (e86_disasm_t *op, unsigned char *src, char *sop) 327{ 328 unsigned cnt; 329 330 strcpy (op->op, sop); 331 cnt = disasm_ea16 (op, op->arg1, src + 1); 332 333 op->dat_n = 1 + cnt; 334 op->arg_n = 1; 335} 336 337static 338void dop_seg_prefix (e86_disasm_t *op, unsigned char *src, const char *sop, unsigned i) 339{ 340 unsigned tmp; 341 342 tmp = op->seg; 343 344 op->seg = i; 345 346 e86_disasm_op (op, src + 1); 347 348 if (op->seg == 0) { 349 op->dat_n += 1; 350 } 351 else { 352 dop_const (op, sop, 1); 353 } 354 355 op->seg = tmp; 356} 357 358 359/* DOP 00: ADD r/m8, reg8 */ 360static 361void dop_00 (e86_disasm_t *op, unsigned char *src) 362{ 363 dop_ea8_reg8 (op, src, "ADD"); 364} 365 366/* DOP 01: ADD r/m16, reg16 */ 367static 368void dop_01 (e86_disasm_t *op, unsigned char *src) 369{ 370 dop_ea16_reg16 (op, src, "ADD"); 371} 372 373/* DOP 02: ADD reg8, r/m8 */ 374static 375void dop_02 (e86_disasm_t *op, unsigned char *src) 376{ 377 dop_reg8_ea8 (op, src, "ADD"); 378} 379 380/* DOP 03: ADD reg16, r/m16 */ 381static void dop_03 (e86_disasm_t *op, unsigned char *src) 382{ 383 dop_reg16_ea16 (op, src, "ADD"); 384} 385 386/* DOP 04: ADD AL, data8 */ 387static void dop_04 (e86_disasm_t *op, unsigned char *src) 388{ 389 op->dat_n = 2; 390 op->arg_n = 2; 391 392 strcpy (op->op, "ADD"); 393 strcpy (op->arg1, "AL"); 394 disasm_imm8 (op->arg2, src + 1); 395} 396 397/* DOP 05: ADD AX, data16 */ 398static void dop_05 (e86_disasm_t *op, unsigned char *src) 399{ 400 op->dat_n = 3; 401 op->arg_n = 2; 402 403 strcpy (op->op, "ADD"); 404 strcpy (op->arg1, "AX"); 405 disasm_imm16 (op->arg2, src + 1); 406} 407 408/* DOP 06: PUSH ES */ 409static void dop_06 (e86_disasm_t *op, unsigned char *src) 410{ 411 op->dat_n = 1; 412 op->arg_n = 1; 413 414 strcpy (op->op, "PUSH"); 415 strcpy (op->arg1, "ES"); 416} 417 418/* DOP 07: POP ES */ 419static void dop_07 (e86_disasm_t *op, unsigned char *src) 420{ 421 op->dat_n = 1; 422 op->arg_n = 1; 423 424 strcpy (op->op, "POP"); 425 strcpy (op->arg1, "ES"); 426} 427 428/* DOP 08: OR r/m8, reg8 */ 429static void dop_08 (e86_disasm_t *op, unsigned char *src) 430{ 431 dop_ea8_reg8 (op, src, "OR"); 432} 433 434/* DOP 09: OR r/m16, reg16 */ 435static void dop_09 (e86_disasm_t *op, unsigned char *src) 436{ 437 dop_ea16_reg16 (op, src, "OR"); 438} 439 440/* DOP 0A: OR reg8, r/m8 */ 441static void dop_0a (e86_disasm_t *op, unsigned char *src) 442{ 443 dop_reg8_ea8 (op, src, "OR"); 444} 445 446/* DOP 0B: OR reg16, r/m16 */ 447static void dop_0b (e86_disasm_t *op, unsigned char *src) 448{ 449 dop_reg16_ea16 (op, src, "OR"); 450} 451 452/* DOP 0C: OR AL, data8 */ 453static void dop_0c (e86_disasm_t *op, unsigned char *src) 454{ 455 op->dat_n = 2; 456 op->arg_n = 2; 457 458 strcpy (op->op, "OR"); 459 strcpy (op->arg1, "AL"); 460 disasm_imm8 (op->arg2, src + 1); 461} 462 463/* DOP 0D: OR AX, data16 */ 464static void dop_0d (e86_disasm_t *op, unsigned char *src) 465{ 466 op->dat_n = 3; 467 op->arg_n = 2; 468 469 strcpy (op->op, "OR"); 470 strcpy (op->arg1, "AX"); 471 disasm_imm16 (op->arg2, src + 1); 472} 473 474/* DOP 0E: PUSH CS */ 475static void dop_0e (e86_disasm_t *op, unsigned char *src) 476{ 477 op->dat_n = 1; 478 op->arg_n = 1; 479 480 strcpy (op->op, "PUSH"); 481 strcpy (op->arg1, "CS"); 482} 483 484/* DOP 0F: POP ES */ 485static void dop_0f (e86_disasm_t *op, unsigned char *src) 486{ 487 op->dat_n = 1; 488 op->arg_n = 1; 489 490 strcpy (op->op, "POP"); 491 strcpy (op->arg1, "CS"); 492} 493 494/* DOP 10: ADC r/m8, reg8 */ 495static void dop_10 (e86_disasm_t *op, unsigned char *src) 496{ 497 dop_ea8_reg8 (op, src, "ADC"); 498} 499 500/* DOP 11: ADC r/m16, reg16 */ 501static void dop_11 (e86_disasm_t *op, unsigned char *src) 502{ 503 dop_ea16_reg16 (op, src, "ADC"); 504} 505 506/* DOP 12: ADC reg8, r/m8 */ 507static void dop_12 (e86_disasm_t *op, unsigned char *src) 508{ 509 dop_reg8_ea8 (op, src, "ADC"); 510} 511 512/* DOP 13: ADC reg16, r/m16 */ 513static void dop_13 (e86_disasm_t *op, unsigned char *src) 514{ 515 dop_reg16_ea16 (op, src, "ADC"); 516} 517 518/* DOP 14: ADC AL, data8 */ 519static void dop_14 (e86_disasm_t *op, unsigned char *src) 520{ 521 op->dat_n = 2; 522 op->arg_n = 2; 523 524 strcpy (op->op, "ADC"); 525 strcpy (op->arg1, "AL"); 526 disasm_imm8 (op->arg2, src + 1); 527} 528 529/* DOP 15: ADC AX, data16 */ 530static void dop_15 (e86_disasm_t *op, unsigned char *src) 531{ 532 op->dat_n = 3; 533 op->arg_n = 2; 534 535 strcpy (op->op, "ADC"); 536 strcpy (op->arg1, "AX"); 537 disasm_imm16 (op->arg2, src + 1); 538} 539 540/* DOP 16: PUSH SS */ 541static void dop_16 (e86_disasm_t *op, unsigned char *src) 542{ 543 op->dat_n = 1; 544 op->arg_n = 1; 545 546 strcpy (op->op, "PUSH"); 547 strcpy (op->arg1, "SS"); 548} 549 550/* DOP 17: POP SS */ 551static void dop_17 (e86_disasm_t *op, unsigned char *src) 552{ 553 op->dat_n = 1; 554 op->arg_n = 1; 555 556 strcpy (op->op, "POP"); 557 strcpy (op->arg1, "SS"); 558} 559 560/* DOP 18: SBB r/m8, reg8 */ 561static 562void dop_18 (e86_disasm_t *op, unsigned char *src) 563{ 564 dop_ea8_reg8 (op, src, "SBB"); 565} 566 567/* DOP 19: SBB r/m16, reg16 */ 568static 569void dop_19 (e86_disasm_t *op, unsigned char *src) 570{ 571 dop_ea16_reg16 (op, src, "SBB"); 572} 573 574/* DOP 1A: SBB reg8, r/m8 */ 575static 576void dop_1a (e86_disasm_t *op, unsigned char *src) 577{ 578 dop_reg8_ea8 (op, src, "SBB"); 579} 580 581/* DOP 1B: SBB reg16, r/m16 */ 582static void dop_1b (e86_disasm_t *op, unsigned char *src) 583{ 584 dop_reg16_ea16 (op, src, "SBB"); 585} 586 587/* DOP 1C: SBB AL, data8 */ 588static void dop_1c (e86_disasm_t *op, unsigned char *src) 589{ 590 op->dat_n = 2; 591 op->arg_n = 2; 592 593 strcpy (op->op, "SBB"); 594 strcpy (op->arg1, "AL"); 595 disasm_imm8 (op->arg2, src + 1); 596} 597 598/* DOP 1D: SBB AX, data16 */ 599static void dop_1d (e86_disasm_t *op, unsigned char *src) 600{ 601 op->dat_n = 3; 602 op->arg_n = 2; 603 604 strcpy (op->op, "SBB"); 605 strcpy (op->arg1, "AX"); 606 disasm_imm16 (op->arg2, src + 1); 607} 608 609/* DOP 1E: PUSH DS */ 610static void dop_1e (e86_disasm_t *op, unsigned char *src) 611{ 612 op->dat_n = 1; 613 op->arg_n = 1; 614 615 strcpy (op->op, "PUSH"); 616 strcpy (op->arg1, "DS"); 617} 618 619/* DOP 1F: POP SS */ 620static void dop_1f (e86_disasm_t *op, unsigned char *src) 621{ 622 op->dat_n = 1; 623 op->arg_n = 1; 624 625 strcpy (op->op, "POP"); 626 strcpy (op->arg1, "DS"); 627} 628 629/* DOP 20: AND r/m8, reg8 */ 630static void dop_20 (e86_disasm_t *op, unsigned char *src) 631{ 632 dop_ea8_reg8 (op, src, "AND"); 633} 634 635/* DOP 21: AND r/m16, reg16 */ 636static void dop_21 (e86_disasm_t *op, unsigned char *src) 637{ 638 dop_ea16_reg16 (op, src, "AND"); 639} 640 641/* DOP 22: AND reg8, r/m8 */ 642static void dop_22 (e86_disasm_t *op, unsigned char *src) 643{ 644 dop_reg8_ea8 (op, src, "AND"); 645} 646 647/* DOP 23: AND reg16, r/m16 */ 648static void dop_23 (e86_disasm_t *op, unsigned char *src) 649{ 650 dop_reg16_ea16 (op, src, "AND"); 651} 652 653/* DOP 24: AND AL, data8 */ 654static void dop_24 (e86_disasm_t *op, unsigned char *src) 655{ 656 op->dat_n = 2; 657 op->arg_n = 2; 658 659 strcpy (op->op, "AND"); 660 strcpy (op->arg1, "AL"); 661 disasm_imm8 (op->arg2, src + 1); 662} 663 664/* DOP 25: AND AX, data16 */ 665static void dop_25 (e86_disasm_t *op, unsigned char *src) 666{ 667 op->dat_n = 3; 668 op->arg_n = 2; 669 670 strcpy (op->op, "AND"); 671 strcpy (op->arg1, "AX"); 672 disasm_imm16 (op->arg2, src + 1); 673} 674 675/* DOP 26: ES: */ 676static 677void dop_26 (e86_disasm_t *op, unsigned char *src) 678{ 679 dop_seg_prefix (op, src, "ES:", 1); 680} 681 682/* DOP 27: DAA */ 683static 684void dop_27 (e86_disasm_t *op, unsigned char *src) 685{ 686 dop_const (op, "DAA", 1); 687} 688 689/* DOP 28: SUB r/m8, reg8 */ 690static void dop_28 (e86_disasm_t *op, unsigned char *src) 691{ 692 dop_ea8_reg8 (op, src, "SUB"); 693} 694 695/* DOP 29: SUB r/m16, reg16 */ 696static void dop_29 (e86_disasm_t *op, unsigned char *src) 697{ 698 dop_ea16_reg16 (op, src, "SUB"); 699} 700 701/* DOP 2A: SUB reg8, r/m8 */ 702static void dop_2a (e86_disasm_t *op, unsigned char *src) 703{ 704 dop_reg8_ea8 (op, src, "SUB"); 705} 706 707/* DOP 2B: SUB reg16, r/m16 */ 708static void dop_2b (e86_disasm_t *op, unsigned char *src) 709{ 710 dop_reg16_ea16 (op, src, "SUB"); 711} 712 713/* DOP 2C: SUB AL, data8 */ 714static void dop_2c (e86_disasm_t *op, unsigned char *src) 715{ 716 op->dat_n = 2; 717 op->arg_n = 2; 718 719 strcpy (op->op, "SUB"); 720 strcpy (op->arg1, "AL"); 721 disasm_imm8 (op->arg2, src + 1); 722} 723 724/* DOP 2D: SUB AX, data16 */ 725static void dop_2d (e86_disasm_t *op, unsigned char *src) 726{ 727 op->dat_n = 3; 728 op->arg_n = 2; 729 730 strcpy (op->op, "SUB"); 731 strcpy (op->arg1, "AX"); 732 disasm_imm16 (op->arg2, src + 1); 733} 734 735/* DOP 2E: CS: */ 736static 737void dop_2e (e86_disasm_t *op, unsigned char *src) 738{ 739 dop_seg_prefix (op, src, "CS:", 2); 740} 741 742/* DOP 2F: DAS */ 743static 744void dop_2f (e86_disasm_t *op, unsigned char *src) 745{ 746 dop_const (op, "DAS", 1); 747} 748 749/* DOP 30: XOR r/m8, reg8 */ 750static void dop_30 (e86_disasm_t *op, unsigned char *src) 751{ 752 dop_ea8_reg8 (op, src, "XOR"); 753} 754 755/* DOP 31: XOR r/m16, reg16 */ 756static void dop_31 (e86_disasm_t *op, unsigned char *src) 757{ 758 dop_ea16_reg16 (op, src, "XOR"); 759} 760 761/* DOP 32: XOR reg8, r/m8 */ 762static void dop_32 (e86_disasm_t *op, unsigned char *src) 763{ 764 dop_reg8_ea8 (op, src, "XOR"); 765} 766 767/* DOP 33: XOR reg16, r/m16 */ 768static void dop_33 (e86_disasm_t *op, unsigned char *src) 769{ 770 dop_reg16_ea16 (op, src, "XOR"); 771} 772 773/* DOP 34: XOR AL, data8 */ 774static void dop_34 (e86_disasm_t *op, unsigned char *src) 775{ 776 op->dat_n = 2; 777 op->arg_n = 2; 778 779 strcpy (op->op, "XOR"); 780 strcpy (op->arg1, "AL"); 781 disasm_imm8 (op->arg2, src + 1); 782} 783 784/* DOP 35: XOR AX, data16 */ 785static void dop_35 (e86_disasm_t *op, unsigned char *src) 786{ 787 op->dat_n = 3; 788 op->arg_n = 2; 789 790 strcpy (op->op, "XOR"); 791 strcpy (op->arg1, "AX"); 792 disasm_imm16 (op->arg2, src + 1); 793} 794 795/* DOP 36: SS: */ 796static 797void dop_36 (e86_disasm_t *op, unsigned char *src) 798{ 799 dop_seg_prefix (op, src, "SS:", 3); 800} 801 802/* DOP 37: AAA */ 803static 804void dop_37 (e86_disasm_t *op, unsigned char *src) 805{ 806 dop_const (op, "AAA", 1); 807} 808 809/* DOP 38: CMP r/m8, reg8 */ 810static void dop_38 (e86_disasm_t *op, unsigned char *src) 811{ 812 dop_ea8_reg8 (op, src, "CMP"); 813} 814 815/* DOP 39: CMP r/m16, reg16 */ 816static void dop_39 (e86_disasm_t *op, unsigned char *src) 817{ 818 dop_ea16_reg16 (op, src, "CMP"); 819} 820 821/* DOP 3A: CMP reg8, r/m8 */ 822static void dop_3a (e86_disasm_t *op, unsigned char *src) 823{ 824 dop_reg8_ea8 (op, src, "CMP"); 825} 826 827/* DOP 3B: CMP reg16, r/m16 */ 828static void dop_3b (e86_disasm_t *op, unsigned char *src) 829{ 830 dop_reg16_ea16 (op, src, "CMP"); 831} 832 833/* DOP 3C: CMP AL, data8 */ 834static void dop_3c (e86_disasm_t *op, unsigned char *src) 835{ 836 op->dat_n = 2; 837 op->arg_n = 2; 838 839 strcpy (op->op, "CMP"); 840 strcpy (op->arg1, "AL"); 841 disasm_imm8 (op->arg2, src + 1); 842} 843 844/* DOP 3D: CMP AX, data16 */ 845static void dop_3d (e86_disasm_t *op, unsigned char *src) 846{ 847 op->dat_n = 3; 848 op->arg_n = 2; 849 850 strcpy (op->op, "CMP"); 851 strcpy (op->arg1, "AX"); 852 disasm_imm16 (op->arg2, src + 1); 853} 854 855/* DOP 3E: DS: */ 856static 857void dop_3e (e86_disasm_t *op, unsigned char *src) 858{ 859 dop_seg_prefix (op, src, "DS:", 4); 860} 861 862/* DOP 3F: AAS */ 863static 864void dop_3f (e86_disasm_t *op, unsigned char *src) 865{ 866 dop_const (op, "AAS", 1); 867} 868 869/* DOP 4x: INC reg16 */ 870static void dop_40 (e86_disasm_t *op, unsigned char *src) 871{ 872 op->dat_n = 1; 873 op->arg_n = 1; 874 875 strcpy (op->op, "INC"); 876 disasm_reg16 (op->arg1, src[0] & 7); 877} 878 879/* DOP 4x: DEC reg16 */ 880static void dop_48 (e86_disasm_t *op, unsigned char *src) 881{ 882 op->dat_n = 1; 883 op->arg_n = 1; 884 885 strcpy (op->op, "DEC"); 886 disasm_reg16 (op->arg1, src[0] & 7); 887} 888 889/* DOP 5x: PUSH reg16 */ 890static void dop_50 (e86_disasm_t *op, unsigned char *src) 891{ 892 op->dat_n = 1; 893 op->arg_n = 1; 894 895 strcpy (op->op, "PUSH"); 896 disasm_reg16 (op->arg1, src[0] & 7); 897} 898 899/* DOP 5x: POP reg16 */ 900static void dop_58 (e86_disasm_t *op, unsigned char *src) 901{ 902 op->dat_n = 1; 903 op->arg_n = 1; 904 905 strcpy (op->op, "POP"); 906 disasm_reg16 (op->arg1, src[0] & 7); 907} 908 909static char *d_tab_70[16] = { 910"JO", "JNO", "JC", "JNC", "JZ", "JNZ", "JBE", "JA", 911"JS", "JNS", "JPE", "JPO", "JL", "JGE", "JLE", "JG" 912}; 913 914/* DOP 60: PUSHA */ 915static 916void dop_60 (e86_disasm_t *op, unsigned char *src) 917{ 918 op->flags |= E86_DFLAGS_186; 919 dop_const (op, "PUSHA", 1); 920} 921 922/* DOP 61: POPA */ 923static 924void dop_61 (e86_disasm_t *op, unsigned char *src) 925{ 926 op->flags |= E86_DFLAGS_186; 927 dop_const (op, "POPA", 1); 928} 929 930/* DOP 62: BOUND */ 931static 932void dop_62 (e86_disasm_t *op, unsigned char *src) 933{ 934 op->flags |= E86_DFLAGS_186; 935 936 dop_reg16_ea16 (op, src, "BOUND"); 937} 938 939/* DOP 66: PCE HOOK */ 940static 941void dop_66 (e86_disasm_t *op, unsigned char *src) 942{ 943 if (src[1] != 0x66) { 944 dop_ud (op, src); 945 return; 946 } 947 948 op->dat_n = 4; 949 op->arg_n = 2; 950 951 strcpy (op->op, "PCEH"); 952 disasm_imm8 (op->arg1, src + 2); 953 disasm_imm8 (op->arg2, src + 3); 954} 955 956/* DOP 68: PUSH imm16 */ 957static 958void dop_68 (e86_disasm_t *op, unsigned char *src) 959{ 960 op->flags |= E86_DFLAGS_186; 961 962 op->dat_n = 3; 963 op->arg_n = 1; 964 965 strcpy (op->op, "PUSH"); 966 disasm_imm16 (op->arg1, src + 1); 967} 968 969/* DOP 6A: PUSH imm8 */ 970static 971void dop_6a (e86_disasm_t *op, unsigned char *src) 972{ 973 op->flags |= E86_DFLAGS_186; 974 975 op->dat_n = 2; 976 op->arg_n = 1; 977 978 strcpy (op->op, "PUSH"); 979 disasm_simm8 (op->arg1, src + 1); 980} 981 982/* DOP 6C: INSB */ 983static 984void dop_6c (e86_disasm_t *op, unsigned char *src) 985{ 986 op->flags |= E86_DFLAGS_186; 987 dop_const (op, "INSB", 1); 988} 989 990/* DOP 6D: INSW */ 991static 992void dop_6d (e86_disasm_t *op, unsigned char *src) 993{ 994 op->flags |= E86_DFLAGS_186; 995 dop_const (op, "INSW", 1); 996} 997 998/* DOP 6E: OUTB */ 999static 1000void dop_6e (e86_disasm_t *op, unsigned char *src) 1001{ 1002 op->flags |= E86_DFLAGS_186; 1003 dop_const (op, "OUTSB", 1); 1004} 1005 1006/* DOP 6F: OUTW */ 1007static 1008void dop_6f (e86_disasm_t *op, unsigned char *src) 1009{ 1010 op->flags |= E86_DFLAGS_186; 1011 dop_const (op, "OUTSW", 1); 1012} 1013 1014/* DOP 7x: Jxx imm8 */ 1015static void dop_70 (e86_disasm_t *op, unsigned char *src) 1016{ 1017 unsigned short t; 1018 1019 op->dat_n = 2; 1020 op->arg_n = 1; 1021 1022 t = 2 + e86_add_sint8 (op->ip, src[1]); 1023 1024 strcpy (op->op, d_tab_70[src[0] & 15]); 1025 disasm_uint16 (op->arg1, t); 1026} 1027 1028static char *d_tab_80[16] = { 1029 "ADD", "OR", "ADC", "SBB", 1030 "AND", "SUB", "XOR", "CMP" 1031}; 1032 1033/* DOP 80: xxx r/m8, imm8 */ 1034static void dop_80 (e86_disasm_t *op, unsigned char *src) 1035{ 1036 unsigned cnt; 1037 1038 strcpy (op->op, d_tab_80[(src[1] >> 3) & 7]); 1039 cnt = disasm_ea8 (op, op->arg1, src + 1); 1040 disasm_imm8 (op->arg2, src + 1 + cnt); 1041 1042 op->dat_n = 2 + cnt; 1043 op->arg_n = 2; 1044} 1045 1046/* DOP 81: xxx r/m16, imm16 */ 1047static void dop_81 (e86_disasm_t *op, unsigned char *src) 1048{ 1049 unsigned cnt; 1050 1051 strcpy (op->op, d_tab_80[(src[1] >> 3) & 7]); 1052 cnt = disasm_ea16 (op, op->arg1, src + 1); 1053 disasm_imm16 (op->arg2, src + 1 + cnt); 1054 1055 op->dat_n = 3 + cnt; 1056 op->arg_n = 2; 1057} 1058 1059/* DOP 83: xxx r/m16, imm8 */ 1060static void dop_83 (e86_disasm_t *op, unsigned char *src) 1061{ 1062 unsigned cnt; 1063 1064 strcpy (op->op, d_tab_80[(src[1] >> 3) & 7]); 1065 cnt = disasm_ea16 (op, op->arg1, src + 1); 1066 disasm_simm8 (op->arg2, src + 1 + cnt); 1067 1068 op->dat_n = 2 + cnt; 1069 op->arg_n = 2; 1070} 1071 1072/* DOP 84: TEST r/m8, reg8 */ 1073static 1074void dop_84 (e86_disasm_t *op, unsigned char *src) 1075{ 1076 dop_ea8_reg8 (op, src, "TEST"); 1077} 1078 1079/* DOP 85: TEST r/m16, reg16 */ 1080static 1081void dop_85 (e86_disasm_t *op, unsigned char *src) 1082{ 1083 dop_ea16_reg16 (op, src, "TEST"); 1084} 1085 1086/* DOP 86: XCHG r/m8, reg8 */ 1087static void dop_86 (e86_disasm_t *op, unsigned char *src) 1088{ 1089 dop_ea8_reg8 (op, src, "XCHG"); 1090} 1091 1092/* DOP 87: XCHG r/m16, reg16 */ 1093static void dop_87 (e86_disasm_t *op, unsigned char *src) 1094{ 1095 dop_ea16_reg16 (op, src, "XCHG"); 1096} 1097 1098/* DOP 88: MOV r/m8, reg8 */ 1099static void dop_88 (e86_disasm_t *op, unsigned char *src) 1100{ 1101 dop_ea8_reg8 (op, src, "MOV"); 1102} 1103 1104/* DOP 89: MOV r/m16, reg16 */ 1105static void dop_89 (e86_disasm_t *op, unsigned char *src) 1106{ 1107 dop_ea16_reg16 (op, src, "MOV"); 1108} 1109 1110/* DOP 8A: MOV reg8, r/m8 */ 1111static void dop_8a (e86_disasm_t *op, unsigned char *src) 1112{ 1113 dop_reg8_ea8 (op, src, "MOV"); 1114} 1115 1116/* DOP 8B: MOV reg16, r/m16 */ 1117static void dop_8b (e86_disasm_t *op, unsigned char *src) 1118{ 1119 dop_reg16_ea16 (op, src, "MOV"); 1120} 1121 1122/* DOP 8C: MOV r/m16, sreg */ 1123static void dop_8c (e86_disasm_t *op, unsigned char *src) 1124{ 1125 unsigned cnt; 1126 1127 strcpy (op->op, "MOV"); 1128 cnt = disasm_ea16 (op, op->arg1, src + 1); 1129 disasm_sreg (op->arg2, (src[1] >> 3) & 3); 1130 1131 op->dat_n = 1 + cnt; 1132 op->arg_n = 2; 1133} 1134 1135/* DOP 8D: LEA reg16, r/m16 */ 1136static void dop_8d (e86_disasm_t *op, unsigned char *src) 1137{ 1138 dop_reg16_ea16 (op, src, "LEA"); 1139} 1140 1141/* DOP 8E: MOV sreg, r/m16 */ 1142static void dop_8e (e86_disasm_t *op, unsigned char *src) 1143{ 1144 unsigned cnt; 1145 1146 strcpy (op->op, "MOV"); 1147 disasm_sreg (op->arg1, (src[1] >> 3) & 3); 1148 cnt = disasm_ea16 (op, op->arg2, src + 1); 1149 1150 op->dat_n = cnt + 1; 1151 op->arg_n = 2; 1152} 1153 1154/* DOP 8F: POP r/m16 */ 1155static void dop_8f (e86_disasm_t *op, unsigned char *src) 1156{ 1157 dop_ea16 (op, src, "POP"); 1158} 1159 1160/* DOP 90: NOP */ 1161static 1162void dop_90 (e86_disasm_t *op, unsigned char *src) 1163{ 1164 dop_const (op, "NOP", 1); 1165} 1166 1167/* DOP 9x: XCHG AX, reg16 */ 1168static void dop_91 (e86_disasm_t *op, unsigned char *src) 1169{ 1170 strcpy (op->op, "XCHG"); 1171 strcpy (op->arg1, "AX"); 1172 disasm_reg16 (op->arg2, src[0] & 7); 1173 1174 op->dat_n = 1; 1175 op->arg_n = 2; 1176} 1177 1178/* DOP 98: CBW */ 1179static void dop_98 (e86_disasm_t *op, unsigned char *src) 1180{ 1181 dop_const (op, "CBW", 1); 1182} 1183 1184/* DOP 99: CWD */ 1185static void dop_99 (e86_disasm_t *op, unsigned char *src) 1186{ 1187 dop_const (op, "CWD", 1); 1188} 1189 1190/* DOP 9A: CALL imm32 */ 1191static 1192void dop_9a (e86_disasm_t *op, unsigned char *src) 1193{ 1194 op->flags |= E86_DFLAGS_CALL; 1195 1196 op->dat_n = 5; 1197 op->arg_n = 1; 1198 1199 strcpy (op->op, "CALL"); 1200 disasm_imm32 (op->arg1, src + 1); 1201} 1202 1203/* DOP 9B: WAIT */ 1204static void dop_9b (e86_disasm_t *op, unsigned char *src) 1205{ 1206 dop_const (op, "WAIT", 1); 1207} 1208 1209/* DOP 9C: PUSHF */ 1210static void dop_9c (e86_disasm_t *op, unsigned char *src) 1211{ 1212 dop_const (op, "PUSHF", 1); 1213} 1214 1215/* DOP 9D: POPF */ 1216static void dop_9d (e86_disasm_t *op, unsigned char *src) 1217{ 1218 dop_const (op, "POPF", 1); 1219} 1220 1221/* DOP 9E: SAHF */ 1222static void dop_9e (e86_disasm_t *op, unsigned char *src) 1223{ 1224 dop_const (op, "SAHF", 1); 1225} 1226 1227/* DOP 9F: LAHF */ 1228static void dop_9f (e86_disasm_t *op, unsigned char *src) 1229{ 1230 dop_const (op, "LAHF", 1); 1231} 1232 1233/* DOP A0: MOV AL, [data16] */ 1234static void dop_a0 (e86_disasm_t *op, unsigned char *src) 1235{ 1236 op->dat_n = 3; 1237 op->arg_n = 2; 1238 1239 strcpy (op->op, "MOV"); 1240 strcpy (op->arg1, "AL"); 1241 disasm_addr16 (op, op->arg2, src + 1); 1242} 1243 1244/* DOP A1: MOV AX, [data16] */ 1245static void dop_a1 (e86_disasm_t *op, unsigned char *src) 1246{ 1247 op->dat_n = 3; 1248 op->arg_n = 2; 1249 1250 strcpy (op->op, "MOV"); 1251 strcpy (op->arg1, "AX"); 1252 disasm_addr16 (op, op->arg2, src + 1); 1253} 1254 1255/* DOP A2: MOV [data16], AL */ 1256static void dop_a2 (e86_disasm_t *op, unsigned char *src) 1257{ 1258 op->dat_n = 3; 1259 op->arg_n = 2; 1260 1261 strcpy (op->op, "MOV"); 1262 disasm_addr16 (op, op->arg1, src + 1); 1263 strcpy (op->arg2, "AL"); 1264} 1265 1266/* DOP A3: MOV [data16], AX */ 1267static void dop_a3 (e86_disasm_t *op, unsigned char *src) 1268{ 1269 op->dat_n = 3; 1270 op->arg_n = 2; 1271 1272 strcpy (op->op, "MOV"); 1273 disasm_addr16 (op, op->arg1, src + 1); 1274 strcpy (op->arg2, "AX"); 1275} 1276 1277/* DOP A4: MOVSB */ 1278static 1279void dop_a4 (e86_disasm_t *op, unsigned char *src) 1280{ 1281 dop_const (op, "MOVSB", 1); 1282 1283 if (op->seg != 0) { 1284 strcpy (op->arg1, "[ES:DI]"); 1285 disasm_addr16_index (op, op->arg2, "SI"); 1286 op->arg_n = 2; 1287 op->seg = 0; 1288 } 1289} 1290 1291/* DOP A5: MOVSW */ 1292static 1293void dop_a5 (e86_disasm_t *op, unsigned char *src) 1294{ 1295 dop_const (op, "MOVSW", 1); 1296 1297 if (op->seg != 0) { 1298 strcpy (op->arg1, "[ES:DI]"); 1299 disasm_addr16_index (op, op->arg2, "SI"); 1300 op->arg_n = 2; 1301 op->seg = 0; 1302 } 1303} 1304 1305/* DOP A6: CMPSB */ 1306static 1307void dop_a6 (e86_disasm_t *op, unsigned char *src) 1308{ 1309 dop_const (op, "CMPSB", 1); 1310 1311 if (op->seg != 0) { 1312 strcpy (op->arg1, "[ES:DI]"); 1313 disasm_addr16_index (op, op->arg2, "SI"); 1314 op->arg_n = 2; 1315 op->seg = 0; 1316 } 1317} 1318 1319/* DOP A7: CMPSW */ 1320static 1321void dop_a7 (e86_disasm_t *op, unsigned char *src) 1322{ 1323 dop_const (op, "CMPSW", 1); 1324 1325 if (op->seg != 0) { 1326 strcpy (op->arg1, "[ES:DI]"); 1327 disasm_addr16_index (op, op->arg2, "SI"); 1328 op->arg_n = 2; 1329 op->seg = 0; 1330 } 1331} 1332 1333/* DOP A8: TEST AL, data8 */ 1334static void dop_a8 (e86_disasm_t *op, unsigned char *src) 1335{ 1336 op->dat_n = 2; 1337 op->arg_n = 2; 1338 1339 strcpy (op->op, "TEST"); 1340 strcpy (op->arg1, "AL"); 1341 disasm_imm8 (op->arg2, src + 1); 1342} 1343 1344/* DOP A9: TEST AX, data16 */ 1345static void dop_a9 (e86_disasm_t *op, unsigned char *src) 1346{ 1347 op->dat_n = 3; 1348 op->arg_n = 2; 1349 1350 strcpy (op->op, "TEST"); 1351 strcpy (op->arg1, "AX"); 1352 disasm_imm16 (op->arg2, src + 1); 1353} 1354 1355/* DOP AA: STOSB */ 1356static 1357void dop_aa (e86_disasm_t *op, unsigned char *src) 1358{ 1359 dop_const (op, "STOSB", 1); 1360} 1361 1362/* DOP AB: STOSW */ 1363static 1364void dop_ab (e86_disasm_t *op, unsigned char *src) 1365{ 1366 dop_const (op, "STOSW", 1); 1367} 1368 1369/* DOP AC: LODSB */ 1370static 1371void dop_ac (e86_disasm_t *op, unsigned char *src) 1372{ 1373 dop_const (op, "LODSB", 1); 1374 1375 if (op->seg != 0) { 1376 disasm_addr16_index (op, op->arg1, "SI"); 1377 op->arg_n = 1; 1378 op->seg = 0; 1379 } 1380} 1381 1382/* DOP AD: LODSW */ 1383static 1384void dop_ad (e86_disasm_t *op, unsigned char *src) 1385{ 1386 dop_const (op, "LODSW", 1); 1387 1388 if (op->seg != 0) { 1389 disasm_addr16_index (op, op->arg1, "SI"); 1390 op->arg_n = 1; 1391 op->seg = 0; 1392 } 1393} 1394 1395/* DOP AE: SCASB */ 1396static 1397void dop_ae (e86_disasm_t *op, unsigned char *src) 1398{ 1399 dop_const (op, "SCASB", 1); 1400} 1401 1402/* DOP AF: SCASW */ 1403static 1404void dop_af (e86_disasm_t *op, unsigned char *src) 1405{ 1406 dop_const (op, "SCASW", 1); 1407} 1408 1409/* DOP Bx: MOV reg8, imm8 */ 1410static void dop_b0 (e86_disasm_t *op, unsigned char *src) 1411{ 1412 op->dat_n = 2; 1413 op->arg_n = 2; 1414 1415 strcpy (op->op, "MOV"); 1416 disasm_reg8 (op->arg1, src[0] & 7); 1417 disasm_imm8 (op->arg2, src + 1); 1418} 1419 1420/* DOP Bx: MOV reg16, imm16 */ 1421static void dop_b8 (e86_disasm_t *op, unsigned char *src) 1422{ 1423 op->dat_n = 3; 1424 op->arg_n = 2; 1425 1426 strcpy (op->op, "MOV"); 1427 disasm_reg16 (op->arg1, src[0] & 7); 1428 disasm_imm16 (op->arg2, src + 1); 1429} 1430 1431static char *d_tab_c0[8] = { 1432 "ROL", "ROR", "RCL", "RCR", 1433 "SHL", "SHR", "???", "SAR" 1434}; 1435 1436/* DOP C0: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m8, imm8 */ 1437static void dop_c0 (e86_disasm_t *op, unsigned char *src) 1438{ 1439 unsigned xop, cnt; 1440 1441 op->flags |= E86_DFLAGS_186; 1442 1443 xop = (src[1] >> 3) & 7; 1444 1445 strcpy (op->op, d_tab_c0[xop]); 1446 cnt = disasm_ea8 (op, op->arg1, src + 1); 1447 disasm_imm8 (op->arg2, src + cnt + 1); 1448 1449 op->dat_n = 2 + cnt; 1450 op->arg_n = 2; 1451} 1452 1453/* DOP C1: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m16, imm8 */ 1454static void dop_c1 (e86_disasm_t *op, unsigned char *src) 1455{ 1456 unsigned xop, cnt; 1457 1458 op->flags |= E86_DFLAGS_186; 1459 1460 xop = (src[1] >> 3) & 7; 1461 1462 strcpy (op->op, d_tab_c0[xop]); 1463 cnt = disasm_ea16 (op, op->arg1, src + 1); 1464 disasm_imm8 (op->arg2, src + cnt + 1); 1465 1466 op->dat_n = 2 + cnt; 1467 op->arg_n = 2; 1468} 1469 1470/* DOP C2: RET imm16 */ 1471static void dop_c2 (e86_disasm_t *op, unsigned char *src) 1472{ 1473 op->dat_n = 3; 1474 op->arg_n = 1; 1475 1476 strcpy (op->op, "RETN"); 1477 disasm_imm16 (op->arg1, src + 1); 1478} 1479 1480/* DOP C3: RET */ 1481static 1482void dop_c3 (e86_disasm_t *op, unsigned char *src) 1483{ 1484 dop_const (op, "RETN", 1); 1485} 1486 1487/* DOP C4: LES reg16, r/m16 */ 1488static void dop_c4 (e86_disasm_t *op, unsigned char *src) 1489{ 1490 dop_reg16_ea16 (op, src, "LES"); 1491} 1492 1493/* DOP C5: LDS reg16, r/m16 */ 1494static void dop_c5 (e86_disasm_t *op, unsigned char *src) 1495{ 1496 dop_reg16_ea16 (op, src, "LDS"); 1497} 1498 1499/* DOP C6: MOV r/m8, imm8 */ 1500static void dop_c6 (e86_disasm_t *op, unsigned char *src) 1501{ 1502 strcpy (op->op, "MOV"); 1503 op->dat_n = disasm_ea8 (op, op->arg1, src + 1); 1504 disasm_imm8 (op->arg2, src + 1 + op->dat_n); 1505 1506 op->dat_n += 2; 1507 op->arg_n = 2; 1508} 1509 1510/* DOP C7: MOV r/m16, imm16 */ 1511static void dop_c7 (e86_disasm_t *op, unsigned char *src) 1512{ 1513 strcpy (op->op, "MOV"); 1514 op->dat_n = disasm_ea16 (op, op->arg1, src + 1); 1515 disasm_imm16 (op->arg2, src + 1 + op->dat_n); 1516 1517 op->dat_n += 3; 1518 op->arg_n = 2; 1519} 1520 1521/* DOP C8: ENTER imm16, imm8 */ 1522static 1523void dop_c8 (e86_disasm_t *op, unsigned char *src) 1524{ 1525 op->flags |= E86_DFLAGS_186; 1526 1527 strcpy (op->op, "ENTER"); 1528 disasm_imm16 (op->arg1, src + 1); 1529 disasm_imm8 (op->arg2, src + 3); 1530 1531 op->dat_n = 4; 1532 op->arg_n = 2; 1533} 1534 1535/* DOP C9: LEAVE */ 1536static 1537void dop_c9 (e86_disasm_t *op, unsigned char *src) 1538{ 1539 op->flags |= E86_DFLAGS_186; 1540 dop_const (op, "LEAVE", 1); 1541} 1542 1543/* DOP CA: RETF imm16 */ 1544static 1545void dop_ca (e86_disasm_t *op, unsigned char *src) 1546{ 1547 op->dat_n = 3; 1548 op->arg_n = 1; 1549 1550 strcpy (op->op, "RETF"); 1551 disasm_imm16 (op->arg1, src + 1); 1552} 1553 1554/* DOP CB: RETF */ 1555static 1556void dop_cb (e86_disasm_t *op, unsigned char *src) 1557{ 1558 dop_const (op, "RETF", 1); 1559} 1560 1561/* DOP CC: INT3 */ 1562static 1563void dop_cc (e86_disasm_t *op, unsigned char *src) 1564{ 1565 dop_const (op, "INT3", 1); 1566 op->flags |= E86_DFLAGS_CALL; 1567} 1568 1569/* DOP CD: INT imm8 */ 1570static 1571void dop_cd (e86_disasm_t *op, unsigned char *src) 1572{ 1573 op->flags |= E86_DFLAGS_CALL; 1574 1575 op->dat_n = 2; 1576 op->arg_n = 1; 1577 1578 strcpy (op->op, "INT"); 1579 disasm_imm8 (op->arg1, src + 1); 1580} 1581 1582/* DOP CE: INTO */ 1583static 1584void dop_ce (e86_disasm_t *op, unsigned char *src) 1585{ 1586 dop_const (op, "INTO", 1); 1587 op->flags |= E86_DFLAGS_CALL; 1588} 1589 1590/* DOP CF: IRET */ 1591static 1592void dop_cf (e86_disasm_t *op, unsigned char *src) 1593{ 1594 dop_const (op, "IRET", 1); 1595} 1596 1597static char *d_tab_d0[8] = { 1598 "ROL", "ROR", "RCL", "RCR", 1599 "SHL", "SHR", "???", "SAR" 1600}; 1601 1602/* DOP D0: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m8, 1 */ 1603static void dop_d0 (e86_disasm_t *op, unsigned char *src) 1604{ 1605 unsigned xop, cnt; 1606 1607 xop = (src[1] >> 3) & 7; 1608 1609 strcpy (op->op, d_tab_d0[xop]); 1610 cnt = disasm_ea8 (op, op->arg1, src + 1); 1611 strcpy (op->arg2, "1"); 1612 1613 op->dat_n = 1 + cnt; 1614 op->arg_n = 2; 1615} 1616 1617/* DOP D1: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m16, 1 */ 1618static void dop_d1 (e86_disasm_t *op, unsigned char *src) 1619{ 1620 unsigned xop, cnt; 1621 1622 xop = (src[1] >> 3) & 7; 1623 1624 strcpy (op->op, d_tab_d0[xop]); 1625 cnt = disasm_ea16 (op, op->arg1, src + 1); 1626 strcpy (op->arg2, "1"); 1627 1628 op->dat_n = 1 + cnt; 1629 op->arg_n = 2; 1630} 1631 1632static char *d_tab_d2[8] = { 1633 "ROL", "ROR", "RCL", "RCR", 1634 "SHL", "SHR", "???", "SAR" 1635}; 1636 1637/* DOP D2: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m8, CL */ 1638static void dop_d2 (e86_disasm_t *op, unsigned char *src) 1639{ 1640 unsigned xop, cnt; 1641 1642 xop = (src[1] >> 3) & 7; 1643 1644 strcpy (op->op, d_tab_d2[xop]); 1645 cnt = disasm_ea8 (op, op->arg1, src + 1); 1646 disasm_reg8 (op->arg2, E86_REG_CL); 1647 1648 op->dat_n = 1 + cnt; 1649 op->arg_n = 2; 1650} 1651 1652/* DOP D3: ROL, ROR, RCL, RCR, SHL, SHR, SAR r/m16, CL */ 1653static void dop_d3 (e86_disasm_t *op, unsigned char *src) 1654{ 1655 unsigned xop, cnt; 1656 1657 xop = (src[1] >> 3) & 7; 1658 1659 strcpy (op->op, d_tab_d2[xop]); 1660 cnt = disasm_ea16 (op, op->arg1, src + 1); 1661 disasm_reg8 (op->arg2, E86_REG_CL); 1662 1663 op->dat_n = 1 + cnt; 1664 op->arg_n = 2; 1665} 1666 1667/* DOP D4: AAM imm8 */ 1668static void dop_d4 (e86_disasm_t *op, unsigned char *src) 1669{ 1670 strcpy (op->op, "AAM"); 1671 disasm_imm8 (op->arg1, src + 1); 1672 1673 op->dat_n = 2; 1674 op->arg_n = 1; 1675} 1676 1677/* DOP D5: AAD imm8 */ 1678static void dop_d5 (e86_disasm_t *op, unsigned char *src) 1679{ 1680 strcpy (op->op, "AAD"); 1681 disasm_imm8 (op->arg1, src + 1); 1682 1683 op->dat_n = 2; 1684 op->arg_n = 1; 1685} 1686 1687/* DOP D7: XLAT */ 1688static 1689void dop_d7 (e86_disasm_t *op, unsigned char *src) 1690{ 1691 dop_const (op, "XLAT", 1); 1692} 1693 1694static char *d_tab_e0[4] = { 1695 "LOOPNZ", "LOOPZ", "LOOP", "JCXZ" 1696}; 1697 1698/* DOP E0-E3: LOOPxx imm8 */ 1699static void dop_e0 (e86_disasm_t *op, unsigned char *src) 1700{ 1701 unsigned short t; 1702 1703 op->flags |= E86_DFLAGS_LOOP; 1704 1705 op->dat_n = 2; 1706 op->arg_n = 1; 1707 1708 t = 2 + e86_add_sint8 (op->ip, src[1]); 1709 1710 strcpy (op->op, d_tab_e0[src[0] - 0xe0]); 1711 disasm_uint16 (op->arg1, t); 1712} 1713 1714/* DOP E4: IN AL, imm8 */ 1715static void dop_e4 (e86_disasm_t *op, unsigned char *src) 1716{ 1717 op->dat_n = 2; 1718 op->arg_n = 2; 1719 1720 strcpy (op->op, "IN"); 1721 strcpy (op->arg1, "AL"); 1722 disasm_imm8 (op->arg2, src + 1); 1723} 1724 1725/* DOP E5: IN AX, imm8 */ 1726static void dop_e5 (e86_disasm_t *op, unsigned char *src) 1727{ 1728 op->dat_n = 2; 1729 op->arg_n = 2; 1730 1731 strcpy (op->op, "IN"); 1732 strcpy (op->arg1, "AX"); 1733 disasm_imm8 (op->arg2, src + 1); 1734} 1735 1736/* DOP E6: OUT imm8, AL */ 1737static void dop_e6 (e86_disasm_t *op, unsigned char *src) 1738{ 1739 op->dat_n = 2; 1740 op->arg_n = 2; 1741 1742 strcpy (op->op, "OUT"); 1743 disasm_imm8 (op->arg1, src + 1); 1744 strcpy (op->arg2, "AL"); 1745} 1746 1747/* DOP E7: OUT imm8, AX */ 1748static void dop_e7 (e86_disasm_t *op, unsigned char *src) 1749{ 1750 op->dat_n = 2; 1751 op->arg_n = 2; 1752 1753 strcpy (op->op, "OUT"); 1754 disasm_imm8 (op->arg1, src + 1); 1755 strcpy (op->arg2, "AX"); 1756} 1757 1758/* DOP E8: CALL imm16 */ 1759static 1760void dop_e8 (e86_disasm_t *op, unsigned char *src) 1761{ 1762 unsigned short t; 1763 1764 op->flags |= E86_DFLAGS_CALL; 1765 1766 op->dat_n = 3; 1767 op->arg_n = 1; 1768 1769 t = (op->ip + e86_mk_uint16 (src[1], src[2]) + 3) & 0xffff; 1770 1771 strcpy (op->op, "CALL"); 1772 disasm_uint16 (op->arg1, t); 1773} 1774 1775/* DOP E9: JMP imm16 */ 1776static void dop_e9 (e86_disasm_t *op, unsigned char *src) 1777{ 1778 unsigned short t; 1779 1780 op->dat_n = 3; 1781 op->arg_n = 1; 1782 1783 t = (op->ip + e86_mk_uint16 (src[1], src[2]) + 3) & 0xffff; 1784 1785 strcpy (op->op, "JMPN"); 1786 disasm_uint16 (op->arg1, t); 1787} 1788 1789/* DOP EA: JMP imm32 */ 1790static void dop_ea (e86_disasm_t *op, unsigned char *src) 1791{ 1792 op->dat_n = 5; 1793 op->arg_n = 1; 1794 1795 strcpy (op->op, "JMPF"); 1796 disasm_imm32 (op->arg1, src + 1); 1797} 1798 1799/* DOP EB: JMP imm8 */ 1800static void dop_eb (e86_disasm_t *op, unsigned char *src) 1801{ 1802 unsigned short t; 1803 1804 op->dat_n = 2; 1805 op->arg_n = 1; 1806 1807 t = e86_add_sint8 (op->ip + 2, src[1]); 1808 1809 strcpy (op->op, "JMPS"); 1810 disasm_uint16 (op->arg1, t); 1811} 1812 1813/* DOP EC: IN AL, DX */ 1814static void dop_ec (e86_disasm_t *op, unsigned char *src) 1815{ 1816 op->dat_n = 1; 1817 op->arg_n = 2; 1818 1819 strcpy (op->op, "IN"); 1820 strcpy (op->arg1, "AL"); 1821 strcpy (op->arg2, "DX"); 1822} 1823 1824/* DOP ED: IN AX, DX */ 1825static void dop_ed (e86_disasm_t *op, unsigned char *src) 1826{ 1827 op->dat_n = 1; 1828 op->arg_n = 2; 1829 1830 strcpy (op->op, "IN"); 1831 strcpy (op->arg1, "AX"); 1832 strcpy (op->arg2, "DX"); 1833} 1834 1835/* DOP EE: OUT DX, AL */ 1836static 1837void dop_ee (e86_disasm_t *op, unsigned char *src) 1838{ 1839 op->dat_n = 1; 1840 op->arg_n = 2; 1841 1842 strcpy (op->op, "OUT"); 1843 strcpy (op->arg1, "DX"); 1844 strcpy (op->arg2, "AL"); 1845} 1846 1847/* DOP EF: OUT DX, AX */ 1848static 1849void dop_ef (e86_disasm_t *op, unsigned char *src) 1850{ 1851 op->dat_n = 1; 1852 op->arg_n = 2; 1853 1854 strcpy (op->op, "OUT"); 1855 strcpy (op->arg1, "DX"); 1856 strcpy (op->arg2, "AX"); 1857} 1858 1859/* DOP F0: LOCK */ 1860static 1861void dop_f0 (e86_disasm_t *op, unsigned char *src) 1862{ 1863 char tmp[256]; 1864 1865 e86_disasm (op, src + 1, op->ip); 1866 1867 strcpy (tmp, op->op); 1868 strcpy (op->op, "LOCK "); 1869 strcat (op->op, tmp); 1870 1871 op->dat_n += 1; 1872} 1873 1874/* DOP F2: REPNE */ 1875static 1876void dop_f2 (e86_disasm_t *op, unsigned char *src) 1877{ 1878 char tmp[256]; 1879 1880 e86_disasm (op, src + 1, op->ip); 1881 1882 strcpy (tmp, op->op); 1883 strcpy (op->op, "REPNE "); 1884 strcat (op->op, tmp); 1885 1886 op->dat_n += 1; 1887} 1888 1889/* DOP F3: REP */ 1890static 1891void dop_f3 (e86_disasm_t *op, unsigned char *src) 1892{ 1893 char tmp[256]; 1894 1895 e86_disasm (op, src + 1, op->ip); 1896 1897 strcpy (tmp, op->op); 1898 strcpy (op->op, "REP "); 1899 strcat (op->op, tmp); 1900 1901 op->dat_n += 1; 1902} 1903 1904/* DOP F4: HLT */ 1905static 1906void dop_f4 (e86_disasm_t *op, unsigned char *src) 1907{ 1908 dop_const (op, "HLT", 1); 1909} 1910 1911/* DOP F5: CMC */ 1912static 1913void dop_f5 (e86_disasm_t *op, unsigned char *src) 1914{ 1915 dop_const (op, "CMC", 1); 1916} 1917 1918/* DOP F6: xxx r/m8 */ 1919static 1920void dop_f6 (e86_disasm_t *op, unsigned char *src) 1921{ 1922 unsigned xop, cnt; 1923 1924 xop = (src[1] >> 3) & 7; 1925 1926 switch (xop) { 1927 case 0: 1928 strcpy (op->op, "TEST"); 1929 cnt = disasm_ea8 (op, op->arg1, src + 1); 1930 disasm_imm8 (op->arg2, src + 1 + cnt); 1931 op->dat_n = cnt + 2; 1932 op->arg_n = 2; 1933 return; 1934 1935 case 1: 1936 dop_ud (op, src); 1937 return; 1938 1939 case 2: 1940 dop_ea8 (op, src, "NOT"); 1941 return; 1942 1943 case 3: 1944 dop_ea8 (op, src, "NEG"); 1945 return; 1946 1947 case 4: 1948 dop_ea8 (op, src, "MUL"); 1949 return; 1950 1951 case 5: 1952 dop_ea8 (op, src, "IMUL"); 1953 return; 1954 1955 case 6: 1956 dop_ea8 (op, src, "DIV"); 1957 return; 1958 1959 case 7: 1960 dop_ea8 (op, src, "IDIV"); 1961 return; 1962 1963 default: 1964 dop_ud (op, src); 1965 return; 1966 } 1967} 1968 1969/* DOP F7: xxx r/m16 */ 1970static 1971void dop_f7 (e86_disasm_t *op, unsigned char *src) 1972{ 1973 unsigned xop, cnt; 1974 1975 xop = (src[1] >> 3) & 7; 1976 1977 switch (xop) { 1978 case 0: 1979 strcpy (op->op, "TEST"); 1980 cnt = disasm_ea16 (op, op->arg1, src + 1); 1981 disasm_imm16 (op->arg2, src + 1 + cnt); 1982 op->dat_n = cnt + 3; 1983 op->arg_n = 2; 1984 return; 1985 1986 case 1: 1987 dop_ud (op, src); 1988 return; 1989 1990 case 2: 1991 dop_ea16 (op, src, "NOT"); 1992 return; 1993 1994 case 3: 1995 dop_ea16 (op, src, "NEG"); 1996 return; 1997 1998 case 4: 1999 dop_ea16 (op, src, "MUL"); 2000 return; 2001 2002 case 5: 2003 dop_ea16 (op, src, "IMUL"); 2004 return; 2005 2006 case 6: 2007 dop_ea16 (op, src, "DIV"); 2008 return; 2009 2010 case 7: 2011 dop_ea16 (op, src, "IDIV"); 2012 return; 2013 2014 default: 2015 dop_ud (op, src); 2016 return; 2017 } 2018} 2019 2020static char *d_tab_f8[6] = { 2021 "CLC", "STC", "CLI", "STI", "CLD", "STD" 2022}; 2023 2024/* DOP F8-FD: CLC, STC, CLI, STI, CLD, STD */ 2025static void dop_f8 (e86_disasm_t *op, unsigned char *src) 2026{ 2027 op->dat_n = 1; 2028 op->arg_n = 0; 2029 2030 strcpy (op->op, d_tab_f8[src[0] - 0xf8]); 2031} 2032 2033/* DOP FE: INC, DEC r/m8 */ 2034static void dop_fe (e86_disasm_t *op, unsigned char *src) 2035{ 2036 unsigned xop, cnt; 2037 2038 xop = (src[1] >> 3) & 7; 2039 2040 switch (xop) { 2041 case 0: /* INC r/m8 */ 2042 strcpy (op->op, "INC"); 2043 cnt = disasm_ea8 (op, op->arg1, src + 1); 2044 op->dat_n = cnt + 1; 2045 op->arg_n = 1; 2046 return; 2047 2048 case 1: /* DEC r/m8 */ 2049 strcpy (op->op, "DEC"); 2050 cnt = disasm_ea8 (op, op->arg1, src + 1); 2051 op->dat_n = cnt + 1; 2052 op->arg_n = 1; 2053 return; 2054 2055 default: 2056 dop_ud (op, src); 2057 return; 2058 } 2059} 2060 2061/* DOP FF: xxx r/m16 */ 2062static 2063void dop_ff (e86_disasm_t *op, unsigned char *src) 2064{ 2065 unsigned xop; 2066 2067 xop = (src[1] >> 3) & 7; 2068 2069 switch (xop) { 2070 case 0: 2071 dop_ea16 (op, src, "INC"); 2072 return; 2073 2074 case 1: 2075 dop_ea16 (op, src, "DEC"); 2076 return; 2077 2078 case 2: 2079 dop_ea16 (op, src, "CALL"); 2080 op->flags |= E86_DFLAGS_CALL; 2081 return; 2082 2083 case 3: 2084 dop_ea16 (op, src, "CALLF"); 2085 op->flags |= E86_DFLAGS_CALL; 2086 return; 2087 2088 case 4: 2089 dop_ea16 (op, src, "JMP"); 2090 return; 2091 2092 case 5: 2093 dop_ea16 (op, src, "JMPF"); 2094 return; 2095 2096 case 6: 2097 dop_ea16 (op, src, "PUSH"); 2098 return; 2099 2100 case 7: 2101 dop_ud (op, src); 2102 return; 2103 2104 default: 2105 dop_ud (op, src); 2106 return; 2107 } 2108} 2109 2110 2111typedef void (*e86_disasm_f) (e86_disasm_t *op, unsigned char *src); 2112 2113static 2114e86_disasm_f dop_list[256] = { 2115 &dop_00, &dop_01, &dop_02, &dop_03, &dop_04, &dop_05, &dop_06, &dop_07, 2116 &dop_08, &dop_09, &dop_0a, &dop_0b, &dop_0c, &dop_0d, &dop_0e, &dop_0f, 2117 &dop_10, &dop_11, &dop_12, &dop_13, &dop_14, &dop_15, &dop_16, &dop_17, 2118 &dop_18, &dop_19, &dop_1a, &dop_1b, &dop_1c, &dop_1d, &dop_1e, &dop_1f, 2119 &dop_20, &dop_21, &dop_22, &dop_23, &dop_24, &dop_25, &dop_26, &dop_27, /* 20 */ 2120 &dop_28, &dop_29, &dop_2a, &dop_2b, &dop_2c, &dop_2d, &dop_2e, &dop_2f, 2121 &dop_30, &dop_31, &dop_32, &dop_33, &dop_34, &dop_35, &dop_36, &dop_37, /* 30 */ 2122 &dop_38, &dop_39, &dop_3a, &dop_3b, &dop_3c, &dop_3d, &dop_3e, &dop_3f, 2123 &dop_40, &dop_40, &dop_40, &dop_40, &dop_40, &dop_40, &dop_40, &dop_40, /* 40 */ 2124 &dop_48, &dop_48, &dop_48, &dop_48, &dop_48, &dop_48, &dop_48, &dop_48, 2125 &dop_50, &dop_50, &dop_50, &dop_50, &dop_50, &dop_50, &dop_50, &dop_50, /* 50 */ 2126 &dop_58, &dop_58, &dop_58, &dop_58, &dop_58, &dop_58, &dop_58, &dop_58, 2127 &dop_60, &dop_61, &dop_62, &dop_ud, &dop_ud, &dop_ud, &dop_66, &dop_ud, /* 60 */ 2128 &dop_68, &dop_ud, &dop_6a, &dop_ud, &dop_6c, &dop_6d, &dop_6e, &dop_6f, 2129 &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, /* 70 */ 2130 &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, &dop_70, 2131 &dop_80, &dop_81, &dop_80, &dop_83, &dop_84, &dop_85, &dop_86, &dop_87, /* 80 */ 2132 &dop_88, &dop_89, &dop_8a, &dop_8b, &dop_8c, &dop_8d, &dop_8e, &dop_8f, 2133 &dop_90, &dop_91, &dop_91, &dop_91, &dop_91, &dop_91, &dop_91, &dop_91, /* 90 */ 2134 &dop_98, &dop_99, &dop_9a, &dop_9b, &dop_9c, &dop_9d, &dop_9e, &dop_9f, 2135 &dop_a0, &dop_a1, &dop_a2, &dop_a3, &dop_a4, &dop_a5, &dop_a6, &dop_a7, /* A0 */ 2136 &dop_a8, &dop_a9, &dop_aa, &dop_ab, &dop_ac, &dop_ad, &dop_ae, &dop_af, 2137 &dop_b0, &dop_b0, &dop_b0, &dop_b0, &dop_b0, &dop_b0, &dop_b0, &dop_b0, /* B0 */ 2138 &dop_b8, &dop_b8, &dop_b8, &dop_b8, &dop_b8, &dop_b8, &dop_b8, &dop_b8, 2139 &dop_c0, &dop_c1, &dop_c2, &dop_c3, &dop_c4, &dop_c5, &dop_c6, &dop_c7, /* C0 */ 2140 &dop_c8, &dop_c9, &dop_ca, &dop_cb, &dop_cc, &dop_cd, &dop_ce, &dop_cf, 2141 &dop_d0, &dop_d1, &dop_d2, &dop_d3, &dop_d4, &dop_d5, &dop_ud, &dop_d7, /* D0 */ 2142 &dop_ud, &dop_ud, &dop_ud, &dop_ud, &dop_ud, &dop_ud, &dop_ud, &dop_ud, 2143 &dop_e0, &dop_e0, &dop_e0, &dop_e0, &dop_e4, &dop_e5, &dop_e6, &dop_e7, /* E0 */ 2144 &dop_e8, &dop_e9, &dop_ea, &dop_eb, &dop_ec, &dop_ed, &dop_ee, &dop_ef, 2145 &dop_f0, &dop_ud, &dop_f2, &dop_f3, &dop_f4, &dop_f5, &dop_f6, &dop_f7, /* F0 */ 2146 &dop_f8, &dop_f8, &dop_f8, &dop_f8, &dop_f8, &dop_f8, &dop_fe, &dop_ff 2147}; 2148 2149static 2150void e86_disasm_op (e86_disasm_t *op, unsigned char *src) 2151{ 2152 dop_list[src[0]] (op, src); 2153} 2154 2155void e86_disasm (e86_disasm_t *op, unsigned char *src, unsigned short ip) 2156{ 2157 unsigned i; 2158 2159 op->flags = 0; 2160 op->seg = 0; 2161 op->ip = ip; 2162 2163 e86_disasm_op (op, src); 2164 2165 for (i = 0; i < op->dat_n; i++) { 2166 op->dat[i] = src[i]; 2167 } 2168} 2169 2170void e86_disasm_mem (e8086_t *c, e86_disasm_t *op, unsigned short cs, unsigned short ip) 2171{ 2172 unsigned i; 2173 unsigned char src[16]; 2174 2175 for (i = 0; i < 16; i++) { 2176 src[i] = e86_get_mem8 (c, cs, (ip + i) & 0xffff); 2177 } 2178 2179 e86_disasm (op, src, ip); 2180} 2181 2182void e86_disasm_cur (e8086_t *c, e86_disasm_t *op) 2183{ 2184 e86_disasm_mem (c, op, c->sreg[E86_REG_CS], c->ip); 2185}