OSDN Git Service

[VM][I386] Add SEGMENT descripter (internal values) to some flags to be faster emulation.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 22 May 2019 13:55:23 +0000 (22:55 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 22 May 2019 13:55:23 +0000 (22:55 +0900)
source/src/vm/i386.cpp
source/src/vm/mame/emu/cpu/i386/i386.c
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
source/src/vm/mame/emu/cpu/i386/pentops.c

index f210245..f9a14b4 100644 (file)
@@ -851,7 +851,7 @@ int I386::get_shutdown_flag()
        return cpustate->shutdown;
 }
 
-#define STATE_VERSION  6
+#define STATE_VERSION  7
 
 void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
 {
@@ -860,7 +860,13 @@ void process_state_SREG(I386_SREG* val, FILEIO* state_fio)
        state_fio->StateValue(val->base);
        state_fio->StateValue(val->limit);
        state_fio->StateValue(val->d);
+       state_fio->StateValue(val->priv);
+       state_fio->StateValue(val->whole_address);
+       state_fio->StateValue(val->expand_down);
+       state_fio->StateValue(val->executable);
+       state_fio->StateValue(val->rwn);
        state_fio->StateValue(val->valid);
+       
 }
 
 void process_state_SYS_TABLE(I386_SYS_TABLE* val, FILEIO* state_fio)
index 7743986..3ae94ea 100644 (file)
@@ -104,6 +104,12 @@ static void cpu_reset_generic(i386_state* cpustate)
                seg->limit = 0;
                seg->d = 0;
                seg->valid = false;
+               seg->whole_address = false;
+               seg->expand_down = false;
+               seg->is_system = true;
+               seg->executable = false;
+               seg->rwn = false;
+               seg->priv = 0;
                return 0;
        }
 
@@ -117,8 +123,17 @@ static void cpu_reset_generic(i386_state* cpustate)
        }
 
        entry = seg->selector & ~0x7;
-       if (limit == 0 || entry + 7 > limit)
+       if (limit == 0 || entry + 7 > limit) {
+               seg->whole_address = false;
+               seg->valid       = false;
+               seg->whole_address = false;
+               seg->expand_down = (seg->flags & SREG_FLAGS_DC) ? true : false;
+               seg->is_system   = ((seg->flags & SREG_FLAGS_NS) == 0) ? true : false;
+               seg->executable  = (seg->flags & SREG_FLAGS_EX) ? true : false;
+               seg->rwn                 = (seg->flags & SREG_FLAGS_RW) ? true : false;
+               seg->priv = (seg->flags & 0x60) >> 5;
                return 0;
+       }
 
        v1 = READ32PL0(cpustate, base + entry );
        v2 = READ32PL0(cpustate, base + entry + 4 );
@@ -126,10 +141,16 @@ static void cpu_reset_generic(i386_state* cpustate)
        seg->flags = (v2 >> 8) & 0xf0ff;
        seg->base = (v2 & 0xff000000) | ((v2 & 0xff) << 16) | ((v1 >> 16) & 0xffff);
        seg->limit = (v2 & 0xf0000) | (v1 & 0xffff);
-       if (seg->flags & 0x8000)
+       if (seg->flags & SREG_FLAGS_GR)
                seg->limit = (seg->limit << 12) | 0xfff;
-       seg->d = (seg->flags & 0x4000) ? 1 : 0;
+       seg->d = (seg->flags & SREG_FLAGS_SZ) ? 1 : 0;
        seg->valid = true;
+       seg->whole_address = false;
+       seg->expand_down = (seg->flags & SREG_FLAGS_DC) ? true : false;
+       seg->is_system   = ((seg->flags & SREG_FLAGS_NS) == 0) ? true : false;
+       seg->executable  = (seg->flags & SREG_FLAGS_EX) ? true : false;
+       seg->rwn                 = (seg->flags & SREG_FLAGS_RW) ? true : false;
+       seg->priv = (seg->flags & 0x60) >> 5;
 
        if(desc)
                *desc = ((UINT64)v2<<32)|v1;
@@ -198,7 +219,7 @@ static void cpu_reset_generic(i386_state* cpustate)
                        if(cpustate->sreg[segment].selector)
                        {
                                i386_set_descriptor_accessed(cpustate, cpustate->sreg[segment].selector);
-                               cpustate->sreg[segment].flags |= 0x0001;
+                               cpustate->sreg[segment].flags |= SREG_FLAGS_AC;
                        }
                }
                else
@@ -207,6 +228,12 @@ static void cpu_reset_generic(i386_state* cpustate)
                        cpustate->sreg[segment].limit = 0xffff;
                        cpustate->sreg[segment].flags = (segment == CS) ? 0x00fb : 0x00f3;
                        cpustate->sreg[segment].d = 0;
+                       cpustate->sreg[segment].expand_down = (cpustate->sreg[segment].flags & SREG_FLAGS_DC) ? true : false;
+                       cpustate->sreg[segment].is_system        = ((cpustate->sreg[segment].flags & SREG_FLAGS_NS) == 0) ? true : false;
+                       cpustate->sreg[segment].executable  = (cpustate->sreg[segment].flags & SREG_FLAGS_EX) ? true : false;
+                       cpustate->sreg[segment].rwn              = (cpustate->sreg[segment].flags & SREG_FLAGS_RW) ? true : false;
+                       cpustate->sreg[segment].priv = (cpustate->sreg[segment].flags & 0x60) >> 5;
+                       cpustate->sreg[segment].whole_address   = false;
                        cpustate->sreg[segment].valid = true;
                }
 //             if (segment == CS && cpustate->sreg[segment].flags != old_flags)
@@ -217,13 +244,26 @@ static void cpu_reset_generic(i386_state* cpustate)
                cpustate->sreg[segment].base = cpustate->sreg[segment].selector << 4;
                cpustate->sreg[segment].d = 0;
                cpustate->sreg[segment].valid = true;
+               cpustate->sreg[segment].expand_down = (cpustate->sreg[segment].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[segment].is_system        = ((cpustate->sreg[segment].flags & SREG_FLAGS_NS) == 0) ? true : false;
+               cpustate->sreg[segment].executable  = (cpustate->sreg[segment].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[segment].rwn              = (cpustate->sreg[segment].flags & SREG_FLAGS_RW) ? true : false;
+               cpustate->sreg[segment].priv = (cpustate->sreg[segment].flags & 0x60) >> 5;
+               cpustate->sreg[segment].whole_address   = false;
+               cpustate->sreg[segment].valid = true;
 
                if( segment == CS )
                {
                        if( !cpustate->performed_intersegment_jump )
                                cpustate->sreg[segment].base |= 0xfff00000;
-                       if(cpustate->cpu_version < 0x5000)
+                       if(cpustate->cpu_version < 0x5000) {
                                cpustate->sreg[segment].flags = 0x93;
+                               cpustate->sreg[segment].expand_down = (cpustate->sreg[segment].flags & SREG_FLAGS_DC) ? true : false;
+                               cpustate->sreg[segment].is_system        = ((cpustate->sreg[segment].flags & SREG_FLAGS_NS) == 0) ? true : false;
+                               cpustate->sreg[segment].executable  = (cpustate->sreg[segment].flags & SREG_FLAGS_EX) ? true : false;
+                               cpustate->sreg[segment].rwn              = (cpustate->sreg[segment].flags & SREG_FLAGS_RW) ? true : false;
+                               cpustate->sreg[segment].priv = (cpustate->sreg[segment].flags & 0x60) >> 5;
+                       }
                }
        }
 }
@@ -307,7 +347,7 @@ static UINT32 i386_get_stack_ptr(i386_state* cpustate, UINT8 privilege)
        cpustate->VIP = (f & 0x100000) ? 1 : 0;
        cpustate->ID = (f & 0x200000) ? 1 : 0;
        //if(((cpustate->eflags & 0x3000) != (f & 0x3000)) && ((f & 0x3000) == 0)) logerror("SET IOPL to 0 PC=%08X\n", cpustate->pc);
-       //if(old_vm != cpustate->VM) logerror("Change VM flag to %d at %08X\n", cpustate->VM, cpustate->pc);
+//     if(old_vm != cpustate->VM) logerror("Change VM flag to %d at %08X\n", cpustate->VM, cpustate->prev_pc);
        //if(PROTECTED_MODE) {
        cpustate->eflags = f;
        //} else {
@@ -505,13 +545,15 @@ static UINT32 i386_get_stack_ptr(i386_state* cpustate, UINT8 privilege)
        }
 
        /* Must be either a data or readable code segment */
-       if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0002)) || (desc.flags & 0x0018) == 0x0010)
+//     if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0002)) || (desc.flags & 0x0018) == 0x0010)
+       if(((!(desc.is_system) && (desc.executable)) && (desc.rwn)) || (!(desc.is_system) && !(desc.executable)))
                invalid = 0;
        else
                invalid = 1;
 
        /* If a data segment or non-conforming code segment, then either DPL >= CPL or DPL >= RPL */
-       if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0004) == 0) || (desc.flags & 0x0018) == 0x0010)
+//     if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0004) == 0) || (desc.flags & 0x0018) == 0x0010)
+       if(((!(desc.is_system) && (desc.executable)) && !(desc.expand_down)) || (!(desc.is_system) && !(desc.executable)))
        {
                if((DPL < CPL) || (DPL < RPL))
                        invalid = 1;
@@ -603,6 +645,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        FAULT(FAULT_GP,selector & ~0x03)
                }
                if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0)
+               //if(!(!(stack.is_system) && (stack.executable)) && (stack.rwn))
                {
                        logerror("SReg Load (%08x): Segment is not a writable data segment.\n",cpustate->pc);
                        FAULT(FAULT_GP,selector & ~0x03)
@@ -612,7 +655,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        logerror("SReg Load (%08x): Segment DPL does not equal CPL.\n",cpustate->pc);
                        FAULT(FAULT_GP,selector & ~0x03)
                }
-               if(!(stack.flags & 0x0080))
+               if(!(stack.flags & SREG_FLAGS_PR))
                {
                        logerror("SReg Load (%08x): Segment is not present.\n",cpustate->pc);
                        FAULT(FAULT_SS,selector & ~0x03)
@@ -651,15 +694,18 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
+//             if(!(!(desc.is_system) && !(desc.executable)))
                if((desc.flags & 0x0018) != 0x10)
                {
-                       if((((desc.flags & 0x0002) != 0) && ((desc.flags & 0x0018) != 0x18)) || !(desc.flags & 0x10))
+//                     if((((desc.flags & 0x0002) != 0) && ((desc.flags & 0x0018) != 0x18)) || !(desc.flags & 0x10))
+                       if(((desc.rwn) && !(!(desc.is_system) && (desc.executable))) || (desc.is_system))
                        {
                                logerror("SReg Load (%08x): Segment is not a data segment or readable code segment.\n",cpustate->pc);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
-               if(((desc.flags & 0x0018) == 0x10) || ((!(desc.flags & 0x0004)) && ((desc.flags & 0x0018) == 0x18)))
+//             if(((desc.flags & 0x0018) == 0x10) || ((!(desc.flags & 0x0004)) && ((desc.flags & 0x0018) == 0x18)))
+               if((!(desc.is_system) && !(desc.executable)) || (!(desc.expand_down) && (!(desc.is_system) && (desc.executable))))
                {
                        // if data or non-conforming code segment
                        if((RPL > DPL) || (CPL > DPL))
@@ -794,7 +840,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        }
                }
 
-               if((flags & 0x0080) == 0)
+               if((flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("IRQ: Vector segment is not present.\n");
                        FAULT_EXP(FAULT_NP,entry+2)
@@ -819,19 +865,20 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                        FAULT_EXP(FAULT_TS,segment & ~0x03);
                                }
                        }
-                       if((desc.flags & 0x000f) != 0x09 && (desc.flags & 0x000f) != 0x01)
+                       UINT16 tmpflag = desc.flags & (SREG_FLAGS_AC | SREG_FLAGS_RW | SREG_FLAGS_DC | SREG_FLAGS_EX);
+                       if(tmpflag != (SREG_FLAGS_AC | SREG_FLAGS_EX)  && tmpflag != SREG_FLAGS_AC)
                        {
                                logerror("IRQ: Task gate: TSS is not an available TSS.\n");
                                FAULT_EXP(FAULT_TS,segment & ~0x03);
                        }
-                       if((desc.flags & 0x0080) == 0)
+                       if((desc.flags & SREG_FLAGS_PR) == 0)
                        {
                                logerror("IRQ: Task gate: TSS is not present.\n");
                                FAULT_EXP(FAULT_NP,segment & ~0x03);
                        }
                        if(!(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1))
                                cpustate->eip = cpustate->prev_eip;
-                       if(desc.flags & 0x08)
+                       if(desc.flags & SREG_FLAGS_EX)
                                i386_task_switch(cpustate,desc.selector,1);
                        else
                                i286_task_switch(cpustate,desc.selector,1);
@@ -868,17 +915,17 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                        FAULT_EXP(FAULT_GP,(segment & 0x03)+cpustate->ext)
                                }
                        }
-                       if((desc.flags & 0x0018) != 0x18)
+                       if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                        {
                                logerror("IRQ: Gate descriptor is not a code segment.\n");
                                FAULT_EXP(FAULT_GP,(segment & 0x03)+cpustate->ext)
                        }
-                       if((desc.flags & 0x0080) == 0)
+                       if((desc.flags & SREG_FLAGS_PR) == 0)
                        {
                                logerror("IRQ: Gate segment is not present.\n");
                                FAULT_EXP(FAULT_NP,(segment & 0x03)+cpustate->ext)
                        }
-                       if((desc.flags & 0x0004) == 0 && (DPL < CPL))
+                       if((desc.flags & SREG_FLAGS_DC) == 0 && (DPL < CPL))
                        {
                                /* IRQ to inner privilege */
                                I386_SREG stack;
@@ -929,12 +976,12 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                        logerror("IRQ: New stack segment DPL is not equal to code segment DPL.\n");
                                        FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext)
                                }
-                               if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0)
+                               if(((stack.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != SREG_FLAGS_NS) && (stack.flags & SREG_FLAGS_RW) != 0)
                                {
                                        logerror("IRQ: New stack segment is not a writable data segment.\n");
                                        FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext) // #TS(stack selector + EXT)
                                }
-                               if((stack.flags & 0x0080) == 0)
+                               if((stack.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("IRQ: New stack segment is not present.\n");
                                        FAULT_EXP(FAULT_SS,(stack.selector & ~0x03)+cpustate->ext) // #TS(stack selector + EXT)
@@ -942,7 +989,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                newESP = i386_get_stack_ptr(cpustate,DPL);
                                if(type & 0x08) // 32-bit gate
                                {
-                                       if(((newESP < (V8086_MODE?36:20)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?36:20))) && (stack.flags & 0x4)))
+                                       if(((newESP < (V8086_MODE?36:20)) && !(stack.flags & SREG_FLAGS_DC)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?36:20))) && (stack.flags & SREG_FLAGS_DC)))
                                        {
                                                logerror("IRQ: New stack has no space for return addresses.\n");
                                                FAULT_EXP(FAULT_SS,0)
@@ -951,7 +998,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                                else // 16-bit gate
                                {
                                        newESP &= 0xffff;
-                                       if(((newESP < (V8086_MODE?18:10)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?18:10))) && (stack.flags & 0x4)))
+                                       if(((newESP < (V8086_MODE?18:10)) && !(stack.flags & SREG_FLAGS_DC)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?18:10))) && (stack.flags & SREG_FLAGS_DC)))
                                        {
                                                logerror("IRQ: New stack has no space for return addresses.\n");
                                                FAULT_EXP(FAULT_SS,0)
@@ -1019,7 +1066,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                        else
                        {
                                int stack_limit;
-                               if((desc.flags & 0x0004) || (DPL == CPL))
+                               if((desc.flags & SREG_FLAGS_DC) || (DPL == CPL))
                                {
                                        /* IRQ to same privilege */
                                        if(V8086_MODE && !cpustate->ext)
@@ -1055,8 +1102,8 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                try
                {
                        // this is ugly but the alternative is worse
-                       //if(/*type != 0x0e && type != 0x0f */(type & 0x08) == 0)  // if not 386 interrupt or trap gate
-                       if(type != 0x0e && type != 0x0f)  // if not 386 interrupt or trap gate
+                       if((type & 0x08) == 0)  // if not 386 interrupt or trap gate
+                               //if(type != 0x0e && type != 0x0f)  // if not 386 interrupt or trap gate
                        {
                                PUSH16(cpustate, oldflags & 0xffff );
                                PUSH16(cpustate, cpustate->sreg[CS].selector );
@@ -1161,23 +1208,34 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
 static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int trap_level, UINT32 error, int is_top)
 {
        // buffering direct call from trap.
+       UINT32 nowESP;/* = REG32(ESP)*/;
+       if((irq_gate == 0) &&
+          ((irq == FAULT_DE) || (irq == FAULT_DB) ||  (irq == FAULT_BR) || (irq == FAULT_UD) || (irq == FAULT_NM) || (irq == FAULT_NM)))  {
+//             if(cpustate->backout_sp != 0) {
+//                     REG32(ESP) = cpustate->old_esp;
+//             }
+       }
        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;
+//                     return;
                } catch(UINT32 e) {
                        logerror("Irregular exception happened %08x for 16bit.\n", e);
-                       return;
+//                     return;
                }
        } else {
                i386_trap(cpustate,irq,irq_gate,trap_level);
        }               
                
-       if(irq == FAULT_DF || irq == FAULT_TS || irq == FAULT_NP || irq == FAULT_SS || irq == FAULT_GP || irq == FAULT_PF /*|| irq == FAULT_AC */)
+       if(irq == FAULT_DF || irq == FAULT_TS || irq == FAULT_NP || irq == FAULT_SS || irq == FAULT_GP || irq == FAULT_PF || irq == FAULT_AC)
        {
-               //if((irq == FAULT_AC) || (irq == FAULT_DF)) error = 0;
+//             nowESP = REG32(ESP);
+//             if(cpustate->backout_sp != 0) {
+//                     REG32(ESP) = cpustate->old_esp;
+//             }
+               if((irq == FAULT_AC) || (irq == FAULT_DF)) error = 0;
                // for these exceptions, an error code is pushed onto the stack by the processor.
                // no error code is pushed for software interrupts, either.
                if(PROTECTED_MODE)
@@ -1192,13 +1250,13 @@ static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int
                                        v2 = READ32PL0(cpustate, cpustate->gdtr.base + ((v2 >> 16) & 0xfff8) + 4);
                                        type = (v2>>8) & 0x1F;
                                }
-                               if(type >= 9)
+                               if(type == 9)
                                        PUSH32(cpustate,error);
                                else
                                        PUSH16(cpustate,error);
                }
                else {
-                               PUSH16(cpustate,error);
+                       PUSH16(cpustate,error);
                }
        }
 }
@@ -1509,10 +1567,11 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
        
        //logerror("JMP: protected mode PC=%08X SEG=%04x OFFSET=%08x VALID=%s BASE=%08x LIMIT=%08x FLAGS=%08x INDIRECT=%s OP32=%s V8086=%s CPL=%d DPL=%d RPL=%d\n", cpustate->prev_pc, seg, off,  (desc.valid) ? "YES" : "NO", desc.base, desc.limit, desc.flags, (indirect != 0) ? "YES" : "NO", (operand32 != 0) ? "YES" : "NO" ,(V8086_MODE) ? "YES" : "NO", CPL, DPL, RPL);
 
-       if((desc.flags & 0x0018) == 0x0018)
+//     if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) == (SREG_FLAGS_NS | SREG_FLAGS_EX))
+       if(!(desc.is_system) && (desc.executable))
        {
                /* code segment */
-               if((desc.flags & 0x0004) == 0)
+               if(!(desc.expand_down))
                {
                        /* non-conforming */
                        if(RPL < CPL)
@@ -1536,7 +1595,7 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                        }
                }
                SetRPL = 1;
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("JMP: Segment is not present\n");
                        FAULT(FAULT_NP,segment & 0xfffc)
@@ -1549,7 +1608,8 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
        }
        else
        {
-               if((desc.flags & 0x0010) != 0)
+//             if(!(desc.executable))
+               if(!(desc.is_system))
                {
                        logerror("JMP: Segment is a data segment\n");
                        FAULT(FAULT_GP,segment & 0xfffc)  // #GP (cannot execute code in a data segment)
@@ -1575,15 +1635,16 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                                        logerror("JMP: TSS: DPL %i is less than TSS RPL %i\n",DPL,RPL);
                                        FAULT(FAULT_GP,segment & 0xfffc)
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("JMP: TSS: Segment is not present\n");
                                        FAULT(FAULT_GP,segment & 0xfffc)
                                }
-                               if(desc.flags & 0x0008)
+                               if(desc.flags & SREG_FLAGS_EX)
                                        i386_task_switch(cpustate,desc.selector,0);
                                else
                                        i286_task_switch(cpustate,desc.selector,0);
+                               
                                return;
                        case 0x04:  // 286 Call Gate
                        case 0x0c:  // 386 Call Gate
@@ -1603,7 +1664,7 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                                        logerror("JMP: Call Gate: DPL %i is less than RPL %i\n",DPL,RPL);
                                        FAULT(FAULT_GP,segment & 0xfffc)
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("JMP: Call Gate: Segment is not present\n");
                                        FAULT(FAULT_NP,segment & 0xfffc)
@@ -1633,7 +1694,7 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                                desc.selector = call_gate.selector;
                                i386_load_protected_mode_segment(cpustate,&desc,NULL);
                                DPL = (desc.flags >> 5) & 0x03;
-                               if((desc.flags & 0x0018) != 0x18)
+                               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                                {
                                        logerror("JMP: Call Gate: Gate does not point to a code segment\n");
                                        FAULT(FAULT_GP,call_gate.selector & 0xfffc)
@@ -1654,7 +1715,7 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                                                FAULT(FAULT_GP,call_gate.selector & 0xfffc)
                                        }
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("JMP: Call Gate: Gate Segment is not present\n");
                                        FAULT(FAULT_NP,call_gate.selector & 0xfffc)
@@ -1720,6 +1781,7 @@ static void i386_protected_mode_jump(i386_state *cpustate, UINT16 seg, UINT32 of
                                        i386_task_switch(cpustate,call_gate.selector,0);
                                else
                                        i286_task_switch(cpustate,call_gate.selector,0);
+                               // CPU_SET_PREV_ESP();
                                return;
                        default:  // invalid segment type
                                logerror("JMP: Invalid segment type (%i) to jump to.\n",desc.flags & 0x000f);
@@ -1780,7 +1842,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
        DPL = (desc.flags >> 5) & 0x03;  // descriptor privilege level
        RPL = selector & 0x03;  // requested privilege level
        //logerror("CALL: protected mode PC=%08X SEG=%04x OFFSET=%08x VALID=%s BASE=%08x LIMIT=%08x FLAGS=%08x INDIRECT=%s OP32=%s V8086=%s CPL=%d DPL=%d RPL=%d\n", cpustate->prev_pc, seg, off,  (desc.valid) ? "YES" : "NO", desc.base, desc.limit, desc.flags, (indirect != 0) ? "YES" : "NO", (operand32 != 0) ? "YES" : "NO" ,(V8086_MODE) ? "YES" : "NO", CPL, DPL, RPL);
-       if((desc.flags & 0x0018) == 0x18)  // is a code segment
+       if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) == (SREG_FLAGS_NS | SREG_FLAGS_EX))  // is a code segment
        {
                if(desc.flags & 0x0004)
                {
@@ -1806,7 +1868,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                        }
                }
                SetRPL = 1;
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("CALL (%08x): Code segment is not present.\n",cpustate->pc);
                        FAULT(FAULT_NP,selector & ~0x03)  // #NP(selector)
@@ -1838,7 +1900,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
        else
        {
                /* special segment type */
-               if(desc.flags & 0x0010)
+               if(desc.flags & SREG_FLAGS_NS)
                {
                        logerror("CALL: Segment is a data segment.\n");
                        FAULT(FAULT_GP,desc.selector & ~0x03)  // #GP(selector)
@@ -1924,7 +1986,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        }
                                }
                                i386_load_protected_mode_segment(cpustate,&desc,NULL);
-                               if((desc.flags & 0x0018) != 0x18)
+                               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                                {
                                        logerror("CALL: Call gate: Segment is not a code segment.\n");
                                        FAULT(FAULT_GP,desc.selector & ~0x03)  // #GP(selector)
@@ -1935,7 +1997,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        logerror("CALL: Call gate: Segment DPL %i is greater than CPL %i.\n",DPL,CPL);
                                        FAULT(FAULT_GP,desc.selector & ~0x03)  // #GP(selector)
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("CALL (%08x): Code segment is not present.\n",cpustate->pc);
                                        FAULT(FAULT_NP,desc.selector & ~0x03)  // #NP(selector)
@@ -1981,12 +2043,12 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                                logerror("CALL: Call gate: Stack DPL does not equal code segment DPL %i\n",DPL);
                                                FAULT(FAULT_TS,stack.selector)  // #TS(SS selector)
                                        }
-                                       if((stack.flags & 0x0018) != 0x10 && (stack.flags & 0x0002))
+                                       if((stack.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != SREG_FLAGS_NS && (stack.rwn))
                                        {
                                                logerror("CALL: Call gate: Stack segment is not a writable data segment\n");
                                                FAULT(FAULT_TS,stack.selector)  // #TS(SS selector)
                                        }
-                                       if((stack.flags & 0x0080) == 0)
+                                       if((stack.flags & SREG_FLAGS_PR) == 0)
                                        {
                                                logerror("CALL: Call gate: Stack segment is not present\n");
                                                FAULT(FAULT_SS,stack.selector)  // #SS(SS selector)
@@ -2146,7 +2208,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        logerror("CALL: Task Gate: TSS is busy.\n");
                                        FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector)
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("CALL: Task Gate: TSS is not present.\n");
                                        FAULT(FAULT_NP,gate.selector & ~0x03) // #TS(selector)
@@ -2267,7 +2329,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                                FAULT(FAULT_GP,newCS & ~0x03)
                        }
                }
-               if((desc.flags & 0x0018) != 0x0018)
+               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                {
                        logerror("RETF: Return segment is not a code segment.\n");
                        FAULT(FAULT_GP,newCS & ~0x03)
@@ -2288,7 +2350,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                                FAULT(FAULT_GP,newCS & ~0x03)
                        }
                }
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("RETF (%08x): Code segment is not present.\n",cpustate->pc);
                        FAULT(FAULT_NP,newCS & ~0x03)
@@ -2365,7 +2427,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                                FAULT(FAULT_GP,newCS & ~0x03)
                        }
                }
-               if((desc.flags & 0x0018) != 0x0018)
+               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                {
                        logerror("RETF: CS segment is not a code segment.\n");
                        FAULT(FAULT_GP,newCS & ~0x03)
@@ -2386,7 +2448,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                                FAULT(FAULT_GP,newCS & ~0x03)
                        }
                }
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("RETF: CS segment is not present.\n");
                        FAULT(FAULT_NP,newCS & ~0x03)
@@ -2440,7 +2502,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                        logerror("RETF: SS segment RPL is not equal to CS segment RPL.\n");
                        FAULT(FAULT_GP,newSS & ~0x03)
                }
-               if((desc.flags & 0x0018) != 0x0010 || (desc.flags & 0x0002) == 0)
+               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != SREG_FLAGS_NS || !(desc.rwn))
                {
                        logerror("RETF: SS segment is not a writable data segment.\n");
                        FAULT(FAULT_GP,newSS & ~0x03)
@@ -2450,7 +2512,7 @@ static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 op
                        logerror("RETF: SS DPL is not equal to CS segment RPL.\n");
                        FAULT(FAULT_GP,newSS & ~0x03)
                }
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("RETF: SS segment is not present.\n");
                        FAULT(FAULT_GP,newSS & ~0x03)
@@ -2566,7 +2628,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        logerror("IRET (%08x): Task return: Back-linked TSS is not a busy TSS.\n",cpustate->pc);
                        FAULT(FAULT_TS,task & ~0x03)
                }
-               if((desc.flags & 0x0080) == 0)
+               if((desc.flags & SREG_FLAGS_PR) == 0)
                {
                        logerror("IRET: Task return: Back-linked TSS is not present.\n");
                        FAULT(FAULT_NP,task & ~0x03)
@@ -2703,7 +2765,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                i386_load_protected_mode_segment(cpustate,&desc,NULL);
                                DPL = (desc.flags >> 5) & 0x03;  // descriptor privilege level
                                RPL = newCS & 0x03;
-                               if((desc.flags & 0x0018) != 0x0018)
+                               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                                {
                                        logerror("IRET (%08x): Return CS segment is not a code segment.\n",cpustate->pc);
                                        FAULT(FAULT_GP,newCS & ~0x07)
@@ -2724,7 +2786,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                                FAULT(FAULT_GP,newCS & ~0x03)
                                        }
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("IRET: (%08x) Return CS segment is not present.\n", cpustate->pc);
                                        FAULT(FAULT_NP,newCS & ~0x03)
@@ -2809,7 +2871,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                                FAULT(FAULT_GP,newCS & ~0x03);
                                        }
                                }
-                               if((desc.flags & 0x0018) != 0x0018)
+                               if((desc.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != (SREG_FLAGS_NS | SREG_FLAGS_EX))
                                {
                                        logerror("IRET: Return CS segment is not a code segment.\n");
                                        FAULT(FAULT_GP,newCS & ~0x03)
@@ -2830,7 +2892,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                                FAULT(FAULT_GP,newCS & ~0x03)
                                        }
                                }
-                               if((desc.flags & 0x0080) == 0)
+                               if((desc.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("IRET: Return CS segment is not present.\n");
                                        FAULT(FAULT_NP,newCS & ~0x03)
@@ -2877,12 +2939,12 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                        logerror("IRET: Return SS RPL is not equal to return CS RPL.\n");
                                        FAULT(FAULT_GP,newSS & ~0x03)
                                }
-                               if((stack.flags & 0x0018) != 0x0010)
+                               if((stack.flags & (SREG_FLAGS_NS | SREG_FLAGS_EX)) != SREG_FLAGS_NS)
                                {
                                        logerror("IRET: Return SS segment is not a data segment.\n");
                                        FAULT(FAULT_GP,newSS & ~0x03)
                                }
-                               if((stack.flags & 0x0002) == 0)
+                               if(!(stack.rwn))
                                {
                                        logerror("IRET: Return SS segment is not writable.\n");
                                        FAULT(FAULT_GP,newSS & ~0x03)
@@ -2892,7 +2954,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                                        logerror("IRET: Return SS DPL does not equal SS RPL.\n");
                                        FAULT(FAULT_GP,newSS & ~0x03)
                                }
-                               if((stack.flags & 0x0080) == 0)
+                               if((stack.flags & SREG_FLAGS_PR) == 0)
                                {
                                        logerror("IRET: Return SS segment is not present.\n");
                                        FAULT(FAULT_NP,newSS & ~0x03)
@@ -3477,6 +3539,16 @@ static CPU_RESET( i386 )
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
        cpustate->sreg[DS].valid = cpustate->sreg[ES].valid = cpustate->sreg[FS].valid = cpustate->sreg[GS].valid = cpustate->sreg[SS].valid =true;
 
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
        cpustate->smm = false;
@@ -3783,16 +3855,16 @@ static CPU_EXECUTE( i386 )
                        catch(UINT64 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); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->prev_pc, cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, 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); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->prev_pc, 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"); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=UNKNOWN\n", cpustate->prev_pc, cpustate->eip, (cpustate->VM) ? "YES" : "NO"); 
                                i386_trap_with_error(cpustate,0,0,0,0, 1);
                        }
                        
@@ -3857,19 +3929,19 @@ static CPU_EXECUTE( i386 )
                        catch(UINT64 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); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->prev_pc, cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, 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); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n",cpustate->prev_pc, 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); 
+                               logerror("Illegal instruction PC=%08X EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n",cpustate->prev_pc, cpustate->eip, (cpustate->VM) ? "YES" : "NO", 0, 0); 
                                i386_trap_with_error(cpustate,0,0,0,0, 1);
                        }
 //#ifdef SINGLE_MODE_DMA
@@ -3939,6 +4011,16 @@ static CPU_RESET( i486 )
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
 
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;
+       }               
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
 
@@ -3994,6 +4076,16 @@ static CPU_RESET( pentium )
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
 
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;
+       }               
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
 
@@ -4065,6 +4157,16 @@ static CPU_RESET( mediagx )
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;
+       }               
 
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
@@ -4129,6 +4231,16 @@ static CPU_RESET( pentium_pro )
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
 
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
@@ -4202,6 +4314,16 @@ static CPU_RESET( pentium_mmx )
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].valid = true;
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
 
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
@@ -4274,6 +4396,16 @@ static CPU_RESET( pentium2 )
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].valid = true; // OK?
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
 
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
@@ -4340,6 +4472,16 @@ static CPU_RESET( pentium3 )
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].valid = true; // OK?
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
 
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
@@ -4404,11 +4546,28 @@ static CPU_RESET( pentium4 )
        cpustate->sreg[CS].base     = 0xffff0000;
        cpustate->sreg[CS].limit    = 0xffff;
        cpustate->sreg[CS].flags    = 0x0093;
-
+       cpustate->sreg[CS].d        = 0;
+       cpustate->sreg[CS].whole_address    = false;
+       cpustate->sreg[CS].expand_down          = false;
+       cpustate->sreg[CS].rwn                          = true;
+       cpustate->sreg[CS].is_system            = false;
+       cpustate->sreg[CS].executable           = true;
+       cpustate->sreg[CS].priv                         = 0;
+       
        cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
        cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
        cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0093;
-
+       for(int i = 0; i <= GS; i++) {
+               cpustate->sreg[i].priv = 0;
+               cpustate->sreg[i].valid = true; // OK?
+               cpustate->sreg[i].d = 0; // OK?
+               cpustate->sreg[i].whole_address = false;
+               cpustate->sreg[i].rwn         = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false;;
+               cpustate->sreg[i].expand_down = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[i].executable  = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[i].is_system   = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false;;
+       }               
+       
        cpustate->idtr.base = 0;
        cpustate->idtr.limit = 0x3ff;
 
index bb25a83..e96d279 100644 (file)
@@ -3441,8 +3441,9 @@ static void I386OP(group0F01_16)(i386_state *cpustate)      // Opcode 0x0f 01
                                        FAULT(FAULT_GP,0)
                                }
                                if( modrm >= 0xc0 ) {
-                                       address = LOAD_RM16(modrm);
-                                       ea = i386_translate(cpustate, CS, address, 0, 6 );
+                                       //address = LOAD_RM16(modrm);
+                                       //ea = i386_translate(cpustate, CS, address, 0, 6 );
+                                       FAULT(FAULT_UD,0)
                                } else {
                                        ea = GetEA(cpustate,modrm,0,6);
                                }
index 57f0dfa..24ae52a 100644 (file)
@@ -3207,8 +3207,9 @@ static void I386OP(group0F01_32)(i386_state *cpustate)      // Opcode 0x0f 01
                                if(PROTECTED_MODE && cpustate->CPL)
                                        FAULT(FAULT_GP,0)
                                if( modrm >= 0xc0 ) {
-                                       address = LOAD_RM32(modrm);
-                                       ea = i386_translate(cpustate, CS, address, 0, 6 );
+                                       //      address = LOAD_RM32(modrm);
+                                       //      ea = i386_translate(cpustate, CS, address, 0, 6 );
+                                       FAULT(FAULT_UD,0)
                                } else {
                                        ea = GetEA(cpustate,modrm,0,6);
                                }
index 3c8be1e..9ce14c3 100644 (file)
@@ -310,6 +310,11 @@ static void I386OP(cli)(i386_state *cpustate)               // Opcode 0xfa
        if(PROTECTED_MODE)
        {
                UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+               if(V8086_MODE) {
+                       if(IOPL < 3) {
+                               FAULT(FAULT_GP,0);
+                       }
+               } else
                if(cpustate->CPL > IOPL) {
                        logerror("Privilege error: I386OP(cli) CPL=%d IOPL=%d PC=%08X\n", cpustate->CPL, IOPL, cpustate->pc); 
                        FAULT(FAULT_GP,0);
@@ -660,7 +665,7 @@ static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
 #if 1
        UINT32 oldpc = cpustate->prev_pc;
        if((PROTECTED_MODE && ((V8086_MODE) || (cpustate->CPL != 0)))) {
-               logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr) at %08X", oldpc); 
+               logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr) at %08X V8086=%s CPL=%d", oldpc, (V8086_MODE) ? "YES" : "NO", cpustate->CPL); 
                FAULT(FAULT_GP, 0);
                //return;
        }
@@ -1877,6 +1882,11 @@ static void I386OP(sti)(i386_state *cpustate)               // Opcode 0xfb
        if(PROTECTED_MODE)
        {
                UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+               if(V8086_MODE) {
+                       if(IOPL < 3) {
+                               FAULT(FAULT_GP,0);
+                       }
+               } else 
                if(cpustate->CPL > IOPL) {
                        logerror("Privilege error: I386OP(sti) CPL=%d IOPL=%d\n", cpustate->CPL, IOPL); 
                        FAULT(FAULT_GP,0);
@@ -2816,11 +2826,16 @@ static void I386OP(loadall)(i386_state *cpustate)       // Opcode 0x0f 0x07 (0x0
        cpustate->sreg[ES].base = READ32(cpustate, ea + 0xc4);
        cpustate->sreg[ES].limit = READ32(cpustate, ea + 0xc8);
        cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3; // cpl == dpl of ss
-
+       
        for(int i = 0; i <= GS; i++)
        {
-               cpustate->sreg[i].valid = (cpustate->sreg[i].flags & 0x80) ? true : false;
-               cpustate->sreg[i].d = (cpustate->sreg[i].flags & 0x4000) ? 1 : 0;
+               cpustate->sreg[i].valid                 = (cpustate->sreg[i].flags & SREG_FLAGS_PR) ? true : false;
+               cpustate->sreg[i].d                             = (cpustate->sreg[i].flags & SREG_FLAGS_SZ) ? 1 : 0;
+               cpustate->sreg[i].whole_address = false; // From NP2 v0.83
+               cpustate->sreg[i].is_system     = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false; // From NP2 v0.83
+               cpustate->sreg[i].executable    = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false; // From NP2 v0.83
+               cpustate->sreg[i].expand_down   = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false; // From NP2 v0.83
+               cpustate->sreg[i].rwn                   = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false; // From NP2 v0.83
        }
        CHANGE_PC(cpustate, cpustate->eip);
 }
index 8993814..e8acf62 100644 (file)
@@ -296,12 +296,35 @@ enum smram_intel_p5
 #define MXCSR_RC  (3<<13) // Rounding Control
 #define MXCSR_FZ  (1<<15) // Flush to Zero
 
+// IN SEGMENT DESCRIPTOR TABLE
+// ACCESS BYTE BITFIELDS (bit40-47) 
+#define SREG_FLAGS_AC          0x0001 /* '1' is before accessed */
+#define SREG_FLAGS_RW          0x0002 /* READABLE for CODE SEGMENT/WRITABLE for DATA SEGMENT*/
+#define SREG_FLAGS_DC          0x0004 /* '1' to expand down, '0' to expand up */
+#define SREG_FLAGS_EX          0x0008 /* '1' to executable */
+#define SREG_FLAGS_NS          0x0010 /* '0' to system-segment */ 
+#define SREG_FLAGS_PRIV_LO     0x0020 /* PRIVILEGE (0 to 3) */
+#define SREG_FLAGS_PRIV_HI     0x0040
+#define SREG_FLAGS_PR          0x0080 /* '1' = valid segment */
+
+// FLAGS (bit52-55)
+#define SREG_FLAGS_RESV1       0x1000
+#define SREG_FLAGS_RESV2       0x2000
+#define SREG_FLAGS_SZ          0x4000 /* '1' at 32bit protected mode */
+#define SREG_FLAGS_GR          0x8000 /* '1' at limit multiplies to $1000 */
+
 struct I386_SREG {
        UINT16 selector;
        UINT16 flags;
        UINT32 base;
        UINT32 limit;
        int d;      // Operand size
+       uint8_t priv;
+       bool whole_address;
+       bool expand_down;
+       bool is_system;
+       bool executable;
+       bool rwn;
        bool valid;
 };
 
@@ -674,26 +697,72 @@ extern MODRM_TABLE i386_MODRM_table[256];
 INLINE int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size)
 {
 //     size = 1; // TBD
+       // Re-Implement From NP2 v0.83
        if(PROTECTED_MODE && !V8086_MODE)
        {
-               if((cpustate->sreg[seg].flags & 0x0018) == 0x0010 && cpustate->sreg[seg].flags & 0x0004) // if expand-down data segment
+               UINT32 limit = cpustate->sreg[seg].limit;
+               bool is_32bit = (cpustate->sreg[seg].d != 0) ? true : false;
+               UINT32 seg_limit = (is_32bit) ? 0xffffffff : 0x0000ffff;
+               bool do_exception = false;
+               bool is_system = cpustate->sreg[seg].is_system;
+               bool executable = cpustate->sreg[seg].executable;
+               bool expand_down = cpustate->sreg[seg].expand_down;
+               if((is_32bit) && (cpustate->sreg[seg].whole_address)) return 0; // OK?
+               if(!(is_system) && !(executable) && (expand_down)) // if expand-down data segment
                {
+                       if(limit == 0) {
+                               if(!(is_32bit)) { // 16bit
+                                       if((offset + size - 1) > 0x0000ffff) {
+                                               do_exception = true;
+                                       }
+                               } else {
+                                       cpustate->sreg[seg].whole_address = true;
+                                       // SET WHOLE ADDRESS BIT.
+                               }
+                       } else { // limit != 0
+//                             if((((offset - (size - 1)) <= limit) || ((is_32bit)?0:((offset - (size - 1)) > 0xffff)))) {
+                               if((offset < limit) || ((offset + size - 1) > seg_limit) || ((offset + size - 1) < offset) ||
+                                  (seg_limit < (limit + size - 1))) {
+                                       do_exception = true;
+                               }
+                       }
+                       if(do_exception) {
+                               logerror("Limit check at 0x%08X failed. Segment %04X, base %08X, limit %08X, offset %08X size=%d(expand-down)\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].base,cpustate->sreg[seg].limit,offset, size);
+                               return 1;
+                       }
+               } else { // Expand up
+                       if((is_32bit) && ((limit == 0x00000000) || (limit == 0xffffffff))) {
+                               cpustate->sreg[seg].whole_address = true;
+                               // SET WHOLE ADDRESS BIT.
+                       } //else if((limit > seg_limit) || ((size - 1) > limit) || ((offset + size - 1) > (limit + 1)) || ((offset + size - 1) < offset)) {
+                       else if(((offset + size - 1) > limit)){
+                               do_exception = true;
+                       }
+                       if(do_exception) {
+                               logerror("Limit check at 0x%08X failed. Segment %04X, base %08X, limit %08X, offset %08X size=%d\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].base,cpustate->sreg[seg].limit,offset, size);
+                               return 1;
+                       }
+               }                       
+
+               /*
                        // compare if greater then 0xffffffff when we're passed the access size
                        //if(offset < size) size = offset;
-                       if(/*(cpustate->sreg[seg].limit != 0) && */(((offset - (size - 1)) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset - (size - 1)) > 0xffff))))
+               if(((cpustate->sreg[seg].flags & 0x18) == 0x0010) && (cpustate->sreg[seg].expand_down)) { 
+                       if((((offset - (size - 1)) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset - (size - 1)) > 0xffff))))
                        {
-                               logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
+                               logerror("Limit check at 0x%08X failed. Segment %04X, base %08X, limit %08X, offset %08X size=%d(expand-down)\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].base,cpustate->sreg[seg].limit,offset, size);
                                return 1;
                        }
                }
                else
                {
-                       if(((offset + size - 1) > cpustate->sreg[seg].limit) /*&& (cpustate->sreg[seg].limit != 0)*/)
+                       if(((offset + size - 1) > cpustate->sreg[seg].limit))
                        {
-                               logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
+                               logerror("Limit check at 0x%08X failed. Segment %04X, base %08X limit %08X, offset %08X size=%d\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].base,cpustate->sreg[seg].limit,offset, size);
                                return 1;
                        }
                }
+               */
        }
        return 0;
 }
@@ -703,14 +772,26 @@ INLINE UINT32 i386_translate(i386_state *cpustate, int segment, UINT32 ip, int r
        // TODO: segment limit access size, execution permission, handle exception thrown from exception handler
        if(PROTECTED_MODE && !V8086_MODE && (rwn != -1))
        {
+               /*
                if(!(cpustate->sreg[segment].valid))
                        FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
                if(i386_limit_check(cpustate, segment, ip, size))
                        FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
-               if((rwn == 0) && ((cpustate->sreg[segment].flags & 8) && !(cpustate->sreg[segment].flags & 2)))
+               if((rwn == 0) && ((cpustate->sreg[segment].flags& 8) && !(cpustate->sreg[segment].flags & 2)))
                        FAULT_THROW(FAULT_GP, 0);
                if((rwn == 1) && ((cpustate->sreg[segment].flags & 8) || !(cpustate->sreg[segment].flags & 2)))
                        FAULT_THROW(FAULT_GP, 0);
+               */
+               
+               if(!(cpustate->sreg[segment].valid))
+                       FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
+               if(i386_limit_check(cpustate, segment, ip, size))
+                       FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
+               if((rwn == 0) && ((cpustate->sreg[segment].executable) && !(cpustate->sreg[segment].rwn)))
+                       FAULT_THROW(FAULT_GP, 0);
+               if((rwn == 1) && ((cpustate->sreg[segment].executable) || !(cpustate->sreg[segment].rwn)))
+                       FAULT_THROW(FAULT_GP, 0);
+               
        }
        return cpustate->sreg[segment].base + ip;
 }
index ea38632..4b843a0 100644 (file)
@@ -173,11 +173,24 @@ static void PENTIUMOP(rsm)(i386_state* cpustate)
        {
                if(PROTECTED_MODE && !V8086_MODE)
                {
-                       cpustate->sreg[i].valid = cpustate->sreg[i].selector ? true : false;
-                       cpustate->sreg[i].d = (cpustate->sreg[i].flags & 0x4000) ? 1 : 0;
+                       cpustate->sreg[i].valid                 = cpustate->sreg[i].selector ? true : false;
+                       cpustate->sreg[i].d                             = (cpustate->sreg[i].flags & SREG_FLAGS_SZ) ? 1 : 0;
+                       cpustate->sreg[i].whole_address = false; // From NP2 v0.83
+                       cpustate->sreg[i].is_system     = ((cpustate->sreg[i].flags & SREG_FLAGS_NS) == 0) ? true : false; // From NP2 v0.83
+                       cpustate->sreg[i].executable    = (cpustate->sreg[i].flags & SREG_FLAGS_EX) ? true : false; // From NP2 v0.83
+                       cpustate->sreg[i].expand_down   = (cpustate->sreg[i].flags & SREG_FLAGS_DC) ? true : false; // From NP2 v0.83
+                       cpustate->sreg[i].rwn                   = (cpustate->sreg[i].flags & SREG_FLAGS_RW) ? true : false; // From NP2 v0.83
+                       cpustate->sreg[i].priv                  = (cpustate->sreg[i].flags & 0x60) >> 5;
                }
-               else
+               else {
                        cpustate->sreg[i].valid = true;
+                       cpustate->sreg[i].whole_address = false;
+                       cpustate->sreg[i].is_system = true;
+                       cpustate->sreg[i].executable = true;
+                       cpustate->sreg[i].expand_down = false;
+                       cpustate->sreg[i].rwn = true;
+                       cpustate->sreg[i].priv                  = 3;  // OK?
+               }
        }
 
 //     if(!cpustate->smiact.isnull())
@@ -2033,7 +2046,7 @@ static void I386OP(cyrix_svdc)(i386_state* cpustate) // Opcode 0f 78
 
                limit = cpustate->sreg[index].limit;
 
-               if (cpustate->sreg[index].flags & 0x8000) //G bit
+               if (cpustate->sreg[index].flags & SREG_FLAGS_GR) //G bit
                {
                        limit >>= 12;
                }
@@ -2101,7 +2114,7 @@ static void I386OP(cyrix_rsdc)(i386_state* cpustate) // Opcode 0f 79
                flags = READ16(cpustate,ea + 5);
                limit = READ16(cpustate,ea + 0) | ((flags & 3) << 16);
 
-               if (flags & 0x8000) //G bit
+               if (flags & SREG_FLAGS_GR) //G bit
                {
                        limit = (limit << 12) | 0xfff;
                }
@@ -2110,6 +2123,14 @@ static void I386OP(cyrix_rsdc)(i386_state* cpustate) // Opcode 0f 79
                cpustate->sreg[index].flags = flags;
                cpustate->sreg[index].base = base;
                cpustate->sreg[index].limit = limit;
+               cpustate->sreg[index].whole_address = 0;
+               cpustate->sreg[index].rwn         = (cpustate->sreg[index].flags & SREG_FLAGS_RW) ? true : false;
+               cpustate->sreg[index].expand_down = (cpustate->sreg[index].flags & SREG_FLAGS_DC) ? true : false;
+               cpustate->sreg[index].executable  = (cpustate->sreg[index].flags & SREG_FLAGS_EX) ? true : false;
+               cpustate->sreg[index].is_system   = ((cpustate->sreg[index].flags & SREG_FLAGS_NS) == 0) ? true : false;
+               cpustate->sreg[index].valid               = true; // OK?
+               cpustate->sreg[index].priv        = (cpustate->sreg[index].flags & 0x60) >> 5;
+               
        } else {
                i386_trap(cpustate, 6, 0, 0);
        }
@@ -2126,7 +2147,7 @@ static void I386OP(cyrix_svldt)(i386_state* cpustate) // Opcode 0f 7a
                        UINT32 ea = GetEA(cpustate,modrm,0,10);
                        UINT32 limit = cpustate->ldtr.limit;
 
-                       if (cpustate->ldtr.flags & 0x8000) //G bit
+                       if (cpustate->ldtr.flags & SREG_FLAGS_GR) //G bit
                        {
                                limit >>= 12;
                        }
@@ -2161,7 +2182,7 @@ static void I386OP(cyrix_rsldt)(i386_state* cpustate) // Opcode 0f 7b
                        UINT32 limit = READ16(cpustate,ea + 0) | ((flags & 3) << 16);
                        I386_SREG seg;
 
-                       if (flags & 0x8000) //G bit
+                       if (flags & SREG_FLAGS_GR) //G bit
                        {
                                limit = (limit << 12) | 0xfff;
                        }
@@ -2191,7 +2212,7 @@ static void I386OP(cyrix_svts)(i386_state* cpustate) // Opcode 0f 7c
                        UINT32 ea = GetEA(cpustate,modrm,0,10);
                        UINT32 limit = cpustate->task.limit;
 
-                       if (cpustate->task.flags & 0x8000) //G bit
+                       if (cpustate->task.flags & SREG_FLAGS_GR) //G bit
                        {
                                limit >>= 12;
                        }
@@ -2224,7 +2245,7 @@ static void I386OP(cyrix_rsts)(i386_state* cpustate) // Opcode 0f 7d
                        UINT32 base = (READ32(cpustate,ea + 2) | 0x00ffffff) | (READ8(cpustate,ea + 7) << 24);
                        UINT32 limit = READ16(cpustate,ea + 0) | ((flags & 3) << 16);
 
-                       if (flags & 0x8000) //G bit
+                       if (flags & SREG_FLAGS_GR) //G bit
                        {
                                limit = (limit << 12) | 0xfff;
                        }