From: Toni Wilen Date: Sun, 19 Aug 2018 15:53:48 +0000 (+0300) Subject: Removed dosbox and fake86 bridgeboard cores. X-Git-Tag: 4100~116 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f06420ea542ac3c11c5948db9179f4a3d72ff15e;p=francis%2Fwinuae.git Removed dosbox and fake86 bridgeboard cores. --- diff --git a/dosbox/callback.h b/dosbox/callback.h deleted file mode 100644 index c4e6fa6e..00000000 --- a/dosbox/callback.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: callback.h,v 1.26 2009-08-23 17:24:54 c2woody Exp $ */ - -#ifndef DOSBOX_CALLBACK_H -#define DOSBOX_CALLBACK_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -typedef Bitu (*CallBack_Handler)(void); -extern CallBack_Handler CallBack_Handlers[]; - -enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, - CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE, - CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, - CB_INT21 }; - -#define CB_MAX 128 -#define CB_SIZE 32 -#define CB_SEG 0xF000 -#define CB_SOFFSET 0x1000 - -enum { - CBRET_NONE=0,CBRET_STOP=1 -}; - -extern Bit8u lastint; - -static INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); -} -static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); -} - -static INLINE PhysPt CALLBACK_GetBase(void) { - return (CB_SEG << 4) + CB_SOFFSET; -} - -Bitu CALLBACK_Allocate(); - -void CALLBACK_Idle(void); - - -void CALLBACK_RunRealInt(Bit8u intnum); -void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); - -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr); -Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr); - -const char* CALLBACK_GetDescription(Bitu callback); -bool CALLBACK_Free(Bitu callback); - -void CALLBACK_SCF(bool val); -void CALLBACK_SZF(bool val); -void CALLBACK_SIF(bool val); - -extern Bitu call_priv_io; - - -class CALLBACK_HandlerObject{ -private: - bool installed; - Bitu m_callback; - enum {NONE,SETUP,SETUPAT} m_type; - struct { - RealPt old_vector; - Bit8u interrupt; - bool installed; - } vectorhandler; -public: - CALLBACK_HandlerObject():installed(false),m_type(NONE) { - vectorhandler.installed=false; - } - ~CALLBACK_HandlerObject(); - - //Install and allocate a callback. - void Install(CallBack_Handler handler,Bitu type,const char* description); - void Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description); - - //Only allocate a callback number - void Allocate(CallBack_Handler handler,const char* description=0); - Bit16u Get_callback() { - return (Bit16u)m_callback; - } - RealPt Get_RealPointer() { - return CALLBACK_RealPointer(m_callback); - } - void Set_RealVec(Bit8u vec); -}; -#endif diff --git a/dosbox/cmos.cpp b/dosbox/cmos.cpp deleted file mode 100644 index 3b66ec6f..00000000 --- a/dosbox/cmos.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: cmos.cpp,v 1.29 2009-06-16 18:19:18 qbix79 Exp $ */ - -#include -#include -#include - -#include "dosbox.h" -//#include "timer.h" -#include "pic.h" -#include "inout.h" -#include "mem.h" -//#include "bios_disk.h" -#include "setup.h" -//#include "cross.h" //fmod on certain platforms - -static struct { - Bit8u regs[3 * 0x40]; - bool nmi; - bool bcd; - Bit8u reg; - struct { - bool enabled; - Bit8u div; - float delay; - bool acknowledged; - } timer; - struct { - double timer; - double ended; - double alarm; - } last; - bool update_ended; - int ram_mask; -} cmos; -extern int x86_cmos_bank; - -Bit8u *x86_cmos_regs(Bit8u *regs) -{ - if (regs) { - memcpy(cmos.regs, regs, 3 * 0x40); - } - return cmos.regs; -} - -static void cmos_timerevent(Bitu val) { - if (cmos.timer.acknowledged) { - cmos.timer.acknowledged=false; - PIC_ActivateIRQ(8); - } - if (cmos.timer.enabled) { -// PIC_AddEvent(cmos_timerevent,cmos.timer.delay); - cmos.regs[0xc] = 0xC0;//Contraption Zack (music) - } -} - -static void cmos_checktimer(void) { - //PIC_RemoveEvents(cmos_timerevent); - if (cmos.timer.div<=2) cmos.timer.div+=7; - cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1)))); - if (!cmos.timer.div || !cmos.timer.enabled) return; - LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay); -// PIC_AddEvent(cmos_timerevent,cmos.timer.delay); - /* A rtc is always running */ - double remd=fmod(PIC_FullIndex(),(double)cmos.timer.delay); - //PIC_AddEvent(cmos_timerevent,(float)((double)cmos.timer.delay-remd)); //Should be more like a real pc. Check -// status reg A reading with this (and with other delays actually) -} - -extern void write_log(const char*,...); - -void cmos_selreg(Bitu port,Bitu val,Bitu iolen) { - cmos.reg=val & cmos.ram_mask; - cmos.nmi=(val & 0x80)>0; -} - -void cmos_writereg(Bitu port,Bitu val,Bitu iolen) -{ - int reg = cmos.reg; - if (reg >= 64 && x86_cmos_bank) - reg += 64; - - //write_log("cmos_write %02x (%d) = %02x\n", cmos.reg, x86_cmos_bank, val); - - reg &= cmos.ram_mask; - - switch (reg) - { - case 0x00: /* Seconds */ - case 0x02: /* Minutes */ - case 0x04: /* Hours */ - case 0x06: /* Day of week */ - case 0x07: /* Date of month */ - case 0x08: /* Month */ - case 0x09: /* Year */ - case 0x32: /* Century */ - /* Ignore writes to change alarm */ - break; - case 0x01: /* Seconds Alarm */ - case 0x03: /* Minutes Alarm */ - case 0x05: /* Hours Alarm */ - LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Trying to set alarm"); - cmos.regs[reg]=val; - break; - case 0x0a: /* Status reg A */ - cmos.regs[reg]=val & 0x7f; - if ((val & 0x70)!=0x20) LOG(LOG_BIOS,LOG_ERROR)("CMOS Illegal 22 stage divider value"); - cmos.timer.div=(val & 0xf); - cmos_checktimer(); - break; - case 0x0b: /* Status reg B */ - cmos.bcd=!(val & 0x4); - cmos.regs[reg]=val & 0x7f; - cmos.timer.enabled=(val & 0x40)>0; - if (val&0x10) LOG(LOG_BIOS,LOG_ERROR)("CMOS:Updated ended interrupt not supported yet"); - cmos_checktimer(); - break; - case 0x0d:/* Status reg D */ - cmos.regs[reg]=val & 0x80; /*Bit 7=1:RTC Pown on*/ - break; - case 0x0f: /* Shutdown status byte */ - cmos.regs[reg]=val;// & 0x7f; - break; - default: - cmos.regs[reg]=val; // & 0x7f; - LOG(LOG_BIOS,LOG_ERROR)("CMOS:WRite to unhandled register %x",cmos.reg); - } -} - - -#define MAKE_RETURN(_VAL) (cmos.bcd ? ((((_VAL) / 10) << 4) | ((_VAL) % 10)) : (_VAL)); - -extern double vblank_hz; -extern unsigned long int timeframes; -extern int vpos; -extern bool x86_turbo_on; - -static Bitu cmos_readreg2(Bitu port,Bitu iolen) { -#if 0 - if (cmos.reg>0x3f) { - LOG(LOG_BIOS,LOG_ERROR)("CMOS:Read from illegal register %x",cmos.reg); - return 0xff; - } -#endif - time_t curtime; - struct tm *loctime; - int reg = cmos.reg; - if (reg >= 64 && x86_cmos_bank) - reg += 64; - reg &= cmos.ram_mask; - - /* Get the current time. */ - curtime = time (NULL); - - /* Convert it to local time representation. */ - loctime = localtime (&curtime); - - switch (reg) { - case 0x00: /* Seconds */ - return MAKE_RETURN(loctime->tm_sec); - case 0x02: /* Minutes */ - return MAKE_RETURN(loctime->tm_min); - case 0x04: /* Hours */ - return MAKE_RETURN(loctime->tm_hour); - case 0x06: /* Day of week */ - return MAKE_RETURN(loctime->tm_wday + 1); - case 0x07: /* Date of month */ - return MAKE_RETURN(loctime->tm_mday); - case 0x08: /* Month */ - return MAKE_RETURN(loctime->tm_mon + 1); - case 0x09: /* Year */ - return MAKE_RETURN(loctime->tm_year % 100); - case 0x32: /* Century */ - return MAKE_RETURN(loctime->tm_year / 100 + 19); - case 0x01: /* Seconds Alarm */ - case 0x03: /* Minutes Alarm */ - case 0x05: /* Hours Alarm */ - return cmos.regs[reg]; - case 0x0a: /* Status register A */ - if (x86_turbo_on) { - static bool toggle; - toggle = !toggle; - if (toggle) { - return (cmos.regs[0x0a] & 0x7f) | 0x80; - } else { - return (cmos.regs[0x0a] & 0x7f); - } - } else { - if (PIC_TickIndex()<0.002) { - return (cmos.regs[0x0a]&0x7f) | 0x80; - } else { - return (cmos.regs[0x0a]&0x7f); - } - } - case 0x0c: /* Status register C */ - cmos.timer.acknowledged=true; - if (cmos.timer.enabled) { - /* In periodic interrupt mode only care for those flags */ - Bit8u val=cmos.regs[0xc]; - cmos.regs[0xc]=0; - return val; - } else { - /* Give correct values at certain times */ - Bit8u val=0; - double index=PIC_FullIndex(); - if (index>=(cmos.last.timer+cmos.timer.delay)) { - cmos.last.timer=index; - val|=0x40; - } - if (index>=(cmos.last.ended+1000)) { - cmos.last.ended=index; - val|=0x10; - } - return val; - } -#if 0 - case 0x10: /* Floppy size */ - drive_a = 0; - drive_b = 0; - if(imageDiskList[0] != NULL) drive_a = imageDiskList[0]->GetBiosType(); - if(imageDiskList[1] != NULL) drive_b = imageDiskList[1]->GetBiosType(); - return ((drive_a << 4) | (drive_b)); - /* First harddrive info */ - case 0x12: - hdparm = 0; - if(imageDiskList[2] != NULL) hdparm |= 0xf; - if(imageDiskList[3] != NULL) hdparm |= 0xf0; - return hdparm; - case 0x19: - if(imageDiskList[2] != NULL) return 47; /* User defined type */ - return 0; - case 0x1b: - if(imageDiskList[2] != NULL) return (imageDiskList[2]->cylinders & 0xff); - return 0; - case 0x1c: - if(imageDiskList[2] != NULL) return ((imageDiskList[2]->cylinders & 0xff00)>>8); - return 0; - case 0x1d: - if(imageDiskList[2] != NULL) return (imageDiskList[2]->heads); - return 0; - case 0x1e: - if(imageDiskList[2] != NULL) return 0xff; - return 0; - case 0x1f: - if(imageDiskList[2] != NULL) return 0xff; - return 0; - case 0x20: - if(imageDiskList[2] != NULL) return (0xc0 | (((imageDiskList[2]->heads) > 8) << 3)); - return 0; - case 0x21: - if(imageDiskList[2] != NULL) return (imageDiskList[2]->cylinders & 0xff); - return 0; - case 0x22: - if(imageDiskList[2] != NULL) return ((imageDiskList[2]->cylinders & 0xff00)>>8); - return 0; - case 0x23: - if(imageDiskList[2] != NULL) return (imageDiskList[2]->sectors); - return 0; - /* Second harddrive info */ - case 0x1a: - if(imageDiskList[3] != NULL) return 47; /* User defined type */ - return 0; - case 0x24: - if(imageDiskList[3] != NULL) return (imageDiskList[3]->cylinders & 0xff); - return 0; - case 0x25: - if(imageDiskList[3] != NULL) return ((imageDiskList[3]->cylinders & 0xff00)>>8); - return 0; - case 0x26: - if(imageDiskList[3] != NULL) return (imageDiskList[3]->heads); - return 0; - case 0x27: - if(imageDiskList[3] != NULL) return 0xff; - return 0; - case 0x28: - if(imageDiskList[3] != NULL) return 0xff; - return 0; - case 0x29: - if(imageDiskList[3] != NULL) return (0xc0 | (((imageDiskList[3]->heads) > 8) << 3)); - return 0; - case 0x2a: - if(imageDiskList[3] != NULL) return (imageDiskList[3]->cylinders & 0xff); - return 0; - case 0x2b: - if(imageDiskList[3] != NULL) return ((imageDiskList[3]->cylinders & 0xff00)>>8); - return 0; - case 0x2c: - if(imageDiskList[3] != NULL) return (imageDiskList[3]->sectors); - return 0; - case 0x39: - return 0; - case 0x3a: - return 0; -#endif - - - case 0x0b: /* Status register B */ - case 0x0d: /* Status register D */ - case 0x0f: /* Shutdown status byte */ - case 0x14: /* Equipment */ - case 0x15: /* Base Memory KB Low Byte */ - case 0x16: /* Base Memory KB High Byte */ - case 0x17: /* Extended memory in KB Low Byte */ - case 0x18: /* Extended memory in KB High Byte */ - case 0x30: /* Extended memory in KB Low Byte */ - case 0x31: /* Extended memory in KB High Byte */ -// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X : %04X",cmos.reg,cmos.regs[reg]); - return cmos.regs[reg]; - default: - LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X",cmos.reg); - return cmos.regs[reg]; - } -} - -Bitu cmos_readreg(Bitu port, Bitu iolen) -{ - Bitu v = cmos_readreg2(port, iolen); - //write_log("cmos_read %02x (%d) = %02x\n", cmos.reg, x86_cmos_bank, v); - return v; -} - -void CMOS_SetRegister(Bitu regNr, Bit8u val) { - cmos.regs[regNr] = val; -} - - -class CMOS:public Module_base{ -private: -// IO_ReadHandleObject ReadHandler[2]; -// IO_WriteHandleObject WriteHandler[2]; -public: - CMOS(Section* configuration, int ram_mask):Module_base(configuration){ -// WriteHandler[0].Install(0x70,cmos_selreg,IO_MB); -// WriteHandler[1].Install(0x71,cmos_writereg,IO_MB); -// ReadHandler[0].Install(0x71,cmos_readreg,IO_MB); - cmos.timer.enabled=false; - cmos.timer.acknowledged=true; - cmos.ram_mask = ram_mask; - cmos.reg=0xa; - cmos_writereg(0x71,0x26,1); - cmos.reg=0xb; - cmos_writereg(0x71,0x2,1); //Struct tm *loctime is of 24 hour format, - cmos.reg=0xd; - cmos_writereg(0x71,0x80,1); /* RTC power on */ -#if 0 - // Equipment is updated from bios.cpp and bios_disk.cpp - /* Fill in base memory size, it is 640K always */ - cmos.regs[0x15]=(Bit8u)0x80; - cmos.regs[0x16]=(Bit8u)0x02; - /* Fill in extended memory size */ - Bitu exsize=(MEM_TotalPages()*4)-1024; - cmos.regs[0x17]=(Bit8u)exsize; - cmos.regs[0x18]=(Bit8u)(exsize >> 8); - cmos.regs[0x30]=(Bit8u)exsize; - cmos.regs[0x31]=(Bit8u)(exsize >> 8); -#endif - } -}; - -static CMOS* test; - -void CMOS_Destroy(Section* sec){ - delete test; -} - -void CMOS_Init(Section* sec, int ram_mask) { - test = new CMOS(sec, ram_mask); - sec->AddDestroyFunction(&CMOS_Destroy,true); -} diff --git a/dosbox/core_full.cpp b/dosbox/core_full.cpp deleted file mode 100644 index fe2f2d36..00000000 --- a/dosbox/core_full.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "dosbox.h" - -#include "pic.h" -#include "regs.h" -#include "cpu.h" -#include "lazyflags.h" -#include "paging.h" -#include "fpu.h" -//#include "debug.h" -#include "inout.h" -#include "callback.h" - - -typedef PhysPt EAPoint; -#define SegBase(c) SegPhys(c) - -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) - -#define LoadD(reg) reg -#define SaveD(reg,val) reg=val - - - -#include "core_full/loadwrite.h" -#include "core_full/support.h" -#include "core_full/optable.h" -#include "instructions.h" - -#define EXCEPTION(blah) \ - { \ - Bit8u new_num=blah; \ - CPU_Exception(new_num,0); \ - continue; \ - } - -Bits CPU_Core_Full_Run(void) { - FullData inst; - while (CPU_Cycles-->0) { -#if C_DEBUG - cycle_count++; -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif -#endif - LoadIP(); - inst.entry=cpu.code.big*0x200; - inst.prefix=cpu.code.big; -restartopcode: - inst.entry=(inst.entry & 0xffffff00) | Fetchb(); - inst.code=OpCodeTable[inst.entry]; - #include "core_full/load.h" - #include "core_full/op.h" - #include "core_full/save.h" -nextopcode:; - SaveIP(); - continue; -illegalopcode: - LOG(LOG_CPU,LOG_NORMAL)("Illegal opcode"); - CPU_Exception(0x6,0); - } - FillFlags(); - return CBRET_NONE; -} - - -void CPU_Core_Full_Init(void) { - -} diff --git a/dosbox/core_full/ea_lookup.h b/dosbox/core_full/ea_lookup.h deleted file mode 100644 index cd8834e0..00000000 --- a/dosbox/core_full/ea_lookup.h +++ /dev/null @@ -1,237 +0,0 @@ -{ - EAPoint seg_base; - Bit16u off; - switch ((inst.rm_mod<<3)|inst.rm_eai) { - case 0x00: - off=reg_bx+reg_si; - seg_base=SegBase(ds); - break; - case 0x01: - off=reg_bx+reg_di; - seg_base=SegBase(ds); - break; - case 0x02: - off=reg_bp+reg_si; - seg_base=SegBase(ss); - break; - case 0x03: - off=reg_bp+reg_di; - seg_base=SegBase(ss); - break; - case 0x04: - off=reg_si; - seg_base=SegBase(ds); - break; - case 0x05: - off=reg_di; - seg_base=SegBase(ds); - break; - case 0x06: - off=Fetchw(); - seg_base=SegBase(ds); - break; - case 0x07: - off=reg_bx; - seg_base=SegBase(ds); - break; - - case 0x08: - off=reg_bx+reg_si+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x09: - off=reg_bx+reg_di+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0a: - off=reg_bp+reg_si+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0b: - off=reg_bp+reg_di+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0c: - off=reg_si+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0d: - off=reg_di+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0e: - off=reg_bp+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0f: - off=reg_bx+Fetchbs(); - seg_base=SegBase(ds); - break; - - case 0x10: - off=reg_bx+reg_si+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x11: - off=reg_bx+reg_di+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x12: - off=reg_bp+reg_si+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x13: - off=reg_bp+reg_di+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x14: - off=reg_si+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x15: - off=reg_di+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x16: - off=reg_bp+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x17: - off=reg_bx+Fetchws(); - seg_base=SegBase(ds); - break; - } - inst.rm_off=off; - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa=inst.seg.base+off; - } else { - inst.rm_eaa=seg_base+off; - } -} else { - - -#define SIB(MODE) { \ - Bitu sib=Fetchb(); \ - switch (sib&7) { \ - case 0:seg_base=SegBase(ds);off=reg_eax;break; \ - case 1:seg_base=SegBase(ds);off=reg_ecx;break; \ - case 2:seg_base=SegBase(ds);off=reg_edx;break; \ - case 3:seg_base=SegBase(ds);off=reg_ebx;break; \ - case 4:seg_base=SegBase(ss);off=reg_esp;break; \ - case 5:if (!MODE) { seg_base=SegBase(ds);off=Fetchd();break; \ - } else { seg_base=SegBase(ss);off=reg_ebp;break;} \ - case 6:seg_base=SegBase(ds);off=reg_esi;break; \ - case 7:seg_base=SegBase(ds);off=reg_edi;break; \ - } \ - off+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); \ -}; - static Bit32u SIBZero=0; - static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - EAPoint seg_base; - Bit32u off; - switch ((inst.rm_mod<<3)|inst.rm_eai) { - case 0x00: - off=reg_eax; - seg_base=SegBase(ds); - break; - case 0x01: - off=reg_ecx; - seg_base=SegBase(ds); - break; - case 0x02: - off=reg_edx; - seg_base=SegBase(ds); - break; - case 0x03: - off=reg_ebx; - seg_base=SegBase(ds); - break; - case 0x04: - SIB(0); - break; - case 0x05: - off=Fetchd(); - seg_base=SegBase(ds); - break; - case 0x06: - off=reg_esi; - seg_base=SegBase(ds); - break; - case 0x07: - off=reg_edi; - seg_base=SegBase(ds); - break; - - case 0x08: - off=reg_eax+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x09: - off=reg_ecx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0a: - off=reg_edx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0b: - off=reg_ebx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0c: - SIB(1); - off+=Fetchbs(); - break; - case 0x0d: - off=reg_ebp+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0e: - off=reg_esi+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0f: - off=reg_edi+Fetchbs(); - seg_base=SegBase(ds); - break; - - case 0x10: - off=reg_eax+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x11: - off=reg_ecx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x12: - off=reg_edx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x13: - off=reg_ebx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x14: - SIB(1); - off+=Fetchds(); - break; - case 0x15: - off=reg_ebp+Fetchds(); - seg_base=SegBase(ss); - break; - case 0x16: - off=reg_esi+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x17: - off=reg_edi+Fetchds(); - seg_base=SegBase(ds); - break; - } - inst.rm_off=off; - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa=inst.seg.base+off; - } else { - inst.rm_eaa=seg_base+off; - } -} diff --git a/dosbox/core_full/load.h b/dosbox/core_full/load.h deleted file mode 100644 index a5e7adeb..00000000 --- a/dosbox/core_full/load.h +++ /dev/null @@ -1,489 +0,0 @@ -switch (inst.code.load) { -/* General loading */ - case L_POPwRM: - inst_op1_w = Pop_16(); - goto case_L_MODRM; - case L_POPdRM: - inst_op1_d = Pop_32(); - goto case_L_MODRM; - case L_MODRM_NVM: - if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; - goto case_L_MODRM; -case_L_MODRM: - case L_MODRM: - inst.rm=Fetchb(); - inst.rm_index=(inst.rm >> 3) & 7; - inst.rm_eai=inst.rm&07; - inst.rm_mod=inst.rm>>6; - /* Decode address of mod/rm if needed */ - if (inst.rm<0xc0) { - if (!(inst.prefix & PREFIX_ADDR)) - #include "ea_lookup.h" - } -l_MODRMswitch: - switch (inst.code.extra) { -/* Byte */ - case M_Ib: - inst_op1_d=Fetchb(); - break; - case M_Ebx: - if (inst.rm<0xc0) inst_op1_ds=(Bit8s)LoadMb(inst.rm_eaa); - else inst_op1_ds=(Bit8s)reg_8(inst.rm_eai); - break; - case M_EbIb: - inst_op2_d=Fetchb(); - case M_Eb: - if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); - else inst_op1_d=reg_8(inst.rm_eai); - break; - case M_EbGb: - if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); - else inst_op1_d=reg_8(inst.rm_eai); - inst_op2_d=reg_8(inst.rm_index); - break; - case M_GbEb: - if (inst.rm<0xc0) inst_op2_d=LoadMb(inst.rm_eaa); - else inst_op2_d=reg_8(inst.rm_eai); - case M_Gb: - inst_op1_d=reg_8(inst.rm_index);; - break; -/* Word */ - case M_Iw: - inst_op1_d=Fetchw(); - break; - case M_EwxGwx: - inst_op2_ds=(Bit16s)reg_16(inst.rm_index); - goto l_M_Ewx; - case M_EwxIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ewx; - case M_EwxIwx: - inst_op2_ds=Fetchws(); -l_M_Ewx: - case M_Ewx: - if (inst.rm<0xc0) inst_op1_ds=(Bit16s)LoadMw(inst.rm_eaa); - else inst_op1_ds=(Bit16s)reg_16(inst.rm_eai); - break; - case M_EwIb: - inst_op2_d=Fetchb(); - goto l_M_Ew; - case M_EwIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ew; - case M_EwIw: - inst_op2_d=Fetchw(); - goto l_M_Ew; - case M_EwGwCL: - inst_imm_d=reg_cl; - goto l_M_EwGw; - case M_EwGwIb: - inst_imm_d=Fetchb(); - goto l_M_EwGw; - case M_EwGwt: - inst_op2_d=reg_16(inst.rm_index); - inst.rm_eaa+=((Bit16s)inst_op2_d >> 4) * 2; - goto l_M_Ew; -l_M_EwGw: - case M_EwGw: - inst_op2_d=reg_16(inst.rm_index); -l_M_Ew: - case M_Ew: - if (inst.rm<0xc0) inst_op1_d=LoadMw(inst.rm_eaa); - else inst_op1_d=reg_16(inst.rm_eai); - break; - case M_GwEw: - if (inst.rm<0xc0) inst_op2_d=LoadMw(inst.rm_eaa); - else inst_op2_d=reg_16(inst.rm_eai); - case M_Gw: - inst_op1_d=reg_16(inst.rm_index);; - break; -/* DWord */ - case M_Id: - inst_op1_d=Fetchd(); - break; - case M_EdxGdx: - inst_op2_ds=(Bit32s)reg_32(inst.rm_index); - case M_Edx: - if (inst.rm<0xc0) inst_op1_d=(Bit32s)LoadMd(inst.rm_eaa); - else inst_op1_d=(Bit32s)reg_32(inst.rm_eai); - break; - case M_EdIb: - inst_op2_d=Fetchb(); - goto l_M_Ed; - case M_EdIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ed; - case M_EdId: - inst_op2_d=Fetchd(); - goto l_M_Ed; - case M_EdGdCL: - inst_imm_d=reg_cl; - goto l_M_EdGd; - case M_EdGdt: - inst_op2_d=reg_32(inst.rm_index); - inst.rm_eaa+=((Bit32s)inst_op2_d >> 5) * 4; - goto l_M_Ed; - case M_EdGdIb: - inst_imm_d=Fetchb(); - goto l_M_EdGd; -l_M_EdGd: - case M_EdGd: - inst_op2_d=reg_32(inst.rm_index); -l_M_Ed: - case M_Ed: - if (inst.rm<0xc0) inst_op1_d=LoadMd(inst.rm_eaa); - else inst_op1_d=reg_32(inst.rm_eai); - break; - case M_GdEd: - if (inst.rm<0xc0) inst_op2_d=LoadMd(inst.rm_eaa); - else inst_op2_d=reg_32(inst.rm_eai); - case M_Gd: - inst_op1_d=reg_32(inst.rm_index); - break; -/* Others */ - - case M_SEG: - //TODO Check for limit - inst_op1_d=SegValue((SegNames)inst.rm_index); - break; - case M_Efw: - if (inst.rm>=0xc0) goto illegalopcode; - inst_op1_d=LoadMw(inst.rm_eaa); - inst_op2_d=LoadMw(inst.rm_eaa+2); - break; - case M_Efd: - if (inst.rm>=0xc0) goto illegalopcode; - inst_op1_d=LoadMd(inst.rm_eaa); - inst_op2_d=LoadMw(inst.rm_eaa+4); - break; - case M_EA: - inst_op1_d=inst.rm_off; - break; - case M_POPw: - inst_op1_d = Pop_16(); - break; - case M_POPd: - inst_op1_d = Pop_32(); - break; - case M_GRP: - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_Ib: - inst_op2_d=Fetchb(); - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_CL: - inst_op2_d=reg_cl; - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_1: - inst_op2_d=1; - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); - break; - } - break; - case L_POPw: - inst_op1_d = Pop_16(); - break; - case L_POPd: - inst_op1_d = Pop_32(); - break; - case L_POPfw: - inst_op1_d = Pop_16(); - inst_op2_d = Pop_16(); - break; - case L_POPfd: - inst_op1_d = Pop_32(); - inst_op2_d = Pop_16(); - break; - case L_Ib: - inst_op1_d=Fetchb(); - break; - case L_Ibx: - inst_op1_ds=Fetchbs(); - break; - case L_Iw: - inst_op1_d=Fetchw(); - break; - case L_Iwx: - inst_op1_ds=Fetchws(); - break; - case L_Idx: - case L_Id: - inst_op1_d=Fetchd(); - break; - case L_Ifw: - inst_op1_d=Fetchw(); - inst_op2_d=Fetchw(); - break; - case L_Ifd: - inst_op1_d=Fetchd(); - inst_op2_d=Fetchw(); - break; -/* Direct load of registers */ - case L_REGbIb: - inst_op2_d=Fetchb(); - case L_REGb: - inst_op1_d=reg_8(inst.code.extra); - break; - case L_REGwIw: - inst_op2_d=Fetchw(); - case L_REGw: - inst_op1_d=reg_16(inst.code.extra); - break; - case L_REGdId: - inst_op2_d=Fetchd(); - case L_REGd: - inst_op1_d=reg_32(inst.code.extra); - break; - case L_SEG: - inst_op1_d=SegValue((SegNames)inst.code.extra); - break; -/* Depending on addressize */ - case L_OP: - if (inst.prefix & PREFIX_ADDR) { - inst.rm_eaa=Fetchd(); - } else { - inst.rm_eaa=Fetchw(); - } - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa+=inst.seg.base; - } else { - inst.rm_eaa+=SegBase(ds); - } - break; - /* Special cases */ - case L_DOUBLE: - inst.entry|=0x100; - goto restartopcode; - case L_PRESEG: - inst.prefix|=PREFIX_SEG; - inst.seg.base=SegBase((SegNames)inst.code.extra); - goto restartopcode; - case L_PREREPNE: - inst.prefix|=PREFIX_REP; - inst.repz=false; - goto restartopcode; - case L_PREREP: - inst.prefix|=PREFIX_REP; - inst.repz=true; - goto restartopcode; - case L_PREOP: - inst.entry=(cpu.code.big ^1) * 0x200; - goto restartopcode; - case L_PREADD: - inst.prefix=(inst.prefix & ~1) | (cpu.code.big ^ 1); - goto restartopcode; - case L_VAL: - inst_op1_d=inst.code.extra; - break; - case L_INTO: - if (!get_OF()) goto nextopcode; - inst_op1_d=4; - break; - case D_IRETw: - CPU_IRET(false,GetIP()); - if (GETFLAG(IF) && PIC_IRQCheck) { - return CBRET_NONE; - } - continue; - case D_IRETd: - CPU_IRET(true,GetIP()); - if (GETFLAG(IF) && PIC_IRQCheck) - return CBRET_NONE; - continue; - case D_RETFwIw: - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(false,words,GetIP()); - continue; - } - case D_RETFw: - FillFlags(); - CPU_RET(false,0,GetIP()); - continue; - case D_RETFdIw: - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(true,words,GetIP()); - continue; - } - case D_RETFd: - FillFlags(); - CPU_RET(true,0,GetIP()); - continue; -/* Direct operations */ - case L_STRING: - #include "string.h" - goto nextopcode; - case D_PUSHAw: - { - Bit16u old_sp=reg_sp; - Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); - Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); - } - goto nextopcode; - case D_PUSHAd: - { - Bit32u old_esp=reg_esp; - Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); - Push_32(old_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); - } - goto nextopcode; - case D_POPAw: - reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP - reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); - goto nextopcode; - case D_POPAd: - reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP - reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); - goto nextopcode; - case D_POPSEGw: - if (CPU_PopSeg((SegNames)inst.code.extra,false)) RunException(); - goto nextopcode; - case D_POPSEGd: - if (CPU_PopSeg((SegNames)inst.code.extra,true)) RunException(); - goto nextopcode; - case D_SETALC: - reg_al = get_CF() ? 0xFF : 0; - goto nextopcode; - case D_XLAT: - if (inst.prefix & PREFIX_SEG) { - if (inst.prefix & PREFIX_ADDR) { - reg_al=LoadMb(inst.seg.base+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(inst.seg.base+(Bit16u)(reg_bx+reg_al)); - } - } else { - if (inst.prefix & PREFIX_ADDR) { - reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); - } - } - goto nextopcode; - case D_CBW: - reg_ax=(Bit8s)reg_al; - goto nextopcode; - case D_CWDE: - reg_eax=(Bit16s)reg_ax; - goto nextopcode; - case D_CWD: - if (reg_ax & 0x8000) reg_dx=0xffff; - else reg_dx=0; - goto nextopcode; - case D_CDQ: - if (reg_eax & 0x80000000) reg_edx=0xffffffff; - else reg_edx=0; - goto nextopcode; - case D_CLI: - if (CPU_CLI()) RunException(); - goto nextopcode; - case D_STI: - if (CPU_STI()) RunException(); - goto nextopcode; - case D_STC: - FillFlags();SETFLAGBIT(CF,true); - goto nextopcode; - case D_CLC: - FillFlags();SETFLAGBIT(CF,false); - goto nextopcode; - case D_CMC: - FillFlags(); - SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); - goto nextopcode; - case D_CLD: - SETFLAGBIT(DF,false); - cpu.direction=1; - goto nextopcode; - case D_STD: - SETFLAGBIT(DF,true); - cpu.direction=-1; - goto nextopcode; - case D_PUSHF: - if (CPU_PUSHF(inst.code.extra)) RunException(); - goto nextopcode; - case D_POPF: - if (CPU_POPF(inst.code.extra)) RunException(); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - goto nextopcode; - case D_SAHF: - SETFLAGSb(reg_ah); - goto nextopcode; - case D_LAHF: - FillFlags(); - reg_ah=reg_flags&0xff; - goto nextopcode; - case D_WAIT: - case D_NOP: - goto nextopcode; - case D_LOCK: /* FIXME: according to intel, LOCK should raise an exception if it's not followed by one of a small set of instructions; - probably doesn't matter for our purposes as it is a pentium prefix anyhow */ - LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); - goto nextopcode; - case D_ENTERw: - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(false,bytes,level); - goto nextopcode; - } - case D_ENTERd: - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(true,bytes,level); - goto nextopcode; - } - case D_LEAVEw: - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_bp=Pop_16(); - goto nextopcode; - case D_LEAVEd: - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_ebp=Pop_32(); - goto nextopcode; - case D_DAA: - DAA(); - goto nextopcode; - case D_DAS: - DAS(); - goto nextopcode; - case D_AAA: - AAA(); - goto nextopcode; - case D_AAS: - AAS(); - goto nextopcode; - case D_CPUID: - if (!CPU_CPUID()) goto illegalopcode; - goto nextopcode; - case D_HLT: - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - CPU_HLT(GetIP()); - return CBRET_NONE; - case D_CLTS: - if (cpu.pmode && cpu.cpl) goto illegalopcode; - cpu.cr0&=(~CR0_TASKSWITCH); - goto nextopcode; - case D_ICEBP: - CPU_SW_Interrupt_NoIOPLCheck(1,GetIP()); - continue; - default: - LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); - goto illegalopcode; -} - diff --git a/dosbox/core_full/loadwrite.h b/dosbox/core_full/loadwrite.h deleted file mode 100644 index aca53c49..00000000 --- a/dosbox/core_full/loadwrite.h +++ /dev/null @@ -1,39 +0,0 @@ -#define SaveIP() reg_eip=(Bit32u)(inst.cseip-SegBase(cs)); -#define LoadIP() inst.cseip=SegBase(cs)+reg_eip; -#define GetIP() (inst.cseip-SegBase(cs)) - -#define RunException() { \ - CPU_Exception(cpu.exception.which,cpu.exception.error); \ - continue; \ -} - -static INLINE Bit8u the_Fetchb(EAPoint & loc) { - Bit8u temp=LoadMb(loc); - loc+=1; - return temp; -} - -static INLINE Bit16u the_Fetchw(EAPoint & loc) { - Bit16u temp=LoadMw(loc); - loc+=2; - return temp; -} -static INLINE Bit32u the_Fetchd(EAPoint & loc) { - Bit32u temp=LoadMd(loc); - loc+=4; - return temp; -} - -#define Fetchb() the_Fetchb(inst.cseip) -#define Fetchw() the_Fetchw(inst.cseip) -#define Fetchd() the_Fetchd(inst.cseip) - -#define Fetchbs() (Bit8s)the_Fetchb(inst.cseip) -#define Fetchws() (Bit16s)the_Fetchw(inst.cseip) -#define Fetchds() (Bit32s)the_Fetchd(inst.cseip) - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - diff --git a/dosbox/core_full/op.h b/dosbox/core_full/op.h deleted file mode 100644 index 5e4114eb..00000000 --- a/dosbox/core_full/op.h +++ /dev/null @@ -1,651 +0,0 @@ -/* Do the actual opcode */ -switch (inst.code.op) { - case t_ADDb: case t_ADDw: case t_ADDd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d + lf_var2d; - lflags.type=inst.code.op; - break; - case t_CMPb: case t_CMPw: case t_CMPd: - case t_SUBb: case t_SUBw: case t_SUBd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d - lf_var2d; - lflags.type=inst.code.op; - break; - case t_ORb: case t_ORw: case t_ORd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d | lf_var2d; - lflags.type=inst.code.op; - break; - case t_XORb: case t_XORw: case t_XORd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d ^ lf_var2d; - lflags.type=inst.code.op; - break; - case t_TESTb: case t_TESTw: case t_TESTd: - case t_ANDb: case t_ANDw: case t_ANDd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d & lf_var2d; - lflags.type=inst.code.op; - break; - case t_ADCb: case t_ADCw: case t_ADCd: - lflags.oldcf=(get_CF()!=0); - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; - lflags.type=inst.code.op; - break; - case t_SBBb: case t_SBBw: case t_SBBd: - lflags.oldcf=(get_CF()!=0); - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; - lflags.type=inst.code.op; - break; - case t_INCb: case t_INCw: case t_INCd: - LoadCF; - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=inst_op1_d+1; - lflags.type=inst.code.op; - break; - case t_DECb: case t_DECw: case t_DECd: - LoadCF; - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=inst_op1_d-1; - lflags.type=inst.code.op; - break; -/* Using the instructions.h defines */ - case t_ROLb: - ROLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_ROLw: - ROLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_ROLd: - ROLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RORb: - RORB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RORw: - RORW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RORd: - RORD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RCLb: - RCLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RCLw: - RCLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RCLd: - RCLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RCRb: - RCRB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RCRw: - RCRW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RCRd: - RCRD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SHLb: - SHLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SHLw: - SHLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SHLd: - SHLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SHRb: - SHRB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SHRw: - SHRW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SHRd: - SHRD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SARb: - SARB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SARw: - SARW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SARd: - SARD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case O_DSHLw: - { - DSHLW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHRw: - { - DSHRW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHLd: - { - DSHLD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHRd: - { - DSHRD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); - break; - } - - case t_NEGb: - lf_var1b=inst_op1_b; - inst_op1_b=lf_resb=0-inst_op1_b; - lflags.type=t_NEGb; - break; - case t_NEGw: - lf_var1w=inst_op1_w; - inst_op1_w=lf_resw=0-inst_op1_w; - lflags.type=t_NEGw; - break; - case t_NEGd: - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=0-inst_op1_d; - lflags.type=t_NEGd; - break; - - case O_NOT: - inst_op1_d=~inst_op1_d; - break; - - /* Special instructions */ - case O_IMULRw: - DIMULW(inst_op1_ws,inst_op1_ws,inst_op2_ws,LoadD,SaveD); - break; - case O_IMULRd: - DIMULD(inst_op1_ds,inst_op1_ds,inst_op2_ds,LoadD,SaveD); - break; - case O_MULb: - MULB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_MULw: - MULW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_MULd: - MULD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_IMULb: - IMULB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_IMULw: - IMULW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_IMULd: - IMULD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_DIVb: - DIVB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_DIVw: - DIVW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_DIVd: - DIVD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_IDIVb: - IDIVB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_IDIVw: - IDIVW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_IDIVd: - IDIVD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_AAM: - AAM(inst_op1_b); - goto nextopcode; - case O_AAD: - AAD(inst_op1_b); - goto nextopcode; - - case O_C_O: inst.cond=TFLG_O; break; - case O_C_NO: inst.cond=TFLG_NO; break; - case O_C_B: inst.cond=TFLG_B; break; - case O_C_NB: inst.cond=TFLG_NB; break; - case O_C_Z: inst.cond=TFLG_Z; break; - case O_C_NZ: inst.cond=TFLG_NZ; break; - case O_C_BE: inst.cond=TFLG_BE; break; - case O_C_NBE: inst.cond=TFLG_NBE; break; - case O_C_S: inst.cond=TFLG_S; break; - case O_C_NS: inst.cond=TFLG_NS; break; - case O_C_P: inst.cond=TFLG_P; break; - case O_C_NP: inst.cond=TFLG_NP; break; - case O_C_L: inst.cond=TFLG_L; break; - case O_C_NL: inst.cond=TFLG_NL; break; - case O_C_LE: inst.cond=TFLG_LE; break; - case O_C_NLE: inst.cond=TFLG_NLE; break; - - case O_ALOP: - reg_al=LoadMb(inst.rm_eaa); - goto nextopcode; - case O_AXOP: - reg_ax=LoadMw(inst.rm_eaa); - goto nextopcode; - case O_EAXOP: - reg_eax=LoadMd(inst.rm_eaa); - goto nextopcode; - case O_OPAL: - SaveMb(inst.rm_eaa,reg_al); - goto nextopcode; - case O_OPAX: - SaveMw(inst.rm_eaa,reg_ax); - goto nextopcode; - case O_OPEAX: - SaveMd(inst.rm_eaa,reg_eax); - goto nextopcode; - case O_SEGDS: - inst.code.extra=ds; - break; - case O_SEGES: - inst.code.extra=es; - break; - case O_SEGFS: - inst.code.extra=fs; - break; - case O_SEGGS: - inst.code.extra=gs; - break; - case O_SEGSS: - inst.code.extra=ss; - break; - - case O_LOOP: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx) break; - } else { - if (--reg_cx) break; - } - goto nextopcode; - case O_LOOPZ: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx && get_ZF()) break; - } else { - if (--reg_cx && get_ZF()) break; - } - goto nextopcode; - case O_LOOPNZ: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx && !get_ZF()) break; - } else { - if (--reg_cx && !get_ZF()) break; - } - goto nextopcode; - case O_JCXZ: - if (inst.prefix & PREFIX_ADDR) { - if (reg_ecx) goto nextopcode; - } else { - if (reg_cx) goto nextopcode; - } - break; - case O_XCHG_AX: - { - Bit16u temp=reg_ax; - reg_ax=inst_op1_w; - inst_op1_w=temp; - break; - } - case O_XCHG_EAX: - { - Bit32u temp=reg_eax; - reg_eax=inst_op1_d; - inst_op1_d=temp; - break; - } - case O_CALLNw: - SaveIP(); - Push_16(reg_ip); - break; - case O_CALLNd: - SaveIP(); - Push_32(reg_eip); - break; - case O_CALLFw: - FillFlags(); - CPU_CALL(false,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_CALLFd: - FillFlags(); - CPU_CALL(true,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_JMPFw: - FillFlags(); - CPU_JMP(false,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_JMPFd: - FillFlags(); - CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_INT: -#if C_DEBUG - FillFlags(); - if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) - return debugCallback; - else if (DEBUG_IntBreakpoint(inst_op1_b)) - return debugCallback; -#endif - CPU_SW_Interrupt(inst_op1_b,GetIP()); - continue; - case O_INb: - if (CPU_IO_Exception(inst_op1_d,1)) RunException(); - reg_al=IO_ReadB(inst_op1_d); - goto nextopcode; - case O_INw: - if (CPU_IO_Exception(inst_op1_d,2)) RunException(); - reg_ax=IO_ReadW(inst_op1_d); - goto nextopcode; - case O_INd: - if (CPU_IO_Exception(inst_op1_d,4)) RunException(); - reg_eax=IO_ReadD(inst_op1_d); - goto nextopcode; - case O_OUTb: - if (CPU_IO_Exception(inst_op1_d,1)) RunException(); - IO_WriteB(inst_op1_d,reg_al); - goto nextopcode; - case O_OUTw: - if (CPU_IO_Exception(inst_op1_d,2)) RunException(); - IO_WriteW(inst_op1_d,reg_ax); - goto nextopcode; - case O_OUTd: - if (CPU_IO_Exception(inst_op1_d,4)) RunException(); - IO_WriteD(inst_op1_d,reg_eax); - goto nextopcode; - case O_CBACK: - FillFlags();SaveIP(); - return inst_op1_d; - case O_GRP6w: - case O_GRP6d: - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - switch (inst.rm_index) { - case 0x00: /* SLDT */ - inst_op1_d=(Bit32u)CPU_SLDT(); - break; - case 0x01: /* STR */ - inst_op1_d=(Bit32u)CPU_STR(); - break; - case 0x02: /* LLDT */ - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(inst_op1_d)) RunException(); - goto nextopcode; /* Else value will saved */ - case 0x03: /* LTR */ - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(inst_op1_d)) RunException(); - goto nextopcode; /* Else value will saved */ - case 0x04: /* VERR */ - CPU_VERR(inst_op1_d); - goto nextopcode; /* Else value will saved */ - case 0x05: /* VERW */ - CPU_VERW(inst_op1_d); - goto nextopcode; /* Else value will saved */ - default: - LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); - goto illegalopcode; - } - break; - case O_GRP7w: - case O_GRP7d: - switch (inst.rm_index) { - case 0: /* SGDT */ - SaveMw(inst.rm_eaa,CPU_SGDT_limit()); - SaveMd(inst.rm_eaa+2,CPU_SGDT_base()); - goto nextopcode; - case 1: /* SIDT */ - SaveMw(inst.rm_eaa,CPU_SIDT_limit()); - SaveMd(inst.rm_eaa+2,CPU_SIDT_base()); - goto nextopcode; - case 2: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - goto nextopcode; - case 3: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - goto nextopcode; - case 4: /* SMSW */ - inst_op1_d=CPU_SMSW(); - break; - case 6: /* LMSW */ - FillFlags(); - if (CPU_LMSW(inst_op1_w)) RunException(); - goto nextopcode; - case 7: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - PAGING_ClearTLB(); - goto nextopcode; - default: - LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); - goto illegalopcode; - } - break; - case O_M_CRx_Rd: - if (CPU_WRITE_CRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_CRx: - if (CPU_READ_CRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_DRx_Rd: - if (CPU_WRITE_DRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_DRx: - if (CPU_READ_DRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_TRx_Rd: - if (CPU_WRITE_TRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_TRx: - if (CPU_READ_TRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_LAR: - { - Bitu ar=inst_op2_d; - CPU_LAR(inst_op1_w,ar); - inst_op1_d=(Bit32u)ar; - } - break; - case O_LSL: - { - Bitu limit=inst_op2_d; - CPU_LSL(inst_op1_w,limit); - inst_op1_d=(Bit32u)limit; - } - break; - case O_ARPL: - { - Bitu new_sel=inst_op1_d; - CPU_ARPL(new_sel,inst_op2_d); - inst_op1_d=(Bit32u)new_sel; - } - break; - case O_BSFw: - { - FillFlags(); - if (!inst_op1_w) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=0; - while (1) { - if (inst_op1_w & 0x1) break; - count++;inst_op1_w>>=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSFd: - { - FillFlags(); - if (!inst_op1_d) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=0; - while (1) { - if (inst_op1_d & 0x1) break; - count++;inst_op1_d>>=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSRw: - { - FillFlags(); - if (!inst_op1_w) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=15; - while (1) { - if (inst_op1_w & 0x8000) break; - count--;inst_op1_w<<=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSRd: - { - FillFlags(); - if (!inst_op1_d) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=31; - while (1) { - if (inst_op1_d & 0x80000000) break; - count--;inst_op1_d<<=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BTw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - break; - case O_BTSw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d|=(1 << (inst_op2_d & 15)); - break; - case O_BTCw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d^=(1 << (inst_op2_d & 15)); - break; - case O_BTRw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d&=~(1 << (inst_op2_d & 15)); - break; - case O_BTd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - break; - case O_BTSd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d|=(1 << (inst_op2_d & 31)); - break; - case O_BTCd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d^=(1 << (inst_op2_d & 31)); - break; - case O_BTRd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d&=~(1 << (inst_op2_d & 31)); - break; - case O_BSWAPw: - if (CPU_ArchitectureType=0xc0) << 3) | inst.code.save) { - case 0x00: FPU_ESC0_EA(inst.rm,inst.rm_eaa);break; - case 0x01: FPU_ESC1_EA(inst.rm,inst.rm_eaa);break; - case 0x02: FPU_ESC2_EA(inst.rm,inst.rm_eaa);break; - case 0x03: FPU_ESC3_EA(inst.rm,inst.rm_eaa);break; - case 0x04: FPU_ESC4_EA(inst.rm,inst.rm_eaa);break; - case 0x05: FPU_ESC5_EA(inst.rm,inst.rm_eaa);break; - case 0x06: FPU_ESC6_EA(inst.rm,inst.rm_eaa);break; - case 0x07: FPU_ESC7_EA(inst.rm,inst.rm_eaa);break; - - case 0x08: FPU_ESC0_Normal(inst.rm);break; - case 0x09: FPU_ESC1_Normal(inst.rm);break; - case 0x0a: FPU_ESC2_Normal(inst.rm);break; - case 0x0b: FPU_ESC3_Normal(inst.rm);break; - case 0x0c: FPU_ESC4_Normal(inst.rm);break; - case 0x0d: FPU_ESC5_Normal(inst.rm);break; - case 0x0e: FPU_ESC6_Normal(inst.rm);break; - case 0x0f: FPU_ESC7_Normal(inst.rm);break; - } - } - goto nextopcode; -#else - LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save); - goto nextopcode; -#endif - case O_BOUNDw: - { - Bit16s bound_min, bound_max; - bound_min=LoadMw(inst.rm_eaa); - bound_max=LoadMw(inst.rm_eaa+2); - if ( (((Bit16s)inst_op1_w) < bound_min) || (((Bit16s)inst_op1_w) > bound_max) ) { - EXCEPTION(5); - } - } - break; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("OP:Unhandled code %d entry %X",inst.code.op,inst.entry); - -} diff --git a/dosbox/core_full/optable.h b/dosbox/core_full/optable.h deleted file mode 100644 index a938a8fe..00000000 --- a/dosbox/core_full/optable.h +++ /dev/null @@ -1,814 +0,0 @@ -/* Big ass opcode table normal,double, 66 normal, 66 double */ -static OpCode OpCodeTable[1024]={ -/* 0x00 - 0x07 */ -{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADDw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,es },{D_POPSEGw,0 ,0 ,es }, -/* 0x08 - 0x0f */ -{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ORb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ORw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,cs },{L_DOUBLE ,0 ,0 ,0 }, - -/* 0x10 - 0x17 */ -{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADCw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ss },{D_POPSEGw,0 ,0 ,ss }, -/* 0x18 - 0x1f */ -{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SBBw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ds },{D_POPSEGw,0 ,0 ,ds }, - -/* 0x20 - 0x27 */ -{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ANDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ANDw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ANDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ANDw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,es },{D_DAA ,0 ,0 ,0 }, -/* 0x28 - 0x2f */ -{L_MODRM ,t_SUBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SUBw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_SUBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SUBw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_SUBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SUBw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,cs },{D_DAS ,0 ,0 ,0 }, - -/* 0x30 - 0x37 */ -{L_MODRM ,t_XORb ,S_Eb ,M_EbGb },{L_MODRM ,t_XORw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_XORb ,S_Gb ,M_GbEb },{L_MODRM ,t_XORw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_XORb ,S_REGb ,REGI_AL },{L_REGwIw ,t_XORw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ss },{D_AAA ,0 ,0 ,0 }, -/* 0x38 - 0x3f */ -{L_MODRM ,t_CMPb ,0 ,M_EbGb },{L_MODRM ,t_CMPw ,0 ,M_EwGw }, -{L_MODRM ,t_CMPb ,0 ,M_GbEb },{L_MODRM ,t_CMPw ,0 ,M_GwEw }, -{L_REGbIb ,t_CMPb ,0 ,REGI_AL },{L_REGwIw ,t_CMPw ,0 ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ds },{D_AAS ,0 ,0 ,0 }, - -/* 0x40 - 0x47 */ -{L_REGw ,t_INCw ,S_REGw ,REGI_AX},{L_REGw ,t_INCw ,S_REGw ,REGI_CX}, -{L_REGw ,t_INCw ,S_REGw ,REGI_DX},{L_REGw ,t_INCw ,S_REGw ,REGI_BX}, -{L_REGw ,t_INCw ,S_REGw ,REGI_SP},{L_REGw ,t_INCw ,S_REGw ,REGI_BP}, -{L_REGw ,t_INCw ,S_REGw ,REGI_SI},{L_REGw ,t_INCw ,S_REGw ,REGI_DI}, -/* 0x48 - 0x4f */ -{L_REGw ,t_DECw ,S_REGw ,REGI_AX},{L_REGw ,t_DECw ,S_REGw ,REGI_CX}, -{L_REGw ,t_DECw ,S_REGw ,REGI_DX},{L_REGw ,t_DECw ,S_REGw ,REGI_BX}, -{L_REGw ,t_DECw ,S_REGw ,REGI_SP},{L_REGw ,t_DECw ,S_REGw ,REGI_BP}, -{L_REGw ,t_DECw ,S_REGw ,REGI_SI},{L_REGw ,t_DECw ,S_REGw ,REGI_DI}, - -/* 0x50 - 0x57 */ -{L_REGw ,0 ,S_PUSHw,REGI_AX},{L_REGw ,0 ,S_PUSHw,REGI_CX}, -{L_REGw ,0 ,S_PUSHw,REGI_DX},{L_REGw ,0 ,S_PUSHw,REGI_BX}, -{L_REGw ,0 ,S_PUSHw,REGI_SP},{L_REGw ,0 ,S_PUSHw,REGI_BP}, -{L_REGw ,0 ,S_PUSHw,REGI_SI},{L_REGw ,0 ,S_PUSHw,REGI_DI}, -/* 0x58 - 0x5f */ -{L_POPw ,0 ,S_REGw ,REGI_AX},{L_POPw ,0 ,S_REGw ,REGI_CX}, -{L_POPw ,0 ,S_REGw ,REGI_DX},{L_POPw ,0 ,S_REGw ,REGI_BX}, -{L_POPw ,0 ,S_REGw ,REGI_SP},{L_POPw ,0 ,S_REGw ,REGI_BP}, -{L_POPw ,0 ,S_REGw ,REGI_SI},{L_POPw ,0 ,S_REGw ,REGI_DI}, - - -/* 0x60 - 0x67 */ -{D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM_NVM ,O_ARPL ,S_Ew ,M_EwGw }, -{L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, -/* 0x68 - 0x6f */ -{L_Iw ,0 ,S_PUSHw,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxIwx}, -{L_Ibx ,0 ,S_PUSHw,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxIbx}, -{L_STRING ,R_INSB ,0 ,0 },{L_STRING ,R_INSW ,0 ,0 }, -{L_STRING ,R_OUTSB ,0 ,0 },{L_STRING ,R_OUTSW ,0 ,0 }, - - -/* 0x70 - 0x77 */ -{L_Ibx ,O_C_O ,S_C_AIPw,0 },{L_Ibx ,O_C_NO ,S_C_AIPw,0 }, -{L_Ibx ,O_C_B ,S_C_AIPw,0 },{L_Ibx ,O_C_NB ,S_C_AIPw,0 }, -{L_Ibx ,O_C_Z ,S_C_AIPw,0 },{L_Ibx ,O_C_NZ ,S_C_AIPw,0 }, -{L_Ibx ,O_C_BE ,S_C_AIPw,0 },{L_Ibx ,O_C_NBE ,S_C_AIPw,0 }, -/* 0x78 - 0x7f */ -{L_Ibx ,O_C_S ,S_C_AIPw,0 },{L_Ibx ,O_C_NS ,S_C_AIPw,0 }, -{L_Ibx ,O_C_P ,S_C_AIPw,0 },{L_Ibx ,O_C_NP ,S_C_AIPw,0 }, -{L_Ibx ,O_C_L ,S_C_AIPw,0 },{L_Ibx ,O_C_NL ,S_C_AIPw,0 }, -{L_Ibx ,O_C_LE ,S_C_AIPw,0 },{L_Ibx ,O_C_NLE ,S_C_AIPw,0 }, - - -/* 0x80 - 0x87 */ -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,1 ,0 ,M_GRP }, -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,3 ,0 ,M_GRP }, -{L_MODRM ,t_TESTb ,0 ,M_EbGb },{L_MODRM ,t_TESTw ,0 ,M_EwGw }, -{L_MODRM ,0 ,S_EbGb ,M_GbEb },{L_MODRM ,0 ,S_EwGw ,M_GwEw }, -/* 0x88 - 0x8f */ -{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ew ,M_Gw }, -{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, -{L_MODRM ,0 ,S_Ew ,M_SEG },{L_MODRM ,0 ,S_Gw ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPwRM ,0 ,S_Ew ,M_None }, - -/* 0x90 - 0x97 */ -{D_NOP ,0 ,0 ,0 },{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_CX}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DX},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_BX}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SP},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_BP}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SI},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DI}, -/* 0x98 - 0x9f */ -{D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, -{L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{D_PUSHF ,0 ,0 ,0 },{D_POPF ,0 ,0 ,0 }, -{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 }, - - -/* 0xa0 - 0xa7 */ -{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_AXOP ,0 ,0 }, -{L_OP ,O_OPAL ,0 ,0 },{L_OP ,O_OPAX ,0 ,0 }, -{L_STRING ,R_MOVSB ,0 ,0 },{L_STRING ,R_MOVSW ,0 ,0 }, -{L_STRING ,R_CMPSB ,0 ,0 },{L_STRING ,R_CMPSW ,0 ,0 }, -/* 0xa8 - 0xaf */ -{L_REGbIb ,t_TESTb ,0 ,REGI_AL},{L_REGwIw ,t_TESTw ,0 ,REGI_AX}, -{L_STRING ,R_STOSB ,0 ,0 },{L_STRING ,R_STOSW ,0 ,0 }, -{L_STRING ,R_LODSB ,0 ,0 },{L_STRING ,R_LODSW ,0 ,0 }, -{L_STRING ,R_SCASB ,0 ,0 },{L_STRING ,R_SCASW ,0 ,0 }, - -/* 0xb0 - 0xb7 */ -{L_Ib ,0 ,S_REGb ,REGI_AL},{L_Ib ,0 ,S_REGb ,REGI_CL}, -{L_Ib ,0 ,S_REGb ,REGI_DL},{L_Ib ,0 ,S_REGb ,REGI_BL}, -{L_Ib ,0 ,S_REGb ,REGI_AH},{L_Ib ,0 ,S_REGb ,REGI_CH}, -{L_Ib ,0 ,S_REGb ,REGI_DH},{L_Ib ,0 ,S_REGb ,REGI_BH}, -/* 0xb8 - 0xbf */ -{L_Iw ,0 ,S_REGw ,REGI_AX},{L_Iw ,0 ,S_REGw ,REGI_CX}, -{L_Iw ,0 ,S_REGw ,REGI_DX},{L_Iw ,0 ,S_REGw ,REGI_BX}, -{L_Iw ,0 ,S_REGw ,REGI_SP},{L_Iw ,0 ,S_REGw ,REGI_BP}, -{L_Iw ,0 ,S_REGw ,REGI_SI},{L_Iw ,0 ,S_REGw ,REGI_DI}, - -/* 0xc0 - 0xc7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,6 ,0 ,M_GRP_Ib }, -{L_POPw ,0 ,S_IPIw ,0 },{L_POPw ,0 ,S_IP ,0 }, -{L_MODRM ,O_SEGES ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGDS ,S_SEGGw,M_Efw }, -{L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ew ,M_Iw }, -/* 0xc8 - 0xcf */ -{D_ENTERw ,0 ,0 ,0 },{D_LEAVEw ,0 ,0 ,0 }, -{D_RETFwIw ,0 ,0 ,0 },{D_RETFw ,0 ,0 ,0 }, -{L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{D_IRETw ,0 ,0 ,0 }, - -/* 0xd0 - 0xd7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL }, -{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, -//TODO FPU -/* 0xd8 - 0xdf */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, -{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, -{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, -{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, - -/* 0xe0 - 0xe7 */ -{L_Ibx ,O_LOOPNZ ,S_AIPw ,0 },{L_Ibx ,O_LOOPZ ,S_AIPw ,0 }, -{L_Ibx ,O_LOOP ,S_AIPw ,0 },{L_Ibx ,O_JCXZ ,S_AIPw ,0 }, -{L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INw ,0 ,0 }, -{L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTw ,0 ,0 }, -/* 0xe8 - 0xef */ -{L_Iw ,O_CALLNw ,S_AIPw ,0 },{L_Iwx ,0 ,S_AIPw ,0 }, -{L_Ifw ,O_JMPFw ,0 ,0 },{L_Ibx ,0 ,S_AIPw ,0 }, -{L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INw ,0 ,REGI_DX}, -{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX}, - -/* 0xf0 - 0xf7 */ -{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, -{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, -{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP }, -/* 0xf8 - 0xff */ -{D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, -{D_CLI ,0 ,0 ,0 },{D_STI ,0 ,0 ,0 }, -{D_CLD ,0 ,0 ,0 },{D_STD ,0 ,0 ,0 }, -{L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xc ,0 ,M_GRP }, - -/* 0x100 - 0x107 */ -{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM_NVM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM_NVM ,O_LSL ,S_Gw ,M_EwGw }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x108 - 0x10f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x110 - 0x117 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x118 - 0x11f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x120 - 0x127 */ -{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, -{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, - -/* 0x128 - 0x12f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x130 - 0x137 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x138 - 0x13f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x140 - 0x147 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x148 - 0x14f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x150 - 0x157 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x158 - 0x15f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x160 - 0x167 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x168 - 0x16f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x170 - 0x177 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x178 - 0x17f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x180 - 0x187 */ -{L_Iwx ,O_C_O ,S_C_AIPw,0 },{L_Iwx ,O_C_NO ,S_C_AIPw,0 }, -{L_Iwx ,O_C_B ,S_C_AIPw,0 },{L_Iwx ,O_C_NB ,S_C_AIPw,0 }, -{L_Iwx ,O_C_Z ,S_C_AIPw,0 },{L_Iwx ,O_C_NZ ,S_C_AIPw,0 }, -{L_Iwx ,O_C_BE ,S_C_AIPw,0 },{L_Iwx ,O_C_NBE ,S_C_AIPw,0 }, -/* 0x188 - 0x18f */ -{L_Iwx ,O_C_S ,S_C_AIPw,0 },{L_Iwx ,O_C_NS ,S_C_AIPw,0 }, -{L_Iwx ,O_C_P ,S_C_AIPw,0 },{L_Iwx ,O_C_NP ,S_C_AIPw,0 }, -{L_Iwx ,O_C_L ,S_C_AIPw,0 },{L_Iwx ,O_C_NL ,S_C_AIPw,0 }, -{L_Iwx ,O_C_LE ,S_C_AIPw,0 },{L_Iwx ,O_C_NLE ,S_C_AIPw,0 }, - -/* 0x190 - 0x197 */ -{L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, -{L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, -{L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, -{L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, -/* 0x198 - 0x19f */ -{L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, -{L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, -{L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, -{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, - -/* 0x1a0 - 0x1a7 */ -{L_SEG ,0 ,S_PUSHw ,fs },{D_POPSEGw,0 ,0 ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1a8 - 0x1af */ -{L_SEG ,0 ,S_PUSHw ,gs },{D_POPSEGw,0 ,0 ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, - -/* 0x1b0 - 0x1b7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, -{L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, -/* 0x1b8 - 0x1bf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, -{L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, - -/* 0x1c0 - 0x1cc */ -{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDw ,S_EwGw ,M_GwEw }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1c8 - 0x1cf */ -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_AX},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_CX}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_DX},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_BX}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_SP},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_BP}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_SI},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_DI}, - -/* 0x1d0 - 0x1d7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1d8 - 0x1df */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x1e0 - 0x1ee */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1e8 - 0x1ef */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x1f0 - 0x1fc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1f8 - 0x1ff */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x200 - 0x207 */ -{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADDd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,es },{D_POPSEGd,0 ,0 ,es }, -/* 0x208 - 0x20f */ -{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ORb ,S_REGb ,REGI_AL },{L_REGdId ,t_ORd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,cs },{L_DOUBLE ,0 ,0 ,0 }, - -/* 0x210 - 0x217 */ -{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADCd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ss },{D_POPSEGd,0 ,0 ,ss }, -/* 0x218 - 0x21f */ -{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SBBd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ds },{D_POPSEGd,0 ,0 ,ds }, - -/* 0x220 - 0x227 */ -{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ANDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ANDd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ANDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ANDd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,es },{D_DAA ,0 ,0 ,0 }, -/* 0x228 - 0x22f */ -{L_MODRM ,t_SUBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SUBd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_SUBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SUBd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_SUBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SUBd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,cs },{D_DAS ,0 ,0 ,0 }, - -/* 0x230 - 0x237 */ -{L_MODRM ,t_XORb ,S_Eb ,M_EbGb },{L_MODRM ,t_XORd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_XORb ,S_Gb ,M_GbEb },{L_MODRM ,t_XORd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_XORb ,S_REGb ,REGI_AL },{L_REGdId ,t_XORd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ss },{D_AAA ,0 ,0 ,0 }, -/* 0x238 - 0x23f */ -{L_MODRM ,t_CMPb ,0 ,M_EbGb },{L_MODRM ,t_CMPd ,0 ,M_EdGd }, -{L_MODRM ,t_CMPb ,0 ,M_GbEb },{L_MODRM ,t_CMPd ,0 ,M_GdEd }, -{L_REGbIb ,t_CMPb ,0 ,REGI_AL },{L_REGdId ,t_CMPd ,0 ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ds },{D_AAS ,0 ,0 ,0 }, - -/* 0x240 - 0x247 */ -{L_REGd ,t_INCd ,S_REGd ,REGI_AX},{L_REGd ,t_INCd ,S_REGd ,REGI_CX}, -{L_REGd ,t_INCd ,S_REGd ,REGI_DX},{L_REGd ,t_INCd ,S_REGd ,REGI_BX}, -{L_REGd ,t_INCd ,S_REGd ,REGI_SP},{L_REGd ,t_INCd ,S_REGd ,REGI_BP}, -{L_REGd ,t_INCd ,S_REGd ,REGI_SI},{L_REGd ,t_INCd ,S_REGd ,REGI_DI}, -/* 0x248 - 0x24f */ -{L_REGd ,t_DECd ,S_REGd ,REGI_AX},{L_REGd ,t_DECd ,S_REGd ,REGI_CX}, -{L_REGd ,t_DECd ,S_REGd ,REGI_DX},{L_REGd ,t_DECd ,S_REGd ,REGI_BX}, -{L_REGd ,t_DECd ,S_REGd ,REGI_SP},{L_REGd ,t_DECd ,S_REGd ,REGI_BP}, -{L_REGd ,t_DECd ,S_REGd ,REGI_SI},{L_REGd ,t_DECd ,S_REGd ,REGI_DI}, - -/* 0x250 - 0x257 */ -{L_REGd ,0 ,S_PUSHd,REGI_AX},{L_REGd ,0 ,S_PUSHd,REGI_CX}, -{L_REGd ,0 ,S_PUSHd,REGI_DX},{L_REGd ,0 ,S_PUSHd,REGI_BX}, -{L_REGd ,0 ,S_PUSHd,REGI_SP},{L_REGd ,0 ,S_PUSHd,REGI_BP}, -{L_REGd ,0 ,S_PUSHd,REGI_SI},{L_REGd ,0 ,S_PUSHd,REGI_DI}, -/* 0x258 - 0x25f */ -{L_POPd ,0 ,S_REGd ,REGI_AX},{L_POPd ,0 ,S_REGd ,REGI_CX}, -{L_POPd ,0 ,S_REGd ,REGI_DX},{L_POPd ,0 ,S_REGd ,REGI_BX}, -{L_POPd ,0 ,S_REGd ,REGI_SP},{L_POPd ,0 ,S_REGd ,REGI_BP}, -{L_POPd ,0 ,S_REGd ,REGI_SI},{L_POPd ,0 ,S_REGd ,REGI_DI}, - -/* 0x260 - 0x267 */ -{D_PUSHAd ,0 ,0 ,0 },{D_POPAd ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDd ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, -/* 0x268 - 0x26f */ -{L_Id ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdId}, -{L_Ibx ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdIbx}, -{L_STRING ,R_INSB ,0 ,0 },{L_STRING ,R_INSD ,0 ,0 }, -{L_STRING ,R_OUTSB ,0 ,0 },{L_STRING ,R_OUTSD ,0 ,0 }, - -/* 0x270 - 0x277 */ -{L_Ibx ,O_C_O ,S_C_AIPd,0 },{L_Ibx ,O_C_NO ,S_C_AIPd,0 }, -{L_Ibx ,O_C_B ,S_C_AIPd,0 },{L_Ibx ,O_C_NB ,S_C_AIPd,0 }, -{L_Ibx ,O_C_Z ,S_C_AIPd,0 },{L_Ibx ,O_C_NZ ,S_C_AIPd,0 }, -{L_Ibx ,O_C_BE ,S_C_AIPd,0 },{L_Ibx ,O_C_NBE ,S_C_AIPd,0 }, -/* 0x278 - 0x27f */ -{L_Ibx ,O_C_S ,S_C_AIPd,0 },{L_Ibx ,O_C_NS ,S_C_AIPd,0 }, -{L_Ibx ,O_C_P ,S_C_AIPd,0 },{L_Ibx ,O_C_NP ,S_C_AIPd,0 }, -{L_Ibx ,O_C_L ,S_C_AIPd,0 },{L_Ibx ,O_C_NL ,S_C_AIPd,0 }, -{L_Ibx ,O_C_LE ,S_C_AIPd,0 },{L_Ibx ,O_C_NLE ,S_C_AIPd,0 }, - -/* 0x280 - 0x287 */ -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,2 ,0 ,M_GRP }, -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,4 ,0 ,M_GRP }, -{L_MODRM ,t_TESTb ,0 ,M_EbGb },{L_MODRM ,t_TESTd ,0 ,M_EdGd }, -{L_MODRM ,0 ,S_EbGb ,M_GbEb },{L_MODRM ,0 ,S_EdGd ,M_GdEd }, -/* 0x288 - 0x28f */ -{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ed ,M_Gd }, -{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ed }, -{L_MODRM ,0 ,S_EdMw ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPdRM ,0 ,S_Ed ,M_None }, - -/* 0x290 - 0x297 */ -{D_NOP ,0 ,0 ,0 },{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_CX}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DX},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BX}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SP},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BP}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, -/* 0x298 - 0x29f */ -{D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, -{L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{D_PUSHF ,0 ,0 ,true },{D_POPF ,0 ,0 ,true }, -{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 }, - -/* 0x2a0 - 0x2a7 */ -{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_EAXOP ,0 ,0 }, -{L_OP ,O_OPAL ,0 ,0 },{L_OP ,O_OPEAX ,0 ,0 }, -{L_STRING ,R_MOVSB ,0 ,0 },{L_STRING ,R_MOVSD ,0 ,0 }, -{L_STRING ,R_CMPSB ,0 ,0 },{L_STRING ,R_CMPSD ,0 ,0 }, -/* 0x2a8 - 0x2af */ -{L_REGbIb ,t_TESTb ,0 ,REGI_AL},{L_REGdId ,t_TESTd ,0 ,REGI_AX}, -{L_STRING ,R_STOSB ,0 ,0 },{L_STRING ,R_STOSD ,0 ,0 }, -{L_STRING ,R_LODSB ,0 ,0 },{L_STRING ,R_LODSD ,0 ,0 }, -{L_STRING ,R_SCASB ,0 ,0 },{L_STRING ,R_SCASD ,0 ,0 }, - -/* 0x2b0 - 0x2b7 */ -{L_Ib ,0 ,S_REGb ,REGI_AL},{L_Ib ,0 ,S_REGb ,REGI_CL}, -{L_Ib ,0 ,S_REGb ,REGI_DL},{L_Ib ,0 ,S_REGb ,REGI_BL}, -{L_Ib ,0 ,S_REGb ,REGI_AH},{L_Ib ,0 ,S_REGb ,REGI_CH}, -{L_Ib ,0 ,S_REGb ,REGI_DH},{L_Ib ,0 ,S_REGb ,REGI_BH}, -/* 0x2b8 - 0x2bf */ -{L_Id ,0 ,S_REGd ,REGI_AX},{L_Id ,0 ,S_REGd ,REGI_CX}, -{L_Id ,0 ,S_REGd ,REGI_DX},{L_Id ,0 ,S_REGd ,REGI_BX}, -{L_Id ,0 ,S_REGd ,REGI_SP},{L_Id ,0 ,S_REGd ,REGI_BP}, -{L_Id ,0 ,S_REGd ,REGI_SI},{L_Id ,0 ,S_REGd ,REGI_DI}, - -/* 0x2c0 - 0x2c7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,7 ,0 ,M_GRP_Ib }, -{L_POPd ,0 ,S_IPIw ,0 },{L_POPd ,0 ,S_IP ,0 }, -{L_MODRM ,O_SEGES ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGDS ,S_SEGGd,M_Efd }, -{L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ed ,M_Id }, -/* 0x2c8 - 0x2cf */ -{D_ENTERd ,0 ,0 ,0 },{D_LEAVEd ,0 ,0 ,0 }, -{D_RETFdIw ,0 ,0 ,0 },{D_RETFd ,0 ,0 ,0 }, -{L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{D_IRETd ,0 ,0 ,0 }, - -/* 0x2d0 - 0x2d7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, -{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, -/* 0x2d8 - 0x2df */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, -{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, -{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, -{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, - -/* 0x2e0 - 0x2e7 */ -{L_Ibx ,O_LOOPNZ ,S_AIPd ,0 },{L_Ibx ,O_LOOPZ ,S_AIPd ,0 }, -{L_Ibx ,O_LOOP ,S_AIPd ,0 },{L_Ibx ,O_JCXZ ,S_AIPd ,0 }, -{L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INd ,0 ,0 }, -{L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTd ,0 ,0 }, -/* 0x2e8 - 0x2ef */ -{L_Id ,O_CALLNd ,S_AIPd ,0 },{L_Idx ,0 ,S_AIPd ,0 }, -{L_Ifd ,O_JMPFd ,0 ,0 },{L_Ibx ,0 ,S_AIPd ,0 }, -{L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INd ,0 ,REGI_DX}, -{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX}, - -/* 0x2f0 - 0x2f7 */ -{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, -{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, -{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, -/* 0x2f8 - 0x2ff */ -{D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, -{D_CLI ,0 ,0 ,0 },{D_STI ,0 ,0 ,0 }, -{D_CLD ,0 ,0 ,0 },{D_STD ,0 ,0 ,0 }, -{L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xd ,0 ,M_GRP }, - - -/* 0x300 - 0x307 */ -{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM_NVM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM_NVM ,O_LSL ,S_Gd ,M_EdGd }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x308 - 0x30f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x310 - 0x317 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x318 - 0x31f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x320 - 0x327 */ -{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, -{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, - -/* 0x328 - 0x32f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x330 - 0x337 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x338 - 0x33f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x340 - 0x347 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x348 - 0x34f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x350 - 0x357 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x358 - 0x35f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x360 - 0x367 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x368 - 0x36f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x370 - 0x377 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x378 - 0x37f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x380 - 0x387 */ -{L_Idx ,O_C_O ,S_C_AIPd,0 },{L_Idx ,O_C_NO ,S_C_AIPd,0 }, -{L_Idx ,O_C_B ,S_C_AIPd,0 },{L_Idx ,O_C_NB ,S_C_AIPd,0 }, -{L_Idx ,O_C_Z ,S_C_AIPd,0 },{L_Idx ,O_C_NZ ,S_C_AIPd,0 }, -{L_Idx ,O_C_BE ,S_C_AIPd,0 },{L_Idx ,O_C_NBE ,S_C_AIPd,0 }, -/* 0x388 - 0x38f */ -{L_Idx ,O_C_S ,S_C_AIPd,0 },{L_Idx ,O_C_NS ,S_C_AIPd,0 }, -{L_Idx ,O_C_P ,S_C_AIPd,0 },{L_Idx ,O_C_NP ,S_C_AIPd,0 }, -{L_Idx ,O_C_L ,S_C_AIPd,0 },{L_Idx ,O_C_NL ,S_C_AIPd,0 }, -{L_Idx ,O_C_LE ,S_C_AIPd,0 },{L_Idx ,O_C_NLE ,S_C_AIPd,0 }, - -/* 0x390 - 0x397 */ -{L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, -{L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, -{L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, -{L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, -/* 0x398 - 0x39f */ -{L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, -{L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, -{L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, -{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, - -/* 0x3a0 - 0x3a7 */ -{L_SEG ,0 ,S_PUSHd ,fs },{D_POPSEGd,0 ,0 ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3a8 - 0x3af */ -{L_SEG ,0 ,S_PUSHd ,gs },{D_POPSEGd,0 ,0 ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, - -/* 0x3b0 - 0x3b7 */ -{0 ,0 ,0 ,0 },{L_MODRM ,O_CMPXCHG ,S_Ed ,M_Ed }, -{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, -{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, -/* 0x3b8 - 0x3bf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, -{L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, - -/* 0x3c0 - 0x3cc */ -{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDd ,S_EdGd ,M_GdEd }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3c8 - 0x3cf */ -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_AX},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_CX}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_DX},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_BX}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_SP},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_BP}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_SI},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_DI}, - -/* 0x3d0 - 0x3d7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3d8 - 0x3df */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x3e0 - 0x3ee */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3e8 - 0x3ef */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x3f0 - 0x3fc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3f8 - 0x3ff */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -}; - -static OpCode Groups[16][8]={ -{ /* 0x00 Group 1 Eb,Ib */ -{0 ,t_ADDb ,S_Eb ,M_EbIb },{0 ,t_ORb ,S_Eb ,M_EbIb }, -{0 ,t_ADCb ,S_Eb ,M_EbIb },{0 ,t_SBBb ,S_Eb ,M_EbIb }, -{0 ,t_ANDb ,S_Eb ,M_EbIb },{0 ,t_SUBb ,S_Eb ,M_EbIb }, -{0 ,t_XORb ,S_Eb ,M_EbIb },{0 ,t_CMPb ,0 ,M_EbIb }, -},{ /* 0x01 Group 1 Ew,Iw */ -{0 ,t_ADDw ,S_Ew ,M_EwIw },{0 ,t_ORw ,S_Ew ,M_EwIw }, -{0 ,t_ADCw ,S_Ew ,M_EwIw },{0 ,t_SBBw ,S_Ew ,M_EwIw }, -{0 ,t_ANDw ,S_Ew ,M_EwIw },{0 ,t_SUBw ,S_Ew ,M_EwIw }, -{0 ,t_XORw ,S_Ew ,M_EwIw },{0 ,t_CMPw ,0 ,M_EwIw }, -},{ /* 0x02 Group 1 Ed,Id */ -{0 ,t_ADDd ,S_Ed ,M_EdId },{0 ,t_ORd ,S_Ed ,M_EdId }, -{0 ,t_ADCd ,S_Ed ,M_EdId },{0 ,t_SBBd ,S_Ed ,M_EdId }, -{0 ,t_ANDd ,S_Ed ,M_EdId },{0 ,t_SUBd ,S_Ed ,M_EdId }, -{0 ,t_XORd ,S_Ed ,M_EdId },{0 ,t_CMPd ,0 ,M_EdId }, -},{ /* 0x03 Group 1 Ew,Ibx */ -{0 ,t_ADDw ,S_Ew ,M_EwIbx },{0 ,t_ORw ,S_Ew ,M_EwIbx }, -{0 ,t_ADCw ,S_Ew ,M_EwIbx },{0 ,t_SBBw ,S_Ew ,M_EwIbx }, -{0 ,t_ANDw ,S_Ew ,M_EwIbx },{0 ,t_SUBw ,S_Ew ,M_EwIbx }, -{0 ,t_XORw ,S_Ew ,M_EwIbx },{0 ,t_CMPw ,0 ,M_EwIbx }, -},{ /* 0x04 Group 1 Ed,Ibx */ -{0 ,t_ADDd ,S_Ed ,M_EdIbx },{0 ,t_ORd ,S_Ed ,M_EdIbx }, -{0 ,t_ADCd ,S_Ed ,M_EdIbx },{0 ,t_SBBd ,S_Ed ,M_EdIbx }, -{0 ,t_ANDd ,S_Ed ,M_EdIbx },{0 ,t_SUBd ,S_Ed ,M_EdIbx }, -{0 ,t_XORd ,S_Ed ,M_EdIbx },{0 ,t_CMPd ,0 ,M_EdIbx }, - -},{ /* 0x05 Group 2 Eb,XXX */ -{0 ,t_ROLb ,S_Eb ,M_Eb },{0 ,t_RORb ,S_Eb ,M_Eb }, -{0 ,t_RCLb ,S_Eb ,M_Eb },{0 ,t_RCRb ,S_Eb ,M_Eb }, -{0 ,t_SHLb ,S_Eb ,M_Eb },{0 ,t_SHRb ,S_Eb ,M_Eb }, -{0 ,t_SHLb ,S_Eb ,M_Eb },{0 ,t_SARb ,S_Eb ,M_Eb }, -},{ /* 0x06 Group 2 Ew,XXX */ -{0 ,t_ROLw ,S_Ew ,M_Ew },{0 ,t_RORw ,S_Ew ,M_Ew }, -{0 ,t_RCLw ,S_Ew ,M_Ew },{0 ,t_RCRw ,S_Ew ,M_Ew }, -{0 ,t_SHLw ,S_Ew ,M_Ew },{0 ,t_SHRw ,S_Ew ,M_Ew }, -{0 ,t_SHLw ,S_Ew ,M_Ew },{0 ,t_SARw ,S_Ew ,M_Ew }, -},{ /* 0x07 Group 2 Ed,XXX */ -{0 ,t_ROLd ,S_Ed ,M_Ed },{0 ,t_RORd ,S_Ed ,M_Ed }, -{0 ,t_RCLd ,S_Ed ,M_Ed },{0 ,t_RCRd ,S_Ed ,M_Ed }, -{0 ,t_SHLd ,S_Ed ,M_Ed },{0 ,t_SHRd ,S_Ed ,M_Ed }, -{0 ,t_SHLd ,S_Ed ,M_Ed },{0 ,t_SARd ,S_Ed ,M_Ed }, - - -},{ /* 0x08 Group 3 Eb */ -{0 ,t_TESTb ,0 ,M_EbIb },{0 ,t_TESTb ,0 ,M_EbIb }, -{0 ,O_NOT ,S_Eb ,M_Eb },{0 ,t_NEGb ,S_Eb ,M_Eb }, -{0 ,O_MULb ,0 ,M_Eb },{0 ,O_IMULb ,0 ,M_Eb }, -{0 ,O_DIVb ,0 ,M_Eb },{0 ,O_IDIVb ,0 ,M_Eb }, -},{ /* 0x09 Group 3 Ew */ -{0 ,t_TESTw ,0 ,M_EwIw },{0 ,t_TESTw ,0 ,M_EwIw }, -{0 ,O_NOT ,S_Ew ,M_Ew },{0 ,t_NEGw ,S_Ew ,M_Ew }, -{0 ,O_MULw ,0 ,M_Ew },{0 ,O_IMULw ,0 ,M_Ew }, -{0 ,O_DIVw ,0 ,M_Ew },{0 ,O_IDIVw ,0 ,M_Ew }, -},{ /* 0x0a Group 3 Ed */ -{0 ,t_TESTd ,0 ,M_EdId },{0 ,t_TESTd ,0 ,M_EdId }, -{0 ,O_NOT ,S_Ed ,M_Ed },{0 ,t_NEGd ,S_Ed ,M_Ed }, -{0 ,O_MULd ,0 ,M_Ed },{0 ,O_IMULd ,0 ,M_Ed }, -{0 ,O_DIVd ,0 ,M_Ed },{0 ,O_IDIVd ,0 ,M_Ed }, - -},{ /* 0x0b Group 4 Eb */ -{0 ,t_INCb ,S_Eb ,M_Eb },{0 ,t_DECb ,S_Eb ,M_Eb }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,O_CBACK ,0 ,M_Iw }, -},{ /* 0x0c Group 5 Ew */ -{0 ,t_INCw ,S_Ew ,M_Ew },{0 ,t_DECw ,S_Ew ,M_Ew }, -{0 ,O_CALLNw ,S_IP ,M_Ew },{0 ,O_CALLFw ,0 ,M_Efw }, -{0 ,0 ,S_IP ,M_Ew },{0 ,O_JMPFw ,0 ,M_Efw }, -{0 ,0 ,S_PUSHw,M_Ew },{0 ,0 ,0 ,0 }, -},{ /* 0x0d Group 5 Ed */ -{0 ,t_INCd ,S_Ed ,M_Ed },{0 ,t_DECd ,S_Ed ,M_Ed }, -{0 ,O_CALLNd ,S_IP ,M_Ed },{0 ,O_CALLFd ,0 ,M_Efd }, -{0 ,0 ,S_IP ,M_Ed },{0 ,O_JMPFd ,0 ,M_Efd }, -{0 ,0 ,S_PUSHd,M_Ed },{0 ,0 ,0 ,0 }, - - -},{ /* 0x0e Group 8 Ew */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTw ,S_Ew ,M_EwIb },{0 ,O_BTSw ,S_Ew ,M_EwIb }, -{0 ,O_BTRw ,S_Ew ,M_EwIb },{0 ,O_BTCw ,S_Ew ,M_EwIb }, -},{ /* 0x0f Group 8 Ed */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTd ,S_Ed ,M_EdIb },{0 ,O_BTSd ,S_Ed ,M_EdIb }, -{0 ,O_BTRd ,S_Ed ,M_EdIb },{0 ,O_BTCd ,S_Ed ,M_EdIb }, - - - -} -}; - - - diff --git a/dosbox/core_full/save.h b/dosbox/core_full/save.h deleted file mode 100644 index 4e10db12..00000000 --- a/dosbox/core_full/save.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Write the data from the opcode */ -switch (inst.code.save) { -/* Byte */ - case S_C_Eb: - inst_op1_b=inst.cond ? 1 : 0; - case S_Eb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); - else reg_8(inst.rm_eai)=inst_op1_b; - break; - case S_Gb: - reg_8(inst.rm_index)=inst_op1_b; - break; - case S_EbGb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); - else reg_8(inst.rm_eai)=inst_op1_b; - reg_8(inst.rm_index)=inst_op2_b; - break; -/* Word */ - case S_Ew: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_16(inst.rm_eai)=inst_op1_w; - break; - case S_Gw: - reg_16(inst.rm_index)=inst_op1_w; - break; - case S_EwGw: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_16(inst.rm_eai)=inst_op1_w; - reg_16(inst.rm_index)=inst_op2_w; - break; -/* Dword */ - case S_Ed: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); - else reg_32(inst.rm_eai)=inst_op1_d; - break; - case S_EdMw: /* Special one 16 to memory, 32 zero extend to reg */ - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_32(inst.rm_eai)=inst_op1_d; - break; - case S_Gd: - reg_32(inst.rm_index)=inst_op1_d; - break; - case S_EdGd: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); - else reg_32(inst.rm_eai)=inst_op1_d; - reg_32(inst.rm_index)=inst_op2_d; - break; - - case S_REGb: - reg_8(inst.code.extra)=inst_op1_b; - break; - case S_REGw: - reg_16(inst.code.extra)=inst_op1_w; - break; - case S_REGd: - reg_32(inst.code.extra)=inst_op1_d; - break; - case S_SEGm: - if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst_op1_w)) RunException(); - break; - case S_SEGGw: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); - reg_16(inst.rm_index)=inst_op1_w; - break; - case S_SEGGd: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); - reg_32(inst.rm_index)=inst_op1_d; - break; - case S_PUSHw: - Push_16(inst_op1_w); - break; - case S_PUSHd: - Push_32(inst_op1_d); - break; - - case S_C_AIPw: - if (!inst.cond) goto nextopcode; - case S_AIPw: - SaveIP(); - reg_eip+=inst_op1_d; - reg_eip&=0xffff; - continue; - case S_C_AIPd: - if (!inst.cond) goto nextopcode; - case S_AIPd: - SaveIP(); - reg_eip+=inst_op1_d; - continue; - case S_IPIw: - reg_esp+=Fetchw(); - case S_IP: - SaveIP(); - reg_eip=inst_op1_d; - continue; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("SAVE:Unhandled code %d entry %X",inst.code.save,inst.entry); -} diff --git a/dosbox/core_full/string.h b/dosbox/core_full/string.h deleted file mode 100644 index 5da65b10..00000000 --- a/dosbox/core_full/string.h +++ /dev/null @@ -1,227 +0,0 @@ -{ - EAPoint si_base,di_base; - Bitu si_index,di_index; - Bitu add_mask; - Bitu count,count_left; - Bits add_index; - - if (inst.prefix & PREFIX_SEG) si_base=inst.seg.base; - else si_base=SegBase(ds); - di_base=SegBase(es); - if (inst.prefix & PREFIX_ADDR) { - add_mask=0xFFFFFFFF; - si_index=reg_esi; - di_index=reg_edi; - count=reg_ecx; - } else { - add_mask=0xFFFF; - si_index=reg_si; - di_index=reg_di; - count=reg_cx; - } - if (!(inst.prefix & PREFIX_REP)) { - count=1; - } else { - /* Calculate amount of ops to do before cycles run out */ - CPU_Cycles++; - if ((count>(Bitu)CPU_Cycles) && (inst.code.op0;count--) { - IO_WriteB(reg_dx,LoadMb(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSW: - add_index<<=1; - for (;count>0;count--) { - IO_WriteW(reg_dx,LoadMw(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSD: - add_index<<=2; - for (;count>0;count--) { - IO_WriteD(reg_dx,LoadMd(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_INSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,IO_ReadB(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,IO_ReadW(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,reg_al); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,reg_ax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,reg_eax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_MOVSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,LoadMb(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,LoadMw(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,LoadMd(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSB: - for (;count>0;count--) { - reg_al=LoadMb(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSW: - add_index<<=1; - for (;count>0;count--) { - reg_ax=LoadMw(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSD: - add_index<<=2; - for (;count>0;count--) { - reg_eax=LoadMd(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_SCASB: - { - Bit8u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMb(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_al==val2)!=inst.repz) break; - } - CMPB(reg_al,val2,LoadD,0); - } - break; - case R_SCASW: - { - add_index<<=1;Bit16u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMw(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_ax==val2)!=inst.repz) break; - } - CMPW(reg_ax,val2,LoadD,0); - } - break; - case R_SCASD: - { - add_index<<=2;Bit32u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMd(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_eax==val2)!=inst.repz) break; - } - CMPD(reg_eax,val2,LoadD,0); - } - break; - case R_CMPSB: - { - Bit8u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMb(si_base+si_index); - val2=LoadMb(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPB(val1,val2,LoadD,0); - } - break; - case R_CMPSW: - { - add_index<<=1;Bit16u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMw(si_base+si_index); - val2=LoadMw(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPW(val1,val2,LoadD,0); - } - break; - case R_CMPSD: - { - add_index<<=2;Bit32u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMd(si_base+si_index); - val2=LoadMd(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPD(val1,val2,LoadD,0); - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled string %d entry %X",inst.code.op,inst.entry); - } - /* Clean up after certain amount of instructions */ - reg_esi&=(~add_mask); - reg_esi|=(si_index & add_mask); - reg_edi&=(~add_mask); - reg_edi|=(di_index & add_mask); - if (inst.prefix & PREFIX_REP) { - count+=count_left; - reg_ecx&=(~add_mask); - reg_ecx|=(count & add_mask); - } -} diff --git a/dosbox/core_full/support.h b/dosbox/core_full/support.h deleted file mode 100644 index 7a0c4dc2..00000000 --- a/dosbox/core_full/support.h +++ /dev/null @@ -1,249 +0,0 @@ -enum { - L_N=0, - L_SKIP, - /* Grouped ones using MOD/RM */ - L_MODRM,L_MODRM_NVM,L_POPwRM,L_POPdRM, - - L_Ib,L_Iw,L_Id, - L_Ibx,L_Iwx,L_Idx, //Sign extend - L_Ifw,L_Ifd, - L_OP, - - L_REGb,L_REGw,L_REGd, - L_REGbIb,L_REGwIw,L_REGdId, - L_POPw,L_POPd, - L_POPfw,L_POPfd, - L_SEG, - - L_INTO, - - L_VAL, - L_PRESEG, - L_DOUBLE, - L_PREOP,L_PREADD,L_PREREP,L_PREREPNE, - L_STRING, - -/* Direct ones */ - D_IRETw,D_IRETd, - D_PUSHAw,D_PUSHAd, - D_POPAw,D_POPAd, - D_POPSEGw,D_POPSEGd, - D_DAA,D_DAS, - D_AAA,D_AAS, - D_CBW,D_CWDE, - D_CWD,D_CDQ, - D_SETALC, - D_XLAT, - D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, - D_NOP,D_WAIT, - D_ENTERw,D_ENTERd, - D_LEAVEw,D_LEAVEd, - - D_RETFw,D_RETFd, - D_RETFwIw,D_RETFdIw, - D_POPF,D_PUSHF, - D_SAHF,D_LAHF, - D_CPUID, - D_HLT,D_CLTS, - D_LOCK,D_ICEBP, - L_ERROR -}; - - -enum { - O_N=t_LASTFLAG, - O_COND, - O_XCHG_AX,O_XCHG_EAX, - O_IMULRw,O_IMULRd, - O_BOUNDw,O_BOUNDd, - O_CALLNw,O_CALLNd, - O_CALLFw,O_CALLFd, - O_JMPFw,O_JMPFd, - - O_OPAL,O_ALOP, - O_OPAX,O_AXOP, - O_OPEAX,O_EAXOP, - O_INT, - O_SEGDS,O_SEGES,O_SEGFS,O_SEGGS,O_SEGSS, - O_LOOP,O_LOOPZ,O_LOOPNZ,O_JCXZ, - O_INb,O_INw,O_INd, - O_OUTb,O_OUTw,O_OUTd, - - O_NOT,O_AAM,O_AAD, - O_MULb,O_MULw,O_MULd, - O_IMULb,O_IMULw,O_IMULd, - O_DIVb,O_DIVw,O_DIVd, - O_IDIVb,O_IDIVw,O_IDIVd, - O_CBACK, - - - O_DSHLw,O_DSHLd, - O_DSHRw,O_DSHRd, - O_C_O ,O_C_NO ,O_C_B ,O_C_NB ,O_C_Z ,O_C_NZ ,O_C_BE ,O_C_NBE, - O_C_S ,O_C_NS ,O_C_P ,O_C_NP ,O_C_L ,O_C_NL ,O_C_LE ,O_C_NLE, - - O_GRP6w,O_GRP6d, - O_GRP7w,O_GRP7d, - O_M_CRx_Rd,O_M_Rd_CRx, - O_M_DRx_Rd,O_M_Rd_DRx, - O_M_TRx_Rd,O_M_Rd_TRx, - O_LAR,O_LSL, - O_ARPL, - - O_BTw,O_BTSw,O_BTRw,O_BTCw, - O_BTd,O_BTSd,O_BTRd,O_BTCd, - O_BSFw,O_BSRw,O_BSFd,O_BSRd, - - O_BSWAPw, O_BSWAPd, - O_CMPXCHG, - O_FPU - - -}; - -enum { - S_N=0, - S_C_Eb, - S_Eb,S_Gb,S_EbGb, - S_Ew,S_Gw,S_EwGw, - S_Ed,S_Gd,S_EdGd,S_EdMw, - - - S_REGb,S_REGw,S_REGd, - S_PUSHw,S_PUSHd, - S_SEGm, - S_SEGGw,S_SEGGd, - - - S_AIPw,S_C_AIPw, - S_AIPd,S_C_AIPd, - - S_IP,S_IPIw -}; - -enum { - R_OUTSB,R_OUTSW,R_OUTSD, - R_INSB,R_INSW,R_INSD, - R_MOVSB,R_MOVSW,R_MOVSD, - R_LODSB,R_LODSW,R_LODSD, - R_STOSB,R_STOSW,R_STOSD, - R_SCASB,R_SCASW,R_SCASD, - R_CMPSB,R_CMPSW,R_CMPSD -}; - -enum { - M_None=0, - M_Ebx,M_Eb,M_Gb,M_EbGb,M_GbEb, - M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,M_EwGwt, - M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,M_EdGdt, - - M_EbIb,M_EwIb,M_EdIb, - M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL, - M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL, - - M_Efw,M_Efd, - - M_Ib,M_Iw,M_Id, - - - M_SEG,M_EA, - M_GRP, - M_GRP_Ib,M_GRP_CL,M_GRP_1, - - M_POPw,M_POPd -}; - -struct OpCode { - Bit8u load,op,save,extra; -}; - -struct FullData { - Bitu entry; - Bitu rm; - EAPoint rm_eaa; - Bitu rm_off; - Bitu rm_eai; - Bitu rm_index; - Bitu rm_mod; - OpCode code; - EAPoint cseip; -#ifdef WORDS_BIGENDIAN - union { - Bit32u dword[1]; - Bit32s dwords[1]; - Bit16u word[2]; - Bit16s words[2]; - Bit8u byte[4]; - Bit8s bytes[4]; - } blah1,blah2,blah_imm; -#else - union { - Bit8u b;Bit8s bs; - Bit16u w;Bit16s ws; - Bit32u d;Bit32s ds; - } op1,op2,imm; -#endif - Bitu new_flags; - struct { - EAPoint base; - } seg; - Bitu cond; - bool repz; - Bitu prefix; -}; - -/* Some defines to get the names correct. */ -#ifdef WORDS_BIGENDIAN - -#define inst_op1_b inst.blah1.byte[3] -#define inst_op1_bs inst.blah1.bytes[3] -#define inst_op1_w inst.blah1.word[1] -#define inst_op1_ws inst.blah1.words[1] -#define inst_op1_d inst.blah1.dword[0] -#define inst_op1_ds inst.blah1.dwords[0] - -#define inst_op2_b inst.blah2.byte[3] -#define inst_op2_bs inst.blah2.bytes[3] -#define inst_op2_w inst.blah2.word[1] -#define inst_op2_ws inst.blah2.words[1] -#define inst_op2_d inst.blah2.dword[0] -#define inst_op2_ds inst.blah2.dwords[0] - -#define inst_imm_b inst.blah_imm.byte[3] -#define inst_imm_bs inst.blah_imm.bytes[3] -#define inst_imm_w inst.blah_imm.word[1] -#define inst_imm_ws inst.blah_imm.words[1] -#define inst_imm_d inst.blah_imm.dword[0] -#define inst_imm_ds inst.blah_imm.dwords[0] - -#else - -#define inst_op1_b inst.op1.b -#define inst_op1_bs inst.op1.bs -#define inst_op1_w inst.op1.w -#define inst_op1_ws inst.op1.ws -#define inst_op1_d inst.op1.d -#define inst_op1_ds inst.op1.ds - -#define inst_op2_b inst.op2.b -#define inst_op2_bs inst.op2.bs -#define inst_op2_w inst.op2.w -#define inst_op2_ws inst.op2.ws -#define inst_op2_d inst.op2.d -#define inst_op2_ds inst.op2.ds - -#define inst_imm_b inst.imm.b -#define inst_imm_bs inst.imm.bs -#define inst_imm_w inst.imm.w -#define inst_imm_ws inst.imm.ws -#define inst_imm_d inst.imm.d -#define inst_imm_ds inst.imm.ds - -#endif - - -#define PREFIX_NONE 0x0 -#define PREFIX_ADDR 0x1 -#define PREFIX_SEG 0x2 -#define PREFIX_REP 0x4 - diff --git a/dosbox/core_normal.cpp b/dosbox/core_normal.cpp deleted file mode 100644 index 7f3b25b7..00000000 --- a/dosbox/core_normal.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include "dosbox.h" -#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" -#include "fpu.h" -#include "paging.h" - -#if C_DEBUG -#include "debug.h" -#endif - -#if (!C_CORE_INLINE) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) -#else -#include "paging.h" -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) -#endif - -extern Bitu cycle_count; - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -#define CPU_PIC_CHECK 1 -#define CPU_TRAP_CHECK 1 - -#define OPCODE_NONE 0x000 -#define OPCODE_0F 0x100 -#define OPCODE_SIZE 0x200 - -#define PREFIX_ADDR 0x1 -#define PREFIX_REP 0x2 - -#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) -#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) - -#define DO_PREFIX_SEG(_SEG) \ - BaseDS=SegBase(_SEG); \ - BaseSS=SegBase(_SEG); \ - core.base_val_ds=_SEG; \ - goto restart_opcode; - -#define DO_PREFIX_ADDR() \ - core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ - (cpu.code.big ^ PREFIX_ADDR); \ - core.ea_table=&EATable[(core.prefixes&1) * 256]; \ - goto restart_opcode; - -#define DO_PREFIX_REP(_ZERO) \ - core.prefixes|=PREFIX_REP; \ - core.rep_zero=_ZERO; \ - goto restart_opcode; - -typedef PhysPt (*GetEAHandler)(void); - -static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; - -static struct { - Bitu opcode_index; - PhysPt cseip; - PhysPt base_ds,base_ss; - SegNames base_val_ds; - bool rep_zero; - Bitu prefixes; - GetEAHandler * ea_table; -} core; - -#define GETIP (core.cseip-SegBase(cs)) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(SegBase(cs)+reg_eip); - -#define SegBase(c) SegPhys(c) -#define BaseDS core.base_ds -#define BaseSS core.base_ss - -static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(core.cseip); - core.cseip+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(core.cseip); - core.cseip+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(core.cseip); - core.cseip+=4; - return temp; -} - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - -#include "instructions.h" -#include "core_normal/support.h" -#include "core_normal/string.h" - - -#define EALookupTable (core.ea_table) - -Bits CPU_Core_Normal_Run(void) { - while (CPU_Cycles-->0) { - LOADIP; - core.opcode_index=cpu.code.big*0x200; - core.prefixes=cpu.code.big; - core.ea_table=&EATable[cpu.code.big*256]; - BaseDS=SegBase(ds); - BaseSS=SegBase(ss); - core.base_val_ds=ds; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif - cycle_count++; -#endif -restart_opcode: - switch (core.opcode_index+Fetchb()) { - #include "core_normal/prefix_none.h" - #include "core_normal/prefix_0f.h" - #include "core_normal/prefix_66.h" - #include "core_normal/prefix_66_0f.h" - default: - illegal_opcode: -#if C_DEBUG - { - Bitu len=(GETIP-reg_eip); - LOADIP; - if (len>16) len=16; - char tempcode[16*2+1];char * writecode=tempcode; - for (;len>0;len--) { - sprintf(writecode,"%02X",mem_readb(core.cseip++)); - writecode+=2; - } - LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); - } -#endif - CPU_Exception(6,0); - continue; - } - SAVEIP; - } - FillFlags(); - return CBRET_NONE; -decode_end: - SAVEIP; - FillFlags(); - return CBRET_NONE; -} - -Bits CPU_Core_Normal_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Normal_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Normal_Run; - - return ret; -} - - - -void CPU_Core_Normal_Init(void) { - -} - diff --git a/dosbox/core_normal/helpers.h b/dosbox/core_normal/helpers.h deleted file mode 100644 index f0fb75c2..00000000 --- a/dosbox/core_normal/helpers.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define GetEAa \ - PhysPt eaa=EALookupTable[rm](); - -#define GetRMEAa \ - GetRM; \ - GetEAa; - - -#define RMEbGb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \ - } - -#define RMGbEb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \ - } - -#define RMEb(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,LoadMb,SaveMb);} \ - } - -#define RMEwGw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \ - } - -#define RMEwGwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \ - } - -#define RMGwEw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \ - } - -#define RMGwEwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \ - } - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEdGd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \ - } - -#define RMEdGdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \ - } - - -#define RMGdEd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \ - } - -#define RMGdEdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \ - } - - - - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEd(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,LoadMd,SaveMd);} \ - } - -#define ALIb(inst) \ - { inst(reg_al,Fetchb(),LoadRb,SaveRb)} - -#define AXIw(inst) \ - { inst(reg_ax,Fetchw(),LoadRw,SaveRw);} - -#define EAXId(inst) \ - { inst(reg_eax,Fetchd(),LoadRd,SaveRd);} - -#define FPU_ESC(code) { \ - Bit8u rm=Fetchb(); \ - if (rm >= 0xc0) { \ - FPU_ESC ## code ## _Normal(rm); \ - } else { \ - GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ - } \ -} - -#define CASE_W(_WHICH) \ - case (OPCODE_NONE+_WHICH): - -#define CASE_D(_WHICH) \ - case (OPCODE_SIZE+_WHICH): - -#define CASE_B(_WHICH) \ - CASE_W(_WHICH) \ - CASE_D(_WHICH) - -#define CASE_0F_W(_WHICH) \ - case ((OPCODE_0F|OPCODE_NONE)+_WHICH): - -#define CASE_0F_D(_WHICH) \ - case ((OPCODE_0F|OPCODE_SIZE)+_WHICH): - -#define CASE_0F_B(_WHICH) \ - CASE_0F_W(_WHICH) \ - CASE_0F_D(_WHICH) diff --git a/dosbox/core_normal/prefix_0f.h b/dosbox/core_normal/prefix_0f.h deleted file mode 100644 index 1c191b51..00000000 --- a/dosbox/core_normal/prefix_0f.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - CASE_0F_W(0x00) /* GRP 6 Exxx */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* SLDT */ - case 0x01: /* STR */ - { - Bitu saveval; - if (!which) saveval=CPU_SLDT(); - else saveval=CPU_STR(); - if (rm >= 0xc0) {GetEArw;*earw=saveval;} - else {GetEAa;SaveMw(eaa,saveval);} - } - break; - case 0x02:case 0x03:case 0x04:case 0x05: - { - Bitu loadval; - if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} - else {GetEAa;loadval=LoadMw(eaa);} - switch (which) { - case 0x02: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(loadval)) RUNEXCEPTION(); - break; - case 0x03: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(loadval)) RUNEXCEPTION(); - break; - case 0x04: - CPU_VERR(loadval); - break; - case 0x05: - CPU_VERW(loadval); - break; - } - } - break; - default: - goto illegal_opcode; - } - } - break; - CASE_0F_W(0x01) /* Group 7 Ew */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit; - switch (which) { - case 0x00: /* SGDT */ - SaveMw(eaa,CPU_SGDT_limit()); - SaveMd(eaa+2,CPU_SGDT_base()); - break; - case 0x01: /* SIDT */ - SaveMw(eaa,CPU_SIDT_limit()); - SaveMd(eaa+2,CPU_SIDT_base()); - break; - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x04: /* SMSW */ - SaveMw(eaa,CPU_SMSW()); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (CPU_LMSW(limit)) RUNEXCEPTION(); - break; - case 0x07: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - PAGING_ClearTLB(); - break; - } - } else { - GetEArw; - switch (which) { - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x04: /* SMSW */ - *earw=CPU_SMSW(); - break; - case 0x06: /* LMSW */ - if (CPU_LMSW(*earw)) RUNEXCEPTION(); - break; - default: - goto illegal_opcode; - } - } - } - break; - CASE_0F_W(0x02) /* LAR Gw,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw;Bitu ar=*rmrw; - if (rm >= 0xc0) { - GetEArw;CPU_LAR(*earw,ar); - } else { - GetEAa;CPU_LAR(LoadMw(eaa),ar); - } - *rmrw=(Bit16u)ar; - } - break; - CASE_0F_W(0x03) /* LSL Gw,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw;Bitu limit=*rmrw; - if (rm >= 0xc0) { - GetEArw;CPU_LSL(*earw,limit); - } else { - GetEAa;CPU_LSL(LoadMw(eaa),limit); - } - *rmrw=(Bit16u)limit; - } - break; - CASE_0F_B(0x06) /* CLTS */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - cpu.cr0&=(~CR0_TASKSWITCH); - break; - CASE_0F_B(0x08) /* INVD */ - CASE_0F_B(0x09) /* WBINVD */ - if (CPU_ArchitectureType> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); - } - GetEArd; - Bit32u crx_value; - if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION(); - *eard=crx_value; - } - break; - CASE_0F_B(0x21) /* MOV Rd,DRx */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR%u with non-register",which); - } - GetEArd; - Bit32u drx_value; - if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION(); - *eard=drx_value; - } - break; - CASE_0F_B(0x22) /* MOV CRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); - } - GetEArd; - if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x23) /* MOV DRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV DR%u,XXX with non-register",which); - } - GetEArd; - if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x24) /* MOV Rd,TRx */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR%u with non-register",which); - } - GetEArd; - Bit32u trx_value; - if (CPU_READ_TRX(which,trx_value)) RUNEXCEPTION(); - *eard=trx_value; - } - break; - CASE_0F_B(0x26) /* MOV TRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV TR%u,XXX with non-register",which); - } - GetEArd; - if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x31) /* RDTSC */ - { - if (CPU_ArchitectureType>32); - reg_eax=(Bit32u)(tsc&0xffffffff); - } - break; - CASE_0F_W(0x80) /* JO */ - JumpCond16_w(TFLG_O);break; - CASE_0F_W(0x81) /* JNO */ - JumpCond16_w(TFLG_NO);break; - CASE_0F_W(0x82) /* JB */ - JumpCond16_w(TFLG_B);break; - CASE_0F_W(0x83) /* JNB */ - JumpCond16_w(TFLG_NB);break; - CASE_0F_W(0x84) /* JZ */ - JumpCond16_w(TFLG_Z);break; - CASE_0F_W(0x85) /* JNZ */ - JumpCond16_w(TFLG_NZ);break; - CASE_0F_W(0x86) /* JBE */ - JumpCond16_w(TFLG_BE);break; - CASE_0F_W(0x87) /* JNBE */ - JumpCond16_w(TFLG_NBE);break; - CASE_0F_W(0x88) /* JS */ - JumpCond16_w(TFLG_S);break; - CASE_0F_W(0x89) /* JNS */ - JumpCond16_w(TFLG_NS);break; - CASE_0F_W(0x8a) /* JP */ - JumpCond16_w(TFLG_P);break; - CASE_0F_W(0x8b) /* JNP */ - JumpCond16_w(TFLG_NP);break; - CASE_0F_W(0x8c) /* JL */ - JumpCond16_w(TFLG_L);break; - CASE_0F_W(0x8d) /* JNL */ - JumpCond16_w(TFLG_NL);break; - CASE_0F_W(0x8e) /* JLE */ - JumpCond16_w(TFLG_LE);break; - CASE_0F_W(0x8f) /* JNLE */ - JumpCond16_w(TFLG_NLE);break; - CASE_0F_B(0x90) /* SETO */ - SETcc(TFLG_O);break; - CASE_0F_B(0x91) /* SETNO */ - SETcc(TFLG_NO);break; - CASE_0F_B(0x92) /* SETB */ - SETcc(TFLG_B);break; - CASE_0F_B(0x93) /* SETNB */ - SETcc(TFLG_NB);break; - CASE_0F_B(0x94) /* SETZ */ - SETcc(TFLG_Z);break; - CASE_0F_B(0x95) /* SETNZ */ - SETcc(TFLG_NZ); break; - CASE_0F_B(0x96) /* SETBE */ - SETcc(TFLG_BE);break; - CASE_0F_B(0x97) /* SETNBE */ - SETcc(TFLG_NBE);break; - CASE_0F_B(0x98) /* SETS */ - SETcc(TFLG_S);break; - CASE_0F_B(0x99) /* SETNS */ - SETcc(TFLG_NS);break; - CASE_0F_B(0x9a) /* SETP */ - SETcc(TFLG_P);break; - CASE_0F_B(0x9b) /* SETNP */ - SETcc(TFLG_NP);break; - CASE_0F_B(0x9c) /* SETL */ - SETcc(TFLG_L);break; - CASE_0F_B(0x9d) /* SETNL */ - SETcc(TFLG_NL);break; - CASE_0F_B(0x9e) /* SETLE */ - SETcc(TFLG_LE);break; - CASE_0F_B(0x9f) /* SETNLE */ - SETcc(TFLG_NLE);break; - - CASE_0F_W(0xa0) /* PUSH FS */ - Push_16(SegValue(fs));break; - CASE_0F_W(0xa1) /* POP FS */ - if (CPU_PopSeg(fs,false)) RUNEXCEPTION(); - break; - CASE_0F_B(0xa2) /* CPUID */ - if (!CPU_CPUID()) goto illegal_opcode; - break; - CASE_0F_W(0xa3) /* BT Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - } - break; - } - CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */ - RMEwGwOp3(DSHLW,Fetchb()); - break; - CASE_0F_W(0xa5) /* SHLD Ew,Gw,CL */ - RMEwGwOp3(DSHLW,reg_cl); - break; - CASE_0F_W(0xa8) /* PUSH GS */ - Push_16(SegValue(gs));break; - CASE_0F_W(0xa9) /* POP GS */ - if (CPU_PopSeg(gs,false)) RUNEXCEPTION(); - break; - CASE_0F_W(0xab) /* BTS Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw|=mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old | mask); - } - break; - } - CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */ - RMEwGwOp3(DSHRW,Fetchb()); - break; - CASE_0F_W(0xad) /* SHRD Ew,Gw,CL */ - RMEwGwOp3(DSHRW,reg_cl); - break; - CASE_0F_W(0xaf) /* IMUL Gw,Ew */ - RMGwEwOp3(DIMULW,*rmrw); - break; - CASE_0F_B(0xb0) /* cmpxchg Eb,Gb */ - { - if (CPU_ArchitectureType= 0xc0 ) { - GetEArb; - if (reg_al == *earb) { - *earb=*rmrb; - SETFLAGBIT(ZF,1); - } else { - reg_al = *earb; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit8u val = LoadMb(eaa); - if (reg_al == val) { - SaveMb(eaa,*rmrb); - SETFLAGBIT(ZF,1); - } else { - SaveMb(eaa,val); // cmpxchg always issues a write - reg_al = val; - SETFLAGBIT(ZF,0); - } - } - break; - } - CASE_0F_W(0xb1) /* cmpxchg Ew,Gw */ - { - if (CPU_ArchitectureType= 0xc0 ) { - GetEArw; - if(reg_ax == *earw) { - *earw = *rmrw; - SETFLAGBIT(ZF,1); - } else { - reg_ax = *earw; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit16u val = LoadMw(eaa); - if(reg_ax == val) { - SaveMw(eaa,*rmrw); - SETFLAGBIT(ZF,1); - } else { - SaveMw(eaa,val); // cmpxchg always issues a write - reg_ax = val; - SETFLAGBIT(ZF,0); - } - } - break; - } - - CASE_0F_W(0xb2) /* LSS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb3) /* BTR Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw&= ~mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old & ~mask); - } - break; - } - CASE_0F_W(0xb4) /* LFS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb5) /* LGS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb6) /* MOVZX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;} - else {GetEAa;*rmrw=LoadMb(eaa);} - break; - } - CASE_0F_W(0xb7) /* MOVZX Gw,Ew */ - CASE_0F_W(0xbf) /* MOVSX Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - CASE_0F_W(0xba) /* GRP8 Ew,Ib */ - { - FillFlags();GetRM; - if (rm >= 0xc0 ) { - GetEArw; - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(*earw & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *earw|=mask; - break; - case 0x30: /* BTR */ - *earw&= ~mask; - break; - case 0x38: /* BTC */ - *earw^=mask; - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit16u old=LoadMw(eaa); - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMw(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMw(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - SaveMw(eaa,old ^ mask); - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - break; - } - CASE_0F_W(0xbb) /* BTC Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw^=mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old ^ mask); - } - break; - } - CASE_0F_W(0xbc) /* BSF Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_W(0xbd) /* BSR Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 15; // Operandsize-1 - while ((value & 0x8000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_W(0xbe) /* MOVSX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;} - else {GetEAa;*rmrw=LoadMbs(eaa);} - break; - } - CASE_0F_B(0xc0) /* XADD Gb,Eb */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;} - else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);} - break; - } - CASE_0F_W(0xc1) /* XADD Gw,Ew */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;} - else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);} - break; - } - CASE_0F_W(0xc8) /* BSWAP AX */ - if (CPU_ArchitectureType bound_max) ) { - EXCEPTION(5); - } - } - break; - CASE_D(0x63) /* ARPL Ed,Rd */ - { - if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw; - if (rm >= 0xc0 ) { - GetEArd;Bitu new_sel=(Bit16u)*eard; - CPU_ARPL(new_sel,*rmrw); - *eard=(Bit32u)new_sel; - } else { - GetEAa;Bitu new_sel=LoadMw(eaa); - CPU_ARPL(new_sel,*rmrw); - SaveMd(eaa,(Bit32u)new_sel); - } - } - break; - CASE_D(0x68) /* PUSH Id */ - Push_32(Fetchd());break; - CASE_D(0x69) /* IMUL Gd,Ed,Id */ - RMGdEdOp3(DIMULD,Fetchds()); - break; - CASE_D(0x6a) /* PUSH Ib */ - Push_32(Fetchbs());break; - CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ - RMGdEdOp3(DIMULD,Fetchbs()); - break; - CASE_D(0x6d) /* INSD */ - if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); - DoString(R_INSD);break; - CASE_D(0x6f) /* OUTSD */ - if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); - DoString(R_OUTSD);break; - CASE_D(0x70) /* JO */ - JumpCond32_b(TFLG_O);break; - CASE_D(0x71) /* JNO */ - JumpCond32_b(TFLG_NO);break; - CASE_D(0x72) /* JB */ - JumpCond32_b(TFLG_B);break; - CASE_D(0x73) /* JNB */ - JumpCond32_b(TFLG_NB);break; - CASE_D(0x74) /* JZ */ - JumpCond32_b(TFLG_Z);break; - CASE_D(0x75) /* JNZ */ - JumpCond32_b(TFLG_NZ);break; - CASE_D(0x76) /* JBE */ - JumpCond32_b(TFLG_BE);break; - CASE_D(0x77) /* JNBE */ - JumpCond32_b(TFLG_NBE);break; - CASE_D(0x78) /* JS */ - JumpCond32_b(TFLG_S);break; - CASE_D(0x79) /* JNS */ - JumpCond32_b(TFLG_NS);break; - CASE_D(0x7a) /* JP */ - JumpCond32_b(TFLG_P);break; - CASE_D(0x7b) /* JNP */ - JumpCond32_b(TFLG_NP);break; - CASE_D(0x7c) /* JL */ - JumpCond32_b(TFLG_L);break; - CASE_D(0x7d) /* JNL */ - JumpCond32_b(TFLG_NL);break; - CASE_D(0x7e) /* JLE */ - JumpCond32_b(TFLG_LE);break; - CASE_D(0x7f) /* JNLE */ - JumpCond32_b(TFLG_NLE);break; - CASE_D(0x81) /* Grpl Ed,Id */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm >= 0xc0) { - GetEArd;Bit32u id=Fetchd(); - switch (which) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=Fetchd(); - switch (which) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - CASE_D(0x83) /* Grpl Ed,Ix */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm >= 0xc0) { - GetEArd;Bit32u id=(Bit32s)Fetchbs(); - switch (which) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=(Bit32s)Fetchbs(); - switch (which) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - CASE_D(0x85) /* TEST Ed,Gd */ - RMEdGd(TESTD);break; - CASE_D(0x87) /* XCHG Ed,Gd */ - { - GetRMrd;Bit32u oldrmrd=*rmrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} - else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} - break; - } - CASE_D(0x89) /* MOV Ed,Gd */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;} - else {GetEAa;SaveMd(eaa,*rmrd);} - break; - } - CASE_D(0x8b) /* MOV Gd,Ed */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;} - else {GetEAa;*rmrd=LoadMd(eaa);} - break; - } - CASE_D(0x8c) /* Mov Ew,Sw */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* MOV Ew,ES */ - val=SegValue(es);break; - case 0x01: /* MOV Ew,CS */ - val=SegValue(cs);break; - case 0x02: /* MOV Ew,SS */ - val=SegValue(ss);break; - case 0x03: /* MOV Ew,DS */ - val=SegValue(ds);break; - case 0x04: /* MOV Ew,FS */ - val=SegValue(fs);break; - case 0x05: /* MOV Ew,GS */ - val=SegValue(gs);break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); - goto illegal_opcode; - } - if (rm >= 0xc0 ) {GetEArd;*eard=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_D(0x8d) /* LEA Gd */ - { - //Little hack to always use segprefixed version - GetRMrd; - BaseDS=BaseSS=0; - if (TEST_PREFIX_ADDR) { - *rmrd=(Bit32u)(*EATable[256+rm])(); - } else { - *rmrd=(Bit32u)(*EATable[rm])(); - } - break; - } - CASE_D(0x8f) /* POP Ed */ - { - Bit32u val=Pop_32(); - GetRM; - if (rm >= 0xc0 ) {GetEArd;*eard=val;} - else {GetEAa;SaveMd(eaa,val);} - break; - } - CASE_D(0x91) /* XCHG ECX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;} - CASE_D(0x92) /* XCHG EDX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;} - break; - CASE_D(0x93) /* XCHG EBX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;} - break; - CASE_D(0x94) /* XCHG ESP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;} - break; - CASE_D(0x95) /* XCHG EBP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;} - break; - CASE_D(0x96) /* XCHG ESI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;} - break; - CASE_D(0x97) /* XCHG EDI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;} - break; - CASE_D(0x98) /* CWDE */ - reg_eax=(Bit16s)reg_ax;break; - CASE_D(0x99) /* CDQ */ - if (reg_eax & 0x80000000) reg_edx=0xffffffff; - else reg_edx=0; - break; - CASE_D(0x9a) /* CALL FAR Ad */ - { - Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); - FillFlags(); - CPU_CALL(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_D(0x9c) /* PUSHFD */ - if (CPU_PUSHF(true)) RUNEXCEPTION(); - break; - CASE_D(0x9d) /* POPFD */ - if (CPU_POPF(true)) RUNEXCEPTION(); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - goto decode_end; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_D(0xa1) /* MOV EAX,Od */ - { - GetEADirect; - reg_eax=LoadMd(eaa); - } - break; - CASE_D(0xa3) /* MOV Od,EAX */ - { - GetEADirect; - SaveMd(eaa,reg_eax); - } - break; - CASE_D(0xa5) /* MOVSD */ - DoString(R_MOVSD);break; - CASE_D(0xa7) /* CMPSD */ - DoString(R_CMPSD);break; - CASE_D(0xa9) /* TEST EAX,Id */ - EAXId(TESTD);break; - CASE_D(0xab) /* STOSD */ - DoString(R_STOSD);break; - CASE_D(0xad) /* LODSD */ - DoString(R_LODSD);break; - CASE_D(0xaf) /* SCASD */ - DoString(R_SCASD);break; - CASE_D(0xb8) /* MOV EAX,Id */ - reg_eax=Fetchd();break; - CASE_D(0xb9) /* MOV ECX,Id */ - reg_ecx=Fetchd();break; - CASE_D(0xba) /* MOV EDX,Iw */ - reg_edx=Fetchd();break; - CASE_D(0xbb) /* MOV EBX,Id */ - reg_ebx=Fetchd();break; - CASE_D(0xbc) /* MOV ESP,Id */ - reg_esp=Fetchd();break; - CASE_D(0xbd) /* MOV EBP.Id */ - reg_ebp=Fetchd();break; - CASE_D(0xbe) /* MOV ESI,Id */ - reg_esi=Fetchd();break; - CASE_D(0xbf) /* MOV EDI,Id */ - reg_edi=Fetchd();break; - CASE_D(0xc1) /* GRP2 Ed,Ib */ - GRP2D(Fetchb());break; - CASE_D(0xc2) /* RETN Iw */ - reg_eip=Pop_32(); - reg_esp+=Fetchw(); - continue; - CASE_D(0xc3) /* RETN */ - reg_eip=Pop_32(); - continue; - CASE_D(0xc4) /* LES */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_D(0xc5) /* LDS */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_D(0xc7) /* MOV Ed,Id */ - { - GetRM; - if (rm >= 0xc0) {GetEArd;*eard=Fetchd();} - else {GetEAa;SaveMd(eaa,Fetchd());} - break; - } - CASE_D(0xc8) /* ENTER Iw,Ib */ - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(true,bytes,level); - } - break; - CASE_D(0xc9) /* LEAVE */ - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_ebp=Pop_32(); - break; - CASE_D(0xca) /* RETF Iw */ - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(true,words,GETIP); - continue; - } - CASE_D(0xcb) /* RETF */ - { - FillFlags(); - CPU_RET(true,0,GETIP); - continue; - } - CASE_D(0xcf) /* IRET */ - { - CPU_IRET(true,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; -#endif - continue; - } - CASE_D(0xd1) /* GRP2 Ed,1 */ - GRP2D(1);break; - CASE_D(0xd3) /* GRP2 Ed,CL */ - GRP2D(reg_cl);break; - CASE_D(0xe0) /* LOOPNZ */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx && !get_ZF()); - } else { - JumpCond32_b(--reg_cx && !get_ZF()); - } - break; - CASE_D(0xe1) /* LOOPZ */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx && get_ZF()); - } else { - JumpCond32_b(--reg_cx && get_ZF()); - } - break; - CASE_D(0xe2) /* LOOP */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx); - } else { - JumpCond32_b(--reg_cx); - } - break; - CASE_D(0xe3) /* JCXZ */ - JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); - break; - CASE_D(0xe5) /* IN EAX,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); - reg_eax=IO_ReadD(port); - break; - } - CASE_D(0xe7) /* OUT Ib,EAX */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); - IO_WriteD(port,reg_eax); - break; - } - CASE_D(0xe8) /* CALL Jd */ - { - Bit32s addip=Fetchds(); - SAVEIP; - Push_32(reg_eip); - reg_eip+=addip; - continue; - } - CASE_D(0xe9) /* JMP Jd */ - { - Bit32s addip=Fetchds(); - SAVEIP; - reg_eip+=addip; - continue; - } - CASE_D(0xea) /* JMP Ad */ - { - Bit32u newip=Fetchd(); - Bit16u newcs=Fetchw(); - FillFlags(); - CPU_JMP(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_D(0xeb) /* JMP Jb */ - { - Bit32s addip=Fetchbs(); - SAVEIP; - reg_eip+=addip; - continue; - } - CASE_D(0xed) /* IN EAX,DX */ - reg_eax=IO_ReadD(reg_dx); - break; - CASE_D(0xef) /* OUT DX,EAX */ - IO_WriteD(reg_dx,reg_eax); - break; - CASE_D(0xf7) /* GRP3 Ed(,Id) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Ed,Id */ - case 0x01: /* TEST Ed,Id Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);} - else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);} - break; - } - case 0x02: /* NOT Ed */ - { - if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} - else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} - break; - } - case 0x03: /* NEG Ed */ - { - lflags.type=t_NEGd; - if (rm >= 0xc0 ) { - GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d; - *eard=lf_resd; - } else { - GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d; - SaveMd(eaa,lf_resd); - } - break; - } - case 0x04: /* MUL EAX,Ed */ - RMEd(MULD); - break; - case 0x05: /* IMUL EAX,Ed */ - RMEd(IMULD); - break; - case 0x06: /* DIV Ed */ - RMEd(DIVD); - break; - case 0x07: /* IDIV Ed */ - RMEd(IDIVD); - break; - } - break; - } - CASE_D(0xff) /* GRP 5 Ed */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Ed */ - RMEd(INCD); - break; - case 0x01: /* DEC Ed */ - RMEd(DECD); - break; - case 0x02: /* CALL NEAR Ed */ - if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} - else {GetEAa;reg_eip=LoadMd(eaa);} - Push_32(GETIP); - continue; - case 0x03: /* CALL FAR Ed */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit32u newip=LoadMd(eaa); - Bit16u newcs=LoadMw(eaa+4); - FillFlags(); - CPU_CALL(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - case 0x04: /* JMP NEAR Ed */ - if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} - else {GetEAa;reg_eip=LoadMd(eaa);} - continue; - case 0x05: /* JMP FAR Ed */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit32u newip=LoadMd(eaa); - Bit16u newcs=LoadMw(eaa+4); - FillFlags(); - CPU_JMP(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x06: /* Push Ed */ - if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);} - else {GetEAa;Push_32(LoadMd(eaa));} - break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",which); - goto illegal_opcode; - } - break; - } - - diff --git a/dosbox/core_normal/prefix_66_0f.h b/dosbox/core_normal/prefix_66_0f.h deleted file mode 100644 index eed5bac8..00000000 --- a/dosbox/core_normal/prefix_66_0f.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - CASE_0F_D(0x00) /* GRP 6 Exxx */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* SLDT */ - case 0x01: /* STR */ - { - Bitu saveval; - if (!which) saveval=CPU_SLDT(); - else saveval=CPU_STR(); - if (rm >= 0xc0) {GetEArw;*earw=(Bit16u)saveval;} - else {GetEAa;SaveMw(eaa,saveval);} - } - break; - case 0x02:case 0x03:case 0x04:case 0x05: - { - /* Just use 16-bit loads since were only using selectors */ - Bitu loadval; - if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} - else {GetEAa;loadval=LoadMw(eaa);} - switch (which) { - case 0x02: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(loadval)) RUNEXCEPTION(); - break; - case 0x03: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(loadval)) RUNEXCEPTION(); - break; - case 0x04: - CPU_VERR(loadval); - break; - case 0x05: - CPU_VERW(loadval); - break; - } - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); - goto illegal_opcode; - } - } - break; - CASE_0F_D(0x01) /* Group 7 Ed */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit; - switch (which) { - case 0x00: /* SGDT */ - SaveMw(eaa,(Bit16u)CPU_SGDT_limit()); - SaveMd(eaa+2,(Bit32u)CPU_SGDT_base()); - break; - case 0x01: /* SIDT */ - SaveMw(eaa,(Bit16u)CPU_SIDT_limit()); - SaveMd(eaa+2,(Bit32u)CPU_SIDT_base()); - break; - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x04: /* SMSW */ - SaveMw(eaa,(Bit16u)CPU_SMSW()); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (CPU_LMSW((Bit16u)limit)) RUNEXCEPTION(); - break; - case 0x07: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - PAGING_ClearTLB(); - break; - } - } else { - GetEArd; - switch (which) { - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x04: /* SMSW */ - *eard=(Bit32u)CPU_SMSW(); - break; - case 0x06: /* LMSW */ - if (CPU_LMSW(*eard)) RUNEXCEPTION(); - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); - goto illegal_opcode; - break; - } - - } - } - break; - CASE_0F_D(0x02) /* LAR Gd,Ed */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrd;Bitu ar=*rmrd; - if (rm >= 0xc0) { - GetEArw;CPU_LAR(*earw,ar); - } else { - GetEAa;CPU_LAR(LoadMw(eaa),ar); - } - *rmrd=(Bit32u)ar; - } - break; - CASE_0F_D(0x03) /* LSL Gd,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrd;Bitu limit=*rmrd; - /* Just load 16-bit values for selectors */ - if (rm >= 0xc0) { - GetEArw;CPU_LSL(*earw,limit); - } else { - GetEAa;CPU_LSL(LoadMw(eaa),limit); - } - *rmrd=(Bit32u)limit; - } - break; - CASE_0F_D(0x80) /* JO */ - JumpCond32_d(TFLG_O);break; - CASE_0F_D(0x81) /* JNO */ - JumpCond32_d(TFLG_NO);break; - CASE_0F_D(0x82) /* JB */ - JumpCond32_d(TFLG_B);break; - CASE_0F_D(0x83) /* JNB */ - JumpCond32_d(TFLG_NB);break; - CASE_0F_D(0x84) /* JZ */ - JumpCond32_d(TFLG_Z);break; - CASE_0F_D(0x85) /* JNZ */ - JumpCond32_d(TFLG_NZ);break; - CASE_0F_D(0x86) /* JBE */ - JumpCond32_d(TFLG_BE);break; - CASE_0F_D(0x87) /* JNBE */ - JumpCond32_d(TFLG_NBE);break; - CASE_0F_D(0x88) /* JS */ - JumpCond32_d(TFLG_S);break; - CASE_0F_D(0x89) /* JNS */ - JumpCond32_d(TFLG_NS);break; - CASE_0F_D(0x8a) /* JP */ - JumpCond32_d(TFLG_P);break; - CASE_0F_D(0x8b) /* JNP */ - JumpCond32_d(TFLG_NP);break; - CASE_0F_D(0x8c) /* JL */ - JumpCond32_d(TFLG_L);break; - CASE_0F_D(0x8d) /* JNL */ - JumpCond32_d(TFLG_NL);break; - CASE_0F_D(0x8e) /* JLE */ - JumpCond32_d(TFLG_LE);break; - CASE_0F_D(0x8f) /* JNLE */ - JumpCond32_d(TFLG_NLE);break; - - CASE_0F_D(0xa0) /* PUSH FS */ - Push_32(SegValue(fs));break; - CASE_0F_D(0xa1) /* POP FS */ - if (CPU_PopSeg(fs,true)) RUNEXCEPTION(); - break; - CASE_0F_D(0xa3) /* BT Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - } - break; - } - CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */ - RMEdGdOp3(DSHLD,Fetchb()); - break; - CASE_0F_D(0xa5) /* SHLD Ed,Gd,CL */ - RMEdGdOp3(DSHLD,reg_cl); - break; - CASE_0F_D(0xa8) /* PUSH GS */ - Push_32(SegValue(gs));break; - CASE_0F_D(0xa9) /* POP GS */ - if (CPU_PopSeg(gs,true)) RUNEXCEPTION(); - break; - CASE_0F_D(0xab) /* BTS Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard|=mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old | mask); - } - break; - } - - CASE_0F_D(0xac) /* SHRD Ed,Gd,Ib */ - RMEdGdOp3(DSHRD,Fetchb()); - break; - CASE_0F_D(0xad) /* SHRD Ed,Gd,CL */ - RMEdGdOp3(DSHRD,reg_cl); - break; - CASE_0F_D(0xaf) /* IMUL Gd,Ed */ - { - RMGdEdOp3(DIMULD,*rmrd); - break; - } - CASE_0F_D(0xb1) /* CMPXCHG Ed,Gd */ - { - if (CPU_ArchitectureType= 0xc0) { - GetEArd; - if (*eard==reg_eax) { - *eard=*rmrd; - SETFLAGBIT(ZF,1); - } else { - reg_eax=*eard; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit32u val=LoadMd(eaa); - if (val==reg_eax) { - SaveMd(eaa,*rmrd); - SETFLAGBIT(ZF,1); - } else { - SaveMd(eaa,val); // cmpxchg always issues a write - reg_eax=val; - SETFLAGBIT(ZF,0); - } - } - break; - } - CASE_0F_D(0xb2) /* LSS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb3) /* BTR Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard&= ~mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old & ~mask); - } - break; - } - CASE_0F_D(0xb4) /* LFS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb5) /* LGS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb6) /* MOVZX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;} - else {GetEAa;*rmrd=LoadMb(eaa);} - break; - } - CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;} - else {GetEAa;*rmrd=LoadMw(eaa);} - break; - } - CASE_0F_D(0xba) /* GRP8 Ed,Ib */ - { - FillFlags();GetRM; - if (rm >= 0xc0 ) { - GetEArd; - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(*eard & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *eard|=mask; - break; - case 0x30: /* BTR */ - *eard&=~mask; - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) *eard&=~mask; - else *eard|=mask; - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit32u old=LoadMd(eaa); - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMd(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMd(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) old&=~mask; - else old|=mask; - SaveMd(eaa,old); - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - break; - } - CASE_0F_D(0xbb) /* BTC Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard^=mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old ^ mask); - } - break; - } - CASE_0F_D(0xbc) /* BSF Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_D(0xbd) /* BSR Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 31; // Operandsize-1 - while ((value & 0x80000000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_D(0xbe) /* MOVSX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;} - else {GetEAa;*rmrd=LoadMbs(eaa);} - break; - } - CASE_0F_D(0xbf) /* MOVSX Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;} - else {GetEAa;*rmrd=LoadMws(eaa);} - break; - } - CASE_0F_D(0xc1) /* XADD Gd,Ed */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;} - else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);} - break; - } - CASE_0F_D(0xc8) /* BSWAP EAX */ - if (CPU_ArchitectureType bound_max) ) { - EXCEPTION(5); - } - } - break; - CASE_W(0x63) /* ARPL Ew,Rw */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw; - if (rm >= 0xc0 ) { - GetEArw;Bitu new_sel=*earw; - CPU_ARPL(new_sel,*rmrw); - *earw=(Bit16u)new_sel; - } else { - GetEAa;Bitu new_sel=LoadMw(eaa); - CPU_ARPL(new_sel,*rmrw); - SaveMw(eaa,(Bit16u)new_sel); - } - } - break; - CASE_B(0x64) /* SEG FS: */ - DO_PREFIX_SEG(fs);break; - CASE_B(0x65) /* SEG GS: */ - DO_PREFIX_SEG(gs);break; - CASE_B(0x66) /* Operand Size Prefix */ - core.opcode_index=(cpu.code.big^0x1)*0x200; - goto restart_opcode; - CASE_B(0x67) /* Address Size Prefix */ - DO_PREFIX_ADDR(); - CASE_W(0x68) /* PUSH Iw */ - Push_16(Fetchw());break; - CASE_W(0x69) /* IMUL Gw,Ew,Iw */ - RMGwEwOp3(DIMULW,Fetchws()); - break; - CASE_W(0x6a) /* PUSH Ib */ - Push_16(Fetchbs()); - break; - CASE_W(0x6b) /* IMUL Gw,Ew,Ib */ - RMGwEwOp3(DIMULW,Fetchbs()); - break; - CASE_B(0x6c) /* INSB */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - DoString(R_INSB);break; - CASE_W(0x6d) /* INSW */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - DoString(R_INSW);break; - CASE_B(0x6e) /* OUTSB */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - DoString(R_OUTSB);break; - CASE_W(0x6f) /* OUTSW */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - DoString(R_OUTSW);break; - CASE_W(0x70) /* JO */ - JumpCond16_b(TFLG_O);break; - CASE_W(0x71) /* JNO */ - JumpCond16_b(TFLG_NO);break; - CASE_W(0x72) /* JB */ - JumpCond16_b(TFLG_B);break; - CASE_W(0x73) /* JNB */ - JumpCond16_b(TFLG_NB);break; - CASE_W(0x74) /* JZ */ - JumpCond16_b(TFLG_Z);break; - CASE_W(0x75) /* JNZ */ - JumpCond16_b(TFLG_NZ);break; - CASE_W(0x76) /* JBE */ - JumpCond16_b(TFLG_BE);break; - CASE_W(0x77) /* JNBE */ - JumpCond16_b(TFLG_NBE);break; - CASE_W(0x78) /* JS */ - JumpCond16_b(TFLG_S);break; - CASE_W(0x79) /* JNS */ - JumpCond16_b(TFLG_NS);break; - CASE_W(0x7a) /* JP */ - JumpCond16_b(TFLG_P);break; - CASE_W(0x7b) /* JNP */ - JumpCond16_b(TFLG_NP);break; - CASE_W(0x7c) /* JL */ - JumpCond16_b(TFLG_L);break; - CASE_W(0x7d) /* JNL */ - JumpCond16_b(TFLG_NL);break; - CASE_W(0x7e) /* JLE */ - JumpCond16_b(TFLG_LE);break; - CASE_W(0x7f) /* JNLE */ - JumpCond16_b(TFLG_NLE);break; - CASE_B(0x80) /* Grpl Eb,Ib */ - CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArb;Bit8u ib=Fetchb(); - switch (which) { - case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; - case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break; - case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break; - case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break; - case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break; - case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break; - case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break; - case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break; - } - } else { - GetEAa;Bit8u ib=Fetchb(); - switch (which) { - case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; - case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break; - case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break; - case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break; - case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break; - case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break; - case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break; - case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break; - } - } - break; - } - CASE_W(0x81) /* Grpl Ew,Iw */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=Fetchw(); - switch (which) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=Fetchw(); - switch (which) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - CASE_W(0x83) /* Grpl Ew,Ix */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=(Bit16s)Fetchbs(); - switch (which) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=(Bit16s)Fetchbs(); - switch (which) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - CASE_B(0x84) /* TEST Eb,Gb */ - RMEbGb(TESTB); - break; - CASE_W(0x85) /* TEST Ew,Gw */ - RMEwGw(TESTW); - break; - CASE_B(0x86) /* XCHG Eb,Gb */ - { - GetRMrb;Bit8u oldrmrb=*rmrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} - else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} - break; - } - CASE_W(0x87) /* XCHG Ew,Gw */ - { - GetRMrw;Bit16u oldrmrw=*rmrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} - else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} - break; - } - CASE_B(0x88) /* MOV Eb,Gb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} - else { - if (cpu.pmode) { - if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) { - Descriptor desc; - cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); - if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { - CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); - continue; - } - } - } - GetEAa;SaveMb(eaa,*rmrb); - } - break; - } - CASE_W(0x89) /* MOV Ew,Gw */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} - else {GetEAa;SaveMw(eaa,*rmrw);} - break; - } - CASE_B(0x8a) /* MOV Gb,Eb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} - else {GetEAa;*rmrb=LoadMb(eaa);} - break; - } - CASE_W(0x8b) /* MOV Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - CASE_W(0x8c) /* Mov Ew,Sw */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* MOV Ew,ES */ - val=SegValue(es);break; - case 0x01: /* MOV Ew,CS */ - val=SegValue(cs);break; - case 0x02: /* MOV Ew,SS */ - val=SegValue(ss);break; - case 0x03: /* MOV Ew,DS */ - val=SegValue(ds);break; - case 0x04: /* MOV Ew,FS */ - val=SegValue(fs);break; - case 0x05: /* MOV Ew,GS */ - val=SegValue(gs);break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); - goto illegal_opcode; - } - if (rm >= 0xc0 ) {GetEArw;*earw=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_W(0x8d) /* LEA Gw */ - { - //Little hack to always use segprefixed version - BaseDS=BaseSS=0; - GetRMrw; - if (TEST_PREFIX_ADDR) { - *rmrw=(Bit16u)(*EATable[256+rm])(); - } else { - *rmrw=(Bit16u)(*EATable[rm])(); - } - break; - } - CASE_B(0x8e) /* MOV Sw,Ew */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - if (rm >= 0xc0 ) {GetEArw;val=*earw;} - else {GetEAa;val=LoadMw(eaa);} - switch (which) { - case 0x02: /* MOV SS,Ew */ - CPU_Cycles++; //Always do another instruction - case 0x00: /* MOV ES,Ew */ - case 0x03: /* MOV DS,Ew */ - case 0x05: /* MOV GS,Ew */ - case 0x04: /* MOV FS,Ew */ - if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION(); - break; - default: - goto illegal_opcode; - } - break; - } - CASE_W(0x8f) /* POP Ew */ - { - Bit16u val=Pop_16(); - GetRM; - if (rm >= 0xc0 ) {GetEArw;*earw=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_B(0x90) /* NOP */ - break; - CASE_W(0x91) /* XCHG CX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } - break; - CASE_W(0x92) /* XCHG DX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } - break; - CASE_W(0x93) /* XCHG BX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } - break; - CASE_W(0x94) /* XCHG SP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } - break; - CASE_W(0x95) /* XCHG BP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } - break; - CASE_W(0x96) /* XCHG SI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } - break; - CASE_W(0x97) /* XCHG DI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } - break; - CASE_W(0x98) /* CBW */ - reg_ax=(Bit8s)reg_al;break; - CASE_W(0x99) /* CWD */ - if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0; - break; - CASE_W(0x9a) /* CALL Ap */ - { - FillFlags(); - Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - CPU_CALL(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_B(0x9b) /* WAIT */ - break; /* No waiting here */ - CASE_W(0x9c) /* PUSHF */ - if (CPU_PUSHF(false)) RUNEXCEPTION(); - break; - CASE_W(0x9d) /* POPF */ - if (CPU_POPF(false)) RUNEXCEPTION(); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - goto decode_end; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_B(0x9e) /* SAHF */ - SETFLAGSb(reg_ah); - break; - CASE_B(0x9f) /* LAHF */ - FillFlags(); - reg_ah=reg_flags&0xff; - break; - CASE_B(0xa0) /* MOV AL,Ob */ - { - GetEADirect; - reg_al=LoadMb(eaa); - } - break; - CASE_W(0xa1) /* MOV AX,Ow */ - { - GetEADirect; - reg_ax=LoadMw(eaa); - } - break; - CASE_B(0xa2) /* MOV Ob,AL */ - { - GetEADirect; - SaveMb(eaa,reg_al); - } - break; - CASE_W(0xa3) /* MOV Ow,AX */ - { - GetEADirect; - SaveMw(eaa,reg_ax); - } - break; - CASE_B(0xa4) /* MOVSB */ - DoString(R_MOVSB);break; - CASE_W(0xa5) /* MOVSW */ - DoString(R_MOVSW);break; - CASE_B(0xa6) /* CMPSB */ - DoString(R_CMPSB);break; - CASE_W(0xa7) /* CMPSW */ - DoString(R_CMPSW);break; - CASE_B(0xa8) /* TEST AL,Ib */ - ALIb(TESTB);break; - CASE_W(0xa9) /* TEST AX,Iw */ - AXIw(TESTW);break; - CASE_B(0xaa) /* STOSB */ - DoString(R_STOSB);break; - CASE_W(0xab) /* STOSW */ - DoString(R_STOSW);break; - CASE_B(0xac) /* LODSB */ - DoString(R_LODSB);break; - CASE_W(0xad) /* LODSW */ - DoString(R_LODSW);break; - CASE_B(0xae) /* SCASB */ - DoString(R_SCASB);break; - CASE_W(0xaf) /* SCASW */ - DoString(R_SCASW);break; - CASE_B(0xb0) /* MOV AL,Ib */ - reg_al=Fetchb();break; - CASE_B(0xb1) /* MOV CL,Ib */ - reg_cl=Fetchb();break; - CASE_B(0xb2) /* MOV DL,Ib */ - reg_dl=Fetchb();break; - CASE_B(0xb3) /* MOV BL,Ib */ - reg_bl=Fetchb();break; - CASE_B(0xb4) /* MOV AH,Ib */ - reg_ah=Fetchb();break; - CASE_B(0xb5) /* MOV CH,Ib */ - reg_ch=Fetchb();break; - CASE_B(0xb6) /* MOV DH,Ib */ - reg_dh=Fetchb();break; - CASE_B(0xb7) /* MOV BH,Ib */ - reg_bh=Fetchb();break; - CASE_W(0xb8) /* MOV AX,Iw */ - reg_ax=Fetchw();break; - CASE_W(0xb9) /* MOV CX,Iw */ - reg_cx=Fetchw();break; - CASE_W(0xba) /* MOV DX,Iw */ - reg_dx=Fetchw();break; - CASE_W(0xbb) /* MOV BX,Iw */ - reg_bx=Fetchw();break; - CASE_W(0xbc) /* MOV SP,Iw */ - reg_sp=Fetchw();break; - CASE_W(0xbd) /* MOV BP.Iw */ - reg_bp=Fetchw();break; - CASE_W(0xbe) /* MOV SI,Iw */ - reg_si=Fetchw();break; - CASE_W(0xbf) /* MOV DI,Iw */ - reg_di=Fetchw();break; - CASE_B(0xc0) /* GRP2 Eb,Ib */ - GRP2B(Fetchb());break; - CASE_W(0xc1) /* GRP2 Ew,Ib */ - GRP2W(Fetchb());break; - CASE_W(0xc2) /* RETN Iw */ - reg_eip=Pop_16(); - reg_esp+=Fetchw(); - continue; - CASE_W(0xc3) /* RETN */ - reg_eip=Pop_16(); - continue; - CASE_W(0xc4) /* LES */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_W(0xc5) /* LDS */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_B(0xc6) /* MOV Eb,Ib */ - { - GetRM; - if (rm >= 0xc0) {GetEArb;*earb=Fetchb();} - else {GetEAa;SaveMb(eaa,Fetchb());} - break; - } - CASE_W(0xc7) /* MOV EW,Iw */ - { - GetRM; - if (rm >= 0xc0) {GetEArw;*earw=Fetchw();} - else {GetEAa;SaveMw(eaa,Fetchw());} - break; - } - CASE_W(0xc8) /* ENTER Iw,Ib */ - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(false,bytes,level); - } - break; - CASE_W(0xc9) /* LEAVE */ - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_bp=Pop_16(); - break; - CASE_W(0xca) /* RETF Iw */ - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(false,words,GETIP); - continue; - } - CASE_W(0xcb) /* RETF */ - FillFlags(); - CPU_RET(false,0,GETIP); - continue; - CASE_B(0xcc) /* INT3 */ -#if C_DEBUG - FillFlags(); - if (DEBUG_Breakpoint()) - return debugCallback; -#endif - CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - CASE_B(0xcd) /* INT Ib */ - { - Bit8u num=Fetchb(); -#if C_DEBUG - FillFlags(); - if (DEBUG_IntBreakpoint(num)) { - return debugCallback; - } -#endif - CPU_SW_Interrupt(num,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - } - CASE_B(0xce) /* INTO */ - if (get_OF()) { - CPU_SW_Interrupt(4,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - } - break; - CASE_W(0xcf) /* IRET */ - { - CPU_IRET(false,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; -#endif - continue; - } - CASE_B(0xd0) /* GRP2 Eb,1 */ - GRP2B(1);break; - CASE_W(0xd1) /* GRP2 Ew,1 */ - GRP2W(1);break; - CASE_B(0xd2) /* GRP2 Eb,CL */ - GRP2B(reg_cl);break; - CASE_W(0xd3) /* GRP2 Ew,CL */ - GRP2W(reg_cl);break; - CASE_B(0xd4) /* AAM Ib */ - AAM(Fetchb());break; - CASE_B(0xd5) /* AAD Ib */ - AAD(Fetchb());break; - CASE_B(0xd6) /* SALC */ - reg_al = get_CF() ? 0xFF : 0; - break; - CASE_B(0xd7) /* XLAT */ - if (TEST_PREFIX_ADDR) { - reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al)); - } - break; -#ifdef CPU_FPU - CASE_B(0xd8) /* FPU ESC 0 */ - if (x86_fpu_enabled) { - FPU_ESC(0); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xd9) /* FPU ESC 1 */ - if (x86_fpu_enabled) { - FPU_ESC(1); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xda) /* FPU ESC 2 */ - if (x86_fpu_enabled) { - FPU_ESC(2); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xdb) /* FPU ESC 3 */ - if (x86_fpu_enabled) { - FPU_ESC(3); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xdc) /* FPU ESC 4 */ - if (x86_fpu_enabled) { - FPU_ESC(4); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xdd) /* FPU ESC 5 */ - if (x86_fpu_enabled) { - FPU_ESC(5); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xde) /* FPU ESC 6 */ - if (x86_fpu_enabled) { - FPU_ESC(6); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; - CASE_B(0xdf) /* FPU ESC 7 */ - if (x86_fpu_enabled) { - FPU_ESC(7); - } else { - Bit8u rm = Fetchb(); - if (rm<0xc0) GetEAa; - } - break; -#else - CASE_B(0xd8) /* FPU ESC 0 */ - CASE_B(0xd9) /* FPU ESC 1 */ - CASE_B(0xda) /* FPU ESC 2 */ - CASE_B(0xdb) /* FPU ESC 3 */ - CASE_B(0xdc) /* FPU ESC 4 */ - CASE_B(0xdd) /* FPU ESC 5 */ - CASE_B(0xde) /* FPU ESC 6 */ - CASE_B(0xdf) /* FPU ESC 7 */ - { - LOG(LOG_CPU,LOG_NORMAL)("FPU used"); - Bit8u rm=Fetchb(); - if (rm<0xc0) GetEAa; - } - break; -#endif - CASE_W(0xe0) /* LOOPNZ */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx && !get_ZF()); - } else { - JumpCond16_b(--reg_cx && !get_ZF()); - } - break; - CASE_W(0xe1) /* LOOPZ */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx && get_ZF()); - } else { - JumpCond16_b(--reg_cx && get_ZF()); - } - break; - CASE_W(0xe2) /* LOOP */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx); - } else { - JumpCond16_b(--reg_cx); - } - break; - CASE_W(0xe3) /* JCXZ */ - JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); - break; - CASE_B(0xe4) /* IN AL,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); - reg_al=IO_ReadB(port); - break; - } - CASE_W(0xe5) /* IN AX,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); - reg_al=IO_ReadW(port); - break; - } - CASE_B(0xe6) /* OUT Ib,AL */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); - IO_WriteB(port,reg_al); - break; - } - CASE_W(0xe7) /* OUT Ib,AX */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); - IO_WriteW(port,reg_ax); - break; - } - CASE_W(0xe8) /* CALL Jw */ - { - Bit16u addip=Fetchws(); - SAVEIP; - Push_16(reg_eip); - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_W(0xe9) /* JMP Jw */ - { - Bit16u addip=Fetchws(); - SAVEIP; - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_W(0xea) /* JMP Ap */ - { - Bit16u newip=Fetchw(); - Bit16u newcs=Fetchw(); - FillFlags(); - CPU_JMP(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_W(0xeb) /* JMP Jb */ - { - Bit16s addip=Fetchbs(); - SAVEIP; - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_B(0xec) /* IN AL,DX */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - reg_al=IO_ReadB(reg_dx); - break; - CASE_W(0xed) /* IN AX,DX */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - reg_ax=IO_ReadW(reg_dx); - break; - CASE_B(0xee) /* OUT DX,AL */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - IO_WriteB(reg_dx,reg_al); - break; - CASE_W(0xef) /* OUT DX,AX */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - IO_WriteW(reg_dx,reg_ax); - break; - CASE_B(0xf0) /* LOCK */ - LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ - break; - CASE_B(0xf1) /* ICEBP */ - CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - CASE_B(0xf2) /* REPNZ */ - DO_PREFIX_REP(false); - break; - CASE_B(0xf3) /* REPZ */ - DO_PREFIX_REP(true); - break; - CASE_B(0xf4) /* HLT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - CPU_HLT(GETIP); - return CBRET_NONE; //Needs to return for hlt cpu core - CASE_B(0xf5) /* CMC */ - FillFlags(); - SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); - break; - CASE_B(0xf6) /* GRP3 Eb(,Ib) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Eb,Ib */ - case 0x01: /* TEST Eb,Ib Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} - else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} - break; - } - case 0x02: /* NOT Eb */ - { - if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} - else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} - break; - } - case 0x03: /* NEG Eb */ - { - lflags.type=t_NEGb; - if (rm >= 0xc0 ) { - GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b; - *earb=lf_resb; - } else { - GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b; - SaveMb(eaa,lf_resb); - } - break; - } - case 0x04: /* MUL AL,Eb */ - RMEb(MULB); - break; - case 0x05: /* IMUL AL,Eb */ - RMEb(IMULB); - break; - case 0x06: /* DIV Eb */ - RMEb(DIVB); - break; - case 0x07: /* IDIV Eb */ - RMEb(IDIVB); - break; - } - break; - } - CASE_W(0xf7) /* GRP3 Ew(,Iw) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Ew,Iw */ - case 0x01: /* TEST Ew,Iw Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} - else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} - break; - } - case 0x02: /* NOT Ew */ - { - if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} - else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} - break; - } - case 0x03: /* NEG Ew */ - { - lflags.type=t_NEGw; - if (rm >= 0xc0 ) { - GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w; - *earw=lf_resw; - } else { - GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w; - SaveMw(eaa,lf_resw); - } - break; - } - case 0x04: /* MUL AX,Ew */ - RMEw(MULW); - break; - case 0x05: /* IMUL AX,Ew */ - RMEw(IMULW) - break; - case 0x06: /* DIV Ew */ - RMEw(DIVW) - break; - case 0x07: /* IDIV Ew */ - RMEw(IDIVW) - break; - } - break; - } - CASE_B(0xf8) /* CLC */ - FillFlags(); - SETFLAGBIT(CF,false); - break; - CASE_B(0xf9) /* STC */ - FillFlags(); - SETFLAGBIT(CF,true); - break; - CASE_B(0xfa) /* CLI */ - if (CPU_CLI()) RUNEXCEPTION(); - break; - CASE_B(0xfb) /* STI */ - if (CPU_STI()) RUNEXCEPTION(); -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_B(0xfc) /* CLD */ - SETFLAGBIT(DF,false); - cpu.direction=1; - break; - CASE_B(0xfd) /* STD */ - SETFLAGBIT(DF,true); - cpu.direction=-1; - break; - CASE_B(0xfe) /* GRP4 Eb */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Eb */ - RMEb(INCB); - break; - case 0x01: /* DEC Eb */ - RMEb(DECB); - break; - case 0x07: /* CallBack */ - { - Bitu cb=Fetchw(); - FillFlags();SAVEIP; - return cb; - } - default: - E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); - break; - } - break; - } - CASE_W(0xff) /* GRP5 Ew */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Ew */ - RMEw(INCW); - break; - case 0x01: /* DEC Ew */ - RMEw(DECW); - break; - case 0x02: /* CALL Ev */ - if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} - else {GetEAa;reg_eip=LoadMw(eaa);} - Push_16(GETIP); - continue; - case 0x03: /* CALL Ep */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - FillFlags(); - CPU_CALL(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x04: /* JMP Ev */ - if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} - else {GetEAa;reg_eip=LoadMw(eaa);} - continue; - case 0x05: /* JMP Ep */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - FillFlags(); - CPU_JMP(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x06: /* PUSH Ev */ - if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} - else {GetEAa;Push_16(LoadMw(eaa));} - break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",which); - goto illegal_opcode; - } - break; - } - - - - diff --git a/dosbox/core_normal/string.h b/dosbox/core_normal/string.h deleted file mode 100644 index 6fdfc7bd..00000000 --- a/dosbox/core_normal/string.h +++ /dev/null @@ -1,232 +0,0 @@ -enum STRING_OP { - R_OUTSB,R_OUTSW,R_OUTSD, - R_INSB,R_INSW,R_INSD, - R_MOVSB,R_MOVSW,R_MOVSD, - R_LODSB,R_LODSW,R_LODSD, - R_STOSB,R_STOSW,R_STOSD, - R_SCASB,R_SCASW,R_SCASD, - R_CMPSB,R_CMPSW,R_CMPSD -}; - -#define LoadD(_BLAH) _BLAH - -static void DoString(STRING_OP type) { - PhysPt si_base,di_base; - Bitu si_index,di_index; - Bitu add_mask; - Bitu count,count_left; - Bits add_index; - - si_base=BaseDS; - di_base=SegBase(es); - add_mask=AddrMaskTable[core.prefixes & PREFIX_ADDR]; - si_index=reg_esi & add_mask; - di_index=reg_edi & add_mask; - count=reg_ecx & add_mask; - if (!TEST_PREFIX_REP) { - count=1; - } else { - CPU_Cycles++; - /* Calculate amount of ops to do before cycles run out */ - if ((count>(Bitu)CPU_Cycles) && (type0;count--) { - IO_WriteB(reg_dx,LoadMb(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSW: - add_index<<=1; - for (;count>0;count--) { - IO_WriteW(reg_dx,LoadMw(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSD: - add_index<<=2; - for (;count>0;count--) { - IO_WriteD(reg_dx,LoadMd(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_INSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,IO_ReadB(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,IO_ReadW(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,reg_al); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,reg_ax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,reg_eax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_MOVSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,LoadMb(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,LoadMw(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,LoadMd(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSB: - for (;count>0;count--) { - reg_al=LoadMb(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSW: - add_index<<=1; - for (;count>0;count--) { - reg_ax=LoadMw(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSD: - add_index<<=2; - for (;count>0;count--) { - reg_eax=LoadMd(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_SCASB: - { - Bit8u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMb(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_al==val2)!=core.rep_zero) break; - } - CMPB(reg_al,val2,LoadD,0); - } - break; - case R_SCASW: - { - add_index<<=1;Bit16u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMw(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_ax==val2)!=core.rep_zero) break; - } - CMPW(reg_ax,val2,LoadD,0); - } - break; - case R_SCASD: - { - add_index<<=2;Bit32u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMd(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_eax==val2)!=core.rep_zero) break; - } - CMPD(reg_eax,val2,LoadD,0); - } - break; - case R_CMPSB: - { - Bit8u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMb(si_base+si_index); - val2=LoadMb(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPB(val1,val2,LoadD,0); - } - break; - case R_CMPSW: - { - add_index<<=1;Bit16u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMw(si_base+si_index); - val2=LoadMw(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPW(val1,val2,LoadD,0); - } - break; - case R_CMPSD: - { - add_index<<=2;Bit32u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMd(si_base+si_index); - val2=LoadMd(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPD(val1,val2,LoadD,0); - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled string op %d",type); - } - /* Clean up after certain amount of instructions */ - reg_esi&=(~add_mask); - reg_esi|=(si_index & add_mask); - reg_edi&=(~add_mask); - reg_edi|=(di_index & add_mask); - if (TEST_PREFIX_REP) { - count+=count_left; - reg_ecx&=(~add_mask); - reg_ecx|=(count & add_mask); - } -} diff --git a/dosbox/core_normal/support.h b/dosbox/core_normal/support.h deleted file mode 100644 index 9b230816..00000000 --- a/dosbox/core_normal/support.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define LoadRb(reg) reg -#define LoadRw(reg) reg -#define LoadRd(reg) reg - -#define SaveRb(reg,val) reg=val -#define SaveRw(reg,val) reg=val -#define SaveRd(reg,val) reg=val - -static INLINE Bit8s Fetchbs() { - return Fetchb(); -} -static INLINE Bit16s Fetchws() { - return Fetchw(); -} - -static INLINE Bit32s Fetchds() { - return Fetchd(); -} - - -#define RUNEXCEPTION() { \ - CPU_Exception(cpu.exception.which,cpu.exception.error); \ - continue; \ -} - -#define EXCEPTION(blah) \ - { \ - CPU_Exception(blah); \ - continue; \ - } - -//TODO Could probably make all byte operands fast? -#define JumpCond16_b(COND) { \ - SAVEIP; \ - if (COND) reg_ip+=Fetchbs(); \ - reg_ip+=1; \ - continue; \ -} - -#define JumpCond16_w(COND) { \ - SAVEIP; \ - if (COND) reg_ip+=Fetchws(); \ - reg_ip+=2; \ - continue; \ -} - -#define JumpCond32_b(COND) { \ - SAVEIP; \ - if (COND) reg_eip+=Fetchbs(); \ - reg_eip+=1; \ - continue; \ -} - -#define JumpCond32_d(COND) { \ - SAVEIP; \ - if (COND) reg_eip+=Fetchds(); \ - reg_eip+=4; \ - continue; \ -} - - -#define SETcc(cc) \ - { \ - GetRM; \ - if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ - else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ - } - -#include "helpers.h" -#include "table_ea.h" -#include "../modrm.h" - - diff --git a/dosbox/core_normal/table_ea.h b/dosbox/core_normal/table_ea.h deleted file mode 100644 index 08d46132..00000000 --- a/dosbox/core_normal/table_ea.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -typedef PhysPt (*EA_LookupHandler)(void); - -/* The MOD/RM Decoder for EA for this decoder's addressing modes */ -static PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); } -static PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); } -static PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());} -static PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); } - -static PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); } - -static PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } - -static Bit32u SIBZero=0; -static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - -static INLINE PhysPt Sib(Bitu mode) { - Bit8u sib=Fetchb(); - PhysPt base; - switch (sib&7) { - case 0: /* EAX Base */ - base=BaseDS+reg_eax;break; - case 1: /* ECX Base */ - base=BaseDS+reg_ecx;break; - case 2: /* EDX Base */ - base=BaseDS+reg_edx;break; - case 3: /* EBX Base */ - base=BaseDS+reg_ebx;break; - case 4: /* ESP Base */ - base=BaseSS+reg_esp;break; - case 5: /* #1 Base */ - if (!mode) { - base=BaseDS+Fetchd();break; - } else { - base=BaseSS+reg_ebp;break; - } - case 6: /* ESI Base */ - base=BaseDS+reg_esi;break; - case 7: /* EDI Base */ - base=BaseDS+reg_edi;break; - } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - return base; -} - -static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } -static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } -static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; } -static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; } -static PhysPt EA_32_04_n(void) { return Sib(0);} -static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); } -static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; } -static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; } - -static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); } -static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); } -static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); } -static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); } -static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} -//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} -static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); } -static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); } -static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); } - -static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); } -static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); } -static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); } -static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); } -static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} -//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} -static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); } -static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); } -static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); } - -static GetEAHandler EATable[512]={ -/* 00 */ - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, -/* 01 */ - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, -/* 10 */ - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 00 */ - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, -/* 01 */ - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, -/* 10 */ - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#define GetEADirect \ - PhysPt eaa; \ - if (TEST_PREFIX_ADDR) { \ - eaa=BaseDS+Fetchd(); \ - } else { \ - eaa=BaseDS+Fetchw(); \ - } \ - - diff --git a/dosbox/core_simple.cpp b/dosbox/core_simple.cpp deleted file mode 100644 index 2d026b94..00000000 --- a/dosbox/core_simple.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include "dosbox.h" -#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" -#include "fpu.h" - -#if C_DEBUG -#include "debug.h" -#endif - -#include "paging.h" -#define SegBase(c) SegPhys(c) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) - -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) - -extern Bitu cycle_count; - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -#define CPU_PIC_CHECK 1 -#define CPU_TRAP_CHECK 1 - -#define OPCODE_NONE 0x000 -#define OPCODE_0F 0x100 -#define OPCODE_SIZE 0x200 - -#define PREFIX_ADDR 0x1 -#define PREFIX_REP 0x2 - -#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) -#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) - -#define DO_PREFIX_SEG(_SEG) \ - BaseDS=SegBase(_SEG); \ - BaseSS=SegBase(_SEG); \ - core.base_val_ds=_SEG; \ - goto restart_opcode; - -#define DO_PREFIX_ADDR() \ - core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ - (cpu.code.big ^ PREFIX_ADDR); \ - core.ea_table=&EATable[(core.prefixes&1) * 256]; \ - goto restart_opcode; - -#define DO_PREFIX_REP(_ZERO) \ - core.prefixes|=PREFIX_REP; \ - core.rep_zero=_ZERO; \ - goto restart_opcode; - -typedef PhysPt (*GetEAHandler)(void); - -static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; - -static struct { - Bitu opcode_index; -#if defined (_MSC_VER) - volatile HostPt cseip; -#else - HostPt cseip; -#endif - PhysPt base_ds,base_ss; - SegNames base_val_ds; - bool rep_zero; - Bitu prefixes; - GetEAHandler * ea_table; -} core; - -#define GETIP (core.cseip-SegBase(cs)-MemBase) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(MemBase+SegBase(cs)+reg_eip); - -#define SegBase(c) SegPhys(c) -#define BaseDS core.base_ds -#define BaseSS core.base_ss - -static INLINE Bit8u Fetchb() { - Bit8u temp=host_readb(core.cseip); - core.cseip+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=host_readw(core.cseip); - core.cseip+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=host_readd(core.cseip); - core.cseip+=4; - return temp; -} - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - -#include "instructions.h" -#include "core_normal/support.h" -#include "core_normal/string.h" - - -#define EALookupTable (core.ea_table) - -Bits CPU_Core_Simple_Run(void) { - while (CPU_Cycles-->0) { - LOADIP; - core.opcode_index=cpu.code.big*0x200; - core.prefixes=cpu.code.big; - core.ea_table=&EATable[cpu.code.big*256]; - BaseDS=SegBase(ds); - BaseSS=SegBase(ss); - core.base_val_ds=ds; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif - cycle_count++; -#endif -restart_opcode: - switch (core.opcode_index+Fetchb()) { - - #include "core_normal/prefix_none.h" - #include "core_normal/prefix_0f.h" - #include "core_normal/prefix_66.h" - #include "core_normal/prefix_66_0f.h" - default: - illegal_opcode: -#if C_DEBUG - { - Bitu len=(GETIP-reg_eip); - LOADIP; - if (len>16) len=16; - char tempcode[16*2+1];char * writecode=tempcode; - for (;len>0;len--) { -// sprintf(writecode,"%X",mem_readb(core.cseip++)); - writecode+=2; - } - LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); - } -#endif - CPU_Exception(6,0); - continue; - } - SAVEIP; - } - FillFlags(); - return CBRET_NONE; -decode_end: - SAVEIP; - FillFlags(); - return CBRET_NONE; -} - -// not really used -Bits CPU_Core_Simple_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Normal_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Simple_Run; - - return ret; -} - - - -void CPU_Core_Simple_Init(void) { - -} diff --git a/dosbox/cpu.cpp b/dosbox/cpu.cpp deleted file mode 100644 index 1498cfef..00000000 --- a/dosbox/cpu.cpp +++ /dev/null @@ -1,2451 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: cpu.cpp,v 1.116 2009-03-16 18:10:08 c2woody Exp $ */ - -#include -#include -#include -#include "dosbox.h" -#include "cpu.h" -//#include "memory.h" -//#include "debug.h" -//#include "mapper.h" -#include "setup.h" -//#include "programs.h" -#include "paging.h" -#include "lazyflags.h" -#include "support.h" - -Bitu DEBUG_EnableDebugger(void); -extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); - -#if 1 -#undef LOG -#if defined (_MSC_VER) -#define LOG(X,Y) -#else -#define LOG(X,Y) CPU_LOG -#define CPU_LOG(...) -#endif -#endif - -CPU_Regs cpu_regs; -CPUBlock cpu; -Segments Segs; - -Bit32s CPU_Cycles = 0; -Bit32s CPU_CycleLeft = 3000; -Bit32s CPU_CycleMax = 3000; -Bit32s CPU_OldCycleMax = 3000; -Bit32s CPU_CyclePercUsed = 100; -Bit32s CPU_CycleLimit = -1; -Bit32s CPU_CycleUp = 0; -Bit32s CPU_CycleDown = 0; -Bit64s CPU_IODelayRemoved = 0; -CPU_Decoder * cpudecoder; -bool CPU_CycleAutoAdjust = false; -bool CPU_SkipCycleAutoAdjust = false; -Bitu CPU_AutoDetermineMode = 0; - -Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - -Bitu CPU_flag_id_toggle=0; - -Bitu CPU_PrefetchQueueSize=0; - -void CPU_Core_Full_Init(void); -void CPU_Core_Normal_Init(void); -void CPU_Core_Simple_Init(void); -#if (C_DYNAMIC_X86) -void CPU_Core_Dyn_X86_Init(void); -void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); -void CPU_Core_Dyn_X86_Cache_Close(void); -void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); -#elif (C_DYNREC) -void CPU_Core_Dynrec_Init(void); -void CPU_Core_Dynrec_Cache_Init(bool enable_cache); -void CPU_Core_Dynrec_Cache_Close(void); -#endif - -/* In debug mode exceptions are tested and dosbox exits when - * a unhandled exception state is detected. - * USE CHECK_EXCEPT to raise an exception in that case to see if that exception - * solves the problem. - * - * In non-debug mode dosbox doesn't do detection (and hence doesn't crash at - * that point). (game might crash later due to the unhandled exception) */ - -#if C_DEBUG -// #define CPU_CHECK_EXCEPT 1 -// #define CPU_CHECK_IGNORE 1 - /* Use CHECK_EXCEPT when something doesn't work to see if a exception is - * needed that isn't enabled by default.*/ -#else -/* NORMAL NO CHECKING => More Speed */ -#define CPU_CHECK_IGNORE 1 -#endif /* C_DEBUG */ - -#if defined(CPU_CHECK_IGNORE) -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) do {} while (0); \ -} -#elif defined(CPU_CHECK_EXCEPT) -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) { \ - CPU_Exception(exc,sel); \ - return; \ - } \ -} -#else -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) E_Exit(msg); \ -} -#endif - - -void Descriptor::Load(PhysPt address) { - cpu.mpl=0; - Bit32u* data = (Bit32u*)&saved; - *data = mem_readd(address); - *(data+1) = mem_readd(address+4); - cpu.mpl=3; -} -void Descriptor:: Save(PhysPt address) { - cpu.mpl=0; - Bit32u* data = (Bit32u*)&saved; - mem_writed(address,*data); - mem_writed(address+4,*(data+1)); - cpu.mpl=03; -} - - -void CPU_Push16(Bitu value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); - mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); - reg_esp=new_esp; -} - -void CPU_Push32(Bitu value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); - mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); - reg_esp=new_esp; -} - -Bitu CPU_Pop16(void) { - Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - return val; -} - -Bitu CPU_Pop32(void) { - Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - return val; -} - -PhysPt SelBase(Bitu sel) { - if (cpu.cr0 & CR0_PROTECTION) { - Descriptor desc; - cpu.gdt.GetDescriptor(sel,desc); - return desc.GetBase(); - } else { - return sel<<4; - } -} - - -void CPU_SetFlags(Bitu word,Bitu mask) { - mask|=CPU_flag_id_toggle; // ID-flag can be toggled on cpuid-supporting CPUs - reg_flags=(reg_flags & ~mask)|(word & mask)|2; - cpu.direction=1-((reg_flags & FLAG_DF) >> 9); -} - -bool CPU_PrepareException(Bitu which,Bitu error) { - cpu.exception.which=which; - cpu.exception.error=error; - return true; -} - -bool CPU_CLI(void) { - if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL0)) mask &= (~FLAG_IOPL); - if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPLdesc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(es,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(ds,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(fs,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(gs,0); -} - - -class TaskStateSegment { -public: - TaskStateSegment() { - valid=false; - } - bool IsValid(void) { - return valid; - } - Bitu Get_back(void) { - cpu.mpl=0; - Bit16u backlink=mem_readw(base); - cpu.mpl=3; - return backlink; - } - void SaveSelector(void) { - cpu.gdt.SetDescriptor(selector,desc); - } - void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { - cpu.mpl=0; - if (is386) { - PhysPt where=base+offsetof(TSS_32,esp0)+level*8; - _esp=mem_readd(where); - _ss=mem_readw(where+4); - } else { - PhysPt where=base+offsetof(TSS_16,sp0)+level*4; - _esp=mem_readw(where); - _ss=mem_readw(where+2); - } - cpu.mpl=3; - } - bool SetSelector(Bitu new_sel) { - valid=false; - if ((new_sel & 0xfffc)==0) { - selector=0; - base=0; - limit=0; - is386=1; - return true; - } - if (new_sel&4) return false; - if (!cpu.gdt.GetDescriptor(new_sel,desc)) return false; - switch (desc.Type()) { - case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_386_TSS_A: case DESC_386_TSS_B: - break; - default: - return false; - } - if (!desc.saved.seg.p) return false; - selector=new_sel; - valid=true; - base=desc.GetBase(); - limit=desc.GetLimit(); - is386=desc.Is386(); - return true; - } - TSS_Descriptor desc; - Bitu selector; - PhysPt base; - Bitu limit; - Bitu is386; - bool valid; -}; - -TaskStateSegment cpu_tss; - -enum TSwitchType { - TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET -}; - -bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { - FillFlags(); - TaskStateSegment new_tss; - if (!new_tss.SetSelector(new_tss_selector)) - E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); - if (tstype==TSwitch_IRET) { - if (!new_tss.desc.IsBusy()) - E_Exit("TSS not busy for IRET"); - } else { - if (new_tss.desc.IsBusy()) - E_Exit("TSS busy for JMP/CALL/INT"); - } - Bitu new_cr3=0; - Bitu new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi; - Bitu new_es,new_cs,new_ss,new_ds,new_fs,new_gs; - Bitu new_ldt,new_eip,new_eflags; - /* Read new context from new TSS */ - if (new_tss.is386) { - new_cr3=mem_readd(new_tss.base+offsetof(TSS_32,cr3)); - new_eip=mem_readd(new_tss.base+offsetof(TSS_32,eip)); - new_eflags=mem_readd(new_tss.base+offsetof(TSS_32,eflags)); - new_eax=mem_readd(new_tss.base+offsetof(TSS_32,eax)); - new_ecx=mem_readd(new_tss.base+offsetof(TSS_32,ecx)); - new_edx=mem_readd(new_tss.base+offsetof(TSS_32,edx)); - new_ebx=mem_readd(new_tss.base+offsetof(TSS_32,ebx)); - new_esp=mem_readd(new_tss.base+offsetof(TSS_32,esp)); - new_ebp=mem_readd(new_tss.base+offsetof(TSS_32,ebp)); - new_edi=mem_readd(new_tss.base+offsetof(TSS_32,edi)); - new_esi=mem_readd(new_tss.base+offsetof(TSS_32,esi)); - - new_es=mem_readw(new_tss.base+offsetof(TSS_32,es)); - new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); - new_ss=mem_readw(new_tss.base+offsetof(TSS_32,ss)); - new_ds=mem_readw(new_tss.base+offsetof(TSS_32,ds)); - new_fs=mem_readw(new_tss.base+offsetof(TSS_32,fs)); - new_gs=mem_readw(new_tss.base+offsetof(TSS_32,gs)); - new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt)); - } else { - E_Exit("286 task switch"); - new_cr3=0; - new_eip=0; - new_eflags=0; - new_eax=0; new_ecx=0; new_edx=0; new_ebx=0; - new_esp=0; new_ebp=0; new_edi=0; new_esi=0; - - new_es=0; new_cs=0; new_ss=0; new_ds=0; new_fs=0; new_gs=0; - new_ldt=0; - } - - /* Check if we need to clear busy bit of old TASK */ - if (tstype==TSwitch_JMP || tstype==TSwitch_IRET) { - cpu_tss.desc.SetBusy(false); - cpu_tss.SaveSelector(); - } - Bit32u old_flags = reg_flags; - if (tstype==TSwitch_IRET) old_flags &= (~FLAG_NT); - - /* Save current context in current TSS */ - if (cpu_tss.is386) { - mem_writed(cpu_tss.base+offsetof(TSS_32,eflags),old_flags); - mem_writed(cpu_tss.base+offsetof(TSS_32,eip),old_eip); - - mem_writed(cpu_tss.base+offsetof(TSS_32,eax),reg_eax); - mem_writed(cpu_tss.base+offsetof(TSS_32,ecx),reg_ecx); - mem_writed(cpu_tss.base+offsetof(TSS_32,edx),reg_edx); - mem_writed(cpu_tss.base+offsetof(TSS_32,ebx),reg_ebx); - mem_writed(cpu_tss.base+offsetof(TSS_32,esp),reg_esp); - mem_writed(cpu_tss.base+offsetof(TSS_32,ebp),reg_ebp); - mem_writed(cpu_tss.base+offsetof(TSS_32,esi),reg_esi); - mem_writed(cpu_tss.base+offsetof(TSS_32,edi),reg_edi); - - mem_writed(cpu_tss.base+offsetof(TSS_32,es),SegValue(es)); - mem_writed(cpu_tss.base+offsetof(TSS_32,cs),SegValue(cs)); - mem_writed(cpu_tss.base+offsetof(TSS_32,ss),SegValue(ss)); - mem_writed(cpu_tss.base+offsetof(TSS_32,ds),SegValue(ds)); - mem_writed(cpu_tss.base+offsetof(TSS_32,fs),SegValue(fs)); - mem_writed(cpu_tss.base+offsetof(TSS_32,gs),SegValue(gs)); - } else { - E_Exit("286 task switch"); - } - - /* Setup a back link to the old TSS in new TSS */ - if (tstype==TSwitch_CALL_INT) { - if (new_tss.is386) { - mem_writed(new_tss.base+offsetof(TSS_32,back),cpu_tss.selector); - } else { - mem_writew(new_tss.base+offsetof(TSS_16,back),cpu_tss.selector); - } - /* And make the new task's eflag have the nested task bit */ - new_eflags|=FLAG_NT; - } - /* Set the busy bit in the new task */ - if (tstype==TSwitch_JMP || tstype==TSwitch_CALL_INT) { - new_tss.desc.SetBusy(true); - new_tss.SaveSelector(); - } - -// cpu.cr0|=CR0_TASKSWITCHED; - if (new_tss_selector == cpu_tss.selector) { - reg_eip = old_eip; - new_cs = SegValue(cs); - new_ss = SegValue(ss); - new_ds = SegValue(ds); - new_es = SegValue(es); - new_fs = SegValue(fs); - new_gs = SegValue(gs); - } else { - - /* Setup the new cr3 */ - PAGING_SetDirBase(new_cr3); - - /* Load new context */ - if (new_tss.is386) { - reg_eip=new_eip; - CPU_SetFlags(new_eflags,FMASK_ALL | FLAG_VM); - reg_eax=new_eax; - reg_ecx=new_ecx; - reg_edx=new_edx; - reg_ebx=new_ebx; - reg_esp=new_esp; - reg_ebp=new_ebp; - reg_edi=new_edi; - reg_esi=new_esi; - -// new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); - } else { - E_Exit("286 task switch"); - } - } - /* Load the new selectors */ - if (reg_flags & FLAG_VM) { - SegSet16(cs,new_cs); - cpu.code.big=false; - cpu.cpl=3; //We don't have segment caches so this will do - } else { - /* Protected mode task */ - if (new_ldt!=0) CPU_LLDT(new_ldt); - /* Load the new CS*/ - Descriptor cs_desc; - cpu.cpl=new_cs & 3; - if (!cpu.gdt.GetDescriptor(new_cs,cs_desc)) - E_Exit("Task switch with CS beyond limits"); - if (!cs_desc.saved.seg.p) - E_Exit("Task switch with non present code-segment"); - switch (cs_desc.Type()) { - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl != cs_desc.DPL()) E_Exit("Task CS RPL != DPL"); - goto doconforming; - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - if (cpu.cpl < cs_desc.DPL()) E_Exit("Task CS RPL < DPL"); -doconforming: - Segs.phys[cs]=cs_desc.GetBase(); - cpu.code.big=cs_desc.Big()>0; - Segs.val[cs]=new_cs; - break; - default: - E_Exit("Task switch CS Type %d",cs_desc.Type()); - } - } - CPU_SetSegGeneral(es,new_es); - CPU_SetSegGeneral(ss,new_ss); - CPU_SetSegGeneral(ds,new_ds); - CPU_SetSegGeneral(fs,new_fs); - CPU_SetSegGeneral(gs,new_gs); - if (!cpu_tss.SetSelector(new_tss_selector)) { - LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); - } -// cpu_tss.desc.SetBusy(true); -// cpu_tss.SaveSelector(); -// LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); - return true; -} - -bool CPU_IO_Exception(Bitu port,Bitu size) { - if (cpu.pmode && ((GETFLAG_IOPLcpu_tss.limit) goto doexception; - bwhere=cpu_tss.base+ofs+(port/8); - Bitu map=mem_readw(bwhere); - Bitu mask=(0xffff>>(16-size)) << (port&7); - if (map & mask) goto doexception; - cpu.mpl=3; - } - return false; -doexception: - cpu.mpl=3; - LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); - return CPU_PrepareException(EXCEPTION_GP,0); -} - -void CPU_Exception(Bitu which,Bitu error ) { -// LOG_MSG("Exception %d error %x",which,error); - cpu.exception.error=error; - CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); -} - -Bit8u lastint; -void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { - lastint=num; - FillFlags(); -#if C_DEBUG - switch (num) { - case 0xcd: -#if C_HEAVY_DEBUG - LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); - DEBUG_HeavyWriteLogInstruction(); - E_Exit("Call to interrupt 0xCD this is BAD"); -#endif - break; - case 0x03: - if (DEBUG_Breakpoint()) { - CPU_Cycles=0; - return; - } - }; -#endif - if (!cpu.pmode) { - /* Save everything on a 16-bit stack */ - CPU_Push16(reg_flags & 0xffff); - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - /* Get the new CS:IP from vector table */ - PhysPt base=cpu.idt.GetBase(); - reg_eip=mem_readw(base+(num << 2)); - Segs.val[cs]=mem_readw(base+(num << 2)+2); - Segs.phys[cs]=Segs.val[cs]<<4; - cpu.code.big=false; - return; - } else { - /* Protected Mode Interrupt */ - if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE) && !(type&CPU_INT_NOIOPLCHECK)) { -// LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); - if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - CPU_Exception(EXCEPTION_GP,0); - return; - } - } - - Descriptor gate; - if (!cpu.idt.GetDescriptor(num<<3,gate)) { - // zone66 - CPU_Exception(EXCEPTION_GP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1); - return; - } - - if ((type&CPU_INT_SOFTWARE) && (gate.DPL()cpu.cpl, - "Interrupt to higher privilege", - EXCEPTION_GP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - switch (cs_desc.Type()) { - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cs_dpl0", - EXCEPTION_GP,gate_sel & 0xfffc) - - Bitu n_ss,n_esp; - Bitu o_ss,o_esp; - o_ss=SegValue(ss); - o_esp=reg_esp; - cpu_tss.Get_SSx_ESPx(cs_dpl,n_ss,n_esp); - CPU_CHECK_COND((n_ss & 0xfffc)==0, - "INT:Gate with SS zero selector", - EXCEPTION_TS,(type&CPU_INT_SOFTWARE)?0:1) - Descriptor n_ss_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), - "INT:Gate with SS beyond limit", - EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - CPU_CHECK_COND(((n_ss & 3)!=cs_dpl) || (n_ss_desc.DPL()!=cs_dpl), - "INT:Inner level with CS_DPL!=SS_DPL and SS_RPL", - EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - - // check if stack segment is a writable data segment - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - break; - default: - E_Exit("INT:Inner level:Stack segment not writable."); // or #TS(ss_sel+EXT) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "INT:Inner level with nonpresent SS", - EXCEPTION_SS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - - // commit point - Segs.phys[ss]=n_ss_desc.GetBase(); - Segs.val[ss]=n_ss; - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=n_esp & 0xffff; - } - - cpu.cpl=cs_dpl; - if (gate.Type() & 0x8) { /* 32-bit Gate */ - if (reg_flags & FLAG_VM) { - CPU_Push32(SegValue(gs));SegSet16(gs,0x0); - CPU_Push32(SegValue(fs));SegSet16(fs,0x0); - CPU_Push32(SegValue(ds));SegSet16(ds,0x0); - CPU_Push32(SegValue(es));SegSet16(es,0x0); - } - CPU_Push32(o_ss); - CPU_Push32(o_esp); - } else { /* 16-bit Gate */ - if (reg_flags & FLAG_VM) E_Exit("V86 to 16-bit gate"); - CPU_Push16(o_ss); - CPU_Push16(o_esp); - } -// LOG_MSG("INT:Gate to inner level SS:%X SP:%X",n_ss,n_esp); - goto do_interrupt; - } - if (cs_dpl!=cpu.cpl) - E_Exit("Non-conforming intra privilege INT with DPL!=CPL"); - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - /* Prepare stack for gate to same priviledge */ - CPU_CHECK_COND(!cs_desc.saved.seg.p, - "INT:Same level:CS segment not present", - EXCEPTION_NP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - if ((reg_flags & FLAG_VM) && (cs_dpl0; - reg_eip=gate_off; - - if (!(gate.Type()&1)) { - SETFLAGBIT(IF,false); - } - SETFLAGBIT(TF,false); - SETFLAGBIT(NT,false); - SETFLAGBIT(VM,false); - LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); - return; - } - case DESC_TASK_GATE: - CPU_CHECK_COND(!gate.saved.seg.p, - "INT:Gate segment not present", - EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1) - - CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip); - if (type & CPU_INT_HAS_ERROR) { - //TODO Be sure about this, seems somewhat unclear - if (cpu_tss.is386) CPU_Push32(cpu.exception.error); - else CPU_Push16(cpu.exception.error); - } - return; - default: - E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); - } - } - assert(1); - return ; // make compiler happy -} - - -void CPU_IRET(bool use32,Bitu oldeip) { - if (!cpu.pmode) { /* RealMode IRET */ - if (use32) { - reg_eip=CPU_Pop32(); - SegSet16(cs,CPU_Pop32()); - CPU_SetFlags(CPU_Pop32(),FMASK_ALL); - } else { - reg_eip=CPU_Pop16(); - SegSet16(cs,CPU_Pop16()); - CPU_SetFlags(CPU_Pop16(),FMASK_ALL & 0xffff); - } - cpu.code.big=false; - DestroyConditionFlags(); - return; - } else { /* Protected mode IRET */ - if (reg_flags & FLAG_VM) { - if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - // win3.x e - CPU_Exception(EXCEPTION_GP,0); - return; - } else { - if (use32) { - Bit32u new_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - Bit32u new_cs=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - Bit32u new_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - - reg_eip=new_eip; - SegSet16(cs,(Bit16u)(new_cs&0xffff)); - /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); - } else { - Bit16u new_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - Bit16u new_cs=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - Bit16u new_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - - reg_eip=(Bit32u)new_eip; - SegSet16(cs,new_cs); - /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); - } - cpu.code.big=false; - DestroyConditionFlags(); - return; - } - } - /* Check if this is task IRET */ - if (GETFLAG(NT)) { - if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); - CPU_CHECK_COND(!cpu_tss.IsValid(), - "TASK Iret without valid TSS", - EXCEPTION_TS,cpu_tss.selector & 0xfffc) - if (!cpu_tss.desc.IsBusy()) { - LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); - } - Bitu back_link=cpu_tss.Get_back(); - CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); - return; - } - Bitu n_cs_sel,n_eip,n_flags; - Bit32u tempesp; - if (use32) { - n_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - n_cs_sel=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff; - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - n_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - - if ((n_flags & FLAG_VM) && (cpu.cpl==0)) { - // commit point - reg_esp=tempesp; - reg_eip=n_eip & 0xffff; - Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; - n_esp=CPU_Pop32(); - n_ss=CPU_Pop32() & 0xffff; - n_es=CPU_Pop32() & 0xffff; - n_ds=CPU_Pop32() & 0xffff; - n_fs=CPU_Pop32() & 0xffff; - n_gs=CPU_Pop32() & 0xffff; - - CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); - DestroyConditionFlags(); - cpu.cpl=3; - - CPU_SetSegGeneral(ss,n_ss); - CPU_SetSegGeneral(es,n_es); - CPU_SetSegGeneral(ds,n_ds); - CPU_SetSegGeneral(fs,n_fs); - CPU_SetSegGeneral(gs,n_gs); - reg_esp=n_esp; - cpu.code.big=false; - SegSet16(cs,n_cs_sel); - LOG(LOG_CPU,LOG_NORMAL)("IRET:Back to V86: CS:%X IP %X SS:%X SP %X FLAGS:%X",SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); - return; - } - if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0"); - } else { - n_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - n_cs_sel=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - n_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - n_flags|=(reg_flags & 0xffff0000); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - - if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); - } - CPU_CHECK_COND((n_cs_sel & 0xfffc)==0, - "IRET:CS selector zero", - EXCEPTION_GP,0) - Bitu n_cs_rpl=n_cs_sel & 3; - Descriptor n_cs_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc), - "IRET:CS selector beyond limits", - EXCEPTION_GP,n_cs_sel & 0xfffc) - CPU_CHECK_COND(n_cs_rpln_cs_rpl, - "IRET:C:DPL>RPL", - EXCEPTION_GP,n_cs_sel & 0xfffc) - break; - default: - E_Exit("IRET:Illegal descriptor type %X",n_cs_desc.Type()); - } - CPU_CHECK_COND(!n_cs_desc.saved.seg.p, - "IRET with nonpresent code segment", - EXCEPTION_NP,n_cs_sel & 0xfffc) - - if (n_cs_rpl==cpu.cpl) { - /* Return to same level */ - - // commit point - reg_esp=tempesp; - Segs.phys[cs]=n_cs_desc.GetBase(); - cpu.code.big=n_cs_desc.Big()>0; - Segs.val[cs]=n_cs_sel; - reg_eip=n_eip; - - Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; - if (GETFLAG_IOPL0; - Segs.val[cs]=n_cs_sel; - - Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; - if (GETFLAG_IOPLcpu.cpl, - "JMP:NC:RPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - CPU_CHECK_COND(cpu.cpl!=desc.DPL(), - "JMP:NC:RPL != DPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); - goto CODE_jmp; - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); - CPU_CHECK_COND(cpu.cpl0; - Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; - reg_eip=offset; - return; - case DESC_386_TSS_A: - CPU_CHECK_COND(desc.DPL()cpu.cpl, - "CALL:CODE:NC:RPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - CPU_CHECK_COND(call.DPL()!=cpu.cpl, - "CALL:CODE:NC:DPL!=CPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:NC to %X:%X",selector,offset); - goto call_code; - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - CPU_CHECK_COND(call.DPL()>cpu.cpl, - "CALL:CODE:C:DPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:C to %X:%X",selector,offset); -call_code: - if (!call.saved.seg.p) { - // borland extender (RTM) - CPU_Exception(EXCEPTION_NP,selector & 0xfffc); - return; - } - // commit point - if (!use32) { - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - reg_eip=offset & 0xffff; - } else { - CPU_Push32(SegValue(cs)); - CPU_Push32(oldeip); - reg_eip=offset; - } - Segs.phys[cs]=call.GetBase(); - cpu.code.big=call.Big()>0; - Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; - return; - case DESC_386_CALL_GATE: - case DESC_286_CALL_GATE: - { - CPU_CHECK_COND(call.DPL()cpu.cpl, - "CALL:Gate:CS DPL>CPL", - EXCEPTION_GP,n_cs_sel & 0xfffc) - - CPU_CHECK_COND(!n_cs_desc.saved.seg.p, - "CALL:Gate:CS not present", - EXCEPTION_NP,n_cs_sel & 0xfffc) - - Bitu n_eip = call.GetOffset(); - switch (n_cs_desc.Type()) { - case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: - /* Check if we goto inner priviledge */ - if (n_cs_dpl < cpu.cpl) { - /* Get new SS:ESP out of TSS */ - Bitu n_ss_sel,n_esp; - Descriptor n_ss_desc; - cpu_tss.Get_SSx_ESPx(n_cs_dpl,n_ss_sel,n_esp); - CPU_CHECK_COND((n_ss_sel & 0xfffc)==0, - "CALL:Gate:NC:SS selector zero", - EXCEPTION_TS,0) - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss_sel,n_ss_desc), - "CALL:Gate:Invalid SS selector", - EXCEPTION_TS,n_ss_sel & 0xfffc) - CPU_CHECK_COND(((n_ss_sel & 3)!=n_cs_desc.DPL()) || (n_ss_desc.DPL()!=n_cs_desc.DPL()), - "CALL:Gate:Invalid SS selector privileges", - EXCEPTION_TS,n_ss_sel & 0xfffc) - - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - // writable data segment - break; - default: - E_Exit("Call:Gate:SS no writable data segment"); // or #TS(ss_sel) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "CALL:Gate:Stack segment not present", - EXCEPTION_SS,n_ss_sel & 0xfffc) - - /* Load the new SS:ESP and save data on it */ - Bitu o_esp = reg_esp; - Bitu o_ss = SegValue(ss); - PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask); - - - // catch pagefaults - if (call.saved.gate.paramcount&31) { - if (call.Type()==DESC_386_CALL_GATE) { - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - mem_readd(o_stack+i*4); - } else { - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - mem_readw(o_stack+i*2); - } - } - - // commit point - Segs.val[ss]=n_ss_sel; - Segs.phys[ss]=n_ss_desc.GetBase(); - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=n_esp & 0xffff; - } - - cpu.cpl = n_cs_desc.DPL(); - Bit16u oldcs = SegValue(cs); - /* Switch to new CS:EIP */ - Segs.phys[cs] = n_cs_desc.GetBase(); - Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; - cpu.code.big = n_cs_desc.Big()>0; - reg_eip = n_eip; - if (!use32) reg_eip&=0xffff; - - if (call.Type()==DESC_386_CALL_GATE) { - CPU_Push32(o_ss); //save old stack - CPU_Push32(o_esp); - if (call.saved.gate.paramcount&31) - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - CPU_Push32(mem_readd(o_stack+i*4)); - CPU_Push32(oldcs); - CPU_Push32(oldeip); - } else { - CPU_Push16(o_ss); //save old stack - CPU_Push16(o_esp); - if (call.saved.gate.paramcount&31) - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - CPU_Push16(mem_readw(o_stack+i*2)); - CPU_Push16(oldcs); - CPU_Push16(oldeip); - } - - break; - } else if (n_cs_dpl > cpu.cpl) - E_Exit("CALL:GATE:CS DPL>CPL"); // or #GP(sel) - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - // zrdx extender - - if (call.Type()==DESC_386_CALL_GATE) { - CPU_Push32(SegValue(cs)); - CPU_Push32(oldeip); - } else { - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - } - - /* Switch to new CS:EIP */ - Segs.phys[cs] = n_cs_desc.GetBase(); - Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; - cpu.code.big = n_cs_desc.Big()>0; - reg_eip = n_eip; - if (!use32) reg_eip&=0xffff; - break; - default: - E_Exit("CALL:GATE:CS no executable segment"); - } - } /* Call Gates */ - break; - case DESC_386_TSS_A: - CPU_CHECK_COND(call.DPL()cpu.cpl, - "RET to C segment of higher privilege", - EXCEPTION_GP,selector & 0xfffc) - break; - default: - E_Exit("RET from illegal descriptor type %X",desc.Type()); - } -RET_same_level: - if (!desc.saved.seg.p) { - // borland extender (RTM) - CPU_Exception(EXCEPTION_NP,selector & 0xfffc); - return; - } - - // commit point - if (!use32) { - offset=CPU_Pop16(); - selector=CPU_Pop16(); - } else { - offset=CPU_Pop32(); - selector=CPU_Pop32() & 0xffff; - } - - Segs.phys[cs]=desc.GetBase(); - cpu.code.big=desc.Big()>0; - Segs.val[cs]=selector; - reg_eip=offset; - if (cpu.stack.big) { - reg_esp+=bytes; - } else { - reg_sp+=bytes; - } - LOG(LOG_CPU,LOG_NORMAL)("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); - return; - } else { - /* Return to outer level */ - switch (desc.Type()) { - case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: - CPU_CHECK_COND(desc.DPL()!=rpl, - "RET to outer NC segment with DPL!=RPL", - EXCEPTION_GP,selector & 0xfffc) - break; - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - CPU_CHECK_COND(desc.DPL()>rpl, - "RET to outer C segment with DPL>RPL", - EXCEPTION_GP,selector & 0xfffc) - break; - default: - E_Exit("RET from illegal descriptor type %X",desc.Type()); // or #GP(selector) - } - - CPU_CHECK_COND(!desc.saved.seg.p, - "RET:Outer level:CS not present", - EXCEPTION_NP,selector & 0xfffc) - - // commit point - Bitu n_esp,n_ss; - if (use32) { - offset=CPU_Pop32(); - selector=CPU_Pop32() & 0xffff; - reg_esp+=bytes; - n_esp = CPU_Pop32(); - n_ss = CPU_Pop32() & 0xffff; - } else { - offset=CPU_Pop16(); - selector=CPU_Pop16(); - reg_esp+=bytes; - n_esp = CPU_Pop16(); - n_ss = CPU_Pop16(); - } - - CPU_CHECK_COND((n_ss & 0xfffc)==0, - "RET to outer level with SS selector zero", - EXCEPTION_GP,0) - - Descriptor n_ss_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), - "RET:SS beyond limits", - EXCEPTION_GP,n_ss & 0xfffc) - - CPU_CHECK_COND(((n_ss & 3)!=rpl) || (n_ss_desc.DPL()!=rpl), - "RET to outer segment with invalid SS privileges", - EXCEPTION_GP,n_ss & 0xfffc) - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - break; - default: - E_Exit("RET:SS selector type no writable data segment"); // or #GP(selector) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "RET:Stack segment not present", - EXCEPTION_SS,n_ss & 0xfffc) - - cpu.cpl = rpl; - Segs.phys[cs]=desc.GetBase(); - cpu.code.big=desc.Big()>0; - Segs.val[cs]=(selector&0xfffc) | cpu.cpl; - reg_eip=offset; - - Segs.val[ss]=n_ss; - Segs.phys[ss]=n_ss_desc.GetBase(); - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp+bytes; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=(n_esp & 0xffff)+bytes; - } - - CPU_CheckSegments(); - -// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); - return; - } - LOG(LOG_CPU,LOG_NORMAL)("Prot ret %X:%X",selector,offset); - return; - } - assert(1); -} - - -Bitu CPU_SLDT(void) { - return cpu.gdt.SLDT(); -} - -bool CPU_LLDT(Bitu selector) { - if (!cpu.gdt.LLDT(selector)) { - LOG(LOG_CPU,LOG_ERROR)("LLDT failed, selector=%X",selector); - return true; - } - LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); - return false; -} - -Bitu CPU_STR(void) { - return cpu_tss.selector; -} - -bool CPU_LTR(Bitu selector) { - if ((selector & 0xfffc)==0) { - cpu_tss.SetSelector(selector); - return false; - } - TSS_Descriptor desc; - if ((selector & 4) || (!cpu.gdt.GetDescriptor(selector,desc))) { - LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X",selector); - return CPU_PrepareException(EXCEPTION_GP,selector); - } - - if ((desc.Type()==DESC_286_TSS_A) || (desc.Type()==DESC_386_TSS_A)) { - if (!desc.saved.seg.p) { - LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X (not present)",selector); - return CPU_PrepareException(EXCEPTION_NP,selector); - } - if (!cpu_tss.SetSelector(selector)) E_Exit("LTR failed, selector=%X",selector); - cpu_tss.desc.SetBusy(true); - cpu_tss.SaveSelector(); - } else { - /* Descriptor was no available TSS descriptor */ - LOG(LOG_CPU,LOG_NORMAL)("LTR failed, selector=%X (type=%X)",selector,desc.Type()); - return CPU_PrepareException(EXCEPTION_GP,selector); - } - return false; -} - -void CPU_LGDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X",base,limit); - cpu.gdt.SetLimit(limit); - cpu.gdt.SetBase(base); -} - -void CPU_LIDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("IDT Set to base:%X limit:%X",base,limit); - cpu.idt.SetLimit(limit); - cpu.idt.SetBase(base); -} - -Bitu CPU_SGDT_base(void) { - return cpu.gdt.GetBase(); -} -Bitu CPU_SGDT_limit(void) { - return cpu.gdt.GetLimit(); -} - -Bitu CPU_SIDT_base(void) { - return cpu.idt.GetBase(); -} -Bitu CPU_SIDT_limit(void) { - return cpu.idt.GetLimit(); -} - -static bool printed_cycles_auto_info = false; -void CPU_SET_CRX(Bitu cr,Bitu value) { - switch (cr) { - case 0: - { - Bitu changed=cpu.cr0 ^ value; - if (!changed) return; - cpu.cr0=value; - if (value & CR0_PROTECTION) { - cpu.pmode=true; - LOG(LOG_CPU,LOG_NORMAL)("Protected mode"); - PAGING_Enable((value & CR0_PAGING)>0); - - if (!(CPU_AutoDetermineMode&CPU_AUTODETERMINE_MASK)) break; - - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) { - CPU_CycleAutoAdjust=true; - CPU_CycleLeft=0; - CPU_Cycles=0; - CPU_OldCycleMax=CPU_CycleMax; - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - if(!printed_cycles_auto_info) { - printed_cycles_auto_info = true; - LOG_MSG("DOSBox switched to max cycles, because of the setting: cycles=auto. If the game runs too fast try a fixed cycles amount in DOSBox's options."); - } - } else { - GFX_SetTitle(-1,-1,false); - } -#if (C_DYNAMIC_X86) - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - CPU_Core_Dyn_X86_Cache_Init(true); - cpudecoder=&CPU_Core_Dyn_X86_Run; - } -#elif (C_DYNREC) - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - CPU_Core_Dynrec_Cache_Init(true); - cpudecoder=&CPU_Core_Dynrec_Run; - } -#endif - CPU_AutoDetermineMode<<=CPU_AUTODETERMINE_SHIFT; - } else { - cpu.pmode=false; - if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); - PAGING_Enable(false); - LOG(LOG_CPU,LOG_NORMAL)("Real mode"); - } - break; - } - case 2: - paging.cr2=value; - break; - case 3: - PAGING_SetDirBase(value); - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV CR%d,%X",cr,value); - break; - } -} - -bool CPU_WRITE_CRX(Bitu cr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); - if (CPU_ArchitectureType=CPU_ARCHTYPE_PENTIUMSLOW) return cpu.cr0; - else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) return (cpu.cr0 & 0xe005003f); - else return (cpu.cr0 | 0x7ffffff0); - case 2: - return paging.cr2; - case 3: - return PAGING_GetDirBase() & 0xfffff000; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); - break; - } - return 0; -} - -bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); - retvalue=CPU_GET_CRX(cr); - return false; -} - - -bool CPU_WRITE_DRX(Bitu dr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (dr) { - case 0: - case 1: - case 2: - case 3: - cpu.drx[dr]=value; - break; - case 4: - case 6: - cpu.drx[6]=(value|0xffff0ff0) & 0xffffefff; - break; - case 5: - case 7: - if (CPU_ArchitectureType0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (dr) { - case 0: - case 1: - case 2: - case 3: - case 6: - case 7: - retvalue=cpu.drx[dr]; - break; - case 4: - retvalue=cpu.drx[6]; - break; - case 5: - retvalue=cpu.drx[7]; - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, DR%d",dr); - retvalue=0; - break; - } - return false; -} - -bool CPU_WRITE_TRX(Bitu tr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (tr) { -// case 3: - case 6: - case 7: - cpu.trx[tr]=value; - return false; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV TR%d,%X",tr,value); - break; - } - return CPU_PrepareException(EXCEPTION_UD,0); -} - -bool CPU_READ_TRX(Bitu tr,Bit32u & retvalue) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (tr) { -// case 3: - case 6: - case 7: - retvalue=cpu.trx[tr]; - return false; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, TR%d",tr); - break; - } - return CPU_PrepareException(EXCEPTION_UD,0); -} - - -Bitu CPU_SMSW(void) { - return cpu.cr0; -} - -bool CPU_LMSW(Bitu word) { - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - word&=0xf; - if (cpu.cr0 & 1) word|=1; - word|=(cpu.cr0&0xfffffff0); - CPU_SET_CRX(0,word); - return false; -} - -void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { - FillFlags(); - if ((dest_sel & 3) < (src_sel & 3)) { - dest_sel=(dest_sel & 0xfffc) + (src_sel & 3); -// dest_sel|=0xff3f0000; - SETFLAGBIT(ZF,true); - } else { - SETFLAGBIT(ZF,false); - } -} - -void CPU_LAR(Bitu selector,Bitu & ar) { - FillFlags(); - if (selector == 0) { - SETFLAGBIT(ZF,false); - return; - } - Descriptor desc;Bitu rpl=selector & 3; - if (!cpu.gdt.GetDescriptor(selector,desc)){ - SETFLAGBIT(ZF,false); - return; - } - switch (desc.Type()){ - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - break; - - case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: { - case DESC_386_INT_GATE: case DESC_386_TRAP_GATE: - SETFLAGBIT(ZF,false); - return; - } - - case DESC_LDT: - case DESC_TASK_GATE: - - case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_286_CALL_GATE: - - case DESC_386_TSS_A: case DESC_386_TSS_B: - case DESC_386_CALL_GATE: - - - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (desc.DPL()desc.DPL()) || (cpu.cpl>desc.DPL())) { - // extreme pinball - return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); - } - break; - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - break; - default: - // gabriel knight - return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); - - } - if (!desc.saved.seg.p) { - // win - return CPU_PrepareException(EXCEPTION_NP,value & 0xfffc); - } - - Segs.val[seg]=value; - Segs.phys[seg]=desc.GetBase(); - } - - return false; - } -} - -bool CPU_PopSeg(SegNames seg,bool use32) { - Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - if (CPU_SetSegGeneral(seg,val)) return true; - Bitu addsp=use32?0x04:0x02; - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask); - return false; -} - -bool CPU_CPUID(void) { - if (CPU_ArchitectureType105) CPU_CyclePercUsed=105; - LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - } else { - Bit32s old_cycles=CPU_CycleMax; - if (CPU_CycleUp < 100) { - CPU_CycleMax = (Bit32s)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); - } else { - CPU_CycleMax = (Bit32s)(CPU_CycleMax + CPU_CycleUp); - } - - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - if(CPU_CycleMax > 15000 ) - LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax); - else - LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); - } -} - -static void CPU_CycleDecrease(bool pressed) { - if (!pressed) return; - if (CPU_CycleAutoAdjust) { - CPU_CyclePercUsed-=5; - if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1; - if(CPU_CyclePercUsed <=70) - LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed); - else - LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - } else { - if (CPU_CycleDown < 100) { - CPU_CycleMax = (Bit32s)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); - } else { - CPU_CycleMax = (Bit32s)(CPU_CycleMax - CPU_CycleDown); - } - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax <= 0) CPU_CycleMax=1; - LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); - } -} - -void CPU_Enable_SkipAutoAdjust(void) { - if (CPU_CycleAutoAdjust) { - CPU_CycleMax /= 2; - if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) - CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; - } - CPU_SkipCycleAutoAdjust=true; -} - -void CPU_Disable_SkipAutoAdjust(void) { - CPU_SkipCycleAutoAdjust=false; -} - - -extern Bit32s ticksDone; -extern Bit32u ticksScheduled; - -void CPU_Reset_AutoAdjust(void) { - CPU_IODelayRemoved = 0; - ticksDone = 0; - ticksScheduled = 0; -} - -class CPU: public Module_base { -private: - static bool inited; -public: - CPU(Section* configuration, int cpumode, int cpuarch):Module_base(configuration) { -// if(inited) { -// Change_Config(configuration); -// return; -// } -// Section_prop * section=static_cast(configuration); - inited=true; - reg_eax=0; - reg_ebx=0; - reg_ecx=0; - reg_edx=0; - reg_edi=0; - reg_esi=0; - reg_ebp=0; - reg_esp=0; - - SegSet16(cs,0); - SegSet16(ds,0); - SegSet16(es,0); - SegSet16(fs,0); - SegSet16(gs,0); - SegSet16(ss,0); - - CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts - cpu.cr0=0xffffffff; - CPU_SET_CRX(0,0); //Initialize - cpu.code.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - cpu.stack.big=false; - cpu.trap_skip=false; - cpu.idt.SetBase(0); - cpu.idt.SetLimit(1023); - - for (Bitu i=0; i<7; i++) { - cpu.drx[i]=0; - cpu.trx[i]=0; - } - if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) { - cpu.drx[6]=0xffff0ff0; - } else { - cpu.drx[6]=0xffff1ff0; - } - cpu.drx[7]=0x00000400; - - /* Init the cpu cores */ - CPU_Core_Normal_Init(); - CPU_Core_Simple_Init(); - CPU_Core_Full_Init(); -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Init(); -#elif (C_DYNREC) - CPU_Core_Dynrec_Init(); -#endif - MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); - MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); - Change_Config(configuration, cpumode, cpuarch); - CPU_JMP(false,0,0,0); //Setup the first cpu core - } - bool Change_Config(Section* newconfig, int cpumode, int cpuarch){ - Section_prop * section=static_cast(newconfig); - CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; - //CPU_CycleLeft=0;//needed ? - CPU_Cycles=0; - CPU_SkipCycleAutoAdjust=false; - -#if 0 - Prop_multival* p = section->Get_multival("cycles"); - std::string type = p->GetSection()->Get_string("type"); - std::string str ; - CommandLine cmd(0,p->GetSection()->Get_string("parameters")); -#endif - CommandLine cmd(0, NULL); - std::string str; - std::string type = "max"; - if (type=="max") { - CPU_CycleMax=0; - CPU_CyclePercUsed=100; - CPU_CycleAutoAdjust=true; - CPU_CycleLimit=-1; - for (Bitu cmdnum=1; cmdnum<=cmd.GetCount(); cmdnum++) { - if (cmd.FindCommand(cmdnum,str)) { - if (str.find('%')==str.length()-1) { - str.erase(str.find('%')); - int percval=0; - std::istringstream stream(str); - stream >> percval; - if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; - } else if (str=="limit") { - cmdnum++; - if (cmd.FindCommand(cmdnum,str)) { - int cyclimit=0; - std::istringstream stream(str); - stream >> cyclimit; - if (cyclimit>0) CPU_CycleLimit=cyclimit; - } - } - } - } - } else { - if (type=="auto") { - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; - CPU_CycleMax=3000; - CPU_OldCycleMax=3000; - CPU_CyclePercUsed=100; - for (Bitu cmdnum=0; cmdnum<=cmd.GetCount(); cmdnum++) { - if (cmd.FindCommand(cmdnum,str)) { - if (str.find('%')==str.length()-1) { - str.erase(str.find('%')); - int percval=0; - std::istringstream stream(str); - stream >> percval; - if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; - } else if (str=="limit") { - cmdnum++; - if (cmd.FindCommand(cmdnum,str)) { - int cyclimit=0; - std::istringstream stream(str); - stream >> cyclimit; - if (cyclimit>0) CPU_CycleLimit=cyclimit; - } - } else { - int rmdval=0; - std::istringstream stream(str); - stream >> rmdval; - if (rmdval>0) { - CPU_CycleMax=(Bit32s)rmdval; - CPU_OldCycleMax=(Bit32s)rmdval; - } - } - } - } - } else if(type =="fixed") { - cmd.FindCommand(1,str); - int rmdval=0; - std::istringstream stream(str); - stream >> rmdval; - CPU_CycleMax=(Bit32s)rmdval; - } else { - std::istringstream stream(type); - int rmdval=0; - stream >> rmdval; - if(rmdval) CPU_CycleMax=(Bit32s)rmdval; - } - CPU_CycleAutoAdjust=false; - } - - CPU_CycleUp=section->Get_int("cycleup"); - CPU_CycleDown=section->Get_int("cycledown"); - //std::string core(section->Get_string("core")); - - std::string core = "simple"; - if (cpumode == 2) - core = "normal"; - else if (cpumode == 3) - core = "full"; - else if (cpumode == 4) - core = "auto"; - - cpudecoder=&CPU_Core_Normal_Run; - if (core == "normal") { - cpudecoder=&CPU_Core_Normal_Run; - } else if (core =="simple") { - cpudecoder=&CPU_Core_Simple_Run; - } else if (core == "full") { - cpudecoder=&CPU_Core_Full_Run; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Normal_Run; -#if (C_DYNAMIC_X86) - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } - else if (core == "dynamic") { - cpudecoder=&CPU_Core_Dyn_X86_Run; - CPU_Core_Dyn_X86_SetFPUMode(true); - } else if (core == "dynamic_nodhfpu") { - cpudecoder=&CPU_Core_Dyn_X86_Run; - CPU_Core_Dyn_X86_SetFPUMode(false); -#elif (C_DYNREC) - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } - else if (core == "dynamic") { - cpudecoder=&CPU_Core_Dynrec_Run; -#else - -#endif - } - -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Init((core == "dynamic") || (core == "dynamic_nodhfpu")); -#elif (C_DYNREC) - CPU_Core_Dynrec_Cache_Init( core == "dynamic" ); -#endif - - CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - //std::string cputype(section->Get_string("cputype")); - - std::string cputype = "auto"; - if (cpuarch == 1) - cputype = "386"; - else if (cpuarch == 2) - cputype = "386_prefetch"; - else if (cpuarch == 3) - cputype = "386_slow"; - else if (cpuarch == 4) - cputype = "486_slow"; - else if (cpuarch == 5) - cputype = "486_prefetch"; - else if (cpuarch == 6) - cputype = "pentium_slow"; - - if (cputype == "auto") { - CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - } else if (cputype == "386") { - CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; - } else if (cputype == "386_prefetch") { - CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; - if (core == "normal") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 16; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 16; - CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); - } else { - E_Exit("prefetch queue emulation requires the normal core setting."); - } - } else if (cputype == "386_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW; - } else if (cputype == "486_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; - } else if (cputype == "486_prefetch") { - CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; - if (core == "normal") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 32; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 32; - CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); - } else { - E_Exit("prefetch queue emulation requires the normal core setting."); - } - } else if (cputype == "pentium_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW; - } - - if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_flag_id_toggle=FLAG_ID; - else CPU_flag_id_toggle=0; - - - if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; - if(CPU_CycleUp <= 0) CPU_CycleUp = 500; - if(CPU_CycleDown <= 0) CPU_CycleDown = 20; - if (CPU_CycleAutoAdjust) GFX_SetTitle(CPU_CyclePercUsed,-1,false); - else GFX_SetTitle(CPU_CycleMax,-1,false); - return true; - } - ~CPU(){ /* empty */}; -}; - -static CPU * test; - -void CPU_ShutDown(Section* sec) { -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Close(); -#elif (C_DYNREC) - CPU_Core_Dynrec_Cache_Close(); -#endif - delete test; - test = NULL; -} - -void CPU_Init(Section* sec, int cpumode, int cpuarch) { - test = new CPU(sec, cpumode, cpuarch); - sec->AddDestroyFunction(&CPU_ShutDown,true); -} -//initialize static members -bool CPU::inited=false; diff --git a/dosbox/cpu.h b/dosbox/cpu.h deleted file mode 100644 index d18caa2f..00000000 --- a/dosbox/cpu.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: cpu.h,v 1.57 2009-05-27 09:15:40 qbix79 Exp $ */ - -#ifndef DOSBOX_CPU_H -#define DOSBOX_CPU_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_REGS_H -#include "regs.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#define CPU_AUTODETERMINE_NONE 0x00 -#define CPU_AUTODETERMINE_CORE 0x01 -#define CPU_AUTODETERMINE_CYCLES 0x02 - -#define CPU_AUTODETERMINE_SHIFT 0x02 -#define CPU_AUTODETERMINE_MASK 0x03 - -#define CPU_CYCLES_LOWER_LIMIT 100 - - -#define CPU_ARCHTYPE_MIXED 0xff -#define CPU_ARCHTYPE_386SLOW 0x30 -#define CPU_ARCHTYPE_386FAST 0x35 -#define CPU_ARCHTYPE_486OLDSLOW 0x40 -#define CPU_ARCHTYPE_486NEWSLOW 0x45 -#define CPU_ARCHTYPE_PENTIUMSLOW 0x50 - -/* CPU Cycle Timing */ -extern Bit32s CPU_Cycles; -extern Bit32s CPU_CycleLeft; -extern Bit32s CPU_CycleMax; -extern Bit32s CPU_OldCycleMax; -extern Bit32s CPU_CyclePercUsed; -extern Bit32s CPU_CycleLimit; -extern Bit64s CPU_IODelayRemoved; -extern bool CPU_CycleAutoAdjust; -extern bool CPU_SkipCycleAutoAdjust; -extern Bitu CPU_AutoDetermineMode; - -extern Bitu CPU_ArchitectureType; - -extern Bitu CPU_PrefetchQueueSize; - -/* Some common Defines */ -/* A CPU Handler */ -typedef Bits (CPU_Decoder)(void); -extern CPU_Decoder * cpudecoder; - -Bits CPU_Core_Normal_Run(void); -Bits CPU_Core_Normal_Trap_Run(void); -Bits CPU_Core_Simple_Run(void); -Bits CPU_Core_Full_Run(void); -Bits CPU_Core_Dyn_X86_Run(void); -Bits CPU_Core_Dyn_X86_Trap_Run(void); -Bits CPU_Core_Dynrec_Run(void); -Bits CPU_Core_Dynrec_Trap_Run(void); -Bits CPU_Core_Prefetch_Run(void); -Bits CPU_Core_Prefetch_Trap_Run(void); - -void CPU_Enable_SkipAutoAdjust(void); -void CPU_Disable_SkipAutoAdjust(void); -void CPU_Reset_AutoAdjust(void); - - -//CPU Stuff - -extern Bit16u parity_lookup[256]; - -bool CPU_LLDT(Bitu selector); -bool CPU_LTR(Bitu selector); -void CPU_LIDT(Bitu limit,Bitu base); -void CPU_LGDT(Bitu limit,Bitu base); - -Bitu CPU_STR(void); -Bitu CPU_SLDT(void); -Bitu CPU_SIDT_base(void); -Bitu CPU_SIDT_limit(void); -Bitu CPU_SGDT_base(void); -Bitu CPU_SGDT_limit(void); - -void CPU_ARPL(Bitu & dest_sel,Bitu src_sel); -void CPU_LAR(Bitu selector,Bitu & ar); -void CPU_LSL(Bitu selector,Bitu & limit); - -void CPU_SET_CRX(Bitu cr,Bitu value); -bool CPU_WRITE_CRX(Bitu cr,Bitu value); -Bitu CPU_GET_CRX(Bitu cr); -bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue); - -bool CPU_WRITE_DRX(Bitu dr,Bitu value); -bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue); - -bool CPU_WRITE_TRX(Bitu dr,Bitu value); -bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue); - -Bitu CPU_SMSW(void); -bool CPU_LMSW(Bitu word); - -void CPU_VERR(Bitu selector); -void CPU_VERW(Bitu selector); - -void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip); -void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip); -void CPU_RET(bool use32,Bitu bytes,Bitu oldeip); -void CPU_IRET(bool use32,Bitu oldeip); -void CPU_HLT(Bitu oldeip); - -bool CPU_POPF(Bitu use32); -bool CPU_PUSHF(Bitu use32); -bool CPU_CLI(void); -bool CPU_STI(void); - -bool CPU_IO_Exception(Bitu port,Bitu size); -void CPU_RunException(void); - -void CPU_ENTER(bool use32,Bitu bytes,Bitu level); - -#define CPU_INT_SOFTWARE 0x1 -#define CPU_INT_EXCEPTION 0x2 -#define CPU_INT_HAS_ERROR 0x4 -#define CPU_INT_NOIOPLCHECK 0x8 - -void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip); -static INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0,reg_eip); -} -static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { - CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); -} -static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) { - CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip); -} - -bool CPU_PrepareException(Bitu which,Bitu error); -void CPU_Exception(Bitu which,Bitu error=0); - -bool CPU_SetSegGeneral(SegNames seg,Bitu value); -bool CPU_PopSeg(SegNames seg,bool use32); - -bool CPU_CPUID(void); -Bitu CPU_Pop16(void); -Bitu CPU_Pop32(void); -void CPU_Push16(Bitu value); -void CPU_Push32(Bitu value); - -void CPU_SetFlags(Bitu word,Bitu mask); - - -#define EXCEPTION_UD 6 -#define EXCEPTION_TS 10 -#define EXCEPTION_NP 11 -#define EXCEPTION_SS 12 -#define EXCEPTION_GP 13 -#define EXCEPTION_PF 14 - -#define CR0_PROTECTION 0x00000001 -#define CR0_MONITORPROCESSOR 0x00000002 -#define CR0_FPUEMULATION 0x00000004 -#define CR0_TASKSWITCH 0x00000008 -#define CR0_FPUPRESENT 0x00000010 -#define CR0_PAGING 0x80000000 - - -// ********************************************************************* -// Descriptor -// ********************************************************************* - -#define DESC_INVALID 0x00 -#define DESC_286_TSS_A 0x01 -#define DESC_LDT 0x02 -#define DESC_286_TSS_B 0x03 -#define DESC_286_CALL_GATE 0x04 -#define DESC_TASK_GATE 0x05 -#define DESC_286_INT_GATE 0x06 -#define DESC_286_TRAP_GATE 0x07 - -#define DESC_386_TSS_A 0x09 -#define DESC_386_TSS_B 0x0b -#define DESC_386_CALL_GATE 0x0c -#define DESC_386_INT_GATE 0x0e -#define DESC_386_TRAP_GATE 0x0f - -/* EU/ED Expand UP/DOWN RO/RW Read Only/Read Write NA/A Accessed */ -#define DESC_DATA_EU_RO_NA 0x10 -#define DESC_DATA_EU_RO_A 0x11 -#define DESC_DATA_EU_RW_NA 0x12 -#define DESC_DATA_EU_RW_A 0x13 -#define DESC_DATA_ED_RO_NA 0x14 -#define DESC_DATA_ED_RO_A 0x15 -#define DESC_DATA_ED_RW_NA 0x16 -#define DESC_DATA_ED_RW_A 0x17 - -/* N/R Readable NC/C Confirming A/NA Accessed */ -#define DESC_CODE_N_NC_A 0x18 -#define DESC_CODE_N_NC_NA 0x19 -#define DESC_CODE_R_NC_A 0x1a -#define DESC_CODE_R_NC_NA 0x1b -#define DESC_CODE_N_C_A 0x1c -#define DESC_CODE_N_C_NA 0x1d -#define DESC_CODE_R_C_A 0x1e -#define DESC_CODE_R_C_NA 0x1f - -#ifdef _MSC_VER -#pragma pack (1) -#endif - -struct S_Descriptor { -#ifdef WORDS_BIGENDIAN - Bit32u base_0_15 :16; - Bit32u limit_0_15 :16; - Bit32u base_24_31 :8; - Bit32u g :1; - Bit32u big :1; - Bit32u r :1; - Bit32u avl :1; - Bit32u limit_16_19 :4; - Bit32u p :1; - Bit32u dpl :2; - Bit32u type :5; - Bit32u base_16_23 :8; -#else - Bit32u limit_0_15 :16; - Bit32u base_0_15 :16; - Bit32u base_16_23 :8; - Bit32u type :5; - Bit32u dpl :2; - Bit32u p :1; - Bit32u limit_16_19 :4; - Bit32u avl :1; - Bit32u r :1; - Bit32u big :1; - Bit32u g :1; - Bit32u base_24_31 :8; -#endif -}GCC_ATTRIBUTE(packed); - -struct G_Descriptor { -#ifdef WORDS_BIGENDIAN - Bit32u selector: 16; - Bit32u offset_0_15 :16; - Bit32u offset_16_31 :16; - Bit32u p :1; - Bit32u dpl :2; - Bit32u type :5; - Bit32u reserved :3; - Bit32u paramcount :5; -#else - Bit32u offset_0_15 :16; - Bit32u selector :16; - Bit32u paramcount :5; - Bit32u reserved :3; - Bit32u type :5; - Bit32u dpl :2; - Bit32u p :1; - Bit32u offset_16_31 :16; -#endif -} GCC_ATTRIBUTE(packed); - -struct TSS_16 { - Bit16u back; /* Back link to other task */ - Bit16u sp0; /* The CK stack pointer */ - Bit16u ss0; /* The CK stack selector */ - Bit16u sp1; /* The parent KL stack pointer */ - Bit16u ss1; /* The parent KL stack selector */ - Bit16u sp2; /* Unused */ - Bit16u ss2; /* Unused */ - Bit16u ip; /* The instruction pointer */ - Bit16u flags; /* The flags */ - Bit16u ax, cx, dx, bx; /* The general purpose registers */ - Bit16u sp, bp, si, di; /* The special purpose registers */ - Bit16u es; /* The extra selector */ - Bit16u cs; /* The code selector */ - Bit16u ss; /* The application stack selector */ - Bit16u ds; /* The data selector */ - Bit16u ldt; /* The local descriptor table */ -} GCC_ATTRIBUTE(packed); - -struct TSS_32 { - Bit32u back; /* Back link to other task */ - Bit32u esp0; /* The CK stack pointer */ - Bit32u ss0; /* The CK stack selector */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit32u ss1; /* The parent KL stack selector */ - Bit32u esp2; /* Unused */ - Bit32u ss2; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit32u es; /* The extra selector */ - Bit32u cs; /* The code selector */ - Bit32u ss; /* The application stack selector */ - Bit32u ds; /* The data selector */ - Bit32u fs; /* And another extra selector */ - Bit32u gs; /* ... and another one */ - Bit32u ldt; /* The local descriptor table */ -} GCC_ATTRIBUTE(packed); - -#ifdef _MSC_VER -#pragma pack() -#endif -class Descriptor -{ -public: - Descriptor() { saved.fill[0]=saved.fill[1]=0; } - - void Load(PhysPt address); - void Save(PhysPt address); - - PhysPt GetBase (void) { - return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15; - } - Bitu GetLimit (void) { - Bitu limit = (saved.seg.limit_16_19<<16) | saved.seg.limit_0_15; - if (saved.seg.g) return (limit<<12) | 0xFFF; - return limit; - } - Bitu GetOffset(void) { - return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15; - } - Bitu GetSelector(void) { - return saved.gate.selector; - } - Bitu Type(void) { - return saved.seg.type; - } - Bitu Conforming(void) { - return saved.seg.type & 8; - } - Bitu DPL(void) { - return saved.seg.dpl; - } - Bitu Big(void) { - return saved.seg.big; - } -public: - union { - S_Descriptor seg; - G_Descriptor gate; - Bit32u fill[2]; - } saved; -}; - -class DescriptorTable { -public: - PhysPt GetBase (void) { return table_base; } - Bitu GetLimit (void) { return table_limit; } - void SetBase (PhysPt _base) { table_base = _base; } - void SetLimit (Bitu _limit) { table_limit= _limit; } - - bool GetDescriptor (Bitu selector, Descriptor& desc) { - selector&=~7; - if (selector>=table_limit) return false; - desc.Load(table_base+(selector)); - return true; - } -protected: - PhysPt table_base; - Bitu table_limit; -}; - -class GDTDescriptorTable : public DescriptorTable { -public: - bool GetDescriptor(Bitu selector, Descriptor& desc) { - Bitu address=selector & ~7; - if (selector & 4) { - if (address>=ldt_limit) return false; - desc.Load(ldt_base+address); - return true; - } else { - if (address>=table_limit) return false; - desc.Load(table_base+address); - return true; - } - } - bool SetDescriptor(Bitu selector, Descriptor& desc) { - Bitu address=selector & ~7; - if (selector & 4) { - if (address>=ldt_limit) return false; - desc.Save(ldt_base+address); - return true; - } else { - if (address>=table_limit) return false; - desc.Save(table_base+address); - return true; - } - } - Bitu SLDT(void) { - return ldt_value; - } - bool LLDT(Bitu value) { - if ((value&0xfffc)==0) { - ldt_value=0; - ldt_base=0; - ldt_limit=0; - return true; - } - Descriptor desc; - if (!GetDescriptor(value,desc)) return !CPU_PrepareException(EXCEPTION_GP,value); - if (desc.Type()!=DESC_LDT) return !CPU_PrepareException(EXCEPTION_GP,value); - if (!desc.saved.seg.p) return !CPU_PrepareException(EXCEPTION_NP,value); - ldt_base=desc.GetBase(); - ldt_limit=desc.GetLimit(); - ldt_value=value; - return true; - } -private: - PhysPt ldt_base; - Bitu ldt_limit; - Bitu ldt_value; -}; - -class TSS_Descriptor : public Descriptor { -public: - Bitu IsBusy(void) { - return saved.seg.type & 2; - } - Bitu Is386(void) { - return saved.seg.type & 8; - } - void SetBusy(bool busy) { - if (busy) saved.seg.type|=2; - else saved.seg.type&=~2; - } -}; - - -struct CPUBlock { - Bitu cpl; /* Current Privilege */ - Bitu mpl; - Bitu cr0; - bool pmode; /* Is Protected mode enabled */ - GDTDescriptorTable gdt; - DescriptorTable idt; - struct { - Bitu mask,notmask; - bool big; - } stack; - struct { - bool big; - } code; - struct { - Bitu cs,eip; - CPU_Decoder * old_decoder; - } hlt; - struct { - Bitu which,error; - } exception; - Bits direction; - bool trap_skip; - Bit32u drx[8]; - Bit32u trx[8]; -}; - -extern CPUBlock cpu; - -static INLINE void CPU_SetFlagsd(Bitu word) { - Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; - CPU_SetFlags(word,mask); -} - -static INLINE void CPU_SetFlagsw(Bitu word) { - Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; - CPU_SetFlags(word,mask); -} - - -#endif diff --git a/dosbox/db_memory.cpp b/dosbox/db_memory.cpp deleted file mode 100644 index 726cde07..00000000 --- a/dosbox/db_memory.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: memory.cpp,v 1.56 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include "dosbox.h" -#include "mem.h" -#include "inout.h" -#include "setup.h" -#include "paging.h" -#include "regs.h" - -#include - -#define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) -#define SAFE_MEMORY 32 -#define MAX_MEMORY 64 -#define MAX_PAGE_ENTRIES (MAX_MEMORY*1024*1024/4096) -#define LFB_PAGES 512 -#define MAX_LINKS ((MAX_MEMORY*1024/4)+4096) //Hopefully enough - -struct LinkBlock { - Bitu used; - Bit32u pages[MAX_LINKS]; -}; - -static struct MemoryBlock { - Bitu pages; - PageHandler * * phandlers; - MemHandle * mhandles; - LinkBlock links; - struct { - Bitu start_page; - Bitu end_page; - Bitu pages; - PageHandler *handler; - PageHandler *mmiohandler; - } lfb; - struct { - bool enabled; - Bit8u controlport; - } a20; -} memory; - -HostPt MemBase; - -class IllegalPageHandler : public PageHandler { -public: - IllegalPageHandler() { - flags=PFLAG_INIT|PFLAG_NOCODE; - } - Bitu readb(PhysPt addr) { -#if C_DEBUG - LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); -#else - static Bits lcount=0; - if (lcount<1000) { - lcount++; - LOG_MSG("Illegal read from %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); - } -#endif - return 0; - } - void writeb(PhysPt addr,Bitu val) { -#if C_DEBUG - LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); -#else - static Bits lcount=0; - if (lcount<1000) { - lcount++; - LOG_MSG("Illegal write to %x, CS:IP %8x:%8x",addr,SegValue(cs),reg_eip); - } -#endif - } -}; - -class RAMPageHandler : public PageHandler { -public: - RAMPageHandler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE; - } - HostPt GetHostReadPt(Bitu phys_page) { - return MemBase+phys_page*MEM_PAGESIZE; - } - HostPt GetHostWritePt(Bitu phys_page) { - return MemBase+phys_page*MEM_PAGESIZE; - } -}; - -class ROMPageHandler : public RAMPageHandler { -public: - ROMPageHandler() { - flags=PFLAG_READABLE|PFLAG_HASROM; - } - void writeb(PhysPt addr,Bitu val){ - LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); - } - void writew(PhysPt addr,Bitu val){ - LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); - } - void writed(PhysPt addr,Bitu val){ - LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); - } -}; - - -extern void write_log(const char*,...); -extern void vga_ram_put(int board, int offset, uint8_t v); -extern uint8_t vga_ram_get(int board, int offset); -extern int x86_vga_board; - - -class VGA_Handler : public PageHandler { -public: - VGA_Handler() { - flags = PFLAG_NOCODE; - } - Bitu readb(PhysPt addr) { - return vga_ram_get(x86_vga_board, addr); - } - Bitu readw(PhysPt addr) { - Bitu v = vga_ram_get(x86_vga_board,addr) << 0; - v |= vga_ram_get(x86_vga_board, addr + 1) << 8; - return v; - } - Bitu readd(PhysPt addr) { - Bitu v = readw(addr); - v |= readw(addr + 2) << 16; - return v; - } - void writeb(PhysPt addr, Bitu val) { - vga_ram_put(x86_vga_board, addr, val); - } - void writew(PhysPt addr, Bitu val) { - vga_ram_put(x86_vga_board, addr, val); - vga_ram_put(x86_vga_board, addr + 1, val >> 8); - return; - } - void writed(PhysPt addr, Bitu val) { - writew(addr, val); - writew(addr + 2, val >> 16); - return; - } -}; -static VGA_Handler vga_page_handler; - -void MEM_SetVGAHandler(void) -{ - MEM_SetPageHandler(0xa0000 >> 12, (0xc0000 - 0xa0000) >> 12, &vga_page_handler); -} - - -static IllegalPageHandler illegal_page_handler; -static RAMPageHandler ram_page_handler; -static ROMPageHandler rom_page_handler; - -void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler) { - memory.lfb.handler=handler; - memory.lfb.mmiohandler=mmiohandler; - memory.lfb.start_page=page; - memory.lfb.end_page=page+pages; - memory.lfb.pages=pages; - PAGING_ClearTLB(); -} - -PageHandler * MEM_GetPageHandler(Bitu phys_page) { - if (phys_page=memory.lfb.start_page) && (phys_page=memory.lfb.start_page+0x01000000/4096) && - (phys_page0;pages--) { - memory.phandlers[phys_page]=handler; - phys_page++; - } -} - -void MEM_ResetPageHandlerRAM(Bitu phys_page, Bitu pages) { - for (;pages>0;pages--) { - memory.phandlers[phys_page]=&ram_page_handler; - phys_page++; - } -} - -void MEM_ResetPageHandlerROM(Bitu phys_page, Bitu pages) -{ - for (; pages>0; pages--) { - memory.phandlers[phys_page] = &rom_page_handler; - phys_page++; - } -} - -Bitu mem_strlen(PhysPt pt) { - Bitu x=0; - while (x<1024) { - if (!mem_readb_inline(pt+x)) return x; - x++; - } - return 0; //Hope this doesn't happen -} - -void mem_strcpy(PhysPt dest,PhysPt src) { - Bit8u r; - while ( (r = mem_readb(src++)) ) mem_writeb_inline(dest++,r); - mem_writeb_inline(dest,0); -} - -void mem_memcpy(PhysPt dest,PhysPt src,Bitu size) { - while (size--) mem_writeb_inline(dest++,mem_readb_inline(src++)); -} - -void MEM_BlockRead(PhysPt pt,void * data,Bitu size) { - Bit8u * write=reinterpret_cast(data); - while (size--) { - *write++=mem_readb_inline(pt++); - } -} - -void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size) { - Bit8u const * read = reinterpret_cast(data); - while (size--) { - mem_writeb_inline(pt++,*read++); - } -} - -void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size) { - mem_memcpy(dest,src,size); -} - -void MEM_StrCopy(PhysPt pt,char * data,Bitu size) { - while (size--) { - Bit8u r=mem_readb_inline(pt++); - if (!r) break; - *data++=r; - } - *data=0; -} - -Bitu MEM_TotalPages(void) { - return memory.pages; -} - -Bitu MEM_FreeLargest(void) { - Bitu size=0;Bitu largest=0; - Bitu index=XMS_START; - while (indexlargest) largest=size; - size=0; - } - index++; - } - if (size>largest) largest=size; - return largest; -} - -Bitu MEM_FreeTotal(void) { - Bitu free=0; - Bitu index=XMS_START; - while (index0) { - pages++; - handle=memory.mhandles[handle]; - } - return pages; -} - -//TODO Maybe some protection for this whole allocation scheme - -INLINE Bitu BestMatch(Bitu size) { - Bitu index=XMS_START; - Bitu first=0; - Bitu best=0xfffffff; - Bitu best_first=0; - while (indexsize) { - if (pages=size) && (index-first0) { - MemHandle next=memory.mhandles[handle]; - memory.mhandles[handle]=0; - handle=next; - } -} - -bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) { - if (handle<=0) { - if (!pages) return true; - handle=MEM_AllocatePages(pages,sequence); - return (handle>0); - } - if (!pages) { - MEM_ReleasePages(handle); - handle=-1; - return true; - } - MemHandle index=handle; - MemHandle last;Bitu old_pages=0; - while (index>0) { - old_pages++; - last=index; - index=memory.mhandles[index]; - } - if (old_pages == pages) return true; - if (old_pages > pages) { - /* Decrease size */ - pages--;index=handle;old_pages--; - while (pages) { - index=memory.mhandles[index]; - pages--;old_pages--; - } - MemHandle next=memory.mhandles[index]; - memory.mhandles[index]=-1; - index=next; - while (old_pages) { - next=memory.mhandles[index]; - memory.mhandles[index]=0; - index=next; - old_pages--; - } - return true; - } else { - /* Increase size, check for enough free space */ - Bitu need=pages-old_pages; - if (sequence) { - index=last+1; - Bitu free=0; - while ((index<(MemHandle)memory.pages) && !memory.mhandles[index]) { - index++;free++; - } - if (free>=need) { - /* Enough space allocate more pages */ - index=last; - while (need) { - memory.mhandles[index]=index+1; - need--;index++; - } - memory.mhandles[index]=-1; - return true; - } else { - /* Not Enough space allocate new block and copy */ - MemHandle newhandle=MEM_AllocatePages(pages,true); - if (!newhandle) return false; - MEM_BlockCopy(newhandle*4096,handle*4096,old_pages*4096); - MEM_ReleasePages(handle); - handle=newhandle; - return true; - } - } else { - MemHandle rem=MEM_AllocatePages(need,false); - if (!rem) return false; - memory.mhandles[last]=rem; - return true; - } - } - return 0; -} - -MemHandle MEM_NextHandle(MemHandle handle) { - return memory.mhandles[handle]; -} - -MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where) { - while (where) { - where--; - handle=memory.mhandles[handle]; - } - return handle; -} - - -/* - A20 line handling, - Basically maps the 4 pages at the 1mb to 0mb in the default page directory -*/ -bool MEM_A20_Enabled(void) { - return memory.a20.enabled; -} - -void MEM_A20_Enable(bool enabled) { - Bitu phys_base=enabled ? (1024/4) : 0; - for (Bitu i=0;i<16;i++) PAGING_MapPage((1024/4)+i,phys_base+i); - memory.a20.enabled=enabled; -} - - -/* Memory access functions */ -Bit16u mem_unalignedreadw(PhysPt address) { - return mem_readb_inline(address) | - mem_readb_inline(address+1) << 8; -} - -Bit32u mem_unalignedreadd(PhysPt address) { - return mem_readb_inline(address) | - (mem_readb_inline(address+1) << 8) | - (mem_readb_inline(address+2) << 16) | - (mem_readb_inline(address+3) << 24); -} - - -void mem_unalignedwritew(PhysPt address,Bit16u val) { - mem_writeb_inline(address,(Bit8u)val);val>>=8; - mem_writeb_inline(address+1,(Bit8u)val); -} - -void mem_unalignedwrited(PhysPt address,Bit32u val) { - mem_writeb_inline(address,(Bit8u)val);val>>=8; - mem_writeb_inline(address+1,(Bit8u)val);val>>=8; - mem_writeb_inline(address+2,(Bit8u)val);val>>=8; - mem_writeb_inline(address+3,(Bit8u)val); -} - - -bool mem_unalignedreadw_checked(PhysPt address, Bit16u * val) { - Bit8u rval1,rval2; - if (mem_readb_checked(address+0, &rval1)) return true; - if (mem_readb_checked(address+1, &rval2)) return true; - *val=(Bit16u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8)); - return false; -} - -bool mem_unalignedreadd_checked(PhysPt address, Bit32u * val) { - Bit8u rval1,rval2,rval3,rval4; - if (mem_readb_checked(address+0, &rval1)) return true; - if (mem_readb_checked(address+1, &rval2)) return true; - if (mem_readb_checked(address+2, &rval3)) return true; - if (mem_readb_checked(address+3, &rval4)) return true; - *val=(Bit32u)(((Bit8u)rval1) | (((Bit8u)rval2) << 8) | (((Bit8u)rval3) << 16) | (((Bit8u)rval4) << 24)); - return false; -} - -bool mem_unalignedwritew_checked(PhysPt address,Bit16u val) { - if (mem_writeb_checked(address,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked(address+1,(Bit8u)(val & 0xff))) return true; - return false; -} - -bool mem_unalignedwrited_checked(PhysPt address,Bit32u val) { - if (mem_writeb_checked(address,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked(address+1,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked(address+2,(Bit8u)(val & 0xff))) return true;val>>=8; - if (mem_writeb_checked(address+3,(Bit8u)(val & 0xff))) return true; - return false; -} - -Bit8u mem_readb(PhysPt address) { - return mem_readb_inline(address); -} - -Bit16u mem_readw(PhysPt address) { - return mem_readw_inline(address); -} - -Bit32u mem_readd(PhysPt address) { - return mem_readd_inline(address); -} - -void mem_writeb(PhysPt address,Bit8u val) { - mem_writeb_inline(address,val); -} - -void mem_writew(PhysPt address,Bit16u val) { - mem_writew_inline(address,val); -} - -void mem_writed(PhysPt address,Bit32u val) { - mem_writed_inline(address,val); -} - -static void write_p92(Bitu port,Bitu val,Bitu iolen) { - // Bit 0 = system reset (switch back to real mode) - if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported."); - memory.a20.controlport = val & ~2; - MEM_A20_Enable((val & 2)>0); -} - -static Bitu read_p92(Bitu port,Bitu iolen) { - return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); -} - -void RemoveEMSPageFrame(void) { - /* Setup rom at 0xe0000-0xf0000 */ - for (Bitu ct=0xe0;ct<0xf0;ct++) { - memory.phandlers[ct] = &rom_page_handler; - } -} - -void PreparePCJRCartRom(void) { - /* Setup rom at 0xd0000-0xe0000 */ - for (Bitu ct=0xd0;ct<0xe0;ct++) { - memory.phandlers[ct] = &rom_page_handler; - } -} - -HostPt GetMemBase(void) { return MemBase; } - -extern int x86_memsize; -extern int x86_biosstart; -extern int x86_xrom_start[2], x86_xrom_end[2]; - -class MEMORY:public Module_base{ -#if 0 -private: - IO_ReadHandleObject ReadHandler; - IO_WriteHandleObject WriteHandler; -#endif -public: - MEMORY(Section* configuration):Module_base(configuration){ - Bitu i; - Section_prop * section=static_cast(configuration); - - /* Setup the Physical Page Links */ -#if 0 - Bitu memsize=section->Get_int("memsize"); -#else - Bitu memsize = x86_memsize / (1024 * 1024); -#endif - if (memsize < 1) memsize = 1; - /* max 63 to solve problems with certain xms handlers */ - if (memsize > MAX_MEMORY-1) { - LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); - memsize = MAX_MEMORY-1; - } - if (memsize > SAFE_MEMORY-1) { - LOG_MSG("Memory sizes above %d MB are NOT recommended.",SAFE_MEMORY - 1); - LOG_MSG("Stick with the default values unless you are absolutely certain."); - } -#if 0 - MemBase = new Bit8u[memsize*1024*1024]; - if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); - /* Clear the memory, as new doesn't always give zeroed memory - * (Visual C debug mode). We want zeroed memory though. */ - memset((void*)MemBase,0,memsize*1024*1024); -#endif - - // make sure (unused) lfb is out side of our memory range - memory.lfb.start_page = (128 * 1024 * 1024) / 4096; - - memory.pages = (memsize*1024*1024)/4096; - /* Allocate the data for the different page information blocks */ - memory.phandlers=new PageHandler * [memory.pages]; - memory.mhandles=new MemHandle [memory.pages]; - for (i = 0;i < memory.pages;i++) { - memory.phandlers[i] = &ram_page_handler; - memory.mhandles[i] = 0; //Set to 0 for memory allocation - } -#if 0 - /* Setup rom at 0xc0000-0xc8000 */ - for (i=0xc0;i<0xc8;i++) { - memory.phandlers[i] = &rom_page_handler; - } -#endif - for (int j = 0; j < 2; j++) { - if (x86_xrom_start[j]) { - for (i = (x86_xrom_start[j] >> 12); i < (x86_xrom_end[j] >> 12); i++) { - memory.phandlers[i] = &rom_page_handler; - } - } - } - - /* Setup rom at 0xf0000-0x100000 */ - for (i= (x86_biosstart >> 12);i<0x100;i++) { - memory.phandlers[i] = &rom_page_handler; - } -#if 0 - if (machine==MCH_PCJR) { - /* Setup cartridge rom at 0xe0000-0xf0000 */ - for (i=0xe0;i<0xf0;i++) { - memory.phandlers[i] = &rom_page_handler; - } - } -#endif - /* Reset some links */ - memory.links.used = 0; -#if 0 - // A20 Line - PS/2 system control port A - WriteHandler.Install(0x92,write_p92,IO_MB); - ReadHandler.Install(0x92,read_p92,IO_MB); -#endif - MEM_A20_Enable(false); - } - ~MEMORY(){ - //delete [] MemBase; - delete [] memory.phandlers; - delete [] memory.mhandles; - } -}; - - -static MEMORY* test; - -void MEM_ShutDown(Section * sec) { - delete test; -} - -void MEM_Init(Section * sec) { - /* shutdown function */ - test = new MEMORY(sec); - sec->AddDestroyFunction(&MEM_ShutDown); -} diff --git a/dosbox/dosbox.h b/dosbox/dosbox.h deleted file mode 100644 index a0c20b11..00000000 --- a/dosbox/dosbox.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef DOSBOX_H -#define DOSBOX_H - -#ifndef CH_LIST -#define CH_LIST -#include -#endif - -#ifndef CH_STRING -#define CH_STRING -#include -#endif - -#define C_FPU 1 - -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -#if defined(_MSC_VER) -typedef unsigned __int64 Bit64u; -typedef signed __int64 Bit64s; -#else -typedef unsigned long long int Bit64u; -typedef signed long long int Bit64s; -#endif -typedef Bit32u Bitu; -typedef Bit32s Bits; -typedef double Real64; - -#define C_UNALIGNED_MEMORY - -#define LONGTYPE(a) a##LL - -#define INLINE __inline - -#define GCC_ATTRIBUTE(x) - -#include "logging.h" - -extern void E_Exit(char*,...); -extern void DOSBOX_RunMachine(void); - -#define GCC_UNLIKELY(x) x -#define GCC_LIKELY(x) x - -#define MAPPER_AddHandler(x1,x2,x3,x4,x5) - -class CommandLine { -public: - CommandLine(int argc, char const * const argv[]); - CommandLine(char const * const name, char const * const cmdline); - const char * GetFileName() { return file_name.c_str(); } - - bool FindExist(char const * const name, bool remove = false); - bool FindHex(char const * const name, int & value, bool remove = false); - bool FindInt(char const * const name, int & value, bool remove = false); - bool FindString(char const * const name, std::string & value, bool remove = false); - bool FindCommand(unsigned int which, std::string & value); - bool FindStringBegin(char const * const begin, std::string & value, bool remove = false); - bool FindStringRemain(char const * const name, std::string & value); - bool GetStringRemain(std::string & value); - unsigned int GetCount(void); - void Shift(unsigned int amount = 1); - Bit16u Get_arglength(); - -private: - typedef std::list::iterator cmd_it; - std::list cmds; - std::string file_name; - bool FindEntry(char const * const name, cmd_it & it, bool neednext = false); -}; - -extern int x86_fpu_enabled; - -#endif diff --git a/dosbox/flags.cpp b/dosbox/flags.cpp deleted file mode 100644 index 2e9532f5..00000000 --- a/dosbox/flags.cpp +++ /dev/null @@ -1,1188 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Lazy flag system was designed after the same kind of system used in Bochs. - Probably still some bugs left in here. -*/ - -#include "dosbox.h" -#include "cpu.h" -#include "lazyflags.h" -#include "pic.h" - -LazyFlags lflags; - -/* CF Carry Flag -- Set on high-order bit carry or borrow; cleared - otherwise. -*/ -Bit32u get_CF(void) { - - switch (lflags.type) { - case t_UNKNOWN: - case t_INCb: - case t_INCw: - case t_INCd: - case t_DECb: - case t_DECw: - case t_DECd: - case t_MUL: - return GETFLAG(CF); - case t_ADDb: - return (lf_resb8) return false; - else return (lf_var1b >> (8-lf_var2b)) & 1; - case t_SHLw: - if (lf_var2b>16) return false; - else return (lf_var1w >> (16-lf_var2b)) & 1; - case t_SHLd: - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - case t_DSHLd: - return (lf_var1d >> (32 - lf_var2b)) & 1; - case t_RCRb: - case t_SHRb: - return (lf_var1b >> (lf_var2b - 1)) & 1; - case t_RCRw: - case t_SHRw: - return (lf_var1w >> (lf_var2b - 1)) & 1; - case t_RCRd: - case t_SHRd: - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - case t_DSHRd: - return (lf_var1d >> (lf_var2b - 1)) & 1; - case t_SARb: - return (((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1; - case t_SARw: - return (((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1; - case t_SARd: - return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; - case t_NEGb: - return lf_var1b; - case t_NEGw: - return lf_var1w; - case t_NEGd: - return lf_var1d; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - return false; /* Set to false */ - case t_DIV: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",lflags.type); - } - return 0; -} - -/* AF Adjust flag -- Set on carry from or borrow to the low order - four bits of AL; cleared otherwise. Used for decimal - arithmetic. -*/ -Bit32u get_AF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(AF); - case t_ADDb: - case t_ADCb: - case t_SBBb: - case t_SUBb: - case t_CMPb: - return ((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10; - case t_ADDw: - case t_ADCw: - case t_SBBw: - case t_SUBw: - case t_CMPw: - return ((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10; - case t_ADCd: - case t_ADDd: - case t_SBBd: - case t_SUBd: - case t_CMPd: - return ((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10; - case t_INCb: - return (lf_resb & 0x0f) == 0; - case t_INCw: - return (lf_resw & 0x0f) == 0; - case t_INCd: - return (lf_resd & 0x0f) == 0; - case t_DECb: - return (lf_resb & 0x0f) == 0x0f; - case t_DECw: - return (lf_resw & 0x0f) == 0x0f; - case t_DECd: - return (lf_resd & 0x0f) == 0x0f; - case t_NEGb: - return lf_var1b & 0x0f; - case t_NEGw: - return lf_var1w & 0x0f; - case t_NEGd: - return lf_var1d & 0x0f; - case t_SHLb: - case t_SHRb: - case t_SARb: - return lf_var2b & 0x1f; - case t_SHLw: - case t_SHRw: - case t_SARw: - return lf_var2w & 0x1f; - case t_SHLd: - case t_SHRd: - case t_SARd: - return lf_var2d & 0x1f; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - case t_DSHLw: - case t_DSHLd: - case t_DSHRw: - case t_DSHRd: - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",lflags.type); - } - return 0; -} - -/* ZF Zero Flag -- Set if result is zero; cleared otherwise. -*/ - -Bit32u get_ZF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(ZF); - case t_ADDb: - case t_ORb: - case t_ADCb: - case t_SBBb: - case t_ANDb: - case t_XORb: - case t_SUBb: - case t_CMPb: - case t_INCb: - case t_DECb: - case t_TESTb: - case t_SHLb: - case t_SHRb: - case t_SARb: - case t_NEGb: - return (lf_resb==0); - case t_ADDw: - case t_ORw: - case t_ADCw: - case t_SBBw: - case t_ANDw: - case t_XORw: - case t_SUBw: - case t_CMPw: - case t_INCw: - case t_DECw: - case t_TESTw: - case t_SHLw: - case t_SHRw: - case t_SARw: - case t_DSHLw: - case t_DSHRw: - case t_NEGw: - return (lf_resw==0); - case t_ADDd: - case t_ORd: - case t_ADCd: - case t_SBBd: - case t_ANDd: - case t_XORd: - case t_SUBd: - case t_CMPd: - case t_INCd: - case t_DECd: - case t_TESTd: - case t_SHLd: - case t_SHRd: - case t_SARd: - case t_DSHLd: - case t_DSHRd: - case t_NEGd: - return (lf_resd==0); - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",lflags.type); - } - return false; -} -/* SF Sign Flag -- Set equal to high-order bit of result (0 is - positive, 1 if negative). -*/ -Bit32u get_SF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(SF); - case t_ADDb: - case t_ORb: - case t_ADCb: - case t_SBBb: - case t_ANDb: - case t_XORb: - case t_SUBb: - case t_CMPb: - case t_INCb: - case t_DECb: - case t_TESTb: - case t_SHLb: - case t_SHRb: - case t_SARb: - case t_NEGb: - return (lf_resb&0x80); - case t_ADDw: - case t_ORw: - case t_ADCw: - case t_SBBw: - case t_ANDw: - case t_XORw: - case t_SUBw: - case t_CMPw: - case t_INCw: - case t_DECw: - case t_TESTw: - case t_SHLw: - case t_SHRw: - case t_SARw: - case t_DSHLw: - case t_DSHRw: - case t_NEGw: - return (lf_resw&0x8000); - case t_ADDd: - case t_ORd: - case t_ADCd: - case t_SBBd: - case t_ANDd: - case t_XORd: - case t_SUBd: - case t_CMPd: - case t_INCd: - case t_DECd: - case t_TESTd: - case t_SHLd: - case t_SHRd: - case t_SARd: - case t_DSHLd: - case t_DSHRd: - case t_NEGd: - return (lf_resd&0x80000000); - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",lflags.type); - } - return false; - -} -Bit32u get_OF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - case t_MUL: - return GETFLAG(OF); - case t_ADDb: - case t_ADCb: - return ((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var2b)) & 0x80; - case t_ADDw: - case t_ADCw: - return ((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var2w)) & 0x8000; - case t_ADDd: - case t_ADCd: - return ((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var2d)) & 0x80000000; - case t_SBBb: - case t_SUBb: - case t_CMPb: - return ((lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb)) & 0x80; - case t_SBBw: - case t_SUBw: - case t_CMPw: - return ((lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw)) & 0x8000; - case t_SBBd: - case t_SUBd: - case t_CMPd: - return ((lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd)) & 0x80000000; - case t_INCb: - return (lf_resb == 0x80); - case t_INCw: - return (lf_resw == 0x8000); - case t_INCd: - return (lf_resd == 0x80000000); - case t_DECb: - return (lf_resb == 0x7f); - case t_DECw: - return (lf_resw == 0x7fff); - case t_DECd: - return (lf_resd == 0x7fffffff); - case t_NEGb: - return (lf_var1b == 0x80); - case t_NEGw: - return (lf_var1w == 0x8000); - case t_NEGd: - return (lf_var1d == 0x80000000); - case t_SHLb: - return (lf_resb ^ lf_var1b) & 0x80; - case t_SHLw: - case t_DSHRw: - case t_DSHLw: - return (lf_resw ^ lf_var1w) & 0x8000; - case t_SHLd: - case t_DSHRd: - case t_DSHLd: - return (lf_resd ^ lf_var1d) & 0x80000000; - case t_SHRb: - if ((lf_var2b&0x1f)==1) return (lf_var1b > 0x80); - else return false; - case t_SHRw: - if ((lf_var2b&0x1f)==1) return (lf_var1w > 0x8000); - else return false; - case t_SHRd: - if ((lf_var2b&0x1f)==1) return (lf_var1d > 0x80000000); - else return false; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - case t_SARb: - case t_SARw: - case t_SARd: - return false; /* Return false */ - case t_DIV: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",lflags.type); - } - return false; -} - -Bit16u parity_lookup[256] = { - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF - }; - -Bit32u get_PF(void) { - switch (lflags.type) { - case t_UNKNOWN: - return GETFLAG(PF); - default: - return (parity_lookup[lf_resb]); - }; - return 0; -} - - -#if 0 - -Bitu FillFlags(void) { -// if (lflags.type==t_UNKNOWN) return reg_flags; - Bitu new_word=(reg_flags & ~FLAG_MASK); - if (get_CF()) new_word|=FLAG_CF; - if (get_PF()) new_word|=FLAG_PF; - if (get_AF()) new_word|=FLAG_AF; - if (get_ZF()) new_word|=FLAG_ZF; - if (get_SF()) new_word|=FLAG_SF; - if (get_OF()) new_word|=FLAG_OF; - reg_flags=new_word; - lflags.type=t_UNKNOWN; - return reg_flags; -} - -#else - -#define DOFLAG_PF reg_flags=(reg_flags & ~FLAG_PF) | parity_lookup[lf_resb]; - -#define DOFLAG_AF reg_flags=(reg_flags & ~FLAG_AF) | (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10); - -#define DOFLAG_ZFb SETFLAGBIT(ZF,lf_resb==0); -#define DOFLAG_ZFw SETFLAGBIT(ZF,lf_resw==0); -#define DOFLAG_ZFd SETFLAGBIT(ZF,lf_resd==0); - -#define DOFLAG_SFb reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resb & 0x80) >> 0); -#define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000) >> 8); -#define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000) >> 24); - -#define SETCF(NEWBIT) reg_flags=(reg_flags & ~FLAG_CF)|(NEWBIT); - -#define SET_FLAG SETFLAGBIT - -Bitu FillFlags(void) { - switch (lflags.type) { - case t_UNKNOWN: - break; - case t_ADDb: - SET_FLAG(CF,(lf_resb8) SET_FLAG(CF,false); - else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHLw: - if (lf_var2b>16) SET_FLAG(CF,false); - else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHLd: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHLw: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - break; - case t_DSHLd: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - break; - - - case t_SHRb: - SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - if ((lf_var2b&0x1f)==1) SET_FLAG(OF,(lf_var1b >= 0x80)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHRw: - SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - if ((lf_var2w&0x1f)==1) SET_FLAG(OF,(lf_var1w >= 0x8000)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - if ((lf_var2d&0x1f)==1) SET_FLAG(OF,(lf_var1d >= 0x80000000)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - break; - case t_DSHRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - break; - - - case t_SARb: - SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SARw: - SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SARd: - SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - case t_INCb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb == 0x80)); - DOFLAG_PF; - break; - case t_INCw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw == 0x8000)); - DOFLAG_PF; - break; - case t_INCd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd == 0x80000000)); - DOFLAG_PF; - break; - - case t_DECb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb == 0x7f)); - DOFLAG_PF; - break; - case t_DECw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw == 0x7fff)); - DOFLAG_PF; - break; - case t_DECd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd == 0x7fffffff)); - DOFLAG_PF; - break; - - case t_NEGb: - SET_FLAG(CF,(lf_var1b!=0)); - SET_FLAG(AF,(lf_resb & 0x0f) != 0); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_var1b == 0x80)); - DOFLAG_PF; - break; - case t_NEGw: - SET_FLAG(CF,(lf_var1w!=0)); - SET_FLAG(AF,(lf_resw & 0x0f) != 0); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_var1w == 0x8000)); - DOFLAG_PF; - break; - case t_NEGd: - SET_FLAG(CF,(lf_var1d!=0)); - SET_FLAG(AF,(lf_resd & 0x0f) != 0); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_var1d == 0x80000000)); - DOFLAG_PF; - break; - - - case t_DIV: - case t_MUL: - break; - - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); - return 0; - } - lflags.type=t_UNKNOWN; - return reg_flags; -} - -void FillFlagsNoCFOF(void) { - switch (lflags.type) { - case t_UNKNOWN: - return; - case t_ADDb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ADDw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ADDd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - case t_ADCb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ADCw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ADCd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SBBb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_SBBw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_SBBd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SUBb: - case t_CMPb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_SUBw: - case t_CMPw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_SUBd: - case t_CMPd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_ORb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ORw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ORd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_TESTb: - case t_ANDb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_TESTw: - case t_ANDw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_TESTd: - case t_ANDd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_XORb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_XORw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_XORd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SHLb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHLw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHLd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHLw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DSHLd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SHRb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHRw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHRd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DSHRd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SARb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SARw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SARd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - case t_INCb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_INCw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_INCd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - case t_DECb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_DECw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DECd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - case t_NEGb: - SET_FLAG(AF,(lf_resb & 0x0f) != 0); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_NEGw: - SET_FLAG(AF,(lf_resw & 0x0f) != 0); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_NEGd: - SET_FLAG(AF,(lf_resd & 0x0f) != 0); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_DIV: - case t_MUL: - break; - - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); - break; - } - lflags.type=t_UNKNOWN; -} - -void DestroyConditionFlags(void) { - lflags.type=t_UNKNOWN; -} - -#endif diff --git a/dosbox/fpu.cpp b/dosbox/fpu.cpp deleted file mode 100644 index 6a0cc80a..00000000 --- a/dosbox/fpu.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: fpu.cpp,v 1.31 2009-09-16 18:01:53 qbix79 Exp $ */ - -#include "dosbox.h" -#if C_FPU - -#include -#include -#include "setup.h" -//#include "cross.h" -#include "mem.h" -#include "fpu.h" -#include "cpu.h" - -FPU_rec fpu; - -void FPU_FLDCW(PhysPt addr){ - Bit16u temp = mem_readw(addr); - FPU_SetCW(temp); -} - -Bit16u FPU_GetTag(void){ - Bit16u tag=0; - for(Bitu i=0;i<8;i++) - tag |= ( (fpu.tags[i]&3) <<(2*i)); - return tag; -} - -#if C_FPU_X86 -#include "fpu_instructions_x86.h" -#else -#include "fpu_instructions.h" -#endif - -/* WATCHIT : ALWAYS UPDATE REGISTERS BEFORE AND AFTER USING THEM - STATUS WORD => FPU_SET_TOP(TOP) BEFORE a read - TOP=FPU_GET_TOP() after a write; - */ - -static void EATREE(Bitu _rm){ - Bitu group=(_rm >> 3) & 7; - switch(group){ - case 0x00: /* FADD */ - FPU_FADD_EA(TOP); - break; - case 0x01: /* FMUL */ - FPU_FMUL_EA(TOP); - break; - case 0x02: /* FCOM */ - FPU_FCOM_EA(TOP); - break; - case 0x03: /* FCOMP */ - FPU_FCOM_EA(TOP); - FPU_FPOP(); - break; - case 0x04: /* FSUB */ - FPU_FSUB_EA(TOP); - break; - case 0x05: /* FSUBR */ - FPU_FSUBR_EA(TOP); - break; - case 0x06: /* FDIV */ - FPU_FDIV_EA(TOP); - break; - case 0x07: /* FDIVR */ - FPU_FDIVR_EA(TOP); - break; - default: - break; - } -} - -void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 32 BITS REALS */ - FPU_FLD_F32_EA(addr); - EATREE(rm); -} - -void FPU_ESC0_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FADD ST,STi */ - FPU_FADD(TOP,STV(sub)); - break; - case 0x01: /* FMUL ST,STi */ - FPU_FMUL(TOP,STV(sub)); - break; - case 0x02: /* FCOM STi */ - FPU_FCOM(TOP,STV(sub)); - break; - case 0x03: /* FCOMP STi */ - FPU_FCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FSUB ST,STi */ - FPU_FSUB(TOP,STV(sub)); - break; - case 0x05: /* FSUBR ST,STi */ - FPU_FSUBR(TOP,STV(sub)); - break; - case 0x06: /* FDIV ST,STi */ - FPU_FDIV(TOP,STV(sub)); - break; - case 0x07: /* FDIVR ST,STi */ - FPU_FDIVR(TOP,STV(sub)); - break; - default: - break; - } -} - -void FPU_ESC1_EA(Bitu rm,PhysPt addr) { -// floats - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FLD float*/ - FPU_PREP_PUSH(); - FPU_FLD_F32(addr,TOP); - break; - case 0x01: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST float*/ - FPU_FST_F32(addr); - break; - case 0x03: /* FSTP float*/ - FPU_FST_F32(addr); - FPU_FPOP(); - break; - case 0x04: /* FLDENV */ - FPU_FLDENV(addr); - break; - case 0x05: /* FLDCW */ - FPU_FLDCW(addr); - break; - case 0x06: /* FSTENV */ - FPU_FSTENV(addr); - break; - case 0x07: /* FNSTCW*/ - mem_writew(addr,fpu.cw); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC1_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FLD STi */ - { - Bitu reg_from=STV(sub); - FPU_PREP_PUSH(); - FPU_FST(reg_from, TOP); - break; - } - case 0x01: /* FXCH STi */ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FNOP */ - FPU_FNOP(); - break; - case 0x03: /* FSTP STi */ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: - switch(sub){ - case 0x00: /* FCHS */ - FPU_FCHS(); - break; - case 0x01: /* FABS */ - FPU_FABS(); - break; - case 0x02: /* UNKNOWN */ - case 0x03: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - case 0x04: /* FTST */ - FPU_FTST(); - break; - case 0x05: /* FXAM */ - FPU_FXAM(); - break; - case 0x06: /* FTSTP (cyrix)*/ - case 0x07: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x05: - switch(sub){ - case 0x00: /* FLD1 */ - FPU_FLD1(); - break; - case 0x01: /* FLDL2T */ - FPU_FLDL2T(); - break; - case 0x02: /* FLDL2E */ - FPU_FLDL2E(); - break; - case 0x03: /* FLDPI */ - FPU_FLDPI(); - break; - case 0x04: /* FLDLG2 */ - FPU_FLDLG2(); - break; - case 0x05: /* FLDLN2 */ - FPU_FLDLN2(); - break; - case 0x06: /* FLDZ*/ - FPU_FLDZ(); - break; - case 0x07: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x06: - switch(sub){ - case 0x00: /* F2XM1 */ - FPU_F2XM1(); - break; - case 0x01: /* FYL2X */ - FPU_FYL2X(); - break; - case 0x02: /* FPTAN */ - FPU_FPTAN(); - break; - case 0x03: /* FPATAN */ - FPU_FPATAN(); - break; - case 0x04: /* FXTRACT */ - FPU_FXTRACT(); - break; - case 0x05: /* FPREM1 */ - FPU_FPREM1(); - break; - case 0x06: /* FDECSTP */ - TOP = (TOP - 1) & 7; - break; - case 0x07: /* FINCSTP */ - TOP = (TOP + 1) & 7; - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x07: - switch(sub){ - case 0x00: /* FPREM */ - FPU_FPREM(); - break; - case 0x01: /* FYL2XP1 */ - FPU_FYL2XP1(); - break; - case 0x02: /* FSQRT */ - FPU_FSQRT(); - break; - case 0x03: /* FSINCOS */ - FPU_FSINCOS(); - break; - case 0x04: /* FRNDINT */ - FPU_FRNDINT(); - break; - case 0x05: /* FSCALE */ - FPU_FSCALE(); - break; - case 0x06: /* FSIN */ - FPU_FSIN(); - break; - case 0x07: /* FCOS */ - FPU_FCOS(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - } -} - - -void FPU_ESC2_EA(Bitu rm,PhysPt addr) { - /* 32 bits integer operants */ - FPU_FLD_I32_EA(addr); - EATREE(rm); -} - -void FPU_ESC2_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x05: - switch(sub){ - case 0x01: /* FUCOMPP */ - FPU_FUCOM(TOP,STV(1)); - FPU_FPOP(); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } -} - - -void FPU_ESC3_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FILD */ - FPU_PREP_PUSH(); - FPU_FLD_I32(addr,TOP); - break; - case 0x01: /* FISTTP */ - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST */ - FPU_FST_I32(addr); - break; - case 0x03: /* FISTP */ - FPU_FST_I32(addr); - FPU_FPOP(); - break; - case 0x05: /* FLD 80 Bits Real */ - FPU_PREP_PUSH(); - FPU_FLD_F80(addr); - break; - case 0x07: /* FSTP 80 Bits Real */ - FPU_FST_F80(addr); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - } -} - -void FPU_ESC3_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group) { - case 0x04: - switch (sub) { - case 0x00: //FNENI - case 0x01: //FNDIS - LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub); - break; - case 0x02: //FNCLEX FCLEX - FPU_FCLEX(); - break; - case 0x03: //FNINIT FINIT - FPU_FINIT(); - break; - case 0x04: //FNSETPM - case 0x05: //FRSTPM -// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); - FPU_FNOP(); - break; - default: - E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub); - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); - break; - } - return; -} - - -void FPU_ESC4_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 64 BITS REALS */ - FPU_FLD_F64_EA(addr); - EATREE(rm); -} - -void FPU_ESC4_Normal(Bitu rm) { - /* LOOKS LIKE number 6 without popping */ - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FADD STi,ST*/ - FPU_FADD(STV(sub),TOP); - break; - case 0x01: /* FMUL STi,ST*/ - FPU_FMUL(STV(sub),TOP); - break; - case 0x02: /* FCOM*/ - FPU_FCOM(TOP,STV(sub)); - break; - case 0x03: /* FCOMP*/ - FPU_FCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FSUBR STi,ST*/ - FPU_FSUBR(STV(sub),TOP); - break; - case 0x05: /* FSUB STi,ST*/ - FPU_FSUB(STV(sub),TOP); - break; - case 0x06: /* FDIVR STi,ST*/ - FPU_FDIVR(STV(sub),TOP); - break; - case 0x07: /* FDIV STi,ST*/ - FPU_FDIV(STV(sub),TOP); - break; - default: - break; - } -} - -void FPU_ESC5_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FLD double real*/ - FPU_PREP_PUSH(); - FPU_FLD_F64(addr,TOP); - break; - case 0x01: /* FISTTP longint*/ - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST double real*/ - FPU_FST_F64(addr); - break; - case 0x03: /* FSTP double real*/ - FPU_FST_F64(addr); - FPU_FPOP(); - break; - case 0x04: /* FRSTOR */ - FPU_FRSTOR(addr); - break; - case 0x06: /* FSAVE */ - FPU_FSAVE(addr); - break; - case 0x07: /*FNSTSW NG DISAGREES ON THIS*/ - FPU_SET_TOP(TOP); - mem_writew(addr,fpu.sw); - //seems to break all dos4gw games :) - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - } -} - -void FPU_ESC5_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FFREE STi */ - fpu.tags[STV(sub)]=TAG_Empty; - break; - case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FST STi */ - FPU_FST(TOP,STV(sub)); - break; - case 0x03: /* FSTP STi*/ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FUCOM STi */ - FPU_FUCOM(TOP,STV(sub)); - break; - case 0x05: /*FUCOMP STi */ - FPU_FUCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC6_EA(Bitu rm,PhysPt addr) { - /* 16 bit (word integer) operants */ - FPU_FLD_I16_EA(addr); - EATREE(rm); -} - -void FPU_ESC6_Normal(Bitu rm) { - /* all P variants working only on registers */ - /* get top before switch and pop afterwards */ - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /*FADDP STi,ST*/ - FPU_FADD(STV(sub),TOP); - break; - case 0x01: /* FMULP STi,ST*/ - FPU_FMUL(STV(sub),TOP); - break; - case 0x02: /* FCOMP5*/ - FPU_FCOM(TOP,STV(sub)); - break; /* TODO IS THIS ALLRIGHT ????????? */ - case 0x03: /*FCOMPP*/ - if(sub != 1) { - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); - return; - } - FPU_FCOM(TOP,STV(1)); - FPU_FPOP(); /* extra pop at the bottom*/ - break; - case 0x04: /* FSUBRP STi,ST*/ - FPU_FSUBR(STV(sub),TOP); - break; - case 0x05: /* FSUBP STi,ST*/ - FPU_FSUB(STV(sub),TOP); - break; - case 0x06: /* FDIVRP STi,ST*/ - FPU_FDIVR(STV(sub),TOP); - break; - case 0x07: /* FDIVP STi,ST*/ - FPU_FDIV(STV(sub),TOP); - break; - default: - break; - } - FPU_FPOP(); -} - - -void FPU_ESC7_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FILD Bit16s */ - FPU_PREP_PUSH(); - FPU_FLD_I16(addr,TOP); - break; - case 0x01: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST Bit16s */ - FPU_FST_I16(addr); - break; - case 0x03: /* FISTP Bit16s */ - FPU_FST_I16(addr); - FPU_FPOP(); - break; - case 0x04: /* FBLD packed BCD */ - FPU_PREP_PUSH(); - FPU_FBLD(addr,TOP); - break; - case 0x05: /* FILD Bit64s */ - FPU_PREP_PUSH(); - FPU_FLD_I64(addr,TOP); - break; - case 0x06: /* FBSTP packed BCD */ - FPU_FBST(addr); - FPU_FPOP(); - break; - case 0x07: /* FISTP Bit64s */ - FPU_FST_I64(addr); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC7_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FFREEP STi*/ - fpu.tags[STV(sub)]=TAG_Empty; - FPU_FPOP(); - break; - case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FSTP STi*/ - case 0x03: /* FSTP STi*/ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: - switch(sub){ - case 0x00: /* FNSTSW AX*/ - FPU_SET_TOP(TOP); - reg_ax = fpu.sw; - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } -} - - -void FPU_Init(Section*) { - FPU_FINIT(); -} - -#endif diff --git a/dosbox/fpu.h b/dosbox/fpu.h deleted file mode 100644 index 67f7db41..00000000 --- a/dosbox/fpu.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_FPU_H -#define DOSBOX_FPU_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -void FPU_ESC0_Normal(Bitu rm); -void FPU_ESC0_EA(Bitu func,PhysPt ea); -void FPU_ESC1_Normal(Bitu rm); -void FPU_ESC1_EA(Bitu func,PhysPt ea); -void FPU_ESC2_Normal(Bitu rm); -void FPU_ESC2_EA(Bitu func,PhysPt ea); -void FPU_ESC3_Normal(Bitu rm); -void FPU_ESC3_EA(Bitu func,PhysPt ea); -void FPU_ESC4_Normal(Bitu rm); -void FPU_ESC4_EA(Bitu func,PhysPt ea); -void FPU_ESC5_Normal(Bitu rm); -void FPU_ESC5_EA(Bitu func,PhysPt ea); -void FPU_ESC6_Normal(Bitu rm); -void FPU_ESC6_EA(Bitu func,PhysPt ea); -void FPU_ESC7_Normal(Bitu rm); -void FPU_ESC7_EA(Bitu func,PhysPt ea); - - -typedef union { - double d; -#ifndef WORDS_BIGENDIAN - struct { - Bit32u lower; - Bit32s upper; - } l; -#else - struct { - Bit32s upper; - Bit32u lower; - } l; -#endif - Bit64s ll; -} FPU_Reg; - -typedef struct { - Bit32u m1; - Bit32u m2; - Bit16u m3; - - Bit16u d1; - Bit32u d2; -} FPU_P_Reg; - -enum FPU_Tag { - TAG_Valid = 0, - TAG_Zero = 1, - TAG_Weird = 2, - TAG_Empty = 3 -}; - -enum FPU_Round { - ROUND_Nearest = 0, - ROUND_Down = 1, - ROUND_Up = 2, - ROUND_Chop = 3 -}; - -typedef struct { - FPU_Reg regs[9]; - FPU_P_Reg p_regs[9]; - FPU_Tag tags[9]; - Bit16u cw,cw_mask_all; - Bit16u sw; - Bitu top; - FPU_Round round; -} FPU_rec; - - -//get pi from a real library -#define PI 3.14159265358979323846 -#define L2E 1.4426950408889634 -#define L2T 3.3219280948873623 -#define LN2 0.69314718055994531 -#define LG2 0.3010299956639812 - - -extern FPU_rec fpu; - -#define TOP fpu.top -#define STV(i) ( (fpu.top+ (i) ) & 7 ) - - -Bit16u FPU_GetTag(void); -void FPU_FLDCW(PhysPt addr); - -static INLINE void FPU_SetTag(Bit16u tag){ - for(Bitu i=0;i<8;i++) - fpu.tags[i] = static_cast((tag >>(2*i))&3); -} - -static INLINE void FPU_SetCW(Bitu word){ - fpu.cw = (Bit16u)word; - fpu.cw_mask_all = (Bit16u)(word | 0x3f); - fpu.round = (FPU_Round)((word >> 10) & 3); -} - - -static INLINE Bitu FPU_GET_TOP(void) { - return (fpu.sw & 0x3800)>>11; -} - -static INLINE void FPU_SET_TOP(Bitu val){ - fpu.sw &= ~0x3800; - fpu.sw |= (val&7)<<11; -} - - -static INLINE void FPU_SET_C0(Bitu C){ - fpu.sw &= ~0x0100; - if(C) fpu.sw |= 0x0100; -} - -static INLINE void FPU_SET_C1(Bitu C){ - fpu.sw &= ~0x0200; - if(C) fpu.sw |= 0x0200; -} - -static INLINE void FPU_SET_C2(Bitu C){ - fpu.sw &= ~0x0400; - if(C) fpu.sw |= 0x0400; -} - -static INLINE void FPU_SET_C3(Bitu C){ - fpu.sw &= ~0x4000; - if(C) fpu.sw |= 0x4000; -} - - -#endif diff --git a/dosbox/fpu_instructions.h b/dosbox/fpu_instructions.h deleted file mode 100644 index 9a505a2b..00000000 --- a/dosbox/fpu_instructions.h +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: fpu_instructions.h,v 1.33 2009-05-27 09:15:41 qbix79 Exp $ */ - - -static void FPU_FINIT(void) { - FPU_SetCW(0x37F); - fpu.sw = 0; - TOP=FPU_GET_TOP(); - fpu.tags[0] = TAG_Empty; - fpu.tags[1] = TAG_Empty; - fpu.tags[2] = TAG_Empty; - fpu.tags[3] = TAG_Empty; - fpu.tags[4] = TAG_Empty; - fpu.tags[5] = TAG_Empty; - fpu.tags[6] = TAG_Empty; - fpu.tags[7] = TAG_Empty; - fpu.tags[8] = TAG_Valid; // is only used by us -} - -static void FPU_FCLEX(void){ - fpu.sw &= 0x7f00; //should clear exceptions -} - -static void FPU_FNOP(void){ - return; -} - -static void FPU_PUSH(double in){ - TOP = (TOP - 1) &7; - //actually check if empty - fpu.tags[TOP] = TAG_Valid; - fpu.regs[TOP].d = in; -// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); - return; -} - -static void FPU_PREP_PUSH(void){ - TOP = (TOP - 1) &7; - fpu.tags[TOP] = TAG_Valid; -} - -static void FPU_FPOP(void){ - fpu.tags[TOP]=TAG_Empty; - //maybe set zero in it as well - TOP = ((TOP+1)&7); -// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d); - return; -} - -static double FROUND(double in){ - switch(fpu.round){ - case ROUND_Nearest: - if (in-floor(in)>0.5) return (floor(in)+1); - else if (in-floor(in)<0.5) return (floor(in)); - else return (((static_cast(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); - break; - case ROUND_Down: - return (floor(in)); - break; - case ROUND_Up: - return (ceil(in)); - break; - case ROUND_Chop: - return in; //the cast afterwards will do it right maybe cast here - break; - default: - return in; - break; - } -} - -#define BIAS80 16383 -#define BIAS64 1023 - -static Real64 FPU_FLD80(PhysPt addr) { - struct { - Bit16s begin; - FPU_Reg eind; - } test; - test.eind.l.lower = mem_readd(addr); - test.eind.l.upper = mem_readd(addr+4); - test.begin = mem_readw(addr+8); - - Bit64s exp64 = (((test.begin&0x7fff) - BIAS80)); - Bit64s blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - Bit64s exp64final = ((exp64 >0)?blah:-blah) +BIAS64; - - Bit64s mant64 = (test.eind.ll >> 11) & LONGTYPE(0xfffffffffffff); - Bit64s sign = (test.begin&0x8000)?1:0; - FPU_Reg result; - result.ll = (sign <<63)|(exp64final << 52)| mant64; - return result.d; - - //mant64= test.mant80/2***64 * 2 **53 -} - -static void FPU_ST80(PhysPt addr,Bitu reg) { - struct { - Bit16s begin; - FPU_Reg eind; - } test; - Bit64s sign80 = (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; - Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final = (exp80>>52); - Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); - Bit64s mant80final = (mant80 << 11); - if(fpu.regs[reg].d != 0){ //Zero is a special case - // Elvira wants the 8 and tcalc doesn't - mant80final |= LONGTYPE(0x8000000000000000); - //Ca-cyber doesn't like this when result is zero. - exp80final += (BIAS80 - BIAS64); - } - test.begin = (static_cast(sign80)<<15)| static_cast(exp80final); - test.eind.ll = mant80final; - mem_writed(addr,test.eind.l.lower); - mem_writed(addr+4,test.eind.l.upper); - mem_writew(addr+8,test.begin); -} - - -static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { - union { - float f; - Bit32u l; - } blah; - blah.l = mem_readd(addr); - fpu.regs[store_to].d = static_cast(blah.f); -} - -static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { - fpu.regs[store_to].l.lower = mem_readd(addr); - fpu.regs[store_to].l.upper = mem_readd(addr+4); -} - -static void FPU_FLD_F80(PhysPt addr) { - fpu.regs[TOP].d = FPU_FLD80(addr); -} - -static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { - Bit16s blah = mem_readw(addr); - fpu.regs[store_to].d = static_cast(blah); -} - -static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { - Bit32s blah = mem_readd(addr); - fpu.regs[store_to].d = static_cast(blah); -} - -static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { - FPU_Reg blah; - blah.l.lower = mem_readd(addr); - blah.l.upper = mem_readd(addr+4); - fpu.regs[store_to].d = static_cast(blah.ll); -} - -static void FPU_FBLD(PhysPt addr,Bitu store_to) { - Bit64u val = 0; - Bitu in = 0; - Bit64u base = 1; - for(Bitu i = 0;i < 9;i++){ - in = mem_readb(addr + i); - val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 - base *= 10; - val += ((( in>>4)&0xf) * base); - base *= 10; - } - - //last number, only now convert to float in order to get - //the best signification - Real64 temp = static_cast(val); - in = mem_readb(addr + 9); - temp += ( (in&0xf) * base ); - if(in&0x80) temp *= -1.0; - fpu.regs[store_to].d = temp; -} - - -static INLINE void FPU_FLD_F32_EA(PhysPt addr) { - FPU_FLD_F32(addr,8); -} -static INLINE void FPU_FLD_F64_EA(PhysPt addr) { - FPU_FLD_F64(addr,8); -} -static INLINE void FPU_FLD_I32_EA(PhysPt addr) { - FPU_FLD_I32(addr,8); -} -static INLINE void FPU_FLD_I16_EA(PhysPt addr) { - FPU_FLD_I16(addr,8); -} - - -static void FPU_FST_F32(PhysPt addr) { - union { - float f; - Bit32u l; - } blah; - //should depend on rounding method - blah.f = static_cast(fpu.regs[TOP].d); - mem_writed(addr,blah.l); -} - -static void FPU_FST_F64(PhysPt addr) { - mem_writed(addr,fpu.regs[TOP].l.lower); - mem_writed(addr+4,fpu.regs[TOP].l.upper); -} - -static void FPU_FST_F80(PhysPt addr) { - FPU_ST80(addr,TOP); -} - -static void FPU_FST_I16(PhysPt addr) { - mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); -} - -static void FPU_FST_I32(PhysPt addr) { - mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); -} - -static void FPU_FST_I64(PhysPt addr) { - FPU_Reg blah; - blah.ll = static_cast(FROUND(fpu.regs[TOP].d)); - mem_writed(addr,blah.l.lower); - mem_writed(addr+4,blah.l.upper); -} - -static void FPU_FBST(PhysPt addr) { - FPU_Reg val = fpu.regs[TOP]; - bool sign = false; - if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) { //sign - sign=true; - val.d=-val.d; - } - //numbers from back to front - Real64 temp=val.d; - Bitu p; - for(Bitu i=0;i<9;i++){ - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p |= (static_cast(val.d - 10.0*temp)<<4); - - mem_writeb(addr+i,p); - } - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - if(sign) - p|=0x80; - mem_writeb(addr+9,p); -} - -static void FPU_FADD(Bitu op1, Bitu op2){ - fpu.regs[op1].d+=fpu.regs[op2].d; - //flags and such :) - return; -} - -static void FPU_FSIN(void){ - fpu.regs[TOP].d = sin(fpu.regs[TOP].d); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FSINCOS(void){ - Real64 temp = fpu.regs[TOP].d; - fpu.regs[TOP].d = sin(temp); - FPU_PUSH(cos(temp)); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FCOS(void){ - fpu.regs[TOP].d = cos(fpu.regs[TOP].d); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FSQRT(void){ - fpu.regs[TOP].d = sqrt(fpu.regs[TOP].d); - //flags and such :) - return; -} -static void FPU_FPATAN(void){ - fpu.regs[STV(1)].d = atan2(fpu.regs[STV(1)].d,fpu.regs[TOP].d); - FPU_FPOP(); - //flags and such :) - return; -} -static void FPU_FPTAN(void){ - fpu.regs[TOP].d = tan(fpu.regs[TOP].d); - FPU_PUSH(1.0); - FPU_SET_C2(0); - //flags and such :) - return; -} -static void FPU_FDIV(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FDIVR(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d; - // flags and such :) - return; -} - -static void FPU_FMUL(Bitu st, Bitu other){ - fpu.regs[st].d*=fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FSUB(Bitu st, Bitu other){ - fpu.regs[st].d = fpu.regs[st].d - fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FSUBR(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d; - //flags and such :) - return; -} - -static void FPU_FXCH(Bitu st, Bitu other){ - FPU_Tag tag = fpu.tags[other]; - FPU_Reg reg = fpu.regs[other]; - fpu.tags[other] = fpu.tags[st]; - fpu.regs[other] = fpu.regs[st]; - fpu.tags[st] = tag; - fpu.regs[st] = reg; -} - -static void FPU_FST(Bitu st, Bitu other){ - fpu.tags[other] = fpu.tags[st]; - fpu.regs[other] = fpu.regs[st]; -} - - -static void FPU_FCOM(Bitu st, Bitu other){ - if(((fpu.tags[st] != TAG_Valid) && (fpu.tags[st] != TAG_Zero)) || - ((fpu.tags[other] != TAG_Valid) && (fpu.tags[other] != TAG_Zero))){ - FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; - } - if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return; - } - if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return; - } - // st > other - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return; -} - -static void FPU_FUCOM(Bitu st, Bitu other){ - //does atm the same as fcom - FPU_FCOM(st,other); -} - -static void FPU_FRNDINT(void){ - Bit64s temp= static_cast(FROUND(fpu.regs[TOP].d)); - fpu.regs[TOP].d=static_cast(temp); -} - -static void FPU_FPREM(void){ - Real64 valtop = fpu.regs[TOP].d; - Real64 valdiv = fpu.regs[STV(1)].d; - Bit64s ressaved = static_cast( (valtop/valdiv) ); -// Some backups -// Real64 res=valtop - ressaved*valdiv; -// res= fmod(valtop,valdiv); - fpu.regs[TOP].d = valtop - ressaved*valdiv; - FPU_SET_C0(static_cast(ressaved&4)); - FPU_SET_C3(static_cast(ressaved&2)); - FPU_SET_C1(static_cast(ressaved&1)); - FPU_SET_C2(0); -} - -static void FPU_FPREM1(void){ - Real64 valtop = fpu.regs[TOP].d; - Real64 valdiv = fpu.regs[STV(1)].d; - double quot = valtop/valdiv; - double quotf = floor(quot); - Bit64s ressaved; - if (quot-quotf>0.5) ressaved = static_cast(quotf+1); - else if (quot-quotf<0.5) ressaved = static_cast(quotf); - else ressaved = static_cast((((static_cast(quotf))&1)!=0)?(quotf+1):(quotf)); - fpu.regs[TOP].d = valtop - ressaved*valdiv; - FPU_SET_C0(static_cast(ressaved&4)); - FPU_SET_C3(static_cast(ressaved&2)); - FPU_SET_C1(static_cast(ressaved&1)); - FPU_SET_C2(0); -} - -static void FPU_FXAM(void){ - if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) //sign - { - FPU_SET_C1(1); - } - else - { - FPU_SET_C1(0); - } - if(fpu.tags[TOP] == TAG_Empty) - { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); - return; - } - if(fpu.regs[TOP].d == 0.0) //zero or normalized number. - { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); - } - else - { - FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); - } -} - - -static void FPU_F2XM1(void){ - fpu.regs[TOP].d = pow(2.0,fpu.regs[TOP].d) - 1; - return; -} - -static void FPU_FYL2X(void){ - fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); - FPU_FPOP(); - return; -} - -static void FPU_FYL2XP1(void){ - fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d+1.0)/log(static_cast(2.0)); - FPU_FPOP(); - return; -} - -static void FPU_FSCALE(void){ - fpu.regs[TOP].d *= pow(2.0,static_cast(static_cast(fpu.regs[STV(1)].d))); - return; //2^x where x is chopped. -} - -static void FPU_FSTENV(PhysPt addr){ - FPU_SET_TOP(TOP); - if(!cpu.code.big) { - mem_writew(addr+0,static_cast(fpu.cw)); - mem_writew(addr+2,static_cast(fpu.sw)); - mem_writew(addr+4,static_cast(FPU_GetTag())); - } else { - mem_writed(addr+0,static_cast(fpu.cw)); - mem_writed(addr+4,static_cast(fpu.sw)); - mem_writed(addr+8,static_cast(FPU_GetTag())); - } -} - -static void FPU_FLDENV(PhysPt addr){ - Bit16u tag; - Bit32u tagbig; - Bitu cw; - if(!cpu.code.big) { - cw = mem_readw(addr+0); - fpu.sw = mem_readw(addr+2); - tag = mem_readw(addr+4); - } else { - cw = mem_readd(addr+0); - fpu.sw = (Bit16u)mem_readd(addr+4); - tagbig = mem_readd(addr+8); - tag = static_cast(tagbig); - } - FPU_SetTag(tag); - FPU_SetCW(cw); - TOP = FPU_GET_TOP(); -} - -static void FPU_FSAVE(PhysPt addr){ - FPU_FSTENV(addr); - Bitu start = (cpu.code.big?28:14); - for(Bitu i = 0;i < 8;i++){ - FPU_ST80(addr+start,STV(i)); - start += 10; - } - FPU_FINIT(); -} - -static void FPU_FRSTOR(PhysPt addr){ - FPU_FLDENV(addr); - Bitu start = (cpu.code.big?28:14); - for(Bitu i = 0;i < 8;i++){ - fpu.regs[STV(i)].d = FPU_FLD80(addr+start); - start += 10; - } -} - -static void FPU_FXTRACT(void) { - // function stores real bias in st and - // pushes the significant number onto the stack - // if double ever uses a different base please correct this function - - FPU_Reg test = fpu.regs[TOP]; - Bit64s exp80 = test.ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final = (exp80>>52) - BIAS64; - Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); - fpu.regs[TOP].d = static_cast(exp80final); - FPU_PUSH(mant); -} - -static void FPU_FCHS(void){ - fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d); -} - -static void FPU_FABS(void){ - fpu.regs[TOP].d = fabs(fpu.regs[TOP].d); -} - -static void FPU_FTST(void){ - fpu.regs[8].d = 0.0; - FPU_FCOM(TOP,8); -} - -static void FPU_FLD1(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = 1.0; -} - -static void FPU_FLDL2T(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = L2T; -} - -static void FPU_FLDL2E(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = L2E; -} - -static void FPU_FLDPI(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = PI; -} - -static void FPU_FLDLG2(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = LG2; -} - -static void FPU_FLDLN2(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = LN2; -} - -static void FPU_FLDZ(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = 0.0; - fpu.tags[TOP] = TAG_Zero; -} - - -static INLINE void FPU_FADD_EA(Bitu op1){ - FPU_FADD(op1,8); -} -static INLINE void FPU_FMUL_EA(Bitu op1){ - FPU_FMUL(op1,8); -} -static INLINE void FPU_FSUB_EA(Bitu op1){ - FPU_FSUB(op1,8); -} -static INLINE void FPU_FSUBR_EA(Bitu op1){ - FPU_FSUBR(op1,8); -} -static INLINE void FPU_FDIV_EA(Bitu op1){ - FPU_FDIV(op1,8); -} -static INLINE void FPU_FDIVR_EA(Bitu op1){ - FPU_FDIVR(op1,8); -} -static INLINE void FPU_FCOM_EA(Bitu op1){ - FPU_FCOM(op1,8); -} - diff --git a/dosbox/fpu_instructions_x86.h b/dosbox/fpu_instructions_x86.h deleted file mode 100644 index 16d96d66..00000000 --- a/dosbox/fpu_instructions_x86.h +++ /dev/null @@ -1,1489 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: fpu_instructions_x86.h,v 1.7 2009-05-27 09:15:41 qbix79 Exp $ */ - - -// #define WEAK_EXCEPTIONS - - -#if defined (_MSC_VER) - -#ifdef WEAK_EXCEPTIONS -#define clx -#else -#define clx fclex -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD(op,szI,szA) \ - __asm { \ - __asm mov ebx, store_to \ - __asm shl ebx, 4 \ - __asm op szI PTR fpu.p_regs[128].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } -#else -#define FPUD_LOAD(op,szI,szA) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, 8 \ - __asm shl eax, 4 \ - __asm mov ebx, store_to \ - __asm shl ebx, 4 \ - __asm fclex \ - __asm op szI PTR fpu.p_regs[eax].m1 \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD_EA(op,szI,szA) \ - __asm { \ - __asm op szI PTR fpu.p_regs[128].m1 \ - } -#else -#define FPUD_LOAD_EA(op,szI,szA) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, 8 \ - __asm shl eax, 4 \ - __asm fclex \ - __asm op szI PTR fpu.p_regs[eax].m1 \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_STORE(op,szI,szA) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, TOP \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op szI PTR fpu.p_regs[128].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_STORE(op,szI,szA) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm mov ebx, 8 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op szI PTR fpu.p_regs[ebx].m1 \ - __asm fnstsw new_sw \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsin,fcos,f2xm1,fchs,fabs -#define FPUD_TRIG(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fsincos -#define FPUD_SINCOS() \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm fsincos \ - __asm fnstsw new_sw \ - __asm mov cx, new_sw \ - __asm and ch, 0x04 \ - __asm jnz argument_too_large1 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm jmp end_sincos \ - __asm argument_too_large1: \ - __asm fstp st(0) \ - __asm end_sincos: \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fptan -#define FPUD_PTAN() \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm fptan \ - __asm fnstsw new_sw \ - __asm mov cx, new_sw \ - __asm and ch, 0x04 \ - __asm jnz argument_too_large2 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm jmp end_ptan \ - __asm argument_too_large2: \ - __asm fstp st(0) \ - __asm end_ptan: \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fxtract -#ifdef WEAK_EXCEPTIONS -#define FPUD_XTRACT \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxtract \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - FPU_PREP_PUSH(); -#else -#define FPUD_XTRACT \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm fxtract \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_PREP_PUSH(); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fldcw fpu.cw_mask_all \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH1(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm clx \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1_EA(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH1_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm clx \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsqrt,frndint -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH2(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, TOP \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fldcw fpu.cw_mask_all \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH3(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fclex \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3_EA(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH3_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm fclex \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -// handles fprem,fprem1,fscale -#define FPUD_REMINDER(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fstp st(0) \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov ebx, op2 \ - __asm mov eax, op1 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -#define FPUD_COMPARE_EA(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fxam,ftst -#define FPUD_EXAMINE(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp st(0) \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fpatan,fyl2xp1 -#ifdef WEAK_EXCEPTIONS -#define FPUD_WITH_POP(op) \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - FPU_FPOP(); -#else -#define FPUD_WITH_POP(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// handles fyl2x -#ifdef WEAK_EXCEPTIONS -#define FPUD_FYL2X(op) \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - FPU_FPOP(); -#else -#define FPUD_FYL2X(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// load math constants -#define FPUD_LOAD_CONST(op) \ - FPU_PREP_PUSH(); \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm clx \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - -#else - -#ifdef WEAK_EXCEPTIONS -#define clx -#else -#define clx "fclex" -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD(op,szI,szA) \ - __asm__ volatile ( \ - "movl $128, %%eax \n" \ - "shl $4, %0 \n" \ - #op #szA " (%1, %%eax) \n" \ - "fstpt (%1, %0) " \ - : \ - : "r" (store_to), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); -#else -#define FPUD_LOAD(op,szI,szA) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ - "shl $4, %1 \n" \ - "fclex \n" \ - #op #szA " (%2, %%eax) \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (store_to), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD_EA(op,szI,szA) \ - __asm__ volatile ( \ - "movl $128, %%eax \n" \ - #op #szA " (%0, %%eax) \n" \ - : \ - : "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); -#else -#define FPUD_LOAD_EA(op,szI,szA) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ - "fclex \n" \ - #op #szA " (%1, %%eax) \n" \ - "fnstsw %0 \n" \ - : "=m" (new_sw) \ - : "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_STORE(op,szI,szA) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "shll $4, %1 \n" \ - "fldcw %3 \n" \ - "movl $128, %%eax \n" \ - "fldt (%2, %1) \n" \ - #op #szA " (%2, %%eax) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "eax", "memory" \ - ); -#else -#define FPUD_STORE(op,szI,szA) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "movl $8, %%eax \n" \ - "shl $4, %%eax \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ - #op #szA " (%3, %%eax) \n" \ - "fnstsw %0 \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsin,fcos,f2xm1,fchs,fabs -#define FPUD_TRIG(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fsincos -#define FPUD_SINCOS() \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ - clx" \n" \ - "fsincos \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - "movw %0, %%ax \n" \ - "sahf \n" \ - "jp argument_too_large1 \n" \ - "fstpt (%2, %1) \n" \ - "argument_too_large1: " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "cc", "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fptan -#define FPUD_PTAN() \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ - clx" \n" \ - "fptan \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - "movw %0, %%ax \n" \ - "sahf \n" \ - "jp argument_too_large2 \n" \ - "fstpt (%2, %1) \n" \ - "argument_too_large2: " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "cc", "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fxtract -#ifdef WEAK_EXCEPTIONS -#define FPUD_XTRACT \ - __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "shll $4, %0 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%1, %0) \n" \ - "fxtract \n" \ - "fstpt (%1, %%eax) \n" \ - "fstpt (%1, %0) " \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - FPU_PREP_PUSH(); -#else -#define FPUD_XTRACT \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "shll $4, %1 \n" \ - "decl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "fldt (%2, %1) \n" \ - "fclex \n" \ - "fxtract \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - "fstpt (%2, %1) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_PREP_PUSH(); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ - #op" \n" \ - "fstpt (%3, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else -#define FPUD_ARITH1(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %5 \n" \ - "shll $4, %3 \n" \ - "shll $4, %2 \n" \ - "fldt (%4, %3) \n" \ - "fldt (%4, %2) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%4, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1_EA(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - #op" \n" \ - "fstpt (%2, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else -#define FPUD_ARITH1_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsqrt,frndint -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH2(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - #op" \n" \ - "fstpt (%2, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ - #op" \n" \ - "fstpt (%3, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else -#define FPUD_ARITH3(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %5 \n" \ - "shll $4, %3 \n" \ - "shll $4, %2 \n" \ - "fldt (%4, %3) \n" \ - "fldt (%4, %2) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%4, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH3_EA(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - #op" \n" \ - "fstpt (%2, %1) \n" \ - "fldcw %0 " \ - : "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); -#else -#define FPUD_ARITH3_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "shll $4, %2 \n" \ - "fldt (%3, %2) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%3, %2) \n" \ - "fldcw %1 " \ - : "=m" (new_sw), "=m" (save_cw) \ - : "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -// handles fprem,fprem1,fscale -#define FPUD_REMINDER(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %1) \n" \ - "fstp %%st(0) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "shll $4, %2 \n" \ - "shll $4, %1 \n" \ - "fldt (%3, %2) \n" \ - "fldt (%3, %1) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 " \ - : "=m" (new_sw) \ - : "r" (op1), "r" (op2), "r" (fpu.p_regs) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE_EA(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 " \ - : "=m" (new_sw) \ - : "r" (op1), "r" (fpu.p_regs) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fxam,ftst -#define FPUD_EXAMINE(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "shll $4, %1 \n" \ - "fldt (%2, %1) \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstp %%st(0) " \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fpatan,fyl2xp1 -#ifdef WEAK_EXCEPTIONS -#define FPUD_WITH_POP(op) \ - __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %0 \n" \ - "fldt (%1, %%eax) \n" \ - "fldt (%1, %0) \n" \ - #op" \n" \ - "fstpt (%1, %%eax) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - FPU_FPOP(); -#else -#define FPUD_WITH_POP(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// handles fyl2x -#ifdef WEAK_EXCEPTIONS -#define FPUD_FYL2X(op) \ - __asm__ volatile ( \ - "movl %0, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %0 \n" \ - "fldt (%1, %%eax) \n" \ - "fldt (%1, %0) \n" \ - #op" \n" \ - "fstpt (%1, %%eax) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - FPU_FPOP(); -#else -#define FPUD_FYL2X(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "movl %1, %%eax \n" \ - "incl %%eax \n" \ - "andl $7, %%eax \n" \ - "shll $4, %%eax \n" \ - "shll $4, %1 \n" \ - "fldt (%2, %%eax) \n" \ - "fldt (%2, %1) \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt (%2, %%eax) \n" \ - : "=m" (new_sw) \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "eax", "memory" \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// load math constants -#define FPUD_LOAD_CONST(op) \ - FPU_PREP_PUSH(); \ - __asm__ volatile ( \ - "shll $4, %0 \n" \ - clx" \n" \ - #op" \n" \ - "fstpt (%1, %0) \n" \ - : \ - : "r" (TOP), "r" (fpu.p_regs) \ - : "memory" \ - ); - -#endif - -#ifdef WEAK_EXCEPTIONS -const Bit16u exc_mask=0x7f00; -#else -const Bit16u exc_mask=0xffbf; -#endif - -static void FPU_FINIT(void) { - FPU_SetCW(0x37F); - fpu.sw=0; - TOP=FPU_GET_TOP(); - fpu.tags[0]=TAG_Empty; - fpu.tags[1]=TAG_Empty; - fpu.tags[2]=TAG_Empty; - fpu.tags[3]=TAG_Empty; - fpu.tags[4]=TAG_Empty; - fpu.tags[5]=TAG_Empty; - fpu.tags[6]=TAG_Empty; - fpu.tags[7]=TAG_Empty; - fpu.tags[8]=TAG_Valid; // is only used by us -} - -static void FPU_FCLEX(void){ - fpu.sw&=0x7f00; //should clear exceptions -} - -static void FPU_FNOP(void){ -} - -static void FPU_PREP_PUSH(void){ - TOP = (TOP - 1) &7; - fpu.tags[TOP]=TAG_Valid; -} - -static void FPU_FPOP(void){ - fpu.tags[TOP]=TAG_Empty; - TOP = ((TOP+1)&7); -} - -static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD(fld,DWORD,s) -} - -static void FPU_FLD_F32_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD_EA(fld,DWORD,s) -} - -static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD(fld,QWORD,l) -} - -static void FPU_FLD_F64_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD_EA(fld,QWORD,l) -} - -static void FPU_FLD_F80(PhysPt addr) { - fpu.p_regs[TOP].m1 = mem_readd(addr); - fpu.p_regs[TOP].m2 = mem_readd(addr+4); - fpu.p_regs[TOP].m3 = mem_readw(addr+8); - FPU_SET_C1(0); -} - -static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD(fild,WORD,) -} - -static void FPU_FLD_I16_EA(PhysPt addr) { - fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD_EA(fild,WORD,) -} - -static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD(fild,DWORD,l) -} - -static void FPU_FLD_I32_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD_EA(fild,DWORD,l) -} - -static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD(fild,QWORD,q) -} - -static void FPU_FBLD(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - fpu.p_regs[8].m3 = mem_readw(addr+8); - FPUD_LOAD(fbld,TBYTE,) -} - -static void FPU_FST_F32(PhysPt addr) { - FPUD_STORE(fstp,DWORD,s) - mem_writed(addr,fpu.p_regs[8].m1); -} - -static void FPU_FST_F64(PhysPt addr) { - FPUD_STORE(fstp,QWORD,l) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); -} - -static void FPU_FST_F80(PhysPt addr) { - mem_writed(addr,fpu.p_regs[TOP].m1); - mem_writed(addr+4,fpu.p_regs[TOP].m2); - mem_writew(addr+8,fpu.p_regs[TOP].m3); - FPU_SET_C1(0); -} - -static void FPU_FST_I16(PhysPt addr) { - FPUD_STORE(fistp,WORD,) - mem_writew(addr,(Bit16u)fpu.p_regs[8].m1); -} - -static void FPU_FST_I32(PhysPt addr) { - FPUD_STORE(fistp,DWORD,l) - mem_writed(addr,fpu.p_regs[8].m1); -} - -static void FPU_FST_I64(PhysPt addr) { - FPUD_STORE(fistp,QWORD,q) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); -} - -static void FPU_FBST(PhysPt addr) { - FPUD_STORE(fbstp,TBYTE,) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); - mem_writew(addr+8,fpu.p_regs[8].m3); -} - - -static void FPU_FSIN(void){ - FPUD_TRIG(fsin) -} - -static void FPU_FSINCOS(void){ - FPUD_SINCOS() -} - -static void FPU_FCOS(void){ - FPUD_TRIG(fcos) -} - -static void FPU_FSQRT(void){ - FPUD_ARITH2(fsqrt) -} - -static void FPU_FPATAN(void){ - FPUD_WITH_POP(fpatan) -} - -static void FPU_FPTAN(void){ - FPUD_PTAN() -} - - -static void FPU_FADD(Bitu op1, Bitu op2){ - FPUD_ARITH1(faddp) -} - -static void FPU_FADD_EA(Bitu op1){ - FPUD_ARITH1_EA(faddp) -} - -static void FPU_FDIV(Bitu op1, Bitu op2){ - FPUD_ARITH3(fdivp) -} - -static void FPU_FDIV_EA(Bitu op1){ - FPUD_ARITH3_EA(fdivp) -} - -static void FPU_FDIVR(Bitu op1, Bitu op2){ - FPUD_ARITH3(fdivrp) -} - -static void FPU_FDIVR_EA(Bitu op1){ - FPUD_ARITH3_EA(fdivrp) -} - -static void FPU_FMUL(Bitu op1, Bitu op2){ - FPUD_ARITH1(fmulp) -} - -static void FPU_FMUL_EA(Bitu op1){ - FPUD_ARITH1_EA(fmulp) -} - -static void FPU_FSUB(Bitu op1, Bitu op2){ - FPUD_ARITH1(fsubp) -} - -static void FPU_FSUB_EA(Bitu op1){ - FPUD_ARITH1_EA(fsubp) -} - -static void FPU_FSUBR(Bitu op1, Bitu op2){ - FPUD_ARITH1(fsubrp) -} - -static void FPU_FSUBR_EA(Bitu op1){ - FPUD_ARITH1_EA(fsubrp) -} - -static void FPU_FXCH(Bitu stv, Bitu other){ - FPU_Tag tag = fpu.tags[other]; - fpu.tags[other] = fpu.tags[stv]; - fpu.tags[stv] = tag; - - Bit32u m1s = fpu.p_regs[other].m1; - Bit32u m2s = fpu.p_regs[other].m2; - Bit16u m3s = fpu.p_regs[other].m3; - fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; - fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; - fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; - fpu.p_regs[stv].m1 = m1s; - fpu.p_regs[stv].m2 = m2s; - fpu.p_regs[stv].m3 = m3s; - - FPU_SET_C1(0); -} - -static void FPU_FST(Bitu stv, Bitu other){ - fpu.tags[other] = fpu.tags[stv]; - - fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; - fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; - fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; - - FPU_SET_C1(0); -} - - -static void FPU_FCOM(Bitu op1, Bitu op2){ - FPUD_COMPARE(fcompp) -} - -static void FPU_FCOM_EA(Bitu op1){ - FPUD_COMPARE_EA(fcompp) -} - -static void FPU_FUCOM(Bitu op1, Bitu op2){ - FPUD_COMPARE(fucompp) -} - -static void FPU_FRNDINT(void){ - FPUD_ARITH2(frndint) -} - -static void FPU_FPREM(void){ - FPUD_REMINDER(fprem) -} - -static void FPU_FPREM1(void){ - FPUD_REMINDER(fprem1) -} - -static void FPU_FXAM(void){ - FPUD_EXAMINE(fxam) - // handle empty registers (C1 set to sign in any way!) - if(fpu.tags[TOP] == TAG_Empty) { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); - return; - } -} - -static void FPU_F2XM1(void){ - FPUD_TRIG(f2xm1) -} - -static void FPU_FYL2X(void){ - FPUD_FYL2X(fyl2x) -} - -static void FPU_FYL2XP1(void){ - FPUD_WITH_POP(fyl2xp1) -} - -static void FPU_FSCALE(void){ - FPUD_REMINDER(fscale) -} - - -static void FPU_FSTENV(PhysPt addr){ - FPU_SET_TOP(TOP); - if(!cpu.code.big) { - mem_writew(addr+0,static_cast(fpu.cw)); - mem_writew(addr+2,static_cast(fpu.sw)); - mem_writew(addr+4,static_cast(FPU_GetTag())); - } else { - mem_writed(addr+0,static_cast(fpu.cw)); - mem_writed(addr+4,static_cast(fpu.sw)); - mem_writed(addr+8,static_cast(FPU_GetTag())); - } -} - -static void FPU_FLDENV(PhysPt addr){ - Bit16u tag; - Bit32u tagbig; - Bitu cw; - if(!cpu.code.big) { - cw = mem_readw(addr+0); - fpu.sw = mem_readw(addr+2); - tag = mem_readw(addr+4); - } else { - cw = mem_readd(addr+0); - fpu.sw = (Bit16u)mem_readd(addr+4); - tagbig = mem_readd(addr+8); - tag = static_cast(tagbig); - } - FPU_SetTag(tag); - FPU_SetCW(cw); - TOP=FPU_GET_TOP(); -} - -static void FPU_FSAVE(PhysPt addr){ - FPU_FSTENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - mem_writed(addr+start,fpu.p_regs[STV(i)].m1); - mem_writed(addr+start+4,fpu.p_regs[STV(i)].m2); - mem_writew(addr+start+8,fpu.p_regs[STV(i)].m3); - start+=10; - } - FPU_FINIT(); -} - -static void FPU_FRSTOR(PhysPt addr){ - FPU_FLDENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - fpu.p_regs[STV(i)].m1 = mem_readd(addr+start); - fpu.p_regs[STV(i)].m2 = mem_readd(addr+start+4); - fpu.p_regs[STV(i)].m3 = mem_readw(addr+start+8); - start+=10; - } -} - - -static void FPU_FXTRACT(void) { - FPUD_XTRACT -} - -static void FPU_FCHS(void){ - FPUD_TRIG(fchs) -} - -static void FPU_FABS(void){ - FPUD_TRIG(fabs) -} - -static void FPU_FTST(void){ - FPUD_EXAMINE(ftst) -} - -static void FPU_FLD1(void){ - FPUD_LOAD_CONST(fld1) -} - -static void FPU_FLDL2T(void){ - FPUD_LOAD_CONST(fldl2t) -} - -static void FPU_FLDL2E(void){ - FPUD_LOAD_CONST(fldl2e) -} - -static void FPU_FLDPI(void){ - FPUD_LOAD_CONST(fldpi) -} - -static void FPU_FLDLG2(void){ - FPUD_LOAD_CONST(fldlg2) -} - -static void FPU_FLDLN2(void){ - FPUD_LOAD_CONST(fldln2) -} - -static void FPU_FLDZ(void){ - FPUD_LOAD_CONST(fldz) - fpu.tags[TOP]=TAG_Zero; -} diff --git a/dosbox/inout.h b/dosbox/inout.h deleted file mode 100644 index 798e9db9..00000000 --- a/dosbox/inout.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: inout.h,v 1.13 2009-05-27 09:15:41 qbix79 Exp $ */ - -#ifndef DOSBOX_INOUT_H -#define DOSBOX_INOUT_H - -#define IO_MAX (64*1024+3) - -#define IO_MB 0x1 -#define IO_MW 0x2 -#define IO_MD 0x4 -#define IO_MA (IO_MB | IO_MW | IO_MD ) - -typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen); -typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen); - -extern IO_WriteHandler * io_writehandlers[3][IO_MAX]; -extern IO_ReadHandler * io_readhandlers[3][IO_MAX]; - -void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1); -void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1); - -void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=1); -void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=1); - -void IO_WriteB(Bitu port,Bitu val); -void IO_WriteW(Bitu port,Bitu val); -void IO_WriteD(Bitu port,Bitu val); - -Bitu IO_ReadB(Bitu port); -Bitu IO_ReadW(Bitu port); -Bitu IO_ReadD(Bitu port); - -/* Classes to manage the IO objects created by the various devices. - * The io objects will remove itself on destruction.*/ -class IO_Base{ -protected: - bool installed; - Bitu m_port, m_mask,m_range; -public: - IO_Base():installed(false){}; -}; -class IO_ReadHandleObject: private IO_Base{ -public: - void Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1); - ~IO_ReadHandleObject(); -}; -class IO_WriteHandleObject: private IO_Base{ -public: - void Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1); - ~IO_WriteHandleObject(); -}; - -static INLINE void IO_Write(Bitu port,Bit8u val) { - IO_WriteB(port,val); -} -static INLINE Bit8u IO_Read(Bitu port){ - return (Bit8u)IO_ReadB(port); -} - -#endif diff --git a/dosbox/instructions.h b/dosbox/instructions.h deleted file mode 100644 index 1696997c..00000000 --- a/dosbox/instructions.h +++ /dev/null @@ -1,963 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Jumps */ - -/* All Byte general instructions */ -#define ADDB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b+lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ADDb; - -#define ADCB(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \ - save(op1,lf_resb); \ - lflags.type=t_ADCb; - -#define SBBB(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \ - save(op1,lf_resb); \ - lflags.type=t_SBBb; - -#define SUBB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SUBb; - -#define ORB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b | lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ORb; - -#define XORB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b ^ lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_XORb; - -#define ANDB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b & lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ANDb; - -#define CMPB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-lf_var2b; \ - lflags.type=t_CMPb; - -#define TESTB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b & lf_var2b; \ - lflags.type=t_TESTb; - -/* All Word General instructions */ - -#define ADDW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w+lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ADDw; - -#define ADCW(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \ - save(op1,lf_resw); \ - lflags.type=t_ADCw; - -#define SBBW(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \ - save(op1,lf_resw); \ - lflags.type=t_SBBw; - -#define SUBW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_SUBw; - -#define ORW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w | lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ORw; - -#define XORW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w ^ lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_XORw; - -#define ANDW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w & lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ANDw; - -#define CMPW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-lf_var2w; \ - lflags.type=t_CMPw; - -#define TESTW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w & lf_var2w; \ - lflags.type=t_TESTw; - -/* All DWORD General Instructions */ - -#define ADDD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d+lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ADDd; - -#define ADCD(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \ - save(op1,lf_resd); \ - lflags.type=t_ADCd; - -#define SBBD(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \ - save(op1,lf_resd); \ - lflags.type=t_SBBd; - -#define SUBD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_SUBd; - -#define ORD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d | lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ORd; - -#define XORD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d ^ lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_XORd; - -#define ANDD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d & lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ANDd; - -#define CMPD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-lf_var2d; \ - lflags.type=t_CMPd; - - -#define TESTD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d & lf_var2d; \ - lflags.type=t_TESTd; - - - - -#define INCB(op1,load,save) \ - LoadCF;lf_var1b=load(op1); \ - lf_resb=lf_var1b+1; \ - save(op1,lf_resb); \ - lflags.type=t_INCb; \ - -#define INCW(op1,load,save) \ - LoadCF;lf_var1w=load(op1); \ - lf_resw=lf_var1w+1; \ - save(op1,lf_resw); \ - lflags.type=t_INCw; - -#define INCD(op1,load,save) \ - LoadCF;lf_var1d=load(op1); \ - lf_resd=lf_var1d+1; \ - save(op1,lf_resd); \ - lflags.type=t_INCd; - -#define DECB(op1,load,save) \ - LoadCF;lf_var1b=load(op1); \ - lf_resb=lf_var1b-1; \ - save(op1,lf_resb); \ - lflags.type=t_DECb; - -#define DECW(op1,load,save) \ - LoadCF;lf_var1w=load(op1); \ - lf_resw=lf_var1w-1; \ - save(op1,lf_resw); \ - lflags.type=t_DECw; - -#define DECD(op1,load,save) \ - LoadCF;lf_var1d=load(op1); \ - lf_resd=lf_var1d-1; \ - save(op1,lf_resd); \ - lflags.type=t_DECd; - - - -#define ROLB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (lf_var1b >> (8-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,lf_resb & 1); \ - SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); - -#define ROLW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1w=load(op1); \ - lf_var2b=op2&0xf; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (lf_var1w >> (16-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,lf_resw & 1); \ - SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); - -#define ROLD(op1,op2,load,save) \ - if (!op2) break; \ - FillFlagsNoCFOF(); \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d << lf_var2b) | \ - (lf_var1d >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,lf_resd & 1); \ - SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); - - -#define RORB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>7); \ - SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (lf_var1b << (8-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,lf_resb & 0x80); \ - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); - -#define RORW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>15); \ - SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1w=load(op1); \ - lf_var2b=op2&0xf; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (lf_var1w << (16-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,lf_resw & 0x8000); \ - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); - -#define RORD(op1,op2,load,save) \ - if (!op2) break; \ - FillFlagsNoCFOF(); \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (lf_var1d << (32-lf_var2b)); \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,lf_resd & 0x80000000); \ - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); - - -#define RCLB(op1,op2,load,save) \ - if (!(op2%9)) break; \ -{ Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1b >> (9-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); \ -} - -#define RCLW(op1,op2,load,save) \ - if (!(op2%17)) break; \ -{ Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1w >> (17-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); \ -} - -#define RCLD(op1,op2,load,save) \ - if (!op2) break; \ -{ Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - if (lf_var2b==1) { \ - lf_resd=(lf_var1d << 1) | cf; \ - } else { \ - lf_resd=(lf_var1d << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1d >> (33-lf_var2b)); \ - } \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ -} - - - -#define RCRB(op1,op2,load,save) \ - if (op2%9) { \ - Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (cf << (8-lf_var2b)) | \ - (lf_var1b << (9-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); \ - } - -#define RCRW(op1,op2,load,save) \ - if (op2%17) { \ - Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (cf << (16-lf_var2b)) | \ - (lf_var1w << (17-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); \ - } - -#define RCRD(op1,op2,load,save) \ - if (op2) { \ - Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - if (lf_var2b==1) { \ - lf_resd=lf_var1d >> 1 | cf << 31; \ - } else { \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (cf << (32-lf_var2b)) | \ - (lf_var1d << (33-lf_var2b)); \ - } \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); \ - } - - -#define SHLB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b << lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SHLb; - -#define SHLW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2 ; \ - lf_resw=lf_var1w << lf_var2b; \ - save(op1,lf_resw); \ - lflags.type=t_SHLw; - -#define SHLD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1d=load(op1);lf_var2b=op2; \ - lf_resd=lf_var1d << lf_var2b; \ - save(op1,lf_resd); \ - lflags.type=t_SHLd; - - -#define SHRB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b >> lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SHRb; - -#define SHRW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2; \ - lf_resw=lf_var1w >> lf_var2b; \ - save(op1,lf_resw); \ - lflags.type=t_SHRw; - -#define SHRD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1d=load(op1);lf_var2b=op2; \ - lf_resd=lf_var1d >> lf_var2b; \ - save(op1,lf_resd); \ - lflags.type=t_SHRd; - - -#define SARB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - if (lf_var2b>8) lf_var2b=8; \ - if (lf_var1b & 0x80) { \ - lf_resb=(lf_var1b >> lf_var2b)| \ - (0xff << (8 - lf_var2b)); \ - } else { \ - lf_resb=lf_var1b >> lf_var2b; \ - } \ - save(op1,lf_resb); \ - lflags.type=t_SARb; - -#define SARW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2; \ - if (lf_var2b>16) lf_var2b=16; \ - if (lf_var1w & 0x8000) { \ - lf_resw=(lf_var1w >> lf_var2b)| \ - (0xffff << (16 - lf_var2b)); \ - } else { \ - lf_resw=lf_var1w >> lf_var2b; \ - } \ - save(op1,lf_resw); \ - lflags.type=t_SARw; - -#define SARD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var2b=op2;lf_var1d=load(op1); \ - if (lf_var1d & 0x80000000) { \ - lf_resd=(lf_var1d >> lf_var2b)| \ - (0xffffffff << (32 - lf_var2b)); \ - } else { \ - lf_resd=lf_var1d >> lf_var2b; \ - } \ - save(op1,lf_resd); \ - lflags.type=t_SARd; - - - -#define DAA() \ - if (((reg_al & 0x0F)>0x09) || get_AF()) { \ - if ((reg_al > 0x99) || get_CF()) { \ - reg_al+=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - reg_al+=0x06; \ - SETFLAGBIT(AF,true); \ - } else { \ - if ((reg_al > 0x99) || get_CF()) { \ - reg_al+=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(SF,(reg_al&0x80)); \ - SETFLAGBIT(ZF,(reg_al==0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; - - -#define DAS() \ -{ \ - Bit8u osigned=reg_al & 0x80; \ - if (((reg_al & 0x0f) > 9) || get_AF()) { \ - if ((reg_al>0x99) || get_CF()) { \ - reg_al-=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,(reg_al<=0x05)); \ - } \ - reg_al-=6; \ - SETFLAGBIT(AF,true); \ - } else { \ - if ((reg_al>0x99) || get_CF()) { \ - reg_al-=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0)); \ - SETFLAGBIT(SF,(reg_al&0x80)); \ - SETFLAGBIT(ZF,(reg_al==0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; \ -} - - -#define AAA() \ - SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9))); \ - if ((reg_al & 0xf) > 9) { \ - SETFLAGBIT(OF,(reg_al&0xf0)==0x70); \ - reg_ax += 0x106; \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(AF,true); \ - } else if (get_AF()) { \ - reg_ax += 0x106; \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(ZF,false); \ - SETFLAGBIT(AF,true); \ - } else { \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; - -#define AAS() \ - if ((reg_al & 0x0f)>9) { \ - SETFLAGBIT(SF,(reg_al>0x85)); \ - reg_ax -= 0x106; \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(AF,true); \ - } else if (get_AF()) { \ - SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85))); \ - SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85)); \ - reg_ax -= 0x106; \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(AF,true); \ - } else { \ - SETFLAGBIT(SF,(reg_al>=0x80)); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; - -#define AAM(op1) \ -{ \ - Bit8u dv=op1; \ - if (dv!=0) { \ - reg_ah=reg_al / dv; \ - reg_al=reg_al % dv; \ - SETFLAGBIT(SF,(reg_al & 0x80)); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(AF,false); \ - lflags.type=t_UNKNOWN; \ - } else EXCEPTION(0); \ -} - - -//Took this from bochs, i seriously hate these weird bcd opcodes -#define AAD(op1) \ - { \ - Bit16u ax1 = reg_ah * op1; \ - Bit16u ax2 = ax1 + reg_al; \ - reg_al = (Bit8u) ax2; \ - reg_ah = 0; \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(AF,false); \ - SETFLAGBIT(SF,reg_al >= 0x80); \ - SETFLAGBIT(ZF,reg_al == 0); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; \ - } - -#define MULB(op1,load,save) \ - reg_ax=reg_al*load(op1); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_al == 0); \ - if (reg_ax & 0xff00) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } - -#define MULW(op1,load,save) \ -{ \ - Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ - reg_ax=(Bit16u)(tempu); \ - reg_dx=(Bit16u)(tempu >> 16); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_ax == 0); \ - if (reg_dx) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } \ -} - -#define MULD(op1,load,save) \ -{ \ - Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ - reg_eax=(Bit32u)(tempu); \ - reg_edx=(Bit32u)(tempu >> 32); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_eax == 0); \ - if (reg_edx) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } \ -} - -#define DIVB(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bitu quo=reg_ax / val; \ - Bit8u rem=(Bit8u)(reg_ax % val); \ - Bit8u quo8=(Bit8u)(quo&0xff); \ - if (quo>0xff) EXCEPTION(0); \ - reg_ah=rem; \ - reg_al=quo8; \ -} - - -#define DIVW(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bitu num=((Bit32u)reg_dx<<16)|reg_ax; \ - Bitu quo=num/val; \ - Bit16u rem=(Bit16u)(num % val); \ - Bit16u quo16=(Bit16u)(quo&0xffff); \ - if (quo!=(Bit32u)quo16) EXCEPTION(0); \ - reg_dx=rem; \ - reg_ax=quo16; \ -} - -#define DIVD(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ - Bit64u quo=num/val; \ - Bit32u rem=(Bit32u)(num % val); \ - Bit32u quo32=(Bit32u)(quo&0xffffffff); \ - if (quo!=(Bit64u)quo32) EXCEPTION(0); \ - reg_edx=rem; \ - reg_eax=quo32; \ -} - - -#define IDIVB(op1,load,save) \ -{ \ - Bits val=(Bit8s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bits quo=((Bit16s)reg_ax) / val; \ - Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); \ - Bit8s quo8s=(Bit8s)(quo&0xff); \ - if (quo!=(Bit16s)quo8s) EXCEPTION(0); \ - reg_ah=rem; \ - reg_al=quo8s; \ -} - - -#define IDIVW(op1,load,save) \ -{ \ - Bits val=(Bit16s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \ - Bits quo=num/val; \ - Bit16s rem=(Bit16s)(num % val); \ - Bit16s quo16s=(Bit16s)quo; \ - if (quo!=(Bit32s)quo16s) EXCEPTION(0); \ - reg_dx=rem; \ - reg_ax=quo16s; \ -} - -#define IDIVD(op1,load,save) \ -{ \ - Bits val=(Bit32s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \ - Bit64s quo=num/val; \ - Bit32s rem=(Bit32s)(num % val); \ - Bit32s quo32s=(Bit32s)(quo&0xffffffff); \ - if (quo!=(Bit64s)quo32s) EXCEPTION(0); \ - reg_edx=rem; \ - reg_eax=quo32s; \ -} - -#define IMULB(op1,load,save) \ -{ \ - reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ - FillFlagsNoCFOF(); \ - if ((reg_ax & 0xff80)==0xff80 || \ - (reg_ax & 0xff80)==0x0000) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - - -#define IMULW(op1,load,save) \ -{ \ - Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ - reg_ax=(Bit16s)(temps); \ - reg_dx=(Bit16s)(temps >> 16); \ - FillFlagsNoCFOF(); \ - if (((temps & 0xffff8000)==0xffff8000 || \ - (temps & 0xffff8000)==0x0000)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define IMULD(op1,load,save) \ -{ \ - Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ - ((Bit64s)((Bit32s)(load(op1)))); \ - reg_eax=(Bit32u)(temps); \ - reg_edx=(Bit32u)(temps >> 32); \ - FillFlagsNoCFOF(); \ - if ((reg_edx==0xffffffff) && \ - (reg_eax & 0x80000000) ) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else if ( (reg_edx==0x00000000) && \ - (reg_eax< 0x80000000) ) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define DIMULW(op1,op2,op3,load,save) \ -{ \ - Bits res=((Bit16s)op2) * ((Bit16s)op3); \ - save(op1,res & 0xffff); \ - FillFlagsNoCFOF(); \ - if ((res> -32768) && (res<32767)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define DIMULD(op1,op2,op3,load,save) \ -{ \ - Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ - save(op1,(Bit32s)res); \ - FillFlagsNoCFOF(); \ - if ((res>-((Bit64s)(2147483647)+1)) && \ - (res<(Bit64s)2147483647)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define GRP2B(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArb; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ - case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break; \ - case 0x07:SARB(*earb,val,LoadRb,SaveRb);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ - case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break; \ - case 0x07:SARB(eaa,val,LoadMb,SaveMb);break; \ - } \ - } \ -} - - - -#define GRP2W(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArw; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ - case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break; \ - case 0x07:SARW(*earw,val,LoadRw,SaveRw);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ - case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break; \ - case 0x07:SARW(eaa,val,LoadMw,SaveMw);break; \ - } \ - } \ -} - - -#define GRP2D(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArd; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ - case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break; \ - case 0x07:SARD(*eard,val,LoadRd,SaveRd);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \ - case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break; \ - case 0x07:SARD(eaa,val,LoadMd,SaveMd);break; \ - } \ - } \ -} - -/* let's hope bochs has it correct with the higher than 16 shifts */ -/* double-precision shift left has low bits in second argument */ -#define DSHLW(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \ - Bit32u tempd=lf_var1d << lf_var2b; \ - if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \ - lf_resw=(Bit16u)(tempd >> 16); \ - save(op1,lf_resw); \ - lflags.type=t_DSHLw; - -#define DSHLD(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=load(op1); \ - lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_DSHLd; - -/* double-precision shift right has high bits in second argument */ -#define DSHRW(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \ - Bit32u tempd=lf_var1d >> lf_var2b; \ - if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); \ - lf_resw=(Bit16u)(tempd); \ - save(op1,lf_resw); \ - lflags.type=t_DSHRw; - -#define DSHRD(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=load(op1); \ - lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_DSHRd; - -#define BSWAPW(op1) \ - op1 = 0; - -#define BSWAPD(op1) \ - op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); diff --git a/dosbox/keyboard.cpp b/dosbox/keyboard.cpp deleted file mode 100644 index c857cddd..00000000 --- a/dosbox/keyboard.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: keyboard.cpp,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include "dosbox.h" -#include "keyboard.h" -#include "inout.h" -#include "pic.h" -#include "mem.h" -#include "setup.h" -//#include "mixer.h" -//#include "timer.h" - -extern void write_log(const char*,...); - -#define KEYBUFSIZE 32 -#define KEYDELAY 0.300f //Considering 20-30 khz serial clock and 11 bits/char - -enum KeyCommands { - CMD_NONE, - CMD_SETLEDS, - CMD_SETTYPERATE, - CMD_SETOUTPORT, - CMD_JUMPERS -}; - -static struct { - Bit8u buffer[KEYBUFSIZE]; - Bitu used; - Bitu pos; - struct { -// KBD_KEYS key; - Bitu wait; - Bitu pause,rate; - } repeat; - KeyCommands command; - Bit8u p60data; - bool p60changed; - bool active; - bool scanning; - bool scheduled; - Bit8u outport; -} keyb; - -extern void x86_doirq_keyboard(void); - -bool x86_is_keyboard(void) -{ - return keyb.p60changed; -} - -static void KEYBOARD_SetPort60(Bit8u val) { - keyb.p60changed=true; - keyb.p60data=val; -// if (machine==MCH_PCJR) -// PIC_ActivateIRQ(6); -// else -// PIC_ActivateIRQ(1); - x86_doirq_keyboard(); -} - -static void KEYBOARD_TransferBuffer(Bitu val) { - keyb.scheduled=false; - if (!keyb.used) { - LOG(LOG_KEYBOARD,LOG_NORMAL)("Transfer started with empty buffer"); - return; - } - KEYBOARD_SetPort60(keyb.buffer[keyb.pos]); - if (++keyb.pos>=KEYBUFSIZE) keyb.pos-=KEYBUFSIZE; - keyb.used--; -} - - -void KEYBOARD_ClrBuffer(void) { - keyb.used=0; - keyb.pos=0; -// PIC_RemoveEvents(KEYBOARD_TransferBuffer); - keyb.scheduled=false; -} - -void KEYBOARD_AddBuffer(Bit8u data) { - if (keyb.used>=KEYBUFSIZE) { - LOG(LOG_KEYBOARD,LOG_NORMAL)("Buffer full, dropping code"); - return; - } - Bitu start=keyb.pos+keyb.used; - if (start>=KEYBUFSIZE) start-=KEYBUFSIZE; - keyb.buffer[start]=data; - keyb.used++; - /* Start up an event to start the first IRQ */ - if (!keyb.scheduled && !keyb.p60changed) { - keyb.scheduled=true; - KEYBOARD_TransferBuffer(0); -// PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); - } -} - - -static Bitu read_p60(Bitu port,Bitu iolen) { - keyb.p60changed=false; - if (!keyb.scheduled && keyb.used) { - keyb.scheduled=true; - KEYBOARD_TransferBuffer(0); -// PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); - } - return keyb.p60data; -} - -void x86_init_reset(void); -uint8_t x86_get_jumpers(void); - -static void write_p60(Bitu port,Bitu val,Bitu iolen) { - switch (keyb.command) { - case CMD_NONE: /* None */ - /* No active command this would normally get sent to the keyboard then */ - KEYBOARD_ClrBuffer(); - switch (val) { - case 0xed: /* Set Leds */ - keyb.command=CMD_SETLEDS; - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - case 0xee: /* Echo */ - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - case 0xf2: /* Identify keyboard */ - /* AT's just send acknowledge */ - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - case 0xf3: /* Typematic rate programming */ - keyb.command=CMD_SETTYPERATE; - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - case 0xf4: /* Enable keyboard,clear buffer, start scanning */ - LOG(LOG_KEYBOARD,LOG_NORMAL)("Clear buffer,enable Scaning"); - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - keyb.scanning=true; - break; - case 0xf5: /* Reset keyboard and disable scanning */ - LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, disable scanning"); - keyb.scanning=false; - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - case 0xf6: /* Reset keyboard and enable scanning */ - LOG(LOG_KEYBOARD,LOG_NORMAL)("Reset, enable scanning"); - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - keyb.scanning=false; - break; - case 0xff: - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - KEYBOARD_AddBuffer(0xaa); - break; - default: - /* Just always acknowledge strange commands */ - LOG(LOG_KEYBOARD,LOG_ERROR)("60:Unhandled command %X",val); - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - } - return; - case CMD_SETOUTPORT: - MEM_A20_Enable((val & 2)>0); - keyb.outport = val; - if (!(val & 1)) { - x86_init_reset(); - } - keyb.command = CMD_NONE; - break; - case CMD_SETTYPERATE: - { - static const int delay[] = { 250, 500, 750, 1000 }; - static const int repeat[] = - { 33,37,42,46,50,54,58,63,67,75,83,92,100, - 109,118,125,133,149,167,182,200,217,233, - 250,270,303,333,370,400,435,476,500 }; - keyb.repeat.pause = delay[(val>>5)&3]; - keyb.repeat.rate = repeat[val&0x1f]; - keyb.command=CMD_NONE; - } - /* Fallthrough! as setleds does what we want */ - case CMD_SETLEDS: - keyb.command=CMD_NONE; - KEYBOARD_ClrBuffer(); - KEYBOARD_AddBuffer(0xfa); /* Acknowledge */ - break; - } -} - -static Bit8u port_61_data = 0; -static Bitu read_p61(Bitu port,Bitu iolen) { - port_61_data^=0x20; - port_61_data^=0x10; - return port_61_data; -} - -extern void TIMER_SetGate2(bool); -static void write_p61(Bitu port,Bitu val,Bitu iolen) { - if ((port_61_data ^ val) & 3) { - if((port_61_data ^ val) & 1) - TIMER_SetGate2(val&0x1); -// PCSPEAKER_SetType(val & 3); - } - port_61_data = val; -} - -static void write_p64(Bitu port,Bitu val,Bitu iolen) { - switch (val) { - case 0xae: /* Activate keyboard */ - keyb.active=true; - if (keyb.used && !keyb.scheduled && !keyb.p60changed) { - keyb.scheduled=true; - KEYBOARD_TransferBuffer(0); - //PIC_AddEvent(KEYBOARD_TransferBuffer,KEYDELAY); - } - LOG(LOG_KEYBOARD,LOG_NORMAL)("Activated"); - break; - case 0xad: /* Deactivate keyboard */ - keyb.active=false; - LOG(LOG_KEYBOARD,LOG_NORMAL)("De-Activated"); - break; - case 0xc0: // read config jumpers - KEYBOARD_SetPort60(x86_get_jumpers()); - break; - case 0xd0: /* Outport on buffer */ - KEYBOARD_SetPort60(MEM_A20_Enabled() ? 0x02 : 0); - break; - case 0xd1: /* Write to outport */ - keyb.command=CMD_SETOUTPORT; - break; - case 0xaa: - KEYBOARD_SetPort60(0x55); - break; - case 0xe0: - // bit 0 = clock line state, 1 = data line state - KEYBOARD_SetPort60((keyb.outport & 30) ? 2 : 3); - break; - case 0xfe: // pulse reset pin - case 0xfc: - case 0xfa: - case 0xf8: - case 0xf6: - case 0xf4: - case 0xf2: - case 0xf0: - x86_init_reset(); - break; - default: - LOG(LOG_KEYBOARD,LOG_ERROR)("Port 64 write with val %d",val); - break; - } -} - -static Bitu read_p64(Bitu port,Bitu iolen) { - Bit8u status= (keyb.outport & 0x7c) | (keyb.p60changed ? 0x1 : 0x0); - return status; -} - -Bitu x86_in_keyboard(Bitu port) -{ - Bitu v = 0xff; - switch (port) { - case 0x60: - v = read_p60(port, 1); - break; - case 0x61: - v = read_p61(port, 1); - break; - case 0x64: - v = read_p64(port, 1); - break; - } - //write_log("read %02x %02x\n", port, v); - return v; -} - -void x86_out_keyboard(Bitu port, Bitu val) -{ - //write_log("write %02x %02x\n", port, val); - switch(port) - { - case 0x60: - write_p60(port, val, 1); - break; - case 0x61: - write_p61(port, val, 1); - break; - case 0x64: - write_p64(port, val, 1); - break; - } -} - -#if 0 -void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) { - Bit8u ret=0;bool extend=false; - switch (keytype) { - case KBD_esc:ret=1;break; - case KBD_1:ret=2;break; - case KBD_2:ret=3;break; - case KBD_3:ret=4;break; - case KBD_4:ret=5;break; - case KBD_5:ret=6;break; - case KBD_6:ret=7;break; - case KBD_7:ret=8;break; - case KBD_8:ret=9;break; - case KBD_9:ret=10;break; - case KBD_0:ret=11;break; - - case KBD_minus:ret=12;break; - case KBD_equals:ret=13;break; - case KBD_backspace:ret=14;break; - case KBD_tab:ret=15;break; - - case KBD_q:ret=16;break; - case KBD_w:ret=17;break; - case KBD_e:ret=18;break; - case KBD_r:ret=19;break; - case KBD_t:ret=20;break; - case KBD_y:ret=21;break; - case KBD_u:ret=22;break; - case KBD_i:ret=23;break; - case KBD_o:ret=24;break; - case KBD_p:ret=25;break; - - case KBD_leftbracket:ret=26;break; - case KBD_rightbracket:ret=27;break; - case KBD_enter:ret=28;break; - case KBD_leftctrl:ret=29;break; - - case KBD_a:ret=30;break; - case KBD_s:ret=31;break; - case KBD_d:ret=32;break; - case KBD_f:ret=33;break; - case KBD_g:ret=34;break; - case KBD_h:ret=35;break; - case KBD_j:ret=36;break; - case KBD_k:ret=37;break; - case KBD_l:ret=38;break; - - case KBD_semicolon:ret=39;break; - case KBD_quote:ret=40;break; - case KBD_grave:ret=41;break; - case KBD_leftshift:ret=42;break; - case KBD_backslash:ret=43;break; - case KBD_z:ret=44;break; - case KBD_x:ret=45;break; - case KBD_c:ret=46;break; - case KBD_v:ret=47;break; - case KBD_b:ret=48;break; - case KBD_n:ret=49;break; - case KBD_m:ret=50;break; - - case KBD_comma:ret=51;break; - case KBD_period:ret=52;break; - case KBD_slash:ret=53;break; - case KBD_rightshift:ret=54;break; - case KBD_kpmultiply:ret=55;break; - case KBD_leftalt:ret=56;break; - case KBD_space:ret=57;break; - case KBD_capslock:ret=58;break; - - case KBD_f1:ret=59;break; - case KBD_f2:ret=60;break; - case KBD_f3:ret=61;break; - case KBD_f4:ret=62;break; - case KBD_f5:ret=63;break; - case KBD_f6:ret=64;break; - case KBD_f7:ret=65;break; - case KBD_f8:ret=66;break; - case KBD_f9:ret=67;break; - case KBD_f10:ret=68;break; - - case KBD_numlock:ret=69;break; - case KBD_scrolllock:ret=70;break; - - case KBD_kp7:ret=71;break; - case KBD_kp8:ret=72;break; - case KBD_kp9:ret=73;break; - case KBD_kpminus:ret=74;break; - case KBD_kp4:ret=75;break; - case KBD_kp5:ret=76;break; - case KBD_kp6:ret=77;break; - case KBD_kpplus:ret=78;break; - case KBD_kp1:ret=79;break; - case KBD_kp2:ret=80;break; - case KBD_kp3:ret=81;break; - case KBD_kp0:ret=82;break; - case KBD_kpperiod:ret=83;break; - - case KBD_extra_lt_gt:ret=86;break; - case KBD_f11:ret=87;break; - case KBD_f12:ret=88;break; - - //The Extended keys - - case KBD_kpenter:extend=true;ret=28;break; - case KBD_rightctrl:extend=true;ret=29;break; - case KBD_kpdivide:extend=true;ret=53;break; - case KBD_rightalt:extend=true;ret=56;break; - case KBD_home:extend=true;ret=71;break; - case KBD_up:extend=true;ret=72;break; - case KBD_pageup:extend=true;ret=73;break; - case KBD_left:extend=true;ret=75;break; - case KBD_right:extend=true;ret=77;break; - case KBD_end:extend=true;ret=79;break; - case KBD_down:extend=true;ret=80;break; - case KBD_pagedown:extend=true;ret=81;break; - case KBD_insert:extend=true;ret=82;break; - case KBD_delete:extend=true;ret=83;break; - case KBD_pause: - KEYBOARD_AddBuffer(0xe1); - KEYBOARD_AddBuffer(29|(pressed?0:0x80)); - KEYBOARD_AddBuffer(69|(pressed?0:0x80)); - return; - case KBD_printscreen: - /* Not handled yet. But usuable in mapper for special events */ - return; - default: - E_Exit("Unsupported key press"); - break; - } - /* Add the actual key in the keyboard queue */ - if (pressed) { - if (keyb.repeat.key==keytype) keyb.repeat.wait=keyb.repeat.rate; - else keyb.repeat.wait=keyb.repeat.pause; - keyb.repeat.key=keytype; - } else { - keyb.repeat.key=KBD_NONE; - keyb.repeat.wait=0; - ret+=128; - } - if (extend) KEYBOARD_AddBuffer(0xe0); - KEYBOARD_AddBuffer(ret); -} - -static void KEYBOARD_TickHandler(void) { - if (keyb.repeat.wait) { - keyb.repeat.wait--; - if (!keyb.repeat.wait) KEYBOARD_AddKey(keyb.repeat.key,true); - } -} -#endif - -void KEYBOARD_Init(Section* sec) { -#if 0 - IO_RegisterWriteHandler(0x60,write_p60,IO_MB); - IO_RegisterReadHandler(0x60,read_p60,IO_MB); - IO_RegisterWriteHandler(0x61,write_p61,IO_MB); - IO_RegisterReadHandler(0x61,read_p61,IO_MB); - IO_RegisterWriteHandler(0x64,write_p64,IO_MB); - IO_RegisterReadHandler(0x64,read_p64,IO_MB); -#endif -// TIMER_AddTickHandler(&KEYBOARD_TickHandler); - write_p61(0,0,0); - /* Init the keyb struct */ - keyb.active=true; - keyb.scanning=true; - keyb.command=CMD_NONE; - keyb.p60changed=false; -// keyb.repeat.key=KBD_NONE; - keyb.repeat.pause=500; - keyb.repeat.rate=33; - keyb.repeat.wait=0; - KEYBOARD_ClrBuffer(); -} diff --git a/dosbox/lazyflags.h b/dosbox/lazyflags.h deleted file mode 100644 index a2a031d7..00000000 --- a/dosbox/lazyflags.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#if !defined __LAZYFLAGS_H -#define __LAZYFLAG_H - -//Flag Handling -Bit32u get_CF(void); -Bit32u get_AF(void); -Bit32u get_ZF(void); -Bit32u get_SF(void); -Bit32u get_OF(void); -Bit32u get_PF(void); - -Bitu FillFlags(void); -void FillFlagsNoCFOF(void); -void DestroyConditionFlags(void); - -#include "regs.h" - -struct LazyFlags { - GenReg32 var1,var2,res; - Bitu type; - Bitu prev_type; - Bitu oldcf; -}; - -extern LazyFlags lfags; - -#define lf_var1b lflags.var1.byte[BL_INDEX] -#define lf_var2b lflags.var2.byte[BL_INDEX] -#define lf_resb lflags.res.byte[BL_INDEX] - -#define lf_var1w lflags.var1.word[W_INDEX] -#define lf_var2w lflags.var2.word[W_INDEX] -#define lf_resw lflags.res.word[W_INDEX] - -#define lf_var1d lflags.var1.dword[DW_INDEX] -#define lf_var2d lflags.var2.dword[DW_INDEX] -#define lf_resd lflags.res.dword[DW_INDEX] - - -extern LazyFlags lflags; - -#define SETFLAGSb(FLAGB) \ -{ \ - SETFLAGBIT(OF,get_OF()); \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlags(FLAGB,FMASK_NORMAL & 0xff); \ -} - -#define SETFLAGSw(FLAGW) \ -{ \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlagsw(FLAGW); \ -} - -#define SETFLAGSd(FLAGD) \ -{ \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlagsd(FLAGD); \ -} - -#define LoadCF SETFLAGBIT(CF,get_CF()); -#define LoadZF SETFLAGBIT(ZF,get_ZF()); -#define LoadSF SETFLAGBIT(SF,get_SF()); -#define LoadOF SETFLAGBIT(OF,get_OF()); -#define LoadAF SETFLAGBIT(AF,get_AF()); - -#define TFLG_O (get_OF()) -#define TFLG_NO (!get_OF()) -#define TFLG_B (get_CF()) -#define TFLG_NB (!get_CF()) -#define TFLG_Z (get_ZF()) -#define TFLG_NZ (!get_ZF()) -#define TFLG_BE (get_CF() || get_ZF()) -#define TFLG_NBE (!get_CF() && !get_ZF()) -#define TFLG_S (get_SF()) -#define TFLG_NS (!get_SF()) -#define TFLG_P (get_PF()) -#define TFLG_NP (!get_PF()) -#define TFLG_L ((get_SF()!=0) != (get_OF()!=0)) -#define TFLG_NL ((get_SF()!=0) == (get_OF()!=0)) -#define TFLG_LE (get_ZF() || ((get_SF()!=0) != (get_OF()!=0))) -#define TFLG_NLE (!get_ZF() && ((get_SF()!=0) == (get_OF()!=0))) - -//Types of Flag changing instructions -enum { - t_UNKNOWN=0, - t_ADDb,t_ADDw,t_ADDd, - t_ORb,t_ORw,t_ORd, - t_ADCb,t_ADCw,t_ADCd, - t_SBBb,t_SBBw,t_SBBd, - t_ANDb,t_ANDw,t_ANDd, - t_SUBb,t_SUBw,t_SUBd, - t_XORb,t_XORw,t_XORd, - t_CMPb,t_CMPw,t_CMPd, - t_INCb,t_INCw,t_INCd, - t_DECb,t_DECw,t_DECd, - t_TESTb,t_TESTw,t_TESTd, - t_SHLb,t_SHLw,t_SHLd, - t_SHRb,t_SHRw,t_SHRd, - t_SARb,t_SARw,t_SARd, - t_ROLb,t_ROLw,t_ROLd, - t_RORb,t_RORw,t_RORd, - t_RCLb,t_RCLw,t_RCLd, - t_RCRb,t_RCRw,t_RCRd, - t_NEGb,t_NEGw,t_NEGd, - - t_DSHLw,t_DSHLd, - t_DSHRw,t_DSHRd, - t_MUL,t_DIV, - t_NOTDONE, - t_LASTFLAG -}; - -#endif diff --git a/dosbox/logging.h b/dosbox/logging.h deleted file mode 100644 index ae3daae9..00000000 --- a/dosbox/logging.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef DOSBOX_LOGGING_H -#define DOSBOX_LOGGING_H -enum LOG_TYPES { - LOG_ALL, - LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, - LOG_SB,LOG_DMACONTROL, - LOG_FPU,LOG_CPU,LOG_PAGING, - LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, - LOG_PIT,LOG_KEYBOARD,LOG_PIC, - LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, - LOG_IO, - LOG_MAX -}; - -enum LOG_SEVERITIES { - LOG_NORMAL, - LOG_WARN, - LOG_ERROR -}; - -#if C_DEBUG -class LOG -{ - LOG_TYPES d_type; - LOG_SEVERITIES d_severity; -public: - - LOG (LOG_TYPES type , LOG_SEVERITIES severity): - d_type(type), - d_severity(severity) - {} - void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp - -}; - -void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); -#define LOG_MSG DEBUG_ShowMsg - -#else //C_DEBUG - -struct LOG -{ - LOG(LOG_TYPES , LOG_SEVERITIES ) { } - void operator()(char const* ) { } - void operator()(char const* , double ) { } - void operator()(char const* , double , double ) { } - void operator()(char const* , double , double , double ) { } - void operator()(char const* , double , double , double , double ) { } - void operator()(char const* , double , double , double , double , double ) { } - - void operator()(char const* , char const* ) { } - void operator()(char const* , char const* , double ) { } - void operator()(char const* , char const* , double ,double ) { } - void operator()(char const* , double , char const* ) { } - void operator()(char const* , double , double, char const* ) { } - void operator()(char const* , char const*, char const*) { } - - -}; //add missing operators to here - //try to avoid anything smaller than bit32... -void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); -#define LOG_MSG GFX_ShowMsg - -#endif //C_DEBUG - - -#endif //DOSBOX_LOGGING_H diff --git a/dosbox/mem.h b/dosbox/mem.h deleted file mode 100644 index 885cee61..00000000 --- a/dosbox/mem.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_MEM_H -#define DOSBOX_MEM_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -typedef Bit32u PhysPt; -typedef Bit8u * HostPt; -typedef Bit32u RealPt; - -typedef Bit32s MemHandle; - -#define MEM_PAGESIZE 4096 - -extern HostPt MemBase; -HostPt GetMemBase(void); - -bool MEM_A20_Enabled(void); -void MEM_A20_Enable(bool enable); - -/* Memory management / EMS mapping */ -HostPt MEM_GetBlockPage(void); -Bitu MEM_FreeTotal(void); //Free 4 kb pages -Bitu MEM_FreeLargest(void); //Largest free 4 kb pages block -Bitu MEM_TotalPages(void); //Total amount of 4 kb pages -Bitu MEM_AllocatedPages(MemHandle handle); // amount of allocated pages of handle -MemHandle MEM_AllocatePages(Bitu pages,bool sequence); -MemHandle MEM_GetNextFreePage(void); -PhysPt MEM_AllocatePage(void); -void MEM_ReleasePages(MemHandle handle); -bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); - -MemHandle MEM_NextHandle(MemHandle handle); -MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); - -/* - The folowing six functions are used everywhere in the end so these should be changed for - Working on big or little endian machines -*/ - -void bridge_mono_hit(void); -void bridge_color_hit(void); -extern HostPt mono_start, mono_end, color_start, color_end; -static INLINE void bridge_special_addr_check(HostPt off) -{ - if (off >= mono_start && off < mono_end) - bridge_mono_hit(); - if (off >= color_start && off < color_end) - bridge_color_hit(); -} - -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - -static INLINE Bit8u host_readb(HostPt off) { - return off[0]; -} -static INLINE Bit16u host_readw(HostPt off) { - return off[0] | (off[1] << 8); -} -static INLINE Bit32u host_readd(HostPt off) { - return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); -} -static INLINE void host_writeb(HostPt off,Bit8u val) { - bridge_special_addr_check(off); - off[0]=val; -} -static INLINE void host_writew(HostPt off,Bit16u val) { - bridge_special_addr_check(off); - off[0]=(Bit8u)(val); - off[1]=(Bit8u)(val >> 8); -} -static INLINE void host_writed(HostPt off,Bit32u val) { - bridge_special_addr_check(off); - off[0]=(Bit8u)(val); - off[1]=(Bit8u)(val >> 8); - off[2]=(Bit8u)(val >> 16); - off[3]=(Bit8u)(val >> 24); -} - -#else - -static INLINE Bit8u host_readb(HostPt off) { - return *(Bit8u *)off; -} -static INLINE Bit16u host_readw(HostPt off) { - return *(Bit16u *)off; -} -static INLINE Bit32u host_readd(HostPt off) { - return *(Bit32u *)off; -} -static INLINE void host_writeb(HostPt off,Bit8u val) { - bridge_special_addr_check(off); - *(Bit8u *)(off)=val; -} -static INLINE void host_writew(HostPt off,Bit16u val) { - bridge_special_addr_check(off); - *(Bit16u *)(off)=val; -} -static INLINE void host_writed(HostPt off,Bit32u val) { - bridge_special_addr_check(off); - *(Bit32u *)(off)=val; -} - -#endif - - -static INLINE void var_write(Bit8u * var, Bit8u val) { - host_writeb((HostPt)var, val); -} - -static INLINE void var_write(Bit16u * var, Bit16u val) { - host_writew((HostPt)var, val); -} - -static INLINE void var_write(Bit32u * var, Bit32u val) { - host_writed((HostPt)var, val); -} - -/* The Folowing six functions are slower but they recognize the paged memory system */ - -Bit8u mem_readb(PhysPt pt); -Bit16u mem_readw(PhysPt pt); -Bit32u mem_readd(PhysPt pt); - -void mem_writeb(PhysPt pt,Bit8u val); -void mem_writew(PhysPt pt,Bit16u val); -void mem_writed(PhysPt pt,Bit32u val); - -static INLINE void phys_writeb(PhysPt addr,Bit8u val) { - host_writeb(MemBase+addr,val); -} -static INLINE void phys_writew(PhysPt addr,Bit16u val){ - host_writew(MemBase+addr,val); -} -static INLINE void phys_writed(PhysPt addr,Bit32u val){ - host_writed(MemBase+addr,val); -} - -static INLINE Bit8u phys_readb(PhysPt addr) { - return host_readb(MemBase+addr); -} -static INLINE Bit16u phys_readw(PhysPt addr){ - return host_readw(MemBase+addr); -} -static INLINE Bit32u phys_readd(PhysPt addr){ - return host_readd(MemBase+addr); -} - -/* These don't check for alignment, better be sure it's correct */ - -void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size); -void MEM_BlockRead(PhysPt pt,void * data,Bitu size); -void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size); -void MEM_StrCopy(PhysPt pt,char * data,Bitu size); - -void mem_memcpy(PhysPt dest,PhysPt src,Bitu size); -Bitu mem_strlen(PhysPt pt); -void mem_strcpy(PhysPt dest,PhysPt src); - -/* The folowing functions are all shortcuts to the above functions using physical addressing */ - -static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { - return mem_readb((seg<<4)+off); -} -static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { - return mem_readw((seg<<4)+off); -} -static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) { - return mem_readd((seg<<4)+off); -} - -static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { - mem_writeb(((seg<<4)+off),val); -} -static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { - mem_writew(((seg<<4)+off),val); -} -static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { - mem_writed(((seg<<4)+off),val); -} - - -static INLINE Bit16u RealSeg(RealPt pt) { - return (Bit16u)(pt>>16); -} - -static INLINE Bit16u RealOff(RealPt pt) { - return (Bit16u)(pt&0xffff); -} - -static INLINE PhysPt Real2Phys(RealPt pt) { - return (RealSeg(pt)<<4) +RealOff(pt); -} - -static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { - return (seg<<4)+off; -} - -static INLINE RealPt RealMake(Bit16u seg,Bit16u off) { - return (seg<<16)+off; -} - -static INLINE void RealSetVec(Bit8u vec,RealPt pt) { - mem_writed(vec<<2,pt); -} - -static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { - old = mem_readd(vec<<2); - mem_writed(vec<<2,pt); -} - -static INLINE RealPt RealGetVec(Bit8u vec) { - return mem_readd(vec<<2); -} - -#endif - diff --git a/dosbox/modrm.cpp b/dosbox/modrm.cpp deleted file mode 100644 index bbac41e0..00000000 --- a/dosbox/modrm.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "cpu.h" - - -Bit8u * lookupRMregb[]= -{ - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh -}; - -Bit16u * lookupRMregw[]={ - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di -}; - -Bit32u * lookupRMregd[256]={ - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi -}; - - -Bit8u * lookupRMEAregb[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh -}; - -Bit16u * lookupRMEAregw[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di -}; - -Bit32u * lookupRMEAregd[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi -}; - - diff --git a/dosbox/modrm.h b/dosbox/modrm.h deleted file mode 100644 index 60482bf9..00000000 --- a/dosbox/modrm.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -extern Bit8u * lookupRMregb[]; -extern Bit16u * lookupRMregw[]; -extern Bit32u * lookupRMregd[]; -extern Bit8u * lookupRMEAregb[256]; -extern Bit16u * lookupRMEAregw[256]; -extern Bit32u * lookupRMEAregd[256]; - -#define GetRM \ - Bit8u rm=Fetchb(); - -#define Getrb \ - Bit8u * rmrb; \ - rmrb=lookupRMregb[rm]; - -#define Getrw \ - Bit16u * rmrw; \ - rmrw=lookupRMregw[rm]; - -#define Getrd \ - Bit32u * rmrd; \ - rmrd=lookupRMregd[rm]; - - -#define GetRMrb \ - GetRM; \ - Getrb; - -#define GetRMrw \ - GetRM; \ - Getrw; - -#define GetRMrd \ - GetRM; \ - Getrd; - - -#define GetEArb \ - Bit8u * earb=lookupRMEAregb[rm]; - -#define GetEArw \ - Bit16u * earw=lookupRMEAregw[rm]; - -#define GetEArd \ - Bit32u * eard=lookupRMEAregd[rm]; - - diff --git a/dosbox/paging.cpp b/dosbox/paging.cpp deleted file mode 100644 index e3088edb..00000000 --- a/dosbox/paging.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: paging.cpp,v 1.36 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include -#include -#include - -#include "dosbox.h" -#include "mem.h" -#include "paging.h" -#include "regs.h" -#include "lazyflags.h" -#include "cpu.h" -//#include "debug.h" -#include "setup.h" - -#define LINK_TOTAL (64*1024) - -#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) - - -PagingBlock paging; - - -Bitu PageHandler::readb(PhysPt addr) { - E_Exit("No byte handler for read from %d",addr); - return 0; -} -Bitu PageHandler::readw(PhysPt addr) { - return - (readb(addr+0) << 0) | - (readb(addr+1) << 8); -} -Bitu PageHandler::readd(PhysPt addr) { - return - (readb(addr+0) << 0) | - (readb(addr+1) << 8) | - (readb(addr+2) << 16) | - (readb(addr+3) << 24); -} - -void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { - E_Exit("No byte handler for write to %d",addr); -} - -void PageHandler::writew(PhysPt addr,Bitu val) { - writeb(addr+0,(Bit8u) (val >> 0)); - writeb(addr+1,(Bit8u) (val >> 8)); -} -void PageHandler::writed(PhysPt addr,Bitu val) { - writeb(addr+0,(Bit8u) (val >> 0)); - writeb(addr+1,(Bit8u) (val >> 8)); - writeb(addr+2,(Bit8u) (val >> 16)); - writeb(addr+3,(Bit8u) (val >> 24)); -} - -HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) { - return 0; -} - -HostPt PageHandler::GetHostWritePt(Bitu /*phys_page*/) { - return 0; -} - -bool PageHandler::readb_checked(PhysPt addr, Bit8u * val) { - *val=(Bit8u)readb(addr); return false; -} -bool PageHandler::readw_checked(PhysPt addr, Bit16u * val) { - *val=(Bit16u)readw(addr); return false; -} -bool PageHandler::readd_checked(PhysPt addr, Bit32u * val) { - *val=(Bit32u)readd(addr); return false; -} -bool PageHandler::writeb_checked(PhysPt addr,Bitu val) { - writeb(addr,val); return false; -} -bool PageHandler::writew_checked(PhysPt addr,Bitu val) { - writew(addr,val); return false; -} -bool PageHandler::writed_checked(PhysPt addr,Bitu val) { - writed(addr,val); return false; -} - - - -struct PF_Entry { - Bitu cs; - Bitu eip; - Bitu page_addr; - Bitu mpl; -}; - -#define PF_QUEUESIZE 16 -static struct { - Bitu used; - PF_Entry entries[PF_QUEUESIZE]; -} pf_queue; - -static Bits PageFaultCore(void) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - Bits ret=CPU_Core_Full_Run(); - CPU_CycleLeft+=CPU_Cycles; - if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); - if (ret) - return ret; - if (!pf_queue.used) E_Exit("PF Core without PF"); - PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; - X86PageEntry pentry; - pentry.load=phys_readd(entry->page_addr); - if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) { - cpu.mpl=entry->mpl; - return -1; - } - return 0; -} -#if C_DEBUG -Bitu DEBUG_EnableDebugger(void); -#endif - -bool first=false; - -void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { - /* Save the state of the cpu cores */ - LazyFlags old_lflags; - memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); - CPU_Decoder * old_cpudecoder; - old_cpudecoder=cpudecoder; - cpudecoder=&PageFaultCore; - paging.cr2=lin_addr; - PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; - LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x] queue %d",lin_addr,faultcode,pf_queue.used); -// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); -// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); - entry->cs=SegValue(cs); - entry->eip=reg_eip; - entry->page_addr=page_addr; - entry->mpl=cpu.mpl; - cpu.mpl=3; - - CPU_Exception(EXCEPTION_PF,faultcode); -#if C_DEBUG -// DEBUG_EnableDebugger(); -#endif - DOSBOX_RunMachine(); - pf_queue.used--; - LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,pf_queue.used); - memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); - cpudecoder=old_cpudecoder; -// LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); -} - -static INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr) { - if (relink==0) return; - if (paging.links.used) { - if (paging.links.entries[paging.links.used-1]==(addr>>12)) { - paging.links.used--; - PAGING_UnlinkPages(addr>>12,1); - } - } - if (relink>1) PAGING_LinkPage_ReadOnly(addr>>12,relink); -} - -static INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { - Bitu lin_page=lin_addr >> 12; - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; - table.load=phys_readd(table_addr); - if (!table.block.p) { - LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - table.load=phys_readd(table_addr); - if (GCC_UNLIKELY(!table.block.p)) - E_Exit("Pagefault didn't correct table"); - } - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { -// LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - entry.load=phys_readd(entry_addr); - if (GCC_UNLIKELY(!entry.block.p)) - E_Exit("Pagefault didn't correct page"); - } -} - -static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { - Bitu lin_page=lin_addr >> 12; - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; - table.load=phys_readd(table_addr); - if (!table.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } - return true; -} - -// check if a user-level memory access would trigger a privilege page fault -static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_386FAST: - default: - return ((u1)==0) && ((u2)==0); - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - return ((u1)==0) || ((u2)==0); - } -} - - -class InitPageHandler : public PageHandler { -public: - InitPageHandler() { - flags=PFLAG_INIT|PFLAG_NOCODE; - } - Bitu readb(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit8u val=mem_readb(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - Bitu readw(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit16u val=mem_readw(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - Bitu readd(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit32u val=mem_readd(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - void writeb(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - mem_writeb(addr,val); - InitPageUpdateLink(needs_reset,addr); - } - void writew(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - mem_writew(addr,val); - InitPageUpdateLink(needs_reset,addr); - } - void writed(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - mem_writed(addr,val); - InitPageUpdateLink(needs_reset,addr); - } - bool readb_checked(PhysPt addr, Bit8u * val) { - if (InitPageCheckOnly(addr,false)) { - *val=mem_readb(addr); - return false; - } else return true; - } - bool readw_checked(PhysPt addr, Bit16u * val) { - if (InitPageCheckOnly(addr,false)){ - *val=mem_readw(addr); - return false; - } else return true; - } - bool readd_checked(PhysPt addr, Bit32u * val) { - if (InitPageCheckOnly(addr,false)) { - *val=mem_readd(addr); - return false; - } else return true; - } - bool writeb_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - mem_writeb(addr,val); - return false; - } else return true; - } - bool writew_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - mem_writew(addr,val); - return false; - } else return true; - } - bool writed_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - mem_writed(addr,val); - return false; - } else return true; - } - Bitu InitPage(Bitu lin_addr,bool writing) { - Bitu lin_page=lin_addr >> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,writing,table,entry); - - // 0: no action - // 1: can (but currently does not) fail a user-level access privilege check - // 2: can (but currently does not) fail a write privilege check - // 3: fails a privilege check - Bitu priv_check=0; - if (InitPage_CheckUseraccess(entry.block.us,table.block.us)) { - if ((cpu.cpl&cpu.mpl)==3) priv_check=3; - else { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386FAST: - default: -// priv_check=0; // default - break; - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - priv_check=1; - break; - } - } - } - if ((entry.block.wr==0) || (table.block.wr==0)) { - // page is write-protected for user mode - if (priv_check==0) { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386FAST: - default: -// priv_check=0; // default - break; - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - priv_check=2; - break; - } - } - // check if actually failing the write-protected check - if (writing && USERWRITE_PROHIBITED) priv_check=3; - } - if (priv_check==3) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x05 | (writing?0x02:0x00)); - priv_check=0; - } - - if (!table.block.a) { - table.block.a=1; // set page table accessed - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; // set page accessed - - // page is dirty if we're writing to it, or if we're reading but the - // page will be fully linked so we can't track later writes - if (writing || (priv_check==0)) entry.block.d=1; // mark page as dirty - - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - - phys_page=entry.block.base; - - // now see how the page should be linked best, if we need to catch privilege - // checks later on it should be linked as read-only page - if (priv_check==0) { - // if reading we could link the page as read-only to later cacth writes, - // will slow down pretty much but allows catching all dirty events - PAGING_LinkPage(lin_page,phys_page); - } else { - if (priv_check==1) { - PAGING_LinkPage(lin_page,phys_page); - return 1; - } else if (writing) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - PAGING_LinkPage(lin_page,phys_page); - if (!(handler->flags & PFLAG_READABLE)) return 1; - if (!(handler->flags & PFLAG_WRITEABLE)) return 1; - if (get_tlb_read(lin_addr)!=get_tlb_write(lin_addr)) return 1; - if (phys_page>1) return phys_page; - else return 1; - } else { - PAGING_LinkPage_ReadOnly(lin_page,phys_page); - } - } - } else { - if (lin_page> 12; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - if (!InitPageCheckPresence_CheckOnly(lin_addr,writing,table,entry)) return false; - - if (!USERWRITE_PROHIBITED) return true; - - if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || - (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=0x05 | (writing?0x02:0x00); - return false; - } - } else { - Bitu phys_page; - if (lin_page> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,false,table,entry); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if (!entry.block.a) { - entry.block.a=1; //Set access - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - // maybe use read-only page here if possible - } else { - if (lin_page1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - host_writeb(tlb_addr+addr,(Bit8u)(val&0xff)); - return false; - } - return true; - } - bool writew_checked(PhysPt addr,Bitu val) { - Bitu writecode=InitPageCheckOnly(addr,(Bit16u)(val&0xffff)); - if (writecode) { - HostPt tlb_addr; - if (writecode>1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - host_writew(tlb_addr+addr,(Bit16u)(val&0xffff)); - return false; - } - return true; - } - bool writed_checked(PhysPt addr,Bitu val) { - Bitu writecode=InitPageCheckOnly(addr,(Bit32u)val); - if (writecode) { - HostPt tlb_addr; - if (writecode>1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - host_writed(tlb_addr+addr,(Bit32u)val); - return false; - } - return true; - } - void InitPage(Bitu lin_addr,Bitu val) { - Bitu lin_page=lin_addr >> 12; - Bitu phys_page; - if (paging.enabled) { - if (!USERWRITE_PROHIBITED) return; - - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,true,table,entry); - - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x07); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; //Set access - entry.block.d=1; //Set dirty - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - PAGING_LinkPage(lin_page,phys_page); - } else { - if (lin_page> 12; - if (paging.enabled) { - if (!USERWRITE_PROHIBITED) return 2; - - X86PageEntry table; - X86PageEntry entry; - if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0; - - if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=0x07; - return 0; - } - PAGING_LinkPage(lin_page,entry.block.base); - } else { - Bitu phys_page; - if (lin_page> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,true,table,entry); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if (!entry.block.a) { - entry.block.a=1; //Set access - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - } else { - if (lin_page> 10; - Bitu t_index=page & 0x3ff; - X86PageEntry table; - table.load=phys_readd((paging.base.page<<12)+d_index*4); - if (!table.block.p) return false; - X86PageEntry entry; - entry.load=phys_readd((table.block.base<<12)+t_index*4); - if (!entry.block.p) return false; - page=entry.block.base; - } else { - if (page>12,1); - init_page_handler_userro.InitPageForced(lin_addr); - return true; - } - return false; -} - -#if defined(USE_FULL_TLB) -void PAGING_InitTLB(void) { - for (Bitu i=0;i0;paging.links.used--) { - Bitu page=*entries++; - paging.tlb.read[page]=0; - paging.tlb.write[page]=0; - paging.tlb.readhandler[page]=&init_page_handler; - paging.tlb.writehandler[page]=&init_page_handler; - } - paging.links.used=0; -} - -void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { - for (;pages>0;pages--) { - paging.tlb.read[lin_page]=0; - paging.tlb.write[lin_page]=0; - paging.tlb.readhandler[lin_page]=&init_page_handler; - paging.tlb.writehandler[lin_page]=&init_page_handler; - lin_page++; - } -} - -void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { - if (lin_page=TLB_SIZE || phys_page>=TLB_SIZE) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - paging.tlb.phys_page[lin_page]=phys_page; - if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; - else paging.tlb.read[lin_page]=0; - if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=handler->GetHostWritePt(phys_page)-lin_base; - else paging.tlb.write[lin_page]=0; - - paging.links.entries[paging.links.used++]=lin_page; - paging.tlb.readhandler[lin_page]=handler; - paging.tlb.writehandler[lin_page]=handler; -} - -void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - Bitu lin_base=lin_page << 12; - if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - paging.tlb.phys_page[lin_page]=phys_page; - if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; - else paging.tlb.read[lin_page]=0; - paging.tlb.write[lin_page]=0; - - paging.links.entries[paging.links.used++]=lin_page; - paging.tlb.readhandler[lin_page]=handler; - paging.tlb.writehandler[lin_page]=&init_page_handler_userro; -} - -#else - -static INLINE void InitTLBInt(tlb_entry *bank) { - for (Bitu i=0;i0;paging.links.used--) { - Bitu page=*entries++; - tlb_entry *entry = get_tlb_entry(page<<12); - entry->read=0; - entry->write=0; - entry->readhandler=&init_page_handler; - entry->writehandler=&init_page_handler; - } - paging.links.used=0; -} - -void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { - for (;pages>0;pages--) { - tlb_entry *entry = get_tlb_entry(lin_page<<12); - entry->read=0; - entry->write=0; - entry->readhandler=&init_page_handler; - entry->writehandler=&init_page_handler; - lin_page++; - } -} - -void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { - if (lin_page=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - tlb_entry *entry = get_tlb_entry(lin_base); - entry->phys_page=phys_page; - if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; - else entry->read=0; - if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base; - else entry->write=0; - - paging.links.entries[paging.links.used++]=lin_page; - entry->readhandler=handler; - entry->writehandler=handler; -} - -void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - Bitu lin_base=lin_page << 12; - if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - tlb_entry *entry = get_tlb_entry(lin_base); - entry->phys_page=phys_page; - if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; - else entry->read=0; - entry->write=0; - - paging.links.entries[paging.links.used++]=lin_page; - entry->readhandler=handler; - entry->writehandler=&init_page_handler_userro; -} - -#endif - - -void PAGING_SetDirBase(Bitu cr3) { - paging.cr3=cr3; - - paging.base.page=cr3 >> 12; - paging.base.addr=cr3 & ~4095; -// LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page); - if (paging.enabled) { - PAGING_ClearTLB(); - } -} - -void PAGING_Enable(bool enabled) { - /* If paging is disable we work from a default paging table */ - if (paging.enabled==enabled) return; - paging.enabled=enabled; - if (enabled) { - if (GCC_UNLIKELY(cpudecoder==CPU_Core_Simple_Run)) { -// LOG_MSG("CPU core simple won't run this game,switching to normal"); - cpudecoder=CPU_Core_Normal_Run; - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } -// LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); - PAGING_SetDirBase(paging.cr3); - } - PAGING_ClearTLB(); -} - -bool PAGING_Enabled(void) { - return paging.enabled; -} - -class PAGING:public Module_base{ -public: - PAGING(Section* configuration):Module_base(configuration){ - /* Setup default Page Directory, force it to update */ - paging.enabled=false; - PAGING_InitTLB(); - Bitu i; - for (i=0;i>12]; -} -static INLINE HostPt get_tlb_write(PhysPt address) { - return paging.tlb.write[address>>12]; -} -static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return paging.tlb.readhandler[address>>12]; -} -static INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return paging.tlb.writehandler[address>>12]; -} - -/* Use these helper functions to access linear addresses in readX/writeX functions */ -static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - return (paging.tlb.phys_page[linePage>>12]<<12); -} - -static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); -} - -#else - -void PAGING_InitTLBBank(tlb_entry **bank); - -static INLINE tlb_entry *get_tlb_entry(PhysPt address) { - Bitu index=(address>>12); - if (TLB_BANKS && (index > TLB_SIZE)) { - Bitu bank=(address>>BANK_SHIFT) - 1; - if (!paging.tlbh_banks[bank]) - PAGING_InitTLBBank(&paging.tlbh_banks[bank]); - return &paging.tlbh_banks[bank][index & BANK_MASK]; - } - return &paging.tlbh[index]; -} - -static INLINE HostPt get_tlb_read(PhysPt address) { - return get_tlb_entry(address)->read; -} -static INLINE HostPt get_tlb_write(PhysPt address) { - return get_tlb_entry(address)->write; -} -static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return get_tlb_entry(address)->readhandler; -} -static INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return get_tlb_entry(address)->writehandler; -} - -/* Use these helper functions to access linear addresses in readX/writeX functions */ -static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - tlb_entry *entry = get_tlb_entry(linePage); - return (entry->phys_page<<12); -} - -static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - tlb_entry *entry = get_tlb_entry(linAddr); - return (entry->phys_page<<12)|(linAddr&0xfff); -} -#endif - -/* Special inlined memory reading/writing */ - -static INLINE Bit8u mem_readb_inline(PhysPt address) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readb(tlb_addr+address); - else return (Bit8u)(get_tlb_readhandler(address))->readb(address); -} - -static INLINE Bit16u mem_readw_inline(PhysPt address) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readw(tlb_addr+address); - else return (Bit16u)(get_tlb_readhandler(address))->readw(address); - } else return mem_unalignedreadw(address); -} - -static INLINE Bit32u mem_readd_inline(PhysPt address) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readd(tlb_addr+address); - else return (get_tlb_readhandler(address))->readd(address); - } else return mem_unalignedreadd(address); -} - -static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writeb(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writeb(address,val); -} - -static INLINE void mem_writew_inline(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writew(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writew(address,val); - } else mem_unalignedwritew(address,val); -} - -static INLINE void mem_writed_inline(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writed(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writed(address,val); - } else mem_unalignedwrited(address,val); -} - - -static INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readb(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readb_checked(address, val); -} - -static INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readw(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readw_checked(address, val); - } else return mem_unalignedreadw_checked(address, val); -} - -static INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readd(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readd_checked(address, val); - } else return mem_unalignedreadd_checked(address, val); -} - -static INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writeb(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writeb_checked(address,val); -} - -static INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writew(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writew_checked(address,val); - } else return mem_unalignedwritew_checked(address,val); -} - -static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writed(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writed_checked(address,val); - } else return mem_unalignedwrited_checked(address,val); -} - - -#endif diff --git a/dosbox/pic.cpp b/dosbox/pic.cpp deleted file mode 100644 index 3a68d062..00000000 --- a/dosbox/pic.cpp +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: pic.cpp,v 1.44 2009-05-27 09:15:41 qbix79 Exp $ */ - -#include - -#include "dosbox.h" -#include "inout.h" -#include "cpu.h" -#include "callback.h" -#include "pic.h" -#include "timer.h" -#include "setup.h" - -#define PIC_QUEUESIZE 512 - -struct IRQ_Block { - bool masked; - bool active; - bool inservice; - Bitu vector; -}; - -struct PIC_Controller { - Bitu icw_words; - Bitu icw_index; - Bitu masked; - - bool special; - bool auto_eoi; - bool rotate_on_auto_eoi; - bool single; - bool request_issr; - Bit8u vector_base; -}; - -Bitu PIC_Ticks=0; -Bitu PIC_IRQCheck; -Bitu PIC_IRQOnSecondPicActive; -Bitu PIC_IRQActive; - - -static IRQ_Block irqs[16]; -static PIC_Controller pics[2]; -static bool PIC_Special_Mode = false; //Saves one compare in the pic_run_irqloop -struct PICEntry { - float index; - Bitu value; - PIC_EventHandler pic_event; - PICEntry * next; -}; - -static struct { - PICEntry entries[PIC_QUEUESIZE]; - PICEntry * free_entry; - PICEntry * next_entry; -} pic_queue; - -void x86_ack_keyboard(void); - -static void write_command(Bitu port,Bitu val,Bitu iolen) { - PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; - Bitu irq_base=port==0x20 ? 0 : 8; - Bitu i; - static Bit16u IRQ_priority_table[16] = - { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; - if (GCC_UNLIKELY(val&0x10)) { // ICW1 issued - if (val&0x04) E_Exit("PIC: 4 byte interval not handled"); - if (val&0x08) E_Exit("PIC: level triggered mode not handled"); - if (val&0xe0) E_Exit("PIC: 8080/8085 mode not handled"); - pic->single=(val&0x02)==0x02; - pic->icw_index=1; // next is ICW2 - pic->icw_words=2 + (val&0x01); // =3 if ICW4 needed - } else if (GCC_UNLIKELY(val&0x08)) { // OCW3 issued - if (val&0x04) E_Exit("PIC: poll command not handled"); - if (val&0x02) { // function select - if (val&0x01) pic->request_issr=true; /* select read interrupt in-service register */ - else pic->request_issr=false; /* select read interrupt request register */ - } - if (val&0x40) { // special mask select - if (val&0x20) pic->special=true; - else pic->special=false; - if(pic[0].special || pics[1].special) - PIC_Special_Mode = true; else - PIC_Special_Mode = false; - if (PIC_IRQCheck) { //Recheck irqs - CPU_CycleLeft += CPU_Cycles; - CPU_Cycles = 0; - } - LOG(LOG_PIC,LOG_NORMAL)("port %X : special mask %s",port,(pic->special)?"ON":"OFF"); - } - } else { // OCW2 issued - if (val&0x20) { // EOI commands - if (GCC_UNLIKELY(val&0x80)) E_Exit("rotate mode not supported"); - if (val&0x40) { // specific EOI - if (PIC_IRQActive==(irq_base+val-0x60U)) { - irqs[PIC_IRQActive].inservice=false; - if (PIC_IRQActive == 1) - x86_ack_keyboard(); - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++) { - if (irqs[IRQ_priority_table[i]].inservice) { - PIC_IRQActive=IRQ_priority_table[i]; - break; - } - } - } -// if (val&0x80); // perform rotation - } else { // nonspecific EOI - if (PIC_IRQActive<(irq_base+8)) { - irqs[PIC_IRQActive].inservice=false; - if (PIC_IRQActive == 1) - x86_ack_keyboard(); - PIC_IRQActive=PIC_NOIRQ; - for (i=0; i<=15; i++){ - if(GCC_UNLIKELY(irqs[IRQ_priority_table[i]].inservice)) { - PIC_IRQActive=IRQ_priority_table[i]; - break; - } - } - } -// if (val&0x80); // perform rotation - } - } else { - if ((val&0x40)==0) { // rotate in auto EOI mode - if (val&0x80) pic->rotate_on_auto_eoi=true; - else pic->rotate_on_auto_eoi=false; - } else if (val&0x80) { - LOG(LOG_PIC,LOG_NORMAL)("set priority command not handled"); - } // else NOP command - } - } // end OCW2 -} - -static void write_data(Bitu port,Bitu val,Bitu iolen) { - PIC_Controller * pic=&pics[port==0x21 ? 0 : 1]; - Bitu irq_base=(port==0x21) ? 0 : 8; - Bitu i; - bool old_irq2_mask = irqs[2].masked; - switch(pic->icw_index) { - case 0: /* mask register */ - LOG(LOG_PIC,LOG_NORMAL)("%d mask %X",port==0x21 ? 0 : 1,val); - for (i=0;i<=7;i++) { - irqs[i+irq_base].masked=(val&(1<0; - if(port==0x21) { - if (irqs[i+irq_base].active && !irqs[i+irq_base].masked) PIC_IRQCheck|=(1 << (i+irq_base)); - else PIC_IRQCheck&=~(1 << (i+irq_base)); - } else { - if (irqs[i+irq_base].active && !irqs[i+irq_base].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i+irq_base)); - else PIC_IRQCheck&=~(1 << (i+irq_base)); - } - } -#if 0 - if (machine==MCH_PCJR) { - /* irq6 cannot be disabled as it serves as pseudo-NMI */ - irqs[6].masked=false; - } -#endif - if(irqs[2].masked != old_irq2_mask) { - /* Irq 2 mask has changed recheck second pic */ - for(i=8;i<=15;i++) { - if (irqs[i].active && !irqs[i].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i)); - else PIC_IRQCheck&=~(1 << (i)); - } - } - if (PIC_IRQCheck) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } - break; - case 1: /* icw2 */ - LOG(LOG_PIC,LOG_NORMAL)("%d:Base vector %X",port==0x21 ? 0 : 1,val); - for (i=0;i<=7;i++) { - irqs[i+irq_base].vector=(val&0xf8)+i; - }; - if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; - else if(pic->single) pic->icw_index=3; /* skip ICW3 in single mode */ - break; - case 2: /* icw 3 */ - LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 3 %X",port==0x21 ? 0 : 1,val); - if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; - break; - case 3: /* icw 4 */ - /* - 0 1 8086/8080 0 mcs-8085 mode - 1 1 Auto EOI 0 Normal EOI - 2-3 0x Non buffer Mode - 10 Buffer Mode Slave - 11 Buffer mode Master - 4 Special/Not Special nested mode - */ - pic->auto_eoi=(val & 0x2)>0; - - LOG(LOG_PIC,LOG_NORMAL)("%d:ICW 4 %X",port==0x21 ? 0 : 1,val); - - if ((val&0x01)==0) E_Exit("PIC:ICW4: %x, 8085 mode not handled",val); - if ((val&0x10)!=0) LOG_MSG("PIC:ICW4: %x, special fully-nested mode not handled",val); - - if(pic->icw_index++ >= pic->icw_words) pic->icw_index=0; - break; - default: - LOG(LOG_PIC,LOG_NORMAL)("ICW HUH? %X",val); - break; - } -} - - -static Bitu read_command(Bitu port,Bitu iolen) { - PIC_Controller * pic=&pics[port==0x20 ? 0 : 1]; - Bitu irq_base=(port==0x20) ? 0 : 8; - Bitu i;Bit8u ret=0;Bit8u b=1; - if (pic->request_issr) { - for (i=irq_base;i 7 && irqs[2].masked) return false; - irqs[i].active = false; - PIC_IRQCheck&= ~(1 << i); - PIC_IRQOnSecondPicActive&= ~(1 << i); - CPU_HW_Interrupt(irqs[i].vector); - Bitu pic=(i&8)>>3; - if (!pics[pic].auto_eoi) { //irq 0-7 => pic 0 else pic 1 - PIC_IRQActive = i; - irqs[i].inservice = true; - } else if (GCC_UNLIKELY(pics[pic].rotate_on_auto_eoi)) { - E_Exit("rotate on auto EOI not handled"); - } - return true; -} - -void PIC_runIRQs(void) { - if (!GETFLAG(IF)) return; - if (GCC_UNLIKELY(!PIC_IRQCheck)) return; - if (GCC_UNLIKELY(cpudecoder==CPU_Core_Normal_Trap_Run)) return; - - static Bitu IRQ_priority_order[16] = - { 0,1,2,8,9,10,11,12,13,14,15,3,4,5,6,7 }; - static Bit16u IRQ_priority_lookup[17] = - { 0,1,2,11,12,13,14,15,3,4,5,6,7,8,9,10,16 }; - Bit16u activeIRQ = PIC_IRQActive; - if (activeIRQ == PIC_NOIRQ) activeIRQ = 16; - /* Get the priority of the active irq */ - Bit16u Priority_Active_IRQ = IRQ_priority_lookup[activeIRQ]; - - Bitu i,j; - /* j is the priority (walker) - * i is the irq at the current priority */ - - /* If one of the pics is in special mode use a check that cares for that. */ - if(!PIC_Special_Mode) { - for (j = 0; j < Priority_Active_IRQ; j++) { - i = IRQ_priority_order[j]; - if (!irqs[i].masked && irqs[i].active) { - if(GCC_LIKELY(PIC_startIRQ(i))) return; - } - } - } else { /* Special mode variant */ - for (j = 0; j<= 15; j++) { - i = IRQ_priority_order[j]; - if ( (j < Priority_Active_IRQ) || (pics[ ((i&8)>>3) ].special) ) { - if (!irqs[i].masked && irqs[i].active) { - /* the irq line is active. it's not masked and - * the irq is allowed priority wise. So let's start it */ - /* If started successfully return, else go for the next */ - if(PIC_startIRQ(i)) return; - } - } - } - } -} - -void PIC_SetIRQMask(Bitu irq, bool masked) { - if(irqs[irq].masked == masked) return; /* Do nothing if mask doesn't change */ - bool old_irq2_mask = irqs[2].masked; - irqs[irq].masked=masked; - if(irq < 8) { - if (irqs[irq].active && !irqs[irq].masked) { - PIC_IRQCheck|=(1 << (irq)); - } else { - PIC_IRQCheck&=~(1 << (irq)); - } - } else { - if (irqs[irq].active && !irqs[irq].masked && !irqs[2].masked) { - PIC_IRQCheck|=(1 << (irq)); - } else { - PIC_IRQCheck&=~(1 << (irq)); - } - } - if(irqs[2].masked != old_irq2_mask) { - /* Irq 2 mask has changed recheck second pic */ - for(Bitu i=8;i<=15;i++) { - if (irqs[i].active && !irqs[i].masked && !irqs[2].masked) PIC_IRQCheck|=(1 << (i)); - else PIC_IRQCheck&=~(1 << (i)); - } - } - if (PIC_IRQCheck) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } -} - -static void AddEntry(PICEntry * entry) { - PICEntry * find_entry=pic_queue.next_entry; - if (GCC_UNLIKELY(find_entry ==0)) { - entry->next=0; - pic_queue.next_entry=entry; - } else if (find_entry->index>entry->index) { - pic_queue.next_entry=entry; - entry->next=find_entry; - } else while (find_entry) { - if (find_entry->next) { - /* See if the next index comes later than this one */ - if (find_entry->next->index > entry->index) { - entry->next=find_entry->next; - find_entry->next=entry; - break; - } else { - find_entry=find_entry->next; - } - } else { - entry->next=find_entry->next; - find_entry->next=entry; - break; - } - } - Bits cycles=PIC_MakeCycles(pic_queue.next_entry->index-PIC_TickIndex()); - if (cyclesindex = delay + srv_lag; - else entry->index = delay + PIC_TickIndex(); - - entry->pic_event=handler; - entry->value=val; - pic_queue.free_entry=pic_queue.free_entry->next; - AddEntry(entry); -} - -void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) { - PICEntry * entry=pic_queue.next_entry; - PICEntry * prev_entry; - prev_entry = 0; - while (entry) { - if (GCC_UNLIKELY((entry->pic_event == handler)) && (entry->value == val)) { - if (prev_entry) { - prev_entry->next=entry->next; - entry->next=pic_queue.free_entry; - pic_queue.free_entry=entry; - entry=prev_entry->next; - continue; - } else { - pic_queue.next_entry=entry->next; - entry->next=pic_queue.free_entry; - pic_queue.free_entry=entry; - entry=pic_queue.next_entry; - continue; - } - } - prev_entry=entry; - entry=entry->next; - } -} - -void PIC_RemoveEvents(PIC_EventHandler handler) { - PICEntry * entry=pic_queue.next_entry; - PICEntry * prev_entry; - prev_entry=0; - while (entry) { - if (GCC_UNLIKELY(entry->pic_event==handler)) { - if (prev_entry) { - prev_entry->next=entry->next; - entry->next=pic_queue.free_entry; - pic_queue.free_entry=entry; - entry=prev_entry->next; - continue; - } else { - pic_queue.next_entry=entry->next; - entry->next=pic_queue.free_entry; - pic_queue.free_entry=entry; - entry=pic_queue.next_entry; - continue; - } - } - prev_entry=entry; - entry=entry->next; - } -} - - -bool PIC_RunQueue(void) { - /* Check to see if a new milisecond needs to be started */ - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - if (CPU_CycleLeft<=0) { - return false; - } - /* Check the queue for an entry */ - Bits index_nd=PIC_TickIndexND(); - InEventService = true; - while (pic_queue.next_entry && (pic_queue.next_entry->index*CPU_CycleMax<=index_nd)) { - PICEntry * entry=pic_queue.next_entry; - pic_queue.next_entry=entry->next; - - srv_lag = entry->index; - (entry->pic_event)(entry->value); // call the event handler - - /* Put the entry in the free list */ - entry->next=pic_queue.free_entry; - pic_queue.free_entry=entry; - } - InEventService = false; - - /* Check when to set the new cycle end */ - if (pic_queue.next_entry) { - Bits cycles=(Bits)(pic_queue.next_entry->index*CPU_CycleMax-index_nd); - if (GCC_UNLIKELY(!cycles)) cycles=1; - if (cycleshandler==handler) { - *tick_where=ticker->next; - delete ticker; - return; - } - tick_where=&ticker->next; - ticker=ticker->next; - } -} - -void TIMER_AddTickHandler(TIMER_TickHandler handler) { - TickerBlock * newticker=new TickerBlock; - newticker->next=firstticker; - newticker->handler=handler; - firstticker=newticker; -} - -void TIMER_AddTick(void) { - /* Setup new amount of cycles for PIC */ - CPU_CycleLeft=CPU_CycleMax; - CPU_Cycles=0; - PIC_Ticks++; - /* Go through the list of scheduled events and lower their index with 1000 */ - PICEntry * entry=pic_queue.next_entry; - while (entry) { - entry->index -= 1.0; - entry=entry->next; - } - /* Call our list of ticker handlers */ - TickerBlock * ticker=firstticker; - while (ticker) { - TickerBlock * nextticker=ticker->next; - ticker->handler(); - ticker=nextticker; - } -} - -void x86_pic_write(Bitu port, Bitu val) -{ - switch(port) - { - case 0x20: - case 0xa0: - write_command(port, val, 1); - break; - case 0x21: - case 0xa1: - write_data(port, val, 1); - break; - } -} -Bitu x86_pic_read(Bitu port) -{ - switch (port) - { - case 0x20: - case 0xa0: - return read_command(port, 1); - case 0x21: - case 0xa1: - return read_data(port, 1); - break; - } - return 0; -} - -class PIC:public Module_base{ -//private: -// IO_ReadHandleObject ReadHandler[4]; -// IO_WriteHandleObject WriteHandler[4]; -public: - PIC(Section* configuration):Module_base(configuration){ - /* Setup pic0 and pic1 with initial values like DOS has normally */ - PIC_IRQCheck=0; - PIC_IRQActive=PIC_NOIRQ; - PIC_Ticks=0; - Bitu i; - for (i=0;i<2;i++) { - pics[i].masked=0xff; - pics[i].auto_eoi=false; - pics[i].rotate_on_auto_eoi=false; - pics[i].request_issr=false; - pics[i].special=false; - pics[i].single=false; - pics[i].icw_index=0; - pics[i].icw_words=0; - } - for (i=0;i<=7;i++) { - irqs[i].active=false; - irqs[i].masked=true; - irqs[i].inservice=false; - irqs[i+8].active=false; - irqs[i+8].masked=true; - irqs[i+8].inservice=false; - irqs[i].vector=0x8+i; - irqs[i+8].vector=0x70+i; - } - irqs[0].masked=false; /* Enable system timer */ - irqs[1].masked=false; /* Enable Keyboard IRQ */ - irqs[2].masked=false; /* Enable second pic */ - irqs[8].masked=false; /* Enable RTC IRQ */ -#if 0 - if (machine==MCH_PCJR) { - /* Enable IRQ6 (replacement for the NMI for PCJr) */ - irqs[6].masked=false; - } - ReadHandler[0].Install(0x20,read_command,IO_MB); - ReadHandler[1].Install(0x21,read_data,IO_MB); - WriteHandler[0].Install(0x20,write_command,IO_MB); - WriteHandler[1].Install(0x21,write_data,IO_MB); - ReadHandler[2].Install(0xa0,read_command,IO_MB); - ReadHandler[3].Install(0xa1,read_data,IO_MB); - WriteHandler[2].Install(0xa0,write_command,IO_MB); - WriteHandler[3].Install(0xa1,write_data,IO_MB); -#endif - /* Initialize the pic queue */ - for (i=0;iAddDestroyFunction(&PIC_Destroy); -} diff --git a/dosbox/pic.h b/dosbox/pic.h deleted file mode 100644 index 8b6e2f4d..00000000 --- a/dosbox/pic.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_PIC_H -#define DOSBOX_PIC_H - - -/* CPU Cycle Timing */ -extern Bit32s CPU_Cycles; -extern Bit32s CPU_CycleLeft; -extern Bit32s CPU_CycleMax; - -typedef void (PIC_EOIHandler) (void); -typedef void (* PIC_EventHandler)(Bitu val); - - -#define PIC_MAXIRQ 15 -#define PIC_NOIRQ 0xFF - -extern Bitu PIC_IRQCheck; -extern Bitu PIC_IRQActive; -extern Bitu PIC_Ticks; - -static INLINE float PIC_TickIndex(void) { - return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; -} - -static INLINE Bits PIC_TickIndexND(void) { - return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles; -} - -static INLINE Bits PIC_MakeCycles(double amount) { - return (Bits)(CPU_CycleMax*amount); -} - -static INLINE double PIC_FullIndex(void) { - return PIC_Ticks+(double)PIC_TickIndex(); -} - -void PIC_ActivateIRQ(Bitu irq); -void PIC_DeActivateIRQ(Bitu irq); - -void PIC_runIRQs(void); -bool PIC_RunQueue(void); - -//Delay in milliseconds -void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0); -void PIC_RemoveEvents(PIC_EventHandler handler); -void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val); - -void PIC_SetIRQMask(Bitu irq, bool masked); -#endif diff --git a/dosbox/regs.h b/dosbox/regs.h deleted file mode 100644 index 13da9233..00000000 --- a/dosbox/regs.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_REGS_H -#define DOSBOX_REGS_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#define FLAG_CF 0x00000001 -#define FLAG_PF 0x00000004 -#define FLAG_AF 0x00000010 -#define FLAG_ZF 0x00000040 -#define FLAG_SF 0x00000080 -#define FLAG_OF 0x00000800 - -#define FLAG_TF 0x00000100 -#define FLAG_IF 0x00000200 -#define FLAG_DF 0x00000400 - -#define FLAG_IOPL 0x00003000 -#define FLAG_NT 0x00004000 -#define FLAG_VM 0x00020000 -#define FLAG_AC 0x00040000 -#define FLAG_ID 0x00200000 - -#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 | FLAG_AC ) -#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 { - Bit16u val; - PhysPt phys; /* The phyiscal address start in emulated machine */ -}; - -enum SegNames { es=0,cs,ss,ds,fs,gs}; - -struct Segments { - Bitu val[8]; - PhysPt phys[8]; -}; - -union GenReg32 { - Bit32u dword[1]; - Bit16u word[2]; - Bit8u 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 SegPhys(SegNames index) { - return Segs.phys[index]; -} - -static INLINE Bit16u SegValue(SegNames index) { - return (Bit16u)Segs.val[index]; -} - -static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { - return RealMake(SegValue(index),off); -} - - -static INLINE void SegSet16(Bitu index,Bit16u val) { - Segs.val[index]=val; - Segs.phys[index]=val << 4; -} - -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 diff --git a/dosbox/setup.h b/dosbox/setup.h deleted file mode 100644 index db75ada8..00000000 --- a/dosbox/setup.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: setup.h,v 1.41 2009-05-27 09:15:41 qbix79 Exp $ */ - -#ifndef DOSBOX_SETUP_H -#define DOSBOX_SETUP_H - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#pragma warning ( disable : 4290 ) -#endif - - -#ifndef CH_LIST -#define CH_LIST -#include -#endif - -#ifndef CH_VECTOR -#define CH_VECTOR -#include -#endif - -#ifndef CH_STRING -#define CH_STRING -#include -#endif - - -class Hex { -private: - int _hex; -public: - Hex(int in):_hex(in) { }; - Hex():_hex(0) { }; - bool operator==(Hex const& other) {return _hex == other._hex;} - operator int () const { return _hex; } - -}; - -class Value { -/* - * Multitype storage container that is aware of the currently stored type in it. - * Value st = "hello"; - * Value in = 1; - * st = 12 //Exception - * in = 12 //works - */ -private: - Hex _hex; - bool _bool; - int _int; - std::string* _string; - double _double; -public: - class WrongType { }; // Conversion error class - enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type; - - /* Constructors */ - Value() :_string(0), type(V_NONE) { }; - Value(Hex in) :_hex(in), type(V_HEX) { }; - Value(int in) :_int(in), type(V_INT) { }; - Value(bool in) :_bool(in), type(V_BOOL) { }; - Value(double in) :_double(in), type(V_DOUBLE) { }; - Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { }; - Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { }; - Value(Value const& in):_string(0) {plaincopy(in);} - ~Value() { destroy();}; - Value(std::string const& in,Etype _t) :_string(0),type(V_NONE) {SetValue(in,_t);} - - /* Assigment operators */ - Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));} - Value& operator= (int in) throw(WrongType) { return copy(Value(in));} - Value& operator= (bool in) throw(WrongType) { return copy(Value(in));} - Value& operator= (double in) throw(WrongType) { return copy(Value(in));} - Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));} - Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));} - Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));} - - bool operator== (Value const & other); - operator bool () const throw(WrongType); - operator Hex () const throw(WrongType); - operator int () const throw(WrongType); - operator double () const throw(WrongType); - operator char const* () const throw(WrongType); - void SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType); - std::string ToString() const; - -private: - void destroy() throw(); - Value& copy(Value const& in) throw(WrongType); - void plaincopy(Value const& in) throw(); - void set_hex(std::string const& in); - void set_int(std::string const&in); - void set_bool(std::string const& in); - void set_string(std::string const& in); - void set_double(std::string const& in); -}; - -class Property { -public: - struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};}; - const std::string propname; - - Property(std::string const& _propname, Changeable::Value when):propname(_propname),change(when) { } - void Set_values(const char * const * in); - void Set_help(std::string const& str); - char const* Get_help(); - virtual void SetValue(std::string const& str)=0; - Value const& GetValue() const { return value;} - Value const& Get_Default_Value() const { return default_value; } - //CheckValue returns true if value is in suggested_values; - //Type specific properties are encouraged to override this and check for type - //specific features. - virtual bool CheckValue(Value const& in, bool warn); - //Set interval value to in or default if in is invalid. force always sets the value. - void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;} - virtual ~Property(){ } - virtual const std::vector& GetValues() const; - Value::Etype Get_type(){return default_value.type;} - -protected: - Value value; - std::vector suggested_values; - typedef std::vector::iterator iter; - Value default_value; - const Changeable::Value change; -}; - -class Prop_int:public Property { -public: - Prop_int(std::string const& _propname,Changeable::Value when, int _value) - :Property(_propname,when) { - default_value = value = _value; - min = max = -1; - } - Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value) - :Property(_propname,when) { - default_value = value = _value; - min = _min; - max = _max; - } - void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} - void SetValue(std::string const& in); - ~Prop_int(){ } - virtual bool CheckValue(Value const& in, bool warn); -private: - Value min,max; -}; - -class Prop_double:public Property { -public: - Prop_double(std::string const & _propname, Changeable::Value when, double _value) - :Property(_propname,when){ - default_value = value = _value; - } - void SetValue(std::string const& input); - ~Prop_double(){ } -}; - -class Prop_bool:public Property { -public: - Prop_bool(std::string const& _propname, Changeable::Value when, bool _value) - :Property(_propname,when) { - default_value = value = _value; - } - void SetValue(std::string const& in); - ~Prop_bool(){ } -}; - -class Prop_string:public Property{ -public: - Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value) - :Property(_propname,when) { - default_value = value = _value; - } - void SetValue(std::string const& in); - virtual bool CheckValue(Value const& in, bool warn); - ~Prop_string(){ } -}; -class Prop_path:public Prop_string{ -public: - std::string realpath; - Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value) - :Prop_string(_propname,when,_value) { - default_value = value = _value; - realpath = _value; - } - void SetValue(std::string const& in); - ~Prop_path(){ } -}; - -class Prop_hex:public Property { -public: - Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value) - :Property(_propname,when) { - default_value = value = _value; - } - void SetValue(std::string const& in); - ~Prop_hex(){ } -}; - -#define NO_SUCH_PROPERTY "PROP_NOT_EXIST" -class Section { -private: - typedef void (*SectionFunction)(Section*); - /* Wrapper class around startup and shutdown functions. the variable - * canchange indicates it can be called on configuration changes */ - struct Function_wrapper { - SectionFunction function; - bool canchange; - Function_wrapper(SectionFunction const _fun,bool _ch){ - function=_fun; - canchange=_ch; - } - }; - std::list initfunctions; - std::list destroyfunctions; - std::string sectionname; -public: - Section(std::string const& _sectionname):sectionname(_sectionname) { } - - void AddInitFunction(SectionFunction func,bool canchange=false); - void AddDestroyFunction(SectionFunction func,bool canchange=false); - void ExecuteInit(bool initall=true); - void ExecuteDestroy(bool destroyall=true); - const char* GetName() const {return sectionname.c_str();} - - virtual std::string GetPropValue(std::string const& _property) const =0; - virtual void HandleInputline(std::string const& _line)=0; - virtual void PrintData(FILE* outfile) const =0; - virtual ~Section() { /*Children must call executedestroy ! */} -}; - -class Prop_multival; -class Prop_multival_remain; -class Section_prop:public Section { -private: - std::list properties; - typedef std::list::iterator it; - typedef std::list::const_iterator const_it; - -public: - Section_prop(std::string const& _sectionname):Section(_sectionname){} - Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0); - Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); - Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); - Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false); - Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0); -// void Add_double(char const * const _propname, double _value=0.0); - Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); - Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); - - Property* Get_prop(int index); - int Get_int(std::string const& _propname) const; - const char* Get_string(std::string const& _propname) const; - bool Get_bool(std::string const& _propname) const; - Hex Get_hex(std::string const& _propname) const; - double Get_double(std::string const& _propname) const; - Prop_path* Get_path(std::string const& _propname) const; - Prop_multival* Get_multival(std::string const& _propname) const; - Prop_multival_remain* Get_multivalremain(std::string const& _propname) const; - void HandleInputline(std::string const& gegevens); - void PrintData(FILE* outfile) const; - virtual std::string GetPropValue(std::string const& _property) const; - //ExecuteDestroy should be here else the destroy functions use destroyed properties - virtual ~Section_prop(); -}; - -class Prop_multival:public Property{ -protected: - Section_prop* section; - std::string seperator; - void make_default_value(); -public: - Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),seperator(sep) { - default_value = value = ""; - } - Section_prop *GetSection() { return section; } - const Section_prop *GetSection() const { return section; } - virtual void SetValue(std::string const& input); - virtual const std::vector& GetValues() const; - ~Prop_multival() { delete section; } -}; //value bevat totale string. setvalue zet elk van de sub properties en checked die. - -class Prop_multival_remain:public Prop_multival{ -public: - Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ } - - virtual void SetValue(std::string const& input); -}; - - -class Section_line: public Section{ -public: - Section_line(std::string const& _sectionname):Section(_sectionname){} - ~Section_line(){ExecuteDestroy(true);} - void HandleInputline(std::string const& gegevens); - void PrintData(FILE* outfile) const; - virtual std::string GetPropValue(std::string const& _property) const; - std::string data; -}; - -class Module_base { - /* Base for all hardware and software "devices" */ -protected: - Section* m_configuration; -public: - Module_base(Section* configuration){m_configuration=configuration;}; -// Module_base(Section* configuration, SaveState* state) {}; - virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required - /* Returns true if succesful.*/ - virtual bool Change_Config(Section* /*newconfig*/) {return false;} ; -}; -#endif diff --git a/dosbox/support.h b/dosbox/support.h deleted file mode 100644 index 32e1e202..00000000 --- a/dosbox/support.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: support.h,v 1.18 2009-05-27 09:15:41 qbix79 Exp $ */ - -#ifndef DOSBOX_SUPPORT_H -#define DOSBOX_SUPPORT_H - -#include -#include -#include -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -#if defined (_MSC_VER) /* MS Visual C++ */ -#define strcasecmp(a,b) stricmp(a,b) -#define strncasecmp(a,b,n) _strnicmp(a,b,n) -#endif - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -#ifdef HAVE_STRINGS_H -#include -#endif - -void strreplace(char * str,char o,char n); -char *ltrim(char *str); -char *rtrim(char *str); -char *trim(char * str); -char * upcase(char * str); -char * lowcase(char * str); - -bool ScanCMDBool(char * cmd,char const * const check); -char * ScanCMDRemain(char * cmd); -char * StripWord(char *&cmd); -bool IsDecWord(char * word); -bool IsHexWord(char * word); -Bits ConvDecWord(char * word); -Bits ConvHexWord(char * word); - -void upcase(std::string &str); -void lowcase(std::string &str); - -#endif diff --git a/dosbox/timer.cpp b/dosbox/timer.cpp deleted file mode 100644 index 373dad10..00000000 --- a/dosbox/timer.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: timer.cpp,v 1.49 2009-04-10 09:53:04 c2woody Exp $ */ - -#include -#include "dosbox.h" -#include "inout.h" -#include "pic.h" -#include "mem.h" -//#include "mixer.h" -#include "timer.h" -#include "setup.h" - -static INLINE void BIN2BCD(Bit16u& val) { - Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12); - val=temp; -} - -static INLINE void BCD2BIN(Bit16u& val) { - Bit16u temp= (val&0x0f) +((val>>4)&0x0f) *10 +((val>>8)&0x0f) *100 +((val>>12)&0x0f) *1000; - val=temp; -} - -struct PIT_Block { - Bitu cntr; - float delay; - double start; - - Bit16u read_latch; - Bit16u write_latch; - - Bit8u mode; - Bit8u latch_mode; - Bit8u read_state; - Bit8u write_state; - - bool bcd; - bool go_read_latch; - bool new_mode; - bool counterstatus_set; - bool counting; - bool update_count; -}; - -static PIT_Block pit[3]; -static bool gate2; - -static Bit8u latched_timerstatus; -// the timer status can not be overwritten until it is read or the timer was -// reprogrammed. -static bool latched_timerstatus_locked; - -static void PIT0_Event(Bitu /*val*/) { - PIC_ActivateIRQ(0); - if (pit[0].mode != 0) { - pit[0].start += pit[0].delay; - - if (GCC_UNLIKELY(pit[0].update_count)) { - pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[0].update_count=false; - } - PIC_AddEvent(PIT0_Event,pit[0].delay); - } -} - -static bool counter_output(Bitu counter) { - PIT_Block * p=&pit[counter]; - double index=PIC_FullIndex()-p->start; - switch (p->mode) { - case 0: - if (p->new_mode) return false; - if (index>p->delay) return true; - else return false; - break; - case 2: - if (p->new_mode) return true; - index=fmod(index,(double)p->delay); - return index>0; - case 3: - if (p->new_mode) return true; - index=fmod(index,(double)p->delay); - return index*2delay; - case 4: - //Only low on terminal count - // if(fmod(index,(double)p->delay) == 0) return false; //Maybe take one rate tick in consideration - //Easiest solution is to report always high (Space marines uses this mode) - return true; - default: - LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode); - return true; - } -} -static void status_latch(Bitu counter) { - // the timer status can not be overwritten until it is read or the timer was - // reprogrammed. - if(!latched_timerstatus_locked) { - PIT_Block * p=&pit[counter]; - latched_timerstatus=0; - // Timer Status Word - // 0: BCD - // 1-3: Timer mode - // 4-5: read/load mode - // 6: "NULL" - this is 0 if "the counter value is in the counter" ;) - // should rarely be 1 (i.e. on exotic modes) - // 7: OUT - the logic level on the Timer output pin - if(p->bcd)latched_timerstatus|=0x1; - latched_timerstatus|=((p->mode&7)<<1); - if((p->read_state==0)||(p->read_state==3)) latched_timerstatus|=0x30; - else if(p->read_state==1) latched_timerstatus|=0x10; - else if(p->read_state==2) latched_timerstatus|=0x20; - if(counter_output(counter)) latched_timerstatus|=0x80; - if(p->new_mode) latched_timerstatus|=0x40; - // The first thing that is being read from this counter now is the - // counter status. - p->counterstatus_set=true; - latched_timerstatus_locked=true; - } -} -static void counter_latch(Bitu counter) { - /* Fill the read_latch of the selected counter with current count */ - PIT_Block * p=&pit[counter]; - p->go_read_latch=false; - - //If gate2 is disabled don't update the read_latch - if(counter == 2 && !gate2 && p->mode !=1) return; - - double index=PIC_FullIndex()-p->start; - switch (p->mode) { - case 4: /* Software Triggered Strobe */ - case 0: /* Interrupt on Terminal Count */ - /* Counter keeps on counting after passing terminal count */ - if (index>p->delay) { - index-=p->delay; - if(p->bcd) { - index = fmod(index,(1000.0/PIT_TICK_RATE)*10000.0); - p->read_latch = (Bit16u)(9999-index*(PIT_TICK_RATE/1000.0)); - } else { - index = fmod(index,(1000.0/PIT_TICK_RATE)*(double)0x10000); - p->read_latch = (Bit16u)(0xffff-index*(PIT_TICK_RATE/1000.0)); - } - } else { - p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); - } - break; - case 1: // countdown - if(p->counting) { - if (index>p->delay) { // has timed out - p->read_latch = 0xffff; //unconfirmed - } else { - p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0)); - } - } - break; - case 2: /* Rate Generator */ - index=fmod(index,(double)p->delay); - p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); - break; - case 3: /* Square Wave Rate Generator */ - index=fmod(index,(double)p->delay); - index*=2; - if (index>p->delay) index-=p->delay; - p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr); - // In mode 3 it never returns odd numbers LSB (if odd number is written 1 will be - // subtracted on first clock and then always 2) - // fixes "Corncob 3D" - p->read_latch&=0xfffe; - break; - default: - LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading counter %d",p->mode,counter); - p->read_latch=0xffff; - break; - } -} - - -static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) { -//LOG(LOG_PIT,LOG_ERROR)("port %X write:%X state:%X",port,val,pit[port-0x40].write_state); - Bitu counter=port-0x40; - PIT_Block * p=&pit[counter]; - if(p->bcd == true) BIN2BCD(p->write_latch); - - switch (p->write_state) { - case 0: - p->write_latch = p->write_latch | ((val & 0xff) << 8); - p->write_state = 3; - break; - case 3: - p->write_latch = val & 0xff; - p->write_state = 0; - break; - case 1: - p->write_latch = val & 0xff; - break; - case 2: - p->write_latch = (val & 0xff) << 8; - break; - } - if (p->bcd==true) BCD2BIN(p->write_latch); - if (p->write_state != 0) { - if (p->write_latch == 0) { - if (p->bcd == false) p->cntr = 0x10000; - else p->cntr=9999; - } else p->cntr = p->write_latch; - - if ((!p->new_mode) && (p->mode == 2) && (counter == 0)) { - // In mode 2 writing another value has no direct effect on the count - // until the old one has run out. This might apply to other modes too. - // This is not fixed for PIT2 yet!! - p->update_count=true; - return; - } - p->start=PIC_FullIndex(); - p->delay=(1000.0f/((float)PIT_TICK_RATE/(float)p->cntr)); - - switch (counter) { - case 0x00: /* Timer hooked to IRQ 0 */ - if (p->new_mode || p->mode == 0 ) { - if(p->mode==0) PIC_RemoveEvents(PIT0_Event); // DoWhackaDo demo - PIC_AddEvent(PIT0_Event,p->delay); - } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word"); - LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.4f Hz mode %d",1000.0/p->delay,p->mode); - break; - case 0x02: /* Timer hooked to PC-Speaker */ -// LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode); -// PCSPEAKER_SetCounter(p->cntr,p->mode); - // HACK. A1060 bios hardware diagnostics reads latch with timer gate 2 disabled - // and expects original written value. - if (!gate2) - p->read_latch = p->write_latch; - break; - default: - LOG(LOG_PIT,LOG_ERROR)("PIT:Illegal timer selected for writing"); - } - p->new_mode=false; - } -} - -static Bitu read_latch(Bitu port,Bitu /*iolen*/) { -//LOG(LOG_PIT,LOG_ERROR)("port read %X",port); - Bit32u counter=port-0x40; - Bit8u ret=0; - if(GCC_UNLIKELY(pit[counter].counterstatus_set)){ - pit[counter].counterstatus_set = false; - latched_timerstatus_locked = false; - ret = latched_timerstatus; - } else { - if (pit[counter].go_read_latch == true) - counter_latch(counter); - - if( pit[counter].bcd == true) BIN2BCD(pit[counter].read_latch); - - switch (pit[counter].read_state) { - case 0: /* read MSB & return to state 3 */ - ret=(pit[counter].read_latch >> 8) & 0xff; - pit[counter].read_state = 3; - pit[counter].go_read_latch = true; - break; - case 3: /* read LSB followed by MSB */ - ret = pit[counter].read_latch & 0xff; - pit[counter].read_state = 0; - break; - case 1: /* read LSB */ - ret = pit[counter].read_latch & 0xff; - pit[counter].go_read_latch = true; - break; - case 2: /* read MSB */ - ret = (pit[counter].read_latch >> 8) & 0xff; - pit[counter].go_read_latch = true; - break; - default: - E_Exit("Timer.cpp: error in readlatch"); - break; - } - if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch); - } - return ret; -} - -static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { -//LOG(LOG_PIT,LOG_ERROR)("port 43 %X",val); - Bitu latch=(val >> 6) & 0x03; - switch (latch) { - case 0: - case 1: - case 2: - if ((val & 0x30) == 0) { - /* Counter latch command */ - counter_latch(latch); - } else { - pit[latch].bcd = (val&1)>0; - if (val & 1) { - if(pit[latch].cntr>=9999) pit[latch].cntr=9999; - } - - // Timer is being reprogrammed, unlock the status - if(pit[latch].counterstatus_set) { - pit[latch].counterstatus_set=false; - latched_timerstatus_locked=false; - } - pit[latch].update_count = false; - pit[latch].counting = false; - pit[latch].read_state = (val >> 4) & 0x03; - pit[latch].write_state = (val >> 4) & 0x03; - Bit8u mode = (val >> 1) & 0x07; - if (mode > 5) - mode -= 4; //6,7 become 2 and 3 - - /* Don't set it directly so counter_output uses the old mode */ - /* That's theory. It breaks panic. So set it here again */ - if(!pit[latch].mode) pit[latch].mode = mode; - - /* If the line goes from low to up => generate irq. - * ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: ) - * If the line goes to low => disable irq. - * Mode 0 starts with a low line. (so always disable irq) - * Mode 2,3 start with a high line. - * counter_output tells if the current counter is high or low - * So actually a mode 2 timer enables and disables irq al the time. (not handled) */ - - if (latch == 0) { - PIC_RemoveEvents(PIT0_Event); - if (!counter_output(0) && mode) { - PIC_ActivateIRQ(0); - //Don't raise instantaniously. (Origamo) - if(CPU_Cycles < 25) CPU_Cycles = 25; - } - if(!mode) - PIC_DeActivateIRQ(0); - } - pit[latch].new_mode = true; - pit[latch].mode = mode; //Set the correct mode (here) - } - break; - case 3: - if ((val & 0x20)==0) { /* Latch multiple pit counters */ - if (val & 0x02) counter_latch(0); - if (val & 0x04) counter_latch(1); - if (val & 0x08) counter_latch(2); - } - // status and values can be latched simultaneously - if ((val & 0x10)==0) { /* Latch status words */ - // but only 1 status can be latched simultaneously - if (val & 0x02) status_latch(0); - else if (val & 0x04) status_latch(1); - else if (val & 0x08) status_latch(2); - } - break; - } -} - -bool TIMER_GetGate2(void) -{ - if (!gate2) { - return true; - } - return false; -} - -void TIMER_SetGate2(bool in) { - //No changes if gate doesn't change - if(gate2 == in) return; - Bit8u & mode=pit[2].mode; - switch(mode) { - case 0: - if(in) pit[2].start = PIC_FullIndex(); - else { - //Fill readlatch and store it. - counter_latch(2); - pit[2].cntr = pit[2].read_latch; - } - break; - case 1: - // gate 1 on: reload counter; off: nothing - if(in) { - pit[2].counting = true; - pit[2].start = PIC_FullIndex(); - } - break; - case 2: - case 3: - //If gate is enabled restart counting. If disable store the current read_latch - if(in) pit[2].start = PIC_FullIndex(); - else counter_latch(2); - break; - case 4: - case 5: - LOG(LOG_MISC,LOG_WARN)("unsupported gate 2 mode %x",mode); - break; - } - gate2 = in; //Set it here so the counter_latch above works -} - -void x86_timer_write(Bitu port, Bitu val) -{ - switch (port) - { - case 0x40: - case 0x41: - case 0x42: - write_latch(port, val, 1); - break; - case 0x43: - write_p43(port, val, 1); - break; - } -} -Bitu x86_timer_read(Bitu port) -{ - switch (port) - { - case 0x40: - case 0x41: - case 0x42: - return read_latch(port, 1); - break; - } - return 0; -} - -class TIMER:public Module_base{ -//private: -// IO_ReadHandleObject ReadHandler[4]; -// IO_WriteHandleObject WriteHandler[4]; -public: - TIMER(Section* configuration):Module_base(configuration){ -#if 0 - WriteHandler[0].Install(0x40,write_latch,IO_MB); - // WriteHandler[1].Install(0x41,write_latch,IO_MB); - WriteHandler[2].Install(0x42,write_latch,IO_MB); - WriteHandler[3].Install(0x43,write_p43,IO_MB); - ReadHandler[0].Install(0x40,read_latch,IO_MB); - ReadHandler[1].Install(0x41,read_latch,IO_MB); - ReadHandler[2].Install(0x42,read_latch,IO_MB); -#endif - /* Setup Timer 0 */ - pit[0].cntr=0x10000; - pit[0].write_state = 3; - pit[0].read_state = 3; - pit[0].read_latch=0; - pit[0].write_latch=0; - pit[0].mode=3; - pit[0].bcd = false; - pit[0].go_read_latch = true; - pit[0].counterstatus_set = false; - pit[0].update_count = false; - - pit[1].bcd = false; - pit[1].write_state = 1; - pit[1].read_state = 1; - pit[1].go_read_latch = true; - pit[1].cntr = 18; - pit[1].mode = 2; - pit[1].write_state = 3; - pit[1].counterstatus_set = false; - - pit[2].read_latch=1320; /* MadTv1 */ - pit[2].write_state = 3; /* Chuck Yeager */ - pit[2].read_state = 3; - pit[2].mode=3; - pit[2].bcd=false; - pit[2].cntr=1320; - pit[2].go_read_latch=true; - pit[2].counterstatus_set = false; - pit[2].counting = false; - - pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); - pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - - latched_timerstatus_locked=false; - gate2 = false; - PIC_AddEvent(PIT0_Event,pit[0].delay); - } - ~TIMER(){ - PIC_RemoveEvents(PIT0_Event); - } -}; -static TIMER* test; - -void TIMER_Destroy(Section*){ - delete test; -} -void TIMER_Init(Section* sec) { - test = new TIMER(sec); - sec->AddDestroyFunction(&TIMER_Destroy); -} diff --git a/dosbox/timer.h b/dosbox/timer.h deleted file mode 100644 index 28268093..00000000 --- a/dosbox/timer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2002-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_TIMER_H -#define DOSBOX_TIMER_H - -/* underlying clock rate in HZ */ -//#include - -#define PIT_TICK_RATE 1193182 - -//#define GetTicks() SDL_GetTicks() - -typedef void (*TIMER_TickHandler)(void); - -/* Register a function that gets called everytime if 1 or more ticks pass */ -void TIMER_AddTickHandler(TIMER_TickHandler handler); -void TIMER_DelTickHandler(TIMER_TickHandler handler); - -/* This will add 1 milliscond to all timers */ -void TIMER_AddTick(void); - -#endif diff --git a/fake86_cpu.cpp b/fake86_cpu.cpp deleted file mode 100644 index 717b7c59..00000000 --- a/fake86_cpu.cpp +++ /dev/null @@ -1,3577 +0,0 @@ -/* - Fake86: A portable, open-source 8086 PC emulator. - Copyright (C)2010-2012 Mike Chambers - - 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. -*/ - -/* cpu.c: functions to emulate the 8086/V20 CPU in software. the heart of Fake86. */ - -#include -#include - -#define CPU_V20 -static int x86_cpu_v20; - -extern void write_log(const char*,...); - - -#define regax 0 -#define regcx 1 -#define regdx 2 -#define regbx 3 -#define regsp 4 -#define regbp 5 -#define regsi 6 -#define regdi 7 -#define reges 0 -#define regcs 1 -#define regss 2 -#define regds 3 - -#ifdef __BIG_ENDIAN__ -#define regal 1 -#define regah 0 -#define regcl 3 -#define regch 2 -#define regdl 5 -#define regdh 4 -#define regbl 7 -#define regbh 6 -#else -#define regal 0 -#define regah 1 -#define regcl 2 -#define regch 3 -#define regdl 4 -#define regdh 5 -#define regbl 6 -#define regbh 7 -#endif - -union _bytewordregs_ { - uint16_t wordregs[8]; - uint8_t byteregs[8]; -}; - -#define StepIP(x) ip += x -#define getmem8(x, y) read86(segbase(x) + y) -#define getmem16(x, y) readw86(segbase(x) + y) -#define putmem8(x, y, z) write86(segbase(x) + y, z) -#define putmem16(x, y, z) writew86(segbase(x) + y, z) -#define signext(value) (int16_t)(int8_t)(value) -#define signext32(value) (int32_t)(int16_t)(value) -#define getreg16(regid) regs.wordregs[regid] -#define getreg8(regid) regs.byteregs[byteregtable[regid]] -#define putreg16(regid, writeval) regs.wordregs[regid] = writeval -#define putreg8(regid, writeval) regs.byteregs[byteregtable[regid]] = writeval -#define getsegreg(regid) segregs[regid] -#define putsegreg(regid, writeval) segregs[regid] = writeval -#define segbase(x) ((uint32_t) x << 4) - -#if 0 -#include "config.h" -#include -#include -#include "cpu.h" -#include "i8259.h" -#include "i8253.h" - -extern struct i8253_s i8253; - -extern struct structpic i8259; -#endif - -uint64_t curtimer, lasttimer, timerfreq; - -static uint8_t byteregtable[8] = { regal, regcl, regdl, regbl, regah, regch, regdh, regbh }; - -static const uint8_t parity[0x100] = { - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 -}; - -#if 0 -uint8_t RAM[0x100000], readonly[0x100000]; -#endif -static uint8_t opcode, segoverride, reptype, bootdrive = 0, hdcount = 0; -static uint16_t segregs[4], savecs, saveip, ip, useseg, oldsp; -static uint8_t tempcf, oldcf, cf, pf, af, zf, sf, tf, ifl, df, of, mode, reg, rm; -static uint16_t oper1, oper2, res16, disp16, temp16, dummy, stacksize, frametemp; -static uint8_t oper1b, oper2b, res8, disp8, temp8, nestlev, addrbyte; -static uint32_t temp1, temp2, temp3, temp4, temp5, temp32, tempaddr32, ea; -static int32_t result; -static uint64_t totalexec; - -#if 0 -extern uint16_t VGA_SC[0x100], VGA_CRTC[0x100], VGA_ATTR[0x100], VGA_GC[0x100]; -extern uint8_t updatedscreen; -#endif - -static union _bytewordregs_ regs; - -#if 0 -uint8_t portram[0x10000]; -uint8_t running = 0, debugmode, showcsip, verbose; -uint8_t ethif; -#endif -static int verbose = 1; -static int running = 1; - -#if 0 -extern uint8_t vidmode; -extern uint8_t verbose; - -extern void vidinterrupt(); - -extern uint8_t readVGA (uint32_t addr32); -#endif - -void intcall86 (uint8_t intnum); - -#define makeflagsword() \ - ( \ - 2 | (uint16_t) cf | ((uint16_t) pf << 2) | ((uint16_t) af << 4) | ((uint16_t) zf << 6) | ((uint16_t) sf << 7) | \ - ((uint16_t) tf << 8) | ((uint16_t) ifl << 9) | ((uint16_t) df << 10) | ((uint16_t) of << 11) \ - ) - -#define decodeflagsword(x) { \ - temp16 = x; \ - cf = temp16 & 1; \ - pf = (temp16 >> 2) & 1; \ - af = (temp16 >> 4) & 1; \ - zf = (temp16 >> 6) & 1; \ - sf = (temp16 >> 7) & 1; \ - tf = (temp16 >> 8) & 1; \ - ifl = (temp16 >> 9) & 1; \ - df = (temp16 >> 10) & 1; \ - of = (temp16 >> 11) & 1; \ - } - -#if 0 -extern void writeVGA (uint32_t addr32, uint8_t value); -#endif -extern void portout (uint16_t portnum, uint8_t value); -extern void portout16 (uint16_t portnum, uint16_t value); -extern uint8_t portin (uint16_t portnum); -extern uint16_t portin16 (uint16_t portnum); - -void write86(uint32_t addr32, uint8_t value); -void writew86(uint32_t addr32, uint16_t value); -uint8_t read86(uint32_t addr32); -uint16_t readw86(uint32_t addr32); - -void flag_szp8 (uint8_t value) { - if (!value) { - zf = 1; - } - else { - zf = 0; /* set or clear zero flag */ - } - - if (value & 0x80) { - sf = 1; - } - else { - sf = 0; /* set or clear sign flag */ - } - - pf = parity[value]; /* retrieve parity state from lookup table */ -} - -void flag_szp16 (uint16_t value) { - if (!value) { - zf = 1; - } - else { - zf = 0; /* set or clear zero flag */ - } - - if (value & 0x8000) { - sf = 1; - } - else { - sf = 0; /* set or clear sign flag */ - } - - pf = parity[value & 255]; /* retrieve parity state from lookup table */ -} - -void flag_log8 (uint8_t value) { - flag_szp8 (value); - cf = 0; - of = 0; /* bitwise logic ops always clear carry and overflow */ -} - -void flag_log16 (uint16_t value) { - flag_szp16 (value); - cf = 0; - of = 0; /* bitwise logic ops always clear carry and overflow */ -} - -void flag_adc8 (uint8_t v1, uint8_t v2, uint8_t v3) { - - /* v1 = destination operand, v2 = source operand, v3 = carry flag */ - uint16_t dst; - - dst = (uint16_t) v1 + (uint16_t) v2 + (uint16_t) v3; - flag_szp8 ( (uint8_t) dst); - if ( ( (dst ^ v1) & (dst ^ v2) & 0x80) == 0x80) { - of = 1; - } - else { - of = 0; /* set or clear overflow flag */ - } - - if (dst & 0xFF00) { - cf = 1; - } - else { - cf = 0; /* set or clear carry flag */ - } - - if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) { - af = 1; - } - else { - af = 0; /* set or clear auxilliary flag */ - } -} - -void flag_adc16 (uint16_t v1, uint16_t v2, uint16_t v3) { - - uint32_t dst; - - dst = (uint32_t) v1 + (uint32_t) v2 + (uint32_t) v3; - flag_szp16 ( (uint16_t) dst); - if ( ( ( (dst ^ v1) & (dst ^ v2) ) & 0x8000) == 0x8000) { - of = 1; - } - else { - of = 0; - } - - if (dst & 0xFFFF0000) { - cf = 1; - } - else { - cf = 0; - } - - if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_add8 (uint8_t v1, uint8_t v2) { - /* v1 = destination operand, v2 = source operand */ - uint16_t dst; - - dst = (uint16_t) v1 + (uint16_t) v2; - flag_szp8 ( (uint8_t) dst); - if (dst & 0xFF00) { - cf = 1; - } - else { - cf = 0; - } - - if ( ( (dst ^ v1) & (dst ^ v2) & 0x80) == 0x80) { - of = 1; - } - else { - of = 0; - } - - if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_add16 (uint16_t v1, uint16_t v2) { - /* v1 = destination operand, v2 = source operand */ - uint32_t dst; - - dst = (uint32_t) v1 + (uint32_t) v2; - flag_szp16 ( (uint16_t) dst); - if (dst & 0xFFFF0000) { - cf = 1; - } - else { - cf = 0; - } - - if ( ( (dst ^ v1) & (dst ^ v2) & 0x8000) == 0x8000) { - of = 1; - } - else { - of = 0; - } - - if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_sbb8 (uint8_t v1, uint8_t v2, uint8_t v3) { - - /* v1 = destination operand, v2 = source operand, v3 = carry flag */ - uint16_t dst; - - v2 += v3; - dst = (uint16_t) v1 - (uint16_t) v2; - flag_szp8 ( (uint8_t) dst); - if (dst & 0xFF00) { - cf = 1; - } - else { - cf = 0; - } - - if ( (dst ^ v1) & (v1 ^ v2) & 0x80) { - of = 1; - } - else { - of = 0; - } - - if ( (v1 ^ v2 ^ dst) & 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_sbb16 (uint16_t v1, uint16_t v2, uint16_t v3) { - - /* v1 = destination operand, v2 = source operand, v3 = carry flag */ - uint32_t dst; - - v2 += v3; - dst = (uint32_t) v1 - (uint32_t) v2; - flag_szp16 ( (uint16_t) dst); - if (dst & 0xFFFF0000) { - cf = 1; - } - else { - cf = 0; - } - - if ( (dst ^ v1) & (v1 ^ v2) & 0x8000) { - of = 1; - } - else { - of = 0; - } - - if ( (v1 ^ v2 ^ dst) & 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_sub8 (uint8_t v1, uint8_t v2) { - - /* v1 = destination operand, v2 = source operand */ - uint16_t dst; - - dst = (uint16_t) v1 - (uint16_t) v2; - flag_szp8 ( (uint8_t) dst); - if (dst & 0xFF00) { - cf = 1; - } - else { - cf = 0; - } - - if ( (dst ^ v1) & (v1 ^ v2) & 0x80) { - of = 1; - } - else { - of = 0; - } - - if ( (v1 ^ v2 ^ dst) & 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void flag_sub16 (uint16_t v1, uint16_t v2) { - - /* v1 = destination operand, v2 = source operand */ - uint32_t dst; - - dst = (uint32_t) v1 - (uint32_t) v2; - flag_szp16 ( (uint16_t) dst); - if (dst & 0xFFFF0000) { - cf = 1; - } - else { - cf = 0; - } - - if ( (dst ^ v1) & (v1 ^ v2) & 0x8000) { - of = 1; - } - else { - of = 0; - } - - if ( (v1 ^ v2 ^ dst) & 0x10) { - af = 1; - } - else { - af = 0; - } -} - -void op_adc8() { - res8 = oper1b + oper2b + cf; - flag_adc8 (oper1b, oper2b, cf); -} - -void op_adc16() { - res16 = oper1 + oper2 + cf; - flag_adc16 (oper1, oper2, cf); -} - -void op_add8() { - res8 = oper1b + oper2b; - flag_add8 (oper1b, oper2b); -} - -void op_add16() { - res16 = oper1 + oper2; - flag_add16 (oper1, oper2); -} - -void op_and8() { - res8 = oper1b & oper2b; - flag_log8 (res8); -} - -void op_and16() { - res16 = oper1 & oper2; - flag_log16 (res16); -} - -void op_or8() { - res8 = oper1b | oper2b; - flag_log8 (res8); -} - -void op_or16() { - res16 = oper1 | oper2; - flag_log16 (res16); -} - -void op_xor8() { - res8 = oper1b ^ oper2b; - flag_log8 (res8); -} - -void op_xor16() { - res16 = oper1 ^ oper2; - flag_log16 (res16); -} - -void op_sub8() { - res8 = oper1b - oper2b; - flag_sub8 (oper1b, oper2b); -} - -void op_sub16() { - res16 = oper1 - oper2; - flag_sub16 (oper1, oper2); -} - -void op_sbb8() { - res8 = oper1b - (oper2b + cf); - flag_sbb8 (oper1b, oper2b, cf); -} - -void op_sbb16() { - res16 = oper1 - (oper2 + cf); - flag_sbb16 (oper1, oper2, cf); -} - -#define modregrm() { \ - addrbyte = getmem8(segregs[regcs], ip); \ - StepIP(1); \ - mode = addrbyte >> 6; \ - reg = (addrbyte >> 3) & 7; \ - rm = addrbyte & 7; \ - switch(mode) \ - { \ - case 0: \ - if(rm == 6) { \ - disp16 = getmem16(segregs[regcs], ip); \ - StepIP(2); \ - } \ - if(((rm == 2) || (rm == 3)) && !segoverride) { \ - useseg = segregs[regss]; \ - } \ - break; \ - \ - case 1: \ - disp16 = signext(getmem8(segregs[regcs], ip)); \ - StepIP(1); \ - if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \ - useseg = segregs[regss]; \ - } \ - break; \ - \ - case 2: \ - disp16 = getmem16(segregs[regcs], ip); \ - StepIP(2); \ - if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \ - useseg = segregs[regss]; \ - } \ - break; \ - \ - default: \ - disp8 = 0; \ - disp16 = 0; \ - } \ - } - -void getea (uint8_t rmval) { - uint32_t tempea; - - tempea = 0; - switch (mode) { - case 0: - switch (rmval) { - case 0: - tempea = regs.wordregs[regbx] + regs.wordregs[regsi]; - break; - case 1: - tempea = regs.wordregs[regbx] + regs.wordregs[regdi]; - break; - case 2: - tempea = regs.wordregs[regbp] + regs.wordregs[regsi]; - break; - case 3: - tempea = regs.wordregs[regbp] + regs.wordregs[regdi]; - break; - case 4: - tempea = regs.wordregs[regsi]; - break; - case 5: - tempea = regs.wordregs[regdi]; - break; - case 6: - tempea = disp16; - break; - case 7: - tempea = regs.wordregs[regbx]; - break; - } - break; - - case 1: - case 2: - switch (rmval) { - case 0: - tempea = regs.wordregs[regbx] + regs.wordregs[regsi] + disp16; - break; - case 1: - tempea = regs.wordregs[regbx] + regs.wordregs[regdi] + disp16; - break; - case 2: - tempea = regs.wordregs[regbp] + regs.wordregs[regsi] + disp16; - break; - case 3: - tempea = regs.wordregs[regbp] + regs.wordregs[regdi] + disp16; - break; - case 4: - tempea = regs.wordregs[regsi] + disp16; - break; - case 5: - tempea = regs.wordregs[regdi] + disp16; - break; - case 6: - tempea = regs.wordregs[regbp] + disp16; - break; - case 7: - tempea = regs.wordregs[regbx] + disp16; - break; - } - break; - } - - ea = (tempea & 0xFFFF) + (useseg << 4); -} - -void push (uint16_t pushval) { - putreg16 (regsp, getreg16 (regsp) - 2); - putmem16 (segregs[regss], getreg16 (regsp), pushval); -} - -uint16_t pop() { - - uint16_t tempval; - - tempval = getmem16 (segregs[regss], getreg16 (regsp) ); - putreg16 (regsp, getreg16 (regsp) + 2); - return tempval; -} - -void reset86(int v20) { - segregs[regcs] = 0xFFFF; - ip = 0x0000; - x86_cpu_v20 = v20; - //regs.wordregs[regsp] = 0xFFFE; -} - -uint16_t readrm16 (uint8_t rmval) { - if (mode < 3) { - getea (rmval); - return read86 (ea) | ( (uint16_t) read86 (ea + 1) << 8); - } - else { - return getreg16 (rmval); - } -} - -uint8_t readrm8 (uint8_t rmval) { - if (mode < 3) { - getea (rmval); - return read86 (ea); - } - else { - return getreg8 (rmval); - } -} - -void writerm16 (uint8_t rmval, uint16_t value) { - if (mode < 3) { - getea (rmval); - write86 (ea, value & 0xFF); - write86 (ea + 1, value >> 8); - } - else { - putreg16 (rmval, value); - } -} - -void writerm8 (uint8_t rmval, uint8_t value) { - if (mode < 3) { - getea (rmval); - write86 (ea, value); - } - else { - putreg8 (rmval, value); - } -} - -uint8_t op_grp2_8 (uint8_t cnt) { - - uint16_t s; - uint16_t shift; - uint16_t oldcf; - uint16_t msb; - - s = oper1b; - oldcf = cf; - if (x86_cpu_v20) - cnt &= 0x1F; - switch (reg) { - case 0: /* ROL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - if (s & 0x80) { - cf = 1; - } - else { - cf = 0; - } - - s = s << 1; - s = s | cf; - } - - if (cnt == 1) { - of = cf ^ ( (s >> 7) & 1); - } - break; - - case 1: /* ROR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - cf = s & 1; - s = (s >> 1) | (cf << 7); - } - - if (cnt == 1) { - of = (s >> 7) ^ ( (s >> 6) & 1); - } - break; - - case 2: /* RCL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - oldcf = cf; - if (s & 0x80) { - cf = 1; - } - else { - cf = 0; - } - - s = s << 1; - s = s | oldcf; - } - - if (cnt == 1) { - of = cf ^ ( (s >> 7) & 1); - } - break; - - case 3: /* RCR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - oldcf = cf; - cf = s & 1; - s = (s >> 1) | (oldcf << 7); - } - - if (cnt == 1) { - of = (s >> 7) ^ ( (s >> 6) & 1); - } - break; - - case 4: - case 6: /* SHL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - if (s & 0x80) { - cf = 1; - } - else { - cf = 0; - } - - s = (s << 1) & 0xFF; - } - - if ( (cnt == 1) && (cf == (s >> 7) ) ) { - of = 0; - } - else { - of = 1; - } - - flag_szp8 ( (uint8_t) s); - break; - - case 5: /* SHR r/m8 */ - if ( (cnt == 1) && (s & 0x80) ) { - of = 1; - } - else { - of = 0; - } - - for (shift = 1; shift <= cnt; shift++) { - cf = s & 1; - s = s >> 1; - } - - flag_szp8 ( (uint8_t) s); - break; - - case 7: /* SAR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - msb = s & 0x80; - cf = s & 1; - s = (s >> 1) | msb; - } - - of = 0; - flag_szp8 ( (uint8_t) s); - break; - } - - return s & 0xFF; -} - -uint16_t op_grp2_16 (uint8_t cnt) { - - uint32_t s; - uint32_t shift; - uint32_t oldcf; - uint32_t msb; - - s = oper1; - oldcf = cf; - if (x86_cpu_v20) - cnt &= 0x1F; - switch (reg) { - case 0: /* ROL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - if (s & 0x8000) { - cf = 1; - } - else { - cf = 0; - } - - s = s << 1; - s = s | cf; - } - - if (cnt == 1) { - of = cf ^ ( (s >> 15) & 1); - } - break; - - case 1: /* ROR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - cf = s & 1; - s = (s >> 1) | (cf << 15); - } - - if (cnt == 1) { - of = (s >> 15) ^ ( (s >> 14) & 1); - } - break; - - case 2: /* RCL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - oldcf = cf; - if (s & 0x8000) { - cf = 1; - } - else { - cf = 0; - } - - s = s << 1; - s = s | oldcf; - } - - if (cnt == 1) { - of = cf ^ ( (s >> 15) & 1); - } - break; - - case 3: /* RCR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - oldcf = cf; - cf = s & 1; - s = (s >> 1) | (oldcf << 15); - } - - if (cnt == 1) { - of = (s >> 15) ^ ( (s >> 14) & 1); - } - break; - - case 4: - case 6: /* SHL r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - if (s & 0x8000) { - cf = 1; - } - else { - cf = 0; - } - - s = (s << 1) & 0xFFFF; - } - - if ( (cnt == 1) && (cf == (s >> 15) ) ) { - of = 0; - } - else { - of = 1; - } - - flag_szp16 ( (uint16_t) s); - break; - - case 5: /* SHR r/m8 */ - if ( (cnt == 1) && (s & 0x8000) ) { - of = 1; - } - else { - of = 0; - } - - for (shift = 1; shift <= cnt; shift++) { - cf = s & 1; - s = s >> 1; - } - - flag_szp16 ( (uint16_t) s); - break; - - case 7: /* SAR r/m8 */ - for (shift = 1; shift <= cnt; shift++) { - msb = s & 0x8000; - cf = s & 1; - s = (s >> 1) | msb; - } - - of = 0; - flag_szp16 ( (uint16_t) s); - break; - } - - return (uint16_t) s & 0xFFFF; -} - -void op_div8 (uint16_t valdiv, uint8_t divisor) { - if (divisor == 0) { - intcall86 (0); - return; - } - - if ( (valdiv / (uint16_t) divisor) > 0xFF) { - intcall86 (0); - return; - } - - regs.byteregs[regah] = valdiv % (uint16_t) divisor; - regs.byteregs[regal] = valdiv / (uint16_t) divisor; -} - -void op_idiv8 (uint16_t valdiv, uint8_t divisor) { - - uint16_t s1; - uint16_t s2; - uint16_t d1; - uint16_t d2; - int sign; - - if (divisor == 0) { - intcall86 (0); - return; - } - - s1 = valdiv; - s2 = divisor; - sign = ( ( (s1 ^ s2) & 0x8000) != 0); - s1 = (s1 < 0x8000) ? s1 : ( (~s1 + 1) & 0xffff); - s2 = (s2 < 0x8000) ? s2 : ( (~s2 + 1) & 0xffff); - d1 = s1 / s2; - d2 = s1 % s2; - if (d1 & 0xFF00) { - intcall86 (0); - return; - } - - if (sign) { - d1 = (~d1 + 1) & 0xff; - d2 = (~d2 + 1) & 0xff; - } - - regs.byteregs[regah] = (uint8_t) d2; - regs.byteregs[regal] = (uint8_t) d1; -} - -void op_grp3_8() { - oper1 = signext (oper1b); - oper2 = signext (oper2b); - switch (reg) { - case 0: - case 1: /* TEST */ - flag_log8 (oper1b & getmem8 (segregs[regcs], ip) ); - StepIP (1); - break; - - case 2: /* NOT */ - res8 = ~oper1b; - break; - - case 3: /* NEG */ - res8 = (~oper1b) + 1; - flag_sub8 (0, oper1b); - if (res8 == 0) { - cf = 0; - } - else { - cf = 1; - } - break; - - case 4: /* MUL */ - temp1 = (uint32_t) oper1b * (uint32_t) regs.byteregs[regal]; - putreg16 (regax, temp1 & 0xFFFF); - flag_szp8 ( (uint8_t) temp1); - if (regs.byteregs[regah]) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - - if (!x86_cpu_v20) - zf = 0; - break; - - case 5: /* IMUL */ - oper1 = signext (oper1b); - temp1 = signext (regs.byteregs[regal]); - temp2 = oper1; - if ( (temp1 & 0x80) == 0x80) { - temp1 = temp1 | 0xFFFFFF00; - } - - if ( (temp2 & 0x80) == 0x80) { - temp2 = temp2 | 0xFFFFFF00; - } - - temp3 = (temp1 * temp2) & 0xFFFF; - putreg16 (regax, temp3 & 0xFFFF); - if (regs.byteregs[regah]) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - if (!x86_cpu_v20) - zf = 0; - break; - - case 6: /* DIV */ - op_div8 (getreg16 (regax), oper1b); - break; - - case 7: /* IDIV */ - op_idiv8 (getreg16 (regax), oper1b); - break; - } -} - -void op_div16 (uint32_t valdiv, uint16_t divisor) { - if (divisor == 0) { - intcall86 (0); - return; - } - - if ( (valdiv / (uint32_t) divisor) > 0xFFFF) { - intcall86 (0); - return; - } - - putreg16 (regdx, valdiv % (uint32_t) divisor); - putreg16 (regax, valdiv / (uint32_t) divisor); -} - -void op_idiv16 (uint32_t valdiv, uint16_t divisor) { - - uint32_t d1; - uint32_t d2; - uint32_t s1; - uint32_t s2; - int sign; - - if (divisor == 0) { - intcall86 (0); - return; - } - - s1 = valdiv; - s2 = divisor; - s2 = (s2 & 0x8000) ? (s2 | 0xffff0000) : s2; - sign = ( ( (s1 ^ s2) & 0x80000000) != 0); - s1 = (s1 < 0x80000000) ? s1 : ( (~s1 + 1) & 0xffffffff); - s2 = (s2 < 0x80000000) ? s2 : ( (~s2 + 1) & 0xffffffff); - d1 = s1 / s2; - d2 = s1 % s2; - if (d1 & 0xFFFF0000) { - intcall86 (0); - return; - } - - if (sign) { - d1 = (~d1 + 1) & 0xffff; - d2 = (~d2 + 1) & 0xffff; - } - - putreg16 (regax, d1); - putreg16 (regdx, d2); -} - -void op_grp3_16() { - switch (reg) { - case 0: - case 1: /* TEST */ - flag_log16 (oper1 & getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 2: /* NOT */ - res16 = ~oper1; - break; - - case 3: /* NEG */ - res16 = (~oper1) + 1; - flag_sub16 (0, oper1); - if (res16) { - cf = 1; - } - else { - cf = 0; - } - break; - - case 4: /* MUL */ - temp1 = (uint32_t) oper1 * (uint32_t) getreg16 (regax); - putreg16 (regax, temp1 & 0xFFFF); - putreg16 (regdx, temp1 >> 16); - flag_szp16 ( (uint16_t) temp1); - if (getreg16 (regdx) ) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - if (!x86_cpu_v20) - zf = 0; - break; - - case 5: /* IMUL */ - temp1 = getreg16 (regax); - temp2 = oper1; - if (temp1 & 0x8000) { - temp1 |= 0xFFFF0000; - } - - if (temp2 & 0x8000) { - temp2 |= 0xFFFF0000; - } - - temp3 = temp1 * temp2; - putreg16 (regax, temp3 & 0xFFFF); /* into register ax */ - putreg16 (regdx, temp3 >> 16); /* into register dx */ - if (getreg16 (regdx) ) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - if (!x86_cpu_v20) - zf = 0; - break; - - case 6: /* DIV */ - op_div16 ( ( (uint32_t) getreg16 (regdx) << 16) + getreg16 (regax), oper1); - break; - - case 7: /* DIV */ - op_idiv16 ( ( (uint32_t) getreg16 (regdx) << 16) + getreg16 (regax), oper1); - break; - } -} - -void op_grp5() { - switch (reg) { - case 0: /* INC Ev */ - oper2 = 1; - tempcf = cf; - op_add16(); - cf = tempcf; - writerm16 (rm, res16); - break; - - case 1: /* DEC Ev */ - oper2 = 1; - tempcf = cf; - op_sub16(); - cf = tempcf; - writerm16 (rm, res16); - break; - - case 2: /* CALL Ev */ - push (ip); - ip = oper1; - break; - - case 3: /* CALL Mp */ - push (segregs[regcs]); - push (ip); - getea (rm); - ip = (uint16_t) read86 (ea) + (uint16_t) read86 (ea + 1) * 256; - segregs[regcs] = (uint16_t) read86 (ea + 2) + (uint16_t) read86 (ea + 3) * 256; - break; - - case 4: /* JMP Ev */ - ip = oper1; - break; - - case 5: /* JMP Mp */ - getea (rm); - ip = (uint16_t) read86 (ea) + (uint16_t) read86 (ea + 1) * 256; - segregs[regcs] = (uint16_t) read86 (ea + 2) + (uint16_t) read86 (ea + 3) * 256; - break; - - case 6: /* PUSH Ev */ - push (oper1); - break; - } -} - -#if 0 -uint8_t dolog = 0, didintr = 0; -FILE *logout; -uint8_t printops = 0; -#endif - -#ifdef NETWORKING_ENABLED -extern void nethandler(); -#endif -#if 0 -extern void diskhandler(); -extern void readdisk(uint8_t drivenum, uint16_t dstseg, uint16_t dstoff, uint16_t cyl, uint16_t sect, uint16_t head, uint16_t sectcount); -#endif - -void intcall86(uint8_t intnum) -{ -#if 0 - static uint16_t lastint10ax; - uint16_t oldregax; - - didintr = 1; - - if (intnum == 0x19) didbootstrap = 1; - - switch (intnum) { - case 0x10: - updatedscreen = 1; - if ((regs.byteregs[regah] == 0x00) || (regs.byteregs[regah] == 0x10)) { - oldregax = regs.wordregs[regax]; - vidinterrupt(); - regs.wordregs[regax] = oldregax; - if (regs.byteregs[regah] == 0x10) return; - if (vidmode == 9) return; - } - if ((regs.byteregs[regah] == 0x1A) && (lastint10ax != 0x0100)) { //the 0x0100 is a cheap hack to make it not do this if DOS EDIT/QBASIC - regs.byteregs[regal] = 0x1A; - regs.byteregs[regbl] = 0x8; - return; - } - lastint10ax = regs.wordregs[regax]; - break; -#ifndef DISK_CONTROLLER_ATA - case 0x19: //bootstrap - if (bootdrive<255) { //read first sector of boot drive into 07C0:0000 and execute it - regs.byteregs[regdl] = bootdrive; - readdisk(regs.byteregs[regdl], 0x07C0, 0x0000, 0, 1, 0, 1); - segregs[regcs] = 0x0000; - ip = 0x7C00; - } else { - segregs[regcs] = 0xF600; //start ROM BASIC at bootstrap if requested - ip = 0x0000; - } - return; - - case 0x13: - case 0xFD: - diskhandler(); - return; -#endif -#ifdef NETWORKING_OLDCARD - case 0xFC: -#ifdef NETWORKING_ENABLED - nethandler(); -#endif - return; -#endif - } -#endif - - push(makeflagsword()); - push(segregs[regcs]); - push(ip); - segregs[regcs] = getmem16(0, (uint16_t)intnum * 4 + 2); - ip = getmem16(0, (uint16_t)intnum * 4); - ifl = 0; - tf = 0; -} - - -#if defined(NETWORKING_ENABLED) -extern struct netstruct { - uint8_t enabled; - uint8_t canrecv; - uint16_t pktlen; -} net; -#endif -#if 0 -uint64_t frametimer = 0, didwhen = 0, didticks = 0; -uint32_t makeupticks = 0; -extern float timercomp; -uint64_t timerticks = 0, realticks = 0; -#endif -uint64_t lastcountertimer = 0, counterticks = 10000; -//extern uint8_t nextintr(); -//extern void timing(); - -extern void check_x86_irq(void); - -void exec86 (uint32_t execloops) { - - uint32_t loopcount; - uint8_t docontinue; - static uint16_t firstip; - static uint16_t trap_toggle = 0; - - counterticks = (uint64_t) ( (double) timerfreq / (double) 65536.0); - - for (loopcount = 0; loopcount < execloops; loopcount++) { - - //if ( (totalexec & 31) == 0) timing(); - - if (trap_toggle) { - intcall86 (1); - } - - if (tf) { - trap_toggle = 1; - } - else { - trap_toggle = 0; - } - - if (!trap_toggle && ifl) - check_x86_irq(); - - reptype = 0; - segoverride = 0; - useseg = segregs[regds]; - docontinue = 0; - firstip = ip; - -#if 0 - if ( (segregs[regcs] == 0xF000) && (ip == 0xE066) ) didbootstrap = 0; //detect if we hit the BIOS entry point to clear didbootstrap because we've rebooted -#endif - - while (!docontinue) { - segregs[regcs] = segregs[regcs] & 0xFFFF; - ip = ip & 0xFFFF; - savecs = segregs[regcs]; - saveip = ip; - opcode = getmem8 (segregs[regcs], ip); - StepIP (1); - - switch (opcode) { - /* segment prefix check */ - case 0x2E: /* segment segregs[regcs] */ - useseg = segregs[regcs]; - segoverride = 1; - break; - - case 0x3E: /* segment segregs[regds] */ - useseg = segregs[regds]; - segoverride = 1; - break; - - case 0x26: /* segment segregs[reges] */ - useseg = segregs[reges]; - segoverride = 1; - break; - - case 0x36: /* segment segregs[regss] */ - useseg = segregs[regss]; - segoverride = 1; - break; - - /* repetition prefix check */ - case 0xF3: /* REP/REPE/REPZ */ - reptype = 1; - break; - - case 0xF2: /* REPNE/REPNZ */ - reptype = 2; - break; - - default: - docontinue = 1; - break; - } - } - - totalexec++; - - /* - * if (printops == 1) { printf("%04X:%04X - %s\n", savecs, saveip, oplist[opcode]); - * } - */ - switch (opcode) { - case 0x0: /* 00 ADD Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_add8(); - writerm8 (rm, res8); - break; - - case 0x1: /* 01 ADD Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_add16(); - writerm16 (rm, res16); - break; - - case 0x2: /* 02 ADD Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_add8(); - putreg8 (reg, res8); - break; - - case 0x3: /* 03 ADD Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_add16(); - putreg16 (reg, res16); - break; - - case 0x4: /* 04 ADD regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_add8(); - regs.byteregs[regal] = res8; - break; - - case 0x5: /* 05 ADD eAX Iv */ - oper1 = (getreg16 (regax) ); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_add16(); - putreg16 (regax, res16); - break; - - case 0x6: /* 06 PUSH segregs[reges] */ - push (segregs[reges]); - break; - - case 0x7: /* 07 POP segregs[reges] */ - segregs[reges] = pop(); - break; - - case 0x8: /* 08 OR Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_or8(); - writerm8 (rm, res8); - break; - - case 0x9: /* 09 OR Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_or16(); - writerm16 (rm, res16); - break; - - case 0xA: /* 0A OR Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_or8(); - putreg8 (reg, res8); - break; - - case 0xB: /* 0B OR Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_or16(); - if ( (oper1 == 0xF802) && (oper2 == 0xF802) ) { - sf = 0; /* cheap hack to make Wolf 3D think we're a 286 so it plays */ - } - - putreg16 (reg, res16); - break; - - case 0xC: /* 0C OR regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_or8(); - regs.byteregs[regal] = res8; - break; - - case 0xD: /* 0D OR eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_or16(); - putreg16 (regax, res16); - break; - - case 0xE: /* 0E PUSH segregs[regcs] */ - push (segregs[regcs]); - break; - - case 0xF: //0F POP CS - if (!x86_cpu_v20) - segregs[regcs] = pop(); - break; - - case 0x10: /* 10 ADC Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_adc8(); - writerm8 (rm, res8); - break; - - case 0x11: /* 11 ADC Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_adc16(); - writerm16 (rm, res16); - break; - - case 0x12: /* 12 ADC Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_adc8(); - putreg8 (reg, res8); - break; - - case 0x13: /* 13 ADC Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_adc16(); - putreg16 (reg, res16); - break; - - case 0x14: /* 14 ADC regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_adc8(); - regs.byteregs[regal] = res8; - break; - - case 0x15: /* 15 ADC eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_adc16(); - putreg16 (regax, res16); - break; - - case 0x16: /* 16 PUSH segregs[regss] */ - push (segregs[regss]); - break; - - case 0x17: /* 17 POP segregs[regss] */ - segregs[regss] = pop(); - break; - - case 0x18: /* 18 SBB Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_sbb8(); - writerm8 (rm, res8); - break; - - case 0x19: /* 19 SBB Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_sbb16(); - writerm16 (rm, res16); - break; - - case 0x1A: /* 1A SBB Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_sbb8(); - putreg8 (reg, res8); - break; - - case 0x1B: /* 1B SBB Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_sbb16(); - putreg16 (reg, res16); - break; - - case 0x1C: /* 1C SBB regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_sbb8(); - regs.byteregs[regal] = res8; - break; - - case 0x1D: /* 1D SBB eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_sbb16(); - putreg16 (regax, res16); - break; - - case 0x1E: /* 1E PUSH segregs[regds] */ - push (segregs[regds]); - break; - - case 0x1F: /* 1F POP segregs[regds] */ - segregs[regds] = pop(); - break; - - case 0x20: /* 20 AND Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_and8(); - writerm8 (rm, res8); - break; - - case 0x21: /* 21 AND Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_and16(); - writerm16 (rm, res16); - break; - - case 0x22: /* 22 AND Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_and8(); - putreg8 (reg, res8); - break; - - case 0x23: /* 23 AND Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_and16(); - putreg16 (reg, res16); - break; - - case 0x24: /* 24 AND regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_and8(); - regs.byteregs[regal] = res8; - break; - - case 0x25: /* 25 AND eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_and16(); - putreg16 (regax, res16); - break; - - case 0x27: /* 27 DAA */ - if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) { - oper1 = regs.byteregs[regal] + 6; - regs.byteregs[regal] = oper1 & 255; - if (oper1 & 0xFF00) { - cf = 1; - } - else { - cf = 0; - } - - af = 1; - } - else { - af = 0; - } - - if ( ( (regs.byteregs[regal] & 0xF0) > 0x90) || (cf == 1) ) { - regs.byteregs[regal] = regs.byteregs[regal] + 0x60; - cf = 1; - } - else { - cf = 0; - } - - regs.byteregs[regal] = regs.byteregs[regal] & 255; - flag_szp8 (regs.byteregs[regal]); - break; - - case 0x28: /* 28 SUB Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_sub8(); - writerm8 (rm, res8); - break; - - case 0x29: /* 29 SUB Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_sub16(); - writerm16 (rm, res16); - break; - - case 0x2A: /* 2A SUB Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_sub8(); - putreg8 (reg, res8); - break; - - case 0x2B: /* 2B SUB Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_sub16(); - putreg16 (reg, res16); - break; - - case 0x2C: /* 2C SUB regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_sub8(); - regs.byteregs[regal] = res8; - break; - - case 0x2D: /* 2D SUB eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_sub16(); - putreg16 (regax, res16); - break; - - case 0x2F: /* 2F DAS */ - if ( ( (regs.byteregs[regal] & 15) > 9) || (af == 1) ) { - oper1 = regs.byteregs[regal] - 6; - regs.byteregs[regal] = oper1 & 255; - if (oper1 & 0xFF00) { - cf = 1; - } - else { - cf = 0; - } - - af = 1; - } - else { - af = 0; - } - - if ( ( (regs.byteregs[regal] & 0xF0) > 0x90) || (cf == 1) ) { - regs.byteregs[regal] = regs.byteregs[regal] - 0x60; - cf = 1; - } - else { - cf = 0; - } - - flag_szp8 (regs.byteregs[regal]); - break; - - case 0x30: /* 30 XOR Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - op_xor8(); - writerm8 (rm, res8); - break; - - case 0x31: /* 31 XOR Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - op_xor16(); - writerm16 (rm, res16); - break; - - case 0x32: /* 32 XOR Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - op_xor8(); - putreg8 (reg, res8); - break; - - case 0x33: /* 33 XOR Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - op_xor16(); - putreg16 (reg, res16); - break; - - case 0x34: /* 34 XOR regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - op_xor8(); - regs.byteregs[regal] = res8; - break; - - case 0x35: /* 35 XOR eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - op_xor16(); - putreg16 (regax, res16); - break; - - case 0x37: /* 37 AAA ASCII */ - if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) { - regs.byteregs[regal] = regs.byteregs[regal] + 6; - regs.byteregs[regah] = regs.byteregs[regah] + 1; - af = 1; - cf = 1; - } - else { - af = 0; - cf = 0; - } - - regs.byteregs[regal] = regs.byteregs[regal] & 0xF; - break; - - case 0x38: /* 38 CMP Eb Gb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getreg8 (reg); - flag_sub8 (oper1b, oper2b); - break; - - case 0x39: /* 39 CMP Ev Gv */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getreg16 (reg); - flag_sub16 (oper1, oper2); - break; - - case 0x3A: /* 3A CMP Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - flag_sub8 (oper1b, oper2b); - break; - - case 0x3B: /* 3B CMP Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - flag_sub16 (oper1, oper2); - break; - - case 0x3C: /* 3C CMP regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - flag_sub8 (oper1b, oper2b); - break; - - case 0x3D: /* 3D CMP eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - flag_sub16 (oper1, oper2); - break; - - case 0x3F: /* 3F AAS ASCII */ - if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) { - regs.byteregs[regal] = regs.byteregs[regal] - 6; - regs.byteregs[regah] = regs.byteregs[regah] - 1; - af = 1; - cf = 1; - } - else { - af = 0; - cf = 0; - } - - regs.byteregs[regal] = regs.byteregs[regal] & 0xF; - break; - - case 0x40: /* 40 INC eAX */ - oldcf = cf; - oper1 = getreg16 (regax); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regax, res16); - break; - - case 0x41: /* 41 INC eCX */ - oldcf = cf; - oper1 = getreg16 (regcx); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regcx, res16); - break; - - case 0x42: /* 42 INC eDX */ - oldcf = cf; - oper1 = getreg16 (regdx); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regdx, res16); - break; - - case 0x43: /* 43 INC eBX */ - oldcf = cf; - oper1 = getreg16 (regbx); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regbx, res16); - break; - - case 0x44: /* 44 INC eSP */ - oldcf = cf; - oper1 = getreg16 (regsp); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regsp, res16); - break; - - case 0x45: /* 45 INC eBP */ - oldcf = cf; - oper1 = getreg16 (regbp); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regbp, res16); - break; - - case 0x46: /* 46 INC eSI */ - oldcf = cf; - oper1 = getreg16 (regsi); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regsi, res16); - break; - - case 0x47: /* 47 INC eDI */ - oldcf = cf; - oper1 = getreg16 (regdi); - oper2 = 1; - op_add16(); - cf = oldcf; - putreg16 (regdi, res16); - break; - - case 0x48: /* 48 DEC eAX */ - oldcf = cf; - oper1 = getreg16 (regax); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regax, res16); - break; - - case 0x49: /* 49 DEC eCX */ - oldcf = cf; - oper1 = getreg16 (regcx); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regcx, res16); - break; - - case 0x4A: /* 4A DEC eDX */ - oldcf = cf; - oper1 = getreg16 (regdx); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regdx, res16); - break; - - case 0x4B: /* 4B DEC eBX */ - oldcf = cf; - oper1 = getreg16 (regbx); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regbx, res16); - break; - - case 0x4C: /* 4C DEC eSP */ - oldcf = cf; - oper1 = getreg16 (regsp); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regsp, res16); - break; - - case 0x4D: /* 4D DEC eBP */ - oldcf = cf; - oper1 = getreg16 (regbp); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regbp, res16); - break; - - case 0x4E: /* 4E DEC eSI */ - oldcf = cf; - oper1 = getreg16 (regsi); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regsi, res16); - break; - - case 0x4F: /* 4F DEC eDI */ - oldcf = cf; - oper1 = getreg16 (regdi); - oper2 = 1; - op_sub16(); - cf = oldcf; - putreg16 (regdi, res16); - break; - - case 0x50: /* 50 PUSH eAX */ - push (getreg16 (regax) ); - break; - - case 0x51: /* 51 PUSH eCX */ - push (getreg16 (regcx) ); - break; - - case 0x52: /* 52 PUSH eDX */ - push (getreg16 (regdx) ); - break; - - case 0x53: /* 53 PUSH eBX */ - push (getreg16 (regbx) ); - break; - - case 0x54: /* 54 PUSH eSP */ - push (getreg16 (regsp) - 2); - break; - - case 0x55: /* 55 PUSH eBP */ - push (getreg16 (regbp) ); - break; - - case 0x56: /* 56 PUSH eSI */ - push (getreg16 (regsi) ); - break; - - case 0x57: /* 57 PUSH eDI */ - push (getreg16 (regdi) ); - break; - - case 0x58: /* 58 POP eAX */ - putreg16 (regax, pop() ); - break; - - case 0x59: /* 59 POP eCX */ - putreg16 (regcx, pop() ); - break; - - case 0x5A: /* 5A POP eDX */ - putreg16 (regdx, pop() ); - break; - - case 0x5B: /* 5B POP eBX */ - putreg16 (regbx, pop() ); - break; - - case 0x5C: /* 5C POP eSP */ - putreg16 (regsp, pop() ); - break; - - case 0x5D: /* 5D POP eBP */ - putreg16 (regbp, pop() ); - break; - - case 0x5E: /* 5E POP eSI */ - putreg16 (regsi, pop() ); - break; - - case 0x5F: /* 5F POP eDI */ - putreg16 (regdi, pop() ); - break; - - case 0x60: /* 60 PUSHA (80186+) */ - if (!x86_cpu_v20) - goto nov20; - oldsp = getreg16 (regsp); - push (getreg16 (regax) ); - push (getreg16 (regcx) ); - push (getreg16 (regdx) ); - push (getreg16 (regbx) ); - push (oldsp); - push (getreg16 (regbp) ); - push (getreg16 (regsi) ); - push (getreg16 (regdi) ); - break; - - case 0x61: /* 61 POPA (80186+) */ - if (!x86_cpu_v20) - goto nov20; - putreg16 (regdi, pop() ); - putreg16 (regsi, pop() ); - putreg16 (regbp, pop() ); - dummy = pop(); - putreg16 (regbx, pop() ); - putreg16 (regdx, pop() ); - putreg16 (regcx, pop() ); - putreg16 (regax, pop() ); - break; - - case 0x62: /* 62 BOUND Gv, Ev (80186+) */ - if (!x86_cpu_v20) - goto nov20; - modregrm(); - getea (rm); - if (signext32 (getreg16 (reg) ) < signext32 ( getmem16 (ea >> 4, ea & 15) ) ) { - intcall86 (5); //bounds check exception - } - else { - ea += 2; - if (signext32 (getreg16 (reg) ) > signext32 ( getmem16 (ea >> 4, ea & 15) ) ) { - intcall86(5); //bounds check exception - } - } - break; - - case 0x68: /* 68 PUSH Iv (80186+) */ - if (!x86_cpu_v20) - goto nov20; - push (getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0x69: /* 69 IMUL Gv Ev Iv (80186+) */ - if (!x86_cpu_v20) - goto nov20; - modregrm(); - temp1 = readrm16 (rm); - temp2 = getmem16 (segregs[regcs], ip); - StepIP (2); - if ( (temp1 & 0x8000L) == 0x8000L) { - temp1 = temp1 | 0xFFFF0000L; - } - - if ( (temp2 & 0x8000L) == 0x8000L) { - temp2 = temp2 | 0xFFFF0000L; - } - - temp3 = temp1 * temp2; - putreg16 (reg, temp3 & 0xFFFFL); - if (temp3 & 0xFFFF0000L) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - break; - - case 0x6A: /* 6A PUSH Ib (80186+) */ - if (!x86_cpu_v20) - goto nov20; - push (getmem8 (segregs[regcs], ip) ); - StepIP (1); - break; - - case 0x6B: /* 6B IMUL Gv Eb Ib (80186+) */ - if (!x86_cpu_v20) - goto nov20; - modregrm(); - temp1 = readrm16 (rm); - temp2 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if ( (temp1 & 0x8000L) == 0x8000L) { - temp1 = temp1 | 0xFFFF0000L; - } - - if ( (temp2 & 0x8000L) == 0x8000L) { - temp2 = temp2 | 0xFFFF0000L; - } - - temp3 = temp1 * temp2; - putreg16 (reg, temp3 & 0xFFFFL); - if (temp3 & 0xFFFF0000L) { - cf = 1; - of = 1; - } - else { - cf = 0; - of = 0; - } - break; - - case 0x6C: /* 6E INSB */ - if (!x86_cpu_v20) - goto nov20; - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem8 (useseg, getreg16 (regsi) , portin (regs.wordregs[regdx]) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 1); - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regsi, getreg16 (regsi) + 1); - putreg16 (regdi, getreg16 (regdi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0x6D: /* 6F INSW */ - if (!x86_cpu_v20) - goto nov20; - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem16 (useseg, getreg16 (regsi) , portin16 (regs.wordregs[regdx]) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 2); - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regsi, getreg16 (regsi) + 2); - putreg16 (regdi, getreg16 (regdi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0x6E: /* 6E OUTSB */ - if (!x86_cpu_v20) - goto nov20; - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - portout (regs.wordregs[regdx], getmem8 (useseg, getreg16 (regsi) ) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 1); - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regsi, getreg16 (regsi) + 1); - putreg16 (regdi, getreg16 (regdi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0x6F: /* 6F OUTSW */ - if (!x86_cpu_v20) - goto nov20; - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - portout16 (regs.wordregs[regdx], getmem16 (useseg, getreg16 (regsi) ) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 2); - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regsi, getreg16 (regsi) + 2); - putreg16 (regdi, getreg16 (regdi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0x70: /* 70 JO Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (of) { - ip = ip + temp16; - } - break; - - case 0x71: /* 71 JNO Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!of) { - ip = ip + temp16; - } - break; - - case 0x72: /* 72 JB Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (cf) { - ip = ip + temp16; - } - break; - - case 0x73: /* 73 JNB Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!cf) { - ip = ip + temp16; - } - break; - - case 0x74: /* 74 JZ Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (zf) { - ip = ip + temp16; - } - break; - - case 0x75: /* 75 JNZ Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!zf) { - ip = ip + temp16; - } - break; - - case 0x76: /* 76 JBE Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (cf || zf) { - ip = ip + temp16; - } - break; - - case 0x77: /* 77 JA Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!cf && !zf) { - ip = ip + temp16; - } - break; - - case 0x78: /* 78 JS Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (sf) { - ip = ip + temp16; - } - break; - - case 0x79: /* 79 JNS Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!sf) { - ip = ip + temp16; - } - break; - - case 0x7A: /* 7A JPE Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (pf) { - ip = ip + temp16; - } - break; - - case 0x7B: /* 7B JPO Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!pf) { - ip = ip + temp16; - } - break; - - case 0x7C: /* 7C JL Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (sf != of) { - ip = ip + temp16; - } - break; - - case 0x7D: /* 7D JGE Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (sf == of) { - ip = ip + temp16; - } - break; - - case 0x7E: /* 7E JLE Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if ( (sf != of) || zf) { - ip = ip + temp16; - } - break; - - case 0x7F: /* 7F JG Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (!zf && (sf == of) ) { - ip = ip + temp16; - } - break; - - case 0x80: - case 0x82: /* 80/82 GRP1 Eb Ib */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - switch (reg) { - case 0: - op_add8(); - break; - case 1: - op_or8(); - break; - case 2: - op_adc8(); - break; - case 3: - op_sbb8(); - break; - case 4: - op_and8(); - break; - case 5: - op_sub8(); - break; - case 6: - op_xor8(); - break; - case 7: - flag_sub8 (oper1b, oper2b); - break; - default: - break; /* to avoid compiler warnings */ - } - - if (reg < 7) { - writerm8 (rm, res8); - } - break; - - case 0x81: /* 81 GRP1 Ev Iv */ - case 0x83: /* 83 GRP1 Ev Ib */ - modregrm(); - oper1 = readrm16 (rm); - if (opcode == 0x81) { - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - } - else { - oper2 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - } - - switch (reg) { - case 0: - op_add16(); - break; - case 1: - op_or16(); - break; - case 2: - op_adc16(); - break; - case 3: - op_sbb16(); - break; - case 4: - op_and16(); - break; - case 5: - op_sub16(); - break; - case 6: - op_xor16(); - break; - case 7: - flag_sub16 (oper1, oper2); - break; - default: - break; /* to avoid compiler warnings */ - } - - if (reg < 7) { - writerm16 (rm, res16); - } - break; - - case 0x84: /* 84 TEST Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - oper2b = readrm8 (rm); - flag_log8 (oper1b & oper2b); - break; - - case 0x85: /* 85 TEST Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - oper2 = readrm16 (rm); - flag_log16 (oper1 & oper2); - break; - - case 0x86: /* 86 XCHG Gb Eb */ - modregrm(); - oper1b = getreg8 (reg); - putreg8 (reg, readrm8 (rm) ); - writerm8 (rm, oper1b); - break; - - case 0x87: /* 87 XCHG Gv Ev */ - modregrm(); - oper1 = getreg16 (reg); - putreg16 (reg, readrm16 (rm) ); - writerm16 (rm, oper1); - break; - - case 0x88: /* 88 MOV Eb Gb */ - modregrm(); - writerm8 (rm, getreg8 (reg) ); - break; - - case 0x89: /* 89 MOV Ev Gv */ - modregrm(); - writerm16 (rm, getreg16 (reg) ); - break; - - case 0x8A: /* 8A MOV Gb Eb */ - modregrm(); - putreg8 (reg, readrm8 (rm) ); - break; - - case 0x8B: /* 8B MOV Gv Ev */ - modregrm(); - putreg16 (reg, readrm16 (rm) ); - break; - - case 0x8C: /* 8C MOV Ew Sw */ - modregrm(); - writerm16 (rm, getsegreg (reg) ); - break; - - case 0x8D: /* 8D LEA Gv M */ - modregrm(); - getea (rm); - putreg16 (reg, ea - segbase (useseg) ); - break; - - case 0x8E: /* 8E MOV Sw Ew */ - modregrm(); - putsegreg (reg, readrm16 (rm) ); - break; - - case 0x8F: /* 8F POP Ev */ - modregrm(); - writerm16 (rm, pop() ); - break; - - case 0x90: /* 90 NOP */ - break; - - case 0x91: /* 91 XCHG eCX eAX */ - oper1 = getreg16 (regcx); - putreg16 (regcx, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x92: /* 92 XCHG eDX eAX */ - oper1 = getreg16 (regdx); - putreg16 (regdx, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x93: /* 93 XCHG eBX eAX */ - oper1 = getreg16 (regbx); - putreg16 (regbx, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x94: /* 94 XCHG eSP eAX */ - oper1 = getreg16 (regsp); - putreg16 (regsp, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x95: /* 95 XCHG eBP eAX */ - oper1 = getreg16 (regbp); - putreg16 (regbp, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x96: /* 96 XCHG eSI eAX */ - oper1 = getreg16 (regsi); - putreg16 (regsi, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x97: /* 97 XCHG eDI eAX */ - oper1 = getreg16 (regdi); - putreg16 (regdi, getreg16 (regax) ); - putreg16 (regax, oper1); - break; - - case 0x98: /* 98 CBW */ - if ( (regs.byteregs[regal] & 0x80) == 0x80) { - regs.byteregs[regah] = 0xFF; - } - else { - regs.byteregs[regah] = 0; - } - break; - - case 0x99: /* 99 CWD */ - if ( (regs.byteregs[regah] & 0x80) == 0x80) { - putreg16 (regdx, 0xFFFF); - } - else { - putreg16 (regdx, 0); - } - break; - - case 0x9A: /* 9A CALL Ap */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - push (segregs[regcs]); - push (ip); - ip = oper1; - segregs[regcs] = oper2; - break; - - case 0x9B: /* 9B WAIT */ - break; - - case 0x9C: /* 9C PUSHF */ - push (makeflagsword() | 0xF800); - break; - - case 0x9D: /* 9D POPF */ - temp16 = pop(); - decodeflagsword (temp16); - break; - - case 0x9E: /* 9E SAHF */ - decodeflagsword ( (makeflagsword() & 0xFF00) | regs.byteregs[regah]); - break; - - case 0x9F: /* 9F LAHF */ - regs.byteregs[regah] = makeflagsword() & 0xFF; - break; - - case 0xA0: /* A0 MOV regs.byteregs[regal] Ob */ - regs.byteregs[regal] = getmem8 (useseg, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xA1: /* A1 MOV eAX Ov */ - oper1 = getmem16 (useseg, getmem16 (segregs[regcs], ip) ); - StepIP (2); - putreg16 (regax, oper1); - break; - - case 0xA2: /* A2 MOV Ob regs.byteregs[regal] */ - putmem8 (useseg, getmem16 (segregs[regcs], ip), regs.byteregs[regal]); - StepIP (2); - break; - - case 0xA3: /* A3 MOV Ov eAX */ - putmem16 (useseg, getmem16 (segregs[regcs], ip), getreg16 (regax) ); - StepIP (2); - break; - - case 0xA4: /* A4 MOVSB */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem8 (segregs[reges], getreg16 (regdi), getmem8 (useseg, getreg16 (regsi) ) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 1); - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regsi, getreg16 (regsi) + 1); - putreg16 (regdi, getreg16 (regdi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xA5: /* A5 MOVSW */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem16 (segregs[reges], getreg16 (regdi), getmem16 (useseg, getreg16 (regsi) ) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 2); - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regsi, getreg16 (regsi) + 2); - putreg16 (regdi, getreg16 (regdi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xA6: /* A6 CMPSB */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - oper1b = getmem8 (useseg, getreg16 (regsi) ); - oper2b = getmem8 (segregs[reges], getreg16 (regdi) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 1); - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regsi, getreg16 (regsi) + 1); - putreg16 (regdi, getreg16 (regdi) + 1); - } - - flag_sub8 (oper1b, oper2b); - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - if ( (reptype == 1) && !zf) { - break; - } - else if ( (reptype == 2) && (zf == 1) ) { - break; - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xA7: /* A7 CMPSW */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - oper1 = getmem16 (useseg, getreg16 (regsi) ); - oper2 = getmem16 (segregs[reges], getreg16 (regdi) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 2); - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regsi, getreg16 (regsi) + 2); - putreg16 (regdi, getreg16 (regdi) + 2); - } - - flag_sub16 (oper1, oper2); - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - if ( (reptype == 1) && !zf) { - break; - } - - if ( (reptype == 2) && (zf == 1) ) { - break; - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xA8: /* A8 TEST regs.byteregs[regal] Ib */ - oper1b = regs.byteregs[regal]; - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - flag_log8 (oper1b & oper2b); - break; - - case 0xA9: /* A9 TEST eAX Iv */ - oper1 = getreg16 (regax); - oper2 = getmem16 (segregs[regcs], ip); - StepIP (2); - flag_log16 (oper1 & oper2); - break; - - case 0xAA: /* AA STOSB */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem8 (segregs[reges], getreg16 (regdi), regs.byteregs[regal]); - if (df) { - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regdi, getreg16 (regdi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xAB: /* AB STOSW */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - putmem16 (segregs[reges], getreg16 (regdi), getreg16 (regax) ); - if (df) { - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regdi, getreg16 (regdi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xAC: /* AC LODSB */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - regs.byteregs[regal] = getmem8 (useseg, getreg16 (regsi) ); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 1); - } - else { - putreg16 (regsi, getreg16 (regsi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xAD: /* AD LODSW */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - oper1 = getmem16 (useseg, getreg16 (regsi) ); - putreg16 (regax, oper1); - if (df) { - putreg16 (regsi, getreg16 (regsi) - 2); - } - else { - putreg16 (regsi, getreg16 (regsi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xAE: /* AE SCASB */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - oper1b = getmem8 (segregs[reges], getreg16 (regdi) ); - oper2b = regs.byteregs[regal]; - flag_sub8 (oper1b, oper2b); - if (df) { - putreg16 (regdi, getreg16 (regdi) - 1); - } - else { - putreg16 (regdi, getreg16 (regdi) + 1); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - if ( (reptype == 1) && !zf) { - break; - } - else if ( (reptype == 2) && (zf == 1) ) { - break; - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xAF: /* AF SCASW */ - if (reptype && (getreg16 (regcx) == 0) ) { - break; - } - - oper1 = getmem16 (segregs[reges], getreg16 (regdi) ); - oper2 = getreg16 (regax); - flag_sub16 (oper1, oper2); - if (df) { - putreg16 (regdi, getreg16 (regdi) - 2); - } - else { - putreg16 (regdi, getreg16 (regdi) + 2); - } - - if (reptype) { - putreg16 (regcx, getreg16 (regcx) - 1); - } - - if ( (reptype == 1) && !zf) { - break; - } - else if ( (reptype == 2) & (zf == 1) ) { - break; - } - - totalexec++; - loopcount++; - if (!reptype) { - break; - } - - ip = firstip; - break; - - case 0xB0: /* B0 MOV regs.byteregs[regal] Ib */ - regs.byteregs[regal] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB1: /* B1 MOV regs.byteregs[regcl] Ib */ - regs.byteregs[regcl] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB2: /* B2 MOV regs.byteregs[regdl] Ib */ - regs.byteregs[regdl] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB3: /* B3 MOV regs.byteregs[regbl] Ib */ - regs.byteregs[regbl] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB4: /* B4 MOV regs.byteregs[regah] Ib */ - regs.byteregs[regah] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB5: /* B5 MOV regs.byteregs[regch] Ib */ - regs.byteregs[regch] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB6: /* B6 MOV regs.byteregs[regdh] Ib */ - regs.byteregs[regdh] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB7: /* B7 MOV regs.byteregs[regbh] Ib */ - regs.byteregs[regbh] = getmem8 (segregs[regcs], ip); - StepIP (1); - break; - - case 0xB8: /* B8 MOV eAX Iv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - putreg16 (regax, oper1); - break; - - case 0xB9: /* B9 MOV eCX Iv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - putreg16 (regcx, oper1); - break; - - case 0xBA: /* BA MOV eDX Iv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - putreg16 (regdx, oper1); - break; - - case 0xBB: /* BB MOV eBX Iv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - putreg16 (regbx, oper1); - break; - - case 0xBC: /* BC MOV eSP Iv */ - putreg16 (regsp, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xBD: /* BD MOV eBP Iv */ - putreg16 (regbp, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xBE: /* BE MOV eSI Iv */ - putreg16 (regsi, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xBF: /* BF MOV eDI Iv */ - putreg16 (regdi, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xC0: /* C0 GRP2 byte imm8 (80186+) */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = getmem8 (segregs[regcs], ip); - StepIP (1); - writerm8 (rm, op_grp2_8 (oper2b) ); - break; - - case 0xC1: /* C1 GRP2 word imm8 (80186+) */ - modregrm(); - oper1 = readrm16 (rm); - oper2 = getmem8 (segregs[regcs], ip); - StepIP (1); - writerm16 (rm, op_grp2_16 ( (uint8_t) oper2) ); - break; - - case 0xC2: /* C2 RET Iw */ - oper1 = getmem16 (segregs[regcs], ip); - ip = pop(); - putreg16 (regsp, getreg16 (regsp) + oper1); - break; - - case 0xC3: /* C3 RET */ - ip = pop(); - break; - - case 0xC4: /* C4 LES Gv Mp */ - modregrm(); - getea (rm); - putreg16 (reg, read86 (ea) + read86 (ea + 1) * 256); - segregs[reges] = read86 (ea + 2) + read86 (ea + 3) * 256; - break; - - case 0xC5: /* C5 LDS Gv Mp */ - modregrm(); - getea (rm); - putreg16 (reg, read86 (ea) + read86 (ea + 1) * 256); - segregs[regds] = read86 (ea + 2) + read86 (ea + 3) * 256; - break; - - case 0xC6: /* C6 MOV Eb Ib */ - modregrm(); - writerm8 (rm, getmem8 (segregs[regcs], ip) ); - StepIP (1); - break; - - case 0xC7: /* C7 MOV Ev Iv */ - modregrm(); - writerm16 (rm, getmem16 (segregs[regcs], ip) ); - StepIP (2); - break; - - case 0xC8: /* C8 ENTER (80186+) */ - stacksize = getmem16 (segregs[regcs], ip); - StepIP (2); - nestlev = getmem8 (segregs[regcs], ip); - StepIP (1); - push (getreg16 (regbp) ); - frametemp = getreg16 (regsp); - if (nestlev) { - for (temp16 = 1; temp16 < nestlev; temp16++) { - putreg16 (regbp, getreg16 (regbp) - 2); - push (getreg16 (regbp) ); - } - - push (getreg16 (regsp) ); - } - - putreg16 (regbp, frametemp); - putreg16 (regsp, getreg16 (regbp) - stacksize); - - break; - - case 0xC9: /* C9 LEAVE (80186+) */ - putreg16 (regsp, getreg16 (regbp) ); - putreg16 (regbp, pop() ); - - break; - - case 0xCA: /* CA RETF Iw */ - oper1 = getmem16 (segregs[regcs], ip); - ip = pop(); - segregs[regcs] = pop(); - putreg16 (regsp, getreg16 (regsp) + oper1); - break; - - case 0xCB: /* CB RETF */ - ip = pop();; - segregs[regcs] = pop(); - break; - - case 0xCC: /* CC INT 3 */ - intcall86 (3); - break; - - case 0xCD: /* CD INT Ib */ - oper1b = getmem8 (segregs[regcs], ip); - StepIP (1); - intcall86 (oper1b); - break; - - case 0xCE: /* CE INTO */ - if (of) { - intcall86 (4); - } - break; - - case 0xCF: /* CF IRET */ - ip = pop(); - segregs[regcs] = pop(); - decodeflagsword (pop() ); - - /* - * if (net.enabled) net.canrecv = 1; - */ - break; - - case 0xD0: /* D0 GRP2 Eb 1 */ - modregrm(); - oper1b = readrm8 (rm); - writerm8 (rm, op_grp2_8 (1) ); - break; - - case 0xD1: /* D1 GRP2 Ev 1 */ - modregrm(); - oper1 = readrm16 (rm); - writerm16 (rm, op_grp2_16 (1) ); - break; - - case 0xD2: /* D2 GRP2 Eb regs.byteregs[regcl] */ - modregrm(); - oper1b = readrm8 (rm); - writerm8 (rm, op_grp2_8 (regs.byteregs[regcl]) ); - break; - - case 0xD3: /* D3 GRP2 Ev regs.byteregs[regcl] */ - modregrm(); - oper1 = readrm16 (rm); - writerm16 (rm, op_grp2_16 (regs.byteregs[regcl]) ); - break; - - case 0xD4: /* D4 AAM I0 */ - oper1 = getmem8 (segregs[regcs], ip); - StepIP (1); - if (!oper1) { - intcall86 (0); - break; - } /* division by zero */ - - regs.byteregs[regah] = (regs.byteregs[regal] / oper1) & 255; - regs.byteregs[regal] = (regs.byteregs[regal] % oper1) & 255; - flag_szp16 (getreg16 (regax) ); - break; - - case 0xD5: /* D5 AAD I0 */ - oper1 = getmem8 (segregs[regcs], ip); - StepIP (1); - regs.byteregs[regal] = (regs.byteregs[regah] * oper1 + regs.byteregs[regal]) & 255; - regs.byteregs[regah] = 0; - flag_szp16 (regs.byteregs[regah] * oper1 + regs.byteregs[regal]); - sf = 0; - break; - - case 0xD6: /* D6 XLAT on V20/V30, SALC on 8086/8088 */ - - if (x86_cpu_v20) - regs.byteregs[regal] = read86(useseg * 16 + (regs.wordregs[regbx]) + regs.byteregs[regal]); - else - regs.byteregs[regal] = cf ? 0xFF : 0x00; - break; - - case 0xD7: /* D7 XLAT */ - regs.byteregs[regal] = read86(useseg * 16 + (regs.wordregs[regbx]) + regs.byteregs[regal]); - break; - - case 0xD8: - case 0xD9: - case 0xDA: - case 0xDB: - case 0xDC: - case 0xDE: - case 0xDD: - case 0xDF: /* escape to x87 FPU (unsupported) */ - modregrm(); - break; - - case 0xE0: /* E0 LOOPNZ Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - putreg16 (regcx, getreg16 (regcx) - 1); - if ( (getreg16 (regcx) ) && !zf) { - ip = ip + temp16; - } - break; - - case 0xE1: /* E1 LOOPZ Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - putreg16 (regcx, (getreg16 (regcx) ) - 1); - if ( (getreg16 (regcx) ) && (zf == 1) ) { - ip = ip + temp16; - } - break; - - case 0xE2: /* E2 LOOP Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - putreg16 (regcx, (getreg16 (regcx) ) - 1); - if (getreg16 (regcx) ) { - ip = ip + temp16; - } - break; - - case 0xE3: /* E3 JCXZ Jb */ - temp16 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - if (! (getreg16 (regcx) ) ) { - ip = ip + temp16; - } - break; - - case 0xE4: /* E4 IN regs.byteregs[regal] Ib */ - oper1b = getmem8 (segregs[regcs], ip); - StepIP (1); - regs.byteregs[regal] = (uint8_t) portin (oper1b); - break; - - case 0xE5: /* E5 IN eAX Ib */ - oper1b = getmem8 (segregs[regcs], ip); - StepIP (1); - putreg16 (regax, portin16 (oper1b) ); - break; - - case 0xE6: /* E6 OUT Ib regs.byteregs[regal] */ - oper1b = getmem8 (segregs[regcs], ip); - StepIP (1); - portout (oper1b, regs.byteregs[regal]); - break; - - case 0xE7: /* E7 OUT Ib eAX */ - oper1b = getmem8 (segregs[regcs], ip); - StepIP (1); - portout16 (oper1b, (getreg16 (regax) ) ); - break; - - case 0xE8: /* E8 CALL Jv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - push (ip); - ip = ip + oper1; - break; - - case 0xE9: /* E9 JMP Jv */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - ip = ip + oper1; - break; - - case 0xEA: /* EA JMP Ap */ - oper1 = getmem16 (segregs[regcs], ip); - StepIP (2); - oper2 = getmem16 (segregs[regcs], ip); - ip = oper1; - segregs[regcs] = oper2; - break; - - case 0xEB: /* EB JMP Jb */ - oper1 = signext (getmem8 (segregs[regcs], ip) ); - StepIP (1); - ip = ip + oper1; - break; - - case 0xEC: /* EC IN regs.byteregs[regal] regdx */ - oper1 = (getreg16 (regdx) ); - regs.byteregs[regal] = (uint8_t) portin (oper1); - break; - - case 0xED: /* ED IN eAX regdx */ - oper1 = (getreg16 (regdx) ); - putreg16 (regax, portin16 (oper1) ); - break; - - case 0xEE: /* EE OUT regdx regs.byteregs[regal] */ - oper1 = (getreg16 (regdx) ); - portout (oper1, regs.byteregs[regal]); - break; - - case 0xEF: /* EF OUT regdx eAX */ - oper1 = (getreg16 (regdx) ); - portout16 (oper1, (getreg16 (regax) ) ); - break; - - case 0xF0: /* F0 LOCK */ - break; - - case 0xF4: /* F4 HLT */ - ip--; - break; - - case 0xF5: /* F5 CMC */ - if (!cf) { - cf = 1; - } - else { - cf = 0; - } - break; - - case 0xF6: /* F6 GRP3a Eb */ - modregrm(); - oper1b = readrm8 (rm); - op_grp3_8(); - if ( (reg > 1) && (reg < 4) ) { - writerm8 (rm, res8); - } - break; - - case 0xF7: /* F7 GRP3b Ev */ - modregrm(); - oper1 = readrm16 (rm); - op_grp3_16(); - if ( (reg > 1) && (reg < 4) ) { - writerm16 (rm, res16); - } - break; - - case 0xF8: /* F8 CLC */ - cf = 0; - break; - - case 0xF9: /* F9 STC */ - cf = 1; - break; - - case 0xFA: /* FA CLI */ - ifl = 0; - break; - - case 0xFB: /* FB STI */ - ifl = 1; - break; - - case 0xFC: /* FC CLD */ - df = 0; - break; - - case 0xFD: /* FD STD */ - df = 1; - break; - - case 0xFE: /* FE GRP4 Eb */ - modregrm(); - oper1b = readrm8 (rm); - oper2b = 1; - if (!reg) { - tempcf = cf; - res8 = oper1b + oper2b; - flag_add8 (oper1b, oper2b); - cf = tempcf; - writerm8 (rm, res8); - } - else { - tempcf = cf; - res8 = oper1b - oper2b; - flag_sub8 (oper1b, oper2b); - cf = tempcf; - writerm8 (rm, res8); - } - break; - - case 0xFF: /* FF GRP5 Ev */ - modregrm(); - oper1 = readrm16 (rm); - op_grp5(); - break; - - default: -nov20: - if (x86_cpu_v20) - intcall86 (6); /* trip invalid opcode exception (this occurs on the 80186+, 8086/8088 CPUs treat them as NOPs. */ - /* technically they aren't exactly like NOPs in most cases, but for our pursoses, that's accurate enough. */ - - if (verbose) { - write_log ("Illegal opcode: %02X @ %04X:%04X\n", opcode, savecs, saveip); - } - break; - } - - if (!running) { - return; - } - } -} -