- update sector count before calling write completion function (SF patch #2144692)
[bochs-mirror.git] / cpu / soft_int.cc
blob3e4e36feb9967f23a5a3c7543106708332136b02
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: soft_int.cc,v 1.45 2008/10/01 09:44:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
33 // Make code more tidy with a few macros.
34 #if BX_SUPPORT_X86_64==0
35 #define RSP ESP
36 #endif
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BOUND_GwMa(bxInstruction_c *i)
40 Bit16s bound_min, bound_max;
41 Bit16s op1_16 = BX_READ_16BIT_REG(i->nnn());
43 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
45 bound_min = (Bit16s) read_virtual_word(i->seg(), eaddr);
46 bound_max = (Bit16s) read_virtual_word(i->seg(), eaddr+2);
48 if (op1_16 < bound_min || op1_16 > bound_max) {
49 BX_INFO(("BOUND_GdMa: fails bounds test"));
50 exception(BX_BR_EXCEPTION, 0, 0);
54 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BOUND_GdMa(bxInstruction_c *i)
56 Bit32s bound_min, bound_max;
57 Bit32s op1_32 = BX_READ_32BIT_REG(i->nnn());
59 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
61 bound_min = (Bit32s) read_virtual_dword(i->seg(), eaddr);
62 bound_max = (Bit32s) read_virtual_dword(i->seg(), eaddr+4);
64 if (op1_32 < bound_min || op1_32 > bound_max) {
65 BX_INFO(("BOUND_GdMa: fails bounds test"));
66 exception(BX_BR_EXCEPTION, 0, 0);
70 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT1(bxInstruction_c *i)
72 // This is an undocumented instrucion (opcode 0xf1)
73 // which is useful for an ICE system.
75 #if BX_DEBUGGER
76 BX_CPU_THIS_PTR show_flag |= Flag_softint;
77 #endif
79 BX_CPU_THIS_PTR speculative_rsp = 1;
80 BX_CPU_THIS_PTR prev_rsp = RSP;
82 // interrupt is not RSP safe
83 interrupt(1, 1, 0, 0);
85 BX_CPU_THIS_PTR speculative_rsp = 0;
87 BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
88 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
89 EIP);
92 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT3(bxInstruction_c *i)
94 // INT 3 is not IOPL sensitive
96 #if BX_DEBUGGER
97 BX_CPU_THIS_PTR show_flag |= Flag_softint;
98 #endif
100 BX_CPU_THIS_PTR speculative_rsp = 1;
101 BX_CPU_THIS_PTR prev_rsp = RSP;
103 // interrupt is not RSP safe
104 interrupt(3, 1, 0, 0);
106 BX_CPU_THIS_PTR speculative_rsp = 0;
108 BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
109 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
110 EIP);
114 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c *i)
116 #if BX_DEBUGGER
117 BX_CPU_THIS_PTR show_flag |= Flag_softint;
118 #endif
120 Bit8u vector = i->Ib();
122 BX_CPU_THIS_PTR speculative_rsp = 1;
123 BX_CPU_THIS_PTR prev_rsp = RSP;
125 if (v8086_mode()) {
126 #if BX_SUPPORT_VME
127 if (BX_CPU_THIS_PTR cr4.get_VME())
129 bx_address tr_base = BX_CPU_THIS_PTR tr.cache.u.system.base;
131 Bit16u io_base = system_read_word(tr_base + 102);
132 Bit8u vme_redirection_bitmap = system_read_byte(tr_base + io_base - 32 + (vector >> 3));
134 if (! (vme_redirection_bitmap & (1 << (vector & 7))))
136 // redirect interrupt through virtual-mode idt
137 v86_redirect_interrupt(vector);
138 goto done;
141 #endif
142 // interrupt is not redirected or VME is OFF
143 if (BX_CPU_THIS_PTR get_IOPL() < 3)
145 BX_DEBUG(("INT_Ib(): Interrupt cannot be redirected, generate #GP(0)"));
146 exception(BX_GP_EXCEPTION, 0, 0);
150 #ifdef SHOW_EXIT_STATUS
151 if ((vector == 0x21) && (AH == 0x4c)) {
152 BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL, (unsigned) BX));
154 #endif
156 interrupt(vector, 1, 0, 0);
158 done:
160 BX_CPU_THIS_PTR speculative_rsp = 0;
162 BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
163 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
164 EIP);
167 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INTO(bxInstruction_c *i)
169 #if BX_DEBUGGER
170 BX_CPU_THIS_PTR show_flag |= Flag_softint;
171 #endif
173 if (get_OF()) {
174 BX_CPU_THIS_PTR speculative_rsp = 1;
175 BX_CPU_THIS_PTR prev_rsp = RSP;
177 // interrupt is not RSP safe
178 interrupt(4, 1, 0, 0);
180 BX_CPU_THIS_PTR speculative_rsp = 0;
182 BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
183 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
184 EIP);