chihiro.c: under the hood 3d accelerator changes [Samuele Zannoli]
-correct some errors -add more primitives to some graphic methods -add color mask support -method 0x100 (NOP) generates correct interrupt -some method parameters are readable from mmio registers
This commit is contained in:
parent
017ebde24e
commit
ece079aa74
@ -185,6 +185,7 @@ public:
|
||||
memset(pfifo, 0, sizeof(pfifo));
|
||||
memset(pcrtc, 0, sizeof(pcrtc));
|
||||
memset(pmc, 0, sizeof(pmc));
|
||||
memset(pgraph, 0, sizeof(pgraph));
|
||||
memset(ramin, 0, sizeof(ramin));
|
||||
computedilated();
|
||||
objectdata = &(object_data_alloc());
|
||||
@ -194,6 +195,7 @@ public:
|
||||
enabled_vertex_attributes = 0;
|
||||
indexesleft_count = 0;
|
||||
vertex_pipeline = 4;
|
||||
color_mask = 0xffffffff;
|
||||
alpha_test_enabled = false;
|
||||
alpha_reference = 0;
|
||||
alpha_func = nv2a_renderer::ALWAYS;
|
||||
@ -238,8 +240,10 @@ public:
|
||||
}
|
||||
DECLARE_READ32_MEMBER(geforce_r);
|
||||
DECLARE_WRITE32_MEMBER(geforce_w);
|
||||
bool vblank_callback(screen_device &screen, bool state);
|
||||
void vblank_callback(screen_device &screen, bool state);
|
||||
UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
bool update_interrupts();
|
||||
void set_interrupt_device(pic8259_device *device);
|
||||
|
||||
void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
|
||||
void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
|
||||
@ -303,10 +307,12 @@ public:
|
||||
UINT32 pfifo[0x2000 / 4];
|
||||
UINT32 pcrtc[0x1000 / 4];
|
||||
UINT32 pmc[0x1000 / 4];
|
||||
UINT32 pgraph[0x2000 / 4];
|
||||
UINT32 ramin[0x100000 / 4];
|
||||
UINT32 dma_offset[2];
|
||||
UINT32 dma_size[2];
|
||||
UINT8 *basemempointer;
|
||||
pic8259_device *interruptdevice;
|
||||
rectangle limits_rendertarget;
|
||||
UINT32 pitch_rendertarget;
|
||||
UINT32 pitch_depthbuffer;
|
||||
@ -441,6 +447,7 @@ public:
|
||||
int used;
|
||||
osd_lock *lock;
|
||||
} combiner;
|
||||
UINT32 color_mask;
|
||||
bool alpha_test_enabled;
|
||||
int alpha_func;
|
||||
int alpha_reference;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "emu.h"
|
||||
#include "video/poly.h"
|
||||
#include "bitmap.h"
|
||||
#include "machine/pic8259.h"
|
||||
#include "includes/chihiro.h"
|
||||
|
||||
//#define LOG_NV2A
|
||||
@ -945,14 +946,20 @@ int nv2a_renderer::geforce_commandkind(UINT32 word)
|
||||
UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
|
||||
{
|
||||
UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
|
||||
UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ?
|
||||
UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain
|
||||
UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
|
||||
UINT32 w;
|
||||
|
||||
if (ramin[e / 4] != handle)
|
||||
e = 0;
|
||||
if (ramin[e / 4] != handle) {
|
||||
// this should never happen
|
||||
for (UINT32 aa = o / 4; aa < (sizeof(ramin) / 4); aa = aa + 2) {
|
||||
if (ramin[aa] == handle) {
|
||||
e = aa * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
w = ramin[e / 4 + 1];
|
||||
return (w & 0xffff) * 0x10;
|
||||
return (w & 0xffff) * 0x10; // 0xffff is not certain
|
||||
}
|
||||
|
||||
void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
|
||||
@ -1246,7 +1253,9 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
|
||||
addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
|
||||
else // type_rendertarget == LINEAR*/
|
||||
addr = rendertarget + (pitch_rendertarget / 4)*y + x;
|
||||
fbcolor = *addr;
|
||||
fbcolor = 0;
|
||||
if (color_mask != 0)
|
||||
fbcolor = *addr;
|
||||
daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
|
||||
deptsten = *daddr;
|
||||
c[3] = color >> 24;
|
||||
@ -1772,8 +1781,12 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
|
||||
break;
|
||||
}
|
||||
}
|
||||
fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
|
||||
*addr = fbcolor;
|
||||
if (color_mask != 0) {
|
||||
UINT32 fbcolor_tmp;
|
||||
|
||||
fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
|
||||
*addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask);
|
||||
}
|
||||
if (depth_write_enabled)
|
||||
dep = depth;
|
||||
deptsten = (dep << 8) | sten;
|
||||
@ -2233,6 +2246,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
maddress = method * 4;
|
||||
data = space.read_dword(address);
|
||||
channel[chanel][subchannel].object.method[method] = data;
|
||||
#ifdef LOG_NV2A
|
||||
printf("A:%08X MTHD:%08X D:%08X\n\r",address,maddress,data);
|
||||
#endif
|
||||
if (maddress == 0x17fc) {
|
||||
indexesleft_count = 0;
|
||||
indexesleft_first = 0;
|
||||
@ -2270,6 +2286,21 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
}
|
||||
wait();
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLE_FAN) {
|
||||
vertex_nv vert[3];
|
||||
vertex_t xy[3];
|
||||
|
||||
read_vertices_0x1810(space, vert, offset, 2);
|
||||
convert_vertices_poly(vert, xy, 2);
|
||||
count = count - 2;
|
||||
offset = offset + 2;
|
||||
for (n = 0; n <= count; n++) {
|
||||
read_vertices_0x1810(space, vert + (((n + 1) & 1) + 1), offset + n, 1);
|
||||
convert_vertices_poly(vert + (((n + 1) & 1) + 1), xy + (((n + 1) & 1) + 1), 1);
|
||||
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~(n + 1) & 1) + 1], xy[((n + 1) & 1) + 1]);
|
||||
}
|
||||
wait();
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLE_STRIP) {
|
||||
vertex_nv vert[4];
|
||||
vertex_t xy[4];
|
||||
@ -2311,9 +2342,6 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
// each dword after 1800 contains two 16 bit index values to select the vartices
|
||||
// each dword after 1808 contains a 32 bit index value to select the vartices
|
||||
type = channel[chanel][subchannel].object.method[0x17fc / 4];
|
||||
#ifdef LOG_NV2A
|
||||
printf("vertex %d %d %d\n\r", type, offset, count);
|
||||
#endif
|
||||
if (type == nv2a_renderer::QUADS) {
|
||||
while (1) {
|
||||
vertex_nv vert[4];
|
||||
@ -2332,6 +2360,34 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
|
||||
}
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLE_FAN) {
|
||||
if ((countlen * mult + indexesleft_count) >= 3) {
|
||||
vertex_nv vert[3];
|
||||
vertex_t xy[3];
|
||||
int c, count;
|
||||
|
||||
if (mult == 1)
|
||||
c = read_vertices_0x1808(space, vert, address, 2);
|
||||
else
|
||||
c = read_vertices_0x1800(space, vert, address, 2);
|
||||
convert_vertices_poly(vert, xy, 2);
|
||||
address = address + c * 4;
|
||||
countlen = countlen - c;
|
||||
count = countlen * mult + indexesleft_count;
|
||||
for (n = 1; n <= count; n++) {
|
||||
if (mult == 1)
|
||||
c = read_vertices_0x1808(space, vert + ((n & 1) + 1), address, 1);
|
||||
else
|
||||
c = read_vertices_0x1800(space, vert + ((n & 1) + 1), address, 1);
|
||||
|
||||
convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
|
||||
address = address + c * 4;
|
||||
countlen = countlen - c;
|
||||
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
|
||||
}
|
||||
wait();
|
||||
}
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLES) {
|
||||
while (1) {
|
||||
vertex_nv vert[3];
|
||||
@ -2446,6 +2502,24 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
}
|
||||
wait();
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLES) {
|
||||
while (countlen > 0) {
|
||||
vertex_nv vert[3];
|
||||
vertex_t xy[3];
|
||||
int c;
|
||||
|
||||
c = read_vertices_0x1818(space, vert, address, 3);
|
||||
convert_vertices_poly(vert, xy, 3);
|
||||
countlen = countlen - c;
|
||||
if (countlen < 0) {
|
||||
logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
|
||||
countlen = 0;
|
||||
break;
|
||||
}
|
||||
address = address + c * 3;
|
||||
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
|
||||
}
|
||||
}
|
||||
else if (type == nv2a_renderer::TRIANGLE_STRIP) {
|
||||
vertex_nv vert[4];
|
||||
vertex_t xy[4];
|
||||
@ -2613,7 +2687,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
// clear colors
|
||||
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
|
||||
bm.fill(color);
|
||||
//printf("clearscreen\n\r");
|
||||
#ifdef LOG_NV2A
|
||||
printf("clearscreen\n\r");
|
||||
#endif
|
||||
}
|
||||
if ((data & 0x03) == 3) {
|
||||
bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
|
||||
@ -2649,19 +2725,28 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
|
||||
}
|
||||
if (maddress == 0x020c) {
|
||||
// line size ?
|
||||
pitch_rendertarget=data & 0xffff;
|
||||
pitch_depthbuffer=(data >> 16) & 0xffff;
|
||||
//printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
|
||||
#ifdef LOG_NV2A
|
||||
printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
|
||||
#endif
|
||||
countlen--;
|
||||
}
|
||||
if (maddress == 0x0100) {
|
||||
// just temporarily
|
||||
if ((data & 0x1f) == 1) {
|
||||
data = data >> 5;
|
||||
data = data & 0x0ffffff0;
|
||||
displayedtarget = (UINT32 *)direct_access_ptr(data);
|
||||
countlen--;
|
||||
if (data != 0) {
|
||||
pgraph[0x704 / 4] = 0x100;
|
||||
pgraph[0x708 / 4] = data;
|
||||
pgraph[0x100 / 4] |= 1;
|
||||
pgraph[0x108 / 4] |= 1;
|
||||
if (update_interrupts() == true)
|
||||
interruptdevice->ir3_w(1); // IRQ 3
|
||||
else
|
||||
interruptdevice->ir3_w(0); // IRQ 3
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (maddress == 0x0130) {
|
||||
countlen--;
|
||||
@ -2670,16 +2755,32 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (maddress == 0x1d8c) {
|
||||
countlen--;
|
||||
// it is used to specify the clear value for the depth buffer (zbuffer)
|
||||
// but also as a parameter for interrupt routines
|
||||
pgraph[0x1a88 / 4] = data;
|
||||
}
|
||||
if (maddress == 0x1d90) {
|
||||
countlen--;
|
||||
// it is used to specify the clear value for the color buffer
|
||||
// but also as a parameter for interrupt routines
|
||||
pgraph[0x186c / 4] = data;
|
||||
}
|
||||
if (maddress == 0x0210) {
|
||||
// framebuffer offset ?
|
||||
rendertarget = (UINT32 *)direct_access_ptr(data);
|
||||
//printf("Render target at %08X\n\r",data);
|
||||
#ifdef LOG_NV2A
|
||||
printf("Render target at %08X\n\r", data);
|
||||
#endif
|
||||
countlen--;
|
||||
}
|
||||
if (maddress == 0x0214) {
|
||||
// zbuffer offset ?
|
||||
depthbuffer = (UINT32 *)direct_access_ptr(data);
|
||||
//printf("Depth buffer at %08X\n\r",data);
|
||||
#ifdef LOG_NV2A
|
||||
printf("Depth buffer at %08X\n\r",data);
|
||||
#endif
|
||||
if ((data == 0) || (data > 0x7ffffffc))
|
||||
depth_write_enabled = false;
|
||||
else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
|
||||
@ -2709,6 +2810,18 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
|
||||
if (maddress == 0x0354) {
|
||||
depth_function = data;
|
||||
}
|
||||
if (maddress == 0x0358) {
|
||||
//color_mask = data;
|
||||
if (data & 0x000000ff)
|
||||
data |= 0x000000ff;
|
||||
if (data & 0x0000ff00)
|
||||
data |= 0x0000ff00;
|
||||
if (data & 0x00ff0000)
|
||||
data |= 0x00ff0000;
|
||||
if (data & 0xff000000)
|
||||
data |= 0xff000000;
|
||||
color_mask = data;
|
||||
}
|
||||
if (maddress == 0x035c) {
|
||||
UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
|
||||
depth_write_enabled = data != 0;
|
||||
@ -3648,22 +3761,40 @@ void nv2a_renderer::combiner_compute_a_outputs(int stage_number)
|
||||
combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f);
|
||||
}
|
||||
|
||||
bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
|
||||
void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
|
||||
{
|
||||
//printf("vblank_callback\n\r");
|
||||
if (state == true)
|
||||
pcrtc[0x100 / 4] |= 1;
|
||||
else
|
||||
pcrtc[0x100 / 4] &= ~1;
|
||||
if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
|
||||
pmc[0x100 / 4] |= 0x1000000;
|
||||
else
|
||||
pmc[0x100 / 4] &= ~0x1000000;
|
||||
#ifdef LOG_NV2A
|
||||
printf("vblank_callback\n\r");
|
||||
#endif
|
||||
if ((state == true) && (puller_waiting == 1)) {
|
||||
puller_waiting = 0;
|
||||
puller_timer_work(NULL, 0);
|
||||
}
|
||||
if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) {
|
||||
if (state == true) {
|
||||
pcrtc[0x100 / 4] |= 1;
|
||||
pcrtc[0x808 / 4] |= 0x10000;
|
||||
}
|
||||
else {
|
||||
pcrtc[0x100 / 4] &= ~1;
|
||||
pcrtc[0x808 / 4] &= ~0x10000;
|
||||
}
|
||||
if (update_interrupts() == true)
|
||||
interruptdevice->ir3_w(1); // IRQ 3
|
||||
else
|
||||
interruptdevice->ir3_w(0); // IRQ 3
|
||||
}
|
||||
|
||||
bool nv2a_renderer::update_interrupts()
|
||||
{
|
||||
if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
|
||||
pmc[0x100 / 4] |= 0x1000000;
|
||||
else
|
||||
pmc[0x100 / 4] &= ~0x1000000;
|
||||
if (pgraph[0x100 / 4] & pgraph[0x140 / 4])
|
||||
pmc[0x100 / 4] |= 0x1000;
|
||||
else
|
||||
pmc[0x100 / 4] &= ~0x1000;
|
||||
if (((pmc[0x100 / 4] & 0x7fffffff) && (pmc[0x140 / 4] & 1)) || ((pmc[0x100 / 4] & 0x80000000) && (pmc[0x140 / 4] & 2))) {
|
||||
// send interrupt
|
||||
return true;
|
||||
}
|
||||
@ -3692,6 +3823,9 @@ TIMER_CALLBACK_MEMBER(nv2a_renderer::puller_timer_work)
|
||||
int countlen;
|
||||
int ret;
|
||||
address_space *space = puller_space;
|
||||
#ifdef LOG_NV2A
|
||||
UINT32 subch;
|
||||
#endif
|
||||
|
||||
chanel = puller_channel;
|
||||
subchannel = puller_subchannel;
|
||||
@ -3748,7 +3882,7 @@ TIMER_CALLBACK_MEMBER(nv2a_renderer::puller_timer_work)
|
||||
}
|
||||
if (ret != 0) {
|
||||
puller_timer->enable(false);
|
||||
puller_waiting = 1;
|
||||
puller_waiting = ret;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3847,6 +3981,7 @@ READ32_MEMBER(nv2a_renderer::geforce_r)
|
||||
//logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
|
||||
}
|
||||
else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
|
||||
ret = pgraph[offset - 0x00400000 / 4];
|
||||
//logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
|
||||
}
|
||||
else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
|
||||
@ -3870,16 +4005,16 @@ READ32_MEMBER(nv2a_renderer::geforce_r)
|
||||
//logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
//logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(nv2a_renderer::geforce_w)
|
||||
{
|
||||
UINT32 old;
|
||||
bool update_int;
|
||||
|
||||
update_int = false;
|
||||
if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
|
||||
//logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
|
||||
}
|
||||
@ -3898,16 +4033,47 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
|
||||
//logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
|
||||
}
|
||||
else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
|
||||
int e = offset - 0x00400000 / 4;
|
||||
if (e >= (sizeof(pgraph) / sizeof(UINT32)))
|
||||
return;
|
||||
old = pgraph[e];
|
||||
COMBINE_DATA(pgraph + e);
|
||||
if (e == 0x100 / 4) {
|
||||
pgraph[e] = old & ~data;
|
||||
if (data & 1)
|
||||
pgraph[0x108 / 4] = 0;
|
||||
update_int = true;
|
||||
}
|
||||
if (e == 0x140 / 4)
|
||||
update_int = true;
|
||||
if (e == 0x720 / 4) {
|
||||
if ((data & 1) && (puller_waiting == 2)) {
|
||||
puller_waiting = 0;
|
||||
puller_timer->enable();
|
||||
puller_timer->adjust(attotime::zero);
|
||||
}
|
||||
}
|
||||
if ((e >= 0x900 / 4) && (e < 0xa00 / 4))
|
||||
pgraph[e] = 0;
|
||||
//logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
|
||||
}
|
||||
else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
|
||||
int e = offset - 0x00600000 / 4;
|
||||
if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
|
||||
return;
|
||||
old = pcrtc[e];
|
||||
COMBINE_DATA(pcrtc + e);
|
||||
if (e == 0x100 / 4) {
|
||||
pcrtc[e] = old & ~data;
|
||||
update_int = true;
|
||||
}
|
||||
if (e == 0x140 / 4)
|
||||
update_int = true;
|
||||
if (e == 0x800 / 4) {
|
||||
displayedtarget = (UINT32 *)direct_access_ptr(data);
|
||||
//printf("crtc buffer %08X\n\r", data);
|
||||
displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]);
|
||||
#ifdef LOG_NV2A
|
||||
printf("crtc buffer %08X\n\r", data);
|
||||
#endif
|
||||
}
|
||||
//logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
|
||||
}
|
||||
@ -3922,9 +4088,6 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
|
||||
// 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
|
||||
int chanel, subchannel, suboffset;
|
||||
//int method, count, handle, objclass;
|
||||
#ifdef LOG_NV2A
|
||||
int subch;
|
||||
#endif
|
||||
|
||||
suboffset = offset - 0x00800000 / 4;
|
||||
chanel = (suboffset >> (16 - 2)) & 31;
|
||||
@ -3959,6 +4122,12 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
|
||||
}
|
||||
//else
|
||||
// logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
|
||||
if (update_int == true) {
|
||||
if (update_interrupts() == true)
|
||||
interruptdevice->ir3_w(1); // IRQ 3
|
||||
else
|
||||
interruptdevice->ir3_w(0); // IRQ 3
|
||||
}
|
||||
}
|
||||
|
||||
void nv2a_renderer::savestate_items()
|
||||
@ -3971,3 +4140,8 @@ void nv2a_renderer::start(address_space *cpu_space)
|
||||
puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
|
||||
puller_timer->enable(false);
|
||||
}
|
||||
|
||||
void nv2a_renderer::set_interrupt_device(pic8259_device *device)
|
||||
{
|
||||
interruptdevice = device;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user