mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Merge remote-tracking branch 'upstream/master' into feature/ich2
This commit is contained in:
@@ -761,7 +761,7 @@ void
|
||||
pc_full_speed(void)
|
||||
{
|
||||
if (!atfullspeed) {
|
||||
pc_log("Set fullspeed - %i %i\n", is386, AT);
|
||||
pc_log("Set fullspeed - %i %i\n", is386, is486);
|
||||
pc_speed_changed();
|
||||
}
|
||||
atfullspeed = 1;
|
||||
@@ -962,6 +962,8 @@ pc_reset_hard_close(void)
|
||||
video_reset_close();
|
||||
|
||||
cpu_close();
|
||||
|
||||
serial_set_next_inst(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -38,12 +38,25 @@ typedef struct
|
||||
uint8_t cur_reg, tries,
|
||||
reg_base, reg_last,
|
||||
reg_00, is_471,
|
||||
force_flush, shadowed,
|
||||
smram_enabled, pad,
|
||||
regs[39], scratch[2];
|
||||
uint32_t mem_state[8];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c4xx_t;
|
||||
|
||||
static void
|
||||
sis_85c4xx_recalcremap(sis_85c4xx_t *dev)
|
||||
{
|
||||
if (dev->is_471) {
|
||||
if ((mem_size > 8192) || (dev->shadowed & 0x3c) || (dev->regs[0x0b] & 0x02))
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(-256);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
{
|
||||
@@ -52,6 +65,8 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
uint32_t readext, writeext;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
|
||||
dev->shadowed = 0x00;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
@@ -73,25 +88,34 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
if (dev->regs[0x02] & 0x80)
|
||||
dev->shadowed |= (1 << i);
|
||||
if (!(dev->regs[0x02] & 0x40))
|
||||
dev->shadowed |= (1 << i);
|
||||
if (dev->force_flush || (dev->mem_state[i] != shflags)) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
mem_set_mem_state_both(base, 0x8000, shflags);
|
||||
if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(base, base + 0x7fff);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
} else {
|
||||
shflags = readext | writeext;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
if (dev->force_flush || (dev->mem_state[i] != shflags)) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
mem_set_mem_state_both(base, 0x8000, shflags);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
if (dev->force_flush) {
|
||||
flushmmucache();
|
||||
dev->force_flush = 0;
|
||||
} else if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
|
||||
sis_85c4xx_recalcremap(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -158,12 +182,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case 0x0b:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
if (dev->is_471 && (valxor & 0x02)) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
if (valxor & 0x02)
|
||||
sis_85c4xx_recalcremap(dev);
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
@@ -184,8 +204,10 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
ram_base = 0x00000000;
|
||||
break;
|
||||
}
|
||||
dev->smram_enabled = (ram_base != 0x00000000);
|
||||
if (ram_base != 0x00000000)
|
||||
smram_enable(dev->smram, host_base, ram_base, 0x00010000, (val & 0x10), 1);
|
||||
sis_85c4xx_recalcremap(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -289,7 +311,6 @@ sis_85c4xx_reset(void *priv)
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
|
||||
mem_remap_top(256);
|
||||
soft_reset_mask = 0;
|
||||
} else {
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
@@ -309,6 +330,7 @@ sis_85c4xx_reset(void *priv)
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
dev->force_flush = 1;
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -364,6 +364,96 @@ static int op0F_l_a32(uint32_t fetchdat)
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
|
||||
const OpFn OP_TABLE(186_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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*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*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*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,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(286_0f)[1024] =
|
||||
{
|
||||
@@ -1916,6 +2006,97 @@ const OpFn OP_TABLE(pentium2d_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,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(186)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16,
|
||||
/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w,
|
||||
/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS,
|
||||
/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS,
|
||||
|
||||
/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI,
|
||||
/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI,
|
||||
/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, ILLEGAL, 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,
|
||||
/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE,
|
||||
|
||||
/*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,
|
||||
/*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_186, opSAHF, opLAHF,
|
||||
/*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,
|
||||
/*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,
|
||||
|
||||
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_186,
|
||||
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
|
||||
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
|
||||
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16,
|
||||
/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w,
|
||||
/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS,
|
||||
/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS,
|
||||
|
||||
/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI,
|
||||
/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI,
|
||||
/*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,
|
||||
/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE,
|
||||
|
||||
/*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,
|
||||
/*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_186, opSAHF, opLAHF,
|
||||
/*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,
|
||||
/*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,
|
||||
|
||||
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_186,
|
||||
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
|
||||
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
|
||||
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16,
|
||||
/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w,
|
||||
/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS,
|
||||
/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS,
|
||||
|
||||
/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI,
|
||||
/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI,
|
||||
/*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,
|
||||
/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE,
|
||||
|
||||
/*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,
|
||||
/*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_186, opSAHF, opLAHF,
|
||||
/*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,
|
||||
/*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,
|
||||
|
||||
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_186,
|
||||
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
|
||||
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
|
||||
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16,
|
||||
/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w,
|
||||
/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, opES_w_a16, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, opCS_w_a16, opDAS,
|
||||
/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, opSS_w_a16, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, opDS_w_a16, opAAS,
|
||||
|
||||
/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI,
|
||||
/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI,
|
||||
/*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,
|
||||
/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE,
|
||||
|
||||
/*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,
|
||||
/*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_186, opSAHF, opLAHF,
|
||||
/*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,
|
||||
/*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,
|
||||
|
||||
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_186,
|
||||
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
|
||||
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
|
||||
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(286)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
|
||||
225
src/cpu/8080.c
Normal file
225
src/cpu/8080.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* 8080 CPU emulation.
|
||||
*
|
||||
* Authors: Cacodemon345
|
||||
*
|
||||
* Copyright 2022 Cacodemon345
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/i8080.h>
|
||||
#include <86box/mem.h>
|
||||
|
||||
static int completed = 1;
|
||||
static int in_rep = 0, repeating = 0, rep_c_flag = 0;
|
||||
static int oldc, cycdiff;
|
||||
#ifdef UNUSED_8080_VARS
|
||||
static int prefetching = 1;
|
||||
static int refresh = 0, clear_lock = 0;
|
||||
|
||||
static uint32_t cpu_src = 0, cpu_dest = 0;
|
||||
static uint32_t cpu_data = 0;
|
||||
#endif
|
||||
|
||||
static void
|
||||
clock_start(void)
|
||||
{
|
||||
cycdiff = cycles;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clock_end(void)
|
||||
{
|
||||
int diff = cycdiff - cycles;
|
||||
|
||||
/* On 808x systems, clock speed is usually crystal frequency divided by an integer. */
|
||||
tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
}
|
||||
|
||||
static void
|
||||
i8080_wait(int c, int bus)
|
||||
{
|
||||
cycles -= c;
|
||||
if (bus < 2) {
|
||||
clock_end();
|
||||
clock_start();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNUSED_8080_FUNCS
|
||||
static uint8_t
|
||||
readmemb(uint32_t a)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
i8080_wait(4, 1);
|
||||
ret = read_mem_b(a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ins_fetch(i8080* cpu)
|
||||
{
|
||||
uint8_t ret = cpu->readmembyte(cpu->pmembase + cpu->pc);
|
||||
|
||||
cpu->pc++;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
transfer_from_808x(i8080* cpu)
|
||||
{
|
||||
cpu->hl = BX;
|
||||
cpu->bc = CX;
|
||||
cpu->de = DX;
|
||||
cpu->a = AL;
|
||||
cpu->flags = cpu_state.flags & 0xFF;
|
||||
cpu->sp = BP;
|
||||
cpu->pc = cpu_state.pc;
|
||||
cpu->oldpc = cpu_state.oldpc;
|
||||
cpu->pmembase = cs;
|
||||
cpu->dmembase = ds;
|
||||
}
|
||||
|
||||
void
|
||||
transfer_to_808x(i8080* cpu)
|
||||
{
|
||||
BX = cpu->hl;
|
||||
CX = cpu->bc;
|
||||
DX = cpu->de;
|
||||
AL = cpu->a;
|
||||
cpu_state.flags &= 0xFF00;
|
||||
cpu_state.flags |= cpu->flags & 0xFF;
|
||||
BP = cpu->sp;
|
||||
cpu_state.pc = cpu->pc;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
getreg_i8080(i8080 *cpu, uint8_t reg)
|
||||
{
|
||||
uint8_t ret = 0xFF;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: ret = cpu->b; break;
|
||||
case 0x1: ret = cpu->c; break;
|
||||
case 0x2: ret = cpu->d; break;
|
||||
case 0x3: ret = cpu->e; break;
|
||||
case 0x4: ret = cpu->h; break;
|
||||
case 0x5: ret = cpu->l; break;
|
||||
case 0x6: ret = cpu->readmembyte(cpu->dmembase + cpu->sp); break;
|
||||
case 0x7: ret = cpu->a; break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
getreg_i8080_emu(i8080 *cpu, uint8_t reg)
|
||||
{
|
||||
uint8_t ret = 0xFF;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: ret = CH; break;
|
||||
case 0x1: ret = CL; break;
|
||||
case 0x2: ret = DH; break;
|
||||
case 0x3: ret = DL; break;
|
||||
case 0x4: ret = BH; break;
|
||||
case 0x5: ret = BL; break;
|
||||
case 0x6: ret = cpu->readmembyte(cpu->dmembase + BP); break;
|
||||
case 0x7: ret = AL; break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
setreg_i8080_emu(i8080 *cpu, uint8_t reg, uint8_t val)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: CH = val; break;
|
||||
case 0x1: CL = val; break;
|
||||
case 0x2: DH = val; break;
|
||||
case 0x3: DL = val; break;
|
||||
case 0x4: BH = val; break;
|
||||
case 0x5: BL = val; break;
|
||||
case 0x6: cpu->writemembyte(cpu->dmembase + BP, val); break;
|
||||
case 0x7: AL = val; break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: cpu->b = val; break;
|
||||
case 0x1: cpu->c = val; break;
|
||||
case 0x2: cpu->d = val; break;
|
||||
case 0x3: cpu->e = val; break;
|
||||
case 0x4: cpu->h = val; break;
|
||||
case 0x5: cpu->l = val; break;
|
||||
case 0x6: cpu->writemembyte(cpu->dmembase + cpu->sp, val); break;
|
||||
case 0x7: cpu->a = val; break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
interpret_exec8080(i8080* cpu, uint8_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case 0x00:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Actually implement i8080 emulation. */
|
||||
void
|
||||
exec8080(i8080* cpu, int cycs)
|
||||
{
|
||||
#ifdef UNUSED_8080_VARS
|
||||
uint8_t temp = 0, temp2;
|
||||
uint8_t old_af;
|
||||
uint8_t handled = 0;
|
||||
uint16_t addr, tempw;
|
||||
uint16_t new_ip;
|
||||
int bits;
|
||||
#endif
|
||||
|
||||
cycles += cycs;
|
||||
|
||||
while (cycles > 0) {
|
||||
cpu->startclock();
|
||||
|
||||
if (!repeating) {
|
||||
cpu->oldpc = cpu->pc;
|
||||
opcode = cpu->fetchinstruction(cpu);
|
||||
oldc = cpu->flags & C_FLAG_I8080;
|
||||
i8080_wait(1, 0);
|
||||
}
|
||||
completed = 1;
|
||||
if (completed) {
|
||||
repeating = 0;
|
||||
in_rep = 0;
|
||||
rep_c_flag = 0;
|
||||
cpu->endclock();
|
||||
if (cpu->checkinterrupts) cpu->checkinterrupts();
|
||||
}
|
||||
}
|
||||
}
|
||||
3047
src/cpu/808x.c
3047
src/cpu/808x.c
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
|
||||
386_dynarec.c x86seg.c x87.c x87_timings.c)
|
||||
386_dynarec.c x86seg.c x87.c x87_timings.c 8080.c)
|
||||
|
||||
if(AMD_K5)
|
||||
target_compile_definitions(cpu PRIVATE USE_AMD_K5)
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2018 leilei.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2018-2021 Fred N. van Kempen.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
@@ -112,6 +112,7 @@ int isa_cycles, cpu_inited,
|
||||
cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed,
|
||||
cpu_cyrix_alignment, CPUID,
|
||||
|
||||
is186, is_nec,
|
||||
is286, is386, is6117, is486 = 1,
|
||||
cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc,
|
||||
is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu,
|
||||
@@ -356,7 +357,9 @@ cpu_set(void)
|
||||
unmask_a20_in_smm = 0;
|
||||
|
||||
CPUID = cpu_s->cpuid_model;
|
||||
is8086 = (cpu_s->cpu_type > CPU_8088);
|
||||
is8086 = (cpu_s->cpu_type > CPU_8088) && !(cpu_s->cpu_type == CPU_V20);
|
||||
is_nec = (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
||||
is186 = (cpu_s->cpu_type == CPU_186) || (cpu_s->cpu_type == CPU_188) || (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
||||
is286 = (cpu_s->cpu_type >= CPU_286);
|
||||
is386 = (cpu_s->cpu_type >= CPU_386SX);
|
||||
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
@@ -514,6 +517,17 @@ cpu_set(void)
|
||||
case CPU_8086:
|
||||
break;
|
||||
|
||||
case CPU_V20:
|
||||
case CPU_V30:
|
||||
case CPU_186:
|
||||
case CPU_188:
|
||||
#ifdef USE_DYNAREC
|
||||
x86_setopcodes(ops_186, ops_186_0f, dynarec_ops_186, dynarec_ops_186_0f);
|
||||
#else
|
||||
x86_setopcodes(ops_186, ops_186_0f);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CPU_286:
|
||||
#ifdef USE_DYNAREC
|
||||
x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2018 leilei.
|
||||
* Copyright 2016,2018 Miran Grca.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_CPU_H
|
||||
#define EMU_CPU_H
|
||||
@@ -24,6 +24,7 @@
|
||||
enum {
|
||||
FPU_NONE,
|
||||
FPU_8087,
|
||||
FPU_80187,
|
||||
FPU_287,
|
||||
FPU_287XL,
|
||||
FPU_387,
|
||||
@@ -34,10 +35,10 @@ enum {
|
||||
enum {
|
||||
CPU_8088 = 1, /* 808x class CPUs */
|
||||
CPU_8086,
|
||||
#ifdef USE_NEC_808X
|
||||
CPU_V20, /* NEC 808x class CPUs - future proofing */
|
||||
CPU_V20, /* NEC 808x class CPUs */
|
||||
CPU_V30,
|
||||
#endif
|
||||
CPU_188, /* 18x class CPUs */
|
||||
CPU_186,
|
||||
CPU_286, /* 286 class CPUs */
|
||||
CPU_386SX, /* 386 class CPUs */
|
||||
CPU_IBM386SLC,
|
||||
@@ -86,26 +87,30 @@ enum {
|
||||
CPU_PKG_8088 = (1 << 0),
|
||||
CPU_PKG_8088_EUROPC = (1 << 1),
|
||||
CPU_PKG_8086 = (1 << 2),
|
||||
CPU_PKG_286 = (1 << 3),
|
||||
CPU_PKG_386SX = (1 << 4),
|
||||
CPU_PKG_386DX = (1 << 5),
|
||||
CPU_PKG_M6117 = (1 << 6),
|
||||
CPU_PKG_386SLC_IBM = (1 << 7),
|
||||
CPU_PKG_486SLC = (1 << 8),
|
||||
CPU_PKG_486SLC_IBM = (1 << 9),
|
||||
CPU_PKG_486BL = (1 << 10),
|
||||
CPU_PKG_486DLC = (1 << 11),
|
||||
CPU_PKG_SOCKET1 = (1 << 12),
|
||||
CPU_PKG_SOCKET3 = (1 << 13),
|
||||
CPU_PKG_SOCKET3_PC330 = (1 << 14),
|
||||
CPU_PKG_STPC = (1 << 15),
|
||||
CPU_PKG_SOCKET4 = (1 << 16),
|
||||
CPU_PKG_SOCKET5_7 = (1 << 17),
|
||||
CPU_PKG_SOCKET8 = (1 << 18),
|
||||
CPU_PKG_SLOT1 = (1 << 19),
|
||||
CPU_PKG_SLOT2 = (1 << 20),
|
||||
CPU_PKG_SOCKET370 = (1 << 21),
|
||||
CPU_PKG_EBGA368 = (1 << 22)
|
||||
CPU_PKG_188 = (1 << 3),
|
||||
CPU_PKG_186 = (1 << 4),
|
||||
CPU_PKG_286 = (1 << 5),
|
||||
CPU_PKG_386SX = (1 << 6),
|
||||
CPU_PKG_386DX = (1 << 7),
|
||||
CPU_PKG_M6117 = (1 << 8),
|
||||
CPU_PKG_386SLC_IBM = (1 << 9),
|
||||
CPU_PKG_486SLC = (1 << 10),
|
||||
CPU_PKG_486SLC_IBM = (1 << 11),
|
||||
CPU_PKG_486BL = (1 << 12),
|
||||
CPU_PKG_486DLC = (1 << 13),
|
||||
CPU_PKG_SOCKET1 = (1 << 14),
|
||||
CPU_PKG_SOCKET3 = (1 << 15),
|
||||
CPU_PKG_SOCKET3_PC330 = (1 << 16),
|
||||
CPU_PKG_STPC = (1 << 17),
|
||||
CPU_PKG_SOCKET4 = (1 << 18),
|
||||
CPU_PKG_SOCKET5_7 = (1 << 19),
|
||||
CPU_PKG_SOCKET8 = (1 << 20),
|
||||
CPU_PKG_SLOT1 = (1 << 21),
|
||||
CPU_PKG_SLOT2 = (1 << 22),
|
||||
CPU_PKG_SLOTA = (1 << 23),
|
||||
CPU_PKG_SOCKET370 = (1 << 24),
|
||||
CPU_PKG_SOCKETA = (1 << 25),
|
||||
CPU_PKG_EBGA368 = (1 << 26)
|
||||
};
|
||||
|
||||
#define MANU_INTEL 0
|
||||
@@ -113,6 +118,7 @@ enum {
|
||||
#define MANU_CYRIX 2
|
||||
#define MANU_IDT 3
|
||||
#define MANU_NEC 4
|
||||
#define MANU_IBM 5
|
||||
|
||||
#define CPU_SUPPORTS_DYNAREC 1
|
||||
#define CPU_REQUIRES_DYNAREC 2
|
||||
@@ -176,6 +182,7 @@ typedef struct {
|
||||
#define D_FLAG 0x0400
|
||||
#define V_FLAG 0x0800
|
||||
#define NT_FLAG 0x4000
|
||||
#define MD_FLAG 0x8000
|
||||
|
||||
#define RF_FLAG 0x0001 /* in EFLAGS */
|
||||
#define VM_FLAG 0x0002 /* in EFLAGS */
|
||||
@@ -392,6 +399,8 @@ typedef struct {
|
||||
uint16_t flags, eflags;
|
||||
|
||||
uint32_t _smbase;
|
||||
|
||||
uint8_t inside_emulation_mode;
|
||||
} cpu_state_t;
|
||||
|
||||
#define in_smm cpu_state._in_smm
|
||||
@@ -493,10 +502,11 @@ extern double fpu_multi;
|
||||
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
|
||||
penalties when crossing 8-byte boundaries*/
|
||||
|
||||
extern int is8086, is286, is386, is6117, is486;
|
||||
extern int is8086, is186, is286, is386, is6117, is486;
|
||||
extern int is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm;
|
||||
extern int hascache;
|
||||
extern int isibm486;
|
||||
extern int is_nec;
|
||||
extern int is_rapidcad;
|
||||
extern int hasfpu;
|
||||
#define CPU_FEATURE_RDTSC (1 << 0)
|
||||
@@ -506,6 +516,7 @@ extern int hasfpu;
|
||||
#define CPU_FEATURE_VME (1 << 4)
|
||||
#define CPU_FEATURE_CX8 (1 << 5)
|
||||
#define CPU_FEATURE_3DNOW (1 << 6)
|
||||
#define CPU_FEATURE_SYSCALL (1 << 7)
|
||||
|
||||
extern uint32_t cpu_features;
|
||||
|
||||
@@ -727,6 +738,7 @@ extern void (*cpu_exec)(int cycs);
|
||||
extern uint8_t do_translate, do_translate2;
|
||||
|
||||
extern void reset_808x(int hard);
|
||||
extern void interrupt_808x(uint16_t addr);
|
||||
|
||||
extern void cpu_register_fast_off_handler(void *timer);
|
||||
extern void cpu_fast_off_advance(void);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 leilei.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2020 RichardG.
|
||||
* Copyright 2021 dob205.
|
||||
*/
|
||||
@@ -43,6 +43,13 @@ FPU fpus_8088[] =
|
||||
{"8087", "8087", FPU_8087},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
FPU fpus_80186[] =
|
||||
{
|
||||
{"None", "none", FPU_NONE},
|
||||
{"8087", "8087", FPU_8087},
|
||||
{"80187", "80187", FPU_80187},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
FPU fpus_80286[] =
|
||||
{
|
||||
{"None", "none", FPU_NONE},
|
||||
@@ -79,6 +86,7 @@ const cpu_family_t cpu_families[] = {
|
||||
{"4.77", CPU_8088, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"7.16", CPU_8088, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8", CPU_8088, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
// {"9.54", CPU_8088, fpus_8088, 9545456, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"10", CPU_8088, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"12", CPU_8088, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"16", CPU_8088, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
@@ -109,6 +117,66 @@ const cpu_family_t cpu_families[] = {
|
||||
{"16", CPU_8086, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"", 0}
|
||||
}
|
||||
}, {
|
||||
.package = CPU_PKG_188,
|
||||
.manufacturer = "Intel",
|
||||
.name = "80188",
|
||||
.internal_name = "80188",
|
||||
.cpus = (const CPU[]) {
|
||||
{"6", CPU_188, fpus_8088, 6000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"7.16", CPU_188, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8", CPU_188, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"9.54", CPU_188, fpus_8088, 9545456, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"10", CPU_188, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"12", CPU_188, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"16", CPU_188, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"20", CPU_188, fpus_8088, 20000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3},
|
||||
{"25", CPU_188, fpus_8088, 25000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3},
|
||||
{"", 0}
|
||||
}
|
||||
}, {
|
||||
.package = CPU_PKG_8088,
|
||||
.manufacturer = "NEC",
|
||||
.name = "V20",
|
||||
.internal_name = "necv20",
|
||||
.cpus = (const CPU[]) {
|
||||
{"5", CPU_V20, fpus_8088, 5000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8", CPU_V20, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"10", CPU_V20, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"12", CPU_V20, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"16", CPU_V20, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"", 0}
|
||||
}
|
||||
}, {
|
||||
.package = CPU_PKG_186,
|
||||
.manufacturer = "Intel",
|
||||
.name = "80186",
|
||||
.internal_name = "80186",
|
||||
.cpus = (const CPU[]) {
|
||||
{"6", CPU_186, fpus_80186, 6000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"7.16", CPU_186, fpus_80186, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8", CPU_186, fpus_80186, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"9.54", CPU_186, fpus_80186, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"10", CPU_186, fpus_80186, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"12", CPU_186, fpus_80186, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"16", CPU_186, fpus_80186, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"20", CPU_186, fpus_80186, 20000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3},
|
||||
{"25", CPU_186, fpus_80186, 25000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3},
|
||||
{"", 0}
|
||||
}
|
||||
}, {
|
||||
.package = CPU_PKG_186,
|
||||
.manufacturer = "NEC",
|
||||
.name = "V30",
|
||||
.internal_name = "necv30",
|
||||
.cpus = (const CPU[]) {
|
||||
{"5", CPU_V30, fpus_80186, 5000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8", CPU_V30, fpus_80186, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"10", CPU_V30, fpus_80186, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"12", CPU_V30, fpus_80186, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"16", CPU_V30, fpus_80186, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"", 0}
|
||||
}
|
||||
}, {
|
||||
.package = CPU_PKG_286,
|
||||
.manufacturer = "Intel",
|
||||
|
||||
@@ -72,6 +72,9 @@ extern const OpFn *x86_dynarec_opcodes_REPE;
|
||||
extern const OpFn *x86_dynarec_opcodes_REPNE;
|
||||
extern const OpFn *x86_dynarec_opcodes_3DNOW;
|
||||
|
||||
extern const OpFn dynarec_ops_186[1024];
|
||||
extern const OpFn dynarec_ops_186_0f[1024];
|
||||
|
||||
extern const OpFn dynarec_ops_286[1024];
|
||||
extern const OpFn dynarec_ops_286_0f[1024];
|
||||
|
||||
@@ -171,6 +174,9 @@ extern const OpFn *x86_opcodes_REPE;
|
||||
extern const OpFn *x86_opcodes_REPNE;
|
||||
extern const OpFn *x86_opcodes_3DNOW;
|
||||
|
||||
extern const OpFn ops_186[1024];
|
||||
extern const OpFn ops_186_0f[1024];
|
||||
|
||||
extern const OpFn ops_286[1024];
|
||||
extern const OpFn ops_286_0f[1024];
|
||||
|
||||
|
||||
@@ -163,6 +163,33 @@ static int opPUSHFD(uint32_t fetchdat)
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opPOPF_186(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
@@ -96,6 +96,51 @@ static int opRETF_a32_imm(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIRET_186(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opIRET_286(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
@@ -85,6 +85,82 @@ const x87_timings_t x87_timings_8087 = {
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
const x87_timings_t x87_timings_80187 =
|
||||
{
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
.fabs = (10 + 17) / 2,
|
||||
.fadd = (70 + 100) / 2,
|
||||
.fadd_32 = (90 + 120) / 2,
|
||||
.fadd_64 = (95 + 125) / 2,
|
||||
.fbld = (290 + 310) / 2,
|
||||
.fbstp = (520 + 540) / 2,
|
||||
.fchs = (10 + 17) / 2,
|
||||
.fclex = (2 + 8) / 2,
|
||||
.fcom = (40 + 50) / 2,
|
||||
.fcom_32 = (60 + 70) / 2,
|
||||
.fcom_64 = (65 + 75) / 2,
|
||||
.fcos = 0, /*387+*/
|
||||
.fincdecstp = (6 + 12) / 2,
|
||||
.fdisi_eni = (6 + 12) / 2,
|
||||
.fdiv = (193 + 203) / 2,
|
||||
.fdiv_32 = (215 + 225) / 2,
|
||||
.fdiv_64 = (220 + 230) / 2,
|
||||
.ffree = (9 + 16) / 2,
|
||||
.fadd_i16 = (102 + 137) / 2,
|
||||
.fadd_i32 = (108 + 143) / 2,
|
||||
.fcom_i16 = (72 + 86) / 2,
|
||||
.fcom_i32 = (78 + 91) / 2,
|
||||
.fdiv_i16 = (224 + 238) / 2,
|
||||
.fdiv_i32 = (230 + 243) / 2,
|
||||
.fild_16 = (46 + 54) / 2,
|
||||
.fild_32 = (50 + 60) / 2,
|
||||
.fild_64 = (60 + 68) / 2,
|
||||
.fmul_i16 = (124 + 138) / 2,
|
||||
.fmul_i32 = (130 + 144) / 2,
|
||||
.finit = (2 + 8) / 2,
|
||||
.fist_16 = (80 + 90) / 2,
|
||||
.fist_32 = (82 + 92) / 2,
|
||||
.fist_64 = (94 + 105) / 2,
|
||||
.fld = (17 + 22) / 2,
|
||||
.fld_32 = (38 + 56) / 2,
|
||||
.fld_64 = (40 + 60) / 2,
|
||||
.fld_80 = (53 + 65) / 2,
|
||||
.fld_z1 = (11 + 21) / 2,
|
||||
.fld_const = (15 + 24) / 2,
|
||||
.fldcw = (7 + 14) / 2,
|
||||
.fldenv = (35 + 45) / 2,
|
||||
.fmul = (90 + 145) / 2,
|
||||
.fmul_32 = (110 + 125) / 2,
|
||||
.fmul_64 = (154 + 168) / 2,
|
||||
.fnop = (10 + 16) / 2,
|
||||
.fpatan = (250 + 800) / 2,
|
||||
.fprem = (15 + 190) / 2,
|
||||
.fprem1 = 0, /*387+*/
|
||||
.fptan = (30 + 540) / 2,
|
||||
.frndint = (16 + 50) / 2,
|
||||
.frstor = (197 + 207) / 2,
|
||||
.fsave = (197 + 207) / 2,
|
||||
.fscale = (32 + 38) / 2,
|
||||
.fsetpm = 0, /*287+*/
|
||||
.fsin_cos = 0, /*387+*/
|
||||
.fsincos = 0, /*387+*/
|
||||
.fsqrt = (180 + 186) / 2,
|
||||
.fst = (15 + 22) / 2,
|
||||
.fst_32 = (84 + 90) / 2,
|
||||
.fst_64 = (96 + 104) / 2,
|
||||
.fst_80 = (52 + 58) / 2,
|
||||
.fstcw_sw = (12 + 18) / 2,
|
||||
.fstenv = (40 + 50) / 2,
|
||||
.ftst = (38 + 48) / 2,
|
||||
.fucom = 0, /*387+*/
|
||||
.fwait = 4,
|
||||
.fxam = (12 + 23) / 2,
|
||||
.fxch = (10 + 15) / 2,
|
||||
.fxtract = (27 + 55) / 2,
|
||||
.fyl2x = (900 + 1100) / 2,
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
/*Mostly the same as 8087*/
|
||||
const x87_timings_t x87_timings_287 = {
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef struct
|
||||
} x87_timings_t;
|
||||
|
||||
extern const x87_timings_t x87_timings_8087;
|
||||
extern const x87_timings_t x87_timings_80187;
|
||||
extern const x87_timings_t x87_timings_287;
|
||||
extern const x87_timings_t x87_timings_387;
|
||||
extern const x87_timings_t x87_timings_486;
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#define KBD_TYPE_VTECH 7
|
||||
#define KBD_TYPE_OLIVETTI 8
|
||||
#define KBD_TYPE_ZENITH 9
|
||||
#define KBD_TYPE_PRAVETZ 10
|
||||
|
||||
typedef struct {
|
||||
int want_irq;
|
||||
@@ -73,7 +74,7 @@ typedef struct {
|
||||
|
||||
uint8_t pa, pb, pd;
|
||||
uint8_t key_waiting;
|
||||
uint8_t type;
|
||||
uint8_t type, pravetz_flags;
|
||||
|
||||
pc_timer_t send_delay_timer;
|
||||
} xtkbd_t;
|
||||
@@ -513,6 +514,7 @@ static void
|
||||
kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
xtkbd_t *kbd = (xtkbd_t *) priv;
|
||||
uint8_t bit, set;
|
||||
|
||||
switch (port) {
|
||||
case 0x61: /* Keyboard Control Register (aka Port B) */
|
||||
@@ -527,7 +529,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
timer_process();
|
||||
|
||||
if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) && (cassette != NULL))
|
||||
if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) &&
|
||||
(cassette != NULL))
|
||||
pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0);
|
||||
|
||||
speaker_update();
|
||||
@@ -546,16 +549,25 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82))
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
|
||||
kbd_log("Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
|
||||
#endif
|
||||
break;
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82))
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
|
||||
kbd_log("Cassette IN is %i\n", !!(val & 0x10));
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0xc0 ... 0xcf: /* Pravetz Flags */
|
||||
kbd_log("Port %02X out: %02X\n", port, val);
|
||||
if (kbd->type == KBD_TYPE_PRAVETZ) {
|
||||
bit = (port >> 1) & 0x07;
|
||||
set = (port & 0x01) << bit;
|
||||
kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,8 +579,8 @@ kbd_read(uint16_t port, void *priv)
|
||||
|
||||
switch (port) {
|
||||
case 0x60: /* Keyboard Data Register (aka Port A) */
|
||||
if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_ZENITH))) {
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82))
|
||||
if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_ZENITH))) {
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
|
||||
ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00);
|
||||
else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86))
|
||||
ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */
|
||||
@@ -600,7 +612,7 @@ kbd_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) {
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) {
|
||||
if (kbd->pb & 0x04) /* PB2 */
|
||||
switch (mem_size + isa_mem_size) {
|
||||
case 64:
|
||||
@@ -640,7 +652,7 @@ kbd_read(uint16_t port, void *priv)
|
||||
|
||||
/* This is needed to avoid error 131 (cassette error).
|
||||
This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) {
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) {
|
||||
if (cassette == NULL)
|
||||
ret |= (ppispeakon ? 0x10 : 0);
|
||||
else
|
||||
@@ -657,6 +669,12 @@ kbd_read(uint16_t port, void *priv)
|
||||
|| (kbd->type == KBD_TYPE_TOSHIBA))
|
||||
ret = kbd->pd;
|
||||
break;
|
||||
|
||||
case 0xc0: /* Pravetz Flags */
|
||||
if (kbd->type == KBD_TYPE_PRAVETZ)
|
||||
ret = kbd->pravetz_flags;
|
||||
kbd_log("Port %02X in : %02X\n", port, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
@@ -671,6 +689,7 @@ kbd_reset(void *priv)
|
||||
kbd->blocked = 0;
|
||||
kbd->pa = 0x00;
|
||||
kbd->pb = 0x00;
|
||||
kbd->pravetz_flags = 0x00;
|
||||
|
||||
keyboard_scan = 1;
|
||||
|
||||
@@ -697,16 +716,19 @@ kbd_init(const device_t *info)
|
||||
keyboard_send = kbd_adddata_ex;
|
||||
kbd_reset(kbd);
|
||||
kbd->type = info->local;
|
||||
if (kbd->type == KBD_TYPE_PRAVETZ) {
|
||||
io_sethandler(0x00c0, 16,
|
||||
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
|
||||
}
|
||||
|
||||
key_queue_start = key_queue_end = 0;
|
||||
|
||||
video_reset(gfxcard);
|
||||
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)
|
||||
|| (kbd->type == KBD_TYPE_XT82) || (kbd->type <= KBD_TYPE_XT86)
|
||||
|| (kbd->type == KBD_TYPE_COMPAQ)
|
||||
|| (kbd->type == KBD_TYPE_TOSHIBA)
|
||||
|| (kbd->type == KBD_TYPE_OLIVETTI)) {
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
|
||||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) ||
|
||||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_COMPAQ) ||
|
||||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_OLIVETTI)) {
|
||||
|
||||
/* DIP switch readout: bit set = OFF, clear = ON. */
|
||||
if (kbd->type == KBD_TYPE_OLIVETTI)
|
||||
@@ -894,6 +916,20 @@ const device_t keyboard_pc82_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_pravetz_device = {
|
||||
.name = "Pravetz Keyboard",
|
||||
.internal_name = "keyboard_pravetz",
|
||||
.flags = 0,
|
||||
.local = KBD_TYPE_PRAVETZ,
|
||||
.init = kbd_init,
|
||||
.close = kbd_close,
|
||||
.reset = kbd_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_xt_device = {
|
||||
.name = "XT (1982) Keyboard",
|
||||
.internal_name = "keyboard_xt",
|
||||
|
||||
@@ -167,14 +167,9 @@ mouse_set_buttons(int buttons)
|
||||
void
|
||||
mouse_process(void)
|
||||
{
|
||||
static int poll_delay = 2;
|
||||
|
||||
if (mouse_curr == NULL)
|
||||
return;
|
||||
|
||||
if (--poll_delay)
|
||||
return;
|
||||
|
||||
mouse_poll();
|
||||
|
||||
if ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL)) {
|
||||
@@ -186,8 +181,6 @@ mouse_process(void)
|
||||
/* Reset mouse deltas. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
}
|
||||
|
||||
poll_delay = 2;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -115,6 +115,7 @@ static const struct {
|
||||
{ &st506_xt_wd1002a_27x_device },
|
||||
{ &st506_xt_wd1004_27x_device },
|
||||
{ &st506_xt_wd1004a_27x_device },
|
||||
{ &st506_xt_victor_v86p_device },
|
||||
{ &esdi_at_wd1007vse1_device },
|
||||
{ &ide_isa_device },
|
||||
{ &ide_isa_2ch_device },
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
#define WD1002A_27X_BIOS_FILE "roms/hdd/st506/wd1002a_27x-62-000094-032.bin"
|
||||
#define WD1004_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
||||
#define WD1004A_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
||||
#define VICTOR_V86P_BIOS_FILE "roms/machines/v86p/2793VG.10010688.rom"
|
||||
|
||||
#define ST506_TIME (250 * TIMER_USEC)
|
||||
#define ST506_TIME_MS (1000 * TIMER_USEC)
|
||||
@@ -182,6 +183,7 @@
|
||||
#define CMD_WRITE_BUFFER 0x0f
|
||||
#define CMD_ALT_TRACK 0x11
|
||||
#define CMD_INQUIRY_ST11 0x12 /* ST-11 BIOS */
|
||||
#define CMD_V86P_POWEROFF 0x1a /* Victor V86P */
|
||||
#define CMD_RAM_DIAGNOSTIC 0xe0
|
||||
/* reserved 0xe1 */
|
||||
/* reserved 0xe2 */
|
||||
@@ -819,6 +821,29 @@ st506_callback(void *priv)
|
||||
/* For a 615/4/26 we get 666/2/31 geometry. */
|
||||
st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n",
|
||||
dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
|
||||
if (dev->type == 23 && drive->cfg_hpc == 2) {
|
||||
/*
|
||||
* On Victor V86P, there's a disagreement between
|
||||
* the physical geometry, what the controller
|
||||
* pretends it to be, and what the BIOS uses.
|
||||
*
|
||||
* The disk physically has 2/34 heads/sectors per
|
||||
* track, but it is treated as 4/17 in order to
|
||||
* look like a regular type 3 drive (see [1],
|
||||
* line 1859). The controller accepts the 4/17
|
||||
* geometry, so this should not really matter.
|
||||
*
|
||||
* However, the BIOS issues SPECIFY (see [1],
|
||||
* line 2089) with head count of two. Let's
|
||||
* hardwire the correct number instead, just like
|
||||
* the real hardware seems to.
|
||||
*
|
||||
* [1] https://archive.org/download/v86p-hd/V86P-HD.TXT
|
||||
*/
|
||||
drive->cfg_hpc = 4;
|
||||
st506_xt_log("ST506: drive%i: corrected to heads=%i\n",
|
||||
dev->drive_sel, drive->cfg_hpc);
|
||||
}
|
||||
st506_complete(dev);
|
||||
break;
|
||||
}
|
||||
@@ -949,6 +974,34 @@ st506_callback(void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_V86P_POWEROFF:
|
||||
if (dev->type == 23) {
|
||||
/*
|
||||
* Main BIOS (not the option ROM on disk) issues this.
|
||||
* Not much we can do, since we don't have a physical disk
|
||||
* to spin down, but handle this anyways so that we log
|
||||
* something more reasonable than "unknown command".
|
||||
*
|
||||
* Entirely undocumented, but this is what's been observed:
|
||||
* BIOS setting | Command sent
|
||||
* 1 minutes | 1a 00 00 0c 02 00
|
||||
* 2 minutes | 1a 00 00 18 02 00
|
||||
* 3 minutes | 1a 00 00 24 02 00
|
||||
* 4 minutes | 1a 00 00 30 02 00
|
||||
* 5 minutes | 1a 00 00 3c 02 00
|
||||
* off | 1a 00 00 00 02 00
|
||||
*/
|
||||
if (dev->command[3])
|
||||
st506_xt_log("ST506: Auto power-off in %d seconds (type=%i)\n",
|
||||
dev->command[3] * 5, dev->type);
|
||||
else
|
||||
st506_xt_log("ST506: Auto power-off disabled (type=%i)\n", dev->type);
|
||||
} else {
|
||||
st506_error(dev, ERR_BAD_COMMAND);
|
||||
}
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_RAM_DIAGNOSTIC:
|
||||
#ifdef ENABLE_ST506_XT_LOG
|
||||
st506_xt_log("ST506: RAM_DIAG\n");
|
||||
@@ -1485,6 +1538,9 @@ st506_init(const device_t *info)
|
||||
dev->switches |= 0x40;
|
||||
dev->bios_addr = device_get_config_hex20("bios_addr");
|
||||
break;
|
||||
case 23: /* Victor V86P (RLL) */
|
||||
fn = VICTOR_V86P_BIOS_FILE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Load the ROM BIOS. */
|
||||
@@ -1605,6 +1661,12 @@ wd1004a_27x_available(void)
|
||||
return (rom_present(WD1004A_27X_BIOS_FILE));
|
||||
}
|
||||
|
||||
static int
|
||||
victor_v86p_available(void)
|
||||
{
|
||||
return (rom_present(VICTOR_V86P_BIOS_FILE));
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const device_config_t dtc_config[] = {
|
||||
{
|
||||
@@ -2036,3 +2098,17 @@ const device_t st506_xt_wd1004a_27x_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = wd_rll_config
|
||||
};
|
||||
|
||||
const device_t st506_xt_victor_v86p_device = {
|
||||
.name = "Victor V86P RLL Fixed Disk Adapter",
|
||||
.internal_name = "st506_xt_victor_v86p",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = (HDD_BUS_MFM << 8) | 23,
|
||||
.init = st506_init,
|
||||
.close = st506_close,
|
||||
.reset = NULL,
|
||||
{ .available = victor_v86p_available },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -1121,7 +1121,7 @@ td0_seek(int drive, int track)
|
||||
id[1] = dev->sects[track][side][actual_sector].head;
|
||||
id[2] = real_sector;
|
||||
id[3] = dev->sects[track][side][actual_sector].size;
|
||||
pclog("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags);
|
||||
td0_log("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags);
|
||||
fm = dev->sects[track][side][actual_sector].fm;
|
||||
if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive))
|
||||
ssize = 3;
|
||||
|
||||
@@ -40,6 +40,7 @@ extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */
|
||||
extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */
|
||||
extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */
|
||||
extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */
|
||||
extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */
|
||||
|
||||
extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */
|
||||
extern const device_t esdi_ps2_device; /* esdi_mca */
|
||||
|
||||
56
src/include/86box/i8080.h
Normal file
56
src/include/86box/i8080.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* 8080 CPU emulation (header).
|
||||
*
|
||||
* Authors: Cacodemon345
|
||||
*
|
||||
* Copyright 2022 Cacodemon345
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct i8080
|
||||
{
|
||||
union {
|
||||
uint16_t af; /* Intended in case we also go for μPD9002 emulation, which also has a Z80 emulation mode. */
|
||||
struct { uint8_t a, flags; };
|
||||
};
|
||||
union
|
||||
{
|
||||
uint16_t bc;
|
||||
struct { uint8_t b, c; };
|
||||
};
|
||||
union
|
||||
{
|
||||
uint16_t de;
|
||||
struct { uint8_t d, e; };
|
||||
};
|
||||
union
|
||||
{
|
||||
uint16_t hl;
|
||||
struct { uint8_t h, l; };
|
||||
};
|
||||
uint16_t pc, sp;
|
||||
uint16_t oldpc, ei;
|
||||
uint32_t pmembase, dmembase; /* Base from where i8080 starts. */
|
||||
uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */
|
||||
uint16_t* cpu_flags;
|
||||
void (*writemembyte)(uint32_t, uint8_t);
|
||||
uint8_t (*readmembyte)(uint32_t);
|
||||
void (*startclock)();
|
||||
void (*endclock)();
|
||||
void (*checkinterrupts)();
|
||||
uint8_t (*fetchinstruction)();
|
||||
} i8080;
|
||||
|
||||
#define C_FLAG_I8080 (1 << 0)
|
||||
#define P_FLAG_I8080 (1 << 2)
|
||||
#define AC_FLAG_I8080 (1 << 4)
|
||||
#define Z_FLAG_I8080 (1 << 6)
|
||||
#define S_FLAG_I8080 (1 << 7)
|
||||
@@ -146,6 +146,7 @@ extern int mouse_scan;
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t keyboard_pc_device;
|
||||
extern const device_t keyboard_pc82_device;
|
||||
extern const device_t keyboard_pravetz_device;
|
||||
extern const device_t keyboard_xt_device;
|
||||
extern const device_t keyboard_xt86_device;
|
||||
extern const device_t keyboard_xt_compaq_device;
|
||||
|
||||
@@ -336,6 +336,7 @@ extern int machine_get_max_ram(int m);
|
||||
extern int machine_get_ram_granularity(int m);
|
||||
extern int machine_get_type(int m);
|
||||
extern void machine_close(void);
|
||||
extern int machine_has_mouse(void);
|
||||
|
||||
extern uint8_t machine_get_p1(void);
|
||||
extern void machine_load_p1(int m);
|
||||
@@ -714,6 +715,9 @@ extern int machine_at_vpc2007_init(const machine_t *);
|
||||
/* m_at_t3100e.c */
|
||||
extern int machine_at_t3100e_init(const machine_t *);
|
||||
|
||||
/* m_elt.c */
|
||||
extern int machine_elt_init(const machine_t *);
|
||||
|
||||
/* m_europc.c */
|
||||
extern int machine_europc_init(const machine_t *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
|
||||
@@ -97,6 +97,7 @@ extern const device_t ami_1994_nvr_device;
|
||||
extern const device_t ami_1995_nvr_device;
|
||||
extern const device_t via_nvr_device;
|
||||
extern const device_t p6rp4_nvr_device;
|
||||
extern const device_t elt_nvr_device;
|
||||
#endif
|
||||
|
||||
extern void rtc_tick(void);
|
||||
|
||||
@@ -67,7 +67,9 @@ void cga_poll(void *p);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_config_t cga_config[];
|
||||
|
||||
extern const device_t cga_device;
|
||||
extern const device_t cga_pravetz_device;
|
||||
#endif
|
||||
|
||||
#endif /*VIDEO_CGA_H*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c
|
||||
m_xt_philips.c
|
||||
m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c
|
||||
m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_v86p.c
|
||||
m_amstrad.c m_europc.c m_elt.c m_xt_olivetti.c m_tandy.c m_v86p.c
|
||||
m_at.c m_at_commodore.c
|
||||
m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c
|
||||
m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c
|
||||
|
||||
199
src/machine/m_elt.c
Normal file
199
src/machine/m_elt.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Epson Equity LT portable computer emulation.
|
||||
*
|
||||
* Author: Lubomir Rintel, <lkundrak@v3.sk>
|
||||
*
|
||||
* Copyright 2022 Lubomir Rintel.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
// clang-format on
|
||||
|
||||
static void
|
||||
elt_vid_off_poll(void *p)
|
||||
{
|
||||
cga_t *cga = p;
|
||||
uint8_t hdisp = cga->crtc[1];
|
||||
|
||||
/* Don't display anything.
|
||||
* TODO: Do something less stupid to emulate backlight off. */
|
||||
cga->crtc[1] = 0;
|
||||
cga_poll(cga);
|
||||
cga->crtc[1] = hdisp;
|
||||
}
|
||||
|
||||
static void
|
||||
sysstat_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = p;
|
||||
|
||||
switch (val) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
/* Backlight off. */
|
||||
if (cga)
|
||||
timer_set_callback(&cga->timer, elt_vid_off_poll);
|
||||
break;
|
||||
case 2:
|
||||
/* Backlight on. */
|
||||
if (cga)
|
||||
timer_set_callback(&cga->timer, cga_poll);
|
||||
break;
|
||||
default:
|
||||
pclog("Unknown sysstat command: 0x%02x\n", val);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sysstat_in(uint16_t port, void *p)
|
||||
{
|
||||
cga_t *cga = p;
|
||||
uint8_t ret = 0x0a; /* No idea what these bits are */
|
||||
|
||||
/* External CRT. We don't emulate the LCD/CRT switching, let's just
|
||||
* frivolously use this bit to indicate we're using the LCD if the
|
||||
* user didn't override the video card for now. */
|
||||
if (cga == NULL)
|
||||
ret |= 0x40;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
elt_vid_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = p;
|
||||
|
||||
/* The Equity LT chipset's CRTC contains more registers than the
|
||||
* regular CGA. The BIOS writes one of them, register 36 (0x24).
|
||||
* Nothing is known about the number or function of those registers,
|
||||
* let's just ignore them so that we don't clobber the CGA register.
|
||||
* Also, the BIOS writes that register via the 3D0h/3D1h alias
|
||||
* instead of the usual 3D4h/3D5h, possibly to keep the wraparound
|
||||
* behavior on the usual addresses (just an assumption, not
|
||||
* verified). */
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
cga->crtcreg = val;
|
||||
return;
|
||||
case 0x3d1:
|
||||
if (cga->crtcreg >= 32)
|
||||
return;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
cga->crtcreg &= 31;
|
||||
cga_out(addr, val, p);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
elt_vid_in(uint16_t addr, void *p)
|
||||
{
|
||||
cga_t *cga = p;
|
||||
|
||||
/* Just make sure we don't ever let regular CGA code run with crtcreg
|
||||
* pointing out of crtcregs[] bounds. */
|
||||
cga->crtcreg &= 31;
|
||||
return cga_in(addr, p);
|
||||
}
|
||||
|
||||
static void
|
||||
load_font_rom(uint32_t font_data)
|
||||
{
|
||||
int c, d;
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = mem_readb_phys(font_data++);
|
||||
}
|
||||
|
||||
int
|
||||
machine_elt_init(const machine_t *model)
|
||||
{
|
||||
cga_t *cga = NULL;
|
||||
int ret;
|
||||
|
||||
ret = bios_load_interleavedr("roms/machines/elt/HLO-B2.rom",
|
||||
"roms/machines/elt/HLO-A2.rom",
|
||||
0x000fc000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
/* The machine doesn't have any separate font ROM chip. The text mode
|
||||
* font is likely a mask ROM in the chipset. video_reset() will try
|
||||
* to load a MDA font, but let's have a reasonable fall back if it's
|
||||
* not available. Read in the graphical mode font from the BIOS ROM
|
||||
* image. */
|
||||
load_font_rom(0xffa6e);
|
||||
|
||||
machine_common_init(model);
|
||||
|
||||
nmi_init();
|
||||
|
||||
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_xt_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL) {
|
||||
cga = device_add(&cga_device);
|
||||
io_removehandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
|
||||
io_sethandler(0x03d0, 0x0010, elt_vid_in, NULL, NULL, elt_vid_out, NULL, NULL, cga);
|
||||
}
|
||||
|
||||
/* Keyboard goes after the video, because on XT compatibles it's dealt
|
||||
* with by the same PPI as the config switches and we need them to
|
||||
* indicate the correct display type */
|
||||
device_add(&keyboard_xt_device);
|
||||
|
||||
device_add(&elt_nvr_device);
|
||||
|
||||
io_sethandler(0x11b8, 1, sysstat_in, NULL, NULL, sysstat_out, NULL, NULL, cga);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/port_6x.h>
|
||||
|
||||
static void
|
||||
machine_xt_common_init(const machine_t *model)
|
||||
@@ -331,15 +332,33 @@ machine_xt_iskra3104_init(const machine_t *model)
|
||||
int
|
||||
machine_xt_pravetz16_imko4_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin",
|
||||
0x000fe000, 8192, 0);
|
||||
0x000fe000, 65536, 0);
|
||||
if (ret) {
|
||||
ret = bios_load_aux_linear("roms/machines/pravetz16/IMKO4-D34_SGS-M2764ADIP28.BIN",
|
||||
0x000f4000, 8192, 0);
|
||||
|
||||
if (ret) {
|
||||
bios_load_aux_linear("roms/machines/pravetz16/1.bin",
|
||||
0x000f6000, 8192, 0);
|
||||
|
||||
bios_load_aux_linear("roms/machines/pravetz16/2.bin",
|
||||
0x000fa000, 8192, 0);
|
||||
|
||||
bios_load_aux_linear("roms/machines/pravetz16/5.bin",
|
||||
0x000f8000, 8192, 0);
|
||||
|
||||
bios_load_aux_linear("roms/machines/pravetz16/6.bin",
|
||||
0x000fc000, 8192, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&keyboard_pravetz_device);
|
||||
|
||||
machine_xt_common_init(model);
|
||||
|
||||
|
||||
@@ -2118,6 +2118,42 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[8086] Epson Equity LT",
|
||||
.internal_name = "elt",
|
||||
.type = MACHINE_TYPE_8086,
|
||||
.chipset = MACHINE_CHIPSET_PROPRIETARY,
|
||||
.init = machine_elt_init,
|
||||
.pad = 0,
|
||||
.pad0 = 0,
|
||||
.pad1 = MACHINE_AVAILABLE,
|
||||
.pad2 = 0,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_8086,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PC,
|
||||
.flags = MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.max = 640,
|
||||
.step = 640
|
||||
},
|
||||
.nvrmask = 0x3f,
|
||||
.kbc = KBC_IBM_PC_XT,
|
||||
.kbc_p1 = 0xff00,
|
||||
.gpio = 0xffffffff,
|
||||
.device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
|
||||
{
|
||||
@@ -12174,3 +12210,9 @@ machine_get_machine_from_internal_name(char *s)
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
machine_has_mouse(void)
|
||||
{
|
||||
return(machines[machine].flags & MACHINE_MOUSE);
|
||||
}
|
||||
|
||||
177
src/mem/mem.c
177
src/mem/mem.c
@@ -55,11 +55,12 @@
|
||||
#endif
|
||||
|
||||
mem_mapping_t ram_low_mapping, /* 0..640K mapping */
|
||||
ram_mid_mapping,
|
||||
ram_mid_mapping, /* 640..1024K mapping */
|
||||
ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */
|
||||
ram_remapped_mapping, /* 640..1024K mapping */
|
||||
ram_remapped_mapping2,/* 640..1024K second mapping, for SiS 471 mode */
|
||||
ram_high_mapping, /* 1024K+ mapping */
|
||||
ram_2gb_mapping, /* 1024M+ mapping */
|
||||
ram_remapped_mapping,
|
||||
ram_split_mapping,
|
||||
bios_mapping,
|
||||
bios_high_mapping;
|
||||
@@ -71,6 +72,7 @@ uint32_t pages_sz; /* #pages in table */
|
||||
uint8_t *ram, *ram2; /* the virtual RAM */
|
||||
uint8_t page_ff[4096];
|
||||
uint32_t rammask;
|
||||
uint32_t addr_space_size;
|
||||
|
||||
uint8_t *rom; /* the virtual ROM */
|
||||
uint32_t biosmask, biosaddr;
|
||||
@@ -127,7 +129,7 @@ static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
|
||||
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
|
||||
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
static mem_state_t _mem_state[MEM_MAPPINGS_NO];
|
||||
static uint32_t remap_start_addr;
|
||||
static uint32_t remap_start_addr, remap_start_addr2;
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
static size_t ram_size = 0, ram2_size = 0;
|
||||
#else
|
||||
@@ -157,7 +159,8 @@ mem_addr_is_ram(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping);
|
||||
return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) ||
|
||||
(mapping == &ram_mid_mapping2) || (mapping == &ram_remapped_mapping);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2087,6 +2090,33 @@ mem_read_remappedl(uint32_t addr, void *priv)
|
||||
return *(uint32_t *) &ram[addr];
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
mem_read_remapped2(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return ram[addr];
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
mem_read_remappedw2(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint16_t *) &ram[addr];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mem_read_remappedl2(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint32_t *) &ram[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
mem_write_remapped(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -2123,6 +2153,42 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv)
|
||||
*(uint32_t *) &ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
mem_write_remapped2(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint32_t oldaddr = addr;
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
mem_write_remappedw2(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
uint32_t oldaddr = addr;
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
*(uint16_t *) &ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
mem_write_remappedl2(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
uint32_t oldaddr = addr;
|
||||
addr = 0xD0000 + (addr - remap_start_addr2);
|
||||
if (is286) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_raml_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
*(uint32_t *) &ram[addr] = val;
|
||||
}
|
||||
|
||||
void
|
||||
mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
|
||||
{
|
||||
@@ -2605,6 +2671,8 @@ mem_reset(void)
|
||||
m = 256;
|
||||
}
|
||||
|
||||
addr_space_size = m;
|
||||
|
||||
/*
|
||||
* Allocate and initialize the (new) page table.
|
||||
*/
|
||||
@@ -2687,15 +2755,26 @@ mem_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (mem_size > 768)
|
||||
if (mem_size > 768) {
|
||||
mem_add_ram_mapping(&ram_mid_mapping, 0xa0000, 0x60000);
|
||||
|
||||
mem_add_ram_mapping(&ram_mid_mapping2, 0xa0000, 0x60000);
|
||||
mem_mapping_disable(&ram_mid_mapping2);
|
||||
}
|
||||
|
||||
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
|
||||
mem_read_remapped, mem_read_remappedw, mem_read_remappedl,
|
||||
mem_write_remapped, mem_write_remappedw, mem_write_remappedl,
|
||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_disable(&ram_remapped_mapping);
|
||||
|
||||
/* Mapping for SiS 471 relocation which relocates A0000-BFFFF, D0000-EFFFF, which is non-contiguous. */
|
||||
mem_mapping_add(&ram_remapped_mapping2, mem_size * 1024, 256 * 1024,
|
||||
mem_read_remapped2, mem_read_remappedw2, mem_read_remappedl2,
|
||||
mem_write_remapped2, mem_write_remappedw2, mem_write_remappedl2,
|
||||
ram + 0xd0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_disable(&ram_remapped_mapping2);
|
||||
|
||||
mem_a20_init();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
@@ -2729,11 +2808,19 @@ mem_remap_top(int kb)
|
||||
int offset, size = mem_size - 640;
|
||||
int set = 1;
|
||||
static int old_kb = 0;
|
||||
int sis_mode = 0;
|
||||
uint32_t start_addr = 0, addr = 0;
|
||||
|
||||
mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size);
|
||||
if (mem_size <= 640)
|
||||
return;
|
||||
|
||||
/* SiS 471 special mode. */
|
||||
if (kb == -256) {
|
||||
kb = 256;
|
||||
sis_mode = 1;
|
||||
}
|
||||
|
||||
if (kb == 0) {
|
||||
kb = old_kb;
|
||||
set = 0;
|
||||
@@ -2744,27 +2831,95 @@ mem_remap_top(int kb)
|
||||
size = kb;
|
||||
|
||||
remap_start_addr = start << 10;
|
||||
remap_start_addr2 = (start << 10) + 0x00020000;
|
||||
|
||||
for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) {
|
||||
offset = c - ((start * 1024) >> 12);
|
||||
pages[c].mem = set ? &ram[0xa0000 + (offset << 12)] : page_ff;
|
||||
/* Use A0000-BFFFF, D0000-EFFFF instead of C0000-DFFFF, E0000-FFFFF. */
|
||||
addr = 0xa0000 + (offset << 12);
|
||||
if (sis_mode) {
|
||||
/* A0000-DFFFF -> A0000-BFFFF, D0000-EFFFF */
|
||||
if (addr >= 0x000c0000)
|
||||
addr += 0x00010000;
|
||||
}
|
||||
if (start_addr != 0)
|
||||
start_addr = addr;
|
||||
pages[c].mem = set ? &ram[addr] : page_ff;
|
||||
pages[c].write_b = set ? mem_write_ramb_page : NULL;
|
||||
pages[c].write_w = set ? mem_write_ramw_page : NULL;
|
||||
pages[c].write_l = set ? mem_write_raml_page : NULL;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
pages[c].evict_prev = EVICT_NOT_IN_LIST;
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64];
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[(addr >> 12) * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[(addr >> 12) * 64];
|
||||
#endif
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
|
||||
for (c = 0xa0; c < 0xf0; c++) {
|
||||
if ((c >= 0xc0) && (c <= 0xcf))
|
||||
continue;
|
||||
|
||||
if (sis_mode || ((c << 12) >= (mem_size << 10)))
|
||||
pages[c].mem = page_ff;
|
||||
else {
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (mem_size > 1048576) {
|
||||
if ((c << 12) < (1 << 30))
|
||||
pages[c].mem = &ram[c << 12];
|
||||
else
|
||||
pages[c].mem = &ram2[(c << 12) - (1 << 30)];
|
||||
} else
|
||||
pages[c].mem = &ram[c << 12];
|
||||
#else
|
||||
pages[c].mem = &ram[c << 12];
|
||||
#endif
|
||||
}
|
||||
if (!sis_mode && (c < addr_space_size)) {
|
||||
pages[c].write_b = mem_write_ramb_page;
|
||||
pages[c].write_w = mem_write_ramw_page;
|
||||
pages[c].write_l = mem_write_raml_page;
|
||||
} else {
|
||||
pages[c].write_b = NULL;
|
||||
pages[c].write_w = NULL;
|
||||
pages[c].write_l = NULL;
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
pages[c].evict_prev = EVICT_NOT_IN_LIST;
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (set) {
|
||||
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
|
||||
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0xa0000);
|
||||
} else
|
||||
if (sis_mode) {
|
||||
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, 0x00020000);
|
||||
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0x000a0000);
|
||||
mem_mapping_set_addr(&ram_remapped_mapping2, (start * 1024) + 0x00020000, 0x00020000);
|
||||
mem_mapping_set_exec(&ram_remapped_mapping2, ram + 0x000d0000);
|
||||
|
||||
mem_mapping_set_addr(&ram_mid_mapping, 0x000c0000, 0x00010000);
|
||||
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000c0000);
|
||||
mem_mapping_set_addr(&ram_mid_mapping2, 0x000f0000, 0x00010000);
|
||||
mem_mapping_set_exec(&ram_mid_mapping2, ram + 0x000f0000);
|
||||
} else {
|
||||
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
|
||||
mem_mapping_set_exec(&ram_remapped_mapping, ram + start_addr);
|
||||
mem_mapping_disable(&ram_remapped_mapping2);
|
||||
|
||||
mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000);
|
||||
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000);
|
||||
mem_mapping_disable(&ram_mid_mapping2);
|
||||
}
|
||||
} else {
|
||||
mem_mapping_disable(&ram_remapped_mapping);
|
||||
mem_mapping_disable(&ram_remapped_mapping2);
|
||||
|
||||
mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000);
|
||||
mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000);
|
||||
mem_mapping_disable(&ram_mid_mapping2);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
62
src/nvr_at.c
62
src/nvr_at.c
@@ -280,6 +280,7 @@
|
||||
#define REGD_VRT 0x80
|
||||
#define RTC_CENTURY_AT 0x32 /* century register for AT etc */
|
||||
#define RTC_CENTURY_PS 0x37 /* century register for PS/1 PS/2 */
|
||||
#define RTC_CENTURY_ELT 0x1A /* century register for Epson Equity LT */
|
||||
#define RTC_ALDAY 0x7D /* VIA VT82C586B - alarm day */
|
||||
#define RTC_ALMONTH 0x7E /* VIA VT82C586B - alarm month */
|
||||
#define RTC_CENTURY_VIA 0x7F /* century register for VIA VT82C586B */
|
||||
@@ -981,9 +982,9 @@ nvr_at_init(const device_t *info)
|
||||
memset(local->lock, 0x00, nvr->size);
|
||||
local->def = 0xff /*0x00*/;
|
||||
local->flags = 0x00;
|
||||
switch (info->local & 7) {
|
||||
switch (info->local & 0x0f) {
|
||||
case 0: /* standard AT, no century register */
|
||||
if (info->local == 16) {
|
||||
if (info->local == 32) {
|
||||
local->flags |= FLAG_P6RP4_HACK;
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_AT;
|
||||
@@ -996,13 +997,13 @@ nvr_at_init(const device_t *info)
|
||||
case 1: /* standard AT */
|
||||
case 5: /* AMI WinBIOS 1994 */
|
||||
case 6: /* AMI BIOS 1995 */
|
||||
if (info->local == 9)
|
||||
if ((info->local & 0x0f) == 1)
|
||||
local->flags |= FLAG_PIIX4;
|
||||
else {
|
||||
local->def = 0x00;
|
||||
if ((info->local & 7) == 5)
|
||||
if ((info->local & 0x0f) == 5)
|
||||
local->flags |= FLAG_AMI_1994_HACK;
|
||||
else if ((info->local & 7) == 6)
|
||||
else if ((info->local & 0x0f) == 6)
|
||||
local->flags |= FLAG_AMI_1995_HACK;
|
||||
else
|
||||
local->def = 0xff;
|
||||
@@ -1015,7 +1016,7 @@ nvr_at_init(const device_t *info)
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_PS;
|
||||
local->def = 0x00;
|
||||
if (info->local & 8)
|
||||
if (info->local & 0x10)
|
||||
local->flags |= FLAG_NO_NMI;
|
||||
break;
|
||||
|
||||
@@ -1023,15 +1024,15 @@ nvr_at_init(const device_t *info)
|
||||
nvr->irq = 1;
|
||||
local->cent = RTC_CENTURY_AT;
|
||||
local->def = 0xff;
|
||||
if (info->local & 8)
|
||||
if (info->local & 0x10)
|
||||
local->flags |= FLAG_NO_NMI;
|
||||
break;
|
||||
|
||||
case 4: /* IBM AT */
|
||||
if (info->local == 12) {
|
||||
if (info->local & 0x10) {
|
||||
local->def = 0x00;
|
||||
local->flags |= FLAG_AMI_1992_HACK;
|
||||
} else if (info->local == 20)
|
||||
} else if (info->local == 36)
|
||||
local->def = 0x00;
|
||||
else
|
||||
local->def = 0xff;
|
||||
@@ -1043,6 +1044,10 @@ nvr_at_init(const device_t *info)
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_VIA;
|
||||
break;
|
||||
case 8: /* Epson Equity LT */
|
||||
nvr->irq = -1;
|
||||
local->cent = RTC_CENTURY_ELT;
|
||||
break;
|
||||
}
|
||||
|
||||
local->read_addr = 1;
|
||||
@@ -1067,9 +1072,14 @@ nvr_at_init(const device_t *info)
|
||||
timer_load_count(nvr);
|
||||
|
||||
/* Set up the I/O handler for this device. */
|
||||
io_sethandler(0x0070, 2,
|
||||
nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr);
|
||||
if (info->local & 8) {
|
||||
if (info->local == 8) {
|
||||
io_sethandler(0x11b4, 2,
|
||||
nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr);
|
||||
} else {
|
||||
io_sethandler(0x0070, 2,
|
||||
nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr);
|
||||
}
|
||||
if (info->local & 0x10) {
|
||||
io_sethandler(0x0072, 2,
|
||||
nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr);
|
||||
}
|
||||
@@ -1180,7 +1190,7 @@ const device_t piix4_nvr_device = {
|
||||
.name = "Intel PIIX4 PC/AT NVRAM",
|
||||
.internal_name = "piix4_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 9,
|
||||
.local = 0x10 | 1,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1220,7 +1230,7 @@ const device_t ami_1992_nvr_device = {
|
||||
.name = "AMI Color 1992 PC/AT NVRAM",
|
||||
.internal_name = "ami_1992_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 12,
|
||||
.local = 0x10 | 4,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1234,7 +1244,7 @@ const device_t ami_1994_nvr_device = {
|
||||
.name = "AMI WinBIOS 1994 PC/AT NVRAM",
|
||||
.internal_name = "ami_1994_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 13,
|
||||
.local = 0x10 | 5,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1248,7 +1258,7 @@ const device_t ami_1995_nvr_device = {
|
||||
.name = "AMI WinBIOS 1995 PC/AT NVRAM",
|
||||
.internal_name = "ami_1995_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 14,
|
||||
.local = 0x10 | 6,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1262,7 +1272,7 @@ const device_t via_nvr_device = {
|
||||
.name = "VIA PC/AT NVRAM",
|
||||
.internal_name = "via_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 15,
|
||||
.local = 0x10 | 7,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1276,7 +1286,7 @@ const device_t p6rp4_nvr_device = {
|
||||
.name = "ASUS P/I-P6RP4 PC/AT NVRAM",
|
||||
.internal_name = "p6rp4_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 16,
|
||||
.local = 32,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
@@ -1290,7 +1300,21 @@ const device_t amstrad_megapc_nvr_device = {
|
||||
.name = "Amstrad MegapC NVRAM",
|
||||
.internal_name = "amstrad_megapc_nvr",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 20,
|
||||
.local = 36,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = nvr_at_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t elt_nvr_device = {
|
||||
.name = "Epson Equity LT NVRAM",
|
||||
.internal_name = "elt_nvr",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 8,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
|
||||
@@ -104,7 +104,7 @@ void plat_setfullscreen(int on) {
|
||||
}
|
||||
|
||||
void plat_mouse_capture(int on) {
|
||||
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE))
|
||||
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse())
|
||||
return;
|
||||
|
||||
main_window->setMouseCapture(on > 0 ? true : false);
|
||||
|
||||
@@ -117,6 +117,22 @@ cga_in(uint16_t addr, void *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cga_pravetz_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *) p;
|
||||
|
||||
cga->fontbase = (((unsigned int) val) << 8);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cga_pravetz_in(uint16_t addr, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *) p;
|
||||
|
||||
return (cga->fontbase >> 8);
|
||||
}
|
||||
|
||||
void
|
||||
cga_waitstates(void *p)
|
||||
{
|
||||
@@ -524,6 +540,21 @@ cga_standalone_init(const device_t *info)
|
||||
return cga;
|
||||
}
|
||||
|
||||
void *
|
||||
cga_pravetz_init(const device_t *info)
|
||||
{
|
||||
cga_t *cga = cga_standalone_init(info);
|
||||
|
||||
loadfont("roms/video/cga/CGA - PRAVETZ.BIN", 10);
|
||||
|
||||
io_removehandler(0x03dd, 0x0001, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
|
||||
io_sethandler(0x03dd, 0x0001, cga_pravetz_in, NULL, NULL, cga_pravetz_out, NULL, NULL, cga);
|
||||
|
||||
cga->fontbase = 0x0300;
|
||||
|
||||
return cga;
|
||||
}
|
||||
|
||||
void
|
||||
cga_close(void *p)
|
||||
{
|
||||
@@ -637,3 +668,17 @@ const device_t cga_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
const device_t cga_pravetz_device = {
|
||||
.name = "Pravetz VDC-2",
|
||||
.internal_name = "cga_pravetz",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = cga_pravetz_init,
|
||||
.close = cga_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
@@ -2131,12 +2131,17 @@ void
|
||||
pgc_recalctimings(pgc_t *dev)
|
||||
{
|
||||
double disptime, _dispontime, _dispofftime;
|
||||
double pixel_clock = (cpuclock * (double) (1ull << 32)) / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock);
|
||||
double pixel_clock = (cpuclock / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock) * (double) (1ull << 32));
|
||||
uint8_t crtc0 = 97, crtc1 = 80; /* Values from MDA, taken from there due to the 25 MHz refresh rate. */
|
||||
|
||||
/* Multiply pixel clock by 8. */
|
||||
pixel_clock *= 8.0;
|
||||
/* Use a fixed 640x400 display. */
|
||||
disptime = dev->screenw + 11;
|
||||
_dispontime = dev->screenw * pixel_clock;
|
||||
_dispofftime = (disptime - dev->screenw) * pixel_clock;
|
||||
disptime = crtc0 + 1;
|
||||
_dispontime = crtc1;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= pixel_clock;
|
||||
_dispofftime *= pixel_clock;
|
||||
dev->dispontime = (uint64_t) (_dispontime);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ video_cards[] = {
|
||||
{ ¶dise_wd90c30_device },
|
||||
{ &colorplus_device },
|
||||
{ &pgc_device },
|
||||
{ &cga_pravetz_device },
|
||||
{ &radius_svga_multiview_isa_device },
|
||||
{ &realtek_rtg3106_device },
|
||||
{ &s3_diamond_stealth_vram_isa_device },
|
||||
@@ -329,7 +330,7 @@ video_reset(int card)
|
||||
|
||||
/* Do not initialize internal cards here. */
|
||||
if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
|
||||
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name);
|
||||
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name);
|
||||
|
||||
video_prepare();
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ static uint32_t cga_2_table[16];
|
||||
static void (*blit_func)(int x, int y, int w, int h, int monitor_index);
|
||||
|
||||
#ifdef ENABLE_VIDEO_LOG
|
||||
int sdl_do_log = ENABLE_VIDEO_LOG;
|
||||
int video_do_log = ENABLE_VIDEO_LOG;
|
||||
|
||||
static void
|
||||
video_log(const char *fmt, ...)
|
||||
@@ -1083,6 +1083,13 @@ loadfont_common(FILE *f, int format)
|
||||
for (c = 0; c < 256; c++)
|
||||
(void) !fread(&fontdat12x18[c][0], 1, 36, f);
|
||||
break;
|
||||
|
||||
case 10: /* Pravetz */
|
||||
for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(f) & 0xff;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
(void) fclose(f);
|
||||
|
||||
@@ -562,6 +562,7 @@ MCHOBJ := machine.o machine_table.o \
|
||||
m_xt_xi8088.o m_xt_zenith.o \
|
||||
m_pcjr.o \
|
||||
m_amstrad.o m_europc.o \
|
||||
m_elt.o \
|
||||
m_xt_olivetti.o m_tandy.o m_v86p.o \
|
||||
m_at.o m_at_commodore.o \
|
||||
m_at_t3100e.o m_at_t3100e_vid.o \
|
||||
|
||||
@@ -1549,7 +1549,7 @@ plat_mouse_capture(int on)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE))
|
||||
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse())
|
||||
return;
|
||||
|
||||
if (on && !mouse_capture) {
|
||||
|
||||
Reference in New Issue
Block a user