trunk/src/mame/video/chihiro.c
| r249014 | r249015 | |
| 3 | 3 | #include "emu.h" |
| 4 | 4 | #include "video/poly.h" |
| 5 | 5 | #include "bitmap.h" |
| 6 | #include "machine/pic8259.h" |
| 6 | 7 | #include "includes/chihiro.h" |
| 7 | 8 | |
| 8 | 9 | //#define LOG_NV2A |
| r249014 | r249015 | |
| 945 | 946 | UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle) |
| 946 | 947 | { |
| 947 | 948 | UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff; |
| 948 | | UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ? |
| 949 | UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain |
| 949 | 950 | UINT32 e = o + h * 8; // at 0xfd000000+0x00700000 |
| 950 | 951 | UINT32 w; |
| 951 | 952 | |
| 952 | | if (ramin[e / 4] != handle) |
| 953 | | e = 0; |
| 953 | if (ramin[e / 4] != handle) { |
| 954 | // this should never happen |
| 955 | for (UINT32 aa = o / 4; aa < (sizeof(ramin) / 4); aa = aa + 2) { |
| 956 | if (ramin[aa] == handle) { |
| 957 | e = aa * 4; |
| 958 | } |
| 959 | } |
| 960 | } |
| 954 | 961 | w = ramin[e / 4 + 1]; |
| 955 | | return (w & 0xffff) * 0x10; |
| 962 | return (w & 0xffff) * 0x10; // 0xffff is not certain |
| 956 | 963 | } |
| 957 | 964 | |
| 958 | 965 | void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size) |
| r249014 | r249015 | |
| 1246 | 1253 | addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]); |
| 1247 | 1254 | else // type_rendertarget == LINEAR*/ |
| 1248 | 1255 | addr = rendertarget + (pitch_rendertarget / 4)*y + x; |
| 1249 | | fbcolor = *addr; |
| 1256 | fbcolor = 0; |
| 1257 | if (color_mask != 0) |
| 1258 | fbcolor = *addr; |
| 1250 | 1259 | daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x; |
| 1251 | 1260 | deptsten = *daddr; |
| 1252 | 1261 | c[3] = color >> 24; |
| r249014 | r249015 | |
| 1772 | 1781 | break; |
| 1773 | 1782 | } |
| 1774 | 1783 | } |
| 1775 | | fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; |
| 1776 | | *addr = fbcolor; |
| 1784 | if (color_mask != 0) { |
| 1785 | UINT32 fbcolor_tmp; |
| 1786 | |
| 1787 | fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; |
| 1788 | *addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask); |
| 1789 | } |
| 1777 | 1790 | if (depth_write_enabled) |
| 1778 | 1791 | dep = depth; |
| 1779 | 1792 | deptsten = (dep << 8) | sten; |
| r249014 | r249015 | |
| 2233 | 2246 | maddress = method * 4; |
| 2234 | 2247 | data = space.read_dword(address); |
| 2235 | 2248 | channel[chanel][subchannel].object.method[method] = data; |
| 2249 | #ifdef LOG_NV2A |
| 2250 | printf("A:%08X MTHD:%08X D:%08X\n\r",address,maddress,data); |
| 2251 | #endif |
| 2236 | 2252 | if (maddress == 0x17fc) { |
| 2237 | 2253 | indexesleft_count = 0; |
| 2238 | 2254 | indexesleft_first = 0; |
| r249014 | r249015 | |
| 2270 | 2286 | } |
| 2271 | 2287 | wait(); |
| 2272 | 2288 | } |
| 2289 | else if (type == nv2a_renderer::TRIANGLE_FAN) { |
| 2290 | vertex_nv vert[3]; |
| 2291 | vertex_t xy[3]; |
| 2292 | |
| 2293 | read_vertices_0x1810(space, vert, offset, 2); |
| 2294 | convert_vertices_poly(vert, xy, 2); |
| 2295 | count = count - 2; |
| 2296 | offset = offset + 2; |
| 2297 | for (n = 0; n <= count; n++) { |
| 2298 | read_vertices_0x1810(space, vert + (((n + 1) & 1) + 1), offset + n, 1); |
| 2299 | convert_vertices_poly(vert + (((n + 1) & 1) + 1), xy + (((n + 1) & 1) + 1), 1); |
| 2300 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~(n + 1) & 1) + 1], xy[((n + 1) & 1) + 1]); |
| 2301 | } |
| 2302 | wait(); |
| 2303 | } |
| 2273 | 2304 | else if (type == nv2a_renderer::TRIANGLE_STRIP) { |
| 2274 | 2305 | vertex_nv vert[4]; |
| 2275 | 2306 | vertex_t xy[4]; |
| r249014 | r249015 | |
| 2311 | 2342 | // each dword after 1800 contains two 16 bit index values to select the vartices |
| 2312 | 2343 | // each dword after 1808 contains a 32 bit index value to select the vartices |
| 2313 | 2344 | type = channel[chanel][subchannel].object.method[0x17fc / 4]; |
| 2314 | | #ifdef LOG_NV2A |
| 2315 | | printf("vertex %d %d %d\n\r", type, offset, count); |
| 2316 | | #endif |
| 2317 | 2345 | if (type == nv2a_renderer::QUADS) { |
| 2318 | 2346 | while (1) { |
| 2319 | 2347 | vertex_nv vert[4]; |
| r249014 | r249015 | |
| 2332 | 2360 | render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2333 | 2361 | } |
| 2334 | 2362 | } |
| 2363 | else if (type == nv2a_renderer::TRIANGLE_FAN) { |
| 2364 | if ((countlen * mult + indexesleft_count) >= 3) { |
| 2365 | vertex_nv vert[3]; |
| 2366 | vertex_t xy[3]; |
| 2367 | int c, count; |
| 2368 | |
| 2369 | if (mult == 1) |
| 2370 | c = read_vertices_0x1808(space, vert, address, 2); |
| 2371 | else |
| 2372 | c = read_vertices_0x1800(space, vert, address, 2); |
| 2373 | convert_vertices_poly(vert, xy, 2); |
| 2374 | address = address + c * 4; |
| 2375 | countlen = countlen - c; |
| 2376 | count = countlen * mult + indexesleft_count; |
| 2377 | for (n = 1; n <= count; n++) { |
| 2378 | if (mult == 1) |
| 2379 | c = read_vertices_0x1808(space, vert + ((n & 1) + 1), address, 1); |
| 2380 | else |
| 2381 | c = read_vertices_0x1800(space, vert + ((n & 1) + 1), address, 1); |
| 2382 | |
| 2383 | convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1); |
| 2384 | address = address + c * 4; |
| 2385 | countlen = countlen - c; |
| 2386 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]); |
| 2387 | } |
| 2388 | wait(); |
| 2389 | } |
| 2390 | } |
| 2335 | 2391 | else if (type == nv2a_renderer::TRIANGLES) { |
| 2336 | 2392 | while (1) { |
| 2337 | 2393 | vertex_nv vert[3]; |
| r249014 | r249015 | |
| 2446 | 2502 | } |
| 2447 | 2503 | wait(); |
| 2448 | 2504 | } |
| 2505 | else if (type == nv2a_renderer::TRIANGLES) { |
| 2506 | while (countlen > 0) { |
| 2507 | vertex_nv vert[3]; |
| 2508 | vertex_t xy[3]; |
| 2509 | int c; |
| 2510 | |
| 2511 | c = read_vertices_0x1818(space, vert, address, 3); |
| 2512 | convert_vertices_poly(vert, xy, 3); |
| 2513 | countlen = countlen - c; |
| 2514 | if (countlen < 0) { |
| 2515 | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
| 2516 | countlen = 0; |
| 2517 | break; |
| 2518 | } |
| 2519 | address = address + c * 3; |
| 2520 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv |
| 2521 | } |
| 2522 | } |
| 2449 | 2523 | else if (type == nv2a_renderer::TRIANGLE_STRIP) { |
| 2450 | 2524 | vertex_nv vert[4]; |
| 2451 | 2525 | vertex_t xy[4]; |
| r249014 | r249015 | |
| 2613 | 2687 | // clear colors |
| 2614 | 2688 | UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4]; |
| 2615 | 2689 | bm.fill(color); |
| 2616 | | //printf("clearscreen\n\r"); |
| 2690 | #ifdef LOG_NV2A |
| 2691 | printf("clearscreen\n\r"); |
| 2692 | #endif |
| 2617 | 2693 | } |
| 2618 | 2694 | if ((data & 0x03) == 3) { |
| 2619 | 2695 | bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
| r249014 | r249015 | |
| 2649 | 2725 | dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget]; |
| 2650 | 2726 | } |
| 2651 | 2727 | if (maddress == 0x020c) { |
| 2652 | | // line size ? |
| 2653 | 2728 | pitch_rendertarget=data & 0xffff; |
| 2654 | 2729 | pitch_depthbuffer=(data >> 16) & 0xffff; |
| 2655 | | //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer); |
| 2730 | #ifdef LOG_NV2A |
| 2731 | printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer); |
| 2732 | #endif |
| 2656 | 2733 | countlen--; |
| 2657 | 2734 | } |
| 2658 | 2735 | if (maddress == 0x0100) { |
| 2659 | | // just temporarily |
| 2660 | | if ((data & 0x1f) == 1) { |
| 2661 | | data = data >> 5; |
| 2662 | | data = data & 0x0ffffff0; |
| 2663 | | displayedtarget = (UINT32 *)direct_access_ptr(data); |
| 2736 | countlen--; |
| 2737 | if (data != 0) { |
| 2738 | pgraph[0x704 / 4] = 0x100; |
| 2739 | pgraph[0x708 / 4] = data; |
| 2740 | pgraph[0x100 / 4] |= 1; |
| 2741 | pgraph[0x108 / 4] |= 1; |
| 2742 | if (update_interrupts() == true) |
| 2743 | interruptdevice->ir3_w(1); // IRQ 3 |
| 2744 | else |
| 2745 | interruptdevice->ir3_w(0); // IRQ 3 |
| 2746 | return 2; |
| 2664 | 2747 | } |
| 2748 | else |
| 2749 | return 0; |
| 2665 | 2750 | } |
| 2666 | 2751 | if (maddress == 0x0130) { |
| 2667 | 2752 | countlen--; |
| r249014 | r249015 | |
| 2670 | 2755 | else |
| 2671 | 2756 | return 0; |
| 2672 | 2757 | } |
| 2758 | if (maddress == 0x1d8c) { |
| 2759 | countlen--; |
| 2760 | // it is used to specify the clear value for the depth buffer (zbuffer) |
| 2761 | // but also as a parameter for interrupt routines |
| 2762 | pgraph[0x1a88 / 4] = data; |
| 2763 | } |
| 2764 | if (maddress == 0x1d90) { |
| 2765 | countlen--; |
| 2766 | // it is used to specify the clear value for the color buffer |
| 2767 | // but also as a parameter for interrupt routines |
| 2768 | pgraph[0x186c / 4] = data; |
| 2769 | } |
| 2673 | 2770 | if (maddress == 0x0210) { |
| 2674 | 2771 | // framebuffer offset ? |
| 2675 | 2772 | rendertarget = (UINT32 *)direct_access_ptr(data); |
| 2676 | | //printf("Render target at %08X\n\r",data); |
| 2773 | #ifdef LOG_NV2A |
| 2774 | printf("Render target at %08X\n\r", data); |
| 2775 | #endif |
| 2677 | 2776 | countlen--; |
| 2678 | 2777 | } |
| 2679 | 2778 | if (maddress == 0x0214) { |
| 2680 | 2779 | // zbuffer offset ? |
| 2681 | 2780 | depthbuffer = (UINT32 *)direct_access_ptr(data); |
| 2682 | | //printf("Depth buffer at %08X\n\r",data); |
| 2781 | #ifdef LOG_NV2A |
| 2782 | printf("Depth buffer at %08X\n\r",data); |
| 2783 | #endif |
| 2683 | 2784 | if ((data == 0) || (data > 0x7ffffffc)) |
| 2684 | 2785 | depth_write_enabled = false; |
| 2685 | 2786 | else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0) |
| r249014 | r249015 | |
| 2709 | 2810 | if (maddress == 0x0354) { |
| 2710 | 2811 | depth_function = data; |
| 2711 | 2812 | } |
| 2813 | if (maddress == 0x0358) { |
| 2814 | //color_mask = data; |
| 2815 | if (data & 0x000000ff) |
| 2816 | data |= 0x000000ff; |
| 2817 | if (data & 0x0000ff00) |
| 2818 | data |= 0x0000ff00; |
| 2819 | if (data & 0x00ff0000) |
| 2820 | data |= 0x00ff0000; |
| 2821 | if (data & 0xff000000) |
| 2822 | data |= 0xff000000; |
| 2823 | color_mask = data; |
| 2824 | } |
| 2712 | 2825 | if (maddress == 0x035c) { |
| 2713 | 2826 | UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4]; |
| 2714 | 2827 | depth_write_enabled = data != 0; |
| r249014 | r249015 | |
| 3648 | 3761 | combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f); |
| 3649 | 3762 | } |
| 3650 | 3763 | |
| 3651 | | bool nv2a_renderer::vblank_callback(screen_device &screen, bool state) |
| 3764 | void nv2a_renderer::vblank_callback(screen_device &screen, bool state) |
| 3652 | 3765 | { |
| 3653 | | //printf("vblank_callback\n\r"); |
| 3654 | | if (state == true) |
| 3766 | #ifdef LOG_NV2A |
| 3767 | printf("vblank_callback\n\r"); |
| 3768 | #endif |
| 3769 | if ((state == true) && (puller_waiting == 1)) { |
| 3770 | puller_waiting = 0; |
| 3771 | puller_timer_work(NULL, 0); |
| 3772 | } |
| 3773 | if (state == true) { |
| 3655 | 3774 | pcrtc[0x100 / 4] |= 1; |
| 3775 | pcrtc[0x808 / 4] |= 0x10000; |
| 3776 | } |
| 3777 | else { |
| 3778 | pcrtc[0x100 / 4] &= ~1; |
| 3779 | pcrtc[0x808 / 4] &= ~0x10000; |
| 3780 | } |
| 3781 | if (update_interrupts() == true) |
| 3782 | interruptdevice->ir3_w(1); // IRQ 3 |
| 3656 | 3783 | else |
| 3657 | | pcrtc[0x100 / 4] &= ~1; |
| 3784 | interruptdevice->ir3_w(0); // IRQ 3 |
| 3785 | } |
| 3786 | |
| 3787 | bool nv2a_renderer::update_interrupts() |
| 3788 | { |
| 3658 | 3789 | if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4]) |
| 3659 | 3790 | pmc[0x100 / 4] |= 0x1000000; |
| 3660 | 3791 | else |
| 3661 | 3792 | pmc[0x100 / 4] &= ~0x1000000; |
| 3662 | | if ((state == true) && (puller_waiting == 1)) { |
| 3663 | | puller_waiting = 0; |
| 3664 | | puller_timer_work(NULL, 0); |
| 3665 | | } |
| 3666 | | if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) { |
| 3793 | if (pgraph[0x100 / 4] & pgraph[0x140 / 4]) |
| 3794 | pmc[0x100 / 4] |= 0x1000; |
| 3795 | else |
| 3796 | pmc[0x100 / 4] &= ~0x1000; |
| 3797 | if (((pmc[0x100 / 4] & 0x7fffffff) && (pmc[0x140 / 4] & 1)) || ((pmc[0x100 / 4] & 0x80000000) && (pmc[0x140 / 4] & 2))) { |
| 3667 | 3798 | // send interrupt |
| 3668 | 3799 | return true; |
| 3669 | 3800 | } |
| r249014 | r249015 | |
| 3692 | 3823 | int countlen; |
| 3693 | 3824 | int ret; |
| 3694 | 3825 | address_space *space = puller_space; |
| 3826 | #ifdef LOG_NV2A |
| 3827 | UINT32 subch; |
| 3828 | #endif |
| 3695 | 3829 | |
| 3696 | 3830 | chanel = puller_channel; |
| 3697 | 3831 | subchannel = puller_subchannel; |
| r249014 | r249015 | |
| 3748 | 3882 | } |
| 3749 | 3883 | if (ret != 0) { |
| 3750 | 3884 | puller_timer->enable(false); |
| 3751 | | puller_waiting = 1; |
| 3885 | puller_waiting = ret; |
| 3752 | 3886 | return; |
| 3753 | 3887 | } |
| 3754 | 3888 | } |
| r249014 | r249015 | |
| 3847 | 3981 | //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret); |
| 3848 | 3982 | } |
| 3849 | 3983 | else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) { |
| 3984 | ret = pgraph[offset - 0x00400000 / 4]; |
| 3850 | 3985 | //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret); |
| 3851 | 3986 | } |
| 3852 | 3987 | else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) { |
| r249014 | r249015 | |
| 3870 | 4005 | //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret); |
| 3871 | 4006 | return ret; |
| 3872 | 4007 | } |
| 3873 | | else |
| 3874 | | { |
| 3875 | | /* nothing */ |
| 3876 | | } |
| 3877 | 4008 | //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret); |
| 3878 | 4009 | return ret; |
| 3879 | 4010 | } |
| 3880 | 4011 | |
| 3881 | 4012 | WRITE32_MEMBER(nv2a_renderer::geforce_w) |
| 3882 | 4013 | { |
| 4014 | UINT32 old; |
| 4015 | bool update_int; |
| 4016 | |
| 4017 | update_int = false; |
| 3883 | 4018 | if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) { |
| 3884 | 4019 | //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data); |
| 3885 | 4020 | } |
| r249014 | r249015 | |
| 3898 | 4033 | //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask); |
| 3899 | 4034 | } |
| 3900 | 4035 | else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) { |
| 4036 | int e = offset - 0x00400000 / 4; |
| 4037 | if (e >= (sizeof(pgraph) / sizeof(UINT32))) |
| 4038 | return; |
| 4039 | old = pgraph[e]; |
| 4040 | COMBINE_DATA(pgraph + e); |
| 4041 | if (e == 0x100 / 4) { |
| 4042 | pgraph[e] = old & ~data; |
| 4043 | if (data & 1) |
| 4044 | pgraph[0x108 / 4] = 0; |
| 4045 | update_int = true; |
| 4046 | } |
| 4047 | if (e == 0x140 / 4) |
| 4048 | update_int = true; |
| 4049 | if (e == 0x720 / 4) { |
| 4050 | if ((data & 1) && (puller_waiting == 2)) { |
| 4051 | puller_waiting = 0; |
| 4052 | puller_timer->enable(); |
| 4053 | puller_timer->adjust(attotime::zero); |
| 4054 | } |
| 4055 | } |
| 4056 | if ((e >= 0x900 / 4) && (e < 0xa00 / 4)) |
| 4057 | pgraph[e] = 0; |
| 3901 | 4058 | //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask); |
| 3902 | 4059 | } |
| 3903 | 4060 | else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) { |
| 3904 | 4061 | int e = offset - 0x00600000 / 4; |
| 3905 | 4062 | if (e >= (sizeof(pcrtc) / sizeof(UINT32))) |
| 3906 | 4063 | return; |
| 4064 | old = pcrtc[e]; |
| 3907 | 4065 | COMBINE_DATA(pcrtc + e); |
| 4066 | if (e == 0x100 / 4) { |
| 4067 | pcrtc[e] = old & ~data; |
| 4068 | update_int = true; |
| 4069 | } |
| 4070 | if (e == 0x140 / 4) |
| 4071 | update_int = true; |
| 3908 | 4072 | if (e == 0x800 / 4) { |
| 3909 | | displayedtarget = (UINT32 *)direct_access_ptr(data); |
| 3910 | | //printf("crtc buffer %08X\n\r", data); |
| 4073 | displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]); |
| 4074 | #ifdef LOG_NV2A |
| 4075 | printf("crtc buffer %08X\n\r", data); |
| 4076 | #endif |
| 3911 | 4077 | } |
| 3912 | 4078 | //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask); |
| 3913 | 4079 | } |
| r249014 | r249015 | |
| 3922 | 4088 | // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each |
| 3923 | 4089 | int chanel, subchannel, suboffset; |
| 3924 | 4090 | //int method, count, handle, objclass; |
| 3925 | | #ifdef LOG_NV2A |
| 3926 | | int subch; |
| 3927 | | #endif |
| 3928 | 4091 | |
| 3929 | 4092 | suboffset = offset - 0x00800000 / 4; |
| 3930 | 4093 | chanel = (suboffset >> (16 - 2)) & 31; |
| r249014 | r249015 | |
| 3959 | 4122 | } |
| 3960 | 4123 | //else |
| 3961 | 4124 | // logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data); |
| 4125 | if (update_int == true) { |
| 4126 | if (update_interrupts() == true) |
| 4127 | interruptdevice->ir3_w(1); // IRQ 3 |
| 4128 | else |
| 4129 | interruptdevice->ir3_w(0); // IRQ 3 |
| 4130 | } |
| 3962 | 4131 | } |
| 3963 | 4132 | |
| 3964 | 4133 | void nv2a_renderer::savestate_items() |
| r249014 | r249015 | |
| 3971 | 4140 | puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer"); |
| 3972 | 4141 | puller_timer->enable(false); |
| 3973 | 4142 | } |
| 4143 | |
| 4144 | void nv2a_renderer::set_interrupt_device(pic8259_device *device) |
| 4145 | { |
| 4146 | interruptdevice = device; |
| 4147 | } |