From de09618504c7cc2c9283c1fbcaf7ffb62e58807d Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Fri, 6 Jan 2017 06:24:35 -0600 Subject: [PATCH 1/4] Fix PFIFO NOPs --- src/vid_nv_riva128.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index c2a19fe4a..05e06f277 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1234,7 +1234,7 @@ static void riva128_pusher_run(int chanid, void *p) uint32_t method = cmd & 0x1ffc; int subchannel = (cmd >> 13) & 7; int method_count = (cmd >> 18) & 0x7ff; - for(int i = 0;i<=method_count;i++) + for(int i = 0;i Date: Fri, 6 Jan 2017 07:08:53 -0600 Subject: [PATCH 2/4] MAJOR overhaul to nVidia PGRAPH object loading --- src/vid_nv_riva128.c | 60 ++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 05e06f277..d2a4150ae 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -131,7 +131,7 @@ typedef struct riva128_t int pgraph_speedhack; uint32_t obj_handle[8]; - uint8_t obj_class[8]; + uint16_t obj_class[8]; uint32_t debug[5]; @@ -158,6 +158,8 @@ typedef struct riva128_t uint32_t notify; + uint32_t instance; + struct { uint32_t point_color; @@ -1054,14 +1056,12 @@ static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) } } -static uint8_t riva128_ramht_lookup(uint32_t handle, void *p) +static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) { riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); - uint8_t objclass; - uint32_t ramht_base = riva128->pfifo.ramht_addr; uint32_t tmp = handle; @@ -1085,12 +1085,10 @@ static uint8_t riva128_ramht_lookup(uint32_t handle, void *p) hash ^= riva128->pfifo.caches[1].chanid << (bits - 4); - objclass = riva128->pramin[ramht_base + (hash * 8)]; - objclass &= 0xff; - return objclass; + return riva128->pramin[ramht_base + (hash * 8)]; } -static void riva128_pgraph_point_exec_method_speedhack(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; @@ -1183,7 +1181,7 @@ static void riva128_pgraph_exec_method_speedhack(int subchanid, int offset, uint break; } } -} +}*/ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, uint32_t val, void *p) { @@ -1191,21 +1189,39 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui 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); + if(offset < 0x100) + { + if(offset == 0) + { + if(riva128->card_id == 0x03) + { + uint32_t tmp = riva128_ramht_lookup(val, riva128); + riva128->pgraph.instance = (tmp & 0xffff) << 4; + riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.instance]; + riva128->pgraph.ctx_user = (chanid << 24) | (tmp & 0xf0000) | (subchanid << 13); + } + else if(riva128->card_id >= 0x04 && riva128->card_id < 0x10) + { + riva128->pgraph.ctx_switch[3] = (riva128_ramht_lookup(val, riva128) & 0xffff) << 4; + riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.ctx_switch[3]]; + riva128->pgraph.ctx_switch[1] = riva128->pgraph.ctx_cache[subchanid][1] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 4]; + riva128->pgraph.ctx_switch[2] = riva128->pgraph.ctx_cache[subchanid][2] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 8]; + riva128->pgraph.ctx_user = (chanid << 24) | (subchanid << 13); + } + else if(riva128->card_id >= 0x10 && riva128->card_id < 0x40) + { + riva128->pgraph.ctx_switch[3] = (riva128_ramht_lookup(val, riva128) & 0xffff) << 4; + riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.ctx_switch[3]]; + riva128->pgraph.ctx_switch[1] = riva128->pgraph.ctx_cache[subchanid][1] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 4]; + riva128->pgraph.ctx_switch[2] = riva128->pgraph.ctx_cache[subchanid][2] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 8]; + riva128->pgraph.ctx_switch[4] = riva128->pgraph.ctx_cache[subchanid][4] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 12]; + riva128->pgraph.ctx_user = (chanid << 24) | (subchanid << 13); + } + } + } + if(riva128->pgraph.pgraph_speedhack) { - if(offset < 0x100) - { - //These methods are executed by the puller itself. - if(offset == 0) - { - riva128->pgraph.obj_handle[subchanid] = val; - riva128->pgraph.obj_class[subchanid] = riva128_ramht_lookup(val, riva128); - } - } - else - { - if(riva128->card_id == 0x03) riva128_pgraph_exec_method_speedhack(subchanid, offset, val, riva128); - } } else { From 91939ac23b2251191e4ea7742ba907d43547e540 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Fri, 6 Jan 2017 07:23:52 -0600 Subject: [PATCH 3/4] Fix a little oopsie --- src/vid_nv_riva128.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d2a4150ae..7e448049d 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1198,7 +1198,7 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui uint32_t tmp = riva128_ramht_lookup(val, riva128); riva128->pgraph.instance = (tmp & 0xffff) << 4; riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.instance]; - riva128->pgraph.ctx_user = (chanid << 24) | (tmp & 0xf0000) | (subchanid << 13); + riva128->pgraph.ctx_user = (chanid << 24) | (tmp & 0x1f0000) | (subchanid << 13); } else if(riva128->card_id >= 0x04 && riva128->card_id < 0x10) { From cb4db2fada451ad17b4dbe3816183caafbb8cbe5 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Fri, 6 Jan 2017 09:02:53 -0600 Subject: [PATCH 4/4] MAJOR ATI 18800 improvements --- src/vid_ati18800.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index c7993b2cf..74cc6be64 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -1,4 +1,4 @@ -/* Copyright holders: Sarah Walker +/* Copyright holders: Sarah Walker, Melissa Goad see COPYING for more details */ /*ATI 18800 emulation (VGA Edge-16)*/ @@ -32,7 +32,8 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p) // pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { @@ -41,8 +42,11 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p) break; case 0x1cf: ati18800->regs[ati18800->index] = val; + pclog("ATI 18800 ATI register write %02x %02x\n", ati18800->index, val); switch (ati18800->index) { + case 0xb0: + svga_recalctimings(svga); case 0xb2: case 0xbe: if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ @@ -65,10 +69,22 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p) case 0x3D5: if (svga->crtcreg <= 0x18) val &= mask_crtc[svga->crtcreg]; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if ((ati18800->regs[0xb4] & 4) && (svga->crtcreg == 9)) + val = (svga->crtc[9] & ~0x60) | (val & 0x60); + if ((ati18800->regs[0xb4] & 8) && ((svga->crtcreg == 6) || (svga->crtcreg == 0x10) || (svga->crtcreg == 0x12) || (svga->crtcreg == 0x15) || (svga->crtcreg == 0x16))) + return; + if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 7)) + val = (svga->crtc[9] & ~0x10) | (val & 0x10); + if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 9)) + val = (svga->crtc[9] & ~0xdf) | (val & 0xdf); + if ((ati18800->regs[0xb4] & 8) && (svga->crtcreg == 0x11)) + val = (svga->crtc[9] & ~0xf0) | (val & 0xf0); + if ((ati18800->regs[0xb4] & 0x10) && ((svga->crtcreg == 0x0a) || (svga->crtcreg == 0x0b))) + return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; if (old != val) @@ -130,6 +146,22 @@ uint8_t ati18800_in(uint16_t addr, void *p) return temp; } +void ati18800_recalctimings(svga_t *svga) +{ + ati18800_t *ati18800 = (ati18800_t *)svga->p; + + svga->ma_latch += (ati18800->regs[0xb0] & 0xc0) << 10; + + if(ati18800->regs[0xb1] & 0x40) + { + svga->vtotal >>= 1; + svga->dispend >>= 1; + svga->vsyncstart >>= 1; + svga->split >>= 1; + svga->vblankstart >>= 1; + } +} + void *ati18800_init() { ati18800_t *ati18800 = malloc(sizeof(ati18800_t));