Diff for /np2/i386c/ia32/ia32.c between versions 1.6 and 1.24

version 1.6, 2004/01/23 14:33:26 version 1.24, 2011/12/21 18:07:57
Line 1 Line 1
 /*      $Id$    */  
   
 /*  /*
  * Copyright (c) 2002-2003 NONAKA Kimihiro   * Copyright (c) 2002-2003 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
Line 12 Line 10
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    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   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 31 Line 27
 #include "cpu.h"  #include "cpu.h"
 #include "ia32.mcr"  #include "ia32.mcr"
   
   
 I386CORE        i386core;  I386CORE        i386core;
   
 BYTE iflags[] = {  UINT8   *reg8_b20[0x100];
         0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,  UINT8   *reg8_b53[0x100];
         0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,  UINT16  *reg16_b20[0x100];
         0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,  UINT16  *reg16_b53[0x100];
         0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,  UINT32  *reg32_b20[0x100];
         0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,  UINT32  *reg32_b53[0x100];
         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];  
   
   
 void  void
 ia32_init(void)  ia32_init(void)
Line 83  ia32_init(void) Line 42  ia32_init(void)
         int i;          int i;
   
         memset(&i386core.s, 0, sizeof(i386core.s));          memset(&i386core.s, 0, sizeof(i386core.s));
         CPU_STATSAVE.cpu_inst_default.seg_base = (DWORD)-1;          ia32_initreg();
   
         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;  
   
         for (i = 0; i < 0x100; ++i) {          for (i = 0; i < 0x100; ++i) {
                 /* 8bit */                  /* 8bit */
Line 126  ia32_init(void) Line 72  ia32_init(void)
         }          }
   
         resolve_init();          resolve_init();
 #if defined(IA32_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)  change_pm(BOOL onoff)
 {  {
   #if 0
         int i;          int i;
   #endif
   
         if (onoff) {          if (onoff) {
   #if 0
                 for (i = 0; i < CPU_SEGREG_NUM; i++) {                  for (i = 0; i < CPU_SEGREG_NUM; i++) {
                         CPU_STAT_SREG(i).valid = 1;                          CPU_STAT_SREG(i).valid = 1;
                         CPU_STAT_SREG(i).dpl = 0;                          CPU_STAT_SREG(i).dpl = 0;
                 }                  }
   #endif
                 VERBOSE(("Entering to Protected-Mode..."));                  VERBOSE(("Entering to Protected-Mode..."));
         } else {          } else {
                 VERBOSE(("Leaveing from Protected-Mode..."));                  VERBOSE(("Leaveing from Protected-Mode..."));
Line 156  change_pm(BOOL onoff) Line 155  change_pm(BOOL onoff)
             CPU_STATSAVE.cpu_inst_default.op_32 =               CPU_STATSAVE.cpu_inst_default.op_32 = 
             CPU_STATSAVE.cpu_inst_default.as_32 = 0;              CPU_STATSAVE.cpu_inst_default.as_32 = 0;
         CPU_STAT_SS32 = 0;          CPU_STAT_SS32 = 0;
         CPU_STAT_CPL = 0;          set_cpl(0);
         CPU_STAT_PM = onoff;          CPU_STAT_PM = onoff;
 }  }
   
 void FASTCALL  void CPUCALL
 change_pg(BOOL onoff)  change_pg(BOOL onoff)
 {  {
   
Line 169  change_pg(BOOL onoff) Line 168  change_pg(BOOL onoff)
         } else {          } else {
                 VERBOSE(("Leaveing from Paging-Mode..."));                  VERBOSE(("Leaveing from Paging-Mode..."));
         }          }
   
         CPU_STAT_PAGING = onoff;          CPU_STAT_PAGING = onoff;
 }  }
   
 void FASTCALL  void CPUCALL
 change_vm(BOOL onoff)  change_vm(BOOL onoff)
 {  {
         int i;          int i;
   
         CPU_STAT_VM86 = onoff;          CPU_STAT_VM86 = onoff;
         if (onoff) {          if (onoff) {
                   VERBOSE(("Entering to Virtual-8086-Mode..."));
                 for (i = 0; i < CPU_SEGREG_NUM; i++) {                  for (i = 0; i < CPU_SEGREG_NUM; i++) {
                         CPU_SET_SEGREG(i, CPU_REGS_SREG(i));                          CPU_STAT_SREGLIMIT(i) = 0xffff;
                           LOAD_SEGREG(i, CPU_REGS_SREG(i));
                 }                  }
                 CPU_INST_OP32 = CPU_INST_AS32 =                  CPU_INST_OP32 = CPU_INST_AS32 =
                     CPU_STATSAVE.cpu_inst_default.op_32 =                      CPU_STATSAVE.cpu_inst_default.op_32 =
                     CPU_STATSAVE.cpu_inst_default.as_32 = 0;                      CPU_STATSAVE.cpu_inst_default.as_32 = 0;
                 CPU_STAT_SS32 = 0;                  CPU_STAT_SS32 = 0;
                 CPU_STAT_CPL = 3;                  set_cpl(3);
                 VERBOSE(("Entering to Virtual-8086-Mode..."));  
         } else {          } else {
                 VERBOSE(("Leaveing from Virtual-8086-Mode..."));                  VERBOSE(("Leaveing from Virtual-8086-Mode..."));
         }          }
Line 196  change_vm(BOOL onoff) Line 197  change_vm(BOOL onoff)
 /*  /*
  * flags   * flags
  */   */
 static void  static void CPUCALL
 modify_eflags(DWORD new_flags, DWORD mask)  modify_eflags(UINT32 new_flags, UINT32 mask)
 {  {
         DWORD orig = CPU_EFLAG;          UINT32 orig = CPU_EFLAG;
   
         new_flags &= ALL_EFLAG;          new_flags &= ALL_EFLAG;
         mask &= 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_OV = CPU_FLAG & O_FLAG;
         CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);          CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);
         if ((orig ^ CPU_EFLAG) & VM_FLAG) {          if (CPU_STAT_PM) {
                 if (CPU_EFLAG & VM_FLAG) {                  if ((orig ^ CPU_EFLAG) & VM_FLAG) {
                         change_vm(1);                          if (CPU_EFLAG & VM_FLAG) {
                 } else {                                  change_vm(1);
                         change_vm(0);                          } else {
                                   change_vm(0);
                           }
                 }                  }
         }          }
 }  }
   
 void  void CPUCALL
 set_flags(WORD new_flags, WORD mask)  set_flags(UINT16 new_flags, UINT16 mask)
 {  {
   
         mask &= I_FLAG|IOPL_FLAG;          mask &= I_FLAG|IOPL_FLAG;
Line 225  set_flags(WORD new_flags, WORD mask) Line 228  set_flags(WORD new_flags, WORD mask)
         modify_eflags(new_flags, mask);          modify_eflags(new_flags, mask);
 }  }
   
 void  void CPUCALL
 set_eflags(DWORD new_flags, DWORD mask)  set_eflags(UINT32 new_flags, UINT32 mask)
 {  {
   
         mask &= I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG;          mask &= I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG;
Line 234  set_eflags(DWORD new_flags, DWORD mask) Line 237  set_eflags(DWORD new_flags, DWORD mask)
         mask |= AC_FLAG|ID_FLAG;          mask |= AC_FLAG|ID_FLAG;
         modify_eflags(new_flags, mask);          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;
   }

Removed from v.1.6  
changed lines
  Added in v.1.24


RetroPC.NET-CVS <cvs@retropc.net>