First batch of video fixes, also fixes the MDA timings.

This commit is contained in:
OBattler
2023-08-12 01:16:49 +02:00
parent 6ceb63aacc
commit 33471594f4
3 changed files with 66 additions and 5 deletions

View File

@@ -44,9 +44,9 @@ typedef struct ega_t {
uint8_t colournocare;
uint8_t scrblank;
uint8_t plane_mask;
uint8_t ctl_mode;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t crtc[32];
uint8_t gdcreg[16];
uint8_t attrregs[32];

View File

@@ -1014,7 +1014,11 @@ pit_set_clock(int clock)
PITCONSTD = (cpuclock / 1193182.0);
PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32));
#ifdef IMPRECISE_CGACONST
CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32));
#else
CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32));
#endif
ISACONST = (uint64_t) ((cpuclock / (double) cpu_isa_speed) * (double) (1ULL << 32));
xt_cpu_multi = 1ULL;
} else {
@@ -1064,7 +1068,11 @@ pit_set_clock(int clock)
} else if (cpuclock != 14318184.0) {
PITCONSTD = (cpuclock / 1193182.0);
PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32));
#ifdef IMPRECISE_CGACONST
CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32));
#else
CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32));
#endif
}
ISACONST = (1ULL << 32ULL);
@@ -1074,7 +1082,11 @@ pit_set_clock(int clock)
/* Delay for empty I/O ports. */
io_delay = (int) round(((double) cpu_s->rspeed) / 3000000.0);
#ifdef WRONG_MDACONST
MDACONST = (uint64_t) (cpuclock / 2032125.0 * (double) (1ULL << 32));
#else
MDACONST = (uint64_t) (cpuclock / (16257000.0 / 9.0) * (double) (1ULL << 32));
#endif
HERCCONST = MDACONST;
VGACONST1 = (uint64_t) (cpuclock / 25175000.0 * (double) (1ULL << 32));
VGACONST2 = (uint64_t) (cpuclock / 28322000.0 * (double) (1ULL << 32));

View File

@@ -188,6 +188,10 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
case 0x3c6:
if (ega_type == 2)
ega->ctl_mode = val;
break;
case 0x3ce:
ega->gdcaddr = val;
break;
@@ -308,6 +312,10 @@ ega_in(uint16_t addr, void *priv)
if (ega_type)
ret = ega->seqregs[ega->seqaddr & 0xf];
break;
case 0x3c6:
if (ega_type == 2)
ret = ega->ctl_mode;
break;
case 0x3c8:
if (ega_type)
ret = 2;
@@ -341,7 +349,7 @@ ega_in(uint16_t addr, void *priv)
case 0x10:
case 0x11:
// TODO: Return light pen address once implemented
/* TODO: Return light pen address once implemented. */
if (ega_type)
ret = ega->crtc[ega->crtcreg];
break;
@@ -353,9 +361,23 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3da:
ega->attrff = 0;
ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/
ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */
ret = ega->stat;
break;
case 0x7c6:
ret = 0xfd; /* EGA mode supported. */
break;
case 0xbc6:
/* 0000 = None;
0001 = Compaq Dual-Mode (DM) Monitor;
0010 = RGBI Color Monitor;
0011 = COMAPQ Color Monitor (RrGgBb) or Compatible;
0100 - 1111 = Reserved. */
ret = 0x01;
break;
case 0xfc6:
ret = 0xfd;
break;
default:
break;
@@ -368,6 +390,7 @@ void
ega_recalctimings(ega_t *ega)
{
int clksel;
int color;
double _dispontime;
double _dispofftime;
@@ -411,7 +434,26 @@ ega_recalctimings(ega_t *ega)
ega->linedbl = ega->crtc[9] & 0x80;
ega->rowcount = ega->crtc[9] & 0x1f;
if (ega->eeprom) {
if (ega_type == 2) {
color = (ega->miscout & 1);
clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0);
if (color) {
if (clksel)
crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32));
else
crtcconst = (cpuclock / (157500000.0 / 11.0) * (double) (1ULL << 32));
} else {
if (clksel)
crtcconst = (cpuclock / 18981000.0 * (double) (1ULL << 32));
else
crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32));
}
if (!(ega->seqregs[1] & 1))
crtcconst *= 9.0;
else
crtcconst *= 8.0;
} else if (ega->eeprom) {
clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0);
switch (clksel) {
@@ -1229,7 +1271,7 @@ ega_standalone_init(const device_t *info)
ega_t *ega = malloc(sizeof(ega_t));
int monitor_type;
memset(ega, 0, sizeof(ega_t));
memset(ega, 0x00, sizeof(ega_t));
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega);
@@ -1240,6 +1282,8 @@ ega_standalone_init(const device_t *info)
if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || (info->local == EGA_TSENG))
ega_type = 0;
else if (info->local == EGA_COMPAQ)
ega_type = 2;
else
ega_type = 1;
@@ -1250,6 +1294,7 @@ ega_standalone_init(const device_t *info)
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case EGA_COMPAQ:
ega->ctl_mode = 0x21;
rom_init(&ega->bios_rom, BIOS_CPQ_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
@@ -1293,6 +1338,10 @@ ega_standalone_init(const device_t *info)
ega->eeprom = malloc(sizeof(ati_eeprom_t));
memset(ega->eeprom, 0, sizeof(ati_eeprom_t));
ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0);
} else if (info->local == EGA_COMPAQ) {
io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
io_sethandler(0x0fc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
}
return ega;