diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 8c0ecea0b..ff1a7c985 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -275,4 +275,6 @@ extern const device_t sc1502x_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; +extern const device_t tseng_ics5301_ramdac_device; +extern const device_t tseng_ics5341_ramdac_device; #endif diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 64c92ff63..10b3d7fda 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -96,6 +96,7 @@ typedef struct et4000w32p_t int interleaved; int bank; + int adjust_cursor; /*Accelerator*/ struct @@ -187,6 +188,7 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; uint8_t old; + uint32_t add2addr; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -263,15 +265,15 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) } if (svga->crtcreg == 0x30) { - if (et4000->pci) - { - et4000->linearbase &= 0xc0000000; - et4000->linearbase |= (val & 0xfc) << 22; - } - else - { - et4000->linearbase = val << 22; - } + if (et4000->pci) + { + et4000->linearbase &= 0xc0000000; + et4000->linearbase |= (val & 0xfc) << 22; + } + else + { + et4000->linearbase = val << 22; + } et4000w32p_recalcmapping(et4000); } if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) @@ -285,13 +287,27 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) case 0x210B: case 0x211B: case 0x212B: case 0x213B: case 0x214B: case 0x215B: case 0x216B: case 0x217B: et4000->regs[et4000->index] = val; + svga->hwcursor.xsize = svga->hwcursor.ysize = (et4000->regs[0xEF] & 4) ? 128 : 64; svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); - svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; - svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16; - svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; - svga->hwcursor.xoff = et4000->regs[0xE2] & 63; - svga->hwcursor.yoff = et4000->regs[0xE6] & 63; + svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); + if (svga->hwcursor.xsize == 128) { + svga->hwcursor.xoff = et4000->regs[0xE2] & 0x7f; + svga->hwcursor.yoff = et4000->regs[0xE6] & 0x7f; + } else { + svga->hwcursor.xoff = et4000->regs[0xE2] & 0x3f; + svga->hwcursor.yoff = et4000->regs[0xE6] & 0x3f; + } + svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; + add2addr = svga->hwcursor.yoff * ((svga->hwcursor.xsize == 128) ? 32 : 16); + svga->hwcursor.addr += add2addr; + + if (et4000->type != ET4000W32_DIAMOND) { + if (svga->bpp == 15 || svga->bpp == 16) + svga->hwcursor.x >>= 1; + else if (svga->bpp == 24) + svga->hwcursor.x /= 3; + } return; } @@ -316,7 +332,9 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: if (et4000->type != ET4000W32_DIAMOND) return sdac_ramdac_in(addr, 1, svga->ramdac, svga); - return stg_ramdac_in(addr, svga->ramdac, svga); + else + return stg_ramdac_in(addr, svga->ramdac, svga); + break; case 0x3CB: return et4000->banking2; @@ -401,67 +419,9 @@ void et4000w32p_recalctimings(svga_t *svga) break; } - svga->render = svga_render_blank; - if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) /*40 column*/ - svga->render = svga_render_text_40; - else - svga->render = svga_render_text_80; - } else { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /*256+ colours*/ - if (et4000->type != ET4000W32_DIAMOND) - svga->clock /= 2; - - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 24: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } + if ((svga->gdcreg[5] & 0x60) == 0x40 || (svga->gdcreg[5] & 0x60) == 0x60) { + if (et4000->type != ET4000W32_DIAMOND) + svga->clock /= 2; } } @@ -469,7 +429,7 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000) { svga_t *svga = &et4000->svga; - if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + if (et4000->pci && !(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&et4000->linear_mapping); @@ -1283,28 +1243,32 @@ void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et40 void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { + et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; int x, offset; uint8_t dat; + int pitch = (svga->hwcursor_latch.xsize == 128) ? 32 : 16; 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)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 1] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 1] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 2] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 2] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 3] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 3] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; + for (x = 0; x < (svga->hwcursor_latch.xsize - svga->hwcursor_latch.xoff); x += 4) + { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 1] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 1] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 2] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 2] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 3] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + svga->x_add + x + 3] ^= 0xFFFFFF; + dat >>= 2; + + offset += 4; + } + svga->hwcursor_latch.addr += pitch; } static void et4000w32p_io_remove(et4000w32p_t *et4000) @@ -1434,8 +1398,8 @@ void *et4000w32p_init(const device_t *info) memset(et4000, 0, sizeof(et4000w32p_t)); vram_size = device_get_config_int("memory"); - et4000->interleaved = (vram_size == 2) ? 1 : 0; - + et4000->interleaved = (vram_size == 2 && (info->local >= ET4000W32I)) ? 1 : 0; + if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_pci); else if (info->flags & DEVICE_VLB) @@ -1447,8 +1411,7 @@ void *et4000w32p_init(const device_t *info) et4000w32p_recalctimings, et4000w32p_in, et4000w32p_out, et4000w32p_hwcursor_draw, - NULL); - et4000->svga.hwcursor.ysize = 64; + NULL); et4000->vram_mask = (vram_size << 20) - 1; @@ -1459,7 +1422,7 @@ void *et4000w32p_init(const device_t *info) rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&sdac_ramdac_device); + et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; break; @@ -1468,7 +1431,7 @@ void *et4000w32p_init(const device_t *info) rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&sdac_ramdac_device); + et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; break; @@ -1477,7 +1440,7 @@ void *et4000w32p_init(const device_t *info) rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&sdac_ramdac_device); + et4000->svga.ramdac = device_add(&tseng_ics5341_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; break; @@ -1486,7 +1449,7 @@ void *et4000w32p_init(const device_t *info) rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&sdac_ramdac_device); + et4000->svga.ramdac = device_add(&tseng_ics5341_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; break; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 2a3237e7d..02008c13b 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -196,14 +196,14 @@ typedef struct s3_t uint16_t subsys_cntl; uint16_t setup_md; uint8_t advfunc_cntl; - uint16_t cur_y, cur_y2; - uint16_t cur_x, cur_x2; + uint16_t cur_y, cur_y2, cur_y_bitres; + uint16_t cur_x, cur_x2, cur_x_bitres; uint16_t x2, ropmix; uint16_t pat_x, pat_y; - int16_t desty_axstp, desty_axstp2; - int16_t destx_distp; - int16_t err_term, err_term2; - int16_t maj_axis_pcnt, maj_axis_pcnt2; + int16_t desty_axstp, desty_axstp2; + int16_t destx_distp; + int16_t err_term, err_term2; + int16_t maj_axis_pcnt, maj_axis_pcnt2; uint16_t cmd, cmd2; uint16_t short_stroke; uint32_t pat_bg_color, pat_fg_color; @@ -234,6 +234,7 @@ typedef struct s3_t uint32_t dat_buf; int dat_count; int b2e8_pix, temp_cnt; + uint8_t cur_x_bit12, cur_y_bit12; } accel; struct { @@ -533,11 +534,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) switch (port) { case 0x8148: case 0x82e8: + s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x8149: case 0x82e9: - s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); + s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_y_bit12 = val & 0x10; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: case 0x82ea: @@ -545,17 +549,20 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_cy2 = s3->accel.cur_y2; break; case 0x814b: case 0x82eb: - s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cy2 = s3->accel.cur_y2; break; case 0x8548: case 0x86e8: + s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x8549: case 0x86e9: - s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); + s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_x_bit12 = val & 0x10; s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; @@ -564,7 +571,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; case 0x854b: case 0x86eb: - s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; @@ -604,7 +611,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.point_2_updated = 1; break; case 0x8d4b: case 0x8eeb: - s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0xf) << 8); + s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0x0f) << 8); s3->accel.point_2_updated = 1; break; @@ -4425,12 +4432,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -4561,8 +4566,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0xe0: s3->accel.cx++; break; } } else { - if (s3->accel.cmd & 4) - s3->accel.err_term += s3->accel.desty_axstp; + s3->accel.err_term += s3->accel.desty_axstp; } /*Step major axis*/ @@ -4593,9 +4597,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bit12) { + if (s3->accel.cy <= 0x7ff) { + s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; + } else { + s3->accel.cy |= ~0xfff; + } + } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -4820,11 +4837,37 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy = s3->accel.desty_axstp & 0xfff; if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.dx >= 0xfffff000) { /* avoid overflow */ + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bitres > 0xfff) + s3->accel.cy = s3->accel.cur_y_bitres; + } else { + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { /* overlap x */ + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { /* x end is negative */ + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bit12) { + if (s3->accel.cy <= 0x7ff) { /* overlap y */ + s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; + } else { /* y end is negative */ + s3->accel.cy |= ~0xfff; + } + } + } + s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; } @@ -4838,12 +4881,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && - (s3->accel.bkgd_mix & 0xf) == 7) + (s3->accel.bkgd_mix & 0xf) == 7) { while (1) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) + if (((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { READ(s3->accel.src + s3->accel.cx, src_dat); READ(s3->accel.dest + s3->accel.dx, dest_dat); @@ -4852,7 +4895,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ WRITE(s3->accel.dest + s3->accel.dx, dest_dat); } - + s3->accel.cx++; s3->accel.dx++; s3->accel.sx--; @@ -4877,13 +4920,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } } else - { + { while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) + if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && + ((s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b)) { - if (vram_mask) + if (vram_mask && (s3->accel.cmd & 0x10)) { READ(s3->accel.src + s3->accel.cx, mix_dat); mix_dat = ((mix_dat & rd_mask) == rd_mask); @@ -4894,8 +4937,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0: src_dat = s3->accel.bkgd_color; break; case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); - if (vram_mask) + case 3: READ(s3->accel.src + s3->accel.cx, src_dat); + if (vram_mask && (s3->accel.cmd & 0x10)) src_dat = ((src_dat & rd_mask) == rd_mask); break; } @@ -4981,9 +5024,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; @@ -5002,7 +5045,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { if (vram_mask) @@ -5075,8 +5118,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; } - s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = dstbase + s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -5103,10 +5146,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; } @@ -5290,9 +5333,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.px = s3->accel.pat_x & 0xfff; if (s3->accel.pat_x & 0x1000) s3->accel.px |= ~0xfff; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 5eb2d98dd..d682fca0d 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -46,22 +46,47 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) switch (val >> 4) { case 0x2: case 0x3: + svga->bpp = 15; + break; case 0xa: + if (ramdac->type == 2) + svga->bpp = 16; + else + svga->bpp = 15; + break; case 0x8: svga->bpp = 15; break; case 0x4: case 0x9: - case 0xe: svga->bpp = 24; break; + case 0xe: + if (ramdac->type == 1) + svga->bpp = 16; + else + svga->bpp = 24; + break; case 0x5: - case 0x6: - case 0xc: svga->bpp = 16; break; + case 0x6: + if (ramdac->type == 1) + svga->bpp = 24; + else + svga->bpp = 16; + break; + case 0xc: + if (ramdac->type == 1) + svga->bpp = 15; + else + svga->bpp = 16; + break; case 0x7: - svga->bpp = 32; + if (ramdac->type == 1) + svga->bpp = 24; + else + svga->bpp = 32; break; case 0x0: case 0x1: @@ -69,6 +94,8 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) svga->bpp = 8; break; } + + pclog("BPP = %i, val = %x, type = %i\n", svga->bpp, val >> 4, ramdac->type); } @@ -111,7 +138,7 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); - if ((rs >= 0x04) || (ramdac->type == 7)) switch (rs) { + if ((rs >= 0x04) || (ramdac->type == 7) || (ramdac->type == 1) || (ramdac->type == 2)) switch (rs) { case 0x02: if (ramdac->magic_count == 4) sdac_control_write(ramdac, svga, val); @@ -149,19 +176,19 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); - if ((rs < 0x04) && (ramdac->type != 7)) + if ((rs < 0x04) && (ramdac->type != 7) && (ramdac->type != 1) && (ramdac->type != 2)) temp = svga_in(addr, svga); else switch (rs) { case 0x02: - if (ramdac->magic_count < 5) - ramdac->magic_count++; - if (ramdac->magic_count == 4) - temp = 0x70; /*SDAC ID*/ - else if (ramdac->magic_count == 5) { - temp = ramdac->command; - ramdac->magic_count = 0; - } else - temp = svga_in(addr, svga); + if (ramdac->magic_count < 5) + ramdac->magic_count++; + if ((ramdac->magic_count == 4) && (ramdac->type != 1) && (ramdac->type != 2)) + temp = 0x70; /*SDAC ID*/ + else if (ramdac->magic_count == 5) { + temp = ramdac->command; + ramdac->magic_count = 0; + } else + temp = svga_in(addr, svga); break; case 0x00: case 0x01: @@ -247,6 +274,21 @@ const device_t gendac_ramdac_device = NULL, { NULL }, NULL, NULL }; +const device_t tseng_ics5301_ramdac_device = +{ + "Tseng ICS5301 GENDAC RAMDAC", + 0, 1, + sdac_ramdac_init, sdac_ramdac_close, + NULL, { NULL }, NULL, NULL +}; + +const device_t tseng_ics5341_ramdac_device = +{ + "Tseng ICS5341 GENDAC RAMDAC", + 0, 2, + sdac_ramdac_init, sdac_ramdac_close, + NULL, { NULL }, NULL, NULL +}; const device_t sdac_ramdac_device = {