diff --git a/src/dma.c b/src/dma.c index bcc532a..58270f6 100644 --- a/src/dma.c +++ b/src/dma.c @@ -129,6 +129,7 @@ static uint8_t dma_ps2_read(uint16_t addr, void *priv) switch (dma.xfr_command) { case 2: /*Address*/ + case 3: switch (dma.byte_ptr) { case 0: @@ -146,6 +147,7 @@ static uint8_t dma_ps2_read(uint16_t addr, void *priv) } break; case 4: /*Count*/ + case 5: if (dma.byte_ptr) temp = (dma.xfr_channel & 4) ? (dma16.cc[dma.xfr_channel & 3] >> 8) : (dma.cc[dma.xfr_channel] >> 8); else @@ -155,6 +157,9 @@ static uint8_t dma_ps2_read(uint16_t addr, void *priv) case 7: /*Mode*/ temp = (dma.xfr_channel & 4) ? dma16.mode[dma.xfr_channel & 3] : dma.mode[dma.xfr_channel]; break; + case 8: /*Arbitration Level*/ + temp = (dma.xfr_channel & 4) ? dma16.arb_level[dma.xfr_channel & 3] : dma.arb_level[dma.xfr_channel]; + break; default: fatal("Bad XFR Read command %i channel %i\n", dma.xfr_command, dma.xfr_channel); @@ -261,6 +266,13 @@ static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) dma.mode[dma.xfr_channel] = mode; break; + case 8: /*Arbitration Level*/ + if (dma.xfr_channel & 4) + dma16.arb_level[dma.xfr_channel & 3] = val; + else + dma.arb_level[dma.xfr_channel] = val; + break; + default: fatal("Bad XFR command %i channel %i val %02x\n", dma.xfr_command, dma.xfr_channel, val); } diff --git a/src/ibm.h b/src/ibm.h index 16d52f5..97ea810 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -315,6 +315,7 @@ typedef struct DMA int byte_ptr; int is_ps2; + uint8_t arb_level[4]; } DMA; DMA dma,dma16; @@ -403,6 +404,7 @@ enum ROM_MR386DX_OPTI495, ROM_IBMPS2_M30_286, ROM_IBMPS2_M50, + ROM_IBMPS2_M55SX, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 538e66c..f4c0780 100644 --- a/src/mem.c +++ b/src/mem.c @@ -603,6 +603,20 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_IBMPS2_M55SX: + f=romfopen("roms/i8555081/33f8146.zm41","rb"); + ff=romfopen("roms/i8555081/33f8145.zm40","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); @@ -1800,6 +1814,28 @@ void mem_init() // pclog("Mem resize %i %i\n",mem_size,c); } +void mem_remap_top_256k() +{ + int c; + + for (c = ((mem_size * 1024) >> 12); c < (((mem_size + 256) * 1024) >> 12); c++) + { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } + + for (c = (mem_size / 256); c < ((mem_size + 256) / 256); c++) + { + isram[c] = 1; + if (c >= 0xa && c <= 0xd) + isram[c] = 0; + } + + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (mem_size * 1024), MEM_MAPPING_INTERNAL, NULL); +} void mem_remap_top_384k() { int c; diff --git a/src/mem.h b/src/mem.h index 99b5c4a..1e59cdc 100644 --- a/src/mem.h +++ b/src/mem.h @@ -163,6 +163,7 @@ void mem_reset_page_blocks(); extern mem_mapping_t ram_low_mapping; +void mem_remap_top_256k(); void mem_remap_top_384k(); #endif diff --git a/src/model.c b/src/model.c index 197283b..735bd61 100644 --- a/src/model.c +++ b/src/model.c @@ -53,32 +53,33 @@ #include "vid_tandy.h" #include "wd76c10.h" -void xt_init(); -void pcjr_init(); -void tandy1k_init(); -void tandy1ksl2_init(); -void ams_init(); -void europc_init(); -void olim24_init(); -void at_init(); -void at_ide_init(); -void deskpro386_init(); -void ps1_m2011_init(); -void ps1_m2121_init(); -void ps2_m30_286_init(); -void ps2_init(); -void at_neat_init(); -void at_scat_init(); -void at_acer386sx_init(); -void at_wd76c10_init(); -void at_ali1429_init(); -void at_headland_init(); -void at_opti495_init(); -void at_um8881f_init(); -void at_sis496_init(); -void at_i430vx_init(); -void at_batman_init(); -void at_endeavor_init(); +void xt_init(); +void pcjr_init(); +void tandy1k_init(); +void tandy1ksl2_init(); +void ams_init(); +void europc_init(); +void olim24_init(); +void at_init(); +void at_ide_init(); +void deskpro386_init(); +void ps1_m2011_init(); +void ps1_m2121_init(); +void ps2_m30_286_init(); +void ps2_model_50_init(); +void ps2_model_55sx_init(); +void at_neat_init(); +void at_scat_init(); +void at_acer386sx_init(); +void at_wd76c10_init(); +void at_ali1429_init(); +void at_headland_init(); +void at_opti495_init(); +void at_um8881f_init(); +void at_sis496_init(); +void at_i430vx_init(); +void at_batman_init(); +void at_endeavor_init(); int model; @@ -106,30 +107,31 @@ MODEL models[] = {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"Acer 386SX25/N", ROM_ACER386, "acer386", { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + {"Acer 386SX25/N", ROM_ACER386, "acer386", { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, /* {"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}, - {"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}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_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}, + {"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}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, /* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_um8881f_init},*/ - {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; @@ -353,7 +355,7 @@ void ps2_m30_286_init() fdc_set_dskchg_activelow(); } -void ps2_init() +static void ps2_common_init() { AT = 1; common_init(); @@ -366,10 +368,22 @@ void ps2_init() mouse_ps2_init(); nvr_init(); pic2_init(); - ps2_mca_board_init(); + pit_ps2_init(); } +void ps2_model_50_init() +{ + ps2_common_init(); + ps2_mca_board_model_50_init(); +} + +void ps2_model_55sx_init() +{ + ps2_common_init(); + ps2_mca_board_model_55sx_init(); +} + void at_neat_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 6bbbd13..fb13979 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -210,6 +210,7 @@ void loadnvr() case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "rb"); nvrmask = 127; break; 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_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; @@ -271,6 +272,7 @@ void savenvr() case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "wb"); break; 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_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 613bb64..f453c92 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -22,14 +22,234 @@ static struct uint8_t sys_ctrl_port_a; uint8_t subaddr_lo, subaddr_hi; + uint8_t memory_bank[8]; + uint8_t io_id; + + mem_mapping_t shadow_mapping; + + uint8_t (*planar_read)(uint16_t port); + void (*planar_write)(uint16_t port, uint8_t val); } ps2; + +uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_ram(addr, priv); +} +uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_ramw(addr, priv); +} +uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_raml(addr, priv); +} +void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_ram(addr, val, priv); +} +void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_ramw(addr, val, priv); +} +void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_raml(addr, val, priv); +} + + + #define PS2_SETUP_IO 0x80 #define PS2_SETUP_VGA 0x20 #define PS2_ADAPTER_SETUP 0x08 +static uint8_t model_50_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfb; + 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; + } +} + +static uint8_t model_55sx_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfb; + case 0x102: + return ps2.option[0]; + case 0x103: + return ps2.option[1]; + case 0x104: + return ps2.memory_bank[ps2.option[3] & 7];//ps2.option[2]; + case 0x105: + return ps2.option[3]; + case 0x106: + return ps2.subaddr_lo; + case 0x107: + return ps2.subaddr_hi; + } +} + +static void model_50_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + ps2.io_id = val; + 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] = val; + 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; + } +} + +static void model_55sx_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + ps2.io_id = val; + 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] = val; + break; + case 0x104: + ps2.memory_bank[ps2.option[3] & 7] &= ~0xf; + ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf); + pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); + break; + case 0x105: + pclog("Write POS3 %02x\n", val); + ps2.option[3] = val; + shadowbios = !(val & 0x10); + shadowbios_write = val & 0x10; + + if (shadowbios) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + mem_mapping_disable(&ps2.shadow_mapping); + } + else + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_enable(&ps2.shadow_mapping); + } + + if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20)) + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + 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; @@ -49,7 +269,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x100: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.io_id; + temp = ps2.planar_read(port); else if (!(ps2.setup & PS2_SETUP_VGA)) temp = 0xfd; else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) @@ -59,7 +279,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x101: if (!(ps2.setup & PS2_SETUP_IO)) - temp = 0xfb; + temp = ps2.planar_read(port); else if (!(ps2.setup & PS2_SETUP_VGA)) temp = 0xef; else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) @@ -69,7 +289,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x102: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.option[0]; + temp = ps2.planar_read(port); else if (!(ps2.setup & PS2_SETUP_VGA)) temp = ps2.pos_vga; else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) @@ -79,7 +299,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x103: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.option[1]; + temp = ps2.planar_read(port); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) temp = mca_read(port); else @@ -87,7 +307,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x104: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.option[2]; + temp = ps2.planar_read(port); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) temp = mca_read(port); else @@ -95,7 +315,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x105: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.option[3]; + temp = ps2.planar_read(port); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) temp = mca_read(port); else @@ -103,7 +323,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x106: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.subaddr_lo; + temp = ps2.planar_read(port); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) temp = mca_read(port); else @@ -111,7 +331,7 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; case 0x107: if (!(ps2.setup & PS2_SETUP_IO)) - temp = ps2.subaddr_hi; + temp = ps2.planar_read(port); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) temp = mca_read(port); else @@ -123,14 +343,14 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; } -// pclog("ps2_read: port=%04x temp=%02x\n", port, temp); + pclog("ps2_read: port=%04x temp=%02x\n", port, temp); return temp; } static void ps2_mca_write(uint16_t port, uint8_t val, void *p) { -// pclog("ps2_write: port=%04x val=%02x\n", port, val); + pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); switch (port) { @@ -153,45 +373,19 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p) break; case 0x100: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.io_id = val; + ps2.planar_write(port, val); else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) mca_write(port, val); break; case 0x101: - if ((ps2.setup & PS2_SETUP_VGA) && (ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) mca_write(port, val); break; case 0x102: if (!(ps2.setup & PS2_SETUP_IO)) - { - 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; - } + ps2.planar_write(port, val); else if (!(ps2.setup & PS2_SETUP_VGA)) ps2.pos_vga = val; else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) @@ -199,38 +393,38 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p) break; case 0x103: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.option[1] = val; + ps2.planar_write(port, val); else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; case 0x104: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.option[2] = val; + ps2.planar_write(port, val); else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; case 0x105: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.option[3] = val; + ps2.planar_write(port, val); else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; case 0x106: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.subaddr_lo = val; + ps2.planar_write(port, val); else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; case 0x107: if (!(ps2.setup & PS2_SETUP_IO)) - ps2.subaddr_hi = val; + ps2.planar_write(port, val); else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; } } -void ps2_mca_board_init() +static void ps2_mca_board_common_init() { io_sethandler(0x0091, 0x0002, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); io_sethandler(0x0094, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); @@ -245,10 +439,78 @@ void ps2_mca_board_init() serial1_remove(); serial2_remove(); - - ps2.io_id = 0xfb; +} + +void ps2_mca_board_model_50_init() +{ + ps2_mca_board_common_init(); mem_remap_top_384k(); + mca_init(4); + + ps2.planar_read = model_50_read; + ps2.planar_write = model_50_write; +} + +void ps2_mca_board_model_55sx_init() +{ + ps2_mca_board_common_init(); + + mem_mapping_add(&ps2.shadow_mapping, + (mem_size+256) * 1024, + 128*1024, + ps2_read_shadow_ram, + ps2_read_shadow_ramw, + ps2_read_shadow_raml, + ps2_write_shadow_ram, + ps2_write_shadow_ramw, + ps2_write_shadow_raml, + &ram[0xe0000], + MEM_MAPPING_INTERNAL, + NULL); + + +// mem_remap_top_384k(); + mem_remap_top_256k(); + ps2.option[3] = 0x10; + + memset(ps2.memory_bank, 0xf0, 8); + switch (mem_size/1024) + { + case 1: + ps2.memory_bank[0] = 0x61; + break; + case 2: + ps2.memory_bank[0] = 0x51; + break; + case 3: + ps2.memory_bank[0] = 0x51; + ps2.memory_bank[1] = 0x61; + break; + case 4: + ps2.memory_bank[0] = 0x51; + ps2.memory_bank[1] = 0x51; + break; + case 5: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x61; + break; + case 6: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x51; + break; + case 7: /*Not supported*/ + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x51; + break; + case 8: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x01; + break; + } mca_init(4); + + ps2.planar_read = model_55sx_read; + ps2.planar_write = model_55sx_write; } diff --git a/src/ps2_mca.h b/src/ps2_mca.h index c321b22..95d74e9 100644 --- a/src/ps2_mca.h +++ b/src/ps2_mca.h @@ -1 +1,2 @@ -void ps2_mca_board_init(); +void ps2_mca_board_model_50_init(); +void ps2_mca_board_model_55sx_init(); diff --git a/src/video.c b/src/video.c index ecf6183..6145861 100644 --- a/src/video.c +++ b/src/video.c @@ -297,6 +297,7 @@ void video_init() case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: device_add(&ps1vga_device); return;