MGA: Implement BPLAN for BITBLT operations
This commit is contained in:
@@ -315,6 +315,7 @@
|
||||
#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT)
|
||||
#define DWGCTRL_BLTMOD_MASK (0xf << 25)
|
||||
#define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25)
|
||||
#define DWGCTRL_BLTMOD_BPLAN (0x1 << 25)
|
||||
#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25)
|
||||
#define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25)
|
||||
#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25)
|
||||
@@ -5371,6 +5372,91 @@ blit_bitblt(mystique_t *mystique)
|
||||
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) {
|
||||
case DWGCTRL_ATYPE_BLK:
|
||||
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) {
|
||||
/* TODO: This isn't exactly perfect. */
|
||||
case DWGCTRL_BLTMOD_BPLAN:
|
||||
if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN)
|
||||
fatal("BITBLT RPL/RSTR BPLAN with pattern\n");
|
||||
|
||||
src_addr = mystique->dwgreg.ar[3];
|
||||
|
||||
for (y = 0; y < mystique->dwgreg.length; y++) {
|
||||
uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4];
|
||||
int16_t x = x_start;
|
||||
|
||||
while (1) {
|
||||
uint32_t byte_addr = src_addr & mystique->vram_mask;
|
||||
|
||||
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) {
|
||||
uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol;
|
||||
uint32_t dst;
|
||||
uint32_t old_dst;
|
||||
|
||||
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
|
||||
case MACCESS_PWIDTH_8:
|
||||
dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask];
|
||||
|
||||
dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);
|
||||
|
||||
svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst;
|
||||
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount;
|
||||
break;
|
||||
|
||||
case MACCESS_PWIDTH_16:
|
||||
dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w];
|
||||
|
||||
dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);
|
||||
|
||||
((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst;
|
||||
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount;
|
||||
break;
|
||||
|
||||
case MACCESS_PWIDTH_24:
|
||||
old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask];
|
||||
|
||||
dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK
|
||||
|
||||
*(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000);
|
||||
svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount;
|
||||
break;
|
||||
|
||||
case MACCESS_PWIDTH_32:
|
||||
dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l];
|
||||
|
||||
dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);
|
||||
|
||||
((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst;
|
||||
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running);
|
||||
}
|
||||
}
|
||||
|
||||
if (src_addr == mystique->dwgreg.ar[0]) {
|
||||
mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5];
|
||||
mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5];
|
||||
src_addr = mystique->dwgreg.ar[3];
|
||||
} else
|
||||
src_addr += x_dir;
|
||||
|
||||
if (x != x_end) {
|
||||
if ((x > x_end) && (x_dir == 1))
|
||||
x--;
|
||||
else if ((x < x_end) && (x_dir == -1))
|
||||
x++;
|
||||
else
|
||||
x += x_dir;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (mystique->dwgreg.sgn.sdy)
|
||||
mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK);
|
||||
else
|
||||
mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK);
|
||||
}
|
||||
break;
|
||||
case DWGCTRL_BLTMOD_BMONOLEF:
|
||||
case DWGCTRL_BLTMOD_BMONOWF:
|
||||
src_addr = mystique->dwgreg.ar[3];
|
||||
|
Reference in New Issue
Block a user