From d6d5bcd283368f89c3d7dfb8f9c2ac844e7701df Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 24 Jan 2021 11:18:52 +0200 Subject: [PATCH 1/5] Mass rewrite of the WD76C10 Fairly broken rewrite of the WD76C10 --- src/chipset/wd76c10.c | 688 +++++++++++++++++++++++++++++------------- 1 file changed, 473 insertions(+), 215 deletions(-) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 6233177ba..3be448267 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -6,234 +6,424 @@ * * This file is part of the 86Box distribution. * - * Implementation of the WD76C10 System Controller chip. + * Implementation of the Western Digital WD76C10 chipset. * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * + * Authors: Tiseno100 * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Copyright 2021 Tiseno100 * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. */ + +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/device.h> +#include "cpu.h" #include <86box/timer.h> #include <86box/io.h> -#include <86box/keyboard.h> +#include <86box/device.h> +#include <86box/dma.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/lpt.h> #include <86box/mem.h> #include <86box/port_92.h> #include <86box/serial.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/video.h> #include <86box/chipset.h> +/* Lock/Unlock Procedures */ +#define LOCK dev->lock +#define UNLOCKED !dev->lock -typedef struct { - int type; +#define ENABLE_WD76C10_LOG 1 - uint16_t reg_0092; - uint16_t reg_2072; - uint16_t reg_2872; - uint16_t reg_5872; +#ifdef ENABLE_WD76C10_LOG +int wd76c10_do_log = ENABLE_WD76C10_LOG; +static void +wd76c10_log(const char *fmt, ...) +{ + va_list ap; - uint16_t reg_f872; + if (wd76c10_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define wd76c10_log(fmt, ...) +#endif - serial_t *uart[2]; +typedef struct +{ + uint16_t lock_reg, oscillator_40mhz, cache_flush, ems_page_reg, + ems_page_reg_pointer, port_shadow, pmc_interrupt, + high_mem_protect_boundry, delay_line, diagnostic, + nmi_status, pmc_input, pmc_timer, + pmc_output, ems_control_low_address_boundry, shadow_ram, + split_addr, bank32staddr, bank10staddr, + non_page_mode_dram_timing, mem_control, + refresh_control, disk_chip_select, prog_chip_sel_addr, + bus_timing_power_down_ctl, clk_control; - fdc_t *fdc; + int lock; - mem_mapping_t extram_mapping; - uint8_t extram[65536]; + fdc_t *fdc_controller; + mem_mapping_t *mem_mapping; + serial_t *uart[2]; } wd76c10_t; +static void wd76c10_refresh_control(wd76c10_t *dev) +{ + serial_remove(dev->uart[1]); + /* Serial B */ + switch ((dev->refresh_control >> 1) & 7) + { + case 1: + serial_setup(dev->uart[1], 0x3f8, 3); + break; + case 2: + serial_setup(dev->uart[1], 0x2f8, 3); + break; + case 3: + serial_setup(dev->uart[1], 0x3e8, 3); + break; + case 4: + serial_setup(dev->uart[1], 0x2e8, 3); + break; + } + + serial_remove(dev->uart[0]); + /* Serial A */ + switch ((dev->refresh_control >> 5) & 7) + { + case 1: + serial_setup(dev->uart[0], 0x3f8, 4); + break; + case 2: + serial_setup(dev->uart[0], 0x2f8, 4); + break; + case 3: + serial_setup(dev->uart[0], 0x3e8, 4); + break; + case 4: + serial_setup(dev->uart[0], 0x2e8, 4); + break; + } + + lpt1_remove(); + /* LPT */ + switch ((dev->refresh_control >> 9) & 3) + { + case 1: + lpt1_init(0x3bc); + lpt1_irq(7); + break; + case 2: + lpt1_init(0x378); + lpt1_irq(7); + break; + case 3: + lpt1_init(0x278); + lpt1_irq(7); + break; + } +} + +static void wd76c10_split_addr(wd76c10_t *dev) +{ + switch ((dev->split_addr >> 8) & 3) + { + case 1: + if (((dev->shadow_ram >> 8) & 3) == 2) + mem_remap_top(256); + break; + case 2: + if (((dev->shadow_ram >> 8) & 3) == 1) + mem_remap_top(320); + break; + case 3: + if (((dev->shadow_ram >> 8) & 3) == 3) + mem_remap_top(384); + break; + } +} + +static void wd76c10_disk_chip_select(wd76c10_t *dev) +{ + ide_pri_disable(); + if (!(dev->disk_chip_select & 1)) + { + ide_set_base(0, !(dev->disk_chip_select & 0x0010) ? 0x1f0 : 0x170); + ide_set_side(0, !(dev->disk_chip_select & 0x0010) ? 0x3f6 : 0x376); + } + ide_pri_enable(); + + fdc_remove(dev->fdc_controller); + if (!(dev->disk_chip_select & 2)) + fdc_set_base(dev->fdc_controller, !(dev->disk_chip_select & 0x0010) ? 0x3f0 : 0x370); +} + +static void wd76c10_shadow_recalc(wd76c10_t *dev) +{ + switch ((dev->shadow_ram >> 14) & 3) + { + case 0: + mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 1: + mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); + break; + case 2: + mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); + break; + case 3: + mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); + break; + } + + switch ((dev->shadow_ram >> 8) & 3) + { + case 0: + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); + break; + case 2: + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); + break; + case 3: + mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); + break; + } +} + +static void +wd76c10_write(uint16_t addr, uint16_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *)priv; + + if (UNLOCKED) + { + switch (addr) + { + case 0x1072: + dev->clk_control = val; + break; + + case 0x1872: + dev->bus_timing_power_down_ctl = val; + break; + + case 0x2072: + dev->refresh_control = val; + wd76c10_refresh_control(dev); + break; + + case 0x2872: + dev->disk_chip_select = val; + wd76c10_disk_chip_select(dev); + break; + + case 0x3072: + dev->prog_chip_sel_addr = val; + break; + + case 0x3872: + dev->non_page_mode_dram_timing = val; + break; + + case 0x4072: + dev->mem_control = val; + break; + + case 0x4872: + dev->bank10staddr = val; + break; + + case 0x5072: + dev->bank32staddr = val; + break; + + case 0x5872: + dev->split_addr = val; + wd76c10_split_addr(dev); + break; + + case 0x6072: + dev->shadow_ram = val & 0xffbf; + wd76c10_shadow_recalc(dev); + break; + + case 0x6872: + dev->ems_control_low_address_boundry = val & 0xecff; + break; + + case 0x7072: + dev->pmc_output = (val >> 8) & 0x00ff; + break; + + case 0x7872: + dev->pmc_output = val & 0xff00; + break; + + case 0x8072: + dev->pmc_timer = val; + break; + + case 0x8872: + dev->pmc_input = val; + break; + + case 0x9072: + dev->nmi_status = val & 0x00fc; + break; + + case 0x9872: + dev->diagnostic = val & 0xfdff; + break; + + case 0xa072: + dev->delay_line = val; + break; + + case 0xc872: + dev->pmc_interrupt = val & 0xfcfc; + break; + + case 0xf072: + dev->oscillator_40mhz = 0; + break; + + case 0xf472: + dev->oscillator_40mhz = 1; + break; + + case 0xf872: + dev->cache_flush = val; + flushmmucache(); + break; + } + wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val); + } + + switch (addr) + { + case 0xe072: + dev->ems_page_reg_pointer = val & 0x003f; + break; + + case 0xe872: + dev->ems_page_reg = val & 0x8fff; + break; + + case 0xf073: + dev->lock_reg = val & 0x00ff; + LOCK = !(val && 0x00da); + break; + } +} static uint16_t -wd76c10_read(uint16_t port, void *priv) +wd76c10_read(uint16_t addr, void *priv) { wd76c10_t *dev = (wd76c10_t *)priv; - int16_t ret = 0xffff; + wd76c10_log("WD76C10: R dev->regs[%04x]\n", addr); + switch (addr) + { + case 0x1072: + return dev->clk_control; - switch (port) { - case 0x2072: - ret = dev->reg_2072; - break; + case 0x1872: + return dev->bus_timing_power_down_ctl; - case 0x2872: - ret = dev->reg_2872; - break; + case 0x2072: + return dev->refresh_control; - case 0x5872: - ret = dev->reg_5872; - break; + case 0x2872: + return dev->disk_chip_select; - case 0xf872: - ret = dev->reg_f872; - break; - } + case 0x3072: + return dev->prog_chip_sel_addr; - return(ret); -} + case 0x3872: + return dev->non_page_mode_dram_timing; + case 0x4072: + return dev->mem_control; -static void -wd76c10_write(uint16_t port, uint16_t val, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; + case 0x4872: + return dev->bank10staddr; - switch (port) { - case 0x2072: - dev->reg_2072 = val; + case 0x5072: + return dev->bank32staddr; - serial_remove(dev->uart[0]); - if (!(val & 0x10)) - { - switch ((val >> 5) & 7) - { - case 1: serial_setup(dev->uart[0], 0x3f8, 4); break; - case 2: serial_setup(dev->uart[0], 0x2f8, 4); break; - case 3: serial_setup(dev->uart[0], 0x3e8, 4); break; - case 4: serial_setup(dev->uart[0], 0x2e8, 4); break; - default: break; - } - } - serial_remove(dev->uart[1]); - if (!(val & 0x01)) - { - switch ((val >> 1) & 7) - { - case 1: serial_setup(dev->uart[1], 0x3f8, 3); break; - case 2: serial_setup(dev->uart[1], 0x2f8, 3); break; - case 3: serial_setup(dev->uart[1], 0x3e8, 3); break; - case 4: serial_setup(dev->uart[1], 0x2e8, 3); break; - default: break; - } - } - break; + case 0x5872: + return dev->split_addr; - case 0x2872: - dev->reg_2872 = val; + case 0x6072: + return dev->shadow_ram; - fdc_remove(dev->fdc); - if (! (val & 1)) - fdc_set_base(dev->fdc, 0x03f0); - break; + case 0x6872: + return dev->ems_control_low_address_boundry; - case 0x5872: - dev->reg_5872 = val; - break; + case 0x7072: + return (dev->pmc_output << 8) & 0xff00; - case 0xf872: - dev->reg_f872 = val; - switch (val & 3) { - case 0: - mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 2: - mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); - if (val & 4) - mem_mapping_enable(&dev->extram_mapping); - else - mem_mapping_disable(&dev->extram_mapping); - flushmmucache_nopc(); - break; + case 0x7872: + return (dev->pmc_output) & 0xff00; + + case 0x8072: + return dev->pmc_timer; + + case 0x8872: + return dev->pmc_input; + + case 0x9072: + return dev->nmi_status; + + case 0x9872: + return dev->diagnostic; + + case 0xa072: + return dev->delay_line; + + case 0xb872: + return (inb(0x040b) << 8) | inb(0x04d6); + + case 0xc872: + return dev->pmc_interrupt; + + case 0xd072: + return dev->port_shadow; + + case 0xe072: + return dev->ems_page_reg_pointer; + + case 0xe872: + return dev->ems_page_reg; + + case 0xfc72: + return 0x0ff0; + + default: + return 0xffff; } } - -static uint8_t -wd76c10_readb(uint16_t port, void *priv) -{ - if (port & 1) - return(wd76c10_read(port & ~1, priv) >> 8); - - return(wd76c10_read(port, priv) & 0xff); -} - - -static void -wd76c10_writeb(uint16_t port, uint8_t val, void *priv) -{ - uint16_t temp = wd76c10_read(port, priv); - - if (port & 1) - wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv); - else - wd76c10_write(port , (temp & 0xff00) | val, priv); -} - - -uint8_t -wd76c10_read_extram(uint32_t addr, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - return dev->extram[addr & 0xffff]; -} - - -uint16_t -wd76c10_read_extramw(uint32_t addr, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - return *(uint16_t *)&dev->extram[addr & 0xffff]; -} - - -uint32_t -wd76c10_read_extraml(uint32_t addr, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - return *(uint32_t *)&dev->extram[addr & 0xffff]; -} - - -void -wd76c10_write_extram(uint32_t addr, uint8_t val, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - dev->extram[addr & 0xffff] = val; -} - - -void -wd76c10_write_extramw(uint32_t addr, uint16_t val, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - *(uint16_t *)&dev->extram[addr & 0xffff] = val; -} - - -void -wd76c10_write_extraml(uint32_t addr, uint32_t val, void *priv) -{ - wd76c10_t *dev = (wd76c10_t *)priv; - - *(uint32_t *)&dev->extram[addr & 0xffff] = val; -} - - static void wd76c10_close(void *priv) { @@ -242,51 +432,119 @@ wd76c10_close(void *priv) free(dev); } - static void * wd76c10_init(const device_t *info) { - wd76c10_t *dev; + wd76c10_t *dev = (wd76c10_t *)malloc(sizeof(wd76c10_t)); + memset(dev, 0, sizeof(wd76c10_t)); - dev = (wd76c10_t *) malloc(sizeof(wd76c10_t)); - memset(dev, 0x00, sizeof(wd76c10_t)); - dev->type = info->local; + device_add(&port_92_inv_device); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->fdc_controller = device_add(&fdc_at_device); + device_add(&ide_isa_device); - dev->fdc = (fdc_t *)device_add(&fdc_at_device); + /* Lock Configuration */ + LOCK = 1; - dev->uart[0] = device_add_inst(&i8250_device, 1); - dev->uart[1] = device_add_inst(&i8250_device, 2); + /* Clock Control */ + io_sethandler(0x1072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - device_add(&port_92_word_device); + /* Bus Timing & Power Down Control */ + io_sethandler(0x1872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - io_sethandler(0x2072, 2, - wd76c10_readb,wd76c10_read,NULL, - wd76c10_writeb,wd76c10_write,NULL, dev); - io_sethandler(0x2872, 2, - wd76c10_readb,wd76c10_read,NULL, - wd76c10_writeb,wd76c10_write,NULL, dev); - io_sethandler(0x5872, 2, - wd76c10_readb,wd76c10_read,NULL, - wd76c10_writeb,wd76c10_write,NULL, dev); - io_sethandler(0xf872, 2, - wd76c10_readb,wd76c10_read,NULL, - wd76c10_writeb,wd76c10_write,NULL, dev); + /* Refresh Control(Serial & Parallel) */ + io_sethandler(0x2072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - mem_mapping_add(&dev->extram_mapping, 0xd0000, 0x10000, - wd76c10_read_extram,wd76c10_read_extramw,wd76c10_read_extraml, - wd76c10_write_extram,wd76c10_write_extramw,wd76c10_write_extraml, - dev->extram, MEM_MAPPING_EXTERNAL, dev); - mem_mapping_disable(&dev->extram_mapping); + /* Disk Chip Select */ + io_sethandler(0x2872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - return(dev); + /* Programmable Chip Select Address(Needs more further examination!) */ + io_sethandler(0x3072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Bank 1 & 0 Start Address */ + io_sethandler(0x4872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Bank 3 & 2 Start Address */ + io_sethandler(0x5072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Split Address */ + io_sethandler(0x5872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* EMS Control & EMS Low level boundry */ + io_sethandler(0x6072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* EMS Control & EMS Low level boundry */ + io_sethandler(0x6872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* PMC Output */ + io_sethandler(0x7072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* PMC Output */ + io_sethandler(0x7872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* PMC Status */ + io_sethandler(0x8072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* PMC Status */ + io_sethandler(0x8872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* NMI Status (Needs further checkup) */ + io_sethandler(0x9072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Diagnostics */ + io_sethandler(0x9872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Delay Line */ + io_sethandler(0xa072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* DMA Mode Shadow(Needs Involvement on the DMA code) */ + io_sethandler(0xb872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + /* High Memory Protection Boundry */ + io_sethandler(0xc072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + /* PMC Interrupt Enable */ + io_sethandler(0xc872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + /* Port Shadow (Needs further lookup) */ + io_sethandler(0xd072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + /* EMS Page Register Pointer */ + io_sethandler(0xe072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* EMS Page Register */ + io_sethandler(0xe872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + + /* Lock/Unlock Configuration */ + io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); + + /* 40Mhz Oscillator Enable Disable */ + io_sethandler(0xf072, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xf472, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); + + /* Lock Status */ + io_sethandler(0xfc72, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + /* Cache Flush */ + io_sethandler(0xf872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + + dma_ext_mode_init(); + + wd76c10_shadow_recalc(dev); + wd76c10_refresh_control(dev); + wd76c10_disk_chip_select(dev); + return dev; } - const device_t wd76c10_device = { - "WD 76C10", + "Western Digital WD76C10", 0, 0, - wd76c10_init, wd76c10_close, NULL, - { NULL }, NULL, NULL, - NULL -}; + wd76c10_init, + wd76c10_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; From 3aabb7c2d826f556a7708d11626e8837264e84d4 Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 24 Jan 2021 11:23:11 +0200 Subject: [PATCH 2/5] Removed IDE from the Mega PC --- src/machine/m_at_286_386sx.c | 279 ++++++----------------------------- 1 file changed, 47 insertions(+), 232 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 1c2b6526c..9aac75d6a 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -35,7 +35,6 @@ #include <86box/rom.h> #include <86box/fdd.h> #include <86box/fdc.h> -#include <86box/fdc_ext.h> #include <86box/hdc.h> #include <86box/sio.h> #include <86box/serial.h> @@ -475,7 +474,7 @@ machine_at_wd76c10_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&keyboard_ps2_quadtel_device); @@ -672,9 +671,50 @@ machine_at_pja511m_init(const machine_t *model) } #endif + + +static uint8_t +m290_read(uint16_t port, void *priv) +{ + uint8_t ret = 0x0; + switch (port) { + /* + * port 69: + * dip-switch bank on mainboard (off=1) + * bit 3 - use OCG/CGA display adapter (off) / other display adapter (on) + */ + case 0x69: + if(video_is_cga()) + ret |= 0x8|0x4; + ret |= 0x1|0x2; + } + return (ret); +} + +int +machine_at_olim290_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + device_add(&fdc_at_device); + + io_sethandler(0x069, 1, m290_read, NULL, NULL, NULL, NULL, NULL, NULL); + + return ret; +} + + /* * Current bugs: - * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error + * - ctrl-alt-del produces an 8042 error */ int machine_at_ncrpc8_init(const machine_t *model) @@ -690,23 +730,14 @@ machine_at_ncrpc8_init(const machine_t *model) machine_at_common_init(model); device_add(&keyboard_at_ncr_device); - mem_remap_top(384); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); return ret; } -const device_t * -at_ncr3302_get_device(void) -{ - return ¶dise_pvga1a_ncr3302_device; -} - /* * Current bugs: - * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error + * - ctrl-alt-del produces an 8042 error */ int machine_at_ncr3302_init(const machine_t *model) @@ -727,226 +758,10 @@ machine_at_ncr3302_init(const machine_t *model) machine_at_common_ide_init(model); device_add(&neat_device); device_add(&keyboard_at_ncr_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); if (gfxcard == VID_INTERNAL) - device_add(¶dise_pvga1a_ncr3302_device); + device_add(¶dise_pvga1a_device); return ret; } - - -/* - * Current bugs: - * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error - */ -int -machine_at_ncrpc916sx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved(L"roms/machines/ncr_pc916sx/ncr_386sx_u46-17_7.3.bin", - L"roms/machines/ncr_pc916sx/ncr_386sx_u12-19_7.3.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&keyboard_at_ncr_device); - mem_remap_top(384); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - - - return ret; -} - -/* - * Current bugs: - * - no EMS management due to missing chipset implementation (custom ASIC) - */ -int -machine_at_olim290_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add(&keyboard_at_olivetti_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&olivetti_m290_registers_device); - - return ret; -} - - -/* - * Current bugs: - * - no EMS management due to missing chipset implementation (unidentified chip) - */ -int -machine_at_olim290s_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved(L"roms/machines/olivetti_m290s/286-olivetti-m203-low.bin", - L"roms/machines/olivetti_m290s/286-olivetti-m203-high.bin", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - /* replace with correct chipset implementation */ - mem_remap_top(384); - - device_add(&keyboard_ps2_olivetti_device); - device_add(&fdc_at_device); - - /* should use custom BIOS */ - if (gfxcard == VID_INTERNAL) - device_add(¶dise_pvga1a_device); - - return ret; -} - -const device_t * -at_m300_08_get_device(void) -{ - return &oti067_m300_device; -} - -int -machine_at_olim300_08_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m300_08/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&opti283_device); - device_add(&keyboard_ps2_olivetti_device); - device_add(&pc87310_ide_device); - - if (gfxcard == VID_INTERNAL) - device_add(&oti067_m300_device); - - return ret; -} - -/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */ -int -machine_at_olim300_15_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m300_15/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&opti283_device); - device_add(&keyboard_ps2_olivetti_device); - device_add(&pc87310_ide_device); - - /* Stock VRAM is maxed out, so no need to expose video card config */ - if (gfxcard == VID_INTERNAL) - device_add(&oti067_m300_device); - - return ret; -} - - -/* - * Current bugs: - * - soft-reboot causes a fatal error - * - BIOS complains about FPU if not installed, pressing F1 allows to continue booting. - * - BIOS throws a cache memory error (since L2 cache is not implemented yet), pressing F1 allows to continue booting. - * - no shadow memory due to missing chipset implementation (custom ASIC) - */ -//todo: check if fdc can be disabled -int -machine_at_olim300_10_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m300_10/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - /* replace with correct chipset implementation */ - mem_remap_top(384); - - device_add(&keyboard_ps2_olivetti_device); - /* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */ - device_add(&fdc_at_device); - - /* should be a PVGA1B/WD90C00 with custom BIOS */ - if (gfxcard == VID_INTERNAL) - device_add(¶dise_wd90c11_device); - - - return ret; -} - -/* - * Current bugs: - * - soft-reboot causes a fatal error - * - BIOS complains about FPU if not installed, pressing F1 allows to continue booting. - * - no shadow memory due to missing chipset implementation (custom ASIC) - */ -int -machine_at_olim300_05_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m300_05/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - /* replace with correct chipset implementation */ - mem_remap_top(384); - - device_add(&keyboard_ps2_olivetti_device); - /* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */ - device_add(&fdc_at_device); - - /* should be a PVGA1B/WD90C00 with custom BIOS */ - if (gfxcard == VID_INTERNAL) - device_add(¶dise_wd90c11_device); - - - return ret; -} - - From 35fefd9af7622dae37d14a4d247e1ded50b7cc34 Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 24 Jan 2021 11:25:00 +0200 Subject: [PATCH 3/5] Upstream the 286/386SX machines. "Fixing" issues From 79f7e659e05086581f59957126a2f0c05946a623 Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 24 Jan 2021 11:27:29 +0200 Subject: [PATCH 4/5] Fix a bit more --- src/machine/m_at_286_386sx.c | 277 +++++++++++++++++++++++++++++------ 1 file changed, 231 insertions(+), 46 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 9aac75d6a..7276ae087 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -35,6 +35,7 @@ #include <86box/rom.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/hdc.h> #include <86box/sio.h> #include <86box/serial.h> @@ -671,50 +672,9 @@ machine_at_pja511m_init(const machine_t *model) } #endif - - -static uint8_t -m290_read(uint16_t port, void *priv) -{ - uint8_t ret = 0x0; - switch (port) { - /* - * port 69: - * dip-switch bank on mainboard (off=1) - * bit 3 - use OCG/CGA display adapter (off) / other display adapter (on) - */ - case 0x69: - if(video_is_cga()) - ret |= 0x8|0x4; - ret |= 0x1|0x2; - } - return (ret); -} - -int -machine_at_olim290_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add(&keyboard_at_device); - device_add(&fdc_at_device); - - io_sethandler(0x069, 1, m290_read, NULL, NULL, NULL, NULL, NULL, NULL); - - return ret; -} - - /* * Current bugs: - * - ctrl-alt-del produces an 8042 error + * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error */ int machine_at_ncrpc8_init(const machine_t *model) @@ -730,14 +690,23 @@ machine_at_ncrpc8_init(const machine_t *model) machine_at_common_init(model); device_add(&keyboard_at_ncr_device); - device_add(&fdc_at_device); + mem_remap_top(384); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); return ret; } +const device_t * +at_ncr3302_get_device(void) +{ + return ¶dise_pvga1a_ncr3302_device; +} + /* * Current bugs: - * - ctrl-alt-del produces an 8042 error + * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error */ int machine_at_ncr3302_init(const machine_t *model) @@ -758,10 +727,226 @@ machine_at_ncr3302_init(const machine_t *model) machine_at_common_ide_init(model); device_add(&neat_device); device_add(&keyboard_at_ncr_device); - device_add(&fdc_at_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); if (gfxcard == VID_INTERNAL) - device_add(¶dise_pvga1a_device); + device_add(¶dise_pvga1a_ncr3302_device); return ret; } + + +/* + * Current bugs: + * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error + */ +int +machine_at_ncrpc916sx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/ncr_pc916sx/ncr_386sx_u46-17_7.3.bin", + L"roms/machines/ncr_pc916sx/ncr_386sx_u12-19_7.3.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&keyboard_at_ncr_device); + mem_remap_top(384); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + + return ret; +} + +/* + * Current bugs: + * - no EMS management due to missing chipset implementation (custom ASIC) + */ +int +machine_at_olim290_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_olivetti_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&olivetti_m290_registers_device); + + return ret; +} + + +/* + * Current bugs: + * - no EMS management due to missing chipset implementation (unidentified chip) + */ +int +machine_at_olim290s_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/olivetti_m290s/286-olivetti-m203-low.bin", + L"roms/machines/olivetti_m290s/286-olivetti-m203-high.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + /* replace with correct chipset implementation */ + mem_remap_top(384); + + device_add(&keyboard_ps2_olivetti_device); + device_add(&fdc_at_device); + + /* should use custom BIOS */ + if (gfxcard == VID_INTERNAL) + device_add(¶dise_pvga1a_device); + + return ret; +} + +const device_t * +at_m300_08_get_device(void) +{ + return &oti067_m300_device; +} + +int +machine_at_olim300_08_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m300_08/BIOS.ROM", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti283_device); + device_add(&keyboard_ps2_olivetti_device); + device_add(&pc87310_ide_device); + + if (gfxcard == VID_INTERNAL) + device_add(&oti067_m300_device); + + return ret; +} + +/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */ +int +machine_at_olim300_15_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m300_15/BIOS.ROM", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti283_device); + device_add(&keyboard_ps2_olivetti_device); + device_add(&pc87310_ide_device); + + /* Stock VRAM is maxed out, so no need to expose video card config */ + if (gfxcard == VID_INTERNAL) + device_add(&oti067_m300_device); + + return ret; +} + + +/* + * Current bugs: + * - soft-reboot causes a fatal error + * - BIOS complains about FPU if not installed, pressing F1 allows to continue booting. + * - BIOS throws a cache memory error (since L2 cache is not implemented yet), pressing F1 allows to continue booting. + * - no shadow memory due to missing chipset implementation (custom ASIC) + */ +//todo: check if fdc can be disabled +int +machine_at_olim300_10_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m300_10/BIOS.ROM", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + /* replace with correct chipset implementation */ + mem_remap_top(384); + + device_add(&keyboard_ps2_olivetti_device); + /* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */ + device_add(&fdc_at_device); + + /* should be a PVGA1B/WD90C00 with custom BIOS */ + if (gfxcard == VID_INTERNAL) + device_add(¶dise_wd90c11_device); + + + return ret; +} + +/* + * Current bugs: + * - soft-reboot causes a fatal error + * - BIOS complains about FPU if not installed, pressing F1 allows to continue booting. + * - no shadow memory due to missing chipset implementation (custom ASIC) + */ +int +machine_at_olim300_05_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/olivetti_m300_05/BIOS.ROM", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + /* replace with correct chipset implementation */ + mem_remap_top(384); + + device_add(&keyboard_ps2_olivetti_device); + /* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */ + device_add(&fdc_at_device); + + /* should be a PVGA1B/WD90C00 with custom BIOS */ + if (gfxcard == VID_INTERNAL) + device_add(¶dise_wd90c11_device); + + + return ret; +} + + From 67290bcac81b0525431b590149be4f0708a4b2fa Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 24 Jan 2021 15:34:24 +0200 Subject: [PATCH 5/5] Minor bugfixes on the SiS 5571 --- src/chipset/sis_5571.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 254aa5c4f..2594dbb3c 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -210,7 +210,7 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0xec; break; - case 0x51: /* Cache */ + case 0x51: /* L2 Cache */ dev->pci_conf[addr] = val; cpu_cache_ext_enabled = !!(val & 0x40); cpu_update_waitstates(); @@ -263,7 +263,7 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x83: dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, (val & 0x40), (val & 0x80)); + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); break; case 0x87: @@ -272,7 +272,9 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x93: /* APM SMI */ dev->pci_conf[addr] = val; - apm_set_do_smi(dev->apm, ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02))); + apm_set_do_smi(dev->apm, !!((dev->pci_conf[0x9b] & 0x01) && (val & 0x02))); + if (val & 0x02) + dev->pci_conf[0x9d] |= 1; break; case 0x94: @@ -326,7 +328,7 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x43: case 0x44: dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(PCI_INTA + (val & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; case 0x45: @@ -415,7 +417,7 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) } sis_5571_log("IDE Controller: dev->pci_conf[%02x] = %02x\n", addr, val); - if ((addr == 0x09) || ((addr >= 0x10) && (addr <= 0x23)) || (addr == 0x4a)) + if (((addr >= 0x09) && (addr <= 0x23)) || (addr == 0x4a)) sis_5571_ide_handler(dev); break; @@ -593,7 +595,6 @@ sis_5571_init(const device_t *info) pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev); dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev); - pci_enable_mirq(1); /* APM */ dev->apm = device_add(&apm_pci_device); @@ -601,16 +602,19 @@ sis_5571_init(const device_t *info) /* DMA */ dma_alias_set(); + /* MIRQ */ + pci_enable_mirq(0); + + /* Port 92 & SMRAM */ + dev->port_92 = device_add(&port_92_pci_device); + dev->smram = smram_add(); + /* SFF IDE */ dev->bm[0] = device_add_inst(&sff8038i_device, 1); dev->bm[1] = device_add_inst(&sff8038i_device, 2); dev->program_status_pri = 0; dev->program_status_sec = 0; - /* Port 92 & SMRAM */ - dev->port_92 = device_add(&port_92_pci_device); - dev->smram = smram_add(); - /* USB */ dev->usb = device_add(&usb_device);