1 /*
2  *  Copyright (C) 2002-2010  The DOSBox Team
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #ifndef DOSBOX_FPU_H
20 #define DOSBOX_FPU_H
21 
22 #ifndef DOSBOX_MEM_H
23 #include "mem.h"
24 #endif
25 
26 void FPU_ESC0_Normal(Bitu rm);
27 void FPU_ESC0_EA(Bitu func,PhysPt ea);
28 void FPU_ESC1_Normal(Bitu rm);
29 void FPU_ESC1_EA(Bitu func,PhysPt ea);
30 void FPU_ESC2_Normal(Bitu rm);
31 void FPU_ESC2_EA(Bitu func,PhysPt ea);
32 void FPU_ESC3_Normal(Bitu rm);
33 void FPU_ESC3_EA(Bitu func,PhysPt ea);
34 void FPU_ESC4_Normal(Bitu rm);
35 void FPU_ESC4_EA(Bitu func,PhysPt ea);
36 void FPU_ESC5_Normal(Bitu rm);
37 void FPU_ESC5_EA(Bitu func,PhysPt ea);
38 void FPU_ESC6_Normal(Bitu rm);
39 void FPU_ESC6_EA(Bitu func,PhysPt ea);
40 void FPU_ESC7_Normal(Bitu rm);
41 void FPU_ESC7_EA(Bitu func,PhysPt ea);
42 
43 
44 typedef union {
45     double d;
46 #ifndef WORDS_BIGENDIAN
47     struct {
48         Bit32u lower;
49         Bit32s upper;
50     } l;
51 #else
52     struct {
53         Bit32s upper;
54         Bit32u lower;
55     } l;
56 #endif
57     Bit64s ll;
58 } FPU_Reg;
59 
60 typedef struct {
61     Bit32u m1;
62     Bit32u m2;
63     Bit16u m3;
64 
65     Bit16u d1;
66     Bit32u d2;
67 } FPU_P_Reg;
68 
69 enum FPU_Tag {
70 	TAG_Valid = 0,
71 	TAG_Zero  = 1,
72 	TAG_Weird = 2,
73 	TAG_Empty = 3
74 };
75 
76 enum FPU_Round {
77 	ROUND_Nearest = 0,
78 	ROUND_Down    = 1,
79 	ROUND_Up      = 2,
80 	ROUND_Chop    = 3
81 };
82 
83 typedef struct {
84 	FPU_Reg		regs[9];
85 	FPU_P_Reg	p_regs[9];
86 	FPU_Tag		tags[9];
87 	Bit16u		cw,cw_mask_all;
88 	Bit16u		sw;
89 	Bit32u		top;
90 	FPU_Round	round;
91 } FPU_rec;
92 
93 
94 //get pi from a real library
95 #define PI		3.14159265358979323846
96 #define L2E		1.4426950408889634
97 #define L2T		3.3219280948873623
98 #define LN2		0.69314718055994531
99 #define LG2		0.3010299956639812
100 
101 
102 extern FPU_rec fpu;
103 
104 #define TOP fpu.top
105 #define STV(i)  ( (fpu.top+ (i) ) & 7 )
106 
107 
108 Bit16u FPU_GetTag(void);
109 void FPU_FLDCW(PhysPt addr);
110 
FPU_SetTag(Bit16u tag)111 static INLINE void FPU_SetTag(Bit16u tag){
112 	for(Bitu i=0;i<8;i++)
113 		fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3);
114 }
115 
FPU_SetCW(Bitu word)116 static INLINE void FPU_SetCW(Bitu word){
117 	fpu.cw = (Bit16u)word;
118 	fpu.cw_mask_all = (Bit16u)(word | 0x3f);
119 	fpu.round = (FPU_Round)((word >> 10) & 3);
120 }
121 
122 
FPU_GET_TOP(void)123 static INLINE Bitu FPU_GET_TOP(void) {
124 	return (fpu.sw & 0x3800)>>11;
125 }
126 
FPU_SET_TOP(Bitu val)127 static INLINE void FPU_SET_TOP(Bitu val){
128 	fpu.sw &= ~0x3800;
129 	fpu.sw |= (val&7)<<11;
130 }
131 
132 
FPU_SET_C0(Bitu C)133 static INLINE void FPU_SET_C0(Bitu C){
134 	fpu.sw &= ~0x0100;
135 	if(C) fpu.sw |=  0x0100;
136 }
137 
FPU_SET_C1(Bitu C)138 static INLINE void FPU_SET_C1(Bitu C){
139 	fpu.sw &= ~0x0200;
140 	if(C) fpu.sw |=  0x0200;
141 }
142 
FPU_SET_C2(Bitu C)143 static INLINE void FPU_SET_C2(Bitu C){
144 	fpu.sw &= ~0x0400;
145 	if(C) fpu.sw |=  0x0400;
146 }
147 
FPU_SET_C3(Bitu C)148 static INLINE void FPU_SET_C3(Bitu C){
149 	fpu.sw &= ~0x4000;
150 	if(C) fpu.sw |= 0x4000;
151 }
152 
153 
154 #endif
155