Readded the Award 430VX PCI, this time with the UMC UM8699F Super I/O chip emulated correctly per commit from mainline PCem + my own fixes.
This commit is contained in:
@@ -187,7 +187,7 @@ SYSOBJ = model.o \
|
|||||||
tandy_eeprom.o tandy_rom.o
|
tandy_eeprom.o tandy_rom.o
|
||||||
DEVOBJ = bugger.o lpt.o $(SERIAL) \
|
DEVOBJ = bugger.o lpt.o $(SERIAL) \
|
||||||
fdc37c665.o fdc37c669.o fdc37c932fr.o \
|
fdc37c665.o fdc37c669.o fdc37c932fr.o \
|
||||||
pc87306.o sis85c471.o w83877f.o \
|
pc87306.o sis85c471.o w83877f.o um8669f.o \
|
||||||
keyboard.o \
|
keyboard.o \
|
||||||
keyboard_xt.o keyboard_at.o keyboard_pcjr.o \
|
keyboard_xt.o keyboard_at.o keyboard_pcjr.o \
|
||||||
keyboard_amstrad.o keyboard_olim24.o \
|
keyboard_amstrad.o keyboard_olim24.o \
|
||||||
|
|||||||
11
src/mem.c
11
src/mem.c
@@ -441,16 +441,6 @@ int loadbios()
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case ROM_SIS496:
|
|
||||||
f = romfopen(L"roms/machines/sis496/SIS496_3.AWA", L"rb");
|
|
||||||
if (!f) break;
|
|
||||||
fread(rom, 0x20000, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
biosmask = 0x1ffff;
|
|
||||||
pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
case ROM_430VX:
|
case ROM_430VX:
|
||||||
f = romfopen(L"roms/machines/430vx/55XWUQ0E.BIN", L"rb");
|
f = romfopen(L"roms/machines/430vx/55XWUQ0E.BIN", L"rb");
|
||||||
if (!f) break;
|
if (!f) break;
|
||||||
@@ -458,7 +448,6 @@ int loadbios()
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
biosmask = 0x1ffff;
|
biosmask = 0x1ffff;
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
case ROM_REVENGE:
|
case ROM_REVENGE:
|
||||||
f = romfopen(L"roms/machines/revenge/1009AF2_.BIO", L"rb");
|
f = romfopen(L"roms/machines/revenge/1009AF2_.BIO", L"rb");
|
||||||
|
|||||||
18
src/model.c
18
src/model.c
@@ -66,9 +66,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "tandy_eeprom.h"
|
#include "tandy_eeprom.h"
|
||||||
#include "tandy_rom.h"
|
#include "tandy_rom.h"
|
||||||
#if 0
|
|
||||||
#include "um8669f.h"
|
#include "um8669f.h"
|
||||||
#endif
|
|
||||||
#include "video/vid_pcjr.h"
|
#include "video/vid_pcjr.h"
|
||||||
#include "video/vid_tandy.h"
|
#include "video/vid_tandy.h"
|
||||||
#include "w83877f.h"
|
#include "w83877f.h"
|
||||||
@@ -102,6 +100,7 @@ extern void at_wd76c10_init(void);
|
|||||||
extern void at_ali1429_init(void);
|
extern void at_ali1429_init(void);
|
||||||
extern void at_headland_init(void);
|
extern void at_headland_init(void);
|
||||||
extern void at_opti495_init(void);
|
extern void at_opti495_init(void);
|
||||||
|
extern void at_i430vx_init(void);
|
||||||
extern void at_batman_init(void);
|
extern void at_batman_init(void);
|
||||||
#if 0
|
#if 0
|
||||||
extern void at_586mc1_init(void);
|
extern void at_586mc1_init(void);
|
||||||
@@ -224,6 +223,7 @@ MODEL models[] =
|
|||||||
{"[Socket 7 HX] ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL },
|
{"[Socket 7 HX] ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL },
|
||||||
|
|
||||||
{"[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL },
|
{"[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL },
|
||||||
|
{"[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i430vx_init, NULL },
|
||||||
{"[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL },
|
{"[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL },
|
||||||
|
|
||||||
{"[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL },
|
{"[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL },
|
||||||
@@ -875,6 +875,20 @@ void at_p55tvp4_init(void)
|
|||||||
device_add(&intel_flash_bxt_device);
|
device_add(&intel_flash_bxt_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void at_i430vx_init(void)
|
||||||
|
{
|
||||||
|
at_ide_init();
|
||||||
|
pci_init(PCI_CONFIG_TYPE_1);
|
||||||
|
pci_slot(0x11);
|
||||||
|
pci_slot(0x12);
|
||||||
|
pci_slot(0x13);
|
||||||
|
pci_slot(0x14);
|
||||||
|
i430vx_init();
|
||||||
|
piix_init(7, 18, 17, 20, 19);
|
||||||
|
um8669f_init();
|
||||||
|
device_add(&intel_flash_bxt_device);
|
||||||
|
}
|
||||||
|
|
||||||
void at_p55va_init(void)
|
void at_p55va_init(void)
|
||||||
{
|
{
|
||||||
at_ide_init();
|
at_ide_init();
|
||||||
|
|||||||
277
src/um8669f.c
Normal file
277
src/um8669f.c
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
/*um8669f :
|
||||||
|
|
||||||
|
aa to 108 unlocks
|
||||||
|
next 108 write is register select (Cx?)
|
||||||
|
data read/write to 109
|
||||||
|
55 to 108 locks
|
||||||
|
|
||||||
|
C1
|
||||||
|
bit 7 - enable PnP registers
|
||||||
|
|
||||||
|
PnP registers :
|
||||||
|
|
||||||
|
07 - device :
|
||||||
|
0 = FDC
|
||||||
|
1 = COM1
|
||||||
|
2 = COM2
|
||||||
|
3 = LPT1
|
||||||
|
5 = Game port
|
||||||
|
30 - enable
|
||||||
|
60/61 - addr
|
||||||
|
70 - IRQ
|
||||||
|
74 - DMA*/
|
||||||
|
|
||||||
|
#include "ibm.h"
|
||||||
|
|
||||||
|
#include "disc.h"
|
||||||
|
#include "fdd.h"
|
||||||
|
#include "fdc.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "lpt.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "um8669f.h"
|
||||||
|
|
||||||
|
typedef struct um8669f_t
|
||||||
|
{
|
||||||
|
int locked;
|
||||||
|
int cur_reg_108;
|
||||||
|
uint8_t regs_108[256];
|
||||||
|
|
||||||
|
int cur_reg;
|
||||||
|
int cur_device;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int enable;
|
||||||
|
uint16_t addr;
|
||||||
|
int irq;
|
||||||
|
int dma;
|
||||||
|
} dev[8];
|
||||||
|
} um8669f_t;
|
||||||
|
|
||||||
|
static um8669f_t um8669f_global;
|
||||||
|
|
||||||
|
#define DEV_FDC 0
|
||||||
|
#define DEV_COM1 1
|
||||||
|
#define DEV_COM2 2
|
||||||
|
#define DEV_LPT1 3
|
||||||
|
#define DEV_GAME 5
|
||||||
|
|
||||||
|
#define REG_DEVICE 0x07
|
||||||
|
#define REG_ENABLE 0x30
|
||||||
|
#define REG_ADDRHI 0x60
|
||||||
|
#define REG_ADDRLO 0x61
|
||||||
|
#define REG_IRQ 0x70
|
||||||
|
#define REG_DMA 0x74
|
||||||
|
|
||||||
|
void um8669f_pnp_write(uint16_t port, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
um8669f_t *um8669f = (um8669f_t *)p;
|
||||||
|
|
||||||
|
uint8_t valxor = 0;
|
||||||
|
|
||||||
|
if (port == 0x279)
|
||||||
|
um8669f->cur_reg = val;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (um8669f->cur_reg == REG_DEVICE)
|
||||||
|
um8669f->cur_device = val & 7;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* pclog("Write UM8669F %02x [%02x] %02x\n", um8669f->cur_reg, um8669f->cur_device, val); */
|
||||||
|
switch (um8669f->cur_reg)
|
||||||
|
{
|
||||||
|
case REG_ENABLE:
|
||||||
|
valxor = um8669f->dev[um8669f->cur_device].enable ^ val;
|
||||||
|
um8669f->dev[um8669f->cur_device].enable = val;
|
||||||
|
break;
|
||||||
|
case REG_ADDRLO:
|
||||||
|
valxor = (um8669f->dev[um8669f->cur_device].addr & 0xff) ^ val;
|
||||||
|
um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val;
|
||||||
|
break;
|
||||||
|
case REG_ADDRHI:
|
||||||
|
valxor = ((um8669f->dev[um8669f->cur_device].addr >> 8) & 0xff) ^ val;
|
||||||
|
um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8);
|
||||||
|
break;
|
||||||
|
case REG_IRQ:
|
||||||
|
valxor = um8669f->dev[um8669f->cur_device].irq ^ val;
|
||||||
|
um8669f->dev[um8669f->cur_device].irq = val;
|
||||||
|
break;
|
||||||
|
case REG_DMA:
|
||||||
|
valxor = um8669f->dev[um8669f->cur_device].dma ^ val;
|
||||||
|
um8669f->dev[um8669f->cur_device].dma = val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
valxor = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pclog("UM8669F: Write %02X to [%02X][%02X]...\n", val, um8669f->cur_device, um8669f->cur_reg); */
|
||||||
|
|
||||||
|
switch (um8669f->cur_device)
|
||||||
|
{
|
||||||
|
case DEV_FDC:
|
||||||
|
if ((um8669f->cur_reg == REG_ENABLE) && valxor)
|
||||||
|
{
|
||||||
|
fdc_remove();
|
||||||
|
if (um8669f->dev[DEV_FDC].enable & 1)
|
||||||
|
fdc_add();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_COM1:
|
||||||
|
if (valxor)
|
||||||
|
{
|
||||||
|
serial_remove(1);
|
||||||
|
if (um8669f->dev[DEV_COM1].enable & 1)
|
||||||
|
serial_setup(1, um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_COM2:
|
||||||
|
if (valxor)
|
||||||
|
{
|
||||||
|
serial_remove(2);
|
||||||
|
if (um8669f->dev[DEV_COM2].enable & 1)
|
||||||
|
serial_setup(2, um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_LPT1:
|
||||||
|
if (valxor)
|
||||||
|
{
|
||||||
|
lpt1_remove();
|
||||||
|
if (um8669f->dev[DEV_LPT1].enable & 1)
|
||||||
|
lpt1_init(um8669f->dev[DEV_LPT1].addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t um8669f_pnp_read(uint16_t port, void *p)
|
||||||
|
{
|
||||||
|
um8669f_t *um8669f = (um8669f_t *)p;
|
||||||
|
|
||||||
|
/* pclog("Read UM8669F %02x\n", um8669f->cur_reg); */
|
||||||
|
|
||||||
|
switch (um8669f->cur_reg)
|
||||||
|
{
|
||||||
|
case REG_DEVICE:
|
||||||
|
return um8669f->cur_device;
|
||||||
|
case REG_ENABLE:
|
||||||
|
return um8669f->dev[um8669f->cur_device].enable;
|
||||||
|
case REG_ADDRLO:
|
||||||
|
return um8669f->dev[um8669f->cur_device].addr & 0xff;
|
||||||
|
case REG_ADDRHI:
|
||||||
|
return um8669f->dev[um8669f->cur_device].addr >> 8;
|
||||||
|
case REG_IRQ:
|
||||||
|
return um8669f->dev[um8669f->cur_device].irq;
|
||||||
|
case REG_DMA:
|
||||||
|
return um8669f->dev[um8669f->cur_device].dma;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void um8669f_write(uint16_t port, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
um8669f_t *um8669f = (um8669f_t *)p;
|
||||||
|
|
||||||
|
if (um8669f->locked)
|
||||||
|
{
|
||||||
|
if (port == 0x108 && val == 0xaa)
|
||||||
|
um8669f->locked = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (port == 0x108)
|
||||||
|
{
|
||||||
|
if (val == 0x55)
|
||||||
|
um8669f->locked = 1;
|
||||||
|
else
|
||||||
|
um8669f->cur_reg_108 = val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* pclog("Write UM8669f register %02x %02x %04x:%04x %i\n", um8669f_curreg, val, CS,cpu_state.pc, ins); */
|
||||||
|
um8669f->regs_108[um8669f->cur_reg_108] = val;
|
||||||
|
|
||||||
|
io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f);
|
||||||
|
io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f);
|
||||||
|
io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f);
|
||||||
|
if (um8669f->regs_108[0xc1] & 0x80)
|
||||||
|
{
|
||||||
|
io_sethandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f);
|
||||||
|
io_sethandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f);
|
||||||
|
io_sethandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t um8669f_read(uint16_t port, void *p)
|
||||||
|
{
|
||||||
|
um8669f_t *um8669f = (um8669f_t *)p;
|
||||||
|
|
||||||
|
/* pclog("um8669f_read : port=%04x reg %02X locked=%i %02x\n", port, um8669f_curreg, um8669f_locked, um8669f_regs[um8669f_curreg]); */
|
||||||
|
if (um8669f->locked)
|
||||||
|
return 0xff;
|
||||||
|
|
||||||
|
if (port == 0x108)
|
||||||
|
return um8669f->cur_reg_108; /*???*/
|
||||||
|
else
|
||||||
|
return um8669f->regs_108[um8669f->cur_reg_108];
|
||||||
|
}
|
||||||
|
|
||||||
|
void um8669f_reset(void)
|
||||||
|
{
|
||||||
|
fdc_update_is_nsc(0);
|
||||||
|
|
||||||
|
serial_remove(1);
|
||||||
|
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
|
||||||
|
|
||||||
|
serial_remove(2);
|
||||||
|
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
|
||||||
|
|
||||||
|
lpt2_remove();
|
||||||
|
|
||||||
|
lpt1_remove();
|
||||||
|
lpt1_init(0x378);
|
||||||
|
|
||||||
|
memset(&um8669f_global, 0, sizeof(um8669f_t));
|
||||||
|
|
||||||
|
um8669f_global.locked = 1;
|
||||||
|
|
||||||
|
fdc_update_densel_polarity(1);
|
||||||
|
fdc_update_densel_force(0);
|
||||||
|
|
||||||
|
fdd_swap = 0;
|
||||||
|
|
||||||
|
io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global);
|
||||||
|
io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global);
|
||||||
|
io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, &um8669f_global);
|
||||||
|
|
||||||
|
um8669f_global.dev[DEV_FDC].enable = 1;
|
||||||
|
um8669f_global.dev[DEV_FDC].addr = 0x03f0;
|
||||||
|
um8669f_global.dev[DEV_FDC].irq = 6;
|
||||||
|
um8669f_global.dev[DEV_FDC].dma = 2;
|
||||||
|
|
||||||
|
um8669f_global.dev[DEV_COM1].enable = 1;
|
||||||
|
um8669f_global.dev[DEV_COM1].addr = 0x03f8;
|
||||||
|
um8669f_global.dev[DEV_COM1].irq = 4;
|
||||||
|
|
||||||
|
um8669f_global.dev[DEV_COM2].enable = 1;
|
||||||
|
um8669f_global.dev[DEV_COM2].addr = 0x02f8;
|
||||||
|
um8669f_global.dev[DEV_COM2].irq = 3;
|
||||||
|
|
||||||
|
um8669f_global.dev[DEV_LPT1].enable = 1;
|
||||||
|
um8669f_global.dev[DEV_LPT1].addr = 0x0378;
|
||||||
|
um8669f_global.dev[DEV_LPT1].irq = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void um8669f_init()
|
||||||
|
{
|
||||||
|
io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global);
|
||||||
|
|
||||||
|
um8669f_reset();
|
||||||
|
|
||||||
|
pci_reset_handler.super_io_reset = um8669f_reset;
|
||||||
|
}
|
||||||
1
src/um8669f.h
Normal file
1
src/um8669f.h
Normal file
@@ -0,0 +1 @@
|
|||||||
|
extern void um8669f_init();
|
||||||
Reference in New Issue
Block a user