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:
136
src/device/lpt.c
136
src/device/lpt.c
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user