libhd 5.0
|
00001 /**************************************************************************** 00002 * 00003 * Realmode X86 Emulator Library 00004 * 00005 * Copyright (C) 1996-1999 SciTech Software, Inc. 00006 * Copyright (C) David Mosberger-Tang 00007 * Copyright (C) 1999 Egbert Eich 00008 * 00009 * ======================================================================== 00010 * 00011 * Permission to use, copy, modify, distribute, and sell this software and 00012 * its documentation for any purpose is hereby granted without fee, 00013 * provided that the above copyright notice appear in all copies and that 00014 * both that copyright notice and this permission notice appear in 00015 * supporting documentation, and that the name of the authors not be used 00016 * in advertising or publicity pertaining to distribution of the software 00017 * without specific, written prior permission. The authors makes no 00018 * representations about the suitability of this software for any purpose. 00019 * It is provided "as is" without express or implied warranty. 00020 * 00021 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 00022 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 00023 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 00024 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 00025 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00026 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00027 * PERFORMANCE OF THIS SOFTWARE. 00028 * 00029 * ======================================================================== 00030 * 00031 * Language: ANSI C 00032 * Environment: Any 00033 * Developer: Kendall Bennett 00034 * 00035 * Description: Header file for x86 register definitions. 00036 * 00037 ****************************************************************************/ 00038 /* $XFree86: xc/extras/x86emu/include/x86emu/regs.h,v 1.5 2003/10/22 20:03:05 tsi Exp $ */ 00039 00040 #ifndef __X86EMU_REGS_H 00041 #define __X86EMU_REGS_H 00042 00043 /*---------------------- Macros and type definitions ----------------------*/ 00044 00045 #ifdef PACK 00046 # pragma PACK 00047 #endif 00048 00049 /* 00050 * General EAX, EBX, ECX, EDX type registers. Note that for 00051 * portability, and speed, the issue of byte swapping is not addressed 00052 * in the registers. All registers are stored in the default format 00053 * available on the host machine. The only critical issue is that the 00054 * registers should line up EXACTLY in the same manner as they do in 00055 * the 386. That is: 00056 * 00057 * EAX & 0xff === AL 00058 * EAX & 0xffff == AX 00059 * 00060 * etc. The result is that alot of the calculations can then be 00061 * done using the native instruction set fully. 00062 */ 00063 00064 #ifdef __BIG_ENDIAN__ 00065 00066 typedef struct { 00067 u32 e_reg; 00068 } I32_reg_t; 00069 00070 typedef struct { 00071 u16 filler0, x_reg; 00072 } I16_reg_t; 00073 00074 typedef struct { 00075 u8 filler0, filler1, h_reg, l_reg; 00076 } I8_reg_t; 00077 00078 #else /* !__BIG_ENDIAN__ */ 00079 00080 typedef struct { 00081 u32 e_reg; 00082 } I32_reg_t; 00083 00084 typedef struct { 00085 u16 x_reg; 00086 } I16_reg_t; 00087 00088 typedef struct { 00089 u8 l_reg, h_reg; 00090 } I8_reg_t; 00091 00092 #endif /* BIG_ENDIAN */ 00093 00094 typedef union { 00095 I32_reg_t I32_reg; 00096 I16_reg_t I16_reg; 00097 I8_reg_t I8_reg; 00098 } i386_general_register; 00099 00100 struct i386_general_regs { 00101 i386_general_register A, B, C, D; 00102 }; 00103 00104 typedef struct i386_general_regs Gen_reg_t; 00105 00106 struct i386_special_regs { 00107 i386_general_register SP, BP, SI, DI, IP; 00108 u32 FLAGS; 00109 }; 00110 00111 /* 00112 * Segment registers here represent the 16 bit quantities 00113 * CS, DS, ES, SS. 00114 */ 00115 00116 struct i386_segment_regs { 00117 u16 CS, DS, SS, ES, FS, GS; 00118 }; 00119 00120 /* 8 bit registers */ 00121 #define R_AH gen.A.I8_reg.h_reg 00122 #define R_AL gen.A.I8_reg.l_reg 00123 #define R_BH gen.B.I8_reg.h_reg 00124 #define R_BL gen.B.I8_reg.l_reg 00125 #define R_CH gen.C.I8_reg.h_reg 00126 #define R_CL gen.C.I8_reg.l_reg 00127 #define R_DH gen.D.I8_reg.h_reg 00128 #define R_DL gen.D.I8_reg.l_reg 00129 00130 /* 16 bit registers */ 00131 #define R_AX gen.A.I16_reg.x_reg 00132 #define R_BX gen.B.I16_reg.x_reg 00133 #define R_CX gen.C.I16_reg.x_reg 00134 #define R_DX gen.D.I16_reg.x_reg 00135 00136 /* 32 bit extended registers */ 00137 #define R_EAX gen.A.I32_reg.e_reg 00138 #define R_EBX gen.B.I32_reg.e_reg 00139 #define R_ECX gen.C.I32_reg.e_reg 00140 #define R_EDX gen.D.I32_reg.e_reg 00141 00142 /* special registers */ 00143 #define R_SP spc.SP.I16_reg.x_reg 00144 #define R_BP spc.BP.I16_reg.x_reg 00145 #define R_SI spc.SI.I16_reg.x_reg 00146 #define R_DI spc.DI.I16_reg.x_reg 00147 #define R_IP spc.IP.I16_reg.x_reg 00148 #define R_FLG spc.FLAGS 00149 00150 /* special registers */ 00151 #define R_SP spc.SP.I16_reg.x_reg 00152 #define R_BP spc.BP.I16_reg.x_reg 00153 #define R_SI spc.SI.I16_reg.x_reg 00154 #define R_DI spc.DI.I16_reg.x_reg 00155 #define R_IP spc.IP.I16_reg.x_reg 00156 #define R_FLG spc.FLAGS 00157 00158 /* special registers */ 00159 #define R_ESP spc.SP.I32_reg.e_reg 00160 #define R_EBP spc.BP.I32_reg.e_reg 00161 #define R_ESI spc.SI.I32_reg.e_reg 00162 #define R_EDI spc.DI.I32_reg.e_reg 00163 #define R_EIP spc.IP.I32_reg.e_reg 00164 #define R_EFLG spc.FLAGS 00165 00166 /* segment registers */ 00167 #define R_CS seg.CS 00168 #define R_DS seg.DS 00169 #define R_SS seg.SS 00170 #define R_ES seg.ES 00171 #define R_FS seg.FS 00172 #define R_GS seg.GS 00173 00174 /* flag conditions */ 00175 #define FB_CF 0x0001 /* CARRY flag */ 00176 #define FB_PF 0x0004 /* PARITY flag */ 00177 #define FB_AF 0x0010 /* AUX flag */ 00178 #define FB_ZF 0x0040 /* ZERO flag */ 00179 #define FB_SF 0x0080 /* SIGN flag */ 00180 #define FB_TF 0x0100 /* TRAP flag */ 00181 #define FB_IF 0x0200 /* INTERRUPT ENABLE flag */ 00182 #define FB_DF 0x0400 /* DIR flag */ 00183 #define FB_OF 0x0800 /* OVERFLOW flag */ 00184 00185 /* 80286 and above always have bit#1 set */ 00186 #define F_ALWAYS_ON (0x0002) /* flag bits always on */ 00187 00188 /* 00189 * Define a mask for only those flag bits we will ever pass back 00190 * (via PUSHF) 00191 */ 00192 #define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF) 00193 00194 /* following bits masked in to a 16bit quantity */ 00195 00196 #define F_CF 0x0001 /* CARRY flag */ 00197 #define F_PF 0x0004 /* PARITY flag */ 00198 #define F_AF 0x0010 /* AUX flag */ 00199 #define F_ZF 0x0040 /* ZERO flag */ 00200 #define F_SF 0x0080 /* SIGN flag */ 00201 #define F_TF 0x0100 /* TRAP flag */ 00202 #define F_IF 0x0200 /* INTERRUPT ENABLE flag */ 00203 #define F_DF 0x0400 /* DIR flag */ 00204 #define F_OF 0x0800 /* OVERFLOW flag */ 00205 00206 #define TOGGLE_FLAG(flag) (M.x86.R_FLG ^= (flag)) 00207 #define SET_FLAG(flag) (M.x86.R_FLG |= (flag)) 00208 #define CLEAR_FLAG(flag) (M.x86.R_FLG &= ~(flag)) 00209 #define ACCESS_FLAG(flag) (M.x86.R_FLG & (flag)) 00210 #define CLEARALL_FLAG(m) (M.x86.R_FLG = 0) 00211 00212 #define CONDITIONAL_SET_FLAG(COND,FLAG) \ 00213 if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG) 00214 00215 #define F_PF_CALC 0x010000 /* PARITY flag has been calced */ 00216 #define F_ZF_CALC 0x020000 /* ZERO flag has been calced */ 00217 #define F_SF_CALC 0x040000 /* SIGN flag has been calced */ 00218 00219 #define F_ALL_CALC 0xff0000 /* All have been calced */ 00220 00221 /* 00222 * Emulator machine state. 00223 * Segment usage control. 00224 */ 00225 #define SYSMODE_SEG_DS_SS 0x00000001 00226 #define SYSMODE_SEGOVR_CS 0x00000002 00227 #define SYSMODE_SEGOVR_DS 0x00000004 00228 #define SYSMODE_SEGOVR_ES 0x00000008 00229 #define SYSMODE_SEGOVR_FS 0x00000010 00230 #define SYSMODE_SEGOVR_GS 0x00000020 00231 #define SYSMODE_SEGOVR_SS 0x00000040 00232 #define SYSMODE_PREFIX_REPE 0x00000080 00233 #define SYSMODE_PREFIX_REPNE 0x00000100 00234 #define SYSMODE_PREFIX_DATA 0x00000200 00235 #define SYSMODE_PREFIX_ADDR 0x00000400 00236 #define SYSMODE_INTR_PENDING 0x10000000 00237 #define SYSMODE_EXTRN_INTR 0x20000000 00238 #define SYSMODE_HALTED 0x40000000 00239 00240 #define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \ 00241 SYSMODE_SEGOVR_CS | \ 00242 SYSMODE_SEGOVR_DS | \ 00243 SYSMODE_SEGOVR_ES | \ 00244 SYSMODE_SEGOVR_FS | \ 00245 SYSMODE_SEGOVR_GS | \ 00246 SYSMODE_SEGOVR_SS) 00247 #define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \ 00248 SYSMODE_SEGOVR_CS | \ 00249 SYSMODE_SEGOVR_DS | \ 00250 SYSMODE_SEGOVR_ES | \ 00251 SYSMODE_SEGOVR_FS | \ 00252 SYSMODE_SEGOVR_GS | \ 00253 SYSMODE_SEGOVR_SS | \ 00254 SYSMODE_PREFIX_DATA | \ 00255 SYSMODE_PREFIX_ADDR) 00256 00257 #define INTR_SYNCH 0x1 00258 #define INTR_ASYNCH 0x2 00259 #define INTR_HALTED 0x4 00260 00261 typedef struct { 00262 struct i386_general_regs gen; 00263 struct i386_special_regs spc; 00264 struct i386_segment_regs seg; 00265 /* 00266 * MODE contains information on: 00267 * REPE prefix 2 bits repe,repne 00268 * SEGMENT overrides 5 bits normal,DS,SS,CS,ES 00269 * Delayed flag set 3 bits (zero, signed, parity) 00270 * reserved 6 bits 00271 * interrupt # 8 bits instruction raised interrupt 00272 * BIOS video segregs 4 bits 00273 * Interrupt Pending 1 bits 00274 * Extern interrupt 1 bits 00275 * Halted 1 bits 00276 */ 00277 u32 mode; 00278 volatile int intr; /* mask of pending interrupts */ 00279 int debug; 00280 #ifdef DEBUG 00281 int check; 00282 u16 saved_ip; 00283 u16 saved_cs; 00284 int enc_pos; 00285 int enc_str_pos; 00286 char decode_buf[32]; /* encoded byte stream */ 00287 char decoded_buf[256]; /* disassembled strings */ 00288 #endif 00289 u8 intno; 00290 u8 __pad[3]; 00291 } X86EMU_regs; 00292 00293 /**************************************************************************** 00294 REMARKS: 00295 Structure maintaining the emulator machine state. 00296 00297 MEMBERS: 00298 mem_base - Base real mode memory for the emulator 00299 mem_size - Size of the real mode memory block for the emulator 00300 private - private data pointer 00301 x86 - X86 registers 00302 ****************************************************************************/ 00303 typedef struct { 00304 unsigned long mem_base; 00305 unsigned long mem_size; 00306 void* private; 00307 X86EMU_regs x86; 00308 } X86EMU_sysEnv; 00309 00310 #ifdef END_PACK 00311 # pragma END_PACK 00312 #endif 00313 00314 /*----------------------------- Global Variables --------------------------*/ 00315 00316 #ifdef __cplusplus 00317 extern "C" { /* Use "C" linkage when in C++ mode */ 00318 #endif 00319 00320 /* Global emulator machine state. 00321 * 00322 * We keep it global to avoid pointer dereferences in the code for speed. 00323 */ 00324 00325 extern X86EMU_sysEnv _X86EMU_env; 00326 #define M _X86EMU_env 00327 00328 /*-------------------------- Function Prototypes --------------------------*/ 00329 00330 /* Function to log information at runtime */ 00331 00332 void printk(const char *fmt, ...); 00333 00334 #ifdef __cplusplus 00335 } /* End of "C" linkage for C++ */ 00336 #endif 00337 00338 #endif /* __X86EMU_REGS_H */