mirror of
https://github.com/holub/mame
synced 2025-05-29 00:53:09 +03:00
i386: BTR and page fault fixes from Carl, and basic implementation of FIST and FBLD FPU instructions.
This commit is contained in:
parent
a5c3667e46
commit
d458480a07
@ -2002,7 +2002,7 @@ static void decode_opcode(char *s, const I386_OPCODE *op, UINT8 op1)
|
||||
int i;
|
||||
UINT8 op2;
|
||||
|
||||
if (op->flags & SPECIAL64)
|
||||
if ((op->flags & SPECIAL64) && (address_size == 2))
|
||||
op = &x64_opcode_alt[op->flags >> 24];
|
||||
|
||||
switch( op->flags & FLAGS_MASK )
|
||||
|
@ -337,8 +337,10 @@ static void I386OP(bt_rm16_r16)(i386_state *cpustate) // Opcode 0x0f a3
|
||||
CYCLES(cpustate,CYCLES_BT_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
UINT16 bit = LOAD_REG16(modrm);
|
||||
ea += 2*(bit/16);
|
||||
bit %= 16;
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -366,8 +368,10 @@ static void I386OP(btc_rm16_r16)(i386_state *cpustate) // Opcode 0x0f bb
|
||||
CYCLES(cpustate,CYCLES_BTC_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
UINT16 bit = LOAD_REG16(modrm);
|
||||
ea += 2*(bit/16);
|
||||
bit %= 16;
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -397,8 +401,10 @@ static void I386OP(btr_rm16_r16)(i386_state *cpustate) // Opcode 0x0f b3
|
||||
CYCLES(cpustate,CYCLES_BTR_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
UINT16 bit = LOAD_REG16(modrm);
|
||||
ea += 2*(bit/16);
|
||||
bit %= 16;
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -428,8 +434,10 @@ static void I386OP(bts_rm16_r16)(i386_state *cpustate) // Opcode 0x0f ab
|
||||
CYCLES(cpustate,CYCLES_BTS_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
UINT16 bit = LOAD_REG16(modrm);
|
||||
ea += 2*(bit/16);
|
||||
bit %= 16;
|
||||
UINT16 dst = READ16(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
|
@ -338,8 +338,10 @@ static void I386OP(bt_rm32_r32)(i386_state *cpustate) // Opcode 0x0f a3
|
||||
CYCLES(cpustate,CYCLES_BT_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
UINT32 bit = LOAD_REG32(modrm);
|
||||
ea += 4*(bit/32);
|
||||
bit %= 32;
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -367,8 +369,10 @@ static void I386OP(btc_rm32_r32)(i386_state *cpustate) // Opcode 0x0f bb
|
||||
CYCLES(cpustate,CYCLES_BTC_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
UINT32 bit = LOAD_REG32(modrm);
|
||||
ea += 4*(bit/32);
|
||||
bit %= 32;
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -398,8 +402,10 @@ static void I386OP(btr_rm32_r32)(i386_state *cpustate) // Opcode 0x0f b3
|
||||
CYCLES(cpustate,CYCLES_BTR_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
UINT32 bit = LOAD_REG32(modrm);
|
||||
ea += 4*(bit/32);
|
||||
bit %= 32;
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -429,8 +435,10 @@ static void I386OP(bts_rm32_r32)(i386_state *cpustate) // Opcode 0x0f ab
|
||||
CYCLES(cpustate,CYCLES_BTS_REG_REG);
|
||||
} else {
|
||||
UINT32 ea = GetEA(cpustate,modrm);
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
UINT32 bit = LOAD_REG32(modrm);
|
||||
ea += 4*(bit/32);
|
||||
bit %= 32;
|
||||
UINT32 dst = READ32(cpustate,ea);
|
||||
|
||||
if( dst & (1 << bit) )
|
||||
cpustate->CF = 1;
|
||||
@ -468,7 +476,6 @@ static void I386OP(call_abs32)(i386_state *cpustate) // Opcode 0x9a
|
||||
static void I386OP(call_rel32)(i386_state *cpustate) // Opcode 0xe8
|
||||
{
|
||||
INT32 disp = FETCH32(cpustate);
|
||||
|
||||
PUSH32(cpustate, cpustate->eip );
|
||||
cpustate->eip += disp;
|
||||
CHANGE_PC(cpustate,cpustate->eip);
|
||||
|
@ -867,28 +867,32 @@ INLINE UINT32 DEC32(i386_state *cpustate,UINT32 dst)
|
||||
|
||||
INLINE void PUSH16(i386_state *cpustate,UINT16 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
UINT32 ea, new_esp;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
new_esp = REG32(ESP) - 2;
|
||||
ea = i386_translate(cpustate, SS, new_esp);
|
||||
WRITE16(cpustate, ea, value );
|
||||
REG32(ESP) = new_esp;
|
||||
} else {
|
||||
REG16(SP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
new_esp = (REG16(SP) - 2) & 0xffff;
|
||||
ea = i386_translate(cpustate, SS, new_esp);
|
||||
WRITE16(cpustate, ea, value );
|
||||
REG16(SP) = new_esp;
|
||||
}
|
||||
}
|
||||
INLINE void PUSH32(i386_state *cpustate,UINT32 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
UINT32 ea, new_esp;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
new_esp = REG32(ESP) - 4;
|
||||
ea = i386_translate(cpustate, SS, new_esp);
|
||||
WRITE32(cpustate, ea, value );
|
||||
REG32(ESP) = new_esp;
|
||||
} else {
|
||||
REG16(SP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
new_esp = (REG16(SP) - 4) & 0xffff;
|
||||
ea = i386_translate(cpustate, SS, new_esp);
|
||||
WRITE32(cpustate, ea, value );
|
||||
REG16(SP) = new_esp;
|
||||
}
|
||||
}
|
||||
INLINE void PUSH8(i386_state *cpustate,UINT8 value)
|
||||
@ -903,45 +907,51 @@ INLINE void PUSH8(i386_state *cpustate,UINT8 value)
|
||||
INLINE UINT8 POP8(i386_state *cpustate)
|
||||
{
|
||||
UINT8 value;
|
||||
UINT32 ea;
|
||||
UINT32 ea, new_esp;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) += 1;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) - 1);
|
||||
new_esp = REG32(ESP) + 1;
|
||||
ea = i386_translate(cpustate, SS, new_esp - 1);
|
||||
value = READ8(cpustate, ea );
|
||||
REG32(ESP) = new_esp;
|
||||
} else {
|
||||
REG16(SP) += 1;
|
||||
ea = i386_translate(cpustate, SS, (REG16(SP) - 1) & 0xffff);
|
||||
new_esp = REG16(SP) + 1;
|
||||
ea = i386_translate(cpustate, SS, (new_esp - 1) & 0xffff);
|
||||
value = READ8(cpustate, ea );
|
||||
REG16(SP) = new_esp;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT16 POP16(i386_state *cpustate)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 ea;
|
||||
UINT32 ea, new_esp;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) += 2;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) - 2);
|
||||
new_esp = REG32(ESP) + 2;
|
||||
ea = i386_translate(cpustate, SS, new_esp - 2);
|
||||
value = READ16(cpustate, ea );
|
||||
REG32(ESP) = new_esp;
|
||||
} else {
|
||||
REG16(SP) += 2;
|
||||
ea = i386_translate(cpustate, SS, (REG16(SP) - 2) & 0xffff);
|
||||
new_esp = REG16(SP) + 2;
|
||||
ea = i386_translate(cpustate, SS, (new_esp - 2) & 0xffff);
|
||||
value = READ16(cpustate, ea );
|
||||
REG16(SP) = new_esp;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 POP32(i386_state *cpustate)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 ea;
|
||||
UINT32 ea, new_esp;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) += 4;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) - 4);
|
||||
new_esp = REG32(ESP) + 4;
|
||||
ea = i386_translate(cpustate, SS, new_esp - 4);
|
||||
value = READ32(cpustate, ea );
|
||||
REG32(ESP) = new_esp;
|
||||
} else {
|
||||
REG16(SP) += 4;
|
||||
ea = i386_translate(cpustate, SS, (REG16(SP) - 4) & 0xffff);
|
||||
new_esp = REG16(SP) + 4;
|
||||
ea = i386_translate(cpustate, SS, (new_esp - 4) & 0xffff);
|
||||
value = READ32(cpustate, ea );
|
||||
REG16(SP) = new_esp;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -1529,6 +1529,16 @@ static void I386OP(fpu_group_df)(i386_state *cpustate) // Opcode 0xdf
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // FIST
|
||||
{
|
||||
X87_REG t;
|
||||
|
||||
t = X87_FROUND(cpustate,ST(0));
|
||||
WRITE16(cpustate,ea,(INT16)t.i);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
break;
|
||||
|
||||
}
|
||||
case 3: // FISTP short
|
||||
{
|
||||
X87_REG t;
|
||||
@ -1539,7 +1549,30 @@ static void I386OP(fpu_group_df)(i386_state *cpustate) // Opcode 0xdf
|
||||
CYCLES(cpustate,29);
|
||||
break;
|
||||
}
|
||||
case 4: // FBLD
|
||||
{
|
||||
int i;
|
||||
double bcd_data = 0.0;
|
||||
UINT8 byte;
|
||||
X87_REG t;
|
||||
|
||||
for(i=0;i<9;i++)
|
||||
{
|
||||
byte = READ8(cpustate,ea+i);
|
||||
bcd_data += floor(fmod((byte & 0x0f),10.0));
|
||||
bcd_data *= 10.0;
|
||||
byte >>= 4;
|
||||
bcd_data += floor(fmod((byte & 0x0f),10.0));
|
||||
bcd_data *= 10.0;
|
||||
}
|
||||
byte = READ8(cpustate,ea+9);
|
||||
if(byte & 0x80)
|
||||
bcd_data -= bcd_data;
|
||||
|
||||
t.f = bcd_data;
|
||||
FPU_PUSH(cpustate,t);
|
||||
CYCLES(cpustate,1); // TODO
|
||||
}
|
||||
case 5: // FILD long
|
||||
{
|
||||
X87_REG t;
|
||||
@ -1563,7 +1596,7 @@ static void I386OP(fpu_group_df)(i386_state *cpustate) // Opcode 0xdf
|
||||
res = (UINT8)floor(fmod(bcd_data,10.0));
|
||||
bcd_data -= floor(fmod(bcd_data,10.0));
|
||||
bcd_data /= 10.0;
|
||||
res = (UINT8)floor(fmod(bcd_data,10.0))<<4;
|
||||
res |= (UINT8)floor(fmod(bcd_data,10.0))<<4;
|
||||
bcd_data -= floor(fmod(bcd_data,10.0));
|
||||
bcd_data /= 10.0;
|
||||
WRITE8(cpustate,ea+i,res);
|
||||
|
Loading…
Reference in New Issue
Block a user