EGA/JEGA: More fixes and implemented more C&T SuperEGA behavior.

This commit is contained in:
OBattler
2025-03-30 07:28:20 +02:00
parent 3fc6d29462
commit e4877a57c5
2 changed files with 72 additions and 28 deletions

View File

@@ -61,14 +61,38 @@ int update_overscan = 0;
uint8_t ega_in(uint16_t addr, void *priv);
static int
ega_get_type(ega_t *ega)
{
int ret = ega_type;
if (ega->actual_type == EGA_SUPEREGA)
ret = (ega->crtc[0x17] & 0x10) ? EGA_TYPE_OTHER : EGA_TYPE_IBM;
return ret;
}
static int
ega_get_actual_type(ega_t *ega)
{
int ret = ega->actual_type;
if (ega->actual_type == EGA_SUPEREGA)
ret = (ega->crtc[0x17] & 0x10) ? EGA_SUPEREGA : EGA_IBM;
return ret;
}
void
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;
int type = ega_get_type(ega);
int atype = ega_get_actual_type(ega);
uint8_t gdcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t crtcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x1f;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1))
addr ^= 0x60;
@@ -94,7 +118,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
case 0x3c0:
case 0x3c1:
if (ega->actual_type == EGA_SUPEREGA)
if (atype == EGA_SUPEREGA)
val &= 0x7f; /* Bit 7 indicates the flipflop status (read only) */
if (!ega->attrff) {
ega->attraddr = val & 31;
@@ -110,7 +134,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega->attrregs[ega->attraddr & 31] = val;
if (ega->attraddr < 16)
ega->fullchange = changeframecount;
if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) {
int is_attr14 = ega->chipset && (ega->attraddr == 0x14);
if ((ega->attraddr == 0x10) || is_attr14 || (ega->attraddr < 0x10)) {
for (uint8_t c = 0; c < 16; c++) {
if (ega->chipset) {
if (ega->attrregs[0x10] & 0x80)
@@ -148,7 +173,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
if (!(val & 1))
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
ega_recalctimings(ega);
if ((ega_type == EGA_TYPE_COMPAQ) && !(val & 0x02))
if ((type == EGA_TYPE_COMPAQ) && !(val & 0x02))
mem_mapping_disable(&ega->mapping);
else switch (ega->gdcreg[6] & 0xc) {
case 0x0: /*128k at A0000*/
@@ -198,7 +223,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0x3c6:
if (ega_type == EGA_TYPE_COMPAQ)
if (type == EGA_TYPE_COMPAQ)
ega->ctl_mode = val;
break;
case 0x3ce:
@@ -219,7 +244,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega->chain2_read = val & 0x10;
break;
case 6:
if ((ega_type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02))
if ((type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02))
mem_mapping_disable(&ega->mapping);
else switch (val & 0xc) {
case 0x0: /*128k at A0000*/
@@ -306,6 +331,8 @@ ega_in(uint16_t addr, void *priv)
ega_t *ega = (ega_t *) priv;
uint8_t gdcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t ret = 0xff;
int type = ega_get_type(ega);
int atype = ega_get_actual_type(ega);
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1))
addr ^= 0x60;
@@ -329,48 +356,58 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3c0:
if (ega_type == EGA_TYPE_OTHER)
ret = ega->attraddr | ega->attr_palette_enable;
if (ega->actual_type == EGA_SUPEREGA && ega->attrff)
ret |= 0x80; /* Bit 7 indicates the flipflop status (read only) */
break;
case 0x3c1:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER) {
int data = (atype == EGA_SUPEREGA) ? (ega->attrff & 1) : (addr & 1);
if (data)
ret = ega->attrregs[ega->attraddr];
else
ret = ega->attraddr | ega->attr_palette_enable;
if (atype == EGA_SUPEREGA)
/* Bit 7 indicates the flipflop status (read only) */
ret = (ret & 0x3f) | (ega->attrff ? 0x80 : 0x00);
}
break;
case 0x3c2:
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
break;
case 0x3c4:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->seqaddr;
break;
case 0x3c5:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER) {
if ((ega->seqaddr & 0x0f) > 0x04)
ret = ega->chipset ? ega->seqregs[ega->seqaddr & 0xf] : 0xff;
else
ret = ega->seqregs[ega->seqaddr & 0xf];
}
break;
case 0x3c6:
if (ega_type == EGA_TYPE_COMPAQ)
if (type == EGA_TYPE_COMPAQ)
ret = ega->ctl_mode;
break;
case 0x3c8:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = 2;
break;
case 0x3cc:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->miscout;
break;
case 0x3ce:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->gdcaddr;
break;
case 0x3cf:
if (ega_type == EGA_TYPE_OTHER) {
if (type == EGA_TYPE_OTHER) {
switch (ega->gdcaddr & gdcmask) {
default:
ret = ega->gdcreg[ega->gdcaddr & gdcmask];
break;
case 0x09 ... 0xf7:
ret = ega->chipset ? ega->gdcreg[ega->gdcaddr & gdcmask] : 0xff;
break;
case 0xf8:
ret = ega->la;
break;
@@ -388,8 +425,14 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3d0:
case 0x3d4:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER) {
ret = ega->crtcreg;
if (atype == EGA_SUPEREGA) {
ret = (ret & 0x1f) | 0xc0;
if ((ega->crtcreg & 0xc0) == 0xc0)
ret |= 0x20;
}
}
break;
case 0x3d1:
case 0x3d5:
@@ -402,28 +445,28 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x10:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen >> 8;
break;
case 0x11:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen & 0xff;
break;
default:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
break;
}
break;
case 0x3da:
ega->attrff = 0;
if (ega_type == EGA_TYPE_COMPAQ) {
if (type == EGA_TYPE_COMPAQ) {
ret = ega->stat & 0xcf;
switch ((ega->attrregs[0x12] >> 4) & 0x03) {
case 0x00:

View File

@@ -428,7 +428,8 @@ jega_out(uint16_t addr, uint8_t val, void *priv)
}
} else {
jega->attrregs[jega->attraddr & 31] = val;
if (jega->attraddr < 0x10) {
int is_attr14 = jega->is_vga ? (jega->attraddr == 0x14) : 0;
if (is_attr14 || (jega->attraddr < 0x10)) {
for (uint8_t c = 0; c < 16; c++) {
if (jega->is_vga) {
if (jega->attrregs[0x10] & 0x80)