Previous 199869 Revisions Next

r34096 Sunday 28th December, 2014 at 20:49:12 UTC by Samuele Zannoli
chihiro: add support for vblank wait NV2A accelarator method (nw)

It is disabled by default since is slows down too much.
There is a new debugger command "chihiro waitvblank" to enable and disable it.
[src/mame/drivers]chihiro.c
[src/mame/includes]chihiro.h
[src/mame/video]chihiro.c

trunk/src/mame/drivers/chihiro.c
r242607r242608
777777      debug_console_printf(machine, "Register combiners disabled\n");
778778}
779779
780static void waitvblank_command(running_machine &machine, int ref, int params, const char **param)
781{
782   int en;
783
784   chihiro_state *chst = machine.driver_data<chihiro_state>();
785   en = chst->nvidia_nv2a->toggle_wait_vblank_support();
786   if (en != 0)
787      debug_console_printf(machine, "Vblank method enabled\n");
788   else
789      debug_console_printf(machine, "Vblank method disabled\n");
790}
791
780792static void grab_texture_command(running_machine &machine, int ref, int params, const char **param)
781793{
782794   UINT64 type;
r242607r242608
862874   debug_console_printf(machine, "  chihiro curthread -- Print information about current thread\n");
863875   debug_console_printf(machine, "  chihiro irq,<number> -- Generate interrupt with irq number 0-15\n");
864876   debug_console_printf(machine, "  chihiro nv2a_combiners -- Toggle use of register combiners\n");
877   debug_console_printf(machine, "  chihiro waitvblank -- Toggle support for wait vblank method\n");
865878   debug_console_printf(machine, "  chihiro grab_texture,<type>,<filename> -- Save to <filename> the next used texture of type <type>\n");
866879   debug_console_printf(machine, "  chihiro grab_vprog,<filename> -- save current vertex program instruction slots to <filename>\n");
867880   debug_console_printf(machine, "  chihiro vprogdis,<address>,<length>[,<type>] -- disassemble <lenght> vertex program instructions at <address> of <type>\n");
r242607r242608
886899      generate_irq_command(machine, ref, params - 1, param + 1);
887900   else if (strcmp("nv2a_combiners", param[0]) == 0)
888901      nv2a_combiners_command(machine, ref, params - 1, param + 1);
902   else if (strcmp("waitvblank", param[0]) == 0)
903      waitvblank_command(machine, ref, params - 1, param + 1);
889904   else if (strcmp("grab_texture", param[0]) == 0)
890905      grab_texture_command(machine, ref, params - 1, param + 1);
891906   else if (strcmp("grab_vprog", param[0]) == 0)
r242607r242608
17871802   save_item(NAME(smbusst.words));
17881803   save_item(NAME(pic16lc_buffer));
17891804   save_item(NAME(usbhack_counter));
1805   nvidia_nv2a->start();
17901806   nvidia_nv2a->savestate_items();
17911807}
17921808
trunk/src/mame/includes/chihiro.h
r242607r242608
191191      rendertarget = NULL;
192192      depthbuffer = NULL;
193193      displayedtarget = NULL;
194      puller_channel = 0;
195      puller_subchannel = 0;
196      puller_waiting = 0;
194197      debug_grab_texttype = -1;
195198      debug_grab_textfile = NULL;
199      waitvblank_used = 0;
196200      memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
197201      memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset));
198202   }
r242607r242608
208212   int geforce_commandkind(UINT32 word);
209213   UINT32 geforce_object_offset(UINT32 handle);
210214   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);
212216   UINT32 texture_get_texel(int number, int x, int y);
213217   void write_pixel(int x, int y, UINT32 color, UINT32 depth);
214218   void combiner_initialize_registers(UINT32 argb8[6]);
r242607r242608
238242   void computedilated(void);
239243   void putpixtex(int xp, int yp, int up, int vp);
240244   int toggle_register_combiners_usage();
245   int toggle_wait_vblank_support();
241246   void debug_grab_texture(int type, const char *filename);
242247   void debug_grab_vertex_program_slot(int slot, UINT32 *instruction);
248   void start();
243249   void savestate_items();
244
245250   void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib);
246251   int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
247252   int read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit);
248253   int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit);
249254   void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count);
255   TIMER_CALLBACK_MEMBER(puller_timer_work);
250256
251257   struct {
252258      UINT32 regs[0x80 / 4];
r242607r242608
429435   int enabled_vertex_attributes;
430436   int vertex_attribute_words[16];
431437   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;
432443   UINT32 dilated0[16][2048];
433444   UINT32 dilated1[16][2048];
434445   int dilatechose[256];
435446   nvidia_object_data *objectdata;
436447   int debug_grab_texttype;
437448   char *debug_grab_textfile;
449   int waitvblank_used;
438450
439451   enum VERTEX_PARAMETER {
440452      PARAM_COLOR_B = 0,
r242607r242608
479491      TEX3 = 12
480492   };
481493   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 ?
483495      NV2A_VTXBUF_TYPE_FLOAT = 2,
484496      NV2A_VTXBUF_TYPE_UBYTE = 4,
485497      NV2A_VTXBUF_TYPE_USHORT = 5,
trunk/src/mame/video/chihiro.c
r242607r242608
20272027      }
20282028      break;
20292029   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      }
20302035      break;
2031   case  NV2A_VTXBUF_TYPE_UNKNOWN_0:
2036   case  NV2A_VTXBUF_TYPE_UBYTE2:
20322037      u = space.read_dword(address + 0);
20332038      for (c = 0; c < l; c++) {
20342039         vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0;
r242607r242608
21422147            destination[m].p[PARAM_TEXTURE0_U + u * 2] = source[m].attribute[9 + u].fv[0];
21432148            destination[m].p[PARAM_TEXTURE0_V + u * 2] = source[m].attribute[9 + u].fv[1];
21442149         }
2145         destination[m].p[PARAM_Z] = 0+0xffffff;
2150         destination[m].p[PARAM_Z] = 0xffffff;
21462151      }
21472152   }
21482153   else {
r242607r242608
21642169   }
21652170}
21662171
2167void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen)
2172int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen)
21682173{
21692174   UINT32 maddress;
21702175   UINT32 data;
r242607r242608
23642369         if (countlen < 0) {
23652370            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
23662371            countlen = 0;
2367            return;
2372            return 0;
23682373         }
23692374         address = address + c * 4;
23702375         for (n = 1; countlen > 0; n++) {
r242607r242608
23922397         if (countlen < 0) {
23932398            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
23942399            countlen = 0;
2395            return;
2400            return 0;
23962401         }
23972402         address = address + c * 4;
23982403         for (n = 0; countlen > 0; n++) {
r242607r242608
24392444         if (countlen < 0) {
24402445            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
24412446            countlen = 0;
2442            return;
2447            return 0;
24432448         }
24442449         address = address + c * 4;
24452450         for (n = 0; countlen > 0; n += 2) {
r242607r242608
24492454            if (countlen < 0) {
24502455               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
24512456               countlen = 0;
2452               return;
2457               return 0;
24532458            }
24542459            address = address + c * 4;
24552460            render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]);
r242607r242608
24772482      vertexbuffer_kind[bit] = data & 15;
24782483      vertexbuffer_size[bit] = (data >> 4) & 15;
24792484      switch (vertexbuffer_kind[bit]) {
2480      case NV2A_VTXBUF_TYPE_UNKNOWN_0:
2485      case NV2A_VTXBUF_TYPE_UBYTE2:
24812486         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2;
24822487         break;
24832488      case NV2A_VTXBUF_TYPE_FLOAT:
r242607r242608
25412546         m = 2;
25422547      else
25432548         m = 1;
2544      // possible buffers: color, depth, stencil, and accumulation
2549      // possible buffers: color, depth, stencil
25452550      // clear framebuffer
25462551      if (data & 0xf0) {
25472552         bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
r242607r242608
25502555         bm.fill(color);
25512556         //printf("clearscreen\n\r");
25522557      }
2553      if (data & 0x01) {
2558      if ((data & 0x03) == 3) {
25542559         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);
25582563      }
2564      else if (((data & 0x03) == 1) || ((data & 0x03) == 2))
2565         logerror("Unsupported clear method parameter %d\n\r", data & 0x03);
25592566      countlen--;
25602567   }
25612568   if (maddress == 0x0200) {
r242607r242608
25832590         displayedtarget = (UINT32 *)space.get_write_ptr(data);
25842591      }
25852592   }
2593   if (maddress == 0x0130) {
2594      countlen--;
2595      if (waitvblank_used == 1)
2596         return 1; // block until next vblank
2597      else
2598         return 0;
2599   }
25862600   if (maddress == 0x0210) {
25872601      // framebuffer offset ?
25882602      rendertarget = (UINT32 *)space.get_write_ptr(data);
r242607r242608
29562970      //combiner.=(data >> 27) & 7;
29572971      countlen--;
29582972   }
2973   return 0;
29592974}
29602975
29612976int nv2a_renderer::toggle_register_combiners_usage()
r242607r242608
29642979   return combiner.used;
29652980}
29662981
2982int nv2a_renderer::toggle_wait_vblank_support()
2983{
2984   waitvblank_used = 1 - waitvblank_used;
2985   return waitvblank_used;
2986}
2987
29672988void nv2a_renderer::debug_grab_texture(int type, const char *filename)
29682989{
29692990   debug_grab_texttype = type;
r242607r242608
29823003   instruction[3] = vertexprogram.exec.op[slot].i[3];
29833004}
29843005
2985void nv2a_renderer::savestate_items()
2986{
2987}
2988
29893006void nv2a_renderer::combiner_argb8_float(UINT32 color, float reg[4])
29903007{
29913008   reg[0] = (float)(color & 0xff) / 255.0;
r242607r242608
35693586      pmc[0x100 / 4] |= 0x1000000;
35703587   else
35713588      pmc[0x100 / 4] &= ~0x1000000;
3589   if ((state == true) && (puller_waiting == 1)) {
3590      puller_waiting = 0;
3591      puller_timer_work(NULL, 0);
3592   }
35723593   if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) {
35733594      // send interrupt
35743595      return true;
r242607r242608
35893610   return 0;
35903611}
35913612
3613TIMER_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
35923753READ32_MEMBER(nv2a_renderer::geforce_r)
35933754{
35943755   static int x, ret;
r242607r242608
36843845   else if ((offset >= 0x00800000 / 4) && (offset < 0x00900000 / 4)) {
36853846      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
36863847      int chanel, subchannel, suboffset;
3687      int method, count, handle, objclass;
3848      //int method, count, handle, objclass;
36883849#ifdef LOG_NV2A
36893850      int subch;
36903851#endif
r242607r242608
36993860      COMBINE_DATA(&channel[chanel][subchannel].regs[suboffset]);
37003861      if ((suboffset == 0x40 / 4) || (suboffset == 0x44 / 4)) { // DMA_PUT or DMA_GET
37013862         UINT32 *dmaput, *dmaget;
3702         UINT32 cmd, cmdtype;
3703         int countlen;
37043863
37053864         dmaput = &channel[chanel][subchannel].regs[0x40 / 4];
37063865         dmaget = &channel[chanel][subchannel].regs[0x44 / 4];
37073866         //printf("dmaget %08X dmaput %08X\n\r",*dmaget,*dmaput);
3708         if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000))
3867         if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000)) {
37093868            *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);
38223880            }
38233881         }
38243882      }
38253883   }
3826   else;
3884   //else
38273885   //      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
38283886}
3887
3888void nv2a_renderer::savestate_items()
3889{
3890}
3891
3892void 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}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team