Diff for /np2/i386c/ia32/cpu.c between versions 1.9 and 1.20

version 1.9, 2004/02/04 13:24:34 version 1.20, 2004/08/14 03:09:43
Line 28 Line 28
  */   */
   
 #include "compiler.h"  #include "compiler.h"
   #include "dosio.h"
 #include "cpu.h"  #include "cpu.h"
 #include "ia32.mcr"  #include "ia32.mcr"
   
 #include "inst_table.h"  #include "inst_table.h"
   
   
 #if defined(IA32_INSTRUCTION_TRACE)  sigjmp_buf exec_1step_jmpbuf;
 static FILE *fp = NULL;  
 BOOL cpu_inst_trace = FALSE;  
   
 static const char *opcode_1byte[2][256] = {  #if defined(IA32_INSTRUCTION_TRACE)
 /* 16bit */  typedef struct {
 {          CPU_REGS                regs;
 /*00*/  "addb",  "addw",  "addb",  "addw",  "addb",  "addw",  "push",  "pop",          disasm_context_t        disasm;
         "orb",   "orw",   "orb",   "orw",   "orb",   "orw",   "push",  NULL,  
 /*10*/  "adcb",  "adcw",  "adcb",  "adcw",  "adcb",  "adcw",  "push",  "pop",  
         "sbbb",  "sbbw",  "sbbb",  "sbbw",  "sbbb",  "sbbw",  "push",  "pop",  
 /*20*/  "andb",  "andw",  "andb",  "andw",  "andb",  "andw",  "es:",   "daa",  
         "subb",  "subw",  "subb",  "subw",  "subb",  "subw",  "cs:",   "das",  
 /*30*/  "xorb",  "xorw",  "xorb",  "xorw",  "xorb",  "xorw",  "ss:",   "aaa",  
         "cmpb",  "cmpw",  "cmpb",  "cmpw",  "cmpb",  "cmpw",  "ds:",   "aas",  
 /*40*/  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  
         "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  
 /*50*/  "push",  "push",  "push",  "push",  "push",  "push",  "push",  "push",  
         "pop",   "pop",   "pop",   "pop",   "pop",   "pop",   "pop",   "pop",  
 /*60*/  "pusha", "popa",  "bound", "arpl",  "fs:",   "gs:",   NULL,    NULL,  
         "push",  "imul",  "push",  "imul",  "insb",  "insw",  "outsb", "outsw",  
 /*70*/  "jo",    "jno",   "jc",    "jnc",   "jz",    "jnz",   "jna",   "ja",  
         "js",    "jns",   "jp",    "jnp",   "jl",    "jnl",   "jle",   "jnle",  
 /*80*/  NULL,    NULL,    NULL,    NULL,    "testb", "testw", "xchgb", "xchgw",  
         "movb",  "movw",  "movb",  "movw",  "movw",  "lea",   "movw",  "pop",  
 /*90*/  "nop",   "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw",  
         "cbw",   "cwd",   "callf", "fwait", "pushf", "popf",  "sahf",  "lahf",  
 /*a0*/  "movb",  "movw",  "movb",  "movw",  "movsb", "movsw", "cmpsb", "cmpsw",  
         "testb", "testw", "stosb", "stosw", "lodsb", "lodsw", "scasb", "scasw",  
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    
         "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",    
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movw",  
         "enter", "leave", "retf",  "retf",  "int3",  "int",   "into",  "iret",  
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",  
 /*e0*/  "loopne","loope", "loop",  "jcxz",  "inb",   "inw",   "outb",  "outw",  
         "call",  "jmp",   "jmpf",  "jmp",   "inb",   "inw",   "outb",  "outw",  
 /*f0*/  "lock:", "int1",  "repne", "repe",  "hlt",   "cmc",   NULL,    NULL,  
         "clc",   "stc",   "cli",   "sti",   "cld",   "std",   NULL,    NULL,  
 },  
 /* 32bit */  
 {  
 /*00*/  "addb",  "addl",  "addb",  "addl",  "addb",  "addl",  "pushl", "popl",  
         "orb",   "orl",   "orb",   "orl",   "orb",   "orl",   "pushl", NULL,  
 /*10*/  "adcb",  "adcl",  "adcb",  "adcl",  "adcb",  "adcl",  "pushl", "popl",  
         "sbbb",  "sbbl",  "sbbb",  "sbbl",  "sbbb",  "sbbl",  "pushl", "popl",  
 /*20*/  "andb",  "andl",  "andb",  "andl",  "andb",  "andl",  "es:",   "daa",  
         "subb",  "subl",  "subb",  "subl",  "subb",  "subl",  "cs:",   "das",  
 /*30*/  "xorb",  "xorl",  "xorb",  "xorl",  "xorb",  "xorl",  "ss:",   "aaa",  
         "cmpb",  "cmpl",  "cmpb",  "cmpl",  "cmpb",  "cmpl",  "ds:",   "aas",  
 /*40*/  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  
         "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  
 /*50*/  "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl",  
         "popl",  "popl",  "popl",  "popl",  "popl",  "popl",  "popl",  "pop",  
 /*60*/  "pushad","popad", "bound", "arpl",  "fs:",   "gs:",   NULL,    NULL,  
         "pushl", "imul",  "pushl", "imul",  "insb",  "insl",  "outsb", "outsl",  
 /*70*/  "jo",    "jno",   "jc",    "jnc",   "jz",    "jnz",   "jna",   "ja",  
         "js",    "jns",   "jp",    "jnp",   "jl",    "jnl",   "jle",   "jnle",  
 /*80*/  NULL,    NULL,    NULL,    NULL,    "testb", "testl", "xchgb", "xchgl",  
         "movb",  "movl",  "movb",  "movl",  "movl",  "lea",   "movl",  "popl",  
 /*90*/  "nop",   "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl",  
         "cwde",  "cdq",   "callfl","fwait", "pushfd","popfd", "sahf",  "lahf",  
 /*a0*/  "movb",  "movl",  "movb",  "movl",  "movsb", "movsd", "cmpsb", "cmpsd",  
         "testb", "testl", "stosb", "stosd", "lodsb", "lodsd", "scasb", "scasd",  
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    
         "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",    
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movl",  
         "enter", "leave", "retfd", "retfd", "int3",  "int",   "into",  "iretd",  
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",  
 /*e0*/  "loopne","loope", "loop",  "jecxz", "inb",   "inl",   "outb",  "outl",  
         "call",  "jmp",   "jmpf",  "jmp",   "inb",   "inl",   "outb",  "outl",  
 /*f0*/  "lock:", "int1",  "repne", "repe",  "hlt",   "cmc",   NULL,    NULL,  
         "clc",   "stc",   "cli",   "sti",   "cld",   "std",   NULL,    NULL,  
 }  
 };  
   
 static const char *opcode_2byte[2][256] = {          BYTE                    op[MAX_PREFIX + 2];
 /* 16bit */          int                     opbytes;
 {  } ia32_context_t;
 /*00*/  NULL,      NULL,      "lar",     "lsl",  
         NULL,      "loadall", "clts",    NULL,  
         "invd",    "wbinvd",  NULL,      "UD2",  
         NULL,      NULL,      NULL,      NULL,  
 /*10*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*20*/  "movl",    "movl",    "movl",    "movl",  
         "movl",    NULL,      "movl",    NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*30*/  "wrmsr",   "rdtsc",   "rdmsr",   NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*40*/  "cmovo",   "cmovno",  "cmovc",   "cmovnc",  
         "cmovz",   "cmovnz",  "cmovna",  "cmova",  
         "cmovs",   "cmovns",  "cmovp",   "cmovnp",  
         "cmovl",   "cmovnl",  "cmovle",  "cmovnle",  
 /*50*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*60*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*70*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*80*/  "jo",      "jno",     "jc",      "jnc",  
         "jz",      "jnz",     "jna",     "ja",  
         "js",      "jns",     "jp",      "jnp",  
         "jl",      "jnl",     "jle",     "jnle",  
 /*90*/  "seto",    "setno",   "setc",    "setnc",  
         "setz",    "setnz",   "setna",   "seta",  
         "sets",    "setns",   "setp",    "setnp",  
         "setl",    "setnl",   "setle",   "setnle",  
 /*a0*/  "push",    "pop",     "cpuid",   "bt",  
         "shldb",   "shldw",   "cmpxchgb","cmpxchgw",  
         "push",    "pop",     "rsm",     "bts",  
         "shrdb",   "shrdw",   NULL,      "imul",  
 /*b0*/  "cmpxchgb","cmpxchgw","lss",     "btr",  
         "lfs",     "lgs",     "movzb",   "movzw",  
         NULL,      "UD2",     NULL,      "btc",  
         "bsf",     "bsr",     "movsb",   "movsw",  
 /*c0*/  "xaddb",   "xaddw",   NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         "bswap",   "bswap",   "bswap",   "bswap",  
         "bswap",   "bswap",   "bswap",   "bswap",  
 /*d0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*e0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*f0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 },  
 /* 32bit */  
 {  
 /*00*/  NULL,      NULL,      "lar",     "lsl",  
         NULL,      "loadall", "clts",    NULL,  
         "invd",    "wbinvd",  NULL,      "UD2",  
         NULL,      NULL,      NULL,      NULL,  
 /*10*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*20*/  "movl",    "movl",    "movl",    "movl",  
         "movl",    NULL,      "movl",    NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*30*/  "wrmsr",   "rdtsc",   "rdmsr",   NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*40*/  "cmovo",   "cmovno",  "cmovc",   "cmovnc",  
         "cmovz",   "cmovnz",  "cmovna",  "cmova",  
         "cmovs",   "cmovns",  "cmovp",   "cmovnp",  
         "cmovl",   "cmovnl",  "cmovle",  "cmovnle",  
 /*50*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*60*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*70*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*80*/  "jo",      "jno",     "jc",      "jnc",  
         "jz",      "jnz",     "jna",     "ja",  
         "js",      "jns",     "jp",      "jnp",  
         "jl",      "jnl",     "jle",     "jnle",  
 /*90*/  "seto",    "setno",   "setc",    "setnc",  
         "setz",    "setnz",   "setna",   "seta",  
         "sets",    "setns",   "setp",    "setnp",  
         "setl",    "setnl",   "setle",   "setnle",  
 /*a0*/  "push",    "pop",     "cpuid",   "bt",  
         "shldb",   "shldl",   "cmpxchgb","cmpxchgl",  
         "push",    "pop",     "rsm",     "bts",  
         "shrdb",   "shrdl",   NULL,      "imul",  
 /*b0*/  "cmpxchgb","cmpxchgd","lss",     "btr",  
         "lfs",     "lgs",     "movzbl",  "movzwl",  
         NULL,      "UD2",     NULL,      "btc",  
         "bsf",     "bsr",     "movsbl",  "movswl",  
 /*c0*/  "xaddb",   "xaddl",   NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         "bswapl",  "bswapl",  "bswapl",  "bswapl",  
         "bswapl",  "bswapl",  "bswapl",  "bswapl",  
 /*d0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*e0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*f0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 }  
 };  
   
 static const char *opcode_0x8x[2][2][8] = {  #define NCTX    1024
 /* 16bit */  
 {  
         { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" },  
         { "addw", "orw", "adcw", "sbbw", "andw", "subw", "xorw", "cmpw" }  
 },  
 /* 32bit */  
 {  
         { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" },  
         { "addl", "orl", "adcl", "sbbl", "andl", "subl", "xorl", "cmpl" }  
 }  
 };  
   
 static const char *opcode_shift[2][2][8] = {  ia32_context_t ctx[NCTX];
 /* 16bit */  int ctx_index = 0;
 {  
         { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" },  
         { "rolw", "rorw", "rclw", "rcrw", "shlw", "shrw", "shlw", "sarw" }  
 },  
 /* 32bit */  
 {  
         { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" },  
         { "roll", "rorl", "rcll", "rcrl", "shll", "shrl", "shll", "sarl" }  
 },  
 };  
   
 static const char *opcode_0xf6[2][2][8] = {  int cpu_inst_trace = 0;
 /* 16bit */  #endif
 {  
         { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" },  
         { "testw", "testw", "notw", "negw", "mulw", "imulw", "divw", "idivw" }  
 },  
 /* 32bit */  
 {  
         { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" },  
         { "testl", "testl", "notl", "negl", "mull", "imull", "divl", "idivl" }  
 },  
 };  
   
 static const char *opcode_0xfe[2][2][8] = {  
 /* 16bit */  
 {  
         { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL },  
         { "incw", "decw", "call", "callf", "jmp", "jmpf", "push", NULL }  
 },  
 /* 32bit */  
 {  
         { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL },  
         { "incl", "decl", "call", "callf", "jmp", "jmpf", "pushl", NULL }  
 }  
 };  
   
 static const char *opcode2_g6[8] = {  
         "sldt", "str", "lldt", "ltr", "verr", "verw", NULL, NULL  
 };  
   
 static const char *opcode2_g7[8] = {  
         "sgdt", "sidt", "lgdt", "lidt", "smsw", NULL, "lmsw", "invlpg"  
 };  
   
 static const char *opcode2_g8[8] = {  // #define      IPTRACE                 (1 << 14)
         NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc"  
 };  
   
 static const char *opcode2_g9[8] = {  #if defined(TRACE) && IPTRACE
         NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL  static  UINT    trpos = 0;
 };  static  UINT32  trcs[IPTRACE];
   static  UINT32  treip[IPTRACE];
   
   void iptrace_out(void) {
   
           FILEH   fh;
           UINT    s;
           UINT32  cs;
           UINT32  eip;
           char    buf[32];
   
           s = trpos;
           if (s > IPTRACE) {
                   s -= IPTRACE;
           }
           else {
                   s = 0;
           }
           fh = file_create_c("his.txt");
           while(s < trpos) {
                   cs = trcs[s & (IPTRACE - 1)];
                   eip = treip[s & (IPTRACE - 1)];
                   s++;
                   SPRINTF(buf, "%.4x:%.8x\r\n", cs, eip);
                   file_write(fh, buf, strlen(buf));
           }
           file_close(fh);
   }
   #endif
   
   
 static DWORD  void
 ea(DWORD eip, DWORD op)  exec_1step(void)
 {  {
         static const char *ea16[8] = {          int prefix;
                 "bx + si", "bx + di", "bp + si", "bp + di",          UINT32 op;
                 "si", "di", "bp", "bx"  
         };  
   
         char buf[256];  
         DWORD mod = (op >> 6) & 3;  
         DWORD rm = op & 7;  
         DWORD val;  
   
         __ASSERT(mod != 3);  
   
         buf[0] = '\0';  
   
         if (!CPU_INST_AS32) {          CPU_PREV_EIP = CPU_EIP;
                 if (mod == 0) {          CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;
                         if (rm == 6) {  
                                 /* disp16 */  
                                 val = cpu_codefetch_w(eip);  
                                 eip += 2;  
                                 SPRINTF(buf, "0x%04x", val);  
                         } else {  
                                 SPRINTF(buf, "%s", ea16[rm]);  
                         }  
                 } else {  
                         if (mod == 1) {  
                                 /* disp8 */  
                                 val = cpu_codefetch(eip);  
                                 if (val & 0x80) {  
                                         val |= 0xff00;  
                                 }  
                                 eip++;  
                         } else {  
                                 /* disp16 */  
                                 val = cpu_codefetch_w(eip);  
                                 eip += 2;  
                         }  
                         SPRINTF(buf, "%s + 0x%04x", ea16[rm], val);  
                 }  
         } else {  
                 char tmp[32];  
                 BYTE count[9];  
                 int n;  
                 int i;  
   
                 memset(count, 0, sizeof(count));  #if defined(TRACE) && IPTRACE
           trcs[trpos & (IPTRACE - 1)] = CPU_CS;
           treip[trpos & (IPTRACE - 1)] = CPU_EIP;
           trpos++;
   #endif
   
                 if (rm == 5) {  #if defined(IA32_INSTRUCTION_TRACE)
                         DWORD sib;          ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs;
                         DWORD scale;          if (cpu_inst_trace) {
                         DWORD idx;                  disasm_context_t *d = &ctx[ctx_index].disasm;
                         DWORD base;                  UINT32 eip = CPU_EIP;
                   int rv;
                         sib = cpu_codefetch(eip);  
                         eip++;                  rv = disasm(&eip, d);
                   if (rv == 0) {
                         scale = (sib >> 6) & 3;                          char buf[256];
                         idx = (sib >> 3) & 7;                          char tmp[32];
                         base = sib & 7;                          int len = d->nopbytes > 8 ? 8 : d->nopbytes;
                           int i;
                         if (base == 5 && mod == 0) {  
                                 val = cpu_codefetch_d(eip);                          buf[0] = '\0';
                                 eip += 4;                          for (i = 0; i < len; i++) {
                                 count[8] += val;                                  snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                         } else {                                  milstr_ncat(buf, tmp, sizeof(buf));
                                 count[base]++;  
                         }                          }
                         if (idx != 4) {                          for (; i < 8; i++) {
                                 count[idx] += 1 << scale;                                  milstr_ncat(buf, "   ", sizeof(buf));
                         }                          }
                 }                          VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str));
   
                 if (rm == 6 && mod == 0) {                          buf[0] = '\0';
                         /* disp32 */                          for (; i < d->nopbytes; i++) {
                         val = cpu_codefetch_d(eip);                                  snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                         eip += 4;                                  milstr_ncat(buf, tmp, sizeof(buf));
                         count[8] += val;                                  if ((i % 8) == 7) {
                 } else {                                          VERBOSE(("             : %s", buf));
                         if (mod == 1) {                                          buf[0] = '\0';
                                 /* disp8 */  
                                 val = cpu_codefetch(eip);  
                                 eip++;  
                                 if (val & 0x80) {  
                                         val |= 0xffffff00;  
                                 }                                  }
                                 count[8] += val;  
                         } else if (mod == 2) {  
                                 /* disp32 */  
                                 val = cpu_codefetch_d(eip);  
                                 eip += 4;  
                                 count[8] += val;  
                         }                          }
                         if (rm != 5) {                          if ((i % 8) != 0) {
                                 count[rm]++;                                  VERBOSE(("             : %s", buf));
                         }                          }
                 }                  }
           }
           ctx[ctx_index].opbytes = 0;
   #endif
   
                 n = 0;  #if defined(IA32_SUPPORT_DEBUG_REGISTER)
                 for (i = 0; i < 8; i++) {          if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) {
                         if (count[i] != 0) {                  int i;
                                 if (n > 0) {                  for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) {
                                         milstr_ncat(buf, " + ", sizeof(buf));                          if ((CPU_STAT_BP & (1 << i))
                                 }                           && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_CODE)
                                 if (count[i] > 1) {                           && (CPU_DR(i) == CPU_EIP)
                                         SPRINTF(tmp, "%s * %d",                           && (CPU_DR7_GET_LEN(i) == 0)) {
                                             reg32_str[i], count[i]);                                  CPU_DR6 |= CPU_DR6_B(i);
                                 } else {                                  EXCEPTION(DB_EXCEPTION, 0);
                                         milstr_ncpy(tmp, reg32_str[i], sizeof(tmp));  
                                 }  
                                 milstr_ncat(buf, tmp, sizeof(buf));  
                                 n++;  
                         }  
                 }  
                 if (count[8] != 0) {  
                         if (n > 0) {  
                                 milstr_ncat(buf, " + ", sizeof(buf));  
                         }                          }
                         SPRINTF(tmp, "0x%08x", count[8]);  
                         milstr_ncat(buf, tmp, sizeof(buf));  
                 }                  }
         }          }
         fprintf(fp, "[%s]", buf);  #endif  /* IA32_SUPPORT_DEBUG_REGISTER */
   
         return eip;  
 }  
   
 void  
 close_instruction_trace(void)  
 {  
   
         if (fp) {  
                 fclose(fp);  
                 fp = NULL;  
         }  
 }  
 #endif  /* IA32_INSTRUCTION_TRACE */  
   
   
 sigjmp_buf exec_1step_jmpbuf;  
   
 void  
 exec_1step(void)  
 {  
         int prefix;  
         BYTE op;  
   
         CPU_PREV_EIP = CPU_EIP;  
   
         CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;  
   
 #ifdef  IA32_INSTRUCTION_TRACE  
 {  
         BYTE opcode[MAX_PREFIX + 1];  
         DWORD eip = CPU_EIP;  
         int num = 0;  
         int i;  
         BOOL t = cpu_inst_trace;  
   
         if ((fp == NULL) && t) {  
                 fp = fopen("ia32trace.txt", "a");  
         }  
         if (fp && t) {  
                 fprintf(fp, "%04x:%08x:", CPU_CS, eip);  
         }  
 #endif  
   
         for (prefix = 0; prefix < MAX_PREFIX; prefix++) {          for (prefix = 0; prefix < MAX_PREFIX; prefix++) {
                 GET_PCBYTE(op);                  GET_PCBYTE(op);
   #if defined(IA32_INSTRUCTION_TRACE)
 #ifdef  IA32_INSTRUCTION_TRACE                  ctx[ctx_index].op[prefix] = op;
                 eip++;                  ctx[ctx_index].opbytes++;
                 if (fp && t) {  
                         opcode[num++] = op;  
                         fprintf(fp, " %02x", op);  
                 }  
 #endif  #endif
   
                 /* prefix */                  /* prefix */
Line 508  exec_1step(void) Line 179  exec_1step(void)
                 EXCEPTION(UD_EXCEPTION, 0);                  EXCEPTION(UD_EXCEPTION, 0);
         }          }
   
 #ifdef  IA32_INSTRUCTION_TRACE  #if defined(IA32_INSTRUCTION_TRACE)
         if (fp && t) {          if (op == 0x0f) {
                 BYTE op2 = 0;                  BYTE op2;
                 if ((op == 0x0f)                  op2 = cpu_codefetch(CPU_EIP);
                  || (op >= 0x80 && op <= 0x83)                  ctx[ctx_index].op[prefix + 1] = op2;
                  || (op >= 0xc0 && op <= 0xc1)                  ctx[ctx_index].opbytes++;
                  || (op >= 0xd0 && op <= 0xd3)  
                  || (op >= 0xf6 && op <= 0xf7)  
                  || (op >= 0xfe /* && op <= 0xff */)  
                 ) {  
                         op2 = cpu_codefetch(eip);  
                         eip++;  
                         fprintf(fp, " %02x", op2);  
                 }  
   
                 fprintf(fp, "\t\t");  
                 for (i = 0; i < num; i++) {  
                         BYTE c = opcode[i];  
                         const char *p = opcode_1byte[CPU_INST_OP32][c];  
                         if (p) {  
                                 fprintf(fp, "%s ", p);  
                         } else {  
                                 BYTE t = (op2 >> 3) & 7;  
   
                                 switch (c) {  
                                 case 0x80: case 0x81: case 0x82: case 0x83:  
                                         p = opcode_0x8x[CPU_INST_OP32][c&1][t];  
                                         break;  
   
                                 case 0xc0: case 0xc1:  
                                 case 0xd0: case 0xd1: case 0xd2: case 0xd3:  
                                         p = opcode_shift[CPU_INST_OP32][c&1][t];  
                                         break;  
   
                                 case 0xf6:  
                                 case 0xf7:  
                                         p = opcode_0xf6[CPU_INST_OP32][c&1][t];  
                                         break;  
   
                                 case 0xfe:  
                                 case 0xff:  
                                         p = opcode_0xfe[CPU_INST_OP32][c&1][t];  
                                         break;  
                                 }  
                                 if (p) {  
                                         fprintf(fp, "%s ", p);  
                                 }  
                         }  
                 }  
                 if (op == 0x0f) {  
                         const char *p = opcode_2byte[CPU_INST_OP32][op2];  
                         if (p) {  
                                 fprintf(fp, "%s ", p);  
                         } else {  
                                 BYTE t;  
   
                                 t = cpu_codefetch(eip);  
                                 eip++;  
                                 t = (t >> 3) & 7;  
   
                                 switch (op2) {  
                                 case 0x00:  
                                         p = opcode2_g6[t];  
                                         break;  
   
                                 case 0x01:  
                                         p = opcode2_g7[t];  
                                         break;  
   
                                 case 0xba:  
                                         p = opcode2_g8[t];  
                                         break;  
   
                                 case 0xc7:  
                                         p = opcode2_g9[t];  
                                         break;  
                                 }  
                                 if (p) {  
                                         fprintf(fp, "%s ", p);  
                                 }  
                         }  
                 }  
   
                 /* arg */  
                 switch (op) {  
                 case 0xcd:  
                         op2 = cpu_codefetch(eip);  
                         eip++;  
                         fprintf(fp, "%02xh", op2);  
                         break;  
                 }  
                 fprintf(fp, "\n");  
         }          }
 }          ctx_index = (ctx_index + 1) % NELEMENTS(ctx);
 #endif  #endif
   
         /* normal / rep, but not use */          /* normal / rep, but not use */
         if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) {          if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) {
                 (*insttable_1byte[CPU_INST_OP32][op])();                  (*insttable_1byte[CPU_INST_OP32][op])();
   #if defined(IA32_SUPPORT_DEBUG_REGISTER)
                   goto check_break_point;
   #else
                 return;                  return;
   #endif
         }          }
   
         /* rep */          /* rep */
Line 616  exec_1step(void) Line 205  exec_1step(void)
                 if (CPU_CX != 0) {                  if (CPU_CX != 0) {
                         if (!(insttable_info[op] & REP_CHECKZF)) {                          if (!(insttable_info[op] & REP_CHECKZF)) {
                                 /* rep */                                  /* rep */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX);                                          if (--CPU_CX == 0)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else if (CPU_INST_REPUSE != 0xf2) {                          } else if (CPU_INST_REPUSE != 0xf2) {
                                 /* repe */                                  /* repe */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX && (CPU_FLAGL & Z_FLAG));                                          if (--CPU_CX == 0 || CC_NZ)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else {                          } else {
                                 /* repne */                                  /* repne */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX && !(CPU_FLAGL & Z_FLAG));                                          if (--CPU_CX == 0 || CC_Z)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         }                          }
                 }                  }
         } else {          } else {
                 if (CPU_ECX != 0) {                  if (CPU_ECX != 0) {
                         if (!(insttable_info[op] & REP_CHECKZF)) {                          if (!(insttable_info[op] & REP_CHECKZF)) {
                                 /* rep */                                  /* rep */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX);                                          if (--CPU_ECX == 0)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else if (CPU_INST_REPUSE != 0xf2) {                          } else if (CPU_INST_REPUSE != 0xf2) {
                                 /* repe */                                  /* repe */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX && (CPU_FLAGL & Z_FLAG));                                          if (--CPU_ECX == 0 || CC_NZ)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else {                          } else {
                                 /* repne */                                  /* repne */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX && !(CPU_FLAGL & Z_FLAG));                                          if (--CPU_ECX == 0 || CC_Z)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         }                          }
                 }                  }
         }          }
   
   #if defined(IA32_SUPPORT_DEBUG_REGISTER)
   check_break_point:
           if (CPU_TRAP || (CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF)) {
                   UINT8 orig = CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF;
   
                   CPU_STAT_BP_EVENT &= CPU_STAT_BP_EVENT_RF;
   
                   CPU_DR6 |= (orig & 0xf);
                   if (orig & CPU_STAT_BP_EVENT_TASK) {
                           CPU_DR6 |= CPU_DR6_BT;
                   }
                   if (CPU_TRAP) {
                           CPU_DR6 |= CPU_DR6_BS;
                   }
                   INTERRUPT(DB_EXCEPTION, TRUE, FALSE, 0);
           }
           if (CPU_EFLAG & RF_FLAG) {
                   if (CPU_STAT_BP_EVENT & CPU_STAT_BP_EVENT_RF) {
                           /* after IRETD or task switch */
                           CPU_STAT_BP_EVENT &= ~CPU_STAT_BP_EVENT_RF;
                   } else {
                           CPU_EFLAG &= ~RF_FLAG;
                   }
           }
   #endif  /* IA32_SUPPORT_DEBUG_REGISTER */
 }  }

Removed from v.1.9  
changed lines
  Added in v.1.20


RetroPC.NET-CVS <cvs@retropc.net>