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:
parent
a151e90aeb
commit
b39eb20237
7 changed files with 164 additions and 24 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue