trunk/src/mame/includes/chihiro.h
| r242607 | r242608 | |
| 191 | 191 | rendertarget = NULL; |
| 192 | 192 | depthbuffer = NULL; |
| 193 | 193 | displayedtarget = NULL; |
| 194 | puller_channel = 0; |
| 195 | puller_subchannel = 0; |
| 196 | puller_waiting = 0; |
| 194 | 197 | debug_grab_texttype = -1; |
| 195 | 198 | debug_grab_textfile = NULL; |
| 199 | waitvblank_used = 0; |
| 196 | 200 | memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words)); |
| 197 | 201 | memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset)); |
| 198 | 202 | } |
| r242607 | r242608 | |
| 208 | 212 | int geforce_commandkind(UINT32 word); |
| 209 | 213 | UINT32 geforce_object_offset(UINT32 handle); |
| 210 | 214 | void geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size); |
| 211 | | void geforce_exec_method(address_space &space, UINT32 channel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen); |
| 215 | int geforce_exec_method(address_space &space, UINT32 channel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen); |
| 212 | 216 | UINT32 texture_get_texel(int number, int x, int y); |
| 213 | 217 | void write_pixel(int x, int y, UINT32 color, UINT32 depth); |
| 214 | 218 | void combiner_initialize_registers(UINT32 argb8[6]); |
| r242607 | r242608 | |
| 238 | 242 | void computedilated(void); |
| 239 | 243 | void putpixtex(int xp, int yp, int up, int vp); |
| 240 | 244 | int toggle_register_combiners_usage(); |
| 245 | int toggle_wait_vblank_support(); |
| 241 | 246 | void debug_grab_texture(int type, const char *filename); |
| 242 | 247 | void debug_grab_vertex_program_slot(int slot, UINT32 *instruction); |
| 248 | void start(); |
| 243 | 249 | void savestate_items(); |
| 244 | | |
| 245 | 250 | void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib); |
| 246 | 251 | int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit); |
| 247 | 252 | int read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit); |
| 248 | 253 | int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit); |
| 249 | 254 | void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count); |
| 255 | TIMER_CALLBACK_MEMBER(puller_timer_work); |
| 250 | 256 | |
| 251 | 257 | struct { |
| 252 | 258 | UINT32 regs[0x80 / 4]; |
| r242607 | r242608 | |
| 429 | 435 | int enabled_vertex_attributes; |
| 430 | 436 | int vertex_attribute_words[16]; |
| 431 | 437 | int vertex_attribute_offset[16]; |
| 438 | emu_timer *puller_timer; |
| 439 | int puller_channel; |
| 440 | int puller_subchannel; |
| 441 | int puller_waiting; |
| 442 | address_space *puller_space; |
| 432 | 443 | UINT32 dilated0[16][2048]; |
| 433 | 444 | UINT32 dilated1[16][2048]; |
| 434 | 445 | int dilatechose[256]; |
| 435 | 446 | nvidia_object_data *objectdata; |
| 436 | 447 | int debug_grab_texttype; |
| 437 | 448 | char *debug_grab_textfile; |
| 449 | int waitvblank_used; |
| 438 | 450 | |
| 439 | 451 | enum VERTEX_PARAMETER { |
| 440 | 452 | PARAM_COLOR_B = 0, |
| r242607 | r242608 | |
| 479 | 491 | TEX3 = 12 |
| 480 | 492 | }; |
| 481 | 493 | enum NV2A_VTXBUF_TYPE { |
| 482 | | NV2A_VTXBUF_TYPE_UNKNOWN_0 = 0, // used for vertex color ? |
| 494 | NV2A_VTXBUF_TYPE_UBYTE2 = 0, // what is the difference with UBYTE ? |
| 483 | 495 | NV2A_VTXBUF_TYPE_FLOAT = 2, |
| 484 | 496 | NV2A_VTXBUF_TYPE_UBYTE = 4, |
| 485 | 497 | NV2A_VTXBUF_TYPE_USHORT = 5, |
trunk/src/mame/video/chihiro.c
| r242607 | r242608 | |
| 2027 | 2027 | } |
| 2028 | 2028 | break; |
| 2029 | 2029 | case NV2A_VTXBUF_TYPE_UBYTE: |
| 2030 | u = space.read_dword(address + 0); |
| 2031 | for (c = l-1; c >= l; c--) { |
| 2032 | vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0; |
| 2033 | u = u >> 8; |
| 2034 | } |
| 2030 | 2035 | break; |
| 2031 | | case NV2A_VTXBUF_TYPE_UNKNOWN_0: |
| 2036 | case NV2A_VTXBUF_TYPE_UBYTE2: |
| 2032 | 2037 | u = space.read_dword(address + 0); |
| 2033 | 2038 | for (c = 0; c < l; c++) { |
| 2034 | 2039 | vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0; |
| r242607 | r242608 | |
| 2142 | 2147 | destination[m].p[PARAM_TEXTURE0_U + u * 2] = source[m].attribute[9 + u].fv[0]; |
| 2143 | 2148 | destination[m].p[PARAM_TEXTURE0_V + u * 2] = source[m].attribute[9 + u].fv[1]; |
| 2144 | 2149 | } |
| 2145 | | destination[m].p[PARAM_Z] = 0+0xffffff; |
| 2150 | destination[m].p[PARAM_Z] = 0xffffff; |
| 2146 | 2151 | } |
| 2147 | 2152 | } |
| 2148 | 2153 | else { |
| r242607 | r242608 | |
| 2164 | 2169 | } |
| 2165 | 2170 | } |
| 2166 | 2171 | |
| 2167 | | void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen) |
| 2172 | int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen) |
| 2168 | 2173 | { |
| 2169 | 2174 | UINT32 maddress; |
| 2170 | 2175 | UINT32 data; |
| r242607 | r242608 | |
| 2364 | 2369 | if (countlen < 0) { |
| 2365 | 2370 | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
| 2366 | 2371 | countlen = 0; |
| 2367 | | return; |
| 2372 | return 0; |
| 2368 | 2373 | } |
| 2369 | 2374 | address = address + c * 4; |
| 2370 | 2375 | for (n = 1; countlen > 0; n++) { |
| r242607 | r242608 | |
| 2392 | 2397 | if (countlen < 0) { |
| 2393 | 2398 | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
| 2394 | 2399 | countlen = 0; |
| 2395 | | return; |
| 2400 | return 0; |
| 2396 | 2401 | } |
| 2397 | 2402 | address = address + c * 4; |
| 2398 | 2403 | for (n = 0; countlen > 0; n++) { |
| r242607 | r242608 | |
| 2439 | 2444 | if (countlen < 0) { |
| 2440 | 2445 | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
| 2441 | 2446 | countlen = 0; |
| 2442 | | return; |
| 2447 | return 0; |
| 2443 | 2448 | } |
| 2444 | 2449 | address = address + c * 4; |
| 2445 | 2450 | for (n = 0; countlen > 0; n += 2) { |
| r242607 | r242608 | |
| 2449 | 2454 | if (countlen < 0) { |
| 2450 | 2455 | logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen); |
| 2451 | 2456 | countlen = 0; |
| 2452 | | return; |
| 2457 | return 0; |
| 2453 | 2458 | } |
| 2454 | 2459 | address = address + c * 4; |
| 2455 | 2460 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]); |
| r242607 | r242608 | |
| 2477 | 2482 | vertexbuffer_kind[bit] = data & 15; |
| 2478 | 2483 | vertexbuffer_size[bit] = (data >> 4) & 15; |
| 2479 | 2484 | switch (vertexbuffer_kind[bit]) { |
| 2480 | | case NV2A_VTXBUF_TYPE_UNKNOWN_0: |
| 2485 | case NV2A_VTXBUF_TYPE_UBYTE2: |
| 2481 | 2486 | vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2; |
| 2482 | 2487 | break; |
| 2483 | 2488 | case NV2A_VTXBUF_TYPE_FLOAT: |
| r242607 | r242608 | |
| 2541 | 2546 | m = 2; |
| 2542 | 2547 | else |
| 2543 | 2548 | m = 1; |
| 2544 | | // possible buffers: color, depth, stencil, and accumulation |
| 2549 | // possible buffers: color, depth, stencil |
| 2545 | 2550 | // clear framebuffer |
| 2546 | 2551 | if (data & 0xf0) { |
| 2547 | 2552 | bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
| r242607 | r242608 | |
| 2550 | 2555 | bm.fill(color); |
| 2551 | 2556 | //printf("clearscreen\n\r"); |
| 2552 | 2557 | } |
| 2553 | | if (data & 0x01) { |
| 2558 | if ((data & 0x03) == 3) { |
| 2554 | 2559 | bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
| 2555 | | // clear zbuffer |
| 2556 | | UINT32 depth = channel[chanel][subchannel].object.method[0x1d8c / 4]; |
| 2557 | | bm.fill(depth); |
| 2560 | // clear zbuffer and stencil |
| 2561 | UINT32 depth_stencil = channel[chanel][subchannel].object.method[0x1d8c / 4]; |
| 2562 | bm.fill(depth_stencil); |
| 2558 | 2563 | } |
| 2564 | else if (((data & 0x03) == 1) || ((data & 0x03) == 2)) |
| 2565 | logerror("Unsupported clear method parameter %d\n\r", data & 0x03); |
| 2559 | 2566 | countlen--; |
| 2560 | 2567 | } |
| 2561 | 2568 | if (maddress == 0x0200) { |
| r242607 | r242608 | |
| 2583 | 2590 | displayedtarget = (UINT32 *)space.get_write_ptr(data); |
| 2584 | 2591 | } |
| 2585 | 2592 | } |
| 2593 | if (maddress == 0x0130) { |
| 2594 | countlen--; |
| 2595 | if (waitvblank_used == 1) |
| 2596 | return 1; // block until next vblank |
| 2597 | else |
| 2598 | return 0; |
| 2599 | } |
| 2586 | 2600 | if (maddress == 0x0210) { |
| 2587 | 2601 | // framebuffer offset ? |
| 2588 | 2602 | rendertarget = (UINT32 *)space.get_write_ptr(data); |
| r242607 | r242608 | |
| 2956 | 2970 | //combiner.=(data >> 27) & 7; |
| 2957 | 2971 | countlen--; |
| 2958 | 2972 | } |
| 2973 | return 0; |
| 2959 | 2974 | } |
| 2960 | 2975 | |
| 2961 | 2976 | int nv2a_renderer::toggle_register_combiners_usage() |
| r242607 | r242608 | |
| 2964 | 2979 | return combiner.used; |
| 2965 | 2980 | } |
| 2966 | 2981 | |
| 2982 | int nv2a_renderer::toggle_wait_vblank_support() |
| 2983 | { |
| 2984 | waitvblank_used = 1 - waitvblank_used; |
| 2985 | return waitvblank_used; |
| 2986 | } |
| 2987 | |
| 2967 | 2988 | void nv2a_renderer::debug_grab_texture(int type, const char *filename) |
| 2968 | 2989 | { |
| 2969 | 2990 | debug_grab_texttype = type; |
| r242607 | r242608 | |
| 2982 | 3003 | instruction[3] = vertexprogram.exec.op[slot].i[3]; |
| 2983 | 3004 | } |
| 2984 | 3005 | |
| 2985 | | void nv2a_renderer::savestate_items() |
| 2986 | | { |
| 2987 | | } |
| 2988 | | |
| 2989 | 3006 | void nv2a_renderer::combiner_argb8_float(UINT32 color, float reg[4]) |
| 2990 | 3007 | { |
| 2991 | 3008 | reg[0] = (float)(color & 0xff) / 255.0; |
| r242607 | r242608 | |
| 3569 | 3586 | pmc[0x100 / 4] |= 0x1000000; |
| 3570 | 3587 | else |
| 3571 | 3588 | pmc[0x100 / 4] &= ~0x1000000; |
| 3589 | if ((state == true) && (puller_waiting == 1)) { |
| 3590 | puller_waiting = 0; |
| 3591 | puller_timer_work(NULL, 0); |
| 3592 | } |
| 3572 | 3593 | if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) { |
| 3573 | 3594 | // send interrupt |
| 3574 | 3595 | return true; |
| r242607 | r242608 | |
| 3589 | 3610 | return 0; |
| 3590 | 3611 | } |
| 3591 | 3612 | |
| 3613 | TIMER_CALLBACK_MEMBER(nv2a_renderer::puller_timer_work) |
| 3614 | { |
| 3615 | int chanel, subchannel; |
| 3616 | int method, count, handle, objclass; |
| 3617 | UINT32 *dmaput, *dmaget; |
| 3618 | UINT32 cmd, cmdtype; |
| 3619 | int countlen; |
| 3620 | int ret; |
| 3621 | address_space *space = puller_space; |
| 3622 | |
| 3623 | chanel = puller_channel; |
| 3624 | subchannel = puller_subchannel; |
| 3625 | dmaput = &channel[chanel][subchannel].regs[0x40 / 4]; |
| 3626 | dmaget = &channel[chanel][subchannel].regs[0x44 / 4]; |
| 3627 | chanel = puller_channel; |
| 3628 | subchannel = puller_subchannel; |
| 3629 | while (*dmaget != *dmaput) { |
| 3630 | cmd = space->read_dword(*dmaget); |
| 3631 | *dmaget += 4; |
| 3632 | cmdtype = geforce_commandkind(cmd); |
| 3633 | switch (cmdtype) |
| 3634 | { |
| 3635 | case 6: // jump |
| 3636 | #ifdef LOG_NV2A |
| 3637 | printf("jump dmaget %08X", *dmaget); |
| 3638 | #endif |
| 3639 | *dmaget = cmd & 0xfffffffc; |
| 3640 | #ifdef LOG_NV2A |
| 3641 | printf(" -> %08X\n\r", *dmaget); |
| 3642 | #endif |
| 3643 | break; |
| 3644 | case 0: // increasing method |
| 3645 | method = (cmd >> 2) & 2047; // method*4 is address // if method >= 0x40 send it to assigned object |
| 3646 | #ifdef LOG_NV2A |
| 3647 | subch = (cmd >> 13) & 7; |
| 3648 | #endif |
| 3649 | count = (cmd >> 18) & 2047; |
| 3650 | if ((method == 0) && (count == 1)) { |
| 3651 | handle = space->read_dword(*dmaget); |
| 3652 | handle = geforce_object_offset(handle); |
| 3653 | #ifdef LOG_NV2A |
| 3654 | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3655 | #endif |
| 3656 | channel[chanel][subchannel].object.objhandle = handle; |
| 3657 | handle = ramin[handle / 4]; |
| 3658 | objclass = handle & 0xff; |
| 3659 | channel[chanel][subchannel].object.objclass = objclass; |
| 3660 | *dmaget += 4; |
| 3661 | } |
| 3662 | else { |
| 3663 | #ifdef LOG_NV2A |
| 3664 | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3665 | #endif |
| 3666 | ret = 0; |
| 3667 | while (count > 0) { |
| 3668 | countlen = 1; |
| 3669 | ret=geforce_exec_method(*space, chanel, subchannel, method, *dmaget, countlen); |
| 3670 | count--; |
| 3671 | method++; |
| 3672 | *dmaget += 4; |
| 3673 | if (ret != 0) |
| 3674 | break; |
| 3675 | } |
| 3676 | if (ret != 0) { |
| 3677 | puller_timer->enable(false); |
| 3678 | puller_waiting = 1; |
| 3679 | return; |
| 3680 | } |
| 3681 | } |
| 3682 | break; |
| 3683 | case 5: // non-increasing method |
| 3684 | method = (cmd >> 2) & 2047; |
| 3685 | #ifdef LOG_NV2A |
| 3686 | subch = (cmd >> 13) & 7; |
| 3687 | #endif |
| 3688 | count = (cmd >> 18) & 2047; |
| 3689 | if ((method == 0) && (count == 1)) { |
| 3690 | #ifdef LOG_NV2A |
| 3691 | logerror(" assign channel %d\n", subch); |
| 3692 | #endif |
| 3693 | handle = space->read_dword(*dmaget); |
| 3694 | handle = geforce_object_offset(handle); |
| 3695 | #ifdef LOG_NV2A |
| 3696 | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3697 | #endif |
| 3698 | channel[chanel][subchannel].object.objhandle = handle; |
| 3699 | handle = ramin[handle / 4]; |
| 3700 | objclass = handle & 0xff; |
| 3701 | channel[chanel][subchannel].object.objclass = objclass; |
| 3702 | *dmaget += 4; |
| 3703 | } |
| 3704 | else { |
| 3705 | #ifdef LOG_NV2A |
| 3706 | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3707 | #endif |
| 3708 | while (count > 0) { |
| 3709 | countlen = count; |
| 3710 | ret=geforce_exec_method(*space, chanel, subchannel, method, *dmaget, countlen); |
| 3711 | *dmaget += 4 * (count - countlen); |
| 3712 | count = countlen; |
| 3713 | } |
| 3714 | } |
| 3715 | break; |
| 3716 | case 3: // long non-increasing method |
| 3717 | method = (cmd >> 2) & 2047; |
| 3718 | #ifdef LOG_NV2A |
| 3719 | subch = (cmd >> 13) & 7; |
| 3720 | #endif |
| 3721 | count = space->read_dword(*dmaget); |
| 3722 | *dmaget += 4; |
| 3723 | if ((method == 0) && (count == 1)) { |
| 3724 | handle = space->read_dword(*dmaget); |
| 3725 | handle = geforce_object_offset(handle); |
| 3726 | #ifdef LOG_NV2A |
| 3727 | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3728 | #endif |
| 3729 | channel[chanel][subchannel].object.objhandle = handle; |
| 3730 | handle = ramin[handle / 4]; |
| 3731 | objclass = handle & 0xff; |
| 3732 | channel[chanel][subchannel].object.objclass = objclass; |
| 3733 | *dmaget += 4; |
| 3734 | } |
| 3735 | else { |
| 3736 | #ifdef LOG_NV2A |
| 3737 | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3738 | #endif |
| 3739 | while (count > 0) { |
| 3740 | countlen = count; |
| 3741 | ret=geforce_exec_method(*space, chanel, subchannel, method, *dmaget, countlen); |
| 3742 | *dmaget += 4 * (count - countlen); |
| 3743 | count = countlen; |
| 3744 | } |
| 3745 | } |
| 3746 | break; |
| 3747 | default: |
| 3748 | logerror(" unimplemented command %08X\n", cmd); |
| 3749 | } |
| 3750 | } |
| 3751 | } |
| 3752 | |
| 3592 | 3753 | READ32_MEMBER(nv2a_renderer::geforce_r) |
| 3593 | 3754 | { |
| 3594 | 3755 | static int x, ret; |
| r242607 | r242608 | |
| 3684 | 3845 | else if ((offset >= 0x00800000 / 4) && (offset < 0x00900000 / 4)) { |
| 3685 | 3846 | // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each |
| 3686 | 3847 | int chanel, subchannel, suboffset; |
| 3687 | | int method, count, handle, objclass; |
| 3848 | //int method, count, handle, objclass; |
| 3688 | 3849 | #ifdef LOG_NV2A |
| 3689 | 3850 | int subch; |
| 3690 | 3851 | #endif |
| r242607 | r242608 | |
| 3699 | 3860 | COMBINE_DATA(&channel[chanel][subchannel].regs[suboffset]); |
| 3700 | 3861 | if ((suboffset == 0x40 / 4) || (suboffset == 0x44 / 4)) { // DMA_PUT or DMA_GET |
| 3701 | 3862 | UINT32 *dmaput, *dmaget; |
| 3702 | | UINT32 cmd, cmdtype; |
| 3703 | | int countlen; |
| 3704 | 3863 | |
| 3705 | 3864 | dmaput = &channel[chanel][subchannel].regs[0x40 / 4]; |
| 3706 | 3865 | dmaget = &channel[chanel][subchannel].regs[0x44 / 4]; |
| 3707 | 3866 | //printf("dmaget %08X dmaput %08X\n\r",*dmaget,*dmaput); |
| 3708 | | if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000)) |
| 3867 | if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000)) { |
| 3709 | 3868 | *dmaget = *dmaput; |
| 3710 | | while (*dmaget != *dmaput) { |
| 3711 | | cmd = space.read_dword(*dmaget); |
| 3712 | | *dmaget += 4; |
| 3713 | | cmdtype = geforce_commandkind(cmd); |
| 3714 | | switch (cmdtype) |
| 3715 | | { |
| 3716 | | case 6: // jump |
| 3717 | | #ifdef LOG_NV2A |
| 3718 | | printf("jump dmaget %08X", *dmaget); |
| 3719 | | #endif |
| 3720 | | *dmaget = cmd & 0xfffffffc; |
| 3721 | | #ifdef LOG_NV2A |
| 3722 | | printf(" -> %08X\n\r", *dmaget); |
| 3723 | | #endif |
| 3724 | | break; |
| 3725 | | case 0: // increasing method |
| 3726 | | method = (cmd >> 2) & 2047; // method*4 is address // if method >= 0x40 send it to assigned object |
| 3727 | | #ifdef LOG_NV2A |
| 3728 | | subch = (cmd >> 13) & 7; |
| 3729 | | #endif |
| 3730 | | count = (cmd >> 18) & 2047; |
| 3731 | | if ((method == 0) && (count == 1)) { |
| 3732 | | handle = space.read_dword(*dmaget); |
| 3733 | | handle = geforce_object_offset(handle); |
| 3734 | | #ifdef LOG_NV2A |
| 3735 | | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3736 | | #endif |
| 3737 | | channel[chanel][subchannel].object.objhandle = handle; |
| 3738 | | handle = ramin[handle / 4]; |
| 3739 | | objclass = handle & 0xff; |
| 3740 | | channel[chanel][subchannel].object.objclass = objclass; |
| 3741 | | *dmaget += 4; |
| 3742 | | } |
| 3743 | | else { |
| 3744 | | #ifdef LOG_NV2A |
| 3745 | | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3746 | | #endif |
| 3747 | | while (count > 0) { |
| 3748 | | countlen = 1; |
| 3749 | | geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen); |
| 3750 | | count--; |
| 3751 | | method++; |
| 3752 | | *dmaget += 4; |
| 3753 | | } |
| 3754 | | } |
| 3755 | | break; |
| 3756 | | case 5: // non-increasing method |
| 3757 | | method = (cmd >> 2) & 2047; |
| 3758 | | #ifdef LOG_NV2A |
| 3759 | | subch = (cmd >> 13) & 7; |
| 3760 | | #endif |
| 3761 | | count = (cmd >> 18) & 2047; |
| 3762 | | if ((method == 0) && (count == 1)) { |
| 3763 | | #ifdef LOG_NV2A |
| 3764 | | logerror(" assign channel %d\n", subch); |
| 3765 | | #endif |
| 3766 | | handle = space.read_dword(*dmaget); |
| 3767 | | handle = geforce_object_offset(handle); |
| 3768 | | #ifdef LOG_NV2A |
| 3769 | | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3770 | | #endif |
| 3771 | | channel[chanel][subchannel].object.objhandle = handle; |
| 3772 | | handle = ramin[handle / 4]; |
| 3773 | | objclass = handle & 0xff; |
| 3774 | | channel[chanel][subchannel].object.objclass = objclass; |
| 3775 | | *dmaget += 4; |
| 3776 | | } |
| 3777 | | else { |
| 3778 | | #ifdef LOG_NV2A |
| 3779 | | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3780 | | #endif |
| 3781 | | while (count > 0) { |
| 3782 | | countlen = count; |
| 3783 | | geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen); |
| 3784 | | *dmaget += 4 * (count - countlen); |
| 3785 | | count = countlen; |
| 3786 | | } |
| 3787 | | } |
| 3788 | | break; |
| 3789 | | case 3: // long non-increasing method |
| 3790 | | method = (cmd >> 2) & 2047; |
| 3791 | | #ifdef LOG_NV2A |
| 3792 | | subch = (cmd >> 13) & 7; |
| 3793 | | #endif |
| 3794 | | count = space.read_dword(*dmaget); |
| 3795 | | *dmaget += 4; |
| 3796 | | if ((method == 0) && (count == 1)) { |
| 3797 | | handle = space.read_dword(*dmaget); |
| 3798 | | handle = geforce_object_offset(handle); |
| 3799 | | #ifdef LOG_NV2A |
| 3800 | | logerror(" assign to subchannel %d object at %d\n", subch, handle); |
| 3801 | | #endif |
| 3802 | | channel[chanel][subchannel].object.objhandle = handle; |
| 3803 | | handle = ramin[handle / 4]; |
| 3804 | | objclass = handle & 0xff; |
| 3805 | | channel[chanel][subchannel].object.objclass = objclass; |
| 3806 | | *dmaget += 4; |
| 3807 | | } |
| 3808 | | else { |
| 3809 | | #ifdef LOG_NV2A |
| 3810 | | logerror(" subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count); |
| 3811 | | #endif |
| 3812 | | while (count > 0) { |
| 3813 | | countlen = count; |
| 3814 | | geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen); |
| 3815 | | *dmaget += 4 * (count - countlen); |
| 3816 | | count = countlen; |
| 3817 | | } |
| 3818 | | } |
| 3819 | | break; |
| 3820 | | default: |
| 3821 | | logerror(" unimplemented command %08X\n", cmd); |
| 3869 | puller_waiting = 0; |
| 3870 | puller_timer->enable(false); |
| 3871 | return; |
| 3872 | } |
| 3873 | if (*dmaget != *dmaput) { |
| 3874 | if (puller_waiting == 0) { |
| 3875 | puller_channel = chanel; |
| 3876 | puller_subchannel = subchannel; |
| 3877 | puller_space = &space; |
| 3878 | puller_timer->enable(); |
| 3879 | puller_timer->adjust(attotime::zero); |
| 3822 | 3880 | } |
| 3823 | 3881 | } |
| 3824 | 3882 | } |
| 3825 | 3883 | } |
| 3826 | | else; |
| 3884 | //else |
| 3827 | 3885 | // logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data); |
| 3828 | 3886 | } |
| 3887 | |
| 3888 | void nv2a_renderer::savestate_items() |
| 3889 | { |
| 3890 | } |
| 3891 | |
| 3892 | void nv2a_renderer::start() |
| 3893 | { |
| 3894 | puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer"); |
| 3895 | puller_timer->enable(false); |
| 3896 | } |