2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: 386/486 CPU Emulation Library
5 * PURPOSE: Opcode group handlers.
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
11 // #define WIN32_NO_STATUS
12 // #define _INC_WINDOWS
22 /* PUBLIC FUNCTIONS ***********************************************************/
24 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup8082
)
26 UCHAR Immediate
, Result
, Dummy
, Value
;
27 SOFT386_MOD_REG_RM ModRegRm
;
28 BOOLEAN AddressSize
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
30 if (State
->PrefixFlags
& SOFT386_PREFIX_ADSIZE
)
32 /* The ADSIZE prefix toggles the size */
33 AddressSize
= !AddressSize
;
36 if (!Soft386ParseModRegRm(State
, AddressSize
, &ModRegRm
))
38 /* Exception occurred */
42 /* Fetch the immediate operand */
43 if (!Soft386FetchByte(State
, &Immediate
))
45 /* Exception occurred */
49 /* Read the operands */
50 if (!Soft386ReadModrmByteOperands(State
, &ModRegRm
, &Dummy
, &Value
))
52 /* Exception occurred */
56 /* Check which operation is this */
57 switch (ModRegRm
.Register
)
62 Result
= Value
+ Immediate
;
64 /* Update CF, OF and AF */
65 State
->Flags
.Cf
= (Result
< Value
) && (Result
< Immediate
);
66 State
->Flags
.Of
= ((Value
& SIGN_FLAG_BYTE
) == (Immediate
& SIGN_FLAG_BYTE
))
67 && ((Value
& SIGN_FLAG_BYTE
) != (Result
& SIGN_FLAG_BYTE
));
68 State
->Flags
.Af
= (((Value
& 0x0F) + (Immediate
& 0x0F)) & 0x10) ? TRUE
: FALSE
;
76 Result
= Value
| Immediate
;
83 INT Carry
= State
->Flags
.Cf
? 1 : 0;
85 Result
= Value
+ Immediate
+ Carry
;
87 /* Update CF, OF and AF */
88 State
->Flags
.Cf
= ((Immediate
== 0xFF) && (Carry
== 1))
89 || ((Result
< Value
) && (Result
< (Immediate
+ Carry
)));
90 State
->Flags
.Of
= ((Value
& SIGN_FLAG_BYTE
) == (Immediate
& SIGN_FLAG_BYTE
))
91 && ((Value
& SIGN_FLAG_BYTE
) != (Result
& SIGN_FLAG_BYTE
));
92 State
->Flags
.Af
= (((Value
& 0x0F) + ((Immediate
+ Carry
) & 0x0F)) & 0x10)
101 INT Carry
= State
->Flags
.Cf
? 1 : 0;
103 Result
= Value
- Immediate
- Carry
;
105 /* Update CF, OF and AF */
106 State
->Flags
.Cf
= Value
< (Immediate
+ Carry
);
107 State
->Flags
.Of
= ((Value
& SIGN_FLAG_BYTE
) != (Immediate
& SIGN_FLAG_BYTE
))
108 && ((Value
& SIGN_FLAG_BYTE
) != (Result
& SIGN_FLAG_BYTE
));
109 State
->Flags
.Af
= (Value
& 0x0F) < ((Immediate
+ Carry
) & 0x0F);
117 Result
= Value
& Immediate
;
125 Result
= Value
- Immediate
;
127 /* Update CF, OF and AF */
128 State
->Flags
.Cf
= Value
< Immediate
;
129 State
->Flags
.Of
= ((Value
& SIGN_FLAG_BYTE
) != (Immediate
& SIGN_FLAG_BYTE
))
130 && ((Value
& SIGN_FLAG_BYTE
) != (Result
& SIGN_FLAG_BYTE
));
131 State
->Flags
.Af
= (Value
& 0x0F) < (Immediate
& 0x0F);
145 /* Shouldn't happen */
150 /* Update ZF, SF and PF */
151 State
->Flags
.Zf
= (Result
== 0) ? TRUE
: FALSE
;
152 State
->Flags
.Sf
= (Result
& SIGN_FLAG_BYTE
) ? TRUE
: FALSE
;
153 State
->Flags
.Pf
= Soft386CalculateParity(Result
);
155 /* Unless this is CMP, write back the result */
156 if (ModRegRm
.Register
!= 7)
158 return Soft386WriteModrmByteOperands(State
, &ModRegRm
, FALSE
, Result
);
164 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup81
)
167 return FALSE
; // TODO: NOT IMPLEMENTED
170 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup83
)
173 return FALSE
; // TODO: NOT IMPLEMENTED
176 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup8F
)
179 SOFT386_MOD_REG_RM ModRegRm
;
180 BOOLEAN OperandSize
, AddressSize
;
182 OperandSize
= AddressSize
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
184 if (State
->PrefixFlags
& SOFT386_PREFIX_OPSIZE
)
186 /* The OPSIZE prefix toggles the size */
187 OperandSize
= !OperandSize
;
190 if (State
->PrefixFlags
& SOFT386_PREFIX_ADSIZE
)
192 /* The ADSIZE prefix toggles the size */
193 AddressSize
= !AddressSize
;
196 if (!Soft386ParseModRegRm(State
, AddressSize
, &ModRegRm
))
198 /* Exception occurred */
202 if (ModRegRm
.Register
!= 0)
205 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
209 /* Pop a value from the stack */
210 if (!Soft386StackPop(State
, &Value
))
212 /* Exception occurred */
218 return Soft386WriteModrmDwordOperands(State
,
225 return Soft386WriteModrmWordOperands(State
,
232 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC0
)
235 return FALSE
; // TODO: NOT IMPLEMENTED
238 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC1
)
241 return FALSE
; // TODO: NOT IMPLEMENTED
244 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC6
)
247 SOFT386_MOD_REG_RM ModRegRm
;
248 BOOLEAN AddressSize
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
250 if (State
->PrefixFlags
& SOFT386_PREFIX_ADSIZE
)
252 /* The ADSIZE prefix toggles the size */
253 AddressSize
= !AddressSize
;
256 if (!Soft386ParseModRegRm(State
, AddressSize
, &ModRegRm
))
258 /* Exception occurred */
262 if (ModRegRm
.Register
!= 0)
265 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
269 /* Get the immediate operand */
270 if (!Soft386FetchByte(State
, &Immediate
))
272 /* Exception occurred */
276 return Soft386WriteModrmByteOperands(State
,
282 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC7
)
284 SOFT386_MOD_REG_RM ModRegRm
;
285 BOOLEAN OperandSize
, AddressSize
;
287 OperandSize
= AddressSize
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
289 if (State
->PrefixFlags
& SOFT386_PREFIX_OPSIZE
)
291 /* The OPSIZE prefix toggles the size */
292 OperandSize
= !OperandSize
;
295 if (State
->PrefixFlags
& SOFT386_PREFIX_ADSIZE
)
297 /* The ADSIZE prefix toggles the size */
298 AddressSize
= !AddressSize
;
301 if (!Soft386ParseModRegRm(State
, AddressSize
, &ModRegRm
))
303 /* Exception occurred */
307 if (ModRegRm
.Register
!= 0)
310 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
318 /* Get the immediate operand */
319 if (!Soft386FetchDword(State
, &Immediate
))
321 /* Exception occurred */
325 return Soft386WriteModrmDwordOperands(State
,
334 /* Get the immediate operand */
335 if (!Soft386FetchWord(State
, &Immediate
))
337 /* Exception occurred */
341 return Soft386WriteModrmWordOperands(State
,
348 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD0
)
351 return FALSE
; // TODO: NOT IMPLEMENTED
354 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD1
)
357 return FALSE
; // TODO: NOT IMPLEMENTED
360 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD2
)
363 return FALSE
; // TODO: NOT IMPLEMENTED
366 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD3
)
369 return FALSE
; // TODO: NOT IMPLEMENTED
372 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF6
)
375 return FALSE
; // TODO: NOT IMPLEMENTED
378 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF7
)
381 return FALSE
; // TODO: NOT IMPLEMENTED
384 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFE
)
387 return FALSE
; // TODO: NOT IMPLEMENTED
390 SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF
)
393 return FALSE
; // TODO: NOT IMPLEMENTED