daf2a9fb55
going on when someone sends in a modified file.
386 lines
7.0 KiB
C++
386 lines
7.0 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id: io.cc,v 1.5 2001-10-03 13:10:37 bdenney Exp $
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
|
//
|
|
// MandrakeSoft S.A.
|
|
// 43, rue d'Aboukir
|
|
// 75002 Paris - France
|
|
// http://www.linux-mandrake.com/
|
|
// http://www.mandrakesoft.com/
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define NEED_CPU_REG_SHORTCUTS 1
|
|
#include "bochs.h"
|
|
#define LOG_THIS BX_CPU_THIS_PTR
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
BX_CPU_C::INSB_YbDX(BxInstruction_t *i)
|
|
{
|
|
Bit8u value8=0;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (i->as_32) {
|
|
// Write a zero to memory, to trigger any segment or page
|
|
// faults before reading from IO port.
|
|
write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
|
|
|
|
value8 = BX_INP(DX, 1);
|
|
|
|
/* no seg override possible */
|
|
write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
|
|
|
|
if (BX_CPU_THIS_PTR eflags.df) {
|
|
EDI = EDI - 1;
|
|
}
|
|
else {
|
|
EDI = EDI + 1;
|
|
}
|
|
}
|
|
else {
|
|
// Write a zero to memory, to trigger any segment or page
|
|
// faults before reading from IO port.
|
|
write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
|
|
|
|
value8 = BX_INP(DX, 1);
|
|
|
|
/* no seg override possible */
|
|
write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
|
|
|
|
if (BX_CPU_THIS_PTR eflags.df) {
|
|
DI = DI - 1;
|
|
}
|
|
else {
|
|
DI = DI + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::INSW_YvDX(BxInstruction_t *i)
|
|
// input word/doubleword from port to string
|
|
{
|
|
Bit32u edi;
|
|
unsigned int incr;
|
|
|
|
if (i->as_32)
|
|
edi = EDI;
|
|
else
|
|
edi = DI;
|
|
|
|
if (i->os_32) {
|
|
Bit32u value32=0;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Write a zero to memory, to trigger any segment or page
|
|
// faults before reading from IO port.
|
|
write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
|
|
|
|
value32 = BX_INP(DX, 4);
|
|
|
|
/* no seg override allowed */
|
|
write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
|
|
incr = 4;
|
|
}
|
|
else {
|
|
Bit16u value16=0;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Write a zero to memory, to trigger any segment or page
|
|
// faults before reading from IO port.
|
|
write_virtual_word(BX_SEG_REG_ES, edi, &value16);
|
|
|
|
value16 = BX_INP(DX, 2);
|
|
|
|
/* no seg override allowed */
|
|
write_virtual_word(BX_SEG_REG_ES, edi, &value16);
|
|
incr = 2;
|
|
}
|
|
|
|
if (i->as_32) {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
EDI = EDI - incr;
|
|
else
|
|
EDI = EDI + incr;
|
|
}
|
|
else {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
DI = DI - incr;
|
|
else
|
|
DI = DI + incr;
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUTSB_DXXb(BxInstruction_t *i)
|
|
{
|
|
unsigned seg;
|
|
Bit8u value8;
|
|
Bit32u esi;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (!BX_NULL_SEG_REG(i->seg)) {
|
|
seg = i->seg;
|
|
}
|
|
else {
|
|
seg = BX_SEG_REG_DS;
|
|
}
|
|
|
|
if (i->as_32)
|
|
esi = ESI;
|
|
else
|
|
esi = SI;
|
|
|
|
read_virtual_byte(seg, esi, &value8);
|
|
|
|
BX_OUTP(DX, value8, 1);
|
|
|
|
if (i->as_32) {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
ESI -= 1;
|
|
else
|
|
ESI += 1;
|
|
}
|
|
else {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
SI -= 1;
|
|
else
|
|
SI += 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUTSW_DXXv(BxInstruction_t *i)
|
|
// output word/doubleword string to port
|
|
{
|
|
unsigned seg;
|
|
Bit32u esi;
|
|
unsigned int incr;
|
|
|
|
if (!BX_NULL_SEG_REG(i->seg)) {
|
|
seg = i->seg;
|
|
}
|
|
else {
|
|
seg = BX_SEG_REG_DS;
|
|
}
|
|
|
|
if (i->as_32)
|
|
esi = ESI;
|
|
else
|
|
esi = SI;
|
|
|
|
if (i->os_32) {
|
|
Bit32u value32;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
read_virtual_dword(seg, esi, &value32);
|
|
|
|
BX_OUTP(DX, value32, 4);
|
|
incr = 4;
|
|
}
|
|
else {
|
|
Bit16u value16;
|
|
|
|
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
|
|
if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
}
|
|
|
|
read_virtual_word(seg, esi, &value16);
|
|
|
|
BX_OUTP(DX, value16, 2);
|
|
incr = 2;
|
|
}
|
|
|
|
if (i->as_32) {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
ESI = ESI - incr;
|
|
else
|
|
ESI = ESI + incr;
|
|
}
|
|
else {
|
|
if (BX_CPU_THIS_PTR eflags.df)
|
|
SI = SI - incr;
|
|
else
|
|
SI = SI + incr;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
BX_CPU_C::IN_ALIb(BxInstruction_t *i)
|
|
{
|
|
Bit8u al, imm8;
|
|
|
|
imm8 = i->Ib;
|
|
|
|
al = BX_CPU_THIS_PTR inp8(imm8);
|
|
|
|
AL = al;
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::IN_eAXIb(BxInstruction_t *i)
|
|
{
|
|
Bit8u imm8;
|
|
|
|
|
|
imm8 = i->Ib;
|
|
|
|
#if BX_CPU_LEVEL > 2
|
|
if (i->os_32) {
|
|
Bit32u eax;
|
|
|
|
eax = BX_CPU_THIS_PTR inp32(imm8);
|
|
EAX = eax;
|
|
}
|
|
else
|
|
#endif /* BX_CPU_LEVEL > 2 */
|
|
{
|
|
Bit16u ax;
|
|
|
|
ax = BX_CPU_THIS_PTR inp16(imm8);
|
|
AX = ax;
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUT_IbAL(BxInstruction_t *i)
|
|
{
|
|
Bit8u al, imm8;
|
|
|
|
imm8 = i->Ib;
|
|
|
|
al = AL;
|
|
|
|
BX_CPU_THIS_PTR outp8(imm8, al);
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUT_IbeAX(BxInstruction_t *i)
|
|
{
|
|
Bit8u imm8;
|
|
|
|
imm8 = i->Ib;
|
|
|
|
#if BX_CPU_LEVEL > 2
|
|
if (i->os_32) {
|
|
BX_CPU_THIS_PTR outp32(imm8, EAX);
|
|
}
|
|
else
|
|
#endif /* BX_CPU_LEVEL > 2 */
|
|
{
|
|
BX_CPU_THIS_PTR outp16(imm8, AX);
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::IN_ALDX(BxInstruction_t *i)
|
|
{
|
|
Bit8u al;
|
|
|
|
al = BX_CPU_THIS_PTR inp8(DX);
|
|
|
|
AL = al;
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::IN_eAXDX(BxInstruction_t *i)
|
|
{
|
|
#if BX_CPU_LEVEL > 2
|
|
if (i->os_32) {
|
|
Bit32u eax;
|
|
|
|
eax = BX_CPU_THIS_PTR inp32(DX);
|
|
EAX = eax;
|
|
}
|
|
else
|
|
#endif /* BX_CPU_LEVEL > 2 */
|
|
{
|
|
Bit16u ax;
|
|
|
|
ax = BX_CPU_THIS_PTR inp16(DX);
|
|
AX = ax;
|
|
}
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUT_DXAL(BxInstruction_t *i)
|
|
{
|
|
Bit16u dx;
|
|
Bit8u al;
|
|
|
|
dx = DX;
|
|
al = AL;
|
|
|
|
BX_CPU_THIS_PTR outp8(dx, al);
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::OUT_DXeAX(BxInstruction_t *i)
|
|
{
|
|
Bit16u dx;
|
|
|
|
dx = DX;
|
|
|
|
#if BX_CPU_LEVEL > 2
|
|
if (i->os_32) {
|
|
BX_CPU_THIS_PTR outp32(dx, EAX);
|
|
}
|
|
else
|
|
#endif /* BX_CPU_LEVEL > 2 */
|
|
{
|
|
BX_CPU_THIS_PTR outp16(dx, AX);
|
|
}
|
|
}
|