3 * Copyright (C) 1991 Jim Hudgens
6 * The file is part of GDE.
8 * GDE is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 1, or (at your option)
13 * GDE is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GDE; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* 8086 support structs and definitions */
25 /* definition of the registers */
27 /* general EAX,EBX,ECX, EDX type registers.
28 Note that for portability, and speed, the issue of byte
29 swapping is not addressed in the registers. All registers
30 are stored in the default format available on the
31 host machine. The only critical issue is that the
32 registers should line up EXACTLY in the same manner as
33 they do in the 386. That is:
38 etc. The result is that alot of the calculations can then be
39 done using the native instruction set fully.
43 Priority 1: If LOWFIRST is defined, use it. LOWFIRST must be 1 if the
44 lower part of a 16 bit quantity comes first in memory, otherwise
46 Priority 2: If __BIG_ENDIAN__ is defined, use it to define LOWFIRST accordingly
47 Priority 3: OS 9 on Macintosh needs LOWFIRST 0
48 Priority 4: Use LOWFIRST 1 as default
58 #elif defined (__MWERKS__) && defined (macintosh)
66 typedef struct { uint16 x_reg
; } I16_reg_t
;
67 typedef struct { uint8 l_reg
, h_reg
; } I8_reg_t
;
69 typedef struct { uint16 x_reg
; } I16_reg_t
;
70 typedef struct { uint8 h_reg
, l_reg
; } I8_reg_t
;
77 } i386_general_register
;
79 struct i386_general_regs
81 i386_general_register A
, B
, C
, D
;
84 typedef struct i386_general_regs Gen_reg_t
;
86 struct i386_special_regs
88 i386_general_register SP
, BP
, SI
, DI
, IP
;
93 * segment registers here represent the 16 bit quantities
96 * segment pointers --- used to speed up the expressions:
97 * q = m->R_CSP + m->R_IP;
101 * fetched = GetBYTEExtended(((uint32)m->R_CS << 4) + (m->R_IP++));
102 * Save at least one shift, more if doing two byte moves.
104 struct i386_segment_regs
106 uint16 CS
, DS
, SS
, ES
, FS
, GS
;
109 /* 8 bit registers */
110 #define R_AH Gn_regs.A.I8_reg.h_reg
111 #define R_AL Gn_regs.A.I8_reg.l_reg
112 #define R_BH Gn_regs.B.I8_reg.h_reg
113 #define R_BL Gn_regs.B.I8_reg.l_reg
114 #define R_CH Gn_regs.C.I8_reg.h_reg
115 #define R_CL Gn_regs.C.I8_reg.l_reg
116 #define R_DH Gn_regs.D.I8_reg.h_reg
117 #define R_DL Gn_regs.D.I8_reg.l_reg
119 /* 16 bit registers */
120 #define R_AX Gn_regs.A.I16_reg.x_reg
121 #define R_BX Gn_regs.B.I16_reg.x_reg
122 #define R_CX Gn_regs.C.I16_reg.x_reg
123 #define R_DX Gn_regs.D.I16_reg.x_reg
125 /* special registers */
126 #define R_SP Sp_regs.SP.I16_reg.x_reg
127 #define R_BP Sp_regs.BP.I16_reg.x_reg
128 #define R_SI Sp_regs.SI.I16_reg.x_reg
129 #define R_DI Sp_regs.DI.I16_reg.x_reg
130 #define R_IP Sp_regs.IP.I16_reg.x_reg
131 #define R_FLG Sp_regs.FLAGS
133 /* segment registers */
134 #define R_CS Sg_regs.CS
135 #define R_DS Sg_regs.DS
136 #define R_SS Sg_regs.SS
137 #define R_ES Sg_regs.ES
139 /* 8088 has top 4 bits of the flags set to 1 */
140 /* Also, bit#1 is set. This is (not well) documented behavior. */
141 /* see note in userman.tex about the subtleties of dealing with */
142 /* code which attempts to detect the host processor. */
143 /* This is def'd as F_ALWAYS_ON */
144 #define F_ALWAYS_ON (0xf002) /* flag bits always on */
146 /* following bits masked in to a 16bit quantity */
147 #define F_CF 0x1 /* CARRY flag */
148 #define F_PF 0x4 /* PARITY flag */
149 #define F_AF 0x10 /* AUX flag */
150 #define F_ZF 0x40 /* ZERO flag */
151 #define F_SF 0x80 /* SIGN flag */
152 #define F_TF 0x100 /* TRAP flag */
153 #define F_IF 0x200 /* INTERRUPT ENABLE flag */
154 #define F_DF 0x400 /* DIR flag */
155 #define F_OF 0x800 /* OVERFLOW flag */
158 * DEFINE A MASK FOR ONLY THOSE FLAG BITS WE WILL EVER PASS BACK
161 #define F_MSK (F_CF|F_PF|F_AF|F_ZF|F_SF|F_TF|F_IF|F_DF|F_OF)
163 #define TOGGLE_FLAG(M,FLAG) (M)->R_FLG ^= FLAG
164 #define SET_FLAG(M,FLAG) (M)->R_FLG |= FLAG
165 #define CLEAR_FLAG(M, FLAG) (M)->R_FLG &= ~FLAG
166 #define ACCESS_FLAG(M,FLAG) ((M)->R_FLG & (FLAG))
168 #define CONDITIONAL_SET_FLAG(COND,M,FLAG) \
169 if (COND) SET_FLAG(M,FLAG); else CLEAR_FLAG(M,FLAG)
171 /* emulator machine state. */
172 /* segment usage control */
173 #define SYSMODE_SEG_DS_SS 0x01
174 #define SYSMODE_SEGOVR_CS 0x02
175 #define SYSMODE_SEGOVR_DS 0x04
176 #define SYSMODE_SEGOVR_ES 0x08
177 #define SYSMODE_SEGOVR_SS 0x10
179 #define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | SYSMODE_SEGOVR_CS | \
180 SYSMODE_SEGOVR_DS | SYSMODE_SEGOVR_ES | SYSMODE_SEGOVR_SS)
182 #define SYSMODE_PREFIX_REPE 0x20
183 #define SYSMODE_PREFIX_REPNE 0x40
185 #define INTR_SYNCH 0x1
186 #define INTR_HALTED 0x4
187 #define INTR_ILLEGAL_OPCODE 0x8
189 /* INSTRUCTION DECODING STUFF */
190 #define FETCH_DECODE_MODRM(m,mod,rh,rl) fetch_decode_modrm(m,&mod,&rh,&rl)
191 #define DECODE_RM_BYTE_REGISTER(m,r) decode_rm_byte_register(m,r)
192 #define DECODE_RM_WORD_REGISTER(m,r) decode_rm_word_register(m,r)
193 #define DECODE_CLEAR_SEGOVR(m) m->sysmode &= ~(SYSMODE_SEGMASK)
195 typedef struct pc_env PC_ENV
;
198 /* The registers!! */
199 struct i386_general_regs Gn_regs
;
200 struct i386_special_regs Sp_regs
;
201 struct i386_segment_regs Sg_regs
;
202 /* our flags structrure. This contains information on
203 REPE prefix 2 bits repe,repne
204 SEGMENT overrides 5 bits normal,DS,SS,CS,ES
205 Delayed flag set 3 bits (zero, signed, parity)
207 interrupt # 8 bits instruction raised interrupt
208 BIOS video segregs 4 bits
209 Interrupt Pending 1 bits
210 Extern interrupt 1 bits
220 void halt_sys (PC_ENV
*sys
);
221 void fetch_decode_modrm (PC_ENV
*m
, uint16
*mod
, uint16
*regh
, uint16
*regl
);
222 uint8
*decode_rm_byte_register (PC_ENV
*m
, int reg
);
223 uint16
*decode_rm_word_register (PC_ENV
*m
, int reg
);
224 uint16
*decode_rm_seg_register (PC_ENV
*m
, int reg
);
225 uint8
fetch_byte_imm (PC_ENV
*m
);
226 uint16
fetch_word_imm (PC_ENV
*m
);
227 uint16
decode_rm00_address (PC_ENV
*m
, int rm
);
228 uint16
decode_rm01_address (PC_ENV
*m
, int rm
);
229 uint16
decode_rm10_address (PC_ENV
*m
, int rm
);
230 uint8
fetch_data_byte (PC_ENV
*m
, uint16 offset
);
231 uint8
fetch_data_byte_abs (PC_ENV
*m
, uint16 segment
, uint16 offset
);
232 uint16
fetch_data_word (PC_ENV
*m
, uint16 offset
);
233 uint16
fetch_data_word_abs (PC_ENV
*m
, uint16 segment
, uint16 offset
);
234 void store_data_byte (PC_ENV
*m
, uint16 offset
, uint8 val
);
235 void store_data_byte_abs (PC_ENV
*m
, uint16 segment
, uint16 offset
, uint8 val
);
236 void store_data_word (PC_ENV
*m
, uint16 offset
, uint16 val
);
237 void store_data_word_abs (PC_ENV
*m
, uint16 segment
, uint16 offset
, uint16 val
);
239 typedef void (*OP
)(PC_ENV
*m
);
240 extern OP i86_optab
[256];
242 /* PRIMITIVE OPERATIONS */
244 uint8
aad_word (PC_ENV
*m
, uint16 d
);
245 uint16
aam_word (PC_ENV
*m
, uint8 d
);
246 uint8
adc_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
247 uint16
adc_word (PC_ENV
*m
, uint16 d
, uint16 s
);
248 uint8
add_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
249 uint16
add_word (PC_ENV
*m
, uint16 d
, uint16 s
);
250 uint8
and_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
251 uint16
and_word (PC_ENV
*m
, uint16 d
, uint16 s
);
252 uint8
cmp_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
253 uint16
cmp_word (PC_ENV
*m
, uint16 d
, uint16 s
);
254 uint8
dec_byte (PC_ENV
*m
, uint8 d
);
255 uint16
dec_word (PC_ENV
*m
, uint16 d
);
256 uint8
inc_byte (PC_ENV
*m
, uint8 d
);
257 uint16
inc_word (PC_ENV
*m
, uint16 d
);
258 uint8
or_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
259 uint16
or_word (PC_ENV
*m
, uint16 d
, uint16 s
);
260 uint8
neg_byte (PC_ENV
*m
, uint8 s
);
261 uint16
neg_word (PC_ENV
*m
, uint16 s
);
262 uint8
not_byte (PC_ENV
*m
, uint8 s
);
263 uint16
not_word (PC_ENV
*m
, uint16 s
);
264 uint16
mem_access_word (PC_ENV
*m
, int addr
);
265 void push_word (PC_ENV
*m
, uint16 w
);
266 uint16
pop_word (PC_ENV
*m
);
267 uint8
rcl_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
268 uint16
rcl_word (PC_ENV
*m
, uint16 d
, uint16 s
);
269 uint8
rcr_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
270 uint16
rcr_word (PC_ENV
*m
, uint16 d
, uint16 s
);
271 uint8
rol_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
272 uint16
rol_word (PC_ENV
*m
, uint16 d
, uint16 s
);
273 uint8
ror_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
274 uint16
ror_word (PC_ENV
*m
, uint16 d
, uint16 s
);
275 uint8
shl_byte (PC_ENV
*m
, uint8 d
, uint8 s
) ;
276 uint16
shl_word (PC_ENV
*m
, uint16 d
, uint16 s
);
277 uint8
shr_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
278 uint16
shr_word (PC_ENV
*m
, uint16 d
, uint16 s
);
279 uint8
sar_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
280 uint16
sar_word (PC_ENV
*m
, uint16 d
, uint16 s
);
281 uint8
sbb_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
282 uint16
sbb_word (PC_ENV
*m
, uint16 d
, uint16 s
);
283 uint8
sub_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
284 uint16
sub_word (PC_ENV
*m
, uint16 d
, uint16 s
);
285 void test_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
286 void test_word (PC_ENV
*m
, uint16 d
, uint16 s
);
287 uint8
xor_byte (PC_ENV
*m
, uint8 d
, uint8 s
);
288 uint16
xor_word (PC_ENV
*m
, uint16 d
, uint16 s
);
289 void imul_byte (PC_ENV
*m
, uint8 s
);
290 void imul_word (PC_ENV
*m
, uint16 s
);
291 void mul_byte (PC_ENV
*m
, uint8 s
);
292 void mul_word (PC_ENV
*m
, uint16 s
);
293 void idiv_byte (PC_ENV
*m
, uint8 s
);
294 void idiv_word (PC_ENV
*m
, uint16 s
);
295 void div_byte (PC_ENV
*m
, uint8 s
);
296 void div_word (PC_ENV
*m
, uint16 s
);