mirror of
https://github.com/holub/mame
synced 2025-07-06 10:29:38 +03:00
Added group d9, Funky Ball doesn't moan anymore so let's stop for now
This commit is contained in:
parent
2db950e4a9
commit
54216d4dc3
@ -272,34 +272,90 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
// st(0) -> ea
|
||||
WRITE32(cpustate,ea,FPU_SINGLE_INT32(ST(0)));
|
||||
FPU_POP(cpustate);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
CYCLES(cpustate,7);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // FLDENV
|
||||
{
|
||||
if( cpustate->operand_size ) // 32-bit real/protected mode
|
||||
{
|
||||
cpustate->fpu_control_word = READ16(cpustate,ea);
|
||||
cpustate->fpu_status_word = READ16(cpustate,ea+4);
|
||||
cpustate->fpu_tag_word = READ16(cpustate,ea+8);
|
||||
}
|
||||
else // 16-bit real/protected mode
|
||||
{
|
||||
cpustate->fpu_control_word = READ16(cpustate,ea);
|
||||
cpustate->fpu_status_word = READ16(cpustate,ea+2);
|
||||
cpustate->fpu_tag_word = READ16(cpustate,ea+4);
|
||||
}
|
||||
|
||||
cpustate->fpu_top = (cpustate->fpu_status_word>>11) & 7;
|
||||
|
||||
CYCLES(cpustate,(cpustate->cr[0] & 1) ? 34 : 44);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: // FLDCW
|
||||
{
|
||||
cpustate->fpu_control_word = READ16(cpustate,ea);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
CYCLES(cpustate,4);
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: // FSTENV
|
||||
{ // TODO: 32-bit operand size
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
WRITE16(cpustate,ea+2, cpustate->fpu_status_word);
|
||||
WRITE16(cpustate,ea+4, cpustate->fpu_tag_word);
|
||||
WRITE16(cpustate,ea+6, cpustate->fpu_inst_ptr & 0xffff);
|
||||
WRITE16(cpustate,ea+8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
WRITE16(cpustate,ea+10, cpustate->fpu_data_ptr & 0xffff);
|
||||
WRITE16(cpustate,ea+12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
CYCLES(cpustate,1); // TODO
|
||||
{
|
||||
logerror("x87 FSTENV triggered with mode = %d %02x %02x\n",(cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1,cpustate->cr[0],cpustate->operand_size);
|
||||
switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
|
||||
{
|
||||
case 0: // 16-bit real mode
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
WRITE16(cpustate,ea+2, cpustate->fpu_status_word);
|
||||
WRITE16(cpustate,ea+4, cpustate->fpu_tag_word);
|
||||
WRITE16(cpustate,ea+6, cpustate->fpu_inst_ptr & 0xffff);
|
||||
//WRITE16(cpustate,ea+8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
WRITE16(cpustate,ea+10, cpustate->fpu_data_ptr & 0xffff);
|
||||
//WRITE16(cpustate,ea+12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
break;
|
||||
case 1: // 16-bit protected mode
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
WRITE16(cpustate,ea+2, cpustate->fpu_status_word);
|
||||
WRITE16(cpustate,ea+4, cpustate->fpu_tag_word);
|
||||
WRITE16(cpustate,ea+6, cpustate->fpu_inst_ptr & 0xffff);
|
||||
WRITE16(cpustate,ea+8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
WRITE16(cpustate,ea+10, cpustate->fpu_data_ptr & 0xffff);
|
||||
WRITE16(cpustate,ea+12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
break;
|
||||
case 2: // 32-bit real mode
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
WRITE16(cpustate,ea+4, cpustate->fpu_status_word);
|
||||
WRITE16(cpustate,ea+8, cpustate->fpu_tag_word);
|
||||
WRITE16(cpustate,ea+12, cpustate->fpu_inst_ptr & 0xffff);
|
||||
//WRITE16(cpustate,ea+8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
WRITE16(cpustate,ea+20, cpustate->fpu_data_ptr & 0xffff);
|
||||
//WRITE16(cpustate,ea+12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
|
||||
WRITE32(cpustate,ea+24, (cpustate->fpu_data_ptr>>16)<<12);
|
||||
break;
|
||||
case 3: // 32-bit protected mode
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
WRITE16(cpustate,ea+4, cpustate->fpu_status_word);
|
||||
WRITE16(cpustate,ea+8, cpustate->fpu_tag_word);
|
||||
WRITE32(cpustate,ea+12, cpustate->fpu_inst_ptr);
|
||||
WRITE32(cpustate,ea+16, cpustate->fpu_opcode);
|
||||
WRITE32(cpustate,ea+20, cpustate->fpu_data_ptr);
|
||||
WRITE32(cpustate,ea+24, cpustate->fpu_inst_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
CYCLES(cpustate,(cpustate->cr[0] & 1) ? 56 : 67);
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // FSTCW
|
||||
{
|
||||
WRITE16(cpustate,ea, cpustate->fpu_control_word);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
CYCLES(cpustate,3);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -316,7 +372,7 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
{
|
||||
X87_REG t = ST(modrm & 7);
|
||||
FPU_PUSH(cpustate,t);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
CYCLES(cpustate,4);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -362,6 +418,21 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x25: // FXAM
|
||||
{
|
||||
cpustate->fpu_status_word &= ~(FPU_C3 | FPU_C2 | FPU_C0);
|
||||
if(((cpustate->fpu_tag_word>>((cpustate->fpu_top&1)<<1))&3)==3)
|
||||
cpustate->fpu_status_word |= FPU_C3 | FPU_C0;
|
||||
else if(ST(0).f == 0.0)
|
||||
cpustate->fpu_status_word |= FPU_C3;
|
||||
else
|
||||
cpustate->fpu_status_word |= FPU_C2;
|
||||
if(ST(0).f < 0.0)
|
||||
cpustate->fpu_status_word |= FPU_C1;
|
||||
CYCLES(cpustate,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x28: // FLD1
|
||||
{
|
||||
X87_REG t;
|
||||
@ -416,6 +487,7 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
X87_REG t;
|
||||
t.f = 0.0;
|
||||
FPU_PUSH(cpustate,t);
|
||||
/* TODO: tag moves? */
|
||||
CYCLES(cpustate,4);
|
||||
break;
|
||||
}
|
||||
@ -435,6 +507,85 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x32: // FPTAN
|
||||
{
|
||||
X87_REG t;
|
||||
t.f = 1.0;
|
||||
ST(0).f = tan(ST(0).f);
|
||||
FPU_PUSH(cpustate,t);
|
||||
cpustate->fpu_status_word &= ~(FPU_C2);
|
||||
/* TODO: source operand out-of-range */
|
||||
CYCLES(cpustate,235);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x33: // FPATAN
|
||||
{
|
||||
ST(1).f = atan2(ST(1).f,ST(0).f);
|
||||
FPU_POP(cpustate);
|
||||
CYCLES(cpustate,250);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x36: // FPDECSTP
|
||||
{
|
||||
cpustate->fpu_top -= 1;
|
||||
cpustate->fpu_top &= 7;
|
||||
CYCLES(cpustate,1); // TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x37: // FPINCSTP
|
||||
{
|
||||
cpustate->fpu_top += 1;
|
||||
cpustate->fpu_top &= 7;
|
||||
CYCLES(cpustate,1); // TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x38: // FPREM
|
||||
{
|
||||
X87_REG t;
|
||||
|
||||
if(ST(1).i == 0)
|
||||
fatalerror("Divide by zero on x87 FPREM opcode");
|
||||
|
||||
t.i = ST(0).i / ST(1).i;
|
||||
ST(0).f = ST(0).f-(ST(1).i*t.f);
|
||||
cpustate->fpu_status_word &= ~(FPU_C0 | FPU_C1 | FPU_C2 | FPU_C3);
|
||||
|
||||
if(t.i & 4)
|
||||
cpustate->fpu_status_word |= FPU_C0;
|
||||
|
||||
if(t.i & 2)
|
||||
cpustate->fpu_status_word |= FPU_C3;
|
||||
|
||||
if(t.i & 1)
|
||||
cpustate->fpu_status_word |= FPU_C1;
|
||||
|
||||
CYCLES(cpustate,100);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3a: // FSQRT
|
||||
{
|
||||
ST(0).f = sqrt(ST(0).f);
|
||||
CYCLES(cpustate,83);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3b: // FSINCOS
|
||||
{
|
||||
X87_REG t;
|
||||
t.f = cos(ST(0).f);
|
||||
ST(0).f = sin(ST(0).f);
|
||||
FPU_PUSH(cpustate,t);
|
||||
cpustate->fpu_status_word &= ~(FPU_C2);
|
||||
/* TODO: source operand out-of-range */
|
||||
CYCLES(cpustate,330);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3c: // FRNDINT
|
||||
{
|
||||
ST(0) = X87_FROUND(cpustate,ST(0));
|
||||
@ -442,6 +593,32 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3d: // FSCALE
|
||||
{
|
||||
X87_REG t;
|
||||
t = ST(1);
|
||||
ST(0).f = ST(0).f*pow(2.0,t.f);
|
||||
CYCLES(cpustate,30);
|
||||
}
|
||||
|
||||
case 0x3e: // FSIN
|
||||
{
|
||||
ST(0).f = sin(ST(0).f);
|
||||
cpustate->fpu_status_word &= ~(FPU_C2);
|
||||
/* TODO: source operand out-of-range */
|
||||
CYCLES(cpustate,300);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3f: // FCOS
|
||||
{
|
||||
ST(0).f = cos(ST(0).f);
|
||||
cpustate->fpu_status_word &= ~(FPU_C2);
|
||||
/* TODO: source operand out-of-range */
|
||||
CYCLES(cpustate,300);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatalerror("I386: FPU Op D9 %02X at %08X", modrm, cpustate->pc-2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user