FPU Support
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@86
This commit is contained in:
		
							parent
							
								
									79182b385d
								
							
						
					
					
						commit
						153d381f5d
					
				
					 3 changed files with 205 additions and 5 deletions
				
			
		|  | @ -16,10 +16,12 @@ | |||
|  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
| 
 | ||||
| #include "dosbox.h" | ||||
| #ifdef C_FPU | ||||
| 
 | ||||
| #include <math.h> | ||||
| #include <float.h> | ||||
| #include "mem.h" | ||||
| #include "dosbox.h" | ||||
| #include "fpu.h" | ||||
| 
 | ||||
| typedef PhysPt EAPoint; | ||||
|  | @ -36,13 +38,16 @@ typedef PhysPt EAPoint; | |||
| #define SaveMw(off,val)	mem_writew(off,val) | ||||
| #define SaveMd(off,val)	mem_writed(off,val) | ||||
| 
 | ||||
| typedef double Real; | ||||
| 
 | ||||
| #include "fpu_types.h" | ||||
| #include "fpu_instructions.h" | ||||
| 
 | ||||
| FPU_Flag_Info fpu_flags; | ||||
| FPU_Regs fpu_regs; | ||||
| FPU_Reg fpu_regs[8]; | ||||
| 
 | ||||
| #define FPU_GetZF	fpu_flags.sw.zf = FPU_get_ZF(); | ||||
| 
 | ||||
| #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); \ | ||||
|  | @ -264,8 +269,9 @@ void FPU_ESC7_EA(Bitu rm,PhysPt addr) { | |||
| void FPU_ESC7_Normal(Bitu rm) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void FPU_Init(void) { | ||||
| 	fpu_flags.type = t_FUNKNOWN; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										162
									
								
								src/fpu/fpu_instructions.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/fpu/fpu_instructions.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,162 @@ | |||
| /*
 | ||||
|  *  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. | ||||
|  */ | ||||
| 
 | ||||
| #define FLD(op1) {												\ | ||||
| 	FPU_GetZF; \ | ||||
| 	fpu_flags.type=t_FLD;									\ | ||||
| 	if(--fpu_flags.sw.tos < 0)									\ | ||||
| 		fpu_flags.sw.tos = 7;									\ | ||||
| 	if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) {	\ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN;	\ | ||||
| 		break;													\ | ||||
| 	}															\ | ||||
| 	if(op1)														\ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID;		\ | ||||
| 	else														\ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO;		\ | ||||
| 	fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1;						\ | ||||
| } | ||||
| 
 | ||||
| #define FLDST(op1) { \ | ||||
| 	FPU_GetZF; \ | ||||
| 	fpu_flags.type=t_FLDST;									\ | ||||
| 	Bit8u reg = fpu_flags.sw.tos+op1; \ | ||||
| 	if(reg>7) reg-=8; \ | ||||
| 	if(--fpu_flags.sw.tos < 0)									\ | ||||
| 		fpu_flags.sw.tos = 7;									\ | ||||
| 	if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN;	\ | ||||
| 		break;													\ | ||||
| 	} \ | ||||
| 	fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ | ||||
| 	fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ | ||||
| } | ||||
| 
 | ||||
| #define FPOP { \ | ||||
| 	fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ | ||||
| 	if(++fpu_flags.sw.tos > 7 ) \ | ||||
| 		fpu_flags.sw.tos = 0; \ | ||||
| } | ||||
| /* FPOP:	fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0;  is not really neccessary */ | ||||
| 
 | ||||
| #define FDIVP(op1,op2) { \ | ||||
| 	Bit8u reg1 = fpu_flags.sw.tos+op1; \ | ||||
| 	Bit8u reg2 = fpu_flags.sw.tos+op2; \ | ||||
| 	fpu_flags.type=t_FDIVP;									\ | ||||
| 	if(reg1>7) reg1-=8; \ | ||||
| 	if(reg2>7) reg2-=8; \ | ||||
| 	if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ | ||||
| 		FPOP; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ | ||||
| 		if(fpu_regs.st[reg1].r > 0) \ | ||||
| 			fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ | ||||
| 		else \ | ||||
| 			fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ | ||||
| 		FPOP; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ | ||||
| 		FPOP; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	fpu_flags.result.tag = FPUREG_VALID; \ | ||||
| 	fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ | ||||
| 	FPOP; \ | ||||
| } | ||||
| 
 | ||||
| #define FDIV(op1,op2) { \ | ||||
| 	Bit8u reg1 = fpu_flags.sw.tos+op1; \ | ||||
| 	Bit8u reg2 = fpu_flags.sw.tos+op2; \ | ||||
| 	fpu_flags.type=t_FDIV;									\ | ||||
| 	if(reg1>7) reg1-=7; \ | ||||
| 	if(reg2>7) reg2-=7; \ | ||||
| 	if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ | ||||
| 		if(fpu_regs.st[reg1].r > 0) \ | ||||
| 			fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ | ||||
| 		else \ | ||||
| 			fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ | ||||
| 		fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ | ||||
| 		break; \ | ||||
| 	} \ | ||||
| 	fpu_flags.result.tag = FPUREG_VALID; \ | ||||
| 	fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ | ||||
| } | ||||
| 
 | ||||
| #define FCHS { \ | ||||
| 	FPU_GetZF; \ | ||||
| 	fpu_flags.type=t_FCHS;	\ | ||||
| 	if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ | ||||
| 		fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ | ||||
| 	} else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ | ||||
| 		fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ | ||||
| 	} else \ | ||||
| 	fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ | ||||
| } | ||||
| 
 | ||||
| #define FCOMPP { \ | ||||
| 	Bit8u reg = fpu_flags.sw.tos+1; \ | ||||
| 	FPU_GetZF; \ | ||||
| 	fpu_flags.type=t_FCOMP;									\ | ||||
| 	if(reg>7) \ | ||||
| 		reg=0; \ | ||||
| 	if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ | ||||
| 		fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ | ||||
| 		if(fpu_flags.result.r==0) \ | ||||
| 			fpu_flags.result.tag = FPUREG_ZERO; \ | ||||
| 		else \ | ||||
| 			fpu_flags.result.tag = FPUREG_VALID; \ | ||||
| 		FPOP; \ | ||||
| 		FPOP; \ | ||||
| 		return; \ | ||||
| 	} else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ | ||||
| 		fpu_flags.result.tag = FPUREG_EMPTY; \ | ||||
| 		FPOP; \ | ||||
| 		FPOP; \ | ||||
| 		return; \ | ||||
| 	} \ | ||||
| 	Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ | ||||
| 	if(res==0||fpu_flags.cw.ic==0) { \ | ||||
| 		fpu_flags.result.tag = FPUREG_ZERO; \ | ||||
| 		FPOP; \ | ||||
| 		FPOP; \ | ||||
| 		return; \ | ||||
| 	} else if(res>0) { \ | ||||
| 		fpu_flags.result.tag = FPUREG_NNAN; \ | ||||
| 		FPOP; \ | ||||
| 		FPOP; \ | ||||
| 		return; \ | ||||
| 	} \ | ||||
| 	fpu_flags.result.tag = FPUREG_PNAN; \ | ||||
| 	FPOP; \ | ||||
| 	FPOP; \ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										32
									
								
								src/fpu/fpu_types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/fpu/fpu_types.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| 
 | ||||
| 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, | ||||
| }; | ||||
| 
 | ||||
| struct FPU_Flag_Info {  | ||||
| 	struct { | ||||
| 		Real 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 FPU_Reg { | ||||
| 	Real r; | ||||
| 	Bit8u tag; | ||||
| }; | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue