mirror of
https://github.com/holub/mame
synced 2025-05-14 09:58:14 +03:00
More x87 ... (and yeah, won't stop here)
This commit is contained in:
parent
255e81e695
commit
8b492b8d80
@ -67,6 +67,18 @@ INLINE X87_REG FPU_POP(i386_state *cpustate)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE X87_REG X87_FROUND(i386_state *cpustate, X87_REG t)
|
||||||
|
{
|
||||||
|
switch((cpustate->fpu_control_word >> 10) & 3)
|
||||||
|
{
|
||||||
|
case 0: t.f = (INT64)t.f + 0.5; break; /* Nearest */
|
||||||
|
case 1: t.f = (INT64)floor(t.f); break; /* Down */
|
||||||
|
case 2: t.f = (INT64)ceil(t.f); break; /* Up */
|
||||||
|
case 3: t.f = (INT64)t.f; break; /* Chop */
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
static void I386OP(fpu_group_d8)(i386_state *cpustate) // Opcode 0xd8
|
static void I386OP(fpu_group_d8)(i386_state *cpustate) // Opcode 0xd8
|
||||||
{
|
{
|
||||||
UINT8 modrm = FETCH(cpustate);
|
UINT8 modrm = FETCH(cpustate);
|
||||||
@ -87,8 +99,36 @@ static void I386OP(fpu_group_d8)(i386_state *cpustate) // Opcode 0xd8
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
switch (modrm & 0x3f)
|
||||||
|
{
|
||||||
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: // FADD
|
||||||
|
{
|
||||||
|
ST(0).f+=ST(modrm & 7).f;
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: // FMUL
|
||||||
|
{
|
||||||
|
ST(0).f*=ST(modrm & 7).f;
|
||||||
|
CYCLES(cpustate,16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: // FCOMP
|
||||||
|
{
|
||||||
|
cpustate->fpu_status_word &= ~(FPU_C3 | FPU_C2 | FPU_C0);
|
||||||
|
if(ST(0).f == ST(modrm & 7).f)
|
||||||
|
cpustate->fpu_status_word |= FPU_C3;
|
||||||
|
if(ST(0).f < ST(modrm & 7).f)
|
||||||
|
cpustate->fpu_status_word |= FPU_C0;
|
||||||
|
FPU_POP(cpustate);
|
||||||
|
CYCLES(cpustate,4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
fatalerror("I386: FPU Op D8 %02X at %08X", modrm, cpustate->pc-2);
|
fatalerror("I386: FPU Op D8 %02X at %08X", modrm, cpustate->pc-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
||||||
@ -203,20 +243,65 @@ static void I386OP(fpu_group_d9)(i386_state *cpustate) // Opcode 0xd9
|
|||||||
X87_REG t;
|
X87_REG t;
|
||||||
t.f = 1.0;
|
t.f = 1.0;
|
||||||
FPU_PUSH(cpustate,t);
|
FPU_PUSH(cpustate,t);
|
||||||
CYCLES(cpustate,1); // TODO
|
CYCLES(cpustate,4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x29: // FLDL2T
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.f = 3.3219280948873623;
|
||||||
|
FPU_PUSH(cpustate,t);
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x2a: // FLDL2E
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.f = 1.4426950408889634;
|
||||||
|
FPU_PUSH(cpustate,t);
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x2b: // FLDPI
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.f = 3.141592653589793;
|
||||||
|
FPU_PUSH(cpustate,t);
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x2c: // FLDEG2
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.f = 0.3010299956639812;
|
||||||
|
FPU_PUSH(cpustate,t);
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x2d: // FLDLN2
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.f = 0.693147180559945;
|
||||||
|
FPU_PUSH(cpustate,t);
|
||||||
|
CYCLES(cpustate,8);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x2e: // FLDZ
|
case 0x2e: // FLDZ
|
||||||
{
|
{
|
||||||
X87_REG t;
|
X87_REG t;
|
||||||
t.f = 0.0;
|
t.f = 0.0;
|
||||||
FPU_PUSH(cpustate,t);
|
FPU_PUSH(cpustate,t);
|
||||||
CYCLES(cpustate,1); // TODO
|
CYCLES(cpustate,4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x3c: // FRNDINT
|
||||||
|
{
|
||||||
|
ST(0) = X87_FROUND(cpustate,ST(0));
|
||||||
|
CYCLES(cpustate,21);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatalerror("I386: FPU Op D9 %02X at %08X", modrm, cpustate->pc-2);
|
fatalerror("I386: FPU Op D9 %02X at %08X", modrm, cpustate->pc-2);
|
||||||
@ -301,7 +386,22 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc
|
|||||||
|
|
||||||
switch ((modrm >> 3) & 0x7)
|
switch ((modrm >> 3) & 0x7)
|
||||||
{
|
{
|
||||||
|
case 3: /* FCOMP double */
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
t.i = READ64(cpustate,ea);
|
||||||
|
cpustate->fpu_status_word &= ~(FPU_C3 | FPU_C2 | FPU_C0);
|
||||||
|
if(ST(0).f == t.f)
|
||||||
|
cpustate->fpu_status_word |= FPU_C3;
|
||||||
|
if(ST(0).f < t.f)
|
||||||
|
cpustate->fpu_status_word |= FPU_C0;
|
||||||
|
|
||||||
|
FPU_POP(cpustate);
|
||||||
|
CYCLES(cpustate,4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 6: /* FDIV double */
|
case 6: /* FDIV double */
|
||||||
|
{
|
||||||
X87_REG t;
|
X87_REG t;
|
||||||
t.i = READ64(cpustate,ea);
|
t.i = READ64(cpustate,ea);
|
||||||
if(t.f)
|
if(t.f)
|
||||||
@ -311,6 +411,7 @@ static void I386OP(fpu_group_dc)(i386_state *cpustate) // Opcode 0xdc
|
|||||||
|
|
||||||
CYCLES(cpustate,73);
|
CYCLES(cpustate,73);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("I386: FPU Op DC %02X at %08X", (modrm >> 3) & 0x7, cpustate->pc-2);
|
printf("I386: FPU Op DC %02X at %08X", (modrm >> 3) & 0x7, cpustate->pc-2);
|
||||||
@ -400,6 +501,17 @@ static void I386OP(fpu_group_dd)(i386_state *cpustate) // Opcode 0xdd
|
|||||||
{
|
{
|
||||||
switch (modrm & 0x3f)
|
switch (modrm & 0x3f)
|
||||||
{
|
{
|
||||||
|
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
||||||
|
{
|
||||||
|
UINT16 tmp;
|
||||||
|
ST(modrm & 7) = ST(0);
|
||||||
|
tmp = (cpustate->fpu_tag_word>>((cpustate->fpu_top&7)<<1))&3;
|
||||||
|
cpustate->fpu_tag_word &= ~(3<<((modrm & 7)<< 1));
|
||||||
|
cpustate->fpu_tag_word |= (tmp<<((modrm & 7)<< 1));
|
||||||
|
FPU_POP(cpustate);
|
||||||
|
CYCLES(cpustate,3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
fatalerror("I386: FPU Op DD %02X at %08X", modrm, cpustate->pc-2);
|
fatalerror("I386: FPU Op DD %02X at %08X", modrm, cpustate->pc-2);
|
||||||
}
|
}
|
||||||
@ -496,8 +608,19 @@ static void I386OP(fpu_group_df)(i386_state *cpustate) // Opcode 0xdf
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 7: // FISTP long
|
||||||
|
{
|
||||||
|
X87_REG t;
|
||||||
|
|
||||||
|
t = X87_FROUND(cpustate,ST(0));
|
||||||
|
WRITE64(cpustate,ea,t.i);
|
||||||
|
FPU_POP(cpustate);
|
||||||
|
CYCLES(cpustate,29);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatalerror("I386: FPU Op DF %02X at %08X", modrm, cpustate->pc-2);
|
fatalerror("I386: FPU Op DF %02X at %08X", (modrm >> 3) & 7, cpustate->pc-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8,10 +8,7 @@ Notes:
|
|||||||
It does: mov [ebx],ecx in there, where ebx is 0xfffxxxxx, but only lower
|
It does: mov [ebx],ecx in there, where ebx is 0xfffxxxxx, but only lower
|
||||||
16 bits are used so it ends up in reading at conventional work RAM.
|
16 bits are used so it ends up in reading at conventional work RAM.
|
||||||
CPU core bug?
|
CPU core bug?
|
||||||
bp 0x182a8,ax = 1
|
bp 0x182a8,ax = 1;bp 0x18390,ax = 1;bp 0x183a2,ax = 1;bp 0x1b578,ax = 1
|
||||||
bp 0x18390,ax = 1
|
|
||||||
bp 0x183a2,ax = 1
|
|
||||||
bp 0x1b578,ax = 1
|
|
||||||
|
|
||||||
Funky Ball
|
Funky Ball
|
||||||
dgPIX, 1998
|
dgPIX, 1998
|
||||||
|
Loading…
Reference in New Issue
Block a user