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.
This commit is contained in:
SarahW 2020-06-20 20:22:24 +01:00
commit cf33ab6c39
15 changed files with 751 additions and 101 deletions

View file

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

View file

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

View file

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

View file

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

145
src/i440fx.c Normal file
View file

@ -0,0 +1,145 @@
#include <string.h>
#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*/
}

2
src/i440fx.h Normal file
View file

@ -0,0 +1,2 @@
void i440fx_init();
void i440fx_reset();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

151
src/pc87307.c Normal file
View file

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

1
src/pc87307.h Normal file
View file

@ -0,0 +1 @@
void pc87307_init(uint16_t addr);

View file

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