OSDN Git Service

[VM][I386] Add some debug logs.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 31 Mar 2019 15:50:14 +0000 (00:50 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 31 Mar 2019 15:50:14 +0000 (00:50 +0900)
[VM][I386][WIP] Around V8086 mode.

source/src/vm/i386.cpp
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386ctrlregdefs.h [new file with mode: 0644]
source/src/vm/mame/emu/cpu/i386/i386op16.c
source/src/vm/mame/emu/cpu/i386/i386op32.c
source/src/vm/mame/emu/cpu/i386/i386ops.c
source/src/vm/mame/emu/cpu/i386/i386priv.h

index 49cad49..e3a6a03 100644 (file)
 #define U64(v) UINT64(v)
 
 #define fatalerror(...) exit(1)
+
+#define logdebug(...)                                          \
+       { \
+         if(cpustate != NULL) {                                                                          \
+                 if(cpustate->parent_device != NULL) {                                                 \
+                         cpustate->parent_device->out_debug_log(__VA_ARGS__); \
+                 }                                                                                                                             \
+         }                                                                                                                                     \
+       }
+
+#define loginfo(...)                                           \
+       { \
+         if(cpustate != NULL) {                                                                          \
+                 if(cpustate->parent_device != NULL) {                                                 \
+                         cpustate->parent_device->out_debug_log(__VA_ARGS__); \
+                 }                                                                                                                             \
+         }                                                                                                                                     \
+       }
+
 #if 0
 #define logerror(...)
 #else
index ce27bf6..ff2026d 100644 (file)
@@ -42,15 +42,15 @@ static void cpu_reset_generic(i386_state *cpustate);
 int i386_parity_table[256];
 MODRM_TABLE i386_MODRM_table[256];
 
-static void i386_trap_with_error(i386_state* cpustate, int irq, int irq_gate, int trap_level, UINT32 err);
+static void i386_trap_with_error(i386_state* cpustate, int irq, int irq_gate, int trap_level, UINT32 err, int is_top);
 static void i286_task_switch(i386_state* cpustate, UINT16 selector, UINT8 nested);
 static void i386_task_switch(i386_state* cpustate, UINT16 selector, UINT8 nested);
 static void build_opcode_table(i386_state *cpustate, UINT32 features);
 static void zero_state(i386_state *cpustate);
 static void pentium_smi(i386_state* cpustate);
 
-#define FAULT(fault,error) {logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error); return;}
-#define FAULT_EXP(fault,error) {logerror("FAULT_EXP(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,trap_level+1,error); return;}
+#define FAULT(fault,error) {logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error, 0); return;}
+#define FAULT_EXP(fault,error) {logerror("FAULT_EXP(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,trap_level+1,error, 0); return;}
 
 static void cpu_reset_generic(i386_state* cpustate)
 {
@@ -316,7 +316,7 @@ static void set_flags(i386_state *cpustate, UINT32 f )
        }
 #if 0
        if(old_vm != cpustate->VM) {
-               if((cpustate->VM) && (PROTECTED_MODE)){
+               if((V8086_MODE) && (PROTECTED_MODE)){
                        // LOAD ES CS SS DS FS GS
                        i386_load_segment_descriptor(cpustate, ES);
                        i386_load_segment_descriptor(cpustate, CS);
@@ -574,7 +574,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                stack.selector = selector;
                i386_load_protected_mode_segment(cpustate,&stack,NULL);
                DPL = (stack.flags >> 5) & 0x03;
-
+               logdebug("SReg load: SELECTOR=%04X FLAGS=%04X BASE=%08X LIMIT=%08X VALID=%s %s\n", stack.selector, stack.flags, stack.base, stack.limit, (stack.valid) ? "YES" : "NO", (stack.d == 0) ? "16bit SP" : "32bit ESP");
                if((selector & ~0x0003) == 0)
                {
                        logerror("SReg Load (%08x): Selector is null.\n",cpustate->pc);
@@ -584,7 +584,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                {
                        if((selector & ~0x0007) > cpustate->ldtr.limit)
                        {
-                               logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",cpustate->pc);
+                               logerror("SReg Load (%08x): Selector is out of LDT bounds.LDTR.limit=%4X : selector=%04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
@@ -592,7 +592,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                {
                        if((selector & ~0x0007) > cpustate->gdtr.limit)
                        {
-                               logerror("SReg Load (%08x): Selector is out of GDT bounds.\n",cpustate->pc);
+                               logerror("SReg Load (%08x): Selector is out of bounds. GDT GDTR.limit=%04X : %04X\n",cpustate->pc, cpustate->gdtr.limit, selector);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
@@ -638,7 +638,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                {
                        if((selector & ~0x0007) > cpustate->ldtr.limit)
                        {
-                               logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",cpustate->pc);
+                               logerror("SReg Load (%08x): Selector is out of LDT bounds.LDTR.limit=%04X : %04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
@@ -755,12 +755,12 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
 
                if(trap_level == 2)
                {
-                       logerror("IRQ: Double fault.\n");
+                       logdebug("IRQ: Double fault. IRQ%02Xh GATE=%d PC=%08X\n", irq, irq_gate, cpustate->pc);
                        FAULT_EXP(FAULT_DF,0);
                }
                if(trap_level >= 3)
                {
-                       logerror("IRQ: Triple fault. CPU reset.\n");
+                       logdebug("IRQ: Triple fault. CPU reset. IRQ%02Xh GATE=%d PC=%08X\n", irq, irq_gate, cpustate->pc);
                        //CPU_RESET_CALL(CPU_MODEL);
                        cpu_reset_generic(cpustate);
                        cpustate->shutdown = 1;
@@ -967,6 +967,8 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                                        FAULT_EXP(FAULT_GP,0)
                                }
                                /* change CPL before accessing the stack */
+                               UINT32 _oldCPL = cpustate->CPL;
+                               if(_oldCPL != DPL) logerror("TRAP/INT GATE: Privilege changed from %d to %d at %08X, INT# %d, GATE %d TYPE %d\n", _oldCPL, DPL, cpustate->pc, irq, irq_gate, type);
                                cpustate->CPL = DPL;
                                /* check for page fault at new stack TODO: check if stack frame crosses page boundary */
                                WRITE_TEST(cpustate, stack.base+newESP-1);
@@ -1081,8 +1083,17 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                catch(UINT64 e)
                {
                        REG32(ESP) = tempSP;
-                       logerror("THROWN at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
+                       logerror("THROWN EXCEPTION %08X at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", e, irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
                        throw e;
+               } catch(UINT32 e)
+               {
+                       REG32(ESP) = tempSP;
+                       logerror("THROWN EXCEPTION %08X at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", e, irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
+                       throw (UINT64)e;
+               } catch(...) {
+                       REG32(ESP) = tempSP;
+                       logerror("THROWN EXCEPTION (UNKNOWN) at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
+                       throw 0; // Unknown
                }
                UINT16 o_selector = cpustate->sreg[CS].selector;
                if(SetRPL != 0)
@@ -1107,17 +1118,22 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
 
 }
 
-static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int trap_level, UINT32 error)
+static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int trap_level, UINT32 error, int is_top)
 {
-//     try {
+       // buffering direct call from trap.
+       if(is_top != 0) {
+               try {
+                       i386_trap(cpustate,irq,irq_gate,trap_level);
+               } catch(UINT64 e) {
+                       logerror("Irregular exception happened %08x for 16bit.\n", e);
+                       return;
+               } catch(UINT32 e) {
+                       logerror("Irregular exception happened %08x for 16bit.\n", e);
+                       return;
+               }
+       } else {
                i386_trap(cpustate,irq,irq_gate,trap_level);
-//     } catch(UINT64 e) {
-//             logerror("Irregular exception happened %08x for 16bit.\n", e);
-//             return;
-//     } catch(UINT32 e) {
-//             logerror("Irregular exception happened %08x for 16bit.\n", e);
-//             return;
-//     }
+       }               
                
        if(irq == FAULT_DF || irq == FAULT_TS || irq == FAULT_NP || irq == FAULT_SS || irq == FAULT_GP || irq == FAULT_GP || irq == FAULT_AC)
        {
@@ -1213,7 +1229,7 @@ static void i286_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
        cpustate->task.flags = seg.flags;
 
        /* Set TS bit in CR0 */
-       cpustate->cr[0] |= 0x08;
+       cpustate->cr[0] |= I386_CR0_TS;
 
        /* Load incoming task state from the new task's TSS */
        tss = cpustate->task.base;
@@ -1261,9 +1277,14 @@ static void i286_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
                WRITE16(cpustate,tss+0,old_task);
                cpustate->NT = 1;
        }
-       CHANGE_PC(cpustate,cpustate->eip);
+       UINT32 _oldCPL = cpustate->CPL;
+       UINT32 _oldPC = cpustate->pc;
 
+       CHANGE_PC(cpustate,cpustate->eip);
        cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
+       UINT32 _newCPL = cpustate->CPL;
+       if(_oldCPL != _newCPL) logerror("I286 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->pc);
+       
        logerror("80286 Task Switch from selector %04x to %04x\n",old_task,selector);
 }
 
@@ -1324,7 +1345,7 @@ static void i386_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
        cpustate->task.flags = seg.flags;
 
        /* Set TS bit in CR0 */
-       cpustate->cr[0] |= 0x08;
+       cpustate->cr[0] |= I386_CR0_TS;
 
        /* Load incoming task state from the new task's TSS */
        tss = cpustate->task.base;
@@ -1379,9 +1400,14 @@ static void i386_task_switch(i386_state *cpustate, UINT16 selector, UINT8 nested
                WRITE8(cpustate,cpustate->gdtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02);
        }
 
+       UINT32 _oldCPL = cpustate->CPL;
+       UINT32 _oldPC = cpustate->pc;
+
        CHANGE_PC(cpustate,cpustate->eip);
 
        cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
+       UINT32 _newCPL = cpustate->CPL;
+       if(_oldCPL != _newCPL) logerror("I80386 TASK SWITCH: Privilege changed from %d to %d at ADDR %08X to %08X\n", _oldCPL, _newCPL, _oldPC, cpustate->pc);
    printf("i386 Task Switch from selector %04x to %04x\n",old_task,selector);
 }
 
@@ -1397,7 +1423,16 @@ static void i386_check_irq_line(i386_state *cpustate)
        if ( (cpustate->irq_state) && cpustate->IF )
        {
                cpustate->cycles -= 2;
-               i386_trap(cpustate, cpustate->pic->get_intr_ack(), 1, 0);
+               int irqnum = cpustate->pic->get_intr_ack();
+               try {
+                       i386_trap(cpustate, irqnum, 1, 0);
+               } catch(UINT64 e) {
+                       logdebug("EXCEPTION %08X VIA INTERRUPT/TRAP HANDLING IRQ=%02Xh(%d) ADDR=%08X\n", e, irqnum, irqnum, cpustate->pc);
+               } catch(UINT32 e) {
+                       logdebug("EXCEPTION %08X VIA INTERRUPT/TRAP HANDLING IRQ=%02Xh(%d) ADDR=%08X\n", e, irqnum, irqnum, cpustate->pc);
+               } catch (...) {
+                       logdebug("EXCEPTION (UNKNOWN) VIA INTERRUPT/TRAP HANDLING IRQ=%02Xh(%d) ADDR=%08X\n", irqnum, irqnum, cpustate->pc);
+               }                       
                cpustate->irq_state = 0;
        }
 }
@@ -1962,7 +1997,10 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        selector = gate.selector;
                                        offset = gate.offset;
 
+                                       UINT32 _oldCPL = cpustate->CPL;
                                        cpustate->CPL = (stack.flags >> 5) & 0x03;
+                                       UINT32 _newCPL = cpustate->CPL;
+                                       if(_oldCPL != _newCPL) logerror("Privilege changed by protected mode call from %d to %d ADDR %08X\n", _oldCPL, _newCPL, cpustate->pc);
                                        /* check for page fault at new stack */
                                        WRITE_TEST(cpustate, stack.base+newESP-1);
                                        /* switch to new stack */
@@ -2128,9 +2166,18 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
        catch(UINT64 e)
        {
                REG32(ESP) = tempSP;
-               logerror("THROWN at I386_OP(i386_protected_mode_call)() line %d\n",  __LINE__);
+               logerror("THROWN %08X at I386_OP(i386_protected_mode_call)() at %08X\n",  e, cpustate->pc);
                throw e;
-       }
+       } catch(UINT32 e)
+       {
+               REG32(ESP) = tempSP;
+               logerror("THROWN %08X at I386_OP(i386_protected_mode_call)() at %08X\n", e, cpustate->pc);
+               throw (UINT64)e;
+       } catch(...) {
+               REG32(ESP) = tempSP;
+               logerror("THROWN (UNKNOWN) at I386_OP(i386_protected_mode_call)() at %08X\n",  cpustate->pc);
+               throw (UINT64)0;
+       }               
 
        CHANGE_PC(cpustate,cpustate->eip);
 }
@@ -2550,7 +2597,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        i386_load_segment_descriptor(cpustate,FS);
                        i386_load_segment_descriptor(cpustate,GS);
                        i386_load_segment_descriptor(cpustate,SS);
-                       logerror("Return to V8086 MODE: old CPL=%d new CPL=3 PC=%08X\n", cpustate->CPL, cpustate->pc);
+                       logerror("IRET: Return to V8086 MODE: old CPL=%d new CPL=3 PC=%08X\n", cpustate->CPL, cpustate->pc);
                        cpustate->CPL = 3;  // Virtual 8086 tasks are always run at CPL 3
                }
                else
@@ -3317,12 +3364,12 @@ static void zero_state(i386_state *cpustate)
 
        // Init CR0
        // From ia32_initreg() of np2, i386c/ia32/interface.c
-       cpustate->cr[0] = CPU_CRx_CD | CPU_CRx_NW;
+       cpustate->cr[0] = I386_CR0_CD | I386_CR0_NW;
        // ToDo: FPU
-       //cpustate->cr[0] &= ~CPU_CRx_EM;
-       //cpustate->cr[0] |= CPU_CRx_ET;
-       cpustate->cr[0] |= (CPU_CRx_EM | CPU_CRx_NE);
-       cpustate->cr[0] &= (CPU_CRx_MP | CPU_CRx_ET);
+       //cpustate->cr[0] &= ~I386_CR0_EM;
+       //cpustate->cr[0] |= I386_CR0_ET;
+       cpustate->cr[0] |= (I386_CR0_EM | I386_CR0_NE);
+       cpustate->cr[0] &= ~(I386_CR0_MP | I386_CR0_ET);
        // Init GDTR/IDTR
        cpustate->gdtr.base  = 0x0000;
        cpustate->gdtr.limit = 0xffff;
@@ -3407,7 +3454,7 @@ static CPU_RESET( i386 )
 
        cpustate->a20_mask = ~0;
        // Move to zero_state().
-       //cpustate->cr[0] = 0x7fffffe0; // reserved bits set to 1
+       cpustate->cr[0] = 0x7fffffe0; // reserved bits set to 1
        //cpustate->eflags = 2; // From NP2 : ia32_initreg(), interface.c
        cpustate->eflags_mask = 0x00037fd7;
        cpustate->eip = 0xfff0;
@@ -3420,6 +3467,7 @@ static CPU_RESET( i386 )
        REG32(EDX) = (3 << 8) | (0 << 4) | (8);
 
        cpustate->CPL = 0;
+       logerror("RESET CPL to 0 by resetting\n", cpustate->CPL);
 
        CHANGE_PC(cpustate,cpustate->eip);
 }
@@ -3433,7 +3481,7 @@ static void pentium_smi(i386_state *cpustate)
        if(cpustate->smm)
                return;
 
-       cpustate->cr[0] &= ~(0x8000000d);
+       cpustate->cr[0] &= ~(0x8000000d);// !(PG | TS | EM | PE)
        set_flags(cpustate, 2);
 //     if(!cpustate->smiact.isnull())
 //             cpustate->smiact(true);
@@ -3530,9 +3578,19 @@ static void i386_set_irq_line(i386_state *cpustate,int irqline, int state)
                        cpustate->nmi_latched = true;
                        return;
                }
-               if ( state )
-                       i386_trap(cpustate,2, 1, 0);
+               if ( state ) {
+                       try {
+                               i386_trap(cpustate,2, 1, 0);
+                       } catch(UINT64 e) {
+                               logdebug("EXCEPTION %08X VIA making INT02h at i386_set_irq_line() ADDR=%08X\n", e, cpustate->pc);
+                       } catch(UINT32 e) {
+                               logdebug("EXCEPTION %08X VIA making INT02h at i386_set_irq_line() ADDR=%08X\n", e, cpustate->pc);
+                       } catch(...) {
+                               logdebug("EXCEPTION (UNKNOWN) VIA making INT02h at i386_set_irq_line() ADDR=%08X\n", cpustate->pc);
+                       }                               
+               }
        }
+                       
        else
        {
                cpustate->irq_state = state;
@@ -3671,8 +3729,18 @@ static CPU_EXECUTE( i386 )
                        {
                                cpustate->ext = 1;
                                logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, e >> 32); 
-                               i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32);
+                               i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32, 1);
+                       } catch(UINT32 e)
+                       {
+                               cpustate->ext = 1;
+                               logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, e >> 32); 
+                               i386_trap_with_error(cpustate,e&0xffffffff,0,0,0, 1);
+                       } catch(...) {
+                               cpustate->ext = 1;
+                               logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=UNKNOWN\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO"); 
+                               i386_trap_with_error(cpustate,0,0,0,0, 1);
                        }
+                       
 //#ifdef SINGLE_MODE_DMA
                        if(cpustate->dma != NULL) {
                                cpustate->dma->do_dma();
@@ -3735,7 +3803,19 @@ static CPU_EXECUTE( i386 )
                        {
                                cpustate->ext = 1;
                                logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, e >> 32); 
-                               i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32);
+                               i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32, 1);
+                       }
+                       catch(UINT32 e)
+                       {
+                               cpustate->ext = 1;
+                               logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, 0); 
+                               i386_trap_with_error(cpustate,e,0,0,0, 1);
+                       }
+                       catch(...)
+                       {
+                               cpustate->ext = 1;
+                               logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", 0, 0); 
+                               i386_trap_with_error(cpustate,0,0,0,0, 1);
                        }
 //#ifdef SINGLE_MODE_DMA
                        if(cpustate->dma != NULL) {
@@ -3808,7 +3888,7 @@ static CPU_RESET( i486 )
 
        cpustate->a20_mask = ~0;
 
-       cpustate->cr[0] = 0x00000010;
+       cpustate->cr[0] = 0x00000010; // ET
        //cpustate->eflags = 0;
        cpustate->eflags_mask = 0x00077fd7;
        cpustate->eip = 0xfff0;
diff --git a/source/src/vm/mame/emu/cpu/i386/i386ctrlregdefs.h b/source/src/vm/mame/emu/cpu/i386/i386ctrlregdefs.h
new file mode 100644 (file)
index 0000000..754e37a
--- /dev/null
@@ -0,0 +1,100 @@
+#pragma once
+
+
+// From np2,, ia32/system_inst.c
+// Descriptions of CRx:
+/*
+ * CR0: From https://en.wikipedia.org/wiki/Control_register
+ * 0   PE      Protected Mode Enable   If 1, system is in protected mode, else system is in real mode
+ * 1   MP      Monitor co-processor    Controls interaction of WAIT/FWAIT instructions with TS flag in CR0
+ * 2   EM      Emulation       If set, no x87 floating-point unit present, if clear, x87 FPU present
+ * 3   TS      Task switched   Allows saving x87 task context upon a task switch only after x87 instruction used
+ * 4   ET      Extension type  On the 386, it allowed to specify whether the external math coprocessor was an 80287 or 80387
+ * 5   NE      Numeric error   Enable internal x87 floating point error reporting when set, else enables PC style x87 error detection
+ * 16  WP      Write protect   When set, the CPU can't write to read-only pages when privilege level is 0
+ * 18  AM      Alignment mask  Alignment check enabled if AM set, AC flag (in EFLAGS register) set, and privilege level is 3
+ * 29  NW      Not-write through       Globally enables/disable write-through caching
+ * 30  CD      Cache disable   Globally enables/disable the memory cache
+ * 31  PG      Paging  If 1, enable paging and use the Â§ CR3 register, else disable paging. 
+ */
+#define I386_CR0_PE (1 << 0)
+#define I386_CR0_MP (1 << 1)
+#define I386_CR0_EM (1 << 2)
+#define I386_CR0_TS (1 << 3)
+#define I386_CR0_ET (1 << 4)
+#define I386_CR0_NE (1 << 5)
+#define I386_CR0_WP (1 << 16)
+#define I386_CR0_AM (1 << 18)
+#define I386_CR0_NW (1 << 29)
+#define I386_CR0_CD (1 << 30)
+#define I386_CR0_PG (1 << 31)
+#define        I386_CR0_ALL            (I386_CR0_PE|I386_CR0_MP|I386_CR0_EM|I386_CR0_TS|I386_CR0_ET|I386_CR0_NE|I386_CR0_WP|I386_CR0_AM|I386_CR0_NW|I386_CR0_CD|I386_CR0_PG)
+
+#define        I386_CR3_PD_MASK 0xfffff000
+#define I386_CR3_PCID    0x00000fff
+#define        I386_CR3_PWT     (1 << 3)
+#define        I386_CR3_PCD     (1 << 4)
+#define        I386_CR3_MASK    (I386_CR3_PD_MASK|I386_CR3_PWT|I386_CR3_PCD)
+
+/*
+ * CR4: From https://en.wikipedia.org/wiki/Control_register#CR4
+ * 0 VME       Virtual 8086 Mode Extensions    If set, enables support for the virtual interrupt flag (VIF) in virtual-8086 mode.
+ * 1 PVI       Protected-mode Virtual Interrupts       If set, enables support for the virtual interrupt flag (VIF) in protected mode.
+ * 2 TSD       Time Stamp Disable      If set, RDTSC instruction can only be executed when in ring 0, otherwise RDTSC can be used at any privilege level.
+ * 3 DE        Debugging Extensions    If set, enables debug register based breaks on I/O space access.
+ * 4 PSE       Page Size Extension     If unset, page size is 4 KiB, else page size is increased to 4 MiB If PAE is enabled or the processor is in x86-64 long mode this bit is ignored.[2]
+ * 5 PAE       Physical Address Extension      If set, changes page table layout to translate 32-bit virtual addresses into extended 36-bit physical addresses.
+ * 6 MCE       Machine Check Exception         If set, enables machine check interrupts to occur.
+ * 7 PGE       Page Global Enabled     If set, address translations (PDE or PTE records) may be shared between address spaces.
+ * 8 PCE       Performance-Monitoring Counter enable   If set, RDPMC can be executed at any privilege level, else RDPMC can only be used in ring 0.
+ * 9 OSFXSR    Operating system support for FXSAVE and FXRSTOR instructions    If set, enables Streaming SIMD Extensions (SSE) instructions and fast FPU save & restore.
+ * 10 OSXMMEXCPT       Operating System Support for Unmasked SIMD Floating-Point Exceptions    If set, enables unmasked SSE exceptions.
+ * 11 UMIP     User-Mode Instruction Prevention        If set, the SGDT, SIDT, SLDT, SMSW and STR instructions cannot be executed if CPL > 0.[1]
+ * 12 LA57     (none specified)        If set, enables 5-Level Paging.[3]
+ * 13 VMXE     Virtual Machine Extensions Enable       see Intel VT-x x86 virtualization.
+ * 14 SMXE     Safer Mode Extensions Enable    see Trusted Execution Technology (TXT)
+ * 16 FSGSBASE         Enables the instructions RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE.
+ * 17 PCIDE    PCID Enable     If set, enables process-context identifiers (PCIDs).
+ * 18 OSXSAVE  XSAVE and Processor Extended States Enable      
+ * 20 SMEP     Supervisor Mode Execution Protection Enable     If set, execution of code in a higher ring generates a fault.
+ * 21 SMAP     Supervisor Mode Access Prevention Enable        If set, access of data in a higher ring generates a fault.[5]
+ * 22 PKE Protection Key Enable        See Intel 64 and IA-32 Architectures Software Developer’s Manual. 
+*/
+#define I386_CR4_VME        (1 << 0)
+#define I386_CR4_PVI        (1 << 1)
+#define I386_CR4_TSD        (1 << 2)
+#define I386_CR4_DE         (1 << 3)
+#define I386_CR4_PSE        (1 << 4)
+#define I386_CR4_PAE        (1 << 5)
+#define I386_CR4_MCE        (1 << 6)
+#define I386_CR4_PGE        (1 << 7)
+#define I386_CR4_PCE        (1 << 8)
+#define I386_CR4_OSFXSR     (1 << 9)
+#define I386_CR4_OSXMMEXCPT (1 << 10)
+#define I386_CR4_UMIP       (1 << 11)
+#define I386_CR4_LA57       (1 << 12)
+#define I386_CR4_VMXE       (1 << 13)
+#define I386_CR4_SMXE       (1 << 14)
+// bit15: ??
+#define I386_CR4_FSGBASE    (1 << 16)
+#define I386_CR4_PCIDE      (1 << 17)
+#define I386_CR4_OSXSAVE    (1 << 18)
+// bit19: ??
+#define I386_CR4_SMEP       (1 << 20)
+#define I386_CR4_SMAP       (1 << 21)
+#define I386_CR4_PKE        (1 << 22)
+
+#define I386_CR4_SET_MASK1  ~(I386_CR4_VME | I386_CR4_PVI |  I386_CR4_TSD |  I386_CR4_DE |  I386_CR4_PSE | I386_CR4_PAE | I386_CR4_MCE | I386_CR4_PGE | I386_CR4_PCE |  I386_CR4_OSFXSR)
+
+#define        I386_DR6_B(r)           (1 << (r))
+#define        I386_DR6_BD             (1 << 13)
+#define        I386_DR6_BS             (1 << 14)
+#define        I386_DR6_BT             (1 << 15)
+
+#define        I386_DR7_L(r)           (1 << ((r) * 2))
+#define        I386_DR7_G(r)           (1 << ((r) * 2 + 1))
+#define        I386_DR7_LE             (1 << 8)
+#define        I386_DR7_GE             (1 << 9)
+#define        I386_DR7_GD             (1 << 13)
+#define        I386_DR7_RW(r)          (3 << ((r) * 4 + 16))
+#define        I386_DR7_LEN(r)         (3 << ((r) * 4 + 16 + 2))
index dfba6ba..9e7de7c 100644 (file)
@@ -1644,7 +1644,7 @@ static bool I386OP(pop_seg16)(i386_state *cpustate, int segment)
        {
                cpustate->ext = 1;
                logerror("Illegal address(pop_seg16) EIP=%08x VM8086=%s exception FAULT_SS irq=0 irq_gate=0 trap_level=0 ERROR=0\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO"); 
-               i386_trap_with_error(cpustate,FAULT_SS,0,0,0);
+               i386_trap_with_error(cpustate,FAULT_SS,0,0,0, 0);
                return false;
        }
        CYCLES(cpustate,CYCLES_POP_SREG);
@@ -3217,9 +3217,11 @@ static void I386OP(group0F00_16)(i386_state *cpustate)          // Opcode 0x0f 0
                                memset(&seg, 0, sizeof(seg));
                                seg.selector = cpustate->ldtr.segment;
                                i386_load_protected_mode_segment(cpustate,&seg,NULL);
-                               cpustate->ldtr.limit = seg.limit;
-                               cpustate->ldtr.base = seg.base;
-                               cpustate->ldtr.flags = seg.flags;
+                               {
+                                       cpustate->ldtr.limit = seg.limit;
+                                       cpustate->ldtr.base = seg.base;
+                                       cpustate->ldtr.flags = seg.flags;
+                               }
                        }
                        else
                        {
@@ -3459,11 +3461,11 @@ static void I386OP(group0F01_16)(i386_state *cpustate)      // Opcode 0x0f 01
                                }
                                //logerror("LMSW16 %02x <- VAL=%04x \n", modrm, b);
                                uint32_t cr0_bak = cpustate->cr[0];
-                               cpustate->cr[0] &= ~(CPU_CRx_MP | CPU_CRx_EM | CPU_CRx_TS);
-                               cpustate->cr[0] |= (b & (CPU_CRx_PE | CPU_CRx_MP | CPU_CRx_EM | CPU_CRx_TS));
-                               if(!(cr0_bak & CPU_CRx_PE) && (b & CPU_CRx_PE)) {
-                                       i386_change_protect_mode(cpustate, 1);
-                               }
+                               cpustate->cr[0] &= ~(I386_CR0_MP | I386_CR0_EM | I386_CR0_TS);
+                               cpustate->cr[0] |= (b & (I386_CR0_PE | I386_CR0_MP | I386_CR0_EM | I386_CR0_TS));
+                               //if(!(cr0_bak & I386_CR0_PE) && (b & I386_CR0_PE)) {
+                               //      i386_change_protect_mode(cpustate, 1);
+                               //}
                                break;
                        }
                default:
index 523403f..b2bfbf0 100644 (file)
@@ -1472,7 +1472,7 @@ static bool I386OP(pop_seg32)(i386_state *cpustate, int segment)
        {
                cpustate->ext = 1;
                logerror("Illegal address(pop_seg32) EIP=%08x VM8086=%s exception FAULT_SS irq=0 irq_gate=0 trap_level=0 ERROR=0\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO"); 
-               i386_trap_with_error(cpustate,FAULT_SS,0,0,0);
+               i386_trap_with_error(cpustate,FAULT_SS,0,0,0, 0);
                return false;
        }
        CYCLES(cpustate,CYCLES_POP_SREG);
@@ -2997,9 +2997,11 @@ static void I386OP(group0F00_32)(i386_state *cpustate)          // Opcode 0x0f 0
                                memset(&seg, 0, sizeof(seg));
                                seg.selector = cpustate->ldtr.segment;
                                i386_load_protected_mode_segment(cpustate,&seg,NULL);
-                               cpustate->ldtr.limit = seg.limit;
-                               cpustate->ldtr.base = seg.base;
-                               cpustate->ldtr.flags = seg.flags;
+                               {
+                                       cpustate->ldtr.limit = seg.limit;
+                                       cpustate->ldtr.base = seg.base;
+                                       cpustate->ldtr.flags = seg.flags;
+                               }
                        }
                        else
                        {
@@ -3229,11 +3231,11 @@ static void I386OP(group0F01_32)(i386_state *cpustate)      // Opcode 0x0f 01
                                }
                                //logerror("LMSW32 %02x <- VAL=%04x \n", modrm, b);
                                uint32_t cr0_bak = cpustate->cr[0];
-                               cpustate->cr[0] &= ~(CPU_CRx_MP | CPU_CRx_EM | CPU_CRx_TS);
-                               cpustate->cr[0] |= (b & (CPU_CRx_PE | CPU_CRx_MP | CPU_CRx_EM | CPU_CRx_TS));
-                               if(!(cr0_bak & CPU_CRx_PE) && (b & CPU_CRx_PE)) {
-                                       i386_change_protect_mode(cpustate, 1);
-                               }
+                               cpustate->cr[0] &= ~(I386_CR0_MP | I386_CR0_EM | I386_CR0_TS);
+                               cpustate->cr[0] |= (b & (I386_CR0_PE | I386_CR0_MP | I386_CR0_EM | I386_CR0_TS));
+                               //if(!(cr0_bak & I386_CR0_PE) && (b & I386_CR0_PE)) {
+                               //      i386_change_protect_mode(cpustate, 1);
+                               //}
                                break;
                        }
                default:
index aad1f1b..e094e05 100644 (file)
@@ -652,52 +652,21 @@ static void I386OP(mov_rm8_i8)(i386_state *cpustate)        // Opcode 0xc6
                CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
        }
 }
-
-// From np2,, ia32/system_inst.c
-// Descriptions of CRx:
-/*
- * 0 = PE (protect enable)
- * 1 = MP (monitor coprocesser)
- * 2 = EM (emulation)
- * 3 = TS (task switch)
- * 4 = ET (extend type, FPU present = 1)
- * 5 = NE (numeric error)
- * 16 = WP (write protect)
- * 18 = AM (alignment mask)
- * 29 = NW (not write-through)
- * 30 = CD (cache diable)
- * 31 = PG (pageing)
- */
-#define CPU_CRx_PE (1 << 0)
-#define CPU_CRx_MP (1 << 1)
-#define CPU_CRx_EM (1 << 2)
-#define CPU_CRx_TS (1 << 3)
-#define CPU_CRx_ET (1 << 4)
-#define CPU_CRx_NE (1 << 5)
-#define CPU_CRx_WP (1 << 16)
-#define CPU_CRx_AM (1 << 18)
-#define CPU_CRx_NW (1 << 29)
-#define CPU_CRx_CD (1 << 30)
-#define CPU_CRx_PG (1 << 31)
-#define        CPU_CRx_ALL             (CPU_CRx_PE|CPU_CRx_MP|CPU_CRx_EM|CPU_CRx_TS|CPU_CRx_ET|CPU_CRx_NE|CPU_CRx_WP|CPU_CRx_AM|CPU_CRx_NW|CPU_CRx_CD|CPU_CRx_PG)
-
-#define        CPU_CR3_PD_MASK         0xfffff000
-#define        CPU_CR3_PWT             (1 << 3)
-#define        CPU_CR3_PCD             (1 << 4)
-#define        CPU_CR3_MASK            (CPU_CR3_PD_MASK|CPU_CR3_PWT|CPU_CR3_PCD)
+//#include "./i386ctrlregdefs.h"
 
 static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
 {
-       UINT8 modrm = FETCH(cpustate);
-       if(modrm < 0xc0) {
-               FAULT(FAULT_UD, 0);
-               return;
-       }
-       if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
+       //if(modrm < 0xc0) {
+       //      FAULT(FAULT_UD, 0);
+       //      return;
+       //}
+       if((PROTECTED_MODE && (/*(V8086_MODE) || */(cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr)"); 
                FAULT(FAULT_GP, 0);
        }
+       UINT8 modrm = FETCH(cpustate);
        UINT8 cr = (modrm >> 3) & 0x7;
+       logdebug("MOV r32 CR%d VAL=(%08X)\n", cr, cpustate->cr[cr]);
        if(cr < 5) {
                STORE_RM32(modrm, cpustate->cr[cr]);
                CYCLES(cpustate,CYCLES_MOV_CR_REG);
@@ -706,18 +675,6 @@ static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
        }
 }
 
-#define        CPU_DR6_B(r)            (1 << (r))
-#define        CPU_DR6_BD              (1 << 13)
-#define        CPU_DR6_BS              (1 << 14)
-#define        CPU_DR6_BT              (1 << 15)
-
-#define        CPU_DR7_L(r)            (1 << ((r) * 2))
-#define        CPU_DR7_G(r)            (1 << ((r) * 2 + 1))
-#define        CPU_DR7_LE              (1 << 8)
-#define        CPU_DR7_GE              (1 << 9)
-#define        CPU_DR7_GD              (1 << 13)
-#define        CPU_DR7_RW(r)           (3 << ((r) * 4 + 16))
-#define        CPU_DR7_LEN(r)          (3 << ((r) * 4 + 16 + 2))
 
 
 #if 0
@@ -725,14 +682,14 @@ static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
 #endif
 void i386_change_protect_mode(i386_state *cpustate, int val)
 {
-//     printf("Change protect mode to %s\n", (val == 0) ? "NO" : "YES");
+//     logdebug("Change protect mode to %s\n", (val == 0) ? "NO" : "YES");
 #if 0
        void *np[32];                                                                                                           
        int nptrs =backtrace(np, 32);                                                                           
        char **ss = backtrace_symbols(np, nptrs);                                                       
-       printf("Backtrace: \n");        \
+       logdebug("Backtrace: \n");      \
        for(int __i = 0; __i < nptrs; __i++) {                                                          
-               printf("%s\n", ss[__i]);                                                                                
+               logdebug("%s\n", ss[__i]);                                                                              
        }                                                                               
 #endif
        cpustate->sreg[SS].d = 0;       
@@ -751,21 +708,22 @@ void i386_change_paging_mode(i386_state *cpustate, int val)
 
 static void I386OP(mov_r32_dr)(i386_state *cpustate)        // Opcode 0x0f 21
 {
-       UINT8 modrm = FETCH(cpustate);
-       if(modrm < 0xc0) {
-               FAULT(FAULT_UD, 0);
-               return;
-       }
-       if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
+       //if(modrm < 0xc0) {
+       //      FAULT(FAULT_UD, 0);
+       //      return;
+       //}
+       if((PROTECTED_MODE && (/*(V8086_MODE) || */(cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_r32_dr)"); 
                FAULT(FAULT_GP, 0);
        }
-       if((cpustate->dr[7] & CPU_DR7_GD) != 0) {
-               cpustate->dr[6] |= CPU_DR6_BD;
-               cpustate->dr[7] &= ~CPU_DR7_GD;
+       if((cpustate->dr[7] & I386_DR7_GD) != 0) {
+               cpustate->dr[6] |= I386_DR6_BD;
+               cpustate->dr[7] &= ~I386_DR7_GD;
                FAULT(FAULT_DB, 0);
        }
+       UINT8 modrm = FETCH(cpustate);
        UINT8 dr = (modrm >> 3) & 0x7;
+       logdebug("MOV r32 DR%d VAL=(%08X)\n", dr, cpustate->dr[dr]);
 
        switch(dr)
        {
@@ -786,6 +744,7 @@ static void I386OP(mov_r32_dr)(i386_state *cpustate)        // Opcode 0x0f 21
                        CYCLES(cpustate,CYCLES_MOV_REG_DR6_7);
                        break;
                default:
+                       STORE_RM32(modrm, cpustate->dr[dr]);
                        logerror("i386: mov_r32_dr illegal index \n", dr);
                        return;
                        break;
@@ -794,61 +753,67 @@ static void I386OP(mov_r32_dr)(i386_state *cpustate)        // Opcode 0x0f 21
 
 static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
 {
-       UINT8 modrm = FETCH(cpustate);
-       UINT8 cr = (modrm >> 3) & 0x7;
-       if(modrm < 0xc0) {
-               FAULT(FAULT_UD, 0);
-               return;
-       }
-       if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
+       //if(modrm < 0xc0) {
+       //      FAULT(FAULT_UD, 0);
+       //      return;
+       //}
+       if((PROTECTED_MODE && (/*(V8086_MODE) || */(cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_cr_r32)"); 
                FAULT(FAULT_GP, 0);
        }
+       UINT8 modrm = FETCH(cpustate);
+       UINT8 cr = (modrm >> 3) & 0x7;
        UINT32 data = LOAD_RM32(modrm);
        UINT32 data_bak;
+       logdebug("MOV CR%d r32 VAL=(%08X)\n", cr, data);
        switch(cr)
        {
                case 0:
                        CYCLES(cpustate,CYCLES_MOV_REG_CR0);
 //                     if (PROTECTED_MODE != BIT(data, 0))
 //                             debugger_privilege_hook();
-                       if((data & (CPU_CRx_PE | CPU_CRx_PG)) == (UINT32)CPU_CRx_PG) {
+                       if((data & (I386_CR0_PE | I386_CR0_PG)) == (UINT32)I386_CR0_PG) {
                                FAULT(FAULT_GP, 0);
                        }
-                       if((data & (CPU_CRx_NW | CPU_CRx_CD)) == CPU_CRx_NW) {
+                       if((data & (I386_CR0_NW | I386_CR0_CD)) == I386_CR0_NW) {
                                FAULT(FAULT_GP, 0);
                        }
+#if 0
                        data_bak = cpustate->cr[0];
-                       data &= CPU_CRx_ALL;
-                       data &= ~CPU_CRx_WP; // wp not supported on 386
-                       //printf("MOV CR0,xxxxh %08x -> %08x \n", data_bak, data);
+                       data &= I386_CR0_ALL;
+                       data &= ~I386_CR0_WP; // wp not supported on 386
+                       //logdebug("MOV CR0,xxxxh %08x -> %08x \n", data_bak, data);
                        // ToDo: FPU
-                       //data |= CPU_CRx_ET;   /* FPU present */
-                       //data &= ~CPU_CRx_EM;
-                       data |= CPU_CRx_EM | CPU_CRx_NE;
-                       data &= ~(CPU_CRx_MP | CPU_CRx_ET);
-                       cpustate->cr[0] = data & ~(CPU_CRx_PE | CPU_CRx_PG);
-                       if((data_bak & (CPU_CRx_PE | CPU_CRx_PG)) != (data & (CPU_CRx_PE | CPU_CRx_PG))) {
+                       //data |= I386_CR0_ET;  /* FPU present */
+                       //data &= ~I386_CR0_EM;
+                       data |= I386_CR0_EM | I386_CR0_NE;
+                       data &= ~(I386_CR0_MP | I386_CR0_ET);
+                       cpustate->cr[0] = data & ~(I386_CR0_PE | I386_CR0_PG);
+#endif                 
+                       cpustate->cr[0] = data;
+#if 0
+                       if((data_bak & (I386_CR0_PE | I386_CR0_PG)) != (data & (I386_CR0_PE | I386_CR0_PG))) {
                                // ToDo: TLB flush (paging)
                                vtlb_flush_dynamic(cpustate->vtlb);
                        }
-                       if((data_bak & CPU_CRx_PE) != (data & CPU_CRx_PE)) {
-                               if((data & CPU_CRx_PE) != 0) {
+                       if((data_bak & I386_CR0_PE) != (data & I386_CR0_PE)) {
+                               if((data & I386_CR0_PE) != 0) {
                                        i386_change_protect_mode(cpustate, 1);
                                }
                        }
-                       if((data_bak & CPU_CRx_PG) != (data & CPU_CRx_PG)) {
-                               if((data & CPU_CRx_PG) != 0) {
-                                       cpustate->cr[0] |= CPU_CRx_PG;
+                       if((data_bak & I386_CR0_PG) != (data & I386_CR0_PG)) {
+                               if((data & I386_CR0_PG) != 0) {
+                                       cpustate->cr[0] |= I386_CR0_PG;
                                } else {
-                                       cpustate->cr[0] &= ~CPU_CRx_PG;
+                                       cpustate->cr[0] &= ~I386_CR0_PG;
                                }
                        }
-                       if((data_bak & CPU_CRx_PE) != (data & CPU_CRx_PE)) {
-                               if((data & CPU_CRx_PE) == 0) {
+                       if((data_bak & I386_CR0_PE) != (data & I386_CR0_PE)) {
+                               if((data & I386_CR0_PE) == 0) {
                                        i386_change_protect_mode(cpustate, 0);
                                }
                        }
+#endif
                        return;
                        break;
                case 2: CYCLES(cpustate,CYCLES_MOV_REG_CR2); break;
@@ -872,14 +837,14 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
                         */
                        data_bak = 0x00000000; // ToDo: PGE
                        if((data & ~data_bak) != 0) {
-                               if((data & 0xfffffc00) != 0) {
+                               if((data & I386_CR4_SET_MASK1) != 0) {
                                        FAULT(FAULT_GP, 0);
                                }
                                logerror("mov cr4 r32 : set 0x%08x\n", data);
                        }
                        data_bak = cpustate->cr[4];
-                       cpustate->cr[cr] = data;
-                       if(((data ^ data_bak) & ((1 << 4) | (1 << 7) | (1 << 4))) != 0) { // PSE | PGE | PAE
+                       cpustate->cr[4] = data;
+                       if(((data ^ data_bak) & (I386_CR4_PSE | I386_CR4_PGE | I386_CR4_PAE)) != 0) { // PSE | PGE | PAE
                                vtlb_flush_dynamic(cpustate->vtlb);
                        }
                        CYCLES(cpustate,1);
@@ -894,21 +859,23 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
 
 static void I386OP(mov_dr_r32)(i386_state *cpustate)        // Opcode 0x0f 23
 {
-       UINT8 modrm = FETCH(cpustate);
-       if(modrm < 0xc0) {
-               FAULT(FAULT_UD, 0);
-               return;
-       }
+       //if(modrm < 0xc0) {
+       //      FAULT(FAULT_UD, 0);
+       //      return;
+       //}
        if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_dr_r32)"); 
                FAULT(FAULT_GP, 0);
        }
-       if ((cpustate->dr[7] & CPU_DR7_GD) != 0){
-               cpustate->dr[6] |= CPU_DR6_BD;
-               cpustate->dr[7] &= ~CPU_DR7_GD;
+       if ((cpustate->dr[7] & I386_DR7_GD) != 0){
+               cpustate->dr[6] |= I386_DR6_BD;
+               cpustate->dr[7] &= ~I386_DR7_GD;
                FAULT(FAULT_DB, 0);
        }
+       UINT8 modrm = FETCH(cpustate);
        UINT8 dr = (modrm >> 3) & 0x7;
+       UINT32 data =  LOAD_RM32(modrm);
+       logdebug("MOV DR%d r32 (VAL=%08X)\n", dr, data);
 
        switch(dr)
        {
@@ -916,19 +883,20 @@ static void I386OP(mov_dr_r32)(i386_state *cpustate)        // Opcode 0x0f 23
                case 1:
                case 2:
                case 3:
-                       cpustate->dr[dr] = LOAD_RM32(modrm);
+                       cpustate->dr[dr] = data;
                        CYCLES(cpustate,CYCLES_MOV_DR0_3_REG);
                        break;
                case 6:
-                       cpustate->dr[dr] = LOAD_RM32(modrm);
+                       cpustate->dr[dr] =data;
                        CYCLES(cpustate,CYCLES_MOV_DR6_7_REG);
                        break;
                case 7:
-                       cpustate->dr[dr] = LOAD_RM32(modrm);
+                       cpustate->dr[dr] = data;
                        cpustate->reg.d[EBP] = 0;
                        CYCLES(cpustate,CYCLES_MOV_DR6_7_REG);
                        break;
                default:
+                       cpustate->dr[dr] = data;
                        logerror("i386: mov_dr_r32 DR%d!\n", dr);
                        return;
        }
index 4a0fb72..7d9ba99 100644 (file)
@@ -11,7 +11,7 @@
 #include "../vtlb.h"
 
 #include <math.h>
-
+#include "./i386ctrlregdefs.h"
 //#define DEBUG_MISSING_OPCODE
 
 #define I386OP(XX)      i386_##XX
@@ -597,9 +597,9 @@ static void pf_throw_sub(i386_state* cpustate, uint32_t address, uint64_t error)
 #endif
 #define PROTECTED_MODE      (cpustate->cr[0] & 0x1)
 #define STACK_32BIT         (cpustate->sreg[SS].d)
-#define V8086_MODE          (cpustate->VM)
+#define V8086_MODE          ((cpustate->VM) && (cpustate->cr[4] & I386_CR4_VME))
 #define NESTED_TASK         (cpustate->NT)
-#define WP                  (cpustate->cr[0] & 0x10000)
+#define WP                  (cpustate->cr[0] & I386_CR0_WP)
 
 #define SetOF_Add32(r,s,d)  (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0)
 #define SetOF_Add16(r,s,d)  (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0)
@@ -696,7 +696,7 @@ INLINE vtlb_entry get_permissions(UINT32 pte, int wp)
 static int i386_translate_address(i386_state *cpustate, int intention, offs_t *address, vtlb_entry *entry)
 {
        UINT32 a = *address;
-       UINT32 pdbr = cpustate->cr[3] & 0xfffff000;
+       UINT32 pdbr = cpustate->cr[3] & 0xfffff000;// I386_CR3_PD_MASK
        UINT32 directory = (a >> 22) & 0x3ff;
        UINT32 table = (a >> 12) & 0x3ff;
        vtlb_entry perm = 0;
@@ -705,17 +705,17 @@ static int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
        bool write = (intention & TRANSLATE_WRITE) ? true : false;
        bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false;
 
-       if(!(cpustate->cr[0] & 0x80000000))
+       if(!(cpustate->cr[0] & I386_CR0_PG)) // paging is disabled
        {
                if(entry)
                        *entry = 0x77;
                return TRUE;
        }
-
+       // Paging is enabled
        UINT32 page_dir = cpustate->program->read_data32(pdbr + directory * 4);
        if(page_dir & 1)
        {
-               if ((page_dir & 0x80) && (cpustate->cr[4] & 0x10))
+               if ((page_dir & 0x80) && (cpustate->cr[4] & I386_CR4_PSE))
                {
                        a = (page_dir & 0xffc00000) | (a & 0x003fffff);
                        if(debug)
@@ -785,7 +785,7 @@ static int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
 
 INLINE int translate_address(i386_state *cpustate, int pl, int type, UINT32 *address, UINT32 *error)
 {
-       if(!(cpustate->cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
+       if(!(cpustate->cr[0] & I386_CR0_PG)) // Some (very few) old OS's won't work with this
                return TRUE;
 
        const vtlb_entry *table = vtlb_table(cpustate->vtlb);