First Commit of my working state
[simh.git] / AltairZ80 / i86.h
1 /*
2 * Dos/PC Emulator
3 * Copyright (C) 1991 Jim Hudgens
4 *
5 *
6 * The file is part of GDE.
7 *
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)
11 * any later version.
12 *
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.
17 *
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.
21 *
22 */
23
24 /* 8086 support structs and definitions */
25 /* definition of the registers */
26
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:
34
35 EAX & 0xff === AL
36 EAX & 0xffff == AX
37
38 etc. The result is that alot of the calculations can then be
39 done using the native instruction set fully.
40 */
41
42 /* Endian Logic
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
45 LOWFIRST must be 0
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
49 */
50
51 #ifndef LOWFIRST
52 #ifdef __BIG_ENDIAN__
53 #if __BIG_ENDIAN__
54 #define LOWFIRST 0
55 #else
56 #define LOWFIRST 1
57 #endif
58 #elif defined (__MWERKS__) && defined (macintosh)
59 #define LOWFIRST 0
60 #else
61 #define LOWFIRST 1
62 #endif
63 #endif
64
65 #if LOWFIRST
66 typedef struct { uint16 x_reg; } I16_reg_t;
67 typedef struct { uint8 l_reg, h_reg; } I8_reg_t;
68 #else
69 typedef struct { uint16 x_reg; } I16_reg_t;
70 typedef struct { uint8 h_reg, l_reg; } I8_reg_t;
71 #endif
72
73 typedef union
74 {
75 I16_reg_t I16_reg;
76 I8_reg_t I8_reg;
77 } i386_general_register;
78
79 struct i386_general_regs
80 {
81 i386_general_register A, B, C, D;
82 };
83
84 typedef struct i386_general_regs Gen_reg_t;
85
86 struct i386_special_regs
87 {
88 i386_general_register SP, BP, SI, DI, IP;
89 uint32 FLAGS;
90 };
91
92 /*
93 * segment registers here represent the 16 bit quantities
94 * CS, DS, ES, SS
95 *
96 * segment pointers --- used to speed up the expressions:
97 * q = m->R_CSP + m->R_IP;
98 * fetched = *q;
99 * m->R_IP += 1;
100 * compared to:
101 * fetched = GetBYTEExtended(((uint32)m->R_CS << 4) + (m->R_IP++));
102 * Save at least one shift, more if doing two byte moves.
103 */
104 struct i386_segment_regs
105 {
106 uint16 CS, DS, SS, ES, FS, GS;
107 };
108
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
118
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
124
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
132
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
138
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 */
145
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 */
156
157 /*
158 * DEFINE A MASK FOR ONLY THOSE FLAG BITS WE WILL EVER PASS BACK
159 * (via PUSHF)
160 */
161 #define F_MSK (F_CF|F_PF|F_AF|F_ZF|F_SF|F_TF|F_IF|F_DF|F_OF)
162
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))
167
168 #define CONDITIONAL_SET_FLAG(COND,M,FLAG) \
169 if (COND) SET_FLAG(M,FLAG); else CLEAR_FLAG(M,FLAG)
170
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
178
179 #define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | SYSMODE_SEGOVR_CS | \
180 SYSMODE_SEGOVR_DS | SYSMODE_SEGOVR_ES | SYSMODE_SEGOVR_SS)
181
182 #define SYSMODE_PREFIX_REPE 0x20
183 #define SYSMODE_PREFIX_REPNE 0x40
184
185 #define INTR_SYNCH 0x1
186 #define INTR_HALTED 0x4
187 #define INTR_ILLEGAL_OPCODE 0x8
188 \f
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)
194
195 typedef struct pc_env PC_ENV;
196 struct pc_env
197 {
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)
206 reserved 6 bits
207 interrupt # 8 bits instruction raised interrupt
208 BIOS video segregs 4 bits
209 Interrupt Pending 1 bits
210 Extern interrupt 1 bits
211 Halted 1 bits
212 */
213 long sysmode;
214 uint8 intno;
215 };
216
217 /* GLOBAL */
218 volatile int intr;
219
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);
238
239 typedef void (*OP)(PC_ENV *m);
240 extern OP i86_optab[256];
241
242 /* PRIMITIVE OPERATIONS */
243
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);