fpu updated
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1028
This commit is contained in:
parent
57e3c31efb
commit
3a059c870b
3 changed files with 351 additions and 9 deletions
274
src/fpu/fpu.cpp
274
src/fpu/fpu.cpp
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Add table
Reference in a new issue