DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/regs.h
00001 /*
00002  *  Copyright (C) 2002-2015  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifndef DOSBOX_REGS_H
00020 #define DOSBOX_REGS_H
00021 
00022 #include <iostream>
00023 
00024 #ifndef DOSBOX_MEM_H
00025 #include "mem.h"
00026 #endif
00027 
00028 #define FLAG_CF         0x00000001U
00029 #define FLAG_PF         0x00000004U
00030 #define FLAG_AF         0x00000010U
00031 #define FLAG_ZF         0x00000040U
00032 #define FLAG_SF         0x00000080U
00033 #define FLAG_OF         0x00000800U
00034 
00035 #define FLAG_TF         0x00000100U
00036 #define FLAG_IF         0x00000200U
00037 #define FLAG_DF         0x00000400U
00038 
00039 #define FLAG_IOPL       0x00003000U
00040 #define FLAG_NT         0x00004000U
00041 #define FLAG_VM         0x00020000U
00042 #define FLAG_AC         0x00040000U
00043 #define FLAG_ID         0x00200000U
00044 
00045 #define FMASK_TEST              (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)
00046 #define FMASK_NORMAL    (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF )     
00047 #define FMASK_ALL               (FMASK_NORMAL | FLAG_IOPL | FLAG_NT)
00048 
00049 #define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE
00050 
00051 #define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE)
00052 #define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false )
00053 
00054 #define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12)
00055 
00056 struct Segment {
00057         Bit16u val;
00058         PhysPt phys;                                                    /* The phyiscal address start in emulated machine */
00059         PhysPt limit;
00060 };
00061 
00062 enum SegNames { es=0,cs,ss,ds,fs,gs};
00063 
00064 struct Segments {
00065         Bitu val[8];
00066         PhysPt phys[8];
00067         PhysPt limit[8];
00068         bool expanddown[8];
00069 };
00070 
00071 union GenReg32 {
00072         Bit32u dword[1];
00073         Bit16u word[2];
00074         Bit8u byte[4];
00075 };
00076 
00077 #ifdef WORDS_BIGENDIAN
00078 
00079 #define DW_INDEX 0
00080 #define W_INDEX 1
00081 #define BH_INDEX 2
00082 #define BL_INDEX 3
00083 
00084 #else
00085 
00086 #define DW_INDEX 0
00087 #define W_INDEX 0
00088 #define BH_INDEX 1
00089 #define BL_INDEX 0
00090 
00091 #endif
00092 
00093 struct CPU_Regs {
00094         GenReg32 regs[8],ip;
00095         Bitu flags;
00096 };
00097 
00098 extern Segments Segs;
00099 extern CPU_Regs cpu_regs;
00100 
00101 //serialization
00102 std::ostream& operator<<(std::ostream& stream, const Segments& seg);
00103 std::istream& operator>>(std::istream& stream, Segments& seg);
00104 
00105 std::ostream& operator<<(std::ostream& stream, const CPU_Regs& reg);
00106 std::istream& operator>>(std::istream& stream, CPU_Regs& reg);
00107 
00108 static INLINE PhysPt SegLimit(SegNames index) {
00109         return Segs.limit[index];
00110 }
00111 
00112 static INLINE PhysPt SegPhys(SegNames index) {
00113         return Segs.phys[index];
00114 }
00115 
00116 static INLINE Bit16u SegValue(SegNames index) {
00117         return (Bit16u)Segs.val[index];
00118 }
00119         
00120 static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
00121         return RealMake(SegValue(index),off);   
00122 }
00123 
00124 
00125 static INLINE void SegSet16(Bitu index,Bit16u val) {
00126         Segs.val[index]=(Bitu)val;
00127         Segs.phys[index]=(PhysPt)((unsigned int)val << 4U);
00128         /* real mode does not update limit */
00129 }
00130 
00131 enum {
00132         REGI_AX, REGI_CX, REGI_DX, REGI_BX,
00133         REGI_SP, REGI_BP, REGI_SI, REGI_DI
00134 };
00135 
00136 enum {
00137         REGI_AL, REGI_CL, REGI_DL, REGI_BL,
00138         REGI_AH, REGI_CH, REGI_DH, REGI_BH
00139 };
00140 
00141 
00142 //macros to convert a 3-bit register index to the correct register
00143 #define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX])
00144 #define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX])
00145 #define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3))
00146 #define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX])
00147 #define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
00148 
00149 #define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX]
00150 #define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX]
00151 #define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX]
00152 #define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX]
00153 
00154 #define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX]
00155 #define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX]
00156 #define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX]
00157 #define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX]
00158 
00159 #define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX]
00160 #define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX]
00161 #define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX]
00162 #define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX]
00163 
00164 #define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX]
00165 #define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX]
00166 #define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX]
00167 #define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX]
00168 
00169 #define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX]
00170 #define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX]
00171 
00172 #define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX]
00173 #define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX]
00174 
00175 #define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX]
00176 #define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX]
00177 
00178 #define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX]
00179 #define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX]
00180 
00181 #define reg_ip cpu_regs.ip.word[W_INDEX]
00182 #define reg_eip cpu_regs.ip.dword[DW_INDEX]
00183 
00184 #define reg_flags cpu_regs.flags
00185 
00186 #endif