WIP Plasma code

This commit is contained in:
TC1995
2025-05-17 05:28:45 +02:00
parent 1eb4355d76
commit b97a23aa57

View File

@@ -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
@@ -160,14 +152,31 @@ compaq_plasma_read(uint32_t addr, void *priv)
}
static void
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
compaq_plasma_font_write(uint32_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;
}
addr &= 0x1fff;
self->font_ram[addr] = val;
}
static uint8_t
compaq_plasma_font_read(uint32_t addr, void *priv)
{
compaq_plasma_t *self = (compaq_plasma_t *) priv;
uint8_t ret = 0x00;
addr &= 0x1fff;
ret = self->font_ram[addr];
return ret;
}
static void
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
{
compaq_plasma_t *self = (compaq_plasma_t *) priv;
switch (addr) {
/* Emulated CRTC, register select */
@@ -183,21 +192,11 @@ 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;
@@ -208,10 +207,15 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
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);
pclog("Write 23c6=%02x.\n", val);
if (val & 0x08) { /* Disable internal CGA */
mem_mapping_disable(&self->cga.mapping);
mem_mapping_enable(&self->font_ram_mapping);
} else {
mem_mapping_enable(&self->cga.mapping);
mem_mapping_disable(&self->font_ram_mapping);
}
compaq_plasma_recalcattrs(self);
break;
case 0x27c6:
@@ -229,11 +233,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 +245,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 +254,16 @@ 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
pclog("Read 13c6=%02x, mode=%02x.\n", ret, self->cga.cgamode);
break;
case 0x17c6:
ret = 0xf6;
ret = 0xe6;
pclog("Read 17c6=%02x, mode=%02x.\n", ret, self->cga.cgamode);
break;
case 0x1bc6:
@@ -272,6 +272,7 @@ compaq_plasma_in(uint16_t addr, void *priv)
case 0x23c6:
ret = self->port_23c6;
pclog("Read 23c6=%02x.\n", ret);
break;
case 0x27c6:
@@ -350,12 +351,15 @@ 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;
}
/* 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 |= ((self->port_23c6 >> 5) == 2) && (attr & 0x03);
if (underline) {
/* set forecolor to white */
attr = attr | 0x7;
@@ -376,8 +380,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) && (attr & 0x03))
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 +394,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 (attr & 0x03) {
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 +434,15 @@ 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;
}
/* 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 |= ((self->port_23c6 >> 5) == 2) && (attr & 0x03);
if (underline) {
/* set forecolor to white */
attr = attr | 0x7;
@@ -439,22 +463,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) && (attr & 0x03))
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 (attr & 0x03) {
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 +535,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 +595,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 +672,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 +685,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 +728,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 +736,21 @@ 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->font_ram_mapping, 0xb8000, 0x02000, compaq_plasma_font_read, NULL, NULL, compaq_plasma_font_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 +767,7 @@ compaq_plasma_close(void *priv)
compaq_plasma_t *self = (compaq_plasma_t *) priv;
free(self->cga.vram);
free(self->font_ram);
free(self);
}