diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-16 18:05:05 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-16 18:05:05 +0000 |
commit | 6dbad63eef5947c6c8750e44f408138779b6d0bb (patch) | |
tree | e96572a87e9adb75efde4cd9213472f1903ec742 /op-i386.c | |
parent | 27362c82e9df7770554943ceda36ec4e5638c49d (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.c | 54 |
1 files changed, 54 insertions, 0 deletions
@@ -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) */ |