aboutsummaryrefslogtreecommitdiff
path: root/op-i386.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-03-16 18:05:05 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-03-16 18:05:05 +0000
commit6dbad63eef5947c6c8750e44f408138779b6d0bb (patch)
treee96572a87e9adb75efde4cd9213472f1903ec742 /op-i386.c
parent27362c82e9df7770554943ceda36ec4e5638c49d (diff)
added minimal segment support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@28 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'op-i386.c')
-rw-r--r--op-i386.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/op-i386.c b/op-i386.c
index 6d695ff90d..503fb88ede 100644
--- a/op-i386.c
+++ b/op-i386.c
@@ -858,6 +858,60 @@ void OPPROTO op_das(void)
CC_SRC = eflags;
}
+/* segment handling */
+
+void load_seg(int seg_reg, int selector)
+{
+ SegmentCache *sc;
+ SegmentDescriptorTable *dt;
+ int index;
+ uint32_t e1, e2;
+ uint8_t *ptr;
+
+ env->segs[seg_reg] = selector;
+ sc = &env->seg_cache[seg_reg];
+ if (env->vm86) {
+ sc->base = (void *)(selector << 4);
+ sc->limit = 0xffff;
+ sc->seg_32bit = 0;
+ } else {
+ if (selector & 0x4)
+ dt = &env->ldt;
+ else
+ dt = &env->gdt;
+ index = selector & ~7;
+ if ((index + 7) > dt->limit)
+ raise_exception(EXCP0D_GPF);
+ ptr = dt->base + index;
+ e1 = ldl(ptr);
+ e2 = ldl(ptr + 4);
+ sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
+ sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);
+ if (e2 & (1 << 23))
+ sc->limit = (sc->limit << 12) | 0xfff;
+ sc->seg_32bit = (e2 >> 22) & 1;
+#if 0
+ fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n",
+ selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);
+#endif
+ }
+}
+
+void OPPROTO op_movl_seg_T0(void)
+{
+ load_seg(PARAM1, T0 & 0xffff);
+}
+
+void OPPROTO op_movl_T0_seg(void)
+{
+ T0 = env->segs[PARAM1];
+}
+
+void OPPROTO op_addl_A0_seg(void)
+{
+ A0 += *(unsigned long *)((char *)env + PARAM1);
+}
+
/* flags handling */
/* slow jumps cases (compute x86 flags) */