Diff for /np2/i386c/ia32/ctrlxfer.c between versions 1.11 and 1.18

version 1.11, 2004/02/13 14:50:17 version 1.18, 2005/03/12 12:32:54
Line 12 Line 12
  * 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 37 Line 35
 /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
  * JMPfar_pm   * JMPfar_pm
  */   */
 static void JMPfar_pm_code_segment(selector_t *jmp_sel, DWORD new_ip);  static void JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip);
 static void JMPfar_pm_call_gate(selector_t *jmp_sel);  static void JMPfar_pm_call_gate(const selector_t *callgate_sel);
 static void JMPfar_pm_task_gate(selector_t *jmp_sel);  static void JMPfar_pm_task_gate(selector_t *taskgate_sel);
 static void JMPfar_pm_tss(selector_t *jmp_sel);  static void JMPfar_pm_tss(selector_t *tss_sel);
   
 void  void
 JMPfar_pm(WORD selector, DWORD new_ip)  JMPfar_pm(UINT16 selector, UINT32 new_ip)
 {  {
         selector_t jmp_sel;          selector_t jmp_sel;
         int rv;          int rv;
Line 106  JMPfar_pm(WORD selector, DWORD new_ip) Line 104  JMPfar_pm(WORD selector, DWORD new_ip)
  * JMPfar: code segment   * JMPfar: code segment
  */   */
 static void  static void
 JMPfar_pm_code_segment(selector_t *cs_sel, DWORD new_ip)  JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip)
 {  {
   
         VERBOSE(("JMPfar_pm: CODE-SEGMENT"));          VERBOSE(("JMPfar_pm: CODE-SEGMENT"));
Line 152  JMPfar_pm_code_segment(selector_t *cs_se Line 150  JMPfar_pm_code_segment(selector_t *cs_se
  * JMPfar: call gate   * JMPfar: call gate
  */   */
 static void  static void
 JMPfar_pm_call_gate(selector_t *callgate_sel)  JMPfar_pm_call_gate(const selector_t *callgate_sel)
 {  {
         selector_t cs_sel;          selector_t cs_sel;
         int rv;          int rv;
Line 318  JMPfar_pm_tss(selector_t *tss_sel) Line 316  JMPfar_pm_tss(selector_t *tss_sel)
 /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
  * CALLfar_pm   * CALLfar_pm
  */   */
 static void CALLfar_pm_code_segment(selector_t *call_sel, DWORD new_ip);  static void CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip);
 static void CALLfar_pm_call_gate(selector_t *call_sel);  static void CALLfar_pm_call_gate(const selector_t *callgate_sel);
 static void CALLfar_pm_task_gate(selector_t *call_sel);  static void CALLfar_pm_task_gate(selector_t *taskgate_sel);
 static void CALLfar_pm_tss(selector_t *call_sel);  static void CALLfar_pm_tss(selector_t *tss_sel);
   
 void  void
 CALLfar_pm(WORD selector, DWORD new_ip)  CALLfar_pm(UINT16 selector, UINT32 new_ip)
 {  {
         selector_t call_sel;          selector_t call_sel;
         int rv;          int rv;
Line 387  CALLfar_pm(WORD selector, DWORD new_ip) Line 385  CALLfar_pm(WORD selector, DWORD new_ip)
  * CALLfar_pm: code segment   * CALLfar_pm: code segment
  */   */
 static void  static void
 CALLfar_pm_code_segment(selector_t *cs_sel, DWORD new_ip)  CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip)
 {  {
         DWORD sp;          UINT32 sp;
   
         VERBOSE(("CALLfar_pm: CODE-SEGMENT"));          VERBOSE(("CALLfar_pm: CODE-SEGMENT"));
   
Line 426  CALLfar_pm_code_segment(selector_t *cs_s Line 424  CALLfar_pm_code_segment(selector_t *cs_s
                 sp = CPU_SP;                  sp = CPU_SP;
         }          }
         if (CPU_INST_OP32) {          if (CPU_INST_OP32) {
                 CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8);                  STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8);
   
                 /* 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 437  CALLfar_pm_code_segment(selector_t *cs_s Line 435  CALLfar_pm_code_segment(selector_t *cs_s
                 PUSH0_32(CPU_CS);                  PUSH0_32(CPU_CS);
                 PUSH0_32(CPU_EIP);                  PUSH0_32(CPU_EIP);
         } else {          } else {
                 CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4);                  STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4);
   
                 /* 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 456  CALLfar_pm_code_segment(selector_t *cs_s Line 454  CALLfar_pm_code_segment(selector_t *cs_s
 /*---  /*---
  * CALLfar_pm: call gate   * CALLfar_pm: call gate
  */   */
 static void CALLfar_pm_call_gate_same_privilege(selector_t *call_sel, selector_t *cs_sel);  static void CALLfar_pm_call_gate_same_privilege(const selector_t *call_sel, selector_t *cs_sel);
 static void CALLfar_pm_call_gate_more_privilege(selector_t *call_sel, selector_t *cs_sel);  static void CALLfar_pm_call_gate_more_privilege(const selector_t *call_sel, selector_t *cs_sel);
   
 static void  static void
 CALLfar_pm_call_gate(selector_t *callgate_sel)  CALLfar_pm_call_gate(const selector_t *callgate_sel)
 {  {
         selector_t cs_sel;          selector_t cs_sel;
         int rv;          int rv;
Line 529  CALLfar_pm_call_gate(selector_t *callgat Line 527  CALLfar_pm_call_gate(selector_t *callgat
  * CALLfar_pm: call gate (SAME-PRIVILEGE)   * CALLfar_pm: call gate (SAME-PRIVILEGE)
  */   */
 static void  static void
 CALLfar_pm_call_gate_same_privilege(selector_t *callgate_sel, selector_t *cs_sel)  CALLfar_pm_call_gate_same_privilege(const selector_t *callgate_sel, selector_t *cs_sel)
 {  {
         DWORD sp;          UINT32 sp;
   
         VERBOSE(("CALLfar_pm: SAME-PRIVILEGE"));          VERBOSE(("CALLfar_pm: SAME-PRIVILEGE"));
   
Line 542  CALLfar_pm_call_gate_same_privilege(sele Line 540  CALLfar_pm_call_gate_same_privilege(sele
         }          }
   
         if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) {          if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) {
                 CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8);                  STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8);
   
                 PUSH0_32(CPU_CS);                  PUSH0_32(CPU_CS);
                 PUSH0_32(CPU_EIP);                  PUSH0_32(CPU_EIP);
Line 550  CALLfar_pm_call_gate_same_privilege(sele Line 548  CALLfar_pm_call_gate_same_privilege(sele
                 load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL);                  load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL);
                 SET_EIP(callgate_sel->desc.u.gate.offset);                  SET_EIP(callgate_sel->desc.u.gate.offset);
         } else {          } else {
                 CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4);                  STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4);
   
                 PUSH0_16(CPU_CS);                  PUSH0_16(CPU_CS);
                 PUSH0_16(CPU_IP);                  PUSH0_16(CPU_IP);
Line 564  CALLfar_pm_call_gate_same_privilege(sele Line 562  CALLfar_pm_call_gate_same_privilege(sele
  * CALLfar_pm: call gate (MORE-PRIVILEGE)   * CALLfar_pm: call gate (MORE-PRIVILEGE)
  */   */
 static void  static void
 CALLfar_pm_call_gate_more_privilege(selector_t *callgate_sel, selector_t *cs_sel)  CALLfar_pm_call_gate_more_privilege(const selector_t *callgate_sel, selector_t *cs_sel)
 {  {
         DWORD param[32];        /* copy param */          UINT32 param[32];       /* copy param */
         selector_t ss_sel;          selector_t ss_sel;
         DWORD old_eip, old_esp;          UINT32 old_eip, old_esp;
         DWORD new_esp;          UINT32 new_esp;
         WORD old_cs, old_ss;          UINT16 old_cs, old_ss;
         WORD new_ss;          UINT16 new_ss;
         int param_count;          int param_count;
         int i;          int i;
         int rv;          int rv;
Line 631  CALLfar_pm_call_gate_more_privilege(sele Line 629  CALLfar_pm_call_gate_more_privilege(sele
         VERBOSE(("CALLfar_pm: param_count = %d", param_count));          VERBOSE(("CALLfar_pm: param_count = %d", param_count));
   
         if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) {          if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) {
                 CHECK_STACK_PUSH(&ss_sel.desc, new_esp, 16 + param_count * 4);                  STACK_PUSH_CHECK(ss_sel.idx, &ss_sel.desc, new_esp, 16 + param_count * 4);
   
                 /* dump param */                  /* dump param */
                 for (i = 0; i < param_count; i++) {                  for (i = 0; i < param_count; i++) {
Line 643  CALLfar_pm_call_gate_more_privilege(sele Line 641  CALLfar_pm_call_gate_more_privilege(sele
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         CPU_ESP = new_esp;                          CPU_ESP = new_esp;
                 } else {                  } else {
                         CPU_SP = new_esp;                          CPU_SP = (UINT16)new_esp;
                 }                  }
   
                 load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl);                  load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl);
Line 661  CALLfar_pm_call_gate_more_privilege(sele Line 659  CALLfar_pm_call_gate_more_privilege(sele
                 PUSH0_32(old_cs);                  PUSH0_32(old_cs);
                 PUSH0_32(old_eip);                  PUSH0_32(old_eip);
         } else {          } else {
                 CHECK_STACK_PUSH(&ss_sel.desc, new_esp, 8 + param_count * 2);                  STACK_PUSH_CHECK(ss_sel.idx, &ss_sel.desc, new_esp, 8 + param_count * 2);
   
                 /* dump param */                  /* dump param */
                 for (i = 0; i < param_count; i++) {                  for (i = 0; i < param_count; i++) {
Line 673  CALLfar_pm_call_gate_more_privilege(sele Line 671  CALLfar_pm_call_gate_more_privilege(sele
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         CPU_ESP = new_esp;                          CPU_ESP = new_esp;
                 } else {                  } else {
                         CPU_SP = new_esp;                          CPU_SP = (UINT16)new_esp;
                 }                  }
   
                 load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl);                  load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl);
Line 786  CALLfar_pm_tss(selector_t *tss_sel) Line 784  CALLfar_pm_tss(selector_t *tss_sel)
  */   */
   
 void  void
 RETfar_pm(DWORD nbytes)  RETfar_pm(UINT nbytes)
 {  {
         selector_t cs_sel, ss_sel, temp_sel;          selector_t cs_sel, ss_sel, temp_sel;
         DWORD sp;          UINT32 sp;
         DWORD new_ip, new_sp;          UINT32 new_ip, new_sp;
         WORD new_cs, new_ss;          UINT16 new_cs, new_ss;
         int rv;          int rv;
         int i;          int i;
   
Line 803  RETfar_pm(DWORD nbytes) Line 801  RETfar_pm(DWORD nbytes)
                 sp = CPU_SP;                  sp = CPU_SP;
         }          }
         if (CPU_INST_OP32) {          if (CPU_INST_OP32) {
                 CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 8);                  STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 8);
                 new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp);                  new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp);
                 new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);                  new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);
         } else {          } else {
                 CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 4);                  STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 4);
                 new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp);                  new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp);
                 new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2);                  new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2);
         }          }
Line 863  RETfar_pm(DWORD nbytes) Line 861  RETfar_pm(DWORD nbytes)
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         CPU_ESP += nbytes;                          CPU_ESP += nbytes;
                 } else {                  } else {
                         CPU_SP += nbytes;                          CPU_SP += (UINT16)nbytes;
                 }                  }
   
                 load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL);                  load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL);
Line 872  RETfar_pm(DWORD nbytes) Line 870  RETfar_pm(DWORD nbytes)
                 VERBOSE(("RETfar_pm: RETURN-OUTER-PRIVILEGE-LEVEL"));                  VERBOSE(("RETfar_pm: RETURN-OUTER-PRIVILEGE-LEVEL"));
   
                 if (CPU_INST_OP32) {                  if (CPU_INST_OP32) {
                         CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8 + 8 + nbytes);                          STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8 + 8 + nbytes);
                         new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8 + nbytes);                          new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8 + nbytes);
                         new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8 + nbytes + 4);                          new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8 + nbytes + 4);
                 } else {                  } else {
                         CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4 + 4 + nbytes);                          STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4 + 4 + nbytes);
                         new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes);                          new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes);
                         new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes + 2);                          new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes + 2);
                 }                  }
Line 933  RETfar_pm(DWORD nbytes) Line 931  RETfar_pm(DWORD nbytes)
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         CPU_ESP = new_sp + nbytes;                          CPU_ESP = new_sp + nbytes;
                 } else {                  } else {
                         CPU_SP = new_sp + nbytes;                          CPU_SP = (UINT16)(new_sp + nbytes);
                 }                  }
   
                 /* check segment register */                  /* check segment register */
Line 989  RETfar_pm(DWORD nbytes) Line 987  RETfar_pm(DWORD nbytes)
  * IRET_pm   * IRET_pm
  */   */
 static void IRET_pm_nested_task(void);  static void IRET_pm_nested_task(void);
 static void IRET_pm_protected_mode_return(DWORD new_cs, DWORD new_ip, DWORD new_flags);  static void IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags);
 static void IRET_pm_protected_mode_return_same_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags);  static void IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags);
 static void IRET_pm_protected_mode_return_outer_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags);  static void IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags);
 static void IRET_pm_return_to_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags);  static void IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags);
 static void IRET_pm_return_from_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags);  static void IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags);
   
 void  void
 IRET_pm(void)  IRET_pm(void)
 {  {
         DWORD sp;          UINT32 sp;
         DWORD new_ip, new_flags;          UINT32 new_ip, new_flags;
         WORD new_cs;          UINT16 new_cs;
         int rv;  
   
         VERBOSE(("IRET_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP));          VERBOSE(("IRET_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP));
   
Line 1015  IRET_pm(void) Line 1012  IRET_pm(void)
                         sp = CPU_SP;                          sp = CPU_SP;
                 }                  }
                 if (CPU_INST_OP32) {                  if (CPU_INST_OP32) {
                         CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 12);                          STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 12);
                         new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp);                          new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp);
                         new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);                          new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);
                         new_flags = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8);                          new_flags = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8);
                 } else {                  } else {
                         CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 6);                          STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 6);
                         new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp);                          new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp);
                         new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2);                          new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2);
                         new_flags = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);                          new_flags = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4);
Line 1050  static void Line 1047  static void
 IRET_pm_nested_task(void)  IRET_pm_nested_task(void)
 {  {
         selector_t tss_sel;          selector_t tss_sel;
           UINT16 new_tss;
         int rv;          int rv;
         WORD new_tss;  
   
         VERBOSE(("IRET_pm: TASK-RETURN: PE=1, VM=0, NT=1"));          VERBOSE(("IRET_pm: TASK-RETURN: PE=1, VM=0, NT=1"));
   
Line 1065  IRET_pm_nested_task(void) Line 1062  IRET_pm_nested_task(void)
   
         /* check system segment */          /* check system segment */
         if (tss_sel.desc.s) {          if (tss_sel.desc.s) {
                 VERBOSE(("IRET_pm: task segment is %d segment", tss_sel.desc.u.seg.c ? "code" : "data"));                  VERBOSE(("IRET_pm: task segment is %s segment", tss_sel.desc.u.seg.c ? "code" : "data"));
                 EXCEPTION(GP_EXCEPTION, tss_sel.idx);                  EXCEPTION(GP_EXCEPTION, tss_sel.idx);
         }          }
   
Line 1097  IRET_pm_nested_task(void) Line 1094  IRET_pm_nested_task(void)
  * IRET_pm: PROTECTED-MODE-RETURN   * IRET_pm: PROTECTED-MODE-RETURN
  */   */
 static void  static void
 IRET_pm_protected_mode_return(DWORD new_cs, DWORD new_ip, DWORD new_flags)  IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags)
 {  {
         selector_t cs_sel;          selector_t cs_sel;
         int rv;          int rv;
Line 1148  IRET_pm_protected_mode_return(DWORD new_ Line 1145  IRET_pm_protected_mode_return(DWORD new_
  * IRET_pm: SAME-PRIVILEGE   * IRET_pm: SAME-PRIVILEGE
  */   */
 static void  static void
 IRET_pm_protected_mode_return_same_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags)  IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags)
 {  {
         DWORD mask;          UINT32 mask;
         DWORD stacksize;          UINT stacksize;
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           UINT32 old_flags = CPU_EFLAG;
   #endif
   
         VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL"));          VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL"));
   
Line 1161  IRET_pm_protected_mode_return_same_privi Line 1161  IRET_pm_protected_mode_return_same_privi
                 EXCEPTION(GP_EXCEPTION, 0);                  EXCEPTION(GP_EXCEPTION, 0);
         }          }
   
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           mask = ALL_EFLAG;
           if (CPU_STAT_CPL > CPU_STAT_IOPL)
                   mask &= ~I_FLAG;
           if (CPU_STAT_CPL > 0) {
                   mask &= ~IOPL_FLAG;
                   if (CPU_INST_OP32) {
                           mask &= ~(VM_FLAG|VIF_FLAG|VIP_FLAG);
                   }
           }
   #else
         mask = 0;          mask = 0;
         if (CPU_INST_OP32)          if (CPU_INST_OP32)
                 mask |= RF_FLAG;                  mask |= RF_FLAG;
Line 1172  IRET_pm_protected_mode_return_same_privi Line 1183  IRET_pm_protected_mode_return_same_privi
                         mask |= VM_FLAG|VIF_FLAG|VIP_FLAG;                          mask |= VM_FLAG|VIF_FLAG|VIP_FLAG;
                 }                  }
         }          }
   #endif
   
         if (CPU_INST_OP32) {          if (CPU_INST_OP32) {
                 stacksize = 12;                  stacksize = 12;
         } else {          } else {
Line 1182  IRET_pm_protected_mode_return_same_privi Line 1195  IRET_pm_protected_mode_return_same_privi
         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);          SET_EIP(new_ip);
   
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           CPU_EFLAG = (new_flags & mask) | (CPU_EFLAG & ~mask);
           CPU_OV = CPU_FLAG & O_FLAG;
           CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);
           if ((old_flags ^ CPU_EFLAG) & VM_FLAG) {
                   if (CPU_EFLAG & VM_FLAG) {
                           change_vm(1);
                   } else {
                           change_vm(0);
                   }
           }
   #else
         set_eflags(new_flags, mask);          set_eflags(new_flags, mask);
   #endif
   
         if (CPU_STAT_SS32) {          if (CPU_STAT_SS32) {
                 CPU_ESP += stacksize;                  CPU_ESP += stacksize;
         } else {          } else {
                 CPU_SP += stacksize;                  CPU_SP += (UINT16)stacksize;
         }          }
 }  }
   
Line 1195  IRET_pm_protected_mode_return_same_privi Line 1221  IRET_pm_protected_mode_return_same_privi
  * IRET_pm: OUTER-PRIVILEGE   * IRET_pm: OUTER-PRIVILEGE
  */   */
 static void  static void
 IRET_pm_protected_mode_return_outer_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags)  IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags)
 {  {
         descriptor_t *dp;          descriptor_t *dp;
         selector_t ss_sel;          selector_t ss_sel;
         DWORD mask;          UINT32 mask;
         DWORD sp;          UINT32 sp;
         DWORD new_sp;          UINT32 new_sp;
         WORD new_ss;          UINT16 new_ss;
         int rv;          int rv;
         int i;          int i;
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           UINT32 old_flags = CPU_EFLAG;
   #endif
   
         VERBOSE(("IRET_pm: RETURN-OUTER-PRIVILEGE-LEVEL"));          VERBOSE(("IRET_pm: RETURN-OUTER-PRIVILEGE-LEVEL"));
   
Line 1214  IRET_pm_protected_mode_return_outer_priv Line 1243  IRET_pm_protected_mode_return_outer_priv
                 sp = CPU_SP;                  sp = CPU_SP;
         }          }
         if (CPU_INST_OP32) {          if (CPU_INST_OP32) {
                 CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 20);                  STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 20);
                 new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12);                  new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12);
                 new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16);                  new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16);
         } else {          } else {
                 CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 10);                  STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 10);
                 new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 6);                  new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 6);
                 new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8);                  new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8);
         }          }
Line 1266  IRET_pm_protected_mode_return_outer_priv Line 1295  IRET_pm_protected_mode_return_outer_priv
                 EXCEPTION(GP_EXCEPTION, 0);                  EXCEPTION(GP_EXCEPTION, 0);
         }          }
   
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           mask = ALL_EFLAG;
           if (CPU_STAT_CPL > CPU_STAT_IOPL)
                   mask &= ~I_FLAG;
           if (CPU_STAT_CPL > 0) {
                   mask &= ~IOPL_FLAG;
                   if (CPU_INST_OP32) {
                           mask &= ~(VM_FLAG|VIF_FLAG|VIP_FLAG);
                   }
           }
   #else
         mask = 0;          mask = 0;
         if (CPU_INST_OP32)          if (CPU_INST_OP32)
                 mask |= RF_FLAG;                  mask |= RF_FLAG;
Line 1277  IRET_pm_protected_mode_return_outer_priv Line 1317  IRET_pm_protected_mode_return_outer_priv
                         mask |= VM_FLAG|VIF_FLAG|VIP_FLAG;                          mask |= VM_FLAG|VIF_FLAG|VIP_FLAG;
                 }                  }
         }          }
   #endif
   
         /* set new register */          /* set new register */
         load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->rpl);          load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->rpl);
         SET_EIP(new_ip);          SET_EIP(new_ip);
   
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           CPU_EFLAG = (new_flags & mask) | (CPU_EFLAG & ~mask);
           CPU_OV = CPU_FLAG & O_FLAG;
           CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);
           if ((old_flags ^ CPU_EFLAG) & VM_FLAG) {
                   if (CPU_EFLAG & VM_FLAG) {
                           change_vm(1);
                   } else {
                           change_vm(0);
                   }
           }
   #else
         set_eflags(new_flags, mask);          set_eflags(new_flags, mask);
   #endif
   
         load_ss(ss_sel.selector, &ss_sel.desc, cs_sel->rpl);          load_ss(ss_sel.selector, &ss_sel.desc, cs_sel->rpl);
         if (CPU_STAT_SS32) {          if (CPU_STAT_SS32) {
                 CPU_ESP = new_sp;                  CPU_ESP = new_sp;
         } else {          } else {
                 CPU_SP = new_sp;                  CPU_SP = (UINT16)new_sp;
         }          }
   
         /* check segment register */          /* check segment register */
Line 1300  IRET_pm_protected_mode_return_outer_priv Line 1354  IRET_pm_protected_mode_return_outer_priv
                                 /* segment register is invalid */                                  /* segment register is invalid */
                                 CPU_REGS_SREG(i) = 0;                                  CPU_REGS_SREG(i) = 0;
                                 CPU_STAT_SREG_CLEAR(i);                                  CPU_STAT_SREG_CLEAR(i);
                                 continue;  
                         }                          }
                 }                  }
         }          }
Line 1310  IRET_pm_protected_mode_return_outer_priv Line 1363  IRET_pm_protected_mode_return_outer_priv
  * IRET_pm: new_flags & VM_FLAG   * IRET_pm: new_flags & VM_FLAG
  */   */
 static void  static void
 IRET_pm_return_to_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags)  IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags)
 {  {
         WORD segsel[CPU_SEGREG_NUM];          UINT16 segsel[CPU_SEGREG_NUM];
         DWORD sp;          UINT32 sp;
         DWORD new_sp;          UINT32 new_sp;
         int i;          int i;
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           UINT32 old_flags = CPU_EFLAG;
   #endif
   
         VERBOSE(("IRET_pm: Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image"));          VERBOSE(("IRET_pm: Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image"));
   
Line 1332  IRET_pm_return_to_vm86(DWORD new_cs, DWO Line 1388  IRET_pm_return_to_vm86(DWORD new_cs, DWO
         } else {          } else {
                 sp = CPU_SP;                  sp = CPU_SP;
         }          }
         CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 36);          STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 36);
         new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12);          new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12);
         segsel[CPU_SS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16);          segsel[CPU_SS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16);
         segsel[CPU_ES_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 20);          segsel[CPU_ES_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 20);
         segsel[CPU_DS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 24);          segsel[CPU_DS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 24);
         segsel[CPU_FS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 28);          segsel[CPU_FS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 28);
         segsel[CPU_GS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 32);          segsel[CPU_GS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 32);
         segsel[CPU_CS_INDEX] = new_cs;          segsel[CPU_CS_INDEX] = (UINT16)new_cs;
   
         for (i = 0; i < CPU_SEGREG_NUM; i++) {          for (i = 0; i < CPU_SEGREG_NUM; i++) {
                 CPU_REGS_SREG(i) = segsel[i];                  CPU_REGS_SREG(i) = segsel[i];
Line 1347  IRET_pm_return_to_vm86(DWORD new_cs, DWO Line 1403  IRET_pm_return_to_vm86(DWORD new_cs, DWO
         }          }
   
         /* to VM86 mode */          /* to VM86 mode */
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           CPU_EFLAG = new_flags;
           CPU_OV = CPU_FLAG & O_FLAG;
           CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);
           if ((old_flags ^ CPU_EFLAG) & VM_FLAG) {
                   if (CPU_EFLAG & VM_FLAG) {
                           change_vm(1);
                   } else {
                           change_vm(0);
                   }
           }
   #else
         set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG);          set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG);
   #endif
   
         new_sp &= 0xffff;          new_sp &= 0xffff;
         new_ip &= 0xffff;          new_ip &= 0xffff;
Line 1360  IRET_pm_return_to_vm86(DWORD new_cs, DWO Line 1429  IRET_pm_return_to_vm86(DWORD new_cs, DWO
  * IRET_pm: VM_FLAG   * IRET_pm: VM_FLAG
  */   */
 static void  static void
 IRET_pm_return_from_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags)  IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags)
 {  {
         DWORD stacksize;          UINT stacksize;
   
         VERBOSE(("IRET_pm: virtual-8086 mode: VM=1"));          VERBOSE(("IRET_pm: virtual-8086 mode: VM=1"));
   
Line 1376  IRET_pm_return_from_vm86(DWORD new_cs, D Line 1445  IRET_pm_return_from_vm86(DWORD new_cs, D
                 if (CPU_STAT_SS32) {                  if (CPU_STAT_SS32) {
                         CPU_ESP += stacksize;                          CPU_ESP += stacksize;
                 } else {                  } else {
                         CPU_SP += stacksize;                          CPU_SP += (UINT16)stacksize;
                 }                  }
   
   #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION)
           CPU_EFLAG = (new_flags & ~(IOPL_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG)) | (CPU_EFLAG & (IOPL_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG));
           CPU_OV = CPU_FLAG & O_FLAG;
           CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG);
   #else
                 set_eflags(new_flags, I_FLAG|RF_FLAG);                  set_eflags(new_flags, I_FLAG|RF_FLAG);
   #endif
   
                 CPU_SET_SEGREG(CPU_CS_INDEX, new_cs);                  CPU_SET_SEGREG(CPU_CS_INDEX, new_cs);
                 SET_EIP(new_ip);                  SET_EIP(new_ip);

Removed from v.1.11  
changed lines
  Added in v.1.18


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