#ifndef __LIB_I386_PRIV_H__
#define __LIB_I386_PRIV_H__
+#include "../../../common.h"
+
+#define INLINE inline
// Translation intentions
const int TRANSLATE_TYPE_MASK = 0x03; // read write or fetch
//#define DEBUG_MISSING_OPCODE
-#define I386OP(XX) i386_##XX
-#define I486OP(XX) i486_##XX
-#define PENTIUMOP(XX) pentium_##XX
-#define MMXOP(XX) mmx_##XX
-#define SSEOP(XX) sse_##XX
+#define I386OP(XX) I386_OPS_BASE::i386_##XX
+#define I486OP(XX) I386_OPS_BASE::i486_##XX
+#define PENTIUMOP(XX) I386_OPS_BASE::pentium_##XX
+#define MMXOP(XX) I386_OPS_BASE::mmx_##XX
+#define SSEOP(XX) I386_OPS_BASE::sse_##XX
+
+#define I386OP_D(XX) i386_##XX
+#define I486OP_D(XX) i486_##XX
+#define PENTIUMOP_D(XX) pentium_##XX
+#define MMXOP_D(XX) mmx_##XX
+#define SSEOP_D(XX) sse_##XX
//extern int i386_dasm_one(_TCHAR *buffer, UINT32 pc, const UINT8 *oprom, int mode);
#define SWITCH_ENDIAN_32(x) (((((x) << 24) & (0xff << 24)) | (((x) << 8) & (0xff << 16)) | (((x) >> 8) & (0xff << 8)) | (((x) >> 24) & (0xff << 0))))
-/***********************************************************************************/
-
-INLINE UINT32 I386_OPS_BASE::i386_translate(int segment, UINT32 ip, int rwn)
-{
- // TODO: segment limit access size, execution permission, handle exception thrown from exception handler
- if(PROTECTED_MODE && !V8086_MODE && (rwn != -1))
- {
- if(!(cpustate->sreg[segment].valid))
- FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
- if(i386_limit_check(segment, ip))
- FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
- if((rwn == 0) && ((cpustate->sreg[segment].flags & 8) && !(cpustate->sreg[segment].flags & 2)))
- FAULT_THROW(FAULT_GP, 0);
- if((rwn == 1) && ((cpustate->sreg[segment].flags & 8) || !(cpustate->sreg[segment].flags & 2)))
- FAULT_THROW(FAULT_GP, 0);
- }
- return cpustate->sreg[segment].base + ip;
-}
-
-#define VTLB_FLAG_DIRTY 0x100
-
-INLINE I386_OPS_BASE::vtlb_entry get_permissions(UINT32 pte, int wp)
-{
- vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0);
- if(!wp)
- ret |= VTLB_WRITE_ALLOWED;
- if(pte & 2)
- ret |= VTLB_WRITE_ALLOWED | ((pte & 4) ? VTLB_USER_WRITE_ALLOWED : 0);
- return ret;
-}
-
-//#define TEST_TLB
-
-INLINE int I386_OPS_BASE::translate_address(int pl, int type, UINT32 *address, UINT32 *error)
-{
- if(!(cpustate->cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
- return TRUE;
-
- const vtlb_entry *table = vtlb_table(cpustate->vtlb);
- UINT32 index = *address >> 12;
- vtlb_entry entry = table[index];
- if(type == TRANSLATE_FETCH)
- type = TRANSLATE_READ;
- if(pl == 3)
- type |= TRANSLATE_USER_MASK;
-#ifdef TEST_TLB
- UINT32 test_addr = *address;
-#endif
-
- if(!(entry & VTLB_FLAG_VALID) || ((type & TRANSLATE_WRITE) && !(entry & VTLB_FLAG_DIRTY)))
- {
- if(!i386_translate_address( type, address, &entry))
- {
- *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0);
- if(entry)
- *error |= 1;
- return FALSE;
- }
- vtlb_dynload(cpustate->vtlb, index, *address, entry);
- return TRUE;
- }
- if(!(entry & (1 << type)))
- {
- *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0) | 1;
- return FALSE;
- }
- *address = (entry & 0xfffff000) | (*address & 0xfff);
-#ifdef TEST_TLB
- int test_ret = i386_translate_address( type | TRANSLATE_DEBUG_MASK, &test_addr, NULL);
- if(!test_ret || (test_addr != *address))
- logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, cpustate->pc);
-#endif
- return TRUE;
-}
-
-INLINE void I386_OPS_BASE::CHANGE_PC(UINT32 pc)
-{
- cpustate->pc = i386_translate( CS, pc, -1 );
-}
-
-INLINE void I386_OPS_BASE::NEAR_BRANCH(INT32 offs)
-{
- /* TODO: limit */
- cpustate->eip += offs;
- cpustate->pc += offs;
-}
-
-INLINE UINT8 I386_OPS_BASE::FETCH()
-{
- UINT8 value;
- UINT32 address = cpustate->pc, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
-
- value = cpustate->program->read_data8(address & cpustate->a20_mask);
-#ifdef DEBUG_MISSING_OPCODE
- cpustate->opcode_bytes[cpustate->opcode_bytes_length] = value;
- cpustate->opcode_bytes_length = (cpustate->opcode_bytes_length + 1) & 15;
-#endif
- cpustate->eip++;
- cpustate->pc++;
- return value;
-}
-
-INLINE UINT16 I386_OPS_BASE::FETCH16()
-{
- UINT16 value;
- UINT32 address = cpustate->pc, error;
-
- if( address & 0x1 ) { /* Unaligned read */
- value = (FETCH(cpustate) << 0);
- value |= (FETCH(cpustate) << 8);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16(address);
- cpustate->eip += 2;
- cpustate->pc += 2;
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::FETCH32()
-{
- UINT32 value;
- UINT32 address = cpustate->pc, error;
-
- if( cpustate->pc & 0x3 ) { /* Unaligned read */
- value = (FETCH(cpustate) << 0);
- value |= (FETCH(cpustate) << 8);
- value |= (FETCH(cpustate) << 16);
- value |= (FETCH(cpustate) << 24);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32(address);
- cpustate->eip += 4;
- cpustate->pc += 4;
- }
- return value;
-}
-
-INLINE UINT8 I386_OPS_BASE::READ8(UINT32 ea)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address, &error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- return cpustate->program->read_data8(address);
-}
-
-INLINE UINT16 I386_OPS_BASE::READ16(UINT32 ea)
-{
- UINT16 value;
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned read */
- value = (READ8( cpustate, address+0 ) << 0);
- value |= (READ8( cpustate, address+1 ) << 8);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16( address );
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::READ32(UINT32 ea)
-{
- UINT32 value;
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned read */
- value = (READ8( cpustate, address+0 ) << 0);
- value |= (READ8( cpustate, address+1 ) << 8);
- value |= (READ8( cpustate, address+2 ) << 16),
- value |= (READ8( cpustate, address+3 ) << 24);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32( address );
- }
- return value;
-}
-
-INLINE UINT64 I386_OPS_BASE::READ64(UINT32 ea)
-{
- UINT64 value;
- UINT32 address = ea, error;
-
- if( ea & 0x7 ) { /* Unaligned read */
- value = (((UINT64) READ8( cpustate, address+0 )) << 0);
- value |= (((UINT64) READ8( cpustate, address+1 )) << 8);
- value |= (((UINT64) READ8( cpustate, address+2 )) << 16);
- value |= (((UINT64) READ8( cpustate, address+3 )) << 24);
- value |= (((UINT64) READ8( cpustate, address+4 )) << 32);
- value |= (((UINT64) READ8( cpustate, address+5 )) << 40);
- value |= (((UINT64) READ8( cpustate, address+6 )) << 48);
- value |= (((UINT64) READ8( cpustate, address+7 )) << 56);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = (((UINT64) cpustate->program->read_data32( address+0 )) << 0);
- value |= (((UINT64) cpustate->program->read_data32( address+4 )) << 32);
- }
- return value;
-}
-
-INLINE UINT8 I386_OPS_BASE::READ8PL0(UINT32 ea)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- return cpustate->program->read_data8(address);
-}
-
-INLINE UINT16 I386_OPS_BASE::READ16PL0(UINT32 ea)
-{
- UINT16 value;
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned read */
- value = (READ8PL0( cpustate, address+0 ) << 0);
- value |= (READ8PL0( cpustate, address+1 ) << 8);
- } else {
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16( address );
- }
- return value;
-}
-
-INLINE UINT32 I386_OPS_BASE::READ32PL0(UINT32 ea)
-{
- UINT32 value;
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned read */
- value = (READ8PL0( cpustate, address+0 ) << 0);
- value |= (READ8PL0( cpustate, address+1 ) << 8);
- value |= (READ8PL0( cpustate, address+2 ) << 16);
- value |= (READ8PL0( cpustate, address+3 ) << 24);
- } else {
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32( address );
- }
- return value;
-}
-
-INLINE void I386_OPS_BASE::WRITE_TEST(UINT32 ea)
-{
- UINT32 address = ea, error;
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-}
-
-INLINE void I386_OPS_BASE::WRITE8(UINT32 ea, UINT8 value)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- cpustate->program->write_data8(address, value);
-}
-INLINE void WRITE16(UINT32 ea, UINT16 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- cpustate->program->write_data16(address, value);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITE32(UINT32 ea, UINT32 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- ea &= cpustate->a20_mask;
- cpustate->program->write_data32(address, value);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITE64(UINT32 ea, UINT64 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x7 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
- WRITE8( cpustate, address+4, (value >> 32) & 0xff );
- WRITE8( cpustate, address+5, (value >> 40) & 0xff );
- WRITE8( cpustate, address+6, (value >> 48) & 0xff );
- WRITE8( cpustate, address+7, (value >> 56) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- ea &= cpustate->a20_mask;
- cpustate->program->write_data32(address+0, value & 0xffffffff);
- cpustate->program->write_data32(address+4, (value >> 32) & 0xffffffff);
- }
-}
-
-/***********************************************************************************/
-
-INLINE UINT8 I386_OPS_BASE::OR8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-
-INLINE UINT16 I386_OPS_BASE::OR16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-
-INLINE UINT32 I386_OPS_BASE::OR32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-INLINE UINT8 I386_OPS_BASE::AND8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-INLINE UINT16 I386_OPS_BASE::AND16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-INLINE UINT32 I386_OPS_BASE::AND32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-INLINE UINT8 I386_OPS_BASE::XOR8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-INLINE UINT16 I386_OPS_BASE::XOR16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-INLINE UINT32 I386_OPS_BASE::XOR32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-#define SUB8(cpu, dst, src) SBB8(cpu, dst, src, 0)
-INLINE UINT8 I386_OPS_BASE::SBB8(UINT8 dst, UINT8 src, UINT8 b)
-{
- UINT16 res = (UINT16)dst - (UINT16)src - (UINT8)b;
- SetCF8(res);
- SetOF_Sub8(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-
-#define SUB16(cpu, dst, src) SBB16(cpu, dst, src, 0)
-INLINE UINT16 I386_OPS_BASE::SBB16(UINT16 dst, UINT16 src, UINT16 b)
-{
- UINT32 res = (UINT32)dst - (UINT32)src - (UINT32)b;
- SetCF16(res);
- SetOF_Sub16(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-
-#define SUB32(cpu, dst, src) SBB32(cpu, dst, src, 0)
-INLINE UINT32 I386_OPS_BASE::SBB32(UINT32 dst, UINT32 src, UINT32 b)
-{
- UINT64 res = (UINT64)dst - (UINT64)src - (UINT64) b;
- SetCF32(res);
- SetOF_Sub32(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-#define ADD8(cpu, dst, src) ADC8(cpu, dst, src, 0)
-INLINE UINT8 I386_OPS_BASE::ADC8(UINT8 dst, UINT8 src, UINT8 c)
-{
- UINT16 res = (UINT16)dst + (UINT16)src + (UINT16)c;
- SetCF8(res);
- SetOF_Add8(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-
-#define ADD16(cpu, dst, src) ADC16(cpu, dst, src, 0)
-INLINE UINT16 I386_OPS_BASE::ADC16(UINT16 dst, UINT16 src, UINT8 c)
-{
- UINT32 res = (UINT32)dst + (UINT32)src + (UINT32)c;
- SetCF16(res);
- SetOF_Add16(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-
-#define ADD32(cpu, dst, src) ADC32(cpu, dst, src, 0)
-INLINE UINT32 I386_OPS_BASE::ADC32(UINT32 dst, UINT32 src, UINT32 c)
-{
- UINT64 res = (UINT64)dst + (UINT64)src + (UINT64) c;
- SetCF32(res);
- SetOF_Add32(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-INLINE UINT8 INC8(UINT8 dst)
-{
- UINT16 res = (UINT16)dst + 1;
- SetOF_Add8(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-INLINE UINT16 I386_OPS_BASE::INC16(UINT16 dst)
-{
- UINT32 res = (UINT32)dst + 1;
- SetOF_Add16(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-INLINE UINT32 I386_OPS_BASE::INC32(UINT32 dst)
-{
- UINT64 res = (UINT64)dst + 1;
- SetOF_Add32(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-INLINE UINT8 I386_OPS_BASE::DEC8(UINT8 dst)
-{
- UINT16 res = (UINT16)dst - 1;
- SetOF_Sub8(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-INLINE UINT16 I386_OPS_BASE::DEC16(UINT16 dst)
-{
- UINT32 res = (UINT32)dst - 1;
- SetOF_Sub16(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-INLINE UINT32 I386_OPS_BASE::DEC32(UINT32 dst)
-{
- UINT64 res = (UINT64)dst - 1;
- SetOF_Sub32(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-
-
-INLINE void I386_OPS_BASE::PUSH16(UINT16 value)
-{
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) - 2;
- ea = i386_translate( SS, new_esp, 1);
- WRITE16( ea, value );
- REG32(ESP) = new_esp;
- } else {
- new_esp = (REG16(SP) - 2) & 0xffff;
- ea = i386_translate( SS, new_esp, 1);
- WRITE16( ea, value );
- REG16(SP) = new_esp;
- }
-}
-INLINE void I386_OPS_BASE::PUSH32(UINT32 value)
-{
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) - 4;
- ea = i386_translate( SS, new_esp, 1);
- WRITE32( ea, value );
- REG32(ESP) = new_esp;
- } else {
- new_esp = (REG16(SP) - 4) & 0xffff;
- ea = i386_translate( SS, new_esp, 1);
- WRITE32( ea, value );
- REG16(SP) = new_esp;
- }
-}
-INLINE void I386_OPS_BASE::PUSH8(UINT8 value)
-{
- if( cpustate->operand_size ) {
- PUSH32((INT32)(INT8)value);
- } else {
- PUSH16((INT16)(INT8)value);
- }
-}
-
-INLINE UINT8 I386_OPS_BASE::POP8(i386_state *cpustate)
-{
- UINT8 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 1;
- ea = i386_translate( SS, new_esp - 1, 0);
- value = READ8( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 1;
- ea = i386_translate( SS, (new_esp - 1) & 0xffff, 0);
- value = READ8( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-INLINE UINT16 I386_OPS_BASE::POP16(i386_state *cpustate)
-{
- UINT16 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 2;
- ea = i386_translate( SS, new_esp - 2, 0);
- value = READ16( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 2;
- ea = i386_translate( SS, (new_esp - 2) & 0xffff, 0);
- value = READ16( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::POP32(i386_state *cpustate)
-{
- UINT32 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 4;
- ea = i386_translate( SS, new_esp - 4, 0);
- value = READ32( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 4;
- ea = i386_translate( SS, (new_esp - 4) & 0xffff, 0);
- value = READ32( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-
-INLINE void I386_OPS_BASE::BUMP_SI(int adjustment)
-{
- if ( cpustate->address_size )
- REG32(ESI) += ((cpustate->DF) ? -adjustment : +adjustment);
- else
- REG16(SI) += ((cpustate->DF) ? -adjustment : +adjustment);
-}
-
-INLINE void I386_OPS_BASE::BUMP_DI(int adjustment)
-{
- if ( cpustate->address_size )
- REG32(EDI) += ((cpustate->DF) ? -adjustment : +adjustment);
- else
- REG16(DI) += ((cpustate->DF) ? -adjustment : +adjustment);
-}
-
-
-
-/***********************************************************************************
- I/O ACCESS
-***********************************************************************************/
-
-INLINE void I386_OPS_BASE::check_ioperm( offs_t port, UINT8 mask)
-{
- UINT8 IOPL, map;
- UINT16 IOPB;
- UINT32 address;
-
- if(!PROTECTED_MODE)
- return;
-
- IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if(!V8086_MODE && (cpustate->CPL <= IOPL))
- return;
-
- if((cpustate->task.limit < 0x67) || ((cpustate->task.flags & 0xd) != 9))
- FAULT_THROW(FAULT_GP,0);
-
- address = cpustate->task.base;
- IOPB = READ16PL0( address+0x66);
- if((IOPB+(port/8)) > cpustate->task.limit)
- FAULT_THROW(FAULT_GP,0);
-
- map = READ8PL0( address+IOPB+(port/8));
- map >>= (port%8);
- if(map & mask)
- FAULT_THROW(FAULT_GP,0);
-}
-
-INLINE UINT8 I386_OPS_BASE::READPORT8( offs_t port)
-{
- check_ioperm( port, 1);
- return cpustate->io->read_io8(port);
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT8( offs_t port, UINT8 value)
-{
- check_ioperm( port, 1);
- cpustate->io->write_io8(port, value);
-}
-
-INLINE UINT16 I386_OPS_BASE::READPORT16( offs_t port)
-{
- if (port & 1)
- {
- UINT16 value = READPORT8( port);
- value |= (READPORT8( port + 1) << 8);
- return value;
- }
- else
- {
- check_ioperm( port, 3);
- return cpustate->io->read_io16(port);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT16( offs_t port, UINT16 value)
-{
- if (port & 1)
- {
- WRITEPORT8( port, value & 0xff);
- WRITEPORT8( port + 1, (value >> 8) & 0xff);
- }
- else
- {
- check_ioperm( port, 3);
- cpustate->io->write_io16(port, value);
- }
-}
-
-INLINE UINT32 I386_OPS_BASE::READPORT32( offs_t port)
-{
- if (port & 3)
- {
- UINT32 value = READPORT8( port);
- value |= (READPORT8( port + 1) << 8);
- value |= (READPORT8( port + 2) << 16);
- value |= (READPORT8( port + 3) << 24);
- return value;
- }
- else
- {
- check_ioperm( port, 0xf);
- return cpustate->io->read_io32(port);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT32( offs_t port, UINT32 value)
-{
- if (port & 3)
- {
- WRITEPORT8( port, value & 0xff);
- WRITEPORT8( port + 1, (value >> 8) & 0xff);
- WRITEPORT8( port + 2, (value >> 16) & 0xff);
- WRITEPORT8( port + 3, (value >> 24) & 0xff);
- }
- else
- {
- check_ioperm( port, 0xf);
- cpustate->io->write_io32(port, value);
- }
-}
-
-
-INLINE UINT64 I386_OPS_BASE::MSR_READ(UINT32 offset,UINT8 *valid_msr)
-{
- UINT64 res;
- UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
-
- *valid_msr = 0;
-
- switch(cpu_type)
- {
- case 5: // Pentium
- res = pentium_msr_read(offset,valid_msr);
- break;
- case 6: // Pentium Pro, Pentium II, Pentium III
- res = p6_msr_read(offset,valid_msr);
- break;
- case 15: // Pentium 4+
- res = piv_msr_read(offset,valid_msr);
- break;
- default:
- res = 0;
- break;
- }
-
- return res;
-}
-
-INLINE void I386_OPS_BASE::MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr)
-{
- *valid_msr = 0;
- UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
-
- switch(cpu_type)
- {
- case 5: // Pentium
- pentium_msr_write(offset,data,valid_msr);
- break;
- case 6: // Pentium Pro, Pentium II, Pentium III
- p6_msr_write(offset,data,valid_msr);
- break;
- case 15: // Pentium 4+
- piv_msr_write(offset,data,valid_msr);
- break;
- }
-}
#endif /* __I386_H__ */