home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / ASMDISP.C next >
C/C++ Source or Header  |  1994-06-29  |  56KB  |  1,981 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. /*
  8. ** Display the source for the given source file and line number.
  9. */
  10. #include    <stdio.h>
  11. #include    <stdlib.h>
  12. #include    <ctype.h>
  13. #include    <string.h>
  14. #include    <sys\stat.h>
  15.  
  16. #define     INCL_DOSPROCESS
  17. #include    <os2.h>
  18. #include    "debug.h"
  19.  
  20. #include    "Debugger.h"
  21. #include    "SrcInter.h"
  22. #include    "Source.h"
  23. #include    "SrcDisp.h"
  24.  
  25. typedef struct {
  26.     ULONG   addr;
  27.     int     is32BitSegment:1;
  28.     int     is32BitOperands:1;
  29.     int     is32BitAddress:1;
  30.     char   *ptr;
  31.     ULONG   ptr_offset;
  32.     char    reg[32];
  33.     char    rm[32];
  34.     char    temp[32];
  35. } DumpState;
  36.  
  37. /*
  38. ** Data for disassembly.
  39. */
  40. static char *dword_reg[] = { "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI"};
  41. static char *word_reg[]  = {  "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"};
  42. static char *byte_reg[]  = {  "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"};
  43. static char *drm_reg[]     = { "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI"};
  44. static char *rm_reg[]     = { "BX+SI", "BX+DI", "BP+SI", "BP+DI",
  45.                  "SI",    "DI",    "BP",    "BX"};
  46. static char *seg_reg[]     = {  "ES", "CS", "SS", "DS"};
  47. static char *bw_ptr[]     = { "BYTE PTR", "WORD PTR" };
  48. static char *dbw_ptr[]     = { "BYTE PTR", "DWORD PTR" };
  49.  
  50. /*
  51. ** Function prototypes for the local functions.
  52. */
  53. static int  DispatchByte(UCHAR *ptr, DumpState *state);
  54. static int  reg_mod(int is8BitOp, UCHAR *pData, DumpState *state);
  55. static int  byte_reg_mod(UCHAR *pData, DumpState *state);
  56. static int  word_reg_mod(UCHAR *pData, DumpState *state);
  57. static int  type00(UCHAR *ptr, DumpState *state);
  58. static int  type0F(UCHAR *ptr, DumpState *state);
  59. static int  type40(UCHAR *ptr, DumpState *state);
  60. static int  type60(UCHAR *ptr, DumpState *state);
  61. static int  type70(UCHAR *ptr, DumpState *state);
  62. static int  type80(UCHAR *ptr, DumpState *state);
  63. static int  type90(UCHAR *ptr, DumpState *state);
  64. static int  typeA0(UCHAR *ptr, DumpState *state);
  65. static int  typeB0(UCHAR *ptr, DumpState *state);
  66. static int  typeC0(UCHAR *ptr, DumpState *state);
  67. static int  typeD0(UCHAR *ptr, DumpState *state);
  68. static int  typeE0(UCHAR *ptr, DumpState *state);
  69. static int  typeF0(UCHAR *ptr, DumpState *state);
  70. static int  coprosseser(UCHAR *ptr, DumpState *state);
  71. static int  cotypeD8(UCHAR *ptr, DumpState *state);
  72. static int  cotypeD9(UCHAR *ptr, DumpState *state);
  73. static int  cotypeDA(UCHAR *ptr, DumpState *state);
  74. static int  cotypeDB(UCHAR *ptr, DumpState *state);
  75. static int  cotypeDC(UCHAR *ptr, DumpState *state);
  76. static int  cotypeDD(UCHAR *ptr, DumpState *state);
  77. static int  cotypeDE(UCHAR *ptr, DumpState *state);
  78. static int  cotypeDF(UCHAR *ptr, DumpState *state);
  79.  
  80. /*
  81. ** Disassemable the code starting at addr for the length specified.
  82. */
  83. void DumpAsm(ULONG addr, ULONG length, int is32Bit)
  84. {
  85. int        i;
  86. DumpState   state;
  87.  
  88.     /*
  89.     ** Fill a buffer with the code from the program.
  90.     */
  91.     state.ptr = calloc(length, 1);
  92.     debugBuffer.Addr   = addr;
  93.     debugBuffer.Len    = length;
  94.     debugBuffer.Buffer = (ULONG) state.ptr;
  95.     if((i=DispatchCommand(DBG_C_ReadMemBuf)) != DBG_N_Success) {
  96.     return;
  97.     }
  98.     state.ptr = (UCHAR *) debugBuffer.Buffer;
  99.     state.is32BitSegment  = is32Bit;
  100.     state.is32BitOperands = is32Bit;
  101.     state.is32BitAddress  = is32Bit;
  102.     state.addr      = addr;
  103.     state.ptr_offset = 0;
  104.  
  105.     /*
  106.     ** Dump the code.
  107.     */
  108.     for(state.ptr_offset=0; state.ptr_offset<length;) {
  109.     DispatchByte(&state.ptr[state.ptr_offset], &state);
  110.     }
  111.  
  112.     /*
  113.     ** Clean up.
  114.     */
  115.     free(state.ptr);
  116.     return;
  117. }
  118.  
  119. /*
  120. ** Dispatch the current byte for decode.
  121. */
  122. static int DispatchByte(UCHAR *ptr, DumpState *state)
  123. {
  124. ULONG    length;
  125.  
  126.     switch(ptr[0] & 0xf0) {
  127.     case 0x00:
  128.     case 0x10:
  129.     case 0x20:
  130.     case 0x30:
  131.         length = type00(ptr, state);
  132.         break;
  133.     case 0x40:
  134.     case 0x50:
  135.         length = type40(ptr, state);
  136.         break;
  137.     case 0x60:
  138.         length = type60(ptr, state);
  139.         break;
  140.     case 0x70:
  141.         length = type70(ptr, state);
  142.         break;
  143.     case 0x80:
  144.         length = type80(ptr, state);
  145.         break;
  146.     case 0x90:
  147.         length = type90(ptr, state);
  148.         break;
  149.     case 0xa0:
  150.         length = typeA0(ptr, state);
  151.         break;
  152.     case 0xb0:
  153.         length = typeB0(ptr, state);
  154.         break;
  155.     case 0xc0:
  156.         length = typeC0(ptr, state);
  157.         break;
  158.     case 0xd0:
  159.         length = typeD0(ptr, state);
  160.         break;
  161.     case 0xe0:
  162.         length = typeE0(ptr, state);
  163.         break;
  164.     case 0xf0:
  165.         length = typeF0(ptr, state);
  166.         break;
  167.     }
  168.     state->ptr_offset += length;
  169.     return length;
  170. }
  171.  
  172. /************************************************
  173. **                           **
  174. **  print out the opcode with no/1/2 arguments **
  175. **                           **
  176. ************************************************/
  177. static void opcode0(DumpState *state, char *opcode)
  178. {
  179. ULONG    addr, hiWord, loWord;
  180.  
  181.     addr = state->addr + state->ptr_offset;
  182.     if(state->is32BitSegment) {
  183.     fprintf(logFile, "%08x  %s\n", addr, opcode);
  184.     return;
  185.     }
  186.     loWord = addr & 0xffff;
  187.     hiWord = addr >> 16;
  188.     hiWord = (hiWord << 3) | 0x0007;
  189.     fprintf(logFile, "%04x:%04x %s\n", hiWord, loWord, opcode);
  190. }
  191. static void opcode1(DumpState *state, char *opcode, char *op1)
  192. {
  193. ULONG    addr, hiWord, loWord;
  194.  
  195.     addr = state->addr + state->ptr_offset;
  196.     if(state->is32BitSegment) {
  197.     fprintf(logFile, "%08x  %s\t%s\n", addr, opcode, op1);
  198.     return;
  199.     }
  200.     loWord = addr & 0xffff;
  201.     hiWord = addr >> 16;
  202.     hiWord = (hiWord << 3) | 0x0007;
  203.     fprintf(logFile, "%04x:%04x %s\t%s\n", hiWord, loWord, opcode, op1);
  204. }
  205. static void opcode2(DumpState *state, char *opcode, char *op1, char *op2)
  206. {
  207. ULONG    addr, hiWord, loWord;
  208.  
  209.     addr = state->addr + state->ptr_offset;
  210.     if(state->is32BitSegment) {
  211.     fprintf(logFile, "%08x  %s\t%s,%s\n", addr, opcode, op1, op2);
  212.     return;
  213.     }
  214.     loWord = addr & 0xffff;
  215.     hiWord = addr >> 16;
  216.     hiWord = (hiWord << 3) | 0x0007;
  217.     fprintf(logFile, "%04x:%04x %s\t%s,%s\n", hiWord, loWord, opcode, op1, op2);
  218. }
  219. static void opcode3(DumpState *state, char *opcode, char *op1, char *op2, char *op3)
  220. {
  221. ULONG    addr, hiWord, loWord;
  222.  
  223.     addr = state->addr + state->ptr_offset;
  224.     if(state->is32BitSegment) {
  225.     fprintf(logFile, "%08x  %s\t%s,%s,%s\n", addr, opcode, op1, op2, op3);
  226.     return;
  227.     }
  228.     loWord = addr & 0xffff;
  229.     hiWord = addr >> 16;
  230.     hiWord = (hiWord << 3) | 0x0007;
  231.     fprintf(logFile, "%04x:%04x %s\t%s,%s,%s\n", hiWord, loWord, opcode, op1, op2, op3);
  232. }
  233.  
  234. static ULONG get_immediate(UCHAR *ptr, int *length, int isByte, int is32Bit)
  235. {
  236.     if(isByte) {
  237.     *length = 1;
  238.     return (int) ((char) ptr[0]);
  239.     }
  240.     if(is32Bit) {
  241.     *length = 4;
  242.     return ptr[0]      | ptr[1] << 8|
  243.            ptr[2]<<16 | ptr[3] <<24;
  244.     }
  245.     *length = 2;
  246.     return (int) ((short) ptr[0] | ptr[1] << 8);
  247. }
  248.  
  249. static ULONG get_address(UCHAR *ptr, ULONG *offset, DumpState *state)
  250. {
  251.     if(state->is32BitAddress) {
  252.     *offset = ptr[0]     | ptr[1]<<8 |
  253.           ptr[2]<<16 | ptr[3]<<24;
  254.     return 4;
  255.     }
  256.     *offset = ptr[0] | ptr[1]<<8;
  257.     return 2;
  258. }
  259.  
  260. /************************************************
  261. **                           **
  262. ** Support routine to decode the rm/reg field. **
  263. **                           **
  264. ************************************************/
  265. static int reg_mod(int is8BitOp, UCHAR *pData, DumpState *state)
  266. {
  267.     if(!is8BitOp)
  268.     return byte_reg_mod(pData, state);
  269.  
  270.     return word_reg_mod(pData, state);
  271. }
  272.  
  273. static int word_reg_mod(UCHAR *pData, DumpState *state)
  274. {
  275. int offset,reg_mem,reg,mod;
  276. int length = 1;
  277.  
  278.     reg_mem =  pData[0] & 0x07;
  279.     reg     = (pData[0] & 0x38) >> 3;
  280.     mod     = (pData[0] & 0xC0) >> 6;
  281.     if(state->is32BitOperands)
  282.     sprintf(state->reg, "%s", dword_reg[reg]);
  283.     else
  284.     sprintf(state->reg, "%s", word_reg[reg]);
  285.     if((reg_mem == 0x04) && (mod != 3) && state->is32BitAddress) {
  286.     int ss, index, base;
  287.  
  288.     /*
  289.     ** Get the base, index and scalling factor.
  290.     */
  291.     length++;
  292.     base  =  pData[1] & 0x07;
  293.     index = (pData[1] & 0x38) >> 3;
  294.     switch((pData[1] & 0xC0) >> 6) {
  295.         case 0: ss = 1; break;
  296.         case 1: ss = 2; break;
  297.         case 2: ss = 4; break;
  298.         case 3: ss = 8; break;
  299.     }
  300.     if((mod == 0) && (base == 5)) {
  301.         int offset;
  302.  
  303.         offset = pData[2]      | pData[3]<<8 |
  304.              pData[4]<<16 | pData[5]<<24;
  305.  
  306.         if(state->is32BitAddress)
  307.         sprintf(state->rm, "%s [(%s) * %d + 0x%08x]", state->is32BitOperands ?
  308.             dbw_ptr[1] : bw_ptr[1],
  309.             dword_reg[index], ss, offset);
  310.         else
  311.         sprintf(state->rm, "%s [(%s) * %d + 0x%08x]", state->is32BitOperands ?
  312.             dbw_ptr[1] : bw_ptr[1],
  313.             dword_reg[index], ss, offset);
  314.         return length + 4;
  315.     }
  316.     switch(mod) {
  317.         case 0: offset = 0;
  318.             break;
  319.         case 1: offset = pData[2];
  320.             length += 1;
  321.             break;
  322.         case 2: if(state->is32BitAddress) {
  323.             offset = pData[2]     | pData[3]<<8 |
  324.                  pData[4]<<16 | pData[5]<<24;
  325.             length += 4;
  326.             } else {
  327.             offset = pData[2] | pData[3]<<8;
  328.             length += 2;
  329.             }
  330.             break;
  331.     }
  332.     if(state->is32BitAddress)
  333.         sprintf(state->rm, "%s [%s + %d*(%s) + 0x%08x]", state->is32BitOperands ?
  334.             dbw_ptr[1] : bw_ptr[1],
  335.             dword_reg[base], ss, dword_reg[index], offset);
  336.     else
  337.         sprintf(state->rm, "%s [%s + %d*(%s) + 0x%08x]", state->is32BitOperands ?
  338.             dbw_ptr[1] : bw_ptr[1],
  339.             dword_reg[base], ss, dword_reg[index], offset);
  340.     return length;
  341.     }
  342.     switch(mod) {
  343.         case 0: {
  344.         if(reg_mem == 5)    {
  345.         if(state->is32BitAddress) {
  346.             offset = pData[1]      | pData[2]<< 8 |
  347.                  pData[3]<<16 | pData[4]<<24;
  348.             length += 4;
  349.             sprintf(state->rm, "%s [0x%08x]", state->is32BitOperands ?
  350.                 dbw_ptr[1] : bw_ptr[1], offset);
  351.         } else {
  352.             offset = pData[1] | pData[2] << 8;
  353.             if(offset & 0x8000)
  354.             offset |= 0xffff0000;
  355.             length += 2;
  356.             sprintf(state->rm, "%s [0x%04x]", state->is32BitOperands ?
  357.                 dbw_ptr[1] : bw_ptr[1], offset);
  358.         }
  359.         break;
  360.         }
  361.         if(state->is32BitAddress) {
  362.         sprintf(state->rm, "%s [%s]", state->is32BitOperands ?
  363.             dbw_ptr[1] : bw_ptr[1], drm_reg[reg_mem]);
  364.         } else {
  365.         sprintf(state->rm, "%s [%s]", state->is32BitOperands ?
  366.             dbw_ptr[1] : bw_ptr[1], rm_reg[reg_mem]);
  367.         }
  368.             break;
  369.         }
  370.         case 1: {
  371.         offset = (int) ((char) pData[1]);
  372.         if(state->is32BitAddress)
  373.         sprintf(state->rm, "%s [%s %+#x]", state->is32BitOperands ?
  374.             dbw_ptr[1] : bw_ptr[1], drm_reg[reg_mem], offset);
  375.         else
  376.         sprintf(state->rm, "%s [%s %+#x]", state->is32BitOperands ?
  377.             dbw_ptr[1] : bw_ptr[1], rm_reg[reg_mem], offset);
  378.             length++;
  379.             break;
  380.         }
  381.     case 2: {
  382.         if(state->is32BitAddress) {
  383.         offset = pData[1]     | pData[2]<< 8 |
  384.              pData[3]<<16 | pData[4]<<24;
  385.         length += 4;
  386.         sprintf(state->rm, "%s [%s %+#x]", state->is32BitOperands ?
  387.             dbw_ptr[1] : bw_ptr[1], drm_reg[reg_mem], offset);
  388.         } else {
  389.         offset = pData[1] | pData[2] << 8;
  390.         if(offset & 0x8000)
  391.             offset |= 0xffff0000;
  392.         length += 2;
  393.         sprintf(state->rm, "%s [%s %+#x]", state->is32BitOperands ?
  394.             dbw_ptr[1] : bw_ptr[1], rm_reg[reg_mem], offset);
  395.         }
  396.             break;
  397.         }
  398.     case 3: {
  399.         if(state->is32BitOperands)
  400.         sprintf(state->rm,"%s", dword_reg[reg_mem]);
  401.         else
  402.         sprintf(state->rm,"%s", word_reg[reg_mem]);
  403.             break;
  404.         }
  405.     }
  406.     return length;
  407. }
  408.  
  409. static int byte_reg_mod(UCHAR *pData, DumpState *state)
  410. {
  411. int offset,reg_mem,reg,mod;
  412. int length = 1;
  413.  
  414.     reg_mem =  pData[0] & 0x07;
  415.     reg     = (pData[0] & 0x38) >> 3;
  416.     mod     = (pData[0] & 0xC0) >> 6;
  417.  
  418.     sprintf(state->reg, "%s", byte_reg[reg]);
  419.     if((reg_mem == 0x04) && (mod != 3) && state->is32BitAddress) {
  420.     int ss, index, base;
  421.  
  422.     /*
  423.     ** Get the base, index and scalling factor.
  424.     */
  425.     length++;
  426.     base  =  pData[1] & 0x07;
  427.     index = (pData[1] & 0x38) >> 3;
  428.     switch((pData[1] & 0xC0) >> 6) {
  429.         case 0: ss = 1; break;
  430.         case 1: ss = 2; break;
  431.         case 2: ss = 4; break;
  432.         case 3: ss = 8; break;
  433.     }
  434.     if((mod == 0) && (base == 5)) {
  435.         int offset;
  436.  
  437.         offset = pData[2]      | pData[3]<<8 |
  438.              pData[4]<<16 | pData[5]<<24;
  439.  
  440.         if(state->is32BitAddress)
  441.         sprintf(state->rm, "%s [(%s) * %d + 0x%08x]",
  442.             bw_ptr[0], drm_reg[index], ss, offset);
  443.         else
  444.         sprintf(state->rm, "%s [(%s) * %d + 0x%08x]",
  445.             bw_ptr[0], rm_reg[index], ss, offset);
  446.         return length + 4;
  447.     }
  448.     switch(mod) {
  449.         case 0: offset = 0;
  450.             break;
  451.         case 1: offset = pData[2];
  452.             length += 1;
  453.             break;
  454.         case 2: if(state->is32BitAddress) {
  455.             offset = pData[2]     | pData[3]<<8 |
  456.                  pData[4]<<16 | pData[5]<<24;
  457.             length += 4;
  458.             } else {
  459.             offset = pData[2] | pData[3]<<8;
  460.             length += 2;
  461.             }
  462.             break;
  463.     }
  464.     if(state->is32BitAddress)
  465.         sprintf(state->rm, "%s [%s + %d*(%s) + 0x%08x]",
  466.             bw_ptr[0], drm_reg[base], ss, drm_reg[index], offset);
  467.     else
  468.         sprintf(state->rm, "%s [%s + %d*(%s) + 0x%08x]",
  469.             bw_ptr[0], rm_reg[base], ss, rm_reg[index], offset);
  470.     return length;
  471.     }
  472.     switch(mod) {
  473.         case 0: {
  474.         if(reg_mem == 5)    {
  475.         if(state->is32BitAddress) {
  476.             offset = pData[1]      | pData[2]<< 8 |
  477.                  pData[3]<<16 | pData[4]<<24;
  478.             length += 4;
  479.             sprintf(state->rm, "%s [0x%08x]",
  480.                 bw_ptr[0], offset);
  481.         } else {
  482.             offset = pData[1] | pData[2] << 8;
  483.             if(offset & 0x8000)
  484.             offset |= 0xffff0000;
  485.             length += 2;
  486.             sprintf(state->rm, "%s [0x%04x]",
  487.                 bw_ptr[0], offset);
  488.         }
  489.         break;
  490.         }
  491.         if(state->is32BitAddress) {
  492.         sprintf(state->rm, "%s [%s]",
  493.             bw_ptr[0], drm_reg[reg_mem]);
  494.         } else {
  495.         sprintf(state->rm, "%s [%s]",
  496.             bw_ptr[0], rm_reg[reg_mem]);
  497.         }
  498.             break;
  499.         }
  500.         case 1: {
  501.         offset = (int) ((char) pData[1]);
  502.         if(state->is32BitAddress)
  503.         sprintf(state->rm, "%s [%s %+#x]",
  504.             bw_ptr[0], drm_reg[reg_mem], offset);
  505.         else
  506.         sprintf(state->rm, "%s [%s %+#x]",
  507.             bw_ptr[0], rm_reg[reg_mem], offset);
  508.         length++;
  509.         break;
  510.         }
  511.     case 2: {
  512.         if(state->is32BitAddress) {
  513.         offset = pData[1]     | pData[2]<< 8 |
  514.              pData[3]<<16 | pData[4]<<24;
  515.         length += 4;
  516.         sprintf(state->rm, "%s [%s %+#x]",
  517.             bw_ptr[0], drm_reg[reg_mem], offset);
  518.         } else {
  519.         offset = pData[1] | pData[2] << 8;
  520.         if(offset & 0x8000)
  521.             offset |= 0xffff0000;
  522.         length += 2;
  523.         sprintf(state->rm, "%s [%s %+#x]",
  524.             bw_ptr[0], rm_reg[reg_mem], offset);
  525.         }
  526.             break;
  527.         }
  528.     case 3: {
  529.         sprintf(state->rm,"%s", byte_reg[reg_mem]);
  530.             break;
  531.         }
  532.     }
  533.     return length;
  534. }
  535.  
  536. /**************************************
  537. **                     **
  538. ** Routines to disassemble the code. **
  539. **                     **
  540. **************************************/
  541.  
  542. static int type00(UCHAR *ptr, DumpState *state)
  543. {
  544. char   *opcode,
  545.        *op1,
  546.        *op2;
  547.  
  548. int byte,
  549.     index,
  550.     length,
  551.     operation,
  552.     type;
  553.  
  554.     operation = *ptr;
  555.     byte = (operation & 1) == 0;
  556.     type = operation & 0x07;
  557.     if(type >= 6)   {
  558.         index = (operation >> 3) & 0x03;
  559.         switch (operation)   {
  560.             case    0x06:
  561.             case    0x0E:
  562.             case    0x16:
  563.             case    0x1E:   {
  564.         opcode1(state, "PUSH", seg_reg[index]);
  565.                 break;
  566.             }
  567.             case    0x07:
  568.         case    0x17:
  569.             case    0x1F:   {
  570.         opcode1(state, "POP", seg_reg[index]);
  571.                 break;
  572.             }
  573.         case    0x0F:
  574.         return type0F(ptr, state);
  575.         case    0x26:
  576.             case    0x2E:
  577.             case    0x36:
  578.             case    0x3E:   {
  579.         opcode1(state, "SEG", seg_reg[index]);
  580.                 break;
  581.             }
  582.             case    0x27:   {
  583.         opcode0(state, "DAA");
  584.                 break;
  585.             }
  586.             case    0x2F:   {
  587.         opcode0(state, "DAS");
  588.                 break;
  589.             }
  590.             case    0x37:   {
  591.         opcode0(state, "AAA");
  592.                 break;
  593.             }
  594.             case    0x3F:   {
  595.         opcode0(state, "AAS");
  596.                 break;
  597.             }
  598.         }
  599.     return 1;
  600.     }
  601.     type = operation / 0x08;
  602.     switch(type) {
  603.     case 0x00:  opcode = "ADD"; break;
  604.     case 0x01:  opcode =  "OR"; break;
  605.     case 0x02:  opcode = "ADC"; break;
  606.     case 0x03:  opcode = "SBB"; break;
  607.     case 0x04:  opcode = "AND"; break;
  608.     case 0x05:  opcode = "SUB"; break;
  609.     case 0x06:  opcode = "XOR"; break;
  610.     case 0x07:  opcode = "CMP"; break;
  611.     }
  612.  
  613.     if((operation & 0x04) == 4)  {
  614.     index = get_immediate(ptr+1, &length, byte, state->is32BitOperands);
  615.     length++;
  616.     if(byte)    {
  617.         op1 = "AL";
  618.     } else {
  619.         if(state->is32BitOperands) {
  620.         op1 = "EAX";
  621.         } else {
  622.         op1 = "AX";
  623.         }
  624.         }
  625.     sprintf(state->reg, "0x%08x", index);
  626.     op2 = state->reg;
  627.     } else {
  628.     length = 1 + reg_mod(ptr[0]&1, ptr+1, state);
  629.     op1    = ((operation &    2) == 0) ? state->rm  : state->reg;
  630.     op2    = ((operation &    2) == 0) ? state->reg : state->rm;
  631.     }
  632.     opcode2(state, opcode, op1, op2);
  633.     return length;
  634. }
  635.  
  636. static int type0F(UCHAR *ptr, DumpState *state)
  637. {
  638. ULONG    offset;
  639. int    index;
  640. int    length;
  641. int    tmp;
  642. char   *opcode,
  643.        *op1,
  644.        *op2;
  645.  
  646.  
  647.     index = (ptr[2] & 0x38) >> 3;
  648.     switch(ptr[1]) {
  649.     case 0x00:  tmp = state->is32BitOperands;
  650.             state->is32BitOperands = 0;
  651.             length = 2 + word_reg_mod(ptr+2, state);
  652.             state->is32BitOperands = tmp;
  653.             switch(index) {
  654.             case 0: opcode = "SLDT"; break;
  655.             case 1: opcode = "STR";  break;
  656.             case 2: opcode = "LLDT"; break;
  657.             case 3: opcode = "LTR";  break;
  658.             case 4: opcode = "VERR"; break;
  659.             case 5: opcode = "VERW"; break;
  660.             }
  661.             opcode1(state, opcode, state->rm);
  662.             break;
  663.  
  664.     case 0x01:  tmp = state->is32BitOperands;
  665.             state->is32BitOperands = 0;
  666.             length = 2 + word_reg_mod(ptr+2, state);
  667.             state->is32BitOperands = tmp;
  668.             switch(index) {
  669.             case 0: opcode = "SGDT"; break;
  670.             case 1: opcode = "SIDT"; break;
  671.             case 2: opcode = "LGDT"; break;
  672.             case 3: opcode = "LIDT"; break;
  673.             case 4: opcode = "SMSW"; break;
  674.             case 6: opcode = "LMSW"; break;
  675.             }
  676.             opcode1(state, opcode, state->rm);
  677.             break;
  678.  
  679.     case 0x02:
  680.     case 0x03:  length = 2 + word_reg_mod(ptr+2, state);
  681.             if(ptr[1] == 0x02)
  682.             opcode = "LAR";
  683.             else
  684.             opcode = "LSL";
  685.             opcode2(state, opcode, state->reg, state->rm);
  686.             break;
  687.  
  688.     case 0x06:  length = 2;
  689.             opcode0(state, "CLTS");
  690.             break;
  691.  
  692.     case 0x08:  length = 2;
  693.             opcode0(state, "INVD");
  694.             break;
  695.  
  696.     case 0x09:  length = 2;
  697.             opcode0(state, "WBINVD");
  698.             break;
  699.  
  700.     case 0x20:
  701.     case 0x22:  length = 2 + word_reg_mod(ptr+2, state);
  702.             sprintf(state->reg, "CR%d", index);
  703.             if(ptr[1] == 0x20) {
  704.             op1 = state->rm;
  705.             op2 = state->reg;
  706.             } else {
  707.             op1 = state->reg;
  708.             op2 = state->rm;
  709.             }
  710.             opcode2(state, "MOV", op1, op2);
  711.             break;
  712.  
  713.     case 0x21:
  714.     case 0x23:  length = 2 + word_reg_mod(ptr+2, state);
  715.             sprintf(state->reg, "DR%d", index);
  716.             if(ptr[1] == 0x21) {
  717.             op1 = state->rm;
  718.             op2 = state->reg;
  719.             } else {
  720.             op1 = state->reg;
  721.             op2 = state->rm;
  722.             }
  723.             opcode2(state, "MOV", op1, op2);
  724.             break;
  725.  
  726.     case 0x24:
  727.     case 0x26:  length = 2 + word_reg_mod(ptr+2, state);
  728.             opcode = "MOV";
  729.             sprintf(state->reg, "TR%d", index);
  730.             if(ptr[1] == 0x24) {
  731.             op1 = state->rm;
  732.             op2 = state->reg;
  733.             } else {
  734.             op1 = state->reg;
  735.             op2 = state->rm;
  736.             }
  737.             opcode2(state, opcode, op1, op2);
  738.             break;
  739.  
  740.     case 0x80: case 0x81: case 0x82: case 0x83:
  741.     case 0x84: case 0x85: case 0x86: case 0x87:
  742.     case 0x88: case 0x89: case 0x8A: case 0x8B:
  743.     case 0x8C: case 0x8D: case 0x8E: case 0x8F:
  744.             switch(ptr[1] & 0x0f) {
  745.             case 0x00:  opcode = "JO";   break;
  746.             case 0x01:  opcode = "JNO";  break;
  747.             case 0x02:  opcode = "JB";   break;
  748.             case 0x03:  opcode = "JAE";  break;
  749.             case 0x04:  opcode = "JE";   break;
  750.             case 0x05:  opcode = "JNE";  break;
  751.             case 0x06:  opcode = "JBE";  break;
  752.             case 0x07:  opcode = "JA";;  break;
  753.             case 0x08:  opcode = "JS";   break;
  754.             case 0x09:  opcode = "JNS";  break;
  755.             case 0x0A:  opcode = "JP";   break;
  756.             case 0x0B:  opcode = "JNP";  break;
  757.             case 0x0C:  opcode = "JL";   break;
  758.             case 0x0D:  opcode = "JGE";  break;
  759.             case 0x0E:  opcode = "JLE";  break;
  760.             case 0x0F:  opcode = "JG";   break;
  761.             }
  762.             if(state->is32BitAddress) {
  763.             offset = ptr[2]     | ptr[3]<<8 |
  764.                  ptr[4]<<16 | ptr[5]<<24;
  765.             sprintf(state->reg, "$ + 0x%08x", offset);
  766.             length = 6;
  767.             } else {
  768.             offset = ptr[2] | ptr[3]<<8;
  769.             sprintf(state->reg, "$ + 0x%04x", offset);
  770.             length = 4;
  771.             }
  772.             opcode1(state, opcode, state->reg);
  773.             break;
  774.  
  775.     case 0x90: case 0x91: case 0x92: case 0x93:
  776.     case 0x94: case 0x95: case 0x96: case 0x97:
  777.     case 0x98: case 0x99: case 0x9A: case 0x9B:
  778.     case 0x9C: case 0x9D: case 0x9E: case 0x9F:
  779.             switch(ptr[1]) {
  780.             case 0x90:  opcode = "SETO";   break;
  781.             case 0x91:  opcode = "SETNO";  break;
  782.             case 0x92:  opcode = "SETB";   break;
  783.             case 0x93:  opcode = "SETAE";  break;
  784.             case 0x94:  opcode = "SETE";   break;
  785.             case 0x95:  opcode = "SETNE";  break;
  786.             case 0x96:  opcode = "SETBE";  break;
  787.             case 0x97:  opcode = "SETA";   break;
  788.             case 0x98:  opcode = "SETS";   break;
  789.             case 0x99:  opcode = "SETNS";  break;
  790.             case 0x9A:  opcode = "SETP";   break;
  791.             case 0x9B:  opcode = "SETNP";  break;
  792.             case 0x9C:  opcode = "SETL";   break;
  793.             case 0x9D:  opcode = "SETGE";  break;
  794.             case 0x9E:  opcode = "SETLE";  break;
  795.             case 0x9F:  opcode = "SETG";   break;
  796.             }
  797.             length = 2 + byte_reg_mod(ptr+2, state);
  798.             opcode1(state, opcode, state->rm);
  799.             break;
  800.  
  801.     case 0xA0: case 0xA1: case 0xA8: case 0xA9:
  802.             if(ptr[1] & 0x01)
  803.             opcode = "POP";
  804.             else
  805.             opcode = "PUSH";
  806.             if(ptr[1] & 0x08)
  807.             op1 = "GS";
  808.             else
  809.             op1 = "FS";
  810.             opcode1(state, opcode, op1);
  811.             length = 2;
  812.             break;
  813.  
  814.     case 0xA3:  // BT
  815.     case 0xAB:  // BTS
  816.     case 0xB3:  // BTR
  817.     case 0xBB:  // BTC
  818.             switch((ptr[1] & 0x38) >> 3) {
  819.             case 0x04:  opcode = "BT"; break;
  820.             case 0x05:  opcode = "BTS"; break;
  821.             case 0x06:  opcode = "BTR"; break;
  822.             case 0x07:  opcode = "BTC"; break;
  823.             }
  824.             length = 2 + reg_mod(1, ptr+2, state);
  825.             opcode2(state, opcode, state->rm, state->reg);
  826.             break;
  827.  
  828.     case 0xA4:  // SHLD    Ed, reg32, data8
  829.     case 0xAC:  // SHRD    Ed, reg32, data8
  830.             length = 2 + reg_mod(1, ptr+2, state);
  831.             if(ptr[1] == 0xA4)
  832.             opcode = "SHLD";
  833.             else
  834.             opcode = "SHRD";
  835.             sprintf(state->temp, "%d", ptr[length]);
  836.             length++;
  837.             opcode3(state, opcode, state->rm, state->reg, state->temp);
  838.             break;
  839.  
  840.  
  841.     case 0xA5:  // SHLD    Ed, reg32, CL
  842.     case 0xAD:  // SHRD    Ed, reg32, CL
  843.             length = 2 + reg_mod(1, ptr+2, state);
  844.             if(ptr[1] == 0xA5)
  845.             opcode = "SHLD";
  846.             else
  847.             opcode = "SHRD";
  848.             opcode3(state, opcode, state->rm, state->reg, "CL");
  849.             break;
  850.  
  851.     case 0xAF:  // IMUL    reg32, Ed
  852.             length = 2 + reg_mod(1, ptr+2, state);
  853.             opcode2(state, "IMUL", state->reg, state->rm);
  854.             break;
  855.  
  856.     case 0xB0:  // CMPXCHG
  857.     case 0xB1:  length = 2 + reg_mod(ptr[1] & 0x01, ptr+2, state);
  858.             opcode2(state, "CMPXCHG", state->rm, state->reg);
  859.             break;
  860.  
  861.     case 0xB2:  // LSS  reg32, Ea
  862.     case 0xB4:  // LFS  reg32, Ea
  863.     case 0xB5:  // LGS  reg32, Ea
  864.             length = 2 + reg_mod(1, ptr+2, state);
  865.             switch(ptr[1]) {
  866.             case 0xB2: opcode = "LSS"; break;
  867.             case 0xB4: opcode = "LFS"; break;
  868.             case 0xB5: opcode = "LGS"; break;
  869.             }
  870.             opcode2(state, opcode, state->reg, state->rm);
  871.             break;
  872.  
  873.     case 0xBA:  /* BT, BTS, BTR, BTC */
  874.             switch(index) {
  875.             case 0x04:  opcode = "BT"; break;
  876.             case 0x05:  opcode = "BTS"; break;
  877.             case 0x06:  opcode = "BTR"; break;
  878.             case 0x07:  opcode = "BTC"; break;
  879.             }
  880.             length = 2 + reg_mod(1, ptr+2, state);
  881.             sprintf(state->reg, "%d", ptr[length]);
  882.             length++;
  883.             opcode2(state, opcode, state->rm, state->reg);
  884.             break;
  885.  
  886.     case 0xB6:  // MOVZX
  887.     case 0xB7:  // MOVZX
  888.     case 0xBE:  // MOVSX
  889.     case 0xBF:  // MOVSX
  890.             if((ptr[1] == 0xB6) || (ptr[1] == 0xB7))
  891.             opcode = "MOVZX";
  892.             else
  893.             opcode = "MOVSX";
  894.             length = 2 + reg_mod(1, ptr+2, state);
  895.             strcpy(state->temp, state->reg);
  896.             if(ptr[1] & 0x01) {
  897.             tmp = state->is32BitOperands;
  898.             state->is32BitOperands = 0;
  899.             reg_mod(1, ptr+2, state);
  900.             state->is32BitOperands = tmp;
  901.             } else {
  902.             reg_mod(0, ptr+2, state);
  903.             }
  904.             opcode2(state, opcode, state->temp, state->rm);
  905.             break;
  906.  
  907.     case 0xBC:  // BSF
  908.     case 0xBD:  // BSR
  909.             if(ptr[1] == 0xBC)
  910.             opcode = "BSF";
  911.             else
  912.             opcode = "BSR";
  913.             length = 2 + reg_mod(1, ptr+2, state);
  914.             opcode2(state, opcode, state->reg, state->rm);
  915.             break;
  916.  
  917.     case 0xC0:
  918.     case 0xC1:  length = 2 + reg_mod(ptr[1] & 0x01, ptr+2, state);
  919.             opcode2(state, "XADD", state->rm, state->reg);
  920.             break;
  921.  
  922.     case 0xC8: case 0xC9: case 0xCA: case 0xCB:
  923.     case 0xCC: case 0xCD: case 0xCE: case 0xCF:
  924.             opcode1(state, "BSWAP", dword_reg[ptr[1] & 0x07]);
  925.             length = 2;
  926.             break;
  927.     }
  928.     return length;
  929. }
  930.  
  931. static int type40(UCHAR *ptr, DumpState *state)
  932. {
  933. char   *opcode;
  934. UCHAR    operation, reg;
  935.  
  936.     operation = (UCHAR) (((*ptr) >> 3) & 3);
  937.     reg = (UCHAR) ((*ptr) & 0x07);
  938.     switch(operation)    {
  939.     case 0x00:  { opcode = "INC";  break; }
  940.     case 0x01:  { opcode = "DEC";  break; }
  941.     case 0x02:  { opcode = "PUSH"; break; }
  942.     case 0x03:  { opcode = "POP";  break; }
  943.     }
  944.     if(state->is32BitOperands)
  945.     opcode1(state, opcode, dword_reg[reg]);
  946.     else
  947.     opcode1(state, opcode, word_reg[reg]);
  948.     return 1;
  949. }
  950.  
  951. static int type60(UCHAR *ptr, DumpState *state)
  952. {
  953. int    length;
  954. int    t;
  955. ULONG  *pLong;
  956. USHORT *pShort;
  957.  
  958.     switch(ptr[0] & 0x0f) {
  959.     case 0x00:  opcode0(state, "PUSHAD"); length = 1; break;
  960.     case 0x01:  opcode0(state, "POPAD");  length = 1; break;
  961.     case 0x02:  length = 1 + reg_mod(1, ptr+1, state);
  962.             opcode2(state, "BOUND", state->reg, state->rm);
  963.             break;
  964.     case 0x03:  t = state->is32BitOperands;
  965.             state->is32BitOperands = 0;
  966.             length = 1 + reg_mod(1, ptr+1, state);
  967.             state->is32BitOperands = t;
  968.             opcode2(state, "ARPL", state->rm, state->reg);
  969.             break;
  970.     case 0x04:  opcode1(state, "SEG", "FS"); length = 1; break;
  971.     case 0x05:  opcode1(state, "SEG", "GS"); length = 1; break;
  972.     case 0x06:  state->is32BitOperands = ! state->is32BitOperands;
  973.             opcode0(state, "'OPSIZE'");
  974.             state->ptr_offset++;
  975.             DispatchByte(ptr+1, state);
  976.             length = 1;
  977.             state->ptr_offset--;
  978.             state->is32BitOperands = ! state->is32BitOperands;
  979.             break;
  980.     case 0x07:  state->is32BitAddress = ! state->is32BitAddress;
  981.             opcode0(state, "'ADDR'");
  982.             state->ptr_offset++;
  983.             length = 1 + DispatchByte(ptr+1, state);
  984.             state->ptr_offset--;
  985.             state->is32BitAddress = ! state->is32BitAddress;
  986.             break;
  987.     case 0x08:  if(state->is32BitOperands) {
  988.             length = 5;
  989.             pLong = (ULONG *) &ptr[1];
  990.             sprintf(state->temp, "0x%08x", *pLong);
  991.             opcode1(state, "PUSHD", state->temp);
  992.             } else {
  993.             length = 3;
  994.             pShort = (USHORT *) &ptr[1];
  995.             sprintf(state->temp, "0x%04x", *pShort);
  996.             opcode1(state, "PUSHW", state->temp);
  997.             }
  998.             break;
  999.     case 0x09:
  1000.     case 0x0B:  length = 1 + reg_mod(ptr[0] & 0x02, ptr+1, state);
  1001.             if(state->is32BitOperands) {
  1002.             pLong = (ULONG *) &ptr[length];
  1003.             sprintf(state->temp, "0x%08x", *pLong);
  1004.             length += 4;
  1005.             } else {
  1006.             pShort = (USHORT *) &ptr[length];
  1007.             sprintf(state->temp, "0x%04x", *pShort);
  1008.             length += 2;
  1009.             }
  1010.             opcode3(state, "IMUL", state->reg, state->rm, state->temp);
  1011.             break;
  1012.     case 0x0A:  length = 2;
  1013.             sprintf(state->temp, "0x%02x", (char) ptr[1]);
  1014.             opcode1(state, "PUSH", state->temp);
  1015.             break;
  1016.     case 0x0C:  opcode0(state, "INSB"); length = 1; break;
  1017.     case 0x0D:  if(state->is32BitOperands)
  1018.             opcode0(state, "INSD");
  1019.             else
  1020.             opcode0(state, "INSW");
  1021.             length = 1;
  1022.             break;
  1023.     case 0x0E:  opcode0(state, "OUTSB"); length = 1; break;
  1024.     case 0x0F:  if(state->is32BitOperands)
  1025.             opcode0(state, "OUTSD");
  1026.             else
  1027.             opcode0(state, "OUTSW");
  1028.             length = 1;
  1029.             break;
  1030.  
  1031.     }
  1032.     return length;
  1033. }
  1034.  
  1035. static int type70(UCHAR *ptr, DumpState *state)
  1036. {
  1037. char   *opcode;
  1038.  
  1039.     sprintf(state->temp,"$ 0x%02x", (int) ((char) ptr[1]));
  1040.     switch(ptr[0] & 0x0f) {
  1041.     case 0x00:  opcode = "JO";   break;
  1042.     case 0x01:  opcode = "JNO";  break;
  1043.     case 0x02:  opcode = "JB";   break;
  1044.     case 0x03:  opcode = "JAE";  break;
  1045.     case 0x04:  opcode = "JE";   break;
  1046.     case 0x05:  opcode = "JNE";  break;
  1047.     case 0x06:  opcode = "JBE";  break;
  1048.     case 0x07:  opcode = "JA";;  break;
  1049.     case 0x08:  opcode = "JS";   break;
  1050.     case 0x09:  opcode = "JNS";  break;
  1051.     case 0x0A:  opcode = "JP";   break;
  1052.     case 0x0B:  opcode = "JNP";  break;
  1053.     case 0x0C:  opcode = "JL";   break;
  1054.     case 0x0D:  opcode = "JGE";  break;
  1055.     case 0x0E:  opcode = "JLE";  break;
  1056.     case 0x0F:  opcode = "JG";   break;
  1057.     }
  1058.     opcode1(state, opcode, state->temp);
  1059.     return 2;
  1060. }
  1061.  
  1062. static int type80(UCHAR *ptr, DumpState *state)
  1063. {
  1064. int length,
  1065.     imm_dat,
  1066.     operation,
  1067.     size;
  1068.  
  1069. char   *opcode;
  1070. char   *op1;
  1071. char   *op2;
  1072. unsigned int byte;
  1073.  
  1074.     operation = *ptr & 0x0f;
  1075.     byte = (operation & 1) == 0;
  1076.     switch(operation)   {
  1077.         case 0x00:
  1078.         case 0x01:
  1079.         case 0x02:
  1080.     case 0x03:  operation = (ptr[1] & 0x38) >> 3;
  1081.             switch(operation)    {
  1082.             case 0x00:  opcode = "ADD";  break;
  1083.             case 0x01:  opcode = "OR ";  break;
  1084.             case 0x02:  opcode = "ADC";  break;
  1085.             case 0x03:  opcode = "SBB";  break;
  1086.             case 0x04:  opcode = "AND";  break;
  1087.             case 0x05:  opcode = "SUB";  break;
  1088.             case 0x06:  opcode = "XOR";  break;
  1089.             case 0x07:  opcode = "CMP";  break;
  1090.             }
  1091.             length = 1 + reg_mod(ptr[0] & 0x01, ptr+1, state);
  1092.             if(ptr[0] & 0x02)
  1093.             imm_dat = get_immediate(ptr+length, &size, 1, 0);
  1094.             else
  1095.             imm_dat = get_immediate(ptr+length, &size,
  1096.                    !(ptr[0] & 0x01), state->is32BitOperands);
  1097.             length += size;
  1098.             sprintf(state->temp, "0x%08x", imm_dat);
  1099.             opcode2(state, opcode, state->rm, state->temp);
  1100.             break;
  1101.         case 0x04:
  1102.     case 0x05:  opcode = "TEST";
  1103.             length = 1 + reg_mod(ptr[0]&0x01, ptr+1, state);
  1104.             opcode2(state, opcode, state->rm, state->reg);
  1105.             break;
  1106.         case 0x06:
  1107.     case 0x07:  opcode = "XCHG";
  1108.             length = 1 + reg_mod(ptr[0]&0x01, ptr+1, state);
  1109.             opcode2(state, opcode, state->reg, state->rm);
  1110.             break;
  1111.         case 0x08:
  1112.         case 0x09:
  1113.         case 0x0A:
  1114.     case 0x0B:  opcode = "MOV";
  1115.             length = 1 + reg_mod(ptr[0]&0x01, ptr+1, state);
  1116.             if((ptr[0] & 0x02) == 0)    {
  1117.             op1 = state->rm;
  1118.             op2 = state->reg;
  1119.             } else {
  1120.             op1 = state->reg;
  1121.             op2 = state->rm;
  1122.             }
  1123.             opcode2(state, opcode, op1, op2);
  1124.             break;
  1125.         case 0x0C:
  1126.     case 0x0E:  opcode = "MOV";
  1127.             length = 1 + word_reg_mod(ptr+1, state);
  1128.             if((ptr[0] & 0x02) == 0)    {
  1129.             op1 = state->rm;
  1130.             op2 = seg_reg[(ptr[1] & 0x18) >> 3];
  1131.             } else {
  1132.             op1 = seg_reg[(ptr[1] & 0x18) >> 3];
  1133.             op2 = state->rm;
  1134.             }
  1135.             opcode2(state, opcode, op1, op2);
  1136.             break;
  1137.     case 0x0D:  opcode = "LEA";
  1138.             length = 1 + word_reg_mod(ptr+1, state);
  1139.             opcode2(state, opcode, state->reg, state->rm);
  1140.             break;
  1141.     case 0x0F:  opcode = "POP";
  1142.             length = 1 + word_reg_mod(ptr+1, state);
  1143.             opcode1(state, opcode, state->rm);
  1144.             break;
  1145.     }
  1146.     return length;
  1147. }
  1148.  
  1149. static int type90(UCHAR *ptr, DumpState *state)
  1150. {
  1151. int    length = 1;
  1152. ULONG  *pLong;
  1153. USHORT *pShort;
  1154. ULONG    addr;
  1155.  
  1156.     switch(ptr[0] & 0x0f) {
  1157.     case 0x00:  opcode0(state, "NOP"); length = 1; break;
  1158.     case 0x01:
  1159.     case 0x02:
  1160.     case 0x03:
  1161.     case 0x04:
  1162.     case 0x05:
  1163.     case 0x06:
  1164.     case 0x07:  if(state->is32BitOperands)
  1165.             opcode2(state, "XCHG", "EAX", dword_reg[ptr[0] & 0x07]);
  1166.             else
  1167.             opcode2(state, "XCHG",    "AX",  word_reg[ptr[0] & 0x07]);
  1168.             break;
  1169.     case 0x08:  opcode0(state, state->is32BitOperands ? "CBDE" : "CBW"); break;
  1170.     case 0x09:  opcode0(state, state->is32BitOperands ? "CDQ" : "CWD");  break;
  1171.     case 0x0A:  if(state->is32BitAddress) {
  1172.             length = 7;
  1173.             pLong = (ULONG *) &ptr[1];
  1174.             pShort = (USHORT *) &ptr[5];
  1175.             addr = *pLong;
  1176.             sprintf(state->temp, "%04x:%08x", *pShort, *pLong);
  1177.             } else {
  1178.             length = 5;
  1179.             pShort = (USHORT *) &ptr[1];
  1180.             addr = *pShort;
  1181.             sprintf(state->temp, "%04:%04x", pShort[0], pShort[1]);
  1182.             }
  1183.             addr = addr + state->addr + state->ptr_offset + length;
  1184.             opcode1(state, "CALL", state->temp);
  1185.             break;
  1186.     case 0x0B:  opcode0(state, "WAIT"); break;
  1187.     case 0x0C:  opcode0(state, state->is32BitOperands ? "PUSHFD" : "PUSHF"); break;
  1188.     case 0x0D:  opcode0(state, state->is32BitOperands ? "POPFD"  : "POPF");  break;
  1189.     case 0x0E:  opcode0(state, "SAHF"); break;
  1190.     case 0x0F:  opcode0(state, "LAHF"); break;
  1191.     }
  1192.     return length;
  1193. }
  1194.  
  1195. static int typeA0(UCHAR *ptr, DumpState *state)
  1196. {
  1197. int    length;
  1198. char   *op1, *op2;
  1199. ULONG  *pLong;
  1200. USHORT *pShort;
  1201.  
  1202.     switch(ptr[0] & 0x0f) {
  1203.     case 0x00:
  1204.     case 0x01:
  1205.     case 0x02:
  1206.     case 0x03:
  1207.             if(state->is32BitAddress) {
  1208.             pLong = (ULONG *) &ptr[1];
  1209.             sprintf(state->temp, "[0x%08x]", *pLong);
  1210.             length = 5;
  1211.             } else {
  1212.             pShort = (USHORT *) &ptr[1];
  1213.             sprintf(state->temp, "[0x%04x]", *pShort);
  1214.             length = 3;
  1215.             }
  1216.             switch(ptr[0] & 0x03) {
  1217.             case 0: op1 = "AL";
  1218.                 op2 = state->temp;
  1219.                 break;
  1220.             case 1: op1 = state->is32BitOperands ? "EAX" : "AX";
  1221.                 op2 = state->temp;
  1222.                 break;
  1223.             case 2: op2 = "AL";
  1224.                 op1 = state->temp;
  1225.                 break;
  1226.             case 3: op2 = state->is32BitOperands ? "EAX" : "AX";
  1227.                 op1 = state->temp;
  1228.                 break;
  1229.             }
  1230.             opcode2(state, "MOV", op1, op2);
  1231.             break;
  1232.     case 0x04:  opcode0(state, "MOVSB"); length = 1; break;
  1233.     case 0x05:  opcode0(state, state->is32BitOperands ? "MOVSD" : "MOVSW"); length = 1; break;
  1234.     case 0x06:  opcode0(state, "CMPSB"); length = 1; break;
  1235.     case 0x07:  opcode0(state, state->is32BitOperands ? "CMPSD" : "CMPSW"); length = 1; break;
  1236.     case 0x08:  length = 2;
  1237.             sprintf(state->temp, "0x%02x", ptr[1]);
  1238.             opcode2(state, "TEST", "AL", state->temp);
  1239.             break;
  1240.     case 0x09:  if(state->is32BitOperands) {
  1241.             length = 5;
  1242.             pLong = (ULONG *) &ptr[1];
  1243.             sprintf(state->temp, "0x%08x", *pLong);
  1244.             opcode2(state, "TEST", "EAX", state->temp);
  1245.             } else {
  1246.             length = 3;
  1247.             pShort = (USHORT *) &ptr[1];
  1248.             sprintf(state->temp, "0x%04x", *pShort);
  1249.             opcode2(state, "TEST", "AX", state->temp);
  1250.             }
  1251.             break;
  1252.     case 0x0A:  opcode0(state, "STOSB"); length = 1; break;
  1253.     case 0x0B:  opcode0(state, state->is32BitOperands ? "STOSD" : "STOSW"); length = 1; break;
  1254.     case 0x0C:  opcode0(state, "LODSB"); length = 1; break;
  1255.     case 0x0D:  opcode0(state, state->is32BitOperands ? "LODSD" : "LODSW"); length = 1; break;
  1256.     case 0x0E:  opcode0(state, "SCASB"); length = 1; break;
  1257.     case 0x0F:  opcode0(state, state->is32BitOperands ? "SCASD" : "SCASW"); length = 1; break;
  1258.     }
  1259.     return length;
  1260. }
  1261.  
  1262. static int typeB0(UCHAR *ptr, DumpState *state)
  1263. {
  1264. ULONG  *pLong;
  1265. USHORT *pShort;
  1266.  
  1267.     if(ptr[0] & 0x08) {
  1268.     if(state->is32BitOperands) {
  1269.         pLong = (ULONG *) &ptr[1];
  1270.         sprintf(state->temp, "0x%08x", *pLong);
  1271.         opcode2(state, "MOV", dword_reg[ptr[0] & 0x07], state->temp);
  1272.         return 5;
  1273.     }
  1274.     pShort = (USHORT *) &ptr[1];
  1275.     sprintf(state->temp, "0x%04x", *pShort);
  1276.     opcode2(state, "MOV", word_reg[ptr[0] & 0x07], state->temp);
  1277.     return 3;
  1278.     }
  1279.     sprintf(state->temp, "0x%02x", ptr[1]);
  1280.     opcode2(state, "MOV", byte_reg[ptr[0] & 0x07], state->temp);
  1281.     return 2;
  1282. }
  1283.  
  1284. static int typeC0(UCHAR *ptr, DumpState *state)
  1285. {
  1286. char   *opcode;
  1287. USHORT *pShort;
  1288. ULONG  *pLong;
  1289. int    length = 1;
  1290.  
  1291.     switch(ptr[0] & 0x0f) {
  1292.     case 0x03: case 0x0B:
  1293.             opcode0(state, ptr[0] & 0x08 ? "RETF" : "RET"); break;
  1294.     case 0x02: case 0x0A:
  1295.             pShort = (USHORT *) &ptr[1];
  1296.             sprintf(state->temp, "0x%04x", *pShort);
  1297.             opcode1(state, "RET", state->temp);
  1298.             length = 3;
  1299.             break;
  1300.     case 0x04: case 0x05:
  1301.             opcode = ((ptr[0] & 0x01) == 0) ? "LES" : "LDS";
  1302.             length = 1 + word_reg_mod(ptr+1, state);
  1303.             opcode2(state, opcode, state->reg, state->rm);
  1304.             break;
  1305.     case 0x06: case 0x07:
  1306.             length = 1 + reg_mod(ptr[0] & 1, ptr+1, state);
  1307.             if(ptr[0] & 0x01) {
  1308.             if(state->is32BitOperands) {
  1309.                 pLong = (ULONG *) &ptr[length];
  1310.                 sprintf(state->temp, "0x%08x", *pLong);
  1311.                 length = 5;
  1312.             } else {
  1313.                 pShort = (USHORT *) &ptr[length];
  1314.                 sprintf(state->temp, "0x%04x", *pShort);
  1315.                 length = 3;
  1316.             }
  1317.             } else {
  1318.             sprintf(state->temp, "0x%02x", ptr[length]);
  1319.             length = 2;
  1320.             }
  1321.             opcode2(state, "MOV", state->rm, state->temp);
  1322.             break;
  1323.     case 0x08:  opcode = "ENTER";
  1324.             sprintf(state->reg, "0x%04x", ptr[length] | ptr[length+1] << 8);
  1325.             sprintf(state->rm,    "0x%02x", ptr[length+2]);
  1326.             length += 3;
  1327.             opcode2(state, opcode, state->reg, state->rm);
  1328.             break;
  1329.     case 0x09:  opcode = "LEAVE";
  1330.             opcode0(state, opcode);
  1331.             length = 1;
  1332.             break;
  1333.     case 0x0C:  opcode = "INT";
  1334.             opcode1(state, opcode, "3");
  1335.             length = 1;
  1336.             break;
  1337.     case 0x0D:  sprintf(state->temp, "0x%02x", ptr[1]);
  1338.             opcode1(state, "INT", state->temp);
  1339.             length = 2;
  1340.             break;
  1341.     case 0x0E:  opcode0(state, "INTO");
  1342.             length = 1;
  1343.             break;
  1344.     case 0x0F:  opcode0(state, "IRET");
  1345.             length = 1;
  1346.             break;
  1347.     case 0x00:
  1348.     case 0x01:  length = 1 + reg_mod(ptr[0] & 1, ptr+1, state);
  1349.             switch(ptr[1] >> 3 & 0x07) {
  1350.             case 0: opcode = "ROL"; break;
  1351.             case 1: opcode = "ROR"; break;
  1352.             case 2: opcode = "RCL"; break;
  1353.             case 3: opcode = "RCR"; break;
  1354.             case 4: opcode = "SHL"; break;
  1355.             case 5: opcode = "SHR"; break;
  1356.             case 6: opcode = "???"; break;
  1357.             case 7: opcode = "SAR"; break;
  1358.             }
  1359.             sprintf(state->temp, "%d", ptr[length]);
  1360.             length++;
  1361.             opcode2(state, opcode, state->rm, state->temp);
  1362.             break;
  1363.     }
  1364.     return length;
  1365. }
  1366.  
  1367. static int typeD0(UCHAR *ptr, DumpState *state)
  1368. {
  1369. int    length = 1;
  1370. char   *opcode;
  1371.  
  1372.     switch(ptr[0] & 0x0f) {
  1373.     case 0x00:
  1374.     case 0x01:  length = 1 + reg_mod(ptr[0] & 1, ptr+1, state);
  1375.             switch(ptr[1] >> 3 & 0x07) {
  1376.             case 0: opcode = "ROL"; break;
  1377.             case 1: opcode = "ROR"; break;
  1378.             case 2: opcode = "RCL"; break;
  1379.             case 3: opcode = "RCR"; break;
  1380.             case 4: opcode = "SHL"; break;
  1381.             case 5: opcode = "SHR"; break;
  1382.             case 6: opcode = "???"; break;
  1383.             case 7: opcode = "SAR"; break;
  1384.             }
  1385.             opcode2(state, opcode, state->rm, "1");
  1386.             break;
  1387.     case 0x02:
  1388.     case 0x03:  length = 1 + reg_mod(ptr[0] & 1, ptr+1, state);
  1389.             switch(ptr[1] >> 3 & 0x07) {
  1390.             case 0: opcode = "ROL"; break;
  1391.             case 1: opcode = "ROR"; break;
  1392.             case 2: opcode = "RCL"; break;
  1393.             case 3: opcode = "RCR"; break;
  1394.             case 4: opcode = "SHL"; break;
  1395.             case 5: opcode = "SHR"; break;
  1396.             case 6: opcode = "???"; break;
  1397.             case 7: opcode = "SAR"; break;
  1398.             }
  1399.             opcode2(state, opcode, state->rm, "CL");
  1400.             break;
  1401.     case 0x04:  if(ptr[1] == 0x0A) {
  1402.             opcode0(state, "AAM");
  1403.             length = 2;
  1404.             } else {
  1405.             opcode0(state, "???");
  1406.             }
  1407.             break;
  1408.     case 0x05:  if(ptr[1] == 0x0A) {
  1409.             opcode0(state, "AAD");
  1410.             length = 2;
  1411.             } else {
  1412.             opcode0(state, "???");
  1413.             }
  1414.             break;
  1415.     case 0x06:  opcode0(state, "???"); break;
  1416.     case 0x07:  opcode0(state, "XLAT"); break;
  1417.     case 0x08: case 0x09: case 0x0A: case 0x0B:
  1418.     case 0x0C: case 0x0D: case 0x0E: case 0x0F:
  1419.             length = coprosseser(ptr, state);
  1420.     }
  1421.     return length;
  1422. }
  1423.  
  1424. static int typeE0(UCHAR *ptr, DumpState *state)
  1425. {
  1426. int    length;
  1427. USHORT *pShort;
  1428. ULONG  *pLong;
  1429. char   *opcode;
  1430. char   *op1;
  1431. ULONG    addr;
  1432.  
  1433.     switch(ptr[0] & 0x0f) {
  1434.     case 0x00: case 0x01: case 0x02: case 0x03:
  1435.             switch(ptr[0] & 0x0f) {
  1436.             case 0: opcode = "LOOPNE"; break;
  1437.             case 1: opcode = "LOOPE";  break;
  1438.             case 2: opcode = "LOOP";   break;
  1439.             case 3: opcode = state->is32BitAddress ? "JECXZ" : "JCXZ";   break;
  1440.             }
  1441.             pShort = (USHORT *) &ptr[1];
  1442.             sprintf(state->temp, "$ 0x%02x", *pShort);
  1443.             length = 2;
  1444.             opcode1(state, opcode, state->temp);
  1445.             break;
  1446.         case 0x04:
  1447.     case 0x05:  length = 2;
  1448.             sprintf(state->temp, "0x%02x", ptr[1]);
  1449.             op1 = ((ptr[0] & 0x01) == 0) ? "AL" :
  1450.                             (state->is32BitOperands ? "EAX" : "AX");
  1451.             opcode2(state, "IN", op1, state->temp);
  1452.             break;
  1453.         case 0x06:
  1454.     case 0x07:  length = 2;
  1455.             sprintf(state->temp, "0x%02x", ptr[1]);
  1456.             op1 = ((ptr[0] & 0x01) == 0) ? "AL" :
  1457.                             (state->is32BitOperands ? "EAX" : "AX");
  1458.             opcode2(state, "OUT", state->temp, op1);
  1459.             break;
  1460.     case 0x08:  if(state->is32BitAddress) {
  1461.             length = 5;
  1462.             pLong = (ULONG *) &ptr[1];
  1463.             addr = *pLong;
  1464.             } else {
  1465.             length = 3;
  1466.             pShort = (USHORT *) &ptr[1];
  1467.             addr = *pShort;
  1468.             }
  1469.             addr = addr + state->addr + state->ptr_offset + length;
  1470.             sprintf(state->temp, "$ 0x%08x", addr);
  1471.             opcode1(state, "CALL", state->temp);
  1472.             break;
  1473.     case 0x09:  if(state->is32BitAddress) {
  1474.             length = 5;
  1475.             pLong = (ULONG *) &ptr[1];
  1476.             addr = *pLong;
  1477.             } else {
  1478.             length = 3;
  1479.             pShort = (USHORT *) &ptr[1];
  1480.             addr = *pShort;
  1481.             }
  1482.             addr = addr + state->addr + state->ptr_offset + length;
  1483.             sprintf(state->temp, "0x%08x", addr);
  1484.             opcode1(state, "JMP", state->temp);
  1485.             break;
  1486.     case 0x0A:  if(state->is32BitAddress) {
  1487.             pLong  = (ULONG  *) &ptr[1];
  1488.             pShort = (USHORT *) &ptr[3];
  1489.             sprintf(state->temp, "%04x:%08x", *pShort, *pLong);
  1490.             length = 7;
  1491.             } else {
  1492.             pShort = (USHORT *) &ptr[1];
  1493.             sprintf(state->temp, "%04x:%04x", pShort[0], pShort[1]);
  1494.             length = 5;
  1495.             }
  1496.             opcode1(state, "JMP", state->temp);
  1497.             break;
  1498.     case 0x0B:  sprintf(state->temp,"SHORT $ 0x%02x", ptr[1]);
  1499.             opcode1(state, "JMP", state->temp);
  1500.             length = 2;
  1501.             break;
  1502.         case 0x0C:
  1503.     case 0x0D:  op1 = ((ptr[0] & 0x0f) == 0x0C) ? "AL" :
  1504.                         (state->is32BitOperands ? "EAX" : "AX");
  1505.             opcode2(state, "IN", op1, "DX");
  1506.             length = 1;
  1507.             break;
  1508.         case 0x0E:
  1509.     case 0x0F:  op1 = ((ptr[0] & 0x0f) == 0x0E) ? "AL" :
  1510.                         (state->is32BitOperands ? "EAX" : "AX");
  1511.             opcode2(state, "OUT", "DX", op1);
  1512.             length = 1;
  1513.             break;
  1514.     }
  1515.     return length;
  1516. }
  1517.  
  1518. static int typeF0(UCHAR *ptr, DumpState *state)
  1519. {
  1520. int    length = 1;
  1521. int    operation;
  1522. char   *opcode;
  1523. USHORT *pShort;
  1524. ULONG  *pLong;
  1525.  
  1526.     switch(ptr[0] & 0x0f) {
  1527.     case 0x00:  opcode0(state, "LOCK"); break;
  1528.     case 0x01:  opcode0(state, "???");  break;
  1529.     case 0x02:  opcode0(state, "REPNE");break;
  1530.     case 0x03:  opcode0(state, "REP");  break;
  1531.     case 0x04:  opcode0(state, "HLT");  break;
  1532.     case 0x05:  opcode0(state, "CMC");  break;
  1533.     case 0x08:  opcode0(state, "CLC");  break;
  1534.     case 0x09:  opcode0(state, "STC");  break;
  1535.     case 0x0A:  opcode0(state, "CLI");  break;
  1536.     case 0x0B:  opcode0(state, "STI");  break;
  1537.     case 0x0C:  opcode0(state, "CLD");  break;
  1538.     case 0x0D:  opcode0(state, "STD");  break;
  1539.     case 0x06:
  1540.     case 0x07:  length = 1 + reg_mod(ptr[0] & 0x01, ptr+1, state);
  1541.             switch((ptr[1] & 0x38) >> 3) {
  1542.             case 0x00: opcode = "TEST";
  1543.                    if((ptr[0] & 0x01) == 0) {
  1544.                     sprintf(state->temp, "0x%02x", ptr[length]);
  1545.                     length++;
  1546.                    } else {
  1547.                     if(state->is32BitOperands) {
  1548.                         pLong = (ULONG *) &ptr[length];
  1549.                         length += 4;
  1550.                         sprintf(state->temp, "0x%08x", *pLong);
  1551.                     } else {
  1552.                         pShort = (USHORT *) &ptr[length];
  1553.                         length += 2;
  1554.                         sprintf(state->temp, "0x%04x", *pShort);
  1555.                     }
  1556.                    }
  1557.                    opcode2(state, opcode, state->rm, state->temp);
  1558.                    return length;
  1559.  
  1560.             case 0x01: opcode = "???";  break;
  1561.             case 0x02: opcode = "NOT";  break;
  1562.             case 0x03: opcode = "NEG";  break;
  1563.             case 0x04: opcode = "MUL";  break;
  1564.             case 0x05: opcode = "IMUL"; break;
  1565.             case 0x06: opcode = "DIV";  break;
  1566.             case 0x07: opcode = "IDIV"; break;
  1567.             }
  1568.             opcode1(state, opcode, state->rm);
  1569.             break;
  1570.     case 0x0E:
  1571.     case 0x0F:
  1572.             length = 1 + reg_mod(ptr[0] & 0x01, ptr+1, state);
  1573.             operation = (ptr[1] & 0x38) >> 3;
  1574.             switch((ptr[1] & 0x38) >> 3)   {
  1575.                 case 0: opcode = "INC";  break;
  1576.                 case 1: opcode = "DEC";  break;
  1577.                 case 2: opcode = "CALL"; break;
  1578.                 case 3: opcode = "CALL"; break;
  1579.                 case 4: opcode = "JMP";  break;
  1580.                 case 5: opcode = "JMP";  break;
  1581.                 case 6: opcode = "PUSH"; break;
  1582.                 case 7: opcode = "???";  break;
  1583.             }
  1584.             opcode1(state, opcode, state->rm);
  1585.             break;
  1586.     }
  1587.     return length;
  1588. }
  1589.  
  1590. static int coprosseser(UCHAR *ptr, DumpState *state)
  1591. {
  1592.     switch(ptr[0]) {
  1593.     case 0xD8:  return cotypeD8(ptr, state);
  1594.     case 0xD9:  return cotypeD9(ptr, state);
  1595.     case 0xDA:  return cotypeDA(ptr, state);
  1596.     case 0xDB:  return cotypeDB(ptr, state);
  1597.     case 0xDC:  return cotypeDC(ptr, state);
  1598.     case 0xDD:  return cotypeDD(ptr, state);
  1599.     case 0xDE:  return cotypeDE(ptr, state);
  1600.     case 0xDF:  return cotypeDF(ptr, state);
  1601.     }
  1602. }
  1603.  
  1604. static int cotypeD8(UCHAR *ptr, DumpState *state)
  1605. {
  1606. int    length = 2;
  1607. char   *opcode;
  1608.  
  1609.     switch(ptr[1] & 0xf8) {
  1610.     case 0xc0:
  1611.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1612.         opcode2(state, "FADD", "ST", state->temp);
  1613.         return 2;
  1614.     case 0xc8:
  1615.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1616.         opcode2(state, "FMUL", "ST", state->temp);
  1617.         return 2;
  1618.     case 0xd0:
  1619.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1620.         opcode2(state, "FCOM", "(REAL 32)", state->temp);
  1621.         return 2;
  1622.     case 0xd8:
  1623.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1624.         opcode2(state, "FCOMP", "(REAL 32)", state->temp);
  1625.         return 2;
  1626.     case 0xe0:
  1627.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1628.         opcode2(state, "FSUB", "ST", state->temp);
  1629.         return 2;
  1630.     case 0xe8:
  1631.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1632.         opcode2(state, "FSUBR", "ST", state->temp);
  1633.         return 2;
  1634.     case 0xf0:
  1635.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1636.         opcode2(state, "FDIV", "ST", state->temp);
  1637.         return 2;
  1638.     case 0xf8:
  1639.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1640.         opcode2(state, "FDIVR", "ST", state->temp);
  1641.         return 2;
  1642.     }
  1643.     length = 1 + word_reg_mod(ptr+1, state);
  1644.     switch((ptr[1] & 0x38) >> 3) {
  1645.     case 0: opcode = "FADD";  break;
  1646.     case 1: opcode = "FMUL";  break;
  1647.     case 2: opcode = "FCOM";  break;
  1648.     case 3: opcode = "FCOMP"; break;
  1649.     case 4: opcode = "FSUB";  break;
  1650.     case 5: opcode = "FSUBR"; break;
  1651.     case 6: opcode = "FDIV";  break;
  1652.     case 7: opcode = "FDIVR"; break;
  1653.     }
  1654.     opcode2(state, opcode, "(REAL 32)", state->rm);
  1655.     return length;
  1656. }
  1657.  
  1658. static int cotypeD9(UCHAR *ptr, DumpState *state)
  1659. {
  1660. int    length = 2;
  1661. char   *opcode;
  1662.  
  1663.     switch(ptr[1]) {
  1664.     case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  1665.     case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  1666.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1667.         opcode1(state, "FLD", state->temp);
  1668.         return 2;
  1669.     case 0xc8: case 0xc9: case 0xca: case 0xcb:
  1670.     case 0xcc: case 0xcd: case 0xce: case 0xcf:
  1671.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1672.         opcode1(state, "FXCH", state->temp);
  1673.         return 2;
  1674.     case 0xd0:  opcode0(state, "FNOP");
  1675.             return 2;
  1676.     case 0xe0:  opcode0(state, "FCHS");
  1677.             return 2;
  1678.     case 0xe1:  opcode0(state, "FABS");
  1679.             return 2;
  1680.     case 0xe4:  opcode0(state, "FTST");
  1681.             return 2;
  1682.     case 0xe5:  opcode0(state, "FXAM");
  1683.             return 2;
  1684.     case 0xe8:  opcode0(state, "FLD1");
  1685.             return 2;
  1686.     case 0xe9:  opcode0(state, "FLDL2T");
  1687.             return 2;
  1688.     case 0xea:  opcode0(state, "FLDL2E");
  1689.             return 2;
  1690.     case 0xeb:  opcode0(state, "FLDPI");
  1691.             return 2;
  1692.     case 0xec:  opcode0(state, "FLDG2");
  1693.             return 2;
  1694.     case 0xed:  opcode0(state, "FLDN2");
  1695.             return 2;
  1696.     case 0xee:  opcode0(state, "FLDZ");
  1697.             return 2;
  1698.     case 0xf0:  opcode0(state, "F2XM1");
  1699.             return 2;
  1700.     case 0xf1:  opcode0(state, "FYL2X");
  1701.             return 2;
  1702.     case 0xf2:  opcode0(state, "FPTAN");
  1703.             return 2;
  1704.     case 0xf3:  opcode0(state, "FPATAN");
  1705.             return 2;
  1706.     case 0xf4:  opcode0(state, "FXTRACT");
  1707.             return 2;
  1708.     case 0xf5:  opcode0(state, "FPREM1");
  1709.             return 2;
  1710.     case 0xf6:  opcode0(state, "FDECSTP");
  1711.             return 2;
  1712.     case 0xf7:  opcode0(state, "FINCSTP");
  1713.             return 2;
  1714.     case 0xf8:  opcode0(state, "FPREM");
  1715.             return 2;
  1716.     case 0xf9:  opcode0(state, "FYL2XP1");
  1717.             return 2;
  1718.     case 0xfa:  opcode0(state, "FSQRT");
  1719.             return 2;
  1720.     case 0xfb:  opcode0(state, "FSINCOS");
  1721.             return 2;
  1722.     case 0xfc:  opcode0(state, "FRNDINT");
  1723.             return 2;
  1724.     case 0xfd:  opcode0(state, "FSCALE");
  1725.             return 2;
  1726.     case 0xfe:  opcode0(state, "FSIN");
  1727.             return 2;
  1728.     case 0xff:  opcode0(state, "FCOS");
  1729.             return 2;
  1730.  
  1731.     }
  1732.     length = 1 + word_reg_mod(ptr+1, state);
  1733.     switch((ptr[1] & 0x38) >> 3) {
  1734.     case 0: opcode = "FLD";    break;
  1735.     case 1: opcode = "???";    break;
  1736.     case 2: opcode = "FST";    break;
  1737.     case 3: opcode = "FSTP";   break;
  1738.     case 4: opcode = "FLDEVN"; break;
  1739.     case 5: opcode = "FLDCW";  break;
  1740.     case 6: opcode = "FSTENV"; break;
  1741.     case 7: opcode = "FSTCW";  break;
  1742.     }
  1743.     opcode2(state, opcode, "(REAL 32)", state->rm);
  1744.     return length;
  1745. }
  1746.  
  1747. static int cotypeDA(UCHAR *ptr, DumpState *state)
  1748. {
  1749. int    length = 2;
  1750. char   *opcode;
  1751.  
  1752.     if(ptr[1] == 0xe9) {
  1753.     opcode0(state, "FUCOMPP");
  1754.     return 2;
  1755.     }
  1756.  
  1757.     length = 1 + word_reg_mod(ptr+1, state);
  1758.     switch((ptr[1] & 0x38) >> 3) {
  1759.     case 0: opcode = "FIADD";  break;
  1760.     case 1: opcode = "FIMUL";  break;
  1761.     case 2: opcode = "FICOM";  break;
  1762.     case 3: opcode = "FICOMP"; break;
  1763.     case 4: opcode = "FISUB";  break;
  1764.     case 5: opcode = "FISUBR"; break;
  1765.     case 6: opcode = "FIDIV";  break;
  1766.     case 7: opcode = "FIDIVR"; break;
  1767.     }
  1768.     opcode2(state, opcode, "(INT 16)", state->rm);
  1769.     return length;
  1770. }
  1771.  
  1772. static int cotypeDB(UCHAR *ptr, DumpState *state)
  1773. {
  1774. int    length = 2;
  1775. char   *opSize;
  1776. char   *opcode;
  1777.  
  1778.     if(ptr[1] == 0xe0) {
  1779.     opcode0(state, "FENI");
  1780.     return 2;
  1781.     }
  1782.  
  1783.     if(ptr[1] == 0xe1) {
  1784.     opcode0(state, "FDISI");
  1785.     return 2;
  1786.     }
  1787.  
  1788.     if(ptr[1] == 0xe2) {
  1789.     opcode0(state, "FCLEX");
  1790.     return 2;
  1791.     }
  1792.  
  1793.     if(ptr[1] == 0xe3) {
  1794.     opcode0(state, "FINIT");
  1795.     return 2;
  1796.     }
  1797.  
  1798.     if(ptr[1] == 0xe4) {
  1799.     opcode0(state, "FSETPM");
  1800.     return 2;
  1801.     }
  1802.  
  1803.     length = 1 + word_reg_mod(ptr+1, state);
  1804.     switch((ptr[1] & 0x38) >> 3) {
  1805.     case 0: opcode = "FILD";  opSize = "(INT 16)";    break;
  1806.     case 1: opcode = "???";   opSize = ""; break;
  1807.     case 2: opcode = "FIST";  opSize = "(INT 16)";    break;
  1808.     case 3: opcode = "FISTP"; opSize = "(INT 16)";    break;
  1809.     case 4: opcode = "???";   opSize = ""; break;
  1810.     case 5: opcode = "FLD";   opSize = "(REAL 80)"; break;
  1811.     case 6: opcode = "FSTP";  opSize = "(REAL 80)"; break;
  1812.     case 7: opcode = "FSTP";  opSize = ""; break;
  1813.     }
  1814.     opcode2(state, opcode, opSize, state->rm);
  1815.     return length;
  1816. }
  1817.  
  1818. static int cotypeDC(UCHAR *ptr, DumpState *state)
  1819. {
  1820. int    length = 2;
  1821. char   *opcode;
  1822.  
  1823.     switch(ptr[1] & 0xf8) {
  1824.     case 0xc0:
  1825.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1826.         opcode2(state, "FADD", state->temp, "ST");
  1827.         return 2;
  1828.     case 0xc8:
  1829.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1830.         opcode2(state, "FMUL", state->temp, "ST");
  1831.         return 2;
  1832.     case 0xe0:
  1833.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1834.         opcode2(state, "FSUBR", state->temp, "ST");
  1835.         return 2;
  1836.     case 0xe8:
  1837.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1838.         opcode2(state, "FSUB", state->temp, "ST");
  1839.         return 2;
  1840.     case 0xf0:
  1841.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1842.         opcode2(state, "FDIVR", state->temp, "ST");
  1843.         return 2;
  1844.     case 0xf8:
  1845.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1846.         opcode2(state, "FDIV", state->temp, "ST");
  1847.         return 2;
  1848.     }
  1849.     length = 1 + word_reg_mod(ptr+1, state);
  1850.     switch((ptr[1] & 0x38) >> 3) {
  1851.     case 0: opcode = "FADD";  break;
  1852.     case 1: opcode = "FMUL";  break;
  1853.     case 2: opcode = "FCOM";  break;
  1854.     case 3: opcode = "FCOMP"; break;
  1855.     case 4: opcode = "FSUB";  break;
  1856.     case 5: opcode = "FSUBR"; break;
  1857.     case 6: opcode = "FDIV";  break;
  1858.     case 7: opcode = "FDIVR"; break;
  1859.     }
  1860.     opcode2(state, opcode, "(REAL 64)", state->rm);
  1861.     return length;
  1862. }
  1863.  
  1864. static int cotypeDD(UCHAR *ptr, DumpState *state)
  1865. {
  1866. int    length = 2;
  1867. char   *opcode;
  1868.  
  1869.     switch(ptr[1] & 0xf8) {
  1870.     case 0xc0:
  1871.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1872.         opcode1(state, "FFREE", state->temp);
  1873.         return 2;
  1874.     case 0xd0:
  1875.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1876.         opcode1(state, "FST", state->temp);
  1877.         return 2;
  1878.     case 0xd8:
  1879.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1880.         opcode1(state, "FSTP", state->temp);
  1881.         return 2;
  1882.     case 0xe0:
  1883.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1884.         opcode1(state, "FUCOM", state->temp);
  1885.         return 2;
  1886.     case 0xe8:
  1887.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1888.         opcode1(state, "FUCOMP", state->temp);
  1889.         return 2;
  1890.     }
  1891.     length = 1 + word_reg_mod(ptr+1, state);
  1892.     switch((ptr[1] & 0x38) >> 3) {
  1893.     case 0: opcode = "FLD";   break;
  1894.     case 1: opcode = "???";   break;
  1895.     case 2: opcode = "FST";   break;
  1896.     case 3: opcode = "FSTP";  break;
  1897.     case 4: opcode = "FRSTOR";break;
  1898.     case 5: opcode = "???";   break;
  1899.     case 6: opcode = "FSAVE"; break;
  1900.     case 7: opcode = "FSTSW"; break;
  1901.     }
  1902.     opcode2(state, opcode, "(REAL 64)", state->rm);
  1903.     return length;
  1904. }
  1905.  
  1906. static int cotypeDE(UCHAR *ptr, DumpState *state)
  1907. {
  1908. int    length = 2;
  1909. char   *opcode;
  1910.  
  1911.     if(ptr[1] == 0xd9) {
  1912.     opcode0(state, "FCOMPP");
  1913.     return 2;
  1914.     }
  1915.     switch(ptr[1] & 0xf8) {
  1916.     case 0xc0:
  1917.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1918.         opcode2(state, "FADDP", state->temp, "ST");
  1919.         return 2;
  1920.     case 0xc8:
  1921.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1922.         opcode2(state, "FMULP", state->temp, "ST");
  1923.         return 2;
  1924.     case 0xe0:
  1925.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1926.         opcode2(state, "FSUBRP", state->temp, "ST");
  1927.         return 2;
  1928.     case 0xe8:
  1929.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1930.         opcode2(state, "FSUBP", state->temp, "ST");
  1931.         return 2;
  1932.     case 0xf0:
  1933.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1934.         opcode2(state, "FDIVRP", state->temp, "ST");
  1935.         return 2;
  1936.     case 0xf8:
  1937.         sprintf(state->temp, "ST(%d)", ptr[1] & 0x07);
  1938.         opcode2(state, "FDIVP", state->temp, "ST");
  1939.         return 2;
  1940.     }
  1941.     length = 1 + word_reg_mod(ptr+1, state);
  1942.     switch((ptr[1] & 0x38) >> 3) {
  1943.     case 0: opcode = "FIADD";  break;
  1944.     case 1: opcode = "FIMUL";  break;
  1945.     case 2: opcode = "FICOM";  break;
  1946.     case 3: opcode = "FICOMP"; break;
  1947.     case 4: opcode = "FISUB";  break;
  1948.     case 5: opcode = "FISUBR"; break;
  1949.     case 6: opcode = "FIDIV";  break;
  1950.     case 7: opcode = "FIDIVR"; break;
  1951.     }
  1952.     opcode2(state, opcode, "(INT 32)", state->rm);
  1953.     return length;
  1954. }
  1955.  
  1956. static int cotypeDF(UCHAR *ptr, DumpState *state)
  1957. {
  1958. int    length = 2;
  1959. char   *opSize;
  1960. char   *opcode;
  1961.  
  1962.     if(ptr[1] == 0xe0) {
  1963.     opcode1(state, "FSTSW", "AX");
  1964.     return 2;
  1965.     }
  1966.  
  1967.     length = 1 + word_reg_mod(ptr+1, state);
  1968.     switch((ptr[1] & 0x38) >> 3) {
  1969.     case 0: opcode = "FILD";  opSize = "(INT 32)"; break;
  1970.     case 1: opcode = "???";   opSize = "";           break;
  1971.     case 2: opcode = "FIST";  opSize = "(INT 32)"; break;
  1972.     case 3: opcode = "FISTP"; opSize = "(INT 32)"; break;
  1973.     case 4: opcode = "FBLD";  opSize = "(BCD)";    break;
  1974.     case 5: opcode = "FILD";  opSize = "(INT 64)"; break;
  1975.     case 6: opcode = "FBSTP"; opSize = "(BCD)";    break;
  1976.     case 7: opcode = "FISTP"; opSize = "(INT 64)"; break;
  1977.     }
  1978.     opcode2(state, opcode, opSize, state->rm);
  1979.     return length;
  1980. }
  1981.