From 20cd01aaca7d5d7857dadd3c3d868c67e550b190 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Wed, 19 Aug 2020 23:51:40 +0300 Subject: [PATCH] Added the US Technologies 386 motherboard. Late 386 motherboard using the Award 4.50G BIOS. --- src/chipset/umc491.c | 179 +++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 3 + src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 20 ++++ src/machine/machine_table.c | 1 + src/win/Makefile.mingw | 2 +- 6 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/chipset/umc491.c diff --git a/src/chipset/umc491.c b/src/chipset/umc491.c new file mode 100644 index 000000000..4de917784 --- /dev/null +++ b/src/chipset/umc491.c @@ -0,0 +1,179 @@ +/* + * 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 UMC 491/493 chipset. + * + * + * + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 + * + */ + +#include +#include +#include +#include +#include +#include +#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/mem.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + +#ifdef ENABLE_UMC491_LOG +int ali1429_do_log = ENABLE_UMC491_LOG; +static void +umc491_log(const char *fmt, ...) +{ + va_list ap; + + if (umc491_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define umc491_log(fmt, ...) +#endif + +typedef struct +{ + uint8_t index, + regs[256]; +} umc491_t; + +static void umc491_shadow_recalc(umc491_t *dev) +{ + +shadowbios = (dev->regs[0xcc] & 0x40); +shadowbios_write = (dev->regs[0xcc] & 0x80); + +mem_set_mem_state_both(0xc0000, 0x4000, ((dev->regs[0xcd] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcd] & 0x80) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xc4000, 0x4000, ((dev->regs[0xcd] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcd] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xc8000, 0x4000, ((dev->regs[0xcd] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcd] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xcc000, 0x4000, ((dev->regs[0xcd] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcd] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +mem_set_mem_state_both(0xd0000, 0x4000, ((dev->regs[0xce] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xce] & 0x80) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xd4000, 0x4000, ((dev->regs[0xce] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xce] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xd8000, 0x4000, ((dev->regs[0xce] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xce] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); +mem_set_mem_state_both(0xdc000, 0x4000, ((dev->regs[0xce] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xce] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +/* +Our machine has the E segment into parts although most AMI machines treat it as one. +Probably a flaw by the BIOS as only one register gets enabled for it anyways. +*/ +mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0xcc] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcc] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0xcc] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0xcc] & 0x80) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + +flushmmucache(); +} + +static void +umc491_write(uint16_t addr, uint8_t val, void *priv) +{ + umc491_t *dev = (umc491_t *) priv; + + switch (addr) { + case 0x8022: + dev->index = val; + break; + case 0x8024: + umc491_log("UMC 491: dev->regs[%02x] = %02x\n", dev->index, val); + dev->regs[dev->index] = val; + + switch(dev->index) + { + case 0xcc: + case 0xcd: + case 0xce: + umc491_shadow_recalc(dev); + break; + + case 0xd0: + cpu_update_waitstates(); + break; + + case 0xd1: + cpu_cache_ext_enabled = (val & 0x01); + break; + } + break; + } +} + + +static uint8_t +umc491_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + umc491_t *dev = (umc491_t *) priv; + + switch (addr) { + case 0x8024: + ret = dev->regs[dev->index]; + break; + } + + return ret; +} + + +static void +umc491_close(void *priv) +{ + umc491_t *dev = (umc491_t *) priv; + + free(dev); +} + + +static void * +umc491_init(const device_t *info) +{ + umc491_t *dev = (umc491_t *) malloc(sizeof(umc491_t)); + memset(dev, 0, sizeof(umc491_t)); + + device_add(&port_92_device); + +/* + +UMC 491/493 Ports + +8022h Index Port +8024h Data Port + +*/ + io_sethandler(0x8022, 0x0001, umc491_read, NULL, NULL, umc491_write, NULL, NULL, dev); + io_sethandler(0x8024, 0x0001, umc491_read, NULL, NULL, umc491_write, NULL, NULL, dev); + + dev->regs[0xcc] = 0x00; + dev->regs[0xcd] = 0x00; + dev->regs[0xce] = 0x00; + umc491_shadow_recalc(dev); + + return dev; +} + + +const device_t umc491_device = { + "UMC 491/493", + 0, + 0, + umc491_init, umc491_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index cddd86100..2b4fff78d 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -104,6 +104,9 @@ extern const device_t stpc_serial_device; extern const device_t stpc_lpt_device; #endif +/* UMC */ +extern const device_t umc491_device; + /* VIA */ extern const device_t via_vt82c49x_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 76604b298..bae2e0965 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -252,6 +252,7 @@ extern const device_t *at_commodore_sl386sx_get_device(void); extern int machine_at_acc386_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); +extern int machine_at_ustechnologies386_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 474ff3e1d..dbaf729b7 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -103,6 +103,26 @@ machine_at_ecs386_init(const machine_t *model) return ret; } +int +machine_at_ustechnologies386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ustechnologies386/3umw003.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&umc491_device); + device_add(&keyboard_at_device); + device_add(&fdc_at_device); + + return ret; +} + int machine_at_rycleopardlx_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7b7ab6a9a..6c3d5dfc0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -187,6 +187,7 @@ const machine_t machines[] = { { "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, { "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 1, 16, 1, 127, machine_at_ecs386_init, NULL }, + { "[UMC 491] US Technologies 386", "ustechnologies386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 1, 16, 1, 127, machine_at_ustechnologies386_init, NULL }, /* 386DX machines which utilize the VLB bus */ { "[OPTi 495] Award 386DX clone", "award386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index ea362b2b8..84cd3750e 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -639,7 +639,7 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o cs4031.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \ - sis_85c310.o sis_85c471.o sis_85c496.o opti283.o opti291.o \ + sis_85c310.o sis_85c471.o sis_85c496.o opti283.o opti291.o umc491.o \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o