mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Merge pull request #5593 from 86Box/plasma_wip
Compaq Plasma fixes, fixes #5011.
This commit is contained in:
@@ -84,20 +84,14 @@ compaq_plasma_display_set(uint8_t internal)
|
||||
cpq_st_display_internal = internal;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_display_get(void)
|
||||
{
|
||||
return cpq_st_display_internal;
|
||||
}
|
||||
|
||||
typedef struct compaq_plasma_t {
|
||||
cga_t cga;
|
||||
uint8_t ctl_mode;
|
||||
mem_mapping_t font_ram_mapping;
|
||||
uint8_t *font_ram;
|
||||
uint8_t port_13c6;
|
||||
uint8_t port_23c6;
|
||||
uint8_t port_27c6;
|
||||
uint8_t internal_monitor;
|
||||
uint8_t attrmap;
|
||||
} compaq_plasma_t;
|
||||
|
||||
static int compaq_machine_type = 0;
|
||||
@@ -119,13 +113,11 @@ compaq_plasma_recalctimings(compaq_plasma_t *self)
|
||||
return;
|
||||
}
|
||||
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST / 2;
|
||||
_dispofftime *= CGACONST / 2;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime);
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime);
|
||||
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -143,7 +135,10 @@ compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
if (self->port_23c6 & 0x08)
|
||||
self->font_ram[addr & 0x1fff] = val;
|
||||
else
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
}
|
||||
@@ -154,7 +149,11 @@ compaq_plasma_read(uint32_t addr, void *priv)
|
||||
uint8_t ret;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
ret = (self->font_ram[addr & 0x1fff]);
|
||||
else
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -164,11 +163,6 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
if (self->port_23c6 & 0x08) {
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3dc))
|
||||
addr ^= 0x60;
|
||||
}
|
||||
|
||||
switch (addr) {
|
||||
/* Emulated CRTC, register select */
|
||||
case 0x3d0:
|
||||
@@ -183,35 +177,31 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
/* Register 0x12 controls the attribute mappings for the
|
||||
* plasma screen. */
|
||||
if (self->cga.crtcreg == 0x12) {
|
||||
self->attrmap = val;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
return;
|
||||
}
|
||||
cga_out(addr, val, &self->cga);
|
||||
|
||||
compaq_plasma_recalctimings(self);
|
||||
break;
|
||||
case 0x3d8:
|
||||
case 0x3d9:
|
||||
case 0x3db:
|
||||
case 0x3dc:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
self->port_13c6 = val;
|
||||
compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0);
|
||||
/*
|
||||
For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA;
|
||||
Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA;
|
||||
This leads me to believe bit 2 is not relevant to the mode.
|
||||
*/
|
||||
if ((val & 0x03) == 0x03)
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000);
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
self->port_23c6 = val;
|
||||
if (val & 0x08) /* Disable internal CGA */
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x8000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x8000);
|
||||
compaq_plasma_recalcattrs(self);
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
@@ -229,11 +219,6 @@ compaq_plasma_in(uint16_t addr, void *priv)
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (self->port_23c6 & 0x08) {
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3dc))
|
||||
addr ^= 0x60;
|
||||
}
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d4:
|
||||
case 0x3da:
|
||||
@@ -246,13 +231,8 @@ compaq_plasma_in(uint16_t addr, void *priv)
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
if (self->cga.crtcreg == 0x12) {
|
||||
ret = self->attrmap & 0x0f;
|
||||
if (compaq_plasma_display_get())
|
||||
ret |= 0x30; /* Plasma / CRT */
|
||||
} else
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d8:
|
||||
ret = self->cga.cgamode;
|
||||
@@ -260,10 +240,14 @@ compaq_plasma_in(uint16_t addr, void *priv)
|
||||
|
||||
case 0x13c6:
|
||||
ret = self->port_13c6;
|
||||
#if 0
|
||||
if ((self->cga.cgamode & 0x28) == 0x00)
|
||||
ret |= 0x04;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x17c6:
|
||||
ret = 0xf6;
|
||||
ret = 0xe6;
|
||||
break;
|
||||
|
||||
case 0x1bc6:
|
||||
@@ -350,12 +334,16 @@ compaq_plasma_poll(void *priv)
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = (((self->port_23c6 >> 5) == 2) && (attr & 0x01) && !(attr & 0x06));
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
@@ -376,8 +364,13 @@ compaq_plasma_poll(void *priv)
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
blink = ((attr & 0x80) << 3) + 7 + 16;
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
@@ -385,12 +378,25 @@ compaq_plasma_poll(void *priv)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] ^= (amber ^ black);
|
||||
} else if ((self->port_23c6 >> 5) == 4) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
}
|
||||
@@ -412,13 +418,16 @@ compaq_plasma_poll(void *priv)
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = (((self->port_23c6 >> 5) == 2) && (attr & 0x01) && !(attr & 0x06));
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
@@ -439,22 +448,40 @@ compaq_plasma_poll(void *priv)
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
blink = ((attr & 0x80) << 3) + 7 + 16;
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (self->cga.sc == 7)) {
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1)
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] ^= (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] ^= (amber ^ black);
|
||||
}
|
||||
else if ((self->port_23c6 >> 5) == 4)
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
} else {
|
||||
@@ -493,6 +520,14 @@ compaq_plasma_poll(void *priv)
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
@@ -545,7 +580,7 @@ compaq_plasma_poll(void *priv)
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
/* ogc specific */
|
||||
/* Plasma specific */
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
@@ -622,7 +657,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
for (n = 0x11; n <= 0xFF; n++) {
|
||||
if ((n & 7) == 0)
|
||||
continue;
|
||||
if (self->attrmap & 4) { /* Inverse */
|
||||
if ((self->port_23c6 >> 5) == 1) { /* Inverse */
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
} else { /* Normal */
|
||||
@@ -635,7 +670,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
for (n = 0x01; n <= 0x0E; n++) {
|
||||
if (n == 7)
|
||||
continue;
|
||||
if (self->attrmap & 1) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = amber;
|
||||
@@ -678,11 +713,6 @@ compaq_plasma_init(UNUSED(const device_t *info))
|
||||
{
|
||||
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
|
||||
|
||||
if (compaq_machine_type == COMPAQ_PORTABLEIII)
|
||||
loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2);
|
||||
else
|
||||
loadfont_ex("roms/machines/portableiii/P.2 Combined.bin", 11, 0x4b49);
|
||||
|
||||
cga_init(&self->cga);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
|
||||
|
||||
@@ -691,24 +721,23 @@ compaq_plasma_init(UNUSED(const device_t *info))
|
||||
|
||||
self->cga.vram = malloc(0x8000);
|
||||
self->internal_monitor = 1;
|
||||
self->font_ram = malloc(0x2000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_set_callback(&self->cga.timer, compaq_plasma_poll);
|
||||
timer_set_p(&self->cga.timer, self);
|
||||
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000,
|
||||
compaq_plasma_read, NULL, NULL,
|
||||
compaq_plasma_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
}
|
||||
io_sethandler(0x03d0, 0x000c, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
|
||||
/* Default attribute mapping is 4 */
|
||||
self->attrmap = 4;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
|
||||
self->cga.cgastat = 0xf4;
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
@@ -725,6 +754,7 @@ compaq_plasma_close(void *priv)
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self->font_ram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user