Merge branch 'master' of github.com:86Box/86Box into tc1995
This commit is contained in:
@@ -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
|
||||
@@ -688,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;
|
||||
}
|
||||
@@ -706,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;
|
||||
@@ -727,11 +748,20 @@ 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;
|
||||
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;
|
||||
@@ -747,7 +777,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 +811,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 */
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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
|
||||
{ "[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 */
|
||||
|
@@ -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))) {
|
||||
|
293
src/sio/sio_82091aa.c
Normal file
293
src/sio/sio_82091aa.c
Normal file
@@ -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, <mgrca8@gmail.com>
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#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
|
||||
};
|
@@ -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)",
|
||||
|
@@ -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 \
|
||||
|
Reference in New Issue
Block a user