1 /////////////////////////////////////////////////////////////////////////
2 // $Id: io.cc,v 1.69 2008/12/11 21:19:38 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
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
27 /////////////////////////////////////////////////////////////////////////
29 #define NEED_CPU_REG_SHORTCUTS 1
32 #define LOG_THIS BX_CPU_THIS_PTR
34 #include "iodev/iodev.h"
36 #if BX_SUPPORT_X86_64==0
37 // Make life easier for merging cpu64 and cpu32 code.
45 // Repeat Speedups methods
48 #if BX_SupportRepeatSpeedups
49 Bit32u
BX_CPU_C::FastRepINSW(bxInstruction_c
*i
, bx_address dstOff
, Bit16u port
, Bit32u wordCount
)
52 signed int pointerDelta
;
56 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
58 bx_segment_reg_t
*dstSegPtr
= &BX_CPU_THIS_PTR sregs
[BX_SEG_REG_ES
];
59 if (!(dstSegPtr
->cache
.valid
& SegAccessWOK
))
61 if ((dstOff
| 0xfff) > dstSegPtr
->cache
.u
.segment
.limit_scaled
)
64 bx_address laddrDst
= BX_CPU_THIS_PTR
get_laddr(BX_SEG_REG_ES
, dstOff
);
65 // check that the address is word aligned
66 if (laddrDst
& 1) return 0;
68 hostAddrDst
= v2h_write_byte(laddrDst
, BX_CPU_THIS_PTR user_pl
);
69 // Check that native host access was not vetoed for that page
70 if (!hostAddrDst
) return 0;
72 // See how many words can fit in the rest of this page.
73 if (BX_CPU_THIS_PTR
get_DF()) {
75 // 1st word must cannot cross page boundary because it is word aligned
76 wordsFitDst
= (2 + (PAGE_OFFSET(laddrDst
))) >> 1;
81 wordsFitDst
= (0x1000 - PAGE_OFFSET(laddrDst
)) >> 1;
85 // Restrict word count to the number that will fit in this page.
86 if (wordCount
> wordsFitDst
)
87 wordCount
= wordsFitDst
;
89 // If after all the restrictions, there is anything left to do...
91 for (count
=0; count
<wordCount
; ) {
92 bx_devices
.bulkIOQuantumsTransferred
= 0;
93 if (BX_CPU_THIS_PTR
get_DF()==0) { // Only do accel for DF=0
94 bx_devices
.bulkIOHostAddr
= hostAddrDst
;
95 bx_devices
.bulkIOQuantumsRequested
= (wordCount
- count
);
98 bx_devices
.bulkIOQuantumsRequested
= 0;
99 Bit16u temp16
= BX_INP(port
, 2);
100 if (bx_devices
.bulkIOQuantumsTransferred
) {
101 hostAddrDst
= bx_devices
.bulkIOHostAddr
;
102 count
+= bx_devices
.bulkIOQuantumsTransferred
;
105 WriteHostWordToLittleEndian(hostAddrDst
, temp16
);
106 hostAddrDst
+= pointerDelta
;
109 // Terminate early if there was an event.
110 if (BX_CPU_THIS_PTR async_event
) break;
113 // Reset for next non-bulk IO
114 bx_devices
.bulkIOQuantumsRequested
= 0;
122 Bit32u
BX_CPU_C::FastRepOUTSW(bxInstruction_c
*i
, unsigned srcSeg
, bx_address srcOff
, Bit16u port
, Bit32u wordCount
)
125 signed int pointerDelta
;
129 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
131 bx_segment_reg_t
*srcSegPtr
= &BX_CPU_THIS_PTR sregs
[srcSeg
];
132 if (!(srcSegPtr
->cache
.valid
& SegAccessROK
))
134 if ((srcOff
| 0xfff) > srcSegPtr
->cache
.u
.segment
.limit_scaled
)
137 bx_address laddrSrc
= BX_CPU_THIS_PTR
get_laddr(srcSeg
, srcOff
);
138 // check that the address is word aligned
139 if (laddrSrc
& 1) return 0;
141 hostAddrSrc
= v2h_read_byte(laddrSrc
, BX_CPU_THIS_PTR user_pl
);
143 // Check that native host access was not vetoed for that page
144 if (!hostAddrSrc
) return 0;
146 // See how many words can fit in the rest of this page.
147 if (BX_CPU_THIS_PTR
get_DF()) {
149 // 1st word must cannot cross page boundary because it is word aligned
150 wordsFitSrc
= (2 + (PAGE_OFFSET(laddrSrc
))) >> 1;
151 pointerDelta
= (unsigned) -2;
155 wordsFitSrc
= (0x1000 - PAGE_OFFSET(laddrSrc
)) >> 1;
159 // Restrict word count to the number that will fit in this page.
160 if (wordCount
> wordsFitSrc
)
161 wordCount
= wordsFitSrc
;
163 // If after all the restrictions, there is anything left to do...
165 for (count
=0; count
<wordCount
; ) {
166 bx_devices
.bulkIOQuantumsTransferred
= 0;
167 if (BX_CPU_THIS_PTR
get_DF()==0) { // Only do accel for DF=0
168 bx_devices
.bulkIOHostAddr
= hostAddrSrc
;
169 bx_devices
.bulkIOQuantumsRequested
= (wordCount
- count
);
172 bx_devices
.bulkIOQuantumsRequested
= 0;
174 ReadHostWordFromLittleEndian(hostAddrSrc
, temp16
);
175 BX_OUTP(port
, temp16
, 2);
176 if (bx_devices
.bulkIOQuantumsTransferred
) {
177 hostAddrSrc
= bx_devices
.bulkIOHostAddr
;
178 count
+= bx_devices
.bulkIOQuantumsTransferred
;
181 hostAddrSrc
+= pointerDelta
;
184 // Terminate early if there was an event.
185 if (BX_CPU_THIS_PTR async_event
) break;
188 // Reset for next non-bulk IO
189 bx_devices
.bulkIOQuantumsRequested
= 0;
203 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_INSB_YbDX(bxInstruction_c
*i
)
205 #if BX_SUPPORT_X86_64
207 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSB64_YbDX
);
212 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSB32_YbDX
);
213 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI
); // always clear upper part of RDI
216 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSB16_YbDX
);
220 // 16-bit address size
221 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSB16_YbDX(bxInstruction_c
*i
)
223 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
224 BX_DEBUG(("INSB_YbDX: I/O access not allowed !"));
225 exception(BX_GP_EXCEPTION
, 0, 0);
228 // trigger any segment or page faults before reading from IO port
229 Bit8u value8
= read_RMW_virtual_byte_32(BX_SEG_REG_ES
, DI
);
231 value8
= BX_INP(DX
, 1);
233 write_RMW_virtual_byte(value8
);
235 if (BX_CPU_THIS_PTR
get_DF())
241 // 32-bit address size
242 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSB32_YbDX(bxInstruction_c
*i
)
244 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
245 BX_DEBUG(("INSB_YbDX: I/O access not allowed !"));
246 exception(BX_GP_EXCEPTION
, 0, 0);
249 // trigger any segment or page faults before reading from IO port
250 Bit8u value8
= read_RMW_virtual_byte_32(BX_SEG_REG_ES
, EDI
);
252 value8
= BX_INP(DX
, 1);
254 /* no seg override possible */
255 write_RMW_virtual_byte(value8
);
257 if (BX_CPU_THIS_PTR
get_DF()) {
265 #if BX_SUPPORT_X86_64
267 // 64-bit address size
268 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSB64_YbDX(bxInstruction_c
*i
)
270 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
271 BX_DEBUG(("INSB_YbDX: I/O access not allowed !"));
272 exception(BX_GP_EXCEPTION
, 0, 0);
275 // trigger any segment or page faults before reading from IO port
276 Bit8u value8
= read_RMW_virtual_byte_64(BX_SEG_REG_ES
, RDI
);
278 value8
= BX_INP(DX
, 1);
280 write_RMW_virtual_byte(value8
);
282 if (BX_CPU_THIS_PTR
get_DF())
290 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_INSW_YwDX(bxInstruction_c
*i
)
292 #if BX_SUPPORT_X86_64
294 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSW64_YwDX
);
299 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSW32_YwDX
);
300 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI
); // always clear upper part of RDI
303 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSW16_YwDX
);
307 // 16-bit operand size, 16-bit address size
308 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSW16_YwDX(bxInstruction_c
*i
)
310 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
311 BX_DEBUG(("INSW16_YwDX: I/O access not allowed !"));
312 exception(BX_GP_EXCEPTION
, 0, 0);
315 // trigger any segment or page faults before reading from IO port
316 Bit16u value16
= read_RMW_virtual_word_32(BX_SEG_REG_ES
, DI
);
318 value16
= BX_INP(DX
, 2);
320 write_RMW_virtual_word(value16
);
322 if (BX_CPU_THIS_PTR
get_DF())
328 // 16-bit operand size, 32-bit address size
329 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSW32_YwDX(bxInstruction_c
*i
)
335 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
336 BX_DEBUG(("INSW32_YwDX: I/O access not allowed !"));
337 exception(BX_GP_EXCEPTION
, 0, 0);
340 #if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
341 /* If conditions are right, we can transfer IO to physical memory
342 * in a batch, rather than one instruction at a time.
344 if (i
->repUsedL() && !BX_CPU_THIS_PTR async_event
)
346 Bit32u wordCount
= ECX
;
347 BX_ASSERT(wordCount
> 0);
348 wordCount
= FastRepINSW(i
, edi
, DX
, wordCount
);
350 // Decrement the ticks count by the number of iterations, minus
351 // one, since the main cpu loop will decrement one. Also,
352 // the count is predecremented before examined, so defintely
353 // don't roll it under zero.
354 BX_TICKN(wordCount
-1);
355 RCX
= ECX
- (wordCount
-1);
356 incr
= wordCount
<< 1; // count * 2.
359 // trigger any segment or page faults before reading from IO port
360 value16
= read_RMW_virtual_word_32(BX_SEG_REG_ES
, edi
);
362 value16
= BX_INP(DX
, 2);
364 write_RMW_virtual_word(value16
);
370 // trigger any segment or page faults before reading from IO port
371 value16
= read_RMW_virtual_word_32(BX_SEG_REG_ES
, edi
);
373 value16
= BX_INP(DX
, 2);
375 write_RMW_virtual_word(value16
);
378 if (BX_CPU_THIS_PTR
get_DF())
384 #if BX_SUPPORT_X86_64
386 // 16-bit operand size, 64-bit address size
387 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSW64_YwDX(bxInstruction_c
*i
)
389 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
390 BX_DEBUG(("INSW64_YwDX: I/O access not allowed !"));
391 exception(BX_GP_EXCEPTION
, 0, 0);
394 // trigger any segment or page faults before reading from IO port
395 Bit16u value16
= read_RMW_virtual_word_64(BX_SEG_REG_ES
, RDI
);
397 value16
= BX_INP(DX
, 2);
399 write_RMW_virtual_word(value16
);
401 if (BX_CPU_THIS_PTR
get_DF())
409 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_INSD_YdDX(bxInstruction_c
*i
)
411 #if BX_SUPPORT_X86_64
413 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSD64_YdDX
);
418 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSD32_YdDX
);
419 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI
); // always clear upper part of RDI
422 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::INSD16_YdDX
);
426 // 32-bit operand size, 16-bit address size
427 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSD16_YdDX(bxInstruction_c
*i
)
429 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
430 BX_DEBUG(("INSD16_YdDX: I/O access not allowed !"));
431 exception(BX_GP_EXCEPTION
, 0, 0);
434 // trigger any segment or page faults before reading from IO port
435 Bit32u value32
= read_RMW_virtual_dword_32(BX_SEG_REG_ES
, DI
);
437 value32
= BX_INP(DX
, 4);
439 write_RMW_virtual_dword(value32
);
441 if (BX_CPU_THIS_PTR
get_DF())
447 // 32-bit operand size, 32-bit address size
448 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSD32_YdDX(bxInstruction_c
*i
)
450 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
451 BX_DEBUG(("INSD32_YdDX: I/O access not allowed !"));
452 exception(BX_GP_EXCEPTION
, 0, 0);
455 // trigger any segment or page faults before reading from IO port
456 Bit32u value32
= read_RMW_virtual_dword_32(BX_SEG_REG_ES
, EDI
);
458 value32
= BX_INP(DX
, 4);
460 write_RMW_virtual_dword(value32
);
462 if (BX_CPU_THIS_PTR
get_DF())
468 #if BX_SUPPORT_X86_64
470 // 32-bit operand size, 64-bit address size
471 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSD64_YdDX(bxInstruction_c
*i
)
473 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
474 BX_DEBUG(("INSD64_YdDX: I/O access not allowed !"));
475 exception(BX_GP_EXCEPTION
, 0, 0);
478 // trigger any segment or page faults before reading from IO port
479 Bit32u value32
= read_RMW_virtual_dword_64(BX_SEG_REG_ES
, RDI
);
481 value32
= BX_INP(DX
, 4);
483 write_RMW_virtual_dword(value32
);
485 if (BX_CPU_THIS_PTR
get_DF())
497 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_OUTSB_DXXb(bxInstruction_c
*i
)
499 #if BX_SUPPORT_X86_64
501 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSB64_DXXb
);
506 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSB32_DXXb
);
507 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI
); // always clear upper part of RSI
510 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSB16_DXXb
);
514 // 16-bit address size
515 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSB16_DXXb(bxInstruction_c
*i
)
517 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
518 BX_DEBUG(("OUTSB16_DXXb: I/O access not allowed !"));
519 exception(BX_GP_EXCEPTION
, 0, 0);
522 Bit8u value8
= read_virtual_byte_32(i
->seg(), SI
);
523 BX_OUTP(DX
, value8
, 1);
525 if (BX_CPU_THIS_PTR
get_DF())
531 // 32-bit address size
532 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSB32_DXXb(bxInstruction_c
*i
)
534 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
535 BX_DEBUG(("OUTSB32_DXXb: I/O access not allowed !"));
536 exception(BX_GP_EXCEPTION
, 0, 0);
539 Bit8u value8
= read_virtual_byte(i
->seg(), ESI
);
540 BX_OUTP(DX
, value8
, 1);
542 if (BX_CPU_THIS_PTR
get_DF())
548 #if BX_SUPPORT_X86_64
550 // 64-bit address size
551 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSB64_DXXb(bxInstruction_c
*i
)
553 if (! BX_CPU_THIS_PTR
allow_io(DX
, 1)) {
554 BX_DEBUG(("OUTSB64_DXXb: I/O access not allowed !"));
555 exception(BX_GP_EXCEPTION
, 0, 0);
558 Bit8u value8
= read_virtual_byte_64(i
->seg(), RSI
);
559 BX_OUTP(DX
, value8
, 1);
561 if (BX_CPU_THIS_PTR
get_DF())
569 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_OUTSW_DXXw(bxInstruction_c
*i
)
571 #if BX_SUPPORT_X86_64
573 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSW64_DXXw
);
578 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSW32_DXXw
);
579 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI
); // always clear upper part of RSI
582 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSW16_DXXw
);
586 // 16-bit operand size, 16-bit address size
587 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSW16_DXXw(bxInstruction_c
*i
)
589 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
590 BX_DEBUG(("OUTSW16_DXXw: I/O access not allowed !"));
591 exception(BX_GP_EXCEPTION
, 0, 0);
594 Bit16u value16
= read_virtual_word_32(i
->seg(), SI
);
595 BX_OUTP(DX
, value16
, 2);
597 if (BX_CPU_THIS_PTR
get_DF())
603 // 16-bit operand size, 32-bit address size
604 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSW32_DXXw(bxInstruction_c
*i
)
606 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
607 BX_DEBUG(("OUTSW32_DXXw: I/O access not allowed !"));
608 exception(BX_GP_EXCEPTION
, 0, 0);
615 #if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
616 /* If conditions are right, we can transfer IO to physical memory
617 * in a batch, rather than one instruction at a time.
619 if (i
->repUsedL() && !BX_CPU_THIS_PTR async_event
) {
620 Bit32u wordCount
= ECX
;
621 wordCount
= FastRepOUTSW(i
, i
->seg(), esi
, DX
, wordCount
);
623 // Decrement eCX. Note, the main loop will decrement 1 also, so
624 // decrement by one less than expected, like the case above.
625 BX_TICKN(wordCount
-1); // Main cpu loop also decrements one more.
626 RCX
= ECX
- (wordCount
-1);
627 incr
= wordCount
<< 1; // count * 2.
630 value16
= read_virtual_word(i
->seg(), esi
);
631 BX_OUTP(DX
, value16
, 2);
637 value16
= read_virtual_word(i
->seg(), esi
);
638 BX_OUTP(DX
, value16
, 2);
641 if (BX_CPU_THIS_PTR
get_DF())
647 #if BX_SUPPORT_X86_64
649 // 16-bit operand size, 64-bit address size
650 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSW64_DXXw(bxInstruction_c
*i
)
652 if (! BX_CPU_THIS_PTR
allow_io(DX
, 2)) {
653 BX_DEBUG(("OUTSW64_DXXw: I/O access not allowed !"));
654 exception(BX_GP_EXCEPTION
, 0, 0);
657 Bit16u value16
= read_virtual_word_64(i
->seg(), RSI
);
658 BX_OUTP(DX
, value16
, 2);
660 if (BX_CPU_THIS_PTR
get_DF())
668 void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_OUTSD_DXXd(bxInstruction_c
*i
)
670 #if BX_SUPPORT_X86_64
672 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSD64_DXXd
);
677 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSD32_DXXd
);
678 BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI
); // always clear upper part of RSI
681 BX_CPU_THIS_PTR
repeat(i
, &BX_CPU_C::OUTSD16_DXXd
);
685 // 32-bit operand size, 16-bit address size
686 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSD16_DXXd(bxInstruction_c
*i
)
688 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
689 BX_DEBUG(("OUTSD16_DXXd: I/O access not allowed !"));
690 exception(BX_GP_EXCEPTION
, 0, 0);
693 Bit32u value32
= read_virtual_dword_32(i
->seg(), SI
);
694 BX_OUTP(DX
, value32
, 4);
696 if (BX_CPU_THIS_PTR
get_DF())
702 // 32-bit operand size, 32-bit address size
703 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSD32_DXXd(bxInstruction_c
*i
)
705 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
706 BX_DEBUG(("OUTSD32_DXXd: I/O access not allowed !"));
707 exception(BX_GP_EXCEPTION
, 0, 0);
710 Bit32u value32
= read_virtual_dword(i
->seg(), ESI
);
711 BX_OUTP(DX
, value32
, 4);
713 if (BX_CPU_THIS_PTR
get_DF())
719 #if BX_SUPPORT_X86_64
721 // 32-bit operand size, 64-bit address size
722 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSD64_DXXd(bxInstruction_c
*i
)
724 if (! BX_CPU_THIS_PTR
allow_io(DX
, 4)) {
725 BX_DEBUG(("OUTSD64_DXXd: I/O access not allowed !"));
726 exception(BX_GP_EXCEPTION
, 0, 0);
729 Bit32u value32
= read_virtual_dword_64(i
->seg(), RSI
);
730 BX_OUTP(DX
, value32
, 4);
732 if (BX_CPU_THIS_PTR
get_DF())
741 // non repeatable IN/OUT methods
744 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_ALIb(bxInstruction_c
*i
)
746 AL
= BX_CPU_THIS_PTR
inp8(i
->Ib());
749 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_AXIb(bxInstruction_c
*i
)
751 AX
= BX_CPU_THIS_PTR
inp16(i
->Ib());
754 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_EAXIb(bxInstruction_c
*i
)
756 RAX
= BX_CPU_THIS_PTR
inp32(i
->Ib());
759 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbAL(bxInstruction_c
*i
)
761 BX_CPU_THIS_PTR
outp8(i
->Ib(), AL
);
764 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbAX(bxInstruction_c
*i
)
766 BX_CPU_THIS_PTR
outp16(i
->Ib(), AX
);
769 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbEAX(bxInstruction_c
*i
)
771 BX_CPU_THIS_PTR
outp32(i
->Ib(), EAX
);
774 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_ALDX(bxInstruction_c
*i
)
776 AL
= BX_CPU_THIS_PTR
inp8(DX
);
779 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_AXDX(bxInstruction_c
*i
)
781 AX
= BX_CPU_THIS_PTR
inp16(DX
);
784 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_EAXDX(bxInstruction_c
*i
)
786 RAX
= BX_CPU_THIS_PTR
inp32(DX
);
789 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXAL(bxInstruction_c
*i
)
791 BX_CPU_THIS_PTR
outp8(DX
, AL
);
794 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXAX(bxInstruction_c
*i
)
796 BX_CPU_THIS_PTR
outp16(DX
, AX
);
799 void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXEAX(bxInstruction_c
*i
)
801 BX_CPU_THIS_PTR
outp32(DX
, EAX
);