diff --git a/src/vid_ati68860_ramdac.c b/src/vid_ati68860_ramdac.c index 900e0ce..77a4257 100644 --- a/src/vid_ati68860_ramdac.c +++ b/src/vid_ati68860_ramdac.c @@ -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); + } + } +} diff --git a/src/vid_ati68860_ramdac.h b/src/vid_ati68860_ramdac.h index 59c33a5..bf5192c 100644 --- a/src/vid_ati68860_ramdac.h +++ b/src/vid_ati68860_ramdac.h @@ -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); diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 3a8a1f5..36e1620 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -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; diff --git a/src/vid_svga.c b/src/vid_svga.c index 891ef78..d691772 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -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; } diff --git a/src/vid_svga.h b/src/vid_svga.h index 557adb4..8918b2b 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -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); diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index dc4e825..173fe6c 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -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) diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index ad2f7b4..a0115ad 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -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);