mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 19:08:32 +08:00
@@ -2371,14 +2371,40 @@ static void dyn_interrupt(Bitu num) {
|
|||||||
dyn_closeblock();
|
dyn_closeblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_add_iocheck(Bitu access_size) {
|
static bool dyn_io_writeB(Bitu port,uint8_t val) {
|
||||||
dyn_call_function_pagefault_check((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size);
|
bool ex = CPU_IO_Exception(port,1);
|
||||||
dyn_check_bool_exception_al();
|
if (!ex) IO_WriteB(port,val);
|
||||||
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_add_iocheck_var(uint8_t accessed_port,Bitu access_size) {
|
static bool dyn_io_writeW(Bitu port,uint16_t val) {
|
||||||
dyn_call_function_pagefault_check((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size);
|
bool ex = CPU_IO_Exception(port,2);
|
||||||
dyn_check_bool_exception_al();
|
if (!ex) IO_WriteW(port,val);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dyn_io_writeD(Bitu port,uint32_t val) {
|
||||||
|
bool ex = CPU_IO_Exception(port,4);
|
||||||
|
if (!ex) IO_WriteD(port,val);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dyn_io_readB(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,1);
|
||||||
|
if (!ex) core_dyn.readdata = IO_ReadB(port);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dyn_io_readW(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,2);
|
||||||
|
if (!ex) core_dyn.readdata = IO_ReadW(port);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dyn_io_readD(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,4);
|
||||||
|
if (!ex) core_dyn.readdata = IO_ReadD(port);
|
||||||
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_xlat(void) {
|
static void dyn_xlat(void) {
|
||||||
@@ -3016,35 +3042,33 @@ restart_prefix:
|
|||||||
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;
|
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;
|
||||||
case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block;
|
case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block;
|
||||||
//IN AL/AX,imm
|
//IN AL/AX,imm
|
||||||
case 0xe4: {
|
case 0xe4:
|
||||||
Bitu port=decode_fetchb();
|
dyn_call_function_pagefault_check((void*)&dyn_io_readB,"%Id",decode_fetchb());
|
||||||
dyn_add_iocheck_var(port,1);
|
dyn_check_bool_exception_al();
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadB,"%Id%Rl",port,DREG(EAX));
|
gen_mov_host(&core_dyn.readdata,DREG(EAX),1);
|
||||||
} break;
|
break;
|
||||||
case 0xe5: {
|
case 0xe5:
|
||||||
Bitu port=decode_fetchb();
|
if (!decode.big_op) {
|
||||||
dyn_add_iocheck_var(port,decode.big_op?4:2);
|
dyn_call_function_pagefault_check((void*)&dyn_io_readW,"%Id",decode_fetchb());
|
||||||
if (decode.big_op) {
|
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadD,"%Id%Rd",port,DREG(EAX));
|
|
||||||
} else {
|
} else {
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadW,"%Id%Rw",port,DREG(EAX));
|
dyn_call_function_pagefault_check((void*)&dyn_io_readD,"%Id",decode_fetchb());
|
||||||
}
|
}
|
||||||
} break;
|
dyn_check_bool_exception_al();
|
||||||
|
gen_mov_host(&core_dyn.readdata,DREG(EAX),decode.big_op?4:2);
|
||||||
|
break;
|
||||||
//OUT imm,AL
|
//OUT imm,AL
|
||||||
case 0xe6: {
|
case 0xe6:
|
||||||
Bitu port=decode_fetchb();
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeB,"%Id%Dl",decode_fetchb(),DREG(EAX));
|
||||||
dyn_add_iocheck_var(port,1);
|
dyn_check_bool_exception_al();
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteB,"%Id%Dl",port,DREG(EAX));
|
break;
|
||||||
} break;
|
case 0xe7:
|
||||||
case 0xe7: {
|
if (!decode.big_op) {
|
||||||
Bitu port=decode_fetchb();
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeW,"%Id%Dw",decode_fetchb(),DREG(EAX));
|
||||||
dyn_add_iocheck_var(port,decode.big_op?4:2);
|
|
||||||
if (decode.big_op) {
|
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteD,"%Id%Dd",port,DREG(EAX));
|
|
||||||
} else {
|
} else {
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteW,"%Id%Dw",port,DREG(EAX));
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeD,"%Id%Dd",decode_fetchb(),DREG(EAX));
|
||||||
}
|
}
|
||||||
} break;
|
dyn_check_bool_exception_al();
|
||||||
|
break;
|
||||||
case 0xe8: /* CALL Ivx */
|
case 0xe8: /* CALL Ivx */
|
||||||
dyn_call_near_imm();
|
dyn_call_near_imm();
|
||||||
goto finish_block;
|
goto finish_block;
|
||||||
@@ -3058,29 +3082,31 @@ restart_prefix:
|
|||||||
case 0xeb:dyn_exit_link((int8_t)decode_fetchb());goto finish_block;
|
case 0xeb:dyn_exit_link((int8_t)decode_fetchb());goto finish_block;
|
||||||
/* IN AL/AX,DX*/
|
/* IN AL/AX,DX*/
|
||||||
case 0xec:
|
case 0xec:
|
||||||
dyn_add_iocheck(1);
|
dyn_call_function_pagefault_check((void*)&dyn_io_readB,"%Dw",DREG(EDX));
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX));
|
dyn_check_bool_exception_al();
|
||||||
|
gen_mov_host(&core_dyn.readdata,DREG(EAX),1);
|
||||||
break;
|
break;
|
||||||
case 0xed:
|
case 0xed:
|
||||||
dyn_add_iocheck(decode.big_op?4:2);
|
if (!decode.big_op) {
|
||||||
if (decode.big_op) {
|
dyn_call_function_pagefault_check((void*)&dyn_io_readW,"%Dw",DREG(EDX));
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),DREG(EAX));
|
|
||||||
} else {
|
} else {
|
||||||
dyn_call_function_pagefault_check((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),DREG(EAX));
|
dyn_call_function_pagefault_check((void*)&dyn_io_readD,"%Dw",DREG(EDX));
|
||||||
}
|
}
|
||||||
|
dyn_check_bool_exception_al();
|
||||||
|
gen_mov_host(&core_dyn.readdata,DREG(EAX),decode.big_op?4:2);
|
||||||
break;
|
break;
|
||||||
/* OUT DX,AL/AX */
|
/* OUT DX,AL/AX */
|
||||||
case 0xee:
|
case 0xee:
|
||||||
dyn_add_iocheck(1);
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeB,"%Dw%Dl",DREG(EDX),DREG(EAX));
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteB,"%Dw%Dl",DREG(EDX),DREG(EAX));
|
dyn_check_bool_exception_al();
|
||||||
break;
|
break;
|
||||||
case 0xef:
|
case 0xef:
|
||||||
dyn_add_iocheck(decode.big_op?4:2);
|
if (!decode.big_op) {
|
||||||
if (decode.big_op) {
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeW,"%Dw%Dw",DREG(EDX),DREG(EAX));
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteD,"%Dw%Dd",DREG(EDX),DREG(EAX));
|
|
||||||
} else {
|
} else {
|
||||||
dyn_call_function_pagefault_check((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX));
|
dyn_call_function_pagefault_check((void*)&dyn_io_writeD,"%Dw%Dd",DREG(EDX),DREG(EAX));
|
||||||
}
|
}
|
||||||
|
dyn_check_bool_exception_al();
|
||||||
break;
|
break;
|
||||||
case 0xf0: //LOCK
|
case 0xf0: //LOCK
|
||||||
goto restart_prefix;
|
goto restart_prefix;
|
||||||
|
@@ -1175,28 +1175,6 @@ skip_extend_word:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// add code that checks if port access is allowed
|
|
||||||
// the port is given in a register
|
|
||||||
static void dyn_add_iocheck(HostReg reg_port,Bitu access_size) {
|
|
||||||
if (cpu.pmode) {
|
|
||||||
gen_call_function_RI(CPU_IO_Exception,reg_port,access_size);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add code that checks if port access is allowed
|
|
||||||
// the port is a constant
|
|
||||||
static void dyn_add_iocheck_var(uint8_t accessed_port,Bitu access_size) {
|
|
||||||
if (cpu.pmode) {
|
|
||||||
gen_call_function_II(CPU_IO_Exception,accessed_port,access_size);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// save back the address register
|
// save back the address register
|
||||||
static void gen_protect_addr_reg(void) {
|
static void gen_protect_addr_reg(void) {
|
||||||
#ifdef DRC_PROTECT_ADDR_REG
|
#ifdef DRC_PROTECT_ADDR_REG
|
||||||
|
@@ -1330,84 +1330,68 @@ static void dyn_string(StringOps op) {
|
|||||||
|
|
||||||
|
|
||||||
static void dyn_read_port_byte_direct(uint8_t port) {
|
static void dyn_read_port_byte_direct(uint8_t port) {
|
||||||
dyn_add_iocheck_var(port,1);
|
gen_mov_dword_to_reg_imm(FC_OP1,port);
|
||||||
gen_call_function_I(IO_ReadB,port);
|
gen_call_function_raw(dynrec_io_readB);
|
||||||
MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
|
dyn_check_exception(FC_RETOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_read_port_word_direct(uint8_t port) {
|
static void dyn_read_port_word_direct(uint8_t port) {
|
||||||
dyn_add_iocheck_var(port,decode.big_op?4:2);
|
gen_mov_dword_to_reg_imm(FC_OP1,port);
|
||||||
if (decode.big_op)
|
if(decode.big_op)
|
||||||
gen_call_function_I(IO_ReadD,port);
|
gen_call_function_raw(dynrec_io_readD);
|
||||||
else
|
else
|
||||||
gen_call_function_I(IO_ReadW,port);
|
gen_call_function_raw(dynrec_io_readW);
|
||||||
MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
|
dyn_check_exception(FC_RETOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_write_port_byte_direct(uint8_t port) {
|
static void dyn_write_port_byte_direct(uint8_t port) {
|
||||||
dyn_add_iocheck_var(port,1);
|
gen_mov_dword_to_reg_imm(FC_OP1,port);
|
||||||
MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
|
gen_call_function_raw(dynrec_io_writeB);
|
||||||
gen_extend_byte(false,FC_RETOP);
|
dyn_check_exception(FC_RETOP);
|
||||||
gen_call_function_IR(IO_WriteB,port,FC_RETOP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_write_port_word_direct(uint8_t port) {
|
static void dyn_write_port_word_direct(uint8_t port) {
|
||||||
dyn_add_iocheck_var(port,decode.big_op?4:2);
|
gen_mov_dword_to_reg_imm(FC_OP1,port);
|
||||||
MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
|
if(decode.big_op)
|
||||||
if (!decode.big_op) gen_extend_word(false,FC_RETOP);
|
gen_call_function_raw(dynrec_io_writeD);
|
||||||
if (decode.big_op)
|
|
||||||
gen_call_function_IR(IO_WriteD,port,FC_RETOP);
|
|
||||||
else
|
else
|
||||||
gen_call_function_IR(IO_WriteW,port,FC_RETOP);
|
gen_call_function_raw(dynrec_io_writeW);
|
||||||
|
dyn_check_exception(FC_RETOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dyn_read_port_byte(void) {
|
static void dyn_read_port_byte(void) {
|
||||||
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
|
MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EDX);
|
||||||
gen_extend_word(false,FC_ADDR);
|
gen_extend_word(false,FC_OP1);
|
||||||
gen_protect_addr_reg();
|
gen_call_function_raw(dynrec_io_readB);
|
||||||
dyn_add_iocheck(FC_ADDR,1);
|
dyn_check_exception(FC_RETOP);
|
||||||
gen_restore_addr_reg();
|
|
||||||
gen_call_function_R(IO_ReadB,FC_ADDR);
|
|
||||||
MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_read_port_word(void) {
|
static void dyn_read_port_word(void) {
|
||||||
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
|
MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EDX);
|
||||||
gen_extend_word(false,FC_ADDR);
|
gen_extend_word(false,FC_OP1);
|
||||||
gen_protect_addr_reg();
|
if(decode.big_op)
|
||||||
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
|
gen_call_function_raw(dynrec_io_readD);
|
||||||
gen_restore_addr_reg();
|
|
||||||
if (decode.big_op)
|
|
||||||
gen_call_function_R(IO_ReadD,FC_ADDR);
|
|
||||||
else
|
else
|
||||||
gen_call_function_R(IO_ReadW,FC_ADDR);
|
gen_call_function_raw(dynrec_io_readW);
|
||||||
MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
|
dyn_check_exception(FC_RETOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_write_port_byte(void) {
|
static void dyn_write_port_byte(void) {
|
||||||
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
|
MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EDX);
|
||||||
gen_extend_word(false,FC_ADDR);
|
gen_extend_word(false,FC_OP1);
|
||||||
gen_protect_addr_reg();
|
gen_call_function_raw(dynrec_io_writeB);
|
||||||
dyn_add_iocheck(FC_ADDR,1);
|
dyn_check_exception(FC_RETOP);
|
||||||
MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
|
|
||||||
gen_extend_byte(false,FC_RETOP);
|
|
||||||
gen_restore_addr_reg();
|
|
||||||
gen_call_function_RR(IO_WriteB,FC_ADDR,FC_RETOP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_write_port_word(void) {
|
static void dyn_write_port_word(void) {
|
||||||
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
|
MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EDX);
|
||||||
gen_extend_word(false,FC_ADDR);
|
gen_extend_word(false,FC_OP1);
|
||||||
gen_protect_addr_reg();
|
if(decode.big_op)
|
||||||
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
|
gen_call_function_raw(dynrec_io_writeD);
|
||||||
MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
|
|
||||||
if (!decode.big_op) gen_extend_word(false,FC_RETOP);
|
|
||||||
gen_restore_addr_reg();
|
|
||||||
if (decode.big_op)
|
|
||||||
gen_call_function_RR(IO_WriteD,FC_ADDR,FC_RETOP);
|
|
||||||
else
|
else
|
||||||
gen_call_function_RR(IO_WriteW,FC_ADDR,FC_RETOP);
|
gen_call_function_raw(dynrec_io_writeW);
|
||||||
|
dyn_check_exception(FC_RETOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2006,3 +2006,45 @@ static uint32_t DRC_CALL_CONV dynrec_pop_dword(void) {
|
|||||||
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
|
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeB(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeB(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,1);
|
||||||
|
if (!ex) IO_WriteB(port,reg_al);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeW(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeW(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,2);
|
||||||
|
if (!ex) IO_WriteW(port,reg_ax);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeD(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_writeD(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,4);
|
||||||
|
if (!ex) IO_WriteD(port,reg_eax);
|
||||||
|
return ex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readB(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readB(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,1);
|
||||||
|
if (!ex) reg_al = (uint8_t)IO_ReadB(port);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readW(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readW(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,2);
|
||||||
|
if (!ex) reg_ax = (uint16_t)IO_ReadW(port);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readD(Bitu port) DRC_FC;
|
||||||
|
static bool DRC_CALL_CONV dynrec_io_readD(Bitu port) {
|
||||||
|
bool ex = CPU_IO_Exception(port,4);
|
||||||
|
if (!ex) reg_eax = (uint32_t)IO_ReadD(port);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user