diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index fa40d74..85eab70 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -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); diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index b68e5d2..e64c5dc 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -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); diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 8fb7802..e41241e 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -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) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 1e97404..7a661af 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -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); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index e6dd38d..50c79c3 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -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; diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 5a0d1d6..4e92448 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -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) diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 939d2fa..6064298 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -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); diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 5d75a99..5ff7de0 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -264,6 +264,7 @@ void *paradise_pvga1a_init() svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/ NULL, paradise_in, paradise_out, + NULL, NULL); mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL); @@ -294,6 +295,7 @@ void *paradise_wd90c11_init() svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/ paradise_recalctimings, paradise_in, paradise_out, + NULL, NULL); mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL); diff --git a/src/vid_s3.c b/src/vid_s3.c index 92c13d9..847d47b 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -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); diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index b9e4cc8..0126b9b 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -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) diff --git a/src/vid_svga.c b/src/vid_svga.c index 9a13efc..b6067e8 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -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); diff --git a/src/vid_svga.h b/src/vid_svga.h index 209502e..a13ab20 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -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); diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 545235f..d2b44cb 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -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); diff --git a/src/vid_tvga.c b/src/vid_tvga.c index a6c91e7..9c6d752 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -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); diff --git a/src/vid_vga.c b/src/vid_vga.c index 830fc21..7fb2429 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -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);