Initial S3 ViRGE video overlay emulation.

This commit is contained in:
TomW 2014-06-13 18:43:25 +01:00
commit f1e1cc0b25
15 changed files with 381 additions and 28 deletions

View file

@ -130,6 +130,7 @@ void *ati18800_init()
svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
NULL,
ati18800_in, ati18800_out,
NULL,
NULL);
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);

View file

@ -151,6 +151,7 @@ void *ati28800_init()
svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/
ati28800_recalctimings,
ati28800_in, ati28800_out,
NULL,
NULL);
io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800);

View file

@ -2204,7 +2204,8 @@ void *mach64gx_init()
svga_init(&mach64->svga, mach64, 1 << 22, /*4mb*/
mach64_recalctimings,
mach64_in, mach64_out,
mach64_hwcursor_draw);
mach64_hwcursor_draw,
NULL);
rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (PCI)

View file

@ -824,7 +824,8 @@ void *gd5429_init()
svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/
gd5429_recalctimings,
gd5429_in, gd5429_out,
gd5429_hwcursor_draw);
gd5429_hwcursor_draw,
NULL);
mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL);
mem_mapping_set_p(&gd5429->svga.mapping, gd5429);

View file

@ -140,6 +140,7 @@ void *et4000_init()
svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
et4000_recalctimings,
et4000_in, et4000_out,
NULL,
NULL);
return et4000;

View file

@ -1016,7 +1016,8 @@ void *et4000w32p_init()
svga_init(&et4000->svga, et4000, 1 << 21, /*2mb*/
et4000w32p_recalctimings,
et4000w32p_in, et4000w32p_out,
et4000w32p_hwcursor_draw);
et4000w32p_hwcursor_draw,
NULL);
rom_init(&et4000->bios_rom, "roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (PCI)

View file

@ -123,6 +123,7 @@ void *oti067_common_init(char *bios_fn)
svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
oti067_recalctimings,
oti067_in, oti067_out,
NULL,
NULL);
io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);

View file

@ -264,6 +264,7 @@ void *paradise_pvga1a_init()
svga_init(&paradise->svga, paradise, 1 << 18, /*256kb*/
NULL,
paradise_in, paradise_out,
NULL,
NULL);
mem_mapping_set_handler(&paradise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL);
@ -294,6 +295,7 @@ void *paradise_wd90c11_init()
svga_init(&paradise->svga, paradise, 1 << 19, /*512kb*/
paradise_recalctimings,
paradise_in, paradise_out,
NULL,
NULL);
mem_mapping_set_handler(&paradise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL);

View file

@ -1881,7 +1881,8 @@ static void *s3_init(char *bios_fn)
svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
s3_recalctimings,
s3_in, s3_out,
s3_hwcursor_draw);
s3_hwcursor_draw,
NULL);
svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
svga->crtc[0x37] = 1 | (7 << 5);

View file

@ -123,15 +123,20 @@ typedef struct virge_t
uint32_t sec_fb0, sec_fb1;
uint32_t sec_stride;
uint32_t overlay_ctrl;
uint32_t k1_vert_scale;
uint32_t k2_vert_scale;
uint32_t dda_vert_accumulator;
int32_t k1_vert_scale;
int32_t k2_vert_scale;
int32_t dda_vert_accumulator;
int32_t k1_horiz_scale;
int32_t k2_horiz_scale;
int32_t dda_horiz_accumulator;
uint32_t fifo_ctrl;
uint32_t pri_start;
uint32_t pri_size;
uint32_t sec_start;
uint32_t sec_size;
int sdif;
int pri_x, pri_y, pri_w, pri_h;
int sec_x, sec_y, sec_w, sec_h;
} streams;
@ -224,14 +229,16 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
//return;
case 0x3d4:
svga->crtcreg = val & 0x7f;
svga->crtcreg = val;// & 0x7f;
return;
case 0x3d5:
// pclog("Write CRTC R%02X %02X\n", svga->crtcreg, val);
//pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, pc);
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80)
return;
if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
return;
if (svga->crtcreg >= 0x80)
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
switch (svga->crtcreg)
@ -350,7 +357,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
ret = svga->crtcreg;
break;
case 0x3D5:
// pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]);
//pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]);
switch (svga->crtcreg)
{
case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/
@ -391,7 +398,7 @@ static void s3_virge_recalctimings(svga_t *svga)
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
{
svga->ma_latch |= (virge->ma_ext << 16);
pclog("VGA mode\n");
//pclog("VGA mode\n");
if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
if (!svga->rowoffset) svga->rowoffset = 256;
@ -428,6 +435,7 @@ pclog("VGA mode\n");
{
svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
}
//pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal);
}
else /*Streams mode*/
{
@ -436,8 +444,21 @@ pclog("VGA mode\n");
else
svga->ma_latch = virge->streams.pri_fb0 >> 2;
svga->hdisp = virge->streams.pri_w;
pclog("Streams mode x_disp=%i\n", svga->hdisp);
svga->hdisp = virge->streams.pri_w + 1;
svga->dispend = virge->streams.pri_h;
svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x;
svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y;
svga->overlay.ysize = virge->streams.sec_h;
if (virge->streams.buffer_ctrl & 2)
svga->overlay.addr = virge->streams.sec_fb1;
else
svga->overlay.addr = virge->streams.sec_fb0;
svga->overlay.ena = (svga->overlay.x >= 0);
svga->overlay.v_acc = virge->streams.dda_vert_accumulator;
//pclog("Streams mode x_disp=%i dispend=%i vtotal=%i x=%i y=%i ysize=%i\n", svga->hdisp, svga->dispend, svga->vtotal, svga->overlay.x, svga->overlay.y, svga->overlay.ysize);
svga->rowoffset = virge->streams.pri_stride >> 3;
switch ((virge->streams.pri_ctrl >> 24) & 0x7)
@ -778,7 +799,7 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
virge_t *virge = (virge_t *)p;
svga_t *svga = &virge->svga;
reg_writes++;
// if ((addr & 0xfffc) >= 0x8000)
// if ((addr & 0xfffc) >= 0x8000 && (addr & 0xfffc) < 0x8400)
// pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, pc);
if ((addr & 0xfffc) < 0x8000)
@ -800,12 +821,22 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
break;
case 0x8190:
virge->streams.sec_ctrl = val;
virge->streams.dda_horiz_accumulator = val & 0xfff;
if (val & (1 << 11))
virge->streams.dda_horiz_accumulator |= 0xfffff800;
virge->streams.sdif = (val >> 24) & 7;
break;
case 0x8194:
virge->streams.chroma_upper_bound = val;
break;
case 0x8198:
virge->streams.sec_filter = val;
virge->streams.k1_horiz_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k1_horiz_scale |= 0xfffff800;
virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
if ((val >> 16) & (1 << 10))
virge->streams.k2_horiz_scale |= 0xfffff800;
break;
case 0x81a0:
virge->streams.blend_ctrl = val;
@ -832,24 +863,36 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
break;
case 0x81d0:
virge->streams.sec_fb0 = val;
s3_virge_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81d4:
virge->streams.sec_fb1 = val;
s3_virge_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81d8:
virge->streams.sec_stride = val;
s3_virge_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81dc:
virge->streams.overlay_ctrl = val;
break;
case 0x81e0:
virge->streams.k1_vert_scale = val;
virge->streams.k1_vert_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k1_vert_scale |= 0xfffff800;
break;
case 0x81e4:
virge->streams.k2_vert_scale = val;
virge->streams.k2_vert_scale = val & 0x7ff;
if (val & (1 << 10))
virge->streams.k2_vert_scale |= 0xfffff800;
break;
case 0x81e8:
virge->streams.dda_vert_accumulator = val;
virge->streams.dda_vert_accumulator = val & 0xfff;
if (val & (1 << 11))
virge->streams.dda_vert_accumulator |= 0xfffff800;
break;
case 0x81ec:
virge->streams.fifo_ctrl = val;
@ -872,11 +915,15 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
virge->streams.sec_start = val;
virge->streams.sec_x = (val >> 16) & 0x7ff;
virge->streams.sec_y = val & 0x7ff;
s3_virge_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81fc:
virge->streams.sec_size = val;
virge->streams.sec_w = (val >> 16) & 0x7ff;
virge->streams.sec_h = val & 0x7ff;
s3_virge_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0xa000: case 0xa004: case 0xa008: case 0xa00c:
@ -2547,6 +2594,279 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
}
}
#define DECODE_YCbCr() \
do \
{ \
int c; \
\
for (c = 0; c < 2; c++) \
{ \
uint8_t y1, y2; \
int8_t Cr, Cb; \
int dR, dG, dB; \
\
y1 = src[0]; \
Cr = src[1] - 0x80; \
y2 = src[2]; \
Cb = src[3] - 0x80; \
src += 4; \
\
dR = (359*Cr) >> 8; \
dG = (88*Cb + 183*Cr) >> 8; \
dB = (453*Cb) >> 8; \
\
r[x_write] = y1 + dR; \
CLAMP(r[x_write]); \
g[x_write] = y1 - dG; \
CLAMP(g[x_write]); \
b[x_write] = y1 + dB; \
CLAMP(b[x_write]); \
\
r[x_write+1] = y2 + dR; \
CLAMP(r[x_write+1]); \
g[x_write+1] = y2 - dG; \
CLAMP(g[x_write+1]); \
b[x_write+1] = y2 + dB; \
CLAMP(b[x_write+1]); \
\
x_write = (x_write + 2) & 7; \
} \
} while (0)
/*Both YUV formats are untested*/
#define DECODE_YUV211() \
do \
{ \
uint8_t y1, y2, y3, y4; \
int8_t U, V; \
int dR, dG, dB; \
\
U = src[0] - 0x80; \
y1 = (298 * (src[1] - 16)) >> 8; \
y2 = (298 * (src[2] - 16)) >> 8; \
V = src[3] - 0x80; \
y3 = (298 * (src[4] - 16)) >> 8; \
y4 = (298 * (src[5] - 16)) >> 8; \
src += 6; \
\
dR = (309*V) >> 8; \
dG = (100*U + 208*V) >> 8; \
dB = (516*U) >> 8; \
\
r[x_write] = y1 + dR; \
CLAMP(r[x_write]); \
g[x_write] = y1 - dG; \
CLAMP(g[x_write]); \
b[x_write] = y1 + dB; \
CLAMP(b[x_write]); \
\
r[x_write+1] = y2 + dR; \
CLAMP(r[x_write+1]); \
g[x_write+1] = y2 - dG; \
CLAMP(g[x_write+1]); \
b[x_write+1] = y2 + dB; \
CLAMP(b[x_write+1]); \
\
r[x_write+2] = y2 + dR; \
CLAMP(r[x_write+2]); \
g[x_write+2] = y2 - dG; \
CLAMP(g[x_write+2]); \
b[x_write+2] = y2 + dB; \
CLAMP(b[x_write+2]); \
\
r[x_write+3] = y2 + dR; \
CLAMP(r[x_write+3]); \
g[x_write+3] = y2 - dG; \
CLAMP(g[x_write+3]); \
b[x_write+3] = y2 + dB; \
CLAMP(b[x_write+3]); \
\
x_write = (x_write + 4) & 7; \
} while (0)
#define DECODE_YUV422() \
do \
{ \
int c; \
\
for (c = 0; c < 2; c++) \
{ \
uint8_t y1, y2; \
int8_t U, V; \
int dR, dG, dB; \
\
U = src[0] - 0x80; \
y1 = (298 * (src[1] - 16)) >> 8; \
V = src[2] - 0x80; \
y2 = (298 * (src[3] - 16)) >> 8; \
src += 4; \
\
dR = (309*V) >> 8; \
dG = (100*U + 208*V) >> 8; \
dB = (516*U) >> 8; \
\
r[x_write] = y1 + dR; \
CLAMP(r[x_write]); \
g[x_write] = y1 - dG; \
CLAMP(g[x_write]); \
b[x_write] = y1 + dB; \
CLAMP(b[x_write]); \
\
r[x_write+1] = y2 + dR; \
CLAMP(r[x_write+1]); \
g[x_write+1] = y2 - dG; \
CLAMP(g[x_write+1]); \
b[x_write+1] = y2 + dB; \
CLAMP(b[x_write+1]); \
\
x_write = (x_write + 2) & 7; \
} \
} while (0)
#define DECODE_RGB555() \
do \
{ \
int c; \
\
for (c = 0; c < 4; c++) \
{ \
uint16_t dat; \
\
dat = *(uint16_t *)src; \
src += 2; \
\
r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \
g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \
b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \
} \
x_write = (x_write + 4) & 7; \
} while (0)
#define DECODE_RGB565() \
do \
{ \
int c; \
\
for (c = 0; c < 4; c++) \
{ \
uint16_t dat; \
\
dat = *(uint16_t *)src; \
src += 2; \
\
r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \
g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \
b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \
} \
x_write = (x_write + 4) & 7; \
} while (0)
#define DECODE_RGB888() \
do \
{ \
int c; \
\
for (c = 0; c < 4; c++) \
{ \
r[x_write + c] = src[0]; \
g[x_write + c] = src[1]; \
b[x_write + c] = src[2]; \
src += 3; \
} \
x_write = (x_write + 4) & 7; \
} while (0)
#define DECODE_XRGB8888() \
do \
{ \
int c; \
\
for (c = 0; c < 4; c++) \
{ \
r[x_write + c] = src[0]; \
g[x_write + c] = src[1]; \
b[x_write + c] = src[2]; \
src += 4; \
} \
x_write = (x_write + 4) & 7; \
} while (0)
#define OVERLAY_SAMPLE() \
do \
{ \
switch (virge->streams.sdif) \
{ \
case 1: \
DECODE_YCbCr(); \
break; \
case 2: \
DECODE_YUV422(); \
break; \
case 3: \
DECODE_RGB555(); \
break; \
case 4: \
DECODE_YUV211(); \
break; \
case 5: \
DECODE_RGB565(); \
break; \
case 6: \
DECODE_RGB888(); \
break; \
case 7: \
default: \
DECODE_XRGB8888(); \
break; \
} \
} while (0)
static void s3_virge_overlay_draw(svga_t *svga, int displine)
{
virge_t *virge = (virge_t *)svga->p;
int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1;
int h_acc = virge->streams.dda_horiz_accumulator;
int r[8], g[8], b[8];
int r_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int g_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int b_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int x_size, x_read = 4, x_write = 4;
int x;
uint32_t *p;
uint8_t *src = &svga->vram[svga->overlay_latch.addr];
p = &((uint32_t *)buffer32->line[displine])[offset + 32];
if ((offset + virge->streams.sec_w) > virge->streams.pri_w)
x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1;
else
x_size = virge->streams.sec_w + 1;
OVERLAY_SAMPLE();
for (x = 0; x < x_size; x++)
{
*p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16);
h_acc += virge->streams.k1_horiz_scale;
if (h_acc >= 0)
{
if ((x_read ^ (x_read + 1)) & ~3)
OVERLAY_SAMPLE();
x_read = (x_read + 1) & 7;
h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale);
}
}
svga->overlay_latch.v_acc += virge->streams.k1_vert_scale;
if (svga->overlay_latch.v_acc >= 0)
{
svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale);
svga->overlay_latch.addr += virge->streams.sec_stride;
}
}
static uint8_t s3_virge_pci_read(int func, int addr, void *p)
{
virge_t *virge = (virge_t *)p;
@ -2658,7 +2978,8 @@ static void *s3_virge_init()
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
s3_virge_recalctimings,
s3_virge_in, s3_virge_out,
s3_virge_hwcursor_draw);
s3_virge_hwcursor_draw,
s3_virge_overlay_draw);
rom_init(&virge->bios_rom, "roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (PCI)
@ -2728,7 +3049,8 @@ static void *s3_virge_375_init()
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
s3_virge_recalctimings,
s3_virge_in, s3_virge_out,
s3_virge_hwcursor_draw);
s3_virge_hwcursor_draw,
s3_virge_overlay_draw);
rom_init(&virge->bios_rom, "roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (PCI)

View file

@ -400,7 +400,11 @@ void svga_poll(void *p)
{
// if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount());
if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena)
svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff;
svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff;
if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena)
svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff;
svga->vidtime += svga->dispofftime;
// if (output) printf("Display off %f\n",vidtime);
svga->cgastat |= 1;
@ -414,11 +418,17 @@ void svga_poll(void *p)
if (svga->firstline == 2000)
svga->firstline = svga->displine;
if (svga->hwcursor_on)
if (svga->hwcursor_on || svga->overlay_on)
svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = 2;
svga->render(svga);
if (svga->overlay_on)
{
svga->overlay_draw(svga, svga->displine);
svga->overlay_on--;
}
if (svga->hwcursor_on)
{
svga->hwcursor_draw(svga, svga->displine);
@ -594,6 +604,9 @@ void svga_poll(void *p)
svga->hwcursor_on = 0;
svga->hwcursor_latch = svga->hwcursor;
svga->overlay_on = 0;
svga->overlay_latch = svga->overlay;
// pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr);
// pclog("ADDR %08X\n",hwcursor_addr);
@ -609,7 +622,8 @@ int svga_init(svga_t *svga, void *p, int memsize,
void (*recalctimings_ex)(struct svga_t *svga),
uint8_t (*video_in) (uint16_t addr, void *p),
void (*video_out)(uint16_t addr, uint8_t val, void *p),
void (*hwcursor_draw)(struct svga_t *svga, int displine))
void (*hwcursor_draw)(struct svga_t *svga, int displine),
void (*overlay_draw)(struct svga_t *svga, int displine))
{
int c, d, e;
@ -639,6 +653,7 @@ int svga_init(svga_t *svga, void *p, int memsize,
svga->video_in = video_in;
svga->video_out = video_out;
svga->hwcursor_draw = hwcursor_draw;
svga->overlay_draw = overlay_draw;
// _svga_recalctimings(svga);
mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga);

View file

@ -82,10 +82,13 @@ typedef struct svga_t
int ena;
int x, y;
int xoff, yoff;
int ysize;
uint32_t addr;
} hwcursor, hwcursor_latch;
int v_acc, h_acc;
} hwcursor, hwcursor_latch, overlay, overlay_latch;
int hwcursor_on;
int overlay_on;
void (*render)(struct svga_t *svga);
void (*recalctimings_ex)(struct svga_t *svga);
@ -94,6 +97,8 @@ typedef struct svga_t
uint8_t (*video_in) (uint16_t addr, void *p);
void (*hwcursor_draw)(struct svga_t *svga, int displine);
void (*overlay_draw)(struct svga_t *svga, int displine);
void *p;
} svga_t;
@ -102,13 +107,11 @@ extern int svga_init(svga_t *svga, void *p, int memsize,
void (*recalctimings_ex)(struct svga_t *svga),
uint8_t (*video_in) (uint16_t addr, void *p),
void (*video_out)(uint16_t addr, uint8_t val, void *p),
void (*hwcursor_draw)(struct svga_t *svga, int displine));
void (*hwcursor_draw)(struct svga_t *svga, int displine),
void (*overlay_draw)(struct svga_t *svga, int displine));
extern void svga_recalctimings(svga_t *svga);
extern int svga_hwcursor_on;
extern void (*svga_hwcursor_draw)(int displine);
uint8_t svga_read(uint32_t addr, void *p);
uint16_t svga_readw(uint32_t addr, void *p);
uint32_t svga_readl(uint32_t addr, void *p);

View file

@ -475,7 +475,8 @@ void *tgui9440_init()
svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/
tgui_recalctimings,
tgui_in, tgui_out,
tgui_hwcursor_draw);
tgui_hwcursor_draw,
NULL);
mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &tgui->svga);
mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui);

View file

@ -252,6 +252,7 @@ void *tvga8900d_init()
svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
tvga_recalctimings,
tvga_in, tvga_out,
NULL,
NULL);
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);

View file

@ -86,6 +86,7 @@ void *vga_init()
svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
NULL,
vga_in, vga_out,
NULL,
NULL);
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);