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