Diff for /np2/i386c/ia32/interface.c between versions 1.5 and 1.32

version 1.5, 2004/01/07 06:53:48 version 1.32, 2012/01/08 18:26:55
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 30 Line 26
 #include "compiler.h"  #include "compiler.h"
 #include "cpu.h"  #include "cpu.h"
 #include "ia32.mcr"  #include "ia32.mcr"
 #include "dmap.h"  #if defined(USE_FPU)
   #include "instructions/fpu/fp.h"
   #endif
   
   #include "pccore.h"
   #include "iocore.h"
   #include "dmax86.h"
 #include "bios.h"  #include "bios.h"
   
   
 void  void
 ia32reset(void)  ia32_initreg(void)
 {  {
         int i;          int i;
   
         memset(&i386core.s, 0, sizeof(i386core.s));                     // yui          CPU_STATSAVE.cpu_inst_default.seg_base = (UINT32)-1;
         CPU_STATSAVE.cpu_inst_default.seg_base = (DWORD)-1;  
   
         CPU_EDX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING;          CPU_EDX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING;
         CPU_EFLAG = 2;          CPU_EFLAG = 2;
         CPU_CR0 = CPU_CR0_CD | CPU_CR0_NW | CPU_CR0_ET;          CPU_CR0 = CPU_CR0_CD | CPU_CR0_NW | CPU_CR0_ET;
   #if defined(USE_FPU)
           CPU_CR0 |= CPU_CR0_ET;
   #else
           CPU_CR0 |= CPU_CR0_EM | CPU_CR0_NE;
           CPU_CR0 &= ~(CPU_CR0_MP | CPU_CR0_ET);
   #endif
         CPU_MXCSR = 0x1f80;          CPU_MXCSR = 0x1f80;
   
           CPU_GDTR_BASE = 0x0;
         CPU_GDTR_LIMIT = 0xffff;          CPU_GDTR_LIMIT = 0xffff;
           CPU_IDTR_BASE = 0x0;
         CPU_IDTR_LIMIT = 0xffff;          CPU_IDTR_LIMIT = 0xffff;
           CPU_LDTR_BASE = 0x0;
         for (i = 0; i < CPU_SEGREG_NUM; ++i) {  
                 CPU_STAT_SREG_INIT(i);  
         }  
         CPU_LDTR_LIMIT = 0xffff;          CPU_LDTR_LIMIT = 0xffff;
           CPU_TR_BASE = 0x0;
         CPU_TR_LIMIT = 0xffff;          CPU_TR_LIMIT = 0xffff;
   
 //      CPU_SET_SEGREG(CPU_ES_INDEX, 0x0000);          CPU_STATSAVE.cpu_regs.dr[6] = 0xffff1ff0;
         CPU_SET_SEGREG(CPU_CS_INDEX, 0xf000);  
 //      CPU_SET_SEGREG(CPU_SS_INDEX, 0x0000);          for (i = 0; i < CPU_SEGREG_NUM; ++i) {
 //      CPU_SET_SEGREG(CPU_DS_INDEX, 0x0000);                  segdesc_init(i, 0, &CPU_STAT_SREG(i));
           }
           LOAD_SEGREG(CPU_CS_INDEX, 0xf000);
           CPU_STAT_CS_BASE = 0xffff0000;
         CPU_EIP = 0xfff0;          CPU_EIP = 0xfff0;
         CPU_ADRSMASK = 0xfffff;          CPU_ADRSMASK = 0x000fffff;
   
           tlb_init();
   #if defined(USE_FPU)
           fpu_init();
   #endif
 }  }
   
 void  void
 ia32shut(void)  ia32reset(void)
 {  {
         SINT32  remainclock;                                    // 結局ハマるのか漏れ…  
         SINT32  baseclock;          memset(&i386core.s, 0, sizeof(i386core.s));
         UINT32  clock;          ia32_initreg();
   
         remainclock = CPU_REMCLOCK;  
         baseclock = CPU_BASECLOCK;  
         clock = CPU_CLOCK;  
   
         ia32reset();  
   
         CPU_REMCLOCK = remainclock;  
         CPU_BASECLOCK = baseclock;  
         CPU_CLOCK = clock;  
 }  }
   
 void  void
 ia32(void)  ia32shut(void)
 {  {
         int rv;  
   
 #if defined(WIN32)          memset(&i386core.s, 0, offsetof(I386STAT, cpu_type));
         rv = setjmp(exec_1step_jmpbuf);          ia32_initreg();
 #else  
         rv = sigsetjmp(exec_1step_jmpbuf, 1);  
 #endif  
         switch (rv) {  
         case 0:  
                 break;  
           
         default:  
                 CPU_EIP = CPU_PREV_EIP;  
                 break;  
         }  
   
         do {  
                 exec_1step();  
         } while (CPU_REMCLOCK > 0);  
 }  }
   
 void  void
 ia32withtrap(void)  ia32a20enable(BOOL enable)
 {  {
         int rv;  
   
 #if defined(WIN32)  
         rv = setjmp(exec_1step_jmpbuf);  
 #else  
         rv = sigsetjmp(exec_1step_jmpbuf, 1);  
 #endif  
         switch (rv) {  
         case 0:  
                 break;  
           
         default:  
                 CPU_EIP = CPU_PREV_EIP;  
                 break;  
         }  
   
           CPU_ADRSMASK = (enable)?0xffffffff:0x00ffffff;
         do {  
                 exec_1step();  
                 if (CPU_TRAP) {  
                         ia32_interrupt(1);  
                 }  
         } while (CPU_REMCLOCK > 0);  
 }  }
   
 void  void
 ia32withdma(void)  ia32(void)
 {  {
         int rv;          int rv;
   
 #if defined(WIN32)  
         rv = setjmp(exec_1step_jmpbuf);  
 #else  
         rv = sigsetjmp(exec_1step_jmpbuf, 1);          rv = sigsetjmp(exec_1step_jmpbuf, 1);
 #endif  
         switch (rv) {          switch (rv) {
         case 0:          case 0:
                 break;                  break;
           
           case 1:
                   VERBOSE(("ia32: return from exception"));
                   break;
   
           case 2:
                   VERBOSE(("ia32: return from panic"));
                   return;
   
         default:          default:
                 CPU_EIP = CPU_PREV_EIP;                  VERBOSE(("ia32: return from unknown cause"));
                 break;                  break;
         }          }
   
           if (CPU_TRAP) {
         do {                  do {
                 exec_1step();                          exec_1step();
                 dmap_i286();                          if (CPU_TRAP) {
         } while (CPU_REMCLOCK > 0);                                  CPU_DR6 |= CPU_DR6_BS;
                                   INTERRUPT(1, INTR_TYPE_EXCEPTION);
                           }
                           dmax86();
                   } while (CPU_REMCLOCK > 0);
           } else if (dmac.working) {
                   do {
                           exec_1step();
                           dmax86();
                   } while (CPU_REMCLOCK > 0);
           } else {
                   do {
                           exec_1step();
                   } while (CPU_REMCLOCK > 0);
           }
 }  }
   
 void  void
Line 164  ia32_step(void) Line 151  ia32_step(void)
 {  {
         int rv;          int rv;
   
 #if defined(WIN32)  
         rv = setjmp(exec_1step_jmpbuf);  
 #else  
         rv = sigsetjmp(exec_1step_jmpbuf, 1);          rv = sigsetjmp(exec_1step_jmpbuf, 1);
 #endif  
         switch (rv) {          switch (rv) {
         case 0:          case 0:
                 break;                  break;
           
           case 1:
                   VERBOSE(("ia32_step: return from exception"));
                   break;
   
           case 2:
                   VERBOSE(("ia32_step: return from panic"));
                   return;
   
         default:          default:
                 CPU_EIP = CPU_PREV_EIP;                  VERBOSE(("ia32_step: return from unknown cause"));
                 break;                  break;
         }          }
   
   
         do {          do {
                 exec_1step();                  exec_1step();
                 if (CPU_TRAP) {                  if (CPU_TRAP) {
                         ia32_interrupt(1);                          CPU_DR6 |= CPU_DR6_BS;
                           INTERRUPT(1, INTR_TYPE_EXCEPTION);
                   }
                   if (dmac.working) {
                           dmax86();
                 }                  }
                 dmap_i286();  
         } while (CPU_REMCLOCK > 0);          } while (CPU_REMCLOCK > 0);
 }  }
   
 void CPUCALL  void CPUCALL
 ia32_interrupt(BYTE vect)  ia32_interrupt(int vect, int soft)
 {  {
   
         INTERRUPT(vect, 0, 0, 0);  //      TRACEOUT(("int (%x, %x) PE=%d VM=%d",  vect, soft, CPU_STAT_PM, CPU_STAT_VM86));
           if (!soft) {
                   INTERRUPT(vect, INTR_TYPE_EXTINTR);
           } else {
                   if (CPU_STAT_PM && CPU_STAT_VM86 && CPU_STAT_IOPL < CPU_IOPL3) {
                           VERBOSE(("ia32_interrupt: VM86 && IOPL < 3 && INTn"));
                           EXCEPTION(GP_EXCEPTION, 0);
                   }
                   INTERRUPT(vect, INTR_TYPE_SOFTINTR);
           }
 }  }
   
   
 /*  /*
  * error function   * error function
  */   */
 void  void
 ia32_panic(const char *str, ...)  ia32_panic(const char *str, ...)
 {  {
         char buf[1024];          extern char *cpu_reg2str(void);
           char buf[2048];
         va_list ap;          va_list ap;
   
         va_start(ap, str);          va_start(ap, str);
         vsnprintf(buf, sizeof(buf), str, ap);          vsnprintf(buf, sizeof(buf), str, ap);
         va_end(ap);          va_end(ap);
         strcat(buf, "\n");          strcat(buf, "\n");
           strcat(buf, cpu_reg2str());
           VERBOSE(("%s", buf));
   
 #if defined(_WIN32)          msgbox("ia32_panic", buf);
         MessageBox(NULL, buf, "ia32_panic", MB_OK);  
 #endif  
   
         fprintf(stderr, buf);  #if defined(IA32_REBOOT_ON_PANIC)
           VERBOSE(("ia32_panic: reboot"));
           pccore_reset();
           siglongjmp(exec_1step_jmpbuf, 2);
   #else
         __ASSERT(0);          __ASSERT(0);
         exit(1);          exit(1);
   #endif
 }  }
   
 void  void
Line 227  ia32_warning(const char *str, ...) Line 237  ia32_warning(const char *str, ...)
         va_end(ap);          va_end(ap);
         strcat(buf, "\n");          strcat(buf, "\n");
   
         fprintf(stderr, buf);          msgbox("ia32_warning", buf);
 }  }
   
 void  void
Line 238  ia32_printf(const char *str, ...) Line 248  ia32_printf(const char *str, ...)
         va_start(ap, str);          va_start(ap, str);
         vsnprintf(buf, sizeof(buf), str, ap);          vsnprintf(buf, sizeof(buf), str, ap);
         va_end(ap);          va_end(ap);
           strcat(buf, "\n");
   
         fprintf(stderr, buf);          msgbox("ia32_printf", buf);
 }  }
   
   
 /*  /*
  * bios call interface   * bios call interface
  */   */
 void  void
 ia32_bioscall(void)  ia32_bioscall(void)
 {  {
           UINT32 adrs;
   
         /* XXX */          if (!CPU_STAT_PM || CPU_STAT_VM86) {
         if (!CPU_STAT_PM && !CPU_INST_OP32 && !CPU_INST_AS32) {  #if 1
                 DWORD adrs;                  adrs = CPU_PREV_EIP + (CPU_CS << 4);
                 WORD sreg;  #else
                   adrs = CPU_PREV_EIP + CPU_STAT_CS_BASE;
                 adrs = ((CPU_IP-1) & 0xffff) + CPU_STAT_SREGBASE(CPU_CS_INDEX);  #endif
                 if ((adrs >= 0xf8000) && (adrs < 0x100000)) {                  if ((adrs >= 0xf8000) && (adrs < 0x100000)) {
                         biosfunc(adrs);                          if (biosfunc(adrs)) {
                         sreg = CPU_ES;                                  /* Nothing to do */
                         CPU_SET_SEGREG(CPU_ES_INDEX, sreg);                          }
                         sreg = CPU_CS;                          LOAD_SEGREG(CPU_ES_INDEX, CPU_ES);
                         CPU_SET_SEGREG(CPU_CS_INDEX, sreg);                          LOAD_SEGREG(CPU_CS_INDEX, CPU_CS);
                         sreg = CPU_SS;                          LOAD_SEGREG(CPU_SS_INDEX, CPU_SS);
                         CPU_SET_SEGREG(CPU_SS_INDEX, sreg);                          LOAD_SEGREG(CPU_DS_INDEX, CPU_DS);
                         sreg = CPU_DS;  
                         CPU_SET_SEGREG(CPU_DS_INDEX, sreg);  
                 }                  }
         }          }
 }  }

Removed from v.1.5  
changed lines
  Added in v.1.32


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