1
0
Fork 0

add dyn_fpu_dh.h

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2709
This commit is contained in:
Sebastian Strohhäcker 2006-10-13 17:42:48 +00:00
parent d0a2e8859e
commit 0e087c2f57

View file

@ -0,0 +1,498 @@
/*
* Copyright (C) 2002-2005 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 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.
*/
/* $Id: dyn_fpu_dh.h,v 1.1 2006-10-13 17:42:48 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
static void FPU_FLD_16(PhysPt addr) {
dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw_dyncorex86(addr);
}
static void FPU_FST_16(PhysPt addr) {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.temp.m1);
}
static void FPU_FLD_32(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr);
}
static void FPU_FST_32(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1);
}
static void FPU_FLD_64(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr);
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4);
}
static void FPU_FST_64(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2);
}
static void FPU_FLD_80(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr);
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8);
}
static void FPU_FST_80(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2);
mem_writew_dyncorex86(addr+8,dyn_dh_fpu.temp.m3);
}
static void FPU_FLDCW_DH(PhysPt addr){
dyn_dh_fpu.cw = mem_readw(addr);
dyn_dh_fpu.temp.m1 = (Bit32u)(dyn_dh_fpu.cw|0x3f);
}
static void FPU_FNSTCW_DH(PhysPt addr){
mem_writew(addr,dyn_dh_fpu.cw);
}
static void FPU_FNINIT_DH(void){
dyn_dh_fpu.cw = 0x37f;
}
static void FPU_FSTENV_DH(PhysPt addr){
if(!cpu.code.big) {
mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writew_dyncorex86(addr+2,(Bit16u)dyn_dh_fpu.temp.m2);
mem_writew_dyncorex86(addr+4,dyn_dh_fpu.temp.m3);
} else {
mem_writed_dyncorex86(addr+0,dyn_dh_fpu.temp.m1);
mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2);
mem_writed_dyncorex86(addr+8,dyn_dh_fpu.temp.m3);
}
}
static void FPU_FLDENV_DH(PhysPt addr){
if(!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr);
dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f;
dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw_dyncorex86(addr+2);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+4);
} else {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr);
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr)|0x3f;
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8);
dyn_dh_fpu.temp.d1 = mem_readw_dyncorex86(addr+10);
}
}
static void FPU_FSAVE_DH(PhysPt addr){
if (!cpu.code.big) {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2;
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x08]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x09]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0c]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0d]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x10]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x11]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x14]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x15]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x18]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]);
for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
} else {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2;
for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
}
}
static void FPU_FRSTOR_DH(PhysPt addr){
if (!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr);
dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f;
dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x05] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x08] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x09] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x0c] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x0d] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x10] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x11] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x14] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x15] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x18] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++);
for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
} else {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr);
for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0]|=0x3f;
}
}
static void dh_fpu_esc0(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xd8);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xd8);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc1(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xd9);
cache_addb(decode.modrm.val);
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FLD float*/
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* UNKNOWN */
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST float*/
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP float*/
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x04: /* FLDENV */
// LOG_MSG("fldenv");
gen_call_function((void*)&FPU_FLDENV_DH,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x05: /* FLDCW */
gen_call_function((void *)&FPU_FLDCW_DH,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x06: /* FSTENV */
// LOG_MSG("fstenv");
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FSTENV_DH,"%Ddr",DREG(EA));
break;
case 0x07: /* FNSTCW*/
gen_call_function((void*)&FPU_FNSTCW_DH,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
static void dh_fpu_esc2(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xda);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xda);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc3(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch (group) {
case 0x04:
switch (sub) {
case 0x00: //FNENI
case 0x01: //FNDIS
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub);
break;
case 0x02: //FNCLEX FCLEX
cache_addb(0xdb);
cache_addb(decode.modrm.val);
break;
case 0x03: //FNINIT FINIT
gen_call_function((void*)&FPU_FNINIT_DH,"");
cache_addb(0xdb);
cache_addb(decode.modrm.val);
break;
case 0x04: //FNSETPM
case 0x05: //FRSTPM
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
break;
default:
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub);
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FILD */
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* FISTTP */
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x05: /* FLD 80 Bits Real */
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x07: /* FSTP 80 Bits Real */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dh_fpu_esc4(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
cache_addb(0xdc);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdc);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc5(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xdd);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch(group){
case 0x00: /* FLD double real*/
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* FISTTP longint*/
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST double real*/
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP double real*/
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
case 0x04: /* FRSTOR */
LOG_MSG("frstor");
gen_call_function((void*)&FPU_FRSTOR_DH,"%Ddr",DREG(EA));
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
break;
case 0x06: /* FSAVE */
LOG_MSG("fsave");
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
gen_call_function((void*)&FPU_FSAVE_DH,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0xe3);
break;
case 0x07: /* FNSTSW */
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dh_fpu_esc6(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
cache_addb(0xde);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
cache_addb(0xde);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc7(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
switch (group){
case 0x01: /* FXCH STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);
break;
case 0x02: /* FSTP STi*/
case 0x03: /* FSTP STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);
break;
case 0x04:
switch(sub){
case 0x00: /* FNSTSW AX*/
cache_addb(0xdd);
cache_addb(0x05|(0x07<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_load_host(&(dyn_dh_fpu.temp.m1),DREG(TMPB),4);
gen_dop_word(DOP_MOV,false,DREG(EAX),DREG(TMPB));
gen_releasereg(DREG(TMPB));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
dyn_fill_ea();
switch(group){
case 0x00: /* FILD Bit16s */
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST Bit16s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP Bit16s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
case 0x04: /* FBLD packed BCD */
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x05: /* FILD Bit64s */
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x06: /* FBSTP packed BCD */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
break;
case 0x07: /* FISTP Bit64s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
#endif