From 8067503c67538050903f85a94e8421e2289d54db Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Fri, 2 Mar 2007 21:03:25 +0000 Subject: [PATCH] PUSHA/POP instructions rewritten, fixed PANIC message --- bochs/cpu/stack16.cc | 96 ++++++++++++++++++++++---------------------- bochs/cpu/stack32.cc | 93 +++++++++++++++++++++--------------------- 2 files changed, 96 insertions(+), 93 deletions(-) diff --git a/bochs/cpu/stack16.cc b/bochs/cpu/stack16.cc index d6ef41875..b56a4d567 100644 --- a/bochs/cpu/stack16.cc +++ b/bochs/cpu/stack16.cc @@ -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; diff --git a/bochs/cpu/stack32.cc b/bochs/cpu/stack32.cc index 014d41974..e24e12589 100644 --- a/bochs/cpu/stack32.cc +++ b/bochs/cpu/stack32.cc @@ -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;