--- np2/i386c/ia32/ia32.c 2003/12/22 18:00:31 1.3 +++ np2/i386c/ia32/ia32.c 2011/12/21 18:02:15 1.23 @@ -1,5 +1,3 @@ -/* $Id: ia32.c,v 1.3 2003/12/22 18:00:31 monaka Exp $ */ - /* * Copyright (c) 2002-2003 NONAKA Kimihiro * All rights reserved. @@ -12,8 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -31,72 +27,22 @@ #include "cpu.h" #include "ia32.mcr" - I386CORE i386core; -BYTE iflags[] = { - 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, - 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, -}; - -BYTE *reg8_b20[0x100]; -BYTE *reg8_b53[0x100]; -WORD *reg16_b20[0x100]; -WORD *reg16_b53[0x100]; -DWORD *reg32_b20[0x100]; -DWORD *reg32_b53[0x100]; - +UINT8 *reg8_b20[0x100]; +UINT8 *reg8_b53[0x100]; +UINT16 *reg16_b20[0x100]; +UINT16 *reg16_b53[0x100]; +UINT32 *reg32_b20[0x100]; +UINT32 *reg32_b53[0x100]; void ia32_init(void) { int i; - memset(&i386core, 0, sizeof(i386core)); - CPU_STATSAVE.cpu_inst_default.seg_base = (DWORD)-1; - - CPU_EDX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING; - CPU_EFLAG = 2; - CPU_CR0 = CPU_CR0_CD | CPU_CR0_NW | CPU_CR0_ET; - CPU_MXCSR = 0x1f80; - CPU_GDTR_LIMIT = 0xffff; - CPU_IDTR_LIMIT = 0xffff; - - for (i = 0; i < CPU_SEGREG_NUM; ++i) { - CPU_STAT_SREG_INIT(i); - } - CPU_LDTR_LIMIT = 0xffff; - CPU_TR_LIMIT = 0xffff; + memset(&i386core.s, 0, sizeof(i386core.s)); + ia32_initreg(); for (i = 0; i < 0x100; ++i) { /* 8bit */ @@ -126,92 +72,155 @@ ia32_init(void) } resolve_init(); -#if defined(SUPPORT_TLB) - tlb_init(); -#endif -#ifdef USE_FPU - fpu_init(); -#endif } +void +ia32_setextsize(UINT32 size) +{ + + if (CPU_EXTMEMSIZE != size) { + UINT8 *extmem; + extmem = CPU_EXTMEM; + if (extmem != NULL) { + _MFREE(extmem); + extmem = NULL; + } + if (size != 0) { + extmem = (UINT8 *)_MALLOC(size + 16, "EXTMEM"); + } + if (extmem != NULL) { + ZeroMemory(extmem, size + 16); + CPU_EXTMEM = extmem; + CPU_EXTMEMSIZE = size; + CPU_EXTMEMBASE = CPU_EXTMEM - 0x100000; + CPU_EXTLIMIT16 = min(size + 0x100000, 0xf00000); + CPU_EXTLIMIT = size + 0x100000; + } + else { + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; + CPU_EXTMEMBASE = NULL; + CPU_EXTLIMIT16 = 0; + CPU_EXTLIMIT = 0; + } + } + CPU_EMSPTR[0] = mem + 0xc0000; + CPU_EMSPTR[1] = mem + 0xc4000; + CPU_EMSPTR[2] = mem + 0xc8000; + CPU_EMSPTR[3] = mem + 0xcc000; +} + +void +ia32_setemm(UINT frame, UINT32 addr) { + + BYTE *ptr; + + frame &= 3; + if (addr < USE_HIMEM) { + ptr = mem + addr; + } + else if ((addr - 0x100000 + 0x4000) <= CPU_EXTMEMSIZE) { + ptr = CPU_EXTMEM + (addr - 0x100000); + } + else { + ptr = mem + 0xc0000 + (frame << 14); + } + CPU_EMSPTR[frame] = ptr; +} + + /* * ¥â¡¼¥ÉÁ«°Ü */ -void FASTCALL +void CPUCALL change_pm(BOOL onoff) { +#if 0 int i; +#endif if (onoff) { +#if 0 for (i = 0; i < CPU_SEGREG_NUM; i++) { - CPU_STAT_SREG(i).valid = TRUE; + CPU_STAT_SREG(i).valid = 1; CPU_STAT_SREG(i).dpl = 0; } +#endif VERBOSE(("Entering to Protected-Mode...")); } else { VERBOSE(("Leaveing from Protected-Mode...")); } - CPU_STAT_CPL = 0; + + CPU_INST_OP32 = CPU_INST_AS32 = + CPU_STATSAVE.cpu_inst_default.op_32 = + CPU_STATSAVE.cpu_inst_default.as_32 = 0; + CPU_STAT_SS32 = 0; + set_cpl(0); CPU_STAT_PM = onoff; } -void FASTCALL +void CPUCALL change_pg(BOOL onoff) { if (onoff) { VERBOSE(("Entering to Paging-Mode...")); } else { - VERBOSE(("Leaveing from Pagin-Mode...")); + VERBOSE(("Leaveing from Paging-Mode...")); } + CPU_STAT_PAGING = onoff; } -void FASTCALL +void CPUCALL change_vm(BOOL onoff) { - descriptor_t sd; int i; + CPU_STAT_VM86 = onoff; if (onoff) { + VERBOSE(("Entering to Virtual-8086-Mode...")); for (i = 0; i < CPU_SEGREG_NUM; i++) { - sd.u.seg.limit = 0xffff; - CPU_SET_SEGDESC_DEFAULT(&sd, i, CPU_REGS_SREG(i)); - sd.dpl = 3; - CPU_STAT_SREG(i) = sd; + CPU_STAT_SREGLIMIT(i) = 0xffff; + LOAD_SEGREG(i, CPU_REGS_SREG(i)); } - VERBOSE(("Entering to Virtual-8086-Mode...")); + CPU_INST_OP32 = CPU_INST_AS32 = + CPU_STATSAVE.cpu_inst_default.op_32 = + CPU_STATSAVE.cpu_inst_default.as_32 = 0; + CPU_STAT_SS32 = 0; + set_cpl(3); } else { VERBOSE(("Leaveing from Virtual-8086-Mode...")); } - CPU_STAT_VM86 = onoff; } /* * flags */ -static void -modify_eflags(DWORD new_flags, DWORD mask) +static void CPUCALL +modify_eflags(UINT32 new_flags, UINT32 mask) { - DWORD orig = CPU_EFLAG; + UINT32 orig = CPU_EFLAG; new_flags &= ALL_EFLAG; mask &= ALL_EFLAG; - CPU_EFLAG = (REAL_EFLAGREG & ~mask) | (new_flags & mask) | 0x2; + CPU_EFLAG = (REAL_EFLAGREG & ~mask) | (new_flags & mask); CPU_OV = CPU_FLAG & O_FLAG; CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); - if ((orig ^ CPU_EFLAG) & VM_FLAG) { - if (CPU_EFLAG & VM_FLAG) { - change_vm(1); - } else { - change_vm(0); + if (CPU_STAT_PM) { + if ((orig ^ CPU_EFLAG) & VM_FLAG) { + if (CPU_EFLAG & VM_FLAG) { + change_vm(1); + } else { + change_vm(0); + } } } } -void -set_flags(WORD new_flags, WORD mask) +void CPUCALL +set_flags(UINT16 new_flags, UINT16 mask) { mask &= I_FLAG|IOPL_FLAG; @@ -219,8 +228,8 @@ set_flags(WORD new_flags, WORD mask) modify_eflags(new_flags, mask); } -void -set_eflags(DWORD new_flags, DWORD mask) +void CPUCALL +set_eflags(UINT32 new_flags, UINT32 mask) { mask &= I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG; @@ -228,3 +237,29 @@ set_eflags(DWORD new_flags, DWORD mask) mask |= AC_FLAG|ID_FLAG; modify_eflags(new_flags, mask); } + +/* + * CR3 (Page Directory Entry base physical address) + */ +void CPUCALL +set_cr3(UINT32 new_cr3) +{ + + VERBOSE(("set_CR3: old = %08x, new = 0x%08x", CPU_CR3, new_cr3)); + + CPU_CR3 = new_cr3 & CPU_CR3_MASK; + CPU_STAT_PDE_BASE = CPU_CR3 & CPU_CR3_PD_MASK; + tlb_flush(0); +} + +/* + * CPL (Current Privilege Level) + */ +void CPUCALL +set_cpl(int new_cpl) +{ + int cpl = new_cpl & 3; + + CPU_STAT_CPL = (UINT8)cpl; + CPU_STAT_USER_MODE = (cpl == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; +}