From 0d2e69142d8974d9baf99ecddb5fbf93d1f23bcc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Jul 2020 00:42:38 +0200 Subject: [PATCH 1/5] Fixed an IDE log line and fixed a bug in the implementation of the STPC chipsets caused by an erratum in the STPC Atlas programming manual (corrected in the other STPC chipsets' programming manuals). --- src/chipset/stpc.c | 23 ++++++++++++++++++----- src/disk/hdc_ide.c | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 4e6b4cb9c..f5885d238 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -399,6 +399,10 @@ stpc_ide_write(int func, int addr, uint8_t val, void *priv) 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; @@ -478,8 +482,8 @@ stpc_isab_read(int func, int addr, void *priv) stpc_t *dev = (stpc_t *) priv; uint8_t ret; - if (func == 1 && !(dev->local & STPC_IDE_ATLAS)) - return stpc_ide_read(0, addr, priv); + if ((func == 1) && !(dev->local & STPC_IDE_ATLAS)) + ret = stpc_ide_read(0, addr, priv); else if (func > 0) ret = 0xff; else @@ -727,7 +731,10 @@ stpc_setup(stpc_t *dev) dev->pci_conf[1][0x0a] = 0x01; dev->pci_conf[1][0x0b] = 0x06; - dev->pci_conf[1][0x0e] = 0x40; + /* 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[1][0x0e] = /*0x40*/ 0x80; /* IDE */ dev->pci_conf[2][0x00] = 0x4a; @@ -747,7 +754,10 @@ stpc_setup(stpc_t *dev) dev->pci_conf[2][0x0a] = 0x01; dev->pci_conf[2][0x0b] = 0x01; - dev->pci_conf[2][0x0e] = 0x40; + /* 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[2][0x0e] = /*0x40*/ 0x80; dev->pci_conf[2][0x10] = 0x01; dev->pci_conf[2][0x14] = 0x01; @@ -778,7 +788,10 @@ stpc_setup(stpc_t *dev) dev->pci_conf[3][0x0a] = 0x03; dev->pci_conf[3][0x0b] = 0x0c; - dev->pci_conf[3][0x0e] = 0x40; + /* 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; } /* PCI setup */ diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 941faf29f..762a2d780 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1051,7 +1051,7 @@ ide_atapi_packet_read(ide_t *ide, int length) return 0; if (dev->packet_status == PHASE_DATA_IN) - ide_log("PHASE_DATA_IN read: %i, %i< %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); + ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); bufferw = (uint16_t *) dev->temp_buffer; bufferl = (uint32_t *) dev->temp_buffer; From e0ea2b1f693a50919166ba30dd611eb8e8b08478 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Jul 2020 00:56:45 +0200 Subject: [PATCH 2/5] Fixed the STPC chipset PCI Vendor and Device ID's. --- src/chipset/stpc.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index f5885d238..15b4dc530 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -692,12 +692,16 @@ stpc_setup(stpc_t *dev) stpc_log("STPC: setup()\n"); /* Northbridge */ - dev->pci_conf[0][0x00] = 0x4a; - dev->pci_conf[0][0x01] = 0x10; if (dev->local & STPC_NB_CLIENT) { + /* Client */ + dev->pci_conf[0][0x00] = 0x0e; + dev->pci_conf[0][0x01] = 0x10; dev->pci_conf[0][0x02] = 0x64; dev->pci_conf[0][0x03] = 0x05; } else { + /* Atlas, Elite, Consumer II */ + dev->pci_conf[0][0x00] = 0x4a; + dev->pci_conf[0][0x01] = 0x10; dev->pci_conf[0][0x02] = 0x0a; dev->pci_conf[0][0x03] = 0x02; } @@ -710,17 +714,30 @@ stpc_setup(stpc_t *dev) dev->pci_conf[0][0x0b] = 0x06; /* ISA Bridge */ - dev->pci_conf[1][0x00] = 0x4a; - dev->pci_conf[1][0x01] = 0x10; if (dev->local & STPC_ISAB_CLIENT) { + /* Client */ + dev->pci_conf[1][0x00] = 0x0e; + dev->pci_conf[1][0x01] = 0x10; dev->pci_conf[1][0x02] = 0xcc; dev->pci_conf[1][0x03] = 0x55; } else if (dev->local & STPC_ISAB_CONSUMER2) { + /* Consumer II */ + dev->pci_conf[1][0x00] = 0x4a; + dev->pci_conf[1][0x01] = 0x10; dev->pci_conf[1][0x02] = 0x0b; dev->pci_conf[1][0x03] = 0x02; - } else { + } else if (dev->local & STPC_IDE_ATLAS) { + /* Atlas */ + dev->pci_conf[1][0x00] = 0x4a; + dev->pci_conf[1][0x01] = 0x10; dev->pci_conf[1][0x02] = 0x10; dev->pci_conf[1][0x03] = 0x02; + } else { + /* Elite */ + dev->pci_conf[1][0x00] = 0x4a; + dev->pci_conf[1][0x01] = 0x10; + dev->pci_conf[1][0x02] = 0x1a; + dev->pci_conf[1][0x03] = 0x02; } dev->pci_conf[1][0x04] = 0x0f; From 3c0f4491a8b1357443025ce3f06540a176ab330b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Jul 2020 01:42:26 +0200 Subject: [PATCH 3/5] Fixed STPC Client IDE PCI Vendor ID. --- src/chipset/stpc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 15b4dc530..c3b7d7cc2 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -754,8 +754,14 @@ stpc_setup(stpc_t *dev) dev->pci_conf[1][0x0e] = /*0x40*/ 0x80; /* IDE */ - dev->pci_conf[2][0x00] = 0x4a; - dev->pci_conf[2][0x01] = 0x10; + if (dev->local & STPC_ISAB_CLIENT) { + dev->pci_conf[2][0x00] = 0x0e; + dev->pci_conf[2][0x01] = 0x10; + } else { + dev->pci_conf[2][0x00] = 0x4a; + dev->pci_conf[2][0x01] = 0x10; + } + if (dev->local & STPC_IDE_ATLAS) { dev->pci_conf[2][0x02] = 0x28; dev->pci_conf[2][0x03] = 0x02; From 72cfa4dcb89212873befd19b26c300efafacb40d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Jul 2020 03:37:25 +0200 Subject: [PATCH 4/5] Implemented the Intel 82091AA Super I/O chip and added the Packard Bell PB520R, closes #825. --- src/disk/hdc_ide_cmd640.c | 25 ++- src/include/86box/hdc.h | 1 + src/include/86box/machine.h | 2 + src/include/86box/pci.h | 4 +- src/include/86box/serial.h | 1 + src/include/86box/sio.h | 2 + src/include/86box/video.h | 1 + src/machine/m_at_socket4_5.c | 45 ++++-- src/machine/machine_table.c | 2 - src/pci.c | 1 + src/sio/sio_82091aa.c | 293 +++++++++++++++++++++++++++++++++++ src/video/vid_cl54xx.c | 130 ++++++++++++---- src/win/Makefile.mingw | 5 +- 13 files changed, 461 insertions(+), 51 deletions(-) create mode 100644 src/sio/sio_82091aa.c diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 6e5353629..1efd9245c 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -40,7 +40,7 @@ typedef struct { uint8_t vlb_idx, id, - in_cfg, + in_cfg, single_channel, regs[256]; int slot, irq_mode[2], irq_pin, irq_line; @@ -93,6 +93,9 @@ cmd640_ide_handlers(cmd640_t *dev) if (dev->regs[0x04] & 0x01) ide_pri_enable(); + if (dev->single_channel) + return; + ide_sec_disable(); if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { @@ -360,7 +363,7 @@ cmd640_init(const device_t *info) dev->regs[0x59] = 0x40; if (info->flags & DEVICE_PCI) { - if (info->local == 0x0a) { + if ((info->local & 0xffff) == 0x0a) { dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; If 0, they return 0 and are read-only 8 */ } @@ -388,7 +391,7 @@ cmd640_init(const device_t *info) device_add(&ide_vlb_2ch_device); - dev->slot = pci_add_card(PCI_ADD_NORMAL, cmd640_pci_read, cmd640_pci_write, dev); + dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); dev->irq_mode[0] = dev->irq_mode[1] = 0; dev->irq_pin = PCI_INTA; dev->irq_line = 14; @@ -403,7 +406,7 @@ cmd640_init(const device_t *info) ide_pri_disable(); } else if (info->flags & DEVICE_VLB) { - if (info->local == 0x0078) + if ((info->local & 0xffff) == 0x0078) dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ /* If bit 7 is 1, then device ID has to be written on port x78h before accessing the configuration registers */ @@ -417,7 +420,10 @@ cmd640_init(const device_t *info) dev); } - ide_sec_disable(); + dev->single_channel = !!(info->local & 0x20000); + + if (!dev->single_channel) + ide_sec_disable(); next_id++; @@ -460,3 +466,12 @@ const device_t ide_cmd640_pci_legacy_only_device = { NULL, NULL, NULL, NULL }; + +const device_t ide_cmd640_pci_single_channel_device = { + "CMD PCI-0640B PCI", + DEVICE_PCI, + 0x2000a, + cmd640_init, cmd640_close, cmd640_reset, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index df83c33bd..14bd1e5e7 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -54,6 +54,7 @@ extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ +extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 43e9ad792..068ccae3d 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -317,6 +317,7 @@ extern int machine_at_opti560l_init(const machine_t *); extern int machine_at_dellxp60_init(const machine_t *); #endif extern int machine_at_p5mp3_init(const machine_t *); +extern int machine_at_pb520r_init(const machine_t *); extern int machine_at_586mc1_init(const machine_t *); extern int machine_at_plato_init(const machine_t *); @@ -336,6 +337,7 @@ extern int machine_at_acerv30_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_endeavor_get_device(void); +extern const device_t *at_pb520r_get_device(void); #endif /* m_at_socket7_s7.c */ diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 830324c1a..a36eae830 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -53,6 +53,7 @@ enum { PCI_CARD_ONBOARD, PCI_CARD_SCSI, PCI_CARD_SOUND, + PCI_CARD_IDE, PCI_CARD_SPECIAL }; @@ -62,7 +63,8 @@ enum { PCI_ADD_NORMAL, PCI_ADD_VIDEO, PCI_ADD_SCSI, - PCI_ADD_SOUND + PCI_ADD_SOUND, + PCI_ADD_IDE }; typedef union { diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 37cb9b179..59e179903 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -83,6 +83,7 @@ extern void serial_write_fifo(serial_t *dev, uint8_t dat); extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); extern void serial_set_clock_src(serial_t *dev, double clock_src); +extern void serial_reset_port(serial_t *dev); extern const device_t i8250_device; extern const device_t i8250_pcjr_device; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 29ab81fa6..0fcdb965a 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -25,6 +25,8 @@ extern const device_t fdc37c669_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t i82091aa_device; +extern const device_t i82091aa_ide_device; extern const device_t pc87306_device; extern const device_t pc87307_device; extern const device_t pc87309_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 69682e002..27c40ac06 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -231,6 +231,7 @@ extern const device_t gd5429_vlb_device; extern const device_t gd5430_vlb_device; extern const device_t gd5430_pci_device; extern const device_t gd5434_isa_device; +extern const device_t gd5434_onboard_pci_device; extern const device_t gd5434_vlb_device; extern const device_t gd5434_pci_device; extern const device_t gd5436_pci_device; diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index f7287a093..1ab197fb5 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -152,7 +152,20 @@ machine_at_valuepointp60_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model, 0); + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_zb_device); + device_add(&i82091aa_device); + device_add(&intel_flash_bxt_ami_device); device_add(&i430lx_device); @@ -162,36 +175,48 @@ machine_at_valuepointp60_init(const machine_t *model) int -machine_at_pb502r_init(const machine_t *model) +machine_at_pb520r_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined(L"roms/machines/revenge/1009af2_.bio", - L"roms/machines/revenge/1009af2_.bi1", 0x1c000, 128); + ret = bios_load_linear_combined(L"roms/machines/pb520r/1009bc0r.bio", + L"roms/machines/pb520r/1009bc0r.bi1", 0x1c000, 128); if (bios_only || !ret) return ret; machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_2); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_ONBOARD, 3, 3, 3, 3); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430lx_device); + device_add(&ide_cmd640_pci_single_channel_device); + + if (gfxcard == VID_INTERNAL) + device_add(&gd5434_onboard_pci_device); + device_add(&keyboard_ps2_pci_device); - device_add(&sio_device); - device_add(&ide_cmd640_pci_device); - device_add(&fdc37c665_device); - device_add(&intel_flash_bxt_device); + device_add(&sio_zb_device); + device_add(&i82091aa_ide_device); + device_add(&intel_flash_bxt_ami_device); return ret; } +const device_t * +at_pb520r_get_device(void) +{ + return &gd5434_onboard_pci_device; +} + + int machine_at_opti560l_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 61d440920..3b33d1837 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -251,9 +251,7 @@ const machine_t machines[] = { #endif { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 192, 2, 127, machine_at_p5mp3_init, NULL }, { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, -#ifdef UNFINISHED { "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 2, 128, 2, 127, machine_at_pb520r_init, at_pb520r_get_device }, -#endif /* Socket 5 machines */ /* 430NX */ diff --git a/src/pci.c b/src/pci.c index 336cd8d2f..6001406cd 100644 --- a/src/pci.c +++ b/src/pci.c @@ -905,6 +905,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), ((dev->type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) || ((dev->type == PCI_CARD_SCSI) && (add_type == PCI_ADD_SCSI)) || ((dev->type == PCI_CARD_SOUND) && (add_type == PCI_ADD_SOUND)) || + ((dev->type == PCI_CARD_IDE) && (add_type == PCI_ADD_IDE)) || ((dev->type == PCI_CARD_NORTHBRIDGE) && (add_type == PCI_ADD_NORTHBRIDGE)) || ((dev->type == PCI_CARD_SOUTHBRIDGE) && (add_type == PCI_ADD_SOUTHBRIDGE)) || ((dev->id == add_type) && (add_type < PCI_ADD_NORTHBRIDGE))) { diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c new file mode 100644 index 000000000..c6e2effb8 --- /dev/null +++ b/src/sio/sio_82091aa.c @@ -0,0 +1,293 @@ +/* + * 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 Intel 82019AA Super I/O chip. + * + * + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/rom.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> + + +typedef struct { + uint8_t cur_reg, has_ide, + regs[81]; + uint16_t base_address; + fdc_t * fdc; + serial_t * uart[2]; +} i82091aa_t; + + +static void +fdc_handler(i82091aa_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0x10] & 0x01) + fdc_set_base(dev->fdc, (dev->regs[0x10] & 0x02) ? 0x0370 : 0x03f0); +} + + +static void +lpt1_handler(i82091aa_t *dev) +{ + uint16_t lpt_port = 0x378; + + lpt1_remove(); + + switch ((dev->regs[0x20] >> 1) & 0x03) { + case 0x00: + lpt_port = 0x378; + break; + case 1: + lpt_port = 0x278; + break; + case 2: + lpt_port = 0x3bc; + break; + case 3: + lpt_port = 0x000; + break; + } + + if ((dev->regs[0x20] & 0x01) && lpt_port) + lpt1_init(lpt_port); + + lpt1_irq((dev->regs[0x20] & 0x08) ? 7 : 5); +} + + +static void +serial_handler(i82091aa_t *dev, int uart) +{ + int reg = (0x30 + (uart << 4)); + uint16_t uart_port = 0x3f8; + + serial_remove(dev->uart[uart]); + + switch ((dev->regs[reg] >> 1) & 0x07) { + case 0x00: + uart_port = 0x3f8; + break; + case 0x01: + uart_port = 0x2f8; + break; + case 0x02: + uart_port = 0x220; + break; + case 0x03: + uart_port = 0x228; + break; + case 0x04: + uart_port = 0x238; + break; + case 0x05: + uart_port = 0x2e8; + break; + case 0x06: + uart_port = 0x338; + break; + case 0x07: + uart_port = 0x3e8; + break; + } + + serial_setup(dev->uart[uart], uart_port, (dev->regs[0x20] & 0x10) ? 4 : 3); +} + + +static void +ide_handler(i82091aa_t *dev) +{ + ide_sec_disable(); + ide_set_base(1, (dev->regs[0x50] & 0x02) ? 0x170 : 0x1f0); + ide_set_side(1, (dev->regs[0x50] & 0x02) ? 0x376 : 0x3f6); + if (dev->regs[0x50] & 0x01) + ide_sec_enable(); +} + + +static void +i82091aa_write(uint16_t port, uint8_t val, void *priv) +{ + i82091aa_t *dev = (i82091aa_t *) priv; + uint8_t index, valxor; + uint8_t uart = (dev->cur_reg >> 4) - 0x03; + uint8_t *reg = &(dev->regs[dev->cur_reg]); + + index = (port & 1) ? 0 : 1; + + if (index) { + dev->cur_reg = val; + return; + } else if (dev->cur_reg < 0x51) + valxor = val ^ *reg; + + switch(dev->cur_reg) { + case 0x02: + *reg = (*reg & 0x78) | (val & 0x01); + break; + case 0x03: + *reg = (val & 0xf8); + break; + case 0x10: + *reg = (val & 0x83); + if (valxor & 0x03) + fdc_handler(dev); + break; + case 0x11: + *reg = (val & 0x0f); + if ((valxor & 0x04) && (val & 0x04)) + fdc_reset(dev->fdc); + break; + case 0x20: + *reg = (val & 0xef); + if (valxor & 0x07) + lpt1_handler(dev); + break; + case 0x21: + *reg = (val & 0x2f); + break; + case 0x30: case 0x40: + *reg = (val & 0x9f); + if (valxor & 0x1f) + serial_handler(dev, uart); + if (valxor & 0x80) + serial_set_clock_src(dev->uart[uart], (val & 0x80) ? 2000000.0 : (24000000.0 / 13.0)); + break; + case 0x31: case 0x41: + *reg = (val & 0x1f); + if ((valxor & 0x04) && (val & 0x04)) + serial_reset_port(dev->uart[uart]); + break; + case 0x50: + *reg = (val & 0x07); + if (dev->has_ide && (valxor & 0x03)) + ide_handler(dev); + break; + } +} + + +uint8_t +i82091aa_read(uint16_t port, void *priv) +{ + i82091aa_t *dev = (i82091aa_t *) priv; + uint8_t ret = 0xff, index; + + index = (port & 1) ? 0 : 1; + + if (index) + ret = dev->cur_reg; + else if (dev->cur_reg < 0x51) + ret = dev->regs[dev->cur_reg]; + + return ret; +} + + +void +i82091aa_reset(i82091aa_t *dev) +{ + memset(dev->regs, 0x00, 81); + + dev->regs[0x00] = 0xa0; + dev->regs[0x10] = 0x01; + dev->regs[0x31] = dev->regs[0x41] = 0x02; + dev->regs[0x50] = 0x01; + + fdc_handler(dev); + lpt1_handler(dev); + serial_handler(dev, 0); + serial_handler(dev, 1); + serial_set_clock_src(dev->uart[0], (24000000.0 / 13.0)); + serial_set_clock_src(dev->uart[1], (24000000.0 / 13.0)); + + if (dev->has_ide) + ide_handler(dev); + + fdc_reset(dev->fdc); +} + + +static void +i82091aa_close(void *priv) +{ + i82091aa_t *dev = (i82091aa_t *) priv; + + free(dev); +} + + +static void * +i82091aa_init(const device_t *info) +{ + i82091aa_t *dev = (i82091aa_t *) malloc(sizeof(i82091aa_t)); + memset(dev, 0, sizeof(i82091aa_t)); + + dev->fdc = device_add(&fdc_at_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->has_ide = !!(info->local & 0x200); + + i82091aa_reset(dev); + + dev->regs[0x02] = info->local & 0xff; + + if (info->local & 0x08) + dev->base_address = (info->local & 0x100) ? 0x0398 : 0x0024; + else + dev->base_address = (info->local & 0x100) ? 0x026e : 0x0022; + + io_sethandler(dev->base_address, 0x0002, + i82091aa_read, NULL, NULL, i82091aa_write, NULL, NULL, dev); + + return dev; +} + + +const device_t i82091aa_device = { + "Intel 82091AA Super I/O", + 0, + 0x40, + i82091aa_init, i82091aa_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t i82091aa_ide_device = { + "Intel 82091AA Super I/O (With IDE)", + 0, + 0x240, + i82091aa_init, i82091aa_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 478edd8f4..7c6014199 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -67,6 +67,8 @@ #define CIRRUS_ID_CLGD5428 0x98 #define CIRRUS_ID_CLGD5429 0x9c #define CIRRUS_ID_CLGD5430 0xa0 +#define CIRRUS_ID_CLGD5432 0xa2 +#define CIRRUS_ID_CLGD5434_4 0xa4 #define CIRRUS_ID_CLGD5434 0xa8 #define CIRRUS_ID_CLGD5436 0xac #define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ @@ -2875,43 +2877,82 @@ cl_pci_read(int func, int addr, void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; + uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return 0; - - switch (addr) { - case 0x00: return 0x13; /*Cirrus Logic*/ - case 0x01: return 0x10; + ret = 0x00; + else switch (addr) { + case 0x00: + ret = 0x13; /*Cirrus Logic*/ + break; + case 0x01: + ret = 0x10; + break; case 0x02: - return svga->crtc[0x27]; - case 0x03: return 0x00; + ret = svga->crtc[0x27]; + break; + case 0x03: + ret = 0x00; + break; case PCI_REG_COMMAND: - return gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + ret = gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + break; - case 0x07: return 0x02; /*Fast DEVSEL timing*/ - - case 0x08: return gd54xx->rev; /*Revision ID*/ - case 0x09: return 0x00; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; + case 0x07: + ret = 0x02; /*Fast DEVSEL timing*/ + break; - case 0x10: return 0x08; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return gd54xx->lfb_base >> 24; + case 0x08: + ret = gd54xx->rev; /*Revision ID*/ + break; + case 0x09: + ret = 0x00; /*Programming interface*/ + break; - case 0x30: return (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return gd54xx->pci_regs[0x32]; - case 0x33: return gd54xx->pci_regs[0x33]; + case 0x0a: + ret = 0x00; /*Supports VGA interface*/ + break; + case 0x0b: + ret = 0x03; + break; - case 0x3c: return gd54xx->int_line; - case 0x3d: return PCI_INTA; + case 0x10: + ret = 0x08; /*Linear frame buffer address*/ + break; + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = gd54xx->lfb_base >> 24; + break; + + case 0x30: + ret = (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = gd54xx->pci_regs[0x32]; + break; + case 0x33: + ret = gd54xx->pci_regs[0x33]; + break; + + case 0x3c: + ret = gd54xx->int_line; + break; + case 0x3d: + ret = PCI_INTA; + break; } - return 0; + + return ret; } @@ -3040,10 +3081,22 @@ static void romfn = BIOS_GD5429_PATH; break; - case CIRRUS_ID_CLGD5434: - romfn = BIOS_GD5434_PATH; + case CIRRUS_ID_CLGD5432: + case CIRRUS_ID_CLGD5434_4: + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } break; - + + case CIRRUS_ID_CLGD5434: + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else + romfn = BIOS_GD5434_PATH; + break; + case CIRRUS_ID_CLGD5436: romfn = BIOS_GD5436_PATH; break; @@ -3059,7 +3112,10 @@ static void romfn = BIOS_GD5440_PATH; } else { /* CL-GD 5430 */ - if (gd54xx->pci) + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else if (gd54xx->pci) romfn = BIOS_GD5430_PCI_PATH; else romfn = BIOS_GD5430_VLB_PATH; @@ -3688,6 +3744,20 @@ const device_t gd5434_isa_device = gd5434_config }; +const device_t gd5434_onboard_pci_device = +{ + "Cirrus Logic CL-GD 5434-4 (On-Board PCI)", + DEVICE_PCI, + CIRRUS_ID_CLGD5434 | 0x200, + gd54xx_init, + gd54xx_close, + NULL, + NULL, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5434_config +}; + const device_t gd5434_vlb_device = { "Cirrus Logic CL-GD 5434 (VLB)", diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 2776af130..244d57669 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -622,9 +622,8 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem. mouse_serial.o mouse_ps2.o SIOOBJ := sio_acc3221.o \ - sio_f82c710.o \ - sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o \ - sio_fdc37c93x.o \ + sio_f82c710.o sio_82091aa.o \ + sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \ From f4f7877ef6e9f1973ab9b6478e168fa6f1f1c388 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Jul 2020 04:15:04 +0200 Subject: [PATCH 5/5] Fixed the memory limits for the PB520R. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3b33d1837..c9602b72d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -251,7 +251,7 @@ const machine_t machines[] = { #endif { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 192, 2, 127, machine_at_p5mp3_init, NULL }, { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, - { "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 2, 128, 2, 127, machine_at_pb520r_init, at_pb520r_get_device }, + { "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 136, 2, 127, machine_at_pb520r_init, at_pb520r_get_device }, /* Socket 5 machines */ /* 430NX */