DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/regs.h
00001 /*
00002  *  Copyright (C) 2002-2020  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 along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 static INLINE PhysPt SegLimit(SegNames index) {
00102         return Segs.limit[index];
00103 }
00104 
00105 static INLINE PhysPt SegPhys(SegNames index) {
00106         return Segs.phys[index];
00107 }
00108 
00109 static INLINE Bit16u SegValue(SegNames index) {
00110         return (Bit16u)Segs.val[index];
00111 }
00112         
00113 static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
00114         return RealMake(SegValue(index),off);   
00115 }
00116 
00117 
00118 static INLINE void SegSet16(Bitu index,Bit16u val) {
00119         Segs.val[index]=(Bitu)val;
00120         Segs.phys[index]=(PhysPt)((unsigned int)val << 4U);
00121         /* real mode does not update limit */
00122 }
00123 
00124 enum {
00125         REGI_AX, REGI_CX, REGI_DX, REGI_BX,
00126         REGI_SP, REGI_BP, REGI_SI, REGI_DI
00127 };
00128 
00129 enum {
00130         REGI_AL, REGI_CL, REGI_DL, REGI_BL,
00131         REGI_AH, REGI_CH, REGI_DH, REGI_BH
00132 };
00133 
00134 
00135 //macros to convert a 3-bit register index to the correct register
00136 #define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX])
00137 #define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX])
00138 #define reg_8(reg) ((reg & 4) ? reg_8h((reg) & 3) : reg_8l((reg) & 3))
00139 #define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX])
00140 #define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
00141 
00142 #define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX]
00143 #define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX]
00144 #define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX]
00145 #define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX]
00146 
00147 #define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX]
00148 #define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX]
00149 #define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX]
00150 #define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX]
00151 
00152 #define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX]
00153 #define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX]
00154 #define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX]
00155 #define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX]
00156 
00157 #define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX]
00158 #define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX]
00159 #define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX]
00160 #define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX]
00161 
00162 #define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX]
00163 #define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX]
00164 
00165 #define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX]
00166 #define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX]
00167 
00168 #define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX]
00169 #define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX]
00170 
00171 #define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX]
00172 #define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX]
00173 
00174 #define reg_ip cpu_regs.ip.word[W_INDEX]
00175 #define reg_eip cpu_regs.ip.dword[DW_INDEX]
00176 
00177 #define reg_flags cpu_regs.flags
00178 
00179 #endif