Add initial implementation of Intel VS440FX motherboard.
As part of this, add dummy Pentium Pro emulation, as well as Intel 440FX chipset, PC87307 SuperIO and Intel 28FB200BX-T Flash.
This commit is contained in:
parent
602d6f1ce6
commit
cf33ab6c39
15 changed files with 751 additions and 101 deletions
151
src/pc87307.c
Normal file
151
src/pc87307.c
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "fdc.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "serial.h"
|
||||
#include "pc87307.h"
|
||||
|
||||
typedef struct pc87307_t
|
||||
{
|
||||
int cur_reg;
|
||||
int cur_device;
|
||||
|
||||
uint8_t superio_cfg1, superio_cfg2;
|
||||
|
||||
struct
|
||||
{
|
||||
int enable;
|
||||
uint16_t addr;
|
||||
int irq;
|
||||
int dma;
|
||||
} dev[9];
|
||||
} pc87307_t;
|
||||
|
||||
static pc87307_t pc87307_global;
|
||||
|
||||
#define DEV_KBC 0
|
||||
#define DEV_MOUSE 1
|
||||
#define DEV_RTC 2
|
||||
#define DEV_FDC 3
|
||||
#define DEV_LPT 4
|
||||
#define DEV_COM2 5
|
||||
#define DEV_COM1 6
|
||||
#define DEV_GPIO 7
|
||||
#define DEV_POWER 8
|
||||
|
||||
#define REG_DEVICE 0x07
|
||||
#define REG_SID 0x20
|
||||
#define REG_SUPERIO_CFG1 0x21
|
||||
#define REG_SUPERIO_CFG2 0x22
|
||||
#define REG_ENABLE 0x30
|
||||
#define REG_ADDRHI 0x60
|
||||
#define REG_ADDRLO 0x61
|
||||
#define REG_IRQ 0x70
|
||||
#define REG_DMA 0x74
|
||||
|
||||
void pc87307_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
pc87307_t *pc87307 = (pc87307_t *)p;
|
||||
|
||||
if (port == 0x2e)
|
||||
pc87307->cur_reg = val;
|
||||
else
|
||||
{
|
||||
if (pc87307->cur_reg == REG_DEVICE)
|
||||
pc87307->cur_device = val & 0xf;
|
||||
else
|
||||
{
|
||||
// pclog("Write pc87307 %02x [%02x] %02x\n", pc87307->cur_reg, pc87307->cur_device, val);
|
||||
switch (pc87307->cur_reg)
|
||||
{
|
||||
case REG_ENABLE:
|
||||
if (pc87307->cur_device <= DEV_POWER)
|
||||
pc87307->dev[pc87307->cur_device].enable = val;
|
||||
break;
|
||||
case REG_ADDRLO:
|
||||
if (pc87307->cur_device <= DEV_POWER)
|
||||
pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0xff00) | val;
|
||||
break;
|
||||
case REG_ADDRHI:
|
||||
if (pc87307->cur_device <= DEV_POWER)
|
||||
pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0x00ff) | (val << 8);
|
||||
break;
|
||||
case REG_IRQ:
|
||||
if (pc87307->cur_device <= DEV_POWER)
|
||||
pc87307->dev[pc87307->cur_device].irq = val;
|
||||
break;
|
||||
case REG_DMA:
|
||||
if (pc87307->cur_device <= DEV_POWER)
|
||||
pc87307->dev[pc87307->cur_device].dma = val;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pc87307->cur_device)
|
||||
{
|
||||
case DEV_FDC:
|
||||
fdc_remove();
|
||||
if (pc87307->dev[DEV_FDC].enable & 1)
|
||||
fdc_add();
|
||||
break;
|
||||
case DEV_COM1:
|
||||
serial1_remove();
|
||||
if (pc87307->dev[DEV_COM1].enable & 1)
|
||||
serial1_set(pc87307->dev[DEV_COM1].addr, pc87307->dev[DEV_COM1].irq);
|
||||
break;
|
||||
case DEV_COM2:
|
||||
serial2_remove();
|
||||
if (pc87307->dev[DEV_COM2].enable & 1)
|
||||
serial2_set(pc87307->dev[DEV_COM2].addr, pc87307->dev[DEV_COM2].irq);
|
||||
break;
|
||||
case DEV_LPT:
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
if (pc87307->dev[DEV_LPT].enable & 1)
|
||||
lpt1_init(pc87307->dev[DEV_LPT].addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pc87307_read(uint16_t port, void *p)
|
||||
{
|
||||
pc87307_t *pc87307 = (pc87307_t *)p;
|
||||
|
||||
// pclog("Read pc87307 %02x\n", pc87307->cur_reg);
|
||||
|
||||
switch (pc87307->cur_reg)
|
||||
{
|
||||
case REG_DEVICE:
|
||||
return pc87307->cur_device;
|
||||
case REG_SID:
|
||||
return 0x20; /*PC87307*/
|
||||
case REG_SUPERIO_CFG1:
|
||||
return pc87307->superio_cfg1;
|
||||
case REG_SUPERIO_CFG2:
|
||||
return pc87307->superio_cfg2;
|
||||
case REG_ENABLE:
|
||||
return pc87307->dev[pc87307->cur_device].enable;
|
||||
case REG_ADDRLO:
|
||||
return pc87307->dev[pc87307->cur_device].addr & 0xff;
|
||||
case REG_ADDRHI:
|
||||
return pc87307->dev[pc87307->cur_device].addr >> 8;
|
||||
case REG_IRQ:
|
||||
return pc87307->dev[pc87307->cur_device].irq;
|
||||
case REG_DMA:
|
||||
return pc87307->dev[pc87307->cur_device].dma;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void pc87307_init(uint16_t base)
|
||||
{
|
||||
memset(&pc87307_global, 0, sizeof(pc87307_t));
|
||||
|
||||
pc87307_global.superio_cfg1 = 0x04;
|
||||
pc87307_global.superio_cfg2 = 0x03;
|
||||
|
||||
io_sethandler(base, 0x0002, pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, &pc87307_global);
|
||||
}
|
||||
Loading…
Reference in a new issue