/* * Copyright (C) 2002-2021 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DOSBOX_REGS_H #define DOSBOX_REGS_H #include "mem.h" #define FLAG_CF 0x00000001U #define FLAG_PF 0x00000004U #define FLAG_AF 0x00000010U #define FLAG_ZF 0x00000040U #define FLAG_SF 0x00000080U #define FLAG_OF 0x00000800U #define FLAG_TF 0x00000100U #define FLAG_IF 0x00000200U #define FLAG_DF 0x00000400U #define FLAG_IOPL 0x00003000U #define FLAG_NT 0x00004000U #define FLAG_RF 0x00010000U #define FLAG_VM 0x00020000U #define FLAG_AC 0x00040000U #define FLAG_ID 0x00200000U #define FMASK_TEST (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF) #define FMASK_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF ) #define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT) #define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE #define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE) #define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false ) #define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12) struct Segment { uint16_t val; PhysPt phys; /* The physical address start in emulated machine */ PhysPt limit; }; enum SegNames { es=0,cs,ss,ds,fs,gs}; struct Segments { Bitu val[8]; PhysPt phys[8]; PhysPt limit[8]; bool expanddown[8]; }; union GenReg32 { uint32_t dword[1]; uint16_t word[2]; uint8_t byte[4]; }; #ifdef WORDS_BIGENDIAN #define DW_INDEX 0 #define W_INDEX 1 #define BH_INDEX 2 #define BL_INDEX 3 #else #define DW_INDEX 0 #define W_INDEX 0 #define BH_INDEX 1 #define BL_INDEX 0 #endif struct CPU_Regs { GenReg32 regs[8],ip; Bitu flags; }; extern Segments Segs; extern CPU_Regs cpu_regs; static INLINE PhysPt SegLimit(SegNames index) { return Segs.limit[index]; } static INLINE PhysPt SegPhys(SegNames index) { return Segs.phys[index]; } static INLINE uint16_t SegValue(SegNames index) { return (uint16_t)Segs.val[index]; } static INLINE RealPt RealMakeSeg(SegNames index,uint16_t off) { return RealMake(SegValue(index),off); } static INLINE void SegSet16(Bitu index,uint16_t val) { Segs.val[index]=(Bitu)val; Segs.phys[index]=(PhysPt)((unsigned int)val << 4U); /* real mode does not update limit */ } enum { REGI_AX, REGI_CX, REGI_DX, REGI_BX, REGI_SP, REGI_BP, REGI_SI, REGI_DI }; enum { REGI_AL, REGI_CL, REGI_DL, REGI_BL, REGI_AH, REGI_CH, REGI_DH, REGI_BH }; //macros to convert a 3-bit register index to the correct register #define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX]) #define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX]) #define reg_8(reg) ((reg & 4) ? reg_8h((reg) & 3) : reg_8l((reg) & 3)) #define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX]) #define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX]) #define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX] #define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX] #define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX] #define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX] #define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX] #define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX] #define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX] #define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX] #define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX] #define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX] #define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX] #define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX] #define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX] #define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX] #define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX] #define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX] #define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX] #define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX] #define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX] #define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX] #define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX] #define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX] #define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX] #define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX] #define reg_ip cpu_regs.ip.word[W_INDEX] #define reg_eip cpu_regs.ip.dword[DW_INDEX] #define reg_flags cpu_regs.flags #endif