From: Toni Wilen Date: Wed, 27 Dec 2023 15:13:22 +0000 (+0200) Subject: NCR SVGA updates. Blitter not yet correctly working in 24-bit mode. X-Git-Tag: 5200~121 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=4f282844715416c949272e4c820aef2d1befcbf4;p=francis%2Fwinuae.git NCR SVGA updates. Blitter not yet correctly working in 24-bit mode. --- diff --git a/pcem/vid_ncr.cpp b/pcem/vid_ncr.cpp index 41996a10..d6f1bdf5 100644 --- a/pcem/vid_ncr.cpp +++ b/pcem/vid_ncr.cpp @@ -71,12 +71,14 @@ typedef struct ncr_t uint8_t blt_stage; int8_t blt_fifo_read, blt_fifo_write; uint8_t blt_srcdata, blt_patdata, blt_dstdata; - int8_t blt_expand_offset, blt_expand_bit, blt_first_expand; - uint8_t blt_patdone, blt_start; + int8_t blt_expand_offset, blt_expand_bit; + uint8_t blt_start; uint8_t blt_fifo_size; uint8_t blt_patx, blt_paty; uint8_t blt_src_size; uint8_t blt_bpp; + bool blt_color_expand, blt_color_fill, blt_transparent; + uint8_t blt_pattern_size; } ncr_t; @@ -536,9 +538,9 @@ static uint8_t blitter_rop(uint8_t rop, uint8_t src, uint8_t pat, uint8_t dst) return out; } -static uint8_t blitter_read(ncr_t *ncr, uint32_t addr) +static uint8_t blitter_read(ncr_t *ncr, uint32_t addr, int off) { - uint32_t offset = ((addr >> 3) + ncr->blt_bpp) & ncr->vram_mask; + uint32_t offset = ((addr >> 3) + off) & ncr->vram_mask; return ncr->svga.vram[offset]; } @@ -551,8 +553,6 @@ static void blitter_write(ncr_t *ncr, uint32_t addr, uint8_t v) static bool blitter_proc(ncr_t *ncr) { - bool colorfill = (ncr->blt_control & (1 << 9)) != 0; - bool colorexpand = (ncr->blt_control & (1 << 11)) != 0; int32_t bpp = ncr->svga.bpp; bool next = false; @@ -560,92 +560,91 @@ static bool blitter_proc(ncr_t *ncr) uint8_t src = 0; if (!(ncr->blt_control & (1 << 15))) { // waiting for fifo write? - if (ncr->blt_fifo_size < 8) { + int shift = ncr->blt_expand_offset & 7; + if (ncr->blt_fifo_size - shift < 8) { ncr->blt_fifo_write = 1; return false; } - if (ncr->blt_first_expand && colorexpand && ncr->blt_expand_offset) { - ncr->blt_fifo_size -= ncr->blt_expand_offset; - ncr->blt_fifo_data >>= ncr->blt_expand_offset; - ncr->blt_first_expand = 0; - if (ncr->blt_fifo_size < 8) { - ncr->blt_fifo_write = 1; - return false; - } - } - src = ncr->blt_fifo_data & 0xff; + src = (ncr->blt_fifo_data >> shift) & 0xff; ncr->blt_fifo_data >>= 8; ncr->blt_fifo_size -= 8; ncr->blt_fifo_write = 0; + } else if (ncr->blt_color_expand) { + int shift = ncr->blt_expand_offset & 7; + uint16_t data = blitter_read(ncr, ncr->blt_src, 0) << 0; + if (shift) { + data |= blitter_read(ncr, ncr->blt_src, 1) << 8; + data >>= shift; + } + src = (uint8_t)data; } else { - src = blitter_read(ncr, ncr->blt_src); + src = blitter_read(ncr, ncr->blt_src, ncr->blt_bpp); } - ncr->blt_srcdata = src; ncr->blt_stage++; } if (ncr->blt_stage == 1) { - uint8_t skip = 0; uint8_t srcdata = ncr->blt_srcdata; - if (colorexpand) { + ncr->blt_dstdata = blitter_read(ncr, ncr->blt_dst, ncr->blt_bpp); + ncr->blt_patdata = blitter_read(ncr, ncr->blt_pat, 0); + if (ncr->blt_color_expand) { int8_t offset = ncr->blt_expand_bit; - if (offset < 8) { - if (srcdata & (1 << offset)) { - srcdata = ncr->blt_c0 >> (ncr->blt_bpp * 8); - } else if (ncr->blt_control & (1 << 5)) { - /// transparent - skip = 1; - } else { - srcdata = ncr->blt_c1 >> (ncr->blt_bpp * 8); - } + if (srcdata & (1 << offset)) { + srcdata = ncr->blt_c0 >> (ncr->blt_bpp * 8); + } else if (ncr->blt_transparent) { + srcdata = ncr->blt_dstdata; + } else { + srcdata = ncr->blt_c1 >> (ncr->blt_bpp * 8); } } - if (!skip) { - ncr->blt_patdata = blitter_read(ncr, ncr->blt_pat); - ncr->blt_dstdata = blitter_read(ncr, ncr->blt_dst); - uint8_t out = blitter_rop(ncr->blt_rop, srcdata, ncr->blt_patdata, ncr->blt_dstdata); - blitter_write(ncr, ncr->blt_dst, out); + uint8_t out = blitter_rop(ncr->blt_rop, srcdata, ncr->blt_patdata, ncr->blt_dstdata); + blitter_write(ncr, ncr->blt_dst, out); + + ncr->blt_pat += 1 << 3; + ncr->blt_patx++; + if (ncr->blt_patx == ncr->blt_pattern_size * (bpp / 8)) { + ncr->blt_pat = ncr->blt_patbak; + ncr->blt_patx = 0; } ncr->blt_bpp++; - if (ncr->blt_bpp == bpp / 8) { - ncr->blt_bpp = 0; + if (ncr->blt_bpp >= bpp / 8) { int16_t dir = (ncr->blt_control & (1 << 7)) ? 1 : -1; int16_t dx = (bpp / 8) * dir; - if (colorexpand) { + if (ncr->blt_color_expand) { ncr->blt_expand_bit--; if (ncr->blt_expand_bit < 0) { ncr->blt_expand_bit = 7; - ncr->blt_src += (1 << 3) * dir; + if (ncr->blt_control & (1 << 15)) { + ncr->blt_src += (1 << 3); + } ncr->blt_stage = 0; } else { ncr->blt_stage = 1; } } else { - ncr->blt_src += dx << 3; + if (ncr->blt_control & (1 << 15)) { + ncr->blt_src += dx << 3; + } ncr->blt_stage = 0; } - ncr->blt_dst += dx << 3; - int16_t patsize = (ncr->blt_control & (1 << 4)) ? 16 : 8; - ncr->blt_patx++; - ncr->blt_pat += dx << 3; - if (ncr->blt_patx == patsize) { - ncr->blt_patx = 0; - ncr->blt_pat = ncr->blt_patbak; + if (ncr->blt_control & (1 << 14)) { + ncr->blt_dst += dx << 3; } - + + ncr->blt_bpp = 0; next = true; } else { - if (colorexpand) { - ncr->blt_stage = 1; - } else { + + if (!ncr->blt_color_expand) { ncr->blt_stage = 0; } + } } @@ -658,6 +657,14 @@ static void blitter_done(ncr_t *ncr) ncr->blt_start &= ~1; } +static void blitter_reset_fifo(ncr_t *ncr) +{ + ncr->blt_fifo_size = -ncr->blt_expand_offset; + ncr->blt_fifo_read = 0; + ncr->blt_fifo_write = 0; + ncr->blt_expand_bit = 7; +} + static void blitter_run(ncr_t *ncr) { for (;;) { @@ -670,35 +677,35 @@ static void blitter_run(ncr_t *ncr) if (blitter_proc(ncr)) { ncr->blt_w++; if (ncr->blt_w >= ncr->blt_width) { - ncr->blt_w = 0; - ncr->blt_first_expand = 1; - int bpp = ncr->svga.bpp / 8; + int bpp = ncr->svga.bpp; int dir = (ncr->blt_control & (1 << 6)) ? 1 : -1; int dy = dir * ncr->svga.rowoffset * 8; - ncr->blt_fifo_size = 0; + ncr->blt_w = 0; + ncr->blt_stage = 0; + + blitter_reset_fifo(ncr); - if (!(ncr->blt_control & (1 << 12))) { + if (!(ncr->blt_control & (1 << 12)) && (ncr->blt_control & (1 << 14))) { ncr->blt_dstbak += dy << 3; ncr->blt_dst = ncr->blt_dstbak; } - if (!(ncr->blt_control & (1 << 13))) { + if (!(ncr->blt_control & (1 << 13)) && (ncr->blt_control & (1 << 15))) { ncr->blt_srcbak += dy << 3; ncr->blt_src = ncr->blt_srcbak; } - if (!(ncr->blt_control & (1 << 9))) { - int patsize = (ncr->blt_control & (1 << 4)) ? 16 : 8; - int patdx = (ncr->svga.bpp / 4) << 3; + if (!ncr->blt_color_fill) { + int patdx = (bpp / 4) << 3; ncr->blt_paty++; - ncr->blt_patbak += dir * patdx; - if (ncr->blt_paty == patsize) { + ncr->blt_patbak += patdx; + if (ncr->blt_paty == ncr->blt_pattern_size) { ncr->blt_paty = 0; ncr->blt_patbak = ncr->blt_patbak2; } - ncr->blt_pat = ncr->blt_patbak; } + ncr->blt_pat = ncr->blt_patbak; ncr->blt_h++; if (ncr->blt_h >= ncr->blt_height) { @@ -710,20 +717,74 @@ static void blitter_run(ncr_t *ncr) } } -static void blitter_write_fifo(ncr_t *ncr, uint32_t v, int size) +static void blitter_write_fifo(ncr_t *ncr, uint32_t v) { ncr->blt_fifo_write = -1; - ncr->blt_fifo_data <<= ncr->blt_fifo_size; - ncr->blt_fifo_data |= ((uint64_t)v) << ncr->blt_fifo_size; + ncr->blt_fifo_data <<= 32; + ncr->blt_fifo_data |= v; ncr->blt_fifo_size += 32; blitter_run(ncr); } - static void blitter_start(ncr_t *ncr) { -#if 1 - pclog("C=%04x ROP=%02x W=%d H=%d S=%08x/%d P=%08x/%d D=%08x/%d F=%d E=%d DM=%d SM=%d DL=%d SL=%d TR=%d MW=%d\n", + ncr->blt_expand_offset = ncr->blt_src & 31; + ncr->blt_expand_bit = 7; + ncr->blt_color_fill = (ncr->blt_control & (1 << 9)) != 0; + ncr->blt_color_expand = (ncr->blt_control & (1 << 11)) != 0; + ncr->blt_transparent = (ncr->blt_control & (1 << 5)) != 0; + ncr->blt_pattern_size = (ncr->blt_control & (1 << 4)) ? 16 : 8; + ncr->blt_patx = 0; + ncr->blt_paty = 0; + + ncr->blt_pat &= ~15; + if (ncr->svga.bpp <= 8) { + ncr->blt_pat &= ~15; + } else if (ncr->svga.bpp == 16) { + if (!ncr->blt_color_expand) { + ncr->blt_src &= ~15; + } + ncr->blt_dst &= ~15; + ncr->blt_pat &= ~31; + } + + ncr->blt_srcbak = ncr->blt_src; + ncr->blt_dstbak = ncr->blt_dst; + ncr->blt_patbak = ncr->blt_pat; + ncr->blt_patbak2 = ncr->blt_pat; + +#if 0 + if (ncr->svga.bpp == 24) { + uint32_t src = ncr->blt_src; + uint32_t dst = ncr->blt_dst; + src >>= 3; + dst >>= 3; + src /= 3; + dst /= 3; + int off = src & 3; + int rgboff = 0; + if (off == 1) { + rgboff = 0; + } else if (off == 2) { + rgboff = 2; + } else if (off == 3) { + rgboff = 1; + } + ncr->blt_patbak = ncr->blt_pat; + ncr->blt_patbak2 = ncr->blt_pat; + + ncr->blt_pat += rgboff << 3; + ncr->blt_patx = rgboff; + } +#endif + + ncr->blt_w = 0; + ncr->blt_h = 0; + blitter_reset_fifo(ncr); + ncr->blt_stage = 0; + +#if 0 + pclog("C=%04x ROP=%02x W=%d H=%d S=%08x/%d P=%08x/%d D=%08x/%d F=%d E=%d DM=%d SM=%d DL=%d SL=%d TR=%d MW=%d DX=%d DY=%d\n", ncr->blt_control, ncr->blt_rop, ncr->blt_width, ncr->blt_height, ncr->blt_src >> 3, ncr->blt_src & 7, ncr->blt_pat >> 3, ncr->blt_pat & 7, @@ -735,31 +796,22 @@ static void blitter_start(ncr_t *ncr) (ncr->blt_control & (1 << 14)) != 0, (ncr->blt_control & (1 << 15)) != 0, (ncr->blt_control & (1 << 5)) != 0, - (ncr->blt_control & (1 << 3)) != 0); + (ncr->blt_control & (1 << 3)) != 0, + (ncr->blt_control & (1 << 7)) != 0, + (ncr->blt_control & (1 << 6)) != 0); #endif ncr->blt_status = 0; if (ncr->blt_start & 2) { - pclog("text blits not implemenented"); + pclog("Blitter: text blits not implemented.\n"); blitter_done(ncr); return; } - ncr->blt_expand_offset = ncr->blt_src & 31; - ncr->blt_expand_bit = 7; - ncr->blt_first_expand = 1; - ncr->blt_srcbak = ncr->blt_src; - ncr->blt_dstbak = ncr->blt_dst; - ncr->blt_patbak = ncr->blt_pat; - ncr->blt_patbak2 = ncr->blt_pat; - ncr->blt_w = 0; - ncr->blt_h = 0; - ncr->blt_fifo_read = 0; - ncr->blt_fifo_write = 0; - ncr->blt_fifo_size = 0; - ncr->blt_fifo_data = 0; - ncr->blt_stage = 0; - ncr->blt_patx = 0; - ncr->blt_paty = 0; - ncr->blt_patdone = 0; + if (!(ncr->blt_control & (1 << 14))) { + pclog("Blitter: destination FIFO reads not implemented.\n"); + blitter_done(ncr); + return; + } + blitter_run(ncr); //activate_debugger(); } @@ -849,7 +901,7 @@ static void ncr_mmio_write_w(uint32_t addr, uint16_t val, void *p) ncr->blt_c0 &= 0x0000ffff; ncr->blt_c0 |= val << 16; break; - case 0x50: // foreground + case 0x50: // background ncr->blt_c1 &= 0xffff0000; ncr->blt_c1 |= val << 0; break; @@ -883,7 +935,7 @@ static uint8_t ncr_mmio_read(uint32_t addr, void *p) case 0x09: // mode control val = ncr->svga.seqregs[0x1e]; break; - case 0x30: + case 0x30: // blt start val = ncr->blt_start; break; case 0x32: // blt status @@ -892,8 +944,6 @@ static uint8_t ncr_mmio_read(uint32_t addr, void *p) default: pclog("blitter read reg %02x\n", reg); break; - - } return val; @@ -932,7 +982,7 @@ static void ncr_writel_linear(uint32_t addr, uint32_t val, void *p) svga_t *svga = (svga_t *)p; ncr_t *ncr = (ncr_t *)svga->p; if (ncr->blt_fifo_write > 0) { - blitter_write_fifo(ncr, val, 2); + blitter_write_fifo(ncr, val); return; } svga_writel_linear(addr, val, p);