Diff for /np2/i386c/ia32/exception.c between versions 1.20 and 1.35

version 1.20, 2008/01/25 17:49:46 version 1.35, 2012/01/08 11:36:06
Line 1 Line 1
 /*      $Id$    */  
   
 /*  /*
  * Copyright (c) 2003 NONAKA Kimihiro   * Copyright (c) 2003 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
Line 63  static const int dftable[4][4] = { Line 61  static const int dftable[4][4] = {
         { 1, 1, 1, 1, },          { 1, 1, 1, 1, },
 };  };
   
 void  void CPUCALL
 exception(int num, int error_code)  exception(int num, int error_code)
 {  {
   #if defined(DEBUG)
           extern int cpu_debug_rep_cont;
           extern CPU_REGS cpu_debug_rep_regs;
   #endif
         int errorp = 0;          int errorp = 0;
   
         __ASSERT((unsigned int)num < EXCEPTION_NUM);          __ASSERT((unsigned int)num < EXCEPTION_NUM);
   
 #if 0  #if 0
         iptrace_out();          iptrace_out();
         debugwriteseg("execption.bin", &CPU_STAT_SREG(CPU_CS_INDEX), CPU_PREV_EIP & 0xffff0000, 0x10000);          debugwriteseg("execption.bin", &CPU_CS_DESC, CPU_PREV_EIP & 0xffff0000, 0x10000);
 #endif  #endif
   
         VERBOSE(("exception: -------------------------------------------------------------- start"));          VERBOSE(("exception: -------------------------------------------------------------- start"));
         VERBOSE(("exception: %s, error_code = %x at %04x:%08x", exception_str[num], error_code, CPU_CS, CPU_PREV_EIP));          VERBOSE(("exception: %s, error_code = %x at %04x:%08x", exception_str[num], error_code, CPU_CS, CPU_PREV_EIP));
         VERBOSE(("%s", cpu_reg2str()));          VERBOSE(("%s", cpu_reg2str()));
           VERBOSE(("code: %dbit(%dbit), address: %dbit(%dbit)", CPU_INST_OP32 ? 32 : 16, CPU_STATSAVE.cpu_inst_default.op_32 ? 32 : 16, CPU_INST_AS32 ? 32 : 16, CPU_STATSAVE.cpu_inst_default.as_32 ? 32 : 16));
   #if defined(DEBUG)
           if (cpu_debug_rep_cont) {
                   VERBOSE(("rep: original regs: ecx=%08x, esi=%08x, edi=%08x", cpu_debug_rep_regs.reg[CPU_ECX_INDEX].d, cpu_debug_rep_regs.reg[CPU_ESI_INDEX].d, cpu_debug_rep_regs.reg[CPU_EDI_INDEX].d));
           }
           VERBOSE(("%s", cpu_disasm2str(CPU_PREV_EIP)));
   #endif
   
         CPU_STAT_EXCEPTION_COUNTER_INC();          CPU_STAT_EXCEPTION_COUNTER_INC();
         if ((CPU_STAT_EXCEPTION_COUNTER >= 3)           if ((CPU_STAT_EXCEPTION_COUNTER >= 3) 
Line 87  exception(int num, int error_code) Line 96  exception(int num, int error_code)
         }          }
   
         switch (num) {          switch (num) {
         case DE_EXCEPTION:      /* (F) ½ü»»¥¨¥é¡¼ */          case DE_EXCEPTION:      /* (F) ½ü»»¥¨¥é¡¼ */
         case DB_EXCEPTION:      /* (F/T) ¥Ç¥Ð¥Ã¥° */          case DB_EXCEPTION:      /* (F/T) ¥Ç¥Ð¥Ã¥° */
         case BR_EXCEPTION:      /* (F) BOUND ¤ÎÈϰϳ° */          case BR_EXCEPTION:      /* (F) BOUND ¤ÎÈϰϳ° */
         case UD_EXCEPTION:      /* (F) ̵¸ú¥ª¥Ú¥³¡¼¥É */          case UD_EXCEPTION:      /* (F) ̵¸ú¥ª¥Ú¥³¡¼¥É */
         case NM_EXCEPTION:      /* (F) ¥Ç¥Ð¥¤¥¹»ÈÍÑÉÔ²Ä (FPU ¤¬Ìµ¤¤) */          case NM_EXCEPTION:      /* (F) ¥Ç¥Ð¥¤¥¹»ÈÍÑÉÔ²Ä (FPU ¤¬Ìµ¤¤) */
         case MF_EXCEPTION:      /* (F) ÉâÆ°¾®¿ôÅÀ¥¨¥é¡¼ */          case MF_EXCEPTION:      /* (F) ÉâÆ°¾®¿ôÅÀ¥¨¥é¡¼ */
 #if CPU_FAMILY >= 5  
         case MC_EXCEPTION:      /* (A) ¥Þ¥·¥ó¥Á¥§¥Ã¥¯ */  
 #endif  
 #if CPU_FAMILY >= 6  
         case XF_EXCEPTION:      /* (F) ¥¹¥È¥ê¡¼¥ß¥ó¥° SIMD ³Èĥ̿Îá */  
 #endif  
                 CPU_EIP = CPU_PREV_EIP;                  CPU_EIP = CPU_PREV_EIP;
                   if (CPU_STATSAVE.cpu_stat.backout_sp)
                           CPU_ESP = CPU_PREV_ESP;
                 /*FALLTHROUGH*/                  /*FALLTHROUGH*/
         case NMI_EXCEPTION:     /* (I) NMI ³ä¤ê¹þ¤ß */          case NMI_EXCEPTION:     /* (I) NMI ³ä¤ê¹þ¤ß */
         case BP_EXCEPTION:      /* (T) ¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È */          case BP_EXCEPTION:      /* (T) ¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È */
         case OF_EXCEPTION:      /* (T) ¥ª¡¼¥Ð¡¼¥Õ¥í¡¼ */          case OF_EXCEPTION:      /* (T) ¥ª¡¼¥Ð¡¼¥Õ¥í¡¼ */
                 errorp = 0;                  errorp = 0;
                 break;                  break;
   
         case DF_EXCEPTION:      /* (A) ¡¦¥¿¡¦¥è¡¦ö§¥æ¡¦¥¥¡¦ö§¥Í (errcode: 0) */          case DF_EXCEPTION:      /* (A) åãc«ã©ã (errcode: 0) */
                 errorp = 1;                  errorp = 1;
                 error_code = 0;                  error_code = 0;
                 break;                  break;
   
 #if CPU_FAMILY >= 4          case AC_EXCEPTION:      /* (F) åâ¡Öå㥥åâ¡¢å㥦åã¡£å㥦åã°å¥áå⥡åã¦å¤± (errcode: 0) */
         case AC_EXCEPTION:      /* (F) ¥¢¥é¥¤¥ó¥á¥ó¥È¥Á¥§¥Ã¥¯ (errcode: 0) */  
                 error_code = 0;                  error_code = 0;
                 /*FALLTHROUGH*/                  /*FALLTHROUGH*/
 #endif          case TS_EXCEPTION:      /* (F) ̵¸ú TSS (errcode) */
         case TS_EXCEPTION:      /* (F) ¥Õ¥ª¥¯TSS (errcode) */          case NP_EXCEPTION:      /* (F) ¥»¥°¥á¥ó¥ÈÉG (errcode) */
         case NP_EXCEPTION:      /* (F) ¡¦¥µ¡¦¡¼¡¦â§ó¥ÈÉÔº(errcode) */          case SS_EXCEPTION:      /* (F) ¥¹¥¿¥Ã¥¯¥»¥°¥á¥ó¥È¥Õ¥©¥ë¥È (errcode) */
         case SS_EXCEPTION:      /* (F) ¥¹¥¿¥Ã¥¯¥»¥°¥á¥ó¥È¥Õ¥©¥ë¥È (errcode) */          case GP_EXCEPTION:      /* (F) °ìÈÌÊݸîÎã³° (errcode) */
         case GP_EXCEPTION:      /* (F) °ìÈÌÊݸîÎã³° (errcode) */          case PF_EXCEPTION:      /* (F) ¥Ú¡¼¥¸¥Õ¥©¥ë¥È (errcode) */
         case PF_EXCEPTION:      /* (F) ¥Ú¡¼¥¸¥Õ¥©¥ë¥È (errcode) */  
                 CPU_EIP = CPU_PREV_EIP;                  CPU_EIP = CPU_PREV_EIP;
                   if (CPU_STATSAVE.cpu_stat.backout_sp)
                           CPU_ESP = CPU_PREV_ESP;
                 errorp = 1;                  errorp = 1;
                 break;                  break;
   
Line 142  exception(int num, int error_code) Line 147  exception(int num, int error_code)
   
         VERBOSE(("exception: ---------------------------------------------------------------- end"));          VERBOSE(("exception: ---------------------------------------------------------------- end"));
   
         INTERRUPT(num, 0, errorp, error_code);          interrupt(num, INTR_TYPE_EXTINTR, errorp, error_code);
 #if defined(IA32_SUPPORT_DEBUG_REGISTER)  
         if (num != BP_EXCEPTION) {  
                 if (CPU_INST_OP32) {  
                         set_eflags(REAL_EFLAGREG|RF_FLAG, RF_FLAG);  
                 }  
         }  
 #endif  
         CPU_STAT_EXCEPTION_COUNTER_CLEAR();          CPU_STAT_EXCEPTION_COUNTER_CLEAR();
         siglongjmp(exec_1step_jmpbuf, 1);          siglongjmp(exec_1step_jmpbuf, 1);
 }  }
   
 /*  /*
  * ¡¦¥¦¡£¥·¡¦ö£¥ò¡¦¥¤¡£¥·¡¦¥Í¡£¥ò¡¦¥Ì¡¦¡×¡¦¥±¡¦¥Ã¡¦ô§¥é¡¦¥½   * å⥦å㥷å㥩å㥵å⥤å㥷åã°å¦½åã®å¤¥å⥱åâ¥Ãå㥧åãÎå¤Á
  *   *
  *  31                                16 15 14 13 12       8 7   5 4       0   *  31                                16 15 14 13 12       8 7   5 4       0
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  * |         ¡¦¥§¡¦¥æ¡¦¥µ¡¦¥Æ¡¦¥Í 31..16          | P| DPL | 0 D 1 0 0|0 0 0|¡¦¥©¡¦¥ò¡¦ó¥| 4   * |         ¥ª¥Õ¥»¥Ã¥È 31..16          | P| DPL | 0 D 1 0 0|0 0 0|¥«¥¦¥ó¥È | 4
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  *  31                                16 15                                0   *  31                                16 15                                0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  * |        ¥»¥°¥á¥ó¥È¡¦¥»¥ì¥¯¥¿        |          ¥ª¥Õ¥»¥Ã¥È 15..0         | 0   * |        å⥵å⡼åã¡£å㥦åã°å¦½å⥵åã¥ãåâ¥Ãå⥽        |          å⥧åãÊ夽åã¦å¥è 15..0         | 0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  */   */
   
 /*  /*
  * ¥¦è¦ô»¡¬¡¦¥Ì¡¦¡×¡¦¥±¡¦¥Ã¡¦ô§¥é¡¦¥½   * é饤åâ´ê¥»¥·å᥽åã®å¤¥å⥱åâ¥Ãå㥧åãÎå¤Á
  *--   *--
  * ¡¦¥½¡¦¥±¡¦¥Ã¡£¥ò¡¦¥¤¡£¥·¡¦¥Í   * å⥽å⥱åâ¥Ãå㥵å⥤å㥷å㊠ *
  *  31                                16 15 14 13 12       8 7             0   *  31                                16 15 14 13 12       8 7             0
  * +------------------------------------+--+-----+----------+---------------+   * +------------------------------------+--+-----+----------+---------------+
Line 178  exception(int num, int error_code) Line 176  exception(int num, int error_code)
  * +------------------------------------+--+-----+----------+---------------+   * +------------------------------------+--+-----+----------+---------------+
  *  31                                16 15                                0   *  31                                16 15                                0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  * |      TSS ¥»¥°¥á¥ó¥È¡¦¥»¥ì¥¯¥¿      |              Reserved             | 0   * |      TSS å⥵å⡼åã¡£å㥦åã°å¦½å⥵åã¥ãåâ¥Ãå⥽      |              Reserved             | 0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  *--   *--
  * ¥¦è¦ô»+ * ³ä¤ê¹þ¤ß¡¦¥²¡¼¥È  
  *   *
  *  31                                16 15 14 13 12       8 7   5 4       0   *  31                                16 15 14 13 12       8 7   5 4       0
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  * |         ¡¦¥§¡¦¥æ¡¦¥µ¡¦¥Æ¡¦¥Í 31..16          | P| DPL | 0 D 1 1 0|0 0 0|Reserved | 4   * |         å⥧åãÊ夽åã¦å¥è 31..16          | P| DPL | 0 D 1 1 0|0 0 0|Reserved | 4
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  *  31                                16 15                                0   *  31                                16 15                                0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  * |        ¡¦¥µ¡¦¡¼¡¦â§ó¥È¡¦¥»¥ì¥¯¥       |          ¥ª¥Õ¥»¥Ã¥È 15..0         | 0   * |        å⥵å⡼åã¡£å㥦åã°å¦½å⥵åã¥ãåâ¥Ãå⥽        |          å⥧åãÊ夽åã¦å¥è 15..0         | 0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  *--   *--
  * ¡¦¥Í¡¦ò§¥Æ¡¦¥é¡£¥ò¡¦¥¤¡£¥·¡¦¥Í   * åã°å¦«åã¦å¥÷å㥵å⥤å㥷å㊠ *
  *  31                                16 15 14 13 12       8 7   5 4       0   *  31                                16 15 14 13 12       8 7   5 4       0
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  * |         ¥ª¥Õ¥»¥Ã¥È 31..16          | P| DPL | 0 D 1 1 1|0 0 0|Reserved | 4   * |         å⥧åãÊ夽åã¦å¥è 31..16          | P| DPL | 0 D 1 1 1|0 0 0|Reserved | 4
  * +------------------------------------+--+-----+----------+-----+---------+   * +------------------------------------+--+-----+----------+-----+---------+
  *  31                                16 15                                0   *  31                                16 15                                0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  * |        ¡¦¥µ¡¦¡¼¡¦â§ü§¥Í¡£¥ò¡¦¥µ¡¦ø§¥Ã¡¦¥½        |          ¡¦¥§¡¦¥æ¡¦¥µ¡¦¥Æ¡¦¥Í 15..0         | 0   * |        å⥵å⡼åã¡£å㥦åã°å¦½å⥵åã¥ãåâ¥Ãå⥽        |          å⥧åãÊ夽åã¦å¥è 15..0         | 0
  * +------------------------------------+-----------------------------------+   * +------------------------------------+-----------------------------------+
  *--   *--
  * DPL        : ¡¦¥Ì¡¦¡×¡¦¥±¡¦¥Ã¡¦ô§¥é¡¦¥½¥Ë¥Æ¥¯¡Ö¡¦ø§¥ë¡¦- * ¥ª¥Õ¥»¥Ã¥È : ¥×¥í¥·¡¼¥¸¥ã¡¦¥¨¥ó¥È¥ê¡¦¥Ý¥¤¥ó¥È¤Þ¤Ç¤Î¥ª¥Õ¥»¥Ã¥È   * DPL        : ¥Ç¥£¥¹¥¯¥ê¥×¥¿ÆÃ¸¢¥ì¥Ù¥ë
  * P          : ¥»¥°¥á¥ó¥È¸ºß¥Õ¥é¥°   * ¥ª¥Õ¥»¥Ã¥È : ¥×¥í¥·¡¼¥¸¥ã¡¦¥¨¥ó¥È¥ê¡¦¥Ý¥¤¥ó¥È¤Þ¤Ç¤Î¥ª¥Õ¥»¥Ã¥È
  * ¥»¥ì¥¯¥¿   : ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¡¦¥³¡¼¥É¡¦¥»¥°¥á¥ó¥È¤Î¥»¥°¥á¥ó¥È¡¦¥»¥ì¥¯¥¿   * P          : ¥»¥°¥á¥ó¥È¸ºß¥Õ¥é¥°
  * D          : ¥²¡¼¥È¤Î¥µ¥¤¥º¡¥0 = 16 bit, 1 = 32 bit   * ¥»¥ì¥¯¥¿   : ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¡¦¥³¡¼¥É¡¦¥»¥°¥á¥ó¥È¤Î¥»¥°¥á¥ó¥È¡¦¥»¥ì¥¯¥¿
    * D          : ¥²¡¼¥È¤Î¥µ¥¤¥º¡¥0 = 16 bit, 1 = 32 bit
  */   */
   
 static void interrupt_task_gate(const descriptor_t *gd, int softintp, int errorp, int error_code);  static void CPUCALL interrupt_task_gate(const descriptor_t *gsdp, int intrtype, int errorp, int error_code);
 static void interrupt_intr_or_trap(const descriptor_t *gd, int softintp, int errorp, int error_code);  static void CPUCALL interrupt_intr_or_trap(const descriptor_t *gsdp, int intrtype, int errorp, int error_code);
   
 void  void CPUCALL
 interrupt(int num, int softintp, int errorp, int error_code)  interrupt(int num, int intrtype, int errorp, int error_code)
 {  {
         descriptor_t gd;          descriptor_t gsd;
         UINT idt_idx;          UINT idt_idx;
         UINT32 new_ip;          UINT32 new_ip;
         UINT16 new_cs;          UINT16 new_cs;
           int exc_errcode;
   
         VERBOSE(("interrupt: num = 0x%02x, softintp = %s, errorp = %s, error_code = %08x", num, softintp ? "on" : "off", errorp ? "on" : "off", error_code));          VERBOSE(("interrupt: num = 0x%02x, intrtype = %s, errorp = %s, error_code = %08x", num, intrtype ? "on" : "off", errorp ? "on" : "off", error_code));
   
           CPU_SET_PREV_ESP();
   
         if (!CPU_STAT_PM) {          if (!CPU_STAT_PM) {
                 /* real mode */                  /* real mode */
                   CPU_WORKCLOCK(20);
   
                 idt_idx = num * 4;                  idt_idx = num * 4;
                 if (idt_idx + 3 > CPU_IDTR_LIMIT) {                  if (idt_idx + 3 > CPU_IDTR_LIMIT) {
                         VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));                          VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2);
                 }                  }
   
                 if (!softintp && CPU_STAT_HLT) {                  if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) {
                           VERBOSE(("interrupt: reset HTL in real mode"));
                         CPU_EIP++;                          CPU_EIP++;
                         CPU_STAT_HLT = FALSE;                          CPU_STAT_HLT = 0;
                 }                  }
   
                 REGPUSH0(REAL_FLAGREG);                  REGPUSH0(REAL_FLAGREG);
Line 245  interrupt(int num, int softintp, int err Line 249  interrupt(int num, int softintp, int err
   
                 new_ip = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx);                  new_ip = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx);
                 new_cs = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx + 2);                  new_cs = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx + 2);
                 CPU_SET_SEGREG(CPU_CS_INDEX, new_cs);                  LOAD_SEGREG(CPU_CS_INDEX, new_cs);
                 SET_EIP(new_ip);                  CPU_EIP = new_ip;
                 CPU_WORKCLOCK(20);  
         } else {          } else {
                 /* protected mode */                  /* protected mode */
                 VERBOSE(("interrupt: -------------------------------------------------------------- start"));                  CPU_WORKCLOCK(200);
   
                   VERBOSE(("interrupt: -------------------------------------------------------------- start"));
                 VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP));                  VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP));
   
 #if defined(DEBUG)  #if defined(DEBUG)
                 if (num == 0x80) {                  if (num == 0x80) {
                         /* Linux, FreeBSD, NetBSD, OpenBSD system call */                          /* Linux, FreeBSD, NetBSD, OpenBSD system call */
                         VERBOSE(("interrupt: syscall no = %d\n%s", CPU_EAX, cpu_reg2str()));                          VERBOSE(("interrupt: syscall# = %d\n%s", CPU_EAX, cpu_reg2str()));
                 }                  }
 #endif  #endif
   
                 /* VM86 && IOPL < 3 && interrupt cause == INTn */  
                 if (CPU_STAT_VM86 && (CPU_STAT_IOPL < CPU_IOPL3) && (softintp == -1)) {  
                         VERBOSE(("interrupt: VM86 && IOPL < 3 && INTn"));  
                         EXCEPTION(GP_EXCEPTION, 0);  
                 }  
   
                 idt_idx = num * 8;                  idt_idx = num * 8;
                   exc_errcode = idt_idx + 2;
                   if (intrtype == INTR_TYPE_EXTINTR)
                           exc_errcode++;
   
                 if (idt_idx + 7 > CPU_IDTR_LIMIT) {                  if (idt_idx + 7 > CPU_IDTR_LIMIT) {
                         VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));                          VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                 }                  }
   
                 memset(&gd, 0, sizeof(gd));                  /* load a gate descriptor from interrupt descriptor table */
                 load_descriptor(&gd, CPU_IDTR_BASE + idt_idx);                  memset(&gsd, 0, sizeof(gsd));
                 if (!gd.valid || !gd.p) {                  load_descriptor(&gsd, CPU_IDTR_BASE + idt_idx);
                   if (!SEG_IS_VALID(&gsd)) {
                         VERBOSE(("interrupt: gate descripter is invalid."));                          VERBOSE(("interrupt: gate descripter is invalid."));
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                   }
                   if (!SEG_IS_SYSTEM(&gsd)) {
                           VERBOSE(("interrupt: gate descriptor is not system segment."));
                           EXCEPTION(GP_EXCEPTION, exc_errcode);
                 }                  }
   
                 switch (gd.type) {                  switch (gsd.type) {
                 case CPU_SYSDESC_TYPE_TASK:                  case CPU_SYSDESC_TYPE_TASK:
                 case CPU_SYSDESC_TYPE_INTR_16:                  case CPU_SYSDESC_TYPE_INTR_16:
                 case CPU_SYSDESC_TYPE_INTR_32:                  case CPU_SYSDESC_TYPE_INTR_32:
Line 289  interrupt(int num, int softintp, int err Line 296  interrupt(int num, int softintp, int err
                         break;                          break;
   
                 default:                  default:
                         VERBOSE(("interrupt: invalid gate type (%d)", gd.type));                          VERBOSE(("interrupt: invalid gate type (%d)", gsd.type));
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                         break;                          break;
                 }                  }
   
                 /* 5.10.1.1. Îã³°¡¿³ä¤ê¹þ¤ß¥Ï¥ó¥É¥é¡¦¥×¥í¥·¡¼¥¸¥ã¤ÎÊݸî */                  /* 5.10.1.1. 価¿³ä¤ê¹þ¤ß¥Ï¥ó¥É¥é¡¦¥×¥í¥·¡¼¥¸¥ã¤ÎÊݸî */
                 if (softintp && (gd.dpl < CPU_STAT_CPL)) {                  if ((intrtype != INTR_TYPE_EXTINTR) && (gsd.dpl < CPU_STAT_CPL)) {
                         VERBOSE(("interrupt: softintp && DPL(%d) < CPL(%d)", gd.dpl, CPU_STAT_CPL));                          VERBOSE(("interrupt: intrtype(%d) && DPL(%d) < CPL(%d)", intrtype, gsd.dpl, CPU_STAT_CPL));
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                   }
   
                   if (!SEG_IS_PRESENT(&gsd)) {
                           VERBOSE(("interrupt: gate descriptor is not present."));
                           EXCEPTION(NP_EXCEPTION, exc_errcode);
                 }                  }
   
                 if (!softintp && CPU_STAT_HLT) {                  if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) {
                           VERBOSE(("interrupt: reset HTL in protected mode"));
                         CPU_EIP++;                          CPU_EIP++;
                         CPU_STAT_HLT = FALSE;                          CPU_STAT_HLT = 0;
                 }                  }
   
                 switch (gd.type) {                  switch (gsd.type) {
                 case CPU_SYSDESC_TYPE_TASK:                  case CPU_SYSDESC_TYPE_TASK:
                         interrupt_task_gate(&gd, softintp, errorp, error_code);                          interrupt_task_gate(&gsd, intrtype, errorp, error_code);
                         break;                          break;
   
                 case CPU_SYSDESC_TYPE_INTR_16:                  case CPU_SYSDESC_TYPE_INTR_16:
                 case CPU_SYSDESC_TYPE_INTR_32:                  case CPU_SYSDESC_TYPE_INTR_32:
                 case CPU_SYSDESC_TYPE_TRAP_16:                  case CPU_SYSDESC_TYPE_TRAP_16:
                 case CPU_SYSDESC_TYPE_TRAP_32:                  case CPU_SYSDESC_TYPE_TRAP_32:
                         interrupt_intr_or_trap(&gd, softintp, errorp, error_code);                          interrupt_intr_or_trap(&gsd, intrtype, errorp, error_code);
                         break;                          break;
   
                 default:                  default:
                         EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                         break;                          break;
                 }                  }
   
                 VERBOSE(("interrupt: ---------------------------------------------------------------- end"));                  VERBOSE(("interrupt: ---------------------------------------------------------------- end"));
         }          }
   
           CPU_CLEAR_PREV_ESP();
 }  }
   
 static void  static void CPUCALL
 interrupt_task_gate(const descriptor_t *gd, int softintp, int errorp, int error_code)  interrupt_task_gate(const descriptor_t *gsdp, int intrtype, int errorp, int error_code)
 {  {
         selector_t task_sel;          selector_t task_sel;
         int rv;          int rv;
   
         VERBOSE(("interrupt: TASK-GATE"));          VERBOSE(("interrupt: TASK-GATE"));
   
         (void)softintp;          rv = parse_selector(&task_sel, gsdp->u.gate.selector);
           if (rv < 0 || task_sel.ldt || !SEG_IS_SYSTEM(&task_sel.desc)) {
         rv = parse_selector(&task_sel, gd->u.gate.selector);                  VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT, type = %s)", gsdp->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G', task_sel.desc.s ? "code/data" : "system"));
         if (rv < 0 || task_sel.ldt) {  
                 VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT)", gd->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G'));  
                 EXCEPTION(TS_EXCEPTION, task_sel.idx);                  EXCEPTION(TS_EXCEPTION, task_sel.idx);
         }          }
   
Line 366  interrupt_task_gate(const descriptor_t * Line 379  interrupt_task_gate(const descriptor_t *
   
         task_switch(&task_sel, TASK_SWITCH_INTR);          task_switch(&task_sel, TASK_SWITCH_INTR);
   
           CPU_SET_PREV_ESP();
   
         if (errorp) {          if (errorp) {
                 XPUSH0(error_code);                  XPUSH0(error_code);
         }          }
   
           /* out of range */
           if (CPU_EIP > CPU_STAT_CS_LIMIT) {
                   VERBOSE(("interrupt: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT));
                   EXCEPTION(GP_EXCEPTION, 0);
           }
 }  }
   
 static void  static void CPUCALL
 interrupt_intr_or_trap(const descriptor_t *gd, int softintp, int errorp, int error_code)  interrupt_intr_or_trap(const descriptor_t *gsdp, int intrtype, int errorp, int error_code)
 {  {
         selector_t cs_sel, ss_sel;          selector_t cs_sel, ss_sel;
         UINT stacksize;          UINT stacksize;
Line 383  interrupt_intr_or_trap(const descriptor_ Line 404  interrupt_intr_or_trap(const descriptor_
         UINT32 new_ip, new_sp;          UINT32 new_ip, new_sp;
         UINT32 old_ip, old_sp;          UINT32 old_ip, old_sp;
         UINT16 old_cs, old_ss, new_ss;          UINT16 old_cs, old_ss, new_ss;
           int exc_errcode;
         int rv;           int rv; 
   
         new_ip = gd->u.gate.offset;          new_ip = gsdp->u.gate.offset;
         old_ss = CPU_SS;          old_ss = CPU_SS;
         old_cs = CPU_CS;          old_cs = CPU_CS;
         old_ip = CPU_EIP;          old_ip = CPU_EIP;
Line 394  interrupt_intr_or_trap(const descriptor_ Line 416  interrupt_intr_or_trap(const descriptor_
         new_flags = REAL_EFLAGREG & ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG);          new_flags = REAL_EFLAGREG & ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG);
         mask = T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG;          mask = T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG;
   
         switch (gd->type) {          switch (gsdp->type) {
         case CPU_SYSDESC_TYPE_INTR_16:          case CPU_SYSDESC_TYPE_INTR_16:
         case CPU_SYSDESC_TYPE_INTR_32:          case CPU_SYSDESC_TYPE_INTR_32:
                 VERBOSE(("interrupt: INTERRUPT-GATE"));                  VERBOSE(("interrupt: INTERRUPT-GATE"));
Line 408  interrupt_intr_or_trap(const descriptor_ Line 430  interrupt_intr_or_trap(const descriptor_
                 break;                  break;
   
         default:          default:
                 ia32_panic("interrupt: gate descriptor type is invalid (type = %d)", gd->type);                  ia32_panic("interrupt: gate descriptor type is invalid (type = %d)", gsdp->type);
                 break;                  break;
         }          }
   
         rv = parse_selector(&cs_sel, gd->u.gate.selector);          exc_errcode = gsdp->u.gate.selector & ~3;
           if (intrtype == INTR_TYPE_EXTINTR)
                   exc_errcode++;
   
           rv = parse_selector(&cs_sel, gsdp->u.gate.selector);
         if (rv < 0) {          if (rv < 0) {
                 VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gd->u.gate.selector, rv));                  VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gsdp->u.gate.selector, rv));
                 EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                  EXCEPTION(GP_EXCEPTION, exc_errcode);
         }          }
   
         /* check segment type */          /* check segment type */
         if (!cs_sel.desc.s) {          if (SEG_IS_SYSTEM(&cs_sel.desc)) {
                 VERBOSE(("interrupt: code segment is system segment"));                  VERBOSE(("interrupt: code segment is system segment"));
                 EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                  EXCEPTION(GP_EXCEPTION, exc_errcode);
         }          }
         if (!cs_sel.desc.u.seg.c) {          if (SEG_IS_DATA(&cs_sel.desc)) {
                 VERBOSE(("interrupt: code segment is data segment"));                  VERBOSE(("interrupt: code segment is data segment"));
                 EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                  EXCEPTION(GP_EXCEPTION, exc_errcode);
         }          }
   
         /* check privilege level */          /* check privilege level */
         if (cs_sel.desc.dpl > CPU_STAT_CPL) {          if (cs_sel.desc.dpl > CPU_STAT_CPL) {
                 VERBOSE(("interrupt: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL));                  VERBOSE(("interrupt: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL));
                 EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                  EXCEPTION(GP_EXCEPTION, exc_errcode);
         }          }
   
         /* not present */          /* not present */
         if (selector_is_not_present(&cs_sel)) {          if (selector_is_not_present(&cs_sel)) {
                 VERBOSE(("interrupt: selector is not present"));                  VERBOSE(("interrupt: selector is not present"));
                 EXCEPTION(NP_EXCEPTION, cs_sel.idx + !softintp);                  EXCEPTION(NP_EXCEPTION, exc_errcode);
         }          }
   
         if (!cs_sel.desc.u.seg.ec          if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl < CPU_STAT_CPL)) {
          && (cs_sel.desc.dpl < CPU_STAT_CPL)) {                  stacksize = errorp ? 12 : 10;
                 if (!CPU_STAT_VM86) {                  if (!CPU_STAT_VM86) {
                         VERBOSE(("interrupt: INTER-PRIVILEGE-LEVEL-INTERRUPT"));                          VERBOSE(("interrupt: INTER-PRIVILEGE-LEVEL-INTERRUPT"));
                         stacksize = errorp ? 12 : 10;  
                 } else {                  } else {
                         /* VM86 */                          /* VM86 */
                           VERBOSE(("interrupt: INTERRUPT-FROM-VIRTUAL-8086-MODE"));
                         if (cs_sel.desc.dpl != 0) {                          if (cs_sel.desc.dpl != 0) {
                                 /* 16.3.1.1 */                                  /* 16.3.1.1 */
                                 VERBOSE(("interrupt: DPL[CS](%d) != 0", cs_sel.desc.dpl));                                  VERBOSE(("interrupt: DPL[CS](%d) != 0", cs_sel.desc.dpl));
                                 EXCEPTION(GP_EXCEPTION, cs_sel.idx);                                  EXCEPTION(GP_EXCEPTION, exc_errcode);
                         }                          }
                         VERBOSE(("interrupt: INTERRUPT-FROM-VIRTUAL-8086-MODE"));                          stacksize += 8;
                         stacksize = errorp ? 20 : 18;  
                 }                  }
                 switch (gd->type) {                  if (gsdp->type & CPU_SYSDESC_TYPE_32BIT) {
                 case CPU_SYSDESC_TYPE_INTR_32:  
                 case CPU_SYSDESC_TYPE_TRAP_32:  
                         stacksize *= 2;                          stacksize *= 2;
                         break;  
                 }                  }
   
                   /* get stack pointer from TSS */
                 get_stack_pointer_from_tss(cs_sel.desc.dpl, &new_ss, &new_sp);                  get_stack_pointer_from_tss(cs_sel.desc.dpl, &new_ss, &new_sp);
   
                   /* parse stack segment descriptor */
                 rv = parse_selector(&ss_sel, new_ss);                  rv = parse_selector(&ss_sel, new_ss);
   
                   /* update exception error code */
                   exc_errcode = ss_sel.idx;
                   if (intrtype == INTR_TYPE_EXTINTR)
                           exc_errcode++;
   
                 if (rv < 0) {                  if (rv < 0) {
                         VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv));                          VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
   
                 /* check privilege level */                  /* check privilege level */
                 if (ss_sel.rpl != cs_sel.desc.dpl) {                  if (ss_sel.rpl != cs_sel.desc.dpl) {
                         VERBOSE(("interrupt: RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, cs_sel.desc.dpl));                          VERBOSE(("interrupt: selector RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, cs_sel.desc.dpl));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
                 if (ss_sel.desc.dpl != cs_sel.desc.dpl) {                  if (ss_sel.desc.dpl != cs_sel.desc.dpl) {
                         VERBOSE(("interrupt: DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, cs_sel.desc.dpl));                          VERBOSE(("interrupt: descriptor DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, cs_sel.desc.dpl));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
   
                 /* check segment type */                  /* stack segment must be writable data segment. */
                 if (!ss_sel.desc.s) {                  if (SEG_IS_SYSTEM(&ss_sel.desc)) {
                         VERBOSE(("interrupt: stack segment is system segment"));                          VERBOSE(("interrupt: stack segment is system segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
                 if (ss_sel.desc.u.seg.c) {                  if (SEG_IS_CODE(&ss_sel.desc)) {
                         VERBOSE(("interrupt: stack segment is code segment"));                          VERBOSE(("interrupt: stack segment is code segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
                 if (!ss_sel.desc.u.seg.wr) {                  if (!SEG_IS_WRITABLE_DATA(&ss_sel.desc)) {
                         VERBOSE(("interrupt: stack segment is read-only data segment"));                          VERBOSE(("interrupt: stack segment is read-only data segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(TS_EXCEPTION, exc_errcode);
                 }                  }
   
                 /* not present */                  /* not present */
                 if (selector_is_not_present(&ss_sel)) {                  if (selector_is_not_present(&ss_sel)) {
                         VERBOSE(("interrupt: selector is not present"));                          VERBOSE(("interrupt: selector is not present"));
                         EXCEPTION(SS_EXCEPTION, ss_sel.idx + !softintp);                          EXCEPTION(SS_EXCEPTION, exc_errcode);
                 }                  }
   
                 /* check stack room size */                  /* check stack room size */
                 STACK_PUSH_CHECK(ss_sel.idx, &ss_sel.desc, new_sp, stacksize);                  cpu_stack_push_check(ss_sel.idx, &ss_sel.desc, new_sp, stacksize);
   
                 /* out of range */                  /* out of range */
                 if (new_ip > cs_sel.desc.u.seg.limit) {                  if (new_ip > cs_sel.desc.u.seg.limit) {
Line 513  interrupt_intr_or_trap(const descriptor_ Line 543  interrupt_intr_or_trap(const descriptor_
                 CPU_ESP = new_sp;                  CPU_ESP = new_sp;
   
                 load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.desc.dpl);                  load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.desc.dpl);
                 SET_EIP(new_ip);                  CPU_EIP = new_ip;
   
                 switch (gd->type) {                  if (gsdp->type & CPU_SYSDESC_TYPE_32BIT) {
                 case CPU_SYSDESC_TYPE_INTR_32:  
                 case CPU_SYSDESC_TYPE_TRAP_32:  
                         if (CPU_STAT_VM86) {                          if (CPU_STAT_VM86) {
                                 PUSH0_32(CPU_GS);                                  PUSH0_32(CPU_GS);
                                 PUSH0_32(CPU_FS);                                  PUSH0_32(CPU_FS);
                                 PUSH0_32(CPU_DS);                                  PUSH0_32(CPU_DS);
                                 PUSH0_32(CPU_ES);                                  PUSH0_32(CPU_ES);
   
                                 CPU_SET_SEGREG(CPU_GS_INDEX, 0);                                  LOAD_SEGREG(CPU_GS_INDEX, 0);
                                 CPU_STAT_SREG(CPU_GS_INDEX).valid = 0;                                  CPU_STAT_SREG(CPU_GS_INDEX).valid = 0;
                                 CPU_SET_SEGREG(CPU_FS_INDEX, 0);                                  LOAD_SEGREG(CPU_FS_INDEX, 0);
                                 CPU_STAT_SREG(CPU_FS_INDEX).valid = 0;                                  CPU_STAT_SREG(CPU_FS_INDEX).valid = 0;
                                 CPU_SET_SEGREG(CPU_DS_INDEX, 0);                                  LOAD_SEGREG(CPU_DS_INDEX, 0);
                                 CPU_STAT_SREG(CPU_DS_INDEX).valid = 0;                                  CPU_STAT_SREG(CPU_DS_INDEX).valid = 0;
                                 CPU_SET_SEGREG(CPU_ES_INDEX, 0);                                  LOAD_SEGREG(CPU_ES_INDEX, 0);
                                 CPU_STAT_SREG(CPU_ES_INDEX).valid = 0;                                  CPU_STAT_SREG(CPU_ES_INDEX).valid = 0;
                         }                          }
                         PUSH0_32(old_ss);                          PUSH0_32(old_ss);
Line 541  interrupt_intr_or_trap(const descriptor_ Line 569  interrupt_intr_or_trap(const descriptor_
                         if (errorp) {                          if (errorp) {
                                 PUSH0_32(error_code);                                  PUSH0_32(error_code);
                         }                          }
                         break;                  } else {
   
                 case CPU_SYSDESC_TYPE_INTR_16:  
                 case CPU_SYSDESC_TYPE_TRAP_16:  
                         if (CPU_STAT_VM86) {                          if (CPU_STAT_VM86) {
                                 ia32_panic("interrupt: 16bit gate && VM86");                                  ia32_panic("interrupt: 16bit gate && VM86");
                         }                          }
Line 556  interrupt_intr_or_trap(const descriptor_ Line 581  interrupt_intr_or_trap(const descriptor_
                         if (errorp) {                          if (errorp) {
                                 PUSH0_16(error_code);                                  PUSH0_16(error_code);
                         }                          }
                         break;  
                 }                  }
         } else {          } else {
                 if (CPU_STAT_VM86) {                  if (CPU_STAT_VM86) {
                         VERBOSE(("interrupt: VM86"));                          VERBOSE(("interrupt: VM86"));
                         EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                 }                  }
                 if (!cs_sel.desc.u.seg.ec && (cs_sel.desc.dpl != CPU_STAT_CPL)) {                  if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl != CPU_STAT_CPL)) {
                         VERBOSE(("interrupt: NON-CONFORMING-CODE-SEGMENT(%s) and DPL[CS](%d) != CPL", cs_sel.desc.u.seg.ec ? "false" : "true", cs_sel.desc.dpl, CPU_STAT_CPL));                          VERBOSE(("interrupt: %sCONFORMING-CODE-SEGMENT(%d) && DPL[CS](%d) != CPL", SEG_IS_CONFORMING_CODE(&cs_sel.desc) ? "" : "NON-", cs_sel.desc.dpl, CPU_STAT_CPL));
                         EXCEPTION(GP_EXCEPTION, cs_sel.idx + !softintp);                          EXCEPTION(GP_EXCEPTION, exc_errcode);
                 }                  }
   
                 VERBOSE(("interrupt: INTRA-PRIVILEGE-LEVEL-INTERRUPT"));                  VERBOSE(("interrupt: INTRA-PRIVILEGE-LEVEL-INTERRUPT"));
   
                 stacksize = errorp ? 8 : 6;                  stacksize = errorp ? 8 : 6;
                 switch (gd->type) {                  if (gsdp->type & CPU_SYSDESC_TYPE_32BIT) {
                 case CPU_SYSDESC_TYPE_INTR_32:  
                 case CPU_SYSDESC_TYPE_TRAP_32:  
                         stacksize *= 2;                          stacksize *= 2;
                         break;  
                 }                  }
   
                   /* check stack room size */
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         sp = CPU_ESP;                          sp = CPU_ESP;
                 } else {                  } else {
                         sp = CPU_SP;                          sp = CPU_SP;
                 }                  }
                 STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, stacksize);                  SS_PUSH_CHECK(sp, stacksize);
   
                 /* out of range */                  /* out of range */
                 if (new_ip > cs_sel.desc.u.seg.limit) {                  if (new_ip > cs_sel.desc.u.seg.limit) {
Line 591  interrupt_intr_or_trap(const descriptor_ Line 614  interrupt_intr_or_trap(const descriptor_
                 }                  }
   
                 load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL);                  load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL);
                 SET_EIP(new_ip);                  CPU_EIP = new_ip;
   
                 switch (gd->type) {                  if (gsdp->type & CPU_SYSDESC_TYPE_32BIT) {
                 case CPU_SYSDESC_TYPE_INTR_32:  
                 case CPU_SYSDESC_TYPE_TRAP_32:  
                         PUSH0_32(old_flags);                          PUSH0_32(old_flags);
                         PUSH0_32(old_cs);                          PUSH0_32(old_cs);
                         PUSH0_32(old_ip);                          PUSH0_32(old_ip);
                         if (errorp) {                          if (errorp) {
                                 PUSH0_32(error_code);                                  PUSH0_32(error_code);
                         }                          }
                         break;                  } else {
   
                 case CPU_SYSDESC_TYPE_INTR_16:  
                 case CPU_SYSDESC_TYPE_TRAP_16:  
                         PUSH0_16(old_flags);                          PUSH0_16(old_flags);
                         PUSH0_16(old_cs);                          PUSH0_16(old_cs);
                         PUSH0_16(old_ip);                          PUSH0_16(old_ip);
                         if (errorp) {                          if (errorp) {
                                 PUSH0_16(error_code);                                  PUSH0_16(error_code);
                         }                          }
                         break;  
                 }                  }
         }          }
         set_eflags(new_flags, mask);          set_eflags(new_flags, mask);

Removed from v.1.20  
changed lines
  Added in v.1.35


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