From 221df099126aea842ce6e303a46b2c9d0dad5dd2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Apr 2017 22:24:11 +0100 Subject: [PATCH] Added PS/2 Model 80 (type 2) emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/ibm.h | 1 + src/mem.c | 14 ++++ src/model.c | 8 +++ src/nvr.c | 2 + src/ps2_mca.c | 152 +++++++++++++++++++++++++++++++++++++++++++ src/ps2_mca.h | 1 + src/ps2_nvr.c | 101 ++++++++++++++++++++++++++++ src/ps2_nvr.h | 1 + src/video.c | 1 + 14 files changed, 286 insertions(+), 5 deletions(-) create mode 100644 src/ps2_nvr.c create mode 100644 src/ps2_nvr.h diff --git a/src/Makefile.am b/src/Makefile.am index 2235c66..3552a0d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,7 @@ dac.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665. hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c rom.c rtc.c scat.c serial.c sis496.c sound.c \ +opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sis496.c sound.c \ sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c thread-pthread.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index db0aa11..622d3f8 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -11,7 +11,7 @@ dac.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665. hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 24bf0ce..2c5d4c7 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -10,7 +10,7 @@ dac.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665. hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 039ca1a..e790238 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.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_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 4b4984c..f55c6e1 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.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_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ diff --git a/src/ibm.h b/src/ibm.h index c64f71a..88ed80e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -405,6 +405,7 @@ enum ROM_IBMPS2_M30_286, ROM_IBMPS2_M50, ROM_IBMPS2_M55SX, + ROM_IBMPS2_M80, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 4c6fa54..9815ecc 100644 --- a/src/mem.c +++ b/src/mem.c @@ -617,6 +617,20 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_IBMPS2_M80: + f=romfopen("roms/i8580111/15f6637.bin","rb"); + ff=romfopen("roms/i8580111/15f6639.bin","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x20000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 530b58c..814ab2c 100644 --- a/src/model.c +++ b/src/model.c @@ -70,6 +70,7 @@ void ps1_m2121_init(); void ps2_m30_286_init(); void ps2_model_50_init(); void ps2_model_55sx_init(); +void ps2_model_80_init(); void at_neat_init(); void at_scat_init(); void at_acer386sx_init(); @@ -125,6 +126,7 @@ MODEL models[] = /* {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},*/ {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, + {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 4, 2, ps2_model_80_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, @@ -386,6 +388,12 @@ void ps2_model_55sx_init() ps2_mca_board_model_55sx_init(); } +void ps2_model_80_init() +{ + ps2_common_init(); + ps2_mca_board_model_80_type2_init(); +} + void at_neat_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index fb13979..419e7b9 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -211,6 +211,7 @@ void loadnvr() case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "rb"); break; case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "rb"); break; case ROM_CMDPC30: f = romfopen("nvr/cmdpc30.nvr", "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "rb"); nvrmask = 127; break; @@ -273,6 +274,7 @@ void savenvr() case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "wb"); break; case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "wb"); break; case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "wb"); break; case ROM_CMDPC30: f = romfopen("nvr/cmdpc30.nvr", "wb"); break; case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "wb"); break; case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "wb"); break; diff --git a/src/ps2_mca.c b/src/ps2_mca.c index 6517664..e53cfd6 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -1,10 +1,12 @@ #include "ibm.h" #include "cpu.h" +#include "device.h" #include "io.h" #include "lpt.h" #include "mca.h" #include "mem.h" #include "ps2_mca.h" +#include "ps2_nvr.h" #include "rom.h" #include "serial.h" #include "x86.h" @@ -34,6 +36,10 @@ static struct uint8_t (*planar_read)(uint16_t port); void (*planar_write)(uint16_t port, uint8_t val); + + uint8_t mem_regs[3]; + + uint32_t split_addr; } ps2; @@ -123,6 +129,30 @@ static uint8_t model_55sx_read(uint16_t port) return 0xff; } +static uint8_t model_80_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfd; + case 0x102: + return ps2.option[0]; + case 0x103: + return ps2.option[1]; + case 0x104: + return ps2.option[2]; + case 0x105: + return ps2.option[3]; + case 0x106: + return ps2.subaddr_lo; + case 0x107: + return ps2.subaddr_hi; + } + return 0xff; +} + static void model_50_write(uint16_t port, uint8_t val) { switch (port) @@ -256,6 +286,61 @@ static void model_55sx_write(uint16_t port, uint8_t val) } } +static void model_80_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) + { + if (val & 0x08) + serial1_init(0x3f8, 4); + else + serial1_init(0x2f8, 3); + } + else + serial1_remove(); + if (val & 0x10) + { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2.option[0] = val; + break; + case 0x103: + ps2.option[1] = (ps2.option[1] & 0x0f) | (val & 0xf0); + break; + case 0x104: + ps2.option[2] = val; + break; + case 0x105: + ps2.option[3] = val; + break; + case 0x106: + ps2.subaddr_lo = val; + break; + case 0x107: + ps2.subaddr_hi = val; + break; + } +} + uint8_t ps2_mca_read(uint16_t port, void *p) { uint8_t temp; @@ -520,3 +605,70 @@ void ps2_mca_board_model_55sx_init() ps2.planar_read = model_55sx_read; ps2.planar_write = model_55sx_write; } + +static void mem_encoding_update() +{ + if (ps2.split_addr >= mem_size*1024) + mem_set_mem_state(ps2.split_addr, 256 * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + ps2.split_addr = (ps2.mem_regs[0] & 0xf) << 20; + + if (ps2.mem_regs[1] & 2) + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + + if (!(ps2.mem_regs[1] & 8)) + { + if (ps2.split_addr >= mem_size*1024) + mem_set_mem_state(ps2.split_addr, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } +} + +static uint8_t mem_encoding_read(uint16_t addr, void *p) +{ + switch (addr) + { + case 0xe0: + return ps2.mem_regs[0]; + case 0xe1: + return ps2.mem_regs[1]; + } + return 0xff; +} +static void mem_encoding_write(uint16_t addr, uint8_t val, void *p) +{ + switch (addr) + { + case 0xe0: + ps2.mem_regs[0] = val; + break; + case 0xe1: + ps2.mem_regs[1] = val; + break; + } + mem_encoding_update(); +} + +void ps2_mca_board_model_80_type2_init() +{ + ps2_mca_board_common_init(); + + mem_remap_top_256k(); + ps2.split_addr = mem_size * 1024; + mca_init(8); + + ps2.planar_read = model_80_read; + ps2.planar_write = model_80_write; + + device_add(&ps2_nvr_device); + + io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL); + + ps2.mem_regs[1] = 2; + + if (mem_size == 2*1024) + ps2.option[1] = 0x0e; + else + ps2.option[1] = 0x0a; +} diff --git a/src/ps2_mca.h b/src/ps2_mca.h index 95d74e9..d7a2e13 100644 --- a/src/ps2_mca.h +++ b/src/ps2_mca.h @@ -1,2 +1,3 @@ void ps2_mca_board_model_50_init(); void ps2_mca_board_model_55sx_init(); +void ps2_mca_board_model_80_type2_init(); diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c new file mode 100644 index 0000000..1225f69 --- /dev/null +++ b/src/ps2_nvr.c @@ -0,0 +1,101 @@ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "ps2_nvr.h" + +typedef struct ps2_nvr_t +{ + int addr; + uint8_t ram[8192]; +} ps2_nvr_t; + +static uint8_t ps2_nvr_read(uint16_t port, void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + + switch (port) + { + case 0x74: + return nvr->addr & 0xff; + case 0x75: + return nvr->addr >> 8; + case 0x76: + return nvr->ram[nvr->addr]; + } + + return 0xff; +} + +static void ps2_nvr_write(uint16_t port, uint8_t val, void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + +// pclog("ps2_nvr_write: port=%04x val=%02x\n", port, val); + switch (port) + { + case 0x74: + nvr->addr = (nvr->addr & 0x1f00) | val; + break; + case 0x75: + nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8); + break; + case 0x76: + nvr->ram[nvr->addr] = val; + break; + } +} + +static void *ps2_nvr_init() +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); + FILE *f = NULL; + + memset(nvr, 0, sizeof(ps2_nvr_t)); + + io_sethandler(0x0074, 0x0003, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); + + switch (romset) + { + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "rb"); break; + } + if (f) + { + fread(nvr->ram, 8192, 1, f); + fclose(f); + } + else + memset(nvr->ram, 0xFF, 8192); + + return nvr; +} + +static void ps2_nvr_close(void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + FILE *f = NULL; + + switch (romset) + { + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "wb"); break; + } + if (f) + { + fwrite(nvr->ram, 8192, 1, f); + fclose(f); + } + + free(nvr); +} + +device_t ps2_nvr_device = +{ + "PS/2 NVRRAM", + 0, + ps2_nvr_init, + ps2_nvr_close, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/ps2_nvr.h b/src/ps2_nvr.h new file mode 100644 index 0000000..6527145 --- /dev/null +++ b/src/ps2_nvr.h @@ -0,0 +1 @@ +extern device_t ps2_nvr_device; diff --git a/src/video.c b/src/video.c index 6145861..c4f507c 100644 --- a/src/video.c +++ b/src/video.c @@ -298,6 +298,7 @@ void video_init() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: device_add(&ps1vga_device); return;