vid_ega: Extend 4bpp renderer to handle CGA 2bpp chunky graphics; Remove 2bpp renderer
This also lets planes 2 and 3 be used.
This commit is contained in:
@@ -113,6 +113,7 @@ extern int con, cursoron, cgablink;
|
|||||||
extern int scrollcache;
|
extern int scrollcache;
|
||||||
|
|
||||||
extern uint8_t edatlookup[4][4];
|
extern uint8_t edatlookup[4][4];
|
||||||
|
extern uint8_t egaremap2bpp[256];
|
||||||
|
|
||||||
#if defined(EMU_MEM_H) && defined(EMU_ROM_H)
|
#if defined(EMU_MEM_H) && defined(EMU_ROM_H)
|
||||||
void ega_render_blank(ega_t *ega);
|
void ega_render_blank(ega_t *ega);
|
||||||
@@ -123,10 +124,7 @@ void ega_render_overscan_right(ega_t *ega);
|
|||||||
void ega_render_text_40(ega_t *ega);
|
void ega_render_text_40(ega_t *ega);
|
||||||
void ega_render_text_80(ega_t *ega);
|
void ega_render_text_80(ega_t *ega);
|
||||||
|
|
||||||
void ega_render_2bpp_lowres(ega_t *ega);
|
void ega_render_graphics(ega_t *ega);
|
||||||
void ega_render_2bpp_highres(ega_t *ega);
|
|
||||||
|
|
||||||
void ega_render_4bpp(ega_t *ega);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*VIDEO_EGA_H*/
|
#endif /*VIDEO_EGA_H*/
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static uint8_t ega_rotate[8][256];
|
|||||||
static uint32_t pallook16[256], pallook64[256];
|
static uint32_t pallook16[256], pallook64[256];
|
||||||
static int ega_type = 0, old_overscan_color = 0;
|
static int ega_type = 0, old_overscan_color = 0;
|
||||||
|
|
||||||
extern uint8_t edatlookup[4][4];
|
uint8_t egaremap2bpp[256];
|
||||||
|
|
||||||
/* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour):
|
/* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour):
|
||||||
7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */
|
7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */
|
||||||
@@ -419,19 +419,8 @@ ega_recalctimings(ega_t *ega)
|
|||||||
ega->hdisp_old = ega->hdisp;
|
ega->hdisp_old = ega->hdisp;
|
||||||
} else {
|
} else {
|
||||||
ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8;
|
ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8;
|
||||||
|
ega->render = ega_render_graphics;
|
||||||
ega->hdisp_old = ega->hdisp;
|
ega->hdisp_old = ega->hdisp;
|
||||||
|
|
||||||
switch (ega->gdcreg[5] & 0x20) {
|
|
||||||
case 0x00:
|
|
||||||
ega->render = ega_render_4bpp;
|
|
||||||
break;
|
|
||||||
case 0x20:
|
|
||||||
if (ega->seqregs[1] & 8)
|
|
||||||
ega->render = ega_render_2bpp_lowres;
|
|
||||||
else
|
|
||||||
ega->render = ega_render_2bpp_highres;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,6 +1049,18 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (c = 0; c < 256; c++) {
|
||||||
|
egaremap2bpp[c] = 0;
|
||||||
|
if (c & 0x01)
|
||||||
|
egaremap2bpp[c] |= 0x01;
|
||||||
|
if (c & 0x04)
|
||||||
|
egaremap2bpp[c] |= 0x02;
|
||||||
|
if (c & 0x10)
|
||||||
|
egaremap2bpp[c] |= 0x04;
|
||||||
|
if (c & 0x40)
|
||||||
|
egaremap2bpp[c] |= 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_mono) {
|
if (is_mono) {
|
||||||
for (c = 0; c < 256; c++) {
|
for (c = 0; c < 256; c++) {
|
||||||
if (((c >> 3) & 3) == 0)
|
if (((c >> 3) & 3) == 0)
|
||||||
|
|||||||
@@ -247,95 +247,7 @@ ega_render_text_80(ega_t *ega)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ega_render_2bpp_lowres(ega_t *ega)
|
ega_render_graphics(ega_t *ega)
|
||||||
{
|
|
||||||
int x;
|
|
||||||
uint8_t dat[2];
|
|
||||||
uint32_t addr, *p;
|
|
||||||
|
|
||||||
if ((ega->displine + ega->y_add) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
|
||||||
|
|
||||||
if (ega->firstline_draw == 2000)
|
|
||||||
ega->firstline_draw = ega->displine;
|
|
||||||
ega->lastline_draw = ega->displine;
|
|
||||||
|
|
||||||
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
|
|
||||||
addr = ega->remap_func(ega, ega->ma);
|
|
||||||
|
|
||||||
dat[0] = ega->vram[addr];
|
|
||||||
dat[1] = ega->vram[addr | 0x1];
|
|
||||||
if (ega->seqregs[1] & 4)
|
|
||||||
ega->ma += 2;
|
|
||||||
else
|
|
||||||
ega->ma += 4;
|
|
||||||
|
|
||||||
ega->ma &= ega->vrammask;
|
|
||||||
|
|
||||||
if (ega->crtc[0x17] & 0x80) {
|
|
||||||
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
|
|
||||||
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
|
|
||||||
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
|
|
||||||
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
|
|
||||||
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
|
|
||||||
p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
|
|
||||||
p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
|
|
||||||
p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]];
|
|
||||||
} else
|
|
||||||
memset(p, 0x00, 16 * sizeof(uint32_t));
|
|
||||||
|
|
||||||
p += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ega_render_2bpp_highres(ega_t *ega)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
uint8_t dat[2];
|
|
||||||
uint32_t addr, *p;
|
|
||||||
|
|
||||||
if ((ega->displine + ega->y_add) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
|
||||||
|
|
||||||
if (ega->firstline_draw == 2000)
|
|
||||||
ega->firstline_draw = ega->displine;
|
|
||||||
ega->lastline_draw = ega->displine;
|
|
||||||
|
|
||||||
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
|
|
||||||
addr = ega->remap_func(ega, ega->ma);
|
|
||||||
|
|
||||||
dat[0] = ega->vram[addr];
|
|
||||||
dat[1] = ega->vram[addr | 0x1];
|
|
||||||
if (ega->seqregs[1] & 4)
|
|
||||||
ega->ma += 2;
|
|
||||||
else
|
|
||||||
ega->ma += 4;
|
|
||||||
|
|
||||||
ega->ma &= ega->vrammask;
|
|
||||||
|
|
||||||
if (ega->crtc[0x17] & 0x80) {
|
|
||||||
p[0] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
|
|
||||||
p[1] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
|
|
||||||
p[2] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
|
|
||||||
p[3] = ega->pallook[ega->egapal[dat[0] & 3]];
|
|
||||||
p[4] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
|
|
||||||
p[5] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
|
|
||||||
p[6] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
|
|
||||||
p[7] = ega->pallook[ega->egapal[dat[1] & 3]];
|
|
||||||
} else
|
|
||||||
memset(p, 0x00, 8 * sizeof(uint32_t));
|
|
||||||
|
|
||||||
p += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ega_render_4bpp(ega_t *ega)
|
|
||||||
{
|
{
|
||||||
if ((ega->displine + ega->y_add) < 0)
|
if ((ega->displine + ega->y_add) < 0)
|
||||||
return;
|
return;
|
||||||
@@ -347,6 +259,7 @@ ega_render_4bpp(ega_t *ega)
|
|||||||
ega->lastline_draw = ega->displine;
|
ega->lastline_draw = ega->displine;
|
||||||
|
|
||||||
const bool doublewidth = ((ega->seqregs[1] & 8) != 0);
|
const bool doublewidth = ((ega->seqregs[1] & 8) != 0);
|
||||||
|
const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0);
|
||||||
const int dotwidth = (doublewidth ? 2 : 1);
|
const int dotwidth = (doublewidth ? 2 : 1);
|
||||||
const int charwidth = dotwidth*8;
|
const int charwidth = dotwidth*8;
|
||||||
int secondcclk = 0;
|
int secondcclk = 0;
|
||||||
@@ -369,6 +282,18 @@ ega_render_4bpp(ega_t *ega)
|
|||||||
}
|
}
|
||||||
ega->ma &= 0x3ffff;
|
ega->ma &= 0x3ffff;
|
||||||
|
|
||||||
|
if (cga2bpp) {
|
||||||
|
// Remap CGA 2bpp-chunky data into fully planar data
|
||||||
|
uint8_t dat0 = egaremap2bpp[edat[1] ] | (egaremap2bpp[edat[0] ] << 4);
|
||||||
|
uint8_t dat1 = egaremap2bpp[edat[1]>>1] | (egaremap2bpp[edat[0]>>1] << 4);
|
||||||
|
uint8_t dat2 = egaremap2bpp[edat[3] ] | (egaremap2bpp[edat[2] ] << 4);
|
||||||
|
uint8_t dat3 = egaremap2bpp[edat[3]>>1] | (egaremap2bpp[edat[2]>>1] << 4);
|
||||||
|
edat[0] = dat0;
|
||||||
|
edat[1] = dat1;
|
||||||
|
edat[2] = dat2;
|
||||||
|
edat[3] = dat3;
|
||||||
|
}
|
||||||
|
|
||||||
if (ega->crtc[0x17] & 0x80) {
|
if (ega->crtc[0x17] & 0x80) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
const int outoffs = i*(dotwidth<<1);
|
const int outoffs = i*(dotwidth<<1);
|
||||||
|
|||||||
Reference in New Issue
Block a user