ViRGE changes of the day (August 20th, 2024)
1. ROM updated to 1.03. 2. Re-apply more fixes that were missed during the restructuring to be on par with PCem's speed. 3. Implemented Command DMA bus mastering required by Diamond Stealth 3D specific drivers (especially the GX2-based 4000). 4. Some indentation fixes.
This commit is contained in:
@@ -67,7 +67,7 @@ static int dither[4][4] = {
|
||||
#define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi"
|
||||
#define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin"
|
||||
#define ROM_VIRGE_GX2 "roms/video/s3virge/flagpoint.VBI"
|
||||
#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/86c357.bin"
|
||||
#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/DS3D4K v1.03 Brightness bug fix.bin"
|
||||
#define ROM_TRIO3D2X "roms/video/s3virge/TRIO3D2X_8mbsdr.VBI"
|
||||
|
||||
#define RB_SIZE 256
|
||||
@@ -286,9 +286,9 @@ typedef struct virge_t {
|
||||
s3d_t s3d_tri;
|
||||
|
||||
s3d_t s3d_buffer[RB_SIZE];
|
||||
int s3d_read_idx;
|
||||
int s3d_write_idx;
|
||||
int s3d_busy;
|
||||
atomic_int s3d_read_idx;
|
||||
atomic_int s3d_write_idx;
|
||||
atomic_int s3d_busy;
|
||||
|
||||
struct {
|
||||
uint32_t pri_ctrl;
|
||||
@@ -328,15 +328,14 @@ typedef struct virge_t {
|
||||
} streams;
|
||||
|
||||
fifo_entry_t fifo[FIFO_SIZE];
|
||||
volatile int fifo_read_idx, fifo_write_idx;
|
||||
|
||||
volatile int fifo_thread_run, render_thread_run;
|
||||
atomic_int fifo_read_idx, fifo_write_idx;
|
||||
atomic_int fifo_thread_run, render_thread_run;
|
||||
|
||||
thread_t * fifo_thread;
|
||||
event_t *wake_fifo_thread;
|
||||
event_t * fifo_not_full_event;
|
||||
|
||||
int virge_busy;
|
||||
atomic_int virge_busy;
|
||||
|
||||
uint8_t subsys_stat;
|
||||
uint8_t subsys_cntl;
|
||||
@@ -361,7 +360,16 @@ typedef struct virge_t {
|
||||
uint8_t cmd_dma;
|
||||
|
||||
uint32_t cmd_dma_base;
|
||||
uint32_t dma_ptr;
|
||||
uint32_t cmd_dma_buf_size;
|
||||
uint32_t cmd_dma_buf_size_mask;
|
||||
uint32_t cmd_base_addr;
|
||||
uint32_t cmd_dma_write_ptr_reg;
|
||||
uint32_t cmd_dma_write_ptr_update;
|
||||
uint32_t cmd_dma_read_ptr_reg;
|
||||
uint32_t dma_val;
|
||||
uint32_t dma_dbl_words;
|
||||
uint32_t dma_mmio_addr;
|
||||
uint32_t dma_data_type;
|
||||
|
||||
int pci;
|
||||
int is_agp;
|
||||
@@ -394,6 +402,8 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv);
|
||||
static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv);
|
||||
static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type);
|
||||
|
||||
enum {
|
||||
CMD_SET_AE = 1,
|
||||
CMD_SET_HC = (1 << 1),
|
||||
@@ -440,6 +450,8 @@ enum {
|
||||
#define INT_S3D_DONE (1 << 1)
|
||||
#define INT_FIFO_OVF (1 << 2)
|
||||
#define INT_FIFO_EMP (1 << 3)
|
||||
#define INT_HOST_DONE (1 << 4)
|
||||
#define INT_CMD_DONE (1 << 5)
|
||||
#define INT_3DF_EMP (1 << 6)
|
||||
#define INT_MASK 0xff
|
||||
|
||||
@@ -726,9 +738,6 @@ s3_virge_in(uint16_t addr, void *priv) {
|
||||
case 0x35:
|
||||
ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
|
||||
break;
|
||||
case 0x36:
|
||||
ret = (svga->crtc[0x36] & 0xfc) | 2;
|
||||
break; /*PCI bus*/
|
||||
case 0x45:
|
||||
virge->hwc_col_stack_pos = 0;
|
||||
ret = svga->crtc[0x45];
|
||||
@@ -783,7 +792,8 @@ s3_virge_in(uint16_t addr, void *priv) {
|
||||
}
|
||||
|
||||
static void
|
||||
s3_virge_recalctimings(svga_t *svga) {
|
||||
s3_virge_recalctimings(svga_t *svga)
|
||||
{
|
||||
virge_t *virge = (virge_t *) svga->priv;
|
||||
|
||||
svga->hdisp = svga->hdisp_old;
|
||||
@@ -855,7 +865,7 @@ s3_virge_recalctimings(svga_t *svga) {
|
||||
video_force_resize_set_monitor(1, svga->monitor_index);
|
||||
}
|
||||
|
||||
if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/
|
||||
if (((svga->crtc[0x67] & 0xc) != 0xc) || (virge->chip >= S3_VIRGEGX2)) { /*VGA mode*/
|
||||
svga->ma_latch |= (virge->ma_ext << 16);
|
||||
if (svga->crtc[0x51] & 0x30)
|
||||
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
|
||||
@@ -1035,7 +1045,7 @@ s3_virge_updatemapping(virge_t *virge) {
|
||||
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
|
||||
|
||||
if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/
|
||||
switch (svga->crtc[0x58] & 3) {
|
||||
switch (svga->crtc[0x58] & 7) {
|
||||
case 0: /*64k*/
|
||||
virge->linear_size = 0x10000;
|
||||
break;
|
||||
@@ -1104,7 +1114,8 @@ s3_virge_wait_fifo_idle(virge_t *virge) {
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
s3_virge_mmio_read(uint32_t addr, void *priv) {
|
||||
s3_virge_mmio_read(uint32_t addr, void *priv)
|
||||
{
|
||||
virge_t *virge = (virge_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
@@ -1121,6 +1132,7 @@ s3_virge_mmio_read(uint32_t addr, void *priv) {
|
||||
ret |= 0x10;
|
||||
else
|
||||
ret |= 0x30;
|
||||
|
||||
if (!virge->virge_busy)
|
||||
wake_fifo_thread(virge);
|
||||
return ret;
|
||||
@@ -1153,7 +1165,8 @@ s3_virge_mmio_read(uint32_t addr, void *priv) {
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
s3_virge_mmio_read_w(uint32_t addr, void *priv) {
|
||||
s3_virge_mmio_read_w(uint32_t addr, void *priv)
|
||||
{
|
||||
virge_t *virge = (virge_t *) priv;
|
||||
uint16_t ret;
|
||||
|
||||
@@ -1187,7 +1200,6 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv) {
|
||||
static uint32_t
|
||||
s3_virge_mmio_read_l(uint32_t addr, void *priv) {
|
||||
virge_t *virge = (virge_t *) priv;
|
||||
svga_t *svga = &virge->svga;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
switch (addr & 0xfffc) {
|
||||
@@ -1208,46 +1220,30 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
|
||||
break;
|
||||
case 0x81a0:
|
||||
ret = virge->streams.blend_ctrl;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x81c0:
|
||||
ret = virge->streams.pri_fb0;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81c4:
|
||||
ret = virge->streams.pri_fb1;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81c8:
|
||||
ret = virge->streams.pri_stride;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81cc:
|
||||
ret = virge->streams.buffer_ctrl;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d0:
|
||||
ret = virge->streams.sec_fb0;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d4:
|
||||
ret = virge->streams.sec_fb1;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d8:
|
||||
ret = virge->streams.sec_stride;
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81dc:
|
||||
ret = virge->streams.overlay_ctrl;
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81e0:
|
||||
ret = virge->streams.k1_vert_scale;
|
||||
@@ -1280,6 +1276,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
|
||||
ret |= 0x00001000;
|
||||
else
|
||||
ret |= 0x00003000;
|
||||
|
||||
ret |= virge->subsys_stat;
|
||||
if (!virge->virge_busy)
|
||||
wake_fifo_thread(virge);
|
||||
@@ -1294,12 +1291,15 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
|
||||
ret = virge->cmd_dma_base;
|
||||
break;
|
||||
case 0x8594:
|
||||
ret = virge->cmd_dma_write_ptr_reg;
|
||||
break;
|
||||
case 0x8598:
|
||||
ret = virge->dma_ptr;
|
||||
ret = virge->cmd_dma_read_ptr_reg;
|
||||
if (ret > virge->cmd_dma_write_ptr_reg)
|
||||
ret = virge->cmd_dma_write_ptr_reg;
|
||||
break;
|
||||
case 0x859c:
|
||||
ret = virge->cmd_dma;
|
||||
ret = 0; /*To prevent DMA overflows.*/
|
||||
break;
|
||||
|
||||
case 0xa4d4:
|
||||
@@ -1426,96 +1426,46 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) {
|
||||
|
||||
default:
|
||||
ret = s3_virge_mmio_read_w(addr, priv) | (s3_virge_mmio_read_w(addr + 2, priv) << 16);
|
||||
break;
|
||||
}
|
||||
|
||||
//pclog("MMIO ReadL=%04x, ret=%08x.\n", addr & 0xfffc, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
fifo_thread(void *param) {
|
||||
virge_t *virge = (virge_t *)param;
|
||||
|
||||
while (virge->fifo_thread_run) {
|
||||
thread_set_event(virge->fifo_not_full_event);
|
||||
thread_wait_event(virge->wake_fifo_thread, -1);
|
||||
thread_reset_event(virge->wake_fifo_thread);
|
||||
virge->virge_busy = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK];
|
||||
uint32_t val = fifo->val;
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE) {
|
||||
case FIFO_WRITE_BYTE:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000)
|
||||
s3_virge_bitblt(virge, 8, val);
|
||||
else if (((fifo->addr_type & FIFO_ADDR) & 0xffff) == 0x859c)
|
||||
virge->cmd_dma = val;
|
||||
break;
|
||||
case FIFO_WRITE_WORD:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16);
|
||||
else
|
||||
s3_virge_bitblt(virge, 16, val);
|
||||
} else if (((fifo->addr_type & FIFO_ADDR) & 0xfffe) == 0x859c)
|
||||
virge->cmd_dma = val;
|
||||
break;
|
||||
case FIFO_WRITE_DWORD:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 32,
|
||||
((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
else
|
||||
s3_virge_bitblt(virge, 32, val);
|
||||
} else {
|
||||
switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) {
|
||||
case 0x8590:
|
||||
virge->cmd_dma_base = val;
|
||||
break;
|
||||
|
||||
case 0x8594:
|
||||
virge->dma_ptr = val;
|
||||
break;
|
||||
|
||||
case 0x8598:
|
||||
break;
|
||||
|
||||
case 0x859c:
|
||||
virge->cmd_dma = val;
|
||||
break;
|
||||
|
||||
s3_virge_mmio_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val)
|
||||
{
|
||||
switch (addr) {
|
||||
case 0xa000 ... 0xa1fc:
|
||||
{
|
||||
int x = (fifo->addr_type & FIFO_ADDR) & 4;
|
||||
int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7;
|
||||
int x = addr & 4;
|
||||
int y = (addr >> 3) & 7;
|
||||
int color;
|
||||
int byte;
|
||||
uint32_t addr = (fifo->addr_type & FIFO_ADDR);
|
||||
uint32_t newaddr = addr;
|
||||
virge->s3d.pattern_8[y * 8 + x] = val & 0xff;
|
||||
virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8;
|
||||
virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16;
|
||||
virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24;
|
||||
|
||||
x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6;
|
||||
y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7;
|
||||
x = (addr >> 1) & 6;
|
||||
y = (addr >> 4) & 7;
|
||||
virge->s3d.pattern_16[y * 8 + x] = val & 0xffff;
|
||||
virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16;
|
||||
|
||||
addr &= 0x00ff;
|
||||
newaddr &= 0x00ff;
|
||||
for (uint8_t xx = 0; xx < 4; xx++) {
|
||||
x = ((addr + xx) / 3) % 8;
|
||||
y = ((addr + xx) / 24) % 8;
|
||||
color = ((addr + xx) % 3) << 3;
|
||||
x = ((newaddr + xx) / 3) % 8;
|
||||
y = ((newaddr + xx) / 24) % 8;
|
||||
color = ((newaddr + xx) % 3) << 3;
|
||||
byte = (xx << 3);
|
||||
virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color);
|
||||
virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color;
|
||||
}
|
||||
|
||||
x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7;
|
||||
y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7;
|
||||
x = (addr >> 2) & 7;
|
||||
y = (addr >> 5) & 7;
|
||||
virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff;
|
||||
} break;
|
||||
|
||||
@@ -1788,6 +1738,46 @@ fifo_thread(void *param) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fifo_thread(void *param)
|
||||
{
|
||||
virge_t *virge = (virge_t *)param;
|
||||
|
||||
while (virge->fifo_thread_run) {
|
||||
thread_set_event(virge->fifo_not_full_event);
|
||||
thread_wait_event(virge->wake_fifo_thread, -1);
|
||||
thread_reset_event(virge->wake_fifo_thread);
|
||||
virge->virge_busy = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK];
|
||||
uint32_t val = fifo->val;
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE) {
|
||||
case FIFO_WRITE_BYTE:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xffff) < 0x8000)
|
||||
s3_virge_bitblt(virge, 8, val);
|
||||
break;
|
||||
case FIFO_WRITE_WORD:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xfffe) < 0x8000) {
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16);
|
||||
else
|
||||
s3_virge_bitblt(virge, 16, val);
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITE_DWORD:
|
||||
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) {
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 32,
|
||||
((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
else
|
||||
s3_virge_bitblt(virge, 32, val);
|
||||
} else
|
||||
s3_virge_mmio_write_fifo_l(virge, (fifo->addr_type & FIFO_ADDR) & 0xfffc, val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1802,6 +1792,9 @@ fifo_thread(void *param) {
|
||||
}
|
||||
virge->virge_busy = 0;
|
||||
virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP;
|
||||
if (virge->cmd_dma)
|
||||
virge->subsys_stat |= INT_HOST_DONE | INT_CMD_DONE;
|
||||
|
||||
s3_virge_update_irqs(virge);
|
||||
}
|
||||
}
|
||||
@@ -1852,7 +1845,7 @@ static void
|
||||
s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) {
|
||||
virge_t *virge = (virge_t *) priv;
|
||||
|
||||
if ((addr & 0xfffc) < 0x8000)
|
||||
if ((addr & 0xffff) < 0x8000)
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE);
|
||||
else switch (addr & 0xffff) {
|
||||
case 0x83b0 ... 0x83df:
|
||||
@@ -1870,9 +1863,10 @@ static void
|
||||
s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) {
|
||||
virge_t *virge = (virge_t *) priv;
|
||||
|
||||
if ((addr & 0xfffc) < 0x8000)
|
||||
if ((addr & 0xfffe) < 0x8000)
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD);
|
||||
else switch (addr & 0xfffe) {
|
||||
default:
|
||||
case 0x83d4:
|
||||
s3_virge_mmio_write(addr, val, priv);
|
||||
s3_virge_mmio_write(addr + 1, val >> 8, priv);
|
||||
@@ -1893,7 +1887,8 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
|
||||
else if ((addr & 0xe000) == 0xa000)
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
|
||||
else switch (addr & 0xfffc) {
|
||||
else {
|
||||
switch (addr & 0xfffc) {
|
||||
case 0x8180:
|
||||
virge->streams.pri_ctrl = val;
|
||||
svga_recalctimings(svga);
|
||||
@@ -1927,38 +1922,38 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
|
||||
case 0x81c0:
|
||||
virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ?
|
||||
(val & 0x7fffff) : (val & 0x3fffff));
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81c4:
|
||||
virge->streams.pri_fb1 = ((virge->memory_size == 8) ?
|
||||
(val & 0x7fffff) : (val & 0x3fffff));
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81c8:
|
||||
virge->streams.pri_stride = val & 0xfff;
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81cc:
|
||||
virge->streams.buffer_ctrl = val;
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d0:
|
||||
virge->streams.sec_fb0 = val;
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d4:
|
||||
virge->streams.sec_fb1 = val;
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81d8:
|
||||
virge->streams.sec_stride = val;
|
||||
svga_recalctimings(svga);
|
||||
s3_virge_update_buffer(virge);
|
||||
svga->fullchange = changeframecount;
|
||||
break;
|
||||
case 0x81dc:
|
||||
@@ -2022,32 +2017,79 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
|
||||
s3_virge_updatemapping(virge);
|
||||
break;
|
||||
|
||||
case 0x8590:
|
||||
virge->cmd_dma_base = val;
|
||||
virge->cmd_dma_buf_size = (val & 2) ? 0x10000 : 0x1000;
|
||||
virge->cmd_dma_buf_size_mask = virge->cmd_dma_buf_size - 1;
|
||||
virge->cmd_base_addr = (val & 2) ? (val & 0xffff0000) : (val & 0xfffff000);
|
||||
break;
|
||||
|
||||
case 0x8594:
|
||||
virge->cmd_dma_write_ptr_update = val & (1 << 16);
|
||||
if (virge->cmd_dma_write_ptr_update) {
|
||||
virge->cmd_dma_write_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff);
|
||||
virge->dma_dbl_words = 0;
|
||||
virge->dma_data_type = 0;
|
||||
virge->dma_val = 0;
|
||||
if (virge->cmd_dma) {
|
||||
while (virge->cmd_dma_read_ptr_reg != virge->cmd_dma_write_ptr_reg) {
|
||||
virge->cmd_dma_write_ptr_update = 0;
|
||||
dma_bm_read(virge->cmd_base_addr + virge->cmd_dma_read_ptr_reg, (uint8_t *)&virge->dma_val, 4, 4);
|
||||
if (!virge->dma_dbl_words) {
|
||||
virge->dma_dbl_words = (virge->dma_val & 0xffff);
|
||||
virge->dma_data_type = !!(virge->dma_val & (1 << 31));
|
||||
if (virge->dma_data_type)
|
||||
virge->dma_mmio_addr = 0;
|
||||
else
|
||||
virge->dma_mmio_addr = ((virge->dma_val >> 16) << 2) & 0xfffc;
|
||||
} else {
|
||||
s3_virge_mmio_write_l(virge->dma_mmio_addr, virge->dma_val, virge);
|
||||
virge->dma_dbl_words--;
|
||||
virge->dma_mmio_addr = (virge->dma_mmio_addr + 4) & 0xfffc;
|
||||
}
|
||||
virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_read_ptr_reg + 4) & (virge->cmd_dma_buf_size_mask - 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8598:
|
||||
virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff);
|
||||
break;
|
||||
|
||||
case 0x859c:
|
||||
virge->cmd_dma = val & 1;
|
||||
virge->cmd_dma_write_ptr_reg = 0;
|
||||
virge->cmd_dma_read_ptr_reg = 0;
|
||||
break;
|
||||
|
||||
case 0xff20:
|
||||
s3_virge_mmio_write(addr, val, priv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define READ(addr, val) \
|
||||
do { \
|
||||
switch (bpp) { \
|
||||
case 0: /*8 bpp*/ \
|
||||
val = vram[addr & svga->vram_mask]; \
|
||||
val = vram[addr & virge->vram_mask]; \
|
||||
break; \
|
||||
case 1: /*16 bpp*/ \
|
||||
val = *(uint16_t *)&vram[addr & svga->vram_mask]; \
|
||||
val = *(uint16_t *)&vram[addr & virge->vram_mask]; \
|
||||
break; \
|
||||
case 2: /*24 bpp*/ \
|
||||
val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \
|
||||
val = (*(uint32_t *)&vram[addr & virge->vram_mask]) & 0xffffff; \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask]
|
||||
#define Z_READ(addr) *(uint16_t *)&vram[addr & virge->vram_mask]
|
||||
|
||||
#define Z_WRITE(addr, val) \
|
||||
if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \
|
||||
*(uint16_t *)&vram[addr & svga->vram_mask] = val
|
||||
*(uint16_t *)&vram[addr & virge->vram_mask] = val
|
||||
|
||||
#define CLIP(x, y) \
|
||||
do { \
|
||||
@@ -2133,19 +2175,19 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
|
||||
do { \
|
||||
switch (bpp) { \
|
||||
case 0: /*8 bpp*/ \
|
||||
vram[addr & svga->vram_mask] = val; \
|
||||
virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
|
||||
vram[addr & virge->vram_mask] = val; \
|
||||
virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
|
||||
changeframecount; \
|
||||
break; \
|
||||
case 1: /*16 bpp*/ \
|
||||
*(uint16_t *)&vram[addr & svga->vram_mask] = val; \
|
||||
virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
|
||||
*(uint16_t *)&vram[addr & virge->vram_mask] = val; \
|
||||
virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
|
||||
changeframecount; \
|
||||
break; \
|
||||
case 2: /*24 bpp*/ \
|
||||
*(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) |\
|
||||
(vram[(addr + 3) & svga->vram_mask] << 24); \
|
||||
virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = \
|
||||
*(uint32_t *)&vram[addr & virge->vram_mask] = (val & 0xffffff) |\
|
||||
(vram[(addr + 3) & virge->vram_mask] << 24); \
|
||||
virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \
|
||||
changeframecount; \
|
||||
break; \
|
||||
} \
|
||||
@@ -2153,7 +2195,6 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) {
|
||||
|
||||
static void
|
||||
s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) {
|
||||
svga_t *svga = &virge->svga;
|
||||
uint8_t *vram = virge->svga.vram;
|
||||
uint32_t mono_pattern[64];
|
||||
int count_mask;
|
||||
@@ -3185,7 +3226,6 @@ dest_pixel_lit_texture_modulate(s3d_state_t *state) {
|
||||
|
||||
static void
|
||||
tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) {
|
||||
svga_t *svga = &virge->svga;
|
||||
uint8_t *vram = virge->svga.vram;
|
||||
int x_dir = s3d_tri->tlr ? 1 : -1;
|
||||
int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE);
|
||||
@@ -3305,7 +3345,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
|
||||
}
|
||||
}
|
||||
|
||||
virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount;
|
||||
virge->svga.changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount;
|
||||
|
||||
dest_addr = dest_offset + (x * (bpp + 1));
|
||||
z_addr = z_offset + (x << 1);
|
||||
@@ -3343,16 +3383,17 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int
|
||||
uint32_t src_g = 0;
|
||||
uint32_t src_b = 0;
|
||||
|
||||
|
||||
switch (bpp) {
|
||||
case 0: /*8 bpp*/
|
||||
/*Not implemented yet*/
|
||||
break;
|
||||
case 1: /*16 bpp*/
|
||||
src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask];
|
||||
src_col = *(uint16_t *)&vram[dest_addr & virge->vram_mask];
|
||||
RGB15_TO_24(src_col, src_r, src_g, src_b);
|
||||
break;
|
||||
case 2: /*24 bpp*/
|
||||
src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff;
|
||||
src_col = (*(uint32_t *)&vram[dest_addr & virge->vram_mask]) & 0xffffff;
|
||||
RGB24_TO_24(src_col, src_r, src_g, src_b);
|
||||
break;
|
||||
}
|
||||
@@ -3565,7 +3606,8 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) {
|
||||
}
|
||||
|
||||
static void
|
||||
render_thread(void *param) {
|
||||
render_thread(void *param)
|
||||
{
|
||||
virge_t *virge = (virge_t *)param;
|
||||
|
||||
while (virge->render_thread_run) {
|
||||
@@ -3576,7 +3618,7 @@ render_thread(void *param) {
|
||||
s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]);
|
||||
virge->s3d_read_idx++;
|
||||
|
||||
if (RB_ENTRIES == (RB_SIZE - 1))
|
||||
if (RB_ENTRIES == RB_MASK)
|
||||
thread_set_event(virge->not_full_event);
|
||||
}
|
||||
virge->s3d_busy = 0;
|
||||
@@ -3586,7 +3628,8 @@ render_thread(void *param) {
|
||||
}
|
||||
|
||||
static void
|
||||
queue_triangle(virge_t *virge) {
|
||||
queue_triangle(virge_t *virge)
|
||||
{
|
||||
if (RB_FULL) {
|
||||
thread_reset_event(virge->not_full_event);
|
||||
if (RB_FULL)
|
||||
@@ -4361,7 +4404,7 @@ s3_virge_init(const device_t *info)
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
|
||||
|
||||
virge->pci_regs[PCI_REG_COMMAND] = 3;
|
||||
virge->pci_regs[PCI_REG_COMMAND] = 7;
|
||||
virge->pci_regs[0x05] = 0;
|
||||
virge->pci_regs[0x06] = 0;
|
||||
virge->pci_regs[0x07] = 2;
|
||||
|
Reference in New Issue
Block a user