EGA/JEGA: More fixes and implemented more C&T SuperEGA behavior.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user