1
0
Fork 0

fpu updated

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1028
This commit is contained in:
Peter Veenstra 2003-06-01 14:51:26 +00:00
parent 57e3c31efb
commit 3a059c870b
3 changed files with 351 additions and 9 deletions

View file

@ -23,6 +23,7 @@
#include <float.h>
#include "mem.h"
#include "fpu.h"
#include "cpu.h"
typedef PhysPt EAPoint;
@ -37,8 +38,8 @@ typedef PhysPt EAPoint;
#include "fpu_types.h"
struct {
FPU_Reg regs[8];
FPU_Tag tags[8];
FPU_Reg regs[9];
FPU_Tag tags[9];
Bitu cw;
FPU_Round round;
Bitu ex_mask;
@ -52,33 +53,189 @@ INLINE void FPU_SetCW(Bitu word) {
fpu.round = (FPU_Round)((word >> 8) & 3);
fpu.ex_mask = word & 0x3f;
}
INLINE Bitu FPU_GET_TOP(void){
return (fpu.sw & 0x3800)>>11;
}
INLINE void FPU_SET_TOP(Bitu val){
fpu.sw &= ~0x3800;
fpu.sw |= (val&7)<<11;
return;
}
#include "fpu_instructions.h"
/* TODO : MAKE REGULAR TREE A DEFINE or a function
: ESC6normal => esc4normal+pop or a define as well
: Make a smarter top system. won't matter that much in speed though.
: #define ST fpu.top #define ST(i) (fpu.top+(i))&7 maybe*/
static void EATREE(Bitu _rm){
Bitu group=(_rm >> 3) & 7;
Bitu top = FPU_GET_TOP();
/* data will allready be put in register 8 by caller */
switch(group){
case 0x00: /* FIADD */
FPU_FADD(top, 8);
break;
case 0x01: /* FIMUL */
FPU_FMUL(top, 8);
break;
case 0x02: /* FICOM */
case 0x03: /* FICOMP */
LOG(LOG_FPU,LOG_WARN)("ESC EATREE:Unhandled group %d",group);
break;
case 0x04: /* FISUB */
FPU_FSUB(top,8);
break;
case 0x05: /* FISUBR */
FPU_FSUBR(top,8);
case 0x06: /* FIDIV */
FPU_FDIV(top, 8);
break;
case 0x07: /* FIDIVR */
FPU_FDIVR(top,8);
break;
default:
break;
}
}
void FPU_ESC0_EA(Bitu rm,PhysPt addr) {
/* REGULAR TREE WITH 32 BITS REALS ? float ? */
//THIS SHOULD GO ALLRIGHT !?!
LOG(LOG_FPU, LOG_WARN)("ESC 0 EA used (check the result!)");
union {
float f;
Bit32s l;
} blah;
blah.l = mem_readd(addr);
fpu.regs[8].d = static_cast<double>(blah.f);
EATREE(rm);
}
void FPU_ESC0_Normal(Bitu rm) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub);
Bitu top = FPU_GET_TOP();
switch (group){
case 0x00: /* FADD ST,STi */
FPU_FADD(top,(top+sub)&7);
break;
case 0x01: /* FMUL ST,STi */
FPU_FMUL(top,(top+sub)&7);
break;
case 0x02: /* FCOM STi */
case 0x03: /* FCOMP STi */
LOG(LOG_FPU,LOG_WARN)("ESC 0:Unhandled group %d subfunction %d",group,sub);
break;
case 0x04: /* FSUB ST,STi */
FPU_FSUB(top,(top+sub)&7);
break;
case 0x05: /* FSUBR ST,STi */
FPU_FSUBR(top,(top+sub)&7);
break;
case 0x06: /* FDIV ST,STi */
FPU_FDIV(top,(top+sub)&7);
break;
case 0x07: /* FDIVR ST,STi */
FPU_FDIVR(top,(top+sub)&7);
break;
default:
break;
}
}
void FPU_ESC1_EA(Bitu rm,PhysPt addr) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
}
void FPU_ESC1_Normal(Bitu rm) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %d subfunction %d",group,sub);
switch (group){
case 0x00: /* FLD STi */
{
Bitu top = FPU_GET_TOP();
FPU_PUSH(fpu.regs[(top+sub)&7].d);
}
break;
case 0x04:
switch(sub){
case 0x00: /* FCHS */
case 0x01: /* FABS */
case 0x02: /* UNKNOWN */
case 0x03: /* ILLEGAL */
case 0x04: /* FTST */
case 0x05: /* FXAM */
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_PUSH(1.0);
break;
case 0x01: /* FLDL2T */
case 0x02: /* FLDL2E */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
case 0x03: /* FLDPI */
FPU_PUSH(PI);
break;
case 0x04: /* FLDLG2 */
case 0x05: /* FLDLN2 */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
case 0x06: /* FLDZ*/
FPU_PUSH_ZERO();
break;
case 0x07: /* ILLEGAL */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
break;
case 0x06:
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
case 0x07:
switch(sub){
case 0x03: /* FSINCOS */
FPU_FSINCOS();
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);
}
// 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 */
Bit32s blah = mem_readd(addr);
fpu.regs[8].d = static_cast<double>(blah);
EATREE(rm);
}
void FPU_ESC2_Normal(Bitu rm) {
@ -125,16 +282,52 @@ void FPU_ESC3_Normal(Bitu rm) {
void FPU_ESC4_EA(Bitu rm,PhysPt addr) {
/* REGULAR TREE WITH 64 BITS REALS ? double ? */
E_Exit("how to load a double in esc 4 ea");
//SEE ESC 0 EA
// double blah = mem_readd(addr); //wrong wrong wrong
// fpu.regs[8].d = static_cast<double>(blah);
EATREE(rm);
}
void FPU_ESC4_Normal(Bitu rm) {
//LOOKS LIKE number 6 without popping*/
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
LOG(LOG_FPU,LOG_WARN)("ESC 4:Unhandled group %d subfunction %d",group,sub);
Bitu top = FPU_GET_TOP();
switch(group){
case 0x00: /*FADDP STi,ST*/
FPU_FADD((top+sub)&7,top);
break;
case 0x01: /* FMULP STi,ST*/
FPU_FMUL((top+sub)&7,top);
break;
case 0x02: /* FCOMP5*/
case 0x03: /* weird*/
LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub);
break;
case 0x04: /* FSUBRP STi,ST*/
FPU_FSUBR((top+sub)&7,top);
break;
case 0x05: /* FSUBP STi,ST*/
FPU_FSUB((top+sub)&7,top);
break;
case 0x06: /* FDIVRP STi,ST*/
FPU_FDIVR((top+sub)&7,top);
break;
case 0x07: /* FDIVP STi,ST*/
FPU_FDIV((top+sub)&7,top);
break;
default:
break;
}
}
void FPU_ESC5_EA(Bitu rm,PhysPt addr) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
LOG(LOG_FPU,LOG_WARN)("ESC EA 5:Unhandled group %d subfunction %d",group,sub);
}
void FPU_ESC5_Normal(Bitu rm) {
@ -145,20 +338,85 @@ void FPU_ESC5_Normal(Bitu rm) {
void FPU_ESC6_EA(Bitu rm,PhysPt addr) {
/* 16 bit (word integer) operants */
Bit16s blah = mem_readw(addr);
fpu.regs[8].d = static_cast<double>(blah);
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);
Bitu top = FPU_GET_TOP();
switch(group){
case 0x00: /*FADDP STi,ST*/
FPU_FADD((top+sub)&7,top);
break;
case 0x01: /* FMULP STi,ST*/
FPU_FMUL((top+sub)&7,top);
break;
case 0x02: /* FCOMP5*/
case 0x03: /* weird*/
LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub);
// maybe return and don't pop
break;
case 0x04: /* FSUBRP STi,ST*/
FPU_FSUBR((top+sub)&7,top);
break;
case 0x05: /* FSUBP STi,ST*/
FPU_FSUB((top+sub)&7,top);
break;
case 0x06: /* FDIVRP STi,ST*/
FPU_FDIVR((top+sub)&7,top);
break;
case 0x07: /* FDIVP STi,ST*/
FPU_FDIV((top+sub)&7,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 0x03: /*FISTP */
{ Bitu top = FPU_GET_TOP();
mem_writew(addr,static_cast<Bit16s>(fpu.regs[top].d));
FPU_FPOP();
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
}
}
void FPU_ESC7_Normal(Bitu rm) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
switch (group){
case 0x04:
switch(sub){
case 0x00: /* FNSTSW AX*/
reg_ax = fpu.sw;
break;
default:
break;
}
break;
default:
break;
}
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
}
void FPU_Init(void) {
void FPU_Init(Section*) {
FPU_FINIT();
}

View file

@ -35,4 +35,86 @@ static void FPU_FCLEX(void){
static void FPU_FNOP(void){
return;
}
static void FPU_PUSH(double in){
Bitu newtop = (FPU_GET_TOP() - 1) &7;
FPU_SET_TOP(newtop);
//actually check if empty
fpu.tags[newtop]=TAG_Valid;
fpu.regs[newtop].d=in;
return;
}
static void FPU_PUSH_ZERO(void){
Bitu newtop = (FPU_GET_TOP() - 1) &7;
FPU_SET_TOP(newtop);
//actually check if empty
fpu.tags[newtop]=TAG_Zero;
fpu.regs[newtop].d=0.0;
return;
}
static void FPU_FPOP(void){
Bitu top = FPU_GET_TOP();
fpu.tags[top]=TAG_Empty;
//maybe set zero in it as well
FPU_SET_TOP((top+1)&7);
return;
}
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){
Bitu top = FPU_GET_TOP();
fpu.regs[top].d = sin(fpu.regs[top].d);
//flags and such :)
return;
}
static void FPU_FSINCOS(void){
Bitu top = FPU_GET_TOP();
fpu.regs[top].d = sin(fpu.regs[top].d);
FPU_PUSH(cos(fpu.regs[top].d));
//flags and such :)
return;
}
static void FPU_FCOS(void){
Bitu top = FPU_GET_TOP();
fpu.regs[top].d = cos(fpu.regs[top].d);
//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;
}

View file

@ -36,4 +36,6 @@ enum FPU_Round {
ROUND_Down = 1,
ROUND_Up = 2,
ROUND_Chop = 3
};
};
//get pi from a real library
#define PI 3.1415926535