From d28a908839db7f2e4916dadbc4bee25188fb34d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Feb 2018 15:13:45 +0000 Subject: [PATCH] Video card can now be changed on Amstrad MegaPC. --- src/model.c | 2 +- src/rom.h | 5 +++++ src/vid_paradise.c | 19 +++++++++++++++++++ src/video.c | 9 +++++---- src/wd76c10.c | 19 +++++++++++++++++++ src/wd76c10.h | 3 +++ 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/model.c b/src/model.c index e0719a7..16c7396 100644 --- a/src/model.c +++ b/src/model.c @@ -159,7 +159,7 @@ MODEL models[] = {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, - {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, diff --git a/src/rom.h b/src/rom.h index 0e32d57..5e578ed 100644 --- a/src/rom.h +++ b/src/rom.h @@ -1,3 +1,6 @@ +#ifndef _ROM_H_ +#define _ROM_H_ + FILE *romfopen(char *fn, char *mode); int rom_present(char *fn); @@ -14,3 +17,5 @@ int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t addre uint8_t rom_read(uint32_t addr, void *p); uint16_t rom_readw(uint32_t addr, void *p); uint32_t rom_readl(uint32_t addr, void *p); + +#endif diff --git a/src/vid_paradise.c b/src/vid_paradise.c index e8ad9a2..d371597 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -14,6 +14,7 @@ #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_unk_ramdac.h" +#include "wd76c10.h" typedef struct paradise_t { @@ -32,6 +33,9 @@ typedef struct paradise_t void paradise_remap(paradise_t *paradise); +void paradise_out(uint16_t addr, uint8_t val, void *p); +uint8_t paradise_in(uint16_t addr, void *p); + void paradise_out(uint16_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; @@ -132,6 +136,16 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) } } break; + + case 0x46e8: + io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_disable(¶dise->svga.mapping); + if (val & 8) + { + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_enable(¶dise->svga.mapping); + } + break; } svga_out(addr, val, svga); } @@ -356,6 +370,8 @@ static void *paradise_wd90c11_megapc_init() "megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + wd76c10_set_bios_rom(¶dise->bios_rom); + return paradise; } @@ -368,6 +384,9 @@ static void *paradise_pvga1a_oli_go481_init() "oli_go481_lo.bin", "oli_go481_hi.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + return paradise; } diff --git a/src/video.c b/src/video.c index 0c923b4..be77753 100644 --- a/src/video.c +++ b/src/video.c @@ -663,12 +663,13 @@ void video_init() break; case ROM_MEGAPC: - if (gfxcard == GFX_BUILTIN) + device_add(¶dise_wd90c11_megapc_device); + if (gfxcard != GFX_BUILTIN) { - device_add(¶dise_wd90c11_megapc_device); - return; + svga_set_override(svga_get_pri(), 1); + break; } - break; + return; case ROM_ACER386: device_add(&oti067_acer386_device); diff --git a/src/wd76c10.c b/src/wd76c10.c index 9c77b7d..47062c9 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -2,6 +2,7 @@ #include "fdc.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "serial.h" #include "wd76c10.h" @@ -9,6 +10,13 @@ static uint16_t wd76c10_0092; static uint16_t wd76c10_2072; static uint16_t wd76c10_2872; static uint16_t wd76c10_5872; +static uint16_t wd76c10_6072; +static rom_t *video_bios_rom = NULL; + +void wd76c10_set_bios_rom(rom_t *rom) +{ + video_bios_rom = rom; +} uint16_t wd76c10_read(uint16_t port, void *priv) { @@ -25,6 +33,9 @@ uint16_t wd76c10_read(uint16_t port, void *priv) case 0x5872: return wd76c10_5872; + + case 0x6072: + return wd76c10_6072; } return 0; } @@ -81,6 +92,13 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) case 0x5872: wd76c10_5872 = val; break; + + case 0x6072: + wd76c10_6072 = val; + mem_mapping_disable(&video_bios_rom->mapping); + if ((val & 0xc) == 8) + mem_mapping_enable(&video_bios_rom->mapping); + break; } } @@ -106,4 +124,5 @@ void wd76c10_init() io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x6072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); } diff --git a/src/wd76c10.h b/src/wd76c10.h index 70ed1c9..0ba62e0 100644 --- a/src/wd76c10.h +++ b/src/wd76c10.h @@ -1 +1,4 @@ +#include "rom.h" + void wd76c10_init(); +void wd76c10_set_bios_rom(rom_t *rom);