From 5f69f149622796be751eea44aa4f775f8a0577c1 Mon Sep 17 00:00:00 2001 From: Felix Jakschitsch Date: Sun, 28 Jul 2002 14:51:12 +0000 Subject: [PATCH] some FPU added :) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@81 --- AUTHORS | 4 +- include/dosbox.h | 1 + include/fpu.h | 66 ++++++++++++ include/regs.h | 25 +++++ src/cpu/core_16/main.h | 39 +++++-- src/cpu/slow_16.cpp | 2 + src/fpu/fpu.cpp | 223 +++++++++++++++++++++++++++++++++++++++-- visualc/dosbox.dsp | 26 +++-- 8 files changed, 359 insertions(+), 27 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9873d586..6c649d66 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,6 +3,4 @@ The DOSBox Team Sjoerd v.d. Berg Peter Veenstra - - - +Felix Jakschitsch \ No newline at end of file diff --git a/include/dosbox.h b/include/dosbox.h index 8b7e26c3..d024ff12 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -25,6 +25,7 @@ typedef unsigned short Bit16u; typedef signed short Bit16s; typedef unsigned long Bit32u; typedef signed long Bit32s; +typedef double Real64; #if defined(_MSC_VER) typedef unsigned __int64 Bit64u; typedef signed __int64 Bit64s; diff --git a/include/fpu.h b/include/fpu.h index 8b137891..9f2d819f 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -1 +1,67 @@ +/* + * Copyright (C) 2002 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 Library 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 __FPU_H +#define __FPU_H + +#include +#include +#include + +enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; + +enum { + t_FLD=0, t_FLDST, t_FDIV, + t_FDIVP, t_FCHS, t_FCOMP, + + t_FUNKNOWN, + t_FNOTDONE, +}; + +bool FPU_get_C3(); +bool FPU_get_C2(); +bool FPU_get_C1(); +bool FPU_get_C0(); +bool FPU_get_IR(); +bool FPU_get_SF(); +bool FPU_get_PF(); +bool FPU_get_UF(); +bool FPU_get_OF(); +bool FPU_get_ZF(); +bool FPU_get_DF(); +bool FPU_get_IN(); + +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); + + +#endif \ No newline at end of file diff --git a/include/regs.h b/include/regs.h index bec30b61..43b909e4 100644 --- a/include/regs.h +++ b/include/regs.h @@ -35,6 +35,23 @@ struct Flag_Info { bool oldcf; }; +struct FPU_Flag_Info { + struct { + Real64 r; + Bit8u tag; + } var1,var2, result; + struct { + bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; + Bit8s tos; + } sw; + struct { + bool ic,ie,sf,pf,uf,of,zf,df,in; + Bit8u rc,pc; + } cw; + Bitu type; + Bitu prev_type; +}; + struct Segment { @@ -51,6 +68,7 @@ enum { cs=0,ds,es,fs,gs,ss}; extern Segment Segs[6]; extern Flag_Info flags; +extern FPU_Flag_Info fpu_flags; //extern Regs regs; void SetSegment_16(Bit32u seg,Bit16u val); @@ -66,6 +84,13 @@ struct CPU_Regs { } ax,bx,cx,dx,si,di,sp,bp,ip; }; +struct FPU_Regs { + struct { + Real64 r; + Bit8u tag; + } st[8]; +}; + extern CPU_Regs cpu_regs; #define reg_al cpu_regs.ax.b.l diff --git a/src/cpu/core_16/main.h b/src/cpu/core_16/main.h index 2e9dd4b6..c6e7a670 100644 --- a/src/cpu/core_16/main.h +++ b/src/cpu/core_16/main.h @@ -944,6 +944,33 @@ restart: reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); } break; +#ifdef USE_FPU +#include "../../fpu/fpu_core_16/support.h" + case 0xd8: /* FPU ESC 0 */ + FPU_ESC_0; + break; + case 0xd9: /* FPU ESC 1 */ + FPU_ESC_1; + break; + case 0xda: /* FPU ESC 2 */ + FPU_ESC_2; + break; + case 0xdb: /* FPU ESC 3 */ + FPU_ESC_3; + break; + case 0xdc: /* FPU ESC 4 */ + FPU_ESC_4; + break; + case 0xdd: /* FPU ESC 5 */ + FPU_ESC_5; + break; + case 0xde: /* FPU ESC 6 */ + FPU_ESC_6; + break; + case 0xdf: /* FPU ESC 7 */ + FPU_ESC_7; + break; +#else case 0xd8: /* FPU ESC 0 */ case 0xd9: /* FPU ESC 1 */ case 0xda: /* FPU ESC 2 */ @@ -953,16 +980,12 @@ restart: case 0xde: /* FPU ESC 6 */ case 0xdf: /* FPU ESC 7 */ { - Bit8u rm=Fetchb(); - if (rm>=0xc0) { - FPU_ESC0_Normal(rm); - } else { - GetEAa;FPU_ESC0_EA(rm,eaa); - } - break; + GetRM; + if( rm < 0xc0 ) + GetEAa; } - break; +#endif case 0xe0: /* LOOPNZ */ if ((--reg_cx) && !get_ZF()) ADDIPFAST(Fetchbs()); else ADDIPFAST(1); diff --git a/src/cpu/slow_16.cpp b/src/cpu/slow_16.cpp index 6d02df7d..e0bf5114 100644 --- a/src/cpu/slow_16.cpp +++ b/src/cpu/slow_16.cpp @@ -73,6 +73,8 @@ typedef HostOff EAPoint; extern Bitu cycle_count; #define CPU_386 +#define USE_FPU +#define FPU_386 //TODO Change name #define FULLFLAGS diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 88a7d6b9..61c68de7 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -20,6 +20,7 @@ #include #include "mem.h" #include "dosbox.h" +#include "fpu.h" typedef PhysPt EAPoint; @@ -35,28 +36,236 @@ typedef PhysPt EAPoint; #define SaveMw(off,val) mem_writew(off,val) #define SaveMd(off,val) mem_writed(off,val) -typedef long double FPUREG; +FPU_Flag_Info fpu_flags; +FPU_Regs fpu_regs; +#define FPU_GetZF fpu_flags.sw.zf = FPU_get_ZF(); -#include "fpu_load.h" +#include "fpu_core_16/instructions.h" +#define FPU_ParseCW(newcw) { \ + fpu_flags.cw.ic = ((bool)((newcw&0x1000)>>12)?true:false); \ + fpu_flags.cw.rc = (Bit8u)((newcw&0x0C00)>>10); \ + fpu_flags.cw.pc = (Bit8u)((newcw&0x0300)>>8); \ + fpu_flags.cw.ie = ((bool)((newcw&0x0080)>>7)?true:false); \ + fpu_flags.cw.sf = ((bool)((newcw&0x0040)>>6)?true:false); \ + fpu_flags.cw.pf = ((bool)((newcw&0x0020)>>5)?true:false); \ + fpu_flags.cw.uf = ((bool)((newcw&0x0010)>>4)?true:false); \ + fpu_flags.cw.of = ((bool)((newcw&0x0008)>>3)?true:false); \ + fpu_flags.cw.zf = ((bool)((newcw&0x0004)>>2)?true:false); \ + fpu_flags.cw.df = ((bool)((newcw&0x0002)>>1)?true:false); \ + fpu_flags.cw.in = ((bool)(newcw&0x0001)?true:false); \ +} +#define FPU_makeCW(newcw) { \ + newcw = (Bit16u)fpu_flags.cw.in; \ + newcw |= (fpu_flags.cw.df<<1); \ + newcw |= (fpu_flags.cw.zf<<2); \ + newcw |= (fpu_flags.cw.of<<3); \ + newcw |= (fpu_flags.cw.uf<<4); \ + newcw |= (fpu_flags.cw.pf<<5); \ + newcw |= (fpu_flags.cw.sf<<6); \ + newcw |= (fpu_flags.cw.ie<<7); \ + newcw |= (fpu_flags.cw.pc<<8); \ + newcw |= (fpu_flags.cw.rc<<10); \ + newcw |= (fpu_flags.cw.ic<<12); \ +} +#define FPU_ParseSW(newsw) { \ + fpu_flags.sw.bf = ((bool)((newsw&0x8000)>>15)?true:false); \ + fpu_flags.sw.c3 = ((bool)((newsw&0x4000)>>14)?true:false); \ + fpu_flags.sw.tos = (Bit8s)((newsw&0x3800)>>11); \ + fpu_flags.sw.c2 = ((bool)((newsw&0x0400)>>10)?true:false); \ + fpu_flags.sw.c1 = ((bool)((newsw&0x0200)>>9)?true:false); \ + fpu_flags.sw.c0 = ((bool)((newsw&0x0100)>>8)?true:false); \ + fpu_flags.sw.ir = ((bool)((newsw&0x0080)>>7)?true:false); \ + fpu_flags.sw.sf = ((bool)((newsw&0x0040)>>6)?true:false); \ + fpu_flags.sw.pf = ((bool)((newsw&0x0020)>>5)?true:false); \ + fpu_flags.sw.uf = ((bool)((newsw&0x0010)>>4)?true:false); \ + fpu_flags.sw.of = ((bool)((newsw&0x0008)>>3)?true:false); \ + fpu_flags.sw.zf = ((bool)((newsw&0x0004)>>2)?true:false); \ + fpu_flags.sw.df = ((bool)((newsw&0x0002)>>1)?true:false); \ + fpu_flags.sw.in = ((bool)(newsw&0x0001)?true:false); \ +} +#define FPU_makeSW(newsw) { \ + newsw = (Bit16u)fpu_flags.sw.in; \ + newsw |= (fpu_flags.sw.df<<1); \ + newsw |= (fpu_flags.sw.zf<<2); \ + newsw |= (fpu_flags.sw.of<<3); \ + newsw |= (fpu_flags.sw.uf<<4); \ + newsw |= (fpu_flags.sw.pf<<5); \ + newsw |= (fpu_flags.sw.sf<<6); \ + newsw |= (fpu_flags.sw.ir<<7); \ + newsw |= (fpu_flags.sw.c0<<8); \ + newsw |= (fpu_flags.sw.c1<<9); \ + newsw |= (fpu_flags.sw.c2<<10); \ + newsw |= (fpu_flags.sw.tos<<11); \ + newsw |= (fpu_flags.sw.c3<<14); \ + newsw |= (fpu_flags.sw.bf<<15); \ +} + +#define FPU_LOADFLAGS { \ + fpu_flags.sw.bf = false; \ + fpu_flags.sw.c3 = FPU_get_C3(); \ + fpu_flags.sw.c2 = FPU_get_C2(); \ + fpu_flags.sw.c1 = FPU_get_C1(); \ + fpu_flags.sw.c0 = FPU_get_C0(); \ + fpu_flags.sw.ir = FPU_get_IR(); \ + fpu_flags.sw.sf = FPU_get_SF(); \ + fpu_flags.sw.pf = FPU_get_PF(); \ + fpu_flags.sw.uf = FPU_get_UF(); \ + fpu_flags.sw.of = FPU_get_OF(); \ + fpu_flags.sw.zf = FPU_get_ZF(); \ + fpu_flags.sw.df = FPU_get_DF(); \ + fpu_flags.sw.in = FPU_get_IN(); \ +} void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - - } void FPU_ESC0_Normal(Bitu rm) { - - } +void FPU_ESC1_EA(Bitu rm,PhysPt addr) { + Bit16u cw; + Bitu opcode = (rm&0x38)>>3; + switch(opcode) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 6: + break; + case 5: + FPU_ParseCW(LoadMw(addr)); /* FLDCW */ + break; + case 7: /* FSTCW */ + FPU_makeCW(cw); + SaveMw(addr,cw); + break; + } +} + +void FPU_ESC1_Normal(Bitu rm) { + Bitu opcode = (rm&0xF0); + + switch(opcode) { + case 0xC0: +// if(rm&8) +// else + FLDST(rm-0xC0); /* FLDST */ + break; + case 0xD0: + break; + } + switch(rm) { + case 0xE0: /* FCHS */ + FCHS; + break; + case 0xE8: /* FLD1 */ + FLD(1); + break; + case 0xEE: /* FLDZ */ + FLD(0); + break; + } +} + + +void FPU_ESC2_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC2_Normal(Bitu rm) { +} + + +void FPU_ESC3_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC3_Normal(Bitu rm) { + switch( rm ) { + case 0xE3: /* FINIT */ + FPU_ParseCW(0x037F); + for(int i=0;i<8;i++) { + fpu_regs.st[i].r = 0; + fpu_regs.st[i].tag = FPUREG_EMPTY; + } + break; + } +} + + +void FPU_ESC4_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC4_Normal(Bitu rm) { +} + + +void FPU_ESC5_EA(Bitu rm,PhysPt addr) { + Bit16u sw; + Bitu opcode = (rm&0x38)>>3; + + switch(opcode) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: /* FSTSW */ + FPU_LOADFLAGS; + FPU_makeSW(sw); + SaveMw(addr,sw); + break; + } +} + +void FPU_ESC5_Normal(Bitu rm) { +} + + +void FPU_ESC6_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC6_Normal(Bitu rm) { + Bitu opcode = (rm&0xF0); + + if(rm==0xD9) { /* FCOMPP */ + FCOMPP; + return; + } + switch(opcode) { + case 0xC0: +// if(rm&8) + break; + case 0xD0: +// if(rm&8) + break; + case 0xE0: +// if(rm&8) + break; + case 0xF0: + if(rm&8) + FDIVP(rm-0xF8,0); + break; + } +} + + +void FPU_ESC7_EA(Bitu rm,PhysPt addr) { +} + +void FPU_ESC7_Normal(Bitu rm) { +} void FPU_Init(void) { + fpu_flags.type = t_FUNKNOWN; +} + -} \ No newline at end of file diff --git a/visualc/dosbox.dsp b/visualc/dosbox.dsp index cd0bae59..1e21b1ca 100644 --- a/visualc/dosbox.dsp +++ b/visualc/dosbox.dsp @@ -223,10 +223,6 @@ SOURCE=..\src\dos\dos.cpp # End Source File # Begin Source File -SOURCE=..\src\dos\dos_classes.cpp -# End Source File -# Begin Source File - SOURCE=..\src\dos\dos_devices.cpp # End Source File # Begin Source File @@ -467,10 +463,6 @@ SOURCE=..\src\misc\programs.cpp # End Source File # Begin Source File -SOURCE=..\src\misc\setup.cpp -# End Source File -# Begin Source File - SOURCE=..\src\misc\support.cpp # End Source File # End Group @@ -501,13 +493,25 @@ SOURCE=..\src\shell\shell_misc.cpp # Begin Group "fpu" # PROP Default_Filter "" +# Begin Group "fpu_core_16" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\fpu\fpu_core_16\instructions.h +# End Source File +# Begin Source File + +SOURCE=..\src\fpu\fpu_core_16\support.h +# End Source File +# End Group # Begin Source File SOURCE=..\src\fpu\fpu.cpp # End Source File # Begin Source File -SOURCE=..\src\fpu\fpu_load.h +SOURCE=..\src\fpu\fpu_flags.cpp # End Source File # End Group # Begin Group "visualc" @@ -576,6 +580,10 @@ SOURCE=..\include\dosbox.h # End Source File # Begin Source File +SOURCE=..\include\fpu.h +# End Source File +# Begin Source File + SOURCE=..\include\hardware.h # End Source File # Begin Source File