Compaq 386 machine fixes and Compaq EGA palette mux timer, fixes #3494.
This commit is contained in:
@@ -13,13 +13,14 @@
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c
|
||||
ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c
|
||||
intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c
|
||||
opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c
|
||||
via_pipc.c vl82c480.c wd76c10.c)
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
|
||||
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
|
||||
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
|
||||
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
|
||||
opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c
|
||||
sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c
|
||||
via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
|
||||
@@ -36,6 +36,9 @@ extern const device_t ali6117d_device;
|
||||
/* AMD */
|
||||
extern const device_t amd640_device;
|
||||
|
||||
/* Compaq */
|
||||
extern const device_t compaq_386_device;
|
||||
|
||||
/* Contaq/Cypress */
|
||||
extern const device_t contaq_82c596a_device;
|
||||
extern const device_t contaq_82c597_device;
|
||||
|
||||
@@ -45,8 +45,8 @@ typedef struct ega_t {
|
||||
uint8_t scrblank;
|
||||
uint8_t plane_mask;
|
||||
uint8_t ctl_mode;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t color_mux;
|
||||
uint8_t dot;
|
||||
uint8_t crtc[32];
|
||||
uint8_t gdcreg[16];
|
||||
uint8_t attrregs[32];
|
||||
@@ -108,6 +108,7 @@ typedef struct ega_t {
|
||||
int res_y;
|
||||
int bpp;
|
||||
int index;
|
||||
int remap_required;
|
||||
|
||||
uint32_t charseta;
|
||||
uint32_t charsetb;
|
||||
@@ -117,21 +118,24 @@ typedef struct ega_t {
|
||||
uint32_t ca;
|
||||
uint32_t vram_limit;
|
||||
uint32_t overscan_color;
|
||||
uint32_t cca;
|
||||
|
||||
uint32_t *pallook;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
|
||||
uint64_t dot_time;
|
||||
|
||||
pc_timer_t timer;
|
||||
pc_timer_t dot_timer;
|
||||
|
||||
double clock;
|
||||
double dot_clock;
|
||||
|
||||
int remap_required;
|
||||
uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr);
|
||||
void * eeprom;
|
||||
|
||||
void (*render)(struct ega_t *svga);
|
||||
|
||||
void *eeprom;
|
||||
uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr);
|
||||
void (*render)(struct ega_t *svga);
|
||||
} ega_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
@@ -795,34 +796,28 @@ machine_at_compaq_init(const machine_t *model, int type)
|
||||
{
|
||||
compaq_machine_type = type;
|
||||
|
||||
if ((type != COMPAQ_DESKPRO386) && (type != COMPAQ_DESKPRO386_01_1988))
|
||||
mem_remap_top(384);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if ((type == COMPAQ_DESKPRO386) || (type == COMPAQ_DESKPRO386_01_1988) || (type == COMPAQ_PORTABLEIII386))
|
||||
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
|
||||
read_ram, read_ramw, read_raml,
|
||||
write_ram, write_ramw, write_raml,
|
||||
0xa0000 + ram, MEM_MAPPING_EXTERNAL, NULL);
|
||||
else
|
||||
if (type < COMPAQ_PORTABLEIII386) {
|
||||
mem_remap_top(384);
|
||||
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
|
||||
read_ram, read_ramw, read_raml,
|
||||
write_ram, write_ramw, write_raml,
|
||||
0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL);
|
||||
}
|
||||
|
||||
video_reset(gfxcard[0]);
|
||||
|
||||
switch (type) {
|
||||
case COMPAQ_PORTABLEII:
|
||||
machine_at_init(model);
|
||||
machine_at_init(model);
|
||||
break;
|
||||
|
||||
case COMPAQ_PORTABLEIII:
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&compaq_plasma_device);
|
||||
machine_at_init(model);
|
||||
machine_at_init(model);
|
||||
break;
|
||||
|
||||
case COMPAQ_PORTABLEIII386:
|
||||
@@ -830,13 +825,14 @@ machine_at_compaq_init(const machine_t *model, int type)
|
||||
device_add(&ide_isa_device);
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&compaq_plasma_device);
|
||||
machine_at_init(model);
|
||||
machine_at_init(model);
|
||||
break;
|
||||
|
||||
case COMPAQ_DESKPRO386:
|
||||
case COMPAQ_DESKPRO386_01_1988:
|
||||
if (hdc_current == 1)
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&compaq_386_device);
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_compaq_device);
|
||||
break;
|
||||
|
||||
@@ -4694,9 +4694,9 @@ const machine_t machines[] = {
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_IDE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 63,
|
||||
.kbc_device = NULL,
|
||||
@@ -4732,9 +4732,9 @@ const machine_t machines[] = {
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_IDE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 63,
|
||||
.kbc_device = NULL,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
@@ -302,8 +304,8 @@ ega_in(uint16_t addr, void *priv)
|
||||
ret = ega->attrregs[ega->attraddr];
|
||||
break;
|
||||
case 0x3c2:
|
||||
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
|
||||
break;
|
||||
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x3c4:
|
||||
if (ega_type)
|
||||
ret = ega->seqaddr;
|
||||
@@ -361,8 +363,31 @@ ega_in(uint16_t addr, void *priv)
|
||||
break;
|
||||
case 0x3da:
|
||||
ega->attrff = 0;
|
||||
ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */
|
||||
ret = ega->stat;
|
||||
if (ega_type == 2) {
|
||||
ret = ega->stat & 0xcf;
|
||||
switch ((ega->attrregs[0x12] >> 4) & 0x03) {
|
||||
case 0x00:
|
||||
/* 00 = Pri. Red (5), Pri. Blue (4) */
|
||||
ret |= (ega->color_mux & 0x04) ? 0x20 : 0x00;
|
||||
ret |= (ega->color_mux & 0x01) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
/* 01 = Sec. Red (5), Sec. Green (4) */
|
||||
/* 11 = Sec. Red (5), Sec. Green (4) */
|
||||
ret |= (ega->color_mux & 0x20) ? 0x20 : 0x00;
|
||||
ret |= (ega->color_mux & 0x10) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x02:
|
||||
/* 10 = Sec. Blue (5), Pri. Green (4) */
|
||||
ret |= (ega->color_mux & 0x08) ? 0x20 : 0x00;
|
||||
ret |= (ega->color_mux & 0x02) ? 0x10 : 0x00;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */
|
||||
ret = ega->stat;
|
||||
}
|
||||
break;
|
||||
case 0x7c6:
|
||||
ret = 0xfd; /* EGA mode supported. */
|
||||
@@ -436,15 +461,15 @@ ega_recalctimings(ega_t *ega)
|
||||
|
||||
if (ega_type == 2) {
|
||||
color = (ega->miscout & 1);
|
||||
clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0);
|
||||
clksel = ((ega->miscout & 0xc) >> 2);
|
||||
|
||||
if (color) {
|
||||
if (clksel)
|
||||
if (ega->vidclock)
|
||||
crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32));
|
||||
else
|
||||
crtcconst = (cpuclock / (157500000.0 / 11.0) * (double) (1ULL << 32));
|
||||
} else {
|
||||
if (clksel)
|
||||
if (ega->vidclock)
|
||||
crtcconst = (cpuclock / 18981000.0 * (double) (1ULL << 32));
|
||||
else
|
||||
crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32));
|
||||
@@ -484,6 +509,10 @@ ega_recalctimings(ega_t *ega)
|
||||
else
|
||||
crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0));
|
||||
}
|
||||
if (!(ega->seqregs[1] & 1))
|
||||
ega->dot_clock = crtcconst / 9.0;
|
||||
else
|
||||
ega->dot_clock = crtcconst / 8.0;
|
||||
|
||||
ega->interlace = 0;
|
||||
|
||||
@@ -538,9 +567,110 @@ ega_recalctimings(ega_t *ega)
|
||||
if (ega->dispofftime < TIMER_USEC)
|
||||
ega->dispofftime = TIMER_USEC;
|
||||
|
||||
ega->dot_time = (uint64_t) (ega->dot_clock);
|
||||
if (ega->dot_time < TIMER_USEC)
|
||||
ega->dot_time = TIMER_USEC;
|
||||
|
||||
ega_recalc_remap_func(ega);
|
||||
}
|
||||
|
||||
/* This is needed for the Compaq EGA so that it can pass the 3DA
|
||||
palette mux part of the self-test. */
|
||||
void
|
||||
ega_dot_poll(void *priv)
|
||||
{
|
||||
ega_t *ega = (ega_t *) priv;
|
||||
static uint8_t chr;
|
||||
static uint8_t attr;
|
||||
const bool doublewidth = ((ega->seqregs[1] & 8) != 0);
|
||||
const bool attrblink = ((ega->attrregs[0x10] & 8) != 0);
|
||||
const bool attrlinechars = (ega->attrregs[0x10] & 4);
|
||||
const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0);
|
||||
const bool seq9dot = ((ega->seqregs[1] & 1) == 0);
|
||||
const bool blinked = ega->blink & 0x10;
|
||||
const int dwshift = doublewidth ? 1 : 0;
|
||||
const int dotwidth = 1 << dwshift;
|
||||
const int charwidth = dotwidth * (seq9dot ? 9 : 8);
|
||||
const int cursoron = (ega->sc == (ega->crtc[10] & 31));
|
||||
const int cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
|
||||
uint32_t addr;
|
||||
int drawcursor;
|
||||
uint32_t charaddr;
|
||||
static int fg;
|
||||
static int bg;
|
||||
static uint32_t dat;
|
||||
static int disptime;
|
||||
static int _dispontime;
|
||||
static int _dispofftime;
|
||||
static int cclock = 0;
|
||||
static int active = 0;
|
||||
|
||||
if (ega->seqregs[1] & 8) {
|
||||
disptime = ((ega->crtc[0] + 2) << 1);
|
||||
_dispontime = ((ega->crtc[1] + 1) << 1);
|
||||
} else {
|
||||
disptime = (ega->crtc[0] + 2);
|
||||
_dispontime = (ega->crtc[1] + 1);
|
||||
}
|
||||
_dispofftime = disptime - _dispontime;
|
||||
|
||||
timer_advance_u64(&ega->dot_timer, ega->dot_time);
|
||||
|
||||
if (ega->render == ega_render_text)
|
||||
ega->color_mux = (dat & (0x100 >> (ega->dot >> dwshift))) ? fg : bg;
|
||||
else
|
||||
ega->color_mux = 0x00;
|
||||
|
||||
addr = ega->remap_func(ega, ega->cca) & ega->vrammask;
|
||||
|
||||
if (!crtcreset) {
|
||||
chr = ega->vram[addr];
|
||||
attr = ega->vram[addr + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
drawcursor = ((ega->cca == cursoraddr) && cursoron && ega->cursoron);
|
||||
|
||||
if (attr & 8)
|
||||
charaddr = ega->charsetb + (chr * 0x80);
|
||||
else
|
||||
charaddr = ega->charseta + (chr * 0x80);
|
||||
|
||||
dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
dat <<= 1;
|
||||
if ((chr & ~0x1F) == 0xC0 && attrlinechars)
|
||||
dat |= (dat >> 1) & 1;
|
||||
|
||||
if (!active)
|
||||
dat = 0x200;
|
||||
|
||||
if (drawcursor) {
|
||||
bg = ega->egapal[attr & 0x0f];
|
||||
fg = ega->egapal[attr >> 4];
|
||||
} else {
|
||||
fg = ega->egapal[attr & 0x0f];
|
||||
bg = ega->egapal[attr >> 4];
|
||||
if ((attr & 0x80) && attrblink) {
|
||||
bg = ega->egapal[(attr >> 4) & 7];
|
||||
if (blinked)
|
||||
fg = bg;
|
||||
}
|
||||
}
|
||||
|
||||
ega->dot = (ega->dot + 1) % charwidth;
|
||||
|
||||
if (ega->dot == 0) {
|
||||
ega->cca = (ega->cca + 4) & 0x3ffff;
|
||||
|
||||
cclock++;
|
||||
|
||||
if (active && (cclock == _dispofftime))
|
||||
active = 0;
|
||||
else if (!active && (cclock == _dispontime))
|
||||
active = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ega_poll(void *priv)
|
||||
{
|
||||
@@ -623,6 +753,7 @@ ega_poll(void *priv)
|
||||
if (ega->linedbl && !ega->linecountff) {
|
||||
ega->linecountff = 1;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
}
|
||||
if (ega->sc == (ega->crtc[9] & 31)) {
|
||||
ega->linecountff = 0;
|
||||
@@ -633,11 +764,13 @@ ega_poll(void *priv)
|
||||
ega->maback += (ega->rowoffset << 3);
|
||||
ega->maback &= ega->vrammask;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
} else {
|
||||
ega->linecountff = 0;
|
||||
ega->sc++;
|
||||
ega->sc &= 31;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
}
|
||||
}
|
||||
ega->vc++;
|
||||
@@ -649,6 +782,7 @@ ega_poll(void *priv)
|
||||
else
|
||||
ega->ma = ega->maback = 0;
|
||||
ega->ma <<= 2;
|
||||
ega->cca = ega->ma;
|
||||
ega->maback <<= 2;
|
||||
ega->sc = 0;
|
||||
if (ega->attrregs[0x10] & 0x20) {
|
||||
@@ -676,6 +810,7 @@ ega_poll(void *priv)
|
||||
if (ega->vc == ega->vsyncstart) {
|
||||
ega->dispon = 0;
|
||||
ega->stat |= 8;
|
||||
// picint(1 << 2);
|
||||
x = ega->hdisp;
|
||||
|
||||
if (ega->interlace && !ega->oddeven)
|
||||
@@ -715,6 +850,7 @@ ega_poll(void *priv)
|
||||
ega->ma <<= 2;
|
||||
ega->maback <<= 2;
|
||||
ega->ca <<= 2;
|
||||
ega->cca = ega->ma;
|
||||
}
|
||||
if (ega->vc == ega->vtotal) {
|
||||
ega->vc = 0;
|
||||
@@ -1263,6 +1399,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
|
||||
ega->crtc[6] = 255;
|
||||
|
||||
timer_add(&ega->timer, ega_poll, ega, 1);
|
||||
if (ega_type == 2)
|
||||
timer_add(&ega->dot_timer, ega_dot_poll, ega, 1);
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -1339,6 +1477,7 @@ ega_standalone_init(const device_t *info)
|
||||
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(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
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);
|
||||
|
||||
@@ -582,6 +582,7 @@ CPUOBJ := $(DYNARECOBJ) \
|
||||
softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o
|
||||
|
||||
CHIPSETOBJ := 82c100.o acc2168.o \
|
||||
compaq_386.o \
|
||||
contaq_82c59x.o \
|
||||
cs4031.o cs8230.o \
|
||||
ali1429.o ali1435.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \
|
||||
|
||||
Reference in New Issue
Block a user