PCem

view src/x86_ops_flag.h @ 142:bd46c39a78e8

Implemented selector limits on some instructions - fixes LBA2. GPFs in real mode now work. Selectors correctly zeroed on far return to lower privilege.
author TomW
date Wed Aug 13 20:33:56 2014 +0100
parents 64fa8cf6ba95
children
line source
1 static int opCMC(uint32_t fetchdat)
2 {
3 flags_rebuild();
4 flags ^= C_FLAG;
5 cycles -= 2;
6 return 0;
7 }
10 static int opCLC(uint32_t fetchdat)
11 {
12 flags_rebuild();
13 flags &= ~C_FLAG;
14 cycles -= 2;
15 return 0;
16 }
17 static int opCLD(uint32_t fetchdat)
18 {
19 flags &= ~D_FLAG;
20 cycles -= 2;
21 return 0;
22 }
23 static int opCLI(uint32_t fetchdat)
24 {
25 if (!IOPLp)
26 {
27 x86gpf(NULL,0);
28 }
29 else
30 flags &= ~I_FLAG;
32 cycles -= 3;
33 return 0;
34 }
36 static int opSTC(uint32_t fetchdat)
37 {
38 flags_rebuild();
39 flags |= C_FLAG;
40 cycles -= 2;
41 return 0;
42 }
43 static int opSTD(uint32_t fetchdat)
44 {
45 flags |= D_FLAG;
46 cycles -= 2;
47 return 0;
48 }
49 static int opSTI(uint32_t fetchdat)
50 {
51 if (!IOPLp)
52 {
53 x86gpf(NULL,0);
54 }
55 else
56 flags |= I_FLAG;
58 cycles -= 2;
59 return 0;
60 }
62 static int opSAHF(uint32_t fetchdat)
63 {
64 flags_rebuild();
65 flags = (flags & 0xff00) | (AH & 0xd5) | 2;
66 cycles -= 3;
67 return 0;
68 }
69 static int opLAHF(uint32_t fetchdat)
70 {
71 flags_rebuild();
72 AH = flags & 0xff;
73 cycles -= 3;
74 return 0;
75 }
77 static int opPUSHF(uint32_t fetchdat)
78 {
79 if ((eflags & VM_FLAG) && (IOPL < 3))
80 {
81 x86gpf(NULL,0);
82 return 0;
83 }
84 flags_rebuild();
85 PUSH_W(flags);
86 cycles -= 4;
87 return 0;
88 }
89 static int opPUSHFD(uint32_t fetchdat)
90 {
91 uint16_t tempw;
92 if ((eflags & VM_FLAG) && (IOPL < 3))
93 {
94 x86gpf(NULL, 0);
95 return 0;
96 }
97 if (CPUID) tempw = eflags & 0x24;
98 else tempw = eflags & 4;
99 flags_rebuild();
100 PUSH_L(flags | (tempw << 16));
101 cycles -= 4;
102 return 0;
103 }
105 static int opPOPF_286(uint32_t fetchdat)
106 {
107 uint16_t tempw;
109 if ((eflags & VM_FLAG) && (IOPL < 3))
110 {
111 x86gpf(NULL, 0);
112 return 0;
113 }
115 tempw = POP_W(); if (abrt) return 0;
117 if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2;
118 else if (!(CPL)) flags = (tempw & 0x7fd5) | 2;
119 else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
120 else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
121 flags_extract();
123 cycles -= 5;
124 return 0;
125 }
126 static int opPOPF(uint32_t fetchdat)
127 {
128 uint16_t tempw;
130 if ((eflags & VM_FLAG) && (IOPL < 3))
131 {
132 x86gpf(NULL, 0);
133 return 0;
134 }
136 tempw = POP_W(); if (abrt) return 0;
138 if (!(CPL) || !(msw & 1)) flags = (tempw & 0xffd5) | 2;
139 else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0xcfd5) | 2;
140 else flags = (flags & 0x3200) | (tempw & 0xcdd5) | 2;
141 flags_extract();
143 cycles -= 5;
144 return 0;
145 }
146 static int opPOPFD(uint32_t fetchdat)
147 {
148 uint32_t templ;
150 if ((eflags & VM_FLAG) && (IOPL < 3))
151 {
152 x86gpf(NULL, 0);
153 return 0;
154 }
156 templ = POP_L(); if (abrt) return 0;
158 if (!(CPL) || !(msw & 1)) flags = (templ & 0xffd5) | 2;
159 else if (IOPLp) flags = (flags & 0x3000) | (templ & 0xcfd5) | 2;
160 else flags = (flags & 0x3200) | (templ & 0xcdd5) | 2;
162 templ &= is486 ? 0x240000 : 0;
163 templ |= ((eflags&3) << 16);
164 if (CPUID) eflags = (templ >> 16) & 0x27;
165 else if (is486) eflags = (templ >> 16) & 7;
166 else eflags = (templ >> 16) & 3;
168 flags_extract();
170 cycles -= 5;
171 return 0;
172 }