From cf33ab6c3997b73bca746058cbdc4a5c17e7955b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 20 Jun 2020 20:22:24 +0100 Subject: [PATCH] Add initial implementation of Intel VS440FX motherboard. As part of this, add dummy Pentium Pro emulation, as well as Intel 440FX chipset, PC87307 SuperIO and Intel 28FB200BX-T Flash. --- src/386_ops.h | 93 +++++++++++++++++++- src/cpu.c | 67 +++++++++++++++ src/cpu.h | 2 + src/cpu_tables.c | 9 ++ src/i440fx.c | 145 ++++++++++++++++++++++++++++++++ src/i440fx.h | 2 + src/ibm.h | 15 ++-- src/intel_flash.c | 210 ++++++++++++++++++++++++++++++++++++---------- src/intel_flash.h | 1 + src/mem_bios.c | 129 +++++++++++++++++----------- src/model.c | 20 +++++ src/nvr.c | 2 + src/pc87307.c | 151 +++++++++++++++++++++++++++++++++ src/pc87307.h | 1 + src/x86_ops.h | 3 + 15 files changed, 750 insertions(+), 100 deletions(-) create mode 100644 src/i440fx.c create mode 100644 src/i440fx.h create mode 100644 src/pc87307.c create mode 100644 src/pc87307.h diff --git a/src/386_ops.h b/src/386_ops.h index 34c7847..e57389e 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -820,7 +820,98 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -OpFn OP_TABLE(286)[1024] = +OpFn OP_TABLE(pentiumpro_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ 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_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, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ 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, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ 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_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, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ 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_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, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +OpFn OP_TABLE(286)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ diff --git a/src/cpu.c b/src/cpu.c index d69df1f..6601413 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1005,6 +1005,55 @@ void cpu_set() codegen_timing_set(&codegen_timing_k6); break; + case CPU_PENTIUMPRO: + x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_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; + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 2; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_pentium); + break; + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } @@ -1526,6 +1575,24 @@ void cpu_CPUID() break; } break; + + case CPU_PENTIUMPRO: + if (!EAX) + { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } + else if (EAX == 1) + { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV; + } + else + EAX = EBX = ECX = EDX = 0; + break; } } diff --git a/src/cpu.h b/src/cpu.h index 4188cff..8341be3 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -41,6 +41,7 @@ extern int fpu_type; #define CPU_K6_3 25 #define CPU_K6_2P 26 #define CPU_K6_3P 27 +#define CPU_PENTIUMPRO 28 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -117,6 +118,7 @@ extern CPU cpus_6x86[]; extern CPU cpus_6x86_SS7[]; extern CPU cpus_K6_S7[]; extern CPU cpus_K6_SS7[]; +extern CPU cpus_PentiumPro[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 1c9e1c7..6ee40e8 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -501,3 +501,12 @@ CPU cpus_K6_SS7[] = {"", -1, 0, 0, 0} }; +CPU cpus_PentiumPro[] = +{ + /*Intel Pentium Pro*/ + {"Pentium Pro 150", CPU_PENTIUMPRO, fpus_builtin, 17, 150000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_builtin, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_builtin, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_builtin, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"", -1, 0, 0, 0} +}; diff --git a/src/i440fx.c b/src/i440fx.c new file mode 100644 index 0000000..c95c79c --- /dev/null +++ b/src/i440fx.c @@ -0,0 +1,145 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "keyboard_at.h" +#include "mem.h" +#include "pci.h" +#include "x86.h" + +#include "i440fx.h" + +static uint8_t card_i440fx[256]; + +static void i440fx_map(uint32_t addr, uint32_t size, int state) +{ + switch (state & 3) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +void i440fx_write(int func, int addr, uint8_t val, void *priv) +{ + if (func) + return; + + if (addr >= 0x10 && addr < 0x4f) + return; + + switch (addr) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0e: + return; + + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + + case 0x59: /*PAM0*/ + if ((card_i440fx[0x59] ^ val) & 0xf0) + { + i440fx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i440fx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i440fx[0x5a] ^ val) & 0x0f) + i440fx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5a] ^ val) & 0xf0) + i440fx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i440fx[0x5b] ^ val) & 0x0f) + i440fx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5b] ^ val) & 0xf0) + i440fx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i440fx[0x5c] ^ val) & 0x0f) + i440fx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5c] ^ val) & 0xf0) + i440fx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i440fx[0x5d] ^ val) & 0x0f) + i440fx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5d] ^ val) & 0xf0) + i440fx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i440fx[0x5e] ^ val) & 0x0f) + i440fx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5e] ^ val) & 0xf0) + i440fx_map(0xe4000, 0x04000, val >> 4); + pclog("i440fx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i440fx[0x5f] ^ val) & 0x0f) + i440fx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5f] ^ val) & 0xf0) + i440fx_map(0xec000, 0x04000, val >> 4); + pclog("i440fx_write : PAM6 write %02X\n", val); + break; + } + + card_i440fx[addr] = val; +} + +uint8_t i440fx_read(int func, int addr, void *priv) +{ + if (func) + return 0xff; + + return card_i440fx[addr]; +} + +void i440fx_init() +{ + pci_add_specific(0, i440fx_read, i440fx_write, NULL); + + memset(card_i440fx, 0, 256); + card_i440fx[0x00] = 0x86; card_i440fx[0x01] = 0x80; /*Intel*/ + card_i440fx[0x02] = 0x37; card_i440fx[0x03] = 0x12; /*82441FX*/ + card_i440fx[0x04] = 0x06; card_i440fx[0x05] = 0x00; + card_i440fx[0x06] = 0x80; card_i440fx[0x07] = 0x02; + card_i440fx[0x08] = 0x00; /*A0 stepping*/ + card_i440fx[0x09] = 0x00; card_i440fx[0x0a] = 0x00; card_i440fx[0x0b] = 0x06; + card_i440fx[0x51] = 0x84; /*Uniprocessor, 66 MHz bus*/ + card_i440fx[0x53] = 0x80; + card_i440fx[0x57] = 0x01; + card_i440fx[0x58] = 0x10; + card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01; + card_i440fx[0x71] = 0x10; + card_i440fx[0x72] = 0x02; +} + +void i440fx_reset() +{ + i440fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ +} diff --git a/src/i440fx.h b/src/i440fx.h new file mode 100644 index 0000000..e16eab7 --- /dev/null +++ b/src/i440fx.h @@ -0,0 +1,2 @@ +void i440fx_init(); +void i440fx_reset(); diff --git a/src/ibm.h b/src/ibm.h index 62f8035..925b889 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -95,12 +95,12 @@ typedef struct PIT int initial[3]; int latched[3]; int disabled[3]; - + uint8_t read_status[3]; int do_read_status[3]; - + PIT_nr pit_nr[3]; - + void (*set_out_funcs[3])(int new_out, int old_out); } PIT; @@ -127,7 +127,7 @@ typedef struct dma_t uint8_t stat, stat_rq; uint8_t command; int size; - + uint8_t ps2_mode; uint8_t arb_level; uint16_t io_addr; @@ -181,7 +181,7 @@ enum ROM_PC200, ROM_PC1640, ROM_PC2086, - ROM_PC3086, + ROM_PC3086, ROM_AMIXT, /*XT Clone with AMI BIOS*/ ROM_LTXT, ROM_LXT3, @@ -263,6 +263,7 @@ enum ROM_HYUNDAI_SUPER286TR, ROM_ITAUTEC_INFOWAYM, ROM_DESKPRO, + ROM_VS440FX, ROM_MAX }; @@ -288,7 +289,7 @@ enum GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/ GFX_VIRGE, /*S3 Virge*/ GFX_TGUI9440, /*Trident TGUI9440*/ - GFX_VGA, /*IBM VGA*/ + GFX_VGA, /*IBM VGA*/ GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/ GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/ @@ -298,7 +299,7 @@ enum GFX_VIRGEDX, /*S3 Virge/DX*/ GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ - GFX_INCOLOR, /* Hercules InColor */ + GFX_INCOLOR, /* Hercules InColor */ GFX_COLORPLUS, /* Plantronics ColorPlus */ GFX_WY700, /* Wyse 700 */ GFX_GENIUS, /* MDSI Genius */ diff --git a/src/intel_flash.c b/src/intel_flash.c index 95285ee..2d28956 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -3,6 +3,7 @@ #include "device.h" #include "mem.h" +#define FLASH_2MBIT 4 #define FLASH_IS_BXB 2 #define FLASH_INVERT 1 @@ -10,6 +11,7 @@ #define BLOCK_DATA1 1 #define BLOCK_DATA2 2 #define BLOCK_BOOT 3 +#define BLOCK_MAIN2 4 /*2Mbit devices only*/ enum { @@ -27,10 +29,12 @@ typedef struct flash_t { uint8_t command, status; uint8_t flash_id; + uint8_t type; int invert_high_pin; - mem_mapping_t mapping[8], mapping_h[8]; - uint32_t block_start[4], block_end[4], block_len[4]; - uint8_t array[131072]; + mem_mapping_t mapping[8], mapping_h[10]; + uint32_t block_start[5], block_end[5], block_len[5]; + uint8_t array[256*1024]; + uint32_t addr_mask; } flash_t; static char flash_path[1024]; @@ -42,10 +46,10 @@ static uint8_t flash_read(uint32_t addr, void *p) { // pclog("flash_read : addr=%08x/%08x val=%02x command=%02x %04x:%08x\n", addr, addr ^ 0x10000, flash->array[(addr ^ 0x10000) & 0x1ffff], flash->command, CS, cpu_state.pc); addr ^= 0x10000; - if (addr & 0xfff00000) return flash->array[addr & 0x1ffff]; + if (addr & 0xfff00000) return flash->array[addr & flash->addr_mask]; } // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); - addr &= 0x1ffff; + addr &= flash->addr_mask; switch (flash->command) { case CMD_READ_ARRAY: @@ -65,7 +69,7 @@ static uint8_t flash_read(uint32_t addr, void *p) static uint16_t flash_readw(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; - addr &= 0x1ffff; + addr &= flash->addr_mask; if (flash->invert_high_pin) addr ^= 0x10000; return *(uint16_t *)&(flash->array[addr]); } @@ -73,7 +77,7 @@ static uint16_t flash_readw(uint32_t addr, void *p) static uint32_t flash_readl(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; - addr &= 0x1ffff; + addr &= flash->addr_mask; if (flash->invert_high_pin) addr ^= 0x10000; return *(uint32_t *)&(flash->array[addr]); } @@ -82,14 +86,14 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) { flash_t *flash = (flash_t *)p; int i; - // pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); + pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); if (flash->invert_high_pin) { addr ^= 0x10000; if (addr & 0xfff00000) return; } - addr &= 0x1ffff; + addr &= flash->addr_mask; switch (flash->command) { @@ -111,7 +115,7 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) case CMD_PROGRAM_SETUP: // pclog("flash_write: program %05x %02x\n", addr, val); - if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) + if ((addr & 0x3e000) != (flash->block_start[3] & 0x3e000)) flash->array[addr] = val; flash->command = CMD_READ_STATUS; flash->status = 0x80; @@ -134,9 +138,23 @@ static void intel_flash_add_mappings(flash_t *flash) for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash); + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + (((i << 14) + 0x20000) & flash->addr_mask), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + (((i << 14) + 0x20000) & flash->addr_mask), 0, (void *)flash); } + + if (flash->type & FLASH_2MBIT) + { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x20000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array, 0, (void *)flash); + } } /* This is for boards which invert the high pin - the flash->array pointers need to pointer invertedly in order for INTERNAL writes to go to the right part of the array. */ @@ -146,9 +164,27 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash); + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + ((((i << 14) ^ 0x10000) + 0x20000) & flash->addr_mask), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + ((((i << 14) ^ 0x10000) + 0x20000) & flash->addr_mask), 0, (void *)flash); } + + if (flash->type & FLASH_2MBIT) + { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + 0x10000, 0, (void *)flash); + mem_mapping_add(&flash->mapping_h[9], 0xfffd0000, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array, 0, (void *)flash); + } } void *intel_flash_init(uint8_t type) @@ -158,6 +194,8 @@ void *intel_flash_init(uint8_t type) memset(flash, 0, sizeof(flash_t)); char fpath[1024]; int i; + + flash->type = type; switch(romset) { @@ -191,42 +229,99 @@ void *intel_flash_init(uint8_t type) case ROM_ITAUTEC_INFOWAYM: strcpy(flash_path, "infowaym/"); break; + case ROM_VS440FX: + strcpy(flash_path, "vs440fx/"); + break; + default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } // pclog("Flash init: Path is: %s\n", flash_path); - flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; + switch (type & (FLASH_IS_BXB | FLASH_2MBIT)) + { + case 0: + flash->flash_id = 0x94; + break; + case FLASH_IS_BXB: + flash->flash_id = 0x95; + break; + case FLASH_2MBIT: + flash->flash_id = 0x74; + break; + } + + flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff; + +// flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; flash->invert_high_pin = (type & FLASH_INVERT); - /* The block lengths are the same both flash types. */ - flash->block_len[BLOCK_MAIN] = 0x1c000; - flash->block_len[BLOCK_DATA1] = 0x01000; - flash->block_len[BLOCK_DATA2] = 0x01000; - flash->block_len[BLOCK_BOOT] = 0x02000; + if (type & FLASH_2MBIT) + { + flash->block_len[BLOCK_MAIN] = 0x20000; + flash->block_len[BLOCK_MAIN2] = 0x18000; + flash->block_len[BLOCK_DATA1] = 0x02000; + flash->block_len[BLOCK_DATA2] = 0x02000; + flash->block_len[BLOCK_BOOT] = 0x04000; - if (type & FLASH_IS_BXB) /* 28F001BX-B */ - { - flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1ffff; - flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x03fff; - flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x04fff; - flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x01fff; - } - else /* 28F001BX-T */ - { - flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1bfff; - flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x1cfff; - flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x1dfff; - flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x1ffff; - } + if (type & FLASH_IS_BXB) /* 28F001BX-B */ + { + flash->block_start[BLOCK_MAIN] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x3ffff; + flash->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x04000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x05fff; + flash->block_start[BLOCK_DATA2] = 0x06000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x07fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x03fff; + } + else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x37fff; + flash->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x39fff; + flash->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x3bfff; + flash->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x3ffff; + } + } + else + { + /* The block lengths are the same both flash types. */ + flash->block_len[BLOCK_MAIN] = 0x1c000; + flash->block_len[BLOCK_DATA1] = 0x01000; + flash->block_len[BLOCK_DATA2] = 0x01000; + flash->block_len[BLOCK_BOOT] = 0x02000; + + if (type & FLASH_IS_BXB) /* 28F001BX-B */ + { + flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x03fff; + flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x04fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x01fff; + } + else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1bfff; + flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x1cfff; + flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x1dfff; + flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x1ffff; + } + } for (i = 0; i < 8; i++) { @@ -238,10 +333,17 @@ void *intel_flash_init(uint8_t type) { memcpy(flash->array, rom + 65536, 65536); memcpy(flash->array + 65536, rom, 65536); + if (type & FLASH_2MBIT) + { + memcpy(flash->array + 0x20000, rom + 0x30000, 65536); + memcpy(flash->array + 0x30000, rom + 0x20000, 65536); + } } else { memcpy(flash->array, rom, 131072); + if (type & FLASH_2MBIT) + memcpy(flash->array + 0x20000, rom + 0x20000, 131072); } if (flash->invert_high_pin) @@ -262,7 +364,9 @@ void *intel_flash_init(uint8_t type) if (f) { fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); + if (type & FLASH_2MBIT) + fread(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 1, f); + fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); fread(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); fclose(f); } @@ -288,6 +392,11 @@ void *intel_flash_bxb_init() return intel_flash_init(FLASH_IS_BXB); } +static void *intel_flash_28fb200bxt_init(void) +{ + return intel_flash_init(FLASH_INVERT | FLASH_2MBIT); +} + void intel_flash_close(void *p) { FILE *f; @@ -299,6 +408,8 @@ void intel_flash_close(void *p) strcat(fpath, "flash.bin"); f = romfopen(fpath, "wb"); fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + if (flash->type & FLASH_2MBIT) + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); fclose(f); @@ -344,3 +455,16 @@ device_t intel_flash_bxb_device = NULL, NULL }; + +device_t intel_flash_28fb200bxt_device = +{ + "Intel 28FB200BX-T Flash BIOS", + 0, + intel_flash_28fb200bxt_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/intel_flash.h b/src/intel_flash.h index 2b4cb14..8ab1a6b 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -1,3 +1,4 @@ extern device_t intel_flash_bxt_ami_device; extern device_t intel_flash_bxt_device; extern device_t intel_flash_bxb_device; +extern device_t intel_flash_28fb200bxt_device; diff --git a/src/mem_bios.c b/src/mem_bios.c index 270080d..78e59c7 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -19,7 +19,7 @@ static int mem_load_basic(char *path) { char s[256]; FILE *f; - + sprintf(s, "%s/ibm-basic-1.10.rom", path); f = romfopen(s, "rb"); if (!f) @@ -53,26 +53,26 @@ static int mem_load_basic(char *path) return 1; } - + int loadbios() { FILE *f=NULL,*ff=NULL; int c; - + loadfont("mda.rom", FONT_MDA); loadfont("wy700.rom", FONT_WY700); loadfont("8x12.bin", FONT_MDSI); loadfont("im1024font.bin", FONT_IM1024); - + biosmask = 0xffff; - + if (!rom) - rom = malloc(0x20000); + rom = malloc(0x40000); memset(romext,0x63,0x4000); memset(rom, 0xff, 0x20000); - + pclog("Starting with romset %i\n", romset); - + switch (romset) { case ROM_PC1512: @@ -184,14 +184,14 @@ int loadbios() return 1; } break; - + case ROM_IBMPCJR: f = romfopen("ibmpcjr/bios.rom","rb"); if (!f) break; romfread(rom, 0x10000, 1, f); fclose(f); return 1; - + case ROM_GENXT: f=romfopen("genxt/pcxt.rom","rb"); if (!f) break; @@ -218,7 +218,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_PC2086: f = romfopen("pc2086/40179.ic129" ,"rb"); ff = romfopen("pc2086/40180.ic132","rb"); @@ -246,7 +246,7 @@ int loadbios() f = romfopen("pc3086/c000.bin", "rb"); if (!f) break; fclose(f); - biosmask = 0x3fff; + biosmask = 0x3fff; return 1; case ROM_IBMAT: @@ -434,7 +434,7 @@ int loadbios() if (f && ff) { fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); for (c = 0x0000; c < 0x10000; c += 2) { rom[c] = getc(f); @@ -501,7 +501,7 @@ int loadbios() ff = romfopen("megapc/211253-bios hi.u19", "rb"); if (!f || !ff) break; fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); for (c = 0x0000; c < 0x10000; c+=2) { rom[c]=getc(f); @@ -510,7 +510,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_AMI486: f=romfopen("ami486/ami486.bin","rb"); if (!f) break; @@ -518,7 +518,7 @@ int loadbios() fclose(f); //is486=1; return 1; - + case ROM_WIN486: // f=romfopen("win486/win486.bin","rb"); f=romfopen("win486/ali1429g.amw","rb"); @@ -529,9 +529,9 @@ int loadbios() return 1; case ROM_PCI486: - f=romfopen("hot-433/hot-433.ami","rb"); + f=romfopen("hot-433/hot-433.ami","rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -540,16 +540,16 @@ int loadbios() case ROM_SIS496: f = romfopen("sis496/sis496-1.awa", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; - + case ROM_P55VA: f = romfopen("p55va/va021297.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -557,7 +557,7 @@ int loadbios() case ROM_P55TVP4: f = romfopen("p55tvp4/tv5i0204.awd", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -566,9 +566,9 @@ int loadbios() // f = romfopen("430vx/ga586atv.bin", "rb"); // f = fopen("430vx/vx29.bin", "rb"); f = romfopen("430vx/55xwuq0e.bin", "rb"); -// f=romfopen("430vx/430vx","rb"); +// f=romfopen("430vx/430vx","rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -577,7 +577,7 @@ int loadbios() case ROM_P55T2P4: f = romfopen("p55t2p4/0207_j2.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -586,12 +586,12 @@ int loadbios() f = romfopen("revenge/1009af2_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("revenge/1009af2_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); + romfread(rom, 0xc000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -600,7 +600,7 @@ int loadbios() f = romfopen("endeavor/1006cb0_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("endeavor/1006cb0_.bi1", "rb"); if (!f) break; @@ -630,7 +630,7 @@ int loadbios() f = romfopen("ibmps1es/f80000.bin", "rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); //#endif biosmask = 0x1ffff; @@ -640,7 +640,7 @@ int loadbios() f = romfopen("ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -665,7 +665,7 @@ int loadbios() romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; - + case ROM_LTXT: f = romfopen("ltxt/27c64.bin", "rb"); if (!f) break; @@ -717,11 +717,11 @@ int loadbios() romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; - + case ROM_IBMPS2_M30_286: f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -777,7 +777,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_ATARIPC3: f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); if (!f) break; @@ -797,7 +797,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_EPSON_PCAX: f = romfopen("epson_pcax/EVAX", "rb"); ff = romfopen("epson_pcax/ODAX", "rb"); @@ -824,7 +824,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_EPSON_PCAX3: f = romfopen("epson_pcax3/EVAX3", "rb"); ff = romfopen("epson_pcax3/ODAX3", "rb"); @@ -837,7 +837,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_T3100E: loadfont("t3100e/t3100e_font.bin", FONT_T3100E); f=romfopen("t3100e/t3100e.rom","rb"); @@ -865,14 +865,14 @@ int loadbios() biosmask = 0x7fff; fclose(f); return 1; - + case ROM_PB_L300SX: f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); if (!f) break; romfread(rom, 65536, 1, f); fclose(f); return 1; - + case ROM_NCR_PC4I: f=romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN" ,"rb"); if (!f) break; @@ -880,14 +880,14 @@ int loadbios() fclose(f); biosmask = 0x3fff; return 1; - + case ROM_TO16_PC: f=romfopen("to16_pc/TO16_103.bin","rb"); if (!f) break; romfread(rom+0x8000,32768,1,f); fclose(f); return 1; - + case ROM_COMPAQ_PII: f = romfopen("compaq_pii/109740-001.rom", "rb"); ff = romfopen("compaq_pii/109739-001.rom", "rb"); @@ -901,7 +901,7 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; - + case ROM_ELX_PC425X: /*PC-425X uses a single ROM chip containing both main and video BIOSes. First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. @@ -927,7 +927,7 @@ int loadbios() f = romfopen("pb570/1007by0r.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("pb570/1007by0r.bi1", "rb"); if (!f) break; @@ -937,7 +937,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_ZAPPA: f = romfopen("zappa/1006bs0_.bio", "rb"); if (!f) break; @@ -976,7 +976,7 @@ int loadbios() f = romfopen("pb520r/1009bc0r.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("pb520r/1009bc0r.bi1", "rb"); if (!f) break; @@ -986,7 +986,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_COMPAQ_PIP: f=romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin","rb"); if (!f) break; @@ -1041,7 +1041,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_TULIP_TC7: f = romfopen("tulip_tc7/tc7be.bin", "rb"); ff = romfopen("tulip_tc7/tc7bo.bin", "rb"); @@ -1055,7 +1055,7 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; - + case ROM_ZD_SUPERS: /* [8088] Zenith Data Systems SupersPort */ f=romfopen("zdsupers/z184m v3.1d.10d","rb"); if (!f) break; @@ -1071,7 +1071,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_BULL_MICRAL_45: f = romfopen("bull_micral_45/even.fil", "rb"); ff = romfopen("bull_micral_45/odd.fil", "rb"); @@ -1136,6 +1136,37 @@ int loadbios() fclose(f); biosmask = 0x1fff; return 1; + + case ROM_VS440FX: + f = romfopen("vs440fx/1018CS1_.BIO", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x00000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI2", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x30000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI3", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x20000, 0x0a000, 1, f); + fclose(f); + + f = romfopen("vs440fx/1018CS1_.RCV", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x2c000, 0x04000, 1, f); + fclose(f); + + biosmask = 0x3ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 1b8c40f..35a2efd 100644 --- a/src/model.c +++ b/src/model.c @@ -29,6 +29,7 @@ #include "i430hx.h" #include "i430lx.h" #include "i430vx.h" +#include "i440fx.h" #include "ide.h" #include "intel.h" #include "intel_flash.h" @@ -49,6 +50,7 @@ #include "olivetti_m24.h" #include "opti495.h" #include "pc87306.h" +#include "pc87307.h" #include "pci.h" #include "pic.h" #include "piix.h" @@ -130,6 +132,7 @@ void compaq_xt_init(); void xt_xi8088_init(); void xt_zenith_init(); void at_mvp3_init(); +void at_vs440fx_init(); int model; int AMSTRAD, AT, PCI, TANDY, MCA; @@ -235,6 +238,8 @@ MODEL models[] = {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86_SS7}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + + {"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", { {"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -813,6 +818,21 @@ void at_mvp3_init() device_add(&sst_39sf010_device); } +void at_vs440fx_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xf); + pci_slot(0x11); + pci_slot(0x13); + i440fx_init(); + piix_init(7, 0xb, 0xf, 0x11, 0x13, i440fx_reset); + pc87307_init(0x2e); +// i440fx_init(); + device_add(&intel_flash_28fb200bxt_device); +} + void model_init() { pclog("Initting as %s\n", model_getname()); diff --git a/src/nvr.c b/src/nvr.c index 2d14e08..21df383 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -356,6 +356,7 @@ void loadnvr() case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break; + case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -463,6 +464,7 @@ void savenvr() case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); break; + case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "wb"); break; default: return; } diff --git a/src/pc87307.c b/src/pc87307.c new file mode 100644 index 0000000..e4f8ed4 --- /dev/null +++ b/src/pc87307.c @@ -0,0 +1,151 @@ +#include "ibm.h" + +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "pc87307.h" + +typedef struct pc87307_t +{ + int cur_reg; + int cur_device; + + uint8_t superio_cfg1, superio_cfg2; + + struct + { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[9]; +} pc87307_t; + +static pc87307_t pc87307_global; + +#define DEV_KBC 0 +#define DEV_MOUSE 1 +#define DEV_RTC 2 +#define DEV_FDC 3 +#define DEV_LPT 4 +#define DEV_COM2 5 +#define DEV_COM1 6 +#define DEV_GPIO 7 +#define DEV_POWER 8 + +#define REG_DEVICE 0x07 +#define REG_SID 0x20 +#define REG_SUPERIO_CFG1 0x21 +#define REG_SUPERIO_CFG2 0x22 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + +void pc87307_write(uint16_t port, uint8_t val, void *p) +{ + pc87307_t *pc87307 = (pc87307_t *)p; + + if (port == 0x2e) + pc87307->cur_reg = val; + else + { + if (pc87307->cur_reg == REG_DEVICE) + pc87307->cur_device = val & 0xf; + else + { +// pclog("Write pc87307 %02x [%02x] %02x\n", pc87307->cur_reg, pc87307->cur_device, val); + switch (pc87307->cur_reg) + { + case REG_ENABLE: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].enable = val; + break; + case REG_ADDRLO: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].irq = val; + break; + case REG_DMA: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].dma = val; + break; + } + + switch (pc87307->cur_device) + { + case DEV_FDC: + fdc_remove(); + if (pc87307->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (pc87307->dev[DEV_COM1].enable & 1) + serial1_set(pc87307->dev[DEV_COM1].addr, pc87307->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (pc87307->dev[DEV_COM2].enable & 1) + serial2_set(pc87307->dev[DEV_COM2].addr, pc87307->dev[DEV_COM2].irq); + break; + case DEV_LPT: + lpt1_remove(); + lpt2_remove(); + if (pc87307->dev[DEV_LPT].enable & 1) + lpt1_init(pc87307->dev[DEV_LPT].addr); + break; + } + } + } +} + +uint8_t pc87307_read(uint16_t port, void *p) +{ + pc87307_t *pc87307 = (pc87307_t *)p; + +// pclog("Read pc87307 %02x\n", pc87307->cur_reg); + + switch (pc87307->cur_reg) + { + case REG_DEVICE: + return pc87307->cur_device; + case REG_SID: + return 0x20; /*PC87307*/ + case REG_SUPERIO_CFG1: + return pc87307->superio_cfg1; + case REG_SUPERIO_CFG2: + return pc87307->superio_cfg2; + case REG_ENABLE: + return pc87307->dev[pc87307->cur_device].enable; + case REG_ADDRLO: + return pc87307->dev[pc87307->cur_device].addr & 0xff; + case REG_ADDRHI: + return pc87307->dev[pc87307->cur_device].addr >> 8; + case REG_IRQ: + return pc87307->dev[pc87307->cur_device].irq; + case REG_DMA: + return pc87307->dev[pc87307->cur_device].dma; + } + + return 0xff; +} + +void pc87307_init(uint16_t base) +{ + memset(&pc87307_global, 0, sizeof(pc87307_t)); + + pc87307_global.superio_cfg1 = 0x04; + pc87307_global.superio_cfg2 = 0x03; + + io_sethandler(base, 0x0002, pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, &pc87307_global); +} diff --git a/src/pc87307.h b/src/pc87307.h new file mode 100644 index 0000000..e28ae8a --- /dev/null +++ b/src/pc87307.h @@ -0,0 +1 @@ +void pc87307_init(uint16_t addr); diff --git a/src/x86_ops.h b/src/x86_ops.h index 73a0b6f..d317f50 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -38,6 +38,8 @@ extern OpFn dynarec_ops_winchip2_0f[1024]; extern OpFn dynarec_ops_pentium_0f[1024]; extern OpFn dynarec_ops_pentiummmx_0f[1024]; +extern OpFn dynarec_ops_pentiumpro_0f[1024]; + extern OpFn dynarec_ops_c6x86mx_0f[1024]; extern OpFn dynarec_ops_fpu_d8_a16[32]; @@ -104,6 +106,7 @@ extern OpFn ops_winchip2_0f[1024]; extern OpFn ops_pentium_0f[1024]; extern OpFn ops_pentiummmx_0f[1024]; +extern OpFn ops_pentiumpro_0f[1024]; extern OpFn ops_c6x86mx_0f[1024];