DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/cpu/core_normal.cpp
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 #include <stdio.h>
00020 
00021 #include "dosbox.h"
00022 #include "mem.h"
00023 #include "cpu.h"
00024 #include "lazyflags.h"
00025 #include "inout.h"
00026 #include "callback.h"
00027 #include "pic.h"
00028 #include "fpu.h"
00029 #include "paging.h"
00030 #include "mmx.h"
00031 
00032 bool CPU_RDMSR();
00033 bool CPU_WRMSR();
00034 
00035 #define CPU_CORE CPU_ARCHTYPE_386
00036 
00037 #define DoString DoString_Normal
00038 
00039 extern bool ignore_opcode_63;
00040 
00041 #if C_DEBUG
00042 #include "debug.h"
00043 #endif
00044 
00045 #if (!C_CORE_INLINE)
00046 #define LoadMb(off) mem_readb(off)
00047 #define LoadMw(off) mem_readw(off)
00048 #define LoadMd(off) mem_readd(off)
00049 #define LoadMq(off) ((Bit64u)((Bit64u)mem_readd(off+4)<<32 | (Bit64u)mem_readd(off)))
00050 #define SaveMb(off,val) mem_writeb(off,val)
00051 #define SaveMw(off,val) mem_writew(off,val)
00052 #define SaveMd(off,val) mem_writed(off,val)
00053 #define SaveMq(off,val) {mem_writed(off,val&0xffffffff);mem_writed(off+4,(val>>32)&0xffffffff);}
00054 #else 
00055 #include "paging.h"
00056 #define LoadMb(off) mem_readb_inline(off)
00057 #define LoadMw(off) mem_readw_inline(off)
00058 #define LoadMd(off) mem_readd_inline(off)
00059 #define LoadMq(off) ((Bit64u)((Bit64u)mem_readd_inline(off+4)<<32 | (Bit64u)mem_readd_inline(off)))
00060 #define SaveMb(off,val) mem_writeb_inline(off,val)
00061 #define SaveMw(off,val) mem_writew_inline(off,val)
00062 #define SaveMd(off,val) mem_writed_inline(off,val)
00063 #define SaveMq(off,val) {mem_writed_inline(off,val&0xffffffff);mem_writed_inline(off+4,(val>>32)&0xffffffff);}
00064 #endif
00065 
00066 Bitu cycle_count;
00067 
00068 #if C_FPU
00069 #define CPU_FPU 1u                                              //Enable FPU escape instructions
00070 #endif
00071 
00072 #define CPU_PIC_CHECK 1u
00073 #define CPU_TRAP_CHECK 1u
00074 
00075 #define OPCODE_NONE                     0x000u
00076 #define OPCODE_0F                       0x100u
00077 #define OPCODE_SIZE                     0x200u
00078 
00079 #define PREFIX_ADDR                     0x1u
00080 #define PREFIX_REP                      0x2u
00081 
00082 #define TEST_PREFIX_ADDR        (core.prefixes & PREFIX_ADDR)
00083 #define TEST_PREFIX_REP         (core.prefixes & PREFIX_REP)
00084 
00085 #define DO_PREFIX_SEG(_SEG)                                     \
00086         BaseDS=SegBase(_SEG);                                   \
00087         BaseSS=SegBase(_SEG);                                   \
00088         core.base_val_ds=_SEG;                                  \
00089         goto restart_opcode;
00090 
00091 #define DO_PREFIX_ADDR()                                                                \
00092         core.prefixes=(core.prefixes & ~PREFIX_ADDR) |          \
00093         (cpu.code.big ^ PREFIX_ADDR);                                           \
00094         core.ea_table=&EATable[(core.prefixes&1u) * 256u];      \
00095         goto restart_opcode;
00096 
00097 #define DO_PREFIX_REP(_ZERO)                            \
00098         core.prefixes|=PREFIX_REP;                              \
00099         core.rep_zero=_ZERO;                                    \
00100         goto restart_opcode;
00101 
00102 typedef PhysPt (*GetEAHandler)(void);
00103 
00104 static const Bit32u AddrMaskTable[2]={0x0000ffffu,0xffffffffu};
00105 
00106 static struct {
00107         Bitu opcode_index;
00108         PhysPt cseip;
00109         PhysPt base_ds,base_ss;
00110         SegNames base_val_ds;
00111         bool rep_zero;
00112         Bitu prefixes;
00113         GetEAHandler * ea_table;
00114 } core;
00115 
00116 /* FIXME: Someone at Microsoft tell how subtracting PhysPt - PhysPt = __int64, or PhysPt + PhysPt = __int64 */
00117 #define GETIP           ((PhysPt)(core.cseip-SegBase(cs)))
00118 #define SAVEIP          reg_eip=GETIP;
00119 #define LOADIP          core.cseip=((PhysPt)(SegBase(cs)+reg_eip));
00120 
00121 #define SegBase(c)      SegPhys(c)
00122 #define BaseDS          core.base_ds
00123 #define BaseSS          core.base_ss
00124 
00125 static INLINE Bit8u Fetchb() {
00126         Bit8u temp=LoadMb(core.cseip);
00127         core.cseip+=1;
00128         return temp;
00129 }
00130 
00131 static INLINE Bit16u Fetchw() {
00132         Bit16u temp=LoadMw(core.cseip);
00133         core.cseip+=2;
00134         return temp;
00135 }
00136 static INLINE Bit32u Fetchd() {
00137         Bit32u temp=LoadMd(core.cseip);
00138         core.cseip+=4;
00139         return temp;
00140 }
00141 
00142 #define Push_16 CPU_Push16
00143 #define Push_32 CPU_Push32
00144 #define Pop_16 CPU_Pop16
00145 #define Pop_32 CPU_Pop32
00146 
00147 #include "instructions.h"
00148 #include "core_normal/support.h"
00149 #include "core_normal/string.h"
00150 
00151 
00152 #define EALookupTable (core.ea_table)
00153 
00154 Bits CPU_Core_Normal_Run(void) {
00155         while (CPU_Cycles-->0) {
00156                 LOADIP;
00157                 core.opcode_index=cpu.code.big*0x200u;
00158                 core.prefixes=cpu.code.big;
00159                 core.ea_table=&EATable[cpu.code.big*256u];
00160                 BaseDS=SegBase(ds);
00161                 BaseSS=SegBase(ss);
00162                 core.base_val_ds=ds;
00163 #if C_DEBUG
00164 #if C_HEAVY_DEBUG
00165                 if (DEBUG_HeavyIsBreakpoint()) {
00166                         FillFlags();
00167                         return (Bits)debugCallback;
00168                 };
00169 #endif
00170 #endif
00171                 cycle_count++;
00172 restart_opcode:
00173                 switch (core.opcode_index+Fetchb()) {
00174                 #include "core_normal/prefix_none.h"
00175                 #include "core_normal/prefix_0f.h"
00176                 #include "core_normal/prefix_66.h"
00177                 #include "core_normal/prefix_66_0f.h"
00178                 default:
00179                 illegal_opcode:
00180 #if C_DEBUG     
00181                         {
00182                                 bool ignore=false;
00183                                 Bitu len=(GETIP-reg_eip);
00184                                 LOADIP;
00185                                 if (len>16) len=16;
00186                                 char tempcode[16*2+1];char * writecode=tempcode;
00187                                 if (ignore_opcode_63 && mem_readb(core.cseip) == 0x63)
00188                                         ignore = true;
00189                                 for (;len>0;len--) {
00190                                         sprintf(writecode,"%02X",mem_readb(core.cseip++));
00191                                         writecode+=2;
00192                                 }
00193                                 if (!ignore)
00194                                         LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode);
00195                         }
00196 #endif
00197                         CPU_Exception(6,0);
00198                         continue;
00199                 gp_fault:
00200                         LOG_MSG("Segment limit violation");
00201                         CPU_Exception(EXCEPTION_GP,0);
00202                         continue;
00203                 }
00204                 SAVEIP;
00205         }
00206         FillFlags();
00207         return CBRET_NONE;
00208 decode_end:
00209         SAVEIP;
00210         FillFlags();
00211         return CBRET_NONE;
00212 }
00213 
00214 Bits CPU_Core_Normal_Trap_Run(void) {
00215         Bits oldCycles = CPU_Cycles;
00216         CPU_Cycles = 1;
00217         cpu.trap_skip = false;
00218 
00219         Bits ret=CPU_Core_Normal_Run();
00220         if (!cpu.trap_skip) CPU_HW_Interrupt(1);
00221         CPU_Cycles = oldCycles-1;
00222         cpudecoder = &CPU_Core_Normal_Run;
00223 
00224         return ret;
00225 }
00226 
00227 
00228 
00229 void CPU_Core_Normal_Init(void) {
00230 
00231 }
00232