From ae11e9bf27caa4859e4c4f7458270ddc29e0fe21 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 16 Jul 2025 01:40:45 +0200 Subject: [PATCH] XGA: Redo pattern blitting and clamp the X coordinate to within the width, fixes #5792. --- src/include/86box/vid_xga.h | 9 +- src/video/vid_xga.c | 478 +++++++++++++++++++++++++----------- 2 files changed, 338 insertions(+), 149 deletions(-) diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 62fa7c0ae..8a4867a96 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -154,7 +154,8 @@ typedef struct xga_t { int a5_test; int type; int bus; - int busy; + int src_reverse_order; + int dst_reverse_order; uint32_t linear_base; uint32_t linear_size; @@ -225,15 +226,13 @@ typedef struct xga_t { int y; int sx; int sy; - int dx; - int dy; int px; int py; int pattern; int command_len; int filling; + int y_len; int x_len; - int py_alt; uint32_t short_stroke; uint32_t color_cmp; @@ -243,7 +242,7 @@ typedef struct xga_t { uint32_t bkgd_color; uint32_t command; uint32_t dir_cmd; - uint32_t srcbase_new; + uint32_t pattern_data; uint8_t px_map_format[4]; uint16_t px_map_width[4]; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index f8698ade7..5a9251dad 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -984,19 +984,62 @@ xga_ext_inb(uint16_t addr, void *priv) } \ } -static uint32_t -xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) +static void +xga_set_pixel_map_endianess(xga_t *xga, int srcmap, int dstmap) { - const xga_t *xga = (xga_t *) svga->xga; + if (xga->access_mode & 0x08) { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) + xga->src_reverse_order = 1; + + xga->dst_reverse_order = 1; + } else { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) { + if (xga->accel.px_map_format[srcmap] & 0x08) { + xga->src_reverse_order = 1; + xga->dst_reverse_order = 1; + } + } + if (xga->accel.px_map_format[dstmap] & 0x08) { + xga->src_reverse_order = 1; + xga->dst_reverse_order = 1; + } + } + xga_log("1bpp setendianness: dstmap=%02x, srcmap=%02x, mode=%02x, dstreverse=%d, srcreverse=%d.\n", xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode, xga->dst_reverse_order, xga->src_reverse_order); +} + +static uint32_t +xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int srcmap, int dstmap, uint32_t base, int width) +{ + xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; int bits; uint8_t byte; uint8_t px; int skip = 0; - int pos = (y * width) + x; + int pos = (y * (width + 1)) + (x % (width + 1)); + + if (xga->access_mode & 0x08) { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) + xga->src_reverse_order = 1; + + xga->dst_reverse_order = 1; + } else { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) { + if (xga->accel.px_map_format[srcmap] & 0x08) { + switch (xga->accel.px_map_format[srcmap] & 0x07) { + case 0x00: /*1-bit*/ + xga->src_reverse_order = 1; + break; + default: + break; + } + } + } + if (xga->accel.px_map_format[dstmap] & 0x08) + xga->dst_reverse_order = 1; + } addr += (pos / 8); - bits = 7 - (pos & 7); if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) skip = 1; @@ -1006,49 +1049,85 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int } else byte = mem_readb_phys(addr); - xga_log("0. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), (xga->accel.px_map_format[xga->accel.pat_src] & 0x08)); - if (!(xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) { - if (((xga->accel.px_map_format[xga->accel.src_map] & 0x07) >= 0x02) && ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) >= 0x02) && (xga->accel.pat_src <= 2)) { - bits ^= 7; - } + bits = pos & 7; + + if (xga->src_reverse_order || xga->dst_reverse_order) + bits ^= 7; + + if (!(xga->access_mode & 0x08) && !(xga->accel.px_map_format[xga->accel.pat_src] & 0x08)) + bits ^= 7; + + px = (byte >> bits) & 0x01; + + if ((width + 1) & 7) { + xga_log("CMD=%08x, 1bpp patread: dstmap=%02x, srcmap=%02x, mode=%02x, dstreverse=%d, srcreverse=%d, addr=%06x, pos=%d, width=%d, x=%d, y=%d, byte=%02x, bits=%d, pix=%x.\n", xga->accel.command, xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode, xga->dst_reverse_order, xga->src_reverse_order, addr, pos, width + 1, x, y, byte, bits, px); } - px = (byte >> bits) & 1; - - if (xga->accel.command == 0x08013002) - xga_log("Read Pattern Skip=%d, lx=%d, ly=%d, px=%d, py=%d, dx=%d, dy=%d, xlen=%d, width=%d, byte=%02x, bits=%d, addr=%08x, addrpx=%08x, base=%08x, chain=%08x.\n", skip, xga->accel.x, xga->accel.y, x, y, xga->accel.dx, xga->accel.dy, xga->accel.x_len, width, byte, bits, addr, addr + (x >> 3), base, xga->accel.carry_chain); - return px; } static uint32_t -xga_accel_read_area_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) +xga_accel_read_area_map_pixel(svga_t *svga, int x, int y, int srcmap, int dstmap, uint32_t base, int width) { - const xga_t *xga = (xga_t *) svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; int bits; uint8_t byte; uint8_t px; int skip = 0; + int pos = (y * (width + 1)) + (x % (width + 1)); + + if (xga->access_mode & 0x08) { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) + xga->src_reverse_order = 1; + + xga->dst_reverse_order = 1; + } else { + if ((((xga->accel.command >> 28) & 3) == 2) || (((xga->accel.command >> 30) & 3) == 2)) { + if (xga->accel.px_map_format[srcmap] & 0x08) { + switch (xga->accel.px_map_format[srcmap] & 0x07) { + case 0x00: /*1-bit*/ + xga->src_reverse_order = 1; + break; + default: + break; + } + } + } + if (xga->accel.px_map_format[dstmap] & 0x08) { + switch (xga->accel.px_map_format[dstmap] & 0x07) { + case 0x00: /*1-bit*/ + xga->dst_reverse_order = 1; + break; + default: + break; + } + } + } + + addr += (pos / 8); if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) skip = 1; - addr += (y * (width >> 3)); - addr += (x >> 3); if (!skip) { READ(addr, byte); } else byte = mem_readb_phys(addr); - bits = 7 - (x & 7); + xga_log("1bpp arearead: dstmap=%02x, srcmap=%02x, mode=%02x.\n", xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode); + + bits = pos & 7; + + if (xga->src_reverse_order || xga->dst_reverse_order) + bits ^= 7; px = (byte >> bits) & 0x01; return px; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) +xga_accel_source_read_map_pixel(svga_t *svga, int x, int y, int srcmap, int dstmap, uint32_t base, int width) { xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; @@ -1057,36 +1136,45 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int uint8_t mask; uint8_t px; int skip = 0; + int pos; - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; - - switch (xga->accel.px_map_format[map] & 0x07) { + switch (xga->accel.px_map_format[srcmap] & 0x07) { case 0: /*1-bit*/ - addr += (y * (width >> 3)); - addr += (x >> 3); + pos = (y * (width + 1)) + (x % (width + 1)); + addr += (pos / 8); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { READ(addr, byte); } else byte = mem_readb_phys(addr); - if ((xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->access_mode & 0x08)) - bits = (x & 7); - else - bits = 7 - (x & 7); + xga_log("1bpp srcread: dstmap=%02x, srcmap=%02x, mode=%02x.\n", xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode); - px = (byte >> bits) & 1; - xga_log("1bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, px=%x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, px, x, y, skip); + bits = pos & 7; + + if (xga->src_reverse_order) + bits ^= 7; + + px = (byte >> bits) & 0x01; + xga_log("1bpp srcread: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, srcwidth=%d, pos=%d, bits=%d, px=%x, x=%d, y=%d, skip=%d.\n", + xga->op_mode & 0x08, (xga->accel.px_map_format[srcmap] & 0x0f), (xga->accel.px_map_format[dstmap] & 0x0f), xga->access_mode & 0x0f, srcmap, dstmap, width, pos, bits, px, x, y, skip); return px; case 2: /*4-bit*/ - addr += (y * (width >> 1)); - addr += (x >> 1); + addr += (y * ((width + 1) >> 1)); + addr += ((x % (width + 1)) >> 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { READ(addr, byte); } else byte = mem_readb_phys(addr); - if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08)) + if ((xga->accel.px_map_format[srcmap] & 0x08) && (xga->access_mode & 0x08)) mask = ((1 - (x & 1)) << 2); else { mask = ((x & 1) << 2); @@ -1094,12 +1182,15 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } byte = (byte >> mask) & 0x0f; - xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d, mask=%02x.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip, mask); return byte; case 3: /*8-bit*/ - addr += (y * width); - addr += x; + addr += (y * (width + 1)); + addr += (x % (width + 1)); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { READ(addr, byte); } else @@ -1107,8 +1198,106 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int return byte; case 4: /*16-bit*/ - addr += (y * (width << 1)); - addr += (x << 1); + addr += (y * ((width + 1) << 1)); + addr += ((x % (width + 1)) << 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + + if (!skip) { + READW(addr, byte); + } else { + byte = mem_readw_phys(addr); + if ((xga->access_mode & 0x07) == 0x04) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); + else if (xga->access_mode & 0x08) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); + } + return byte; + + default: + break; + } + return 0; +} + +static uint32_t +xga_accel_destination_read_map_pixel(svga_t *svga, int x, int y, int srcmap, int dstmap, uint32_t base, int width) +{ + xga_t *xga = (xga_t *) svga->xga; + uint32_t addr = base; + int bits; + uint32_t byte; + uint8_t mask; + uint8_t px; + int skip = 0; + int pos; + + switch (xga->accel.px_map_format[dstmap] & 0x07) { + case 0: /*1-bit*/ + pos = (y * (width + 1)) + (x % (width + 1)); + addr += (pos / 8); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + + if (!skip) { + READ(addr, byte); + } else + byte = mem_readb_phys(addr); + + xga_log("1bpp dstread: dstmap=%02x, srcmap=%02x, mode=%02x.\n", xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode); + + bits = pos & 7; + + if (xga->dst_reverse_order) + bits ^= 7; + + px = (byte >> bits) & 0x01; + xga_log("1bpp dstread: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, dstwidth=%d, pos=%d, bits=%d, px=%x, x=%d, y=%d, skip=%d.\n", + xga->op_mode & 0x08, (xga->accel.px_map_format[srcmap] & 0x0f), (xga->accel.px_map_format[dstmap] & 0x0f), xga->access_mode & 0x0f, srcmap, dstmap, width, pos, bits, px, x, y, skip); + return px; + case 2: /*4-bit*/ + addr += (y * ((width + 1) >> 1)); + addr += ((x % (width + 1)) >> 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + + if (!skip) { + READ(addr, byte); + } else + byte = mem_readb_phys(addr); + + if ((xga->accel.px_map_format[dstmap] & 0x08) && (xga->access_mode & 0x08)) + mask = ((1 - (x & 1)) << 2); + else { + mask = ((x & 1) << 2); + mask ^= 0x04; + } + + byte = (byte >> mask) & 0x0f; + xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d, mask=%02x.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip, mask); + return byte; + case 3: /*8-bit*/ + addr += (y * (width + 1)); + addr += (x % (width + 1)); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + + if (!skip) { + READ(addr, byte); + } else + byte = mem_readb_phys(addr); + + return byte; + case 4: /*16-bit*/ + addr += (y * ((width + 1) << 1)); + addr += ((x % (width + 1)) << 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; if (!skip) { READW(addr, byte); @@ -1128,59 +1317,57 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } static void -xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width) +xga_accel_write_map_pixel(svga_t *svga, int x, int y, int srcmap, int dstmap, uint32_t base, uint32_t pixel, int width) { xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; uint8_t byte; uint8_t mask; int skip = 0; + int pos; - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; - - switch (xga->accel.px_map_format[map] & 0x07) { + switch (xga->accel.px_map_format[dstmap] & 0x07) { case 0: /*1-bit*/ - addr += (y * (width >> 3)); - addr += (x >> 3); + pos = (y * (width + 1)) + (x % (width + 1)); + addr += (pos / 8); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { READ(addr, byte); } else byte = mem_readb_phys(addr); - if (xga->access_mode & 0x08) - mask = 1 << (7 - (x & 7)); - else { - if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08)) { - mask = 1 << (x & 7); - } else - mask = 1 << (7 - (x & 7)); - } + xga_log("1bpp dstwrite: dstmap=%02x, srcmap=%02x, mode=%02x.\n", xga->accel.px_map_format[dstmap], xga->accel.px_map_format[srcmap], xga->access_mode); - byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); - if (pixel & 1) { - if (!skip) { - xga->vram[addr & (xga->vram_mask)] |= mask; - xga->changedvram[(addr & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - } - } else { - if (!skip) { - xga->vram[addr & (xga->vram_mask)] &= ~mask; - xga->changedvram[(addr & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - } + pos &= 7; + + if (xga->dst_reverse_order) + pos ^= 7; + + pixel <<= pos; + mask = 1 << pos; + + byte = (byte & ~mask) | (pixel & mask); + if (!skip) { + WRITE(addr, byte); } - xga_log("1bpp write: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, x, y, skip); mem_writeb_phys(addr, byte); break; case 2: /*4-bit*/ - addr += (y * (width >> 1)); - addr += (x >> 1); + addr += (y * ((width + 1) >> 1)); + addr += ((x % (width + 1)) >> 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { READ(addr, byte); } else byte = mem_readb_phys(addr); - if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08)) + if ((xga->accel.px_map_format[dstmap] & 0x08) && (xga->access_mode & 0x08)) mask = ((1 - (x & 1)) << 2); else { mask = ((x & 1) << 2); @@ -1198,16 +1385,23 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui mem_writeb_phys(addr, byte); break; case 3: /*8-bit*/ - addr += (y * width); - addr += x; + addr += (y * (width + 1)); + addr += (x % (width + 1)); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + if (!skip) { - WRITE(addr, pixel); + WRITE(addr, pixel & 0xff); } - mem_writeb_phys(addr, pixel); + mem_writeb_phys(addr, pixel & 0xff); break; case 4: /*16-bit*/ - addr += (y * width << 1); - addr += (x << 1); + addr += (y * ((width + 1) << 1)); + addr += ((x % (width + 1)) << 1); + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; if (!skip) { WRITEW(addr, pixel); @@ -1291,10 +1485,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) if (xga->accel.pat_src == 8) { while (y >= 0) { + xga_set_pixel_map_endianess(xga, xga->accel.src_map, xga->accel.dst_map); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1302,19 +1497,19 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1322,13 +1517,13 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } } @@ -1384,6 +1579,7 @@ xga_line_draw_write(svga_t *svga) if (xga->accel.pat_src == 8) { if ((xga->accel.command & 0x30) == 0x30) { while (y >= 0) { + xga_set_pixel_map_endianess(xga, xga->accel.src_map, xga->accel.dst_map); draw_pixel = 0; if (xga->accel.octant & 0x01) { /*Y Major*/ @@ -1421,26 +1617,26 @@ xga_line_draw_write(svga_t *svga) xga_log("Draw Boundary: DX=%d, DY=%d, wrt_pix=%d, ymajor=%d, bottomtotop=%x, len=%d, err=%d, frgdmix=%02x.\n", dx, dy, draw_pixel, xga->accel.octant & 0x01, xga->accel.octant & 0x02, y, xga->accel.bres_err_term, xga->accel.frgd_mix & 0x1f); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off)) && draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, cx, cy, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } } else { if (draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, cx, cy, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } } @@ -1485,37 +1681,38 @@ xga_line_draw_write(svga_t *svga) } } else { while (y >= 0) { + xga_set_pixel_map_endianess(xga, xga->accel.src_map, xga->accel.dst_map); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, xga->accel.dst_map, srcbase, xga->accel.px_map_width[xga->accel.src_map]) : xga->accel.frgd_color; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map]); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map]); } } @@ -1601,14 +1798,11 @@ xga_bitblt(svga_t *svga) if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; - xga->accel.dx = dx; - xga->accel.dy = dy; - xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d, frgdcol=%04x, bkgdcol=%04x.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth, frgdcol, bkgdcol); xga->accel.pattern = 0; xga->accel.filling = 0; - xga->accel.x_len = 0; + xga->accel.y_len = 0; xga_log("XGA bitblt access_mode=%x, octanty=%d, src command=%08x, " "pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, " @@ -1637,31 +1831,32 @@ xga_bitblt(svga_t *svga) } } - xga_log("CMD=%08x, EnablePat=%d, SRC%d, DST%d: SrcFormat=%x, DstFormat=%x, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d.\n", xga->accel.command, + xga_log("CMD=%08x, EnablePat=%d, SRC%d, DST%d: SrcFormat=%x, DstFormat=%x, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d, sx=%d, sy=%d.\n", xga->accel.command, xga->accel.pattern, xga->accel.src_map, xga->accel.dst_map, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), - srcwidth, srcheight, dstwidth, dstheight); + srcwidth, srcheight, dstwidth, dstheight, xga->accel.sx, xga->accel.sy); while (xga->accel.y >= 0) { + xga_set_pixel_map_endianess(xga, xga->accel.src_map, xga->accel.dst_map); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } @@ -1683,6 +1878,7 @@ xga_bitblt(svga_t *svga) xga->accel.sx = xga->accel.src_map_x & 0xfff; dy += ydir; + xga->accel.y_len++; if (xga->accel.pattern) xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); @@ -1718,13 +1914,13 @@ xga_bitblt(svga_t *svga) } else { if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { - if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40)) + if (patheight > 1) xga->accel.pattern = 0; else xga->accel.pattern = 1; } else if (!(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) { if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x02) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { - if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40)) + if (patheight > 1) xga->accel.pattern = 0; else xga->accel.pattern = 1; @@ -1735,14 +1931,14 @@ xga_bitblt(svga_t *svga) } } - xga_log("EnablePat=%d, PAT%d, SRC%d, DST%d: PatFormat=%x, SrcFormat=%x, DstFormat=%x, PatWidth=%d, PatHeight=%d, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d.\n", + xga_log("CMD=%08x, EnablePat=%d, PAT%d, SRC%d, DST%d: PatFormat=%x, SrcFormat=%x, DstFormat=%x, PatWidth=%d, PatHeight=%d, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d, px=%d, py=%d.\n", xga->accel.command, xga->accel.pattern, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.px_map_format[xga->accel.pat_src], (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), - patwidth, patheight, srcwidth, srcheight, dstwidth, dstheight); + patwidth, patheight, srcwidth, srcheight, dstwidth, dstheight, xga->accel.px, xga->accel.py); if (((xga->accel.command >> 24) & 0x0f) == 0x0a) { if ((xga->accel.bkgd_mix & 0x1f) == 0x05) { while (xga->accel.y >= 0) { - mix = xga_accel_read_area_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1); + mix = xga_accel_read_area_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.src_map, xga->accel.dst_map, patbase, patwidth); if (mix) xga->accel.filling ^= 1; @@ -1750,26 +1946,26 @@ xga_bitblt(svga_t *svga) if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off)) && xga->accel.filling) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_log("XGA Area Fill1: Dest=%02x, Src=%02x, OldD=%02x.\n", dest_dat, src_dat, old_dest_dat); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight) && xga->accel.filling) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_log("XGA Area Fill2: Dest=%02x, Src=%02x, OldD=%02x.\n", dest_dat, src_dat, old_dest_dat); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } @@ -1778,7 +1974,6 @@ xga_bitblt(svga_t *svga) xga->accel.px++; dx++; - xga->accel.dx = dx; xga->accel.x--; if (xga->accel.x < 0) { xga->accel.y--; @@ -1788,8 +1983,6 @@ xga_bitblt(svga_t *svga) if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; - xga->accel.dx = dx; - xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; @@ -1797,7 +1990,6 @@ xga_bitblt(svga_t *svga) xga->accel.py++; dy++; - xga->accel.dy = dy; xga->accel.filling = 0; if (xga->accel.y < 0) { @@ -1810,36 +2002,36 @@ xga_bitblt(svga_t *svga) } } else { while (xga->accel.y >= 0) { - mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1); + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.src_map, xga->accel.dst_map, patbase, patwidth); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : bkgdcol; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : bkgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : frgdcol; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : bkgdcol; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_source_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, xga->accel.dst_map, srcbase, srcwidth) : bkgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + dest_dat = xga_accel_destination_read_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dstwidth); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.src_map, xga->accel.dst_map, dstbase, dest_dat, dstwidth); } } } @@ -1854,7 +2046,7 @@ xga_bitblt(svga_t *svga) xga_log("MIX=%d, DX=%d, DY=%d, LX=%d, LY=%d, PX=%d, PY=%d, SX=%d, SY=%d.\n", mix, dx, dy, xga->accel.x, xga->accel.y, xga->accel.px, xga->accel.py, xga->accel.sx, xga->accel.sy); dx += xdir; - xga->accel.dx = dx; + xga->accel.x--; if (xga->accel.x < 0) { xga->accel.y--; @@ -1864,8 +2056,6 @@ xga_bitblt(svga_t *svga) if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; - xga->accel.dx = dx; - xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; @@ -1876,9 +2066,7 @@ xga_bitblt(svga_t *svga) else xga->accel.py += ydir; - xga->accel.py_alt++; dy += ydir; - xga->accel.dy = dy; if (xga->accel.y < 0) { xga->accel.dst_map_x = dx; @@ -2363,6 +2551,8 @@ exec_command: xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); + xga->src_reverse_order = 0; + xga->dst_reverse_order = 0; switch ((xga->accel.command >> 24) & 0x0f) { case 2: /*Short Stroke Vectors Read */ xga_log("Short Stroke Vectors Read.\n");