Added correct clock support for S3 Trio64 (Number Nine 9FX).
Seperated TGUI9440 and TVGA8900D implementations. Modes > 8 bpp now handled more logically in SVGA core. Fixed broken status window for most SVGA cards. Masking of address on 'legacy' VGA memory ranges now handled better.
This commit is contained in:
parent
c79d161b2b
commit
a8b286a2ec
21 changed files with 1382 additions and 937 deletions
|
|
@ -17,7 +17,7 @@ OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
|
||||||
vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
|
vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
|
||||||
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
|
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
|
||||||
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
||||||
vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
||||||
vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-ddraw.o win-keyboard.o win-midi.o \
|
vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-ddraw.o win-keyboard.o win-midi.o \
|
||||||
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
|
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||||
FMOBJ = fmopl.o ymf262.o
|
FMOBJ = fmopl.o ymf262.o
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,13 @@ void ati18800_force_redraw(void *p)
|
||||||
ati18800->svga.fullchange = changeframecount;
|
ati18800->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ati18800_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &ati18800->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t ati18800_device =
|
device_t ati18800_device =
|
||||||
{
|
{
|
||||||
"ATI-18800",
|
"ATI-18800",
|
||||||
|
|
@ -168,6 +175,6 @@ device_t ati18800_device =
|
||||||
NULL,
|
NULL,
|
||||||
ati18800_speed_changed,
|
ati18800_speed_changed,
|
||||||
ati18800_force_redraw,
|
ati18800_force_redraw,
|
||||||
svga_add_status_info
|
ati18800_add_status_info
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,13 @@ void ati28800_force_redraw(void *p)
|
||||||
ati28800->svga.fullchange = changeframecount;
|
ati28800->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ati28800_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
ati28800_t *ati28800 = (ati28800_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &ati28800->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t ati28800_device =
|
device_t ati28800_device =
|
||||||
{
|
{
|
||||||
"ATI-28800",
|
"ATI-28800",
|
||||||
|
|
@ -189,5 +196,5 @@ device_t ati28800_device =
|
||||||
NULL,
|
NULL,
|
||||||
ati28800_speed_changed,
|
ati28800_speed_changed,
|
||||||
ati28800_force_redraw,
|
ati28800_force_redraw,
|
||||||
svga_add_status_info
|
ati28800_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -336,21 +336,25 @@ void mach64_updatemapping(mach64_t *mach64)
|
||||||
mem_mapping_set_p(&mach64->svga.mapping, mach64);
|
mem_mapping_set_p(&mach64->svga.mapping, mach64);
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
mem_mapping_enable(&mach64->mmio_mapping);
|
mem_mapping_enable(&mach64->mmio_mapping);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
|
mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
|
||||||
mem_mapping_set_p(&mach64->svga.mapping, mach64);
|
mem_mapping_set_p(&mach64->svga.mapping, mach64);
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||||
mem_mapping_set_p(&mach64->svga.mapping, svga);
|
mem_mapping_set_p(&mach64->svga.mapping, svga);
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||||
mem_mapping_set_p(&mach64->svga.mapping, svga);
|
mem_mapping_set_p(&mach64->svga.mapping, svga);
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mach64->linear_base)
|
if (mach64->linear_base)
|
||||||
|
|
@ -2081,6 +2085,13 @@ void mach64_force_redraw(void *p)
|
||||||
mach64->svga.fullchange = changeframecount;
|
mach64->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mach64_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
mach64_t *mach64 = (mach64_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &mach64->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t mach64gx_device =
|
device_t mach64gx_device =
|
||||||
{
|
{
|
||||||
"ATI Mach64GX",
|
"ATI Mach64GX",
|
||||||
|
|
@ -2089,5 +2100,5 @@ device_t mach64gx_device =
|
||||||
NULL,
|
NULL,
|
||||||
mach64_speed_changed,
|
mach64_speed_changed,
|
||||||
mach64_force_redraw,
|
mach64_force_redraw,
|
||||||
svga_add_status_info
|
mach64_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ typedef struct gd5429_t
|
||||||
svga_t svga;
|
svga_t svga;
|
||||||
|
|
||||||
uint32_t bank[2];
|
uint32_t bank[2];
|
||||||
|
uint32_t mask;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
@ -228,19 +229,23 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
mem_mapping_disable(&gd5429->mmio_mapping);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
if (svga->seqregs[0x17] & 0x04)
|
if (svga->seqregs[0x17] & 0x04)
|
||||||
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
|
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
mem_mapping_disable(&gd5429->mmio_mapping);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
mem_mapping_disable(&gd5429->mmio_mapping);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +299,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p);
|
||||||
void gd5429_write(uint32_t addr, uint8_t val, void *p)
|
void gd5429_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
gd5429_t *gd5429 = (gd5429_t *)p;
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
svga_t *svga = &gd5429->svga;
|
||||||
// pclog("gd5429_write : %05X %02X ", addr, val);
|
// pclog("gd5429_write : %05X %02X ", addr, val);
|
||||||
|
addr &= svga->banked_mask;
|
||||||
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
|
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
|
||||||
// pclog("%08X\n", addr);
|
// pclog("%08X\n", addr);
|
||||||
gd5429_write_linear(addr, val, p);
|
gd5429_write_linear(addr, val, p);
|
||||||
|
|
@ -303,8 +310,10 @@ void gd5429_write(uint32_t addr, uint8_t val, void *p)
|
||||||
uint8_t gd5429_read(uint32_t addr, void *p)
|
uint8_t gd5429_read(uint32_t addr, void *p)
|
||||||
{
|
{
|
||||||
gd5429_t *gd5429 = (gd5429_t *)p;
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
svga_t *svga = &gd5429->svga;
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
// pclog("gd5429_read : %05X ", addr);
|
// pclog("gd5429_read : %05X ", addr);
|
||||||
|
addr &= svga->banked_mask;
|
||||||
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
|
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
|
||||||
ret = svga_read_linear(addr, &gd5429->svga);
|
ret = svga_read_linear(addr, &gd5429->svga);
|
||||||
// pclog("%08X %02X\n", addr, ret);
|
// pclog("%08X %02X\n", addr, ret);
|
||||||
|
|
@ -850,6 +859,13 @@ void gd5429_force_redraw(void *p)
|
||||||
gd5429->svga.fullchange = changeframecount;
|
gd5429->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gd5429_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &gd5429->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t gd5429_device =
|
device_t gd5429_device =
|
||||||
{
|
{
|
||||||
"Cirrus Logic GD5429",
|
"Cirrus Logic GD5429",
|
||||||
|
|
@ -858,5 +874,5 @@ device_t gd5429_device =
|
||||||
NULL,
|
NULL,
|
||||||
gd5429_speed_changed,
|
gd5429_speed_changed,
|
||||||
gd5429_force_redraw,
|
gd5429_force_redraw,
|
||||||
svga_add_status_info
|
gd5429_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,15 @@ void et4000_recalctimings(svga_t *svga)
|
||||||
default: svga->clock = cpuclock / 36000000.0; break;
|
default: svga->clock = cpuclock / 36000000.0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (svga->bpp)
|
||||||
|
{
|
||||||
|
case 15: case 16:
|
||||||
|
svga->hdisp /= 2;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
svga->hdisp /= 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *et4000_init()
|
void *et4000_init()
|
||||||
|
|
@ -154,6 +163,13 @@ void et4000_force_redraw(void *p)
|
||||||
et4000->svga.fullchange = changeframecount;
|
et4000->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int et4000_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
et4000_t *et4000 = (et4000_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &et4000->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t et4000_device =
|
device_t et4000_device =
|
||||||
{
|
{
|
||||||
"Tseng Labs ET4000AX",
|
"Tseng Labs ET4000AX",
|
||||||
|
|
@ -162,5 +178,5 @@ device_t et4000_device =
|
||||||
NULL,
|
NULL,
|
||||||
et4000_speed_changed,
|
et4000_speed_changed,
|
||||||
et4000_force_redraw,
|
et4000_force_redraw,
|
||||||
svga_add_status_info
|
et4000_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ void et4000w32p_recalctimings(svga_t *svga)
|
||||||
svga->hdisp >>= 1;
|
svga->hdisp >>= 1;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
svga->hdisp /= 8;
|
svga->hdisp /= 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -277,30 +277,37 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000)
|
||||||
case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
|
case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
mem_mapping_disable(&et4000->mmu_mapping);
|
mem_mapping_disable(&et4000->mmu_mapping);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x1: /*64k at A0000*/
|
case 0x1: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
mem_mapping_disable(&et4000->mmu_mapping);
|
mem_mapping_disable(&et4000->mmu_mapping);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x2: /*32k at B0000*/
|
case 0x2: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
mem_mapping_disable(&et4000->mmu_mapping);
|
mem_mapping_disable(&et4000->mmu_mapping);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0x3: /*32k at B8000*/
|
case 0x3: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
mem_mapping_disable(&et4000->mmu_mapping);
|
mem_mapping_disable(&et4000->mmu_mapping);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/
|
case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/
|
case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
|
mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/
|
case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
|
mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -983,6 +990,13 @@ void et4000w32p_force_redraw(void *p)
|
||||||
et4000w32p->svga.fullchange = changeframecount;
|
et4000w32p->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int et4000w32p_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
et4000w32p_t *et4000w32p = (et4000w32p_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &et4000w32p->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t et4000w32p_device =
|
device_t et4000w32p_device =
|
||||||
{
|
{
|
||||||
"Tseng Labs ET4000/w32p",
|
"Tseng Labs ET4000/w32p",
|
||||||
|
|
@ -991,5 +1005,5 @@ device_t et4000w32p_device =
|
||||||
NULL,
|
NULL,
|
||||||
et4000w32p_speed_changed,
|
et4000w32p_speed_changed,
|
||||||
et4000w32p_force_redraw,
|
et4000w32p_force_redraw,
|
||||||
svga_add_status_info
|
et4000w32p_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,13 @@ void oti067_force_redraw(void *p)
|
||||||
oti067->svga.fullchange = changeframecount;
|
oti067->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int oti067_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
oti067_t *oti067 = (oti067_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &oti067->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t oti067_device =
|
device_t oti067_device =
|
||||||
{
|
{
|
||||||
"Oak OTI-067",
|
"Oak OTI-067",
|
||||||
|
|
@ -157,5 +164,5 @@ device_t oti067_device =
|
||||||
NULL,
|
NULL,
|
||||||
oti067_speed_changed,
|
oti067_speed_changed,
|
||||||
oti067_force_redraw,
|
oti067_force_redraw,
|
||||||
svga_add_status_info
|
oti067_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -70,15 +70,19 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -331,6 +335,13 @@ void paradise_force_redraw(void *p)
|
||||||
paradise->svga.fullchange = changeframecount;
|
paradise->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int paradise_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
paradise_t *paradise = (paradise_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, ¶dise->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t paradise_pvga1a_device =
|
device_t paradise_pvga1a_device =
|
||||||
{
|
{
|
||||||
"Paradise PVGA1A",
|
"Paradise PVGA1A",
|
||||||
|
|
@ -339,7 +350,7 @@ device_t paradise_pvga1a_device =
|
||||||
NULL,
|
NULL,
|
||||||
paradise_speed_changed,
|
paradise_speed_changed,
|
||||||
paradise_force_redraw,
|
paradise_force_redraw,
|
||||||
svga_add_status_info
|
paradise_add_status_info
|
||||||
};
|
};
|
||||||
device_t paradise_wd90c11_device =
|
device_t paradise_wd90c11_device =
|
||||||
{
|
{
|
||||||
|
|
@ -349,5 +360,5 @@ device_t paradise_wd90c11_device =
|
||||||
NULL,
|
NULL,
|
||||||
paradise_speed_changed,
|
paradise_speed_changed,
|
||||||
paradise_force_redraw,
|
paradise_force_redraw,
|
||||||
svga_add_status_info
|
paradise_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
78
src/vid_s3.c
78
src/vid_s3.c
|
|
@ -28,6 +28,9 @@ typedef struct s3_t
|
||||||
|
|
||||||
uint32_t linear_base, linear_size;
|
uint32_t linear_base, linear_size;
|
||||||
|
|
||||||
|
float (*getclock)(int clock, void *p);
|
||||||
|
void *getclock_p;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t subsys_cntl;
|
uint8_t subsys_cntl;
|
||||||
|
|
@ -85,6 +88,16 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
|
if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20)
|
||||||
|
{
|
||||||
|
svga->seqregs[svga->seqaddr] = val;
|
||||||
|
switch (svga->seqaddr)
|
||||||
|
{
|
||||||
|
case 0x12: case 0x13:
|
||||||
|
svga_recalctimings(svga);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (svga->seqaddr == 4) /*Chain-4 - update banking*/
|
if (svga->seqaddr == 4) /*Chain-4 - update banking*/
|
||||||
{
|
{
|
||||||
if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16;
|
if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16;
|
||||||
|
|
@ -213,6 +226,11 @@ uint8_t s3_in(uint16_t addr, void *p)
|
||||||
// if (addr != 0x3da) pclog("S3 in %04X\n", addr);
|
// if (addr != 0x3da) pclog("S3 in %04X\n", addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x3c5:
|
||||||
|
if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20)
|
||||||
|
return svga->seqregs[svga->seqaddr];
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
|
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
|
||||||
// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc);
|
// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc);
|
||||||
return sdac_ramdac_in(addr, &s3->ramdac, svga);
|
return sdac_ramdac_in(addr, &s3->ramdac, svga);
|
||||||
|
|
@ -260,9 +278,14 @@ void s3_recalctimings(svga_t *svga)
|
||||||
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
|
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
|
||||||
if (!svga->rowoffset) svga->rowoffset = 256;
|
if (!svga->rowoffset) svga->rowoffset = 256;
|
||||||
svga->interlace = svga->crtc[0x42] & 0x20;
|
svga->interlace = svga->crtc[0x42] & 0x20;
|
||||||
svga->clock = cpuclock / sdac_getclock((svga->miscout >> 2) & 3, &s3->ramdac);
|
svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p);
|
||||||
// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock);
|
|
||||||
if (svga->bpp > 8) svga->clock /= 2;
|
switch (svga->crtc[0x67] >> 4)
|
||||||
|
{
|
||||||
|
case 3: case 5: case 7:
|
||||||
|
svga->clock /= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
|
svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
|
||||||
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
|
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
|
||||||
|
|
@ -274,23 +297,23 @@ void s3_recalctimings(svga_t *svga)
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
svga->render = svga_render_15bpp_highres;
|
svga->render = svga_render_15bpp_highres;
|
||||||
|
svga->hdisp /= 2;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
svga->render = svga_render_16bpp_highres;
|
svga->render = svga_render_16bpp_highres;
|
||||||
|
svga->hdisp /= 2;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
svga->render = svga_render_24bpp_highres;
|
svga->render = svga_render_24bpp_highres;
|
||||||
|
svga->hdisp /= 3;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
svga->render = svga_render_32bpp_highres;
|
svga->render = svga_render_32bpp_highres;
|
||||||
if (gfxcard == GFX_N9_9FX) /*Trio64*/
|
if (gfxcard != GFX_N9_9FX) /*Trio64*/
|
||||||
svga->hdisp *= 4;
|
svga->hdisp /= 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (svga->bpp == 32) svga->hdisp *= 3;
|
|
||||||
// pclog("svga->hdisp %i %02X %i\n", svga->hdisp, svga->crtc[0x5d], svga->hdisp_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void s3_updatemapping(s3_t *s3)
|
void s3_updatemapping(s3_t *s3)
|
||||||
|
|
@ -305,15 +328,19 @@ void s3_updatemapping(s3_t *s3)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,6 +372,7 @@ void s3_updatemapping(s3_t *s3)
|
||||||
{
|
{
|
||||||
mem_mapping_disable(&s3->linear_mapping);
|
mem_mapping_disable(&s3->linear_mapping);
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
// mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000);
|
// mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -360,6 +388,23 @@ void s3_updatemapping(s3_t *s3)
|
||||||
mem_mapping_disable(&s3->mmio_mapping);
|
mem_mapping_disable(&s3->mmio_mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float s3_trio64_getclock(int clock, void *p)
|
||||||
|
{
|
||||||
|
s3_t *s3 = (s3_t *)p;
|
||||||
|
svga_t *svga = &s3->svga;
|
||||||
|
float t;
|
||||||
|
int m, n1, n2;
|
||||||
|
// pclog("Trio64_getclock %i %02X %02X\n", clock, svga->seqregs[0x13], svga->seqregs[0x12]);
|
||||||
|
if (clock == 0) return 25175000.0;
|
||||||
|
if (clock == 1) return 28322000.0;
|
||||||
|
m = svga->seqregs[0x13] + 2;
|
||||||
|
n1 = (svga->seqregs[0x12] & 0x1f) + 2;
|
||||||
|
n2 = ((svga->seqregs[0x12] >> 5) & 0x07);
|
||||||
|
t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
|
||||||
|
// pclog("TRIO64 clock %i %i %i %f %f %i\n", m, n1, n2, t, 14318184.0 * ((float)m / (float)n1), 1 << n2);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3);
|
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3);
|
||||||
|
|
||||||
|
|
@ -1592,6 +1637,9 @@ void *s3_bahamas64_init()
|
||||||
s3->id = 0xc1; /*Vision864P*/
|
s3->id = 0xc1; /*Vision864P*/
|
||||||
s3->id_ext = 0xc1; /*Trio64*/
|
s3->id_ext = 0xc1; /*Trio64*/
|
||||||
|
|
||||||
|
s3->getclock = sdac_getclock;
|
||||||
|
s3->getclock_p = &s3->ramdac;
|
||||||
|
|
||||||
return s3;
|
return s3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1602,6 +1650,9 @@ void *s3_9fx_init()
|
||||||
s3->id = 0xe1;
|
s3->id = 0xe1;
|
||||||
s3->id_ext = 0x11; /*Trio64*/
|
s3->id_ext = 0x11; /*Trio64*/
|
||||||
|
|
||||||
|
s3->getclock = s3_trio64_getclock;
|
||||||
|
s3->getclock_p = s3;
|
||||||
|
|
||||||
return s3;
|
return s3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1628,6 +1679,13 @@ void s3_force_redraw(void *p)
|
||||||
s3->svga.fullchange = changeframecount;
|
s3->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int s3_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
s3_t *s3 = (s3_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &s3->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t s3_bahamas64_device =
|
device_t s3_bahamas64_device =
|
||||||
{
|
{
|
||||||
"Paradise Bahamas 64 (S3 Vision864)",
|
"Paradise Bahamas 64 (S3 Vision864)",
|
||||||
|
|
@ -1636,7 +1694,7 @@ device_t s3_bahamas64_device =
|
||||||
NULL,
|
NULL,
|
||||||
s3_speed_changed,
|
s3_speed_changed,
|
||||||
s3_force_redraw,
|
s3_force_redraw,
|
||||||
svga_add_status_info
|
s3_add_status_info
|
||||||
};
|
};
|
||||||
|
|
||||||
device_t s3_9fx_device =
|
device_t s3_9fx_device =
|
||||||
|
|
@ -1647,5 +1705,5 @@ device_t s3_9fx_device =
|
||||||
NULL,
|
NULL,
|
||||||
s3_speed_changed,
|
s3_speed_changed,
|
||||||
s3_force_redraw,
|
s3_force_redraw,
|
||||||
svga_add_status_info
|
s3_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -271,15 +271,19 @@ void s3_virge_updatemapping(virge_t *virge)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,6 +507,13 @@ void s3_virge_force_redraw(void *p)
|
||||||
virge->svga.fullchange = changeframecount;
|
virge->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int s3_virge_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
virge_t *virge = (virge_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &virge->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t s3_virge_device =
|
device_t s3_virge_device =
|
||||||
{
|
{
|
||||||
"Diamond Stealth 3D 2000 (S3 VIRGE)",
|
"Diamond Stealth 3D 2000 (S3 VIRGE)",
|
||||||
|
|
@ -511,5 +522,5 @@ device_t s3_virge_device =
|
||||||
NULL,
|
NULL,
|
||||||
s3_virge_speed_changed,
|
s3_virge_speed_changed,
|
||||||
s3_virge_force_redraw,
|
s3_virge_force_redraw,
|
||||||
svga_add_status_info
|
s3_virge_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,9 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga)
|
||||||
return svga_in(addr, svga);
|
return svga_in(addr, svga);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sdac_getclock(int clock, sdac_ramdac_t *ramdac)
|
float sdac_getclock(int clock, void *p)
|
||||||
{
|
{
|
||||||
|
sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p;
|
||||||
float t;
|
float t;
|
||||||
int m, n1, n2;
|
int m, n1, n2;
|
||||||
// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]);
|
// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]);
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,4 @@ typedef struct sdac_ramdac_t
|
||||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga);
|
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga);
|
||||||
uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);
|
uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);
|
||||||
|
|
||||||
float sdac_getclock(int clock, sdac_ramdac_t *ramdac);
|
float sdac_getclock(int clock, void *p);
|
||||||
|
|
|
||||||
|
|
@ -136,23 +136,27 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
case 4: svga->readplane=val&3; break;
|
case 4: svga->readplane=val&3; break;
|
||||||
case 5: svga->writemode=val&3; svga->readmode=val&8; break;
|
case 5: svga->writemode=val&3; svga->readmode=val&8; break;
|
||||||
case 6:
|
case 6:
|
||||||
pclog("svga_out recalcmapping %p\n", svga);
|
// pclog("svga_out recalcmapping %p\n", svga);
|
||||||
if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
|
if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
|
||||||
{
|
{
|
||||||
pclog("Write mapping %02X\n", val);
|
// pclog("Write mapping %02X\n", val);
|
||||||
switch (val&0xC)
|
switch (val&0xC)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -309,49 +313,31 @@ void svga_recalctimings(svga_t *svga)
|
||||||
if (svga->lowres)
|
if (svga->lowres)
|
||||||
svga->render = svga_render_8bpp_lowres;
|
svga->render = svga_render_8bpp_lowres;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
svga->render = svga_render_8bpp_highres;
|
svga->render = svga_render_8bpp_highres;
|
||||||
// svga_hdisp <<= 1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
if (svga->lowres)
|
if (svga->lowres)
|
||||||
svga->render = svga_render_15bpp_lowres;
|
svga->render = svga_render_15bpp_lowres;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
svga->render = svga_render_15bpp_highres;
|
svga->render = svga_render_15bpp_highres;
|
||||||
svga->hdisp <<= 1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
if (svga->lowres)
|
if (svga->lowres)
|
||||||
svga->render = svga_render_16bpp_lowres;
|
svga->render = svga_render_16bpp_lowres;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
svga->render = svga_render_16bpp_highres;
|
svga->render = svga_render_16bpp_highres;
|
||||||
svga->hdisp <<= 1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
if (svga->lowres)
|
if (svga->lowres)
|
||||||
{
|
|
||||||
svga->render = svga_render_24bpp_lowres;
|
svga->render = svga_render_24bpp_lowres;
|
||||||
svga->hdisp = ((svga->hdisp << 3) / 3);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
svga->render = svga_render_24bpp_highres;
|
svga->render = svga_render_24bpp_highres;
|
||||||
svga->hdisp = ((svga->hdisp << 3) / 3);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
if (svga->lowres)
|
if (svga->lowres)
|
||||||
svga->render = svga_render_32bpp_lowres;
|
svga->render = svga_render_32bpp_lowres;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
svga->render = svga_render_32bpp_highres;
|
svga->render = svga_render_32bpp_highres;
|
||||||
svga->hdisp <<= 1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -516,15 +502,12 @@ void svga_poll(void *p)
|
||||||
svga->cgastat |= 8;
|
svga->cgastat |= 8;
|
||||||
x = svga->hdisp;
|
x = svga->hdisp;
|
||||||
|
|
||||||
if (svga->bpp == 16 || svga->bpp == 15) x /= 2;
|
|
||||||
if (svga->bpp == 32) x /= 4;
|
|
||||||
if (svga->interlace && !svga->oddeven) svga->lastline++;
|
if (svga->interlace && !svga->oddeven) svga->lastline++;
|
||||||
if (svga->interlace && svga->oddeven) svga->firstline--;
|
if (svga->interlace && svga->oddeven) svga->firstline--;
|
||||||
|
|
||||||
wx = x;
|
wx = x;
|
||||||
wy = svga->lastline - svga->firstline;
|
wy = svga->lastline - svga->firstline;
|
||||||
|
|
||||||
|
|
||||||
svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga);
|
svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga);
|
||||||
|
|
||||||
readflash = 0;
|
readflash = 0;
|
||||||
|
|
@ -548,7 +531,6 @@ void svga_poll(void *p)
|
||||||
svga->maback <<= 2;
|
svga->maback <<= 2;
|
||||||
svga->ca <<= 2;
|
svga->ca <<= 2;
|
||||||
|
|
||||||
|
|
||||||
svga->video_res_x = wx;
|
svga->video_res_x = wx;
|
||||||
svga->video_res_y = wy + 1;
|
svga->video_res_y = wy + 1;
|
||||||
// pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres);
|
// pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres);
|
||||||
|
|
@ -668,13 +650,8 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
|
||||||
cycles_lost += video_timing_b;
|
cycles_lost += video_timing_b;
|
||||||
|
|
||||||
if (svga_output) pclog("Writeega %06X ",addr);
|
if (svga_output) pclog("Writeega %06X ",addr);
|
||||||
if (addr>=0xB0000) addr&=0x7FFF;
|
addr &= svga->banked_mask;
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (gdcreg[6]&8) return;
|
|
||||||
addr &= 0xFFFF;
|
|
||||||
addr += svga->write_bank;
|
addr += svga->write_bank;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
|
if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
|
||||||
if (svga->chain4)
|
if (svga->chain4)
|
||||||
|
|
@ -848,12 +825,9 @@ uint8_t svga_read(uint32_t addr, void *p)
|
||||||
|
|
||||||
egareads++;
|
egareads++;
|
||||||
// pclog("Readega %06X ",addr);
|
// pclog("Readega %06X ",addr);
|
||||||
if (addr>=0xB0000) addr&=0x7FFF;
|
addr &= svga->banked_mask;
|
||||||
else
|
|
||||||
{
|
|
||||||
addr &= 0xFFFF;
|
|
||||||
addr += svga->read_bank;
|
addr += svga->read_bank;
|
||||||
}
|
|
||||||
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
|
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
|
||||||
// pclog("%i\n", svga->readmode);
|
// pclog("%i\n", svga->readmode);
|
||||||
if (svga->chain4)
|
if (svga->chain4)
|
||||||
|
|
@ -1120,6 +1094,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
|
||||||
// pclog("svga_doblit start\n");
|
// pclog("svga_doblit start\n");
|
||||||
svga->frames++;
|
svga->frames++;
|
||||||
// pclog("doblit %i %i\n", y1, y2);
|
// pclog("doblit %i %i\n", y1, y2);
|
||||||
|
// pclog("svga_doblit %i %i\n", wx, svga->hdisp);
|
||||||
if (y1 > y2)
|
if (y1 > y2)
|
||||||
{
|
{
|
||||||
video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize);
|
video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize);
|
||||||
|
|
@ -1163,7 +1138,7 @@ void svga_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
cycles_lost += video_timing_w;
|
cycles_lost += video_timing_w;
|
||||||
|
|
||||||
if (svga_output) pclog("svga_writew: %05X ", addr);
|
if (svga_output) pclog("svga_writew: %05X ", addr);
|
||||||
addr = (addr & 0xffff) + svga->write_bank;
|
addr = (addr & svga->banked_mask) + svga->write_bank;
|
||||||
addr &= 0x7FFFFF;
|
addr &= 0x7FFFFF;
|
||||||
if (addr >= svga->vram_limit)
|
if (addr >= svga->vram_limit)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1191,7 +1166,7 @@ void svga_writel(uint32_t addr, uint32_t val, void *p)
|
||||||
cycles_lost += video_timing_l;
|
cycles_lost += video_timing_l;
|
||||||
|
|
||||||
if (svga_output) pclog("svga_writel: %05X ", addr);
|
if (svga_output) pclog("svga_writel: %05X ", addr);
|
||||||
addr = (addr & 0xffff) + svga->write_bank;
|
addr = (addr & svga->banked_mask) + svga->write_bank;
|
||||||
addr &= 0x7FFFFF;
|
addr &= 0x7FFFFF;
|
||||||
if (addr >= svga->vram_limit)
|
if (addr >= svga->vram_limit)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1214,7 +1189,7 @@ uint16_t svga_readw(uint32_t addr, void *p)
|
||||||
cycles_lost += video_timing_w;
|
cycles_lost += video_timing_w;
|
||||||
|
|
||||||
// pclog("Readw %05X ", addr);
|
// pclog("Readw %05X ", addr);
|
||||||
addr = (addr & 0xffff) + svga->read_bank;
|
addr = (addr & svga->banked_mask) + svga->read_bank;
|
||||||
addr &= 0x7FFFFF;
|
addr &= 0x7FFFFF;
|
||||||
// pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]);
|
// pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]);
|
||||||
if (addr >= svga->vram_limit) return 0xffff;
|
if (addr >= svga->vram_limit) return 0xffff;
|
||||||
|
|
@ -1235,7 +1210,7 @@ uint32_t svga_readl(uint32_t addr, void *p)
|
||||||
cycles_lost += video_timing_l;
|
cycles_lost += video_timing_l;
|
||||||
|
|
||||||
// pclog("Readl %05X ", addr);
|
// pclog("Readl %05X ", addr);
|
||||||
addr = (addr & 0xffff) + svga->read_bank;
|
addr = (addr & svga->banked_mask) + svga->read_bank;
|
||||||
addr &= 0x7FFFFF;
|
addr &= 0x7FFFFF;
|
||||||
// pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]);
|
// pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]);
|
||||||
if (addr >= svga->vram_limit) return 0xffffffff;
|
if (addr >= svga->vram_limit) return 0xffffffff;
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ typedef struct svga_t
|
||||||
uint8_t *vram;
|
uint8_t *vram;
|
||||||
uint8_t *changedvram;
|
uint8_t *changedvram;
|
||||||
int vrammask;
|
int vrammask;
|
||||||
|
uint32_t banked_mask;
|
||||||
|
|
||||||
uint32_t write_bank, read_bank;
|
uint32_t write_bank, read_bank;
|
||||||
|
|
||||||
|
|
|
||||||
1133
src/vid_tgui9440.c
Normal file
1133
src/vid_tgui9440.c
Normal file
File diff suppressed because it is too large
Load diff
1
src/vid_tgui9440.h
Normal file
1
src/vid_tgui9440.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extern device_t tgui9440_device;
|
||||||
875
src/vid_tvga.c
875
src/vid_tvga.c
|
|
@ -18,50 +18,12 @@ typedef struct tvga_t
|
||||||
svga_t svga;
|
svga_t svga;
|
||||||
tkd8001_ramdac_t ramdac;
|
tkd8001_ramdac_t ramdac;
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t src_x, src_y;
|
|
||||||
uint16_t dst_x, dst_y;
|
|
||||||
uint16_t size_x, size_y;
|
|
||||||
uint16_t fg_col, bg_col;
|
|
||||||
uint8_t rop;
|
|
||||||
uint16_t flags;
|
|
||||||
uint8_t pattern[0x80];
|
|
||||||
int command;
|
|
||||||
int offset;
|
|
||||||
uint8_t ger22;
|
|
||||||
|
|
||||||
int x, y;
|
|
||||||
uint32_t src, dst, src_old, dst_old;
|
|
||||||
int pat_x, pat_y;
|
|
||||||
int use_src;
|
|
||||||
|
|
||||||
int pitch, bpp;
|
|
||||||
|
|
||||||
uint16_t tvga_pattern[8][8];
|
|
||||||
} accel;
|
|
||||||
|
|
||||||
uint8_t tvga_3d8, tvga_3d9;
|
uint8_t tvga_3d8, tvga_3d9;
|
||||||
int oldmode;
|
int oldmode;
|
||||||
|
uint8_t oldctrl1;
|
||||||
uint8_t oldctrl2, newctrl2;
|
uint8_t oldctrl2, newctrl2;
|
||||||
|
|
||||||
uint32_t linear_base, linear_size;
|
|
||||||
} tvga_t;
|
} tvga_t;
|
||||||
|
|
||||||
void tvga_recalcmapping(tvga_t *tvga);
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t tvga_accel_read(uint32_t addr, void *priv);
|
|
||||||
uint16_t tvga_accel_read_w(uint32_t addr, void *priv);
|
|
||||||
uint32_t tvga_accel_read_l(uint32_t addr, void *priv);
|
|
||||||
|
|
||||||
void tvga_accel_write(uint32_t addr, uint8_t val, void *priv);
|
|
||||||
void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv);
|
|
||||||
void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv);
|
|
||||||
|
|
||||||
|
|
||||||
void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv);
|
|
||||||
|
|
||||||
void tvga_out(uint16_t addr, uint8_t val, void *p)
|
void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
tvga_t *tvga = (tvga_t *)p;
|
||||||
|
|
@ -91,33 +53,26 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
tvga->newctrl2 = val;
|
tvga->newctrl2 = val;
|
||||||
break;
|
break;
|
||||||
case 0xE:
|
case 0xE:
|
||||||
|
if (tvga->oldmode)
|
||||||
|
tvga->oldctrl1 = val;
|
||||||
|
else
|
||||||
|
{
|
||||||
svga->seqregs[0xe] = val ^ 2;
|
svga->seqregs[0xe] = val ^ 2;
|
||||||
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
|
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
|
||||||
if (!(svga->gdcreg[0xf] & 1))
|
if (!(svga->gdcreg[0xf] & 1))
|
||||||
svga->read_bank = svga->write_bank;
|
svga->read_bank = svga->write_bank;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
if (gfxcard != GFX_TGUI9440)
|
|
||||||
{
|
|
||||||
tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga);
|
tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x3CF:
|
case 0x3CF:
|
||||||
switch (svga->gdcaddr & 15)
|
switch (svga->gdcaddr & 15)
|
||||||
{
|
{
|
||||||
case 0x6:
|
|
||||||
if (svga->gdcreg[6] != val)
|
|
||||||
{
|
|
||||||
svga->gdcreg[6] = val;
|
|
||||||
tvga_recalcmapping(tvga);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
svga->gdcreg[0xe] = val ^ 2;
|
svga->gdcreg[0xe] = val ^ 2;
|
||||||
if ((svga->gdcreg[0xf] & 1) == 1)
|
if ((svga->gdcreg[0xf] & 1) == 1)
|
||||||
|
|
@ -131,8 +86,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
if (gfxcard == GFX_TGUI9440) svga->crtcreg = val & 0x7f;
|
svga->crtcreg = val & 0x3f;
|
||||||
else svga->crtcreg = val & 0x3f;
|
|
||||||
return;
|
return;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||||
|
|
@ -147,44 +101,6 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
svga_recalctimings(svga);
|
svga_recalctimings(svga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (svga->crtcreg)
|
|
||||||
{
|
|
||||||
case 0x21:
|
|
||||||
if (old != val)
|
|
||||||
{
|
|
||||||
if (!PCI)
|
|
||||||
{
|
|
||||||
tvga->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20;
|
|
||||||
tvga->linear_size = (val & 0x10) ? 0x200000 : 0x100000;
|
|
||||||
}
|
|
||||||
tvga_recalcmapping(tvga);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case 0x38: /*Pixel bus register*/
|
|
||||||
// pclog("Pixel bus register %02X\n", val);
|
|
||||||
if (gfxcard != GFX_TGUI9440)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((val & 0xc) == 4) svga->bpp = 16;
|
|
||||||
else if (!(val & 0xc)) svga->bpp = 8;
|
|
||||||
else svga->bpp = 24;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
|
||||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
|
||||||
svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff;
|
|
||||||
svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff;
|
|
||||||
svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f;
|
|
||||||
svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f;
|
|
||||||
svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x50:
|
|
||||||
svga->hwcursor.ena = val & 0x80;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case 0x3D8:
|
case 0x3D8:
|
||||||
tvga->tvga_3d8 = val;
|
tvga->tvga_3d8 = val;
|
||||||
|
|
@ -227,8 +143,7 @@ uint8_t tvga_in(uint16_t addr, void *p)
|
||||||
{
|
{
|
||||||
// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
|
// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
|
||||||
tvga->oldmode = 0;
|
tvga->oldmode = 0;
|
||||||
if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/
|
return 0x33; /*TVGA8900D*/
|
||||||
else return 0xe3; /*TGUI9440AGi*/
|
|
||||||
}
|
}
|
||||||
if ((svga->seqaddr & 0xf) == 0xc)
|
if ((svga->seqaddr & 0xf) == 0xc)
|
||||||
{
|
{
|
||||||
|
|
@ -242,9 +157,7 @@ uint8_t tvga_in(uint16_t addr, void *p)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||||
if (gfxcard != GFX_TGUI9440)
|
|
||||||
return tkd8001_ramdac_in(addr, &tvga->ramdac, svga);
|
return tkd8001_ramdac_in(addr, &tvga->ramdac, svga);
|
||||||
break;
|
|
||||||
case 0x3D4:
|
case 0x3D4:
|
||||||
return svga->crtcreg;
|
return svga->crtcreg;
|
||||||
case 0x3D5:
|
case 0x3D5:
|
||||||
|
|
@ -266,7 +179,7 @@ void tvga_recalctimings(svga_t *svga)
|
||||||
if (svga->crtc[0x29] & 0x10)
|
if (svga->crtc[0x29] & 0x10)
|
||||||
svga->rowoffset += 0x100;
|
svga->rowoffset += 0x100;
|
||||||
|
|
||||||
if (gfxcard == GFX_TGUI9440 && svga->bpp == 24)
|
if (svga->bpp == 24)
|
||||||
svga->hdisp = (svga->crtc[1] + 1) * 8;
|
svga->hdisp = (svga->crtc[1] + 1) * 8;
|
||||||
|
|
||||||
if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
|
if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
|
||||||
|
|
@ -278,16 +191,13 @@ void tvga_recalctimings(svga_t *svga)
|
||||||
svga->rowoffset <<= 1;
|
svga->rowoffset <<= 1;
|
||||||
svga->ma_latch <<= 1;
|
svga->ma_latch <<= 1;
|
||||||
}
|
}
|
||||||
if (tvga->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
|
if (svga->gdcreg[0xf] & 0x08)
|
||||||
svga->lowres=0;
|
|
||||||
if (gfxcard == GFX_TGUI9440)
|
|
||||||
svga->lowres = !(svga->crtc[0x2a] & 0x40);
|
|
||||||
|
|
||||||
if (svga->gdcreg[0xf] & 8)
|
|
||||||
{
|
{
|
||||||
svga->htotal <<= 1;
|
svga->htotal *= 2;
|
||||||
svga->hdisp <<= 1;
|
svga->hdisp *= 2;
|
||||||
|
svga->hdisp_time *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
svga->interlace = svga->crtc[0x1e] & 4;
|
svga->interlace = svga->crtc[0x1e] & 4;
|
||||||
if (svga->interlace)
|
if (svga->interlace)
|
||||||
svga->rowoffset >>= 1;
|
svga->rowoffset >>= 1;
|
||||||
|
|
@ -302,7 +212,7 @@ void tvga_recalctimings(svga_t *svga)
|
||||||
case 7: svga->clock = cpuclock/40000000.0; break;
|
case 7: svga->clock = cpuclock/40000000.0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tvga->oldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (svga->crtc[0x2a] & 0x40)))
|
if (tvga->oldctrl2 & 0x10)
|
||||||
{
|
{
|
||||||
switch (svga->bpp)
|
switch (svga->bpp)
|
||||||
{
|
{
|
||||||
|
|
@ -311,142 +221,18 @@ void tvga_recalctimings(svga_t *svga)
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
svga->render = svga_render_15bpp_highres;
|
svga->render = svga_render_15bpp_highres;
|
||||||
|
svga->hdisp /= 2;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
svga->render = svga_render_16bpp_highres;
|
svga->render = svga_render_16bpp_highres;
|
||||||
|
svga->hdisp /= 2;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
svga->render = svga_render_24bpp_highres;
|
svga->render = svga_render_24bpp_highres;
|
||||||
break;
|
svga->hdisp /= 3;
|
||||||
case 32:
|
|
||||||
svga->render = svga_render_32bpp_highres;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
svga->lowres = 0;
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_recalcmapping(tvga_t *tvga)
|
|
||||||
{
|
|
||||||
svga_t *svga = &tvga->svga;
|
|
||||||
|
|
||||||
// pclog("tvga_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]);
|
|
||||||
|
|
||||||
if (svga->crtc[0x21] & 0x20)
|
|
||||||
{
|
|
||||||
mem_mapping_disable(&svga->mapping);
|
|
||||||
mem_mapping_set_addr(&tvga->linear_mapping, tvga->linear_base, tvga->linear_size);
|
|
||||||
// pclog("Trident linear framebuffer at %08X - size %06X\n", tvga->linear_base, tvga->linear_size);
|
|
||||||
mem_mapping_enable(&tvga->accel_mapping);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// pclog("Write mapping %02X\n", val);
|
|
||||||
mem_mapping_disable(&tvga->linear_mapping);
|
|
||||||
mem_mapping_disable(&tvga->accel_mapping);
|
|
||||||
switch (svga->gdcreg[6] & 0xC)
|
|
||||||
{
|
|
||||||
case 0x0: /*128k at A0000*/
|
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
|
||||||
break;
|
|
||||||
case 0x4: /*64k at A0000*/
|
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
|
||||||
mem_mapping_enable(&tvga->accel_mapping);
|
|
||||||
break;
|
|
||||||
case 0x8: /*32k at B0000*/
|
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
|
||||||
break;
|
|
||||||
case 0xC: /*32k at B8000*/
|
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_hwcursor_draw(svga_t *svga, int displine)
|
|
||||||
{
|
|
||||||
uint32_t dat[2];
|
|
||||||
int xx;
|
|
||||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
|
||||||
|
|
||||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
|
||||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7];
|
|
||||||
for (xx = 0; xx < 32; xx++)
|
|
||||||
{
|
|
||||||
if (offset >= svga->hwcursor_latch.x)
|
|
||||||
{
|
|
||||||
if (!(dat[0] & 0x80000000))
|
|
||||||
((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0;
|
|
||||||
else if (dat[1] & 0x80000000)
|
|
||||||
((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
|
|
||||||
// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
dat[0] <<= 1;
|
|
||||||
dat[1] <<= 1;
|
|
||||||
}
|
|
||||||
svga->hwcursor_latch.addr += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tvga_pci_read(int func, int addr, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
svga_t *svga = &tvga->svga;
|
|
||||||
|
|
||||||
// pclog("Trident PCI read %08X\n", addr);
|
|
||||||
|
|
||||||
switch (addr)
|
|
||||||
{
|
|
||||||
case 0x00: return 0x23; /*Trident*/
|
|
||||||
case 0x01: return 0x10;
|
|
||||||
|
|
||||||
case 0x02: return 0x40; /*TGUI9440 (9682)*/
|
|
||||||
case 0x03: return 0x94;
|
|
||||||
|
|
||||||
case 0x04: return 0x03; /*Respond to IO and memory accesses*/
|
|
||||||
|
|
||||||
case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
|
|
||||||
|
|
||||||
case 0x08: return 0; /*Revision ID*/
|
|
||||||
case 0x09: return 0; /*Programming interface*/
|
|
||||||
|
|
||||||
case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/
|
|
||||||
case 0x0b: return 0x03;
|
|
||||||
|
|
||||||
case 0x10: return 0x00; /*Linear frame buffer address*/
|
|
||||||
case 0x11: return 0x00;
|
|
||||||
case 0x12: return tvga->linear_base >> 16;
|
|
||||||
case 0x13: return tvga->linear_base >> 24;
|
|
||||||
|
|
||||||
case 0x30: return 0x01; /*BIOS ROM address*/
|
|
||||||
case 0x31: return 0x00;
|
|
||||||
case 0x32: return 0x0C;
|
|
||||||
case 0x33: return 0x00;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_pci_write(int func, int addr, uint8_t val, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
svga_t *svga = &tvga->svga;
|
|
||||||
|
|
||||||
// pclog("Trident PCI write %08X %02X\n", addr, val);
|
|
||||||
|
|
||||||
switch (addr)
|
|
||||||
{
|
|
||||||
case 0x12:
|
|
||||||
tvga->linear_base = (tvga->linear_base & 0xff000000) | ((val & 0xe0) << 16);
|
|
||||||
tvga->linear_size = 2 << 20;
|
|
||||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4);
|
|
||||||
tvga_recalcmapping(tvga);
|
|
||||||
break;
|
|
||||||
case 0x13:
|
|
||||||
tvga->linear_base = (tvga->linear_base & 0xe00000) | (val << 24);
|
|
||||||
tvga->linear_size = 2 << 20;
|
|
||||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6);
|
|
||||||
tvga_recalcmapping(tvga);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,35 +246,10 @@ void *tvga8900d_init()
|
||||||
tvga_in, tvga_out,
|
tvga_in, tvga_out,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
mem_mapping_add(&tvga->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tvga->svga);
|
|
||||||
mem_mapping_add(&tvga->accel_mapping, 0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, tvga);
|
|
||||||
mem_mapping_disable(&tvga->linear_mapping);
|
|
||||||
mem_mapping_disable(&tvga->accel_mapping);
|
|
||||||
|
|
||||||
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
|
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
|
||||||
|
|
||||||
return tvga;
|
return tvga;
|
||||||
}
|
}
|
||||||
void *tgui9440_init()
|
|
||||||
{
|
|
||||||
tvga_t *tvga = malloc(sizeof(tvga_t));
|
|
||||||
memset(tvga, 0, sizeof(tvga_t));
|
|
||||||
|
|
||||||
svga_init(&tvga->svga, tvga, 1 << 21, /*2mb*/
|
|
||||||
tvga_recalctimings,
|
|
||||||
tvga_in, tvga_out,
|
|
||||||
tvga_hwcursor_draw);
|
|
||||||
|
|
||||||
mem_mapping_add(&tvga->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tvga->svga);
|
|
||||||
mem_mapping_add(&tvga->accel_mapping, 0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, tvga);
|
|
||||||
mem_mapping_disable(&tvga->accel_mapping);
|
|
||||||
|
|
||||||
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
|
|
||||||
|
|
||||||
pci_add(tvga_pci_read, tvga_pci_write, tvga);
|
|
||||||
|
|
||||||
return tvga;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_close(void *p)
|
void tvga_close(void *p)
|
||||||
{
|
{
|
||||||
|
|
@ -513,592 +274,11 @@ void tvga_force_redraw(void *p)
|
||||||
tvga->svga.fullchange = changeframecount;
|
tvga->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum
|
int tvga_add_status_info(char *s, int max_len, void *p)
|
||||||
{
|
|
||||||
TGUI_BITBLT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TGUI_SRCCPU = 0,
|
|
||||||
|
|
||||||
TGUI_SRCDISP = 0x04, /*Source is from display*/
|
|
||||||
TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/
|
|
||||||
TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/
|
|
||||||
TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/
|
|
||||||
TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/
|
|
||||||
TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/
|
|
||||||
};
|
|
||||||
|
|
||||||
#define READ(addr, dat) if (tvga->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
|
|
||||||
else dat = vram_w[addr & 0xfffff];
|
|
||||||
|
|
||||||
#define MIX() do \
|
|
||||||
{ \
|
|
||||||
out = 0; \
|
|
||||||
for (c=0;c<16;c++) \
|
|
||||||
{ \
|
|
||||||
d=(dst_dat & (1<<c)) ? 1:0; \
|
|
||||||
if (src_dat & (1<<c)) d|=2; \
|
|
||||||
if (pat_dat & (1<<c)) d|=4; \
|
|
||||||
if (tvga->accel.rop & (1<<d)) out|=(1<<c); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define WRITE(addr, dat) if (tvga->accel.bpp == 0) \
|
|
||||||
{ \
|
|
||||||
svga->vram[addr & 0x1fffff] = dat; \
|
|
||||||
svga->changedvram[((addr) & 0x1fffff) >> 10] = changeframecount; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
vram_w[addr & 0xfffff] = dat; \
|
|
||||||
svga->changedvram[((addr) & 0xfffff) >> 9] = changeframecount; \
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv);
|
|
||||||
void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv);
|
|
||||||
|
|
||||||
void tvga_accel_command(int count, uint32_t cpu_dat, tvga_t *tvga)
|
|
||||||
{
|
|
||||||
svga_t *svga = &tvga->svga;
|
|
||||||
int x, y;
|
|
||||||
int c, d;
|
|
||||||
uint16_t src_dat, dst_dat, pat_dat;
|
|
||||||
uint16_t out;
|
|
||||||
int xdir = (tvga->accel.flags & 0x200) ? -1 : 1;
|
|
||||||
int ydir = (tvga->accel.flags & 0x100) ? -1 : 1;
|
|
||||||
uint16_t trans_col = (tvga->accel.flags & TGUI_TRANSREV) ? tvga->accel.fg_col : tvga->accel.bg_col;
|
|
||||||
uint16_t *vram_w = (uint16_t *)svga->vram;
|
|
||||||
|
|
||||||
if (tvga->accel.bpp == 0)
|
|
||||||
trans_col &= 0xff;
|
|
||||||
|
|
||||||
if (count != -1 && !tvga->accel.x)
|
|
||||||
{
|
|
||||||
count -= tvga->accel.offset;
|
|
||||||
cpu_dat <<= tvga->accel.offset;
|
|
||||||
}
|
|
||||||
if (count == -1)
|
|
||||||
{
|
|
||||||
tvga->accel.x = tvga->accel.y = 0;
|
|
||||||
}
|
|
||||||
if (tvga->accel.flags & TGUI_SOLIDFILL)
|
|
||||||
{
|
|
||||||
// pclog("SOLIDFILL\n");
|
|
||||||
for (y = 0; y < 8; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < 8; x++)
|
|
||||||
{
|
|
||||||
tvga->accel.tvga_pattern[y][x] = tvga->accel.fg_col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (tvga->accel.flags & TGUI_PATMONO)
|
|
||||||
{
|
|
||||||
// pclog("PATMONO\n");
|
|
||||||
for (y = 0; y < 8; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < 8; x++)
|
|
||||||
{
|
|
||||||
tvga->accel.tvga_pattern[y][x] = (tvga->accel.pattern[y] & (1 << x)) ? tvga->accel.fg_col : tvga->accel.bg_col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (tvga->accel.bpp == 0)
|
|
||||||
{
|
|
||||||
// pclog("OTHER 8-bit\n");
|
|
||||||
for (y = 0; y < 8; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < 8; x++)
|
|
||||||
{
|
|
||||||
tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x + y*8];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// pclog("OTHER 16-bit\n");
|
|
||||||
for (y = 0; y < 8; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < 8; x++)
|
|
||||||
{
|
|
||||||
tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x*2 + y*16] | (tvga->accel.pattern[x*2 + y*16 + 1] << 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* for (y = 0; y < 8; y++)
|
|
||||||
{
|
|
||||||
if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga->accel.tvga_pattern[y][0], tvga->accel.tvga_pattern[y][1], tvga->accel.tvga_pattern[y][2], tvga->accel.tvga_pattern[y][3], tvga->accel.tvga_pattern[y][4], tvga->accel.tvga_pattern[y][5], tvga->accel.tvga_pattern[y][6], tvga->accel.tvga_pattern[y][7]);
|
|
||||||
}*/
|
|
||||||
// if (count == -1) pclog("Command %i %i %p\n", tvga->accel.command, TGUI_BITBLT, tvga);
|
|
||||||
switch (tvga->accel.command)
|
|
||||||
{
|
|
||||||
case TGUI_BITBLT:
|
|
||||||
// if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga->accel.src_x, tvga->accel.src_y, tvga->accel.dst_x, tvga->accel.dst_y, tvga->accel.size_x, tvga->accel.size_y, tvga->accel.flags);
|
|
||||||
if (count == -1)
|
|
||||||
{
|
|
||||||
tvga->accel.src = tvga->accel.src_old = tvga->accel.src_x + (tvga->accel.src_y * tvga->accel.pitch);
|
|
||||||
tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_x + (tvga->accel.dst_y * tvga->accel.pitch);
|
|
||||||
tvga->accel.pat_x = tvga->accel.dst_x;
|
|
||||||
tvga->accel.pat_y = tvga->accel.dst_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tvga->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
|
|
||||||
{
|
|
||||||
case TGUI_SRCCPU:
|
|
||||||
if (count == -1)
|
|
||||||
{
|
|
||||||
// pclog("Blit start TGUI_SRCCPU\n");
|
|
||||||
if (svga->crtc[0x21] & 0x20)
|
|
||||||
mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l);
|
|
||||||
|
|
||||||
if (tvga->accel.use_src)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
count >>= 3;
|
|
||||||
// pclog("TGUI_SRCCPU\n");
|
|
||||||
while (count)
|
|
||||||
{
|
|
||||||
if (tvga->accel.bpp == 0)
|
|
||||||
{
|
|
||||||
src_dat = cpu_dat >> 24;
|
|
||||||
cpu_dat <<= 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
|
||||||
cpu_dat <<= 16;
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
READ(tvga->accel.dst, dst_dat);
|
|
||||||
pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
|
|
||||||
|
|
||||||
if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
|
||||||
{
|
|
||||||
MIX();
|
|
||||||
|
|
||||||
WRITE(tvga->accel.dst, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pclog(" %i,%i %02X %02X %02X %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
|
|
||||||
|
|
||||||
tvga->accel.src += xdir;
|
|
||||||
tvga->accel.dst += xdir;
|
|
||||||
tvga->accel.pat_x += xdir;
|
|
||||||
|
|
||||||
tvga->accel.x++;
|
|
||||||
if (tvga->accel.x > tvga->accel.size_x)
|
|
||||||
{
|
|
||||||
tvga->accel.x = 0;
|
|
||||||
tvga->accel.y++;
|
|
||||||
|
|
||||||
tvga->accel.pat_x = tvga->accel.dst_x;
|
|
||||||
|
|
||||||
tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.pat_y += ydir;
|
|
||||||
|
|
||||||
if (tvga->accel.y > tvga->accel.size_y)
|
|
||||||
{
|
|
||||||
if (svga->crtc[0x21] & 0x20)
|
|
||||||
{
|
|
||||||
// pclog("Blit end\n");
|
|
||||||
mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tvga->accel.use_src)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TGUI_SRCMONO | TGUI_SRCCPU:
|
|
||||||
if (count == -1)
|
|
||||||
{
|
|
||||||
// pclog("Blit start TGUI_SRCMONO | TGUI_SRCCPU\n");
|
|
||||||
if (svga->crtc[0x21] & 0x20)
|
|
||||||
mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l);
|
|
||||||
|
|
||||||
// pclog(" %i\n", tvga->accel.command);
|
|
||||||
if (tvga->accel.use_src)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// pclog("TGUI_SRCMONO | TGUI_SRCCPU\n");
|
|
||||||
while (count)
|
|
||||||
{
|
|
||||||
src_dat = ((cpu_dat >> 31) ? tvga->accel.fg_col : tvga->accel.bg_col);
|
|
||||||
if (tvga->accel.bpp == 0)
|
|
||||||
src_dat &= 0xff;
|
|
||||||
|
|
||||||
READ(tvga->accel.dst, dst_dat);
|
|
||||||
pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
|
|
||||||
|
|
||||||
if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
|
||||||
{
|
|
||||||
MIX();
|
|
||||||
|
|
||||||
WRITE(tvga->accel.dst, out);
|
|
||||||
}
|
|
||||||
// pclog(" %i,%i %02X %02X %02X %02X %i\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
|
|
||||||
cpu_dat <<= 1;
|
|
||||||
tvga->accel.src += xdir;
|
|
||||||
tvga->accel.dst += xdir;
|
|
||||||
tvga->accel.pat_x += xdir;
|
|
||||||
|
|
||||||
tvga->accel.x++;
|
|
||||||
if (tvga->accel.x > tvga->accel.size_x)
|
|
||||||
{
|
|
||||||
tvga->accel.x = 0;
|
|
||||||
tvga->accel.y++;
|
|
||||||
|
|
||||||
tvga->accel.pat_x = tvga->accel.dst_x;
|
|
||||||
|
|
||||||
tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.pat_y += ydir;
|
|
||||||
|
|
||||||
if (tvga->accel.y > tvga->accel.size_y)
|
|
||||||
{
|
|
||||||
if (svga->crtc[0x21] & 0x20)
|
|
||||||
{
|
|
||||||
// pclog("Blit end\n");
|
|
||||||
mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tvga->accel.use_src)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
while (count)
|
|
||||||
{
|
|
||||||
READ(tvga->accel.src, src_dat);
|
|
||||||
READ(tvga->accel.dst, dst_dat);
|
|
||||||
pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
|
|
||||||
|
|
||||||
if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
|
|
||||||
{
|
|
||||||
MIX();
|
|
||||||
|
|
||||||
WRITE(tvga->accel.dst, out);
|
|
||||||
}
|
|
||||||
// pclog(" %i,%i %02X %02X %02X %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
|
|
||||||
|
|
||||||
tvga->accel.src += xdir;
|
|
||||||
tvga->accel.dst += xdir;
|
|
||||||
tvga->accel.pat_x += xdir;
|
|
||||||
|
|
||||||
tvga->accel.x++;
|
|
||||||
if (tvga->accel.x > tvga->accel.size_x)
|
|
||||||
{
|
|
||||||
tvga->accel.x = 0;
|
|
||||||
tvga->accel.y++;
|
|
||||||
|
|
||||||
tvga->accel.pat_x = tvga->accel.dst_x;
|
|
||||||
|
|
||||||
tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
|
|
||||||
tvga->accel.pat_y += ydir;
|
|
||||||
|
|
||||||
if (tvga->accel.y > tvga->accel.size_y)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write(uint32_t addr, uint8_t val, void *p)
|
|
||||||
{
|
{
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
tvga_t *tvga = (tvga_t *)p;
|
||||||
// pclog("tvga_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode);
|
|
||||||
if ((addr & ~0xff) != 0xbff00)
|
|
||||||
return;
|
|
||||||
switch (addr & 0xff)
|
|
||||||
{
|
|
||||||
case 0x22:
|
|
||||||
tvga->accel.ger22 = val;
|
|
||||||
tvga->accel.pitch = 512 << ((val >> 2) & 3);
|
|
||||||
tvga->accel.bpp = (val & 3) ? 1 : 0;
|
|
||||||
tvga->accel.pitch >>= tvga->accel.bpp;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x24: /*Command*/
|
return svga_add_status_info(s, max_len, &tvga->svga);
|
||||||
tvga->accel.command = val;
|
|
||||||
tvga_accel_command(-1, 0, tvga);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x27: /*ROP*/
|
|
||||||
tvga->accel.rop = val;
|
|
||||||
tvga->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
|
|
||||||
// pclog("Write ROP %02X %i\n", val, tvga->accel.use_src);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x28: /*Flags*/
|
|
||||||
tvga->accel.flags = (tvga->accel.flags & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x29: /*Flags*/
|
|
||||||
tvga->accel.flags = (tvga->accel.flags & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x2b:
|
|
||||||
tvga->accel.offset = val & 7;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x2c: /*Foreground colour*/
|
|
||||||
tvga->accel.fg_col = (tvga->accel.fg_col & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x2d: /*Foreground colour*/
|
|
||||||
tvga->accel.fg_col = (tvga->accel.fg_col & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x30: /*Background colour*/
|
|
||||||
tvga->accel.bg_col = (tvga->accel.bg_col & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x31: /*Background colour*/
|
|
||||||
tvga->accel.bg_col = (tvga->accel.bg_col & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x38: /*Dest X*/
|
|
||||||
tvga->accel.dst_x = (tvga->accel.dst_x & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x39: /*Dest X*/
|
|
||||||
tvga->accel.dst_x = (tvga->accel.dst_x & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
case 0x3a: /*Dest Y*/
|
|
||||||
tvga->accel.dst_y = (tvga->accel.dst_y & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x3b: /*Dest Y*/
|
|
||||||
tvga->accel.dst_y = (tvga->accel.dst_y & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x3c: /*Src X*/
|
|
||||||
tvga->accel.src_x = (tvga->accel.src_x & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x3d: /*Src X*/
|
|
||||||
tvga->accel.src_x = (tvga->accel.src_x & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
case 0x3e: /*Src Y*/
|
|
||||||
tvga->accel.src_y = (tvga->accel.src_y & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x3f: /*Src Y*/
|
|
||||||
tvga->accel.src_y = (tvga->accel.src_y & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x40: /*Size X*/
|
|
||||||
tvga->accel.size_x = (tvga->accel.size_x & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x41: /*Size X*/
|
|
||||||
tvga->accel.size_x = (tvga->accel.size_x & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
case 0x42: /*Size Y*/
|
|
||||||
tvga->accel.size_y = (tvga->accel.size_y & 0xff00) | val;
|
|
||||||
break;
|
|
||||||
case 0x43: /*Size Y*/
|
|
||||||
tvga->accel.size_y = (tvga->accel.size_y & 0xff) | (val << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
|
||||||
case 0x84: case 0x85: case 0x86: case 0x87:
|
|
||||||
case 0x88: case 0x89: case 0x8a: case 0x8b:
|
|
||||||
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
|
||||||
case 0x90: case 0x91: case 0x92: case 0x93:
|
|
||||||
case 0x94: case 0x95: case 0x96: case 0x97:
|
|
||||||
case 0x98: case 0x99: case 0x9a: case 0x9b:
|
|
||||||
case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
|
||||||
case 0xa0: case 0xa1: case 0xa2: case 0xa3:
|
|
||||||
case 0xa4: case 0xa5: case 0xa6: case 0xa7:
|
|
||||||
case 0xa8: case 0xa9: case 0xaa: case 0xab:
|
|
||||||
case 0xac: case 0xad: case 0xae: case 0xaf:
|
|
||||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
|
|
||||||
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
|
||||||
case 0xb8: case 0xb9: case 0xba: case 0xbb:
|
|
||||||
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
|
|
||||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
|
||||||
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
|
||||||
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
|
||||||
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
|
||||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
|
||||||
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
|
||||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
|
||||||
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
|
||||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
|
||||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
|
||||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
|
||||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
|
||||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
|
||||||
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
|
||||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
|
||||||
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
|
||||||
tvga->accel.pattern[addr & 0x7f] = val;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_w(uint32_t addr, uint16_t val, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
// pclog("tvga_accel_write_w %08X %04X\n", addr, val);
|
|
||||||
tvga_accel_write(addr, val, tvga);
|
|
||||||
tvga_accel_write(addr + 1, val >> 8, tvga);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_l(uint32_t addr, uint32_t val, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
// pclog("tvga_accel_write_l %08X %08X\n", addr, val);
|
|
||||||
tvga_accel_write(addr, val, tvga);
|
|
||||||
tvga_accel_write(addr + 1, val >> 8, tvga);
|
|
||||||
tvga_accel_write(addr + 2, val >> 16, tvga);
|
|
||||||
tvga_accel_write(addr + 3, val >> 24, tvga);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tvga_accel_read(uint32_t addr, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
// pclog("tvga_accel_read : %08X\n", addr);
|
|
||||||
if ((addr & ~0xff) != 0xbff00)
|
|
||||||
return 0xff;
|
|
||||||
switch (addr & 0xff)
|
|
||||||
{
|
|
||||||
case 0x20: /*Status*/
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case 0x27: /*ROP*/
|
|
||||||
return tvga->accel.rop;
|
|
||||||
|
|
||||||
case 0x28: /*Flags*/
|
|
||||||
return tvga->accel.flags & 0xff;
|
|
||||||
case 0x29: /*Flags*/
|
|
||||||
return tvga->accel.flags >> 8;
|
|
||||||
|
|
||||||
case 0x2b:
|
|
||||||
return tvga->accel.offset;
|
|
||||||
|
|
||||||
case 0x2c: /*Background colour*/
|
|
||||||
return tvga->accel.bg_col & 0xff;
|
|
||||||
case 0x2d: /*Background colour*/
|
|
||||||
return tvga->accel.bg_col >> 8;
|
|
||||||
|
|
||||||
case 0x30: /*Foreground colour*/
|
|
||||||
return tvga->accel.fg_col & 0xff;
|
|
||||||
case 0x31: /*Foreground colour*/
|
|
||||||
return tvga->accel.fg_col >> 8;
|
|
||||||
|
|
||||||
case 0x38: /*Dest X*/
|
|
||||||
return tvga->accel.dst_x & 0xff;
|
|
||||||
case 0x39: /*Dest X*/
|
|
||||||
return tvga->accel.dst_x >> 8;
|
|
||||||
case 0x3a: /*Dest Y*/
|
|
||||||
return tvga->accel.dst_y & 0xff;
|
|
||||||
case 0x3b: /*Dest Y*/
|
|
||||||
return tvga->accel.dst_y >> 8;
|
|
||||||
|
|
||||||
case 0x3c: /*Src X*/
|
|
||||||
return tvga->accel.src_x & 0xff;
|
|
||||||
case 0x3d: /*Src X*/
|
|
||||||
return tvga->accel.src_x >> 8;
|
|
||||||
case 0x3e: /*Src Y*/
|
|
||||||
return tvga->accel.src_y & 0xff;
|
|
||||||
case 0x3f: /*Src Y*/
|
|
||||||
return tvga->accel.src_y >> 8;
|
|
||||||
|
|
||||||
case 0x40: /*Size X*/
|
|
||||||
return tvga->accel.size_x & 0xff;
|
|
||||||
case 0x41: /*Size X*/
|
|
||||||
return tvga->accel.size_x >> 8;
|
|
||||||
case 0x42: /*Size Y*/
|
|
||||||
return tvga->accel.size_y & 0xff;
|
|
||||||
case 0x43: /*Size Y*/
|
|
||||||
return tvga->accel.size_y >> 8;
|
|
||||||
|
|
||||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
|
||||||
case 0x84: case 0x85: case 0x86: case 0x87:
|
|
||||||
case 0x88: case 0x89: case 0x8a: case 0x8b:
|
|
||||||
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
|
||||||
case 0x90: case 0x91: case 0x92: case 0x93:
|
|
||||||
case 0x94: case 0x95: case 0x96: case 0x97:
|
|
||||||
case 0x98: case 0x99: case 0x9a: case 0x9b:
|
|
||||||
case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
|
||||||
case 0xa0: case 0xa1: case 0xa2: case 0xa3:
|
|
||||||
case 0xa4: case 0xa5: case 0xa6: case 0xa7:
|
|
||||||
case 0xa8: case 0xa9: case 0xaa: case 0xab:
|
|
||||||
case 0xac: case 0xad: case 0xae: case 0xaf:
|
|
||||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
|
|
||||||
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
|
||||||
case 0xb8: case 0xb9: case 0xba: case 0xbb:
|
|
||||||
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
|
|
||||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
|
||||||
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
|
||||||
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
|
||||||
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
|
||||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
|
||||||
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
|
||||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
|
||||||
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
|
||||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
|
||||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
|
||||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
|
||||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
|
||||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
|
||||||
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
|
||||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
|
||||||
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
|
||||||
return tvga->accel.pattern[addr & 0x7f];
|
|
||||||
}
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t tvga_accel_read_w(uint32_t addr, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
// pclog("tvga_accel_read_w %08X\n", addr);
|
|
||||||
return tvga_accel_read(addr, tvga) | (tvga_accel_read(addr + 1, tvga) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t tvga_accel_read_l(uint32_t addr, void *p)
|
|
||||||
{
|
|
||||||
tvga_t *tvga = (tvga_t *)p;
|
|
||||||
// pclog("tvga_accel_read_l %08X\n", addr);
|
|
||||||
return tvga_accel_read_w(addr, tvga) | (tvga_accel_read_w(addr + 2, tvga) << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *p)
|
|
||||||
{
|
|
||||||
svga_t *svga = (svga_t *)p;
|
|
||||||
tvga_t *tvga = (tvga_t *)svga->p;
|
|
||||||
// pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val);
|
|
||||||
tvga_accel_command(8, val << 24, tvga);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
|
|
||||||
{
|
|
||||||
svga_t *svga = (svga_t *)p;
|
|
||||||
tvga_t *tvga = (tvga_t *)svga->p;
|
|
||||||
// pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val);
|
|
||||||
tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tvga);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
|
|
||||||
{
|
|
||||||
svga_t *svga = (svga_t *)p;
|
|
||||||
tvga_t *tvga = (tvga_t *)svga->p;
|
|
||||||
// pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val);
|
|
||||||
tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tvga);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device_t tvga8900d_device =
|
device_t tvga8900d_device =
|
||||||
|
|
@ -1109,16 +289,5 @@ device_t tvga8900d_device =
|
||||||
NULL,
|
NULL,
|
||||||
tvga_speed_changed,
|
tvga_speed_changed,
|
||||||
tvga_force_redraw,
|
tvga_force_redraw,
|
||||||
svga_add_status_info
|
tvga_add_status_info
|
||||||
};
|
|
||||||
|
|
||||||
device_t tgui9440_device =
|
|
||||||
{
|
|
||||||
"Trident TGUI 9440",
|
|
||||||
tgui9440_init,
|
|
||||||
tvga_close,
|
|
||||||
NULL,
|
|
||||||
tvga_speed_changed,
|
|
||||||
tvga_force_redraw,
|
|
||||||
svga_add_status_info
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
extern device_t tvga8900d_device;
|
extern device_t tvga8900d_device;
|
||||||
extern device_t tgui9440_device;
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,13 @@ void vga_force_redraw(void *p)
|
||||||
vga->svga.fullchange = changeframecount;
|
vga->svga.fullchange = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vga_add_status_info(char *s, int max_len, void *p)
|
||||||
|
{
|
||||||
|
vga_t *vga = (vga_t *)p;
|
||||||
|
|
||||||
|
return svga_add_status_info(s, max_len, &vga->svga);
|
||||||
|
}
|
||||||
|
|
||||||
device_t vga_device =
|
device_t vga_device =
|
||||||
{
|
{
|
||||||
"VGA",
|
"VGA",
|
||||||
|
|
@ -122,5 +129,5 @@ device_t vga_device =
|
||||||
NULL,
|
NULL,
|
||||||
vga_speed_changed,
|
vga_speed_changed,
|
||||||
vga_force_redraw,
|
vga_force_redraw,
|
||||||
svga_add_status_info
|
vga_add_status_info
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "vid_s3.h"
|
#include "vid_s3.h"
|
||||||
#include "vid_s3_virge.h"
|
#include "vid_s3_virge.h"
|
||||||
#include "vid_tandy.h"
|
#include "vid_tandy.h"
|
||||||
|
#include "vid_tgui9440.h"
|
||||||
#include "vid_tvga.h"
|
#include "vid_tvga.h"
|
||||||
#include "vid_vga.h"
|
#include "vid_vga.h"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue