aboutsummaryrefslogtreecommitdiff
path: root/helper-i386.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-07-26 17:59:00 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-07-26 17:59:00 +0000
commit8f186479e26e8207520c062248642153826d5cde (patch)
treec0b1d04576bb2444b39296c1b144c758dd285f78 /helper-i386.c
parent4c3a88a284b288e0ed3c097de7fc07111d848003 (diff)
real mode support (now boots from BOCHS BIOS and LGPL'ed VGA BIOS)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@333 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'helper-i386.c')
-rw-r--r--helper-i386.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/helper-i386.c b/helper-i386.c
index 72b75a5c21..3f63704d5a 100644
--- a/helper-i386.c
+++ b/helper-i386.c
@@ -788,6 +788,37 @@ static inline void load_seg_vm(int seg, int selector)
sc->limit = 0xffff;
}
+/* real mode iret */
+void helper_iret_real(int shift)
+{
+ uint32_t sp, new_cs, new_eip, new_eflags, new_esp;
+ uint8_t *ssp;
+ int eflags_mask;
+
+ sp = env->regs[R_ESP] & 0xffff;
+ ssp = env->segs[R_SS].base + sp;
+ if (shift == 1) {
+ /* 32 bits */
+ new_eflags = ldl(ssp + 8);
+ new_cs = ldl(ssp + 4) & 0xffff;
+ new_eip = ldl(ssp) & 0xffff;
+ } else {
+ /* 16 bits */
+ new_eflags = lduw(ssp + 4);
+ new_cs = lduw(ssp + 2);
+ new_eip = lduw(ssp);
+ }
+ new_esp = sp + (6 << shift);
+ env->regs[R_ESP] = (env->regs[R_ESP] & 0xffff0000) |
+ (new_esp & 0xffff);
+ load_seg_vm(R_CS, new_cs);
+ env->eip = new_eip;
+ eflags_mask = FL_UPDATE_CPL0_MASK;
+ if (shift == 0)
+ eflags_mask &= 0xffff;
+ load_eflags(new_eflags, eflags_mask);
+}
+
/* protected mode iret */
void helper_iret_protected(int shift)
{