- added instructions how to update the online documentation
[bochs-mirror.git] / cpu / data_xfer16.cc
blobd0d68e58d78753ce0ffef66bf9cf4b1ecf5e6916
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: data_xfer16.cc,v 1.63 2008/09/06 21:18:08 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 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RXIw(bxInstruction_c *i)
35 BX_WRITE_16BIT_REG(i->opcodeReg(), i->Iw());
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_RXAX(bxInstruction_c *i)
40 Bit16u temp16 = AX;
41 AX = BX_READ_16BIT_REG(i->opcodeReg());
42 BX_WRITE_16BIT_REG(i->opcodeReg(), temp16);
45 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwGwM(bxInstruction_c *i)
47 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
49 write_virtual_word(i->seg(), eaddr, BX_READ_16BIT_REG(i->nnn()));
52 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GwEwR(bxInstruction_c *i)
54 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
57 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GwEwM(bxInstruction_c *i)
59 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
61 Bit16u val16 = read_virtual_word(i->seg(), eaddr);
62 BX_WRITE_16BIT_REG(i->nnn(), val16);
65 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwSwR(bxInstruction_c *i)
67 /* Illegal to use nonexisting segments */
68 if (i->nnn() >= 6) {
69 BX_INFO(("MOV_EwSw: using of nonexisting segment register %d", i->nnn()));
70 exception(BX_UD_EXCEPTION, 0, 0);
73 Bit16u seg_reg = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value;
75 if (i->os32L()) {
76 BX_WRITE_32BIT_REGZ(i->rm(), seg_reg);
78 else {
79 BX_WRITE_16BIT_REG(i->rm(), seg_reg);
83 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwSwM(bxInstruction_c *i)
85 /* Illegal to use nonexisting segments */
86 if (i->nnn() >= 6) {
87 BX_INFO(("MOV_EwSw: using of nonexisting segment register %d", i->nnn()));
88 exception(BX_UD_EXCEPTION, 0, 0);
91 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
93 Bit16u seg_reg = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value;
94 write_virtual_word(i->seg(), eaddr, seg_reg);
97 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_SwEw(bxInstruction_c *i)
99 Bit16u op2_16;
101 /* Attempt to load CS or nonexisting segment register */
102 if (i->nnn() >= 6 || i->nnn() == BX_SEG_REG_CS) {
103 BX_INFO(("MOV_EwSw: can't use this segment register %d", i->nnn()));
104 exception(BX_UD_EXCEPTION, 0, 0);
107 if (i->modC0()) {
108 op2_16 = BX_READ_16BIT_REG(i->rm());
110 else {
111 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
112 /* pointer, segment address pair */
113 op2_16 = read_virtual_word(i->seg(), eaddr);
116 load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], op2_16);
118 if (i->nnn() == BX_SEG_REG_SS) {
119 // MOV SS inhibits interrupts, debug exceptions and single-step
120 // trap exceptions until the execution boundary following the
121 // next instruction is reached.
122 // Same code as POP_SS()
123 BX_CPU_THIS_PTR inhibit_mask |= BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG;
124 BX_CPU_THIS_PTR async_event = 1;
128 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LEA_GwM(bxInstruction_c *i)
130 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
132 BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) eaddr);
135 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_AXOd(bxInstruction_c *i)
137 AX = read_virtual_word_32(i->seg(), i->Id());
140 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_OdAX(bxInstruction_c *i)
142 write_virtual_word_32(i->seg(), i->Id(), AX);
145 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwIwM(bxInstruction_c *i)
147 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
149 write_virtual_word(i->seg(), eaddr, i->Iw());
152 #if BX_CPU_LEVEL >= 3
153 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GwEbM(bxInstruction_c *i)
155 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
157 Bit8u op2_8 = read_virtual_byte(i->seg(), eaddr);
159 /* zero extend byte op2 into word op1 */
160 BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) op2_8);
163 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GwEbR(bxInstruction_c *i)
165 Bit8u op2_8 = BX_READ_8BIT_REGx(i->rm(), i->extend8bitL());
167 /* zero extend byte op2 into word op1 */
168 BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) op2_8);
171 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbM(bxInstruction_c *i)
173 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
175 Bit8u op2_8 = read_virtual_byte(i->seg(), eaddr);
177 /* sign extend byte op2 into word op1 */
178 BX_WRITE_16BIT_REG(i->nnn(), (Bit8s) op2_8);
181 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbR(bxInstruction_c *i)
183 Bit8u op2_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
185 /* sign extend byte op2 into word op1 */
186 BX_WRITE_16BIT_REG(i->nnn(), (Bit8s) op2_8);
188 #endif
190 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwM(bxInstruction_c *i)
192 Bit16u op1_16, op2_16;
194 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
196 op1_16 = read_RMW_virtual_word(i->seg(), eaddr);
197 op2_16 = BX_READ_16BIT_REG(i->nnn());
199 write_RMW_virtual_word(op2_16);
200 BX_WRITE_16BIT_REG(i->nnn(), op1_16);
203 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwR(bxInstruction_c *i)
205 Bit16u op1_16, op2_16;
207 #if BX_DEBUGGER
208 // Note for mortals: the instruction to trigger this is "xchgw %bx,%bx"
209 if (bx_dbg.magic_break_enabled && (i->nnn() == 3) && (i->rm() == 3))
211 BX_CPU_THIS_PTR magic_break = 1;
212 return;
214 #endif
216 op1_16 = BX_READ_16BIT_REG(i->rm());
217 op2_16 = BX_READ_16BIT_REG(i->nnn());
219 BX_WRITE_16BIT_REG(i->nnn(), op1_16);
220 BX_WRITE_16BIT_REG(i->rm(), op2_16);
223 // Note: CMOV accesses a memory source operand (read), regardless
224 // of whether condition is true or not. Thus, exceptions may
225 // occur even if the MOV does not take place.
227 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVO_GwEwR(bxInstruction_c *i)
229 #if BX_CPU_LEVEL >= 6
230 if (get_OF())
231 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
232 #else
233 BX_INFO(("CMOVO_GwEw: --enable-cpu-level=6 required"));
234 exception(BX_UD_EXCEPTION, 0, 0);
235 #endif
238 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNO_GwEwR(bxInstruction_c *i)
240 #if BX_CPU_LEVEL >= 6
241 if (!get_OF())
242 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
243 #else
244 BX_INFO(("CMOVNO_GwEw: --enable-cpu-level=6 required"));
245 exception(BX_UD_EXCEPTION, 0, 0);
246 #endif
249 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVB_GwEwR(bxInstruction_c *i)
251 #if BX_CPU_LEVEL >= 6
252 if (get_CF())
253 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
254 #else
255 BX_INFO(("CMOVB_GwEw: --enable-cpu-level=6 required"));
256 exception(BX_UD_EXCEPTION, 0, 0);
257 #endif
260 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNB_GwEwR(bxInstruction_c *i)
262 #if BX_CPU_LEVEL >= 6
263 if (!get_CF())
264 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
265 #else
266 BX_INFO(("CMOVNB_GwEw: --enable-cpu-level=6 required"));
267 exception(BX_UD_EXCEPTION, 0, 0);
268 #endif
271 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVZ_GwEwR(bxInstruction_c *i)
273 #if BX_CPU_LEVEL >= 6
274 if (get_ZF())
275 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
276 #else
277 BX_INFO(("CMOVZ_GwEw: --enable-cpu-level=6 required"));
278 exception(BX_UD_EXCEPTION, 0, 0);
279 #endif
282 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNZ_GwEwR(bxInstruction_c *i)
284 #if BX_CPU_LEVEL >= 6
285 if (!get_ZF())
286 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
287 #else
288 BX_INFO(("CMOVNZ_GwEw: --enable-cpu-level=6 required"));
289 exception(BX_UD_EXCEPTION, 0, 0);
290 #endif
293 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVBE_GwEwR(bxInstruction_c *i)
295 #if BX_CPU_LEVEL >= 6
296 if (get_CF() || get_ZF())
297 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
298 #else
299 BX_INFO(("CMOVBE_GwEw: --enable-cpu-level=6 required"));
300 exception(BX_UD_EXCEPTION, 0, 0);
301 #endif
304 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNBE_GwEwR(bxInstruction_c *i)
306 #if BX_CPU_LEVEL >= 6
307 if (! (get_CF() || get_ZF()))
308 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
309 #else
310 BX_INFO(("CMOVNBE_GwEw: --enable-cpu-level=6 required"));
311 exception(BX_UD_EXCEPTION, 0, 0);
312 #endif
315 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVS_GwEwR(bxInstruction_c *i)
317 #if BX_CPU_LEVEL >= 6
318 if (get_SF())
319 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
320 #else
321 BX_INFO(("CMOVS_GwEw: --enable-cpu-level=6 required"));
322 exception(BX_UD_EXCEPTION, 0, 0);
323 #endif
326 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNS_GwEwR(bxInstruction_c *i)
328 #if BX_CPU_LEVEL >= 6
329 if (!get_SF())
330 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
331 #else
332 BX_INFO(("CMOVNS_GwEw: --enable-cpu-level=6 required"));
333 exception(BX_UD_EXCEPTION, 0, 0);
334 #endif
337 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVP_GwEwR(bxInstruction_c *i)
339 #if BX_CPU_LEVEL >= 6
340 if (get_PF())
341 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
342 #else
343 BX_INFO(("CMOVP_GwEw: --enable-cpu-level=6 required"));
344 exception(BX_UD_EXCEPTION, 0, 0);
345 #endif
348 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNP_GwEwR(bxInstruction_c *i)
350 #if BX_CPU_LEVEL >= 6
351 if (!get_PF())
352 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
353 #else
354 BX_INFO(("CMOVNP_GwEw: --enable-cpu-level=6 required"));
355 exception(BX_UD_EXCEPTION, 0, 0);
356 #endif
359 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVL_GwEwR(bxInstruction_c *i)
361 #if BX_CPU_LEVEL >= 6
362 if (getB_SF() != getB_OF())
363 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
364 #else
365 BX_INFO(("CMOVL_GwEw: --enable-cpu-level=6 required"));
366 exception(BX_UD_EXCEPTION, 0, 0);
367 #endif
370 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNL_GwEwR(bxInstruction_c *i)
372 #if BX_CPU_LEVEL >= 6
373 if (getB_SF() == getB_OF())
374 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
375 #else
376 BX_INFO(("CMOVNL_GwEw: --enable-cpu-level=6 required"));
377 exception(BX_UD_EXCEPTION, 0, 0);
378 #endif
381 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVLE_GwEwR(bxInstruction_c *i)
383 #if BX_CPU_LEVEL >= 6
384 if (get_ZF() || (getB_SF() != getB_OF()))
385 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
386 #else
387 BX_INFO(("CMOVLE_GwEw: --enable-cpu-level=6 required"));
388 exception(BX_UD_EXCEPTION, 0, 0);
389 #endif
392 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNLE_GwEwR(bxInstruction_c *i)
394 #if BX_CPU_LEVEL >= 6
395 if (! get_ZF() && (getB_SF() == getB_OF()))
396 BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
397 #else
398 BX_INFO(("CMOVNLE_GwEw: --enable-cpu-level=6 required"));
399 exception(BX_UD_EXCEPTION, 0, 0);
400 #endif