#ifdef I386_PSEUDO_BIOS
#define BIOS_INT(num) if(cpustate->bios != NULL) { \
- uint16_t regs[8], sregs[4]; \
+ uint16_t regs[10], sregs[4]; \
regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
+ regs[8] = 0x0000; regs[9] = 0x0000; \
sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF; \
REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
CYCLES(CYCLES_IRET); \
+ if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { \
+ uint32_t hi = regs[9]; \
+ uint32_t lo = regs[8]; \
+ uint32_t addr = (hi << 16) | lo; \
+ cpustate->eip = addr; \
+ } \
return; \
} \
}
#define BIOS_CALL_FAR(address) if(cpustate->bios != NULL) { \
- uint16_t regs[8], sregs[4]; \
+ uint16_t regs[10], sregs[4]; \
regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
+ regs[8] = 0x0000; regs[9] = 0x0000; \
sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF; \
REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
CYCLES(CYCLES_RET_INTERSEG); \
+ if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { \
+ uint32_t hi = regs[9]; \
+ uint32_t lo = regs[8]; \
+ uint32_t addr = (hi << 16) | lo; \
+ cpustate->eip = addr; \
+ } \
return; \
} \
}
STORE_RM16(modrm, dst);
CYCLES(CYCLES_INC_REG);
} else {
- UINT32 ea = GetEA(modrm,1);
+ UINT32 ea = GetEA(modrm,1, 2);
UINT16 dst = READ16(ea);
dst = INC16(dst);
WRITE16(ea, dst);
STORE_RM16(modrm, dst);
CYCLES(CYCLES_DEC_REG);
} else {
- UINT32 ea = GetEA(modrm,1);
+ UINT32 ea = GetEA(modrm,1, 2);
UINT16 dst = READ16(ea);
dst = DEC16(dst);
WRITE16(ea, dst);
address = LOAD_RM16(modrm);
CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */
} else {
- UINT32 ea = GetEA(modrm,0);
+ UINT32 ea = GetEA(modrm,0, 2);
address = READ16(ea);
CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */
}
}
else
{
- UINT32 ea = GetEA(modrm,0);
+ UINT32 ea = GetEA(modrm,0, 4);
address = READ16(ea + 0);
selector = READ16(ea + 2);
CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */
address = LOAD_RM16(modrm);
CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */
} else {
- UINT32 ea = GetEA(modrm,0);
+ UINT32 ea = GetEA(modrm,0, 2);
address = READ16(ea);
CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */
}
}
else
{
- UINT32 ea = GetEA(modrm,0);
+ UINT32 ea = GetEA(modrm,0, 4);
address = READ16(ea + 0);
selector = READ16(ea + 2);
CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */
if( modrm >= 0xc0 ) {
value = LOAD_RM16(modrm);
} else {
- UINT32 ea = GetEA(modrm,0);
+ UINT32 ea = GetEA(modrm,0, 2);
value = READ16(ea);
}
PUSH16(value);
break;
}
}
+
+void I386_OPS::i386__int() // Opcode 0xcd
+{
+ int interrupt = FETCH();
+ CYCLES(CYCLES_INT);
+
+#ifdef I386_PSEUDO_BIOS
+ BIOS_INT(interrupt)
+#endif
+ cpustate->ext = 0; // not an external interrupt
+ i386_trap(interrupt, 1, 0);
+ cpustate->ext = 1;
+}