Implement Cyrix SMM mode.
This commit is contained in:
parent
8a5a0fc48c
commit
c0bc163eaf
9 changed files with 690 additions and 109 deletions
110
src/386_ops.h
110
src/386_ops.h
|
|
@ -119,6 +119,7 @@ static int ILLEGAL(uint32_t fetchdat)
|
|||
#include "x86_ops_bit.h"
|
||||
#include "x86_ops_bitscan.h"
|
||||
#include "x86_ops_call.h"
|
||||
#include "x86_ops_cyrix.h"
|
||||
#include "x86_ops_flag.h"
|
||||
#include "x86_ops_fpu.h"
|
||||
#include "x86_ops_inc_dec.h"
|
||||
|
|
@ -638,7 +639,98 @@ OpFn OP_TABLE(pentium_0f)[1024] =
|
|||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
};
|
||||
|
||||
OpFn OP_TABLE(pentiummmx_0f)[1024] =
|
||||
OpFn OP_TABLE(c6x86_0f)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
};
|
||||
|
||||
OpFn OP_TABLE(pentiummmx_0f)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
|
|
@ -736,12 +828,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
|||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
|
|
@ -758,12 +850,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
|||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
|
|
@ -780,12 +872,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
|||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
|
|
@ -802,12 +894,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
|||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
{
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
|
||||
if (cpu_iscyrix && (cpu_cur_status & CPU_STATUS_SMM))
|
||||
return 0;
|
||||
|
||||
uop_MMX_ENTER(ir);
|
||||
codegen_mark_code_present(block, cs+op_pc, 1);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
|
|
|
|||
41
src/cpu.c
41
src/cpu.c
|
|
@ -787,7 +787,7 @@ void cpu_set()
|
|||
break;
|
||||
|
||||
case CPU_Cx6x86:
|
||||
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
|
||||
x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
|
||||
timing_rr = 1; /*register dest - register src*/
|
||||
timing_rm = 1; /*register dest - memory src*/
|
||||
timing_mr = 2; /*memory dest - register src*/
|
||||
|
|
@ -2003,6 +2003,13 @@ void cpu_WRMSR()
|
|||
|
||||
static int cyrix_addr;
|
||||
|
||||
#define CCR1_USE_SMI (1 << 1)
|
||||
#define CCR1_SMAC (1 << 2)
|
||||
#define CCR1_SM3 (1 << 7)
|
||||
|
||||
#define CCR3_SMI_LOCK (1 << 0)
|
||||
#define CCR3_NMI_EN (1 << 1)
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
|
|
@ -2013,14 +2020,46 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
|||
ccr0 = val;
|
||||
break;
|
||||
case 0xc1: /*CCR1*/
|
||||
if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM))
|
||||
val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3));
|
||||
ccr1 = val;
|
||||
break;
|
||||
case 0xc2: /*CCR2*/
|
||||
ccr2 = val;
|
||||
break;
|
||||
case 0xc3: /*CCR3*/
|
||||
if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM))
|
||||
val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK;
|
||||
ccr3 = val;
|
||||
break;
|
||||
case 0xcd:
|
||||
if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
|
||||
{
|
||||
cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24);
|
||||
cyrix.smhr &= ~SMHR_VALID;
|
||||
}
|
||||
break;
|
||||
case 0xce:
|
||||
if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
|
||||
{
|
||||
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16);
|
||||
cyrix.smhr &= ~SMHR_VALID;
|
||||
}
|
||||
break;
|
||||
case 0xcf:
|
||||
if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
|
||||
{
|
||||
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8);
|
||||
if ((val & 0xf) == 0xf)
|
||||
cyrix.arr[3].size = 1ull << 32; /*4 GB*/
|
||||
else if (val & 0xf)
|
||||
cyrix.arr[3].size = 2048 << (val & 0xf);
|
||||
else
|
||||
cyrix.arr[3].size = 0; /*Disabled*/
|
||||
cyrix.smhr &= ~SMHR_VALID;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe8: /*CCR4*/
|
||||
if ((ccr3 & 0xf0) == 0x10)
|
||||
{
|
||||
|
|
|
|||
18
src/x86.h
18
src/x86.h
|
|
@ -39,7 +39,7 @@ typedef union
|
|||
typedef struct
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint32_t limit, limit_raw;
|
||||
uint8_t access, access2;
|
||||
uint16_t seg;
|
||||
uint32_t limit_low, limit_high;
|
||||
|
|
@ -325,4 +325,20 @@ void x86_smi_trigger(void);
|
|||
void x86_smi_enter(void);
|
||||
void x86_smi_leave(void);
|
||||
|
||||
void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
|
||||
#define SMHR_VALID (1 << 0)
|
||||
#define SMHR_ADDR_MASK (0xfffffffc)
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t base;
|
||||
uint64_t size;
|
||||
} arr[8];
|
||||
uint32_t smhr;
|
||||
} cyrix;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ extern OpFn dynarec_ops_pentiummmx_0f[1024];
|
|||
extern OpFn dynarec_ops_pentiumpro_0f[1024];
|
||||
extern OpFn dynarec_ops_pentium2_0f[1024];
|
||||
|
||||
extern OpFn dynarec_ops_c6x86_0f[1024];
|
||||
extern OpFn dynarec_ops_c6x86mx_0f[1024];
|
||||
|
||||
extern OpFn dynarec_ops_fpu_d8_a16[32];
|
||||
|
|
@ -110,6 +111,7 @@ extern OpFn ops_pentiummmx_0f[1024];
|
|||
extern OpFn ops_pentiumpro_0f[1024];
|
||||
extern OpFn ops_pentium2_0f[1024];
|
||||
|
||||
extern OpFn ops_c6x86_0f[1024];
|
||||
extern OpFn ops_c6x86mx_0f[1024];
|
||||
|
||||
extern OpFn ops_fpu_d8_a16[32];
|
||||
|
|
|
|||
274
src/x86_ops_cyrix.h
Normal file
274
src/x86_ops_cyrix.h
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/*Cyrix-only instructions*/
|
||||
/*System Management Mode*/
|
||||
static void opSVDC_common(uint32_t fetchdat)
|
||||
{
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, GS);
|
||||
break;
|
||||
default:
|
||||
pclog("opSVDC: unknown rmdat %02x\n", rmdat);
|
||||
x86illegal();
|
||||
}
|
||||
}
|
||||
static int opSVDC_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVDC_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static void opRSDC_common(uint32_t fetchdat)
|
||||
{
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
break;
|
||||
default:
|
||||
pclog("opRSDC: unknown rmdat %02x\n", rmdat);
|
||||
x86illegal();
|
||||
}
|
||||
}
|
||||
static int opRSDC_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSDC_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSVLDT_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVLDT_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opRSLDT_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSLDT_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSVTS_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVTS_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opRSTS_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSTS_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSMINT(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
fatal("opSMINT\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opRDSHR_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
fatal("opRDSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int opRDSHR_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
fatal("opRDSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opWRSHR_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
fatal("opWRSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int opWRSHR_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
fatal("opWRSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat)
|
|||
static int opMOVD_mm_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
|
|
@ -69,6 +69,52 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat)
|
|||
static int opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Cyrix maps both MOVD and SMINT to the same opcode*/
|
||||
static int opMOVD_mm_l_a16_cx(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
return opSMINT(fetchdat);
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVD_mm_l_a32_cx(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_cur_status & CPU_STATUS_SMM)
|
||||
return opSMINT(fetchdat);
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
|||
int dpl, valid, granularity;
|
||||
uint32_t addr, base, limit;
|
||||
uint16_t desc, sel;
|
||||
uint8_t access;
|
||||
uint8_t access, access2;
|
||||
|
||||
// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
|
||||
switch (rmdat & 0x38)
|
||||
|
|
@ -198,10 +198,12 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
|||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
access2 = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt) return 1;
|
||||
ldt.limit = limit;
|
||||
ldt.access = access;
|
||||
ldt.access2 = access2;
|
||||
if (granularity)
|
||||
{
|
||||
ldt.limit <<= 12;
|
||||
|
|
@ -226,6 +228,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
|||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
access2 = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt) return 1;
|
||||
access |= 2;
|
||||
|
|
@ -234,6 +237,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
|||
tr.seg = sel;
|
||||
tr.limit = limit;
|
||||
tr.access = access;
|
||||
tr.access2 = access2;
|
||||
if (granularity)
|
||||
{
|
||||
tr.limit <<= 12;
|
||||
|
|
|
|||
293
src/x86seg.c
293
src/x86seg.c
|
|
@ -219,6 +219,7 @@ static void set_use32(int u)
|
|||
static void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
{
|
||||
s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
|
||||
s->limit_raw = s->limit;
|
||||
if (segdat[3] & 0x80)
|
||||
s->limit = (s->limit << 12) | 0xFFF;
|
||||
s->base = segdat[1] | ((segdat[2] & 0xFF) << 16);
|
||||
|
|
@ -2996,6 +2997,51 @@ static void smi_load_smi_selector(x86seg *seg)
|
|||
seg->access2 = 0;
|
||||
}
|
||||
|
||||
void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
{
|
||||
writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16));
|
||||
writememl(0, addr+4, ((seg->base >> 16) & 0xff) |
|
||||
(seg->access << 8) |
|
||||
(seg->limit_raw & 0xf0000) |
|
||||
(seg->access2 << 16) |
|
||||
(seg->base & 0xff000000));
|
||||
}
|
||||
|
||||
void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
{
|
||||
uint16_t segdat[4], selector;
|
||||
|
||||
segdat[0] = readmemw(0, addr);
|
||||
segdat[1] = readmemw(0, addr+2);
|
||||
segdat[2] = readmemw(0, addr+4);
|
||||
segdat[3] = readmemw(0, addr+6);
|
||||
selector = readmemw(0, addr+8);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
do_seg_load(seg, segdat);
|
||||
seg->seg = selector;
|
||||
seg->checked = 0;
|
||||
if (seg == &cpu_state.seg_ds)
|
||||
{
|
||||
if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
codegen_flat_ds = 0;
|
||||
}
|
||||
if (seg == &cpu_state.seg_ss)
|
||||
{
|
||||
if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
codegen_flat_ss = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void x86_smi_enter(void)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
|
@ -3007,63 +3053,102 @@ void x86_smi_enter(void)
|
|||
cpu_386_flags_rebuild();
|
||||
cpl_override = 1;
|
||||
cr0 = 0; /*Disable MMU*/
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16));
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000);
|
||||
cpl_override = 0;
|
||||
|
||||
cpu_cur_status = CPU_STATUS_SMM;
|
||||
cpu_state.flags = 2;
|
||||
cpu_state.eflags = 0;
|
||||
cpu_state.pc = 0x8000;
|
||||
cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31));
|
||||
dr[7] = 0x400;
|
||||
smi_load_smi_selector(&cpu_state.seg_ds);
|
||||
smi_load_smi_selector(&cpu_state.seg_es);
|
||||
smi_load_smi_selector(&cpu_state.seg_fs);
|
||||
smi_load_smi_selector(&cpu_state.seg_gs);
|
||||
smi_load_smi_selector(&cpu_state.seg_ss);
|
||||
cpu_state.seg_cs.seg = 0x3000;
|
||||
cpu_state.seg_cs.base = cpu_state.smbase;
|
||||
cpu_state.seg_cs.limit = 0xffffffff;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffffffff;
|
||||
cpu_state.seg_cs.access = (0 << 5) | 2;
|
||||
if (cpu_iscyrix)
|
||||
{
|
||||
uint32_t base;
|
||||
|
||||
use32 = 0;
|
||||
stack32 = 0;
|
||||
if (!cyrix.smhr & SMHR_VALID)
|
||||
cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID;
|
||||
base = cyrix.smhr & SMHR_ADDR_MASK;
|
||||
|
||||
writememl(0, base-4, dr[7]);
|
||||
writememl(0, base-8, cpu_state.flags | (cpu_state.eflags << 16));
|
||||
writememl(0, base-0xc, old_cr0);
|
||||
writememl(0, base-0x10, cpu_state.oldpc);
|
||||
writememl(0, base-0x14, cpu_state.pc);
|
||||
writememl(0, base-0x18, CS | (CPL << 21));
|
||||
cyrix_write_seg_descriptor(base-0x20, &cpu_state.seg_cs);
|
||||
writememl(0, base-0x24, 0);
|
||||
|
||||
cpl_override = 0;
|
||||
|
||||
cpu_cur_status = CPU_STATUS_SMM;
|
||||
cpu_state.flags = 2;
|
||||
cpu_state.eflags = 0;
|
||||
cpu_state.pc = 0;
|
||||
cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31));
|
||||
dr[7] = 0x400;
|
||||
cpu_state.seg_cs.seg = cyrix.arr[3].base >> 4; /*Guess*/
|
||||
cpu_state.seg_cs.base = cyrix.arr[3].base;
|
||||
cpu_state.seg_cs.limit = 0xffffffff;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffffffff;
|
||||
cpu_state.seg_cs.access = (0 << 5) | 2;
|
||||
|
||||
use32 = 0;
|
||||
stack32 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16));
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
|
||||
smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase);
|
||||
writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000);
|
||||
cpl_override = 0;
|
||||
|
||||
cpu_cur_status = CPU_STATUS_SMM;
|
||||
cpu_state.flags = 2;
|
||||
cpu_state.eflags = 0;
|
||||
cpu_state.pc = 0x8000;
|
||||
cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31));
|
||||
dr[7] = 0x400;
|
||||
smi_load_smi_selector(&cpu_state.seg_ds);
|
||||
smi_load_smi_selector(&cpu_state.seg_es);
|
||||
smi_load_smi_selector(&cpu_state.seg_fs);
|
||||
smi_load_smi_selector(&cpu_state.seg_gs);
|
||||
smi_load_smi_selector(&cpu_state.seg_ss);
|
||||
cpu_state.seg_cs.seg = 0x3000;
|
||||
cpu_state.seg_cs.base = cpu_state.smbase;
|
||||
cpu_state.seg_cs.limit = 0xffffffff;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffffffff;
|
||||
cpu_state.seg_cs.access = (0 << 5) | 2;
|
||||
|
||||
use32 = 0;
|
||||
stack32 = 0;
|
||||
}
|
||||
|
||||
// pclog("x86_smi_enter\n");
|
||||
}
|
||||
|
|
@ -3073,47 +3158,67 @@ void x86_smi_leave(void)
|
|||
uint32_t temp;
|
||||
uint32_t new_cr0;
|
||||
|
||||
cpl_override = 1;
|
||||
new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc);
|
||||
cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8);
|
||||
temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4);
|
||||
cpu_state.flags = temp & 0xffff;
|
||||
cpu_state.eflags = temp >> 16;
|
||||
cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0);
|
||||
EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec);
|
||||
ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8);
|
||||
EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4);
|
||||
ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0);
|
||||
EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc);
|
||||
EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8);
|
||||
ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4);
|
||||
EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0);
|
||||
dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc);
|
||||
dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8);
|
||||
tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4);
|
||||
ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0);
|
||||
cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc);
|
||||
cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8);
|
||||
cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4);
|
||||
cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0);
|
||||
cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac);
|
||||
cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
|
||||
cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28);
|
||||
cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8);
|
||||
cpl_override = 0;
|
||||
if (cpu_iscyrix)
|
||||
{
|
||||
uint32_t base = cyrix.smhr & SMHR_ADDR_MASK;
|
||||
|
||||
cr0 = new_cr0;
|
||||
cpl_override = 1;
|
||||
dr[7] = readmeml(0, base-4);
|
||||
temp = readmeml(0, base-8);
|
||||
cpu_state.flags = temp & 0xffff;
|
||||
cpu_state.eflags = temp >> 16;
|
||||
new_cr0 = readmeml(0, base-0xc);
|
||||
cpu_state.pc = readmeml(0, base-0x14);
|
||||
cyrix_load_seg_descriptor(base-0x20, &cpu_state.seg_cs);
|
||||
cpl_override = 0;
|
||||
|
||||
cr0 = new_cr0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpl_override = 1;
|
||||
new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc);
|
||||
cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8);
|
||||
temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4);
|
||||
cpu_state.flags = temp & 0xffff;
|
||||
cpu_state.eflags = temp >> 16;
|
||||
cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0);
|
||||
EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec);
|
||||
ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8);
|
||||
EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4);
|
||||
ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0);
|
||||
EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc);
|
||||
EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8);
|
||||
ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4);
|
||||
EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0);
|
||||
dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc);
|
||||
dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8);
|
||||
tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4);
|
||||
ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0);
|
||||
cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc);
|
||||
cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8);
|
||||
cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4);
|
||||
cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0);
|
||||
cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac);
|
||||
cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
|
||||
smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
|
||||
cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28);
|
||||
cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8);
|
||||
cpl_override = 0;
|
||||
|
||||
cr0 = new_cr0;
|
||||
}
|
||||
|
||||
cpu_386_flags_extract();
|
||||
cpu_cur_status = 0;
|
||||
use32 = stack32 = 0;
|
||||
if (cr0 & 1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue