From 5d7ea72881391063953ce87f965719475226988d Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Thu, 31 Dec 2020 21:49:47 +0200 Subject: [PATCH] Added the Mylex MVI486 A 486 Industrial board using the Mylex BIOS --- src/include/86box/machine.h | 1 + src/include/86box/sio.h | 2 + src/machine/m_at_386dx_486.c | 22 ++- src/machine/machine_table.c | 1 + src/sio/sio_pc87311.c | 297 +++++++++++++++++++++++++++++++++++ src/sio/sio_prime3c.c | 2 + src/win/Makefile.mingw | 2 +- 7 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 src/sio/sio_pc87311.c diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 676e36c75..31baeee20 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -309,6 +309,7 @@ extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_403tg_init(const machine_t *); extern int machine_at_pc330_6571_init(const machine_t *); +extern int machine_at_mvi486_init(const machine_t *); extern int machine_at_sis401_init(const machine_t *); extern int machine_at_av4_init(const machine_t *); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index e6e4cbb10..81dc8976e 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,8 @@ extern const device_t pc87307_15c_device; extern const device_t pc87307_both_device; extern const device_t pc87309_device; extern const device_t pc87309_15c_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_ps1_device; extern const device_t pc97307_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4a9ed91a5..e040e3128 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -474,7 +474,6 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } - int machine_at_403tg_init(const machine_t *model) { @@ -519,6 +518,27 @@ machine_at_pc330_6571_init(const machine_t *model) // doesn't like every CPU oth return ret; } +int +machine_at_mvi486_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/mvi486/MVI627.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti895_device); + + device_add(&keyboard_at_device); + device_add(&pc87311_ide_device); + + return ret; +} + static void machine_at_sis_85c471_common_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 64545a0ba..cbad9c07c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -200,6 +200,7 @@ const machine_t machines[] = { { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_mr_init, NULL }, { "[OPTi 802G] IBM PC 330 (type 6571)", "pc330_6571", MACHINE_TYPE_486, CPU_PKG_SOCKET3_PC330, 0, 25000000, 33333333, 0, 0, 2.0, 3.0, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_pc330_6571_init, NULL }, { "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_init, NULL }, + { "[OPTi 895] Mylex MVI486", "mvi486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE_DUAL, 1024, 65536, 1024, 127, machine_at_mvi486_init, NULL }, { "[SiS 401] AMI 486 Clone", "sis401", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_sis401_init, NULL }, { "[SiS 460] ABIT AV4", "av4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_av4_init, NULL }, { "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_valuepoint433_init, NULL }, diff --git a/src/sio/sio_pc87311.c b/src/sio/sio_pc87311.c new file mode 100644 index 000000000..2fff65d6c --- /dev/null +++ b/src/sio/sio_pc87311.c @@ -0,0 +1,297 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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> + +#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 +{ + uint8_t index, regs[256], cfg_lock, ide_function; + uint16_t base, irq; + fdc_t *fdc_controller; + serial_t *uart[2]; + +} 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; + } + break; + } + + pc87311_enable(dev); +} + +static uint8_t +pc87311_read(uint16_t addr, void *priv) +{ + 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) ? 0x0370 : 0x03f0); + pc87311_log("PC87311-FDC: BASE %04x\n", (FUNCTION_ENABLE & 0x20) ? 0x0370 : 0x03f0); +} + +uint16_t com3(pc87311_t *dev) +{ + switch (COM_BA) + { + case 0: + return 0x03e8; + case 1: + return 0x0338; + case 2: + return 0x02e8; + case 3: + return 0x0220; + default: + return 0x03e8; + } +} + +uint16_t com4(pc87311_t *dev) +{ + switch (COM_BA) + { + case 0: + return 0x02e8; + case 1: + return 0x0238; + case 2: + return 0x02e0; + case 3: + return 0x0228; + default: + return 0x02e8; + } +} + +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 = 0x03f8; + dev->irq = 4; + break; + case 1: + dev->base = 0x02f8; + dev->irq = 3; + break; + case 2: + dev->base = com3(dev); + dev->irq = 4; + break; + case 3: + dev->base = com4(dev); + dev->irq = 3; + 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) +{ + lpt1_remove(); + switch (LPT_BA) + { + case 0: + dev->base = 0x0378; + dev->irq = (POWER_TEST & 0x08) ? 7 : 5; + break; + case 1: + dev->base = 0x03bc; + dev->irq = 7; + break; + case 2: + dev->base = 0x0278; + dev->irq = 5; + break; + } + lpt1_init(dev->base); + lpt1_irq(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) : lpt1_remove(); + (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 *)malloc(sizeof(pc87311_t)); + memset(dev, 0, 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); + + 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 = { + "National Semiconductor PC87311", + 0, + 0, + pc87311_init, + pc87311_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; + +const device_t pc87311_ide_device = { + "National Semiconductor PC87311 with IDE functionality", + 0, + 1, + pc87311_init, + pc87311_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c index 2e0b688a3..b18e274fa 100644 --- a/src/sio/sio_prime3c.c +++ b/src/sio/sio_prime3c.c @@ -11,11 +11,13 @@ * Authors: Tiseno100 * Copyright 2020 Tiseno100 */ +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index a73be16b4..46f5d619a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -640,7 +640,7 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm SIOOBJ := sio_acc3221.o \ sio_f82c710.o sio_82091aa.o \ sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ - sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ + sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87311.o sio_pc87332.o \ sio_prime3c.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \