Mach64 fixes :

- Added support for 8-bit RAMDAC mode
- Added ABGR8888 mode
- Add support for mono blitter source
- Identify RAMDAC type correctly
- Use correct colours for hardware cursor
Fixes issues in Corel Linux.
This commit is contained in:
SarahW 2016-05-08 20:41:51 +01:00
commit b39eb20237
7 changed files with 164 additions and 24 deletions

View file

@ -46,6 +46,37 @@ void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac,
ramdac->regs[addr & 0xf] = val;
switch (addr & 0xf)
{
case 0x4:
ramdac->dac_write = val;
ramdac->dac_pos = 0;
break;
case 0x5:
switch (ramdac->dac_pos)
{
case 0:
ramdac->dac_r = val;
ramdac->dac_pos++;
break;
case 1:
ramdac->dac_g = val;
ramdac->dac_pos++;
break;
case 2:
if (ramdac->dac_write > 1)
break;
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
ramdac->pal[ramdac->dac_write].b = val;
if (ramdac->ramdac_type == RAMDAC_8BIT)
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
else
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
ramdac->dac_pos = 0;
ramdac->dac_write = (ramdac->dac_write + 1) & 255;
break;
}
break;
case 0xb:
switch (val)
{
@ -67,6 +98,9 @@ void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac,
case 0xe2: case 0xf7:
ramdac->render = svga_render_32bpp_highres;
break;
case 0xe3:
ramdac->render = svga_render_ABGR8888_highres;
break;
case 0xf2:
ramdac->render = svga_render_RGBA8888_highres;
break;
@ -75,6 +109,9 @@ void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac,
break;
}
break;
case 0xc:
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
break;
}
break;
}
@ -119,3 +156,21 @@ void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
{
ramdac->render = svga_render_8bpp_highres;
}
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
{
int c;
if (ramdac->ramdac_type != type)
{
ramdac->ramdac_type = type;
for (c = 0; c < 2; c++)
{
if (ramdac->ramdac_type == RAMDAC_8BIT)
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b);
else
ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4);
}
}
}

View file

@ -2,8 +2,16 @@ typedef struct ati68860_ramdac_t
{
uint8_t regs[16];
void (*render)(struct svga_t *svga);
int dac_write, dac_pos;
int dac_r, dac_g;
PALETTE pal;
uint32_t pallook[2];
int ramdac_type;
} ati68860_ramdac_t;
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga);
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga);
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac);
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type);

View file

@ -1116,6 +1116,13 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
int mix;
int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff;
int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff;
int src_x;
int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff;
if (mach64->src_cntl & SRC_LINEAR_EN)
src_x = mach64->accel.src_x;
else
src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff;
if (mach64->accel.source_host)
{
@ -1156,17 +1163,23 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
mix = mach64->accel.pattern[dst_y & 7][dst_x & 7];
break;
case MONO_SRC_1:
default:
mix = 1;
break;
case MONO_SRC_BLITSRC:
if (mach64->src_cntl & SRC_LINEAR_EN)
{
READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT);
}
else
{
READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT);
}
break;
}
if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right &&
dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom)
{
int src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff;
int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff;
{
switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
{
case SRC_HOST:
@ -1242,24 +1255,27 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (mach64->accel.x_count <= 0)
{
mach64->accel.x_count = mach64->accel.dst_width;
mach64->accel.src_x = 0;
mach64->accel.dst_x = 0;
mach64->accel.dst_y += mach64->accel.yinc;
mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
mach64->accel.src_x_count = mach64->accel.src_width1;
mach64->accel.src_y += mach64->accel.yinc;
mach64->accel.dst_y += mach64->accel.yinc;
mach64->accel.src_y_count--;
if (mach64->accel.src_y_count <= 0)
if (!(mach64->src_cntl & SRC_LINEAR_EN))
{
mach64->accel.src_y = 0;
if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
mach64->accel.src_x = 0;
mach64->accel.src_y += mach64->accel.yinc;
mach64->accel.src_y_count--;
if (mach64->accel.src_y_count <= 0)
{
mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff;
mach64->accel.src_y_count = mach64->accel.src_height2;
mach64->accel.src_y = 0;
if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN))
{
mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff;
mach64->accel.src_y_count = mach64->accel.src_height2;
}
else
mach64->accel.src_y_count = mach64->accel.src_height1;
}
else
mach64->accel.src_y_count = mach64->accel.src_height1;
}
mach64->accel.poly_draw = 0;
@ -1997,6 +2013,8 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
break;
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
WRITE8(addr, mach64->dac_cntl, val);
svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT);
ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT);
break;
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
@ -2167,6 +2185,9 @@ uint8_t mach64_ext_inb(uint16_t port, void *p)
else
ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/
break;
case 0x72ed:
ret = 5 << 1; /*ATI-68860*/
break;
default:
ret = 0;
@ -2388,22 +2409,26 @@ uint8_t mach64_read(uint32_t addr, void *p)
void mach64_hwcursor_draw(svga_t *svga, int displine)
{
mach64_t *mach64 = (mach64_t *)svga->p;
int x, offset;
uint8_t dat;
uint32_t col0 = mach64->ramdac.pallook[0];
uint32_t col1 = mach64->ramdac.pallook[1];
offset = svga->hwcursor_latch.xoff;
for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
{
dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? col1 : col0;
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
dat >>= 2;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? col1 : col0;
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
dat >>= 2;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? col1 : col0;
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
dat >>= 2;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0;
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? col1 : col0;
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
dat >>= 2;
offset += 4;

View file

@ -142,18 +142,21 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
switch (svga->dac_pos)
{
case 0:
svga->dac_r = val & 63;
svga->dac_r = val;
svga->dac_pos++;
break;
case 1:
svga->dac_g = val & 63;
svga->dac_g = val;
svga->dac_pos++;
break;
case 2:
svga->vgapal[svga->dac_write].r = svga->dac_r;
svga->vgapal[svga->dac_write].g = svga->dac_g;
svga->vgapal[svga->dac_write].b = val & 63;
svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4);
svga->vgapal[svga->dac_write].b = val;
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b);
else
svga->pallook[svga->dac_write] = makecol32((svga->vgapal[svga->dac_write].r & 0x3f) * 4, (svga->vgapal[svga->dac_write].g & 0x3f) * 4, (svga->vgapal[svga->dac_write].b & 0x3f) * 4);
svga->dac_pos = 0;
svga->dac_write = (svga->dac_write + 1) & 255;
break;
@ -267,6 +270,24 @@ uint8_t svga_in(uint16_t addr, void *p)
return 0xFF;
}
void svga_set_ramdac_type(svga_t *svga, int type)
{
int c;
if (svga->ramdac_type != type)
{
svga->ramdac_type = type;
for (c = 0; c < 256; c++)
{
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, (svga->vgapal[c].g & 0x3f) * 4, (svga->vgapal[c].b & 0x3f) * 4);
}
}
}
void svga_recalctimings(svga_t *svga)
{
double crtcconst;
@ -719,6 +740,8 @@ int svga_init(svga_t *svga, void *p, int memsize,
svga_pri = svga;
svga->ramdac_type = RAMDAC_6BIT;
return 0;
}

View file

@ -39,6 +39,8 @@ typedef struct svga_t
uint8_t egapal[16];
uint32_t pallook[256];
PALETTE vgapal;
int ramdac_type;
int vtotal, dispend, vsyncstart, split, vblankstart;
int hdisp, hdisp_old, htotal, hdisp_time, rowoffset;
@ -142,3 +144,7 @@ uint8_t svga_in(uint16_t addr, void *p);
svga_t *svga_get_pri();
void svga_set_override(svga_t *svga, int val);
#define RAMDAC_6BIT 0
#define RAMDAC_8BIT 1
void svga_set_ramdac_type(svga_t *svga, int type);

View file

@ -638,6 +638,28 @@ void svga_render_32bpp_highres(svga_t *svga)
}
}
void svga_render_ABGR8888_highres(svga_t *svga)
{
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++)
{
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]);
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
}
svga->ma += 4;
svga->ma &= svga->vrammask;
}
}
void svga_render_RGBA8888_highres(svga_t *svga)
{
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)

View file

@ -27,6 +27,7 @@ void svga_render_24bpp_lowres(svga_t *svga);
void svga_render_24bpp_highres(svga_t *svga);
void svga_render_32bpp_lowres(svga_t *svga);
void svga_render_32bpp_highres(svga_t *svga);
void svga_render_ABGR8888_highres(svga_t *svga);
void svga_render_RGBA8888_highres(svga_t *svga);
extern void (*svga_render)(svga_t *svga);