i386: Changed READ/WRITEPORT macros to inline functions to properly support aligned vs. unaligned writes. Fixes regressions in MESS for all drivers using the PCI bus and possibly others. [Dirk Best]

This commit is contained in:
Dirk Best 2011-02-13 16:28:43 +00:00
parent 8a0d451bcc
commit 8c07036b0f
4 changed files with 87 additions and 29 deletions

View File

@ -682,7 +682,7 @@ static void I386OP(imul_r16_rm16_i8)(i386_state *cpustate) // Opcode 0x6b
static void I386OP(in_ax_i8)(i386_state *cpustate) // Opcode 0xe5
{
UINT16 port = FETCH(cpustate);
UINT16 data = READPORT16(port);
UINT16 data = READPORT16(cpustate, port);
REG16(AX) = data;
CYCLES(cpustate,CYCLES_IN_VAR);
}
@ -690,7 +690,7 @@ static void I386OP(in_ax_i8)(i386_state *cpustate) // Opcode 0xe5
static void I386OP(in_ax_dx)(i386_state *cpustate) // Opcode 0xed
{
UINT16 port = REG16(DX);
UINT16 data = READPORT16(port);
UINT16 data = READPORT16(cpustate, port);
REG16(AX) = data;
CYCLES(cpustate,CYCLES_IN);
}
@ -1476,7 +1476,7 @@ static void I386OP(out_ax_i8)(i386_state *cpustate) // Opcode 0xe7
{
UINT16 port = FETCH(cpustate);
UINT16 data = REG16(AX);
WRITEPORT16(port, data);
WRITEPORT16(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT_VAR);
}
@ -1484,7 +1484,7 @@ static void I386OP(out_ax_dx)(i386_state *cpustate) // Opcode 0xef
{
UINT16 port = REG16(DX);
UINT16 data = REG16(AX);
WRITEPORT16(port, data);
WRITEPORT16(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT);
}

View File

@ -667,7 +667,7 @@ static void I386OP(imul_r32_rm32_i8)(i386_state *cpustate) // Opcode 0x6b
static void I386OP(in_eax_i8)(i386_state *cpustate) // Opcode 0xe5
{
UINT16 port = FETCH(cpustate);
UINT32 data = READPORT32(port);
UINT32 data = READPORT32(cpustate, port);
REG32(EAX) = data;
CYCLES(cpustate,CYCLES_IN_VAR);
}
@ -675,7 +675,7 @@ static void I386OP(in_eax_i8)(i386_state *cpustate) // Opcode 0xe5
static void I386OP(in_eax_dx)(i386_state *cpustate) // Opcode 0xed
{
UINT16 port = REG16(DX);
UINT32 data = READPORT32(port);
UINT32 data = READPORT32(cpustate, port);
REG32(EAX) = data;
CYCLES(cpustate,CYCLES_IN);
}
@ -1342,7 +1342,7 @@ static void I386OP(out_eax_i8)(i386_state *cpustate) // Opcode 0xe7
{
UINT16 port = FETCH(cpustate);
UINT32 data = REG32(EAX);
WRITEPORT32(port, data);
WRITEPORT32(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT_VAR);
}
@ -1350,7 +1350,7 @@ static void I386OP(out_eax_dx)(i386_state *cpustate) // Opcode 0xef
{
UINT16 port = REG16(DX);
UINT32 data = REG32(EAX);
WRITEPORT32(port, data);
WRITEPORT32(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT);
}

View File

@ -354,7 +354,7 @@ static void I386OP(cmpsb)(i386_state *cpustate) // Opcode 0xa6
static void I386OP(in_al_i8)(i386_state *cpustate) // Opcode 0xe4
{
UINT16 port = FETCH(cpustate);
UINT8 data = READPORT8(port);
UINT8 data = READPORT8(cpustate, port);
REG8(AL) = data;
CYCLES(cpustate,CYCLES_IN_VAR);
}
@ -362,7 +362,7 @@ static void I386OP(in_al_i8)(i386_state *cpustate) // Opcode 0xe4
static void I386OP(in_al_dx)(i386_state *cpustate) // Opcode 0xec
{
UINT16 port = REG16(DX);
UINT8 data = READPORT8(port);
UINT8 data = READPORT8(cpustate, port);
REG8(AL) = data;
CYCLES(cpustate,CYCLES_IN);
}
@ -876,7 +876,7 @@ static void I386OP(out_al_i8)(i386_state *cpustate) // Opcode 0xe6
{
UINT16 port = FETCH(cpustate);
UINT8 data = REG8(AL);
WRITEPORT8(port, data);
WRITEPORT8(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT_VAR);
}
@ -884,7 +884,7 @@ static void I386OP(out_al_dx)(i386_state *cpustate) // Opcode 0xee
{
UINT16 port = REG16(DX);
UINT8 data = REG8(AL);
WRITEPORT8(port, data);
WRITEPORT8(cpustate, port, data);
CYCLES(cpustate,CYCLES_OUT);
}
@ -934,15 +934,15 @@ static void I386OP(ins_generic)(i386_state *cpustate, int size)
switch(size) {
case 1:
vb = READPORT8(REG16(DX));
vb = READPORT8(cpustate, REG16(DX));
WRITE8(cpustate,ead, vb);
break;
case 2:
vw = READPORT16(REG16(DX));
vw = READPORT16(cpustate, REG16(DX));
WRITE16(cpustate,ead, vw);
break;
case 4:
vd = READPORT32(REG16(DX));
vd = READPORT32(cpustate, REG16(DX));
WRITE32(cpustate,ead, vd);
break;
}
@ -982,15 +982,15 @@ static void I386OP(outs_generic)(i386_state *cpustate, int size)
switch(size) {
case 1:
vb = READ8(cpustate,eas);
WRITEPORT8(REG16(DX), vb);
WRITEPORT8(cpustate, REG16(DX), vb);
break;
case 2:
vw = READ16(cpustate,eas);
WRITEPORT16(REG16(DX), vw);
WRITEPORT16(cpustate, REG16(DX), vw);
break;
case 4:
vd = READ32(cpustate,eas);
WRITEPORT32(REG16(DX), vd);
WRITEPORT32(cpustate, REG16(DX), vd);
break;
}

View File

@ -891,17 +891,75 @@ INLINE void BUMP_DI(i386_state *cpustate,int adjustment)
/***********************************************************************************/
/***********************************************************************************
I/O ACCESS
***********************************************************************************/
INLINE UINT8 READPORT8(i386_state *cpustate, offs_t port)
{
return cpustate->io->read_byte(port);
}
INLINE void WRITEPORT8(i386_state *cpustate, offs_t port, UINT8 value)
{
cpustate->io->write_byte(port, value);
}
INLINE UINT16 READPORT16(i386_state *cpustate, offs_t port)
{
if (port & 1)
{
return READPORT8(cpustate, port) |
(READPORT8(cpustate, port + 1) << 8);
}
else
{
return cpustate->io->read_word(port);
}
}
INLINE void WRITEPORT16(i386_state *cpustate, offs_t port, UINT16 value)
{
if (port & 1)
{
WRITEPORT8(cpustate, port, value & 0xff);
WRITEPORT8(cpustate, port + 1, (value >> 8) & 0xff);
}
else
{
cpustate->io->write_word(port, value);
}
}
INLINE UINT32 READPORT32(i386_state *cpustate, offs_t port)
{
if (port & 3)
{
return READPORT8(cpustate, port) |
(READPORT8(cpustate, port + 1) << 8) |
(READPORT8(cpustate, port + 2) << 16) |
(READPORT8(cpustate, port + 3) << 24);
}
else
{
return cpustate->io->read_dword(port);
}
}
INLINE void WRITEPORT32(i386_state *cpustate, offs_t port, UINT32 value)
{
if (port & 3)
{
WRITEPORT8(cpustate, port, value & 0xff);
WRITEPORT8(cpustate, port + 1, (value >> 8) & 0xff);
WRITEPORT8(cpustate, port + 2, (value >> 16) & 0xff);
WRITEPORT8(cpustate, port + 3, (value >> 24) & 0xff);
}
else
{
cpustate->io->write_dword(port, value);
}
}
#define READPORT8(port) (cpustate->io->read_byte(port))
#define READPORT16(port) (READPORT8(port) | (READPORT8(port+1) << 8))
#define READPORT32(port) (READPORT8(port) | (READPORT8(port+1) << 8) | (READPORT8(port+2) << 16) | (READPORT8(port+3) << 24))
#define WRITEPORT8(port, value) (cpustate->io->write_byte(port, value))
#define WRITEPORT16(port, value) WRITEPORT8(port,value & 0xff); \
(WRITEPORT8(port+1,(value >> 8) & 0xff))
#define WRITEPORT32(port, value) WRITEPORT8(port,value & 0xff); \
(WRITEPORT8(port+1,(value >> 8) & 0xff)); \
(WRITEPORT8(port+2,(value >> 16) & 0xff)); \
(WRITEPORT8(port+3,(value >> 24) & 0xff))
#endif /* __I386_H__ */