PUSHA/POP instructions rewritten, fixed PANIC message

This commit is contained in:
Stanislav Shwartsman 2007-03-02 21:03:25 +00:00
parent 0be7d6e5e3
commit 8067503c67
2 changed files with 96 additions and 93 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack16.cc,v 1.20 2006-03-06 22:03:04 sshwarts Exp $
// $Id: stack16.cc,v 1.21 2007-03-02 21:03:23 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -140,63 +140,63 @@ void BX_CPU_C::POP_Ew(bxInstruction_c *i)
#if BX_CPU_LEVEL >= 3
void BX_CPU_C::PUSHAD16(bxInstruction_c *i)
{
Bit32u temp_ESP;
Bit16u sp;
Bit32u temp_ESP = ESP;
Bit16u temp_SP = SP;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
temp_ESP = ESP;
else
temp_ESP = SP;
#if BX_CPU_LEVEL >= 2
if (protected_mode()) {
if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 16) ) {
BX_ERROR(("PUSHAD(): stack doesn't have enough room!"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
}
else
#endif
{
if (temp_ESP < 16)
BX_PANIC(("PUSHAD: eSP < 16"));
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 2), &AX);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 4), &CX);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 6), &DX);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 8), &BX);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 10), &temp_SP);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 12), &BP);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 14), &SI);
write_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 16), &DI);
ESP -= 16;
}
else
{
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 2), &AX);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 4), &CX);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 6), &DX);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 8), &BX);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 10), &temp_SP);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 12), &BP);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 14), &SI);
write_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP - 16), &DI);
SP -= 16;
}
sp = SP;
/* ??? optimize this by using virtual write, all checks passed */
push_16(AX);
push_16(CX);
push_16(DX);
push_16(BX);
push_16(sp);
push_16(BP);
push_16(SI);
push_16(DI);
}
void BX_CPU_C::POPAD16(bxInstruction_c *i)
{
Bit16u di, si, bp, tmp, bx, dx, cx, ax;
Bit16u di, si, bp, bx, dx, cx, ax;
if (protected_mode()) {
if ( !can_pop(16) ) {
BX_ERROR(("POPA: not enough bytes on stack"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
Bit32u temp_ESP = ESP;
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 0), &di);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 2), &si);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 4), &bp);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 8), &bx);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 10), &dx);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 12), &cx);
read_virtual_word(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 14), &ax);
ESP += 16;
}
else
{
Bit16u temp_SP = SP;
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 0), &di);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 2), &si);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 4), &bp);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 8), &bx);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 10), &dx);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 12), &cx);
read_virtual_word(BX_SEG_REG_SS, (Bit16u) (temp_SP + 14), &ax);
SP += 16;
}
/* ??? optimize this */
pop_16(&di);
pop_16(&si);
pop_16(&bp);
pop_16(&tmp); /* value for SP discarded */
pop_16(&bx);
pop_16(&dx);
pop_16(&cx);
pop_16(&ax);
DI = di;
SI = si;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack32.cc,v 1.33 2006-06-12 16:58:27 sshwarts Exp $
// $Id: stack32.cc,v 1.34 2007-03-02 21:03:25 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -158,60 +158,63 @@ void BX_CPU_C::POP32_SS(bxInstruction_c *i)
#if BX_CPU_LEVEL >= 2
void BX_CPU_C::PUSHAD32(bxInstruction_c *i)
{
Bit32u temp_ESP;
Bit32u esp;
Bit32u temp_ESP = ESP;
Bit16u temp_SP = SP;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
temp_ESP = ESP;
{
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 4), &EAX);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 8), &ECX);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 12), &EDX);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 16), &EBX);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 20), &temp_ESP);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 24), &EBP);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 28), &ESI);
write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 32), &EDI);
ESP -= 32;
}
else
temp_ESP = SP;
if (protected_mode()) {
if (! can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 32)) {
BX_ERROR(("PUSHAD(): stack doesn't have enough room!"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
{
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 4), &EAX);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 8), &ECX);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 12), &EDX);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 16), &EBX);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 20), &temp_ESP);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 24), &EBP);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 28), &ESI);
write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP - 32), &EDI);
SP -= 32;
}
else {
if (temp_ESP < 32)
BX_PANIC(("pushad: eSP < 32"));
}
esp = ESP;
/* ??? optimize this by using virtual write, all checks passed */
push_32(EAX);
push_32(ECX);
push_32(EDX);
push_32(EBX);
push_32(esp);
push_32(EBP);
push_32(ESI);
push_32(EDI);
}
void BX_CPU_C::POPAD32(bxInstruction_c *i)
{
Bit32u edi, esi, ebp, etmp, ebx, edx, ecx, eax;
Bit32u edi, esi, ebp, ebx, edx, ecx, eax;
if (protected_mode()) {
if ( !can_pop(32) ) {
BX_ERROR(("POPAD: not enough bytes on stack"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
Bit32u temp_ESP = ESP;
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 0), &edi);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 4), &esi);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 8), &ebp);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 16), &ebx);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 20), &edx);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 24), &ecx);
read_virtual_dword(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 28), &eax);
ESP += 32;
}
else
{
Bit16u temp_SP = SP;
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 0), &edi);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 4), &esi);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 8), &ebp);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 16), &ebx);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 20), &edx);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 24), &ecx);
read_virtual_dword(BX_SEG_REG_SS, (Bit16u) (temp_SP + 28), &eax);
SP += 32;
}
/* ??? optimize this */
pop_32(&edi);
pop_32(&esi);
pop_32(&ebp);
pop_32(&etmp); /* value for ESP discarded */
pop_32(&ebx);
pop_32(&edx);
pop_32(&ecx);
pop_32(&eax);
EDI = edi;
ESI = esi;