Merge pull request #3947 from 86Box/ativga_mode_fixes
More ATI changes plus one IBM 8514/A fix:
This commit is contained in:
@@ -128,6 +128,8 @@ typedef struct svga_t {
|
||||
int hblank_sub;
|
||||
int hblank_end_val;
|
||||
int hblank_end_len;
|
||||
int packed_4bpp;
|
||||
int ati_4color;
|
||||
|
||||
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
|
||||
0MB-1MB - VRAM
|
||||
@@ -287,7 +289,7 @@ extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv);
|
||||
extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv);
|
||||
extern int ibm8514_cpu_src(svga_t *svga);
|
||||
extern int ibm8514_cpu_dest(svga_t *svga);
|
||||
extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len);
|
||||
extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len);
|
||||
extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
|
||||
extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ ibm8514_cpu_dest(svga_t *svga)
|
||||
}
|
||||
|
||||
void
|
||||
ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint16_t val, int len)
|
||||
ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, int len)
|
||||
{
|
||||
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
|
||||
uint8_t nibble = 0;
|
||||
@@ -1298,8 +1298,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
|
||||
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
|
||||
the NOP command)*/
|
||||
if (dev->accel.cmd == 0x53b1 && !cpu_dat)
|
||||
ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix);
|
||||
if (dev->accel.cmd == 0x43b3) {
|
||||
ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frcolor=%02x, bkcolor=%02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_color, bkgd_color, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 0: /*NOP (Short Stroke Vectors)*/
|
||||
@@ -3758,7 +3759,6 @@ bitblt:
|
||||
old_dest_dat = dest_dat;
|
||||
MIX(mix_dat & mix_mask, dest_dat, src_dat);
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
|
||||
if (dev->accel.cmd & 4) {
|
||||
if (dev->accel.sx > 0) {
|
||||
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
|
||||
@@ -4356,6 +4356,7 @@ ibm8514_init(const device_t *info)
|
||||
dev->changedvram = calloc(dev->vram_size >> 12, 1);
|
||||
dev->vram_mask = dev->vram_size - 1;
|
||||
dev->map8 = dev->pallook;
|
||||
dev->local = 0;
|
||||
|
||||
dev->type = info->flags;
|
||||
dev->bpp = 0;
|
||||
|
||||
@@ -186,8 +186,22 @@ ati18800_recalctimings(svga_t *svga)
|
||||
svga->gdcreg[5] &= ~0x40;
|
||||
}
|
||||
|
||||
if (ati18800->regs[0xb0] & 6)
|
||||
if (ati18800->regs[0xb0] & 6) {
|
||||
svga->gdcreg[5] |= 0x40;
|
||||
if ((ati18800->regs[0xb6] & 0x18) >= 0x10)
|
||||
svga->packed_4bpp = 1;
|
||||
else
|
||||
svga->packed_4bpp = 0;
|
||||
} else
|
||||
svga->packed_4bpp = 0;
|
||||
|
||||
if ((ati18800->regs[0xb6] & 0x18) == 8) {
|
||||
svga->hdisp <<= 1;
|
||||
svga->htotal <<= 1;
|
||||
svga->ati_4color = 1;
|
||||
} else
|
||||
svga->ati_4color = 0;
|
||||
|
||||
|
||||
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
@@ -215,8 +229,10 @@ ati18800_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->ma_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -400,7 +400,10 @@ ati28800k_in(uint16_t addr, void *priv)
|
||||
static void
|
||||
ati28800_recalctimings(svga_t *svga)
|
||||
{
|
||||
const ati28800_t *ati28800 = (ati28800_t *) svga->priv;
|
||||
ati28800_t *ati28800 = (ati28800_t *) svga->priv;
|
||||
int clock_sel;
|
||||
|
||||
clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1);
|
||||
|
||||
if (ati28800->regs[0xa3] & 0x10)
|
||||
svga->ma_latch |= 0x10000;
|
||||
@@ -408,66 +411,13 @@ ati28800_recalctimings(svga_t *svga)
|
||||
if (ati28800->regs[0xb0] & 0x40)
|
||||
svga->ma_latch |= 0x20000;
|
||||
|
||||
switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) {
|
||||
case 0x00:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0;
|
||||
break;
|
||||
case 0x01:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0;
|
||||
break;
|
||||
case 0x02:
|
||||
ati28800_log("clock 2\n");
|
||||
break;
|
||||
case 0x03:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0;
|
||||
break;
|
||||
case 0x04:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0;
|
||||
break;
|
||||
case 0x05:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0;
|
||||
break;
|
||||
case 0x06:
|
||||
ati28800_log("clock 2\n");
|
||||
break;
|
||||
case 0x07:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
|
||||
break;
|
||||
case 0x08:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0;
|
||||
break;
|
||||
case 0x09:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0;
|
||||
break;
|
||||
case 0x0A:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0;
|
||||
break;
|
||||
case 0x0B:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0;
|
||||
break;
|
||||
case 0x0C:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0;
|
||||
break;
|
||||
case 0x0D:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0;
|
||||
break;
|
||||
case 0x0E:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0;
|
||||
break;
|
||||
case 0x0F:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ati28800->regs[0xb8] & 0x40)
|
||||
svga->clock *= 2;
|
||||
|
||||
if (ati28800->regs[0xa7] & 0x80)
|
||||
svga->clock *= 3;
|
||||
|
||||
if (ati28800->regs[0xb6] & 0x10) {
|
||||
if ((ati28800->regs[0xb6] & 0x18) >= 0x10) {
|
||||
svga->hdisp <<= 1;
|
||||
svga->htotal <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
@@ -476,10 +426,24 @@ ati28800_recalctimings(svga_t *svga)
|
||||
|
||||
if (ati28800->regs[0xb0] & 0x20) {
|
||||
svga->gdcreg[5] |= 0x40;
|
||||
}
|
||||
if ((ati28800->regs[0xb6] & 0x18) >= 0x10)
|
||||
svga->packed_4bpp = 1;
|
||||
else
|
||||
svga->packed_4bpp = 0;
|
||||
} else
|
||||
svga->packed_4bpp = 0;
|
||||
|
||||
if (!svga->scrblank && svga->attr_palette_enable) {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
if ((ati28800->regs[0xb6] & 0x18) == 8) {
|
||||
svga->hdisp <<= 1;
|
||||
svga->htotal <<= 1;
|
||||
svga->ati_4color = 1;
|
||||
} else
|
||||
svga->ati_4color = 0;
|
||||
|
||||
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
|
||||
ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80);
|
||||
switch (svga->gdcreg[5] & 0x60) {
|
||||
case 0x00:
|
||||
if (svga->seqregs[1] & 8) /*Low res (320)*/
|
||||
@@ -502,8 +466,10 @@ ati28800_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
@@ -516,7 +482,6 @@ ati28800_recalctimings(svga_t *svga)
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -586,6 +551,8 @@ ati28800k_init(const device_t *info)
|
||||
ati28800k_in, ati28800k_out,
|
||||
NULL,
|
||||
NULL);
|
||||
ati28800->svga.clock_gen = device_add(&ati18810_device);
|
||||
ati28800->svga.getclock = ics2494_getclock;
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800);
|
||||
io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800);
|
||||
@@ -652,6 +619,8 @@ ati28800_init(const device_t *info)
|
||||
ati28800_in, ati28800_out,
|
||||
NULL,
|
||||
NULL);
|
||||
ati28800->svga.clock_gen = device_add(&ati18810_device);
|
||||
ati28800->svga.getclock = ics2494_getclock;
|
||||
|
||||
io_sethandler(0x01ce, 2,
|
||||
ati28800_in, NULL, NULL,
|
||||
|
||||
@@ -2579,15 +2579,30 @@ mach_recalctimings(svga_t *svga)
|
||||
if (mach->regs[0xb0] & 0x40)
|
||||
svga->ma_latch |= 0x20000;
|
||||
|
||||
if (mach->regs[0xb6] & 0x10) {
|
||||
if ((mach->regs[0xb6] & 0x18) >= 0x10) {
|
||||
svga->hdisp <<= 1;
|
||||
svga->htotal <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->gdcreg[5] &= ~0x40;
|
||||
}
|
||||
|
||||
if (mach->regs[0xb0] & 0x20)
|
||||
if (mach->regs[0xb0] & 0x20) {
|
||||
svga->gdcreg[5] |= 0x40;
|
||||
if ((mach->regs[0xb6] & 0x18) >= 0x10)
|
||||
svga->packed_4bpp = 1;
|
||||
else
|
||||
svga->packed_4bpp = 0;
|
||||
} else
|
||||
svga->packed_4bpp = 0;
|
||||
|
||||
if ((dev->local & 0xff) < 0x02) {
|
||||
if ((mach->regs[0xb6] & 0x18) == 8) {
|
||||
svga->hdisp <<= 1;
|
||||
svga->htotal <<= 1;
|
||||
svga->ati_4color = 1;
|
||||
} else
|
||||
svga->ati_4color = 0;
|
||||
}
|
||||
|
||||
mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]);
|
||||
if (dev->on[0] || dev->on[1]) {
|
||||
@@ -2606,9 +2621,6 @@ mach_recalctimings(svga_t *svga)
|
||||
if (dev->dispend == 598)
|
||||
dev->dispend += 2;
|
||||
|
||||
if (dev->h_disp == 1024)
|
||||
dev->accel.advfunc_cntl |= 4; /*Bit 2 means high resolution e.g.: 1024x768*/
|
||||
|
||||
if (dev->accel.advfunc_cntl & 4) {
|
||||
if (mach->shadow_set & 2) {
|
||||
if (dev->h_disp == 8) {
|
||||
@@ -2784,8 +2796,10 @@ mach_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->ma_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3628,7 +3642,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
|
||||
case 0x6e8:
|
||||
case 0x6e9:
|
||||
if (!(port & 1)) {
|
||||
if (!dev->on[0] || !dev->on[1])
|
||||
if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0))
|
||||
dev->hdisp = val;
|
||||
else if (!dev->on[0] || !dev->on[1])
|
||||
dev->hdisp = val;
|
||||
|
||||
mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1);
|
||||
@@ -3655,10 +3671,13 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
|
||||
|
||||
case 0x16e8:
|
||||
case 0x16e9:
|
||||
if (!dev->on[0] || !dev->on[1]) {
|
||||
if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) {
|
||||
WRITE8(port, dev->vdisp, val);
|
||||
} else if (!dev->on[0] || !dev->on[1]) {
|
||||
WRITE8(port, dev->vdisp, val);
|
||||
dev->vdisp &= 0x1fff;
|
||||
}
|
||||
dev->vdisp &= 0x1fff;
|
||||
mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", (dev->vdisp >> 1) + 1);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
|
||||
@@ -3848,7 +3867,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
|
||||
case 0x5aef:
|
||||
WRITE8(port, mach->shadow_set, val);
|
||||
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
|
||||
svga_recalctimings(svga);
|
||||
if (mach->shadow_set & 3)
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
|
||||
case 0x5eee:
|
||||
|
||||
@@ -116,6 +116,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint8_t o;
|
||||
uint8_t index;
|
||||
uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f };
|
||||
|
||||
if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed))
|
||||
return;
|
||||
@@ -163,7 +164,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x3c0:
|
||||
case 0x3c1:
|
||||
if (!svga->attrff) {
|
||||
svga->attraddr = val & 31;
|
||||
svga->attraddr = val & 0x1f;
|
||||
if ((val & 0x20) != svga->attr_palette_enable) {
|
||||
svga->fullchange = 3;
|
||||
svga->attr_palette_enable = val & 0x20;
|
||||
@@ -172,19 +173,19 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
} else {
|
||||
if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val))
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
o = svga->attrregs[svga->attraddr & 31];
|
||||
svga->attrregs[svga->attraddr & 31] = val;
|
||||
if (svga->attraddr < 16) {
|
||||
svga->color_2bpp = (val >> 4) & 0x03;
|
||||
o = svga->attrregs[svga->attraddr & 0x1f];
|
||||
svga->attrregs[svga->attraddr & 0x1f] = val;
|
||||
if (svga->attraddr < 0x10)
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
}
|
||||
if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) {
|
||||
for (int c = 0; c < 16; c++) {
|
||||
if (svga->attrregs[0x10] & 0x80) {
|
||||
|
||||
if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) {
|
||||
for (int c = 0; c < 0x10; c++) {
|
||||
if (svga->attrregs[0x10] & 0x80)
|
||||
svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4);
|
||||
} else {
|
||||
else if (svga->ati_4color)
|
||||
svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)];
|
||||
else
|
||||
svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4);
|
||||
}
|
||||
}
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ svga_lookup_lut_ram(svga_t* svga, uint32_t val)
|
||||
{
|
||||
if (!svga->lut_map)
|
||||
return val;
|
||||
|
||||
|
||||
uint8_t r = getcolr(svga->pallook[getcolr(val)]);
|
||||
uint8_t g = getcolg(svga->pallook[getcolg(val)]);
|
||||
uint8_t b = getcolb(svga->pallook[getcolb(val)]);
|
||||
@@ -466,11 +466,12 @@ static void
|
||||
svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
{
|
||||
int x;
|
||||
int xx = 0;
|
||||
uint32_t addr;
|
||||
uint32_t *p;
|
||||
uint32_t changed_offset;
|
||||
|
||||
const bool blinked = svga->blink & 0x10;
|
||||
const bool blinked = !!(svga->blink & 0x10);
|
||||
const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0);
|
||||
|
||||
/*
|
||||
@@ -499,11 +500,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
const uint32_t loadevery = forcepacked ? 1 : (dwordload ? 4 : wordload ? 2 : 1);
|
||||
|
||||
const bool shift4bit = ((svga->gdcreg[0x05] & 0x40) == 0x40) || highres8bpp;
|
||||
const bool shift2bit = ((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit;
|
||||
const bool shift2bit = (((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit);
|
||||
|
||||
const int dwshift = highres ? 0 : 1;
|
||||
const int dotwidth = 1 << dwshift;
|
||||
const int charwidth = dotwidth * (combine8bits ? 4 : 8);
|
||||
const int charwidth = dotwidth * ((combine8bits && !svga->packed_4bpp) ? 4 : 8);
|
||||
const uint32_t planemask = 0x11111111 * (uint32_t) (svga->plane_mask);
|
||||
const uint32_t blinkmask = (attrblink ? 0x88888888 : 0x0);
|
||||
const uint32_t blinkval = (attrblink && blinked ? 0x88888888 : 0x0);
|
||||
@@ -585,8 +586,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
But 4bpp chunky is generally easier to deal with on a modern CPU.
|
||||
shift4bit is the native format for this renderer (4bpp chunky).
|
||||
*/
|
||||
if (!shift4bit) {
|
||||
if (shift2bit) {
|
||||
if (svga->ati_4color || !shift4bit) {
|
||||
if (shift2bit && !svga->ati_4color) {
|
||||
/* Group 2x 2bpp values into 4bpp values */
|
||||
edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC);
|
||||
} else {
|
||||
@@ -637,7 +638,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
*/
|
||||
out_edat = ((out_edat & planemask & ~blinkmask) | ((out_edat | ~planemask) & blinkmask & blinkval)) ^ blinkmask;
|
||||
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
for (int i = 0; i < (8 + (svga->ati_4color ? 8 : 0)); i += (svga->ati_4color ? 4 : 2)) {
|
||||
/*
|
||||
c0 denotes the first 4bpp pixel shifted, while c1 denotes the second.
|
||||
For 8bpp modes, the first 4bpp pixel is the upper 4 bits.
|
||||
@@ -647,12 +648,34 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
uint32_t c1 = (out_edat >> (current_shift & 0x1C)) & 0xF;
|
||||
current_shift >>= 3;
|
||||
|
||||
if (combine8bits) {
|
||||
uint32_t ccombined = (c0 << 4) | c1;
|
||||
uint32_t p0 = svga->map8[ccombined];
|
||||
const int outoffs = (i >> 1) << dwshift;
|
||||
for (int subx = 0; subx < dotwidth; subx++)
|
||||
p[outoffs + subx] = p0;
|
||||
if (svga->ati_4color) {
|
||||
uint32_t q[4];
|
||||
q[0] = svga->pallook[svga->egapal[(c0 & 0x0c) >> 2]];
|
||||
q[1] = svga->pallook[svga->egapal[c0 & 0x03]];
|
||||
q[2] = svga->pallook[svga->egapal[(c1 & 0x0c) >> 2]];
|
||||
q[3] = svga->pallook[svga->egapal[c1 & 0x03]];
|
||||
|
||||
const int outoffs = i << dwshift;
|
||||
for (int ch = 0; ch < 4; ch++) {
|
||||
for (int subx = 0; subx < dotwidth; subx++)
|
||||
p[outoffs + subx + (dotwidth * ch)] = q[ch];
|
||||
}
|
||||
} else if (combine8bits) {
|
||||
if (svga->packed_4bpp) {
|
||||
uint32_t p0 = svga->map8[c0];
|
||||
uint32_t p1 = svga->map8[c1];
|
||||
const int outoffs = i << dwshift;
|
||||
for (int subx = 0; subx < dotwidth; subx++)
|
||||
p[outoffs + subx] = p0;
|
||||
for (int subx = 0; subx < dotwidth; subx++)
|
||||
p[outoffs + subx + dotwidth] = p1;
|
||||
} else {
|
||||
uint32_t ccombined = (c0 << 4) | c1;
|
||||
uint32_t p0 = svga->map8[ccombined];
|
||||
const int outoffs = (i >> 1) << dwshift;
|
||||
for (int subx = 0; subx < dotwidth; subx++)
|
||||
p[outoffs + subx] = p0;
|
||||
}
|
||||
} else {
|
||||
uint32_t p0 = svga->pallook[svga->egapal[c0]];
|
||||
uint32_t p1 = svga->pallook[svga->egapal[c1]];
|
||||
@@ -664,7 +687,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
|
||||
}
|
||||
}
|
||||
|
||||
p += charwidth;
|
||||
if (svga->ati_4color)
|
||||
p += (charwidth << 1);
|
||||
// p += charwidth;
|
||||
else
|
||||
p += charwidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user