From c3d15ef36d183cb54df75466de5bb26fd38ce8d8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Mar 2025 19:45:32 +0100 Subject: [PATCH] EGA and JEGA: Implement some missing SuperEGA stuff and make the JEGA properly set the EGA type to SuperEGA, fixes #5370. --- src/include/86box/vid_ega.h | 1 + src/video/vid_ega.c | 69 +++++++++++++++++++++++++++++++++---- src/video/vid_jega.c | 2 +- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 082cb120a..5ff7d3871 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -178,6 +178,7 @@ extern uint8_t ega_in(uint16_t addr, void *priv); extern void ega_poll(void *priv); extern void ega_write(uint32_t addr, uint8_t val, void *priv); extern uint8_t ega_read(uint32_t addr, void *priv); +extern void ega_set_type(void *priv, uint32_t local); extern int firstline_draw; extern int lastline_draw; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 781e9a9dd..18a53a127 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -67,6 +67,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega_t *ega = (ega_t *) priv; uint8_t o; uint8_t old; + uint8_t gdcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x0f; + uint8_t crtcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x1f; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -200,8 +202,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->gdcaddr = val; break; case 0x3cf: - ega->gdcreg[ega->gdcaddr & 15] = val; - switch (ega->gdcaddr & 15) { + ega->gdcreg[ega->gdcaddr & gdcmask] = val; + switch (ega->gdcaddr & gdcmask) { case 2: ega->colourcompare = val; break; @@ -238,6 +240,19 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->colournocare = val; break; + case 0xf8: + ega->la = val; + break; + case 0xf9: + ega->lb = val; + break; + case 0xfa: + ega->lc = val; + break; + case 0xfb: + ega->ld = val; + break; + default: break; } @@ -247,7 +262,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) if (ega->chipset) ega->crtcreg = val & 0x3f; else - ega->crtcreg = val & 0x1f; + ega->crtcreg = val & crtcmask; return; case 0x3d1: case 0x3d5: @@ -286,7 +301,8 @@ uint8_t ega_in(uint16_t addr, void *priv) { ega_t *ega = (ega_t *) priv; - uint8_t ret = 0xff; + uint8_t gdcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x0f; + uint8_t ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -347,8 +363,25 @@ ega_in(uint16_t addr, void *priv) ret = ega->gdcaddr; break; case 0x3cf: - if (ega_type == EGA_TYPE_OTHER) - ret = ega->gdcreg[ega->gdcaddr & 0xf]; + if (ega_type == EGA_TYPE_OTHER) { + switch (ega->gdcaddr & gdcmask) { + default: + ret = ega->gdcreg[ega->gdcaddr & gdcmask]; + break; + case 0xf8: + ret = ega->la; + break; + case 0xf9: + ret = ega->lb; + break; + case 0xfa: + ret = ega->lc; + break; + case 0xfb: + ret = ega->ld; + break; + } + } break; case 0x3d0: case 0x3d4: @@ -1428,6 +1461,30 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) timer_add(&ega->dot_timer, ega_dot_poll, ega, 1); } +void +ega_set_type(void *priv, uint32_t local) +{ + ega_t *ega = (ega_t *) priv; + + if ((local == EGA_IBM) || (local == EGA_ISKRA) || (local == EGA_TSENG)) + ega_type = EGA_TYPE_IBM; + else if (local == EGA_COMPAQ) + ega_type = EGA_TYPE_COMPAQ; + else + ega_type = EGA_TYPE_OTHER; + + ega->actual_type = local; + ega->chipset = 0; + + switch (local) { + default: + break; + case EGA_ATI800P: + ega->chipset = 1; + break; + } +} + static void * ega_standalone_init(const device_t *info) { diff --git a/src/video/vid_jega.c b/src/video/vid_jega.c index c410a15da..145579cf5 100644 --- a/src/video/vid_jega.c +++ b/src/video/vid_jega.c @@ -632,7 +632,7 @@ jega_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega); jega->pallook = pallook64; ega_init(&jega->ega, 9, 0); - jega->ega.actual_type = EGA_SUPEREGA; + ega_set_type(&jega->ega, EGA_SUPEREGA); jega->ega.priv_parent = jega; mem_mapping_add(&jega->ega.mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, &jega->ega);