From 84ac04d2dfd153ceb10fa5a968e574923c531f7d Mon Sep 17 00:00:00 2001 From: TomW Date: Sun, 23 Nov 2014 20:27:41 +0000 Subject: [PATCH] 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. --- readme.txt | 20 +++++ roms/endeavor/roms.txt | 1 + roms/revenge/roms.txt | 1 + src/386.c | 4 +- src/386_dynarec.c | 4 +- src/Makefile.mingw | 30 +++---- src/i430fx.c | 143 +++++++++++++++++++++++++++++++++ src/i430fx.h | 1 + src/i430lx.c | 146 ++++++++++++++++++++++++++++++++++ src/i430lx.h | 1 + src/ibm.h | 2 + src/intel.c | 80 +++++++++++++++++++ src/intel.h | 2 + src/intel_flash.c | 176 +++++++++++++++++++++++++++++++++++++++++ src/intel_flash.h | 1 + src/keyboard_at.c | 5 ++ src/mem.c | 32 +++++++- src/mem.h | 2 + src/model.c | 110 ++++++++++++++++---------- src/nvr.c | 76 +++++++++--------- src/pc.c | 12 --- src/pci.c | 115 ++++++++++++++++++++------- src/pci.h | 5 +- src/win.c | 3 +- 24 files changed, 835 insertions(+), 137 deletions(-) create mode 100644 roms/endeavor/roms.txt create mode 100644 roms/revenge/roms.txt create mode 100644 src/i430fx.c create mode 100644 src/i430fx.h create mode 100644 src/i430lx.c create mode 100644 src/i430lx.h create mode 100644 src/intel.c create mode 100644 src/intel.h create mode 100644 src/intel_flash.c create mode 100644 src/intel_flash.h diff --git a/readme.txt b/readme.txt index 62612f3..06d9104 100644 --- a/readme.txt +++ b/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. diff --git a/roms/endeavor/roms.txt b/roms/endeavor/roms.txt new file mode 100644 index 0000000..4e9bbdc --- /dev/null +++ b/roms/endeavor/roms.txt @@ -0,0 +1 @@ +This directory needs to contain some ROM files. \ No newline at end of file diff --git a/roms/revenge/roms.txt b/roms/revenge/roms.txt new file mode 100644 index 0000000..4e9bbdc --- /dev/null +++ b/roms/revenge/roms.txt @@ -0,0 +1 @@ +This directory needs to contain some ROM files. \ No newline at end of file diff --git a/src/386.c b/src/386.c index 9c2bf81..3bb5a18 100644 --- a/src/386.c +++ b/src/386.c @@ -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) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 1756333..3249263 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -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++; diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d94b5b6..9db8194 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -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 diff --git a/src/i430fx.c b/src/i430fx.c new file mode 100644 index 0000000..1abe254 --- /dev/null +++ b/src/i430fx.c @@ -0,0 +1,143 @@ +#include + +#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); +} diff --git a/src/i430fx.h b/src/i430fx.h new file mode 100644 index 0000000..fff11d2 --- /dev/null +++ b/src/i430fx.h @@ -0,0 +1 @@ +void i430fx_init(); diff --git a/src/i430lx.c b/src/i430lx.c new file mode 100644 index 0000000..ec82583 --- /dev/null +++ b/src/i430lx.c @@ -0,0 +1,146 @@ +#include + +#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); +} diff --git a/src/i430lx.h b/src/i430lx.h new file mode 100644 index 0000000..8669fa2 --- /dev/null +++ b/src/i430lx.h @@ -0,0 +1 @@ +void i430lx_init(); diff --git a/src/ibm.h b/src/ibm.h index b56a22c..738f84f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -316,6 +316,8 @@ enum ROM_PCI486, ROM_SIS496, ROM_430VX, + ROM_ENDEAVOR, + ROM_REVENGE, ROM_MAX }; diff --git a/src/intel.c b/src/intel.c new file mode 100644 index 0000000..bba57ca --- /dev/null +++ b/src/intel.c @@ -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); +} diff --git a/src/intel.h b/src/intel.h new file mode 100644 index 0000000..eccd668 --- /dev/null +++ b/src/intel.h @@ -0,0 +1,2 @@ +void intel_batman_init(); +void intel_endeavor_init(); diff --git a/src/intel_flash.c b/src/intel_flash.c new file mode 100644 index 0000000..1cdb6e0 --- /dev/null +++ b/src/intel_flash.c @@ -0,0 +1,176 @@ +#include +#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 +}; diff --git a/src/intel_flash.h b/src/intel_flash.h new file mode 100644 index 0000000..379a8d3 --- /dev/null +++ b/src/intel_flash.h @@ -0,0 +1 @@ +extern device_t intel_flash_device; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index ebdbb10..f411113 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -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*/ diff --git a/src/mem.c b/src/mem.c index fb0b7a3..134a995 100644 --- a/src/mem.c +++ b/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); diff --git a/src/mem.h b/src/mem.h index b130239..6991e00 100644 --- a/src/mem.h +++ b/src/mem.h @@ -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]; diff --git a/src/model.c b/src/model.c index f120fdf..21b0ffe 100644 --- a/src/model.c +++ b/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(); diff --git a/src/nvr.c b/src/nvr.c index a26c70e..f5d4601 100644 --- a/src/nvr.c +++ b/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); diff --git a/src/pc.c b/src/pc.c index 8f83040..a760e4c 100644 --- a/src/pc.c +++ b/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(); diff --git a/src/pci.c b/src/pci.c index 309edec..da535ce 100644 --- a/src/pci.c +++ b/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]) { diff --git a/src/pci.h b/src/pci.h index f053f2f..321d7ca 100644 --- a/src/pci.h +++ b/src/pci.h @@ -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 diff --git a/src/win.c b/src/win.c index b3a83e5..f9b2ae6 100644 --- a/src/win.c +++ b/src/win.c @@ -542,7 +542,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } loadbios(); - + resetpchard(); + timeBeginPeriod(1); atexit(releasemouse);