Implement Cyrix SMM mode.

This commit is contained in:
SarahW 2020-11-08 20:46:42 +00:00
commit c0bc163eaf
9 changed files with 690 additions and 109 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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)
{

View file

@ -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

View file

@ -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
View 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;
}

View file

@ -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)

View file

@ -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;

View file

@ -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)