Merge pull request #66 from MoochMcGee/riva128-work

DRAWING
This commit is contained in:
OBattler
2016-12-28 04:52:06 +01:00
committed by GitHub

View File

@@ -128,6 +128,8 @@ typedef struct riva128_t
struct struct
{ {
int pgraph_speedhack;
uint32_t obj_handle[8]; uint32_t obj_handle[8];
uint8_t obj_class[8]; uint8_t obj_class[8];
@@ -139,10 +141,10 @@ typedef struct riva128_t
uint32_t invalid; uint32_t invalid;
uint32_t invalid_en; uint32_t invalid_en;
uint32_t ctx_switch; uint32_t ctx_switch[5];
uint32_t ctx_control; uint32_t ctx_control;
uint32_t ctx_user; uint32_t ctx_user;
uint32_t ctx_cache[8]; uint32_t ctx_cache[8][5];
uint32_t fifo_enable; uint32_t fifo_enable;
@@ -153,6 +155,14 @@ typedef struct riva128_t
uint32_t dst_canvas_min, dst_canvas_max; uint32_t dst_canvas_min, dst_canvas_max;
uint32_t beta; uint32_t beta;
uint32_t notify;
struct
{
uint32_t point_color;
int32_t point_x[0x20], point_y[0x20];
} speedhack;
} pgraph; } pgraph;
struct struct
@@ -286,6 +296,14 @@ static uint32_t riva128_pgraph_do_blend(uint32_t factor, uint32_t dst, uint32_t
return ((dst * (0x100 - factor)) + (src * factor)) >> 6; return ((dst * (0x100 - factor)) + (src * factor)) >> 6;
} }
static uint8_t riva128_pgraph_draw_point(int offset, void *p)
{
riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga;
svga->vram[(riva128->pgraph.speedhack.point_y[offset] * riva128->pfb.width) + riva128->pgraph.speedhack.point_x[offset]] = riva128->pgraph.speedhack.point_color;
}
static uint8_t riva128_pmc_read(uint32_t addr, void *p) static uint8_t riva128_pmc_read(uint32_t addr, void *p)
{ {
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
@@ -363,7 +381,7 @@ static void riva128_pmc_interrupt(int num, void *p)
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga; svga_t *svga = &riva128->svga;
riva128->pmc.intr &= ~(1 << num); riva128->pmc.intr |= (1 << num);
picint(1 << riva128->pci_regs[0x3c]); picint(1 << riva128->pci_regs[0x3c]);
} }
@@ -535,7 +553,7 @@ static void riva128_pfifo_interrupt(int num, void *p)
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga; svga_t *svga = &riva128->svga;
riva128->pfifo.intr &= ~(1 << num); riva128->pfifo.intr |= (1 << num);
riva128_pmc_interrupt(8, riva128); riva128_pmc_interrupt(8, riva128);
} }
@@ -619,7 +637,7 @@ static void riva128_ptimer_interrupt(int num, void *p)
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga; svga_t *svga = &riva128->svga;
riva128->ptimer.intr &= ~(1 << num); riva128->ptimer.intr |= (1 << num);
riva128_pmc_interrupt(20, riva128); riva128_pmc_interrupt(20, riva128);
} }
@@ -755,10 +773,10 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p)
case 0x400146: ret = (riva128->pgraph.invalid_en >> 16) & 0xff; break; case 0x400146: ret = (riva128->pgraph.invalid_en >> 16) & 0xff; break;
case 0x400147: ret = (riva128->pgraph.invalid_en >> 24) & 0xff; break; case 0x400147: ret = (riva128->pgraph.invalid_en >> 24) & 0xff; break;
case 0x400180: ret = riva128->pgraph.ctx_switch & 0xff; break; case 0x400180: ret = riva128->pgraph.ctx_switch[0] & 0xff; break;
case 0x400181: ret = (riva128->pgraph.ctx_switch >> 8) & 0xff; break; case 0x400181: ret = (riva128->pgraph.ctx_switch[0] >> 8) & 0xff; break;
case 0x400182: ret = (riva128->pgraph.ctx_switch >> 16) & 0xff; break; case 0x400182: ret = (riva128->pgraph.ctx_switch[0] >> 16) & 0xff; break;
case 0x400183: ret = (riva128->pgraph.ctx_switch >> 24) & 0xff; break; case 0x400183: ret = (riva128->pgraph.ctx_switch[0] >> 24) & 0xff; break;
case 0x400190: ret = riva128->pgraph.ctx_control & 0xff; break; case 0x400190: ret = riva128->pgraph.ctx_control & 0xff; break;
case 0x400191: ret = (riva128->pgraph.ctx_control >> 8) & 0xff; break; case 0x400191: ret = (riva128->pgraph.ctx_control >> 8) & 0xff; break;
@@ -769,7 +787,7 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p)
case 0x400196: ret = (riva128->pgraph.ctx_user >> 16) & 0xff; break; case 0x400196: ret = (riva128->pgraph.ctx_user >> 16) & 0xff; break;
case 0x400197: ret = (riva128->pgraph.ctx_user >> 24) & 0xff; break; case 0x400197: ret = (riva128->pgraph.ctx_user >> 24) & 0xff; break;
case 0x4001a0 ... 0x4001bf: ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2] >> ((addr & 3) << 3)) & 0xff; break; case 0x4001a0 ... 0x4001bf: ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] >> ((addr & 3) << 3)) & 0xff; break;
case 0x4006a4: ret = riva128->pgraph.fifo_enable & 1; break; case 0x4006a4: ret = riva128->pgraph.fifo_enable & 1; break;
} }
@@ -812,6 +830,10 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p)
case 0x400641: ret = (riva128->pgraph.beta >> 8) & 0xff; break; case 0x400641: ret = (riva128->pgraph.beta >> 8) & 0xff; break;
case 0x400642: ret = (riva128->pgraph.beta >> 16) & 0xff; break; case 0x400642: ret = (riva128->pgraph.beta >> 16) & 0xff; break;
case 0x400643: ret = (riva128->pgraph.beta >> 24) & 0xff; break; case 0x400643: ret = (riva128->pgraph.beta >> 24) & 0xff; break;
case 0x400684: ret = riva128->pgraph.notify & 0xff; break;
case 0x400685: ret = (riva128->pgraph.notify >> 8) & 0xff; break;
case 0x400686: ret = (riva128->pgraph.notify >> 16) & 0xff; break;
case 0x400687: ret = (riva128->pgraph.notify >> 24) & 0xff; break;
} }
return ret; return ret;
@@ -861,7 +883,7 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p)
break; break;
case 0x400180: case 0x400180:
riva128->pgraph.debug[1] &= ~1; //Clear recent volatile reset bit on object switch. riva128->pgraph.debug[1] &= ~1; //Clear recent volatile reset bit on object switch.
riva128->pgraph.ctx_switch = val & 0x3ff3f71f; riva128->pgraph.ctx_switch[0] = val & 0x3ff3f71f;
break; break;
case 0x400190: case 0x400190:
riva128->pgraph.ctx_control = val & 0x11010103; riva128->pgraph.ctx_control = val & 0x11010103;
@@ -870,7 +892,7 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p)
riva128->pgraph.ctx_user = val & 0x7f1fe000; riva128->pgraph.ctx_user = val & 0x7f1fe000;
break; break;
case 0x4001a0 ... 0x4001bc: case 0x4001a0 ... 0x4001bc:
riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2] = val & 0x3ff3f71f; riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] = val & 0x3ff3f71f;
break; break;
case 0x40053c: case 0x40053c:
riva128->pgraph.uclip_xmin = val & 0x3ffff; riva128->pgraph.uclip_xmin = val & 0x3ffff;
@@ -915,6 +937,9 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p)
riva128->pgraph.beta = tmp; riva128->pgraph.beta = tmp;
break; break;
} }
case 0x400684:
riva128->pgraph.notify = val & 0x0011ffff;
break;
case 0x4006a4: case 0x4006a4:
riva128->pgraph.fifo_enable = val & 1; riva128->pgraph.fifo_enable = val & 1;
break; break;
@@ -936,6 +961,26 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p)
} }
} }
static void riva128_pgraph_interrupt(int num, void *p)
{
riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga;
riva128->pgraph.intr |= (1 << num);
riva128_pmc_interrupt(12, riva128);
}
static void riva128_pgraph_invalid_interrupt(int num, void *p)
{
riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga;
riva128->pgraph.invalid |= (1 << num);
riva128_pgraph_interrupt(0, riva128);
}
static uint8_t riva128_pramdac_read(uint32_t addr, void *p) static uint8_t riva128_pramdac_read(uint32_t addr, void *p)
{ {
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
@@ -1045,7 +1090,79 @@ static uint8_t riva128_ramht_lookup(uint32_t handle, void *p)
return objclass; return objclass;
} }
static void riva128_pgraph_exec_method(int subchanid, int offset, uint32_t val, void *p) static void riva128_pgraph_point_exec_method_speedhack(int offset, uint32_t val, void *p)
{
riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga;
switch(offset)
{
case 0x0104:
{
//NOTIFY
if(!(riva128->pgraph.invalid & 0x10000))
{
if(riva128->pgraph.notify & 0x10000)
{
riva128_pgraph_invalid_interrupt(12, riva128);
riva128->pgraph.fifo_enable = 0;
}
}
if(!(riva128->pgraph.invalid & 0x10000) && !(riva128->pgraph.invalid & 0x10))
{
riva128->pgraph.notify |= 1 << 16;
riva128->pgraph.notify |= (val & 0xf) << 20;
}
break;
}
case 0x0304:
{
//COLOR
riva128->pgraph.speedhack.point_color = val;
break;
}
case 0x0400 ... 0x47c:
{
riva128->pgraph.speedhack.point_x[(offset & 0x7c) >> 2] = val & 0xffff;
riva128->pgraph.speedhack.point_y[(offset & 0x7c) >> 2] = val >> 16;
riva128_pgraph_draw_point((offset & 0x7c) >> 2, riva128);
break;
}
break;
}
}
static void riva128_pgraph_gdi_exec_method_speedhack(int offset, uint32_t val, void *p)
{
riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga;
switch(offset)
{
case 0x0104:
{
//NOTIFY
if(!(riva128->pgraph.invalid & 0x10000))
{
if(riva128->pgraph.notify & 0x10000)
{
riva128_pgraph_invalid_interrupt(12, riva128);
riva128->pgraph.fifo_enable = 0;
}
}
if(!(riva128->pgraph.invalid & 0x10000) && !(riva128->pgraph.invalid & 0x10))
{
riva128->pgraph.notify |= 1 << 16;
riva128->pgraph.notify |= (val & 0xf) << 20;
}
break;
}
}
}
static void riva128_pgraph_exec_method_speedhack(int subchanid, int offset, uint32_t val, void *p)
{ {
riva128_t *riva128 = (riva128_t *)p; riva128_t *riva128 = (riva128_t *)p;
svga_t *svga = &riva128->svga; svga_t *svga = &riva128->svga;
@@ -1053,9 +1170,18 @@ static void riva128_pgraph_exec_method(int subchanid, int offset, uint32_t val,
switch(riva128->pgraph.obj_class[subchanid]) switch(riva128->pgraph.obj_class[subchanid])
{ {
case 0x30: case 0x08:
//NV1_NULL {
return; //NV1_POINT
riva128_pgraph_point_exec_method_speedhack(offset, val, riva128);
break;
}
case 0x0c:
{
//NV3_GDI
riva128_pgraph_gdi_exec_method_speedhack(offset, val, riva128);
break;
}
} }
} }
@@ -1065,6 +1191,8 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui
svga_t *svga = &riva128->svga; svga_t *svga = &riva128->svga;
pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc);
if(riva128->pgraph.pgraph_speedhack)
{
if(offset < 0x100) if(offset < 0x100)
{ {
//These methods are executed by the puller itself. //These methods are executed by the puller itself.
@@ -1076,7 +1204,12 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui
} }
else else
{ {
riva128_pgraph_exec_method(subchanid, offset, val, riva128); if(riva128->card_id == 0x03) riva128_pgraph_exec_method_speedhack(subchanid, offset, val, riva128);
}
}
else
{
pclog("RIVA 128 That was a bad idea, turning off the PGRAPH speedhack.\n");
} }
} }
@@ -1938,6 +2071,8 @@ static void *riva128_init()
riva128->memory_size = device_get_config_int("memory"); riva128->memory_size = device_get_config_int("memory");
riva128->pgraph.pgraph_speedhack = device_get_config_int("pgraph_speedhack");
svga_init(&riva128->svga, riva128, riva128->memory_size << 20, svga_init(&riva128->svga, riva128, riva128->memory_size << 20,
riva128_recalctimings, riva128_recalctimings,
riva128_in, riva128_out, riva128_in, riva128_out,
@@ -2092,6 +2227,27 @@ static device_config_t riva128_config[] =
static device_config_t riva128zx_config[] = static device_config_t riva128zx_config[] =
{ {
{
.name = "pgraph_speedhack",
.description = "PGRAPH speedhack",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "Off",
.value = 0,
},
{
.description = "On",
.value = 1,
},
{
.description = ""
}
},
//DO NOT TURN THIS OFF YET. THE PGRAPH SPEEDHACK IS CURRENTLY NECESSARY FOR WORKING EMULATION.
.default_int = 1
},
{ {
.name = "memory", .name = "memory",
.description = "Memory size", .description = "Memory size",