Merge pull request #1321 from 86Box/tc1995

Added Tseng specific variants of the GenDAC ramdac (ICS 53x1).
This commit is contained in:
Miran Grča
2021-03-24 03:56:42 +01:00
committed by GitHub
4 changed files with 212 additions and 162 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 =
{