Previous 199869 Revisions Next

r40503 Friday 28th August, 2015 at 08:08:55 UTC by Samuele Zannoli
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
[src/mame/includes]chihiro.h
[src/mame/video]chihiro.c

trunk/src/mame/includes/chihiro.h
r249014r249015
185185      memset(pfifo, 0, sizeof(pfifo));
186186      memset(pcrtc, 0, sizeof(pcrtc));
187187      memset(pmc, 0, sizeof(pmc));
188      memset(pgraph, 0, sizeof(pgraph));
188189      memset(ramin, 0, sizeof(ramin));
189190      computedilated();
190191      objectdata = &(object_data_alloc());
r249014r249015
194195      enabled_vertex_attributes = 0;
195196      indexesleft_count = 0;
196197      vertex_pipeline = 4;
198      color_mask = 0xffffffff;
197199      alpha_test_enabled = false;
198200      alpha_reference = 0;
199201      alpha_func = nv2a_renderer::ALWAYS;
r249014r249015
238240   }
239241   DECLARE_READ32_MEMBER(geforce_r);
240242   DECLARE_WRITE32_MEMBER(geforce_w);
241   bool vblank_callback(screen_device &screen, bool state);
243   void vblank_callback(screen_device &screen, bool state);
242244   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
245   bool update_interrupts();
246   void set_interrupt_device(pic8259_device *device);
243247
244248   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
245249   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
r249014r249015
303307   UINT32 pfifo[0x2000 / 4];
304308   UINT32 pcrtc[0x1000 / 4];
305309   UINT32 pmc[0x1000 / 4];
310   UINT32 pgraph[0x2000 / 4];
306311   UINT32 ramin[0x100000 / 4];
307312   UINT32 dma_offset[2];
308313   UINT32 dma_size[2];
309314   UINT8 *basemempointer;
315   pic8259_device *interruptdevice;
310316   rectangle limits_rendertarget;
311317   UINT32 pitch_rendertarget;
312318   UINT32 pitch_depthbuffer;
r249014r249015
441447      int used;
442448      osd_lock *lock;
443449   } combiner;
450   UINT32 color_mask;
444451   bool alpha_test_enabled;
445452   int alpha_func;
446453   int alpha_reference;
trunk/src/mame/video/chihiro.c
r249014r249015
33#include "emu.h"
44#include "video/poly.h"
55#include "bitmap.h"
6#include "machine/pic8259.h"
67#include "includes/chihiro.h"
78
89//#define LOG_NV2A
r249014r249015
945946UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
946947{
947948   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
949950   UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
950951   UINT32 w;
951952
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   }
954961   w = ramin[e / 4 + 1];
955   return (w & 0xffff) * 0x10;
962   return (w & 0xffff) * 0x10; // 0xffff is not certain
956963}
957964
958965void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
r249014r249015
12461253      addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
12471254   else // type_rendertarget == LINEAR*/
12481255      addr = rendertarget + (pitch_rendertarget / 4)*y + x;
1249   fbcolor = *addr;
1256   fbcolor = 0;
1257   if (color_mask != 0)
1258      fbcolor = *addr;
12501259   daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
12511260   deptsten = *daddr;
12521261   c[3] = color >> 24;
r249014r249015
17721781            break;
17731782      }
17741783   }
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   }
17771790   if (depth_write_enabled)
17781791      dep = depth;
17791792   deptsten = (dep << 8) | sten;
r249014r249015
22332246   maddress = method * 4;
22342247   data = space.read_dword(address);
22352248   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
22362252   if (maddress == 0x17fc) {
22372253      indexesleft_count = 0;
22382254      indexesleft_first = 0;
r249014r249015
22702286         }
22712287         wait();
22722288      }
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      }
22732304      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
22742305         vertex_nv vert[4];
22752306         vertex_t xy[4];
r249014r249015
23112342      // each dword after 1800 contains two 16 bit index values to select the vartices
23122343      // each dword after 1808 contains a 32 bit index value to select the vartices
23132344      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
23172345      if (type == nv2a_renderer::QUADS) {
23182346         while (1) {
23192347            vertex_nv vert[4];
r249014r249015
23322360            render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
23332361         }
23342362      }
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      }
23352391      else if (type == nv2a_renderer::TRIANGLES) {
23362392         while (1) {
23372393            vertex_nv vert[3];
r249014r249015
24462502         }
24472503         wait();
24482504      }
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      }
24492523      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
24502524         vertex_nv vert[4];
24512525         vertex_t xy[4];
r249014r249015
26132687         // clear colors
26142688         UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
26152689         bm.fill(color);
2616         //printf("clearscreen\n\r");
2690#ifdef LOG_NV2A
2691         printf("clearscreen\n\r");
2692#endif
26172693      }
26182694      if ((data & 0x03) == 3) {
26192695         bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
r249014r249015
26492725      dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
26502726   }
26512727   if (maddress == 0x020c) {
2652      // line size ?
26532728      pitch_rendertarget=data & 0xffff;
26542729      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
26562733      countlen--;
26572734   }
26582735   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;
26642747      }
2748      else
2749         return 0;
26652750   }
26662751   if (maddress == 0x0130) {
26672752      countlen--;
r249014r249015
26702755      else
26712756         return 0;
26722757   }
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   }
26732770   if (maddress == 0x0210) {
26742771      // framebuffer offset ?
26752772      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
26772776      countlen--;
26782777   }
26792778   if (maddress == 0x0214) {
26802779      // zbuffer offset ?
26812780      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
26832784      if ((data == 0) || (data > 0x7ffffffc))
26842785         depth_write_enabled = false;
26852786      else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
r249014r249015
27092810   if (maddress == 0x0354) {
27102811      depth_function = data;
27112812   }
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   }
27122825   if (maddress == 0x035c) {
27132826      UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
27142827      depth_write_enabled = data != 0;
r249014r249015
36483761   combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f);
36493762}
36503763
3651bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
3764void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
36523765{
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) {
36553774      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
36563783   else
3657      pcrtc[0x100 / 4] &= ~1;
3784      interruptdevice->ir3_w(0); // IRQ 3
3785}
3786
3787bool nv2a_renderer::update_interrupts()
3788{
36583789   if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
36593790      pmc[0x100 / 4] |= 0x1000000;
36603791   else
36613792      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))) {
36673798      // send interrupt
36683799      return true;
36693800   }
r249014r249015
36923823   int countlen;
36933824   int ret;
36943825   address_space *space = puller_space;
3826#ifdef LOG_NV2A
3827   UINT32 subch;
3828#endif
36953829
36963830   chanel = puller_channel;
36973831   subchannel = puller_subchannel;
r249014r249015
37483882            }
37493883            if (ret != 0) {
37503884               puller_timer->enable(false);
3751               puller_waiting = 1;
3885               puller_waiting = ret;
37523886               return;
37533887            }
37543888         }
r249014r249015
38473981      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
38483982   }
38493983   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3984      ret = pgraph[offset - 0x00400000 / 4];
38503985      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
38513986   }
38523987   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
r249014r249015
38704005      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
38714006      return ret;
38724007   }
3873   else
3874   {
3875      /* nothing */
3876   }
38774008   //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
38784009   return ret;
38794010}
38804011
38814012WRITE32_MEMBER(nv2a_renderer::geforce_w)
38824013{
4014   UINT32 old;
4015   bool update_int;
4016
4017   update_int = false;
38834018   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
38844019      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
38854020   }
r249014r249015
38984033      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
38994034   }
39004035   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;
39014058      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
39024059   }
39034060   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
39044061      int e = offset - 0x00600000 / 4;
39054062      if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
39064063         return;
4064      old = pcrtc[e];
39074065      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;
39084072      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
39114077      }
39124078      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
39134079   }
r249014r249015
39224088      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
39234089      int chanel, subchannel, suboffset;
39244090      //int method, count, handle, objclass;
3925#ifdef LOG_NV2A
3926      int subch;
3927#endif
39284091
39294092      suboffset = offset - 0x00800000 / 4;
39304093      chanel = (suboffset >> (16 - 2)) & 31;
r249014r249015
39594122   }
39604123   //else
39614124   //      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   }
39624131}
39634132
39644133void nv2a_renderer::savestate_items()
r249014r249015
39714140   puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
39724141   puller_timer->enable(false);
39734142}
4143
4144void nv2a_renderer::set_interrupt_device(pic8259_device *device)
4145{
4146   interruptdevice = device;
4147}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team