Added Intel Premiere/PCI (Batman's Revenge) and Advanced/EV (Endeavor) motherboards.
Added emulation of i430LX and i430FX chipsets. Added support for PCI configuration type 2, used by i430LX. Added AT disable keyboard command, and fixed enable keyboard command. Added emulation of Intel 28F001BXT flash ROM, used by Advanced/EV. Fixed a bug in REP when using multiple 66/67 prefixes.
This commit is contained in:
parent
55b51a4a55
commit
84ac04d2df
24 changed files with 835 additions and 137 deletions
20
readme.txt
20
readme.txt
|
|
@ -256,6 +256,26 @@ ROM files needed:
|
|||
SIS496-1.AWA
|
||||
|
||||
|
||||
Intel Premiere/PCI (Batman's Revenge) (1994)
|
||||
A Socket 4 based board with 430LX chipset.
|
||||
|
||||
ROM files needed:
|
||||
|
||||
1009AF2_.BI0
|
||||
1009AF2_.BI1
|
||||
|
||||
|
||||
Intel Advanced/EV (Endeavor) (1995)
|
||||
A Socket 5/7 based board with 430FX chipset. The real board has a Sound Blaster Vibra 16 on board,
|
||||
which is not emulated - use a discrete card instead. Some Advanced/EVs also had a Trio64 on board,
|
||||
the emulated board does not have this either.
|
||||
|
||||
ROM files needed:
|
||||
|
||||
1006CB0_.BI0
|
||||
1006CB0_.BI1
|
||||
|
||||
|
||||
Award 430VX PCI (1996)
|
||||
A generic Socket 5/7 board with 430VX chipset.
|
||||
|
||||
|
|
|
|||
1
roms/endeavor/roms.txt
Normal file
1
roms/endeavor/roms.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This directory needs to contain some ROM files.
|
||||
1
roms/revenge/roms.txt
Normal file
1
roms/revenge/roms.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This directory needs to contain some ROM files.
|
||||
|
|
@ -320,10 +320,10 @@ int rep386(int fv)
|
|||
ea_seg = &_gs;
|
||||
goto startrep;
|
||||
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
|
||||
rep32^=0x100;
|
||||
rep32 = (rep32 & 0x200) | (use32 ^ 0x100);
|
||||
goto startrep;
|
||||
case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
|
||||
rep32^=0x200;
|
||||
rep32 = (rep32 & 0x100) | (use32 ^ 0x200);
|
||||
goto startrep;
|
||||
case 0x6C: case 0x16C: /*REP INSB*/
|
||||
if (c>0)
|
||||
|
|
|
|||
|
|
@ -335,10 +335,10 @@ int rep386(int fv)
|
|||
ea_seg = &_gs;
|
||||
goto startrep;
|
||||
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
|
||||
rep32^=0x100;
|
||||
rep32 = (rep32 & 0x200) | (use32 ^ 0x100);
|
||||
goto startrep;
|
||||
case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
|
||||
rep32^=0x200;
|
||||
rep32 = (rep32 & 0x100) | (use32 ^ 0x200);
|
||||
goto startrep;
|
||||
case 0x6C: case 0x16C: /*REP INSB*/
|
||||
// cpu_notreps++;
|
||||
|
|
|
|||
|
|
@ -4,21 +4,21 @@ CC = gcc.exe
|
|||
WINDRES = windres.exe
|
||||
CFLAGS = -O3 -march=i686 -fomit-frame-pointer
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
|
||||
codegen.o codegen_timing_486.o codegen_timing_pentium.o codegen_x86.o config.o cpu.o dac.o device.o dma.o fdc.o gameport.o \
|
||||
headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \
|
||||
mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \
|
||||
opti.o pc.o pci.o pic.o piix.o pit.o ppi.o rom.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o \
|
||||
sound_adlibgold.o sound_cms.o sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o \
|
||||
sound_pas16.o sound_resid.o sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o \
|
||||
sound_ssi2001.o sound_wss.o soundopenal.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o \
|
||||
vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \
|
||||
vid_cl5429.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_et4000w32i.o \
|
||||
vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
|
||||
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_pcjr.o vid_s3.o \
|
||||
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
||||
vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
||||
vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
codegen.o codegen_timing_486.o codegen_timing_pentium.o codegen_x86.o config.o cpu.o dac.o \
|
||||
device.o dma.o fdc.o gameport.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o \
|
||||
intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o \
|
||||
keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o mouse_serial.o \
|
||||
neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o rom.o serial.o \
|
||||
sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
|
||||
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_resid.o \
|
||||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
|
||||
soundopenal.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o vid_et4000.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o \
|
||||
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
FMOBJ = dbopl.o
|
||||
|
|
|
|||
143
src/i430fx.c
Normal file
143
src/i430fx.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "i430fx.h"
|
||||
|
||||
static uint8_t card_i430fx[256];
|
||||
|
||||
static void i430fx_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
void i430fx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x59: /*PAM0*/
|
||||
if ((card_i430fx[0x59] ^ val) & 0xf0)
|
||||
{
|
||||
i430fx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
pclog("i430fx_write : PAM0 write %02X\n", val);
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((card_i430fx[0x5a] ^ val) & 0x0f)
|
||||
i430fx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5a] ^ val) & 0xf0)
|
||||
i430fx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((card_i430fx[0x5b] ^ val) & 0x0f)
|
||||
i430fx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5b] ^ val) & 0xf0)
|
||||
i430fx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((card_i430fx[0x5c] ^ val) & 0x0f)
|
||||
i430fx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5c] ^ val) & 0xf0)
|
||||
i430fx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((card_i430fx[0x5d] ^ val) & 0x0f)
|
||||
i430fx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5d] ^ val) & 0xf0)
|
||||
i430fx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((card_i430fx[0x5e] ^ val) & 0x0f)
|
||||
i430fx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5e] ^ val) & 0xf0)
|
||||
i430fx_map(0xe4000, 0x04000, val >> 4);
|
||||
pclog("i430fx_write : PAM5 write %02X\n", val);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((card_i430fx[0x5f] ^ val) & 0x0f)
|
||||
i430fx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((card_i430fx[0x5f] ^ val) & 0xf0)
|
||||
i430fx_map(0xec000, 0x04000, val >> 4);
|
||||
pclog("i430fx_write : PAM6 write %02X\n", val);
|
||||
break;
|
||||
}
|
||||
|
||||
card_i430fx[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t i430fx_read(int func, int addr, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return card_i430fx[addr];
|
||||
}
|
||||
|
||||
/*The Turbo-Reset Control Register isn't listed in the i430FX datasheet, however
|
||||
the Advanced/EV BIOS seems to assume it exists. It aliases with one of the PCI
|
||||
registers.*/
|
||||
static uint8_t trc = 0;
|
||||
|
||||
void i430fx_trc_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
if ((val & 4) && !(trc & 4))
|
||||
{
|
||||
if (val & 2) /*Hard reset*/
|
||||
i430fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/
|
||||
resetx86();
|
||||
}
|
||||
|
||||
trc = val;
|
||||
}
|
||||
|
||||
void i430fx_init()
|
||||
{
|
||||
pci_add_specific(0, i430fx_read, i430fx_write, NULL);
|
||||
|
||||
memset(card_i430fx, 0, 256);
|
||||
card_i430fx[0x00] = 0x86; card_i430fx[0x01] = 0x80; /*Intel*/
|
||||
card_i430fx[0x02] = 0x22; card_i430fx[0x03] = 0x01; /*SB82437FX-66*/
|
||||
card_i430fx[0x04] = 0x06; card_i430fx[0x05] = 0x00;
|
||||
card_i430fx[0x06] = 0x00; card_i430fx[0x07] = 0x82;
|
||||
card_i430fx[0x08] = 0x00; /*A0 stepping*/
|
||||
card_i430fx[0x09] = 0x00; card_i430fx[0x0a] = 0x00; card_i430fx[0x0b] = 0x06;
|
||||
card_i430fx[0x52] = 0x40; /*256kb PLB cache*/
|
||||
// card_i430fx[0x53] = 0x14;
|
||||
// card_i430fx[0x56] = 0x52; /*DRAM control*/
|
||||
card_i430fx[0x57] = 0x01;
|
||||
card_i430fx[0x60] = card_i430fx[0x61] = card_i430fx[0x62] = card_i430fx[0x63] = card_i430fx[0x64] = 0x02;
|
||||
// card_i430fx[0x67] = 0x11;
|
||||
// card_i430fx[0x69] = 0x03;
|
||||
// card_i430fx[0x70] = 0x20;
|
||||
card_i430fx[0x72] = 0x02;
|
||||
// card_i430fx[0x74] = 0x0e;
|
||||
// card_i430fx[0x78] = 0x23;
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, NULL, NULL, NULL, i430fx_trc_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/i430fx.h
Normal file
1
src/i430fx.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void i430fx_init();
|
||||
146
src/i430lx.c
Normal file
146
src/i430lx.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "i430lx.h"
|
||||
|
||||
static uint8_t card_i430lx[256];
|
||||
|
||||
static void i430lx_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
void i430lx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x59: /*PAM0*/
|
||||
if ((card_i430lx[0x59] ^ val) & 0xf0)
|
||||
{
|
||||
i430lx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
pclog("i430lx_write : PAM0 write %02X\n", val);
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((card_i430lx[0x5a] ^ val) & 0x0f)
|
||||
i430lx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5a] ^ val) & 0xf0)
|
||||
i430lx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((card_i430lx[0x5b] ^ val) & 0x0f)
|
||||
i430lx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5b] ^ val) & 0xf0)
|
||||
i430lx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((card_i430lx[0x5c] ^ val) & 0x0f)
|
||||
i430lx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5c] ^ val) & 0xf0)
|
||||
i430lx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((card_i430lx[0x5d] ^ val) & 0x0f)
|
||||
i430lx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5d] ^ val) & 0xf0)
|
||||
i430lx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((card_i430lx[0x5e] ^ val) & 0x0f)
|
||||
i430lx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5e] ^ val) & 0xf0)
|
||||
i430lx_map(0xe4000, 0x04000, val >> 4);
|
||||
pclog("i430lx_write : PAM5 write %02X\n", val);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((card_i430lx[0x5f] ^ val) & 0x0f)
|
||||
i430lx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((card_i430lx[0x5f] ^ val) & 0xf0)
|
||||
i430lx_map(0xec000, 0x04000, val >> 4);
|
||||
pclog("i430lx_write : PAM6 write %02X\n", val);
|
||||
break;
|
||||
}
|
||||
|
||||
card_i430lx[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t i430lx_read(int func, int addr, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return card_i430lx[addr];
|
||||
}
|
||||
|
||||
static uint8_t trc = 0;
|
||||
|
||||
uint8_t i430lx_trc_read(uint16_t port, void *p)
|
||||
{
|
||||
return trc;
|
||||
}
|
||||
|
||||
void i430lx_trc_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
if ((val & 4) && !(trc & 4))
|
||||
{
|
||||
if (val & 2) /*Hard reset*/
|
||||
i430lx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/
|
||||
resetx86();
|
||||
}
|
||||
|
||||
trc = val;
|
||||
}
|
||||
|
||||
void i430lx_init()
|
||||
{
|
||||
pci_add_specific(0, i430lx_read, i430lx_write, NULL);
|
||||
|
||||
memset(card_i430lx, 0, 256);
|
||||
card_i430lx[0x00] = 0x86; card_i430lx[0x01] = 0x80; /*Intel*/
|
||||
card_i430lx[0x02] = 0xa3; card_i430lx[0x03] = 0x04; /*82434LX*/
|
||||
card_i430lx[0x04] = 0x06; card_i430lx[0x05] = 0x00;
|
||||
card_i430lx[0x06] = 0x00; card_i430lx[0x07] = 0x02;
|
||||
card_i430lx[0x08] = 0x03; /*A3 stepping*/
|
||||
card_i430lx[0x09] = 0x00; card_i430lx[0x0a] = 0x00; card_i430lx[0x0b] = 0x06;
|
||||
card_i430lx[0x50] = 0x80;
|
||||
card_i430lx[0x52] = 0x40; /*256kb PLB cache*/
|
||||
// card_i430lx[0x53] = 0x14;
|
||||
// card_i430lx[0x56] = 0x52; /*DRAM control*/
|
||||
card_i430lx[0x57] = 0x31;
|
||||
card_i430lx[0x60] = card_i430lx[0x61] = card_i430lx[0x62] = card_i430lx[0x63] = card_i430lx[0x64] = 0x02;
|
||||
// card_i430lx[0x67] = 0x11;
|
||||
// card_i430lx[0x69] = 0x03;
|
||||
// card_i430lx[0x70] = 0x20;
|
||||
// card_i430lx[0x72] = 0x02;
|
||||
// card_i430lx[0x74] = 0x0e;
|
||||
// card_i430lx[0x78] = 0x23;
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/i430lx.h
Normal file
1
src/i430lx.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void i430lx_init();
|
||||
|
|
@ -316,6 +316,8 @@ enum
|
|||
ROM_PCI486,
|
||||
ROM_SIS496,
|
||||
ROM_430VX,
|
||||
ROM_ENDEAVOR,
|
||||
ROM_REVENGE,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
|
|
|||
80
src/intel.c
Normal file
80
src/intel.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pit.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "intel.h"
|
||||
|
||||
uint8_t batman_brdconfig(uint16_t port, void *p)
|
||||
{
|
||||
// pclog("batman_brdconfig read port=%04x\n", port);
|
||||
switch (port)
|
||||
{
|
||||
case 0x73:
|
||||
return 0xff;
|
||||
case 0x75:
|
||||
return 0xdf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t batman_timer_latch;
|
||||
static int batman_timer = 0;
|
||||
static void batman_timer_over(void *p)
|
||||
{
|
||||
batman_timer = 0;
|
||||
}
|
||||
|
||||
static void batman_timer_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if (addr & 1)
|
||||
batman_timer_latch = (batman_timer_latch & 0xff) | (val << 8);
|
||||
else
|
||||
batman_timer_latch = (batman_timer_latch & 0xff00) | val;
|
||||
batman_timer = batman_timer_latch * TIMER_USEC;
|
||||
}
|
||||
|
||||
static uint8_t batman_timer_read(uint16_t addr, void *p)
|
||||
{
|
||||
uint16_t batman_timer_latch;
|
||||
|
||||
cycles -= (int)PITCONST;
|
||||
|
||||
timer_clock();
|
||||
|
||||
if (batman_timer < 0)
|
||||
return 0;
|
||||
|
||||
batman_timer_latch = batman_timer / TIMER_USEC;
|
||||
|
||||
if (addr & 1)
|
||||
return batman_timer_latch >> 8;
|
||||
return batman_timer_latch & 0xff;
|
||||
}
|
||||
|
||||
void intel_batman_init()
|
||||
{
|
||||
io_sethandler(0x0073, 0x0001, batman_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0x0075, 0x0001, batman_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL);
|
||||
timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL);
|
||||
}
|
||||
|
||||
|
||||
uint8_t endeavor_brdconfig(uint16_t port, void *p)
|
||||
{
|
||||
// pclog("endeavor_brdconfig read port=%04x\n", port);
|
||||
switch (port)
|
||||
{
|
||||
case 0x79:
|
||||
return 0xff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void intel_endeavor_init()
|
||||
{
|
||||
io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
2
src/intel.h
Normal file
2
src/intel.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
void intel_batman_init();
|
||||
void intel_endeavor_init();
|
||||
176
src/intel_flash.c
Normal file
176
src/intel_flash.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "mem.h"
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_READ_ARRAY = 0xff,
|
||||
CMD_IID = 0x90,
|
||||
CMD_READ_STATUS = 0x70,
|
||||
CMD_CLEAR_STATUS = 0x50,
|
||||
CMD_ERASE_SETUP = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0xd0,
|
||||
CMD_ERASE_SUSPEND = 0xb0,
|
||||
CMD_PROGRAM_SETUP = 0x40
|
||||
};
|
||||
|
||||
typedef struct flash_t
|
||||
{
|
||||
uint8_t command, status;
|
||||
mem_mapping_t read_mapping, write_mapping;
|
||||
} flash_t;
|
||||
|
||||
static flash_t flash;
|
||||
|
||||
static uint8_t flash_read(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *flash = (flash_t *)p;
|
||||
// pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, pc);
|
||||
switch (flash->command)
|
||||
{
|
||||
case CMD_IID:
|
||||
if (addr & 1)
|
||||
return 0x94;
|
||||
return 0x89;
|
||||
|
||||
default:
|
||||
return flash->status;
|
||||
}
|
||||
}
|
||||
|
||||
static void flash_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
flash_t *flash = (flash_t *)p;
|
||||
// pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, pc);
|
||||
switch (flash->command)
|
||||
{
|
||||
case CMD_ERASE_SETUP:
|
||||
if (val == CMD_ERASE_CONFIRM)
|
||||
{
|
||||
// pclog("flash_write: erase %05x\n", addr & 0x1ffff);
|
||||
if ((addr & 0x1f000) == 0x0d000)
|
||||
memset(&rom[0x0d000], 0xff, 0x1000);
|
||||
if ((addr & 0x1f000) == 0x0c000)
|
||||
memset(&rom[0x0c000], 0xff, 0x1000);
|
||||
if ((addr & 0x1f000) < 0x0c000 || (addr & 0x1f000) >= 0x10000)
|
||||
{
|
||||
memset(rom, 0xff, 0xc000);
|
||||
memset(&rom[0x10000], 0xff, 0x10000);
|
||||
}
|
||||
flash->status = 0x80;
|
||||
}
|
||||
flash->command = CMD_READ_STATUS;
|
||||
break;
|
||||
|
||||
case CMD_PROGRAM_SETUP:
|
||||
// pclog("flash_write: program %05x %02x\n", addr & 0x1ffff, val);
|
||||
if ((addr & 0x1e000) != 0x0e000)
|
||||
rom[addr & 0x1ffff] = val;
|
||||
flash->command = CMD_READ_STATUS;
|
||||
flash->status = 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
flash->command = val;
|
||||
switch (val)
|
||||
{
|
||||
case CMD_CLEAR_STATUS:
|
||||
flash->status = 0;
|
||||
break;
|
||||
|
||||
case CMD_IID:
|
||||
case CMD_READ_STATUS:
|
||||
mem_mapping_disable(&bios_mapping[0]);
|
||||
mem_mapping_disable(&bios_mapping[1]);
|
||||
mem_mapping_disable(&bios_mapping[2]);
|
||||
mem_mapping_disable(&bios_mapping[3]);
|
||||
mem_mapping_disable(&bios_mapping[4]);
|
||||
mem_mapping_disable(&bios_mapping[5]);
|
||||
mem_mapping_disable(&bios_mapping[6]);
|
||||
mem_mapping_disable(&bios_mapping[7]);
|
||||
mem_mapping_enable(&flash->read_mapping);
|
||||
break;
|
||||
|
||||
case CMD_READ_ARRAY:
|
||||
mem_mapping_enable(&bios_mapping[0]);
|
||||
mem_mapping_enable(&bios_mapping[1]);
|
||||
mem_mapping_enable(&bios_mapping[2]);
|
||||
mem_mapping_enable(&bios_mapping[3]);
|
||||
mem_mapping_enable(&bios_mapping[4]);
|
||||
mem_mapping_enable(&bios_mapping[5]);
|
||||
mem_mapping_enable(&bios_mapping[6]);
|
||||
mem_mapping_enable(&bios_mapping[7]);
|
||||
mem_mapping_disable(&flash->read_mapping);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *intel_flash_init()
|
||||
{
|
||||
FILE *f;
|
||||
flash_t *flash = malloc(sizeof(flash_t));
|
||||
memset(flash, 0, sizeof(flash_t));
|
||||
|
||||
mem_mapping_add(&flash->read_mapping,
|
||||
0xe0000,
|
||||
0x20000,
|
||||
flash_read, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, (void *)flash);
|
||||
mem_mapping_add(&flash->write_mapping,
|
||||
0xe0000,
|
||||
0x20000,
|
||||
NULL, NULL, NULL,
|
||||
flash_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, (void *)flash);
|
||||
mem_mapping_disable(&flash->read_mapping);
|
||||
flash->command = CMD_READ_ARRAY;
|
||||
flash->status = 0;
|
||||
|
||||
memset(&rom[0xc000], 0, 0x2000);
|
||||
|
||||
f = romfopen("roms/endeavor/oemlogo.bin", "rb");
|
||||
if (f)
|
||||
{
|
||||
fread(&rom[0xc000], 0x1000, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
f = romfopen("roms/endeavor/ecsd.bin", "rb");
|
||||
if (f)
|
||||
{
|
||||
fread(&rom[0xd000], 0x1000, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return flash;
|
||||
}
|
||||
|
||||
void intel_flash_close(void *p)
|
||||
{
|
||||
FILE *f;
|
||||
flash_t *flash = (flash_t *)p;
|
||||
|
||||
f = romfopen("roms/endeavor/oemlogo.bin", "wb");
|
||||
fwrite(&rom[0xc000], 0x1000, 1, f);
|
||||
fclose(f);
|
||||
f = romfopen("roms/endeavor/ecsd.bin", "wb");
|
||||
fwrite(&rom[0xd000], 0x1000, 1, f);
|
||||
fclose(f);
|
||||
|
||||
free(flash);
|
||||
}
|
||||
|
||||
device_t intel_flash_device =
|
||||
{
|
||||
"Intel 28F001BXT Flash BIOS",
|
||||
0,
|
||||
intel_flash_init,
|
||||
intel_flash_close,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
1
src/intel_flash.h
Normal file
1
src/intel_flash.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t intel_flash_device;
|
||||
|
|
@ -254,6 +254,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
|||
|
||||
case 0xf4: /*Enable keyboard*/
|
||||
keyboard_scan = 1;
|
||||
keyboard_at_adddata_keyboard(0xfa);
|
||||
break;
|
||||
case 0xf5: /*Disable keyboard*/
|
||||
keyboard_scan = 0;
|
||||
keyboard_at_adddata_keyboard(0xfa);
|
||||
break;
|
||||
|
||||
case 0xff: /*Reset*/
|
||||
|
|
|
|||
32
src/mem.c
32
src/mem.c
|
|
@ -37,7 +37,7 @@ static mem_mapping_t base_mapping;
|
|||
static mem_mapping_t ram_low_mapping;
|
||||
static mem_mapping_t ram_high_mapping;
|
||||
static mem_mapping_t ram_mid_mapping;
|
||||
static mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t bios_mapping[8];
|
||||
static mem_mapping_t bios_high_mapping[8];
|
||||
static mem_mapping_t romext_mapping;
|
||||
|
||||
|
|
@ -90,6 +90,7 @@ int loadbios()
|
|||
biosmask = 0xffff;
|
||||
|
||||
memset(romext,0x63,0x4000);
|
||||
memset(rom, 0xff, 0x20000);
|
||||
|
||||
pclog("Starting with romset %i\n", romset);
|
||||
|
||||
|
|
@ -419,6 +420,35 @@ int loadbios()
|
|||
biosmask = 0x1ffff;
|
||||
//is486=1;
|
||||
return 1;
|
||||
|
||||
case ROM_REVENGE:
|
||||
f = romfopen("roms/revenge/1009AF2_.BIO", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom + 0x10000, 0x10000, 1, f);
|
||||
fclose(f);
|
||||
f = romfopen("roms/revenge/1009AF2_.BI1", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom, 0xc000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
//is486=1;
|
||||
return 1;
|
||||
case ROM_ENDEAVOR:
|
||||
f = romfopen("roms/endeavor/1006CB0_.BIO", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom + 0x10000, 0x10000, 1, f);
|
||||
fclose(f);
|
||||
f = romfopen("roms/endeavor/1006CB0_.BI1", "rb");
|
||||
if (!f) break;
|
||||
fseek(f, 0x80, SEEK_SET);
|
||||
fread(rom, 0xc000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
//is486=1;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
|
|||
|
|
@ -96,3 +96,5 @@ void mem_write_nullw(uint32_t addr, uint16_t val, void *p);
|
|||
void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
|
||||
|
||||
FILE *romfopen(char *fn, char *mode);
|
||||
|
||||
mem_mapping_t bios_mapping[8];
|
||||
|
|
|
|||
110
src/model.c
110
src/model.c
|
|
@ -11,8 +11,12 @@
|
|||
#include "fdc.h"
|
||||
#include "gameport.h"
|
||||
#include "headland.h"
|
||||
#include "i430fx.h"
|
||||
#include "i430lx.h"
|
||||
#include "i430vx.h"
|
||||
#include "ide.h"
|
||||
#include "intel.h"
|
||||
#include "intel_flash.h"
|
||||
#include "jim.h"
|
||||
#include "keyboard_amstrad.h"
|
||||
#include "keyboard_at.h"
|
||||
|
|
@ -38,53 +42,58 @@
|
|||
#include "wd76c10.h"
|
||||
#include "xtide.h"
|
||||
|
||||
void xt_init();
|
||||
void pcjr_init();
|
||||
void tandy1k_init();
|
||||
void ams_init();
|
||||
void europc_init();
|
||||
void olim24_init();
|
||||
void at_init();
|
||||
void at_neat_init();
|
||||
void at_acer386sx_init();
|
||||
void at_wd76c10_init();
|
||||
void at_ali1429_init();
|
||||
void at_headland_init();
|
||||
void at_um8881f_init();
|
||||
void at_sis496_init();
|
||||
void at_i430vx_init();
|
||||
void xt_init();
|
||||
void pcjr_init();
|
||||
void tandy1k_init();
|
||||
void ams_init();
|
||||
void europc_init();
|
||||
void olim24_init();
|
||||
void at_init();
|
||||
void at_neat_init();
|
||||
void at_acer386sx_init();
|
||||
void at_wd76c10_init();
|
||||
void at_ali1429_init();
|
||||
void at_headland_init();
|
||||
void at_um8881f_init();
|
||||
void at_sis496_init();
|
||||
void at_i430vx_init();
|
||||
void at_batman_init();
|
||||
void at_endeavor_init();
|
||||
|
||||
int model;
|
||||
|
||||
MODEL models[] =
|
||||
{
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, pcjr_init},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init},
|
||||
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, pcjr_init},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init},
|
||||
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
|
||||
/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init},*/
|
||||
{"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_sis496_init},
|
||||
#ifdef DYNAREC
|
||||
{"Intel Premiere/PCI", ROM_REVENGE, { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, at_batman_init},
|
||||
{"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "", NULL}, 0, at_endeavor_init},
|
||||
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "", NULL}, 0, at_i430vx_init},
|
||||
#else
|
||||
{"Intel Advanced/EV", ROM_ENDEAVOR, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_endeavor_init},
|
||||
{"Award 430VX PCI", ROM_430VX, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_i430vx_init},
|
||||
#endif
|
||||
{"", -1, {"", 0, "", 0, "", 0}, 0}
|
||||
|
|
@ -245,7 +254,7 @@ void at_um8881f_init()
|
|||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
um8881f_init();
|
||||
}
|
||||
|
||||
|
|
@ -253,15 +262,36 @@ void at_sis496_init()
|
|||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
device_add(&sis496_device);
|
||||
}
|
||||
|
||||
void at_batman_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10);
|
||||
i430lx_init();
|
||||
um8669f_init();
|
||||
intel_batman_init();
|
||||
}
|
||||
void at_endeavor_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
um8669f_init();
|
||||
intel_endeavor_init();
|
||||
device_add(&intel_flash_device);
|
||||
}
|
||||
|
||||
void at_i430vx_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
i430vx_init();
|
||||
piix_init(7);
|
||||
um8669f_init();
|
||||
|
|
|
|||
76
src/nvr.c
76
src/nvr.c
|
|
@ -130,24 +130,26 @@ void loadnvr()
|
|||
oldromset=romset;
|
||||
switch (romset)
|
||||
{
|
||||
case ROM_PC1512: f = romfopen("pc1512.nvr", "rb"); break;
|
||||
case ROM_PC1640: f = romfopen("pc1640.nvr", "rb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr", "rb"); break;
|
||||
case ROM_PC2086: f = romfopen("pc2086.nvr", "rb"); break;
|
||||
case ROM_PC3086: f = romfopen("pc3086.nvr", "rb"); break;
|
||||
case ROM_IBMAT: f = romfopen("at.nvr" , "rb"); break;
|
||||
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI286: f = romfopen("ami286.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_DELL200: f = romfopen("dell200.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_IBMAT386: f = romfopen("at386.nvr" , "rb"); nvrmask = 127; break;
|
||||
case ROM_ACER386: f = romfopen("acer386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_MEGAPC: f = romfopen("megapc.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI386: f = romfopen("ami386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI486: f = romfopen("ami486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_SIS496: f = romfopen("sis496.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_430VX: f = romfopen("430vx.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_PC1512: f = romfopen("pc1512.nvr", "rb"); break;
|
||||
case ROM_PC1640: f = romfopen("pc1640.nvr", "rb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr", "rb"); break;
|
||||
case ROM_PC2086: f = romfopen("pc2086.nvr", "rb"); break;
|
||||
case ROM_PC3086: f = romfopen("pc3086.nvr", "rb"); break;
|
||||
case ROM_IBMAT: f = romfopen("at.nvr", "rb"); break;
|
||||
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI286: f = romfopen("ami286.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_DELL200: f = romfopen("dell200.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_IBMAT386: f = romfopen("at386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_ACER386: f = romfopen("acer386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_MEGAPC: f = romfopen("megapc.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI386: f = romfopen("ami386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI486: f = romfopen("ami486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_SIS496: f = romfopen("sis496.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_430VX: f = romfopen("430vx.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_REVENGE: f = romfopen("revenge.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_ENDEAVOR: f = romfopen("endeavor.nvr", "rb"); nvrmask = 127; break;
|
||||
default: return;
|
||||
}
|
||||
if (!f)
|
||||
|
|
@ -167,24 +169,26 @@ void savenvr()
|
|||
FILE *f;
|
||||
switch (oldromset)
|
||||
{
|
||||
case ROM_PC1512: f = romfopen("pc1512.nvr" , "wb"); break;
|
||||
case ROM_PC1640: f = romfopen("pc1640.nvr" , "wb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr" , "wb"); break;
|
||||
case ROM_PC2086: f = romfopen("pc2086.nvr" , "wb"); break;
|
||||
case ROM_PC3086: f = romfopen("pc3086.nvr" , "wb"); break;
|
||||
case ROM_IBMAT: f = romfopen("at.nvr" , "wb"); break;
|
||||
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "wb"); break;
|
||||
case ROM_AMI286: f = romfopen("ami286.nvr" , "wb"); break;
|
||||
case ROM_DELL200: f = romfopen("dell200.nvr", "wb"); break;
|
||||
case ROM_IBMAT386: f = romfopen("at386.nvr" , "wb"); break;
|
||||
case ROM_ACER386: f = romfopen("acer386.nvr", "wb"); break;
|
||||
case ROM_MEGAPC: f = romfopen("megapc.nvr" , "wb"); break;
|
||||
case ROM_AMI386: f = romfopen("ami386.nvr" , "wb"); break;
|
||||
case ROM_AMI486: f = romfopen("ami486.nvr" , "wb"); break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr" , "wb"); break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "wb"); break;
|
||||
case ROM_SIS496: f = romfopen("sis496.nvr" , "wb"); break;
|
||||
case ROM_430VX: f = romfopen("430vx.nvr" , "wb"); break;
|
||||
case ROM_PC1512: f = romfopen("pc1512.nvr", "wb"); break;
|
||||
case ROM_PC1640: f = romfopen("pc1640.nvr", "wb"); break;
|
||||
case ROM_PC200: f = romfopen("pc200.nvr", "wb"); break;
|
||||
case ROM_PC2086: f = romfopen("pc2086.nvr", "wb"); break;
|
||||
case ROM_PC3086: f = romfopen("pc3086.nvr", "wb"); break;
|
||||
case ROM_IBMAT: f = romfopen("at.nvr", "wb"); break;
|
||||
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "wb"); break;
|
||||
case ROM_AMI286: f = romfopen("ami286.nvr", "wb"); break;
|
||||
case ROM_DELL200: f = romfopen("dell200.nvr", "wb"); break;
|
||||
case ROM_IBMAT386: f = romfopen("at386.nvr", "wb"); break;
|
||||
case ROM_ACER386: f = romfopen("acer386.nvr", "wb"); break;
|
||||
case ROM_MEGAPC: f = romfopen("megapc.nvr", "wb"); break;
|
||||
case ROM_AMI386: f = romfopen("ami386.nvr", "wb"); break;
|
||||
case ROM_AMI486: f = romfopen("ami486.nvr", "wb"); break;
|
||||
case ROM_WIN486: f = romfopen("win486.nvr", "wb"); break;
|
||||
case ROM_PCI486: f = romfopen("hot-433.nvr", "wb"); break;
|
||||
case ROM_SIS496: f = romfopen("sis496.nvr", "wb"); break;
|
||||
case ROM_430VX: f = romfopen("430vx.nvr", "wb"); break;
|
||||
case ROM_REVENGE: f = romfopen("revenge.nvr", "wb"); break;
|
||||
case ROM_ENDEAVOR: f = romfopen("endeavor.nvr", "wb"); break;
|
||||
default: return;
|
||||
}
|
||||
fwrite(nvrram,128,1,f);
|
||||
|
|
|
|||
12
src/pc.c
12
src/pc.c
|
|
@ -238,18 +238,6 @@ void initpc()
|
|||
else
|
||||
#endif
|
||||
ioctl_open(cdrom_drive);
|
||||
model_init();
|
||||
video_init();
|
||||
speaker_init();
|
||||
sound_card_init(sound_card_current);
|
||||
if (GUS)
|
||||
device_add(&gus_device);
|
||||
if (GAMEBLASTER)
|
||||
device_add(&cms_device);
|
||||
if (SSI2001)
|
||||
device_add(&ssi2001_device);
|
||||
|
||||
pc_reset();
|
||||
|
||||
pit_reset();
|
||||
/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed();
|
||||
|
|
|
|||
115
src/pci.c
115
src/pci.c
|
|
@ -7,26 +7,28 @@
|
|||
void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv);
|
||||
uint8_t (*pci_card_read[32])(int func, int addr, void *priv);
|
||||
void *pci_priv[32];
|
||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable;
|
||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
|
||||
static int pci_min_card, pci_max_card;
|
||||
|
||||
void pci_cf8_write(uint16_t port, uint32_t val, void *p)
|
||||
{
|
||||
pci_index = val & 0xff;
|
||||
pci_func = (val >> 8) & 7;
|
||||
pci_card = (val >> 11) & 31;
|
||||
pci_bus = (val >> 16) & 0xff;
|
||||
pci_enable = (val >> 31) & 1;
|
||||
}
|
||||
|
||||
uint32_t pci_cf8_read(uint16_t port, void *p)
|
||||
{
|
||||
return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31);
|
||||
}
|
||||
|
||||
void pci_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0xcf8:
|
||||
pci_index = val;
|
||||
break;
|
||||
case 0xcf9:
|
||||
pci_func = val & 7;
|
||||
pci_card = val >> 3;
|
||||
break;
|
||||
case 0xcfa:
|
||||
pci_bus = val;
|
||||
break;
|
||||
case 0xcfb:
|
||||
pci_enable = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
|
||||
if (!pci_enable)
|
||||
return;
|
||||
|
|
@ -42,17 +44,9 @@ void pci_write(uint16_t port, uint8_t val, void *priv)
|
|||
|
||||
uint8_t pci_read(uint16_t port, void *priv)
|
||||
{
|
||||
// pclog("pci_read: port=%04x %08x:%08x\n", port, cs, pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0xcf8:
|
||||
return pci_index;
|
||||
case 0xcf9:
|
||||
return pci_card << 3;
|
||||
case 0xcfa:
|
||||
return pci_bus;
|
||||
case 0xcfb:
|
||||
return pci_enable;
|
||||
|
||||
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
|
||||
if (!pci_enable)
|
||||
return 0xff;
|
||||
|
|
@ -65,15 +59,82 @@ uint8_t pci_read(uint16_t port, void *priv)
|
|||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
uint8_t pci_type2_read(uint16_t port, void *priv);
|
||||
|
||||
void pci_type2_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("pci_type2_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc);
|
||||
if (port == 0xcf8)
|
||||
{
|
||||
pci_func = (val >> 1) & 7;
|
||||
if (!pci_key && (val & 0xf0))
|
||||
io_sethandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
|
||||
else
|
||||
io_removehandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
|
||||
pci_key = val & 0xf0;
|
||||
}
|
||||
else if (port == 0xcfa)
|
||||
{
|
||||
pci_bus = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc);
|
||||
|
||||
void pci_init()
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pci_type2_read(uint16_t port, void *priv)
|
||||
{
|
||||
// pclog("pci_type2_read: port=%04x %08x:%08x\n", port, cs, pc);
|
||||
if (port == 0xcf8)
|
||||
{
|
||||
return pci_key | (pci_func << 1);
|
||||
}
|
||||
else if (port == 0xcfa)
|
||||
{
|
||||
return pci_bus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
// pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), CS, pc);
|
||||
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void pci_init(int type, int min_card, int max_card)
|
||||
{
|
||||
int c;
|
||||
|
||||
io_sethandler(0x0cf8, 0x0008, pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
|
||||
if (type == PCI_CONFIG_TYPE_1)
|
||||
{
|
||||
io_sethandler(0x0cf8, 0x0001, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
|
||||
io_sethandler(0x0cfc, 0x0004, pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
io_sethandler(0x0cf8, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0cfa, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
for (c = 0; c < 32; c++)
|
||||
pci_card_read[c] = pci_card_write[c] = pci_priv[c] = NULL;
|
||||
|
||||
pci_min_card = min_card;
|
||||
pci_max_card = max_card;
|
||||
}
|
||||
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv)
|
||||
|
|
@ -87,7 +148,7 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int
|
|||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 32; c++)
|
||||
for (c = pci_min_card; c <= pci_max_card; c++)
|
||||
{
|
||||
if (!pci_card_read[c] && !pci_card_write[c])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
void pci_init();
|
||||
void pci_init(int type, int min_card, int max_card);
|
||||
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
|
||||
|
|
@ -6,3 +6,6 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int
|
|||
|
||||
#define PCI_COMMAND_IO 0x01
|
||||
#define PCI_COMMAND_MEM 0x02
|
||||
|
||||
#define PCI_CONFIG_TYPE_1 1
|
||||
#define PCI_CONFIG_TYPE_2 2
|
||||
|
|
|
|||
|
|
@ -542,7 +542,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
}
|
||||
|
||||
loadbios();
|
||||
|
||||
resetpchard();
|
||||
|
||||
timeBeginPeriod(1);
|
||||
|
||||
atexit(releasemouse);
|
||||
|
|
|
|||
Loading…
Reference in a new issue