CGA changes by anikom15.

This commit is contained in:
OBattler
2023-08-09 18:10:05 +02:00
parent 20e41065a4
commit 1a0bebaf4e

View File

@@ -12,9 +12,11 @@
* *
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/> * Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* W. M. Martinez, <anikom15@outlook.com>
* *
* Copyright 2008-2019 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca. * Copyright 2016-2019 Miran Grca.
* Copyright 2023 W. M. Martinez
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
@@ -33,7 +35,6 @@
#include <86box/video.h> #include <86box/video.h>
#include <86box/vid_cga.h> #include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h> #include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
#define CGA_RGB 0 #define CGA_RGB 0
#define CGA_COMPOSITE 1 #define CGA_COMPOSITE 1
@@ -51,9 +52,9 @@ static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w
void cga_recalctimings(cga_t *cga); void cga_recalctimings(cga_t *cga);
void void
cga_out(uint16_t addr, uint8_t val, void *priv) cga_out(uint16_t addr, uint8_t val, void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
uint8_t old; uint8_t old;
if ((addr >= 0x3d0) && (addr <= 0x3d7)) if ((addr >= 0x3d0) && (addr <= 0x3d7))
@@ -90,16 +91,13 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
if (old ^ val) if (old ^ val)
cga_recalctimings(cga); cga_recalctimings(cga);
return; return;
default:
break;
} }
} }
uint8_t uint8_t
cga_in(uint16_t addr, void *priv) cga_in(uint16_t addr, void *p)
{ {
const cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
uint8_t ret = 0xff; uint8_t ret = 0xff;
@@ -116,32 +114,29 @@ cga_in(uint16_t addr, void *priv)
case 0x3DA: case 0x3DA:
ret = cga->cgastat; ret = cga->cgastat;
break; break;
default:
break;
} }
return ret; return ret;
} }
void void
cga_pravetz_out(UNUSED(uint16_t addr), uint8_t val, void *priv) cga_pravetz_out(uint16_t addr, uint8_t val, void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
cga->fontbase = (((unsigned int) val) << 8); cga->fontbase = (((unsigned int) val) << 8);
} }
uint8_t uint8_t
cga_pravetz_in(UNUSED(uint16_t addr), void *priv) cga_pravetz_in(uint16_t addr, void *p)
{ {
const cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
return (cga->fontbase >> 8); return (cga->fontbase >> 8);
} }
void void
cga_waitstates(UNUSED(void *priv)) cga_waitstates(void *p)
{ {
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
int ws; int ws;
@@ -151,9 +146,9 @@ cga_waitstates(UNUSED(void *priv))
} }
void void
cga_write(uint32_t addr, uint8_t val, void *priv) cga_write(uint32_t addr, uint8_t val, void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
cga->vram[addr & 0x3fff] = val; cga->vram[addr & 0x3fff] = val;
if (cga->snow_enabled) { if (cga->snow_enabled) {
@@ -165,9 +160,9 @@ cga_write(uint32_t addr, uint8_t val, void *priv)
} }
uint8_t uint8_t
cga_read(uint32_t addr, void *priv) cga_read(uint32_t addr, void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
cga_waitstates(cga); cga_waitstates(cga);
if (cga->snow_enabled) { if (cga->snow_enabled) {
@@ -182,8 +177,7 @@ void
cga_recalctimings(cga_t *cga) cga_recalctimings(cga_t *cga)
{ {
double disptime; double disptime;
double _dispontime; double _dispontime, _dispofftime;
double _dispofftime;
if (cga->cgamode & 1) { if (cga->cgamode & 1) {
disptime = (double) (cga->crtc[0] + 1); disptime = (double) (cga->crtc[0] + 1);
@@ -200,18 +194,14 @@ cga_recalctimings(cga_t *cga)
} }
void void
cga_poll(void *priv) cga_poll(void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
int drawcursor; int drawcursor;
int x; int x, c, xs_temp, ys_temp;
int c;
int xs_temp;
int ys_temp;
int oldvc; int oldvc;
uint8_t chr; uint8_t chr, attr;
uint8_t attr;
uint8_t border; uint8_t border;
uint16_t dat; uint16_t dat;
int cols[4]; int cols[4];
@@ -231,21 +221,21 @@ cga_poll(void *priv)
video_wait_for_buffer(); video_wait_for_buffer();
} }
cga->lastline = cga->displine; cga->lastline = cga->displine;
for (c = 0; c < 8; c++) { if ((cga->cgamode & 0x12) == 0x12) {
if ((cga->cgamode & 0x12) == 0x12) { for (c = 0; c < 8; ++c) {
buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0; buffer32->line[cga->displine][c] = 0;
if (cga->cgamode & 1) { if (cga->cgamode & 1)
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0; buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0;
} else { else
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0; buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0;
} }
} else { } else {
buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16; for (c = 0; c < 8; ++c) {
if (cga->cgamode & 1) { buffer32->line[cga->displine][c] = (cga->cgacol & 15) + 16;
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; if (cga->cgamode & 1)
} else { buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; else
} buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
} }
} }
if (cga->cgamode & 1) { if (cga->cgamode & 1) {
@@ -265,11 +255,11 @@ cga_poll(void *priv)
cols[0] = (attr >> 4) + 16; cols[0] = (attr >> 4) + 16;
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} }
} else { } else {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
} }
} }
cga->ma++; cga->ma++;
@@ -277,8 +267,8 @@ cga_poll(void *priv)
} else if (!(cga->cgamode & 2)) { } else if (!(cga->cgamode & 2)) {
for (x = 0; x < cga->crtc[1]; x++) { for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) { if (cga->cgamode & 8) {
chr = cga->vram[(cga->ma << 1) & 0x3fff]; chr = cga->vram[((cga->ma << 1) & 0x3fff)];
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
} else } else
chr = attr = 0; chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
@@ -292,11 +282,15 @@ cga_poll(void *priv)
cga->ma++; cga->ma++;
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; buffer32->line[cga->displine][(x << 4) + (c << 1) + 8]
= buffer32->line[cga->displine][(x << 4) + (c << 1) + 9]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} }
} else { } else {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; buffer32->line[cga->displine][(x << 4) + (c << 1) + 8]
= buffer32->line[cga->displine][(x << 4) + (c << 1) + 9]
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
} }
} }
} }
@@ -323,7 +317,9 @@ cga_poll(void *priv)
dat = 0; dat = 0;
cga->ma++; cga->ma++;
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; buffer32->line[cga->displine][(x << 4) + (c << 1) + 8]
= buffer32->line[cga->displine][(x << 4) + (c << 1) + 9]
= cols[dat >> 14];
dat <<= 2; dat <<= 2;
} }
} }
@@ -337,7 +333,7 @@ cga_poll(void *priv)
dat = 0; dat = 0;
cga->ma++; cga->ma++;
for (c = 0; c < 16; c++) { for (c = 0; c < 16; c++) {
buffer32->line[cga->displine << 1][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; buffer32->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15];
dat <<= 1; dat <<= 1;
} }
} }
@@ -345,11 +341,9 @@ cga_poll(void *priv)
} else { } else {
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
if (cga->cgamode & 1) { if (cga->cgamode & 1) {
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]); hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]);
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
} else { } else {
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]); hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]);
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
} }
} }
@@ -361,11 +355,9 @@ cga_poll(void *priv)
if (cga->composite) { if (cga->composite) {
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine << 1]); Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine]);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]);
} else { } else {
video_process_8(x, cga->displine << 1); video_process_8(x, cga->displine);
video_process_8(x, (cga->displine << 1) + 1);
} }
cga->sc = oldsc; cga->sc = oldsc;
@@ -440,31 +432,31 @@ cga_poll(void *priv)
cga->lastline++; cga->lastline++;
xs_temp = x; xs_temp = x;
ys_temp = (cga->lastline - cga->firstline) << 1; ys_temp = cga->lastline - cga->firstline;
if ((xs_temp > 0) && (ys_temp > 0)) { if ((xs_temp > 0) && (ys_temp > 0)) {
if (xs_temp < 64) if (xs_temp < 64)
xs_temp = 656; xs_temp = 656;
if (ys_temp < 32) if (ys_temp < 32)
ys_temp = 400; ys_temp = 200;
if (!enable_overscan) if (!enable_overscan)
xs_temp -= 16; xs_temp -= 16;
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
xsize = xs_temp; xsize = xs_temp;
ysize = ys_temp; ysize = ys_temp;
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0));
if (video_force_resize_get()) if (video_force_resize_get())
video_force_resize_set(0); video_force_resize_set(0);
} }
if (enable_overscan) { if (enable_overscan) {
video_blit_memtoscreen(0, (cga->firstline - 4) << 1, video_blit_memtoscreen(0, cga->firstline - 4,
xsize, ((cga->lastline - cga->firstline) + 8) << 1); xsize, (cga->lastline - cga->firstline) + 8);
} else { } else {
video_blit_memtoscreen(8, cga->firstline << 1, video_blit_memtoscreen(8, cga->firstline,
xsize, (cga->lastline - cga->firstline) << 1); xsize, cga->lastline - cga->firstline);
} }
} }
@@ -498,11 +490,11 @@ cga_poll(void *priv)
} }
if (cga->cgadispon) if (cga->cgadispon)
cga->cgastat &= ~1; cga->cgastat &= ~1;
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))) if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
cga->con = 1; cga->con = 1;
if (cga->cgadispon && (cga->cgamode & 1)) { if (cga->cgadispon && (cga->cgamode & 1)) {
for (x = 0; x < (cga->crtc[1] << 1); x++) for (x = 0; x < (cga->crtc[1] << 1); x++)
cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff]; cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)];
} }
} }
} }
@@ -515,7 +507,7 @@ cga_init(cga_t *cga)
} }
void * void *
cga_standalone_init(UNUSED(const device_t *info)) cga_standalone_init(const device_t *info)
{ {
int display_type; int display_type;
cga_t *cga = malloc(sizeof(cga_t)); cga_t *cga = malloc(sizeof(cga_t));
@@ -561,18 +553,18 @@ cga_pravetz_init(const device_t *info)
} }
void void
cga_close(void *priv) cga_close(void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
free(cga->vram); free(cga->vram);
free(cga); free(cga);
} }
void void
cga_speed_changed(void *priv) cga_speed_changed(void *p)
{ {
cga_t *cga = (cga_t *) priv; cga_t *cga = (cga_t *) p;
cga_recalctimings(cga); cga_recalctimings(cga);
} }