diff --git a/src/cpu/core_dyn_x86/dyn_fpu.h b/src/cpu/core_dyn_x86/dyn_fpu.h new file mode 100644 index 00000000..3664bb8f --- /dev/null +++ b/src/cpu/core_dyn_x86/dyn_fpu.h @@ -0,0 +1,664 @@ +/* + * Copyright (C) 2002-2005 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: dyn_fpu.h,v 1.1 2006-06-01 15:45:37 c2woody Exp $ */ + +#include "dosbox.h" +#if C_FPU + +#include +#include +#include "cross.h" +#include "mem.h" +#include "fpu.h" +#include "cpu.h" + + +static void FPU_FDECSTP(){ + TOP = (TOP - 1) & 7; +} + +static void FPU_FINCSTP(){ + TOP = (TOP + 1) & 7; +} + +static void FPU_FNSTCW(PhysPt addr){ + mem_writew(addr,fpu.cw); +} + +static void FPU_FFREE(Bitu st) { + fpu.tags[st]=TAG_Empty; +} + + +#if C_FPU_X86 +#include "../../fpu/fpu_instructions_x86.h" +#else +#include "../../fpu/fpu_instructions.h" +#endif + + +#define dyn_fpu_top() { \ + gen_protectflags(); \ + gen_load_host(&TOP,DREG(EA),4); \ + gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); \ + gen_dop_word_imm(DOP_AND,true,DREG(EA),7); \ + gen_load_host(&TOP,DREG(TMPB),4); \ +} + +static void dyn_eatree() { + Bitu group=(decode.modrm.val >> 3) & 7; + switch (group){ + case 0x00: /* FADD ST,STi */ + gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB)); + break; + case 0x01: /* FMUL ST,STi */ + gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB)); + break; + case 0x02: /* FCOM STi */ + gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); + break; + case 0x03: /* FCOMP STi */ + gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FSUB ST,STi */ + gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB)); + break; + case 0x05: /* FSUBR ST,STi */ + gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB)); + break; + case 0x06: /* FDIV ST,STi */ + gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB)); + break; + case 0x07: /* FDIVR ST,STi */ + gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB)); + break; + default: + break; + } +} + +static void dyn_fpu_esc0(){ + dyn_get_modrm(); + if (decode.modrm.val >= 0xc0) { + dyn_fpu_top(); + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + switch (group){ + case 0x00: //FADD ST,STi / + gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x01: // FMUL ST,STi / + gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x02: // FCOM STi / + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x03: // FCOMP STi / + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: // FSUB ST,STi / + gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x05: // FSUBR ST,STi / + gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x06: // FDIV ST,STi / + gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x07: // FDIVR ST,STi / + gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + default: + break; + } + } else { + dyn_fill_ea(); + gen_call_function((void*)&FPU_FLD_F32_EA,"%Ddr",DREG(EA)); + gen_load_host(&TOP,DREG(TMPB),4); + dyn_eatree(); + } +} + +static void dyn_fpu_esc1(){ + dyn_get_modrm(); + if (decode.modrm.val >= 0xc0) { + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + switch (group){ + case 0x00: /* FLD STi */ + gen_protectflags(); + gen_load_host(&TOP,DREG(EA),4); + gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); + gen_dop_word_imm(DOP_AND,true,DREG(EA),7); + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: /* FXCH STi */ + dyn_fpu_top(); + gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x02: /* FNOP */ + gen_call_function((void*)&FPU_FNOP,""); + break; + case 0x03: /* FSTP STi */ + dyn_fpu_top(); + gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: + switch(sub){ + case 0x00: /* FCHS */ + gen_call_function((void*)&FPU_FCHS,""); + break; + case 0x01: /* FABS */ + gen_call_function((void*)&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 */ + gen_call_function((void*)&FPU_FTST,""); + break; + case 0x05: /* FXAM */ + gen_call_function((void*)&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 */ + gen_call_function((void*)&FPU_FLD1,""); + break; + case 0x01: /* FLDL2T */ + gen_call_function((void*)&FPU_FLDL2T,""); + break; + case 0x02: /* FLDL2E */ + gen_call_function((void*)&FPU_FLDL2E,""); + break; + case 0x03: /* FLDPI */ + gen_call_function((void*)&FPU_FLDPI,""); + break; + case 0x04: /* FLDLG2 */ + gen_call_function((void*)&FPU_FLDLG2,""); + break; + case 0x05: /* FLDLN2 */ + gen_call_function((void*)&FPU_FLDLN2,""); + break; + case 0x06: /* FLDZ*/ + gen_call_function((void*)&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 */ + gen_call_function((void*)&FPU_F2XM1,""); + break; + case 0x01: /* FYL2X */ + gen_call_function((void*)&FPU_FYL2X,""); + break; + case 0x02: /* FPTAN */ + gen_call_function((void*)&FPU_FPTAN,""); + break; + case 0x03: /* FPATAN */ + gen_call_function((void*)&FPU_FPATAN,""); + break; + case 0x04: /* FXTRACT */ + gen_call_function((void*)&FPU_FXTRACT,""); + break; + case 0x05: /* FPREM1 */ + gen_call_function((void*)&FPU_FPREM1,""); + break; + case 0x06: /* FDECSTP */ + gen_call_function((void*)&FPU_FDECSTP,""); + break; + case 0x07: /* FINCSTP */ + gen_call_function((void*)&FPU_FINCSTP,""); + 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 */ + gen_call_function((void*)&FPU_FPREM,""); + break; + case 0x01: /* FYL2XP1 */ + gen_call_function((void*)&FPU_FYL2XP1,""); + break; + case 0x02: /* FSQRT */ + gen_call_function((void*)&FPU_FSQRT,""); + break; + case 0x03: /* FSINCOS */ + gen_call_function((void*)&FPU_FSINCOS,""); + break; + case 0x04: /* FRNDINT */ + gen_call_function((void*)&FPU_FRNDINT,""); + break; + case 0x05: /* FSCALE */ + gen_call_function((void*)&FPU_FSCALE,""); + break; + case 0x06: /* FSIN */ + gen_call_function((void*)&FPU_FSIN,""); + break; + case 0x07: /* FCOS */ + gen_call_function((void*)&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); + break; + } + } else { + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + dyn_fill_ea(); + switch(group){ + case 0x00: /* FLD float*/ + gen_protectflags(); + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FLD_F32,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: /* UNKNOWN */ + LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); + break; + case 0x02: /* FST float*/ + gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA)); + break; + case 0x03: /* FSTP float*/ + gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FLDENV */ + gen_call_function((void*)&FPU_FLDENV,"%Ddr",DREG(EA)); + break; + case 0x05: /* FLDCW */ + gen_call_function((void *)&FPU_FLDCW,"%Ddr",DREG(EA)); + break; + case 0x06: /* FSTENV */ + gen_call_function((void *)&FPU_FSTENV,"%Ddr",DREG(EA)); + break; + case 0x07: /* FNSTCW*/ + gen_call_function((void *)&FPU_FNSTCW,"%Ddr",DREG(EA)); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); + break; + } + } +} + +static void dyn_fpu_esc2(){ + dyn_get_modrm(); + if (decode.modrm.val >= 0xc0) { + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + switch(group){ + case 0x05: + switch(sub){ + case 0x01: /* FUCOMPP */ + gen_protectflags(); + gen_load_host(&TOP,DREG(EA),4); + gen_dop_word_imm(DOP_ADD,true,DREG(EA),1); + gen_dop_word_imm(DOP_AND,true,DREG(EA),7); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void *)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void *)&FPU_FPOP,""); + gen_call_function((void *)&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; + } + } else { + dyn_fill_ea(); + gen_call_function((void*)&FPU_FLD_I32_EA,"%Ddr",DREG(EA)); + gen_load_host(&TOP,DREG(TMPB),4); + dyn_eatree(); + } +} + +static void dyn_fpu_esc3(){ + dyn_get_modrm(); + if (decode.modrm.val >= 0xc0) { + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 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 + gen_call_function((void*)&FPU_FCLEX,""); + break; + case 0x03: //FNINIT FINIT + gen_call_function((void*)&FPU_FINIT,""); + break; + case 0x04: //FNSETPM + case 0x05: //FRSTPM +// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); + 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; + } + } else { + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + dyn_fill_ea(); + switch(group){ + case 0x00: /* FILD */ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_protectflags(); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FLD_I32,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: /* FISTTP */ + LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); + break; + case 0x02: /* FIST */ + gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA)); + break; + case 0x03: /* FISTP */ + gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x05: /* FLD 80 Bits Real */ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_call_function((void*)&FPU_FLD_F80,"%Ddr",DREG(EA)); + break; + case 0x07: /* FSTP 80 Bits Real */ + gen_call_function((void*)&FPU_FST_F80,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); + } + } +} + +static void dyn_fpu_esc4(){ + dyn_get_modrm(); + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + if (decode.modrm.val >= 0xc0) { + dyn_fpu_top(); + switch(group){ + case 0x00: /* FADD STi,ST*/ + gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: /* FMUL STi,ST*/ + gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x02: /* FCOM*/ + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x03: /* FCOMP*/ + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FSUBR STi,ST*/ + gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x05: /* FSUB STi,ST*/ + gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x06: /* FDIVR STi,ST*/ + gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x07: /* FDIV STi,ST*/ + gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + default: + break; + } + } else { + dyn_fill_ea(); + gen_call_function((void*)&FPU_FLD_F64_EA,"%Ddr",DREG(EA)); + gen_load_host(&TOP,DREG(TMPB),4); + dyn_eatree(); + } +} + +static void dyn_fpu_esc5(){ + dyn_get_modrm(); + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + if (decode.modrm.val >= 0xc0) { + dyn_fpu_top(); + switch(group){ + case 0x00: /* FFREE STi */ + gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA)); + break; + case 0x01: /* FXCH STi*/ + gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x02: /* FST STi */ + gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x03: /* FSTP STi*/ + gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FUCOM STi */ + gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x05: /*FUCOMP STi */ + gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); + break; + } + gen_releasereg(DREG(EA)); + gen_releasereg(DREG(TMPB)); + } else { + dyn_fill_ea(); + switch(group){ + case 0x00: /* FLD double real*/ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_protectflags(); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FLD_F64,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + 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*/ + gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA)); + break; + case 0x03: /* FSTP double real*/ + gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FRSTOR */ + gen_call_function((void*)&FPU_FRSTOR,"%Ddr",DREG(EA)); + break; + case 0x06: /* FSAVE */ + gen_call_function((void*)&FPU_FSAVE,"%Ddr",DREG(EA)); + break; + case 0x07: /*FNSTSW */ + gen_protectflags(); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_SET_TOP,"%Dd",DREG(TMPB)); + gen_load_host(&fpu.sw,DREG(TMPB),4); + gen_call_function((void*)&mem_writew,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); + } + } +} + +static void dyn_fpu_esc6(){ + dyn_get_modrm(); + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + if (decode.modrm.val >= 0xc0) { + dyn_fpu_top(); + switch(group){ + case 0x00: /*FADDP STi,ST*/ + gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: /* FMULP STi,ST*/ + gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x02: /* FCOMP5*/ + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + 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; + } + gen_load_host(&TOP,DREG(EA),4); + gen_dop_word_imm(DOP_ADD,true,DREG(EA),1); + gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); /* extra pop at the bottom*/ + break; + case 0x04: /* FSUBRP STi,ST*/ + gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x05: /* FSUBP STi,ST*/ + gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x06: /* FDIVRP STi,ST*/ + gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x07: /* FDIVP STi,ST*/ + gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + default: + break; + } + gen_call_function((void*)&FPU_FPOP,""); + } else { + dyn_fill_ea(); + gen_call_function((void*)&FPU_FLD_I16_EA,"%Ddr",DREG(EA)); + gen_load_host(&TOP,DREG(TMPB),4); + dyn_eatree(); + } +} + +static void dyn_fpu_esc7(){ + dyn_get_modrm(); + Bitu group=(decode.modrm.val >> 3) & 7; + Bitu sub=(decode.modrm.val & 7); + if (decode.modrm.val >= 0xc0) { + switch (group){ + case 0x01: /* FXCH STi*/ + dyn_fpu_top(); + gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + break; + case 0x02: /* FSTP STi*/ + case 0x03: /* FSTP STi*/ + dyn_fpu_top(); + gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: + switch(sub){ + case 0x00: /* FNSTSW AX*/ + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_SET_TOP,"%Ddr",DREG(TMPB)); + gen_load_host(&fpu.sw,DREG(EAX),2); + 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; + } + } else { + dyn_fill_ea(); + switch(group){ + case 0x00: /* FILD Bit16s */ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FLD_I16,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x01: + LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); + break; + case 0x02: /* FIST Bit16s */ + gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA)); + break; + case 0x03: /* FISTP Bit16s */ + gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x04: /* FBLD packed BCD */ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FBLD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x05: /* FILD Bit64s */ + gen_call_function((void*)&FPU_PREP_PUSH,""); + gen_load_host(&TOP,DREG(TMPB),4); + gen_call_function((void*)&FPU_FLD_I64,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); + break; + case 0x06: /* FBSTP packed BCD */ + gen_call_function((void*)&FPU_FBST,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + case 0x07: /* FISTP Bit64s */ + gen_call_function((void*)&FPU_FST_I64,"%Ddr",DREG(EA)); + gen_call_function((void*)&FPU_FPOP,""); + break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); + break; + } + } +} + +#endif diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h deleted file mode 100644 index 0e5220e2..00000000 --- a/src/fpu/fpu_types.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2002-2006 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_types.h,v 1.13 2006-02-09 11:47:48 qbix79 Exp $ */ -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 -}; - -//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