diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c
index 794feba7b..c836b9ec0 100644
--- a/src/video/vid_et4000.c
+++ b/src/video/vid_et4000.c
@@ -8,7 +8,7 @@
*
* Emulation of the Tseng Labs ET4000.
*
- * Version: @(#)vid_et4000.c 1.0.11 2018/08/23
+ * Version: @(#)vid_et4000.c 1.0.12 2018/08/24
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -57,7 +57,8 @@ typedef struct et4000_t
int get_korean_font_enabled;
int get_korean_font_index;
uint16_t get_korean_font_base;
- uint32_t vram_mask;
+ uint32_t vram_mask, key;
+ uint8_t hcr, mcr;
} et4000_t;
static uint8_t crtc_mask[0x40] =
@@ -72,6 +73,8 @@ static uint8_t crtc_mask[0x40] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+uint8_t et4000_in(uint16_t addr, void *p);
+
void et4000_out(uint16_t addr, uint8_t val, void *p)
{
et4000_t *et4000 = (et4000_t *)p;
@@ -84,15 +87,25 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
switch (addr)
{
+ case 0x3BF: case 0x3DF:
+ et4000->hcr = val;
+ return;
+
+ case 0x3c2:
+ if (val & 1)
+ io_sethandler(0x03bf, 0x0001, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
+ else
+ io_removehandler(0x03bf, 0x0001, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
+ break;
+
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
sc1502x_ramdac_out(addr, val, &et4000->ramdac, svga);
return;
case 0x3CD: /*Banking*/
- if (!(svga->crtc[0x36] & 0x10)) {
- svga->write_bank = ((val & 0xf) * 0x10000) & svga->vram_display_mask;
- svga->read_bank = (((val >> 4) & 0xf) * 0x10000) & svga->vram_display_mask;
- pclog("write bank: %08X, read bank: %08X\n", svga->write_bank, svga->read_bank);
+ if (et4000->key && !(svga->crtc[0x36] & 0x10)) {
+ svga->write_bank = (val & 0xf) * 0x10000;
+ svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
}
et4000->banking = val;
return;
@@ -102,6 +115,10 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
case 0x3D5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
+ if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80))
+ return;
+ if ((svga->crtcreg > 0x18) && (svga->crtcreg != 0x33) && (svga->crtcreg != 0x35) && !et4000->key)
+ return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
@@ -109,12 +126,10 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
svga->crtc[svga->crtcreg] = val;
if (svga->crtcreg == 0x36) {
- svga->vram_display_mask = (val & 0x20) ? et4000->vram_mask : 0x3ffff;
if (!(val & 0x10)) {
- svga->write_bank = ((et4000->banking & 0xf) * 0x10000) & svga->vram_display_mask;
- svga->read_bank = (((et4000->banking >> 4) & 0xf) * 0x10000) & svga->vram_display_mask;
- } else
- svga->write_bank = svga->read_bank = 0;
+ svga->write_bank = (et4000->banking & 0xf) * 0x10000;
+ svga->read_bank = ((et4000->banking >> 4) & 0xf) * 0x10000;
+ }
}
if (old != val)
@@ -170,6 +185,16 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
}
}
break;
+ case 0x3D8:
+ et4000->mcr = val;
+ if (et4000->hcr == 0x03) {
+ if ((et4000->mcr & 0xa0) == 0xa0)
+ et4000->key = 1;
+ } else {
+ if ((et4000->mcr & 0xa0) != 0xa0)
+ et4000->key = 0;
+ }
+ break;
}
svga_out(addr, val, svga);
}
@@ -202,7 +227,7 @@ uint8_t et4000_in(uint16_t addr, void *p)
return sc1502x_ramdac_in(addr, &et4000->ramdac, svga);
case 0x3CD: /*Banking*/
- return et4000->banking;
+ return et4000->banking;
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
@@ -384,6 +409,7 @@ void *et4000_isa_init(const device_t *info)
rom_init(&et4000->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
+ io_sethandler(0x03bf, 0x0001, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
svga_init(&et4000->svga, et4000, device_get_config_int("memory") << 10, /*1mb default*/
@@ -404,6 +430,7 @@ void *et4000k_isa_init(const device_t *info)
rom_init(&et4000->bios_rom, KOREAN_BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
loadfont(KOREAN_FONT_ROM_PATH, 6);
+ io_sethandler(0x03bf, 0x0001, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
io_sethandler(0x22cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000);
@@ -465,6 +492,7 @@ void *et4000_mca_init(const device_t *info)
NULL);
et4000->vram_mask = (1 << 20) - 1;
+ io_sethandler(0x03bf, 0x0001, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
return et4000;
diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c
index bcc723d66..4f2670cbe 100644
--- a/src/video/vid_et4000w32.c
+++ b/src/video/vid_et4000w32.c
@@ -10,7 +10,7 @@
*
* Known bugs: Accelerator doesn't work in planar modes
*
- * Version: @(#)vid_et4000w32.c 1.0.12 2018/08/23
+ * Version: @(#)vid_et4000w32.c 1.0.13 2018/08/24
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -148,6 +148,8 @@ typedef struct et4000w32p_t
uint64_t blitter_time;
uint64_t status_time;
int type;
+ uint8_t hcr, mcr;
+ uint32_t key;
} et4000w32p_t;
void et4000w32p_recalcmapping(et4000w32p_t *et4000);
@@ -179,6 +181,8 @@ et4000w32_log(const char *format, ...)
}
+uint8_t et4000w32p_in(uint16_t addr, void *p);
+
void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
{
et4000w32p_t *et4000 = (et4000w32p_t *)p;
@@ -190,28 +194,36 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
switch (addr)
{
-#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
+ case 0x3BF: case 0x3DF:
+ et4000->hcr = val;
+ return;
+
case 0x3c2:
+ if (val & 1)
+ io_sethandler(0x03bf, 0x0001, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
+ else
+ io_removehandler(0x03bf, 0x0001, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
+#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
if (et4000->type == ET4000W32_DIAMOND)
icd2061_write(&et4000->icd2061, (val >> 2) & 3);
- break;
#endif
+ break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
stg_ramdac_out(addr, val, &et4000->ramdac, svga);
return;
case 0x3CB: /*Banking extension*/
- if (!(svga->crtc[0x36] & 0x10)) {
- svga->write_bank = ((svga->write_bank & 0xfffff) | ((val & 1) << 20)) & svga->vram_display_mask;
- svga->read_bank = ((svga->read_bank & 0xfffff) | ((val & 0x10) << 16)) & svga->vram_display_mask;
+ if (et4000->key && !(svga->crtc[0x36] & 0x10)) {
+ svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20);
+ svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16);
}
et4000->banking2 = val;
return;
case 0x3CD: /*Banking*/
- if (!(svga->crtc[0x36] & 0x10)) {
- svga->write_bank = ((svga->write_bank & 0x100000) | ((val & 0xf) * 65536)) & svga->vram_display_mask;
- svga->read_bank = ((svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536)) & svga->vram_display_mask;
+ if (et4000->key && !(svga->crtc[0x36] & 0x10)) {
+ svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536);
+ svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536);
}
et4000->banking = val;
return;
@@ -230,17 +242,19 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
case 0x3D5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
+ if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80))
+ return;
+ if ((svga->crtcreg > 0x18) && (svga->crtcreg != 0x33) && (svga->crtcreg != 0x35) && !et4000->key)
+ return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (svga->crtcreg == 0x36) {
- svga->vram_display_mask = (val & 0x28) ? et4000->vram_mask : 0x3ffff; /* Both bits 5 and 3 must be off for 256k wraparound. */
if (!(val & 0x10)) {
- svga->write_bank = (((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536)) & svga->vram_display_mask;
- svga->read_bank = (((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536)) & svga->vram_display_mask;
- } else
- svga->write_bank = svga->read_bank = 0;
+ svga->write_bank = ((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536);
+ svga->read_bank = ((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536);
+ }
}
if (old != val)
{
@@ -266,6 +280,16 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36)
et4000w32p_recalcmapping(et4000);
break;
+ case 0x3D8:
+ et4000->mcr = val;
+ if (et4000->hcr == 0x03) {
+ if ((et4000->mcr & 0xa0) == 0xa0)
+ et4000->key = 1;
+ } else {
+ if ((et4000->mcr & 0xa0) != 0xa0)
+ et4000->key = 0;
+ }
+ break;
case 0x210A: case 0x211A: case 0x212A: case 0x213A:
case 0x214A: case 0x215A: case 0x216A: case 0x217A:
@@ -1118,6 +1142,7 @@ void et4000w32p_hwcursor_draw(svga_t *svga, int displine)
static void et4000w32p_io_remove(et4000w32p_t *et4000)
{
+ io_removehandler(0x03bf, 0x0001, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
@@ -1134,6 +1159,8 @@ static void et4000w32p_io_set(et4000w32p_t *et4000)
{
et4000w32p_io_remove(et4000);
+ if (et4000->svga.miscout & 1)
+ io_sethandler(0x03bf, 0x0001, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);