diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index b8ef9edda..e8300f134 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -206,6 +206,7 @@ extern void x386_dynarec_log(const char *fmt, ...); # include "x86_ops_mmx_mov.h" # include "x86_ops_mmx_pack.h" # include "x86_ops_mmx_shift.h" +# include "x86_ops_mmx_emmi.h" #endif #include "x86_ops_mov.h" #ifdef OPS_286_386 @@ -859,12 +860,12 @@ const OpFn OP_TABLE(c486_0f)[1024] = { /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, 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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, 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, 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, @@ -1392,7 +1393,7 @@ const OpFn OP_TABLE(c6x86_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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, 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, @@ -1414,7 +1415,7 @@ const OpFn OP_TABLE(c6x86_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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, 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, @@ -1436,7 +1437,7 @@ const OpFn OP_TABLE(c6x86_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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, 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, @@ -1458,7 +1459,99 @@ const OpFn OP_TABLE(c6x86_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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, 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, + // clang-format on +}; + +const OpFn OP_TABLE(c6x86l_0f)[1024] = { + // clang-format off + /*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*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, 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, opRDSHR_a16, opWRSHR_a16, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, 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*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, 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, opRDSHR_a16, opWRSHR_a16, 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 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*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, 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, opRDSHR_a32, opWRSHR_a32, 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*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, 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, opRDSHR_a32, opWRSHR_a32, 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, @@ -1765,7 +1858,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*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, +/*50*/ opPAVEB_a16, opPADDSIW_a16, opPMAGW_a16, ILLEGAL, opPDISTIB_a16, opPSUBSIW_a16, ILLEGAL, ILLEGAL, opPMVZB_a16, opPMULHRWC_a16, opPMVNZB_a16, opPMVLZB_a16, opPMVGEZB_a16, opPMULHRIW_a16, opPMACHRIW_a16, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16, @@ -1787,7 +1880,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*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, +/*50*/ opPAVEB_a16, opPADDSIW_a16, opPMAGW_a16, ILLEGAL, opPDISTIB_a16, opPSUBSIW_a16, ILLEGAL, ILLEGAL, opPMVZB_a16, opPMULHRWC_a16, opPMVNZB_a16, opPMVLZB_a16, opPMVGEZB_a16, opPMULHRIW_a16, opPMACHRIW_a16, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16, @@ -1809,7 +1902,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*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, +/*50*/ opPAVEB_a32, opPADDSIW_a32, opPMAGW_a32, ILLEGAL, opPDISTIB_a32, opPSUBSIW_a32, ILLEGAL, ILLEGAL, opPMVZB_a32, opPMULHRWC_a32, opPMVNZB_a32, opPMVLZB_a32, opPMVGEZB_a32, opPMULHRIW_a32, opPMACHRIW_a32, 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, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32, @@ -1831,7 +1924,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*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, +/*50*/ opPAVEB_a32, opPADDSIW_a32, opPMAGW_a32, ILLEGAL, opPDISTIB_a32, opPSUBSIW_a32, ILLEGAL, ILLEGAL, opPMVZB_a32, opPMULHRWC_a32, opPMVNZB_a32, opPMVLZB_a32, opPMVGEZB_a32, opPMULHRIW_a32, opPMACHRIW_a32, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32, diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 0802fa3ac..13a109d38 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -279,13 +279,14 @@ uint8_t do_translate2 = 0; void (*cpu_exec)(int32_t cycs); -static uint8_t ccr0; -static uint8_t ccr1; -static uint8_t ccr2; -static uint8_t ccr3; -static uint8_t ccr4; -static uint8_t ccr5; -static uint8_t ccr6; +uint8_t ccr0; +uint8_t ccr1; +uint8_t ccr2; +uint8_t ccr3; +uint8_t ccr4; +uint8_t ccr5; +uint8_t ccr6; +uint8_t ccr7; static int cyrix_addr; @@ -557,7 +558,8 @@ cpu_set(void) cpu_busspeed = cpu_s->rspeed; cpu_multi = (int) ceil(cpu_s->multi); cpu_dmulti = cpu_s->multi; - ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0; + ccr4 = 0x85; cpu_update_waitstates(); @@ -1442,19 +1444,27 @@ cpu_set(void) } # endif /* USE_DYNAREC */ if (fpu_softfloat) { + x86_opcodes_d9_a16 = ops_sf_fpu_cyrix_d9_a16; + x86_opcodes_d9_a32 = ops_sf_fpu_cyrix_d9_a32; x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16; x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_sf_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_sf_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_sf_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_sf_fpu_686_df_a32; + x86_opcodes_db_a16 = ops_sf_fpu_cyrix_686_db_a16; + x86_opcodes_db_a32 = ops_sf_fpu_cyrix_686_db_a32; + x86_opcodes_dd_a16 = ops_sf_fpu_cyrix_dd_a16; + x86_opcodes_dd_a32 = ops_sf_fpu_cyrix_dd_a32; + x86_opcodes_df_a16 = ops_sf_fpu_cyrix_686_df_a16; + x86_opcodes_df_a32 = ops_sf_fpu_cyrix_686_df_a32; } else { + x86_opcodes_d9_a16 = ops_fpu_cyrix_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_cyrix_d9_a32; x86_opcodes_da_a16 = ops_fpu_686_da_a16; x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; + x86_opcodes_db_a16 = ops_fpu_cyrix_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_cyrix_686_db_a32; + x86_opcodes_dd_a16 = ops_fpu_cyrix_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_cyrix_dd_a32; + x86_opcodes_df_a16 = ops_fpu_cyrix_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_cyrix_686_df_a32; } } @@ -1462,22 +1472,16 @@ cpu_set(void) if (cpu_s->cpu_type == CPU_Cx6x86MX) x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); else if (cpu_s->cpu_type == CPU_Cx6x86L) - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + x86_setopcodes(ops_386, ops_c6x86l_0f, dynarec_ops_386, dynarec_ops_c6x86l_0f); else - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); -# if 0 x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); -# endif # else if (cpu_s->cpu_type == CPU_Cx6x86MX) x86_setopcodes(ops_386, ops_c6x86mx_0f); else if (cpu_s->cpu_type == CPU_Cx6x86L) - x86_setopcodes(ops_386, ops_pentium_0f); + x86_setopcodes(ops_386, ops_c6x86l_0f); else - x86_setopcodes(ops_386, ops_c6x86mx_0f); -# if 0 x86_setopcodes(ops_386, ops_c6x86_0f); -# endif # endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ @@ -4297,6 +4301,9 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) if ((ccr3 & 0xf0) == 0x10) ccr6 = val; break; + case 0xeb: /* CCR7 */ + ccr7 = val & 5; + break; } } @@ -4325,6 +4332,8 @@ cpu_read(uint16_t addr, UNUSED(void *priv)) return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; + case 0xeb: + return ccr7; case 0xfe: return cpu_s->cyrix_id & 0xff; case 0xff: diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 1d003ddc9..8324c543e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -87,30 +87,32 @@ enum { enum { CPU_PKG_8088 = (1 << 0), CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_8086_MAZOVIA = (1 << 3), - CPU_PKG_188 = (1 << 4), - CPU_PKG_186 = (1 << 5), - CPU_PKG_286 = (1 << 6), - CPU_PKG_386SX = (1 << 7), - CPU_PKG_386DX = (1 << 8), - CPU_PKG_386DX_DESKPRO386 = (1 << 9), - CPU_PKG_M6117 = (1 << 10), - CPU_PKG_386SLC_IBM = (1 << 11), - CPU_PKG_486SLC = (1 << 12), - CPU_PKG_486SLC_IBM = (1 << 13), - CPU_PKG_486BL = (1 << 14), - CPU_PKG_486DLC = (1 << 15), - CPU_PKG_SOCKET1 = (1 << 16), - CPU_PKG_SOCKET3 = (1 << 17), - CPU_PKG_SOCKET3_PC330 = (1 << 18), - CPU_PKG_STPC = (1 << 19), - CPU_PKG_SOCKET4 = (1 << 20), - CPU_PKG_SOCKET5_7 = (1 << 21), - CPU_PKG_SOCKET8 = (1 << 22), - CPU_PKG_SLOT1 = (1 << 23), - CPU_PKG_SLOT2 = (1 << 24), - CPU_PKG_SOCKET370 = (1 << 25) + CPU_PKG_8088_VTECH = (1 << 2), + CPU_PKG_8086 = (1 << 3), + CPU_PKG_8086_MAZOVIA = (1 << 4), + CPU_PKG_8086_VTECH = (1 << 5), + CPU_PKG_188 = (1 << 6), + CPU_PKG_186 = (1 << 7), + CPU_PKG_286 = (1 << 8), + CPU_PKG_386SX = (1 << 9), + CPU_PKG_386DX = (1 << 10), + CPU_PKG_386DX_DESKPRO386 = (1 << 11), + CPU_PKG_M6117 = (1 << 12), + CPU_PKG_386SLC_IBM = (1 << 13), + CPU_PKG_486SLC = (1 << 14), + CPU_PKG_486SLC_IBM = (1 << 15), + CPU_PKG_486BL = (1 << 16), + CPU_PKG_486DLC = (1 << 17), + CPU_PKG_SOCKET1 = (1 << 18), + CPU_PKG_SOCKET3 = (1 << 19), + CPU_PKG_SOCKET3_PC330 = (1 << 20), + CPU_PKG_STPC = (1 << 21), + CPU_PKG_SOCKET4 = (1 << 22), + CPU_PKG_SOCKET5_7 = (1 << 23), + CPU_PKG_SOCKET8 = (1 << 24), + CPU_PKG_SLOT1 = (1 << 25), + CPU_PKG_SLOT2 = (1 << 26), + CPU_PKG_SOCKET370 = (1 << 27) }; #define CPU_SUPPORTS_DYNAREC 1 @@ -587,6 +589,16 @@ extern uint32_t _tr[8]; extern uint32_t cache_index; extern uint8_t _cache[2048]; +/* For the Cyrix 6x86(MX) */ +extern uint8_t ccr0; +extern uint8_t ccr1; +extern uint8_t ccr2; +extern uint8_t ccr3; +extern uint8_t ccr4; +extern uint8_t ccr5; +extern uint8_t ccr6; +extern uint8_t ccr7; + /*Segments - _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index b2ef71075..104d56d05 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -262,6 +262,50 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, + { + .package = CPU_PKG_8088_VTECH, + .manufacturer = "Intel", + .name = "8088", + .internal_name = "8088_vtech", + .cpus = (const CPU[]) { + { + .name = "4.77", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + + { + .name = "10", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } + } + }, { .package = CPU_PKG_8086, .manufacturer = "Intel", @@ -399,6 +443,49 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, + { + .package = CPU_PKG_8086_VTECH, + .manufacturer = "Intel", + .name = "8086", + .internal_name = "8086_vtech", + .cpus = (const CPU[]) { + { + .name = "4.77", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } + } + }, { .package = CPU_PKG_188, .manufacturer = "Intel", diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 6f15560f3..97ae19f3a 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -272,6 +272,12 @@ reset_common(int hard) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msw = 0; new_ne = 0; + + ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0; + ccr4 = 0x85; + cyrix.arr[3].base = 0x30000; + cyrix.arr[3].size = 65536; + if (hascache) cr0 = 1 << 30; else diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 3dfb3f917..6d93fb435 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -92,6 +92,7 @@ extern const OpFn dynarec_ops_pentiummmx_0f[1024]; # ifdef USE_CYRIX_6X86 extern const OpFn dynarec_ops_c6x86_0f[1024]; +extern const OpFn dynarec_ops_c6x86l_0f[1024]; extern const OpFn dynarec_ops_c6x86mx_0f[1024]; # endif /* USE_CYRIX_6X86 */ @@ -234,6 +235,7 @@ extern const OpFn ops_pentiummmx_0f[1024]; #ifdef USE_CYRIX_6X86 extern const OpFn ops_c6x86_0f[1024]; +extern const OpFn ops_c6x86l_0f[1024]; extern const OpFn ops_c6x86mx_0f[1024]; #endif /* USE_CYRIX_6X86 */ @@ -263,14 +265,20 @@ extern const OpFn ops_sf_fpu_d8_a16[32]; extern const OpFn ops_sf_fpu_d8_a32[32]; extern const OpFn ops_sf_fpu_d9_a16[256]; extern const OpFn ops_sf_fpu_d9_a32[256]; +extern const OpFn ops_sf_fpu_cyrix_d9_a16[256]; +extern const OpFn ops_sf_fpu_cyrix_d9_a32[256]; extern const OpFn ops_sf_fpu_da_a16[256]; extern const OpFn ops_sf_fpu_da_a32[256]; extern const OpFn ops_sf_fpu_db_a16[256]; extern const OpFn ops_sf_fpu_db_a32[256]; +extern const OpFn ops_sf_fpu_cyrix_686_db_a16[256]; +extern const OpFn ops_sf_fpu_cyrix_686_db_a32[256]; extern const OpFn ops_sf_fpu_dc_a16[32]; extern const OpFn ops_sf_fpu_dc_a32[32]; extern const OpFn ops_sf_fpu_dd_a16[256]; extern const OpFn ops_sf_fpu_dd_a32[256]; +extern const OpFn ops_sf_fpu_cyrix_dd_a16[256]; +extern const OpFn ops_sf_fpu_cyrix_dd_a32[256]; extern const OpFn ops_sf_fpu_de_a16[256]; extern const OpFn ops_sf_fpu_de_a32[256]; extern const OpFn ops_sf_fpu_df_a16[256]; @@ -295,6 +303,8 @@ extern const OpFn ops_fpu_d8_a16[32]; extern const OpFn ops_fpu_d8_a32[32]; extern const OpFn ops_fpu_d9_a16[256]; extern const OpFn ops_fpu_d9_a32[256]; +extern const OpFn ops_fpu_cyrix_d9_a16[256]; +extern const OpFn ops_fpu_cyrix_d9_a32[256]; extern const OpFn ops_fpu_da_a16[256]; extern const OpFn ops_fpu_da_a32[256]; extern const OpFn ops_fpu_db_a16[256]; @@ -303,6 +313,8 @@ extern const OpFn ops_fpu_dc_a16[32]; extern const OpFn ops_fpu_dc_a32[32]; extern const OpFn ops_fpu_dd_a16[256]; extern const OpFn ops_fpu_dd_a32[256]; +extern const OpFn ops_fpu_cyrix_dd_a16[256]; +extern const OpFn ops_fpu_cyrix_dd_a32[256]; extern const OpFn ops_fpu_de_a16[256]; extern const OpFn ops_fpu_de_a32[256]; extern const OpFn ops_fpu_df_a16[256]; @@ -314,15 +326,23 @@ extern const OpFn ops_sf_fpu_686_da_a16[256]; extern const OpFn ops_sf_fpu_686_da_a32[256]; extern const OpFn ops_sf_fpu_686_db_a16[256]; extern const OpFn ops_sf_fpu_686_db_a32[256]; +extern const OpFn ops_sf_fpu_cyrix_686_db_a16[256]; +extern const OpFn ops_sf_fpu_cyrix_686_db_a32[256]; extern const OpFn ops_sf_fpu_686_df_a16[256]; extern const OpFn ops_sf_fpu_686_df_a32[256]; +extern const OpFn ops_sf_fpu_cyrix_686_df_a16[256]; +extern const OpFn ops_sf_fpu_cyrix_686_df_a32[256]; extern const OpFn ops_fpu_686_da_a16[256]; extern const OpFn ops_fpu_686_da_a32[256]; extern const OpFn ops_fpu_686_db_a16[256]; extern const OpFn ops_fpu_686_db_a32[256]; +extern const OpFn ops_fpu_cyrix_686_db_a16[256]; +extern const OpFn ops_fpu_cyrix_686_db_a32[256]; extern const OpFn ops_fpu_686_df_a16[256]; extern const OpFn ops_fpu_686_df_a32[256]; +extern const OpFn ops_fpu_cyrix_686_df_a16[256]; +extern const OpFn ops_fpu_cyrix_686_df_a32[256]; extern const OpFn ops_REPE[1024]; extern const OpFn ops_REPNE[1024]; diff --git a/src/cpu/x86_ops_mmx_emmi.h b/src/cpu/x86_ops_mmx_emmi.h new file mode 100644 index 000000000..4c994be0f --- /dev/null +++ b/src/cpu/x86_ops_mmx_emmi.h @@ -0,0 +1,807 @@ +/* Notes: "src2" means "first operand" */ + +static int +opPMULHRWC_a16(UNUSED(uint32_t fetchdat)) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + dst->w[0] = ((int32_t) (dst->sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] = ((int32_t) (dst->sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] = ((int32_t) (dst->sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] = ((int32_t) (dst->sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPMULHRWC_a32(UNUSED(uint32_t fetchdat)) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + dst->w[0] = ((int32_t) (dst->sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] = ((int32_t) (dst->sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] = ((int32_t) (dst->sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] = ((int32_t) (dst->sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPMULHRIW_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->w[0] = (((int32_t) src2.sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] = (((int32_t) src2.sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] = (((int32_t) src2.sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] = (((int32_t) src2.sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPMULHRIW_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->w[0] = (((int32_t) src2.sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] = (((int32_t) src2.sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] = (((int32_t) src2.sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] = (((int32_t) src2.sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPDISTIB_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->b[0] = USATB(dst->b[0] + abs(src2.b[0] - src.b[0])); + dst->b[1] = USATB(dst->b[1] + abs(src2.b[1] - src.b[1])); + dst->b[2] = USATB(dst->b[2] + abs(src2.b[2] - src.b[2])); + dst->b[3] = USATB(dst->b[3] + abs(src2.b[3] - src.b[3])); + dst->b[4] = USATB(dst->b[4] + abs(src2.b[4] - src.b[4])); + dst->b[5] = USATB(dst->b[5] + abs(src2.b[5] - src.b[5])); + dst->b[6] = USATB(dst->b[6] + abs(src2.b[6] - src.b[6])); + dst->b[7] = USATB(dst->b[7] + abs(src2.b[7] - src.b[7])); + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPDISTIB_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->b[0] = USATB(dst->b[0] + abs(src2.b[0] - src.b[0])); + dst->b[1] = USATB(dst->b[1] + abs(src2.b[1] - src.b[1])); + dst->b[2] = USATB(dst->b[2] + abs(src2.b[2] - src.b[2])); + dst->b[3] = USATB(dst->b[3] + abs(src2.b[3] - src.b[3])); + dst->b[4] = USATB(dst->b[4] + abs(src2.b[4] - src.b[4])); + dst->b[5] = USATB(dst->b[5] + abs(src2.b[5] - src.b[5])); + dst->b[6] = USATB(dst->b[6] + abs(src2.b[6] - src.b[6])); + dst->b[7] = USATB(dst->b[7] + abs(src2.b[7] - src.b[7])); + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPMACHRIW_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->w[0] += (((int32_t) src2.sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] += (((int32_t) src2.sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] += (((int32_t) src2.sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] += (((int32_t) src2.sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPMACHRIW_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->w[0] += (((int32_t) src2.sw[0] * (int32_t) src.sw[0]) + 0x4000) >> 15; + dst->w[1] += (((int32_t) src2.sw[1] * (int32_t) src.sw[1]) + 0x4000) >> 15; + dst->w[2] += (((int32_t) src2.sw[2] * (int32_t) src.sw[2]) + 0x4000) >> 15; + dst->w[3] += (((int32_t) src2.sw[3] * (int32_t) src.sw[3]) + 0x4000) >> 15; + + MMX_SETEXP(cpu_reg ^ 1); + return 0; +} + +static int +opPADDSIW_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->sw[0] = SSATW(src2.sw[0] + src.sw[0]); + dst->sw[1] = SSATW(src2.sw[1] + src.sw[1]); + dst->sw[2] = SSATW(src2.sw[2] + src.sw[2]); + dst->sw[3] = SSATW(src2.sw[3] + src.sw[3]); + + MMX_SETEXP(cpu_reg ^ 1); + + return 0; +} + +static int +opPADDSIW_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->sw[0] = SSATW(src2.sw[0] + src.sw[0]); + dst->sw[1] = SSATW(src2.sw[1] + src.sw[1]); + dst->sw[2] = SSATW(src2.sw[2] + src.sw[2]); + dst->sw[3] = SSATW(src2.sw[3] + src.sw[3]); + + MMX_SETEXP(cpu_reg ^ 1); + + return 0; +} + +static int +opPSUBSIW_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->sw[0] = SSATW(src2.sw[0] - src.sw[0]); + dst->sw[1] = SSATW(src2.sw[1] - src.sw[1]); + dst->sw[2] = SSATW(src2.sw[2] - src.sw[2]); + dst->sw[3] = SSATW(src2.sw[3] - src.sw[3]); + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPSUBSIW_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + src2 = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_reg ^ 1); + + MMX_GETSRC(); + + dst->sw[0] = SSATW(src2.sw[0] - src.sw[0]); + dst->sw[1] = SSATW(src2.sw[1] - src.sw[1]); + dst->sw[2] = SSATW(src2.sw[2] - src.sw[2]); + dst->sw[3] = SSATW(src2.sw[3] - src.sw[3]); + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPAVEB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + dst->b[0] = (dst->b[0] + src.b[0]) >> 1; + dst->b[1] = (dst->b[1] + src.b[1]) >> 1; + dst->b[2] = (dst->b[2] + src.b[2]) >> 1; + dst->b[3] = (dst->b[3] + src.b[3]) >> 1; + dst->b[4] = (dst->b[4] + src.b[4]) >> 1; + dst->b[5] = (dst->b[5] + src.b[5]) >> 1; + dst->b[6] = (dst->b[6] + src.b[6]) >> 1; + dst->b[7] = (dst->b[7] + src.b[7]) >> 1; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPAVEB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + dst->b[0] = (dst->b[0] + src.b[0]) >> 1; + dst->b[1] = (dst->b[1] + src.b[1]) >> 1; + dst->b[2] = (dst->b[2] + src.b[2]) >> 1; + dst->b[3] = (dst->b[3] + src.b[3]) >> 1; + dst->b[4] = (dst->b[4] + src.b[4]) >> 1; + dst->b[5] = (dst->b[5] + src.b[5]) >> 1; + dst->b[6] = (dst->b[6] + src.b[6]) >> 1; + dst->b[7] = (dst->b[7] + src.b[7]) >> 1; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMAGW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + if (abs(src.sw[0]) > abs(dst->sw[0])) dst->sw[0] = src.sw[0]; + if (abs(src.sw[1]) > abs(dst->sw[1])) dst->sw[1] = src.sw[1]; + if (abs(src.sw[2]) > abs(dst->sw[2])) dst->sw[2] = src.sw[2]; + if (abs(src.sw[3]) > abs(dst->sw[3])) dst->sw[3] = src.sw[3]; + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPMAGW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + + MMX_GETSRC(); + + if (abs(src.sw[0]) > abs(dst->sw[0])) dst->sw[0] = src.sw[0]; + if (abs(src.sw[1]) > abs(dst->sw[1])) dst->sw[1] = src.sw[1]; + if (abs(src.sw[2]) > abs(dst->sw[2])) dst->sw[2] = src.sw[2]; + if (abs(src.sw[3]) > abs(dst->sw[3])) dst->sw[3] = src.sw[3]; + + MMX_SETEXP(cpu_reg); + + return 0; +} + +static int +opPMVZB_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.b[0] == 0) dst->b[0] = src.b[0]; + if (src2.b[1] == 0) dst->b[1] = src.b[1]; + if (src2.b[2] == 0) dst->b[2] = src.b[2]; + if (src2.b[3] == 0) dst->b[3] = src.b[3]; + if (src2.b[4] == 0) dst->b[4] = src.b[4]; + if (src2.b[5] == 0) dst->b[5] = src.b[5]; + if (src2.b[6] == 0) dst->b[6] = src.b[6]; + if (src2.b[7] == 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVZB_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.b[0] == 0) dst->b[0] = src.b[0]; + if (src2.b[1] == 0) dst->b[1] = src.b[1]; + if (src2.b[2] == 0) dst->b[2] = src.b[2]; + if (src2.b[3] == 0) dst->b[3] = src.b[3]; + if (src2.b[4] == 0) dst->b[4] = src.b[4]; + if (src2.b[5] == 0) dst->b[5] = src.b[5]; + if (src2.b[6] == 0) dst->b[6] = src.b[6]; + if (src2.b[7] == 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVNZB_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.b[0] != 0) dst->b[0] = src.b[0]; + if (src2.b[1] != 0) dst->b[1] = src.b[1]; + if (src2.b[2] != 0) dst->b[2] = src.b[2]; + if (src2.b[3] != 0) dst->b[3] = src.b[3]; + if (src2.b[4] != 0) dst->b[4] = src.b[4]; + if (src2.b[5] != 0) dst->b[5] = src.b[5]; + if (src2.b[6] != 0) dst->b[6] = src.b[6]; + if (src2.b[7] != 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVNZB_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.b[0] != 0) dst->b[0] = src.b[0]; + if (src2.b[1] != 0) dst->b[1] = src.b[1]; + if (src2.b[2] != 0) dst->b[2] = src.b[2]; + if (src2.b[3] != 0) dst->b[3] = src.b[3]; + if (src2.b[4] != 0) dst->b[4] = src.b[4]; + if (src2.b[5] != 0) dst->b[5] = src.b[5]; + if (src2.b[6] != 0) dst->b[6] = src.b[6]; + if (src2.b[7] != 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVLZB_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.sb[0] < 0) dst->b[0] = src.b[0]; + if (src2.sb[1] < 0) dst->b[1] = src.b[1]; + if (src2.sb[2] < 0) dst->b[2] = src.b[2]; + if (src2.sb[3] < 0) dst->b[3] = src.b[3]; + if (src2.sb[4] < 0) dst->b[4] = src.b[4]; + if (src2.sb[5] < 0) dst->b[5] = src.b[5]; + if (src2.sb[6] < 0) dst->b[6] = src.b[6]; + if (src2.sb[7] < 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVLZB_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.sb[0] < 0) dst->b[0] = src.b[0]; + if (src2.sb[1] < 0) dst->b[1] = src.b[1]; + if (src2.sb[2] < 0) dst->b[2] = src.b[2]; + if (src2.sb[3] < 0) dst->b[3] = src.b[3]; + if (src2.sb[4] < 0) dst->b[4] = src.b[4]; + if (src2.sb[5] < 0) dst->b[5] = src.b[5]; + if (src2.sb[6] < 0) dst->b[6] = src.b[6]; + if (src2.sb[7] < 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVGEZB_a16(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.sb[0] >= 0) dst->b[0] = src.b[0]; + if (src2.sb[1] >= 0) dst->b[1] = src.b[1]; + if (src2.sb[2] >= 0) dst->b[2] = src.b[2]; + if (src2.sb[3] >= 0) dst->b[3] = src.b[3]; + if (src2.sb[4] >= 0) dst->b[4] = src.b[4]; + if (src2.sb[5] >= 0) dst->b[5] = src.b[5]; + if (src2.sb[6] >= 0) dst->b[6] = src.b[6]; + if (src2.sb[7] >= 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} + +static int +opPMVGEZB_a32(uint32_t fetchdat) +{ + MMX_REG src, src2; + MMX_REG *dst; + + if (!(ccr7 & 1)) { + x86illegal(); + return 1; + } + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + + if (cpu_mod == 3) { + x86illegal(); + return 1; + } + + dst = MMX_GETREGP(cpu_reg); + src2 = MMX_GETREG(cpu_reg ^ 1); + + MMX_GETSRC(); + + if (src2.sb[0] >= 0) dst->b[0] = src.b[0]; + if (src2.sb[1] >= 0) dst->b[1] = src.b[1]; + if (src2.sb[2] >= 0) dst->b[2] = src.b[2]; + if (src2.sb[3] >= 0) dst->b[3] = src.b[3]; + if (src2.sb[4] >= 0) dst->b[4] = src.b[4]; + if (src2.sb[5] >= 0) dst->b[5] = src.b[5]; + if (src2.sb[6] >= 0) dst->b[6] = src.b[6]; + if (src2.sb[7] >= 0) dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); + return 0; +} \ No newline at end of file diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index f1362bf76..97f5415b9 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -241,6 +241,24 @@ x87_fround32_64(double b) return (int64_t) x87_fround32(b); } +static __inline int64_t +x87_fround_nearest(double b) +{ + double da, dc; + int64_t a, c; + + da = floor(b); + dc = floor(b + 1.0); + a = (int64_t) da; + c = (int64_t) dc; + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; +} + static __inline int64_t x87_fround(double b) { @@ -1267,6 +1285,86 @@ const OpFn OP_TABLE(sf_fpu_d9_a32)[256] = { // clang-format on }; +const OpFn OP_TABLE(sf_fpu_cyrix_d9_a16)[256] = { + // clang-format off + /*0x00*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x18*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0x20*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0x28*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0x30*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0x38*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + + /*0x40*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x58*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0x60*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0x68*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0x70*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0x78*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + + /*0x80*/ sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, sf_FLDs_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, sf_FSTs_a16, + /*0x98*/ sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, sf_FSTPs_a16, + /*0xa0*/ sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, sf_FLDENV_a16, + /*0xa8*/ sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, sf_FLDCW_a16, + /*0xb0*/ sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, sf_FNSTENV_a16, + /*0xb8*/ sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, sf_FNSTCW_a16, + + /*0xc0*/ sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, + /*0xc8*/ sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + /*0xd0*/ sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xd8*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, /*Invalid*/ + /*0xe0*/ sf_FCHS, sf_FABS, ILLEGAL_a16, ILLEGAL_a16, sf_FTST, sf_FXAM, sf_FTSTP, ILLEGAL_a16, + /*0xe8*/ sf_FLD1, sf_FLDL2T, sf_FLDL2E, sf_FLDPI, sf_FLDEG2, sf_FLDLN2, sf_FLDZ, ILLEGAL_a16, + /*0xf0*/ sf_F2XM1, sf_FYL2X, sf_FPTAN, sf_FPATAN, sf_FXTRACT, sf_FPREM1, sf_FDECSTP, sf_FINCSTP, + /*0xf8*/ sf_FPREM, sf_FYL2XP1, sf_FSQRT, sf_FSINCOS, sf_FRNDINT, sf_FSCALE, sf_FSIN, sf_FCOS, + // clang-format on +}; + +const OpFn OP_TABLE(sf_fpu_cyrix_d9_a32)[256] = { + // clang-format off + sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, + sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, + sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, + sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, + sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, + sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, + + sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, + sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, + sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, + sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, + sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, + sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, + + sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, sf_FLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, sf_FSTs_a32, + sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, sf_FSTPs_a32, + sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, sf_FLDENV_a32, + sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, sf_FLDCW_a32, + sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, sf_FNSTENV_a32, + sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, sf_FNSTCW_a32, + + sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, sf_FLD_sti, + sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + sf_FNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, /*Invalid*/ + sf_FCHS, sf_FABS, ILLEGAL_a32, ILLEGAL_a32, sf_FTST, sf_FXAM, sf_FTSTP, ILLEGAL_a32, + sf_FLD1, sf_FLDL2T, sf_FLDL2E, sf_FLDPI, sf_FLDEG2, sf_FLDLN2, sf_FLDZ, ILLEGAL_a32, + sf_F2XM1, sf_FYL2X, sf_FPTAN, sf_FPATAN, sf_FXTRACT, sf_FPREM1, sf_FDECSTP, sf_FINCSTP, + sf_FPREM, sf_FYL2XP1, sf_FSQRT, sf_FSINCOS, sf_FRNDINT, sf_FSCALE, sf_FSIN, sf_FCOS, + // clang-format on +}; + const OpFn OP_TABLE(sf_fpu_287_da_a16)[256] = { // clang-format off sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, @@ -1750,6 +1848,87 @@ const OpFn OP_TABLE(sf_fpu_686_db_a32)[256] = { }; # endif +# ifndef OPS_286_386 +const OpFn OP_TABLE(sf_fpu_cyrix_686_db_a16)[256] = { + // clang-format off + sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + + sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + + sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, sf_FISTil_a16, + sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, sf_FISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, sf_FLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, sf_FSTPe_a16, + + sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, + sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, + sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, + sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, + sf_FNOP, sf_FNOP, sf_FNCLEX, sf_FNINIT, sf_FNOP, sf_FNOP, ILLEGAL_a16, ILLEGAL_a16, + sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, + sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FRINT2, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; +const OpFn OP_TABLE(sf_fpu_cyrix_686_db_a32)[256] = { + // clang-format off + sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, + sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, + + sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, + sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, + + sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, sf_FILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, sf_FISTil_a32, + sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, sf_FISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, sf_FLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, sf_FSTPe_a32, + + sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, sf_FCMOVNB, + sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, sf_FCMOVNE, + sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, sf_FCMOVNBE, + sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, sf_FCMOVNU, + sf_FNOP, sf_FNOP, sf_FNCLEX, sf_FNINIT, sf_FNOP, sf_FNOP, ILLEGAL_a32, ILLEGAL_a32, + sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, sf_FUCOMI_st0_stj, + sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, sf_FCOMI_st0_stj, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FRINT2, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; +# endif + const OpFn OP_TABLE(sf_fpu_287_dc_a16)[32] = { // clang-format off sf_FADDd_a16, sf_FMULd_a16, sf_FCOMd_a16, sf_FCOMPd_a16, sf_FSUBd_a16, sf_FSUBRd_a16, sf_FDIVd_a16, sf_FDIVRd_a16, @@ -1946,6 +2125,86 @@ const OpFn OP_TABLE(sf_fpu_dd_a32)[256] = { // clang-format on }; +const OpFn OP_TABLE(sf_fpu_cyrix_dd_a16)[256] = { + // clang-format off + /*0x00*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x08*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x10*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x18*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0x20*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0x28*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x30*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0x38*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + + /*0x40*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x48*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x50*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x58*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0x60*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0x68*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x70*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0x78*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + + /*0x80*/ sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, sf_FLDd_a16, + /*0x88*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0x90*/ sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, sf_FSTd_a16, + /*0x98*/ sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, sf_FSTPd_a16, + /*0xa0*/ sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, sf_FRSTOR_a16, + /*0xa8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xb0*/ sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, sf_FNSAVE_a16, + /*0xb8*/ sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, sf_FNSTSW_a16, + + /*0xc0*/ sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, + /*0xc8*/ sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + /*0xd0*/ sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, + /*0xd8*/ sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + /*0xe0*/ sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, + /*0xe8*/ sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, + /*0xf0*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + /*0xf8*/ ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FRICHOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; + +const OpFn OP_TABLE(sf_fpu_cyrix_dd_a32)[256] = { + // clang-format off + sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, + sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, + sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, + sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, + + sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, + sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, + sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, + sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, + + sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, sf_FLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, sf_FSTd_a32, + sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, sf_FSTPd_a32, + sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, sf_FRSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, sf_FNSAVE_a32, + sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, sf_FNSTSW_a32, + + sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, sf_FFREE_sti, + sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, sf_FST_sti, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, sf_FUCOM_sti, + sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, sf_FUCOMP_sti, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FRICHOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; + const OpFn OP_TABLE(sf_fpu_287_de_a16)[256] = { // clang-format off sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, sf_FADDiw_a16, @@ -2348,6 +2607,88 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { }; # endif +# ifndef OPS_286_386 +const OpFn OP_TABLE(sf_fpu_cyrix_686_df_a16)[256] = { + // clang-format off + sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + + sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + + sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, + sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, + sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, + sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, + sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, + + sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, + sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + sf_FNSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, + sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FRINEAR, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; + +const OpFn OP_TABLE(sf_fpu_cyrix_686_df_a32)[256] = { + // clang-format off + sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, + sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, + sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, + sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, + sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, + + sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, + sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, + sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, + sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, + sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, + + sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, sf_FILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, + sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, + sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, + sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, + sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, + + sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, sf_FFREEP_sti, + sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, sf_FXCH_sti, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, sf_FSTP_sti, + sf_FNSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, sf_FUCOMIP_st0_stj, + sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, sf_FCOMIP_st0_stj, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FRINEAR, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; +# endif + const OpFn OP_TABLE(fpu_d8_a16)[32] = { // clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, @@ -2526,6 +2867,86 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = { // clang-format on }; +const OpFn OP_TABLE(fpu_cyrix_d9_a16)[256] = { + // clang-format off + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, opFTSTP, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on +}; + +const OpFn OP_TABLE(fpu_cyrix_d9_a32)[256] = { + // clang-format off + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, opFTSTP, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on +}; + const OpFn OP_TABLE(fpu_287_da_a16)[256] = { // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -3009,6 +3430,87 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = { }; # endif +# ifndef OPS_286_386 +const OpFn OP_TABLE(fpu_cyrix_686_db_a16)[256] = { + // clang-format off + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFRINT2, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; +const OpFn OP_TABLE(fpu_cyrix_686_db_a32)[256] = { + // clang-format off + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFRINT2, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; +# endif + const OpFn OP_TABLE(fpu_287_dc_a16)[32] = { // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, @@ -3205,6 +3707,86 @@ const OpFn OP_TABLE(fpu_dd_a32)[256] = { // clang-format on }; +const OpFn OP_TABLE(fpu_cyrix_dd_a16)[256] = { + // clang-format off + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFRICHOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; + +const OpFn OP_TABLE(fpu_cyrix_dd_a32)[256] = { + // clang-format off + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFRICHOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; + const OpFn OP_TABLE(fpu_287_de_a16)[256] = { // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, @@ -3607,6 +4189,88 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { }; # endif +# ifndef OPS_286_386 +const OpFn OP_TABLE(fpu_cyrix_686_df_a16)[256] = { + // clang-format off + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFRINEAR, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on +}; + +const OpFn OP_TABLE(fpu_cyrix_686_df_a32)[256] = { + // clang-format off + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFRINEAR, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; +# endif + const OpFn OP_TABLE(nofpu_a16)[256] = { // clang-format off op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index c1f09fda9..cbad12e56 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -554,6 +554,22 @@ opFTST(UNUSED(uint32_t fetchdat)) return 0; } +static int +opFTSTP(UNUSED(uint32_t fetchdat)) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); + if (ST(0) == 0.0) + cpu_state.npxs |= FPU_SW_C3; + else if (ST(0) < 0.0) + cpu_state.npxs |= FPU_SW_C0; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); + return 0; +} + static int opFXAM(UNUSED(uint32_t fetchdat)) { @@ -838,6 +854,67 @@ opFRNDINT(UNUSED(uint32_t fetchdat)) return 0; } +static int +opFRINT2(UNUSED(uint32_t fetchdat)) +{ + double dst0, st0, integral, frac; + int prevRound; + + FP_ENTER(); + cpu_state.pc++; + prevRound = fegetround(); + fesetround(FE_TONEAREST); + st0 = ST(0); + frac = modf(st0, &integral); + if (frac == 0.5 || frac == -0.5) { + dst0 = (st0 < 0) ? floor(st0) : ceil(st0); + } else { + dst0 = round(st0); + } + fesetround(prevRound); + ST(0) = (double) dst0; + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +opFRINEAR(UNUSED(uint32_t fetchdat)) +{ + double dst0, st0, integral, frac; + int prevRound; + + FP_ENTER(); + cpu_state.pc++; + prevRound = fegetround(); + fesetround(FE_TONEAREST); + ST(0) = (double) x87_fround_nearest(ST(0)); + fesetround(prevRound); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +opFRICHOP(UNUSED(uint32_t fetchdat)) +{ + double dst0, st0, integral, frac; + int prevRound; + + FP_ENTER(); + cpu_state.pc++; + prevRound = fegetround(); + fesetround(FE_TONEAREST); + ST(0) = (double) ((int64_t)(ST(0))); + fesetround(prevRound); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + static int opFSCALE(UNUSED(uint32_t fetchdat)) { diff --git a/src/cpu/x87_ops_sf_arith.h b/src/cpu/x87_ops_sf_arith.h index c9e25e97c..620c44691 100644 --- a/src/cpu/x87_ops_sf_arith.h +++ b/src/cpu/x87_ops_sf_arith.h @@ -800,3 +800,84 @@ next_ins: CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); return 0; } + +static int +sf_FRINT2(uint32_t fetchdat) +{ + floatx80 result; + struct softfloat_status_t status; + + FP_ENTER(); + FPU_check_pending_exceptions(); + cpu_state.pc++; + clear_C1(); + if (IS_TAG_EMPTY(0)) { + FPU_stack_underflow(fetchdat, 0, 0); + goto next_ins; + } + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = extF80_roundToInt(FPU_read_regi(0), softfloat_round_near_maxMag, true, &status); + + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { + FPU_save_regi(result, 0); + } + +next_ins: + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +sf_FRINEAR(uint32_t fetchdat) +{ + floatx80 result; + struct softfloat_status_t status; + + FP_ENTER(); + FPU_check_pending_exceptions(); + cpu_state.pc++; + clear_C1(); + if (IS_TAG_EMPTY(0)) { + FPU_stack_underflow(fetchdat, 0, 0); + goto next_ins; + } + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = extF80_roundToInt(FPU_read_regi(0), softfloat_round_near_even, true, &status); + + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { + FPU_save_regi(result, 0); + } + +next_ins: + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +sf_FRICHOP(uint32_t fetchdat) +{ + floatx80 result; + struct softfloat_status_t status; + + FP_ENTER(); + FPU_check_pending_exceptions(); + cpu_state.pc++; + clear_C1(); + if (IS_TAG_EMPTY(0)) { + FPU_stack_underflow(fetchdat, 0, 0); + goto next_ins; + } + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = extF80_roundToInt(FPU_read_regi(0), softfloat_round_to_zero, true, &status); + + if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0)) { + FPU_save_regi(result, 0); + } + +next_ins: + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} diff --git a/src/cpu/x87_ops_sf_compare.h b/src/cpu/x87_ops_sf_compare.h index 945ed99d3..d1d9bc1dd 100644 --- a/src/cpu/x87_ops_sf_compare.h +++ b/src/cpu/x87_ops_sf_compare.h @@ -459,6 +459,32 @@ sf_FTST(uint32_t fetchdat) return 0; } +static int +sf_FTSTP(uint32_t fetchdat) +{ + const floatx80 Const_Z = packFloatx80(0, 0x0000, 0); + struct softfloat_status_t status; + int rc; + + FP_ENTER(); + FPU_check_pending_exceptions(); + cpu_state.pc++; + clear_C1(); + if (IS_TAG_EMPTY(0)) { + FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); + setcc(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); + } else { + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + rc = extF80_compare_normal(FPU_read_regi(0), Const_Z, &status); + setcc(FPU_status_word_flags_fpu_compare(rc)); + FPU_exception(fetchdat, status.softfloat_exceptionFlags, 0); + FPU_pop(); + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); + return 0; +} + static int sf_FXAM(UNUSED(uint32_t fetchdat)) { diff --git a/src/video/vid_ps55da2.c b/src/video/vid_ps55da2.c index 31559cc52..823ef4d2f 100644 --- a/src/video/vid_ps55da2.c +++ b/src/video/vid_ps55da2.c @@ -10,7 +10,7 @@ * * Notes: There are some known issues that should be corrected. * - Incorrect foreground text color appears on an active window in OS/2 J1.3. - * - BitBlt's text drawing function does not work correctly. + * - Glitches some part of graphics on the Control Panel in OS/2 J2.1 beta. * - The screen resolution and blanking interval time maybe not correct. * * The code should be tested with following cases. @@ -50,20 +50,29 @@ #define DA2_FONTROM_PATH_JPAN "roms/video/da2/94X1320.BIN" #define DA2_FONTROM_PATH_HANT "roms/video/da2/23F2698.BIN" -#define DA2_FONTROM_SIZE 1536 * 1024 +#define DA2_FONTROM_SIZE (1536 * 1024) #define DA2_FONTROM_BASESBCS 0x98000 #define DA2_GAIJIRAM_SBCS 0x34000 #define DA2_GAIJIRAM_SBEX 0x3c000 -#define DA2_INVALIDACCESS8 0xff +#define DA2_VM03_BASECHR 0x18000 +#define DA2_VM03_BASEEXATTR 0x10000 +#define DA2_INVALIDACCESS8 0xffu +#define DA2_INVALIDACCESS16 0xffffu +#define DA2_INVALIDACCESS32 0xffffffffu #define DA2_MASK_MMIO 0x1ffff -#define DA2_MASK_GRAM 0x1ffff -#define DA2_MASK_CRAM 0xfff -#define DA2_MASK_GAIJIRAM 0x3ffff -#define DA2_PIXELCLOCK 58000000.0 +#define DA2_SIZE_VRAM (1024 * 1024) /* 0x100000 */ +#define DA2_SIZE_CRAM (4 * 1024) /* 0x1000 */ +#define DA2_SIZE_GAIJIRAM (256 * 1024) /* 0x40000 */ +#define DA2_MASK_A000 0x1ffff /* 0x1FFFF */ +#define DA2_MASK_CRAM 0xfff /* 0xFFF */ +#define DA2_MASK_GAIJIRAM 0x3ffff /* 0x3FFFF */ +#define DA2_MASK_VRAM 0xfffff /* 0xFFFFF */ +#define DA2_MASK_VRAMPLANE 0x1ffff /* 0x1FFFF */ +#define DA2_PIXELCLOCK 29000000.0 /* 58 MHz interlaced */ #define DA2_BLT_MEMSIZE 0x100 #define DA2_BLT_REGSIZE 0x40 #define DA2_DEBUG_BLTLOG_SIZE (DA2_BLT_REGSIZE + 1) -#define DA2_DEBUG_BLTLOG_MAX 256 * 1024 +#define DA2_DEBUG_BLTLOG_MAX (256 * 1024) #define DA2_DEBUG_BLT_NEVERUSED 0xfefefefe #define DA2_DEBUG_BLT_USEDRESET 0xfefefe #define DA2_DCONFIG_CHARSET_JPAN 0 /* for Code page 932 Japanese */ @@ -82,8 +91,9 @@ #define DA2_BLT_CCOPYF 3 #define DA2_BLT_CCOPYR 4 #define DA2_BLT_CPUTCHAR 5 -#define DA2_BLT_CDONE 6 -#define DA2_BLT_CLOAD 7 +#define DA2_BLT_CLINE 6 +#define DA2_BLT_CDONE 7 +#define DA2_BLT_CLOAD 8 /* POS ID = 0xeffe : Display Adapter II, III, V */ #define DA2_POSID_H 0xef #define DA2_POSID_L 0xfe @@ -247,8 +257,10 @@ #endif #ifdef ENABLE_DA2_LOG -# define ENABLE_DA2_DEBUGBLT 1 +// # define ENABLE_DA2_DEBUGBLT 1 +# define ENABLE_DA2_DEBUGVRAM 1 // # define ENABLE_DA2_DEBUGFULLSCREEN 1 +// # define ENABLE_DA2_DEBUGMONWAIT 1 int da2_do_log = ENABLE_DA2_LOG; static void @@ -265,6 +277,11 @@ da2_log(const char *fmt, ...) #else # define da2_log(fmt, ...) #endif +#ifdef ENABLE_DA2_DEBUGBLT +# define da2_bltlog da2_log +#else +# define da2_bltlog(fmt, ...) +#endif typedef struct da2_t { // mem_mapping_t vmapping; @@ -291,7 +308,6 @@ typedef struct da2_t { uint32_t decode_mask; uint32_t vram_max; - uint32_t vram_mask; uint32_t gdcla[8]; uint32_t gdcinput[8]; @@ -311,7 +327,7 @@ typedef struct da2_t { int fast; uint8_t colourcompare, colournocare; int readmode, writemode, readplane; - uint8_t writemask; + uint8_t planemask; uint32_t charseta, charsetb; uint8_t egapal[16]; @@ -350,13 +366,11 @@ typedef struct da2_t { // uint32_t cram_display_mask; /* APA Buffer A0000-BFFFFh (128 KB) */ uint8_t *vram; - /* addr >> 12 = xx000h */ + /* xxh */ uint8_t *changedvram; /* (vram size - 1) >> 3 = 0x1FFFF */ uint32_t vram_display_mask; - // uint32_t write_bank, read_bank; - int fullchange; void (*render)(struct da2_t *da2); @@ -370,7 +384,7 @@ typedef struct da2_t { { int enable; mem_mapping_t mapping; - uint8_t ram[256 * 1024]; + uint8_t ram[DA2_SIZE_GAIJIRAM]; uint8_t *font; int charset; } mmio; @@ -379,28 +393,35 @@ typedef struct da2_t { int bitshift_destr; int raster_op; uint8_t payload[DA2_BLT_MEMSIZE]; + int payload_addr; int32_t reg[DA2_BLT_REGSIZE]; // must be signed int #ifdef ENABLE_DA2_DEBUGBLT int32_t *debug_reg; // for debug int debug_reg_ip; // for debug + int debug_exesteps; #endif - int payload_addr; pc_timer_t timer; int64_t timerspeed; int exec; int indata; int32_t destaddr; int32_t srcaddr; - int32_t size_x, tile_w; - int32_t size_y; + int16_t size_x; + int16_t tile_w; + int16_t size_y; + int16_t dest_x; + int16_t dest_y; int16_t destpitch; int16_t srcpitch; int32_t fcolor; int32_t maskl, maskr; - int x, y; + int32_t count; + int32_t d; + int octdir; + int x, y, wx1, wx2, wy1, wy2; } bitblt; -#ifdef ENABLE_DA2_DEBUGBLT +#ifdef ENABLE_DA2_DEBUGVRAM FILE *mmdbg_fp; FILE *mmrdbg_fp; uint32_t mmdbg_vidaddr; @@ -410,6 +431,7 @@ typedef struct da2_t { uint8_t pos_regs[8]; svga_t *mb_vga; uint8_t monitorid; + pc_timer_t timer_vidupd; int old_pos2; } da2_t; @@ -420,6 +442,7 @@ void da2_bitblt_exec(void *p); void da2_updatevidselector(da2_t *da2); void da2_reset_ioctl(da2_t *da2); static void da2_reset(void *priv); +uint16_t rightRotate(uint16_t data, uint8_t count); typedef union { uint32_t d; @@ -432,40 +455,51 @@ typedef struct { /* safety read for internal functions */ uint32_t -DA2_readvram_s(uint32_t addr, da2_t *da2) +DA2_vram_r(uint32_t addr, da2_t *da2) { - if (addr & ~da2->vram_mask) - return -1; + if (addr & ~DA2_MASK_VRAM) + return DA2_INVALIDACCESS32; return da2->vram[addr]; } - +/* safety write for internal functions */ +void +DA2_vram_w(uint32_t addr, uint8_t val, da2_t *da2) +{ + if (addr & ~DA2_MASK_VRAM) + return; + da2->vram[addr] = val; + return; +} +/* write pixel data with rop (Note: bitmask must be in big endian) */ void DA2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *srcpx, da2_t *da2) { uint32_t writepx[8]; destaddr &= 0xfffffffe; /* align to word address to work bit shift correctly */ // da2_log("DA2_WPDWB addr %x mask %x rop %x shift %d\n", destaddr, mask, da2->bitblt.raster_op, da2->bitblt.bitshift_destr); - da2->changedvram[(da2->vram_display_mask & destaddr) >> 12] = changeframecount; - da2->changedvram[(da2->vram_display_mask & (destaddr + 1)) >> 12] = changeframecount; + da2->changedvram[(DA2_MASK_VRAMPLANE & destaddr) >> 9] = changeframecount; destaddr <<= 3; /* read destination data with big endian order */ for (int i = 0; i < 8; i++) - writepx[i] = DA2_readvram_s((destaddr + 24) | i, da2) - | (DA2_readvram_s((destaddr + 16) | i, da2) << 8) - | (DA2_readvram_s((destaddr + 8) | i, da2) << 16) - | (DA2_readvram_s((destaddr + 0) | i, da2) << 24); + writepx[i] = DA2_vram_r((destaddr + 24) | i, da2) + | (DA2_vram_r((destaddr + 16) | i, da2) << 8) + | (DA2_vram_r((destaddr + 8) | i, da2) << 16) + | (DA2_vram_r((destaddr + 0) | i, da2) << 24); DA2_VidSeq32 mask32in; mask32in.d = (uint32_t) mask; DA2_VidSeq32 mask32; - mask32.d = 0; mask32.b[3] = mask32in.b[0]; mask32.b[2] = mask32in.b[1]; mask32.d &= 0xffff0000; for (int i = 0; i < 8; i++) { if (da2->bitblt.bitshift_destr > 0) srcpx->p8[i] <<= 16 - da2->bitblt.bitshift_destr; - switch (da2->bitblt.raster_op) { + if (da2->bitblt.raster_op & 0x2010) /* NOT Src or NOT Pattern */ + srcpx->p8[i] = ~srcpx->p8[i] & mask32.d; + if (da2->bitblt.raster_op & 0x20) /* Dest NOT */ + writepx[i] = (~writepx[i] & mask32.d) | (writepx[i] & ~mask32.d); + switch (da2->bitblt.raster_op & 0x03) { case 0x00: /* None */ writepx[i] &= ~mask32.d; writepx[i] |= srcpx->p8[i] & mask32.d; @@ -482,8 +516,8 @@ DA2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s } } for (int i = 0; i < 8; i++) { - da2->vram[(da2->vram_mask & destaddr) | i] = (writepx[i] >> 24) & 0xff; - da2->vram[(da2->vram_mask & (destaddr + 8)) | i] = (writepx[i] >> 16) & 0xff; + DA2_vram_w(destaddr | i, (writepx[i] >> 24) & 0xff, da2); + DA2_vram_w((destaddr + 8) | i, (writepx[i] >> 16) & 0xff, da2); } } @@ -502,13 +536,19 @@ Param Desc 01 Color 03 Bit Shift 04 Select plane? -05 Dir(10 or 11) + Command?(40 or 48) +05 Dir(1000h or 1100h) + Command?(40 or 48) 08 Mask Left 09 Mask Right 0A Plane Mask? -0B ROP?(8h or 200h + 0-3h) +0B ROP + 2000 NOT Source + 200 Source / Pattern + 20 NOT Dest + 10 NOT Pattern + 8 ? + 0-3 Bit op (0 None, 1 AND, 2 OR, 3 XOR) 0D -20 Exec (1) +20 Exec (1) or Exec without reset regs? (21h) 21 ? 22 ? 23 Tile W @@ -526,10 +566,10 @@ DA2_CopyPlaneDataWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, srcaddr &= 0xfffffffe; srcaddr <<= 3; for (int i = 0; i < 8; i++) - srcpx.p8[i] = DA2_readvram_s((srcaddr + 24) | i, da2) - | (DA2_readvram_s((srcaddr + 16) | i, da2) << 8) - | (DA2_readvram_s((srcaddr + 8) | i, da2) << 16) - | (DA2_readvram_s((srcaddr + 0) | i, da2) << 24); + srcpx.p8[i] = DA2_vram_r((srcaddr + 24) | i, da2) + | (DA2_vram_r((srcaddr + 16) | i, da2) << 8) + | (DA2_vram_r((srcaddr + 8) | i, da2) << 16) + | (DA2_vram_r((srcaddr + 0) | i, da2) << 24); DA2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); } @@ -555,7 +595,7 @@ pixel1tohex(uint32_t addr, int index, da2_t *da2) { uint8_t pixeldata = 0; for (int j = 0; j < 8; j++) { - if (da2->vram[(da2->vram_mask & (addr << 3)) | j] & (1 << (7 - index))) + if (DA2_vram_r(((addr << 3) | j) & (1 << (7 - index)), da2)) pixeldata++; } return pixeldata; @@ -578,7 +618,7 @@ print_bytetobin(uint8_t b) b <<= 1; } } -// Convert internal char code to Shift JIS code +/* Convert internal char code to Shift JIS code */ inline int isKanji1(uint8_t chr) { @@ -625,17 +665,19 @@ da2_bitblt_load(da2_t *da2) { uint32_t value32; uint64_t value64; +#ifdef ENABLE_DA2_DEBUGBLT da2_log("bltload: loading params\n"); - // da2_log("BitBlt memory:\n"); - // if (da2->bitblt.payload[0] != 0) - // for (int j = 0; j < DA2_BLT_MEMSIZE / 8; j++) - // { - // int i = j * 8; - // da2_log("%02x %02x %02x %02x %02x %02x %02x %02x \n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], - // da2->bitblt.payload[i + 4], da2->bitblt.payload[i + 5], da2->bitblt.payload[i + 6], da2->bitblt.payload[i + 7]); - // } + da2_log("BitBlt memory:\n"); + if (da2->bitblt.payload[0] != 0) + for (int j = 0; j < DA2_BLT_MEMSIZE / 8; j++) + { + int i = j * 8; + da2_log("%02x %02x %02x %02x %02x %02x %02x %02x \n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], + da2->bitblt.payload[i + 4], da2->bitblt.payload[i + 5], da2->bitblt.payload[i + 6], da2->bitblt.payload[i + 7]); + } +#endif int i = 0; - while (i < DA2_BLT_MEMSIZE) { + while (i < da2->bitblt.payload_addr) { if (da2->bitblt.reg[0x20] & 0x1) break; switch (da2->bitblt.payload[i]) { @@ -645,8 +687,9 @@ da2_bitblt_load(da2_t *da2) value32 = da2->bitblt.payload[i + 3]; value32 <<= 8; value32 |= da2->bitblt.payload[i + 2]; - da2_log("[%02x] %02x: %04x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); + da2_bltlog("[%02x] %02x: %04x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value32; + // da2->gdcreg[da2->bitblt.payload[i + 1]] = value32; i += 3; break; case 0x91: @@ -657,8 +700,9 @@ da2_bitblt_load(da2_t *da2) value32 |= da2->bitblt.payload[i + 3]; value32 <<= 8; value32 |= da2->bitblt.payload[i + 2]; - da2_log("[%02x] %02x: %08x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); + da2_bltlog("[%02x] %02x: %08x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value32; + // da2->gdcreg[da2->bitblt.payload[i + 1]] = value32; i += 5; break; case 0x99: @@ -673,9 +717,10 @@ da2_bitblt_load(da2_t *da2) value64 |= da2->bitblt.payload[i + 3]; value64 <<= 8; value64 |= da2->bitblt.payload[i + 2]; - da2_log("[%02x] %02x: %02x %02x %02x %02x %02x %02x\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], + da2_bltlog("[%02x] %02x: %02x %02x %02x %02x %02x %02x\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], da2->bitblt.payload[i + 4], da2->bitblt.payload[i + 5], da2->bitblt.payload[i + 6], da2->bitblt.payload[i + 7]); da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value64; + // da2->gdcreg[da2->bitblt.payload[i + 1]] = value64; i += 7; break; case 0x00: @@ -687,36 +732,24 @@ da2_bitblt_load(da2_t *da2) i++; } da2->bitblt.exec = DA2_BLT_CIDLE; - // /* clear payload memory */ - // memset(da2->bitblt.payload, 0x00, DA2_BLT_MEMSIZE); - // da2->bitblt.payload_addr = 0; + /* clear payload memory */ + memset(da2->bitblt.payload, 0x00, DA2_BLT_MEMSIZE); + da2->bitblt.payload_addr = 0; /* [89] 20: 0001 (1) then execute payload */ if (da2->bitblt.reg[0x20] & 0x1) { - /* clear payload memory */ - memset(da2->bitblt.payload, 0x00, DA2_BLT_MEMSIZE); - da2->bitblt.payload_addr = 0; #ifdef ENABLE_DA2_DEBUGBLT - for (i = 0; i < DA2_DEBUG_BLTLOG_SIZE; i++) { - // if(da2->bitblt.reg[i] != 0xfefe && da2->bitblt.reg[i] != DA2_DEBUG_BLT_NEVERUSED) da2_log("%02x: %04x (%d)\n",i, da2->bitblt.reg[i], da2->bitblt.reg[i]); - } for (i = 0; i < DA2_DEBUG_BLTLOG_SIZE; i++) { da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip + i] = da2->bitblt.reg[i]; } da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * (da2->bitblt.debug_reg_ip + 1) - 1] = 0; da2->bitblt.debug_reg_ip++; - if (da2->bitblt.debug_reg_ip >= DA2_DEBUG_BLTLOG_MAX) + if ((DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip) >= DA2_DEBUG_BLTLOG_MAX) da2->bitblt.debug_reg_ip = 0; + da2->bitblt.debug_exesteps = 0; #endif - da2->bitblt.bitshift_destr = ((da2->bitblt.reg[0x3] >> 4) & 0x0f); /* set bit shift */ - da2->bitblt.raster_op = da2->bitblt.reg[0x0b] & 0x03; /* 01 AND, 03 XOR */ da2_log("bltload_exec: %x, rop: %x CS:PC=%4x:%4x\n", da2->bitblt.reg[0x5], da2->bitblt.reg[0x0b], CS, cpu_state.pc); - // for (int i = 0; i <= 0xb; i++) - // { - // da2_log("%02x ", da2->gdcreg[i]); - // da2->gdcreg[i] = da2->bitblt.reg[i] & 0xff; - // } - // da2_log("\n"); - + da2->bitblt.bitshift_destr = ((da2->bitblt.reg[0x3] >> 4) & 0x0f); /* set bit shift */ + da2->bitblt.raster_op = da2->bitblt.reg[0x0b]; da2->bitblt.destaddr = da2->bitblt.reg[0x29]; da2->bitblt.size_x = da2->bitblt.reg[0x33]; da2->bitblt.size_y = da2->bitblt.reg[0x35]; @@ -735,13 +768,9 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.x = 0; da2->bitblt.y = 0; da2->bitblt.exec = DA2_BLT_CDONE; - timer_set_delay_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); - if (da2->bitblt.reg[0x2f] < 0x80) /* MS Paint 3.1 will cause hang up in 256 color mode */ - { - da2_log("bitblt not executed 2f:%x\n", da2->bitblt.reg[0x2f]); - da2->bitblt.exec = DA2_BLT_CDONE; - } else if (da2->bitblt.reg[0x10] == 0xbc04) { /* Put char used by OS/2 (i'm not sure what the condition is) */ + /* Put DBCS char used by OS/2 (i'm not sure what the condition is) */ + if (da2->bitblt.reg[0x10] == 0xbc04) { da2->bitblt.exec = DA2_BLT_CPUTCHAR; /* Todo: addressing */ // if (da2->bitblt.reg[0x2F] == 0x90) /* destaddr -= 2, length += 1; */ @@ -754,22 +783,6 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 72 + 2; da2->bitblt.destaddr += 2; da2->bitblt.srcpitch = 0; - da2->bitblt.raster_op = da2->bitblt.reg[0x05] & 0x03; /* XOR */ - da2->bitblt.bitshift_destr += 1; -#ifdef ENABLE_DA2_DEBUGBLT - uint32_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; - uint32_t sjis_l = IBMJtoSJIS(da2->bitblt.reg[0x12]) & 0xff; - da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d, c=%c%c\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); -#endif - } else if (da2->bitblt.reg[0x10] == 0x0004 || da2->bitblt.reg[0x10] == 0x0E04) { - da2->bitblt.exec = DA2_BLT_CPUTCHAR; - da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 64 + 2 + DA2_FONTROM_BASESBCS; - da2->bitblt.destaddr += 2; - da2->bitblt.srcpitch = 0; - da2->bitblt.raster_op = da2->bitblt.reg[0x05] & 0x03; /* XOR */ da2->bitblt.bitshift_destr += 1; #ifdef ENABLE_DA2_DEBUGBLT uint32_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; @@ -780,7 +793,53 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); #endif } - /* Fill a rectangle(or draw a line) */ + /* Put SBCS char used by OS/2 */ + else if (da2->bitblt.reg[0x10] == 0x0004 || da2->bitblt.reg[0x10] == 0x0E04) { + da2->bitblt.exec = DA2_BLT_CPUTCHAR; + da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 64 + 2 + DA2_FONTROM_BASESBCS; + da2->bitblt.destaddr += 2; + da2->bitblt.srcpitch = 0; + da2->bitblt.bitshift_destr += 1; +#ifdef ENABLE_DA2_DEBUGBLT + uint32_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; + uint32_t sjis_l = IBMJtoSJIS(da2->bitblt.reg[0x12]) & 0xff; + da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d, c=%c%c\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); +#endif + } + /* Draw a line */ + else if (da2->bitblt.reg[0x5] == 0x43) { + da2->bitblt.exec = DA2_BLT_CLINE; + da2->bitblt.dest_x = (da2->bitblt.reg[0x32] & 0xffff); + da2->bitblt.dest_y = (da2->bitblt.reg[0x34] & 0xffff); + da2->bitblt.wx1 = (da2->bitblt.reg[0x32]) >> 16; + da2->bitblt.wx2 = (da2->bitblt.reg[0x33]) >> 16; + da2->bitblt.wy1 = (da2->bitblt.reg[0x34]) >> 16; + da2->bitblt.wy2 = (da2->bitblt.reg[0x35]) >> 16; + da2->bitblt.size_x = abs((int16_t)(da2->bitblt.reg[0x33] & 0xffff) - da2->bitblt.dest_x); + da2->bitblt.size_y = abs((int16_t)(da2->bitblt.reg[0x35] & 0xffff) - da2->bitblt.dest_y); + da2->bitblt.count = 0; + da2->bitblt.octdir = da2->bitblt.reg[0x2D]; + da2->bitblt.bitshift_destr = 0; + if (da2->bitblt.octdir & 0x04) /* dX > dY */ + da2->bitblt.d = 2 * da2->bitblt.size_y - da2->bitblt.size_x; + else + da2->bitblt.d = 2 * da2->bitblt.size_x - da2->bitblt.size_y; + da2->bitblt.x = da2->bitblt.dest_x; + da2->bitblt.y = da2->bitblt.dest_y; + da2_log("drawline x=%d, y=%d, dx=%d, dy=%d, oct=%dn", + da2->bitblt.dest_x, da2->bitblt.dest_y, + da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.octdir); + da2_log(" x1=%d, x2=%d, y1=%d, y2=%d\n", + da2->bitblt.reg[0x32] & 0x7ff, da2->bitblt.reg[0x33] & 0x7ff, + da2->bitblt.reg[0x34] & 0x7ff, da2->bitblt.reg[0x35] & 0x7ff); + da2_log(" ux1=%d,ux2=%d,uy1=%d,uy2=%d\n", + (da2->bitblt.reg[0x32] >> 16) & 0x7ff, (da2->bitblt.reg[0x33] >> 16) & 0x7ff, + (da2->bitblt.reg[0x34] >> 16) & 0x7ff, (da2->bitblt.reg[0x35] >> 16) & 0x7ff); + } + /* Fill a rectangle (or draw a horizontal / vertical line) */ else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x40 && da2->bitblt.reg[0x3D] == 0) { da2_log("fillrect x=%d, y=%d, w=%d, h=%d, c=%d, 2f=%x, rowcount=%x\n", da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), @@ -812,7 +871,7 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y); } - /* Block transfer (range copy) */ + /* Block copy */ else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x00) { da2->bitblt.exec = DA2_BLT_CCOPYF; da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; @@ -843,15 +902,75 @@ da2_bitblt_exec(void *p) { da2_t *da2 = (da2_t *) p; // timer_set_delay_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); - da2_log("bitblt_exec: %d\n", da2->bitblt.exec); - // da2_log("blt %x %x %x %x\n", da2->bitblt.destaddr, da2->bitblt.x, da2->bitblt.y); +#ifdef ENABLE_DA2_DEBUGBLT + if(!(da2->bitblt.debug_exesteps & 0xff)) + da2_log("bitblt_exec: %d %d\n", da2->bitblt.exec, da2->bitblt.debug_exesteps); + da2->bitblt.debug_exesteps++; +#endif switch (da2->bitblt.exec) { case DA2_BLT_CIDLE: // timer_disable(&da2->bitblt.timer); break; case DA2_BLT_CLOAD: - da2->bitblt.indata = 0; da2_bitblt_load(da2); + da2->bitblt.indata = 0; + break; + case DA2_BLT_CLINE: + /* Draw a dot */ + // outb(0x680, da2->bitblt.octdir); + da2_bltlog("point: %d %d %d %d %d\n", da2->bitblt.x, da2->bitblt.y, da2->bitblt.d, da2->bitblt.x, da2->bitblt.y); + int destaddr = da2->bitblt.y * (da2->rowoffset * 2) + da2->bitblt.x / 8; + int pixelmask = da2->bitblt.x % 16; + if (pixelmask >= 8) + pixelmask = (0x8000 >> (pixelmask - 8)); + else + pixelmask = (0x80 >> pixelmask); + + /* check the current position is inside the window */ + if (da2->bitblt.x < da2->bitblt.wx1 || da2->bitblt.x > da2->bitblt.wx2 + || da2->bitblt.y < da2->bitblt.wy1 || da2->bitblt.y > da2->bitblt.wy2) + ; + else + DA2_DrawColorWithBitmask(destaddr, da2->bitblt.fcolor, pixelmask, da2); + // da2_log("draw: %x %x %x\n", destaddr, da2->bitblt.fcolor, pixelmask); + da2->bitblt.count++; + + /* calculate the next position with Bresenham's line algorithm */ + if (da2->bitblt.octdir & 0x04) { /* dX > dY */ + if (da2->bitblt.octdir & 0x02) { + da2->bitblt.x++; + } else { + da2->bitblt.x--; + } + if (da2->bitblt.d >= 0) { + da2->bitblt.d -= (2 * da2->bitblt.size_x); + if (da2->bitblt.octdir & 0x01) { + da2->bitblt.y++; + } else { + da2->bitblt.y--; + } + } + da2->bitblt.d += (2 * da2->bitblt.size_y); + if (da2->bitblt.count >= da2->bitblt.size_x) + da2->bitblt.exec = DA2_BLT_CDONE; + } else { + if (da2->bitblt.octdir & 0x01) { + da2->bitblt.y++; + } else { + da2->bitblt.y--; + } + if (da2->bitblt.d >= 0) { + da2->bitblt.d -= (2 * da2->bitblt.size_y); + if (da2->bitblt.octdir & 0x02) { + da2->bitblt.x++; + } else { + da2->bitblt.x--; + } + } + da2->bitblt.d += (2 * da2->bitblt.size_x); + if (da2->bitblt.count >= da2->bitblt.size_y) + da2->bitblt.exec = DA2_BLT_CDONE; + } break; case DA2_BLT_CFILLRECT: // da2_log("%x %x %x\n", da2->bitblt.destaddr, da2->bitblt.x, da2->bitblt.y); @@ -970,11 +1089,14 @@ da2_bitblt_exec(void *p) // da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 72 + (da2->bitblt.x * 2 ) + (da2->bitblt.y * 3) + 2; break; case DA2_BLT_CDONE: - /* initialize regs for debug dump */ - for (int i = 0; i < DA2_BLT_REGSIZE; i++) { - if (da2->bitblt.reg[i] != DA2_DEBUG_BLT_NEVERUSED) - da2->bitblt.reg[i] = DA2_DEBUG_BLT_USEDRESET; - } + if (!(da2->bitblt.reg[0x20] & 0x20)) { + /* initialize regs and set magic value for debug dump */ + for (int i = 0; i < DA2_BLT_REGSIZE; i++) { + if (da2->bitblt.reg[i] != DA2_DEBUG_BLT_NEVERUSED) + da2->bitblt.reg[i] = DA2_DEBUG_BLT_USEDRESET; + } + } else /* without init regs */ + da2->bitblt.reg[0x20] = 0; /* need to stop execution */ if (da2->bitblt.indata) da2->bitblt.exec = DA2_BLT_CLOAD; else @@ -987,26 +1109,15 @@ da2_bitblt_dopayload(void *priv) { da2_t *da2 = (da2_t *) priv; timer_set_delay_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); - // if (da2->bitblt.indata) /* for OS/2 J1.3 */ - // { - // if (da2->bitblt.exec == DA2_BLT_CIDLE) { - // da2->bitblt.exec = DA2_BLT_CLOAD; - // /* do all queues (ignore async executing) for OS/2 J1.3 commannd prompt that doesn't wait for idle */ - // da2_log("da2 Do bitblt\n"); - // while (da2->bitblt.exec != DA2_BLT_CIDLE) { - // da2_bitblt_exec(da2); - // } - // da2_log("da2 End bitblt %x\n", da2->bitblt.exec); - // } - // } - if (da2->bitblt.exec != DA2_BLT_CIDLE) - da2_bitblt_exec(da2); - else if (da2->bitblt.indata) /* for OS/2 J1.3 */ - { - if (da2->bitblt.exec == DA2_BLT_CIDLE) { - da2->bitblt.exec = DA2_BLT_CLOAD; + /* do async operation but it causes the scrolling text glitch in OS/2 J1.3 Command Prompt (TODO) */ + if (da2->bitblt.exec != DA2_BLT_CIDLE) { + while (da2->bitblt.exec != DA2_BLT_CIDLE) /* this disables async operation */ da2_bitblt_exec(da2); - } + } else if (da2->bitblt.indata && !(da2->ioctl[LS_MMIO] & 0x10) && (da2->bitblt.exec == DA2_BLT_CIDLE)) { + da2->bitblt.exec = DA2_BLT_CLOAD; + da2_bitblt_exec(da2); + } else { + // timer_disable(&da2->bitblt.timer); } } @@ -1094,8 +1205,7 @@ da2_out(uint16_t addr, uint16_t val, void *p) oldval = da2->fctl[da2->fctladdr]; da2->fctl[da2->fctladdr] = val; if (da2->fctladdr == 0 && oldval != val) { - da2->fullchange = changeframecount; - da2_recalctimings(da2); + da2_log("DA2 Out FCTL addr %03X idx %02X val %02X %04X:%04X\n", addr, da2->fctladdr, val, cs >> 4, cpu_state.pc); } break; case LC_INDEX: @@ -1104,8 +1214,8 @@ da2_out(uint16_t addr, uint16_t val, void *p) case LC_DATA: if (da2->crtcaddr > 0x1f) return; - // if (!(da2->crtcaddr == LC_CURSOR_LOC_HIGH || da2->crtcaddr == LC_CURSOR_LOC_LOWJ)) - // da2_log("DA2 Out addr %03X idx %02X val %02X %04X:%04X\n", addr, da2->crtcaddr, val, cs >> 4, cpu_state.pc); + if (!(da2->crtcaddr == LC_CURSOR_LOC_HIGH || da2->crtcaddr == LC_CURSOR_LOC_LOWJ)) + da2_log("DA2 Out addr %03X idx %02X val %02X %04X:%04X\n", addr, da2->crtcaddr, val, cs >> 4, cpu_state.pc); if (!(da2->crtc[da2->crtcaddr] ^ val)) return; switch (da2->crtcaddr) { @@ -1117,7 +1227,10 @@ da2_out(uint16_t addr, uint16_t val, void *p) val = 0; break; case LC_START_ADDRESS_HIGH: - // if (da2->crtc[0x1c] & 0x40) return; + case LC_START_ADDRESS_LOW: + /* The DOS J4.0 MODE 4 command and OS/2 driver write 0xFF00. + OS/2 DOS MODE 1 setup reads this to set the base line, but it causes the screen glitch. */ + val = 0; break; case LC_VERTICAL_TOTALJ: /* Vertical Total */ case LC_VERTICAL_SYNC_START: /* Vertical Retrace Start Register */ @@ -1138,8 +1251,8 @@ da2_out(uint16_t addr, uint16_t val, void *p) case LC_H_DISPLAY_ENABLE_END: case LC_VERTICAL_TOTALJ: case LC_MAXIMUM_SCAN_LINE: - case LC_START_ADDRESS_HIGH: - case LC_START_ADDRESS_LOW: + // case LC_START_ADDRESS_HIGH: + // case LC_START_ADDRESS_LOW: case LC_VERTICAL_SYNC_START: case LC_V_DISPLAY_ENABLE_END: case LC_START_VERTICAL_BLANK: @@ -1217,20 +1330,27 @@ da2_out(uint16_t addr, uint16_t val, void *p) da2->attrc[da2->attraddr & 0x3f] = val; break; case LG_INDEX: + da2_log("DA2 Out addr %03X val %02X\n", addr, val); da2->gdcaddr = val; break; case LG_DATA: - // if(da2->gdcaddr != 8 && da2->gdcaddr != 9) da2_log("DA2 Out addr %03X idx %02X val %02X\n", addr, da2->gdcaddr, val); - // if(da2->gdcaddr != 8 && da2->gdcaddr != 9) da2_log("DA2 GCOut idx %X val %02X %04X:%04X esdi %04X:%04X\n", da2->gdcaddr, val, cs >> 4, cpu_state.pc, ES, DI); + // if(da2->gdcaddr != 8 && da2->gdcaddr != 9) da2_log("DA2 GCOut idx %X val %02X %04X:%04X esdi %04X:%04X\n", da2->gdcaddr, val, cs >> 4, cpu_state.pc, ES, DI); + da2_log("DA2 Out addr %03X idx %02X val %02X\n", addr, da2->gdcaddr, val); + da2->gdcreg[da2->gdcaddr & 0x0f] = val & 0xff; switch (da2->gdcaddr & 0x1f) { case LG_READ_MAP_SELECT: da2->readplane = val & 0x7; break; case LG_MODE: da2->writemode = val & 3; + /* Resettting masks here gliches chart drawing in IBM Multitool Chart K3.1 */ + // da2->gdcreg[LG_BIT_MASK_LOW] = 0xff; + // da2->gdcreg[LG_BIT_MASK_HIGH] = 0xff; + // da2->planemask = 0xff; + // da2->gdcreg[LG_MAP_MASKJ] = 0xff; break; case LG_MAP_MASKJ: - da2->writemask = val & 0xff; + da2->planemask = val & 0xff; break; case LG_COMMAND: break; @@ -1238,7 +1358,6 @@ da2_out(uint16_t addr, uint16_t val, void *p) da2_log("!!!DA2 GC Out addr %03X idx 10 val %02X\n", addr, val); return; } - da2->gdcreg[da2->gdcaddr & 0x0f] = val & 0xff; break; // case 0x3ed: /* used by Windows 3.1 display driver */ // da2->gdcreg[5] = val & 0xff; @@ -1292,7 +1411,7 @@ da2_in(uint16_t addr, void *p) case LS_DATA: // da2->ioctl[3] = 0x80; /* 3E1h:3 bit 7 color monitor, bit 3 busy(GC) bit 0 busy (IO?) */ if (da2->ioctladdr > 0xf) - return DA2_INVALIDACCESS8; + return DA2_INVALIDACCESS16; temp = da2->ioctl[da2->ioctladdr]; if (da2->ioctladdr == LS_STATUS) { /* Status register */ if (da2->attrc[LV_COMPATIBILITY] & 0x08) { /* for detecting monitor type and cable wiring */ @@ -1314,7 +1433,7 @@ da2_in(uint16_t addr, void *p) temp |= 0x80; } temp &= 0xf6; /* clear busy bit */ - // if (da2->bitblt.indata) /* for OS/2 J1.3 */ + // if (da2->bitblt.indata) /* for OS/2 J1.3 command prompt scrolling */ // da2_bitblt_dopayload(da2); if (da2->bitblt.exec != DA2_BLT_CIDLE) { // da2_log("exec:%x\n", da2->bitblt.exec); @@ -1325,18 +1444,18 @@ da2_in(uint16_t addr, void *p) // timer_advance_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); // } } - if (da2->bitblt.indata) - temp |= 0x08; - da2_log("DA2 In %04X(%02X) %04X %04X:%04X\n", addr, da2->ioctladdr,temp, cs >> 4, cpu_state.pc); + if (da2->bitblt.indata) temp |= 0x08; +#ifdef ENABLE_DA2_DEBUGMONWAIT + da2_log("DA2 In %04X(%02X) %04X %04X:%04X\n", addr, da2->ioctladdr, temp, cs >> 4, cpu_state.pc); +#endif } - // da2_log("DA2 In %04X(%02X) %04X %04X:%04X\n", addr, da2->ioctladdr,temp, cs >> 4, cpu_state.pc); break; case LF_INDEX: temp = da2->fctladdr; break; case LF_DATA: if (da2->fctladdr > 0x1f) - return DA2_INVALIDACCESS8; + return DA2_INVALIDACCESS16; temp = da2->fctl[da2->fctladdr]; break; case LC_INDEX: @@ -1344,7 +1463,7 @@ da2_in(uint16_t addr, void *p) break; case LC_DATA: if (da2->crtcaddr > 0x1f) - return DA2_INVALIDACCESS8; + return DA2_INVALIDACCESS16; temp = da2->crtc[da2->crtcaddr]; break; case LV_PORT: @@ -1419,7 +1538,7 @@ da2_outb(uint16_t addr, uint8_t val, void *p) void da2_outw(uint16_t addr, uint16_t val, void *p) { - da2_log("DA2 Outw addr %03X val %04X %04X:%04X\n", addr, val, cs >> 4, cpu_state.pc); + da2_log("DA2 Outw addr %03X val %04X\n", addr, val); da2_t *da2 = (da2_t *) p; da2->inflipflop = 0; switch (addr) { @@ -1440,7 +1559,17 @@ da2_outw(uint16_t addr, uint16_t val, void *p) break; case 0x3EC: // da2_log("DA2 Outw addr %03X val %04X %04X:%04X\n", addr, val, cs >> 4, cpu_state.pc); + da2_log(" "); + // val = rightRotate(val, 8); + // da2_out(LG_DATA, val, da2); da2_out(LG_DATA, val >> 8, da2); + /* reset masks for compatibility with Win 3.1 solitaire */ + if (da2->gdcaddr == LG_MODE) { + da2->gdcreg[LG_BIT_MASK_LOW] = 0xff; + da2->gdcreg[LG_BIT_MASK_HIGH] = 0xff; + da2->planemask = 0xff; + da2->gdcreg[LG_MAP_MASKJ] = 0xff; + } break; case 0x3ED: da2->gdcaddr = LG_MODE; @@ -1497,11 +1626,13 @@ da2_inb(uint16_t addr, void *p) uint16_t da2_inw(uint16_t addr, void *p) { - // uint16_t temp; + uint16_t temp; da2_t *da2 = (da2_t *) p; da2->inflipflop = 0; da2->outflipflop = 0; - return da2_in(addr, da2); + temp = da2_in(addr, da2); + da2_log("DA2 Inw addr %03X val %04X\n", addr, temp); + return temp; } /* IO 03DAh : Input Status Register 2 for DOSSHELL used by DOS J4.0 */ uint8_t @@ -1637,14 +1768,13 @@ getfont_ps55dbcs(int32_t code, int32_t line, void *p) if (code >= 0x8000 && code <= 0x8183) code -= 0x6000; /* shift for IBM extended characters (I don't know how the real card works.) */ if (code < DA2_FONTROM_SIZE / 72 && fline >= 0 && fline < 24) { - font = da2->mmio.font[code * 72 + fline * 3]; /* 1111 1111 */ - font <<= 8; /* 1111 1111 0000 0000 */ - font |= da2->mmio.font[code * 72 + fline * 3 + 1] & 0xf0; /* 1111 1111 2222 0000 */ - font >>= 1; /* 0111 1111 1222 2000 */ - font <<= 4; /* 0111 1111 1222 2000 0000 */ - font |= da2->mmio.font[code * 72 + fline * 3 + 1] & 0x0f; /* 0111 1111 1222 2000 2222 */ - font <<= 8; /* 0111 1111 1222 2000 2222 0000 0000 */ - font |= da2->mmio.font[code * 72 + fline * 3 + 2]; /* 0111 1111 1222 2000 2222 3333 3333 */ + font = da2->mmio.font[code * 72 + fline * 3]; /* 0000 0000 0000 0000 0000 0000 1111 1111 */ + font <<= 8; /* 0000 0000 0000 0000 1111 1111 0000 0000 */ + font |= da2->mmio.font[code * 72 + fline * 3 + 1] & 0xf0; /* 0000 0000 0000 0000 1111 1111 2222 0000 */ + font <<= 3; /* 0000 0000 0000 0111 1111 1222 2000 0000 */ + font |= da2->mmio.font[code * 72 + fline * 3 + 1] & 0x0f; /* 0000 0000 0000 0111 1111 1222 2000 2222 */ + font <<= 8; /* 0000 0111 1111 1222 2000 2222 0000 0000 */ + font |= da2->mmio.font[code * 72 + fline * 3 + 2]; /* 0000 0111 1111 1222 2000 2222 3333 3333 */ font <<= 4; /* 0111 1111 1222 2000 2222 3333 3333 0000 */ /* font >>= 1;//put blank at column 1 (and 26) */ } else if (code >= 0xb000 && code <= 0xb75f) { @@ -1690,14 +1820,17 @@ void da2_render_blank(da2_t *da2) { int x, xx; + int cwidth; + if (da2->ioctl[LS_MODE] & 0x01) cwidth = 13; /* in character mode */ + else cwidth = 16; if (da2->firstline_draw == 2000) da2->firstline_draw = da2->displine; da2->lastline_draw = da2->displine; for (x = 0; x < da2->hdisp; x++) { - for (xx = 0; xx < 13; xx++) - ((uint32_t *) buffer32->line[da2->displine])[(x * 13) + xx + 32] = 0; + for (xx = 0; xx < cwidth; xx++) + ((uint32_t *) buffer32->line[da2->displine])[(x * cwidth) + xx + 32] = 0; } } /* Display Adapter Mode 8, E Drawing */ @@ -1719,8 +1852,8 @@ da2_render_text(da2_t *da2) int chr_wide = 0; // da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc); for (x = 0; x < da2->hdisp; x += 13) { - chr = da2->cram[(da2->ma) & da2->vram_display_mask]; - attr = da2->cram[((da2->ma) + 1) & da2->vram_display_mask]; + chr = da2->cram[(da2->ma) & DA2_MASK_CRAM]; + attr = da2->cram[(da2->ma + 1) & DA2_MASK_CRAM]; // if(chr!=0x20) da2_log("chr: %x, attr: %x ", chr, attr); if (da2->attrc[LV_PAS_STATUS_CNTRL] & 0x80) /* IO 3E8h, Index 1Dh */ { /* --Parse attribute byte in color mode-- */ @@ -1760,7 +1893,7 @@ da2_render_text(da2_t *da2) /* Stay drawing If the char code is DBCS and not at last column. */ if (chr_wide) { /* Get high DBCS code from the next video address */ - chr_dbcs = da2->cram[((da2->ma) + 2) & da2->vram_display_mask]; + chr_dbcs = da2->cram[(da2->ma + 2) & DA2_MASK_CRAM]; chr_dbcs <<= 8; chr_dbcs |= chr; /* Get the font pattern */ @@ -1831,7 +1964,7 @@ da2_render_text(da2_t *da2) da2->ma += 2; p += 13; } - da2->ma &= da2->vram_display_mask; + // da2->ma &= DA2_MASK_CRAM; // da2->writelines++; } } @@ -1855,10 +1988,10 @@ da2_render_textm3(da2_t *da2) int chr_wide = 0; // da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc); for (x = 0; x < da2->hdisp; x += 13) { - chr = da2->vram[(0x18000 + (da2->ma)) & da2->vram_mask]; - attr = da2->vram[((0x18000 + (da2->ma)) + 1) & da2->vram_mask]; - extattr = da2->vram[((0x10000 + (da2->ma)) + 1) & da2->vram_mask]; - // if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (0x18000 + da2->ma << 1) & da2->vram_mask, chr, attr); + chr = DA2_vram_r(DA2_VM03_BASECHR + da2->ma, da2); + attr = DA2_vram_r(DA2_VM03_BASECHR + da2->ma + 1, da2); + extattr = DA2_vram_r(DA2_VM03_BASEEXATTR + da2->ma + 1, da2); + // if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->ma << 1) & da2->vram_mask, chr, attr); bg = attr >> 4; // if (da2->blink) bg &= ~0x8; // fg = (da2->blink || (!(attr & 0x80))) ? (attr & 0xf) : bg; @@ -1875,7 +2008,7 @@ da2_render_textm3(da2_t *da2) /* Stay drawing if the char code is DBCS and not at last column. */ if (chr_wide) { /* Get high DBCS code from the next video address */ - chr_dbcs = da2->vram[(0x18000 + (da2->ma) + 2) & da2->vram_mask]; + chr_dbcs = DA2_vram_r(DA2_VM03_BASECHR + da2->ma + 2, da2); chr_dbcs <<= 8; chr_dbcs |= chr; /* Get the font pattern */ @@ -1888,8 +2021,11 @@ da2_render_textm3(da2_t *da2) } else { /* the char code is SBCS (ANK) */ uint32_t fontbase; - fontbase = DA2_GAIJIRAM_SBCS; - uint16_t font = da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2]; /* w13xh29 font */ + if (extattr & 0x80) /* second map of SBCS font */ + fontbase = DA2_GAIJIRAM_SBEX; + else + fontbase = DA2_GAIJIRAM_SBCS; + uint16_t font = da2->mmio.ram[fontbase+ chr * 0x40 + da2->sc * 2]; /* w13xh29 font */ font <<= 8; font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2 + 1]; /* w13xh29 font */ // if(chr!=0x20) da2_log("ma: %x, sc: %x, chr: %x, font: %x ", da2->ma, da2->sc, chr, font); @@ -1925,7 +2061,7 @@ da2_render_textm3(da2_t *da2) da2->ma += 2; p += 13; } - da2->ma &= da2->vram_display_mask; + // da2->ma &= DA2_MASK_CRAM; // da2->writelines++; } } @@ -1933,7 +2069,7 @@ da2_render_textm3(da2_t *da2) void da2_render_color_4bpp(da2_t *da2) { - int changed_offset = da2->ma >> 12; + int changed_offset = da2->ma >> 9; // da2_log("ma %x cf %x\n", da2->ma, changed_offset); da2->plane_mask &= 0x0f; /*safety */ @@ -1982,7 +2118,7 @@ da2_render_color_4bpp(da2_t *da2) void da2_render_color_8bpp(da2_t *da2) { - int changed_offset = da2->ma >> 12; + int changed_offset = da2->ma >> 9; // da2_log("ma %x cf %x\n", da2->ma, changed_offset); if (da2->changedvram[changed_offset] || da2->changedvram[changed_offset + 1] || da2->fullchange) { @@ -2029,8 +2165,9 @@ da2_render_color_8bpp(da2_t *da2) } void -da2_updatevidselector(da2_t *da2) +da2_updatevidselector_tick(void *priv) { + da2_t *da2 = (da2_t *) priv; if (da2->ioctl[LS_MODE] & 0x02) { /* VGA passthrough mode */ da2->override = 1; @@ -2043,6 +2180,23 @@ da2_updatevidselector(da2_t *da2) } } +void +da2_updatevidselector(da2_t *da2) +{ + timer_set_delay_u64(&da2->timer_vidupd, 100000ull * TIMER_USEC); +} + +/* + INT 10h video modes supported in DOS J4.0 (The DA-2 doesn't have a video BIOS on its card.) + Mode Type Colors Text Base Address PELs Render + 3 A/N/K 16 80 x 25 B0000h/B8000h 1040 x 725 textm3 + 8 A/N/K 2 80 x 25 E0000h 1040 x 725 text + Ah APA 1 78 x 25 A0000h 1024 x 768 color_4bpp + Dh APA 16 78 x 25 A0000h 1024 x 768 color_4bpp + Eh A/N/K 16 80 x 25 E0000h 1040 x 725 text + Fh APA 256 NA A0000h 1024 x 768 color_8bpp + 45h(undoc) APA 16 NA A0000h 1040 x 768 color_4bpp +*/ void da2_recalctimings(da2_t *da2) { @@ -2050,8 +2204,10 @@ da2_recalctimings(da2_t *da2) double _dispontime, _dispofftime, disptime; /* if output disabled or VGA passthrough */ - if (!(da2->attrc[LV_COMPATIBILITY] & 0x08) || da2->ioctl[LS_MODE] & 0x02) + if (da2->ioctl[LS_MODE] & 0x02 || !(da2->attrc[LV_COMPATIBILITY] & 0x08)) { + da2->render = da2_render_blank; return; + } da2->vtotal = da2->crtc[LC_VERTICAL_TOTALJ] & 0xfff; da2->dispend = da2->crtc[LC_V_DISPLAY_ENABLE_END] & 0xfff; @@ -2064,14 +2220,7 @@ da2_recalctimings(da2_t *da2) if (da2->crtc[LC_START_H_DISPLAY_ENAB] & 1) { da2->hdisp--; da2->dispend -= 29; - } else { - // da2->vtotal += 2; - da2->dispend--; - // da2->vsyncstart++; - // da2->split++; - // da2->vblankstart++; - // da2->hdisp--; - } + } da2->htotal = da2->crtc[LC_HORIZONTAL_TOTAL]; da2->htotal += 1; @@ -2084,7 +2233,7 @@ da2_recalctimings(da2_t *da2) // da2->interlace = 0; - // da2->ma_latch = ((da2->crtc[0xc] & 0x3ff) << 8) | da2->crtc[0xd];//w + b + // da2->ma_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW];//w + b da2->ca_adj = 0; da2->rowcount = da2->crtc[LC_MAXIMUM_SCAN_LINE]; @@ -2101,10 +2250,10 @@ da2_recalctimings(da2_t *da2) if (da2->crtc[LC_VIEWPORT_PRIORITY] & 0x80) { da2_log("Set videomode to PS/55 8 bpp graphics.\n"); da2->render = da2_render_color_8bpp; - da2->vram_display_mask = DA2_MASK_GRAM; + da2->vram_display_mask = DA2_MASK_A000; } else { /* PS/55 8-color */ da2_log("Set videomode to PS/55 4 bpp graphics.\n"); - da2->vram_display_mask = DA2_MASK_GRAM; + da2->vram_display_mask = DA2_MASK_A000; da2->render = da2_render_color_4bpp; } } else { @@ -2113,9 +2262,7 @@ da2_recalctimings(da2_t *da2) da2_log("Set videomode to PS/55 Mode 03 text.\n"); da2->render = da2_render_textm3; da2->vram_display_mask = DA2_MASK_CRAM; - } - /* PS/55 text(color/mono) */ - else { + } else { /* PS/55 text(color/mono) */ da2_log("Set videomode to PS/55 Mode 8/E text.\n"); da2->render = da2_render_text; da2->vram_display_mask = DA2_MASK_CRAM; @@ -2155,8 +2302,8 @@ da2_recalctimings(da2_t *da2) if (da2->dispofftime < TIMER_USEC) da2->dispofftime = TIMER_USEC; da2_log("da2 horiz total %i display end %i vidclock %f\n", da2->crtc[0], da2->crtc[1], da2->clock); - // da2_log("da2 vert total %i display end %i max row %i vsync %i\n",da2->vtotal,da2->dispend,(da2->crtc[9]&31)+1,da2->vsyncstart); - // da2_log("total %f on %i cycles off %i cycles frame %i sec %i\n",disptime*crtcconst,da2->dispontime,da2->dispofftime,(da2->dispontime+da2->dispofftime)*da2->vtotal,(da2->dispontime+da2->dispofftime)*da2->vtotal*70); + da2_log("da2 vert total %i display end %i max row %i vsync %i\n",da2->vtotal,da2->dispend,(da2->crtc[9]&31)+1,da2->vsyncstart); + da2_log("total %f on %i cycles off %i cycles frame %i sec %i\n",disptime*crtcconst,da2->dispontime,da2->dispofftime,(da2->dispontime+da2->dispofftime)*da2->vtotal,(da2->dispontime+da2->dispofftime)*da2->vtotal*70); // da2_log("da2->render %08X\n", da2->render); } @@ -2230,70 +2377,74 @@ da2_mca_reset(void *p) da2_mca_write(0x102, 0, da2); } +/* ROP gdcinput and gdcsrc, and write the result with bitmask at addr (byte) */ static void da2_gdcropB(uint32_t addr,uint8_t bitmask, da2_t *da2) { for (int i = 0; i < 8; i++) { - if (da2->writemask & (1 << i)) { + if (da2->planemask & (1 << i)) { // da2_log("da2_gdcropB o%x a%x d%x p%d m%x\n", da2->gdcreg[LG_COMMAND] & 0x03, addr, da2->gdcinput[i], i, bitmask); switch (da2->gdcreg[LG_COMMAND] & 0x03) { case 0: /*Set*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | (da2->gdcsrc[i] & ~bitmask); // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask); - da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask); + DA2_vram_w(addr | i, (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 1: /*AND*/ // da2->vram[addr | i] = (da2->gdcinput[i] | ~bitmask) & da2->gdcsrc[i]; - da2->vram[addr | i] = ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask); + DA2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 2: /*OR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | da2->gdcsrc[i]; - da2->vram[addr | i] = ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask); + DA2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 3: /*XOR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) ^ da2->gdcsrc[i]; - da2->vram[addr | i] = ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask); + DA2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; } } } } +/* ROP gdcinput and gdcsrc, and write the result with bitmask at addr (word) */ static void da2_gdcropW(uint32_t addr, uint16_t bitmask, da2_t *da2) { + if((addr & 8) && !(da2->gdcreg[LG_COMMAND] & 0x08)) bitmask = rightRotate(bitmask, 8); + // if((addr & 8)) bitmask = rightRotate(bitmask, 8); uint8_t bitmask_l = bitmask & 0xff; uint8_t bitmask_h = bitmask >> 8; for (int i = 0; i < 8; i++) { - if (da2->writemask & (1 << i)) { + if (da2->planemask & (1 << i)) { // da2_log("da2_gdcropW m%x a%x d%x i%d ml%x mh%x\n", da2->gdcreg[LG_COMMAND] & 0x03, addr, da2->gdcinput[i], i, da2->gdcreg[LG_BIT_MASK_LOW], da2->gdcreg[LG_BIT_MASK_HIGH]); switch (da2->gdcreg[LG_COMMAND] & 0x03) { case 0: /*Set*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) | (da2->gdcsrc[i] & ~bitmask_l); // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) | ((da2->gdcsrc[i] >> 8) & ~bitmask_h); - da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l); - da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) - | (da2->vram[(addr + 8) | i] & ~bitmask_h); + DA2_vram_w(addr | i, (da2->gdcinput[i] & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + DA2_vram_w((addr + 8) | i, ((da2->gdcinput[i] >> 8) & bitmask_h) + | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 1: /*AND*/ // da2->vram[addr | i] = (da2->gdcinput[i] | ~bitmask_l) & da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) | ~bitmask_h) & (da2->gdcsrc[i] >> 8); - da2->vram[addr | i] = ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l); - da2->vram[(addr + 8) | i] = (((da2->gdcinput[i] >> 8) & (da2->gdcsrc[i] >> 8)) & bitmask_h) - | (da2->vram[(addr + 8) | i] & ~bitmask_h); + DA2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) & (da2->gdcsrc[i] >> 8)) & bitmask_h) + | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 2: /*OR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) | da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) | (da2->gdcsrc[i] >> 8); - da2->vram[addr | i] = ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l); - da2->vram[(addr + 8) | i] = (((da2->gdcinput[i] >> 8) | (da2->gdcsrc[i] >> 8)) & bitmask_h) - | (da2->vram[(addr + 8) | i] & ~bitmask_h); + DA2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) | (da2->gdcsrc[i] >> 8)) & bitmask_h) + | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 3: /*XOR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) ^ da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) ^ (da2->gdcsrc[i] >> 8); - da2->vram[addr | i] = ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l); - da2->vram[(addr + 8) | i] = (((da2->gdcinput[i] >> 8) ^ (da2->gdcsrc[i] >> 8)) & bitmask_h) - | (da2->vram[(addr + 8) | i] & ~bitmask_h); + DA2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) ^ (da2->gdcsrc[i] >> 8)) & bitmask_h) + | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; } } @@ -2305,7 +2456,6 @@ da2_mmio_read(uint32_t addr, void *p) { da2_t *da2 = (da2_t *) p; addr &= DA2_MASK_MMIO; - if (da2->ioctl[LS_MMIO] & 0x10) { if (da2->fctl[LF_MMIO_SEL] == 0x80) /* linear access */ @@ -2345,7 +2495,9 @@ da2_mmio_read(uint32_t addr, void *p) cycles -= video_timing_read_b; for (int i = 0; i < 8; i++) da2->gdcla[i] = da2->vram[(addr << 3) | i]; /* read in byte */ - // da2_log("da2_Rb: %05x=%02x\n", addr, da2->gdcla[da2->readplane]); +#ifdef ENABLE_DA2_DEBUGVRAM + da2_log("da2_Rb: %05x=%02x\n", addr, da2->gdcla[da2->readplane]); +#endif if (da2->gdcreg[LG_MODE] & 0x08) { /* compare data across planes if the read mode bit (3EB 05, bit 3) is 1 */ uint8_t ret = 0; for (int i = 0; i < 8; i++) { @@ -2356,7 +2508,6 @@ da2_mmio_read(uint32_t addr, void *p) } else return da2->gdcla[da2->readplane]; } else { /* text mode 3 */ - cycles -= video_timing_read_b; return da2->vram[addr]; } @@ -2365,17 +2516,18 @@ static uint16_t da2_mmio_readw(uint32_t addr, void *p) { da2_t *da2 = (da2_t *) p; - //da2_log("da2_readW: %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr); + // da2_log("da2_readW: %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr); + // da2_log("da2_readW: %x %x %x %x %x CS:PC=%4x:%4x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, CS, cpu_state.pc); + if (da2->ioctl[LS_MMIO] & 0x10) { return (uint16_t) da2_mmio_read(addr, da2) | (uint16_t) (da2_mmio_read(addr + 1, da2) << 8); - } else if (!(da2->ioctl[LS_MODE] & 1)) /* 16 color or 256 color mode */ - { + } else if (!(da2->ioctl[LS_MODE] & 1)) {/* 16 color or 256 color mode */ cycles -= video_timing_read_w; addr &= DA2_MASK_MMIO; for (int i = 0; i < 8; i++) da2->gdcla[i] = (uint16_t) (da2->vram[(addr << 3) | i]) | ((uint16_t) (da2->vram[((addr << 3) + 8) | i]) << 8); /* read vram into latch */ -#ifdef ENABLE_DA2_DEBUGBLT +#ifdef ENABLE_DA2_DEBUGVRAM ////debug // if (((int)addr - (int)da2->mmrdbg_vidaddr) > 2 || (((int)da2->mmrdbg_vidaddr - (int)addr) > 2) || da2->mmrdbg_vidaddr == addr) //{ @@ -2401,7 +2553,9 @@ da2_mmio_readw(uint32_t addr, void *p) } return ~ret; } else { - // da2_log("da2_Rw: %05x=%04x\n", addr, da2->gdcla[da2->readplane]); +#ifdef ENABLE_DA2_DEBUGVRAM + da2_log("da2_Rw: %05x(%d) = %04x\n", addr, da2->readplane, da2->gdcla[da2->readplane]); +#endif return da2->gdcla[da2->readplane]; } } else { @@ -2414,8 +2568,8 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) { da2_t *da2 = (da2_t *) p; // da2_log("da2_mmio_write %x %x\n", addr, val); - if ((addr & ~DA2_MASK_MMIO) != 0xA0000) - return; + // if ((addr & ~DA2_MASK_MMIO) != 0xA0000) + // return; addr &= DA2_MASK_MMIO; if (da2->ioctl[LS_MMIO] & 0x10) { @@ -2431,8 +2585,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) } switch (da2->fctl[LF_MMIO_MODE]) { case 0xb0: /* Gaiji RAM 1011 0000 */ - addr &= DA2_MASK_GAIJIRAM; /* safety access */ - da2->mmio.ram[addr] = val; + da2->mmio.ram[addr & DA2_MASK_GAIJIRAM] = val; break; case 0x10: /* Font ROM 0001 0000 */ /* Read-Only */ @@ -2448,8 +2601,10 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) da2->bitblt.indata = 1; if (da2->bitblt.payload_addr >= DA2_BLT_MEMSIZE) da2_log("da2_mmio_write payload overflow! mem %x, addr %x, val %x\n", da2->fctl[LF_MMIO_MODE], addr, val); - da2->bitblt.payload[da2->bitblt.payload_addr] = val; - da2->bitblt.payload_addr++; + else { + da2->bitblt.payload[da2->bitblt.payload_addr] = val; + da2->bitblt.payload_addr++; + } break; default: da2_log("da2_mmio_write failed mem %x, addr %x, val %x\n", da2->fctl[LF_MMIO_MODE], addr, val); @@ -2457,11 +2612,20 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) } } else if (!(da2->ioctl[LS_MODE] & 1)) { /* 16 color or 256 color mode */ uint8_t bitmask; - /* align bitmask to even address */ - if (addr & 1) bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; - else bitmask = da2->gdcreg[LG_BIT_MASK_LOW]; -#ifdef ENABLE_DA2_DEBUGBLT - da2_log("da2_wB %x %02x\n", addr, val); + /* Align bitmask with even address */ + /* With byte align: Win 3.1 (Window) - ok, Solitaire 3.1 - ok, A-Train IV (splash): bad, OS/2 J2.0(cmd) - ok */ + // if ((addr & 1) && !(da2->gdcreg[LG_COMMAND] & 0x08)) bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; + /* Without byte align: Win 3.1 (Window) - bad, Solitaire 3.1 - ok, A-Train IV (splash): ok, OS/2 J2.0(cmd) - ok */ + /* With byte align: Win 3.1 (Window) - ok, Solitaire 3.1 - ok, A-Train IV (splash): ok, OS/2 J2.0(cmd) - ok */ + if ((addr & 1)) bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; + else + /* No align: Win 3.1 (Window Title) - ok, Solitaire 3.1 - ok, A-Train IV (splash): bad, OS/2 J2.0(cmd) - bad */ + bitmask = da2->gdcreg[LG_BIT_MASK_LOW]; + +#ifdef ENABLE_DA2_DEBUGVRAM + // da2_log("da2_wB %x %02x\n", addr, val); + da2_log("da2_wB %x %d %d %02x\n", addr, + addr % (da2->rowoffset * 2) * 8, addr / (da2->rowoffset * 2), val); // if (!(da2->gdcreg[LG_COMMAND] & 0x08)) //{ if (((int) addr - (int) da2->mmdbg_vidaddr) > 2 || (((int) da2->mmdbg_vidaddr - (int) addr) > 2) || da2->mmdbg_vidaddr == addr) { @@ -2472,7 +2636,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) for (int i = 0; i < 8; i++) { int pixeldata = 0; if (val & (1 << (7 - i))) - pixeldata = (da2->writemask & 0xf); + pixeldata = (da2->planemask & 0xf); fprintf(da2->mmdbg_fp, "%X", pixeldata); } da2->mmdbg_vidaddr = addr; @@ -2481,7 +2645,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) cycles -= video_timing_write_b; - da2->changedvram[addr >> 12] = changeframecount; + da2->changedvram[addr >> 9] = changeframecount;/* 0x1FFFF -> 0x1F */ addr <<= 3; for (int i = 0; i < 8; i++) @@ -2505,16 +2669,16 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) switch (da2->writemode) { case 2: /* equiv to vga write mode 1 */ for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) - da2->vram[addr | i] = da2->gdcsrc[i]; + if (da2->planemask & (1 << i)) + DA2_vram_w(addr | i, da2->gdcsrc[i], da2); break; case 0:/* equiv to vga write mode 0 */ if (da2->gdcreg[LG_DATA_ROTATION] & 7) val = svga_rotate[da2->gdcreg[LG_DATA_ROTATION] & 7][val]; if (bitmask == 0xff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) - da2->vram[addr | i] = val; + if (da2->planemask & (1 << i)) + DA2_vram_w(addr | i, val, da2); } else { for (int i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) @@ -2522,8 +2686,8 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) else da2->gdcinput[i] = val; - for (int i = 0; i < 8; i++) - da2->debug_vramold[i] = da2->vram[addr | i]; /* use latch */ + // for (int i = 0; i < 8; i++) + // da2->debug_vramold[i] = da2->vram[addr | i]; /* use latch */ da2_gdcropB(addr, bitmask, da2); // for (int i = 0; i < 8; i++) // da2_log("\tsrc %02x in %02x bitm %02x mod %x rop %x: %02x -> %02x\n", da2->gdcsrc[i], da2->gdcinput[i], bitmask, da2->gdcreg[5],da2->gdcreg[LG_COMMAND], da2->debug_vramold[i], da2->vram[addr | i]);//use latch @@ -2531,17 +2695,17 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) } break; case 1:/* equiv to vga write mode 2 */ - if (!(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { - for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) - da2->vram[addr | i] = (((val & (1 << i)) ? 0xff : 0) & bitmask) | (da2->gdcsrc[i] & ~bitmask); - //fprintf(da2->mmdbg_fp, "m1-1"); - } else { + // if (!(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { + // for (int i = 0; i < 8; i++) + // if (da2->planemask & (1 << i)) + // DA2_vram_w(addr | i, (((val & (1 << i)) ? 0xff : 0) & bitmask) | (da2->gdcsrc[i] & ~bitmask), da2); + // //fprintf(da2->mmdbg_fp, "m1-1"); + // } else { for (int i = 0; i < 8; i++) da2->gdcinput[i] = ((val & (1 << i)) ? 0xff : 0); da2_gdcropB(addr, bitmask, da2); //fprintf(da2->mmdbg_fp, "m1-2"); - } + // } break; case 3:/* equiv to vga write mode 3 */ if (da2->gdcreg[LG_DATA_ROTATION] & 7) @@ -2549,14 +2713,14 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) bitmask &= val; for (int i = 0; i < 8; i++) - da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xff : 0; + da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xff : 0; da2_gdcropB(addr, bitmask, da2); break; } // da2_log("%02x%02x%02x%02x\n", da2->vram[addr + 0], da2->vram[addr + 1], da2->vram[addr + 2], da2->vram[addr + 3]); } else { /* mode 3h text */ cycles -= video_timing_write_b; - da2->vram[addr] = val; + DA2_vram_w(addr, val, da2); da2->fullchange = 2; } } @@ -2569,34 +2733,37 @@ static void da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) { da2_t *da2 = (da2_t *) p; - uint16_t bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; + uint16_t bitmask; + addr &= DA2_MASK_MMIO; + bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; bitmask <<= 8; bitmask |= (uint16_t) da2->gdcreg[LG_BIT_MASK_LOW]; -#ifdef ENABLE_DA2_DEBUGBLT +#ifdef ENABLE_DA2_DEBUGVRAM + da2_log("da2_wW %x %d %d %02x\n", addr, + addr % (da2->rowoffset * 2) * 8, addr / (da2->rowoffset * 2), val); // if (!(da2->gdcreg[LG_COMMAND] & 0x08)) //{ if (((int) addr - (int) da2->mmdbg_vidaddr) > 2 || (((int) da2->mmdbg_vidaddr - (int) addr) > 2) || da2->mmdbg_vidaddr == addr) { - fprintf(da2->mmdbg_fp, "\nW %x ", addr); + fprintf(da2->mmdbg_fp, "\nW %x %x ", addr, val); for (int i = 0; i <= 0xb; i++) fprintf(da2->mmdbg_fp, "%02x ", da2->gdcreg[i]); } for (int i = 0; i < 16; i++) { int pixeldata = 0; if (val & (1 << (15 - i))) - pixeldata = (da2->writemask & 0xf); + pixeldata = (da2->planemask & 0xf); fprintf(da2->mmdbg_fp, "%X", pixeldata); } da2->mmdbg_vidaddr = addr; //} #endif cycles -= video_timing_write_w; - // cycles_lost += video_timing_write_w; // da2_log("da2_gcW m%d a%x d%x\n", da2->writemode, addr, val); // da2_log("da2_gcW %05X %02X %04X:%04X esdi %04X:%04X dssi %04X:%04X\n", addr, val, cs >> 4, cpu_state.pc, ES, DI, DS, SI); - da2->changedvram[addr >> 12] = changeframecount; - da2->changedvram[(addr + 1) >> 12] = changeframecount; + da2->changedvram[addr >> 9] = changeframecount; + // da2->changedvram[(addr + 1) >> 12] = changeframecount; addr <<= 3; for (int i = 0; i < 8; i++) @@ -2618,19 +2785,19 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) switch (da2->writemode) { case 2: for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) { - da2->vram[addr | i] = da2->gdcsrc[i] & 0xff; - da2->vram[(addr + 8) | i] = da2->gdcsrc[i] >> 8; + if (da2->planemask & (1 << i)) { + DA2_vram_w(addr | i, da2->gdcsrc[i] & 0xff, da2); + DA2_vram_w((addr + 8) | i, da2->gdcsrc[i] >> 8, da2); } break; case 0: if (da2->gdcreg[LG_DATA_ROTATION] & 15) - val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); // val = svga_rotate[da2->gdcreg[LG_DATA_ROTATION] & 7][val]; TODO this wont work + val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); if (bitmask == 0xffff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) { - da2->vram[addr | i] = val & 0xff; - da2->vram[(addr + 8) | i] = val >> 8; + if (da2->planemask & (1 << i)) { + DA2_vram_w(addr | i, val & 0xff, da2); + DA2_vram_w((addr + 8) | i, val >> 8, da2); } } else { for (int i = 0; i < 8; i++) @@ -2643,26 +2810,17 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) } break; case 1: - if (!(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { - for (int i = 0; i < 8; i++) - if (da2->writemask & (1 << i)) { - uint16_t wdata = (((val & (1 << i)) ? 0xffff : 0) & bitmask) | (da2->gdcsrc[i] & ~bitmask); - da2->vram[addr | i] = wdata & 0xff; - da2->vram[(addr + 8) | i] = wdata >> 8; - } - } else { - for (int i = 0; i < 8; i++) - da2->gdcinput[i] = ((val & (1 << i)) ? 0xffff : 0); - da2_gdcropW(addr, bitmask, da2); - } + for (int i = 0; i < 8; i++) + da2->gdcinput[i] = ((val & (1 << i)) ? 0xffff : 0); + da2_gdcropW(addr, bitmask, da2); break; case 3: if (da2->gdcreg[LG_DATA_ROTATION] & 15) - val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); // val = svga_rotate[da2->gdcreg[LG_DATA_ROTATION] & 7][val];; TODO this wont work + val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); bitmask &= val; for (int i = 0; i < 8; i++) - da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xffff : 0; + da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xffff : 0; da2_gdcropW(addr, bitmask, da2); break; } @@ -2673,14 +2831,14 @@ static void da2_mmio_writew(uint32_t addr, uint16_t val, void *p) { da2_t *da2 = (da2_t *) p; + // if (da2->bitblt.exec != DA2_BLT_CIDLE) /* Bitblt is in operation. */ + // return; // if ((addr & ~0x1ffff) != 0xA0000) return; if (da2->ioctl[LS_MMIO] & 0x10) { // da2_log("da2_mmio_writeW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); da2_mmio_write(addr, val & 0xff, da2); da2_mmio_write(addr + 1, val >> 8, da2); } else if (!(da2->ioctl[LS_MODE] & 1)) { /* 16 color or 256 color mode */ - addr &= DA2_MASK_MMIO; - // return; // da2_log("da2_mmio_writeGW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); da2_mmio_gc_writeW(addr, val, da2); } else { /* mode 3h text */ @@ -2722,8 +2880,8 @@ static uint8_t da2_code_read(uint32_t addr, void *p) { da2_t *da2 = (da2_t *) p; - if ((addr & ~DA2_MASK_CRAM) != 0xE0000) - return DA2_INVALIDACCESS8; + // if ((addr & ~DA2_MASK_CRAM) != 0xE0000) + // return DA2_INVALIDACCESS8; addr &= DA2_MASK_CRAM; return da2->cram[addr]; } @@ -2850,7 +3008,7 @@ da2_poll(void *priv) } da2->blink++; - for (x = 0; x < ((da2->vram_mask + 1) >> 12); x++) { + for (x = 0; x <= (DA2_MASK_VRAMPLANE >> 9); x++) { if (da2->changedvram[x]) da2->changedvram[x]--; } @@ -2894,11 +3052,11 @@ da2_poll(void *priv) = da2->maback = da2->ma_latch; da2->ca = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj; - da2->ma <<= 1; - da2->maback <<= 1; + // da2->ma <<= 1; + // da2->maback <<= 1; da2->ca <<= 1; - // da2_log("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,da2_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], da2_interlace, oddeven); + // da2_log("Addr %08X vson %03X vsoff %01X\n",da2->ma,da2->vsyncstart,da2->crtc[0x11]&0xF); } if (da2->vc == da2->vtotal) { // da2_log("VC vtotal\n"); @@ -2922,7 +3080,6 @@ da2_loadfont(char *fname, void *p) { da2_t *da2 = (da2_t *) p; uint8_t buf; - // uint32_t code = 0; uint64_t fsize; if (!fname) return; @@ -2987,12 +3144,11 @@ da2_reset(void *priv) /* Initialize drawing */ da2->bitblt.exec = DA2_BLT_CIDLE; - da2->render = da2_render_blank; da2_reset_ioctl(da2); da2->pos_regs[0] = DA2_POSID_L; /* Adapter Identification Byte (Low byte) */ da2->pos_regs[1] = DA2_POSID_H; /* Adapter Identification Byte (High byte) */ - da2->pos_regs[2] = 0x40; /* Bit 7-5: 010=Mono, 100=Color, Bit 0 : Card Enable (they are changed by system software) */ + da2->pos_regs[2] = 0x40; /* Bit 7-5: 010=Mono, 100=Color, Bit 0 : Card Enable (set by reference diskette) */ da2->ioctl[LS_CONFIG1] = OldLSI | Page_Two; /* Configuration 1 : DA-II, 1024 KB */ da2->ioctl[LS_CONFIG1] |= ((da2->monitorid & 0x8) << 1); /* Configuration 1 : Monitor ID 3 */ da2->ioctl[LS_CONFIG2] = (da2->monitorid & 0x7); /* Configuration 2: Monitor ID 0-2 */ @@ -3029,13 +3185,11 @@ da2_init(UNUSED(const device_t *info)) da2->dispontime = 1000ull << 32; da2->dispofftime = 1000ull << 32; - int memsize = 1024 * 1024; - da2->vram = calloc(1, memsize); - da2->vram_mask = memsize - 1; - da2->cram = calloc(1, 0x1000); + da2->vram = calloc(1, DA2_SIZE_VRAM); + da2->cram = calloc(1, DA2_SIZE_CRAM); da2->vram_display_mask = DA2_MASK_CRAM; - da2->changedvram = calloc(1, /*(memsize >> 12) << 1*/ 0x1000000 >> 12); /* XX000h */ - da2->monitorid = device_get_config_int("montype"); /* Configuration for Monitor ID (aaaa) -> (xxax xxxx, xxxx xaaa) */ + da2->monitorid = device_get_config_int("montype"); + da2->changedvram = calloc(1, (DA2_MASK_VRAMPLANE + 1) >> 9); /* XX000h */ da2->mmio.charset = device_get_config_int("charset"); da2->mmio.font = malloc(DA2_FONTROM_SIZE); @@ -3052,16 +3206,20 @@ da2_init(UNUSED(const device_t *info)) } mca_add(da2_mca_read, da2_mca_write, da2_mca_feedb, da2_mca_reset, da2); - da2->da2const = (uint64_t) ((cpuclock / DA2_PIXELCLOCK) * (float) (1ull << 32)); + da2->da2const = (uint64_t) ((cpuclock / DA2_PIXELCLOCK) * (double) (1ull << 32)); memset(da2->bitblt.payload, 0x00, DA2_BLT_MEMSIZE); memset(da2->bitblt.reg, 0xfe, DA2_BLT_REGSIZE * sizeof(uint32_t)); /* clear memory */ #ifdef ENABLE_DA2_DEBUGBLT da2->bitblt.debug_reg = malloc(DA2_DEBUG_BLTLOG_MAX * DA2_DEBUG_BLTLOG_SIZE); - da2->mmdbg_fp = fopen("da2_mmiowdat.txt", "w"); - da2->mmrdbg_fp = fopen("da2_mmiordat.txt", "w"); da2->bitblt.debug_reg_ip = 0; +#endif +#ifdef ENABLE_DA2_DEBUGVRAM + da2->mmdbg_fp = fopen("da2_mmiowdat.txt", "w"); + da2->mmrdbg_fp = fopen("da2_mmiordat.txt", "w"); #endif da2->bitblt.payload_addr = 0; + + timer_add(&da2->timer_vidupd, da2_updatevidselector_tick, da2, 0);/* Init timer before executing reset */ da2_reset(da2); mem_mapping_add(&da2->mmio.mapping, 0xA0000, 0x20000, da2_mmio_read, da2_mmio_readw, NULL, da2_mmio_write, da2_mmio_writew, NULL, NULL, MEM_MAPPING_EXTERNAL, da2); @@ -3074,7 +3232,7 @@ da2_init(UNUSED(const device_t *info)) mem_mapping_disable(&da2->cmapping); timer_add(&da2->timer, da2_poll, da2, 0); - da2->bitblt.timerspeed = 1 * TIMER_USEC; + da2->bitblt.timerspeed = 5ull * TIMER_USEC; /* Bitblt execution speed */ timer_add(&da2->bitblt.timer, da2_bitblt_dopayload, da2, 0); return da2; @@ -3095,17 +3253,17 @@ da2_close(void *p) FILE *f; f = fopen("da2_cram.dmp", "wb"); if (f != NULL) { - fwrite(da2->cram, 0x1000, 1, f); + fwrite(da2->cram, DA2_SIZE_CRAM, 1, f); fclose(f); } f = fopen("da2_vram.dmp", "wb"); if (f != NULL) { - fwrite(da2->vram, 1024 * 1024, 1, f); + fwrite(da2->vram, DA2_SIZE_VRAM, 1, f); fclose(f); } f = fopen("da2_gram.dmp", "wb"); if (f != NULL) { - fwrite(da2->mmio.ram, 256 * 1024, 1, f); + fwrite(da2->mmio.ram, DA2_SIZE_GAIJIRAM, 1, f); fclose(f); } f = fopen("da2_attrpal.dmp", "wb"); @@ -3158,11 +3316,13 @@ da2_close(void *p) } fclose(f); } + free(da2->bitblt.debug_reg); +#endif +#ifdef ENABLE_DA2_DEBUGVRAM if (da2->mmdbg_fp != NULL) fclose(da2->mmdbg_fp); if (da2->mmrdbg_fp != NULL) fclose(da2->mmrdbg_fp); - free(da2->bitblt.debug_reg); #endif free(da2->cram); free(da2->vram); @@ -3175,7 +3335,7 @@ void da2_speed_changed(void *p) { da2_t *da2 = (da2_t *) p; - da2->da2const = (uint64_t) ((cpuclock / DA2_PIXELCLOCK) * (float) (1ull << 32)); + da2->da2const = (uint64_t) ((cpuclock / DA2_PIXELCLOCK) * (double) (1ull << 32)); da2_recalctimings(da2); }