Support for alternate IBM EGA Address
(Disabled behind ifdef because while it's a thing, you need a custom BIOS to use it)
This commit is contained in:
@@ -148,6 +148,8 @@ typedef struct ega_t {
|
||||
card should not attempt to display anything. */
|
||||
void (*render_override)(void *priv);
|
||||
void * priv_parent;
|
||||
|
||||
uint8_t alt_addr; /* 0 for 0x3XX range, 1 for 0x2XX range */
|
||||
} ega_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
uint8_t gdcmask = (ega_type == 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) == 0x2d0)) || (((addr & 0xfff0) == 0x3b0) || ((addr & 0xfff0) == 0x2b0))) && !(ega->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
@@ -94,7 +94,9 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2c0:
|
||||
case 0x3c0:
|
||||
case 0x2c1:
|
||||
case 0x3c1:
|
||||
if (atype == EGA_SUPEREGA)
|
||||
val &= 0x7f; /* Bit 7 indicates the flipflop status (read only) */
|
||||
@@ -139,6 +141,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
ega->attrff ^= 1;
|
||||
break;
|
||||
case 0x2c2:
|
||||
case 0x3c2:
|
||||
o = ega->miscout;
|
||||
egaswitchread = (val & 0xc) >> 2;
|
||||
@@ -148,9 +151,15 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
ega->miscout = val;
|
||||
ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] :
|
||||
pallook64[ega->attrregs[0x11] & 0x3f];
|
||||
io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
|
||||
uint16_t base_addr = 0x03a0;
|
||||
#ifdef EGA_ALT_ADDR_SUPPORT
|
||||
if (ega->alt_addr == 1)
|
||||
base_addr = 0x02a0;
|
||||
#endif
|
||||
io_removehandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
if (!(val & 1))
|
||||
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
io_sethandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
ega_recalctimings(ega);
|
||||
if ((type == EGA_TYPE_COMPAQ) && !(val & 0x02))
|
||||
mem_mapping_disable(&ega->mapping);
|
||||
@@ -172,9 +181,11 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2c4:
|
||||
case 0x3c4:
|
||||
ega->seqaddr = val;
|
||||
break;
|
||||
case 0x2c5:
|
||||
case 0x3c5:
|
||||
o = ega->seqregs[ega->seqaddr & 0xf];
|
||||
ega->seqregs[ega->seqaddr & 0xf] = val;
|
||||
@@ -201,13 +212,16 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2c6:
|
||||
case 0x3c6:
|
||||
if (type == EGA_TYPE_COMPAQ)
|
||||
ega->ctl_mode = val;
|
||||
break;
|
||||
case 0x2ce:
|
||||
case 0x3ce:
|
||||
ega->gdcaddr = val;
|
||||
break;
|
||||
case 0x2cf:
|
||||
case 0x3cf:
|
||||
ega->gdcreg[ega->gdcaddr & gdcmask] = val;
|
||||
switch (ega->gdcaddr & gdcmask) {
|
||||
@@ -264,14 +278,18 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2d0:
|
||||
case 0x3d0:
|
||||
case 0x2d4:
|
||||
case 0x3d4:
|
||||
if (ega->chipset)
|
||||
ega->crtcreg = val & 0x3f;
|
||||
else
|
||||
ega->crtcreg = val;
|
||||
return;
|
||||
case 0x2d1:
|
||||
case 0x3d1:
|
||||
case 0x2d5:
|
||||
case 0x3d5: {
|
||||
int idx = ega->crtcreg;
|
||||
|
||||
@@ -322,7 +340,7 @@ ega_in(uint16_t addr, void *priv)
|
||||
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) == 0x2d0)) || (((addr & 0xfff0) == 0x3b0) || ((addr & 0xfff0) == 0x2b0))) && !(ega->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
@@ -343,7 +361,9 @@ ega_in(uint16_t addr, void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2c0:
|
||||
case 0x3c0:
|
||||
case 0x2c1:
|
||||
case 0x3c1:
|
||||
if (type == EGA_TYPE_OTHER) {
|
||||
int data = (atype == EGA_SUPEREGA) ? (ega->attrff & 1) : (addr & 1);
|
||||
@@ -356,9 +376,11 @@ ega_in(uint16_t addr, void *priv)
|
||||
ret = (ret & 0x3f) | (ega->attrff ? 0x80 : 0x00);
|
||||
}
|
||||
break;
|
||||
case 0x2c2:
|
||||
case 0x3c2:
|
||||
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x2c4:
|
||||
case 0x3c4:
|
||||
if (type == EGA_TYPE_OTHER) {
|
||||
if (atype == EGA_SUPEREGA)
|
||||
@@ -367,6 +389,7 @@ ega_in(uint16_t addr, void *priv)
|
||||
ret = ega->seqaddr;
|
||||
}
|
||||
break;
|
||||
case 0x2c5:
|
||||
case 0x3c5:
|
||||
if (type == EGA_TYPE_OTHER) {
|
||||
if ((ega->seqaddr & 0x0f) > 0x04)
|
||||
@@ -375,18 +398,22 @@ ega_in(uint16_t addr, void *priv)
|
||||
ret = ega->seqregs[ega->seqaddr & 0xf];
|
||||
}
|
||||
break;
|
||||
case 0x2c6:
|
||||
case 0x3c6:
|
||||
if (type == EGA_TYPE_COMPAQ)
|
||||
ret = ega->ctl_mode;
|
||||
break;
|
||||
case 0x2c8:
|
||||
case 0x3c8:
|
||||
if (type == EGA_TYPE_OTHER)
|
||||
ret = 2;
|
||||
break;
|
||||
case 0x2cc:
|
||||
case 0x3cc:
|
||||
if (type == EGA_TYPE_OTHER)
|
||||
ret = ega->miscout;
|
||||
break;
|
||||
case 0x2ce:
|
||||
case 0x3ce:
|
||||
if (ega_type == EGA_TYPE_OTHER) {
|
||||
ret = ega->gdcaddr;
|
||||
@@ -397,6 +424,7 @@ ega_in(uint16_t addr, void *priv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2cf:
|
||||
case 0x3cf:
|
||||
if (type == EGA_TYPE_OTHER) {
|
||||
switch (ega->gdcaddr & gdcmask) {
|
||||
@@ -421,7 +449,9 @@ ega_in(uint16_t addr, void *priv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2d0:
|
||||
case 0x3d0:
|
||||
case 0x2d4:
|
||||
case 0x3d4:
|
||||
if (ega_type == EGA_TYPE_OTHER) {
|
||||
ret = ega->crtcreg;
|
||||
@@ -432,7 +462,9 @@ ega_in(uint16_t addr, void *priv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2d1:
|
||||
case 0x3d1:
|
||||
case 0x2d5:
|
||||
case 0x3d5:
|
||||
switch (ega->crtcreg & crtcmask) {
|
||||
case 0xc:
|
||||
@@ -467,6 +499,7 @@ ega_in(uint16_t addr, void *priv)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2da:
|
||||
case 0x3da:
|
||||
ega->attrff = 0;
|
||||
if (type == EGA_TYPE_COMPAQ) {
|
||||
@@ -1464,7 +1497,12 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
|
||||
}
|
||||
}
|
||||
|
||||
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
uint16_t base_addr = 0x03a0;
|
||||
#ifdef EGA_ALT_ADDR_SUPPORT
|
||||
if (ega->alt_addr == 1)
|
||||
base_addr = 0x02a0;
|
||||
#endif
|
||||
io_sethandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
} else {
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
|
||||
@@ -1619,7 +1657,15 @@ ega_standalone_init(const device_t *info)
|
||||
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega);
|
||||
if (ega_type == EGA_TYPE_COMPAQ)
|
||||
mem_mapping_disable(&ega->mapping);
|
||||
io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
uint16_t addr = 0x03c0;
|
||||
#ifdef EGA_ALT_ADDR_SUPPORT
|
||||
if (ega_type == EGA_TYPE_IBM) {
|
||||
addr = device_get_config_hex16("base");
|
||||
if (addr == 0x02c0)
|
||||
ega->alt_addr = 1;
|
||||
}
|
||||
#endif
|
||||
io_sethandler(addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
|
||||
if (ega->chipset) {
|
||||
io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
@@ -1699,6 +1745,66 @@ ega_speed_changed(void *priv)
|
||||
|
||||
0 = Switch closed (ON);
|
||||
1 = Switch open (OFF). */
|
||||
static const device_config_t ega_ibm_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 256,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "32 KB", .value = 32 },
|
||||
{ .description = "64 KB", .value = 64 },
|
||||
{ .description = "128 KB", .value = 128 },
|
||||
{ .description = "256 KB", .value = 256 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "monitor_type",
|
||||
.description = "Monitor type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 9,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Monochrome (5151/MDA) (white)", .value = 0x0B | (DISPLAY_WHITE << 4) },
|
||||
{ .description = "Monochrome (5151/MDA) (green)", .value = 0x0B | (DISPLAY_GREEN << 4) },
|
||||
{ .description = "Monochrome (5151/MDA) (amber)", .value = 0x0B | (DISPLAY_AMBER << 4) },
|
||||
{ .description = "Color 40x25 (5153/CGA)", .value = 0x06 },
|
||||
{ .description = "Color 80x25 (5153/CGA)", .value = 0x07 },
|
||||
{ .description = "Enhanced Color - Normal Mode (5154/ECD)", .value = 0x08 },
|
||||
{ .description = "Enhanced Color - Enhanced Mode (5154/ECD)", .value = 0x09 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#ifdef EGA_ALT_ADDR_SUPPORT
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x03c0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3C0", .value = 0x03c0 },
|
||||
{ .description = "0x2C0", .value = 0x02c0 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#endif
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t ega_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
@@ -1753,7 +1859,7 @@ const device_t ega_device = {
|
||||
.available = ega_standalone_available,
|
||||
.speed_changed = ega_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = ega_config
|
||||
.config = ega_ibm_config
|
||||
};
|
||||
|
||||
const device_t cpqega_device = {
|
||||
|
||||
Reference in New Issue
Block a user