@@ -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));
|
||||
|
@@ -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 & 0x1f0000) | (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
|
||||
{
|
||||
@@ -1234,7 +1250,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<method_count;i++)
|
||||
{
|
||||
riva128_puller_exec_method(chanid, subchannel, method, params[i<<2], riva128);
|
||||
method+=4;
|
||||
|
Reference in New Issue
Block a user