Previous 15994 Revisions Next

r14599 Friday 24th February, 2012 at 00:38:41 UTC by Barry Rodewald
i386: Prevent page faults when returning to same privilege and unmapped pages are above the stack. Windows 95 boots now. [Carl]
[src/emu/cpu/i386]i386.c

src/emu/cpu/i386/i386.c
r14598r14599
19151915static void i386_protected_mode_retf(i386_state* cpustate, UINT8 count, UINT8 operand32)
19161916{
19171917   UINT32 newCS, newEIP;
1918   UINT32 newSS, newESP;  // when changing privilege
19191918   I386_SREG desc;
19201919   UINT8 CPL, RPL, DPL;
19211920
r14598r14599
19251924   {
19261925      newEIP = READ16(cpustate, ea) & 0xffff;
19271926      newCS = READ16(cpustate, ea+2) & 0xffff;
1928      ea += count+4;
1929      newESP = READ16(cpustate, ea) & 0xffff;
1930      newSS = READ16(cpustate, ea+2) & 0xffff;
19311927   }
19321928   else
19331929   {
19341930      newEIP = READ32(cpustate, ea);
19351931      newCS = READ32(cpustate, ea+4) & 0xffff;
1936      ea += count+8;
1937      newESP = READ32(cpustate, ea);
1938      newSS = READ32(cpustate, ea+4) & 0xffff;
19391932   }
19401933
19411934   memset(&desc, 0, sizeof(desc));
r14598r14599
20312024   }
20322025   else if(RPL > CPL)
20332026   {
2027      UINT32 newSS, newESP;  // when changing privilege
20342028      /* outer privilege level */
20352029      if(operand32 == 0)
20362030      {
r14598r14599
20502044            FAULT(FAULT_SS,0)
20512045         }
20522046      }
2053
20542047      /* Check CS selector and descriptor */
20552048      if((newCS & ~0x03) == 0)
20562049      {
r14598r14599
21042097         logerror("RETF: EIP is past return CS segment limit.\n");
21052098         FAULT(FAULT_GP,0)
21062099      }
2100     
2101      if(operand32 == 0)
2102      {
2103         ea += count+4;
2104         newESP = READ16(cpustate, ea) & 0xffff;
2105         newSS = READ16(cpustate, ea+2) & 0xffff;
2106      }
2107      else
2108      {
2109         ea += count+8;
2110         newESP = READ32(cpustate, ea);
2111         newSS = READ32(cpustate, ea+4) & 0xffff;
2112      }
2113     
21072114      /* Check SS selector and descriptor */
21082115      desc.selector = newSS;
21092116      i386_load_protected_mode_segment(cpustate,&desc);
r14598r14599
21912198      newEIP = READ16(cpustate, ea) & 0xffff;
21922199      newCS = READ16(cpustate, ea+2) & 0xffff;
21932200      newflags = READ16(cpustate, ea+4) & 0xffff;
2194      newESP = READ16(cpustate, ea+6) & 0xffff;
2195      newSS = READ16(cpustate, ea+8) & 0xffff;
21962201   }
21972202   else
21982203   {
21992204      newEIP = READ32(cpustate, ea);
22002205      newCS = READ32(cpustate, ea+4) & 0xffff;
22012206      newflags = READ32(cpustate, ea+8);
2202      newESP = READ32(cpustate, ea+12);
2203      newSS = READ32(cpustate, ea+16) & 0xffff;
22042207   }
22052208
22062209   if(V8086_MODE)
r14598r14599
22712274      if(newflags & 0x00020000) // if returning to virtual 8086 mode
22722275      {
22732276//          UINT8 SSRPL,SSDPL;
2277         if(operand32 == 0)
2278         {
2279            newESP = READ16(cpustate, ea+6) & 0xffff;
2280            newSS = READ16(cpustate, ea+8) & 0xffff;
2281         }
2282         else
2283         {
2284            newESP = READ32(cpustate, ea+12);
2285            newSS = READ32(cpustate, ea+16) & 0xffff;
2286         }
22742287         memset(&desc, 0, sizeof(desc));
22752288         desc.selector = newCS;
22762289         i386_load_protected_mode_segment(cpustate,&desc);
r14598r14599
25472560         }
25482561         else if(RPL > CPL)
25492562         {
2550            I386_SREG stack;
25512563            /* return to outer privilege level */
25522564            memset(&desc, 0, sizeof(desc));
25532565            desc.selector = newCS;
25542566            i386_load_protected_mode_segment(cpustate,&desc);
25552567            DPL = (desc.flags >> 5) & 0x03;  // descriptor privilege level
25562568            RPL = newCS & 0x03;
2557            memset(&stack, 0, sizeof(stack));
2558            stack.selector = newSS;
2559            i386_load_protected_mode_segment(cpustate,&stack);
25602569            if(operand32 == 0)
25612570            {
25622571               UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
r14598r14599
26252634            }
26262635
26272636            /* Check SS selector and descriptor */
2637            if(operand32 == 0)
2638            {
2639               newESP = READ16(cpustate, ea+6) & 0xffff;
2640               newSS = READ16(cpustate, ea+8) & 0xffff;
2641            }
2642            else
2643            {
2644               newESP = READ32(cpustate, ea+12);
2645               newSS = READ32(cpustate, ea+16) & 0xffff;
2646            }
2647            memset(&stack, 0, sizeof(stack));
2648            stack.selector = newSS;
2649            i386_load_protected_mode_segment(cpustate,&stack);
26282650            DPL = (stack.flags >> 5) & 0x03;
26292651            if((newSS & ~0x03) == 0)
26302652            {

Previous 15994 Revisions Next


© 1998-2018 The MESS Team