• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: Commit

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

Revisionb4fa03bb94a9af4b7438d04da689067c93c7c652 (tree)
Zeit2019-04-09 20:07:44
AutorK.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][I386][WIP] FLAGS around IRET/POPF/POPFD.This is WIP.

Ändern Zusammenfassung

Diff

--- a/source/src/vm/mame/emu/cpu/i386/i386.c
+++ b/source/src/vm/mame/emu/cpu/i386/i386.c
@@ -2451,7 +2451,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
24512451 UINT8 CPL, RPL, DPL;
24522452 UINT32 newflags;
24532453 UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2454-
2454+ UINT32 stack_size = 6;
24552455 CPL = cpustate->CPL;
24562456 UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0, (operand32)?12:6);
24572457 if(operand32 == 0)
@@ -2459,12 +2459,14 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
24592459 newEIP = READ16(cpustate, ea) & 0xffff;
24602460 newCS = READ16(cpustate, ea+2) & 0xffff;
24612461 newflags = READ16(cpustate, ea+4) & 0xffff;
2462+ stack_size = 6;
24622463 }
24632464 else
24642465 {
24652466 newEIP = READ32(cpustate, ea);
24662467 newCS = READ32(cpustate, ea+4) & 0xffff;
24672468 newflags = READ32(cpustate, ea+8);
2469+ stack_size = 12;
24682470 }
24692471
24702472 if(V8086_MODE)
@@ -2489,9 +2491,9 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
24892491 newflags |= (oldflags & I386_EFLAGS_IOPL);
24902492 set_flags(cpustate,(newflags & 0xffff) | (oldflags & ~0xffff));
24912493 if(STACK_32BIT) {
2492- REG32(ESP) += 6;
2494+ REG32(ESP) += stack_size;
24932495 } else {
2494- REG16(SP) += 6;
2496+ REG16(SP) += stack_size;
24952497 }
24962498 }
24972499 else
@@ -2508,9 +2510,9 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
25082510 newflags |= (oldflags & I386_EFLAGS_IOPL) | I386_EFLAGS_VM;
25092511 set_flags(cpustate,newflags);
25102512 if(STACK_32BIT) {
2511- REG32(ESP) += 12;
2513+ REG32(ESP) += stack_size;
25122514 } else {
2513- REG16(SP) += 12;
2515+ REG16(SP) += stack_size;
25142516 }
25152517 }
25162518
@@ -2552,7 +2554,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
25522554 }
25532555 else
25542556 {
2555- if(newflags & 0x00020000) // if returning to virtual 8086 mode
2557+ if((newflags & 0x00020000) && (cpustate->CPL == 0)) // if returning to virtual 8086 mode
25562558 {
25572559 // 16-bit iret can't reach here
25582560 newESP = READ32(cpustate, ea+12);
--- a/source/src/vm/mame/emu/cpu/i386/i386op16.c
+++ b/source/src/vm/mame/emu/cpu/i386/i386op16.c
@@ -1744,18 +1744,18 @@ static void I386OP(popf)(i386_state *cpustate) // Opcode 0x9d
17441744 UINT32 value;
17451745 UINT32 current = get_flags(cpustate);
17461746 UINT8 IOPL = (current >> 12) & 0x03;
1747- UINT32 mask = 0x7fd5;
1747+ //UINT32 mask = 0x7fd5;
1748+ UINT32 mask = I386_EFLAGS_IF | I386_EFLAGS_IOPL | I386_EFLAGS_SZAPC | I386_EFLAGS_T | I386_EFLAGS_D | I386_EFLAGS_O | I386_EFLAGS_NT /*| I386_EFLAGS_AC | I386_EFLAGS_ID*/;
17481749 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
17491750
1751+#if 1
17501752 // IOPL can only change if CPL is 0
17511753 if(cpustate->CPL != 0) {
1752- //mask &= ~0x00003000;
17531754 mask &= ~I386_EFLAGS_IOPL;
17541755 }
17551756
17561757 // IF can only change if CPL is at least as privileged as IOPL
17571758 if(cpustate->CPL > IOPL) {
1758- //mask &= ~0x00000200;
17591759 mask &= ~I386_EFLAGS_IF;
17601760 }
17611761
@@ -1766,10 +1766,30 @@ static void I386OP(popf)(i386_state *cpustate) // Opcode 0x9d
17661766 logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc);
17671767 FAULT(FAULT_GP,0) // #GP(0)
17681768 }
1769- //mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode
17701769 mask &= ~I386_EFLAGS_IOPL; // IOPL cannot be changed while in V8086 mode
17711770 }
1772-
1771+#else
1772+ // Port from NP2
1773+ if(!(PROTECTED_MODE)) {
1774+ mask |= (I386_EFLAGS_IF | I386_EFLAGS_IOPL);
1775+ } else if(!(V8086_MODE)) {
1776+
1777+ if(cpustate->CPL == 0) {
1778+ mask |= (I386_EFLAGS_IF | I386_EFLAGS_IOPL);
1779+ } else if(cpustate->CPL <= IOPL) {
1780+ mask |= I386_EFLAGS_IF;
1781+ }
1782+ } else if(IOPL == 3) {
1783+ mask |= I386_EFLAGS_IF;
1784+ } else {
1785+ mask = 0;
1786+ logerror("POPF(%08x): Wrong mode and IOPL.PC=%08X\n",cpustate->pc);
1787+ FAULT(FAULT_GP,0); // #GP(0)
1788+ set_flags(cpustate,current); // mask out reserved bits
1789+ return;
1790+ }
1791+#endif
1792+
17731793 if(i386_limit_check(cpustate,SS,offset,2) == 0)
17741794 {
17751795 value = POP16(cpustate);
@@ -2024,7 +2044,7 @@ static void I386OP(pushf)(i386_state *cpustate) // Opcode 0x9c
20242044 offset = (REG16(SP) - 2) & 0xffff;
20252045 if(!PROTECTED_MODE || !V8086_MODE || ((cpustate->IOP1) && (cpustate->IOP2))) {
20262046 if(i386_limit_check(cpustate,SS,offset,2) == 0)
2027- PUSH16(cpustate, get_flags(cpustate) & 0xffff );
2047+ PUSH16(cpustate, (get_flags(cpustate) & 0xffff) | 0x0002 );
20282048 else
20292049 FAULT(FAULT_SS,0)
20302050 } else {
--- a/source/src/vm/mame/emu/cpu/i386/i386op32.c
+++ b/source/src/vm/mame/emu/cpu/i386/i386op32.c
@@ -1572,19 +1572,20 @@ static void I386OP(popfd)(i386_state *cpustate) // Opcode 0x9d
15721572 {
15731573 UINT32 value;
15741574 UINT32 current = get_flags(cpustate);
1575+ UINT32 expect_flags = 0xffffffff;
15751576 UINT8 IOPL = (current >> 12) & 0x03;
1577+ //UINT32 mask = I386_EFLAGS_SZAPC | I386_EFLAGS_T | I386_EFLAGS_D | I386_EFLAGS_O | I386_EFLAGS_NT | I386_EFLAGS_AC | I386_EFLAGS_ID;
15761578 UINT32 mask = 0x00257fd5; // VM, VIP and VIF cannot be set by POPF/POPFD
15771579 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
15781580
15791581 // IOPL can only change if CPL is 0
1582+#if 1
15801583 if(cpustate->CPL != 0) {
1581- //mask &= ~0x00003000;
15821584 mask &= ~I386_EFLAGS_IOPL;
15831585 }
15841586 // IF can only change if CPL is at least as privileged as IOPL
15851587 if(cpustate->CPL > IOPL) {
15861588 mask &= ~I386_EFLAGS_IF;
1587- //mask &= ~0x00000200;
15881589 }
15891590
15901591 if(V8086_MODE)
@@ -1596,19 +1597,34 @@ static void I386OP(popfd)(i386_state *cpustate) // Opcode 0x9d
15961597 //set_flags(cpustate,0 ); // EXCEPTION
15971598 }
15981599 mask &= ~I386_EFLAGS_IOPL; // IOPL cannot be changed while in V8086 mode
1599- //mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode
16001600 }
1601-
1601+#else
1602+ if(!(PROTECTED_MODE)) {
1603+ expect_flags = ~(I386_EFLAGS_RF | I386_EFLAGS_VIF | I386_EFLAGS_VIP);
1604+ mask |= I386_EFLAGS_IF | I386_EFLAGS_IOP1 | I386_EFLAGS_IOP2 | I386_EFLAGS_RF | I386_EFLAGS_VIP | I386_EFLAGS_VIF;
1605+ } else if(!(V8086_MODE)) {
1606+ expect_flags = ~(I386_EFLAGS_RF);
1607+ if(cpustate->CPL == 0) {
1608+ expect_flags &= ~(I386_EFLAGS_VIP | I386_EFLAGS_VIF);
1609+ mask |= I386_EFLAGS_IF | I386_EFLAGS_IOP1 | I386_EFLAGS_IOP2 | I386_EFLAGS_RF | I386_EFLAGS_VIP | I386_EFLAGS_VIF;
1610+ } else if(cpustate->CPL <= IOPL) {
1611+ expect_flags &= ~(I386_EFLAGS_VIP | I386_EFLAGS_VIF);
1612+ mask |= I386_EFLAGS_IF | I386_EFLAGS_RF | I386_EFLAGS_VIP | I386_EFLAGS_VIF;
1613+ } else {
1614+ mask |= I386_EFLAGS_RF;
1615+ }
1616+ } else if(IOPL == 3) {
1617+ mask |= I386_EFLAGS_IF;
1618+ } else {
1619+ FAULT(FAULT_GP, 0);
1620+ set_flags(cpustate,current); // mask out reserved bits
1621+ return;
1622+ }
1623+#endif
16021624 if(i386_limit_check(cpustate,SS,offset,4) == 0)
16031625 {
16041626 value = POP32(cpustate);
1605- //value &= ~0x00010000; // RF will always return zero
1606- if(!V8086_MODE) { // RF maybe clear only not V86 mode
1607- value &= ~I386_EFLAGS_RF;
1608- if((cpustate->CPL == 0) || (cpustate->CPL <= IOPL)) {
1609- value &= ~(I386_EFLAGS_VIF | I386_EFLAGS_VIP); // RF will always return zero
1610- }
1611- }
1627+ value = value & expect_flags;
16121628 set_flags(cpustate,(current & ~mask) | (value & mask)); // mask out reserved bits
16131629 }
16141630 else
@@ -1862,7 +1878,7 @@ static void I386OP(pushfd)(i386_state *cpustate) // Opcode 0x9c
18621878 offset = (REG16(SP) - 4) & 0xffff;
18631879 if(!PROTECTED_MODE || !V8086_MODE || ((cpustate->IOP1) && (cpustate->IOP2))) {
18641880 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1865- PUSH32(cpustate, get_flags(cpustate) & 0x00fcffff );
1881+ PUSH32(cpustate, (get_flags(cpustate) & 0x00fcffff) | 0x00000002 );
18661882 else
18671883 FAULT(FAULT_SS,0)
18681884 } else {
Show on old repository browser