From 25fdf5163764f8c2b79c29b4881f61091842bd63 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 17 Nov 2022 17:37:11 +0100 Subject: [PATCH] S3 80x: added 0xe2e8/0xe2e9 ports in MMIO mode, fixes garbled fonts when using MMIO in those chips. S3 (all): Fixes to the commonly used accel commands (0, 1, 2, 6, 7) to make the OS/2 software cursor to not bug on the left edge of the screen. TGUI: Reworked the non-bitblt commands as well as the accel pitch and bpp modes. --- src/video/vid_s3.c | 140 +++++----- src/video/vid_tgui9440.c | 554 ++++++++++++++++++++------------------- 2 files changed, 351 insertions(+), 343 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e5e824400..bdc982502 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -876,12 +876,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1414,12 +1417,15 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1687,8 +1693,15 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } } else { if (addr & 0x8000) { - s3_accel_out_fifo(s3, addr & 0xffff, val); + if ((addr == 0xe2e8) || (addr == 0xe2e9)) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) + goto mmio_byte_write; + else + s3_accel_out_fifo(s3, addr & 0xffff, val); + } else + s3_accel_out_fifo(s3, addr & 0xffff, val); } else { +mmio_byte_write: if (s3->accel.cmd & 0x100) { if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -1740,8 +1753,8 @@ s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) if (addr == 0x811c) s3_accel_out_fifo_w(s3, 0x9ee8, val); else { - if (addr == 0xe2e8 || addr == 0xe2ea) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + if ((addr == 0xe2e8) || (addr == 0xe2ea)) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) s3_accel_out_pixtrans_w(s3, val); else { s3_accel_write_fifo(s3, addr, val); @@ -3142,8 +3155,12 @@ s3_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; if (s3->chip != S3_VISION868) { if (s3->chip == S3_86C928) { - if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; + if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) { + if ((s3->width != 1600) && (svga->dispend == 1024) && (svga->hdisp != 1280)) + svga->hdisp <<= 2; + else + svga->hdisp <<= 1; + } } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; @@ -3554,9 +3571,8 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); else mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } else { - mem_mapping_enable(&s3->mmio_mapping); } + mem_mapping_enable(&s3->mmio_mapping); } else { mem_mapping_disable(&s3->mmio_mapping); } @@ -6214,12 +6230,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -6434,23 +6453,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { - s3->accel.cy |= ~0xfff; - } - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -6659,43 +6670,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; + s3->accel.dx = s3->accel.destx_distp & 0x7ff; + if (s3->accel.destx_distp & 0x800) s3->accel.dx |= ~0x7ff; + s3->accel.dy = s3->accel.desty_axstp & 0x7ff; + if (s3->accel.desty_axstp & 0x800) s3->accel.dy |= ~0x7ff; - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.destx_distp >= 0xfffff000) { /* avoid overflow */ - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bitres > 0xfff) - s3->accel.cy = s3->accel.cur_y_bitres; - } else { - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { /* overlap x */ - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { /* x end is negative */ - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { /* overlap y */ - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { /* y end is negative */ - s3->accel.cy |= ~0xfff; - } - } - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index e48156bf2..b5f1ee72c 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -470,9 +470,12 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (tgui->type >= TGUI_9440) { svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - if (tgui->type >= TGUI_9660 && (tgui->accel.ger22 & 0xff) == 8) { - svga->hwcursor.x <<= 1; + + if ((tgui->accel.ger22 & 0xff) == 8) { + if (svga->bpp != 24) + svga->hwcursor.x <<= 1; } + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x0f) << 18) | (svga->hwcursor.yoff * 8); @@ -622,6 +625,8 @@ void tgui_recalctimings(svga_t *svga) { tgui_t *tgui = (tgui_t *) svga->p; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8); if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -629,11 +634,12 @@ tgui_recalctimings(svga_t *svga) if (svga->crtc[0x29] & 0x10) svga->rowoffset |= 0x100; - if (tgui->type >= TGUI_9440 && svga->bpp >= 24) { - if ((tgui->accel.bpp == 0) && (tgui->accel.ger22 & 0xff) != 14 && (svga->bpp == 24)) + if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) { + if ((tgui->accel.bpp == 0) && (ger22lower != 14) && (svga->bpp == 24)) svga->hdisp = (svga->crtc[1] + 1) * 8; - if (tgui->accel.bpp == 3 && (tgui->accel.ger22 & 0xff) == 14 && (svga->bpp == 32) && (tgui->type == TGUI_9440)) + if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440)) svga->rowoffset <<= 1; + //pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); } if ((svga->crtc[0x1e] & 0xA0) == 0xA0) @@ -667,7 +673,7 @@ tgui_recalctimings(svga_t *svga) svga->lowres = !(svga->crtc[0x2a] & 0x40); svga->interlace = !!(svga->crtc[0x1e] & 4); - if (svga->interlace && tgui->type < TGUI_9440) + if (svga->interlace && (tgui->type < TGUI_9440)) svga->rowoffset >>= 1; if (tgui->type >= TGUI_9440) { @@ -735,10 +741,21 @@ tgui_recalctimings(svga_t *svga) case 8: svga->render = svga_render_8bpp_highres; if (tgui->type >= TGUI_9660) { - if (svga->dispend == 512) + if ((svga->dispend == 510) || (svga->dispend == 512)) svga->hdisp = 1280; - else if (svga->dispend == 600 && svga->hdisp == 800 && svga->vtotal == 651) + else if ((svga->dispend == 600) && (svga->hdisp == 800) && svga->interlace) svga->hdisp = 1600; + + switch (svga->hdisp) { + case 640: + if (ger22upper & 0x01) + svga->rowoffset = 0x50; + break; + case 1600: + if (svga->rowoffset != 0x100) + svga->rowoffset = 0x100; + break; + } } break; case 15: @@ -816,7 +833,6 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); else if ((svga->crtc[0x36] & 0x03) == 0x03) mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); - mem_mapping_disable(&svga->mapping); } else { switch (svga->gdcreg[6] & 0xC) { case 0x0: /*128k at A0000*/ @@ -923,7 +939,7 @@ tgui_pci_read(int func, int addr, void *p) return 0x10; case 0x02: - return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/ + return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI96x0XGi*/ case 0x03: return (tgui->type == TGUI_9440) ? 0x94 : 0x96; @@ -1334,6 +1350,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; uint16_t *vram_w = (uint16_t *) svga->vram; uint32_t *vram_l = (uint32_t *) svga->vram; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8) & 0xff; if (tgui->accel.bpp == 0) { trans_col &= 0xff; @@ -1389,80 +1407,40 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - /*Other than mode stuff, this bit is undocumented*/ - switch (tgui->accel.ger22 & 0xff) { - case 0: - switch (tgui->accel.ger22 >> 8) { - case 0x41: - tgui->accel.pitch = 640; - break; - } + switch (svga->hdisp) { + case 640: + case 1024: + case 1280: + tgui->accel.pitch = svga->hdisp; break; + case 800: /*Disassembly of the TGUI9440/96x0 drivers shows that 800x600 is treated as 832 in the acceleration pitch (0x340 as horizontal display)*/ + tgui->accel.pitch = svga->hdisp + 32; + break; + case 1600: + tgui->accel.pitch = 2048; + break; + } - case 4: - switch (tgui->accel.ger22 >> 8) { - case 0: + switch (ger22lower) { + case 4: /*8-bit mode for modes up to 1024x768.*/ + case 9: /*15-bit and 16-bit modes.*/ + if (!(ger22upper & 0x01)) { + if (ger22upper == 0x00) tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; } break; - case 8: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 2048; - break; - case 0x60: - tgui->accel.pitch = 1280; - break; - } - break; - case 9: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = svga->hdisp; - if (tgui->type == TGUI_9440) - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; - } - break; - case 13: - switch (tgui->accel.ger22 >> 8) { - case 0x60: - tgui->accel.pitch = 2048; - if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1280) - tgui->accel.pitch = svga->hdisp; - } - break; - } - break; - case 14: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; + case 8: /*8-bit mode for modes greater than 1024x768 and 24-bit mode for 640x480 (latter is TGUI9440AGi only).*/ + if (!(ger22upper & 0x01)) { + if (ger22upper == 0x00) { + if (svga->bpp == 24) + tgui->accel.pitch = 2048; + } } break; } + //pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); + switch (tgui->accel.command) { case TGUI_BITBLT: if (count == -1) { @@ -1728,32 +1706,14 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) break; case TGUI_BRESENHAMLINE: - { - int steep = 1; - int16_t dminor, dmajor, destxtmp, tmpswap; - int16_t cx, cy, dx, dy, err; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; -#define SWAP(a, b) \ - tmpswap = a; \ - a = b; \ - b = tmpswap; - - dminor = tgui->accel.src_y; - if (tgui->accel.src_y & 0x1000) - dminor |= ~0xfff; - dminor >>= 1; - - destxtmp = tgui->accel.src_x; - if (tgui->accel.src_x & 0x1000) - destxtmp |= ~0xfff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - cx = dmajor; - cy = dminor; - - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1767,78 +1727,113 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - err = tgui->accel.size_x + tgui->accel.src_y; - if ((tgui->accel.size_x + tgui->accel.src_y) & 0x1000) - err |= ~0xfff; + //pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y); + while (count-- && (tgui->accel.y <= (tgui->accel.size_y))) { + //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - if (tgui->accel.flags & 0x400) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) { + break; + } - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if (steep) { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dx + (dy * tgui->accel.pitch), out); - } - } else { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { - READ(dy + (dx * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dy + (dx * tgui->accel.pitch), out); - } - } - - if (tgui->accel.y == tgui->accel.size_y) { - break; - } - - while (err > 0) { - dy += ydir; - err -= (cx << 1); - if (!cx) { + if (tgui->accel.err >= (tgui->accel.size_y & 0xfff)) { + //pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y); + if ((tgui->accel.src_x >= 2048) && (tgui->accel.src_x < 4096)) + tgui->accel.err -= (4096 - tgui->accel.src_x); + else if ((tgui->accel.src_x >= 4096) && (tgui->accel.src_x < 32768)) + tgui->accel.err -= (32768 - tgui->accel.src_x); + else + tgui->accel.err += tgui->accel.src_x; + /*Step minor axis*/ + switch (tgui->accel.flags & 0x700) { + case 0x300: + tgui->accel.dy--; + break; + case 0x100: + tgui->accel.dy--; + break; + case 0x700: + tgui->accel.dx--; + break; + case 0x500: + tgui->accel.dx++; + break; + case 0x200: + tgui->accel.dy++; + break; + case 0x000: + tgui->accel.dy++; + break; + case 0x600: + tgui->accel.dx--; + break; + case 0x400: + tgui->accel.dx++; break; - } } - dx += xdir; - err += (cy << 1); - - tgui->accel.y++; + } else { + //pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y); + tgui->accel.err += tgui->accel.src_y; } + + /*Step major axis*/ + switch (tgui->accel.flags & 0x700) { + case 0x300: + tgui->accel.dx--; + break; + case 0x100: + tgui->accel.dx++; + break; + case 0x700: + tgui->accel.dy--; + break; + case 0x500: + tgui->accel.dy--; + break; + case 0x200: + tgui->accel.dx--; + break; + case 0x000: + tgui->accel.dx++; + break; + case 0x600: + tgui->accel.dy++; + break; + case 0x400: + tgui->accel.dy++; + break; + } + + tgui->accel.y++; } break; case TGUI_SHORTVECTOR: - { - int16_t dx, dy; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1852,74 +1847,77 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + while (count-- && (tgui->accel.y <= (tgui->accel.sv_size_y & 0xfff))) { + //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); - pat_dat = tgui->accel.fg_col; + pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - MIX(); + MIX(); - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) - break; - - switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } + + if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) + break; + + switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { + case 0x00: + tgui->accel.dx++; + break; + case 0x20: + tgui->accel.dx++; + tgui->accel.dy--; + break; + case 0x40: + tgui->accel.dy--; + break; + case 0x60: + tgui->accel.dx--; + tgui->accel.dy--; + break; + case 0x80: + tgui->accel.dx--; + break; + case 0xa0: + tgui->accel.dx--; + tgui->accel.dy++; + break; + case 0xc0: + tgui->accel.dy++; + break; + case 0xe0: + tgui->accel.dx++; + tgui->accel.dy++; + break; + } + + tgui->accel.y++; } break; case TGUI_FASTLINE: - { - if (tgui->type < TGUI_9660) - break; + if (tgui->type < TGUI_9660) + break; - int16_t dx, dy; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1933,62 +1931,62 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + while (count-- && (tgui->accel.y <= (tgui->accel.size_y & 0xfff))) { + //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if (tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); - pat_dat = tgui->accel.fg_col; + pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - MIX(); + MIX(); - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) - break; - - switch ((tgui->accel.size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } + + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) + break; + + switch ((tgui->accel.size_y >> 8) & 0xe0) { + case 0x00: + tgui->accel.dx++; + break; + case 0x20: + tgui->accel.dx++; + tgui->accel.dy--; + break; + case 0x40: + tgui->accel.dy--; + break; + case 0x60: + tgui->accel.dx--; + tgui->accel.dy--; + break; + case 0x80: + tgui->accel.dx--; + break; + case 0xa0: + tgui->accel.dx--; + tgui->accel.dy++; + break; + case 0xc0: + tgui->accel.dy++; + break; + case 0xe0: + tgui->accel.dx++; + tgui->accel.dy++; + break; + } + + tgui->accel.y++; } break; } @@ -2009,7 +2007,14 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 9: - tgui->accel.bpp = 1; + switch (tgui->svga.bpp) { + case 32: + tgui->accel.bpp = 3; + break; + default: + tgui->accel.bpp = 1; + break; + } break; case 13: @@ -2131,6 +2136,11 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 0x2141: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + tgui->accel.err = tgui->accel.size_x; + if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) + tgui->accel.err -= 4096; + else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) + tgui->accel.err -= 32768; break; case 0x2142: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; @@ -2367,7 +2377,6 @@ tgui_accel_in(uint16_t addr, void *p) case 0x2122: return tgui->accel.ger22 & 0xff; - case 0x2123: return tgui->accel.ger22 >> 8; @@ -2648,7 +2657,14 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 9: - tgui->accel.bpp = 1; + switch (tgui->svga.bpp) { + case 32: + tgui->accel.bpp = 3; + break; + default: + tgui->accel.bpp = 1; + break; + } break; case 13: @@ -2770,6 +2786,11 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 0x41: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + tgui->accel.err = tgui->accel.size_x; + if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) + tgui->accel.err -= 4096; + else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) + tgui->accel.err -= 32768; break; case 0x42: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; @@ -3022,7 +3043,6 @@ tgui_accel_read(uint32_t addr, void *p) case 0x22: return tgui->accel.ger22 & 0xff; - case 0x23: return tgui->accel.ger22 >> 8;