Hook up Bidirectional LPT, EPP, and ECP to all Super I/O chips (missing is vendor-specific Configuration Register B behavior but that's next on my list), fixed Super I/O chip mistakes for a number of machines, split 286/386SX/M6117D machines into three separate files and reordered them as well.

This commit is contained in:
OBattler
2025-08-11 16:36:30 +02:00
parent 42fa1dbe54
commit dbd748636e
51 changed files with 5062 additions and 4463 deletions

View File

@@ -81,7 +81,9 @@ typedef struct {
typedef struct
{
uint8_t ep, p92;
uint8_t addr_sel;
uint8_t addr_regs[8];
uint8_t vbios_states[4];
uint8_t bios_states[8];
uint8_t high_bios_states[8];
@@ -100,6 +102,7 @@ typedef struct
};
uint16_t ems_page_regs[40];
uint16_t lpt_base;
int locked;
@@ -873,6 +876,92 @@ wd76c10_low_pages_recalc(wd76c10_t *dev)
}
}
static void
wd73c30_reset(wd76c10_t *dev)
{
dev->addr_sel = 0x00;
dev->addr_regs[0x00] = 0x00;
dev->addr_regs[0x01] = 0x00;
dev->addr_regs[0x05] = 0x00;
serial_set_type(dev->uart[0], SERIAL_16450);
serial_set_type(dev->uart[1], SERIAL_16450);
serial_set_clock_src(dev->uart[1], 1843200.0);
serial_set_clock_src(dev->uart[0], 1843200.0);
lpt_set_ext(dev->lpt, 0);
}
static void
wd76c30_write(uint16_t port, uint8_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *) priv;
switch (port & 0x0007) {
case 0x0003:
dev->addr_sel = val;
switch (val & 0x60) {
case 0x00:
serial_set_clock_src(dev->uart[1], 1843200.0);
break;
case 0x20:
serial_set_clock_src(dev->uart[1], 3072000.0);
break;
case 0x40:
serial_set_clock_src(dev->uart[1], 6000000.0); /* What is MSTRX1? */
break;
case 0x60:
serial_set_clock_src(dev->uart[1], 8000000.0);
break;
}
switch (val & 0x18) {
case 0x00:
serial_set_clock_src(dev->uart[0], 1843200.0);
break;
case 0x08:
serial_set_clock_src(dev->uart[0], 3072000.0);
break;
case 0x10:
serial_set_clock_src(dev->uart[0], 6000000.0); /* What is MSTRX1? */
break;
case 0x18:
serial_set_clock_src(dev->uart[0], 8000000.0);
break;
}
break;
case 0x0007:
dev->addr_regs[dev->addr_sel & 0x07] = val;
switch (dev->addr_sel & 0x07) {
case 0x05:
lpt_set_ext(dev->lpt, !!(val & 0x02));
serial_set_type(dev->uart[0], (val & 0x01) ? SERIAL_16550 : SERIAL_16450);
serial_set_type(dev->uart[1], (val & 0x01) ? SERIAL_16550 : SERIAL_16450);
break;
}
break;
}
}
static uint8_t
wd76c30_read(uint16_t port, void *priv)
{
wd76c10_t *dev = (wd76c10_t *) priv;
uint8_t ret = 0xff;
switch (port & 0x0007) {
case 0x0003:
ret = dev->addr_sel;
break;
case 0x0007:
ret = dev->addr_regs[dev->addr_sel & 0x07];
break;
}
return ret;
}
static void
wd76c10_ser_par_cs_recalc(wd76c10_t *dev)
{
@@ -912,20 +1001,23 @@ wd76c10_ser_par_cs_recalc(wd76c10_t *dev)
/* LPT */
lpt_port_remove(dev->lpt);
if (dev->lpt_base != 0x0000)
io_removehandler(dev->lpt_base, 0x0008, wd76c30_read, NULL, NULL, wd76c30_write, NULL, NULL, dev);
dev->lpt_base = 0x0000;
switch ((dev->ser_par_cs >> 9) & 0x03) {
case 1:
lpt_port_setup(dev->lpt, LPT_MDA_ADDR);
lpt_port_irq(dev->lpt, LPT1_IRQ);
dev->lpt_base = LPT_MDA_ADDR;
break;
case 2:
lpt_port_setup(dev->lpt, LPT1_ADDR);
lpt_port_irq(dev->lpt, LPT1_IRQ);
dev->lpt_base = LPT1_ADDR;
break;
case 3:
lpt_port_setup(dev->lpt, LPT2_ADDR);
lpt_port_irq(dev->lpt, LPT1_IRQ);
dev->lpt_base = LPT2_ADDR;
break;
}
io_sethandler(dev->lpt_base, 0x0008, wd76c30_read, NULL, NULL, wd76c30_write, NULL, NULL, dev);
lpt_port_setup(dev->lpt, dev->lpt_base);
lpt_port_irq(dev->lpt, LPT1_IRQ);
}
static void
@@ -1239,6 +1331,8 @@ wd76c10_reset(void *priv)
nvr_lock_set(0x38, 0x08, 0x00, dev->nvr);
wd73c30_reset(dev);
wd76c10_banks_recalc(dev);
wd76c10_split_recalc(dev);
wd76c10_dis_mem_recalc(dev);

View File

@@ -23,6 +23,7 @@
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/network.h>
#include <86box/plat_fallthrough.h>
static int next_inst = 0;
int lpt_3bc_used = 0;
@@ -378,7 +379,35 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv)
}
break;
case 0x0400: case 0x0404:
case 0x0404:
if (dev->cfg_regs_enabled) {
switch (dev->eir) {
case 0x00:
dev->ext_regs[0x00] = val & 0x31;
break;
case 0x02:
dev->ext_regs[0x02] = val & 0xd0;
if (dev->ext_regs[0x02] & 0x80)
dev->ecr = dev->ret_ecr;
else switch (dev->ret_ecr & 0xe0) {
case 0x00: case 0x20:
case 0x80:
dev->ecr = (dev->ret_ecr & 0x1f) | 0x60;
break;
}
break;
case 0x04:
dev->ext_regs[0x00] = val & 0x37;
break;
case 0x05:
dev->ext_regs[0x00] = val;
dev->cnfga_readout = (val & 0x80) ? 0x1c : 0x14;
break;
}
break;
} else
fallthrough;
case 0x0400:
switch (dev->ecr >> 5) {
default:
break;
@@ -424,10 +453,23 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv)
dev->state = LPT_STATE_IDLE;
}
dev->ecr = val;
if (dev->ext_regs[0x02] & 0x80)
dev->ecr = val;
else switch (val & 0xe0) {
case 0x00: case 0x20:
case 0x80:
dev->ecr = (val & 0x1f) | 0x60;
break;
}
dev->ret_ecr = val;
lpt_ecp_update_irq(dev);
break;
case 0x0403: case 0x0407:
if (dev->cfg_regs_enabled)
dev->eir = val & 0x07;
break;
default:
break;
}
@@ -519,6 +561,12 @@ lpt_read_status(lpt_t *dev)
return ret;
}
uint8_t
lpt_read_ecp_mode(lpt_t *dev)
{
return ((dev->ret_ecr & 0xe0) == 0x60) ? 0x60 : 0x00;
}
uint8_t
lpt_read(const uint16_t port, void *priv)
{
@@ -567,7 +615,21 @@ lpt_read(const uint16_t port, void *priv)
}
break;
case 0x0400: case 0x0404:
case 0x0404:
if (dev->cfg_regs_enabled) {
switch (dev->eir) {
default:
ret = 0xff;
break;
case 0x00: case 0x02:
case 0x04: case 0x05:
ret = dev->ext_regs[dev->eir];
break;
}
break;
} else
fallthrough;
case 0x0400:
switch (dev->ecr >> 5) {
default:
break;
@@ -587,7 +649,13 @@ lpt_read(const uint16_t port, void *priv)
}
break;
case 0x0401: case 0x0405:
case 0x0405:
if (dev->cfg_regs_enabled) {
ret = 0x00;
break;
} else
fallthrough;
case 0x0401:
if ((dev->ecr & 0xe0) == 0xe0) {
/* CNFGB */
ret = 0x08;
@@ -599,11 +667,16 @@ lpt_read(const uint16_t port, void *priv)
break;
case 0x0402: case 0x0406:
ret = dev->ecr | dev->fifo_stat | (dev->dma_stat & 0x04);
ret = dev->ret_ecr | dev->fifo_stat | (dev->dma_stat & 0x04);
ret |= (fifo_get_full(dev->fifo) ? 0x02 : 0x00);
ret |= (fifo_get_empty(dev->fifo) ? 0x01 : 0x00);
break;
case 0x0403: case 0x0407:
if (dev->cfg_regs_enabled)
ret = dev->eir;
break;
default:
break;
}
@@ -688,6 +761,13 @@ lpt_set_fifo_threshold(lpt_t *dev, const int threshold)
fifo_set_trigger_len(dev->fifo, threshold);
}
void
lpt_set_cfg_regs_enabled(lpt_t *dev, const uint8_t cfg_regs_enabled)
{
if (lpt_ports[dev->id].enabled)
dev->cfg_regs_enabled = cfg_regs_enabled;
}
void
lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout)
{
@@ -834,14 +914,21 @@ lpt_reset(void *priv)
}
}
dev->enable_irq = 0x00;
dev->ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA));
dev->epp = 0;
dev->ecp = 0;
dev->ecr = 0x15;
dev->dat = 0xff;
dev->fifo_stat = 0x00;
dev->dma_stat = 0x00;
dev->enable_irq = 0x00;
dev->cfg_regs_enabled = 0;
dev->ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA));
dev->epp = 0;
dev->ecp = 0;
dev->ecr = 0x15;
dev->ret_ecr = 0x15;
dev->dat = 0xff;
dev->fifo_stat = 0x00;
dev->dma_stat = 0x00;
memset(dev->ext_regs, 0x00, 8);
dev->ext_regs[0x02] = 0x80;
dev->ext_regs[0x04] = 0x07;
dev->cnfga_readout &= 0xf7;
}
}
@@ -869,15 +956,20 @@ lpt_init(const device_t *info)
lpt_port_zero(dev);
dev->addr = 0xffff;
dev->irq = 0xff;
dev->dma = 0xff;
dev->enable_irq = 0x00;
dev->ext = 0;
dev->epp = 0;
dev->ecp = 0;
dev->ecr = 0x15;
dev->cnfga_readout = 0x14;
dev->addr = 0xffff;
dev->irq = 0xff;
dev->dma = 0xff;
dev->enable_irq = 0x00;
dev->cfg_regs_enabled = 0;
dev->ext = 0;
dev->epp = 0;
dev->ecp = 0;
dev->ecr = 0x15;
dev->ret_ecr = 0x15;
dev->cnfga_readout = 0x10;
memset(dev->ext_regs, 0x00, 8);
dev->ext_regs[0x02] = 0x80;
if (lpt_ports[dev->id].enabled) {
if (info->local & 0xfff00000) {

View File

@@ -475,6 +475,12 @@ serial_set_clock_src(serial_t *dev, double clock_src)
serial_update_speed(dev);
}
void
serial_set_type(serial_t *dev, uint8_t type)
{
dev->type = type;
}
void
serial_write(uint16_t addr, uint8_t val, void *priv)
{

View File

@@ -53,6 +53,7 @@ typedef struct lpt_t {
uint8_t epp;
uint8_t ecp;
uint8_t ecr;
uint8_t ret_ecr;
uint8_t in_dat;
uint8_t fifo_stat;
uint8_t dma_stat;
@@ -61,8 +62,11 @@ typedef struct lpt_t {
uint8_t strobe;
uint8_t lv2;
uint8_t cnfga_readout;
uint8_t cfg_regs_enabled;
uint8_t inst;
uint8_t pad[5];
uint8_t eir;
uint8_t pad[2];
uint8_t ext_regs[8];
uint16_t addr;
uint16_t id;
uint16_t pad0[2];
@@ -101,6 +105,8 @@ extern uint8_t lpt_read(uint16_t port, void *priv);
extern uint8_t lpt_read_port(lpt_t *dev, uint16_t reg);
extern uint8_t lpt_read_status(lpt_t *dev);
extern uint8_t lpt_read_ecp_mode(lpt_t *dev);
extern void lpt_irq(void *priv, int raise);
extern int lpt_device_get_from_internal_name(const char *str);
@@ -125,6 +131,7 @@ extern void lpt_set_ext(lpt_t *dev, uint8_t ext);
extern void lpt_set_ecp(lpt_t *dev, uint8_t ecp);
extern void lpt_set_epp(lpt_t *dev, uint8_t epp);
extern void lpt_set_lv2(lpt_t *dev, uint8_t lv2);
extern void lpt_set_cfg_regs_enabled(lpt_t *dev, uint8_t cfg_regs_enabled);
extern void lpt_set_fifo_threshold(lpt_t *dev, int threshold);
extern void lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout);
extern void lpt_port_setup(lpt_t *dev, uint16_t port);

View File

@@ -164,31 +164,32 @@
enum {
MACHINE_TYPE_NONE = 0,
MACHINE_TYPE_8088 = 1,
MACHINE_TYPE_8086 = 2,
MACHINE_TYPE_286 = 3,
MACHINE_TYPE_386SX = 4,
MACHINE_TYPE_486SLC = 5,
MACHINE_TYPE_386DX = 6,
MACHINE_TYPE_386DX_486 = 7,
MACHINE_TYPE_486 = 8,
MACHINE_TYPE_486_S2 = 9,
MACHINE_TYPE_486_S3 = 10,
MACHINE_TYPE_486_S3_PCI = 11,
MACHINE_TYPE_486_MISC = 12,
MACHINE_TYPE_SOCKET4 = 13,
MACHINE_TYPE_SOCKET5 = 14,
MACHINE_TYPE_SOCKET7_3V = 15,
MACHINE_TYPE_SOCKET7 = 16,
MACHINE_TYPE_SOCKETS7 = 17,
MACHINE_TYPE_SOCKET8 = 18,
MACHINE_TYPE_SLOT1 = 19,
MACHINE_TYPE_SLOT1_2 = 20,
MACHINE_TYPE_SLOT1_370 = 21,
MACHINE_TYPE_SLOT2 = 22,
MACHINE_TYPE_SOCKET370 = 23,
MACHINE_TYPE_MISC = 24,
MACHINE_TYPE_MAX = 25
MACHINE_TYPE_8088,
MACHINE_TYPE_8086,
MACHINE_TYPE_286,
MACHINE_TYPE_386SX,
MACHINE_TYPE_M6117,
MACHINE_TYPE_486SLC,
MACHINE_TYPE_386DX,
MACHINE_TYPE_386DX_486,
MACHINE_TYPE_486,
MACHINE_TYPE_486_S2,
MACHINE_TYPE_486_S3,
MACHINE_TYPE_486_S3_PCI,
MACHINE_TYPE_486_MISC,
MACHINE_TYPE_SOCKET4,
MACHINE_TYPE_SOCKET5,
MACHINE_TYPE_SOCKET7_3V,
MACHINE_TYPE_SOCKET7,
MACHINE_TYPE_SOCKETS7,
MACHINE_TYPE_SOCKET8,
MACHINE_TYPE_SLOT1,
MACHINE_TYPE_SLOT1_2,
MACHINE_TYPE_SLOT1_370,
MACHINE_TYPE_SLOT2,
MACHINE_TYPE_SOCKET370,
MACHINE_TYPE_MISC,
MACHINE_TYPE_MAX
};
enum {
@@ -440,78 +441,107 @@ extern void machine_at_ibm_common_ide_init(const machine_t *);
extern void machine_at_ide_init(const machine_t *);
extern void machine_at_ps2_ide_init(const machine_t *);
extern int machine_at_ibm_init(const machine_t *);
extern int machine_at_ibm_init(const machine_t *);
// IBM AT with custom BIOS
extern int machine_at_ibmatami_init(const machine_t *); // IBM AT with AMI BIOS
extern int machine_at_ibmatpx_init(const machine_t *); // IBM AT with Phoenix BIOS
extern int machine_at_ibmatquadtel_init(const machine_t *); // IBM AT with Quadtel BIOS
extern int machine_at_ibmatami_init(const machine_t *); // IBM AT with AMI BIOS
extern int machine_at_ibmatpx_init(const machine_t *); // IBM AT with Phoenix BIOS
extern int machine_at_ibmatquadtel_init(const machine_t *); // IBM AT with Quadtel BIOS
extern int machine_at_ibmxt286_init(const machine_t *);
extern int machine_at_ibmxt286_init(const machine_t *);
extern int machine_at_pb286_init(const machine_t *);
extern int machine_at_pb286_init(const machine_t *);
extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places
extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places
extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS
/* m_at_286.c */
/* ISA */
extern int machine_at_mr286_init(const machine_t *);
extern int machine_at_pc8_init(const machine_t *);
extern int machine_at_m290_init(const machine_t *);
/* m_at_286_386sx.c */
extern int machine_at_tg286m_init(const machine_t *);
extern int machine_at_ama932j_init(const machine_t *);
extern int machine_at_px286_init(const machine_t *);
extern int machine_at_quadt286_init(const machine_t *);
extern int machine_at_mr286_init(const machine_t *);
/* C&T PC/AT */
extern int machine_at_dells200_init(const machine_t *);
extern int machine_at_super286c_init(const machine_t *);
extern int machine_at_at122_init(const machine_t *);
extern int machine_at_tuliptc7_init(const machine_t *);
extern int machine_at_pbl300sx_init(const machine_t *);
extern int machine_at_neat_init(const machine_t *);
extern int machine_at_neat_ami_init(const machine_t *);
extern int machine_at_ataripc4_init(const machine_t *);
/* GC103 */
extern int machine_at_quadt286_init(const machine_t *);
extern void machine_at_headland_common_init(const machine_t *model, int type);
extern int machine_at_tg286m_init(const machine_t *);
/* Wells American A*Star with custom award BIOS. */
extern int machine_at_wellamerastar_init(const machine_t *);
extern int machine_at_quadt386sx_init(const machine_t *);
/* NEAT */
extern int machine_at_ataripc4_init(const machine_t *);
extern int machine_at_neat_ami_init(const machine_t *);
extern int machine_at_3302_init(const machine_t *);
extern int machine_at_px286_init(const machine_t *);
extern int machine_at_award286_init(const machine_t *);
extern int machine_at_gdc212m_init(const machine_t *);
extern int machine_at_gw286ct_init(const machine_t *);
extern int machine_at_drsm35286_init(const machine_t *);
extern int machine_at_senor_scat286_init(const machine_t *);
extern int machine_at_super286c_init(const machine_t *);
extern int machine_at_super286tr_init(const machine_t *);
extern int machine_at_spc4200p_init(const machine_t *);
extern int machine_at_spc4216p_init(const machine_t *);
extern int machine_at_spc4620p_init(const machine_t *);
extern int machine_at_kmxc02_init(const machine_t *);
extern int machine_at_deskmaster286_init(const machine_t *);
/* SCAT */
extern int machine_at_gw286ct_init(const machine_t *);
extern int machine_at_gdc212m_init(const machine_t *);
extern int machine_at_award286_init(const machine_t *);
extern int machine_at_super286tr_init(const machine_t *);
extern int machine_at_drsm35286_init(const machine_t *);
extern int machine_at_deskmaster286_init(const machine_t *);
extern int machine_at_spc4200p_init(const machine_t *);
extern int machine_at_spc4216p_init(const machine_t *);
extern int machine_at_spc4620p_init(const machine_t *);
extern int machine_at_senor_scat286_init(const machine_t *);
extern int machine_at_dells200_init(const machine_t *);
extern int machine_at_at122_init(const machine_t *);
extern int machine_at_tuliptc7_init(const machine_t *);
/* m_at_386sx.c */
/* ISA */
extern int machine_at_pc916sx_init(const machine_t *);
extern int machine_at_quadt386sx_init(const machine_t *);
extern int machine_at_pc8_init(const machine_t *);
extern int machine_at_3302_init(const machine_t *);
/* ACC 2036 */
extern int machine_at_pbl300sx_init(const machine_t *);
extern int machine_at_m290_init(const machine_t *);
/* ALi M1217 */
extern int machine_at_arb1374_init(const machine_t *);
extern int machine_at_sbc350a_init(const machine_t *);
extern int machine_at_flytech386_init(const machine_t *);
extern int machine_at_325ax_init(const machine_t *);
extern int machine_at_mr1217_init(const machine_t *);
extern int machine_at_shuttle386sx_init(const machine_t *);
extern int machine_at_adi386sx_init(const machine_t *);
extern int machine_at_cmdsl386sx16_init(const machine_t *);
extern int machine_at_cmdsl386sx25_init(const machine_t *);
extern int machine_at_dataexpert386sx_init(const machine_t *);
extern int machine_at_dells333sl_init(const machine_t *);
extern int machine_at_if386sx_init(const machine_t *);
extern int machine_at_spc6033p_init(const machine_t *);
extern int machine_at_wd76c10_init(const machine_t *);
extern int machine_at_arb1374_init(const machine_t *);
extern int machine_at_sbc350a_init(const machine_t *);
extern int machine_at_flytech386_init(const machine_t *);
extern int machine_at_325ax_init(const machine_t *);
extern int machine_at_mr1217_init(const machine_t *);
extern int machine_at_pja511m_init(const machine_t *);
extern int machine_at_prox1332_init(const machine_t *);
extern int machine_at_acer100t_init(const machine_t *);
/* ALi M1409 */
extern int machine_at_acer100t_init(const machine_t *);
extern int machine_at_awardsx_init(const machine_t *);
/* HT18 */
extern int machine_at_ama932j_init(const machine_t *);
extern int machine_at_pc916sx_init(const machine_t *);
/* Intel 82335 */
extern int machine_at_adi386sx_init(const machine_t *);
extern int machine_at_shuttle386sx_init(const machine_t *);
/* NEAT */
extern int machine_at_cmdsl386sx16_init(const machine_t *);
extern int machine_at_neat_init(const machine_t *);
/* NEATsx */
extern int machine_at_if386sx_init(const machine_t *);
/* OPTi 291 */
extern int machine_at_awardsx_init(const machine_t *);
/* SCAMP */
extern int machine_at_cmdsl386sx25_init(const machine_t *);
extern int machine_at_dataexpert386sx_init(const machine_t *);
extern int machine_at_dells333sl_init(const machine_t *);
extern int machine_at_spc6033p_init(const machine_t *);
/* SCATsx */
extern int machine_at_kmxc02_init(const machine_t *);
/* WD76C10 */
extern int machine_at_wd76c10_init(const machine_t *);
/* m_at_m6117.c */
/* ALi M6117D */
extern int machine_at_pja511m_init(const machine_t *);
extern int machine_at_prox1332_init(const machine_t *);
/* m_at_386dx_486.c */
/* Note to jriwanek: When merging this into my branch, please make

View File

@@ -135,7 +135,6 @@ extern serial_t *serial_attach_ex_2(int port,
serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv);
extern void serial_remove(serial_t *dev);
extern void serial_set_type(serial_t *dev, int type);
extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq);
extern void serial_irq(serial_t *dev, uint8_t irq);
extern void serial_clear_fifo(serial_t *dev);
@@ -143,6 +142,7 @@ extern void serial_write_fifo(serial_t *dev, uint8_t dat);
extern void serial_set_next_inst(int ni);
extern void serial_standalone_init(void);
extern void serial_set_clock_src(serial_t *dev, double clock_src);
extern void serial_set_type(serial_t *dev, uint8_t type);
extern void serial_reset_port(serial_t *dev);
extern uint8_t serial_read(uint16_t addr, void *priv);
extern void serial_device_timeout(void *priv);

View File

@@ -29,36 +29,35 @@ extern const device_t f82c710_device;
extern const device_t f82c710_pc5086_device;
/* SM(S)C */
extern const device_t fdc37c651_device;
extern const device_t fdc37c651_ide_device;
extern const device_t fdc37c661_device;
extern const device_t fdc37c661_ide_device;
extern const device_t fdc37c661_ide_sec_device;
extern const device_t fdc37c663_device;
extern const device_t fdc37c663_ide_device;
extern const device_t fdc37c665_device;
extern const device_t fdc37c665_ide_device;
extern const device_t fdc37c665_ide_pri_device;
extern const device_t fdc37c665_ide_sec_device;
extern const device_t fdc37c666_device;
#define FDC37C651 0x00051
#define FDC37C661 0x00061
#define FDC37C663 0x00063
#define FDC37C665 0x00065
#define FDC37C666 0x00066
#define FDC37C6XX_IDE_PRI 0x00100
#define FDC37C6XX_IDE_SEC 0x00200
#define FDC37C6XX_370 0x00400
extern const device_t fdc37c6xx_device;
extern const device_t fdc37c669_device;
extern const device_t fdc37c669_370_device;
#define FDC37C93X_NORMAL 0x0002
#define FDC37C93X_FR 0x0003
#define FDC37C93X_APM 0x0030
#define FDC37C93X_CHIP_ID 0x00ff
#define FDC37C93X_NORMAL 0x00002
#define FDC37C93X_FR 0x00003
#define FDC37C93X_APM 0x00030
#define FDC37C93X_CHIP_ID 0x000ff
#define FDC37XXX1 0x0100 /* Compaq KBC firmware and configuration registers on GPIO ports. */
#define FDC37XXX2 0x0200 /* AMI '5' Megakey KBC firmware. */
#define FDC37XXX3 0x0300 /* IBM KBC firmware. */
#define FDC37XXX5 0x0500 /* Phoenix Multikey/42 1.38 KBC firmware. */
#define FDC37XXX7 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define FDC37XXXX_KBC 0x0f00
#define FDC37XXX1 0x00100 /* Compaq KBC firmware and configuration registers on GPIO ports. */
#define FDC37XXX2 0x00200 /* AMI '5' Megakey KBC firmware. */
#define FDC37XXX3 0x00300 /* IBM KBC firmware. */
#define FDC37XXX5 0x00500 /* Phoenix Multikey/42 1.38 KBC firmware. */
#define FDC37XXX7 0x00700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define FDC37XXXX_KBC 0x00f00
#define FDC37C93X_NO_NVR 0x1000
#define FDC37XXXX_370 0x2000
#define FDC37C93X_NO_NVR 0x01000
#define FDC37XXXX_370 0x02000
extern const device_t fdc37c93x_device;
@@ -71,42 +70,52 @@ extern const device_t it8661f_device;
extern const device_t it8671f_device;
/* Intel */
#define I82091AA_022 0x00000 /* Default. */
#define I82091AA_024 0x00008
#define I82091AA_26E 0x00100
#define I82091AA_398 0x00108
#define I82091AA_IDE_PRI 0x00200
#define I82091AA_IDE_SEC 0x00400
extern const device_t i82091aa_device;
extern const device_t i82091aa_26e_device;
extern const device_t i82091aa_398_device;
extern const device_t i82091aa_ide_pri_device;
extern const device_t i82091aa_ide_device;
/* National Semiconductors PC87310 / ALi M5105 */
#define PC87310_IDE 0x0001
#define PC87310_ALI 0x0002
#define PCX73XX_IDE 0x00001
#define PCX73XX_IDE_PRI PCX73XX_IDE
#define PCX73XX_IDE_SEC 0x00002
#define PCX73XX_FDC_ON 0x10000
#define PC87310_ALI 0x00004
#define PC87332 PC87310_ALI
extern const device_t pc87310_device;
/* National Semiconductors */
#define PCX7307_PC87307 0x00c0
#define PCX7307_PC97307 0x00cf
#define PCX7307_PC87307 0x000c0
#define PCX7307_PC97307 0x000cf
#define PC87309_PC87309 0x00e0
#define PC87309_PC87309 0x000e0
#define PCX730X_CHIP_ID 0x00ff
#define PCX730X_CHIP_ID 0x000ff
#define PCX730X_AMI 0x0200 /* AMI '5' Megakey KBC firmware. */
#define PCX730X_PHOENIX_42 0x0500 /* Phoenix Multikey/42 1.37 KBC firmware. */
#define PCX730X_PHOENIX_42I 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define PCX730X_KBC 0x0f00
#define PCX730X_AMI 0x00200 /* AMI '5' Megakey KBC firmware. */
#define PCX730X_PHOENIX_42 0x00500 /* Phoenix Multikey/42 1.37 KBC firmware. */
#define PCX730X_PHOENIX_42I 0x00700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define PCX730X_KBC 0x00f00
#define PCX730X_15C 0x2000
#define PCX730X_398 0x00000
#define PCX730X_26E 0x01000
#define PCX730X_15C 0x02000
#define PCX730X_02E 0x03000
#define PCX730X_BADDR 0x03000
#define PCX730X_BADDR_SHIFT 12
extern const device_t pc87306_device;
extern const device_t pc87311_device;
extern const device_t pc87311_ide_device;
extern const device_t pc87332_device;
extern const device_t pc87332_398_device;
extern const device_t pc87332_398_ide_device;
extern const device_t pc87332_398_ide_sec_device;
extern const device_t pc87332_398_ide_fdcon_device;
extern const device_t pc873xx_device;
/* National Semiconductors PC87307 / PC87309 */
extern const device_t pc87307_device;
@@ -114,10 +123,15 @@ extern const device_t pc87307_device;
extern const device_t pc87309_device;
/* LG Prime */
extern const device_t prime3b_device;
extern const device_t prime3b_ide_device;
extern const device_t prime3c_device;
extern const device_t prime3c_ide_device;
#define GM82C803A 0x00000
#define GM82C803B 0x00001
#define GM82C803_IDE_PRI 0x00100
#define GM82C803_IDE_SEC 0x00200
extern const device_t gm82c803ab_device;
extern const device_t gm82c803c_device;
/* IBM PS/1 */
extern const device_t ps1_m2133_sio;
@@ -128,20 +142,17 @@ extern const device_t sio_detect_device;
#endif /* USE_SIO_DETECT */
/* UMC */
extern const device_t um82c862f_device;
extern const device_t um82c862f_ide_device;
extern const device_t um82c863f_device;
extern const device_t um82c863f_ide_device;
extern const device_t um8663af_device;
extern const device_t um8663af_ide_device;
extern const device_t um8663af_sec_device;
extern const device_t um8663bf_device;
extern const device_t um8663bf_ide_device;
extern const device_t um8663bf_sec_device;
#define UM82C862F 0x00000
#define UM82C863F 0x0c100
#define UM8663AF 0x0c300
#define UM8663BF 0x0c400
#define UM866X_IDE_PRI 0x00001
#define UM866X_IDE_SEC 0x00002
extern const device_t um866x_device;
extern const device_t um8669f_device;
extern const device_t um8669f_ide_device;
extern const device_t um8669f_ide_sec_device;
/* VIA */
extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv);
@@ -152,26 +163,43 @@ extern const device_t via_vt82c686_sio_device;
extern const device_t vl82c113_device;
/* Winbond */
extern const device_t w83787f_88h_device;
extern const device_t w83787f_device;
extern const device_t w83787f_ide_device;
extern const device_t w83787f_ide_en_device;
extern const device_t w83787f_ide_sec_device;
#define W83777F 0x00007
#define W83787F 0x00008
#define W83787IF 0x00009
extern const device_t w83877f_device;
extern const device_t w83877f_president_device;
extern const device_t w83877tf_device;
extern const device_t w83877tf_acorp_device;
#define W837X7_KEY_88 0x00000
#define W837X7_KEY_89 0x00020
#define TYPE_W83977EF 0x52F0
#define TYPE_W83977F 0x9771
#define TYPE_W83977TF 0x9773
#define TYPE_W83977ATF 0x9774
#define W837X7_IDE_START 0x00040
extern const device_t w83977f_device;
extern const device_t w83977f_370_device;
extern const device_t w83977tf_device;
extern const device_t w83977ef_device;
extern const device_t w83977ef_370_device;
#define W83XX7_IDE_PRI 0x10000
#define W83XX7_IDE_SEC 0x20000
extern const device_t w837x7_device;
#define W83877F 0x00a00
#define W83877TF 0x00c00
#define W83877_3F0 0x00005
#define W83877_250 0x00004
extern const device_t w83877_device;
#define W83977F 0x977100
#define W83977TF 0x977300
#define W83977EF 0x52f000
#define W83977_TYPE 0xffff00
#define W83977_TYPE_SHIFT 8
#define W83977_3F0 0x00000
#define W83977_370 0x00001
#define W83977_NO_NVR 0x00002
#define W83977_AMI 0x00010 /* AMI 'H' KBC firmware. */
#define W83977_PHOENIX 0x00020 /* Unknown Phoenix Multikey KBC firmware. */
#define W83977_KBC 0x000f0
extern const device_t w83977_device;
#endif /*EMU_SIO_H*/

View File

@@ -42,7 +42,9 @@ add_library(mch OBJECT
m_ps2_isa.c
m_ps2_mca.c
m_at_compaq.c
m_at_286_386sx.c
m_at_286.c
m_at_386sx.c
m_at_m6117.c
m_at_386dx_486.c
m_at_socket4.c
m_at_socket5.c

609
src/machine/m_at_286.c Normal file
View File

@@ -0,0 +1,609 @@
/*
* 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.
*
* Implementation of 286 machines.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2016-2025 Miran Grca.
* Copyright 2020-2025 EngiNerd.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/nvr.h>
#include <86box/port_6x.h>
#define USE_SIO_DETECT
#include <86box/sio.h>
#include <86box/serial.h>
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/flash.h>
#include <86box/machine.h>
/* ISA */
int
machine_at_mr286_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/mr286/V000B200-1",
"roms/machines/mr286/V000B200-2",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&kbc_at_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
/*
* Current bugs:
* - ctrl-alt-del produces an 8042 error
*/
int
machine_at_pc8_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/pc8/ncr_35117_u127_vers.4-2.bin",
"roms/machines/pc8/ncr_35116_u113_vers.4-2.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&kbc_at_ncr_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_m290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 6);
device_add(&amstrad_megapc_nvr_device);
device_add(&olivetti_eva_device);
device_add(&port_6x_olivetti_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&kbc_at_olivetti_device);
return ret;
}
/* C&T PC/AT */
static void
machine_at_ctat_common_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&cs8220_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&kbc_at_phoenix_device);
}
int
machine_at_dells200_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN",
"roms/machines/dells200/Dell200256_HI_@DIP28.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ctat_common_init(model);
return ret;
}
int
machine_at_super286c_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/super286c/hyundai_award286.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&kbc_at_ami_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&cs8220_device);
return ret;
}
int
machine_at_at122_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/at122/FINAL.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ctat_common_init(model);
return ret;
}
int
machine_at_tuliptc7_init(const machine_t *model)
{
int ret;
ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin",
"roms/machines/tuliptc7/tc7bo.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ctat_common_init(model);
return ret;
}
int
machine_at_wellamerastar_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/wellamerastar/W_3.031_L.BIN",
"roms/machines/wellamerastar/W_3.031_H.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ctat_common_init(model);
return ret;
}
/* GC103 */
int
machine_at_quadt286_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/quadt286/QUADT89L.ROM",
"roms/machines/quadt286/QUADT89H.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&kbc_at_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&headland_gc10x_device);
return ret;
}
void
machine_at_headland_common_init(const machine_t *model, int type)
{
device_add(&kbc_at_ami_device);
if ((type != 2) && (fdc_current[0] == FDC_INTERNAL))
device_add(&fdc_at_device);
if (type == 2)
device_add(&headland_ht18b_device);
else if (type == 1)
device_add(&headland_gc113_device);
else
device_add(&headland_gc10x_device);
}
int
machine_at_tg286m_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/tg286m/ami.bin",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
machine_at_headland_common_init(model, 1);
return ret;
}
// TODO
// Onboard Paradise PVGA1A-JK VGA Graphics
// Data Technology Corporation DTC7187 RLL Controller (Optional)
int
machine_at_ataripc4_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN",
"roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&neat_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&kbc_at_ami_device);
return ret;
}
int
machine_at_neat_ami_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/ami286/AMIC206.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&neat_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&kbc_at_ami_device);
return ret;
}
int
machine_at_3302_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/3302/f000-flex_drive_test.bin",
0x000f0000, 65536, 0);
if (ret) {
ret &= bios_load_aux_linear("roms/machines/3302/f800-setup_ncr3.5-013190.bin",
0x000f8000, 32768, 0);
}
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&neat_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
device_add(&kbc_at_ncr_device);
return ret;
}
int
machine_at_px286_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/px286/KENITEC.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&kbc_at_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&neat_device);
return ret;
}
/* SCAT */
static void
machine_at_scat_init(const machine_t *model, int is_v4, int is_ami)
{
machine_at_common_init(model);
if (machines[machine].bus_flags & MACHINE_BUS_PS2) {
if (is_ami)
device_add(&kbc_ps2_ami_device);
else
device_add(&kbc_ps2_device);
} else {
if (is_ami)
device_add(&kbc_at_ami_device);
else
device_add(&kbc_at_device);
}
if (is_v4)
device_add(&scat_4_device);
else
device_add(&scat_device);
}
int
machine_at_gw286ct_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/gw286ct/2ctc001.bin",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
device_add(&f82c710_device);
machine_at_scat_init(model, 1, 0);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_gdc212m_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/gdc212m/gdc212m_72h.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_award286_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/award286/award.bin",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_super286tr_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/super286tr/hyundai_award286.bin",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_drsm35286_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/drsm35286/syab04-665821fb81363428830424.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
device_add(&ide_isa_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI));
machine_at_scat_init(model, 1, 0);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
return ret;
}
int
machine_at_deskmaster286_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/deskmaster286/SAMSUNG-DESKMASTER-28612-ROM.BIN",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
device_add(&f82c710_device);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_spc4200p_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/spc4200p/u8.01",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
device_add(&f82c710_device);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_spc4216p_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/spc4216p/7101.U8",
"roms/machines/spc4216p/AC64.U10",
0x000f0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 1, 1);
device_add(&f82c710_device);
return ret;
}
int
machine_at_spc4620p_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/spc4620p/31005h.u8",
"roms/machines/spc4620p/31005h.u10",
0x000f0000, 131072, 0x8000);
if (bios_only || !ret)
return ret;
if (gfxcard[0] == VID_INTERNAL)
device_add(&ati28800k_spc4620p_device);
machine_at_scat_init(model, 1, 1);
device_add(&f82c710_device);
device_add(&ide_isa_device);
return ret;
}
int
machine_at_senor_scat286_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/senor286/AMI-DSC2-1115-061390-K8.rom",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_scat_init(model, 0, 1);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}

View File

@@ -423,7 +423,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
device_add(&vl82c113_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI));
return ret;
}
@@ -453,7 +453,7 @@ machine_at_d824_init(const machine_t *model)
device_add(&vl82c113_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C651);
return ret;
}
@@ -477,7 +477,7 @@ machine_at_tuliptc38_init(const machine_t *model)
device_add(&vl82c113_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI));
if (gfxcard[0] == VID_INTERNAL) {
bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN",
@@ -510,7 +510,7 @@ machine_at_martin_init(const machine_t *model)
device_add(&vl82c113_device);
device_add(&ide_vlb_device);
device_add(&fdc37c651_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI));
device_add(&intel_flash_bxt_device);
@@ -586,7 +586,7 @@ machine_at_decpclpv_init(const machine_t *model)
device_add(&kbc_ps2_phoenix_pci_device);
device_add(&ide_isa_2ch_device);
device_add(&fdc37c663_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C663 | FDC37C6XX_IDE_PRI));
return ret;
}
@@ -617,7 +617,7 @@ machine_at_dell466np_init(const machine_t *model)
device_add(&kbc_ps2_phoenix_pci_device);
device_add(&ide_isa_device);
device_add(&fdc37c661_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C661 | FDC37C6XX_IDE_PRI));
return ret;
}
@@ -759,7 +759,7 @@ machine_at_c747_init(const machine_t *model)
desired behavior: command A9 does absolutely nothing.
*/
device_add(&kbc_at_siemens_device);
device_add(&um82c862f_ide_device);
device_add_params(&um866x_device, (void *) (UM82C862F | UM866X_IDE_PRI));
return ret;
}
@@ -921,8 +921,8 @@ machine_at_pb450_init(const machine_t *model)
device_add(&opti602_device);
device_add(&opti822_device);
device_add(&kbc_ps2_phoenix_device);
device_add(&fdc37c665_ide_device);
device_add(&ide_opti611_vlb_sec_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&ide_opti611_vlb_device);
device_add(&intel_flash_bxt_device);
device_add(&phoenix_486_jumper_pci_device);
@@ -952,7 +952,7 @@ machine_at_pc330_6573_common_init(const machine_t *model)
device_add(&opti802g_device);
device_add(&opti822_device);
device_add(&kbc_ps2_ami_device);
device_add(&fdc37c665_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&ide_opti611_vlb_device);
device_add(&intel_flash_bxt_device);
}
@@ -1005,7 +1005,9 @@ machine_at_mvi486_init(const machine_t *model)
device_add(&opti498_device);
device_add(&kbc_at_device);
device_add(&pc87311_ide_device);
device_add(&ide_isa_device);
device_add_params(&pc873xx_device, (void *) (PCX73XX_IDE_PRI | PCX730X_398));
return ret;
}
@@ -1056,7 +1058,7 @@ machine_at_advantage40xxd_init(const machine_t *model)
device_add(machine_get_vid_device(machine));
device_add(&kbc_ps2_phoenix_device);
device_add(&um82c863f_ide_device);
device_add_params(&um866x_device, (void *) (UM82C863F | UM866X_IDE_PRI));
device_add(&intel_flash_bxt_device);
@@ -1262,7 +1264,7 @@ machine_at_r418_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_pci_device);
return ret;
@@ -1288,7 +1290,7 @@ machine_at_m4li_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_pci_device);
return ret;
@@ -1314,7 +1316,7 @@ machine_at_ls486e_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_pci_device);
return ret;
@@ -1340,7 +1342,7 @@ machine_at_4dps_init(const machine_t *model)
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787IF | W837X7_KEY_89));
device_add(&kbc_ps2_ami_device);
device_add(&intel_flash_bxt_device);
@@ -1367,7 +1369,7 @@ machine_at_ms4144_init(const machine_t *model)
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&kbc_at_ami_device);
device_add(&sst_flash_29ee010_device);
@@ -1396,11 +1398,11 @@ machine_at_acerp3_init(const machine_t *model)
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&fdc37c665_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&kbc_ps2_acer_pci_device);
device_add(&ide_cmd640_pci_legacy_only_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&ide_cmd640_pci_legacy_only_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5434_onboard_pci_device);
device_add(&intel_flash_bxt_device);
@@ -1427,7 +1429,7 @@ machine_at_486sp3c_init(const machine_t *model)
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_pci_device);
device_add(&intel_flash_bxt_device);
@@ -1455,7 +1457,7 @@ machine_at_4saw2_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83777F | W837X7_KEY_89));
device_add(&kbc_ps2_pci_device);
device_add(&intel_flash_bxt_device);
@@ -1488,7 +1490,7 @@ machine_at_alfredo_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_ps2_phoenix_device);
device_add(&sio_device);
device_add(&fdc37c663_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C663);
device_add(&intel_flash_bxt_ami_device);
device_add(&i420tx_device);
@@ -1519,7 +1521,7 @@ machine_at_ninja_init(const machine_t *model)
device_add(&intel_flash_bxt_ami_device);
device_add(&i420ex_device);
device_add(&i82091aa_device);
device_add_params(&i82091aa_device, (void *) I82091AA_022);
return ret;
}
@@ -1548,7 +1550,7 @@ machine_at_bat4ip3e_init(const machine_t *model)
device_add(&kbc_ps2_pci_device);
device_add(&i420ex_device);
device_add(&ide_cmd640_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
return ret;
}
@@ -1573,7 +1575,7 @@ machine_at_486pi_init(const machine_t *model)
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&i420ex_device);
return ret;
@@ -1598,7 +1600,7 @@ machine_at_sb486p_init(const machine_t *model)
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1);
device_add(&kbc_ps2_ami_pci_device);
device_add(&i82091aa_device);
device_add_params(&i82091aa_device, (void *) I82091AA_022);
device_add(&i420ex_device);
return ret;
@@ -1628,7 +1630,7 @@ machine_at_486sp3_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_at_ami_device); /* Uses the AMIKEY KBC */
device_add(&sio_device);
device_add(&fdc37c663_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C663 | FDC37C6XX_IDE_PRI));
device_add(&sst_flash_29ee010_device);
device_add(&i420tx_device);
@@ -1657,7 +1659,7 @@ machine_at_amis76_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_ps2_ami_pci_device);
device_add(&sio_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_ami_device);
device_add(&i420tx_device);
@@ -1750,7 +1752,7 @@ machine_at_486sp3g_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_ps2_ami_pci_device); /* Uses the AMIKEY KBC */
device_add(&sio_zb_device);
device_add(&pc87332_398_ide_device);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX73XX_IDE_PRI | PCX730X_398));
device_add(&sst_flash_29ee010_device);
device_add(&i420zx_device);
@@ -1829,7 +1831,7 @@ machine_at_sb486pv_init(const machine_t *model)
device_add(&kbc_ps2_ami_pci_device);
device_add(&sio_zb_device);
device_add(&ide_rz1000_pci_single_channel_device);
device_add(&i82091aa_26e_device);
device_add_params(&i82091aa_device, (void *) I82091AA_26E);
if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom"))
device_add(&intel_flash_bxt_device);
else
@@ -1892,7 +1894,7 @@ machine_at_g486vpa_init(const machine_t *model)
device_add(&via_vt82c49x_pci_ide_device);
device_add(&via_vt82c505_device);
device_add(&pc87332_398_ide_sec_device);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX73XX_IDE_SEC | PCX730X_398));
device_add(&kbc_ps2_ami_pci_device);
device_add(&sst_flash_29ee010_device);
@@ -1921,7 +1923,7 @@ machine_at_486vipio2_init(const machine_t *model)
device_add(&via_vt82c49x_pci_ide_device);
device_add(&via_vt82c505_device);
device_add(&w83787f_ide_sec_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&kbc_ps2_ami_pci_device);
device_add(&sst_flash_29ee010_device);
@@ -1948,7 +1950,7 @@ machine_at_abpb4_init(const machine_t *model)
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&ali1489_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&kbc_at_device);
#if 0
device_add(&intel_flash_bxt_device);
@@ -1978,7 +1980,7 @@ machine_at_win486pci_init(const machine_t *model)
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&ali1489_device);
device_add(&prime3b_device);
device_add_params(&gm82c803ab_device, (void *) GM82C803B);
device_add(&kbc_at_ami_device);
return ret;
@@ -2005,7 +2007,7 @@ machine_at_ms4145_init(const machine_t *model)
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&ali1489_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&kbc_at_ami_device);
device_add(&sst_flash_29ee010_device);
@@ -2037,7 +2039,7 @@ machine_at_sbc490_init(const machine_t *model)
device_add(machine_get_vid_device(machine));
device_add(&ali1489_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_device);
device_add(&sst_flash_29ee010_device);
@@ -2062,8 +2064,8 @@ machine_at_tf486_init(const machine_t *model)
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&ali1489_device);
device_add(&w83977ef_device);
device_add(&kbc_at_device);
device_add(&kbc_at_phoenix_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_NO_NVR));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -2085,7 +2087,7 @@ machine_at_arb1476_init(const machine_t *model)
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
device_add(&ali1489_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&kbc_ps2_device);
device_add(&sst_flash_29ee010_device);
@@ -2103,14 +2105,13 @@ machine_at_itoxstar_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&w83977f_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI));
device_add(&stpc_client_device);
device_add(&sst_flash_29ee020_device);
device_add(&w83781d_device); /* fans: Chassis, CPU, unused; temperatures: Chassis, CPU, unused */
@@ -2132,7 +2133,7 @@ machine_at_arb1423c_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2140,8 +2141,7 @@ machine_at_arb1423c_init(const machine_t *model)
pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 0, 0, 0);
pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&w83977f_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI));
device_add(&stpc_consumer2_device);
device_add(&winbond_flash_w29c020_device);
@@ -2159,7 +2159,7 @@ machine_at_arb1479_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2167,8 +2167,7 @@ machine_at_arb1479_init(const machine_t *model)
pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 0, 0, 0);
pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&w83977f_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI));
device_add(&stpc_consumer2_device);
device_add(&winbond_flash_w29c020_device);
@@ -2186,13 +2185,12 @@ machine_at_iach488_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&w83977f_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI));
device_add(&stpc_consumer2_device);
device_add(&sst_flash_29ee020_device);
@@ -2210,7 +2208,7 @@ machine_at_pcm9340_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2218,9 +2216,8 @@ machine_at_pcm9340_init(const machine_t *model)
pci_register_slot(0x1D, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x1E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 2, 3, 4, 1);
device_add_inst(&w83977f_device, 1);
device_add_inst(&w83977f_device, 2);
device_add(&kbc_ps2_ami_pci_device);
device_add_inst_params(&w83977_device, 1, (void *) (W83977F | W83977_AMI));
device_add_inst_params(&w83977_device, 2, (void *) W83977F);
device_add(&stpc_elite_device);
device_add(&sst_flash_29ee020_device);
@@ -2238,7 +2235,7 @@ machine_at_pcm5330_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2247,8 +2244,7 @@ machine_at_pcm5330_init(const machine_t *model)
pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&stpc_serial_device);
device_add(&w83977f_370_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_370 | W83977_AMI));
device_add(&stpc_atlas_device);
device_add(&sst_flash_29ee020_device);
@@ -2279,7 +2275,7 @@ machine_at_ecs486_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886f_device);
device_add(&ide_cmd640_pci_legacy_only_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
device_add(&kbc_ps2_ami_device);
@@ -2358,9 +2354,9 @@ machine_at_hot433a_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886bf_device);
if (is_award)
device_add(&um8663af_device);
device_add_params(&um866x_device, (void *) UM8663AF);
else
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&winbond_flash_w29c010_device);
if (is_award)
device_add(&kbc_ps2_ami_device);
@@ -2394,7 +2390,7 @@ machine_at_84xxuuda_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886bf_device);
device_add(&um8663bf_device);
device_add_params(&um866x_device, (void *) UM8663BF);
device_add(&winbond_flash_w29c010_device);
device_add(&kbc_ps2_ami_device);
@@ -2425,7 +2421,7 @@ machine_at_pl4600c_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886af_device);
device_add(&um8663af_device);
device_add_params(&um866x_device, (void *) UM8663AF);
device_add(&sst_flash_29ee010_device);
device_add(&kbc_ps2_ami_pci_device);
@@ -2496,7 +2492,7 @@ machine_at_actionpc2600_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886bf_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
device_add(&kbc_ps2_tg_ami_device);
@@ -2528,7 +2524,7 @@ machine_at_actiontower8400_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886f_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&ide_cmd640_pci_device);
device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too.
device_add(&kbc_ps2_ami_pci_device);
@@ -2560,7 +2556,7 @@ machine_at_m919_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */
device_add(&um8663bf_device);
device_add_params(&um866x_device, (void *) UM8663BF);
device_add(&sst_flash_29ee010_device);
device_add(&kbc_at_ami_device);
@@ -2589,7 +2585,7 @@ machine_at_spc7700plw_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886af_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
device_add(&kbc_ps2_ami_device);
@@ -2611,7 +2607,7 @@ machine_at_ms4134_init(const machine_t *model)
device_add(&ali1429g_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2645,7 +2641,7 @@ machine_at_tg486gp_init(const machine_t *model)
device_add(&ali1429g_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2678,7 +2674,7 @@ machine_at_tg486g_init(const machine_t *model)
device_add(&amstrad_megapc_nvr_device);
device_add(&sis_85c471_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI));
device_add(&kbc_ps2_tg_ami_pci_device);
if (gfxcard[0] != VID_INTERNAL) {
@@ -2705,7 +2701,7 @@ machine_at_dvent4xx_init(const machine_t *model)
machine_at_common_init(model);
device_add(&sis_85c471_device);
device_add(&ide_cmd640_vlb_pri_device);
device_add(&fdc37c665_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&kbc_ps2_phoenix_device);
if (gfxcard[0] == VID_INTERNAL)
@@ -2753,7 +2749,7 @@ machine_at_ap4100aa_init(const machine_t *model)
device_add(&ali1429g_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ide_vlb_device);
device_add(&um8663bf_device);
device_add_params(&um866x_device, (void *) UM8663BF);
return ret;
}
@@ -2886,7 +2882,7 @@ machine_at_cobalt_init(const machine_t *model)
device_add(&opti499_device);
device_add(&ide_opti611_vlb_device);
device_add(&ide_isa_sec_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_device);
@@ -2911,7 +2907,7 @@ machine_at_cougar_init(const machine_t *model)
device_add(&ide_vlb_device);
device_add(&opti499_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&kbc_at_ami_device);

File diff suppressed because it is too large Load Diff

88
src/machine/m_at_m6117.c Normal file
View File

@@ -0,0 +1,88 @@
/*
* 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.
*
* Implementation of 386SX machines.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2016-2025 Miran Grca.
* Copyright 2020-2025 EngiNerd.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/nvr.h>
#include <86box/port_6x.h>
#define USE_SIO_DETECT
#include <86box/sio.h>
#include <86box/serial.h>
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/flash.h>
#include <86box/machine.h>
/* ALi M6117D */
int
machine_at_pja511m_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/pja511m/2006915102435734.rom",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add_inst_params(&fdc37c669_device, 1, (void *) FDC37C6XX_IDE_PRI);
device_add_inst_params(&fdc37c669_device, 2, (void *) 0);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ali6117d_device);
device_add(&sst_flash_29ee010_device);
return ret;
}
int
machine_at_prox1332_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/prox1332/D30B3AC1.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ali6117d_device);
device_add(&sst_flash_29ee010_device);
return ret;
}

View File

@@ -65,8 +65,7 @@ machine_at_vpc2007_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&i440bx_no_agp_device);
device_add(&piix4e_device);
device_add(&w83977f_370_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977F | W83977_370 | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */

View File

@@ -110,7 +110,7 @@ machine_at_kn97_init(const machine_t *model)
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&intel_flash_bxt_device);
device_add(&lm78_device); /* fans: Chassis, CPU, Power; temperature: MB */
for (uint8_t i = 0; i < 3; i++)
@@ -142,8 +142,7 @@ machine_at_lx6_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440lx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
@@ -272,8 +271,7 @@ machine_at_p6i440e2_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440ex_device);
device_add(&piix4_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x03, 256);
device_add(&w83781d_device); /* fans: CPU, CHS, PS; temperatures: unused, CPU, System */
@@ -308,8 +306,7 @@ machine_at_p2bls_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
#if 0
device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */
#endif
@@ -345,8 +342,7 @@ machine_at_lgibmx7g_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&winbond_flash_w29c020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -378,8 +374,7 @@ machine_at_p3bf_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(ics9xxx_get(ICS9250_08));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
@@ -415,8 +410,7 @@ machine_at_bf6_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -446,8 +440,7 @@ machine_at_bx6_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977f_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
@@ -478,8 +471,7 @@ machine_at_ax6bc_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_29ee020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&gl518sm_2d_device); /* fans: System, CPU; temperature: CPU; no reporting in BIOS */
@@ -510,8 +502,7 @@ machine_at_atc6310bxii_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&slc90e66_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -541,8 +532,7 @@ machine_at_686bx_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: unused, CPU, unused */
@@ -580,8 +570,7 @@ machine_at_p6sba_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&w83977tf_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */
@@ -653,7 +642,7 @@ machine_at_ficka6130_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro_device);
device_add(&via_vt82c596a_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&kbc_ps2_ami_pci_device);
device_add(&sst_flash_29ee020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -686,8 +675,7 @@ machine_at_p3v133_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133_device);
device_add(&via_vt82c596b_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(ics9xxx_get(ICS9248_39));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
@@ -723,8 +711,7 @@ machine_at_p3v4x_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133a_device);
device_add(&via_vt82c596b_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(ics9xxx_get(ICS9250_18));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
@@ -756,8 +743,7 @@ machine_at_gt694va_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133a_device);
device_add(&via_vt82c596b_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 1024);
device_add(&w83782d_device); /* fans: CPU, unused, unused; temperatures: System, CPU1, unused */
@@ -821,12 +807,11 @@ machine_at_ms6168_common_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440zx_device);
device_add(&piix4e_device);
device_add(&w83977ef_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&voodoo_3_2000_agp_onboard_8m_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);

View File

@@ -65,8 +65,7 @@ machine_at_6gxu_init(const machine_t *model)
device_add(&i440gx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */
@@ -102,8 +101,7 @@ machine_at_s2dge_init(const machine_t *model)
device_add(&i440gx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 512);
device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */

View File

@@ -63,8 +63,7 @@ machine_at_s370slm_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440lx_device);
device_add(&piix4e_device);
device_add(&w83977tf_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */
@@ -98,8 +97,7 @@ machine_at_prosignias31x_bx_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&winbond_flash_w29c020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */
@@ -139,8 +137,7 @@ machine_at_s1857_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -176,8 +173,7 @@ machine_at_p6bap_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133a_device); /* Rebranded as ET82C693A */
device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -211,8 +207,7 @@ machine_at_p6bat_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133_device);
device_add(&via_vt82c596b_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -248,8 +243,7 @@ machine_at_cubx_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&ide_cmd648_ter_qua_onboard_device);
device_add(ics9xxx_get(ICS9250_08));
device_add(&sst_flash_39sf020_device);
@@ -283,8 +277,7 @@ machine_at_atc7020bxii_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&slc90e66_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
@@ -355,8 +348,7 @@ machine_at_ambx133_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&w83977ef_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */
@@ -391,9 +383,8 @@ machine_at_awo671r_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add_inst(&w83977ef_device, 1);
device_add_inst(&w83977ef_device, 2);
device_add(&kbc_ps2_pci_device);
device_add_inst_params(&w83977_device, 1, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add_inst_params(&w83977_device, 2, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&sst_flash_39sf020_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
@@ -426,8 +417,7 @@ machine_at_63a1_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440zx_device);
device_add(&piix4e_device);
device_add(&w83977tf_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
@@ -457,7 +447,7 @@ machine_at_apas3_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro_device);
device_add(&via_vt82c586b_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&kbc_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);

View File

@@ -130,7 +130,7 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch)
device_add(&kbc_ps2_phoenix_device);
device_add(&sio_zb_device);
device_add(&ide_rz1000_pci_single_channel_device);
device_add(&fdc37c665_ide_sec_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&intel_flash_bxt_ami_device);
}
@@ -153,7 +153,7 @@ machine_at_sp4_common_init(const machine_t *model)
device_add(&sis_85c50x_device);
device_add(&ide_cmd640_pci_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
}
@@ -177,7 +177,7 @@ machine_at_excaliburpci_init(const machine_t *model)
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ide_cmd640_pci_legacy_only_device);
@@ -245,7 +245,7 @@ machine_at_dellxp60_init(const machine_t *model)
device_add(&i430lx_device);
device_add(&kbc_ps2_phoenix_device);
device_add(&sio_zb_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -276,7 +276,7 @@ machine_at_opti560l_init(const machine_t *model)
device_add(&i430lx_device);
device_add(&kbc_ps2_phoenix_device);
device_add(&sio_zb_device);
device_add(&i82091aa_device);
device_add_params(&i82091aa_device, (void *) I82091AA_022);
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -308,7 +308,7 @@ machine_at_ambradp60_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_ps2_phoenix_device);
device_add(&sio_zb_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&intel_flash_bxt_ami_device);
device_add(&i430lx_device);
@@ -341,7 +341,7 @@ machine_at_valuepointp60_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&kbc_ps2_ps1_pci_device);
device_add(&sio_device);
device_add(&fdc37c665_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&intel_flash_bxt_ami_device);
device_add(&i430lx_device);
@@ -441,7 +441,7 @@ machine_at_pb520r_init(const machine_t *model)
device_add(&kbc_ps2_pci_device);
device_add(&sio_zb_device);
device_add(&i82091aa_ide_device);
device_add_params(&i82091aa_device, (void *) (I82091AA_022 | I82091AA_IDE_PRI));
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -471,7 +471,7 @@ machine_at_m5pi_init(const machine_t *model)
device_add(&sio_zb_device);
device_add(&kbc_ps2_phoenix_device);
device_add(&ide_w83769f_pci_single_channel_device);
device_add(&fdc37c665_ide_sec_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -523,7 +523,7 @@ machine_at_excalibur_init(const machine_t *model)
device_add(&opti5x7_device);
device_add(&ide_opti611_vlb_device);
device_add(&fdc37c661_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C661);
device_add(&kbc_ps2_intel_ami_pci_device);
return ret;
@@ -583,7 +583,7 @@ machine_at_excaliburpci2_init(const machine_t *model)
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ide_cmd640_pci_legacy_only_device);

View File

@@ -109,7 +109,7 @@ machine_at_d842_init(const machine_t *model)
device_add(&kbc_ps2_pci_device);
device_add(&i430nx_device);
device_add(&sio_zb_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -202,7 +202,7 @@ machine_at_p54np4_init(const machine_t *model)
device_add(&i430nx_device);
device_add(&sio_zb_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&intel_flash_bxt_device);
return ret;
@@ -250,7 +250,7 @@ machine_at_tek932_init(const machine_t *model)
device_add(&i430nx_device);
device_add(&sio_zb_device);
device_add(&ide_vlb_device);
device_add(&fdc37c665_ide_pri_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI));
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -279,7 +279,7 @@ machine_at_acerv30_init(const machine_t *model)
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&kbc_ps2_acer_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&sst_flash_29ee010_device);
@@ -310,7 +310,7 @@ machine_at_apollo_init(const machine_t *model)
device_add(&kbc_ps2_ami_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&pc87332_398_device);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_398));
device_add(&intel_flash_bxt_device);
return ret;
@@ -346,7 +346,7 @@ machine_at_optiplexgxl_init(const machine_t *model)
device_add(&kbc_ps2_phoenix_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&pc87332_device);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_02E));
device_add(&dell_jumper_device);
device_add(&intel_flash_bxt_device);
@@ -437,7 +437,7 @@ machine_at_powermatev_init(const machine_t *model)
device_add(&kbc_ps2_ami_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -466,7 +466,7 @@ machine_at_hawk_init(const machine_t *model)
device_add(&kbc_ps2_tg_ami_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -497,7 +497,7 @@ machine_at_pt2000_init(const machine_t *model)
device_add(&kbc_ps2_holtek_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&pc87332_398_device);
device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_398));
device_add(&intel_flash_bxt_device);
return ret;
@@ -579,7 +579,7 @@ machine_at_ncselp90_init(const machine_t *model)
device_add(&sst_flash_29ee010_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&ide_opti611_vlb_device);
device_add(&fdc37c665_ide_sec_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&ide_vlb_2ch_device);
return ret;
@@ -626,7 +626,7 @@ machine_at_sq588_init(const machine_t *model)
device_add(&sis_85c50x_device);
device_add(&ide_cmd640_pci_single_channel_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_ide_device);
device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -655,7 +655,7 @@ machine_at_p54sps_init(const machine_t *model)
device_add(&sis_85c50x_device);
device_add(&ide_pci_2ch_device);
device_add(&kbc_at_ami_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -686,7 +686,7 @@ machine_at_ms5109_init(const machine_t *model)
device_add(&sis_550x_85c503_device);
device_add(&ide_w83769f_pci_device);
device_add(&kbc_ps2_ami_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -720,7 +720,7 @@ machine_at_torino_init(const machine_t *model)
device_add(&sis_550x_85c503_device);
device_add(&ide_um8673f_device);
device_add(&kbc_ps2_tg_ami_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_ami_device);
return ret;
@@ -752,7 +752,7 @@ machine_at_hot539_init(const machine_t *model)
device_add(&umc_8886af_device);
device_add(&sst_flash_29ee010_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&um8663af_device);
device_add_params(&um866x_device, (void *) UM8663AF);
return ret;
}

View File

@@ -112,7 +112,7 @@ machine_at_ap5vm_init(const machine_t *model)
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&ncr53c810_onboard_pci_device);
device_add(&intel_flash_bxt_device);
@@ -142,7 +142,7 @@ machine_at_p55t2p4_init(const machine_t *model)
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&intel_flash_bxt_device);
return ret;
@@ -384,6 +384,34 @@ machine_at_equium5200_init(const machine_t *model)
return ret;
}
int
machine_at_p55t2s_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p55t2s/s6y08t.rom",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add_params(&pc87306_device, (void *) PCX730X_AMI);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_pcv90_init(const machine_t *model)
{
@@ -458,7 +486,7 @@ machine_at_epc2102_init(const machine_t *model)
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_intel_ami_pci_device);
device_add(&i82091aa_device);
device_add_params(&i82091aa_device, (void *) I82091AA_022);
device_add(&sst_flash_39sf010_device);
return ret;
@@ -487,7 +515,7 @@ machine_at_p55tvp4_init(const machine_t *model)
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device); // It uses the AMIKEY KBC
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&intel_flash_bxt_device);
return ret;
@@ -514,8 +542,8 @@ machine_at_5ivg_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_pci_device);
device_add(&prime3c_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&gm82c803c_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -544,7 +572,7 @@ machine_at_8500tvxa_init(const machine_t *model)
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&sst_flash_29ee010_device);
return ret;
@@ -643,6 +671,35 @@ machine_at_dellhannibalp_init(const machine_t *model)
return ret;
}
int
machine_at_p5vxb_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;
}
int
machine_at_p55va_init(const machine_t *model)
{
@@ -790,7 +847,7 @@ machine_at_mb520n_init(const machine_t *model)
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -819,7 +876,7 @@ machine_at_i430vx_init(const machine_t *model)
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_pci_device);
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -920,8 +977,7 @@ machine_at_nupro592_init(const machine_t *model)
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977ef_device);
device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
device_add(&w83781d_device); /* fans: CPU1, unused, unused; temperatures: System, CPU1, unused */
@@ -958,7 +1014,7 @@ machine_at_tx97_init(const machine_t *model)
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877tf_acorp_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */
@@ -1073,8 +1129,7 @@ machine_at_ym430tx_init(const machine_t *model)
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83977tf_device);
device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
@@ -1104,7 +1159,7 @@ machine_at_mb540n_init(const machine_t *model)
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_pci_device);
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
@@ -1135,7 +1190,7 @@ machine_at_56a5_init(const machine_t *model)
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
@@ -1164,8 +1219,8 @@ machine_at_p5mms98_init(const machine_t *model)
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83977tf_device);
/* This actually has the Winbond W83967AF, for which I can not find any datasheet at all. */
device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI | W83977_NO_NVR));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */
@@ -1270,7 +1325,7 @@ machine_at_ficva502_init(const machine_t *model)
device_add(&via_vpx_device);
device_add(&via_vt82c586b_device);
device_add(&kbc_ps2_pci_device);
device_add(&fdc37c669_370_device);
device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
@@ -1302,7 +1357,7 @@ machine_at_ficpa2012_init(const machine_t *model)
device_add(&via_vp3_device);
device_add(&via_vt82c586b_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
@@ -1334,7 +1389,7 @@ machine_at_via809ds_init(const machine_t *model)
device_add(&via_vp3_device);
device_add(&via_vt82c586b_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
@@ -1364,7 +1419,7 @@ machine_at_r534f_init(const machine_t *model)
device_add(&sis_5571_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1393,7 +1448,7 @@ machine_at_ms5146_init(const machine_t *model)
device_add(&sis_5571_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1422,7 +1477,7 @@ machine_at_cb52xsi_init(const machine_t *model)
device_add(&sis_5571_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_370_device);
device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370);
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1451,7 +1506,7 @@ machine_at_sp97xv_init(const machine_t *model)
pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */
device_add(&sis_5581_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1478,7 +1533,7 @@ machine_at_sq578_init(const machine_t *model)
pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&sis_5581_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1506,7 +1561,7 @@ machine_at_ms5172_init(const machine_t *model)
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&sis_5591_1997_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;

View File

@@ -127,7 +127,7 @@ machine_at_p54tp4xe_common_init(const machine_t *model)
device_add(&kbc_ps2_ami_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
}
@@ -186,7 +186,7 @@ machine_at_exp8551_init(const machine_t *model)
device_add(&kbc_ps2_ami_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -389,7 +389,7 @@ machine_at_ms5119_init(const machine_t *model)
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -484,7 +484,7 @@ machine_at_mb500n_init(const machine_t *model)
device_add(&kbc_ps2_pci_device);
device_add(&i430fx_device);
device_add(&piix_no_mirq_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -514,7 +514,7 @@ machine_at_fmb_init(const machine_t *model)
device_add(&i430fx_device);
device_add(&piix_no_mirq_device);
device_add(&kbc_at_ami_device);
device_add(&w83787f_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89));
device_add(&intel_flash_bxt_device);
return ret;
@@ -574,7 +574,7 @@ machine_at_ap53_init(const machine_t *model)
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -603,54 +603,12 @@ machine_at_8500tuc_init(const machine_t *model)
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_d943_init(const machine_t *model)
{
int ret = 0;
const char* fn;
/* No ROMs available */
if (!device_available(model->device))
return ret;
device_context(model->device);
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_pci_device);
device_add(&fdc37c665_device);
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_EDO, 0x7, 256);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
if (sound_card_current[0] == SOUND_INTERNAL)
machine_snd = device_add(machine_get_snd_device(machine));
return ret;
}
static const device_config_t d943_config[] = {
// clang-format off
{
@@ -677,8 +635,6 @@ static const device_config_t d943_config[] = {
// clang-format on
};
const device_t d943_device = {
.name = "Siemens-Nixdorf D943",
.internal_name = "d943_device",
@@ -694,58 +650,43 @@ const device_t d943_device = {
};
int
machine_at_p55t2s_init(const machine_t *model)
machine_at_d943_init(const machine_t *model)
{
int ret;
int ret = 0;
const char* fn;
ret = bios_load_linear("roms/machines/p55t2s/s6y08t.rom",
0x000e0000, 131072, 0);
if (bios_only || !ret)
/* No ROMs available */
if (!device_available(model->device))
return ret;
device_context(model->device);
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add_params(&pc87306_device, (void *) PCX730X_AMI);
device_add(&kbc_ps2_pci_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_EDO, 0x7, 256);
return ret;
}
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
int
machine_at_p5vxb_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877f_device);
device_add(&sst_flash_29ee010_device);
if (sound_card_current[0] == SOUND_INTERNAL)
machine_snd = device_add(machine_get_snd_device(machine));
return ret;
}
@@ -851,7 +792,7 @@ machine_at_ap5s_init(const machine_t *model)
device_add(&sis_5511_device);
device_add(&kbc_ps2_ami_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&sst_flash_29ee010_device);
return ret;
@@ -880,7 +821,7 @@ machine_at_ms5124_init(const machine_t *model)
device_add(&sis_5511_device);
device_add(&kbc_ps2_ami_device);
device_add(&w83787f_88h_device);
device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_88));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -909,7 +850,7 @@ machine_at_amis727_init(const machine_t *model)
device_add(&sis_5511_device);
device_add(&kbc_ps2_intel_ami_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -1014,7 +955,7 @@ machine_at_5sbm2_init(const machine_t *model)
device_add(&kbc_at_ami_device);
device_add(&sis_550x_device);
device_add(&um8663af_device);
device_add_params(&um866x_device, (void *) UM8663AF);
device_add(&sst_flash_29ee010_device);
return ret;
@@ -1045,7 +986,7 @@ machine_at_pc140_6260_init(const machine_t *model)
device_add(&sis_5511_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&sst_flash_29ee010_device);
return ret;

View File

@@ -66,7 +66,7 @@ machine_at_ap61_init(const machine_t *model)
device_add(&sio_zb_device);
device_add(&ide_cmd646_device);
device_add(&kbc_ps2_acer_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&sst_flash_29ee010_device);
// device_add(&intel_flash_bxt_device);
@@ -101,7 +101,7 @@ machine_at_p6rp4_init(const machine_t *model)
device_add(&ide_cmd646_device);
/* Input port bit 2 must be 1 or CMOS Setup is disabled. */
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c665_device);
device_add_params(&fdc37c6xx_device, (void *) FDC37C665);
device_add(&intel_flash_bxt_device);
return ret;
@@ -130,7 +130,7 @@ machine_at_686nx_init(const machine_t *model)
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device); // Uses the AMIKEY keyboard controller
device_add(&um8669f_device);
device_add_params(&um8669f_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -159,7 +159,7 @@ machine_at_mb600n_init(const machine_t *model)
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -218,7 +218,7 @@ machine_at_lgibmx61_init(const machine_t *model)
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_device);
device_add(&w83877f_president_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_250));
device_add(&sst_flash_29ee010_device);
return ret;
@@ -393,7 +393,7 @@ machine_at_8600ttc_init(const machine_t *model)
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add_params(&fdc37c669_device, (void *) 0);
device_add(&intel_flash_bxt_device);
return ret;
@@ -443,7 +443,7 @@ machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridg
device_add(northbridge);
device_add(&piix3_ioapic_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877f_device);
device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0));
device_add(&sst_flash_29ee010_device);
device_add(&ioapic_device);
}

View File

@@ -232,7 +232,7 @@ machine_at_ax59pro_init(const machine_t *model)
device_add(&via_mvp3_device);
device_add(&via_vt82c586b_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_250));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -263,7 +263,7 @@ machine_at_mvp3_init(const machine_t *model)
device_add(&via_mvp3_device);
device_add(&via_vt82c586b_device);
device_add(&kbc_ps2_pci_device);
device_add(&w83877tf_acorp_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&sst_flash_39sf010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
@@ -365,7 +365,7 @@ machine_at_delhi3_init(const machine_t *model)
device_add(&via_mvp3_device);
device_add(&via_vt82c596a_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_250));
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
@@ -398,7 +398,7 @@ machine_at_5sg100_init(const machine_t *model)
pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0);
device_add(&sis_5591_1997_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&w83877tf_device);
device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0));
device_add(&sst_flash_29ee010_device);
return ret;

View File

@@ -168,6 +168,7 @@ ps2_isa_setup(int model, int cpu_type)
ps2->uart = device_add_inst(&ns16450_device, 1);
ps2->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_ext(ps2->lpt, 1);
lpt_port_remove(ps2->lpt);
lpt_port_setup(ps2->lpt, LPT_MDA_ADDR);

View File

@@ -1601,7 +1601,9 @@ machine_ps2_common_init(const machine_t *model)
nmi_mask = 0x80;
ps2.uart = device_add_inst(&ns16550_device, 1);
ps2.lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_ext(ps2.lpt, 1);
ps2.has_e0000_hole = 0;
}

View File

@@ -81,6 +81,7 @@ const machine_filter_t machine_types[] = {
{ "[1978] 8086", MACHINE_TYPE_8086 },
{ "[1982] 80286", MACHINE_TYPE_286 },
{ "[1988] i386SX", MACHINE_TYPE_386SX },
{ "[1988] ALi M6117", MACHINE_TYPE_M6117 },
{ "[1992] 486SLC", MACHINE_TYPE_486SLC },
{ "[1985] i386DX", MACHINE_TYPE_386DX },
{ "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 },
@@ -4158,6 +4159,47 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM AT KBC firmware. */
{
.name = "[SCAT] Samsung Deskmaster 286",
.internal_name = "deskmaster286",
.type = MACHINE_TYPE_286,
.chipset = MACHINE_CHIPSET_SCAT,
.init = machine_at_deskmaster286_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_286,
.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_PS2,
.flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */
.ram = {
.min = 512,
.max = 8192,
.step = 128
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[SCAT] Samsung SPC-4200P",
@@ -4281,47 +4323,6 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM AT KBC firmware. */
{
.name = "[SCAT] Samsung Deskmaster 286",
.internal_name = "deskmaster286",
.type = MACHINE_TYPE_286,
.chipset = MACHINE_CHIPSET_SCAT,
.init = machine_at_deskmaster286_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_286,
.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_PS2,
.flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */
.ram = {
.min = 512,
.max = 8192,
.step = 128
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[SCAT] Senor Science Co. SCAT-286-003",
.internal_name = "senorscat286",
@@ -4817,7 +4818,7 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
{
.name = "[ALi M1409] Acer 100T",
.internal_name = "acer100t",
.type = MACHINE_TYPE_386SX,
@@ -4858,88 +4859,6 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[ALi M6117] Acrosser PJ-A511M",
.internal_name = "pja511m",
.type = MACHINE_TYPE_386SX,
.chipset = MACHINE_CHIPSET_ALI_M6117,
.init = machine_at_pja511m_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_M6117,
.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_PS2,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
.max = 32768,
.step = 1024
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[ALi M6117] Protech ProX-1332",
.internal_name = "prox1332",
.type = MACHINE_TYPE_386SX,
.chipset = MACHINE_CHIPSET_ALI_M6117,
.init = machine_at_prox1332_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_M6117,
.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_PS2,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
.max = 32768,
.step = 1024
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has an AMI KBC firmware, the only photo of this is too low resolution
for me to read what's on the KBC chip, so I'm going to assume AMI 'F'
based on the other known HT18 AMI BIOS strings. */
@@ -5566,6 +5485,90 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* ALi M6117 machines */
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[ALi M6117] Acrosser PJ-A511M",
.internal_name = "pja511m",
.type = MACHINE_TYPE_M6117,
.chipset = MACHINE_CHIPSET_ALI_M6117,
.init = machine_at_pja511m_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_M6117,
.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_PS2,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
.max = 32768,
.step = 1024
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[ALi M6117] Protech ProX-1332",
.internal_name = "prox1332",
.type = MACHINE_TYPE_M6117,
.chipset = MACHINE_CHIPSET_ALI_M6117,
.init = machine_at_prox1332_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_M6117,
.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_PS2,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
.max = 32768,
.step = 1024
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.kbd_device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* 486SLC machines */
/* 486SLC machines with just the ISA slot */
@@ -16496,10 +16499,9 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
/* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{
{
.name = "[i440BX] ABIT BX6",
.internal_name = "bx6",
.type = MACHINE_TYPE_SLOT1,
@@ -16539,7 +16541,8 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{
.name = "[i440BX] ABIT BF6",
.internal_name = "bf6",

View File

@@ -16,29 +16,28 @@
#
add_library(sio OBJECT
sio_82091aa.c
sio_acc3221.c
sio_ali5123.c
sio_gm82c803ab.c
sio_gm82c803c.c
sio_f82c606.c
sio_f82c710.c
sio_82091aa.c
sio_fdc37c6xx.c
sio_fdc37c67x.c
sio_fdc37c669.c
sio_fdc37c93x.c
sio_fdc37m60x.c
sio_it86x1f.c
sio_pc87310.c
sio_pc873xx.c
sio_pc87306.c
sio_pc87307.c
sio_pc87309.c
sio_pc87310.c
sio_pc87311.c
sio_pc87332.c
sio_prime3b.c
sio_prime3c.c
sio_w83787f.c
sio_w83877f.c
sio_w83977f.c
sio_um8663f.c
sio_w837x7.c
sio_w83877.c
sio_w83977.c
sio_um866x.c
sio_um8669f.c
sio_vl82c113.c
sio_vt82c686.c

View File

@@ -57,9 +57,34 @@ static void
lpt_handler(i82091aa_t *dev)
{
uint16_t lpt_port = LPT1_ADDR;
int enable = (dev->regs[0x20] & 0x01);
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, (dev->regs[0x20] & 0x80) ? 15 : 8);
switch (dev->regs[0x20] & 0x60) {
default:
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x20:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 1);
break;
case 0x40:
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x60:
enable = 0;
break;
}
switch ((dev->regs[0x20] >> 1) & 0x03) {
case 0x00:
lpt_port = LPT1_ADDR;
@@ -78,7 +103,7 @@ lpt_handler(i82091aa_t *dev)
break;
}
if ((dev->regs[0x20] & 0x01) && lpt_port)
if (enable && lpt_port)
lpt_port_setup(dev->lpt, lpt_port);
lpt_port_irq(dev->lpt, (dev->regs[0x20] & 0x08) ? LPT1_IRQ : LPT2_IRQ);
@@ -176,7 +201,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x20:
*reg = (val & 0xef);
if (valxor & 0x07)
if (valxor & 0xe8)
lpt_handler(dev);
break;
case 0x21:
@@ -218,6 +243,8 @@ i82091aa_read(uint16_t port, void *priv)
if (index)
ret = dev->cur_reg;
else if (dev->cur_reg == 0x20)
ret = dev->regs[dev->cur_reg] | lpt_read_ecp_mode(dev->lpt);
else if (dev->cur_reg < 0x51)
ret = dev->regs[dev->cur_reg];
@@ -266,6 +293,7 @@ i82091aa_init(const device_t *info)
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_cnfga_readout(dev->lpt, 0x90);
dev->has_ide = (info->local >> 9) & 0x03;
@@ -288,63 +316,7 @@ const device_t i82091aa_device = {
.name = "Intel 82091AA Super I/O",
.internal_name = "i82091aa",
.flags = 0,
.local = 0x40,
.init = i82091aa_init,
.close = i82091aa_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t i82091aa_26e_device = {
.name = "Intel 82091AA Super I/O (Port 26Eh)",
.internal_name = "i82091aa_26e",
.flags = 0,
.local = 0x140,
.init = i82091aa_init,
.close = i82091aa_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t i82091aa_398_device = {
.name = "Intel 82091AA Super I/O (Port 398h)",
.internal_name = "i82091aa_398",
.flags = 0,
.local = 0x148,
.init = i82091aa_init,
.close = i82091aa_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t i82091aa_ide_pri_device = {
.name = "Intel 82091AA Super I/O (With Primary IDE)",
.internal_name = "i82091aa_ide",
.flags = 0,
.local = 0x240,
.init = i82091aa_init,
.close = i82091aa_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t i82091aa_ide_device = {
.name = "Intel 82091AA Super I/O (With IDE)",
.internal_name = "i82091aa_ide",
.flags = 0,
.local = 0x440,
.local = 0,
.init = i82091aa_init,
.close = i82091aa_close,
.reset = NULL,

View File

@@ -37,7 +37,10 @@
typedef struct fdc37c669_t {
uint8_t id;
uint8_t tries;
uint8_t regs[42];
uint8_t has_ide;
uint8_t dma_map[4];
uint8_t irq_map[10];
uint8_t regs[256];
int locked;
int rw_locked;
int cur_reg;
@@ -70,6 +73,7 @@ static void
fdc37c669_fdc_handler(fdc37c669_t *dev)
{
fdc_remove(dev->fdc);
if (dev->regs[0x20] & 0xc0)
fdc_set_base(dev->fdc, ((uint16_t) dev->regs[0x20]) << 2);
}
@@ -82,6 +86,7 @@ fdc37c669_uart_handler(fdc37c669_t *dev, uint8_t uart)
uint8_t uart_shift = ((uart ^ 1) << 2);
serial_remove(dev->uart[uart]);
if ((dev->regs[0x02] & pwrdn_mask) && (dev->regs[uart_reg] & 0xc0))
serial_setup(dev->uart[0], ((uint16_t) dev->regs[0x24]) << 2,
(dev->regs[0x28] >> uart_shift) & 0x0f);
@@ -107,10 +112,41 @@ fdc37c669_lpt_handler(fdc37c669_t *dev)
uint8_t mask = ~(dev->regs[0x04] & 0x01);
lpt_port_remove(dev->lpt);
if (dev->regs[0x01] & 0x08) {
lpt_set_ext(dev->lpt, 0);
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
} else {
lpt_set_ext(dev->lpt, 1);
lpt_set_epp(dev->lpt, dev->regs[0x04] & 0x01);
lpt_set_ecp(dev->lpt, dev->regs[0x04] & 0x02);
}
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f);
if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40))
lpt_port_setup(dev->lpt, ((uint16_t) (dev->regs[0x23] & mask)) << 2);
}
static void
ide_handler(fdc37c669_t *dev)
{
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_set_base_addr(ide_id, 0, ((uint16_t) (dev->regs[0x21] & 0xfc)) << 2);
ide_set_base_addr(ide_id, 1, (((uint16_t) (dev->regs[0x22] & 0xfc)) << 2) | 0x0006);
if ((dev->regs[0x00] & 0x03) == 0x02)
ide_handlers(ide_id, 1);
}
}
static void
fdc37c669_write(uint16_t port, uint8_t val, void *priv)
{
@@ -139,12 +175,14 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv)
} else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) switch (dev->cur_reg) {
case 0x00:
dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x74) | (val & 0x8b);
if (!dev->id && (valxor & 8))
if (!dev->id && (valxor & 0x08))
fdc_set_power_down(dev->fdc, !(val & 0x08));
if (!dev->id && (valxor & 0x03))
ide_handler(dev);
break;
case 0x01:
dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x73) | (val & 0x8c);
if (valxor & 0x04)
if (valxor & 0x0c)
fdc37c669_lpt_handler(dev);
if (valxor & 0x80)
dev->rw_locked = !(val & 0x80);
@@ -158,6 +196,17 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x03:
dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x08) | (val & 0xf7);
if ((valxor & 0x60) && (dev->fdc != NULL)) {
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
switch (val & 0x0c) {
case 0x00:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2);
break;
case 0x20:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
}
if (!dev->id && (valxor & 0x02))
fdc_update_enh_mode(dev->fdc, !!(val & 0x02));
break;
@@ -191,6 +240,8 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x0a:
dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xf0) | (val & 0x0f);
if (valxor & 0x0f)
fdc37c669_lpt_handler(dev);
break;
case 0x0b:
dev->regs[dev->cur_reg] = val;
@@ -223,9 +274,13 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x21:
dev->regs[dev->cur_reg] = val & 0xfc;
if (!dev->id && (valxor & 0xfc))
ide_handler(dev);
break;
case 0x22:
dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x03) | (val & 0xfc);
if (!dev->id && (valxor & 0xfc))
ide_handler(dev);
break;
case 0x23:
dev->regs[dev->cur_reg] = val;
@@ -246,6 +301,8 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv)
dev->regs[dev->cur_reg] = val;
if (valxor & 0xf0)
fdc_set_dma_ch(dev->fdc, val >> 4);
if (valxor & 0x0f)
lpt_port_dma(dev->lpt, val & 0x0f);
break;
case 0x27:
dev->regs[dev->cur_reg] = val;
@@ -306,9 +363,13 @@ fdc37c669_reset(void *priv)
dev->regs[0x21] = 0x3c;
dev->regs[0x22] = 0x3d;
if (dev->id != 1) {
if (!dev->id) {
fdc_reset(dev->fdc);
fdc37c669_fdc_handler(dev);
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
ide_handler(dev);
}
fdc37c669_uart_handler(dev, 0);
@@ -340,17 +401,34 @@ fdc37c669_init(const device_t *info)
dev->id = next_id;
if (next_id != 1)
dev->fdc = device_add(&fdc_at_smc_device);
if (next_id != 1) {
dev->fdc = device_add(&fdc_at_smc_device);
dev->has_ide = (info->local >> 8) & 0xff;
}
dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1);
dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2);
dev->lpt = device_add_inst(&lpt_port_device, next_id + 1);
io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR),
io_sethandler((info->local & FDC37C6XX_370) ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR),
0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev);
dev->dma_map[0] = 4;
for (int i = 1; i < 4; i++)
dev->dma_map[i] = i;
memset(dev->irq_map, 0xff, 16);
dev->irq_map[0] = 0xff;
for (int i = 1; i < 7; i++)
dev->irq_map[i] = i;
dev->irq_map[1] = 5;
dev->irq_map[5] = 7;
dev->irq_map[7] = 0xff; /* Reserved. */
dev->irq_map[8] = 10;
dev->irq_map[9] = 9; /* This is used by the Acrosser PJ-A511M for IRQ 9. */
dev->irq_map[11] = 11; /* This is used by the Acrosser PJ-A511M for IRQ 11. */
fdc37c669_reset(dev);
next_id++;
@@ -371,17 +449,3 @@ const device_t fdc37c669_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c669_370_device = {
.name = "SMC FDC37C669 Super I/O (Port 370h)",
.internal_name = "fdc37c669_370",
.flags = 0,
.local = 1,
.init = fdc37c669_init,
.close = fdc37c669_close,
.reset = fdc37c669_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -437,7 +437,6 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv)
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
fdc_update_enh_mode(dev->fdc, val & 0x01);
}
if (valxor & 0x10)
fdc_set_swap(dev->fdc, (val & 0x10) >> 4);

View File

@@ -9,11 +9,9 @@
* Implementation of the SMC FDC37C663 and FDC37C665 Super
* I/O Chips.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2016-2025 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -113,8 +111,6 @@ lpt_handler(fdc37c6xx_t *dev)
uint16_t mask = 0xfffc;
uint8_t local_enable = 1;
uint8_t lpt_irq = LPT1_IRQ;
/* DMA is guesswork - what channel do boards actually use? */
uint8_t lpt_dma = 3;
uint8_t lpt_ext = !(dev->regs[1] & 0x08);
uint8_t lpt_mode = (dev->chip_id >= 0x65) ? (dev->regs[4] & 0x03) : 0x00;
@@ -140,9 +136,6 @@ lpt_handler(fdc37c6xx_t *dev)
if (lpt_irq > 15)
lpt_irq = 0xff;
if (lpt_dma >= 4)
lpt_dma = 0xff;
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f);
if (lpt_ext) switch (lpt_mode) {
@@ -192,19 +185,16 @@ fdc_handler(fdc37c6xx_t *dev)
static void
ide_handler(fdc37c6xx_t *dev)
{
/* TODO: Make an ide_disable(channel) and ide_enable(channel) so we can simplify this. */
if (dev->has_ide == 2) {
ide_sec_disable();
ide_set_base(1, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0);
ide_set_side(1, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6);
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_set_base_addr(ide_id, 0, (dev->regs[0x05] & 0x02) ? 0x0170 : 0x01f0);
ide_set_base_addr(ide_id, 1, (dev->regs[0x05] & 0x02) ? 0x0376 : 0x03f6);
if (dev->regs[0x00] & 0x01)
ide_sec_enable();
} else if (dev->has_ide == 1) {
ide_pri_disable();
ide_set_base(0, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0);
ide_set_side(0, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6);
if (dev->regs[0x00] & 0x01)
ide_pri_enable();
ide_handlers(ide_id, 1);
}
}
@@ -228,14 +218,14 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv)
dev->regs[dev->cur_reg] = val;
switch (dev->cur_reg) {
case 0:
case 0x00:
if (dev->has_ide && (valxor & 0x01))
ide_handler(dev);
if (valxor & 0x10)
fdc_handler(dev);
break;
case 1:
if (valxor & 3)
case 0x01:
if (valxor & 0x03)
lpt_handler(dev);
if (valxor & 0x60) {
set_com34_addr(dev);
@@ -243,23 +233,23 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv)
set_serial_addr(dev, 1);
}
break;
case 2:
if (valxor & 7)
case 0x02:
if (valxor & 0x07)
set_serial_addr(dev, 0);
if (valxor & 0x70)
set_serial_addr(dev, 1);
break;
case 3:
if (valxor & 2)
fdc_update_enh_mode(dev->fdc, (dev->regs[3] & 2) ? 1 : 0);
case 0x03:
if (valxor & 0x02)
fdc_update_enh_mode(dev->fdc, !!(dev->regs[0x03] & 0x02));
break;
case 4:
case 0x04:
if (valxor & 0x10)
set_serial_addr(dev, 0);
if (valxor & 0x20)
set_serial_addr(dev, 1);
break;
case 5:
case 0x05:
if (valxor & 0x01)
fdc_handler(dev);
if (dev->has_ide && (valxor & 0x02))
@@ -285,7 +275,7 @@ fdc37c6xx_read(uint16_t port, void *priv)
uint8_t ret = 0xff;
if (dev->tries == 2) {
if ((port == 0x3f1) && (dev->cur_reg <= dev->max_reg))
if ((port == 0x03f1) && (dev->cur_reg <= dev->max_reg))
ret = dev->regs[dev->cur_reg];
}
@@ -385,175 +375,23 @@ fdc37c6xx_init(const device_t *info)
dev->lpt = device_add_inst(&lpt_port_device, 1);
io_sethandler(FDC_PRIMARY_ADDR, 0x0002,
fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev);
if (info->local & FDC37C6XX_370)
io_sethandler(FDC_SECONDARY_ADDR, 0x0002,
fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev);
else
io_sethandler(FDC_PRIMARY_ADDR, 0x0002,
fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev);
fdc37c6xx_reset(dev);
return dev;
}
/* The three appear to differ only in the chip ID, if I
understood their datasheets correctly. */
const device_t fdc37c651_device = {
.name = "SMC FDC37C651 Super I/O",
.internal_name = "fdc37c651",
const device_t fdc37c6xx_device = {
.name = "SMC FDC37C6xx Super I/O",
.internal_name = "fdc37c6xx",
.flags = 0,
.local = 0x51,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c651_ide_device = {
.name = "SMC FDC37C651 Super I/O (With IDE)",
.internal_name = "fdc37c651_ide",
.flags = 0,
.local = 0x151,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c661_device = {
.name = "SMC FDC37C661 Super I/O",
.internal_name = "fdc37c661",
.flags = 0,
.local = 0x61,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c661_ide_device = {
.name = "SMC FDC37C661 Super I/O (With IDE)",
.internal_name = "fdc37c661_ide",
.flags = 0,
.local = 0x161,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c661_ide_sec_device = {
.name = "SMC FDC37C661 Super I/O (With Secondary IDE)",
.internal_name = "fdc37c661_ide_sec",
.flags = 0,
.local = 0x261,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c663_device = {
.name = "SMC FDC37C663 Super I/O",
.internal_name = "fdc37c663",
.flags = 0,
.local = 0x63,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c663_ide_device = {
.name = "SMC FDC37C663 Super I/O (With IDE)",
.internal_name = "fdc37c663_ide",
.flags = 0,
.local = 0x163,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c665_device = {
.name = "SMC FDC37C665 Super I/O",
.internal_name = "fdc37c665",
.flags = 0,
.local = 0x65,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c665_ide_device = {
.name = "SMC FDC37C665 Super I/O (With IDE)",
.internal_name = "fdc37c665_ide",
.flags = 0,
.local = 0x265,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c665_ide_pri_device = {
.name = "SMC FDC37C665 Super I/O (With Primary IDE)",
.internal_name = "fdc37c665_ide_pri",
.flags = 0,
.local = 0x165,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c665_ide_sec_device = {
.name = "SMC FDC37C665 Super I/O (With Secondary IDE)",
.internal_name = "fdc37c665_ide_sec",
.flags = 0,
.local = 0x265,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc37c666_device = {
.name = "SMC FDC37C666 Super I/O",
.internal_name = "fdc37c666",
.flags = 0,
.local = 0x66,
.local = 0,
.init = fdc37c6xx_init,
.close = fdc37c6xx_close,
.reset = NULL,

View File

@@ -906,9 +906,11 @@ fdc37c93x_nvr_pri_handler(const fdc37c93x_t *dev)
if (dev->chip_id != 0x02)
local_enable &= ((dev->ld_regs[6][0xf0] & 0x90) != 0x80);
nvr_at_handler(0, 0x70, dev->nvr);
if (local_enable)
nvr_at_handler(1, 0x70, dev->nvr);
if (dev->has_nvr) {
nvr_at_handler(0, 0x70, dev->nvr);
if (local_enable)
nvr_at_handler(1, 0x70, dev->nvr);
}
}
static void
@@ -926,12 +928,12 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev)
dev->nvr_sec_base = make_port_sec(dev, 6) & 0xfffe;
if (dev->nvr_sec_base != old_base) {
if ((old_base > 0x0000) && (old_base <= 0x0ffe))
if (dev->has_nvr && (old_base > 0x0000) && (old_base <= 0x0ffe))
nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr);
/* Datasheet erratum: First it says minimum address is 0x0100, but later implies that it's 0x0000
and that default is 0x0070, same as (unrelocatable) primary NVR. */
if ((dev->nvr_sec_base > 0x0000) && (dev->nvr_sec_base <= 0x0ffe))
if (dev->has_nvr && (dev->nvr_sec_base > 0x0000) && (dev->nvr_sec_base <= 0x0ffe))
nvr_at_sec_handler(1, dev->nvr_sec_base, dev->nvr);
}
}
@@ -1181,7 +1183,6 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
fdc_update_enh_mode(dev->fdc, val & 0x01);
}
if (valxor & 0x10)
fdc_set_swap(dev->fdc, (val & 0x10) >> 4);
@@ -1365,7 +1366,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
else
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x8f;
if (valxor) {
if (dev->has_nvr && valxor) {
nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr);
nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr);
nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr);

View File

@@ -347,7 +347,6 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
fdc_update_enh_mode(dev->fdc, val & 0x01);
}
if (valxor & 0x10)
fdc_set_swap(dev->fdc, (val & 0x10) >> 4);

372
src/sio/sio_gm82c803ab.c Normal file
View File

@@ -0,0 +1,372 @@
/*
* 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.
*
* Implementation of the GoldStar GM82C803 A andB Super I/O
* Chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2025 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/pci.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
typedef struct gm82c803ab_t {
uint8_t type;
uint8_t tries;
uint8_t has_ide;
uint8_t regs[16];
int cur_reg;
int com3_addr;
int com4_addr;
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
} gm82c803ab_t;
#ifdef ENABLE_GM82C803AB_LOG
int gm82c803ab_do_log = ENABLE_GM82C803AB_LOG;
static void
gm82c803ab_log(const char *fmt, ...)
{
va_list ap;
if (gm82c803ab_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define gm82c803ab_log(fmt, ...)
#endif
static void
ide_handler(gm82c803ab_t *dev)
{
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_set_base_addr(ide_id, 0, (dev->regs[0xa1] & 0x80) ? 0x0170 : 0x01f0);
ide_set_base_addr(ide_id, 1, (dev->regs[0xa1] & 0x80) ? 0x0376 : 0x03f6);
if (dev->regs[0xa0] & 0x20)
ide_handlers(ide_id, 1);
}
}
static void
fdc_handler(gm82c803ab_t *dev)
{
fdc_remove(dev->fdc);
if (dev->regs[0xa0] & 0x10)
fdc_set_base(dev->fdc, (dev->regs[0xa1] & 0x40) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
}
static void
set_com34_addr(gm82c803ab_t *dev)
{
switch (dev->regs[0xa4] & 0xc0) {
case 0x00:
dev->com3_addr = COM3_ADDR;
dev->com4_addr = COM4_ADDR;
break;
case 0x40:
dev->com3_addr = 0x338;
dev->com4_addr = 0x238;
break;
case 0x80:
dev->com3_addr = COM3_ADDR;
dev->com4_addr = 0x2e0;
break;
case 0xc0:
dev->com3_addr = 0x220;
dev->com4_addr = 0x228;
break;
default:
break;
}
}
static void
set_serial_addr(gm82c803ab_t *dev, int port)
{
uint8_t shift = 2 + (port << 1);
double clock_src = 24000000.0 / 13.0;
if (dev->regs[0xa4] & (1 << (4 + port)))
clock_src = 24000000.0 / 12.0;
serial_remove(dev->uart[port]);
if (dev->regs[0xa0] & (0x04 << port)) {
switch ((dev->regs[0xa1] >> shift) & 0x03) {
case 0x00:
serial_setup(dev->uart[port], COM1_ADDR, COM1_IRQ);
break;
case 0x01:
serial_setup(dev->uart[port], COM2_ADDR, COM2_IRQ);
break;
case 0x02:
serial_setup(dev->uart[port], dev->com3_addr, COM3_IRQ);
break;
case 0x03:
serial_setup(dev->uart[port], dev->com4_addr, COM4_IRQ);
break;
default:
break;
}
}
serial_set_clock_src(dev->uart[port], clock_src);
}
static void
lpt_handler(gm82c803ab_t *dev)
{
uint16_t lpt_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t local_enable = 1;
uint8_t lpt_irq = LPT1_IRQ;
uint8_t lpt_mode = (dev->regs[0xa0] & 0x03);
switch (lpt_mode) {
default:
local_enable = 0;
break;
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x01:
if (dev->type == GM82C803B) {
lpt_set_epp(dev->lpt, !!(dev->regs[0xa5] & 0x20));
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
} else
local_enable = 0;
break;
case 0x02:
if (dev->type == GM82C803B) {
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, !!(dev->regs[0xa5] & 0x20));
lpt_set_ext(dev->lpt, 0);
} else
local_enable = 0;
break;
}
switch (dev->regs[0xa1] & 0x03) {
default:
lpt_port = LPT_MDA_ADDR;
lpt_irq = LPT_MDA_IRQ;
break;
case 0x00:
lpt_port = LPT1_ADDR;
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
break;
case 0x01:
lpt_port = LPT2_ADDR;
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
break;
}
if (lpt_irq > 15)
lpt_irq = 0xff;
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f);
if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask)))
lpt_port_setup(dev->lpt, lpt_port);
lpt_port_irq(dev->lpt, lpt_irq);
}
static void
gm82c803ab_write(uint16_t port, uint8_t val, void *priv)
{
gm82c803ab_t *dev = (gm82c803ab_t *) priv;
uint8_t valxor = 0;
if (dev->tries == 2) {
if (port == 0x0398) {
if (val == 0xcc)
dev->tries = 0;
else
dev->cur_reg = val;
} else {
if ((dev->cur_reg < 0xa0) || (dev->cur_reg > 0xa5))
return;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
switch (dev->cur_reg) {
default:
break;
case 0xa0: /* Function Selection Register (FSR) */
if (valxor & 0x20)
ide_handler(dev);
if (valxor & 0x10)
fdc_handler(dev);
if (valxor & 0x08)
set_serial_addr(dev, 1);
if (valxor & 0x04)
set_serial_addr(dev, 0);
if (valxor & 0x03)
lpt_handler(dev);
break;
case 0xa1: /* Address Selection Register (ASR) */
if (valxor & 0x80)
ide_handler(dev);
if (valxor & 0x40)
fdc_handler(dev);
if (valxor & 0x30)
set_serial_addr(dev, 1);
if (valxor & 0x0c)
set_serial_addr(dev, 0);
if (valxor & 0x03)
lpt_handler(dev);
break;
case 0xa4: /* Miscellaneous Function Register */
if (valxor & 0xc0) {
set_com34_addr(dev);
set_serial_addr(dev, 0);
set_serial_addr(dev, 1);
}
if (valxor & 0x20)
set_serial_addr(dev, 1);
if (valxor & 0x10)
set_serial_addr(dev, 0);
if (valxor & 0x01)
fdc_set_swap(dev->fdc, val & 0x01);
break;
case 0xa5: /* ECP Register */
if (valxor & 0x20)
lpt_handler(dev);
break;
}
}
} else if ((port == 0x0398) && (val == 0x33))
dev->tries++;
}
static uint8_t
gm82c803ab_read(uint16_t port, void *priv)
{
const gm82c803ab_t *dev = (gm82c803ab_t *) priv;
uint8_t ret = 0xff;
if (dev->tries == 2) {
if ((port == 0x0399) && (dev->cur_reg >= 0xa0) && (dev->cur_reg <= 0xa1))
ret = dev->regs[dev->cur_reg];
}
return ret;
}
static void
gm82c803ab_reset(gm82c803ab_t *dev)
{
dev->com3_addr = 0x338;
dev->com4_addr = 0x238;
serial_remove(dev->uart[0]);
serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ);
serial_remove(dev->uart[1]);
serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ);
lpt_port_remove(dev->lpt);
lpt_port_setup(dev->lpt, LPT1_ADDR);
fdc_reset(dev->fdc);
fdc_remove(dev->fdc);
dev->tries = 0;
memset(dev->regs, 0, 256);
dev->regs[0xa0] = 0xff;
set_serial_addr(dev, 0);
set_serial_addr(dev, 1);
lpt_handler(dev);
fdc_handler(dev);
if (dev->has_ide)
ide_handler(dev);
}
static void
gm82c803ab_close(void *priv)
{
gm82c803ab_t *dev = (gm82c803ab_t *) priv;
free(dev);
}
static void *
gm82c803ab_init(const device_t *info)
{
gm82c803ab_t *dev = (gm82c803ab_t *) calloc(1, sizeof(gm82c803ab_t));
dev->fdc = device_add(&fdc_at_smc_device);
dev->type = info->local & 0xff;
dev->has_ide = (info->local >> 8) & 0xff;
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
io_sethandler(0x0398, 0x0002,
gm82c803ab_read, NULL, NULL, gm82c803ab_write, NULL, NULL, dev);
gm82c803ab_reset(dev);
return dev;
}
const device_t gm82c803ab_device = {
.name = "Goldstar GMC82C803A/B",
.internal_name = "gm82c803ab",
.flags = 0,
.local = 0,
.init = gm82c803ab_init,
.close = gm82c803ab_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

382
src/sio/sio_gm82c803c.c Normal file
View File

@@ -0,0 +1,382 @@
/*
* 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.
*
* Implementation of the GoldStar GM82C803C Super I/O Chip.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2025 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/pci.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
typedef struct gm82c803c_t {
uint8_t tries;
uint8_t has_ide;
uint8_t dma_map[4];
uint8_t irq_map[10];
uint8_t regs[16];
int cur_reg;
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
} gm82c803c_t;
#ifdef ENABLE_GM82C803C_LOG
int gm82c803c_do_log = ENABLE_GM82C803C_LOG;
static void
gm82c803c_log(const char *fmt, ...)
{
va_list ap;
if (gm82c803c_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define gm82c803c_log(fmt, ...)
#endif
static void
ide_handler(gm82c803c_t *dev)
{
uint16_t ide_port = 0x0000;
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_port = (dev->regs[0xc4] << 2) & 0xfff0;
ide_set_base_addr(ide_id, 0, ide_port);
ide_port = ((dev->regs[0xc5] << 2) & 0xfff0) | 0x0006;
ide_set_base_addr(ide_id, 1, ide_port);
if (dev->regs[0xc2] & 0x20)
ide_handlers(ide_id, 1);
}
}
static void
fdc_handler(gm82c803c_t *dev)
{
uint16_t fdc_port = 0x0000;
uint8_t fdc_irq = 6;
uint8_t fdc_dma = 2;
fdc_port = (dev->regs[0xc3] << 2) & 0xfff0;
fdc_irq = dev->irq_map[dev->regs[0xca] >> 4];
fdc_dma = dev->dma_map[(dev->regs[0xc9] >> 4) & 0x03];
fdc_set_irq(dev->fdc, fdc_irq);
fdc_set_dma_ch(dev->fdc, fdc_dma);
fdc_remove(dev->fdc);
if (dev->regs[0xc2] & 0x10)
fdc_set_base(dev->fdc, fdc_port);
}
static void
set_serial_addr(gm82c803c_t *dev, int port)
{
uint16_t serial_port = 0x0000;
uint8_t serial_irq = COM1_IRQ;
double clock_src = 24000000.0 / 13.0;
if (dev->regs[0xce] & (1 << (6 + port)))
clock_src = 24000000.0 / 3.0;
else if (dev->regs[0xd1] & (1 << port))
clock_src = 24000000.0 / 12.0;
serial_remove(dev->uart[port]);
if (dev->regs[0xc2] & (0x04 << port)) {
serial_port = (dev->regs[0xc7 + port] << 2) & 0xfff8;
serial_irq = dev->irq_map[dev->regs[0xcb] >> ((port ^ 1) * 0xff)];
serial_setup(dev->uart[port], serial_port, serial_irq);
}
serial_set_clock_src(dev->uart[port], clock_src);
}
static void
lpt_handler(gm82c803c_t *dev)
{
uint16_t lpt_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t local_enable = 1;
uint8_t lpt_irq = LPT1_IRQ;
uint8_t lpt_dma = 3;
uint8_t lpt_mode = (dev->regs[0xc2] & 0x03);
switch (lpt_mode) {
default:
local_enable = 0;
break;
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x01:
lpt_set_epp(dev->lpt, !!(dev->regs[0xd0] & 0x20));
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x02:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, !!(dev->regs[0xd0] & 0x20));
lpt_set_ext(dev->lpt, 0);
break;
}
lpt_port = ((dev->regs[0xc6] << 2) & 0xfffc) & mask;
lpt_irq = dev->irq_map[dev->regs[0xca] & 0x0f];
lpt_dma = dev->dma_map[dev->regs[0xc9] & 0x03];
if (lpt_irq > 15)
lpt_irq = 0xff;
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f);
if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask)))
lpt_port_setup(dev->lpt, lpt_port);
lpt_port_irq(dev->lpt, lpt_irq);
lpt_port_dma(dev->lpt, lpt_dma);
}
static void
gm82c803c_write(uint16_t port, uint8_t val, void *priv)
{
gm82c803c_t *dev = (gm82c803c_t *) priv;
uint8_t valxor = 0;
if (dev->tries == 2) {
if (port == 0x0398) {
if (val == 0xcc)
dev->tries = 0;
else
dev->cur_reg = val;
} else {
if ((dev->cur_reg < 0xc2) || (dev->cur_reg > 0xd8))
return;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
switch (dev->cur_reg) {
default:
break;
case 0xc2:
if (valxor & 0x20)
ide_handler(dev);
if (valxor & 0x10)
fdc_handler(dev);
if (valxor & 0x08)
set_serial_addr(dev, 1);
if (valxor & 0x04)
set_serial_addr(dev, 0);
if (valxor & 0x03)
lpt_handler(dev);
break;
case 0xc3:
if (valxor)
fdc_handler(dev);
break;
case 0xc4: case 0xc5:
if (valxor)
ide_handler(dev);
break;
case 0xc6:
if (valxor)
lpt_handler(dev);
break;
case 0xc7:
if (valxor)
set_serial_addr(dev, 0);
case 0xc8:
if (valxor)
set_serial_addr(dev, 1);
case 0xc9:
if (valxor & 0xf0)
fdc_handler(dev);
if (valxor & 0x0f)
lpt_handler(dev);
break;
case 0xca:
if (valxor & 0xf0)
fdc_handler(dev);
if (valxor & 0x0f)
lpt_handler(dev);
break;
case 0xcb:
if (valxor & 0xf0)
set_serial_addr(dev, 0);
if (valxor & 0x0f)
set_serial_addr(dev, 1);
break;
case 0xce:
if (valxor & 0x80)
set_serial_addr(dev, 1);
if (valxor & 0x40)
set_serial_addr(dev, 0);
break;
case 0xd0:
if (valxor & 0x20)
lpt_handler(dev);
break;
case 0xd1:
if (valxor & 0x02)
set_serial_addr(dev, 1);
if (valxor & 0x01)
set_serial_addr(dev, 0);
break;
if (valxor & 0x20)
ide_handler(dev);
if (valxor & 0x08)
set_serial_addr(dev, 1);
if (valxor & 0x04)
set_serial_addr(dev, 0);
break;
}
}
} else if ((port == 0x0398) && (val == 0x33))
dev->tries++;
}
static uint8_t
gm82c803c_read(uint16_t port, void *priv)
{
const gm82c803c_t *dev = (gm82c803c_t *) priv;
uint8_t ret = 0xff;
if (dev->tries == 2) {
if ((port == 0x0399) && (dev->cur_reg >= 0xa0) && (dev->cur_reg <= 0xa1))
ret = dev->regs[dev->cur_reg];
}
return ret;
}
static void
gm82c803c_reset(gm82c803c_t *dev)
{
serial_remove(dev->uart[0]);
serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ);
serial_remove(dev->uart[1]);
serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ);
lpt_port_remove(dev->lpt);
lpt_port_setup(dev->lpt, LPT1_ADDR);
fdc_reset(dev->fdc);
fdc_remove(dev->fdc);
dev->tries = 0;
memset(dev->regs, 0, 256);
dev->regs[0xc0] = 0x3c;
dev->regs[0xc2] = 0x03;
dev->regs[0xc3] = 0x3c;
dev->regs[0xc4] = 0x3c;
dev->regs[0xc5] = 0x3d;
dev->regs[0xd5] = 0x3c;
set_serial_addr(dev, 0);
set_serial_addr(dev, 1);
lpt_handler(dev);
fdc_handler(dev);
if (dev->has_ide)
ide_handler(dev);
}
static void
gm82c803c_close(void *priv)
{
gm82c803c_t *dev = (gm82c803c_t *) priv;
free(dev);
}
static void *
gm82c803c_init(const device_t *info)
{
gm82c803c_t *dev = (gm82c803c_t *) calloc(1, sizeof(gm82c803c_t));
dev->fdc = device_add(&fdc_at_smc_device);
dev->has_ide = (info->local >> 8) & 0xff;
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
io_sethandler(0x0398, 0x0002,
gm82c803c_read, NULL, NULL, gm82c803c_write, NULL, NULL, dev);
dev->dma_map[0] = 4;
for (int i = 1; i < 4; i++)
dev->dma_map[i] = i;
memset(dev->irq_map, 0xff, 16);
dev->irq_map[0] = 0xff;
for (int i = 1; i < 7; i++)
dev->irq_map[i] = i;
dev->irq_map[1] = 5;
dev->irq_map[5] = 7;
dev->irq_map[7] = 0xff; /* Reserved. */
dev->irq_map[8] = 10;
gm82c803c_reset(dev);
return dev;
}
const device_t gm82c803c_device = {
.name = "Goldstar GM82C803C",
.internal_name = "gm82c803c",
.flags = 0,
.local = 0,
.init = gm82c803c_init,
.close = gm82c803c_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -296,6 +296,9 @@ it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri
if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) {
it86x1f_log("IT86x1F: LPT enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq);
lpt_port_setup(dev->lpt, config->io[0].base);
lpt_port_irq(dev->lpt, config->irq[0].irq);
lpt_port_dma(dev->lpt, (config->dma[0].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[0].dma);
} else {
it86x1f_log("IT86x1F: LPT disabled\n");
}
@@ -466,6 +469,13 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv)
case 0x0f0:
dev->ldn_regs[ld][reg & 0x0f] = val & 0x0f;
fdc_set_swwp(dev->fdc, !!(val & 0x01));
if (val & 0x02) {
for (int i = 0; i < 4; i++)
fdc_update_drvrate(dev->fdc, i, 1);
} else {
for (int i = 0; i < 4; i++)
fdc_update_drvrate(dev->fdc, i, 0);
}
fdc_set_swap(dev->fdc, !!(val & 0x04));
break;
@@ -484,6 +494,8 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv)
case 0x3f0:
dev->ldn_regs[ld][reg & 0x0f] = val & 0x07;
lpt_set_epp(dev->lpt, val & 0x01);
lpt_set_ecp(dev->lpt, val & 0x02);
break;
case 0x4f0:
@@ -772,6 +784,9 @@ it86x1f_reset(it86x1f_t *dev)
{
it86x1f_log("IT86x1F: reset()\n");
for (int i = 0; i < 4; i++)
fdc_update_drvrate(dev->fdc, i, 0);
fdc_reset(dev->fdc);
serial_remove(dev->uart[0]);
@@ -780,6 +795,9 @@ it86x1f_reset(it86x1f_t *dev)
lpt_port_remove(dev->lpt);
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
isapnp_enable_card(dev->pnp_card, ISAPNP_CARD_DISABLE);
dev->locked = 1;
@@ -824,6 +842,7 @@ it86x1f_init(UNUSED(const device_t *info))
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_ext(dev->lpt, 1);
dev->gameport = gameport_add(&gameport_sio_device);

View File

@@ -125,13 +125,9 @@ lpt_handler(pc87306_t *dev)
uint16_t lptba;
uint16_t lpt_port = LPT1_ADDR;
uint8_t lpt_irq = LPT2_IRQ;
uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1);
lpt_port_remove(dev->lpt);
if (lpt_dma == 0x00)
lpt_dma = 0xff;
temp = dev->regs[0x01] & 3;
lptba = ((uint16_t) dev->regs[0x19]) << 2;
@@ -172,8 +168,6 @@ lpt_handler(pc87306_t *dev)
lpt_port_setup(dev->lpt, lpt_port);
lpt_port_irq(dev->lpt, lpt_irq);
lpt_port_dma(dev->lpt, lpt_dma);
}
static void
@@ -374,6 +368,8 @@ pc87306_write(uint16_t port, uint8_t val, void *priv)
fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0);
fdc_update_densel_polarity(dev->fdc, (val & 0x40) ? 1 : 0);
}
if (valxor & 0x20)
lpt_set_cnfga_readout(dev->lpt, (val & 0x20) ? 0x18 : 0x10);
break;
case 0x0f:
if (valxor)
@@ -470,6 +466,7 @@ pc87306_reset_common(void *priv)
0 = 360 rpm @ 500 kbps for 3.5"
1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5"
*/
lpt_set_cnfga_readout(dev->lpt, 0x10);
lpt_port_remove(dev->lpt);
lpt_handler(dev);
serial_remove(dev->uart[0x00]);
@@ -517,6 +514,7 @@ pc87306_init(UNUSED(const device_t *info))
dev->uart[0x01] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_cnfga_readout(dev->lpt, 0x10);
dev->nvr = device_add(&at_mb_nvr_device);

View File

@@ -267,6 +267,7 @@ fdc_handler(pc87307_t *dev)
uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) &&
(dev->pm[0x00] & 0x08);
uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f);
uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f);
uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) |
dev->ld_regs[LD_FDC][0x31]) & 0xfff8;
@@ -274,6 +275,7 @@ fdc_handler(pc87307_t *dev)
pc87307_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq);
fdc_set_base(dev->fdc, addr);
fdc_set_irq(dev->fdc, irq);
fdc_set_dma_ch(dev->fdc, dma);
}
}
@@ -283,16 +285,61 @@ lpt_handler(pc87307_t *dev)
uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) &&
(dev->pm[0x00] & 0x10);
uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f);
uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f);
uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) |
dev->ld_regs[LD_LPT][0x31];
uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7);
uint16_t mask = 0xfffc;
if (active && (addr <= 0xfffc)) {
if (irq > 15)
irq = 0xff;
if (dma >= 4)
dma = 0xff;
lpt_port_remove(dev->lpt);
switch (mode) {
default:
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x01:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x02: case 0x03:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x04:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x07:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10));
if (active && (addr <= (0xfffc & mask))) {
pc87307_log("Enabling LPT1 on %04X...\n", addr);
lpt_port_setup(dev->lpt, addr);
lpt_port_setup(dev->lpt, addr & mask);
} else
lpt_port_setup(dev->lpt, 0xffff);
lpt_port_irq(dev->lpt, irq);
lpt_port_dma(dev->lpt, dma);
}
static void
@@ -852,6 +899,7 @@ pc87307_init(const device_t *info)
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_cnfga_readout(dev->lpt, 0x14);
switch (info->local & PCX730X_KBC) {
default:

View File

@@ -183,6 +183,7 @@ fdc_handler(pc87309_t *dev)
uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) &&
(dev->pm[0x00] & 0x08);
uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f);
uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f);
uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) |
dev->ld_regs[LD_FDC][0x31]) & 0xfff8;
@@ -190,6 +191,7 @@ fdc_handler(pc87309_t *dev)
pc87309_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq);
fdc_set_base(dev->fdc, addr);
fdc_set_irq(dev->fdc, irq);
fdc_set_dma_ch(dev->fdc, dma);
}
}
@@ -199,16 +201,61 @@ lpt_handler(pc87309_t *dev)
uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) &&
(dev->pm[0x00] & 0x10);
uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f);
uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f);
uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) |
dev->ld_regs[LD_LPT][0x31];
uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7);
uint16_t mask = 0xfffc;
if (active && (addr <= 0xfffc)) {
if (irq > 15)
irq = 0xff;
if (dma >= 4)
dma = 0xff;
lpt_port_remove(dev->lpt);
switch (mode) {
default:
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x01:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x02: case 0x03:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x04:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x07:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10));
if (active && (addr <= (0xfffc & mask))) {
pc87309_log("Enabling LPT1 on %04X...\n", addr);
lpt_port_setup(dev->lpt, addr);
lpt_port_setup(dev->lpt, addr & mask);
} else
lpt_port_setup(dev->lpt, 0xffff);
lpt_port_irq(dev->lpt, irq);
lpt_port_dma(dev->lpt, dma);
}
static void
@@ -687,6 +734,7 @@ pc87309_init(const device_t *info)
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_cnfga_readout(dev->lpt, 0x14);
switch (info->local & PCX730X_KBC) {
default:

View File

@@ -85,16 +85,16 @@ lpt_handler(pc87310_t *dev)
lpt_port_remove(dev->lpt);
switch (temp) {
case 0:
case 0x00:
lpt_port = LPT1_ADDR;
break;
case 1:
case 0x01:
lpt_port = LPT_MDA_ADDR;
break;
case 2:
case 0x02:
lpt_port = LPT2_ADDR;
break;
case 3:
case 0x03:
lpt_port = 0x000;
lpt_irq = 0xff;
break;
@@ -195,15 +195,15 @@ pc87310_write(UNUSED(uint16_t port), uint8_t val, void *priv)
serial_handler(dev);
/* Reconfigure IDE controller. */
if ((dev->flags & PC87310_IDE) && (valxor & 0x20)) {
if ((dev->flags & PCX73XX_IDE) && (valxor & 0x20)) {
pc87310_log("SIO: HDC disabled\n");
ide_pri_disable();
/* Bit 5: 1 = Disable IDE controller. */
if (!(val & 0x20)) {
pc87310_log("SIO: HDC enabled\n");
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
ide_pri_enable();
ide_set_side(0, 0x3f6);
ide_pri_enable();
}
}
@@ -256,7 +256,7 @@ pc87310_reset(pc87310_t *dev)
lpt_handler(dev);
serial_handler(dev);
if (dev->flags & PC87310_IDE) {
if (dev->flags & PCX73XX_IDE) {
ide_pri_disable();
ide_pri_enable();
}
@@ -285,17 +285,18 @@ pc87310_init(const device_t *info)
dev->uart[1] = device_add_inst(&ns16450_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_ext(dev->lpt, 1);
if (dev->flags & PC87310_IDE)
if (dev->flags & PCX73XX_IDE)
device_add((dev->flags & PC87310_ALI) ? &ide_vlb_device : &ide_isa_device);
pc87310_reset(dev);
io_sethandler(0x3f3, 0x0001,
io_sethandler(0x03f3, 0x0001,
pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev);
if (dev->flags & PC87310_ALI)
io_sethandler(0x3f1, 0x0001,
io_sethandler(0x03f1, 0x0001,
pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev);
return dev;

View File

@@ -1,319 +0,0 @@
/*
* 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.
*
* Emulation of the National Semiconductor PC87311 Super I/O
*
*
*
* Authors: Tiseno100
*
* Copyright 2020 Tiseno100
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#include <86box/plat_unused.h>
#define HAS_IDE_FUNCTIONALITY dev->ide_function
/* Basic Functionalities */
#define FUNCTION_ENABLE dev->regs[0x00]
#define FUNCTION_ADDRESS dev->regs[0x01]
#define POWER_TEST dev->regs[0x02]
/* Base Addresses */
#define LPT_BA (FUNCTION_ADDRESS & 0x03)
#define UART1_BA ((FUNCTION_ADDRESS >> 2) & 0x03)
#define UART2_BA ((FUNCTION_ADDRESS >> 4) & 0x03)
#define COM_BA ((FUNCTION_ADDRESS >> 6) & 0x03)
#ifdef ENABLE_PC87311_LOG
int pc87311_do_log = ENABLE_PC87311_LOG;
static void
pc87311_log(const char *fmt, ...)
{
va_list ap;
if (pc87311_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define pc87311_log(fmt, ...)
#endif
typedef struct pc87311_t {
uint8_t index;
uint8_t regs[256];
uint8_t cfg_lock;
uint8_t ide_function;
uint16_t base;
uint16_t irq;
fdc_t *fdc_controller;
serial_t *uart[2];
lpt_t *lpt;
} pc87311_t;
void pc87311_fdc_handler(pc87311_t *dev);
void pc87311_uart_handler(uint8_t num, pc87311_t *dev);
void pc87311_lpt_handler(pc87311_t *dev);
void pc87311_ide_handler(pc87311_t *dev);
void pc87311_enable(pc87311_t *dev);
static void
pc87311_write(uint16_t addr, uint8_t val, void *priv)
{
pc87311_t *dev = (pc87311_t *) priv;
switch (addr) {
case 0x398:
case 0x26e:
dev->index = val;
break;
case 0x399:
case 0x26f:
switch (dev->index) {
case 0x00:
FUNCTION_ENABLE = val;
break;
case 0x01:
FUNCTION_ADDRESS = val;
break;
case 0x02:
POWER_TEST = val;
break;
default:
break;
}
break;
default:
break;
}
pc87311_enable(dev);
}
static uint8_t
pc87311_read(UNUSED(uint16_t addr), void *priv)
{
const pc87311_t *dev = (pc87311_t *) priv;
return dev->regs[dev->index];
}
void
pc87311_fdc_handler(pc87311_t *dev)
{
fdc_remove(dev->fdc_controller);
fdc_set_base(dev->fdc_controller, (FUNCTION_ENABLE & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
pc87311_log("PC87311-FDC: BASE %04x\n", (FUNCTION_ENABLE & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
}
uint16_t
com3(pc87311_t *dev)
{
switch (COM_BA) {
case 0:
return COM3_ADDR;
case 1:
return 0x0338;
case 2:
return COM4_ADDR;
case 3:
return 0x0220;
default:
return COM3_ADDR;
}
}
uint16_t
com4(pc87311_t *dev)
{
switch (COM_BA) {
case 0:
return COM4_ADDR;
case 1:
return 0x0238;
case 2:
return 0x02e0;
case 3:
return 0x0228;
default:
return COM4_ADDR;
}
}
void
pc87311_uart_handler(uint8_t num, pc87311_t *dev)
{
serial_remove(dev->uart[num & 1]);
switch (!(num & 1) ? UART1_BA : UART2_BA) {
case 0:
dev->base = COM1_ADDR;
dev->irq = COM1_IRQ;
break;
case 1:
dev->base = COM2_ADDR;
dev->irq = COM2_IRQ;
break;
case 2:
dev->base = com3(dev);
dev->irq = COM3_IRQ;
break;
case 3:
dev->base = com4(dev);
dev->irq = COM4_IRQ;
break;
default:
break;
}
serial_setup(dev->uart[num & 1], dev->base, dev->irq);
pc87311_log("PC87311-UART%01x: BASE %04x IRQ %01x\n", num & 1, dev->base, dev->irq);
}
void
pc87311_lpt_handler(pc87311_t *dev)
{
lpt_port_remove(dev->lpt);
switch (LPT_BA) {
case 0:
dev->base = LPT1_ADDR;
dev->irq = (POWER_TEST & 0x08) ? LPT1_IRQ : LPT2_IRQ;
break;
case 1:
dev->base = LPT_MDA_ADDR;
dev->irq = LPT_MDA_IRQ;
break;
case 2:
dev->base = LPT2_ADDR;
dev->irq = LPT2_IRQ;
break;
default:
break;
}
lpt_port_setup(dev->lpt, dev->base);
lpt_port_irq(dev->lpt, dev->irq);
pc87311_log("PC87311-LPT: BASE %04x IRQ %01x\n", dev->base, dev->irq);
}
void
pc87311_ide_handler(pc87311_t *dev)
{
ide_pri_disable();
ide_sec_disable();
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
ide_pri_enable();
if (FUNCTION_ENABLE & 0x80) {
ide_set_base(1, 0x170);
ide_set_side(1, 0x376);
ide_sec_enable();
}
pc87311_log("PC87311-IDE: PRI %01x SEC %01x\n", (FUNCTION_ENABLE >> 6) & 1, (FUNCTION_ENABLE >> 7) & 1);
}
void
pc87311_enable(pc87311_t *dev)
{
(FUNCTION_ENABLE & 0x01) ? pc87311_lpt_handler(dev) : lpt_port_remove(dev->lpt);
(FUNCTION_ENABLE & 0x02) ? pc87311_uart_handler(0, dev) : serial_remove(dev->uart[0]);
(FUNCTION_ENABLE & 0x04) ? pc87311_uart_handler(1, dev) : serial_remove(dev->uart[1]);
(FUNCTION_ENABLE & 0x08) ? pc87311_fdc_handler(dev) : fdc_remove(dev->fdc_controller);
if (FUNCTION_ENABLE & 0x20)
pc87311_fdc_handler(dev);
if (HAS_IDE_FUNCTIONALITY) {
(FUNCTION_ENABLE & 0x40) ? pc87311_ide_handler(dev) : ide_pri_disable();
(FUNCTION_ADDRESS & 0x80) ? pc87311_ide_handler(dev) : ide_sec_disable();
}
}
static void
pc87311_close(void *priv)
{
pc87311_t *dev = (pc87311_t *) priv;
free(dev);
}
static void *
pc87311_init(const device_t *info)
{
pc87311_t *dev = (pc87311_t *) calloc(1, sizeof(pc87311_t));
/* Avoid conflicting with machines that make no use of the PC87311 Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->fdc_controller = device_add(&fdc_at_nsc_device);
dev->uart[0] = device_add_inst(&ns16450_device, 1);
dev->uart[1] = device_add_inst(&ns16450_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_2ch_device);
io_sethandler(0x0398, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev);
io_sethandler(0x026e, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev);
pc87311_enable(dev);
return dev;
}
const device_t pc87311_device = {
.name = "National Semiconductor PC87311",
.internal_name = "pc87311",
.flags = 0,
.local = 0,
.init = pc87311_init,
.close = pc87311_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87311_ide_device = {
.name = "National Semiconductor PC87311 with IDE functionality",
.internal_name = "pc87311_ide",
.flags = 0,
.local = 1,
.init = pc87311_init,
.close = pc87311_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -6,9 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Emulation of the NatSemi PC87332 Super I/O chip.
*
*
* Emulation of the NatSemi PC87311 and PC87332 Super I/O chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
@@ -35,40 +33,50 @@
#include <86box/fdc.h>
#include <86box/sio.h>
typedef struct pc87332_t {
typedef struct pc873xx_t {
uint8_t baddr;
uint8_t is_332;
uint8_t tries;
uint8_t has_ide;
uint8_t fdc_on;
uint8_t regs[15];
uint16_t base_addr;
int cur_reg;
int max_reg;
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
} pc87332_t;
} pc873xx_t;
static void
lpt_handler(pc87332_t *dev)
lpt_handler(pc873xx_t *dev)
{
int temp;
uint16_t lpt_port = LPT1_ADDR;
uint8_t lpt_irq = LPT2_IRQ;
uint8_t lpt_irq = LPT2_IRQ;
uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1);
temp = dev->regs[0x01] & 3;
lpt_port_remove(dev->lpt);
if (lpt_dma == 0x00)
lpt_dma = 0xff;
temp = dev->regs[0x01] & 0x03;
switch (temp) {
case 0:
case 0x00:
lpt_port = LPT1_ADDR;
lpt_irq = (dev->regs[0x02] & 0x08) ? LPT1_IRQ : LPT2_IRQ;
break;
case 1:
case 0x01:
lpt_port = LPT_MDA_ADDR;
lpt_irq = LPT_MDA_IRQ;
lpt_irq = LPT_MDA_IRQ;
break;
case 2:
case 0x02:
lpt_port = LPT2_ADDR;
lpt_irq = LPT2_IRQ;
break;
case 3:
case 0x03:
lpt_port = 0x000;
lpt_irq = 0xff;
break;
@@ -77,6 +85,15 @@ lpt_handler(pc87332_t *dev)
break;
}
lpt_set_ext(dev->lpt, !!(dev->regs[0x02] & 0x80));
if (dev->is_332) {
lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01));
lpt_set_ecp(dev->lpt, !!(dev->regs[0x04] & 0x04));
lpt_port_dma(dev->lpt, lpt_dma);
}
if (lpt_port)
lpt_port_setup(dev->lpt, lpt_port);
@@ -84,7 +101,7 @@ lpt_handler(pc87332_t *dev)
}
static void
serial_handler(pc87332_t *dev, int uart)
serial_handler(pc873xx_t *dev, int uart)
{
int temp;
@@ -142,7 +159,7 @@ serial_handler(pc87332_t *dev, int uart)
}
static void
ide_handler(pc87332_t *dev)
ide_handler(pc873xx_t *dev)
{
/* TODO: Make an ide_disable(channel) and ide_enable(channel) so we can simplify this. */
if (dev->has_ide == 2) {
@@ -161,9 +178,9 @@ ide_handler(pc87332_t *dev)
}
static void
pc87332_write(uint16_t port, uint8_t val, void *priv)
pc873xx_write(uint16_t port, uint8_t val, void *priv)
{
pc87332_t *dev = (pc87332_t *) priv;
pc873xx_t *dev = (pc873xx_t *) priv;
uint8_t index;
uint8_t valxor;
@@ -177,7 +194,7 @@ pc87332_write(uint16_t port, uint8_t val, void *priv)
if (dev->tries) {
valxor = val ^ dev->regs[dev->cur_reg];
dev->tries = 0;
if ((dev->cur_reg <= 14) && (dev->cur_reg != 8))
if ((dev->cur_reg <= dev->max_reg) && (dev->cur_reg != 8))
dev->regs[dev->cur_reg] = val;
else
return;
@@ -187,69 +204,83 @@ pc87332_write(uint16_t port, uint8_t val, void *priv)
}
}
switch (dev->cur_reg) {
case 0:
if (valxor & 1) {
if (dev->cur_reg <= dev->max_reg) switch (dev->cur_reg) {
case 0x00:
if (valxor & 0x01) {
lpt_port_remove(dev->lpt);
if ((val & 1) && !(dev->regs[2] & 1))
if ((val & 0x01) && !(dev->regs[0x02] & 0x01))
lpt_handler(dev);
}
if (valxor & 2) {
if (valxor & 0x02) {
serial_remove(dev->uart[0]);
if ((val & 2) && !(dev->regs[2] & 1))
if ((val & 0x02) && !(dev->regs[0x02] & 0x01))
serial_handler(dev, 0);
}
if (valxor & 4) {
if (valxor & 0x04) {
serial_remove(dev->uart[1]);
if ((val & 4) && !(dev->regs[2] & 1))
if ((val & 0x04) && !(dev->regs[0x02] & 0x01))
serial_handler(dev, 1);
}
if (valxor & 0x28) {
fdc_remove(dev->fdc);
if ((val & 8) && !(dev->regs[2] & 1))
if ((val & 0x08) && !(dev->regs[0x02] & 0x01))
fdc_set_base(dev->fdc, (val & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
}
if (dev->has_ide && (valxor & 0xc0))
ide_handler(dev);
break;
case 1:
if (valxor & 3) {
case 0x01:
if (valxor & 0x03) {
lpt_port_remove(dev->lpt);
if ((dev->regs[0] & 1) && !(dev->regs[2] & 1))
if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01))
lpt_handler(dev);
}
if (valxor & 0xcc) {
serial_remove(dev->uart[0]);
if ((dev->regs[0] & 2) && !(dev->regs[2] & 1))
if ((dev->regs[0x00] & 0x02) && !(dev->regs[0x02] & 0x01))
serial_handler(dev, 0);
}
if (valxor & 0xf0) {
serial_remove(dev->uart[1]);
if ((dev->regs[0] & 4) && !(dev->regs[2] & 1))
if ((dev->regs[0x00] & 0x04) && !(dev->regs[0x02] & 0x01))
serial_handler(dev, 1);
}
break;
case 2:
if (valxor & 1) {
case 0x02:
if (valxor & 0x01) {
lpt_port_remove(dev->lpt);
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
fdc_remove(dev->fdc);
if (!(val & 1)) {
if (dev->regs[0] & 1)
if (!(val & 0x01)) {
if (dev->regs[0x00] & 0x01)
lpt_handler(dev);
if (dev->regs[0] & 2)
if (dev->regs[0x00] & 0x02)
serial_handler(dev, 0);
if (dev->regs[0] & 4)
if (dev->regs[0x00] & 0x04)
serial_handler(dev, 1);
if (dev->regs[0] & 8)
fdc_set_base(dev->fdc, (dev->regs[0] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
if (dev->regs[0x00] & 0x08)
fdc_set_base(dev->fdc, (dev->regs[0x00] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
}
}
if (valxor & 8) {
if (valxor & 0x88) {
lpt_port_remove(dev->lpt);
if ((dev->regs[0] & 1) && !(dev->regs[2] & 1))
if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01))
lpt_handler(dev);
}
break;
case 0x04:
if (valxor & 0x05) {
lpt_port_remove(dev->lpt);
if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01))
lpt_handler(dev);
}
break;
case 0x06:
if (valxor & 0x08) {
lpt_port_remove(dev->lpt);
if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01))
lpt_handler(dev);
}
break;
@@ -260,9 +291,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv)
}
uint8_t
pc87332_read(uint16_t port, void *priv)
pc873xx_read(uint16_t port, void *priv)
{
pc87332_t *dev = (pc87332_t *) priv;
pc873xx_t *dev = (pc873xx_t *) priv;
uint8_t ret = 0xff;
uint8_t index;
@@ -283,7 +314,7 @@ pc87332_read(uint16_t port, void *priv)
}
void
pc87332_reset(pc87332_t *dev)
pc873xx_reset(pc873xx_t *dev)
{
memset(dev->regs, 0, 15);
@@ -314,17 +345,17 @@ pc87332_reset(pc87332_t *dev)
}
static void
pc87332_close(void *priv)
pc873xx_close(void *priv)
{
pc87332_t *dev = (pc87332_t *) priv;
pc873xx_t *dev = (pc873xx_t *) priv;
free(dev);
}
static void *
pc87332_init(const device_t *info)
pc873xx_init(const device_t *info)
{
pc87332_t *dev = (pc87332_t *) calloc(1, sizeof(pc87332_t));
pc873xx_t *dev = (pc873xx_t *) calloc(1, sizeof(pc873xx_t));
dev->fdc = device_add(&fdc_at_nsc_device);
@@ -333,84 +364,45 @@ pc87332_init(const device_t *info)
dev->lpt = device_add_inst(&lpt_port_device, 1);
dev->has_ide = (info->local >> 8) & 0xff;
dev->fdc_on = (info->local >> 16) & 0xff;
pc87332_reset(dev);
dev->is_332 = !!(info->local & PC87332);
dev->max_reg = dev->is_332 ? 0x08 : 0x02;
if ((info->local & 0xff) == 0x01) {
io_sethandler(0x398, 0x0002,
pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev);
} else {
io_sethandler(0x02e, 0x0002,
pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev);
dev->has_ide = info->local & (PCX73XX_IDE_PRI | PCX73XX_IDE_SEC);
dev->fdc_on = info->local & PCX73XX_FDC_ON;
dev->baddr = (info->local & PCX730X_BADDR) >> PCX730X_BADDR_SHIFT;
pc873xx_reset(dev);
switch (dev->baddr) {
default:
case 0x00:
dev->base_addr = 0x0398;
break;
case 0x01:
dev->base_addr = 0x026e;
break;
case 0x02:
dev->base_addr = 0x015c;
break;
case 0x03:
/* Our PC87332 machine use this unless otherwise specified. */
dev->base_addr = 0x002e;
break;
}
io_sethandler(dev->base_addr, 0x0002,
pc873xx_read, NULL, NULL, pc873xx_write, NULL, NULL, dev);
return dev;
}
const device_t pc87332_device = {
.name = "National Semiconductor PC87332 Super I/O",
.internal_name = "pc87332",
const device_t pc873xx_device = {
.name = "National Semiconductor PC873xx Super I/O",
.internal_name = "pc873xx",
.flags = 0,
.local = 0x00,
.init = pc87332_init,
.close = pc87332_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87332_398_device = {
.name = "National Semiconductor PC87332 Super I/O (Port 398h)",
.internal_name = "pc87332_398",
.flags = 0,
.local = 0x01,
.init = pc87332_init,
.close = pc87332_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87332_398_ide_device = {
.name = "National Semiconductor PC87332 Super I/O (Port 398h) (With IDE)",
.internal_name = "pc87332_398_ide",
.flags = 0,
.local = 0x101,
.init = pc87332_init,
.close = pc87332_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87332_398_ide_sec_device = {
.name = "National Semiconductor PC87332 Super I/O (Port 398h) (With Secondary IDE)",
.internal_name = "pc87332_398_ide_sec",
.flags = 0,
.local = 0x201,
.init = pc87332_init,
.close = pc87332_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87332_398_ide_fdcon_device = {
.name = "National Semiconductor PC87332 Super I/O (Port 398h) (With IDE and FDC on)",
.internal_name = "pc87332_398_ide_fdcon",
.flags = 0,
.local = 0x10101,
.init = pc87332_init,
.close = pc87332_close,
.init = pc873xx_init,
.close = pc873xx_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,

View File

@@ -1,312 +0,0 @@
/*
* 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.
*
* Emulation of the Goldstar Prime3B Super I/O
*
*
*
* Authors: Tiseno100
*
* Copyright 2021 Tiseno100
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#include <86box/plat_unused.h>
#define FSR dev->regs[0xa0]
#define ASR dev->regs[0xa1]
#define PDR dev->regs[0xa2]
#define HAS_IDE_FUNCTIONALITY dev->ide_function
#ifdef ENABLE_PRIME3B_LOG
int prime3b_do_log = ENABLE_PRIME3B_LOG;
static void
prime3b_log(const char *fmt, ...)
{
va_list ap;
if (prime3b_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define prime3b_log(fmt, ...)
#endif
typedef struct prime3b_t {
uint8_t index;
uint8_t regs[256];
uint8_t cfg_lock;
uint8_t ide_function;
uint16_t com3_addr;
uint16_t com4_addr;
fdc_t *fdc_controller;
serial_t *uart[2];
lpt_t *lpt;
} prime3b_t;
void prime3b_fdc_handler(prime3b_t *dev);
void prime3b_uart_handler(uint8_t num, prime3b_t *dev);
void prime3b_lpt_handler(prime3b_t *dev);
void prime3b_ide_handler(prime3b_t *dev);
void prime3b_enable(prime3b_t *dev);
void prime3b_powerdown(prime3b_t *dev);
static void
prime3b_write(uint16_t addr, uint8_t val, void *priv)
{
prime3b_t *dev = (prime3b_t *) priv;
if (addr == 0x398) {
dev->index = val;
/* Enter/Escape Configuration Mode */
if (val == 0x33)
dev->cfg_lock = 0;
else if (val == 0xcc)
dev->cfg_lock = 1;
} else if ((addr == 0x399) && !dev->cfg_lock) {
switch (dev->index) {
case 0xa0: /* Function Selection Register (FSR) */
FSR = val;
prime3b_enable(dev);
break;
case 0xa1: /* Address Selection Register (ASR) */
ASR = val;
prime3b_enable(dev);
break;
case 0xa2: /* Power Down Register (PDR) */
dev->regs[0xa2] = val;
break;
case 0xa3: /* Test Mode Register (TMR) */
dev->regs[0xa3] = val;
break;
case 0xa4: /* Miscellaneous Function Register */
dev->regs[0xa4] = val;
switch ((dev->regs[0xa4] >> 6) & 3) {
case 0:
dev->com3_addr = COM3_ADDR;
dev->com4_addr = COM4_ADDR;
break;
case 1:
dev->com3_addr = 0x338;
dev->com4_addr = 0x238;
break;
case 2:
dev->com3_addr = COM4_ADDR;
dev->com4_addr = 0x2e0;
break;
case 3:
dev->com3_addr = 0x220;
dev->com4_addr = 0x228;
break;
default:
break;
}
break;
case 0xa5: /* ECP Register */
dev->regs[0xa5] = val;
break;
default:
break;
}
}
}
static uint8_t
prime3b_read(UNUSED(uint16_t addr), void *priv)
{
const prime3b_t *dev = (prime3b_t *) priv;
return dev->regs[dev->index];
}
void
prime3b_fdc_handler(prime3b_t *dev)
{
uint16_t fdc_base = !(ASR & 0x40) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR;
fdc_remove(dev->fdc_controller);
fdc_set_base(dev->fdc_controller, fdc_base);
prime3b_log("Prime3B-FDC: Enabled with base %03x\n", fdc_base);
}
void
prime3b_uart_handler(uint8_t num, prime3b_t *dev)
{
uint16_t uart_base;
if ((ASR >> (3 + 2 * num)) & 1)
uart_base = !((ASR >> (2 + 2 * num)) & 1) ? dev->com3_addr : dev->com4_addr;
else
uart_base = !((ASR >> (2 + 2 * num)) & 1) ? COM1_ADDR : COM2_ADDR;
serial_remove(dev->uart[num]);
serial_setup(dev->uart[num], uart_base, 4 - num);
prime3b_log("Prime3B-UART%d: Enabled with base %03x\n", num, uart_base);
}
void
prime3b_lpt_handler(prime3b_t *dev)
{
uint16_t lpt_base = (ASR & 2) ? LPT_MDA_ADDR : (!(ASR & 1) ? LPT1_ADDR : LPT2_ADDR);
lpt_port_remove(dev->lpt);
lpt_port_setup(dev->lpt, lpt_base);
lpt_port_irq(dev->lpt, LPT1_IRQ);
prime3b_log("Prime3B-LPT: Enabled with base %03x\n", lpt_base);
}
void
prime3b_ide_handler(prime3b_t *dev)
{
ide_pri_disable();
uint16_t ide_base = !(ASR & 0x80) ? 0x1f0 : 0x170;
uint16_t ide_side = ide_base + 0x206;
ide_set_base(0, ide_base);
ide_set_side(0, ide_side);
prime3b_log("Prime3B-IDE: Enabled with base %03x and side %03x\n", ide_base, ide_side);
}
void
prime3b_enable(prime3b_t *dev)
{
/*
Simulate a device enable/disable scenario
Register A0: Function Selection Register (FSR)
Bit 7: Gameport
Bit 6: 4 FDD Enable
Bit 5: IDE
Bit 4: FDC
Bit 3: UART 2
Bit 2: UART 1
Bit 1/0: PIO (0/0 Bidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled)
Note: 86Box LPT is simplistic and can't do ECP or EPP.
*/
!(FSR & 3) ? prime3b_lpt_handler(dev) : lpt_port_remove(dev->lpt);
(FSR & 4) ? prime3b_uart_handler(0, dev) : serial_remove(dev->uart[0]);
(FSR & 8) ? prime3b_uart_handler(1, dev) : serial_remove(dev->uart[1]);
(FSR & 0x10) ? prime3b_fdc_handler(dev) : fdc_remove(dev->fdc_controller);
if (HAS_IDE_FUNCTIONALITY)
(FSR & 0x20) ? prime3b_ide_handler(dev) : ide_pri_disable();
}
void
prime3b_powerdown(prime3b_t *dev)
{
/* Note: It can be done more efficiently for sure */
uint8_t old_base = PDR;
if (PDR & 1)
PDR |= 0x1e;
if (PDR & 0x40)
io_removehandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev);
if (PDR & 2)
fdc_remove(dev->fdc_controller);
if (PDR & 4)
serial_remove(dev->uart[0]);
if (PDR & 8)
serial_remove(dev->uart[1]);
if (PDR & 0x10)
lpt_port_remove(dev->lpt);
if (PDR & 1)
PDR = old_base;
}
static void
prime3b_close(void *priv)
{
prime3b_t *dev = (prime3b_t *) priv;
free(dev);
}
static void *
prime3b_init(const device_t *info)
{
prime3b_t *dev = (prime3b_t *) calloc(1, sizeof(prime3b_t));
/* Avoid conflicting with machines that make no use of the Prime3B Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->regs[0xa0] = 3;
dev->fdc_controller = device_add(&fdc_at_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
dev->com3_addr = COM3_ADDR;
dev->com4_addr = COM4_ADDR;
fdc_reset(dev->fdc_controller);
prime3b_enable(dev);
io_sethandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev);
return dev;
}
const device_t prime3b_device = {
.name = "Goldstar Prime3B",
.internal_name = "prime3b",
.flags = 0,
.local = 0,
.init = prime3b_init,
.close = prime3b_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t prime3b_ide_device = {
.name = "Goldstar Prime3B with IDE functionality",
.internal_name = "prime3b_ide",
.flags = 0,
.local = 1,
.init = prime3b_init,
.close = prime3b_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -1,358 +0,0 @@
/*
* 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.
*
* Emulation of the LG Prime3C Super I/O
*
*
*
* Authors: Tiseno100
*
* Copyright 2020 Tiseno100
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#include <86box/plat_unused.h>
#ifdef ENABLE_PRIME3C_LOG
int prime3c_do_log = ENABLE_PRIME3C_LOG;
static void
prime3c_log(const char *fmt, ...)
{
va_list ap;
if (prime3c_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define prime3c_log(fmt, ...)
#endif
/* Function Select(Note on prime3c_enable) */
#define FUNCTION_SELECT dev->regs[0xc2]
/* Base Address Registers */
#define FDC_BASE_ADDRESS dev->regs[0xc3]
#define IDE_BASE_ADDRESS dev->regs[0xc4]
#define IDE_SIDE_ADDRESS dev->regs[0xc5]
#define LPT_BASE_ADDRESS dev->regs[0xc6]
#define UART1_BASE_ADDRESS dev->regs[0xc7]
#define UART2_BASE_ADDRESS dev->regs[0xc8]
/* FDC/LPT Configuration */
#define FDC_LPT_DMA dev->regs[0xc9]
#define FDC_LPT_IRQ dev->regs[0xca]
/* UART 1/2 Configuration */
#define UART_IRQ dev->regs[0xcb]
/* Miscellaneous Configuration*/
#define FDC_SWAP (dev->regs[0xd6] & 0x01)
/* IDE functionality(Note on Init) */
#define HAS_IDE_FUNCTIONALITY dev->ide_function
typedef struct prime3c_t {
uint8_t index;
uint8_t regs[256];
uint8_t cfg_lock;
uint8_t ide_function;
fdc_t *fdc_controller;
serial_t *uart[2];
lpt_t *lpt;
} prime3c_t;
void prime3c_fdc_handler(prime3c_t *dev);
void prime3c_uart_handler(uint8_t num, prime3c_t *dev);
void prime3c_lpt_handler(prime3c_t *dev);
void prime3c_ide_handler(prime3c_t *dev);
void prime3c_enable(prime3c_t *dev);
static void
prime3c_write(uint16_t addr, uint8_t val, void *priv)
{
prime3c_t *dev = (prime3c_t *) priv;
switch (addr) {
case 0x398:
dev->index = val;
/* Enter/Escape Configuration Mode */
if (val == 0x33)
dev->cfg_lock = 0;
else if (val == 0x55)
dev->cfg_lock = 1;
break;
case 0x399:
if (!dev->cfg_lock) {
switch (dev->index) {
case 0xc2:
FUNCTION_SELECT = val & 0xbf;
prime3c_enable(dev);
break;
case 0xc3:
FDC_BASE_ADDRESS = val & 0xfc;
prime3c_fdc_handler(dev);
break;
case 0xc4:
IDE_BASE_ADDRESS = val & 0xfc;
if (HAS_IDE_FUNCTIONALITY)
prime3c_ide_handler(dev);
break;
case 0xc5:
IDE_SIDE_ADDRESS = (val & 0xfc) | 0x02;
if (HAS_IDE_FUNCTIONALITY)
prime3c_ide_handler(dev);
break;
case 0xc6:
LPT_BASE_ADDRESS = val;
break;
case 0xc7:
UART1_BASE_ADDRESS = val & 0xfe;
prime3c_uart_handler(0, dev);
break;
case 0xc8:
UART2_BASE_ADDRESS = val & 0xfe;
prime3c_uart_handler(1, dev);
break;
case 0xc9:
FDC_LPT_DMA = val;
prime3c_fdc_handler(dev);
break;
case 0xca:
FDC_LPT_IRQ = val;
prime3c_fdc_handler(dev);
prime3c_lpt_handler(dev);
break;
case 0xcb:
UART_IRQ = val;
prime3c_uart_handler(0, dev);
prime3c_uart_handler(1, dev);
break;
case 0xcd:
case 0xce:
dev->regs[dev->index] = val;
break;
case 0xcf:
dev->regs[dev->index] = val & 0x3f;
break;
case 0xd0:
dev->regs[dev->index] = val & 0xfc;
break;
case 0xd1:
dev->regs[dev->index] = val & 0x3f;
break;
case 0xd3:
dev->regs[dev->index] = val & 0x7c;
break;
case 0xd5:
case 0xd6:
case 0xd7:
case 0xd8:
dev->regs[dev->index] = val;
break;
default:
break;
}
}
break;
default:
break;
}
}
static uint8_t
prime3c_read(UNUSED(uint16_t addr), void *priv)
{
const prime3c_t *dev = (prime3c_t *) priv;
return dev->regs[dev->index];
}
void
prime3c_fdc_handler(prime3c_t *dev)
{
fdc_remove(dev->fdc_controller);
if (FUNCTION_SELECT & 0x10) {
fdc_set_base(dev->fdc_controller, FDC_BASE_ADDRESS << 2);
fdc_set_irq(dev->fdc_controller, (FDC_LPT_IRQ >> 4) & 0xf);
fdc_set_dma_ch(dev->fdc_controller, (FDC_LPT_DMA >> 4) & 0xf);
fdc_set_swap(dev->fdc_controller, FDC_SWAP);
prime3c_log("Prime3C-FDC: BASE %04x IRQ %01x DMA %01x\n", FDC_BASE_ADDRESS << 2, (FDC_LPT_IRQ >> 4) & 0xf, (FDC_LPT_DMA >> 4) & 0xf);
}
}
void
prime3c_uart_handler(uint8_t num, prime3c_t *dev)
{
serial_remove(dev->uart[num & 1]);
if (FUNCTION_SELECT & (!(num & 1) ? 0x04 : 0x08)) {
serial_setup(dev->uart[num & 1], (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf);
prime3c_log("Prime3C-UART%01x: BASE %04x IRQ %01x\n", num & 1, (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf);
}
}
void
prime3c_lpt_handler(prime3c_t *dev)
{
lpt_port_remove(dev->lpt);
if (!(FUNCTION_SELECT & 0x03)) {
lpt_port_setup(dev->lpt, LPT_BASE_ADDRESS << 2);
lpt_port_irq(dev->lpt, FDC_LPT_IRQ & 0xf);
prime3c_log("Prime3C-LPT: BASE %04x IRQ %02x\n", LPT_BASE_ADDRESS << 2, FDC_LPT_IRQ & 0xf);
}
}
void
prime3c_ide_handler(prime3c_t *dev)
{
ide_pri_disable();
if (FUNCTION_SELECT & 0x20) {
ide_set_base(0, IDE_BASE_ADDRESS << 2);
ide_set_side(0, IDE_SIDE_ADDRESS << 2);
ide_pri_enable();
prime3c_log("Prime3C-IDE: BASE %04x SIDE %04x\n", IDE_BASE_ADDRESS << 2, IDE_SIDE_ADDRESS << 2);
}
}
void
prime3c_enable(prime3c_t *dev)
{
/*
Simulate a device enable/disable scenario
Register C2: Function Select
Bit 7: Gameport
Bit 6: Reserved
Bit 5: IDE
Bit 4: FDC
Bit 3: UART 2
Bit 2: UART 1
Bit 1/0: PIO (0/0 Unidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled)
Note: 86Box LPT is simplistic and can't do ECP or EPP.
*/
!(FUNCTION_SELECT & 0x03) ? prime3c_lpt_handler(dev) : lpt_port_remove(dev->lpt);
(FUNCTION_SELECT & 0x04) ? prime3c_uart_handler(0, dev) : serial_remove(dev->uart[0]);
(FUNCTION_SELECT & 0x08) ? prime3c_uart_handler(1, dev) : serial_remove(dev->uart[1]);
(FUNCTION_SELECT & 0x10) ? prime3c_fdc_handler(dev) : fdc_remove(dev->fdc_controller);
if (HAS_IDE_FUNCTIONALITY)
(FUNCTION_SELECT & 0x20) ? prime3c_ide_handler(dev) : ide_pri_disable();
}
static void
prime3c_close(void *priv)
{
prime3c_t *dev = (prime3c_t *) priv;
free(dev);
}
static void *
prime3c_init(const device_t *info)
{
prime3c_t *dev = (prime3c_t *) calloc(1, sizeof(prime3c_t));
/* Avoid conflicting with machines that make no use of the Prime3C Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->regs[0xc0] = 0x3c;
dev->regs[0xc2] = 0x03;
dev->regs[0xc3] = 0x3c;
dev->regs[0xc4] = 0x3c;
dev->regs[0xc5] = 0x3d;
dev->regs[0xd5] = 0x3c;
dev->fdc_controller = device_add(&fdc_at_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
prime3c_fdc_handler(dev);
prime3c_uart_handler(0, dev);
prime3c_uart_handler(1, dev);
prime3c_lpt_handler(dev);
if (HAS_IDE_FUNCTIONALITY)
prime3c_ide_handler(dev);
io_sethandler(0x0398, 0x0002, prime3c_read, NULL, NULL, prime3c_write, NULL, NULL, dev);
return dev;
}
const device_t prime3c_device = {
.name = "Goldstar Prime3C",
.internal_name = "prime3c",
.flags = 0,
.local = 0,
.init = prime3c_init,
.close = prime3c_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t prime3c_ide_device = {
.name = "Goldstar Prime3C with IDE functionality",
.internal_name = "prime3c_ide",
.flags = 0,
.local = 1,
.init = prime3c_init,
.close = prime3c_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -92,7 +92,8 @@ static uint8_t um8669f_pnp_rom[] = {
0x15, 0x41, 0xd0, 0x04, 0x00, 0x01, /* logical device PNP0400, can participate in boot */
0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */
0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */
0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 8 addresses */
0x15, 0x41, 0xd0, 0x06, 0x00, 0x01, /* logical device PNP0600, can participate in boot */
0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */
@@ -120,7 +121,8 @@ static const isapnp_device_config_t um8669f_pnp_defaults[] = {
}, {
.activate = 1,
.io = { { .base = LPT1_ADDR }, },
.irq = { { .irq = LPT1_IRQ }, }
.irq = { { .irq = LPT1_IRQ }, },
.dma = { { .dma = 3 }, }
}, {
.activate = 0,
.io = { { .base = 0x1f0 }, },
@@ -268,6 +270,9 @@ um8669f_write(uint16_t port, uint8_t val, void *priv)
if (dev->cur_reg == 0xc1) {
um8669f_log("UM8669F: ISAPnP %sabled\n", (val & 0x80) ? "en" : "dis");
isapnp_enable_card(dev->pnp_card, (val & 0x80) ? ISAPNP_CARD_FORCE_CONFIG : ISAPNP_CARD_DISABLE);
} else if (dev->cur_reg == 0xc0) {
lpt_set_epp(dev->lpt, val & 0x08);
lpt_set_ecp(dev->lpt, val & 0x10);
}
}
}
@@ -304,6 +309,9 @@ um8669f_reset(um8669f_t *dev)
lpt_port_remove(dev->lpt);
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
if (dev->ide < IDE_BUS_MAX)
ide_remove_handlers(dev->ide);
@@ -341,8 +349,9 @@ um8669f_init(const device_t *info)
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
lpt_set_ext(dev->lpt, 1);
dev->ide = info->local;
dev->ide = (uint8_t) (info->local - 1);
if (dev->ide < IDE_BUS_MAX)
device_add(&ide_isa_device);
@@ -360,20 +369,6 @@ const device_t um8669f_device = {
.name = "UMC UM8669F Super I/O",
.internal_name = "um8669f",
.flags = 0,
.local = 0xff,
.init = um8669f_init,
.close = um8669f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8669f_ide_device = {
.name = "UMC UM8669F Super I/O (With IDE)",
.internal_name = "um8669f_ide",
.flags = 0,
.local = 0,
.init = um8669f_init,
.close = um8669f_close,
@@ -383,17 +378,3 @@ const device_t um8669f_ide_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t um8669f_ide_sec_device = {
.name = "UMC UM8669F Super I/O (With Secondary IDE)",
.internal_name = "um8669f_ide_sec",
.flags = 0,
.local = 1,
.init = um8669f_init,
.close = um8669f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -6,7 +6,8 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the UMC UMF8663F Super I/O chip.
* Implementation of the UMC UM82C862F, UM82C863F, UM86863F,
* and UM8663BF Super I/O chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
@@ -35,25 +36,25 @@
#include <86box/random.h>
#include <86box/plat_unused.h>
#ifdef ENABLE_UM8663F_LOG
int um8663f_do_log = ENABLE_UM8663F_LOG;
#ifdef ENABLE_UM866X_LOG
int um866x_do_log = ENABLE_UM866X_LOG;
static void
um8663f_log(const char *fmt, ...)
um866x_log(const char *fmt, ...)
{
va_list ap;
if (um8663f_do_log) {
if (um866x_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define um8663f_log(fmt, ...)
# define um866x_log(fmt, ...)
#endif
typedef struct um8663f_t {
typedef struct um866x_t {
uint8_t max_reg;
uint8_t ide;
uint8_t locked;
@@ -64,10 +65,10 @@ typedef struct um8663f_t {
serial_t *uart[2];
lpt_t * lpt;
} um8663f_t;
} um866x_t;
static void
um8663f_fdc_handler(um8663f_t *dev)
um866x_fdc_handler(um866x_t *dev)
{
fdc_remove(dev->fdc);
if (dev->regs[0] & 0x01)
@@ -75,7 +76,7 @@ um8663f_fdc_handler(um8663f_t *dev)
}
static void
um8663f_uart_handler(um8663f_t *dev, int port)
um866x_uart_handler(um866x_t *dev, int port)
{
uint8_t shift = (port + 1);
@@ -102,10 +103,32 @@ um8663f_uart_handler(um8663f_t *dev, int port)
}
static void
um8663f_lpt_handler(um8663f_t *dev)
um866x_lpt_handler(um866x_t *dev)
{
int enabled = (dev->regs[0] & 0x08);
lpt_port_remove(dev->lpt);
if (dev->regs[0] & 0x08) {
switch(dev->regs[1] & 0xc0) {
case 0x00:
enabled = 0;
break;
case 0x40:
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x80:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0xc0:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
if (enabled) {
switch ((dev->regs[1] >> 3) & 0x01) {
case 0x01:
lpt_port_setup(dev->lpt, LPT1_ADDR);
@@ -123,7 +146,7 @@ um8663f_lpt_handler(um8663f_t *dev)
}
static void
um8663f_ide_handler(um8663f_t *dev)
um866x_ide_handler(um866x_t *dev)
{
int board = dev->ide - 1;
@@ -137,12 +160,12 @@ um8663f_ide_handler(um8663f_t *dev)
}
static void
um8663f_write(uint16_t port, uint8_t val, void *priv)
um866x_write(uint16_t port, uint8_t val, void *priv)
{
um8663f_t *dev = (um8663f_t *) priv;
um866x_t *dev = (um866x_t *) priv;
uint8_t valxor;
um8663f_log("UM8663F: write(%04X, %02X)\n", port, val);
um866x_log("UM866X: write(%04X, %02X)\n", port, val);
if (dev->locked) {
if ((port == 0x108) && (val == 0xaa))
@@ -160,15 +183,15 @@ um8663f_write(uint16_t port, uint8_t val, void *priv)
/* Port enable register. */
case 0x00:
if (valxor & 0x10)
um8663f_ide_handler(dev);
um866x_ide_handler(dev);
if (valxor & 0x08)
um8663f_lpt_handler(dev);
um866x_lpt_handler(dev);
if (valxor & 0x04)
um8663f_uart_handler(dev, 1);
um866x_uart_handler(dev, 1);
if (valxor & 0x02)
um8663f_uart_handler(dev, 0);
um866x_uart_handler(dev, 0);
if (valxor & 0x01)
um8663f_fdc_handler(dev);
um866x_fdc_handler(dev);
break;
/*
Port configuration register:
@@ -184,16 +207,16 @@ um8663f_write(uint16_t port, uint8_t val, void *priv)
- Bit 0 = 0 = FDC is 370h, 1 = UART 2 is 3f0h.
*/
case 0x01:
if (valxor & 0xc8)
um866x_lpt_handler(dev);
if (valxor & 0x10)
um8663f_ide_handler(dev);
if (valxor & 0x08)
um8663f_lpt_handler(dev);
um866x_ide_handler(dev);
if (valxor & 0x04)
um8663f_uart_handler(dev, 1);
um866x_uart_handler(dev, 1);
if (valxor & 0x02)
um8663f_uart_handler(dev, 0);
um866x_uart_handler(dev, 0);
if (valxor & 0x01)
um8663f_fdc_handler(dev);
um866x_fdc_handler(dev);
break;
}
}
@@ -201,9 +224,9 @@ um8663f_write(uint16_t port, uint8_t val, void *priv)
}
static uint8_t
um8663f_read(uint16_t port, void *priv)
um866x_read(uint16_t port, void *priv)
{
const um8663f_t *dev = (um8663f_t *) priv;
const um866x_t *dev = (um866x_t *) priv;
uint8_t ret = 0xff;
if (!dev->locked) {
@@ -216,15 +239,15 @@ um8663f_read(uint16_t port, void *priv)
}
}
um8663f_log("UM8663F: read(%04X) = %02X\n", port, ret);
um866x_log("UM866X: read(%04X) = %02X\n", port, ret);
return ret;
}
static void
um8663f_reset(void *priv)
um866x_reset(void *priv)
{
um8663f_t *dev = (um8663f_t *) priv;
um866x_t *dev = (um866x_t *) priv;
serial_remove(dev->uart[0]);
serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ);
@@ -243,27 +266,27 @@ um8663f_reset(void *priv)
dev->regs[0x00] = (dev->ide > 0) ? 0x1f : 0x0f;
dev->regs[0x01] = (dev->ide == 2) ? 0x0f : 0x1f;
um8663f_fdc_handler(dev);
um8663f_uart_handler(dev, 0);
um8663f_uart_handler(dev, 1);
um8663f_lpt_handler(dev);
um8663f_ide_handler(dev);
um866x_fdc_handler(dev);
um866x_uart_handler(dev, 0);
um866x_uart_handler(dev, 1);
um866x_lpt_handler(dev);
um866x_ide_handler(dev);
dev->locked = 1;
}
static void
um8663f_close(void *priv)
um866x_close(void *priv)
{
um8663f_t *dev = (um8663f_t *) priv;
um866x_t *dev = (um866x_t *) priv;
free(dev);
}
static void *
um8663f_init(UNUSED(const device_t *info))
um866x_init(UNUSED(const device_t *info))
{
um8663f_t *dev = (um8663f_t *) calloc(1, sizeof(um8663f_t));
um866x_t *dev = (um866x_t *) calloc(1, sizeof(um866x_t));
dev->fdc = device_add(&fdc_at_smc_device);
@@ -279,147 +302,21 @@ um8663f_init(UNUSED(const device_t *info))
dev->max_reg = info->local >> 8;
if (dev->max_reg != 0x00)
io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev);
io_sethandler(0x0108, 0x0002, um866x_read, NULL, NULL, um866x_write, NULL, NULL, dev);
um8663f_reset(dev);
um866x_reset(dev);
return dev;
}
const device_t um82c862f_device = {
.name = "UMC UM82C862F Super I/O",
.internal_name = "um82c862f",
const device_t um866x_device = {
.name = "UMC UM82C86x/866x Super I/O",
.internal_name = "um866x",
.flags = 0,
.local = 0x0000,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um82c862f_ide_device = {
.name = "UMC UM82C862F Super I/O (With IDE)",
.internal_name = "um82c862f_ide",
.flags = 0,
.local = 0x0001,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um82c863f_device = {
.name = "UMC UM82C863F Super I/O",
.internal_name = "um82c863f",
.flags = 0,
.local = 0xc100,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um82c863f_ide_device = {
.name = "UMC UM82C863F Super I/O (With IDE)",
.internal_name = "um82c863f_ide",
.flags = 0,
.local = 0xc101,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663af_device = {
.name = "UMC UM8663AF Super I/O",
.internal_name = "um8663af",
.flags = 0,
.local = 0xc300,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663af_ide_device = {
.name = "UMC UM8663AF Super I/O (With IDE)",
.internal_name = "um8663af_ide",
.flags = 0,
.local = 0xc301,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663af_ide_sec_device = {
.name = "UMC UM8663AF Super I/O (With Secondary IDE)",
.internal_name = "um8663af_ide_sec",
.flags = 0,
.local = 0xc302,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663bf_device = {
.name = "UMC UM8663BF Super I/O",
.internal_name = "um8663bf",
.flags = 0,
.local = 0xc400,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663bf_ide_device = {
.name = "UMC UM8663BF Super I/O (With IDE)",
.internal_name = "um8663bf_ide",
.flags = 0,
.local = 0xc401,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t um8663bf_ide_sec_device = {
.name = "UMC UM8663BF Super I/O (With Secondary IDE)",
.internal_name = "um8663bf_ide_sec",
.flags = 0,
.local = 0xc402,
.init = um8663f_init,
.close = um8663f_close,
.reset = um8663f_reset,
.local = 0,
.init = um866x_init,
.close = um866x_close,
.reset = um866x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,

View File

@@ -86,14 +86,28 @@ vt82c686_lpt_handler(vt82c686_t *dev)
lpt_port_remove(dev->lpt);
lpt_set_ext(dev->lpt, !!(dev->regs[0x10] & 0x80));
switch (dev->regs[0x10] & 0x03) {
case 0x01:
lpt_set_epp(dev->lpt, !!(dev->regs[0x10] & 0x20));
lpt_set_ecp(dev->lpt, 1);
break;
case 0x02:
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, !!(dev->regs[0x10] & 0x20));
break;
}
if (((dev->regs[0x02] & 0x03) != 0x03) && !(dev->regs[0x0f] & 0x11) && (io_base >= 0x100) && (io_base <= io_mask))
lpt_port_setup(dev->lpt, io_base);
if (dev->lpt_irq) {
if (dev->lpt_irq)
lpt_port_irq(dev->lpt, dev->lpt_irq);
} else {
else
lpt_port_irq(dev->lpt, 0xff);
}
lpt_port_dma(dev->lpt, dev->lpt_dma);
}
static void
@@ -178,6 +192,7 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv)
case 0x10:
dev->regs[reg] &= 0xf4;
vt82c686_lpt_handler(dev);
break;
case 0x11:

View File

@@ -1,539 +0,0 @@
/*
* 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.
*
* Emulation of the Winbond W83787F/IF Super I/O Chip.
*
* Winbond W83787F Super I/O Chip
* Used by the Award 430HX
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/gameport.h>
#include <86box/sio.h>
#ifdef ENABLE_W83787_LOG
int w83787_do_log = ENABLE_W83787_LOG;
static void
w83787_log(const char *fmt, ...)
{
va_list ap;
if (w83787_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define w83787_log(fmt, ...)
#endif
#define FDDA_TYPE (dev->regs[7] & 3)
#define FDDB_TYPE ((dev->regs[7] >> 2) & 3)
#define FDDC_TYPE ((dev->regs[7] >> 4) & 3)
#define FDDD_TYPE ((dev->regs[7] >> 6) & 3)
#define FD_BOOT (dev->regs[8] & 3)
#define SWWP ((dev->regs[8] >> 4) & 1)
#define DISFDDWR ((dev->regs[8] >> 5) & 1)
#define EN3MODE ((dev->regs[9] >> 5) & 1)
#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */
#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */
#define IDENT ((dev->regs[0xB] >> 3) & 1)
#define HEFERE ((dev->regs[0xC] >> 5) & 1)
#define HAS_IDE_FUNCTIONALITY dev->ide_function
typedef struct w83787f_t {
uint8_t tries;
uint8_t regs[42];
uint16_t reg_init;
int locked;
int rw_locked;
int cur_reg;
int key;
int ide_function;
int ide_start;
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
void *gameport;
} w83787f_t;
static void w83787f_write(uint16_t port, uint8_t val, void *priv);
static uint8_t w83787f_read(uint16_t port, void *priv);
static void
w83787f_remap(w83787f_t *dev)
{
io_removehandler(0x250, 0x0004,
w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev);
io_sethandler(0x250, 0x0004,
w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev);
dev->key = 0x88 | HEFERE;
}
#ifdef FIXME
/* FIXME: Implement EPP (and ECP) parallel port modes. */
static uint8_t
get_lpt_length(w83787f_t *dev)
{
uint8_t length = 4;
if (dev->regs[9] & 0x80) {
if (dev->regs[0] & 0x04)
length = 8; /* EPP mode. */
if (dev->regs[0] & 0x08)
length |= 0x80; /* ECP mode. */
}
return length;
}
#endif
static void
w83787f_serial_handler(w83787f_t *dev, int uart)
{
int urs0 = !!(dev->regs[1] & (1 << uart));
int urs1 = !!(dev->regs[1] & (4 << uart));
int urs2 = !!(dev->regs[3] & (8 >> uart));
int urs;
int irq = COM1_IRQ;
uint16_t addr = COM1_ADDR;
uint16_t enable = 1;
urs = (urs1 << 1) | urs0;
if (urs2) {
addr = uart ? COM1_ADDR : COM2_ADDR;
irq = uart ? COM1_IRQ : COM2_IRQ;
} else {
switch (urs) {
case 0:
addr = uart ? COM3_ADDR : COM4_ADDR;
irq = uart ? COM3_IRQ : COM4_IRQ;
break;
case 1:
addr = uart ? COM4_ADDR : COM3_ADDR;
irq = uart ? COM4_IRQ : COM3_IRQ;
break;
case 2:
addr = uart ? COM2_ADDR : COM1_ADDR;
irq = uart ? COM2_IRQ : COM1_IRQ;
break;
case 3:
default:
enable = 0;
break;
}
}
if (dev->regs[4] & (0x20 >> uart))
enable = 0;
serial_remove(dev->uart[uart]);
if (enable)
serial_setup(dev->uart[uart], addr, irq);
}
static void
w83787f_lpt_handler(w83787f_t *dev)
{
int ptras = (dev->regs[1] >> 4) & 0x03;
int irq = LPT1_IRQ;
uint16_t addr = LPT1_ADDR;
uint16_t enable = 1;
switch (ptras) {
case 0x00:
addr = LPT_MDA_ADDR;
irq = LPT_MDA_IRQ;
break;
case 0x01:
addr = LPT2_ADDR;
irq = LPT2_IRQ;
break;
case 0x02:
addr = LPT1_ADDR;
irq = LPT1_IRQ;
break;
case 0x03:
default:
enable = 0;
break;
}
if (dev->regs[4] & 0x80)
enable = 0;
lpt_port_remove(dev->lpt);
if (enable) {
lpt_port_setup(dev->lpt, addr);
lpt_port_irq(dev->lpt, irq);
}
}
static void
w83787f_gameport_handler(w83787f_t *dev)
{
if (!(dev->regs[3] & 0x40) && !(dev->regs[4] & 0x40))
gameport_remap(dev->gameport, 0x201);
else
gameport_remap(dev->gameport, 0);
}
static void
w83787f_fdc_handler(w83787f_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[0] & 0x20))
fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR);
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
w83787f_ide_handler(w83787f_t *dev)
{
if (dev->ide_function & 0x20) {
ide_sec_disable();
if (!(dev->regs[0] & 0x80)) {
ide_set_base(1, (dev->regs[0] & 0x40) ? 0x1f0 : 0x170);
ide_set_side(1, (dev->regs[0] & 0x40) ? 0x3f6 : 0x376);
ide_sec_enable();
}
} else {
ide_pri_disable();
if (!(dev->regs[0] & 0x80)) {
ide_set_base(0, (dev->regs[0] & 0x40) ? 0x1f0 : 0x170);
ide_set_side(0, (dev->regs[0] & 0x40) ? 0x3f6 : 0x376);
ide_pri_enable();
}
}
}
static void
w83787f_write(uint16_t port, uint8_t val, void *priv)
{
w83787f_t *dev = (w83787f_t *) priv;
uint8_t valxor = 0;
uint8_t max = 0x15;
if (port == 0x250) {
if (val == dev->key)
dev->locked = 1;
else
dev->locked = 0;
return;
} else if (port == 0x251) {
if (val <= max)
dev->cur_reg = val;
return;
} else {
if (dev->locked) {
if (dev->rw_locked && (dev->cur_reg <= 0x0b))
return;
if (dev->cur_reg == 6)
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else
return;
}
switch (dev->cur_reg) {
case 0:
w83787_log("REG 00: %02X\n", val);
if ((valxor & 0xc0) && (HAS_IDE_FUNCTIONALITY))
w83787f_ide_handler(dev);
if (valxor & 0x30)
w83787f_fdc_handler(dev);
if (valxor & 0x0c)
w83787f_lpt_handler(dev);
break;
case 1:
if (valxor & 0x80)
fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0);
if (valxor & 0x30)
w83787f_lpt_handler(dev);
if (valxor & 0x0a)
w83787f_serial_handler(dev, 1);
if (valxor & 0x05)
w83787f_serial_handler(dev, 0);
break;
case 3:
if (valxor & 0x80)
w83787f_lpt_handler(dev);
if (valxor & 0x40)
w83787f_gameport_handler(dev);
if (valxor & 0x08)
w83787f_serial_handler(dev, 0);
if (valxor & 0x04)
w83787f_serial_handler(dev, 1);
break;
case 4:
if (valxor & 0x10)
w83787f_serial_handler(dev, 1);
if (valxor & 0x20)
w83787f_serial_handler(dev, 0);
if (valxor & 0x80)
w83787f_lpt_handler(dev);
if (valxor & 0x40)
w83787f_gameport_handler(dev);
break;
case 6:
if (valxor & 0x08)
w83787f_fdc_handler(dev);
break;
case 7:
if (valxor & 0x03)
fdc_update_rwc(dev->fdc, 0, FDDA_TYPE);
if (valxor & 0x0c)
fdc_update_rwc(dev->fdc, 1, FDDB_TYPE);
if (valxor & 0x30)
fdc_update_rwc(dev->fdc, 2, FDDC_TYPE);
if (valxor & 0xc0)
fdc_update_rwc(dev->fdc, 3, FDDD_TYPE);
break;
case 8:
if (valxor & 0x03)
fdc_update_boot_drive(dev->fdc, FD_BOOT);
if (valxor & 0x10)
fdc_set_swwp(dev->fdc, SWWP ? 1 : 0);
if (valxor & 0x20)
fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0);
break;
case 9:
if (valxor & 0x20)
fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0);
if (valxor & 0x40)
dev->rw_locked = (val & 0x40) ? 1 : 0;
if (valxor & 0x80)
w83787f_lpt_handler(dev);
break;
case 0xB:
w83787_log("Writing %02X to CRB\n", val);
break;
case 0xC:
if (valxor & 0x20)
w83787f_remap(dev);
break;
default:
break;
}
}
static uint8_t
w83787f_read(uint16_t port, void *priv)
{
w83787f_t *dev = (w83787f_t *) priv;
uint8_t ret = 0xff;
if (dev->locked) {
if (port == 0x251)
ret = dev->cur_reg;
else if (port == 0x252) {
if (dev->cur_reg == 7)
ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2));
else if (!dev->rw_locked || (dev->cur_reg > 0x0b))
ret = dev->regs[dev->cur_reg];
}
}
return ret;
}
static void
w83787f_reset(w83787f_t *dev)
{
uint16_t hefere = dev->reg_init & 0x0100;
lpt_port_remove(dev->lpt);
lpt_port_setup(dev->lpt, LPT1_ADDR);
lpt_port_irq(dev->lpt, LPT1_IRQ);
memset(dev->regs, 0, 0x2A);
if (HAS_IDE_FUNCTIONALITY) {
if (dev->ide_function & 0x20) {
dev->regs[0x00] = 0x90;
ide_sec_disable();
ide_set_base(1, 0x170);
ide_set_side(1, 0x376);
} else {
dev->regs[0x00] = 0xd0;
ide_pri_disable();
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
}
if (dev->ide_start) {
dev->regs[0x00] &= 0x7f;
if (dev->ide_function & 0x20)
ide_sec_enable();
else
ide_pri_enable();
}
} else
dev->regs[0x00] = 0xd0;
fdc_reset(dev->fdc);
w83787f_fdc_handler(dev);
dev->regs[0x01] = 0x2C;
dev->regs[0x03] = 0x70;
dev->regs[0x07] = 0xF5;
dev->regs[0x09] = dev->reg_init & 0xff;
dev->regs[0x0a] = 0x1F;
dev->regs[0x0c] = 0x0C | (hefere >> 3);
dev->regs[0x0d] = 0xA3;
gameport_remap(dev->gameport, 0);
serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ);
serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ);
w83787f_lpt_handler(dev);
dev->key = 0x88 | (hefere >> 8);
w83787f_remap(dev);
dev->locked = 0;
dev->rw_locked = 0;
}
static void
w83787f_close(void *priv)
{
w83787f_t *dev = (w83787f_t *) priv;
free(dev);
}
static void *
w83787f_init(const device_t *info)
{
w83787f_t *dev = (w83787f_t *) calloc(1, sizeof(w83787f_t));
HAS_IDE_FUNCTIONALITY = (info->local & 0x30);
dev->fdc = device_add(&fdc_at_winbond_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
dev->gameport = gameport_add(&gameport_sio_1io_device);
if ((dev->ide_function & 0x30) == 0x10)
device_add(&ide_isa_device);
dev->ide_start = !!(info->local & 0x40);
dev->reg_init = info->local & 0x010f;
w83787f_reset(dev);
return dev;
}
const device_t w83787f_88h_device = {
.name = "Winbond W83787F/IF Super I/O",
.internal_name = "w83787f",
.flags = 0,
.local = 0x0009,
.init = w83787f_init,
.close = w83787f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83787f_device = {
.name = "Winbond W83787F/IF Super I/O",
.internal_name = "w83787f",
.flags = 0,
.local = 0x0109,
.init = w83787f_init,
.close = w83787f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83787f_ide_device = {
.name = "Winbond W83787F/IF Super I/O (With IDE)",
.internal_name = "w83787f_ide",
.flags = 0,
.local = 0x0119,
.init = w83787f_init,
.close = w83787f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83787f_ide_en_device = {
.name = "Winbond W83787F/IF Super I/O (With IDE Enabled)",
.internal_name = "w83787f_ide_en",
.flags = 0,
.local = 0x0159,
.init = w83787f_init,
.close = w83787f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83787f_ide_sec_device = {
.name = "Winbond W83787F/IF Super I/O (With Secondary IDE)",
.internal_name = "w83787f_ide_sec",
.flags = 0,
.local = 0x0139,
.init = w83787f_init,
.close = w83787f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

475
src/sio/sio_w837x7.c Normal file
View File

@@ -0,0 +1,475 @@
/*
* 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.
*
* Emulation of the Winbond W837x7F/IF Super I/O Chip.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Copyright 2020-2025 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/gameport.h>
#include <86box/sio.h>
#define FDDA_TYPE (dev->regs[7] & 3)
#define FDDB_TYPE ((dev->regs[7] >> 2) & 3)
#define FDDC_TYPE ((dev->regs[7] >> 4) & 3)
#define FDDD_TYPE ((dev->regs[7] >> 6) & 3)
#define FD_BOOT (dev->regs[8] & 3)
#define SWWP ((dev->regs[8] >> 4) & 1)
#define DISFDDWR ((dev->regs[8] >> 5) & 1)
#define EN3MODE ((dev->regs[9] >> 5) & 1)
#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */
#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */
#define IDENT ((dev->regs[0xB] >> 3) & 1)
#define HEFERE ((dev->regs[0xC] >> 5) & 1)
typedef struct w837x7_t {
uint8_t tries;
uint8_t has_ide;
uint8_t type;
uint8_t hefere;
uint8_t max_reg;
uint8_t regs[256];
int locked;
int rw_locked;
int cur_reg;
int key;
int ide_start;
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
void *gameport;
} w837x7_t;
#ifdef ENABLE_W837X7_LOG
int w837x7_do_log = ENABLE_W837X7_LOG;
static void
w837x7_log(const char *fmt, ...)
{
va_list ap;
if (w837x7_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define w837x7_log(fmt, ...)
#endif
static void
w837x7_serial_handler(w837x7_t *dev, int uart)
{
int urs0 = !!(dev->regs[0x01] & (0x01 << uart));
int urs1 = !!(dev->regs[0x01] & (0x04 << uart));
int urs2 = !!(dev->regs[0x03] & (0x08 >> uart));
int urs;
int irq = COM1_IRQ;
uint16_t addr = COM1_ADDR;
uint16_t enable = 1;
double clock_src = 24000000.0 / 13.0;
if (dev->regs[0x03] & (1 << (1 - uart)))
clock_src = 24000000.0 / 12.0;
urs = (urs1 << 1) | urs0;
if (urs2) {
addr = uart ? COM1_ADDR : COM2_ADDR;
irq = uart ? COM1_IRQ : COM2_IRQ;
} else {
switch (urs) {
case 0x00:
addr = uart ? COM3_ADDR : COM4_ADDR;
irq = uart ? COM3_IRQ : COM4_IRQ;
break;
case 0x01:
addr = uart ? COM4_ADDR : COM3_ADDR;
irq = uart ? COM4_IRQ : COM3_IRQ;
break;
case 0x02:
addr = uart ? COM2_ADDR : COM1_ADDR;
irq = uart ? COM2_IRQ : COM1_IRQ;
break;
case 0x03:
default:
enable = 0;
break;
}
}
if (dev->regs[0x04] & (0x20 >> uart))
enable = 0;
serial_remove(dev->uart[uart]);
if (enable)
serial_setup(dev->uart[uart], addr, irq);
serial_set_clock_src(dev->uart[uart], clock_src);
}
static void
w837x7_lpt_handler(w837x7_t *dev)
{
int ptras = (dev->regs[1] >> 4) & 0x03;
uint16_t lpt_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t local_enable = 1;
uint8_t lpt_irq = LPT1_IRQ;
uint8_t lpt_mode = (dev->regs[0x09] & 0x80) | (dev->regs[0x00] & 0x0c);
switch (ptras) {
case 0x01:
lpt_port = LPT_MDA_ADDR;
lpt_irq = LPT_MDA_IRQ;
break;
case 0x02:
lpt_port = LPT1_ADDR;
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
break;
case 0x03:
lpt_port = LPT2_ADDR;
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
break;
default:
local_enable = 0;
break;
}
if (dev->regs[0x04] & 0x80)
local_enable = 0;
if (lpt_irq > 15)
lpt_irq = 0xff;
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x05] & 0x0f);
switch (lpt_mode) {
default:
local_enable = 0;
break;
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x84:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x88:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x8c:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask)))
lpt_port_setup(dev->lpt, lpt_port);
lpt_port_irq(dev->lpt, lpt_irq);
}
static void
w837x7_gameport_handler(w837x7_t *dev)
{
if (!(dev->regs[3] & 0x40) && !(dev->regs[4] & 0x40))
gameport_remap(dev->gameport, 0x201);
else
gameport_remap(dev->gameport, 0);
}
static void
w837x7_fdc_handler(w837x7_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[0] & 0x20))
fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR);
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
w837x7_ide_handler(w837x7_t *dev)
{
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_set_base_addr(ide_id, 0, (dev->regs[0x00] & 0x40) ? 0x0170 : 0x01f0);
ide_set_base_addr(ide_id, 1, (dev->regs[0x00] & 0x40) ? 0x0376 : 0x03f6);
if (!(dev->regs[0x00] & 0x80))
ide_handlers(ide_id, 1);
}
}
static void
w837x7_write(uint16_t port, uint8_t val, void *priv)
{
w837x7_t *dev = (w837x7_t *) priv;
uint8_t valxor = 0;
if (port == 0x0250) {
if (val == dev->key)
dev->locked = 1;
else
dev->locked = 0;
return;
} else if (port == 0x0251) {
dev->cur_reg = val;
return;
} else {
if (dev->locked) {
if (dev->rw_locked && (dev->cur_reg <= 0x0b))
return;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else
return;
}
if (dev->cur_reg <= dev->max_reg) switch (dev->cur_reg) {
case 0x00:
w837x7_log("REG 00: %02X\n", val);
if (valxor & 0xc0)
w837x7_ide_handler(dev);
if (valxor & 0x30)
w837x7_fdc_handler(dev);
if (valxor & 0x0c)
w837x7_lpt_handler(dev);
break;
case 0x01:
if (valxor & 0x80)
fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0);
if (valxor & 0x30)
w837x7_lpt_handler(dev);
if (valxor & 0x0a)
w837x7_serial_handler(dev, 1);
if (valxor & 0x05)
w837x7_serial_handler(dev, 0);
break;
case 0x03:
if (valxor & 0x80)
w837x7_lpt_handler(dev);
if (valxor & 0x40)
w837x7_gameport_handler(dev);
if (valxor & 0x0a)
w837x7_serial_handler(dev, 0);
if (valxor & 0x05)
w837x7_serial_handler(dev, 1);
break;
case 0x04:
if (valxor & 0x10)
w837x7_serial_handler(dev, 1);
if (valxor & 0x20)
w837x7_serial_handler(dev, 0);
if (valxor & 0x80)
w837x7_lpt_handler(dev);
if (valxor & 0x40)
w837x7_gameport_handler(dev);
break;
case 0x05:
if (valxor & 0x0f)
w837x7_lpt_handler(dev);
break;
case 0x06:
if (valxor & 0x08)
w837x7_fdc_handler(dev);
break;
case 0x07:
if (valxor & 0x03)
fdc_update_rwc(dev->fdc, 0, FDDA_TYPE);
if (valxor & 0x0c)
fdc_update_rwc(dev->fdc, 1, FDDB_TYPE);
if (valxor & 0x30)
fdc_update_rwc(dev->fdc, 2, FDDC_TYPE);
if (valxor & 0xc0)
fdc_update_rwc(dev->fdc, 3, FDDD_TYPE);
break;
case 0x08:
if (valxor & 0x03)
fdc_update_boot_drive(dev->fdc, FD_BOOT);
if (valxor & 0x10)
fdc_set_swwp(dev->fdc, SWWP ? 1 : 0);
if (valxor & 0x20)
fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0);
break;
case 0x09:
if (valxor & 0x20)
fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0);
if (valxor & 0x40)
dev->rw_locked = (val & 0x40) ? 1 : 0;
if (valxor & 0x80)
w837x7_lpt_handler(dev);
break;
case 0x0b:
if ((valxor & 0x0c) && (dev->type == W83777F)) {
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
switch (val & 0x0c) {
case 0x00:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2);
break;
case 0x04:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
}
break;
case 0x0c:
if (dev->type == W83787IF)
dev->key = 0x88 | HEFERE;
break;
default:
break;
}
}
static uint8_t
w837x7_read(uint16_t port, void *priv)
{
w837x7_t *dev = (w837x7_t *) priv;
uint8_t ret = 0xff;
if (dev->locked) {
if (port == 0x0251)
ret = dev->cur_reg;
else if (port == 0x0252) {
if (dev->cur_reg == 7)
ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2));
else if (!dev->rw_locked || (dev->cur_reg > 0x0b))
ret = dev->regs[dev->cur_reg];
}
}
return ret;
}
static void
w837x7_reset(w837x7_t *dev)
{
memset(dev->regs, 0x00, dev->max_reg + 1);
if (dev->has_ide == 0x02)
dev->regs[0x00] = 0x90;
else if (dev->has_ide == 0x01)
dev->regs[0x00] = 0xd0;
if (dev->ide_start)
dev->regs[0x00] &= 0x7f;
dev->regs[0x01] = 0x2c;
dev->regs[0x03] = 0x30;
dev->regs[0x09] = dev->type;
dev->regs[0x0a] = 0x1f;
if (dev->type == W83787IF) {
dev->regs[0x0c] = 0x0c | dev->hefere;
dev->regs[0x0d] = 0x03;
} else
dev->regs[0x0c] = dev->hefere;
dev->key = 0x88 | HEFERE;
fdc_reset(dev->fdc);
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
w837x7_fdc_handler(dev);
w837x7_lpt_handler(dev);
w837x7_serial_handler(dev, 0);
w837x7_serial_handler(dev, 0);
w837x7_gameport_handler(dev);
w837x7_ide_handler(dev);
dev->locked = 0;
dev->rw_locked = 0;
}
static void
w837x7_close(void *priv)
{
w837x7_t *dev = (w837x7_t *) priv;
free(dev);
}
static void *
w837x7_init(const device_t *info)
{
w837x7_t *dev = (w837x7_t *) calloc(1, sizeof(w837x7_t));
dev->type = info->local & 0x0f;
dev->hefere = info->local & W837X7_KEY_89;
dev->max_reg = (dev->type == W83787IF) ? 0x15 : ((dev->type == W83787F) ? 0x0a : 0x0b);
dev->has_ide = (info->local >> 16) & 0xff;
dev->ide_start = !!(info->local & W837X7_IDE_START);
dev->fdc = device_add(&fdc_at_winbond_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
dev->lpt = device_add_inst(&lpt_port_device, 1);
dev->gameport = gameport_add(&gameport_sio_1io_device);
w837x7_reset(dev);
io_sethandler(0x250, 0x0004,
w837x7_read, NULL, NULL, w837x7_write, NULL, NULL, dev);
return dev;
}
const device_t w837x7_device = {
.name = "Winbond W837x7 Super I/O",
.internal_name = "w837x7",
.flags = 0,
.local = 0,
.init = w837x7_init,
.close = w837x7_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -6,15 +6,10 @@
*
* This file is part of the 86Box distribution.
*
* Emulation of the Winbond W83877F Super I/O Chip.
*
* Winbond W83877F Super I/O Chip
* Used by the Award 430HX
*
*
* Emulation of the Winbond W83877 family of Super I/O Chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2020 Miran Grca.
* Copyright 2016-2025 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -30,35 +25,41 @@
#include <86box/rom.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/machine.h>
#include <86box/sio.h>
#define FDDA_TYPE (dev->regs[7] & 3)
#define FDDB_TYPE ((dev->regs[7] >> 2) & 3)
#define FDDC_TYPE ((dev->regs[7] >> 4) & 3)
#define FDDD_TYPE ((dev->regs[7] >> 6) & 3)
#define FDDA_TYPE (dev->regs[0x07] & 3)
#define FDDB_TYPE ((dev->regs[0x07] >> 2) & 3)
#define FDDC_TYPE ((dev->regs[0x07] >> 4) & 3)
#define FDDD_TYPE ((dev->regs[0x07] >> 6) & 3)
#define FD_BOOT (dev->regs[8] & 3)
#define SWWP ((dev->regs[8] >> 4) & 1)
#define DISFDDWR ((dev->regs[8] >> 5) & 1)
#define FD_BOOT (dev->regs[0x08] & 3)
#define SWWP ((dev->regs[0x08] >> 4) & 1)
#define DISFDDWR ((dev->regs[0x08] >> 5) & 1)
#define EN3MODE ((dev->regs[9] >> 5) & 1)
#define EN3MODE ((dev->regs[0x09] >> 5) & 1)
#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */
#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */
#define IDENT ((dev->regs[0xB] >> 3) & 1)
#define DRV2EN_NEG (dev->regs[0x0b] & 1) /* 0 = drive 2 installed */
#define INVERTZ ((dev->regs[0x0b] >> 1) & 1) /* 0 = invert DENSEL polarity */
#define IDENT ((dev->regs[0x0b] >> 3) & 1)
#define HEFERE ((dev->regs[0xC] >> 5) & 1)
#define HEFERE ((dev->regs[0x0c] >> 5) & 1)
#define HEFRAS (dev->regs[0x16] & 1)
#define PRTIQS (dev->regs[0x27] & 0x0f)
#define ECPIRQ ((dev->regs[0x27] >> 5) & 0x07)
typedef struct w83877f_t {
typedef struct w83877_t {
uint8_t tries;
uint8_t regs[42];
uint8_t has_ide;
uint8_t dma_map[4];
uint8_t irq_map[10];
uint8_t regs[256];
uint16_t reg_init;
int locked;
int rw_locked;
@@ -69,36 +70,36 @@ typedef struct w83877f_t {
fdc_t *fdc;
serial_t *uart[2];
lpt_t *lpt;
} w83877f_t;
} w83877_t;
static void w83877f_write(uint16_t port, uint8_t val, void *priv);
static uint8_t w83877f_read(uint16_t port, void *priv);
static void w83877_write(uint16_t port, uint8_t val, void *priv);
static uint8_t w83877_read(uint16_t port, void *priv);
static void
w83877f_remap(w83877f_t *dev)
w83877_remap(w83877_t *dev)
{
uint8_t hefras = HEFRAS;
io_removehandler(0x250, 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev);
io_removehandler(FDC_PRIMARY_ADDR, 0x0002,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev);
dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250);
io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev);
dev->key_times = hefras + 1;
dev->key = (hefras ? 0x86 : 0x88) | HEFERE;
}
static uint8_t
get_lpt_length(w83877f_t *dev)
get_lpt_length(w83877_t *dev)
{
uint8_t length = 4;
if (dev->regs[9] & 0x80) {
if (dev->regs[0] & 0x04)
if (dev->regs[0x09] & 0x80) {
if (dev->regs[0x00] & 0x04)
length = 8; /* EPP mode. */
if (dev->regs[0] & 0x08)
if (dev->regs[0x00] & 0x08)
length |= 0x80; /* ECP mode. */
}
@@ -106,7 +107,7 @@ get_lpt_length(w83877f_t *dev)
}
static uint16_t
make_port(w83877f_t *dev, uint8_t reg)
make_port(w83877_t *dev, uint8_t reg)
{
uint16_t p = 0;
uint8_t l;
@@ -114,34 +115,31 @@ make_port(w83877f_t *dev, uint8_t reg)
switch (reg) {
case 0x20:
p = ((uint16_t) (dev->regs[reg] & 0xfc)) << 2;
p &= 0xFF0;
if ((p < 0x100) || (p > 0x3F0))
p = 0x3F0;
p &= 0x0ff0;
if ((p < 0x0100) || (p > 0x03f0))
p = 0x03f0;
break;
case 0x23:
l = get_lpt_length(dev);
p = ((uint16_t) (dev->regs[reg] & 0xff)) << 2;
/* 8 ports in EPP mode, 4 in non-EPP mode. */
if ((l & 0x0f) == 8)
p &= 0x3F8;
p &= 0x03f8;
else
p &= 0x3FC;
if ((p < 0x100) || (p > 0x3FF))
p &= 0x03fc;
if ((p < 0x0100) || (p > 0x03ff))
p = LPT1_ADDR;
/* In ECP mode, A10 is active. */
if (l & 0x80)
p |= 0x400;
break;
case 0x24:
p = ((uint16_t) (dev->regs[reg] & 0xfe)) << 2;
p &= 0xFF8;
if ((p < 0x100) || (p > 0x3F8))
p &= 0x0ff8;
if ((p < 0x0100) || (p > 0x03f8))
p = COM1_ADDR;
break;
case 0x25:
p = ((uint16_t) (dev->regs[reg] & 0xfe)) << 2;
p &= 0xFF8;
if ((p < 0x100) || (p > 0x3F8))
p &= 0x0ff8;
if ((p < 0x0100) || (p > 0x03f8))
p = COM2_ADDR;
break;
@@ -153,35 +151,60 @@ make_port(w83877f_t *dev, uint8_t reg)
}
static void
w83877f_fdc_handler(w83877f_t *dev)
w83877_ide_handler(w83877_t *dev)
{
uint16_t ide_port = 0x0000;
if (dev->has_ide > 0) {
int ide_id = dev->has_ide - 1;
ide_handlers(ide_id, 0);
ide_port = (dev->regs[0x21] << 2) & 0xfff0;
ide_set_base_addr(ide_id, 0, ide_port);
ide_port = ((dev->regs[0x22] << 2) & 0xfff0) | 0x0006;
ide_set_base_addr(ide_id, 1, ide_port);
if (!(dev->regs[0x06] & 0x04))
ide_handlers(ide_id, 1);
}
}
static void
w83877_fdc_handler(w83877_t *dev)
{
fdc_remove(dev->fdc);
if (dev->regs[0x20] & 0xc0)
if (!(dev->regs[0x06] & 0x08) && (dev->regs[0x20] & 0xc0))
fdc_set_base(dev->fdc, make_port(dev, 0x20));
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
fdc_set_irq(dev->fdc, dev->irq_map[dev->regs[0x29] >> 4]);
fdc_set_dma_ch(dev->fdc, dev->dma_map[(dev->regs[0x26] >> 4) & 0x03]);
fdc_set_power_down(dev->fdc, !!(dev->regs[0x06] & 0x08));
}
static void
w83877f_lpt_handler(w83877f_t *dev)
w83877_lpt_handler(w83877_t *dev)
{
uint8_t lpt_irq;
uint8_t lpt_irqs[8] = { 0, 7, 9, 10, 11, 14, 15, 5 };
const uint8_t lpt_irq = dev->irq_map[PRTIQS];
lpt_port_remove(dev->lpt);
if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0))
lpt_set_ext(dev->lpt, 1);
lpt_set_epp(dev->lpt, (dev->regs[0x09] & 0x80) && (dev->regs[0x00] & 0x04));
lpt_set_ecp(dev->lpt, (dev->regs[0x09] & 0x80) && (dev->regs[0x00] & 0x08));
lpt_set_fifo_threshold(dev->lpt, dev->regs[0x05] & 0x0f);
if (!(dev->regs[0x04] & 0x80) && (dev->regs[0x23] & 0xc0))
lpt_port_setup(dev->lpt, make_port(dev, 0x23));
lpt_irq = 0xff;
lpt_irq = lpt_irqs[ECPIRQ];
if (lpt_irq == 0)
lpt_irq = PRTIQS;
lpt_port_irq(dev->lpt, lpt_irq);
lpt_port_dma(dev->lpt, dev->dma_map[dev->regs[0x26] & 0x03]);
}
static void
w83877f_serial_handler(w83877f_t *dev, int uart)
w83877_serial_handler(w83877_t *dev, int uart)
{
int reg_mask = uart ? 0x10 : 0x20;
int reg_id = uart ? 0x25 : 0x24;
@@ -191,7 +214,7 @@ w83877f_serial_handler(w83877f_t *dev, int uart)
serial_remove(dev->uart[uart]);
if (!(dev->regs[4] & reg_mask) && (dev->regs[reg_id] & 0xc0))
serial_setup(dev->uart[uart], make_port(dev, reg_id), (dev->regs[0x28] & irq_mask) >> irq_shift);
serial_setup(dev->uart[uart], make_port(dev, reg_id), dev->irq_map[(dev->regs[0x28] & irq_mask) >> irq_shift]);
if (dev->regs[0x19] & (0x02 >> uart)) {
clock_src = 14769000.0;
@@ -205,21 +228,19 @@ w83877f_serial_handler(w83877f_t *dev, int uart)
}
static void
w83877f_write(uint16_t port, uint8_t val, void *priv)
w83877_write(uint16_t port, uint8_t val, void *priv)
{
w83877f_t *dev = (w83877f_t *) priv;
w83877_t *dev = (w83877_t *) priv;
uint8_t valxor = 0;
uint8_t max = 0x2A;
if (port == 0x250) {
if (port == 0x0250) {
if (val == dev->key)
dev->locked = 1;
else
dev->locked = 0;
return;
} else if (port == 0x251) {
if (val <= max)
dev->cur_reg = val;
} else if (port == 0x0251) {
dev->cur_reg = val;
return;
} else if (port == FDC_PRIMARY_ADDR) {
if ((val == dev->key) && !dev->locked) {
@@ -235,8 +256,8 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
}
} else {
if (dev->locked) {
if (val < max)
dev->cur_reg = val;
dev->cur_reg = val;
if (val == 0xaa)
dev->locked = 0;
} else {
@@ -245,16 +266,10 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
}
}
return;
} else if ((port == 0x252) || (port == 0x3f1)) {
} else if ((port == 0x0252) || (port == 0x03f1)) {
if (dev->locked) {
if (dev->rw_locked)
return;
if ((dev->cur_reg >= 0x26) && (dev->cur_reg <= 0x27))
return;
if (dev->cur_reg == 0x29)
return;
if (dev->cur_reg == 6)
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else
@@ -262,33 +277,39 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
}
switch (dev->cur_reg) {
case 0:
case 0x00:
if (valxor & 0x0c)
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
break;
case 1:
case 0x01:
if (valxor & 0x80)
fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0);
fdc_set_swap(dev->fdc, (dev->regs[0x01] & 0x80) ? 1 : 0);
break;
case 3:
case 0x03:
if (valxor & 0x02)
w83877f_serial_handler(dev, 0);
w83877_serial_handler(dev, 0);
if (valxor & 0x01)
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 1);
break;
case 4:
case 0x04:
if (valxor & 0x10)
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 1);
if (valxor & 0x20)
w83877f_serial_handler(dev, 0);
w83877_serial_handler(dev, 0);
if (valxor & 0x80)
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
break;
case 6:
case 0x05:
if (valxor & 0x0f)
w83877_lpt_handler(dev);
break;
case 0x06:
if (valxor & 0x08)
w83877f_fdc_handler(dev);
w83877_fdc_handler(dev);
if (valxor & 0x04)
w83877_ide_handler(dev);
break;
case 7:
case 0x07:
if (valxor & 0x03)
fdc_update_rwc(dev->fdc, 0, FDDA_TYPE);
if (valxor & 0x0c)
@@ -298,7 +319,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
if (valxor & 0xc0)
fdc_update_rwc(dev->fdc, 3, FDDD_TYPE);
break;
case 8:
case 0x08:
if (valxor & 0x03)
fdc_update_boot_drive(dev->fdc, FD_BOOT);
if (valxor & 0x10)
@@ -306,66 +327,106 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
if (valxor & 0x20)
fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0);
break;
case 9:
case 0x09:
if (valxor & 0x20)
fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0);
if (valxor & 0x40)
dev->rw_locked = (val & 0x40) ? 1 : 0;
if (valxor & 0x80)
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
break;
case 0xB:
if (valxor & 1)
fdc_update_drv2en(dev->fdc, DRV2EN_NEG ? 0 : 1);
if (valxor & 2)
case 0x0b:
if (valxor & 0x0c) {
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
switch (val & 0x0c) {
case 0x00:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2);
break;
case 0x04:
fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA);
break;
}
}
if (valxor & 0x02)
fdc_update_densel_polarity(dev->fdc, INVERTZ ? 1 : 0);
if (valxor & 0x01)
fdc_update_drv2en(dev->fdc, DRV2EN_NEG ? 0 : 1);
break;
case 0xC:
case 0x0c:
if (valxor & 0x20)
w83877f_remap(dev);
w83877_remap(dev);
break;
case 0x16:
if (valxor & 1)
w83877f_remap(dev);
if (valxor & 0x02) {
dev->regs[0x1e] = (val & 0x02) ? 0x81 : 0x00;
dev->regs[0x20] = (val & 0x02) ? 0xfc : 0x00;
dev->regs[0x21] = (val & 0x02) ? 0x7c : 0x00;
dev->regs[0x22] = (val & 0x02) ? 0xfd : 0x00;
dev->regs[0x23] = (val & 0x02) ? 0xde : 0x00;
dev->regs[0x24] = (val & 0x02) ? 0xfe : 0x00;
dev->regs[0x25] = (val & 0x02) ? 0xbe : 0x00;
dev->regs[0x26] = (val & 0x02) ? 0x23 : 0x00;
dev->regs[0x27] = (val & 0x02) ? 0x65 : 0x00;
dev->regs[0x28] = (val & 0x02) ? 0x43 : 0x00;
dev->regs[0x29] = (val & 0x02) ? 0x62 : 0x00;
w83877_fdc_handler(dev);
w83877_lpt_handler(dev);
w83877_serial_handler(dev, 0);
w83877_serial_handler(dev, 1);
}
if (valxor & 0x01)
w83877_remap(dev);
break;
case 0x19:
if (valxor & 0x02)
w83877f_serial_handler(dev, 0);
w83877_serial_handler(dev, 0);
if (valxor & 0x01)
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 1);
break;
case 0x20:
if (valxor)
w83877f_fdc_handler(dev);
w83877_fdc_handler(dev);
break;
case 0x21: case 0x22:
if (valxor)
w83877_ide_handler(dev);
break;
case 0x23:
if (valxor)
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
break;
case 0x24:
if (valxor & 0xfe)
w83877f_serial_handler(dev, 0);
w83877_serial_handler(dev, 0);
break;
case 0x25:
if (valxor & 0xfe)
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 1);
break;
case 0x26:
if (valxor & 0x0f)
w83877_lpt_handler(dev);
break;
case 0x27:
if (valxor & 0xef)
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
break;
case 0x28:
if (valxor & 0xf) {
if (valxor & 0x0f) {
if ((dev->regs[0x28] & 0x0f) == 0)
dev->regs[0x28] |= 0x03;
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 1);
}
if (valxor & 0xf0) {
if ((dev->regs[0x28] & 0xf0) == 0)
dev->regs[0x28] |= 0x40;
w83877f_serial_handler(dev, 0);
w83877_serial_handler(dev, 0);
}
break;
case 0x29:
if (valxor & 0xf0)
w83877_fdc_handler(dev);
break;
default:
break;
@@ -373,9 +434,9 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
}
static uint8_t
w83877f_read(uint16_t port, void *priv)
w83877_read(uint16_t port, void *priv)
{
w83877f_t *dev = (w83877f_t *) priv;
w83877_t *dev = (w83877_t *) priv;
uint8_t ret = 0xff;
if (dev->locked) {
@@ -393,7 +454,7 @@ w83877f_read(uint16_t port, void *priv)
}
static void
w83877f_reset(w83877f_t *dev)
w83877_reset(w83877_t *dev)
{
fdc_reset(dev->fdc);
@@ -405,47 +466,40 @@ w83877f_reset(w83877f_t *dev)
dev->regs[0x0c] = 0x28;
dev->regs[0x0d] = 0xA3;
dev->regs[0x16] = dev->reg_init & 0xff;
dev->regs[0x1e] = 0x81;
dev->regs[0x20] = (FDC_PRIMARY_ADDR >> 2) & 0xfc;
dev->regs[0x21] = (0x1f0 >> 2) & 0xfc;
dev->regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1;
dev->regs[0x23] = (LPT1_ADDR >> 2);
dev->regs[0x24] = (COM1_ADDR >> 2) & 0xfe;
dev->regs[0x25] = (COM2_ADDR >> 2) & 0xfe;
dev->regs[0x26] = (2 << 4) | 4;
dev->regs[0x27] = (2 << 4) | 5;
dev->regs[0x28] = (4 << 4) | 3;
dev->regs[0x29] = 0x62;
w83877f_fdc_handler(dev);
w83877_fdc_handler(dev);
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
w83877f_lpt_handler(dev);
w83877_lpt_handler(dev);
w83877f_serial_handler(dev, 0);
w83877f_serial_handler(dev, 1);
w83877_serial_handler(dev, 0);
w83877_serial_handler(dev, 1);
if (dev->has_ide)
w83877_ide_handler(dev);
dev->base_address = FDC_PRIMARY_ADDR;
dev->key = 0x89;
dev->key_times = 1;
w83877f_remap(dev);
w83877_remap(dev);
dev->locked = 0;
dev->rw_locked = 0;
}
static void
w83877f_close(void *priv)
w83877_close(void *priv)
{
w83877f_t *dev = (w83877f_t *) priv;
w83877_t *dev = (w83877_t *) priv;
free(dev);
}
static void *
w83877f_init(const device_t *info)
w83877_init(const device_t *info)
{
w83877f_t *dev = (w83877f_t *) calloc(1, sizeof(w83877f_t));
w83877_t *dev = (w83877_t *) calloc(1, sizeof(w83877_t));
dev->fdc = device_add(&fdc_at_winbond_device);
@@ -456,60 +510,40 @@ w83877f_init(const device_t *info)
dev->reg_init = info->local;
w83877f_reset(dev);
dev->has_ide = (info->local >> 16) & 0xff;
if (!strcmp(machine_get_internal_name(), "ficpa2012")) {
dev->dma_map[0] = 4;
dev->dma_map[1] = 3;
dev->dma_map[2] = 1;
dev->dma_map[3] = 2;
} else {
dev->dma_map[0] = 4;
for (int i = 1; i < 4; i++)
dev->dma_map[i] = i;
}
memset(dev->irq_map, 0xff, 16);
dev->irq_map[0] = 0xff;
for (int i = 1; i < 7; i++)
dev->irq_map[i] = i;
dev->irq_map[1] = 5;
dev->irq_map[5] = 7;
dev->irq_map[7] = 9; /* Guesswork, I can't find a single BIOS that lets me assign IRQ_G to something. */
dev->irq_map[8] = 10;
w83877_reset(dev);
return dev;
}
const device_t w83877f_device = {
const device_t w83877_device = {
.name = "Winbond W83877F Super I/O",
.internal_name = "w83877f",
.internal_name = "w83877",
.flags = 0,
.local = 0x0a05,
.init = w83877f_init,
.close = w83877f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83877f_president_device = {
.name = "Winbond W83877F Super I/O (President)",
.internal_name = "w83877f_president",
.flags = 0,
.local = 0x0a04,
.init = w83877f_init,
.close = w83877f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83877tf_device = {
.name = "Winbond W83877TF Super I/O",
.internal_name = "w83877tf",
.flags = 0,
.local = 0x0c04,
.init = w83877f_init,
.close = w83877f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83877tf_acorp_device = {
.name = "Winbond W83877TF Super I/O",
.internal_name = "w83877tf_acorp",
.flags = 0,
.local = 0x0c05,
.init = w83877f_init,
.close = w83877f_close,
.local = 0,
.init = w83877_init,
.close = w83877_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,

1340
src/sio/sio_w83977.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,680 +0,0 @@
/*
* 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.
*
* Emulation of the Winbond W83977F Super I/O Chip.
*
* Winbond W83977F Super I/O Chip
* Used by the Award 430TX
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2020 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pci.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#define HEFRAS (dev->regs[0x26] & 0x40)
typedef struct w83977f_t {
uint8_t id;
uint8_t tries;
uint8_t regs[48];
uint8_t dev_regs[256][208];
int locked;
int rw_locked;
int cur_reg;
int base_address;
int type;
int hefras;
fdc_t *fdc;
lpt_t *lpt;
serial_t *uart[2];
} w83977f_t;
static int next_id = 0;
static void w83977f_write(uint16_t port, uint8_t val, void *priv);
static uint8_t w83977f_read(uint16_t port, void *priv);
static void
w83977f_remap(w83977f_t *dev)
{
io_removehandler(FDC_PRIMARY_ADDR, 0x0002,
w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
io_removehandler(FDC_SECONDARY_ADDR, 0x0002,
w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
dev->base_address = (HEFRAS ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR);
io_sethandler(dev->base_address, 0x0002,
w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
}
static uint8_t
get_lpt_length(w83977f_t *dev)
{
uint8_t length = 4;
if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x04))
length = 8;
return length;
}
static void
w83977f_fdc_handler(w83977f_t *dev)
{
uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31];
if (dev->id == 1)
return;
fdc_remove(dev->fdc);
if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8))
fdc_set_base(dev->fdc, io_base);
fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f);
}
static void
w83977f_lpt_handler(w83977f_t *dev)
{
uint16_t io_mask;
uint16_t io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31];
int io_len = get_lpt_length(dev);
io_base &= (0xff8 | io_len);
io_mask = 0xffc;
if (io_len == 8)
io_mask = 0xff8;
lpt_port_remove(dev->lpt);
if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask))
lpt_port_setup(dev->lpt, io_base);
lpt_port_irq(dev->lpt, dev->dev_regs[1][0x40] & 0x0f);
}
static void
w83977f_serial_handler(w83977f_t *dev, int uart)
{
uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31];
double clock_src = 24000000.0 / 13.0;
serial_remove(dev->uart[uart]);
if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8))
serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f);
switch (dev->dev_regs[2 + uart][0xc0] & 0x03) {
case 0x00:
clock_src = 24000000.0 / 13.0;
break;
case 0x01:
clock_src = 24000000.0 / 12.0;
break;
case 0x02:
clock_src = 24000000.0 / 1.0;
break;
case 0x03:
clock_src = 24000000.0 / 1.625;
break;
default:
break;
}
serial_set_clock_src(dev->uart[uart], clock_src);
}
static void
w83977f_write(uint16_t port, uint8_t val, void *priv)
{
w83977f_t *dev = (w83977f_t *) priv;
uint8_t index = (port & 1) ? 0 : 1;
uint8_t valxor = 0;
uint8_t ld = dev->regs[7];
if (index) {
if ((val == 0x87) && !dev->locked) {
if (dev->tries) {
dev->locked = 1;
dev->tries = 0;
} else
dev->tries++;
} else {
if (dev->locked) {
if (val == 0xaa)
dev->locked = 0;
else
dev->cur_reg = val;
} else {
if (dev->tries)
dev->tries = 0;
}
}
return;
} else {
if (dev->locked) {
if (dev->rw_locked)
return;
if (dev->cur_reg >= 0x30) {
valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30];
dev->dev_regs[ld][dev->cur_reg - 0x30] = val;
} else {
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
}
} else
return;
}
switch (dev->cur_reg) {
case 0x02:
#if 0
if (valxor & 0x02)
softresetx86();
#endif
break;
case 0x22:
if (valxor & 0x20)
w83977f_serial_handler(dev, 1);
if (valxor & 0x10)
w83977f_serial_handler(dev, 0);
if (valxor & 0x08)
w83977f_lpt_handler(dev);
if (valxor & 0x01)
w83977f_fdc_handler(dev);
break;
case 0x26:
if (valxor & 0x40)
w83977f_remap(dev);
if (valxor & 0x20)
dev->rw_locked = (val & 0x20) ? 1 : 0;
break;
case 0x30:
if (valxor & 0x01)
switch (ld) {
case 0x00:
w83977f_fdc_handler(dev);
break;
case 0x01:
w83977f_lpt_handler(dev);
break;
case 0x02:
case 0x03:
w83977f_serial_handler(dev, ld - 2);
break;
default:
break;
}
break;
case 0x60:
case 0x61:
if (valxor & 0xff)
switch (ld) {
case 0x00:
w83977f_fdc_handler(dev);
break;
case 0x01:
w83977f_lpt_handler(dev);
break;
case 0x02:
case 0x03:
w83977f_serial_handler(dev, ld - 2);
break;
default:
break;
}
break;
case 0x70:
if (valxor & 0x0f)
switch (ld) {
case 0x00:
w83977f_fdc_handler(dev);
break;
case 0x01:
w83977f_lpt_handler(dev);
break;
case 0x02:
case 0x03:
w83977f_serial_handler(dev, ld - 2);
break;
default:
break;
}
break;
case 0xf0:
switch (ld) {
case 0x00:
if (dev->id == 1)
break;
if (!dev->id && (valxor & 0x20))
fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1);
if (!dev->id && (valxor & 0x10))
fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0);
if (!dev->id && (valxor & 0x01))
fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0);
break;
case 0x01:
if (valxor & 0x07)
w83977f_lpt_handler(dev);
break;
case 0x02:
case 0x03:
if (valxor & 0x03)
w83977f_serial_handler(dev, ld - 2);
break;
default:
break;
}
break;
case 0xf1:
switch (ld) {
case 0x00:
if (dev->id == 1)
break;
if (!dev->id && (valxor & 0xc0))
fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6);
if (!dev->id && (valxor & 0x0c))
fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2);
if (!dev->id && (valxor & 0x02))
fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0);
if (!dev->id && (valxor & 0x01))
fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0);
break;
default:
break;
}
break;
case 0xf2:
switch (ld) {
case 0x00:
if (dev->id == 1)
break;
if (!dev->id && (valxor & 0xc0))
fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6);
if (!dev->id && (valxor & 0x30))
fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4);
if (!dev->id && (valxor & 0x0c))
fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2);
if (!dev->id && (valxor & 0x03))
fdc_update_rwc(dev->fdc, 0, val & 0x03);
break;
default:
break;
}
break;
case 0xf4:
case 0xf5:
case 0xf6:
case 0xf7:
switch (ld) {
case 0x00:
if (dev->id == 1)
break;
if (!dev->id && (valxor & 0x18))
fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3);
break;
default:
break;
}
break;
default:
break;
}
}
static uint8_t
w83977f_read(uint16_t port, void *priv)
{
w83977f_t *dev = (w83977f_t *) priv;
uint8_t ret = 0xff;
uint8_t index = (port & 1) ? 0 : 1;
uint8_t ld = dev->regs[7];
if (dev->locked) {
if (index)
ret = dev->cur_reg;
else {
if (!dev->rw_locked) {
if (!dev->id && ((dev->cur_reg == 0xf2) && (ld == 0x00)))
ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6));
else if (dev->cur_reg >= 0x30)
ret = dev->dev_regs[ld][dev->cur_reg - 0x30];
else
ret = dev->regs[dev->cur_reg];
}
}
}
return ret;
}
static void
w83977f_reset(w83977f_t *dev)
{
memset(dev->regs, 0, 48);
for (uint16_t i = 0; i < 256; i++)
memset(dev->dev_regs[i], 0, 208);
if (dev->type < 2) {
dev->regs[0x20] = 0x97;
dev->regs[0x21] = dev->type ? 0x73 : 0x71;
} else {
dev->regs[0x20] = 0x52;
dev->regs[0x21] = 0xf0;
}
dev->regs[0x22] = 0xff;
dev->regs[0x24] = dev->type ? 0x84 : 0xa4;
dev->regs[0x26] = dev->hefras;
/* WARNING: Array elements are register - 0x30. */
/* Logical Device 0 (FDC) */
dev->dev_regs[0][0x00] = 0x01;
if (!dev->type)
dev->dev_regs[0][0x01] = 0x02;
if (next_id == 1) {
dev->dev_regs[0][0x30] = 0x03;
dev->dev_regs[0][0x31] = 0x70;
} else {
dev->dev_regs[0][0x30] = 0x03;
dev->dev_regs[0][0x31] = 0xf0;
}
dev->dev_regs[0][0x40] = 0x06;
if (!dev->type)
dev->dev_regs[0][0x41] = 0x02; /* Read-only */
dev->dev_regs[0][0x44] = 0x02;
dev->dev_regs[0][0xc0] = 0x0e;
/* Logical Device 1 (Parallel Port) */
dev->dev_regs[1][0x00] = 0x01;
if (!dev->type)
dev->dev_regs[1][0x01] = 0x02;
if (next_id == 1) {
dev->dev_regs[1][0x30] = 0x02;
dev->dev_regs[1][0x31] = 0x78;
dev->dev_regs[1][0x40] = 0x05;
} else {
dev->dev_regs[1][0x30] = 0x03;
dev->dev_regs[1][0x31] = 0x78;
dev->dev_regs[1][0x40] = 0x07;
}
if (!dev->type)
dev->dev_regs[1][0x41] = 0x01 /*0x02*/; /* Read-only */
dev->dev_regs[1][0x44] = 0x04;
dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is printer mode. */
/* Logical Device 2 (UART A) */
dev->dev_regs[2][0x00] = 0x01;
if (!dev->type)
dev->dev_regs[2][0x01] = 0x02;
if (next_id == 1) {
dev->dev_regs[2][0x30] = 0x03;
dev->dev_regs[2][0x31] = 0xe8;
} else {
dev->dev_regs[2][0x30] = 0x03;
dev->dev_regs[2][0x31] = 0xf8;
}
dev->dev_regs[2][0x40] = 0x04;
if (!dev->type)
dev->dev_regs[2][0x41] = 0x02; /* Read-only */
/* Logical Device 3 (UART B) */
dev->dev_regs[3][0x00] = 0x01;
if (!dev->type)
dev->dev_regs[3][0x01] = 0x02;
if (next_id == 1) {
dev->dev_regs[3][0x30] = 0x02;
dev->dev_regs[3][0x31] = 0xe8;
} else {
dev->dev_regs[3][0x30] = 0x02;
dev->dev_regs[3][0x31] = 0xf8;
}
dev->dev_regs[3][0x40] = 0x03;
if (!dev->type)
dev->dev_regs[3][0x41] = 0x02; /* Read-only */
/* Logical Device 4 (RTC) */
if (!dev->type) {
dev->dev_regs[4][0x00] = 0x01;
dev->dev_regs[4][0x01] = 0x02;
dev->dev_regs[4][0x30] = 0x00;
dev->dev_regs[4][0x31] = 0x70;
dev->dev_regs[4][0x40] = 0x08;
dev->dev_regs[4][0x41] = 0x02; /* Read-only */
}
/* Logical Device 5 (KBC) */
dev->dev_regs[5][0x00] = 0x01;
if (!dev->type)
dev->dev_regs[5][0x01] = 0x02;
dev->dev_regs[5][0x30] = 0x00;
dev->dev_regs[5][0x31] = 0x60;
dev->dev_regs[5][0x32] = 0x00;
dev->dev_regs[5][0x33] = 0x64;
dev->dev_regs[5][0x40] = 0x01;
if (!dev->type)
dev->dev_regs[5][0x41] = 0x02; /* Read-only */
dev->dev_regs[5][0x42] = 0x0c;
if (!dev->type)
dev->dev_regs[5][0x43] = 0x02; /* Read-only? */
dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40;
/* Logical Device 6 (IR) = UART C */
if (!dev->type) {
dev->dev_regs[6][0x01] = 0x02;
dev->dev_regs[6][0x41] = 0x02; /* Read-only */
dev->dev_regs[6][0x44] = 0x04;
dev->dev_regs[6][0x45] = 0x04;
}
/* Logical Device 7 (Auxiliary I/O Part I) */
if (!dev->type)
dev->dev_regs[7][0x01] = 0x02;
if (!dev->type)
dev->dev_regs[7][0x41] = 0x02; /* Read-only */
if (!dev->type)
dev->dev_regs[7][0x43] = 0x02; /* Read-only? */
dev->dev_regs[7][0xb0] = 0x01;
dev->dev_regs[7][0xb1] = 0x01;
dev->dev_regs[7][0xb2] = 0x01;
dev->dev_regs[7][0xb3] = 0x01;
dev->dev_regs[7][0xb4] = 0x01;
dev->dev_regs[7][0xb5] = 0x01;
dev->dev_regs[7][0xb6] = 0x01;
if (dev->type)
dev->dev_regs[7][0xb7] = 0x01;
/* Logical Device 8 (Auxiliary I/O Part II) */
if (!dev->type)
dev->dev_regs[8][0x01] = 0x02;
if (!dev->type)
dev->dev_regs[8][0x41] = 0x02; /* Read-only */
if (!dev->type)
dev->dev_regs[8][0x43] = 0x02; /* Read-only? */
dev->dev_regs[8][0xb8] = 0x01;
dev->dev_regs[8][0xb9] = 0x01;
dev->dev_regs[8][0xba] = 0x01;
dev->dev_regs[8][0xbb] = 0x01;
dev->dev_regs[8][0xbc] = 0x01;
dev->dev_regs[8][0xbd] = 0x01;
dev->dev_regs[8][0xbe] = 0x01;
dev->dev_regs[8][0xbf] = 0x01;
/* Logical Device 9 (Auxiliary I/O Part III) */
if (dev->type) {
dev->dev_regs[9][0xb0] = 0x01;
dev->dev_regs[9][0xb1] = 0x01;
dev->dev_regs[9][0xb2] = 0x01;
dev->dev_regs[9][0xb3] = 0x01;
dev->dev_regs[9][0xb4] = 0x01;
dev->dev_regs[9][0xb5] = 0x01;
dev->dev_regs[9][0xb6] = 0x01;
dev->dev_regs[9][0xb7] = 0x01;
dev->dev_regs[10][0xc0] = 0x8f;
}
if (dev->id == 1) {
serial_setup(dev->uart[0], COM3_ADDR, COM3_IRQ);
serial_setup(dev->uart[1], COM4_ADDR, COM4_IRQ);
} else {
fdc_reset(dev->fdc);
serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ);
serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ);
w83977f_fdc_handler(dev);
}
w83977f_lpt_handler(dev);
w83977f_serial_handler(dev, 0);
w83977f_serial_handler(dev, 1);
w83977f_remap(dev);
dev->locked = 0;
dev->rw_locked = 0;
}
static void
w83977f_close(void *priv)
{
w83977f_t *dev = (w83977f_t *) priv;
next_id = 0;
free(dev);
}
static void *
w83977f_init(const device_t *info)
{
w83977f_t *dev = (w83977f_t *) calloc(1, sizeof(w83977f_t));
dev->type = info->local & 0x0f;
dev->hefras = info->local & 0x40;
dev->id = next_id;
if (next_id == 1)
dev->hefras ^= 0x40;
else
dev->fdc = device_add(&fdc_at_smc_device);
dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1);
dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2);
dev->lpt = device_add_inst(&lpt_port_device, next_id + 1);
w83977f_reset(dev);
next_id++;
return dev;
}
const device_t w83977f_device = {
.name = "Winbond W83977F Super I/O",
.internal_name = "w83977f",
.flags = 0,
.local = 0,
.init = w83977f_init,
.close = w83977f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83977f_370_device = {
.name = "Winbond W83977F Super I/O (Port 370h)",
.internal_name = "w83977f_370",
.flags = 0,
.local = 0x40,
.init = w83977f_init,
.close = w83977f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83977tf_device = {
.name = "Winbond W83977TF Super I/O",
.internal_name = "w83977tf",
.flags = 0,
.local = 1,
.init = w83977f_init,
.close = w83977f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83977ef_device = {
.name = "Winbond W83977TF Super I/O",
.internal_name = "w83977ef",
.flags = 0,
.local = 2,
.init = w83977f_init,
.close = w83977f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t w83977ef_370_device = {
.name = "Winbond W83977TF Super I/O (Port 370h)",
.internal_name = "w83977ef_370",
.flags = 0,
.local = 0x42,
.init = w83977f_init,
.close = w83977f_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};