2020-07-06 18:45:34 -03:00
|
|
|
/*
|
2022-11-13 16:37:58 -05:00
|
|
|
* 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.
|
2020-07-06 18:45:34 -03:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* This file is part of the 86Box distribution.
|
2020-07-06 18:45:34 -03:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Implementation of the STMicroelectronics STPC series of SoCs.
|
2020-07-06 18:45:34 -03:00
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Authors: RichardG, <richardg867@gmail.com>
|
2020-07-06 18:45:34 -03:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Copyright 2020 RichardG.
|
2020-07-06 18:45:34 -03:00
|
|
|
*/
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
#define HAVE_STDARG_H
|
|
|
|
|
#include <86box/86box.h>
|
|
|
|
|
#include <86box/mem.h>
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
#include <86box/smram.h>
|
2020-07-06 18:45:34 -03:00
|
|
|
#include <86box/io.h>
|
|
|
|
|
#include <86box/pci.h>
|
2020-07-09 16:50:19 -03:00
|
|
|
#include <86box/pic.h>
|
2020-07-10 02:05:49 +02:00
|
|
|
#include <86box/timer.h>
|
|
|
|
|
#include <86box/pit.h>
|
2020-07-06 18:45:34 -03:00
|
|
|
#include <86box/device.h>
|
2023-06-26 12:47:04 -04:00
|
|
|
#include <86box/plat_unused.h>
|
2020-07-06 18:45:34 -03:00
|
|
|
#include <86box/port_92.h>
|
2020-07-07 13:25:17 -03:00
|
|
|
#include <86box/usb.h>
|
2020-07-09 16:50:19 -03:00
|
|
|
#include <86box/hdc_ide.h>
|
|
|
|
|
#include <86box/hdc_ide_sff8038i.h>
|
2020-07-14 22:24:22 -03:00
|
|
|
#include <86box/serial.h>
|
|
|
|
|
#include <86box/lpt.h>
|
2020-07-06 18:45:34 -03:00
|
|
|
#include <86box/chipset.h>
|
|
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
#define STPC_CONSUMER2 0x104a020b
|
|
|
|
|
#define STPC_ATLAS 0x104a0210
|
|
|
|
|
#define STPC_ELITE 0x104a021a
|
|
|
|
|
#define STPC_CLIENT 0x100e55cc
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
typedef struct stpc_t {
|
2023-08-07 03:04:52 +02:00
|
|
|
uint8_t nb_slot;
|
|
|
|
|
uint8_t sb_slot;
|
|
|
|
|
uint8_t ide_slot;
|
|
|
|
|
uint8_t usb_slot;
|
|
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
uint32_t local;
|
2020-07-07 13:25:17 -03:00
|
|
|
|
|
|
|
|
/* Main registers (port 22h/23h) */
|
2022-09-18 17:12:38 -04:00
|
|
|
uint8_t reg_offset;
|
|
|
|
|
uint8_t regs[256];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
/* Host bus interface */
|
2022-09-18 17:12:38 -04:00
|
|
|
uint16_t host_base;
|
|
|
|
|
uint8_t host_offset;
|
2023-08-07 03:04:52 +02:00
|
|
|
uint8_t usb_irq_state;
|
2022-09-18 17:12:38 -04:00
|
|
|
uint8_t host_regs[256];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
/* Local bus */
|
2022-09-18 17:12:38 -04:00
|
|
|
uint16_t localbus_base;
|
|
|
|
|
uint8_t localbus_offset;
|
2023-08-07 03:04:52 +02:00
|
|
|
uint8_t pad0;
|
2022-09-18 17:12:38 -04:00
|
|
|
uint8_t localbus_regs[256];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
/* PCI devices */
|
2022-09-18 17:12:38 -04:00
|
|
|
uint8_t pci_conf[4][256];
|
|
|
|
|
smram_t *smram;
|
|
|
|
|
usb_t *usb;
|
|
|
|
|
sff8038i_t *bm[2];
|
2020-07-06 18:45:34 -03:00
|
|
|
} stpc_t;
|
|
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
typedef struct stpc_serial_t {
|
|
|
|
|
serial_t *uart[2];
|
2020-07-14 22:24:22 -03:00
|
|
|
} stpc_serial_t;
|
|
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
typedef struct stpc_lpt_t {
|
|
|
|
|
uint8_t unlocked;
|
|
|
|
|
uint8_t offset;
|
|
|
|
|
uint8_t reg1;
|
|
|
|
|
uint8_t reg4;
|
2020-07-14 22:24:22 -03:00
|
|
|
} stpc_lpt_t;
|
|
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
#ifdef ENABLE_STPC_LOG
|
|
|
|
|
int stpc_do_log = ENABLE_STPC_LOG;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_log(const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
if (stpc_do_log) {
|
2022-09-18 17:12:38 -04:00
|
|
|
va_start(ap, fmt);
|
|
|
|
|
pclog_ex(fmt, ap);
|
|
|
|
|
va_end(ap);
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
2022-09-18 17:12:38 -04:00
|
|
|
# define stpc_log(fmt, ...)
|
2020-07-06 18:45:34 -03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_recalcmapping(stpc_t *dev)
|
|
|
|
|
{
|
2023-05-11 03:02:36 -04:00
|
|
|
uint32_t base;
|
|
|
|
|
uint32_t size;
|
2022-09-18 17:12:38 -04:00
|
|
|
int state;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
shadowbios = 0;
|
2020-07-06 18:45:34 -03:00
|
|
|
shadowbios_write = 0;
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
for (uint8_t reg = 0; reg <= 3; reg++) {
|
|
|
|
|
for (uint8_t bitpair = 0; bitpair <= ((reg == 3) ? 0 : 3); bitpair++) {
|
2022-09-18 17:12:38 -04:00
|
|
|
if (reg == 3) {
|
|
|
|
|
size = 0x10000;
|
|
|
|
|
base = 0xf0000;
|
|
|
|
|
} else {
|
|
|
|
|
size = 0x4000;
|
|
|
|
|
base = 0xc0000 + (size * ((reg * 4) + bitpair));
|
|
|
|
|
}
|
|
|
|
|
stpc_log("STPC: Shadowing for %05X-%05X (reg %02X bp %d wmask %02X rmask %02X) =", base, base + size - 1, 0x25 + reg, bitpair, 1 << (bitpair * 2), 1 << ((bitpair * 2) + 1));
|
|
|
|
|
|
|
|
|
|
state = 0;
|
|
|
|
|
if (dev->regs[0x25 + reg] & (1 << (bitpair * 2))) {
|
|
|
|
|
stpc_log(" w on");
|
|
|
|
|
state |= MEM_WRITE_INTERNAL;
|
|
|
|
|
if (base >= 0xe0000)
|
|
|
|
|
shadowbios_write |= 1;
|
|
|
|
|
} else {
|
|
|
|
|
stpc_log(" w off");
|
|
|
|
|
state |= MEM_WRITE_EXTANY;
|
|
|
|
|
}
|
|
|
|
|
if (dev->regs[0x25 + reg] & (1 << ((bitpair * 2) + 1))) {
|
|
|
|
|
stpc_log("; r on\n");
|
|
|
|
|
state |= MEM_READ_INTERNAL;
|
|
|
|
|
if (base >= 0xe0000)
|
|
|
|
|
shadowbios |= 1;
|
|
|
|
|
} else {
|
|
|
|
|
stpc_log("; r off\n");
|
|
|
|
|
state |= MEM_READ_EXTANY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mem_set_mem_state(base, size, state);
|
|
|
|
|
}
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
2021-08-09 16:10:55 +02:00
|
|
|
flushmmucache_nopc();
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_host_write(uint16_t addr, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: host_write(%04X, %02X)\n", addr, val);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == dev->host_base)
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->host_offset = val;
|
2020-11-23 14:49:13 -03:00
|
|
|
else if (addr == (dev->host_base + 4))
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->host_regs[dev->host_offset] = val;
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
|
|
|
|
stpc_host_read(uint16_t addr, void *priv)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == dev->host_base)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->host_offset;
|
2020-11-23 14:49:13 -03:00
|
|
|
else if (addr == (dev->host_base + 4))
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->host_regs[dev->host_offset];
|
2020-07-06 18:45:34 -03:00
|
|
|
else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: host_read(%04X) = %02X\n", addr, ret);
|
2020-07-06 18:45:34 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_localbus_write(uint16_t addr, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: localbus_write(%04X, %02X)\n", addr, val);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == dev->localbus_base)
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->localbus_offset = val;
|
2020-11-23 14:49:13 -03:00
|
|
|
else if (addr == (dev->localbus_base + 4))
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->localbus_regs[addr] = val;
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
|
|
|
|
stpc_localbus_read(uint16_t addr, void *priv)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == dev->localbus_base)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->localbus_offset;
|
2020-11-23 14:49:13 -03:00
|
|
|
else if (addr == (dev->localbus_base + 4))
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->localbus_regs[dev->localbus_offset];
|
2020-07-06 18:45:34 -03:00
|
|
|
else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: localbus_read(%04X) = %02X\n", addr, ret);
|
2020-07-06 18:45:34 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_nb_write(int func, int addr, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: nb_write(%d, %02X, %02X)\n", func, addr, val);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
return;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
switch (addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x00:
|
|
|
|
|
case 0x01:
|
|
|
|
|
case 0x02:
|
|
|
|
|
case 0x03:
|
|
|
|
|
case 0x04:
|
|
|
|
|
case 0x06:
|
|
|
|
|
case 0x07:
|
|
|
|
|
case 0x08:
|
|
|
|
|
case 0x09:
|
|
|
|
|
case 0x0a:
|
|
|
|
|
case 0x0b:
|
|
|
|
|
case 0x0e:
|
|
|
|
|
case 0x51:
|
|
|
|
|
case 0x53:
|
|
|
|
|
case 0x54:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case 0x05:
|
|
|
|
|
val &= 0x01;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x50:
|
|
|
|
|
val &= 0x1f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x52:
|
|
|
|
|
val &= 0x70;
|
|
|
|
|
break;
|
2023-06-26 22:31:03 -04:00
|
|
|
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[0][addr] = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
|
|
|
|
stpc_nb_read(int func, int addr, void *priv)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-06 18:45:34 -03:00
|
|
|
else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->pci_conf[0][addr];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: nb_read(%d, %02X) = %02X\n", func, addr, ret);
|
2020-07-06 18:45:34 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-09 16:50:19 -03:00
|
|
|
static void
|
|
|
|
|
stpc_ide_handlers(stpc_t *dev, int bus)
|
|
|
|
|
{
|
2023-05-11 03:02:36 -04:00
|
|
|
uint16_t main;
|
|
|
|
|
uint16_t side;
|
2020-07-09 16:50:19 -03:00
|
|
|
|
|
|
|
|
if (bus & 0x01) {
|
2022-09-18 17:12:38 -04:00
|
|
|
ide_pri_disable();
|
|
|
|
|
|
|
|
|
|
if (dev->pci_conf[2][0x09] & 0x01) {
|
|
|
|
|
main = (dev->pci_conf[2][0x11] << 8) | (dev->pci_conf[2][0x10] & 0xf8);
|
|
|
|
|
side = ((dev->pci_conf[2][0x15] << 8) | (dev->pci_conf[2][0x14] & 0xfc)) + 2;
|
|
|
|
|
} else {
|
|
|
|
|
main = 0x1f0;
|
|
|
|
|
side = 0x3f6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ide_set_base(0, main);
|
|
|
|
|
ide_set_side(0, side);
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: IDE primary main %04X side %04X enable ", main, side);
|
|
|
|
|
if ((dev->pci_conf[2][0x04] & 0x01) && !(dev->pci_conf[2][0x48] & 0x04)) {
|
|
|
|
|
stpc_log("1\n");
|
|
|
|
|
ide_pri_enable();
|
|
|
|
|
} else {
|
|
|
|
|
stpc_log("0\n");
|
|
|
|
|
}
|
2020-07-09 16:50:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bus & 0x02) {
|
2022-09-18 17:12:38 -04:00
|
|
|
ide_sec_disable();
|
|
|
|
|
|
|
|
|
|
if (dev->pci_conf[2][0x09] & 0x04) {
|
|
|
|
|
main = (dev->pci_conf[2][0x19] << 8) | (dev->pci_conf[2][0x18] & 0xf8);
|
|
|
|
|
side = ((dev->pci_conf[2][0x1d] << 8) | (dev->pci_conf[2][0x1c] & 0xfc)) + 2;
|
|
|
|
|
} else {
|
|
|
|
|
main = 0x170;
|
|
|
|
|
side = 0x376;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ide_set_base(1, main);
|
|
|
|
|
ide_set_side(1, side);
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: IDE secondary main %04X side %04X enable ", main, side);
|
|
|
|
|
if ((dev->pci_conf[2][0x04] & 0x01) && !(dev->pci_conf[2][0x48] & 0x08)) {
|
|
|
|
|
stpc_log("1\n");
|
|
|
|
|
ide_sec_enable();
|
|
|
|
|
} else {
|
|
|
|
|
stpc_log("0\n");
|
|
|
|
|
}
|
2020-07-09 16:50:19 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-10 04:23:10 +02:00
|
|
|
static void
|
|
|
|
|
stpc_ide_bm_handlers(stpc_t *dev)
|
|
|
|
|
{
|
|
|
|
|
uint16_t base = (dev->pci_conf[2][0x20] & 0xf0) | (dev->pci_conf[2][0x21] << 8);
|
|
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
sff_bus_master_handler(dev->bm[0], dev->pci_conf[2][0x04] & 1, base);
|
|
|
|
|
sff_bus_master_handler(dev->bm[1], dev->pci_conf[2][0x04] & 1, base + 8);
|
2020-07-10 04:23:10 +02:00
|
|
|
}
|
|
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
static void
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_ide_write(int func, int addr, uint8_t val, void *priv)
|
2020-07-06 18:45:34 -03:00
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: ide_write(%d, %02X, %02X)\n", func, addr, val);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
return;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-06 20:24:24 -03:00
|
|
|
switch (addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x04:
|
|
|
|
|
dev->pci_conf[2][addr] = (dev->pci_conf[2][addr] & 0xbe) | (val & 0x41);
|
|
|
|
|
stpc_ide_handlers(dev, 0x03);
|
|
|
|
|
stpc_ide_bm_handlers(dev);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x05:
|
|
|
|
|
dev->pci_conf[2][addr] = val & 0x01;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x07:
|
|
|
|
|
dev->pci_conf[2][addr] &= ~(val & 0x70);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x09:
|
|
|
|
|
dev->pci_conf[2][addr] = (dev->pci_conf[2][addr] & 0x8a) | (val & 0x05);
|
|
|
|
|
stpc_ide_handlers(dev, 0x03);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x10:
|
|
|
|
|
dev->pci_conf[2][addr] = (val & 0xf8) | 1;
|
|
|
|
|
stpc_ide_handlers(dev, 0x01);
|
|
|
|
|
break;
|
|
|
|
|
case 0x11:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
stpc_ide_handlers(dev, 0x01);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x14:
|
|
|
|
|
dev->pci_conf[2][addr] = (val & 0xfc) | 1;
|
|
|
|
|
stpc_ide_handlers(dev, 0x01);
|
|
|
|
|
break;
|
|
|
|
|
case 0x15:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
stpc_ide_handlers(dev, 0x01);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x18:
|
|
|
|
|
dev->pci_conf[2][addr] = (val & 0xf8) | 1;
|
|
|
|
|
stpc_ide_handlers(dev, 0x02);
|
|
|
|
|
break;
|
|
|
|
|
case 0x19:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
stpc_ide_handlers(dev, 0x02);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x1c:
|
|
|
|
|
dev->pci_conf[2][addr] = (val & 0xfc) | 1;
|
|
|
|
|
stpc_ide_handlers(dev, 0x02);
|
|
|
|
|
break;
|
|
|
|
|
case 0x1d:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
stpc_ide_handlers(dev, 0x02);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x20:
|
|
|
|
|
dev->pci_conf[2][0x20] = (val & 0xf0) | 1;
|
|
|
|
|
stpc_ide_bm_handlers(dev);
|
|
|
|
|
break;
|
|
|
|
|
case 0x21:
|
|
|
|
|
dev->pci_conf[2][0x21] = val;
|
|
|
|
|
stpc_ide_bm_handlers(dev);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x3c:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x40:
|
|
|
|
|
case 0x41:
|
|
|
|
|
case 0x42:
|
|
|
|
|
case 0x43:
|
|
|
|
|
case 0x44:
|
|
|
|
|
case 0x45:
|
|
|
|
|
case 0x46:
|
|
|
|
|
case 0x47:
|
|
|
|
|
dev->pci_conf[2][addr] = val;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x48:
|
|
|
|
|
dev->pci_conf[2][addr] = (val & 0x8c) & ~(val & 0x03);
|
|
|
|
|
stpc_ide_handlers(dev, 0x03);
|
|
|
|
|
if (val & 0x02) {
|
|
|
|
|
sff_bus_master_set_irq(0x01, dev->bm[0]);
|
|
|
|
|
sff_bus_master_set_irq(0x01, dev->bm[1]);
|
|
|
|
|
}
|
|
|
|
|
if (val & 0x01) {
|
|
|
|
|
sff_bus_master_set_irq(0x00, dev->bm[0]);
|
|
|
|
|
sff_bus_master_set_irq(0x00, dev->bm[1]);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-06-26 22:31:03 -04:00
|
|
|
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_ide_read(int func, int addr, void *priv)
|
2020-07-06 18:45:34 -03:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-10 04:23:10 +02:00
|
|
|
else {
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->pci_conf[2][addr];
|
|
|
|
|
if (addr == 0x48) {
|
|
|
|
|
ret &= 0xfc;
|
|
|
|
|
ret |= !!(dev->bm[0]->status & 0x04);
|
|
|
|
|
ret |= (!!(dev->bm[1]->status & 0x04)) << 1;
|
|
|
|
|
}
|
2020-07-10 04:23:10 +02:00
|
|
|
}
|
2020-07-07 13:25:17 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: ide_read(%d, %02X) = %02X\n", func, addr, ret);
|
2020-07-07 13:25:17 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_isab_write(int func, int addr, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
if ((func == 1) && (dev->local != STPC_ATLAS)) {
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_ide_write(0, addr, val, priv);
|
|
|
|
|
return;
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: isab_write(%d, %02X, %02X)\n", func, addr, val);
|
2020-07-07 13:25:17 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
return;
|
2020-07-07 13:25:17 -03:00
|
|
|
|
|
|
|
|
switch (addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x00:
|
|
|
|
|
case 0x01:
|
|
|
|
|
case 0x02:
|
|
|
|
|
case 0x03:
|
|
|
|
|
case 0x04:
|
|
|
|
|
case 0x06:
|
|
|
|
|
case 0x07:
|
|
|
|
|
case 0x08:
|
|
|
|
|
case 0x09:
|
|
|
|
|
case 0x0a:
|
|
|
|
|
case 0x0b:
|
|
|
|
|
case 0x0e:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case 0x05:
|
|
|
|
|
val &= 0x01;
|
|
|
|
|
break;
|
2023-06-26 22:31:03 -04:00
|
|
|
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[1][addr] = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
|
|
|
|
stpc_isab_read(int func, int addr, void *priv)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-07 13:25:17 -03:00
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
if ((func == 1) && (dev->local != STPC_ATLAS))
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = stpc_ide_read(0, addr, priv);
|
2020-07-07 13:25:17 -03:00
|
|
|
else if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-06 18:45:34 -03:00
|
|
|
else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->pci_conf[1][addr];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: isab_read(%d, %02X) = %02X\n", func, addr, ret);
|
2020-07-06 18:45:34 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-06 20:24:24 -03:00
|
|
|
static void
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_usb_write(int func, int addr, uint8_t val, void *priv)
|
2020-07-06 20:24:24 -03:00
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: usb_write(%d, %02X, %02X)\n", func, addr, val);
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
return;
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
switch (addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x00:
|
|
|
|
|
case 0x01:
|
|
|
|
|
case 0x02:
|
|
|
|
|
case 0x03:
|
|
|
|
|
case 0x04:
|
|
|
|
|
case 0x06:
|
|
|
|
|
case 0x07:
|
|
|
|
|
case 0x08:
|
|
|
|
|
case 0x09:
|
|
|
|
|
case 0x0a:
|
|
|
|
|
case 0x0b:
|
|
|
|
|
case 0x0e:
|
|
|
|
|
case 0x10:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case 0x05:
|
|
|
|
|
val &= 0x01;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x11:
|
|
|
|
|
dev->pci_conf[3][addr] = val & 0xf0;
|
|
|
|
|
ohci_update_mem_mapping(dev->usb, dev->pci_conf[3][0x11], dev->pci_conf[3][0x12], dev->pci_conf[3][0x13], 1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x12:
|
|
|
|
|
case 0x13:
|
|
|
|
|
dev->pci_conf[3][addr] = val;
|
|
|
|
|
ohci_update_mem_mapping(dev->usb, dev->pci_conf[3][0x11], dev->pci_conf[3][0x12], dev->pci_conf[3][0x13], 1);
|
|
|
|
|
break;
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-07-06 20:24:24 -03:00
|
|
|
}
|
|
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
dev->pci_conf[3][addr] = val;
|
2020-07-06 20:24:24 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_usb_read(int func, int addr, void *priv)
|
2020-07-06 20:24:24 -03:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
if (func > 0)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = 0xff;
|
2020-07-06 20:24:24 -03:00
|
|
|
else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->pci_conf[3][addr];
|
2020-07-06 20:24:24 -03:00
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: usb_read(%d, %02X) = %02X\n", func, addr, ret);
|
2020-07-06 20:24:24 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
static void
|
|
|
|
|
stpc_remap_host(stpc_t *dev, uint16_t host_base)
|
|
|
|
|
{
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: Remapping host bus from %04X to %04X\n", dev->host_base, host_base);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
io_removehandler(dev->host_base, 5,
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_host_read, NULL, NULL, stpc_host_write, NULL, NULL, dev);
|
2020-07-06 18:45:34 -03:00
|
|
|
if (host_base) {
|
2022-09-18 17:12:38 -04:00
|
|
|
io_sethandler(host_base, 5,
|
|
|
|
|
stpc_host_read, NULL, NULL, stpc_host_write, NULL, NULL, dev);
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
dev->host_base = host_base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_remap_localbus(stpc_t *dev, uint16_t localbus_base)
|
|
|
|
|
{
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: Remapping local bus from %04X to %04X\n", dev->localbus_base, localbus_base);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
io_removehandler(dev->localbus_base, 5,
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_localbus_read, NULL, NULL, stpc_localbus_write, NULL, NULL, dev);
|
2020-07-06 18:45:34 -03:00
|
|
|
if (localbus_base) {
|
2022-09-18 17:12:38 -04:00
|
|
|
io_sethandler(localbus_base, 5,
|
|
|
|
|
stpc_localbus_read, NULL, NULL, stpc_localbus_write, NULL, NULL, dev);
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
dev->localbus_base = localbus_base;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-14 22:24:22 -03:00
|
|
|
static uint8_t
|
|
|
|
|
stpc_serial_handlers(uint8_t val)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_serial_t *dev = device_get_priv(&stpc_serial_device);
|
|
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
if (!dev) {
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_log("STPC: Not remapping UARTs, disabled by strap (raw %02X)\n", val);
|
|
|
|
|
return 0;
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
uint16_t uart0_io = 0x3f8;
|
|
|
|
|
uint16_t uart1_io = 0x3f8;
|
|
|
|
|
uint8_t uart0_irq = 4;
|
|
|
|
|
uint8_t uart1_irq = 3;
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
if (val & 0x10)
|
2022-09-18 17:12:38 -04:00
|
|
|
uart1_io &= 0xfeff;
|
2020-07-14 22:24:22 -03:00
|
|
|
if (val & 0x20)
|
2022-09-18 17:12:38 -04:00
|
|
|
uart1_io &= 0xffef;
|
2020-07-14 22:24:22 -03:00
|
|
|
if (val & 0x40)
|
2022-09-18 17:12:38 -04:00
|
|
|
uart0_io &= 0xfeff;
|
2020-07-14 22:24:22 -03:00
|
|
|
if (val & 0x80)
|
2022-09-18 17:12:38 -04:00
|
|
|
uart0_io &= 0xffef;
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
if (uart0_io == uart1_io) {
|
2022-09-18 17:12:38 -04:00
|
|
|
/* Apply defaults if both UARTs are set to the same address. */
|
|
|
|
|
stpc_log("STPC: Both UARTs set to %02X, resetting to defaults\n", uart0_io);
|
|
|
|
|
uart0_io = 0x3f8;
|
|
|
|
|
uart1_io = 0x2f8;
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
if (!(uart0_io & 0x100)) {
|
2022-09-18 17:12:38 -04:00
|
|
|
/* The address for UART0 establishes the IRQs for both ports. */
|
|
|
|
|
uart0_irq = 3;
|
|
|
|
|
uart1_irq = 4;
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: Remapping UART0 to %04X %d and UART1 to %04X %d (raw %02X)\n", uart0_io, uart0_irq, uart1_io, uart1_irq, val);
|
|
|
|
|
|
|
|
|
|
serial_remove(dev->uart[0]);
|
|
|
|
|
serial_setup(dev->uart[0], uart0_io, uart0_irq);
|
|
|
|
|
serial_remove(dev->uart[1]);
|
|
|
|
|
serial_setup(dev->uart[1], uart1_io, uart1_irq);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
static void
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
|
2020-07-06 18:45:34 -03:00
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
2020-07-08 17:54:05 -03:00
|
|
|
stpc_log("STPC: reg_write(%04X, %02X)\n", addr, val);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == 0x22) {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->reg_offset = val;
|
2020-07-06 18:45:34 -03:00
|
|
|
} else {
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_log("STPC: regs[%02X] = %02X\n", dev->reg_offset, val);
|
|
|
|
|
|
|
|
|
|
switch (dev->reg_offset) {
|
|
|
|
|
case 0x12:
|
|
|
|
|
if (dev->regs[0x10] == 0x07)
|
|
|
|
|
stpc_remap_host(dev, (dev->host_base & 0xff00) | val);
|
|
|
|
|
else if (dev->regs[0x10] == 0x06)
|
|
|
|
|
stpc_remap_localbus(dev, (dev->localbus_base & 0xff00) | val);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x13:
|
|
|
|
|
if (dev->regs[0x10] == 0x07)
|
|
|
|
|
stpc_remap_host(dev, (dev->host_base & 0x00ff) | (val << 8));
|
|
|
|
|
else if (dev->regs[0x10] == 0x06)
|
|
|
|
|
stpc_remap_localbus(dev, (dev->localbus_base & 0x00ff) | (val << 8));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x21:
|
|
|
|
|
val &= 0xfe;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x22:
|
|
|
|
|
val &= 0x7f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x25:
|
|
|
|
|
case 0x26:
|
|
|
|
|
case 0x27:
|
|
|
|
|
case 0x28:
|
|
|
|
|
if (dev->reg_offset == 0x28) {
|
|
|
|
|
val &= 0xe3;
|
|
|
|
|
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
|
|
|
|
}
|
|
|
|
|
dev->regs[dev->reg_offset] = val;
|
|
|
|
|
stpc_recalcmapping(dev);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x29:
|
|
|
|
|
val &= 0x0f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x36:
|
|
|
|
|
val &= 0x3f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x52:
|
|
|
|
|
case 0x53:
|
|
|
|
|
case 0x54:
|
|
|
|
|
case 0x55:
|
|
|
|
|
stpc_log("STPC: Set IRQ routing: INT %c -> %d\n", 0x41 + ((dev->reg_offset - 2) & 0x03), (val & 0x80) ? (val & 0xf) : -1);
|
|
|
|
|
val &= 0x8f;
|
|
|
|
|
pci_set_irq_routing(PCI_INTA + ((dev->reg_offset - 2) & 0x03), (val & 0x80) ? (val & 0xf) : PCI_IRQ_DISABLED);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x56:
|
|
|
|
|
case 0x57:
|
|
|
|
|
pic_elcr_write(dev->reg_offset, val, (dev->reg_offset & 1) ? &pic2 : &pic);
|
|
|
|
|
if (dev->reg_offset == 0x57)
|
|
|
|
|
refresh_at_enable = (val & 0x01);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x59:
|
|
|
|
|
val &= 0xf1;
|
|
|
|
|
stpc_serial_handlers(val);
|
|
|
|
|
break;
|
2023-06-26 12:47:04 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2022-09-18 17:12:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->regs[dev->reg_offset] = val;
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_reg_read(uint16_t addr, void *priv)
|
2020-07-06 18:45:34 -03:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
uint8_t ret;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
if (addr == 0x22)
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->reg_offset;
|
2020-07-07 15:38:34 -03:00
|
|
|
else if (dev->reg_offset >= 0xc0)
|
2022-09-18 17:12:38 -04:00
|
|
|
return 0xff; /* let the CPU code handle Cyrix CPU registers */
|
2020-07-10 02:05:49 +02:00
|
|
|
else if ((dev->reg_offset == 0x56) || (dev->reg_offset == 0x57)) {
|
2022-09-18 17:12:38 -04:00
|
|
|
/* ELCR registers. */
|
|
|
|
|
ret = pic_elcr_read(dev->reg_offset, (dev->reg_offset & 1) ? &pic2 : &pic);
|
|
|
|
|
if (dev->reg_offset == 0x57)
|
|
|
|
|
ret |= (dev->regs[dev->reg_offset] & 0x01);
|
2020-07-10 02:05:49 +02:00
|
|
|
} else
|
2022-09-18 17:12:38 -04:00
|
|
|
ret = dev->regs[dev->reg_offset];
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-09-08 21:44:10 -03:00
|
|
|
stpc_log("STPC: reg_read(%04X) = %02X\n", dev->reg_offset, ret);
|
2020-07-06 18:45:34 -03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_reset(void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: reset()\n");
|
|
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
memset(dev->regs, 0, sizeof(dev->regs));
|
|
|
|
|
dev->regs[0x7b] = 0xff;
|
2020-07-14 22:24:22 -03:00
|
|
|
if (device_get_priv(&stpc_lpt_device))
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->regs[0x4c] |= 0x80; /* LPT strap */
|
2020-07-20 15:24:51 -03:00
|
|
|
if (stpc_serial_handlers(0x00))
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->regs[0x4c] |= 0x03; /* UART straps */
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_setup(stpc_t *dev)
|
|
|
|
|
{
|
|
|
|
|
stpc_log("STPC: setup()\n");
|
|
|
|
|
|
2020-07-14 22:24:22 -03:00
|
|
|
/* Main register interface */
|
|
|
|
|
io_sethandler(0x22, 2,
|
2022-09-18 17:12:38 -04:00
|
|
|
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
|
2020-07-14 22:24:22 -03:00
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
/* Northbridge */
|
2020-11-23 14:49:13 -03:00
|
|
|
if (dev->local & STPC_CLIENT) {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->pci_conf[0][0x00] = 0x0e;
|
|
|
|
|
dev->pci_conf[0][0x01] = 0x10;
|
|
|
|
|
dev->pci_conf[0][0x02] = 0x64;
|
|
|
|
|
dev->pci_conf[0][0x03] = 0x05;
|
2020-07-07 13:25:17 -03:00
|
|
|
} else {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->pci_conf[0][0x00] = 0x4a;
|
|
|
|
|
dev->pci_conf[0][0x01] = 0x10;
|
|
|
|
|
dev->pci_conf[0][0x02] = 0x0a;
|
|
|
|
|
dev->pci_conf[0][0x03] = 0x02;
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
dev->pci_conf[0][0x04] = 0x07;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[0][0x06] = 0x80;
|
|
|
|
|
dev->pci_conf[0][0x07] = 0x02;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[0][0x0b] = 0x06;
|
|
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
/* ISA Bridge */
|
2020-11-23 14:49:13 -03:00
|
|
|
dev->pci_conf[1][0x00] = dev->local >> 16;
|
|
|
|
|
dev->pci_conf[1][0x01] = dev->local >> 24;
|
|
|
|
|
dev->pci_conf[1][0x02] = dev->local;
|
|
|
|
|
dev->pci_conf[1][0x03] = dev->local >> 8;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-06 20:24:24 -03:00
|
|
|
dev->pci_conf[1][0x04] = 0x0f;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
dev->pci_conf[1][0x06] = 0x80;
|
|
|
|
|
dev->pci_conf[1][0x07] = 0x02;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[1][0x0a] = 0x01;
|
|
|
|
|
dev->pci_conf[1][0x0b] = 0x06;
|
|
|
|
|
|
2020-07-11 00:42:38 +02:00
|
|
|
/* NOTE: This is an erratum in the STPC Atlas programming manual, the programming manuals for the other
|
2022-09-18 17:12:38 -04:00
|
|
|
STPC chipsets say 0x80, which is indeed multi-function (as the STPC Atlas programming manual
|
|
|
|
|
indicates as well), and Windows 2000 also issues a 0x7B STOP error if it is 0x40. */
|
2020-07-11 00:42:38 +02:00
|
|
|
dev->pci_conf[1][0x0e] = /*0x40*/ 0x80;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
/* IDE */
|
2020-11-23 14:49:13 -03:00
|
|
|
dev->pci_conf[2][0x00] = dev->local >> 16;
|
|
|
|
|
dev->pci_conf[2][0x01] = dev->local >> 24;
|
2020-07-11 01:42:26 +02:00
|
|
|
|
2020-11-23 14:49:13 -03:00
|
|
|
if (dev->local == STPC_ATLAS) {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->pci_conf[2][0x02] = 0x28;
|
|
|
|
|
dev->pci_conf[2][0x03] = 0x02;
|
2020-07-07 13:25:17 -03:00
|
|
|
} else {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->pci_conf[2][0x02] = dev->pci_conf[1][0x02];
|
|
|
|
|
dev->pci_conf[2][0x03] = dev->pci_conf[1][0x03];
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
dev->pci_conf[2][0x06] = 0x80;
|
|
|
|
|
dev->pci_conf[2][0x07] = 0x02;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[2][0x09] = 0x8a;
|
|
|
|
|
dev->pci_conf[2][0x0a] = 0x01;
|
|
|
|
|
dev->pci_conf[2][0x0b] = 0x01;
|
|
|
|
|
|
2020-07-11 00:42:38 +02:00
|
|
|
/* NOTE: This is an erratum in the STPC Atlas programming manual, the programming manuals for the other
|
2022-09-18 17:12:38 -04:00
|
|
|
STPC chipsets say 0x80, which is indeed multi-function (as the STPC Atlas programming manual
|
|
|
|
|
indicates as well), and Windows 2000 also issues a 0x7B STOP error if it is 0x40. */
|
2020-07-11 00:42:38 +02:00
|
|
|
dev->pci_conf[2][0x0e] = /*0x40*/ 0x80;
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
dev->pci_conf[2][0x10] = 0x01;
|
|
|
|
|
dev->pci_conf[2][0x14] = 0x01;
|
|
|
|
|
dev->pci_conf[2][0x18] = 0x01;
|
|
|
|
|
dev->pci_conf[2][0x1c] = 0x01;
|
2020-07-09 16:50:19 -03:00
|
|
|
dev->pci_conf[2][0x20] = 0x01;
|
2020-07-06 20:24:24 -03:00
|
|
|
|
|
|
|
|
dev->pci_conf[2][0x40] = 0x60;
|
|
|
|
|
dev->pci_conf[2][0x41] = 0x97;
|
|
|
|
|
dev->pci_conf[2][0x42] = 0x60;
|
|
|
|
|
dev->pci_conf[2][0x43] = 0x97;
|
|
|
|
|
dev->pci_conf[2][0x44] = 0x60;
|
|
|
|
|
dev->pci_conf[2][0x45] = 0x97;
|
|
|
|
|
dev->pci_conf[2][0x46] = 0x60;
|
|
|
|
|
dev->pci_conf[2][0x47] = 0x97;
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
/* USB */
|
2020-07-07 17:07:08 -03:00
|
|
|
if (dev->usb) {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->pci_conf[3][0x00] = dev->local >> 16;
|
|
|
|
|
dev->pci_conf[3][0x01] = dev->local >> 24;
|
|
|
|
|
dev->pci_conf[3][0x02] = 0x30;
|
|
|
|
|
dev->pci_conf[3][0x03] = 0x02;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[3][0x06] = 0x80;
|
|
|
|
|
dev->pci_conf[3][0x07] = 0x02;
|
|
|
|
|
|
|
|
|
|
dev->pci_conf[3][0x09] = 0x10;
|
|
|
|
|
dev->pci_conf[3][0x0a] = 0x03;
|
|
|
|
|
dev->pci_conf[3][0x0b] = 0x0c;
|
|
|
|
|
|
|
|
|
|
/* NOTE: This is an erratum in the STPC Atlas programming manual, the programming manuals for the other
|
|
|
|
|
STPC chipsets say 0x80, which is indeed multi-function (as the STPC Atlas programming manual
|
|
|
|
|
indicates as well), and Windows 2000 also issues a 0x7B STOP error if it is 0x40. */
|
|
|
|
|
dev->pci_conf[3][0x0e] = /*0x40*/ 0x80;
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
2020-07-08 18:25:35 -03:00
|
|
|
|
|
|
|
|
/* PCI setup */
|
|
|
|
|
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
|
|
|
|
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
|
|
|
|
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
|
|
|
|
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
2020-07-06 18:45:34 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_close(void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_t *dev = (stpc_t *) priv;
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: close()\n");
|
|
|
|
|
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
smram_del(dev->smram);
|
2020-07-14 22:24:22 -03:00
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
free(dev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
stpc_init(const device_t *info)
|
|
|
|
|
{
|
|
|
|
|
stpc_log("STPC: init()\n");
|
|
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
stpc_t *dev = (stpc_t *) malloc(sizeof(stpc_t));
|
2020-07-07 17:07:08 -03:00
|
|
|
memset(dev, 0, sizeof(stpc_t));
|
2022-02-20 02:26:27 -05:00
|
|
|
|
2020-07-07 13:25:17 -03:00
|
|
|
dev->local = info->local;
|
|
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
|
|
|
|
|
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
|
2020-11-23 14:49:13 -03:00
|
|
|
if (dev->local == STPC_ATLAS) {
|
2023-08-07 03:04:52 +02:00
|
|
|
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
|
2023-08-18 23:16:54 +02:00
|
|
|
|
|
|
|
|
dev->usb = device_add(&usb_device);
|
2023-08-07 03:04:52 +02:00
|
|
|
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
|
2020-07-07 13:25:17 -03:00
|
|
|
}
|
2020-07-06 18:45:34 -03:00
|
|
|
|
2020-07-10 04:23:10 +02:00
|
|
|
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
|
|
|
|
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
|
|
|
|
|
2023-10-20 02:57:50 +02:00
|
|
|
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
|
2020-07-10 04:23:10 +02:00
|
|
|
|
2023-10-20 02:57:50 +02:00
|
|
|
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
2020-07-10 04:23:10 +02:00
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
stpc_setup(dev);
|
|
|
|
|
stpc_reset(dev);
|
|
|
|
|
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
dev->smram = smram_add();
|
2020-07-06 18:45:34 -03:00
|
|
|
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, 0, 1);
|
2020-07-06 18:45:34 -03:00
|
|
|
|
|
|
|
|
device_add(&port_92_pci_device);
|
|
|
|
|
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
pic_elcr_io_handler(0);
|
2020-07-10 02:05:49 +02:00
|
|
|
refresh_at_enable = 0;
|
|
|
|
|
|
2020-07-06 18:45:34 -03:00
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-14 22:24:22 -03:00
|
|
|
static void
|
|
|
|
|
stpc_serial_close(void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_serial_t *dev = (stpc_serial_t *) priv;
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: serial_close()\n");
|
|
|
|
|
|
|
|
|
|
free(dev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *
|
2023-06-26 12:47:04 -04:00
|
|
|
stpc_serial_init(UNUSED(const device_t *info))
|
2020-07-14 22:24:22 -03:00
|
|
|
{
|
|
|
|
|
stpc_log("STPC: serial_init()\n");
|
|
|
|
|
|
|
|
|
|
stpc_serial_t *dev = (stpc_serial_t *) malloc(sizeof(stpc_serial_t));
|
|
|
|
|
memset(dev, 0, sizeof(stpc_serial_t));
|
|
|
|
|
|
|
|
|
|
dev->uart[0] = device_add_inst(&ns16550_device, 1);
|
|
|
|
|
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
|
|
|
|
|
2020-07-20 15:24:51 -03:00
|
|
|
/* Initialization is performed by stpc_reset */
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val)
|
|
|
|
|
{
|
2023-05-11 03:02:36 -04:00
|
|
|
uint8_t old_addr = (dev->reg1 & 0x03);
|
|
|
|
|
uint8_t new_addr = (val & 0x03);
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
switch (old_addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x1:
|
|
|
|
|
lpt3_remove();
|
|
|
|
|
break;
|
2020-07-14 22:24:22 -03:00
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x2:
|
|
|
|
|
lpt1_remove();
|
|
|
|
|
break;
|
2020-07-14 22:24:22 -03:00
|
|
|
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x3:
|
|
|
|
|
lpt2_remove();
|
|
|
|
|
break;
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (new_addr) {
|
2022-09-18 17:12:38 -04:00
|
|
|
case 0x1:
|
|
|
|
|
stpc_log("STPC: Remapping parallel port to LPT3\n");
|
|
|
|
|
lpt3_init(0x3bc);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x2:
|
|
|
|
|
stpc_log("STPC: Remapping parallel port to LPT1\n");
|
|
|
|
|
lpt1_init(0x378);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x3:
|
|
|
|
|
stpc_log("STPC: Remapping parallel port to LPT2\n");
|
|
|
|
|
lpt2_init(0x278);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
stpc_log("STPC: Disabling parallel port\n");
|
|
|
|
|
break;
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->reg1 = (val & 0x08);
|
|
|
|
|
dev->reg1 |= new_addr;
|
2020-11-23 14:49:13 -03:00
|
|
|
dev->reg1 |= 0x84; /* reserved bits that default to 1; hardwired? */
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_lpt_write(uint16_t addr, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
|
|
|
|
|
|
|
|
|
|
if (dev->unlocked < 2) {
|
2022-09-18 17:12:38 -04:00
|
|
|
/* Cheat a little bit: in reality, any write to any
|
|
|
|
|
I/O port is supposed to reset the unlock counter. */
|
|
|
|
|
if ((addr == 0x3f0) && (val == 0x55))
|
|
|
|
|
dev->unlocked++;
|
|
|
|
|
else
|
|
|
|
|
dev->unlocked = 0;
|
2020-07-14 22:24:22 -03:00
|
|
|
} else if (addr == 0x3f0) {
|
2022-09-18 17:12:38 -04:00
|
|
|
if (val == 0xaa)
|
|
|
|
|
dev->unlocked = 0;
|
|
|
|
|
else
|
|
|
|
|
dev->offset = val;
|
2020-07-14 22:24:22 -03:00
|
|
|
} else if (dev->offset == 1) {
|
2022-09-18 17:12:38 -04:00
|
|
|
/* dev->reg1 is set by stpc_lpt_handlers */
|
|
|
|
|
stpc_lpt_handlers(dev, val);
|
2020-07-14 22:24:22 -03:00
|
|
|
} else if (dev->offset == 4) {
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->reg4 = (val & 0x03);
|
2020-07-14 22:24:22 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_lpt_reset(void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: lpt_reset()\n");
|
|
|
|
|
|
|
|
|
|
dev->unlocked = 0;
|
2022-09-18 17:12:38 -04:00
|
|
|
dev->offset = 0x00;
|
|
|
|
|
dev->reg1 = 0x9f;
|
|
|
|
|
dev->reg4 = 0x00;
|
2020-07-14 22:24:22 -03:00
|
|
|
stpc_lpt_handlers(dev, dev->reg1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stpc_lpt_close(void *priv)
|
|
|
|
|
{
|
|
|
|
|
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
|
|
|
|
|
|
|
|
|
|
stpc_log("STPC: lpt_close()\n");
|
|
|
|
|
|
|
|
|
|
free(dev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *
|
2023-06-26 12:47:04 -04:00
|
|
|
stpc_lpt_init(UNUSED(const device_t *info))
|
2020-07-14 22:24:22 -03:00
|
|
|
{
|
|
|
|
|
stpc_log("STPC: lpt_init()\n");
|
|
|
|
|
|
|
|
|
|
stpc_lpt_t *dev = (stpc_lpt_t *) malloc(sizeof(stpc_lpt_t));
|
|
|
|
|
memset(dev, 0, sizeof(stpc_lpt_t));
|
|
|
|
|
|
|
|
|
|
stpc_lpt_reset(dev);
|
|
|
|
|
|
|
|
|
|
io_sethandler(0x3f0, 2,
|
2022-09-18 17:12:38 -04:00
|
|
|
NULL, NULL, NULL, stpc_lpt_write, NULL, NULL, dev);
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* STPC SoCs */
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_client_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Client",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_client",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = DEVICE_PCI,
|
|
|
|
|
.local = STPC_CLIENT,
|
|
|
|
|
.init = stpc_init,
|
|
|
|
|
.close = stpc_close,
|
|
|
|
|
.reset = stpc_reset,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-06 21:12:09 -03:00
|
|
|
};
|
|
|
|
|
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_consumer2_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Consumer-II",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_consumer2",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = DEVICE_PCI,
|
|
|
|
|
.local = STPC_CONSUMER2,
|
|
|
|
|
.init = stpc_init,
|
|
|
|
|
.close = stpc_close,
|
|
|
|
|
.reset = stpc_reset,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-06 18:45:34 -03:00
|
|
|
};
|
|
|
|
|
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_elite_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Elite",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_elite",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = DEVICE_PCI,
|
|
|
|
|
.local = STPC_ELITE,
|
|
|
|
|
.init = stpc_init,
|
|
|
|
|
.close = stpc_close,
|
|
|
|
|
.reset = stpc_reset,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-06 18:45:34 -03:00
|
|
|
};
|
|
|
|
|
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_atlas_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Atlas",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_atlas",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = DEVICE_PCI,
|
|
|
|
|
.local = STPC_ATLAS,
|
|
|
|
|
.init = stpc_init,
|
|
|
|
|
.close = stpc_close,
|
|
|
|
|
.reset = stpc_reset,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-06 18:45:34 -03:00
|
|
|
};
|
2020-07-14 22:24:22 -03:00
|
|
|
|
|
|
|
|
/* Auxiliary devices */
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_serial_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Serial UARTs",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_serial",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = 0,
|
|
|
|
|
.local = 0,
|
|
|
|
|
.init = stpc_serial_init,
|
|
|
|
|
.close = stpc_serial_close,
|
|
|
|
|
.reset = NULL,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-14 22:24:22 -03:00
|
|
|
};
|
|
|
|
|
|
2022-03-13 09:21:08 -04:00
|
|
|
const device_t stpc_lpt_device = {
|
2022-09-18 17:12:38 -04:00
|
|
|
.name = "STPC Parallel Port",
|
2022-03-13 09:21:08 -04:00
|
|
|
.internal_name = "stpc_lpt",
|
2022-09-18 17:12:38 -04:00
|
|
|
.flags = 0,
|
|
|
|
|
.local = 0,
|
|
|
|
|
.init = stpc_lpt_init,
|
|
|
|
|
.close = stpc_lpt_close,
|
|
|
|
|
.reset = stpc_lpt_reset,
|
2022-03-13 09:21:08 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:12:38 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2020-07-14 22:24:22 -03:00
|
|
|
};
|