PCem

changeset 76:fde668922ea4

Implement cascade interrupt correctly. Fixes crashes in Civilization. Re-add 0x82 opcode (same as 0x80).
author TomW
date Thu Feb 27 22:12:57 2014 +0000
parents 9b0c068452e5
children 7d45deb9fc54
files src/386_ops.h src/pic.c
diffstat 2 files changed, 75 insertions(+), 48 deletions(-) [+]
line diff
     1.1 --- a/src/386_ops.h	Thu Feb 27 19:53:54 2014 +0000
     1.2 +++ b/src/386_ops.h	Thu Feb 27 22:12:57 2014 +0000
     1.3 @@ -462,7 +462,7 @@
     1.4  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
     1.5  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
     1.6  
     1.7 -/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
     1.8 +/*80*/  op80_a16,       op81_w_a16,     op80_a16,       op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
     1.9  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
    1.10  /*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
    1.11  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.12 @@ -484,7 +484,7 @@
    1.13  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
    1.14  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.15  
    1.16 -/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.17 +/*80*/  op80_a16,       op81_w_a16,     op80_a16,       op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.18  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
    1.19  /*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
    1.20  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.21 @@ -506,7 +506,7 @@
    1.22  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
    1.23  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.24  
    1.25 -/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.26 +/*80*/  op80_a16,       op81_w_a16,     op80_a16,       op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.27  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
    1.28  /*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
    1.29  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.30 @@ -528,7 +528,7 @@
    1.31  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
    1.32  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.33  
    1.34 -/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.35 +/*80*/  op80_a16,       op81_w_a16,     op80_a16,       op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.36  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
    1.37  /*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
    1.38  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.39 @@ -553,7 +553,7 @@
    1.40  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
    1.41  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.42  
    1.43 -/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.44 +/*80*/  op80_a16,       op81_w_a16,     op80_a16,       op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
    1.45  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF,         opSAHF,         opLAHF,
    1.46  /*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
    1.47  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.48 @@ -575,7 +575,7 @@
    1.49  /*60*/  opPUSHA_l,      opPOPA_l,       opBOUND_l_a16,  opARPL_a16,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_l,   opIMUL_l_il_a16,opPUSH_imm_bl,  opIMUL_l_ib_a16,opINSB_a16,     opINSL_a16,     opOUTSB_a16,    opOUTSL_a16,
    1.50  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.51  
    1.52 -/*80*/  op80_a16,       op81_l_a16,     ILLEGAL,        op83_l_a16,     opTEST_b_a16,   opTEST_l_a16,   opXCHG_b_a16,   opXCHG_l_a16,   opMOV_b_r_a16,  opMOV_l_r_a16,  opMOV_r_b_a16,  opMOV_r_l_a16,  opMOV_l_seg_a16,opLEA_l_a16,    opMOV_seg_w_a16,opPOPL_a16,
    1.53 +/*80*/  op80_a16,       op81_l_a16,     op80_a16,       op83_l_a16,     opTEST_b_a16,   opTEST_l_a16,   opXCHG_b_a16,   opXCHG_l_a16,   opMOV_b_r_a16,  opMOV_l_r_a16,  opMOV_r_b_a16,  opMOV_r_l_a16,  opMOV_l_seg_a16,opLEA_l_a16,    opMOV_seg_w_a16,opPOPL_a16,
    1.54  /*90*/  opNOP,          opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE,         opCDQ,          opCALL_far_l,   opWAIT,         opPUSHFD,       opPOPFD,        opSAHF,         opLAHF,
    1.55  /*a0*/  opMOV_AL_a16,   opMOV_EAX_a16,  opMOV_a16_AL,   opMOV_a16_EAX,  opMOVSB_a16,    opMOVSL_a16,    opCMPSB_a16,    opCMPSL_a16,    opTEST_AL,      opTEST_EAX,     opSTOSB_a16,    opSTOSL_a16,    opLODSB_a16,    opLODSL_a16,    opSCASB_a16,    opSCASL_a16,
    1.56  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_EAX_imm,  opMOV_ECX_imm,  opMOV_EDX_imm,  opMOV_EBX_imm,  opMOV_ESP_imm,  opMOV_EBP_imm,  opMOV_ESI_imm,  opMOV_EDI_imm,
    1.57 @@ -597,7 +597,7 @@
    1.58  /*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a32,  opARPL_a32,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_w,   opIMUL_w_iw_a32,opPUSH_imm_bw,  opIMUL_w_ib_a32,opINSB_a32,     opINSW_a32,     opOUTSB_a32,    opOUTSW_a32,
    1.59  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.60  
    1.61 -/*80*/  op80_a32,       op81_w_a32,     ILLEGAL,        op83_w_a32,     opTEST_b_a32,   opTEST_w_a32,   opXCHG_b_a32,   opXCHG_w_a32,   opMOV_b_r_a32,  opMOV_w_r_a32,  opMOV_r_b_a32,  opMOV_r_w_a32,  opMOV_w_seg_a32,opLEA_w_a32,    opMOV_seg_w_a32,opPOPW_a32,
    1.62 +/*80*/  op80_a32,       op81_w_a32,     op80_a32,       op83_w_a32,     opTEST_b_a32,   opTEST_w_a32,   opXCHG_b_a32,   opXCHG_w_a32,   opMOV_b_r_a32,  opMOV_w_r_a32,  opMOV_r_b_a32,  opMOV_r_w_a32,  opMOV_w_seg_a32,opLEA_w_a32,    opMOV_seg_w_a32,opPOPW_a32,
    1.63  /*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF,         opSAHF,         opLAHF,
    1.64  /*a0*/  opMOV_AL_a32,   opMOV_AX_a32,   opMOV_a32_AL,   opMOV_a32_AX,   opMOVSB_a32,    opMOVSW_a32,    opCMPSB_a32,    opCMPSW_a32,    opTEST_AL,      opTEST_AX,      opSTOSB_a32,    opSTOSW_a32,    opLODSB_a32,    opLODSW_a32,    opSCASB_a32,    opSCASW_a32,
    1.65  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
    1.66 @@ -619,7 +619,7 @@
    1.67  /*60*/  opPUSHA_l,      opPOPA_l,       opBOUND_l_a32,  opARPL_a32,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_l,   opIMUL_l_il_a32,opPUSH_imm_bl,  opIMUL_l_ib_a32,opINSB_a32,     opINSL_a32,     opOUTSB_a32,    opOUTSL_a32,
    1.68  /*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
    1.69  
    1.70 -/*80*/  op80_a32,       op81_l_a32,     ILLEGAL,        op83_l_a32,     opTEST_b_a32,   opTEST_l_a32,   opXCHG_b_a32,   opXCHG_l_a32,   opMOV_b_r_a32,  opMOV_l_r_a32,  opMOV_r_b_a32,  opMOV_r_l_a32,  opMOV_l_seg_a32,opLEA_l_a32,    opMOV_seg_w_a32,opPOPL_a32,
    1.71 +/*80*/  op80_a32,       op81_l_a32,     op80_a32,       op83_l_a32,     opTEST_b_a32,   opTEST_l_a32,   opXCHG_b_a32,   opXCHG_l_a32,   opMOV_b_r_a32,  opMOV_l_r_a32,  opMOV_r_b_a32,  opMOV_r_l_a32,  opMOV_l_seg_a32,opLEA_l_a32,    opMOV_seg_w_a32,opPOPL_a32,
    1.72  /*90*/  opNOP,          opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE,         opCDQ,          opCALL_far_l,   opWAIT,         opPUSHFD,       opPOPFD,        opSAHF,         opLAHF,
    1.73  /*a0*/  opMOV_AL_a32,   opMOV_EAX_a32,  opMOV_a32_AL,   opMOV_a32_EAX,  opMOVSB_a32,    opMOVSL_a32,    opCMPSB_a32,    opCMPSL_a32,    opTEST_AL,      opTEST_EAX,     opSTOSB_a32,    opSTOSL_a32,    opLODSB_a32,    opLODSL_a32,    opSCASB_a32,    opSCASL_a32,
    1.74  /*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_EAX_imm,  opMOV_ECX_imm,  opMOV_EDX_imm,  opMOV_EBX_imm,  opMOV_ESP_imm,  opMOV_EBP_imm,  opMOV_ESI_imm,  opMOV_EDI_imm,
     2.1 --- a/src/pic.c	Thu Feb 27 19:53:54 2014 +0000
     2.2 +++ b/src/pic.c	Thu Feb 27 22:12:57 2014 +0000
     2.3 @@ -9,8 +9,11 @@
     2.4  
     2.5  void pic_updatepending()
     2.6  {
     2.7 -        pic_intpending = (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2));
     2.8 -//        pclog("pic_intpending = %i  %02X %02X %02X\n", pic_intpending, pic.pend, pic.mask, pic.mask2);
     2.9 +        pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
    2.10 +        if (!((pic.mask | pic.mask2) & (1 << 2)))
    2.11 +                pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2);
    2.12 +/*        pclog("pic_intpending = %i  %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2);
    2.13 +        pclog("                    %02X %02X %02X %02X\n", pic_intpending, pic2.ins, pic2.pend, pic2.mask, pic2.mask2);*/
    2.14  }
    2.15  
    2.16  
    2.17 @@ -29,6 +32,20 @@
    2.18          pic_intpending = 0;
    2.19  }
    2.20  
    2.21 +void pic_update_mask(uint8_t *mask, uint8_t ins)
    2.22 +{
    2.23 +        int c;
    2.24 +        *mask = 0;
    2.25 +        for (c = 0; c < 8; c++)
    2.26 +        {
    2.27 +                if (ins & (1 << c))
    2.28 +                {
    2.29 +                        *mask = 0xff << c;
    2.30 +                        return;
    2.31 +                }
    2.32 +        }
    2.33 +}
    2.34 +
    2.35  void pic_write(uint16_t addr, uint8_t val, void *priv)
    2.36  {
    2.37          int c;
    2.38 @@ -75,7 +92,9 @@
    2.39                          {
    2.40  //                                pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7));
    2.41                                  pic.ins&=~(1<<(val&7));
    2.42 -                                pic.mask2&=~(1<<(val&7));
    2.43 +                                pic_update_mask(&pic.mask2, pic.ins);
    2.44 +                                if (val == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
    2.45 +                                        pic.pend |= (1 << 2);
    2.46  //                                pic.pend&=(1<<(val&7));
    2.47  //                                if ((val&7)==1) pollkeywaiting();
    2.48                                  pic_updatepending();
    2.49 @@ -87,7 +106,11 @@
    2.50                                          if (pic.ins&(1<<c))
    2.51                                          {
    2.52                                                  pic.ins&=~(1<<c);
    2.53 -                                                pic.mask2&=~(1<<c);
    2.54 +                                                pic_update_mask(&pic.mask2, pic.ins);
    2.55 +
    2.56 +                                                if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
    2.57 +                                                        pic.pend |= (1 << 2);
    2.58 +
    2.59  //                                                pic.pend&=~(1<<c);
    2.60                                                  if (c==1 && keywaiting)
    2.61                                                  {
    2.62 @@ -166,7 +189,8 @@
    2.63                          if ((val&0xE0)==0x60)
    2.64                          {
    2.65                                  pic2.ins&=~(1<<(val&7));
    2.66 -                                pic2.mask2&=~(1<<(val&7));
    2.67 +                                pic_update_mask(&pic2.mask2, pic2.ins);
    2.68 +
    2.69                                  pic_updatepending();
    2.70                          }
    2.71                          else
    2.72 @@ -175,8 +199,9 @@
    2.73                                  {
    2.74                                          if (pic2.ins&(1<<c))
    2.75                                          {
    2.76 -                                                pic2.ins&=~(1<<c);
    2.77 -                                                pic2.mask2&=~(1<<c);
    2.78 +                                                pic2.ins &= ~(1<<c);
    2.79 +                                                pic_update_mask(&pic2.mask2, pic2.ins);
    2.80 +                                                        
    2.81                                                  pic_updatepending();
    2.82                                                  return;
    2.83                                          }
    2.84 @@ -220,6 +245,8 @@
    2.85          if (num>0xFF)
    2.86          {
    2.87                  pic2.pend|=(num>>8);
    2.88 +                if ((pic2.pend&~pic2.mask)&~pic2.mask2)
    2.89 +                        pic.pend |= (1 << 2);
    2.90          }
    2.91          else
    2.92          {
    2.93 @@ -254,64 +281,64 @@
    2.94          while (!(num & (1 << c))) c++;
    2.95          //pclog("INTC %04X %i\n", num, c);
    2.96          pic_current[c]=0;
    2.97 +#if 0
    2.98          if (num>0xFF) pic2.pend&=~(num>>8);
    2.99          else
   2.100          {
   2.101                  pic.pend&=~num;
   2.102          }
   2.103 +#endif
   2.104  }
   2.105  
   2.106  uint8_t picinterrupt()
   2.107  {
   2.108          uint8_t temp=pic.pend&~pic.mask;
   2.109          int c;
   2.110 -        for (c=0;c<8;c++)
   2.111 +        for (c = 0; c < 2; c++)
   2.112          {
   2.113 -                if (temp&(1<<c))
   2.114 +                if (temp & (1 << c))
   2.115                  {
   2.116 -                        pic.pend&=~(1<<c);
   2.117 -                        pic.ins|=(1<<c);
   2.118 -                        pic.mask2|=(1<<c);
   2.119 -                        
   2.120 +                        pic.pend &= ~(1 << c);
   2.121 +                        pic.ins |= (1 << c);
   2.122 +                        pic_update_mask(&pic.mask2, pic.ins);                      
   2.123                          pic_updatepending();
   2.124 -//                        pclog("picinterrupt : Taking PIC1 int %i\n", c);
   2.125 -//                        if (!c) pclog("Taking timer int\n");
   2.126 -//                        if (c==5) printf("GUS IRQ!\n");
   2.127 -//                        if (c==1) printf("Keyboard int!\n");
   2.128 -//                        if (c==0) pic.ins&=~1;
   2.129                          return c+pic.vector;
   2.130                  }
   2.131          }
   2.132 -/*        if (pic.mask2 & 4)
   2.133 -                return 0xff;*/
   2.134 -        temp=pic2.pend&~pic2.mask;
   2.135 -        for (c=0;c<8;c++)
   2.136 +        if (temp & (1 << 2))
   2.137          {
   2.138 -                if (temp&(1<<c))
   2.139 +                uint8_t temp2 = pic2.pend & ~pic2.mask;
   2.140 +                for (c = 0; c < 8; c++)
   2.141                  {
   2.142 -                        pic2.pend&=~(1<<c);
   2.143 -                        pic2.ins|=(1<<c);
   2.144 -                        pic2.mask2|=(1<<c);
   2.145 +                        if (temp2 & (1 << c))
   2.146 +                        {
   2.147 +                                pic2.pend &= ~(1 << c);
   2.148 +                                pic2.ins |= (1 << c);
   2.149 +                                pic_update_mask(&pic2.mask2, pic2.ins);
   2.150 +                        
   2.151 +                                pic.pend &= ~(1 << c);
   2.152 +                                pic.ins |= (1 << 2); /*Cascade IRQ*/
   2.153 +                                pic_update_mask(&pic.mask2, pic.ins);
   2.154 +
   2.155 +                                pic_updatepending();
   2.156 +                                return c+pic2.vector;
   2.157 +                        }
   2.158 +                }
   2.159 +        }
   2.160 +        for (c = 3; c < 8; c++)
   2.161 +        {
   2.162 +                if (temp & (1 << c))
   2.163 +                {
   2.164 +                        pic.pend &= ~(1 << c);
   2.165 +                        pic.ins |= (1 << c);
   2.166 +                        pic_update_mask(&pic.mask2, pic.ins);                      
   2.167                          pic_updatepending();
   2.168 -                        //pclog("Taking PIC2 int %i\n", c);                        
   2.169 -//                        if (c==(14-8)) pclog("Taking IRQ 14 %02X\n",c+pic2.vector);
   2.170 -//                        printf("Taking high IRQ! %i\n",c);
   2.171 -//                        if (c==1) printf("Keyboard int!\n");
   2.172 -//                        if (c==0) pic.ins&=~1;
   2.173 -                        return c+pic2.vector;
   2.174 +                        return c+pic.vector;
   2.175                  }
   2.176          }
   2.177          return 0xFF;
   2.178  }
   2.179  
   2.180 -void picclear(int num)
   2.181 -{
   2.182 -//        pclog("Pic clear %02X\n",num);
   2.183 -        pic.pend&=~num;
   2.184 -        pic.ins&=~num;
   2.185 -        pic_updatepending();
   2.186 -}
   2.187 -
   2.188  void dumppic()
   2.189  {
   2.190          pclog("PIC1 : MASK %02X PEND %02X INS %02X VECTOR %02X\n",pic.mask,pic.pend,pic.ins,pic.vector);