Previous 199869 Revisions Next

r29517 Thursday 10th April, 2014 at 20:30:44 UTC by Tafoid
Chihiro improvements:  [Samuele Zannoli]
* i386 cpu x87 opcodes FPREM and FPREM1 must clear status bit C2 not C0
* Add basic management of some Nvidia APU sound registers.
* Store modelview/projection matrices and translate/scale vectors sent to NV2A.
* Store vertex program (vertex shader) sent to NV2A 3d accelerator.
* Added debug command "chihiro grab_texture,<type>,<filename>", it saves to <filename> the next used texture of type <type>.
* Fixed DXT3 and adds DXt5 texture decompression.
* Add 3d accelerator method 0x1800 for indexed mode vertex sending.
[src/emu/cpu/i386]x87ops.inc
[src/mame/drivers]chihiro.c

trunk/src/mame/drivers/chihiro.c
r29516r29517
416416   void dword_write_le(UINT8 *addr,UINT32 d);
417417   void word_write_le(UINT8 *addr,UINT16 d);
418418   void debug_generate_irq(int irq,bool active);
419   void debug_grab_texture(int type, char *filename);
419420
420421   void vblank_callback(screen_device &screen, bool state);
421422   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
r29516r29517
445446      UINT32 words[256/4];
446447   } smbusst;
447448   struct apu_state {
448      UINT32 memory0_sgaddress;
449      UINT32 memory0_sgblocks;
450      UINT32 memory0_address;
451      UINT32 memory1_sgaddress;
452      UINT32 memory1_sgblocks;
449      UINT32 memory[0x60000/4];
450      UINT32 gpdsp_sgaddress; // global processor scatter-gather
451      UINT32 gpdsp_sgblocks;
452      UINT32 gpdsp_address;
453      UINT32 epdsp_sgaddress; // encoder processor scatter-gather
454      UINT32 epdsp_sgblocks;
455      UINT32 unknown_sgaddress;
456      UINT32 unknown_sgblocks;
457      int voice_number;
458      UINT32 voices_heap_blockaddr[1024];
459      UINT64 voices_active[4]; //one bit for each voice: 1 playing 0 not
460      UINT32 voicedata_address;
461      int voices_frequency[256]; // sample rate
462      int voices_position[256]; // position in samples * 1000
463      int voices_position_start[256]; // position in samples * 1000
464      int voices_position_end[256]; // position in samples * 1000
465      int voices_position_increment[256]; // position increment every 1ms * 1000
453466      emu_timer *timer;
454467      address_space *space;
455468   } apust;
r29516r29517
503516      combiner.used=0;
504517      combiner.lock=osd_lock_alloc();
505518      enabled_vertex_attributes=0;
506      memset(words_vertex_attributes,0,sizeof(words_vertex_attributes));
519      indexesleft_count = 0;
520      debug_grab_texttype = -1;
521      debug_grab_textfile = NULL;
522      memset(words_vertex_attributes, 0, sizeof(words_vertex_attributes));
507523   }
508524   DECLARE_READ32_MEMBER( geforce_r );
509525   DECLARE_WRITE32_MEMBER( geforce_w );
r29516r29517
546562   void computedilated(void);
547563   void putpixtex(int xp,int yp,int up,int vp);
548564   int toggle_register_combiners_usage();
565   void debug_grab_texture(int type, const char *filename);
549566   void savestate_items();
550567
551568   struct {
r29516r29517
570587      int rectangle_pitch;
571588      void *buffer;
572589   } texture[4];
590   int primitives_count;
591   int indexesleft_count;
592   UINT32 indexesleft[8];
573593   struct {
574594      float variable_A[4]; // 0=R 1=G 2=B 3=A
575595      float variable_B[4];
r29516r29517
673693      int used;
674694      osd_lock *lock;
675695   } combiner;
696   struct {
697      float modelview[16];
698      float modelview_inverse[16];
699      float projection[16];
700      float translate[4];
701      float scale[4];
702   } matrix;
703   struct {
704      UINT32 instruction[1024];
705      int instructions;
706      int upload_instruction;
707      UINT32 parameter[1024];
708      int upload_parameter;
709   } vertexprogram;
676710   int enabled_vertex_attributes;
677711   int words_vertex_attributes[16];
678712   bitmap_rgb32 fb;
r29516r29517
680714   UINT32 dilated1[16][2048];
681715   int dilatechose[256];
682716   nvidia_object_data *objectdata;
717   int debug_grab_texttype;
718   char *debug_grab_textfile;
683719
684720   enum NV2A_BEGIN_END {
685721      STOP=0,
r29516r29517
10521088      debug_console_printf(machine,"Register combiners disabled\n");
10531089}
10541090
1091static void grab_texture_command(running_machine &machine, int ref, int params, const char **param)
1092{
1093   UINT64 type;
1094   chihiro_state *chst = machine.driver_data<chihiro_state>();
1095
1096   if (params < 2)
1097      return;
1098   if (!debug_command_parameter_number(machine, param[0], &type))
1099      return;
1100   if ((param[1][0] == 0) || (strlen(param[1]) > 127))
1101      return;
1102   chst->nvidia_nv2a->debug_grab_texture((int)type,param[1]);
1103}
1104
10551105static void help_command(running_machine &machine, int ref, int params, const char **param)
10561106{
10571107   debug_console_printf(machine,"Available Chihiro commands:\n");
r29516r29517
10621112   debug_console_printf(machine,"  chihiro curthread -- Print information about current thread\n");
10631113   debug_console_printf(machine,"  chihiro irq,<number> -- Generate interrupt with irq number 0-15\n");
10641114   debug_console_printf(machine,"  chihiro nv2a_combiners -- Toggle use of register combiners\n");
1115   debug_console_printf(machine,"  chihiro grab_texture,<type>,<filename> -- Save to <filename> the next used texture of type <type>\n");
10651116   debug_console_printf(machine,"  chihiro help -- this list\n");
10661117}
10671118
r29516r29517
10831134      generate_irq_command(machine,ref,params-1,param+1);
10841135   else if (strcmp("nv2a_combiners",param[0]) == 0)
10851136      nv2a_combiners_command(machine,ref,params-1,param+1);
1137   else if (strcmp("grab_texture", param[0]) == 0)
1138      grab_texture_command(machine, ref, params - 1, param + 1);
10861139   else
10871140      help_command(machine,ref,params-1,param+1);
10881141}
r29516r29517
12561309
12571310UINT32 nv2a_renderer::texture_get_texel(int number,int x,int y)
12581311{
1259   UINT32 to,s,c,sa,ca;
1260   UINT32 a4r4g4b4,a1r5g5b5,r5g6b5;
1261   int bx,by;
1262   int color0,color1,color0m2,color1m2;
1312   UINT32 to, s, c, sa, ca;
1313   UINT32 a4r4g4b4, a1r5g5b5, r5g6b5;
1314   int bx, by;
1315   int color0, color1, color0m2, color1m2, alpha0, alpha1;
12631316   UINT32 codes;
12641317   UINT64 alphas;
1265   int cr,cg,cb;
1318   int cr, cg, cb;
12661319
1320   // force to [0,size-1]
1321   x = (unsigned int)x & (texture[number].sizeu - 1);
1322   y = (unsigned int)y & (texture[number].sizev - 1);
12671323   switch (texture[number].format) {
1268      case A8R8G8B8:
1269         to=dilated0[texture[number].dilate][x]+dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1270         return *(((UINT32 *)texture[number].buffer)+to); // get texel color
1271      case DXT1:
1272         bx=x >> 2;
1273         by=y >> 2;
1274         x=x & 3;
1275         y=y & 3;
1276         //to=dilated0[texture[number].dilate][bx]+dilated1[texture[number].dilate][by]; // swizzle 4x4 blocks ?
1277         to=bx+by*(texture[number].sizeu >> 2);
1278         color0=*((UINT16 *)(((UINT64 *)texture[number].buffer)+to)+0);
1279         color1=*((UINT16 *)(((UINT64 *)texture[number].buffer)+to)+1);
1280         codes=*((UINT32 *)(((UINT64 *)texture[number].buffer)+to)+1);
1281         s=(y << 3)+(x << 1);
1282         c=(codes >> s) & 3;
1283         c=c+(color0 > color1 ? 0 : 4);
1284         color0m2=color0 << 1;
1285         color1m2=color1 << 1;
1286         switch (c) {
1287            case 0:
1288               return 0xff000000+convert_r5g6b5_r8g8b8(color0);
1289               break;
1290            case 1:
1291               return 0xff000000+convert_r5g6b5_r8g8b8(color1);
1292               break;
1293            case 2:
1294               cb=pal5bit(((color0m2 & 0x003e)+(color1 & 0x001f))/3);
1295               cg=pal6bit(((color0m2 & 0x0fc0)+(color1 & 0x07e0))/3 >> 5);
1296               cr=pal5bit(((color0m2 & 0x1f000)+color1)/3 >> 11);
1297               return 0xff000000|(cr<<16)|(cg<<8)|(cb);
1298               break;
1299            case 3:
1300               cb=pal5bit(((color1m2 & 0x003e)+(color0 & 0x001f))/3);
1301               cg=pal6bit(((color1m2 & 0x0fc0)+(color0 & 0x07e0))/3 >> 5);
1302               cr=pal5bit(((color1m2 & 0x1f000)+color0)/3 >> 11);
1303               return 0xff000000|(cr<<16)|(cg<<8)|(cb);
1304               break;
1305            case 4:
1306               return 0xff000000+convert_r5g6b5_r8g8b8(color0);
1307               break;
1308            case 5:
1309               return 0xff000000+convert_r5g6b5_r8g8b8(color1);
1310               break;
1311            case 6:
1312               cb=pal5bit(((color0 & 0x001f)+(color1 & 0x001f))/2);
1313               cg=pal6bit(((color0 & 0x07e0)+(color1 & 0x07e0))/2 >> 5);
1314               cr=pal5bit((color0+color1)/2 >> 11);
1315               return 0xff000000|(cr<<16)|(cg<<8)|(cb);
1316               break;
1317            default:
1318               return 0xff000000;
1319               break;
1320         }
1321      case DXT3:
1322         bx=x >> 2;
1323         by=y >> 2;
1324         x=x & 3;
1325         y=y & 3;
1326         //to=(dilated0[texture[number].dilate][bx]+dilated1[texture[number].dilate][by]) << 1; // swizzle 4x4 blocks ?
1327         to=(bx+by*(texture[number].sizeu >> 2)) << 1;
1328         color0=*((UINT16 *)(((UINT64 *)texture[number].buffer)+to)+4);
1329         color1=*((UINT16 *)(((UINT64 *)texture[number].buffer)+to)+5);
1330         codes=*((UINT32 *)(((UINT64 *)texture[number].buffer)+to)+3);
1331         alphas=*(((UINT64 *)texture[number].buffer)+to);
1332         s=(y << 3)+(x << 1);
1333         sa=((y << 2)+x) << 2;
1334         c=(codes >> s) & 3;
1335         ca=(alphas >> sa) & 15;
1336         switch (c) {
1337            case 0:
1338               return ((ca+(ca << 4)) << 24)+convert_r5g6b5_r8g8b8(color0);
1339               break;
1340            case 1:
1341               return ((ca+(ca << 4)) << 24)+convert_r5g6b5_r8g8b8(color1);
1342               break;
1343            case 2:
1344               cb=pal5bit(((color0 & 0x001f)+(color1 & 0x001f))/2);
1345               cg=pal6bit(((color0 & 0x07e0)+(color1 & 0x07e0))/2 >> 5);
1346               cr=pal5bit((color0+color1)/2 >> 11);
1347               return ((ca+(ca << 4)) << 24)|(cr<<16)|(cg<<8)|(cb);
1348               break;
1349            default:
1350               return (ca+(ca << 4)) << 24;
1351               break;
1352         }
1324   case A8R8G8B8:
1325      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1326      return *(((UINT32 *)texture[number].buffer) + to); // get texel color
1327   case DXT1:
1328      bx = x >> 2;
1329      by = y >> 2;
1330      x = x & 3;
1331      y = y & 3;
1332      to = bx + by*(texture[number].sizeu >> 2);
1333      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 0);
1334      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1335      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1336      s = (y << 3) + (x << 1);
1337      c = (codes >> s) & 3;
1338      c = c + (color0 > color1 ? 0 : 4);
1339      color0m2 = color0 << 1;
1340      color1m2 = color1 << 1;
1341      switch (c) {
1342      case 0:
1343         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
13531344         break;
1354      case A4R4G4B4:
1355         to=dilated0[texture[number].dilate][x]+dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1356         a4r4g4b4=*(((UINT16 *)texture[number].buffer)+to); // get texel color
1357         return convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
1358      case A1R5G5B5:
1359         to=dilated0[texture[number].dilate][x]+dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1360         a1r5g5b5=*(((UINT16 *)texture[number].buffer)+to); // get texel color
1361         return convert_a1r5g5b5_a8r8g8b8(a1r5g5b5);
1362      case R5G6B5:
1363         to=dilated0[texture[number].dilate][x]+dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1364         r5g6b5=*(((UINT16 *)texture[number].buffer)+to); // get texel color
1365         return 0xff000000+convert_r5g6b5_r8g8b8(r5g6b5);
1366      case R8G8B8_RECT:
1367         to=texture[number].rectangle_pitch*y+(x << 2);
1368         return *((UINT32 *)(((UINT8 *)texture[number].buffer)+to));
1345      case 1:
1346         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
1347         break;
1348      case 2:
1349         cb = pal5bit(((color0m2 & 0x003e) + (color1 & 0x001f)) / 3);
1350         cg = pal6bit(((color0m2 & 0x0fc0) + (color1 & 0x07e0)) / 3 >> 5);
1351         cr = pal5bit(((color0m2 & 0x1f000) + color1) / 3 >> 11);
1352         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1353         break;
1354      case 3:
1355         cb = pal5bit(((color1m2 & 0x003e) + (color0 & 0x001f)) / 3);
1356         cg = pal6bit(((color1m2 & 0x0fc0) + (color0 & 0x07e0)) / 3 >> 5);
1357         cr = pal5bit(((color1m2 & 0x1f000) + color0) / 3 >> 11);
1358         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1359         break;
1360      case 4:
1361         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
1362         break;
1363      case 5:
1364         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
1365         break;
1366      case 6:
1367         cb = pal5bit(((color0 & 0x001f) + (color1 & 0x001f)) / 2);
1368         cg = pal6bit(((color0 & 0x07e0) + (color1 & 0x07e0)) / 2 >> 5);
1369         cr = pal5bit(((color0 & 0xf800) + (color1 & 0xf800)) / 2 >> 11);
1370         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1371         break;
13691372      default:
1370         return 0xff00ff00;
1373         return 0xff000000;
1374         break;
1375      }
1376   case DXT3:
1377      bx = x >> 2;
1378      by = y >> 2;
1379      x = x & 3;
1380      y = y & 3;
1381      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
1382      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
1383      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
1384      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
1385      alphas = *(((UINT64 *)texture[number].buffer) + to);
1386      s = (y << 3) + (x << 1);
1387      sa = ((y << 2) + x) << 2;
1388      c = (codes >> s) & 3;
1389      ca = (alphas >> sa) & 15;
1390      switch (c) {
1391      case 0:
1392         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color0);
1393         break;
1394      case 1:
1395         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color1);
1396         break;
1397      case 2:
1398         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
1399         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
1400         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
1401         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
1402         break;
1403      default:
1404         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
1405         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
1406         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
1407         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
1408         break;
1409      }
1410      break;
1411   case A4R4G4B4:
1412      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1413      a4r4g4b4 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1414      return convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
1415   case A1R5G5B5:
1416      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1417      a1r5g5b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1418      return convert_a1r5g5b5_a8r8g8b8(a1r5g5b5);
1419   case R5G6B5:
1420      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1421      r5g6b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1422      return 0xff000000 + convert_r5g6b5_r8g8b8(r5g6b5);
1423   case R8G8B8_RECT:
1424      to = texture[number].rectangle_pitch*y + (x << 2);
1425      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
1426   case A8R8G8B8_RECT:
1427      to = texture[number].rectangle_pitch*y + (x << 2);
1428      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
1429   case DXT5:
1430      bx = x >> 2;
1431      by = y >> 2;
1432      x = x & 3;
1433      y = y & 3;
1434      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
1435      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
1436      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
1437      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
1438      alpha0 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 0);
1439      alpha1 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1440      alphas = *(((UINT64 *)texture[number].buffer) + to);
1441      s = (y << 3) + (x << 1);
1442      sa = ((y << 2) + x) * 3;
1443      c = (codes >> s) & 3;
1444      ca = (alphas >> sa) & 7;
1445      ca = ca + (alpha0 > alpha1 ? 0 : 8);
1446      switch (ca) {
1447      case 0:
1448         ca = alpha0;
1449         break;
1450      case 1:
1451         ca = alpha1;
1452         break;
1453      case 2:
1454         ca = (6 * alpha0 + 1 * alpha1) / 7;
1455         break;
1456      case 3:
1457         ca = (5 * alpha0 + 2 * alpha1) / 7;
1458         break;
1459      case 4:
1460         ca = (4 * alpha0 + 3 * alpha1) / 7;
1461         break;
1462      case 5:
1463         ca = (3 * alpha0 + 4 * alpha1) / 7;
1464         break;
1465      case 6:
1466         ca = (2 * alpha0 + 5 * alpha1) / 7;
1467         break;
1468      case 7:
1469         ca = (1 * alpha0 + 6 * alpha1) / 7;
1470         break;
1471      case 8:
1472         ca = alpha0;
1473         break;
1474      case 9:
1475         ca = alpha1;
1476         break;
1477      case 10:
1478         ca = (4 * alpha0 + 1 * alpha1) / 5;
1479         break;
1480      case 11:
1481         ca = (3 * alpha0 + 2 * alpha1) / 5;
1482         break;
1483      case 12:
1484         ca = (2 * alpha0 + 3 * alpha1) / 5;
1485         break;
1486      case 13:
1487         ca = (1 * alpha0 + 4 * alpha1) / 5;
1488         break;
1489      case 14:
1490         ca = 0;
1491         break;
1492      case 15:
1493         ca = 255;
1494         break;
1495      }
1496      switch (c) {
1497      case 0:
1498         return (ca << 24) + convert_r5g6b5_r8g8b8(color0);
1499         break;
1500      case 1:
1501         return (ca << 24) + convert_r5g6b5_r8g8b8(color1);
1502         break;
1503      case 2:
1504         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
1505         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
1506         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
1507         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
1508         break;
1509      default:
1510         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
1511         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
1512         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
1513         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
1514         break;
1515      }
1516   default:
1517      return 0xff00ff00;
13711518   }
13721519}
13731520
r29516r29517
16161763   maddress=method*4;
16171764   data=space.read_dword(address);
16181765   channel[chanel][subchannel].object.method[method]=data;
1766   if (maddress == 0x17fc) {
1767      indexesleft_count = 0;
1768      primitives_count = 0;
1769      countlen--;
1770   }
16191771   if (maddress == 0x1810) {
16201772      // draw vertices
16211773      int offset,count,type;
r29516r29517
16291781      offset=data & 0xffffff;
16301782      count=(data >> 24) & 0xff;
16311783      type=channel[chanel][subchannel].object.method[0x17fc/4];
1632      tmp=channel[chanel][subchannel].object.method[0x1720/4];
16331784      dmahand[0]=channel[chanel][subchannel].object.method[0x019c/4];
16341785      dmahand[1]=channel[chanel][subchannel].object.method[0x01a0/4];
16351786      geforce_read_dma_object(dmahand[0],dmaoff[0],smasiz[0]);
r29516r29517
16741825               *((UINT32 *)(&xy[m].y))=space.read_dword(vtxbuf_address[0]+(n+m+offset)*vtxbuf_stride[0]+4);
16751826               *((UINT32 *)(&z[m]))=space.read_dword(vtxbuf_address[0]+(n+m+offset)*vtxbuf_stride[0]+8);
16761827               *((UINT32 *)(&w[m]))=space.read_dword(vtxbuf_address[0]+(n+m+offset)*vtxbuf_stride[0]+12);
1677               c[m]=space.read_dword(vtxbuf_address[3]+(n+m+offset)*vtxbuf_stride[0]+0); // color
1828               c[m]=space.read_dword(vtxbuf_address[3]+(n+m+offset)*vtxbuf_stride[3]+0); // color
16781829               xy[m].p[0]=c[m] & 0xff; // b
16791830               xy[m].p[1]=(c[m] & 0xff00) >> 8; // g
16801831               xy[m].p[2]=(c[m] & 0xff0000) >> 16; // r
r29516r29517
17111862            *((UINT32 *)(&xy[m].y))=space.read_dword(vtxbuf_address[0]+(m+offset)*vtxbuf_stride[0]+4);
17121863            *((UINT32 *)(&z[m]))=space.read_dword(vtxbuf_address[0]+(m+offset)*vtxbuf_stride[0]+8);
17131864            *((UINT32 *)(&w[m]))=space.read_dword(vtxbuf_address[0]+(m+offset)*vtxbuf_stride[0]+12);
1714            c[m]=space.read_dword(vtxbuf_address[3]+(m+offset)*vtxbuf_stride[0]+0); // color
1865            c[m]=space.read_dword(vtxbuf_address[3]+(m+offset)*vtxbuf_stride[3]+0); // color
17151866            xy[m].p[0]=c[m] & 0xff; // b
17161867            xy[m].p[1]=(c[m] & 0xff00) >> 8;  // g
17171868            xy[m].p[2]=(c[m] & 0xff0000) >> 16;  // r
r29516r29517
17311882            *((UINT32 *)(&xy[2].y))=space.read_dword(vtxbuf_address[0]+(n+offset)*vtxbuf_stride[0]+4);
17321883            *((UINT32 *)(&z[2]))=space.read_dword(vtxbuf_address[0]+(n+offset)*vtxbuf_stride[0]+8);
17331884            *((UINT32 *)(&w[2]))=space.read_dword(vtxbuf_address[0]+(n+offset)*vtxbuf_stride[0]+12);
1734            c[2]=space.read_dword(vtxbuf_address[3]+(n+offset)*vtxbuf_stride[0]+0); // color
1885            c[2]=space.read_dword(vtxbuf_address[3]+(n+offset)*vtxbuf_stride[3]+0); // color
17351886            xy[2].p[0]=c[2] & 0xff; // b
17361887            xy[2].p[1]=(c[2] & 0xff00) >> 8; // g
17371888            xy[2].p[2]=(c[2] & 0xff0000) >> 16; // r
r29516r29517
17601911      }
17611912      countlen--;
17621913   }
1914   if (maddress == 0x1800) {
1915      int vtxbuf_stride[16];
1916      UINT32 vtxbuf_address[16];
1917      UINT32 dmahand[2], dmaoff[2], smasiz[2];
1918      UINT32 type, tmp, n, m, u;
1919      render_delegate renderspans;
1920
1921      // vertices are selected from the vertex buffer using an array of indexes
1922      // each dword after 1800 contains two 16 bit index values to select the vartices
1923      type = channel[chanel][subchannel].object.method[0x17fc / 4];
1924      dmahand[0] = channel[chanel][subchannel].object.method[0x019c / 4];
1925      dmahand[1] = channel[chanel][subchannel].object.method[0x01a0 / 4];
1926      geforce_read_dma_object(dmahand[0], dmaoff[0], smasiz[0]);
1927      geforce_read_dma_object(dmahand[1], dmaoff[1], smasiz[1]);
1928      if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
1929         renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
1930      }
1931      else if (texture[0].enabled) {
1932         renderspans = render_delegate(FUNC(nv2a_renderer::render_texture_simple), this);
1933      }
1934      else
1935         renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
1936#ifdef LOG_NV2A
1937      printf("vertex %d %d %d\n\r", type, offset, count);
1938#endif
1939      for (n = 0; n < 16; n++) {
1940#ifdef LOG_NV2A
1941         printf(" %08X %08X\n\r", channel[chanel][subchannel].object.method[0x1720 / 4 + n], channel[chanel][subchannel].object.method[0x1760 / 4 + n]);
1942#endif
1943         tmp = channel[chanel][subchannel].object.method[0x1760 / 4 + n]; // VTXBUF_FMT
1944         //vtxbuf_kind[n]=tmp & 15;
1945         //vtxbuf_size[n]=(tmp >> 4) & 15;
1946         vtxbuf_stride[n] = (tmp >> 8) & 255;
1947         tmp = channel[chanel][subchannel].object.method[0x1720 / 4 + n]; // VTXBUF_OFFSET
1948         if (tmp & 0x80000000)
1949            vtxbuf_address[n] = (tmp & 0x0fffffff) + dmaoff[1];
1950         else
1951            vtxbuf_address[n] = (tmp & 0x0fffffff) + dmaoff[0];
1952      }
1953      if (type == nv2a_renderer::QUADS) {
1954         while (1) {
1955            vertex_t xy[4];
1956            float z[4], w[4];
1957            UINT32 c[4];
1958
1959            // need 4 per object
1960            // get remaining
1961            while ((indexesleft_count < 4) && (countlen > 0)) {
1962               indexesleft[indexesleft_count] = data & 0xffff;
1963               indexesleft[indexesleft_count+ 1] = (data >> 16) & 0xffff;
1964               indexesleft_count+=2;
1965               countlen--;
1966               address = address + 4;
1967               data = space.read_dword(address);
1968            }
1969            if ((indexesleft_count < 4) && (countlen == 0))
1970               break;
1971            //printf("draw quad\n\r");
1972            for (m = 0; m < 4; m++) {
1973               *((UINT32 *)(&xy[m].x)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 0);
1974               *((UINT32 *)(&xy[m].y)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 4);
1975               *((UINT32 *)(&z[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 8);
1976               *((UINT32 *)(&w[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 12);
1977               c[m] = space.read_dword(vtxbuf_address[3] + indexesleft[m] * vtxbuf_stride[3] + 0); // color
1978               xy[m].p[0] = c[m] & 0xff; // b
1979               xy[m].p[1] = (c[m] & 0xff00) >> 8; // g
1980               xy[m].p[2] = (c[m] & 0xff0000) >> 16; // r
1981               xy[m].p[3] = (c[m] & 0xff000000) >> 24; // a
1982               for (u = 0; u < 4; u++) {
1983                  xy[m].p[4 + u * 2] = 0;
1984                  xy[m].p[5 + u * 2] = 0;
1985                  if (texture[u].enabled) {
1986                     *((UINT32 *)(&xy[m].p[4 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 0);
1987                     *((UINT32 *)(&xy[m].p[5 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 4);
1988                  }
1989               }
1990            }
1991
1992            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
1993            /*myline(fb,xy[0].x,xy[0].y,xy[1].x,xy[1].y);
1994            myline(fb,xy[1].x,xy[1].y,xy[2].x,xy[2].y);
1995            myline(fb,xy[2].x,xy[2].y,xy[3].x,xy[3].y);
1996            myline(fb,xy[3].x,xy[3].y,xy[0].x,xy[0].y);*/
1997#ifdef LOG_NV2A
1998            printf(" (%f,%f,%f)-(%f,%f,%f)-(%f,%f,%f)-(%f,%f,%f)\n\r", xy[0].x, xy[0].y, z[0], xy[1].x, xy[1].y, z[1], xy[2].x, xy[2].y, z[2], xy[3].x, xy[3].y, z[3]);
1999#endif
2000            for (m = 4; m < indexesleft_count; m++)
2001               indexesleft[m - 4] = indexesleft[m];
2002            indexesleft_count = indexesleft_count - 4;
2003         }
2004         wait();
2005      }
2006      else if (type == nv2a_renderer::TRIANGLES) {
2007         while (1) {
2008            vertex_t xy[4];
2009            float z[4], w[4];
2010            UINT32 c[4];
2011
2012            // need 3 dwords per object
2013            // get remaining
2014            while ((indexesleft_count < 3) && (countlen > 0)) {
2015               indexesleft[indexesleft_count] = data & 0xffff;
2016               indexesleft[indexesleft_count + 1] = (data >> 16) & 0xffff;
2017               indexesleft_count += 2;
2018               countlen--;
2019               address = address + 4;
2020               data = space.read_dword(address);
2021            }
2022            if ((indexesleft_count < 3) && (countlen == 0))
2023               break;
2024            //printf("draw triangle\n\r");
2025            for (m = 0; m < 3; m++) {
2026               *((UINT32 *)(&xy[m].x)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 0);
2027               *((UINT32 *)(&xy[m].y)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 4);
2028               *((UINT32 *)(&z[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 8);
2029               *((UINT32 *)(&w[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 12);
2030               c[m] = space.read_dword(vtxbuf_address[3] + indexesleft[m] * vtxbuf_stride[3] + 0); // color
2031               xy[m].p[0] = c[m] & 0xff; // b
2032               xy[m].p[1] = (c[m] & 0xff00) >> 8; // g
2033               xy[m].p[2] = (c[m] & 0xff0000) >> 16; // r
2034               xy[m].p[3] = (c[m] & 0xff000000) >> 24; // a
2035               for (u = 0; u < 4; u++) {
2036                  xy[m].p[4 + u * 2] = 0;
2037                  xy[m].p[5 + u * 2] = 0;
2038                  if (texture[u].enabled) {
2039                     *((UINT32 *)(&xy[m].p[4 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 0);
2040                     *((UINT32 *)(&xy[m].p[5 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 4);
2041                  }
2042               }
2043            }
2044
2045            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
2046            /*myline(fb,xy[0].x,xy[0].y,xy[1].x,xy[1].y);
2047            myline(fb,xy[1].x,xy[1].y,xy[2].x,xy[2].y);
2048            myline(fb,xy[2].x,xy[2].y,xy[3].x,xy[3].y);*/
2049#ifdef LOG_NV2A
2050            printf(" (%f,%f,%f)-(%f,%f,%f)-(%f,%f,%f)\n\r", xy[0].x, xy[0].y, z[0], xy[1].x, xy[1].y, z[1], xy[2].x, xy[2].y, z[2]);
2051#endif
2052            for (m = 3; m < indexesleft_count; m++)
2053               indexesleft[m - 3] = indexesleft[m];
2054            indexesleft_count = indexesleft_count - 3;
2055         }
2056         wait();
2057      }
2058      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2059         while (1) {
2060            vertex_t xy[4];
2061            float z[4], w[4];
2062            UINT32 c[4];
2063
2064            // need 3 dwords per object
2065            // get remaining
2066            while ((indexesleft_count < 3) && (countlen > 0)) {
2067               indexesleft[indexesleft_count] = data & 0xffff;
2068               indexesleft[indexesleft_count + 1] = (data >> 16) & 0xffff;
2069               indexesleft_count += 2;
2070               countlen--;
2071               address = address + 4;
2072               data = space.read_dword(address);
2073            }
2074            if ((indexesleft_count < 3) && (countlen == 0))
2075               break;
2076            //printf("draw triangle\n\r");
2077            for (m = 0; m < 3; m++) {
2078               *((UINT32 *)(&xy[m].x)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 0);
2079               *((UINT32 *)(&xy[m].y)) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 4);
2080               *((UINT32 *)(&z[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 8);
2081               *((UINT32 *)(&w[m])) = space.read_dword(vtxbuf_address[0] + indexesleft[m] * vtxbuf_stride[0] + 12);
2082               c[m] = space.read_dword(vtxbuf_address[3] + indexesleft[m] * vtxbuf_stride[3] + 0); // color
2083               xy[m].p[0] = c[m] & 0xff; // b
2084               xy[m].p[1] = (c[m] & 0xff00) >> 8; // g
2085               xy[m].p[2] = (c[m] & 0xff0000) >> 16; // r
2086               xy[m].p[3] = (c[m] & 0xff000000) >> 24; // a
2087               for (u = 0; u < 4; u++) {
2088                  xy[m].p[4 + u * 2] = 0;
2089                  xy[m].p[5 + u * 2] = 0;
2090                  if (texture[u].enabled) {
2091                     *((UINT32 *)(&xy[m].p[4 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 0);
2092                     *((UINT32 *)(&xy[m].p[5 + u * 2])) = space.read_dword(vtxbuf_address[9 + u] + indexesleft[m] * vtxbuf_stride[9 + u] + 4);
2093                  }
2094               }
2095            }
2096
2097            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[primitives_count & 1], xy[~primitives_count & 1], xy[2]); // 012,102,012,102...
2098            /*myline(fb,xy[0].x,xy[0].y,xy[1].x,xy[1].y);
2099            myline(fb,xy[1].x,xy[1].y,xy[2].x,xy[2].y);
2100            myline(fb,xy[2].x,xy[2].y,xy[3].x,xy[3].y);*/
2101#ifdef LOG_NV2A
2102            printf(" (%f,%f,%f)-(%f,%f,%f)-(%f,%f,%f)\n\r", xy[0].x, xy[0].y, z[0], xy[1].x, xy[1].y, z[1], xy[2].x, xy[2].y, z[2]);
2103#endif
2104            primitives_count++;
2105            for (m = 1; m < indexesleft_count; m++)
2106               indexesleft[m - 1] = indexesleft[m];
2107            indexesleft_count = indexesleft_count - 1;
2108         }
2109         wait();
2110      }
2111      else {
2112         logerror("Unsupported primitive %d for method 0x1800\n", type);
2113         countlen = 0;
2114      }
2115   }
17632116   if (maddress == 0x1818) {
17642117      int n,m,u,vwords;
17652118      int vattrpos[16];
r29516r29517
19002253         }
19012254         for (n=2;countlen > 0;n++) {
19022255            // put vertex n data in element 2 of arrays
1903            // put vertex n data in element 2 of arrays
19042256            // position
19052257            *((UINT32 *)(&xy[2].x))=space.read_dword(address+vattrpos[0]*4+0);
19062258            *((UINT32 *)(&xy[2].y))=space.read_dword(address+vattrpos[0]*4+4);
r29516r29517
20552407         wait();
20562408      } else {
20572409         logerror("Unsupported primitive %d for method 0x1818\n",type);
2410         countlen = 0;
20582411      }
20592412   }
2413   if ((maddress >= 0x1760) && (maddress < 0x17A0)) {
2414      int bit=method-0x1760/4;
2415
2416      data=data & 255;
2417      if (data > 15)
2418         enabled_vertex_attributes |= (1 << bit);
2419      else
2420         enabled_vertex_attributes &= ~(1 << bit);
2421      switch (data & 15) {
2422         case 0:
2423            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
2424            break;
2425         case nv2a_renderer::FLOAT:
2426            words_vertex_attributes[bit]=(data >> 4);
2427            break;
2428         case nv2a_renderer::UBYTE:
2429            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
2430            break;
2431         case nv2a_renderer::USHORT:
2432            words_vertex_attributes[bit]=(((data >> 4) + 1) & 15) >> 1;
2433            break;
2434         default:
2435            words_vertex_attributes[bit]=0;
2436      }
2437      countlen--;
2438   }
20602439   if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
20612440      countlen--;
20622441   if (maddress == 0x1d70) {
r29516r29517
21242503         texture[unit].sizew=1 << basesizew;
21252504         texture[unit].dilate=dilatechose[(basesizeu << 4)+basesizev];
21262505         texture[unit].format=format;
2506         if (debug_grab_texttype == format) {
2507            FILE *f;
2508            int written;
2509
2510            debug_grab_texttype = -1;
2511            f = fopen(debug_grab_textfile, "wb");
2512            if (f) {
2513               written=(int)fwrite(texture[unit].buffer, texture[unit].sizeu*texture[unit].sizev*4, 1, f);
2514               fclose(f);
2515               logerror("Written %d bytes of texture to specified file\n", written);
2516            } else
2517               logerror("Unable to save texture to specified file\n");
2518         }
21272519      }
21282520      if (maddress == 0x1b0c) {
21292521         // enable texture
r29516r29517
21372529      }
21382530      countlen--;
21392531   }
2140   if ((maddress >= 0x1760) && (maddress < 0x17A0)) {
2141      int bit=method-0x1760/4;
2142
2143      data=data & 255;
2144      if (data > 15)
2145         enabled_vertex_attributes |= (1 << bit);
2532   // modelview matrix
2533   if ((maddress >= 0x0480) && (maddress < 0x04c0)) {
2534      maddress = (maddress - 0x0480) / 4;
2535      *(UINT32 *)(&matrix.modelview[maddress]) = data;
2536      countlen--;
2537   }
2538   // inverse modelview matrix
2539   if ((maddress >= 0x0580) && (maddress < 0x05c0)) {
2540      maddress = (maddress - 0x0580) / 4;
2541      *(UINT32 *)(&matrix.modelview_inverse[maddress]) = data;
2542      countlen--;
2543   }
2544   // projection matrix
2545   if ((maddress >= 0x0680) && (maddress < 0x06c0)) {
2546      maddress = (maddress - 0x0680) / 4;
2547      *(UINT32 *)(&matrix.projection[maddress]) = data;
2548      countlen--;
2549   }
2550   // viewport translate
2551   if ((maddress >= 0x0a20) && (maddress < 0x0a30)) {
2552      maddress = (maddress - 0x0a20) / 4;
2553      *(UINT32 *)(&matrix.translate[maddress]) = data;
2554      countlen--;
2555   }
2556   // viewport scale
2557   if ((maddress >= 0x0af0) && (maddress < 0x0b00)) {
2558      maddress = (maddress - 0x0af0) / 4;
2559      *(UINT32 *)(&matrix.scale[maddress]) = data;
2560      countlen--;
2561   }
2562   // Vertex program (shader)
2563   if (maddress == 0x1e94) {
2564      /*if (data == 2)
2565         logerror("Enabled vertex program\n");
2566      else if (data == 4)
2567         logerror("Enabled fixed function pipeline\n");
2568      else if (data == 6)
2569         logerror("Enabled both fixed function pipeline and vertex program ?\n");
21462570      else
2147         enabled_vertex_attributes &= ~(1 << bit);
2148      switch (data & 15) {
2149         case 0:
2150            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
2151            break;
2152         case nv2a_renderer::FLOAT:
2153            words_vertex_attributes[bit]=(data >> 4);
2154            break;
2155         case nv2a_renderer::UBYTE:
2156            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
2157            break;
2158         case nv2a_renderer::USHORT:
2159            words_vertex_attributes[bit]=(((data >> 4) + 1) & 15) >> 1;
2160            break;
2161         default:
2162            words_vertex_attributes[bit]=0;
2163      }
2571         logerror("Unknown value %d to method 0x1e94\n",data);*/
2572      countlen--;
21642573   }
2574   if (maddress == 0x1e9c) {
2575      //logerror("VP_UPLOAD_FROM_ID %d\n",data);
2576      vertexprogram.upload_instruction=data*4;
2577      countlen--;
2578   }
2579   if (maddress == 0x1ea0) {
2580      //logerror("VP_START_FROM_ID %d\n",data);
2581      vertexprogram.instructions=vertexprogram.upload_instruction/4;
2582      countlen--;
2583   }
2584   if (maddress == 0x1ea4) {
2585      //logerror("VP_UPLOAD_CONST_ID %d\n",data);
2586      vertexprogram.upload_parameter=data;
2587      countlen--;
2588   }
2589   if ((maddress >= 0x0b00) && (maddress < 0x0b80)) {
2590      //logerror("VP_UPLOAD_INST\n");
2591      if (vertexprogram.upload_instruction < 1024)
2592         vertexprogram.instruction[vertexprogram.upload_instruction]=data;
2593      else
2594         logerror("Need to increase size of vertexprogram.instruction to %d\n\r", vertexprogram.upload_parameter);
2595      vertexprogram.upload_instruction++;
2596   }
2597   if ((maddress >= 0x0b80) && (maddress < 0x0c00)) {
2598      //logerror("VP_UPLOAD_CONST\n");
2599      if (vertexprogram.upload_parameter < 1024)
2600         vertexprogram.parameter[vertexprogram.upload_parameter] = data;
2601      else
2602         logerror("Need to increase size of vertexprogram.parameter to %d\n\r", vertexprogram.upload_parameter);
2603      vertexprogram.upload_parameter++;
2604   }
2605   // Register combiners
21652606   if (maddress == 0x1e60) {
21662607      combiner.stages=data & 15;
21672608      countlen--;
r29516r29517
22902731   return combiner.used;
22912732}
22922733
2734void nv2a_renderer::debug_grab_texture(int type, const char *filename)
2735{
2736   debug_grab_texttype = type;
2737   if (debug_grab_textfile == NULL)
2738      debug_grab_textfile = (char *)malloc(128);
2739   strncpy(debug_grab_textfile, filename, 127);
2740}
2741
22932742void nv2a_renderer::savestate_items()
22942743{
22952744}
r29516r29517
30083457   }
30093458}
30103459
3460void chihiro_state::debug_grab_texture(int type, char *filename)
3461{
3462   nvidia_nv2a->debug_grab_texture(type, filename);
3463}
3464
30113465void chihiro_state::vblank_callback(screen_device &screen, bool state)
30123466{
30133467   nvidia_nv2a->vblank_callback(screen,state);
r29516r29517
33383792READ32_MEMBER( chihiro_state::audio_apu_r )
33393793{
33403794   logerror("Audio_APU: read from %08X mask %08X\n",0xfe800000+offset*4,mem_mask);
3341   if (offset == 0x20010/4)
3795   if (offset == 0x20010/4) // some kind of internal counter or state value
33423796      return 0x20+4+8+0x48+0x80;
3343   return 0;
3797   return apust.memory[offset];
33443798}
33453799
33463800WRITE32_MEMBER( chihiro_state::audio_apu_w )
33473801{
3802   //UINT32 old;
3803   UINT32 v;
3804
33483805   logerror("Audio_APU: write at %08X mask %08X value %08X\n",0xfe800000+offset*4,mem_mask,data);
3349   if (offset == 0x2040/4)
3350      apust.memory0_sgaddress=data;
3351   if (offset == 0x20d4/4) {
3352      apust.memory0_sgblocks=data;
3353      apust.memory0_address=apust.space->read_dword(apust.memory0_sgaddress);
3806   //old = apust.memory[offset];
3807   apust.memory[offset] = data;
3808   if (offset == 0x02040/4) // address of memory area with scatter-gather info (gpdsp scratch dma)
3809      apust.gpdsp_sgaddress=data;
3810   if (offset == 0x020d4/4) { // block count (gpdsp)
3811      apust.gpdsp_sgblocks=data;
3812      apust.gpdsp_address=apust.space->read_dword(apust.gpdsp_sgaddress); // memory address of first block
33543813      apust.timer->enable();
33553814      apust.timer->adjust(attotime::from_msec(1),0,attotime::from_msec(1));
33563815   }
3357   if (offset == 0x2048/4)
3358      apust.memory1_sgaddress=data;
3359   if (offset == 0x20dc/4)
3360      apust.memory1_sgblocks=data;
3816   if (offset == 0x02048 / 4) // (epdsp scratch dma)
3817      apust.epdsp_sgaddress=data;
3818   if (offset == 0x020dc / 4) // (epdsp)
3819      apust.epdsp_sgblocks=data;
3820   if (offset == 0x0204c / 4) // address of memory area with information about blocks
3821      apust.unknown_sgaddress = data;
3822   if (offset == 0x020e0 / 4) // block count - 1
3823      apust.unknown_sgblocks = data;
3824   if (offset == 0x0202c / 4) { // address of memory area with 0x80 bytes for each voice
3825      apust.voicedata_address = data;
3826      return;
3827   }
3828   if (offset == 0x04024 / 4) // offset in memory area indicated by 0x204c (analog output ?)
3829      return;
3830   if (offset == 0x04034 / 4) // size
3831      return;
3832   if (offset == 0x04028 / 4) // offset in memory area indicated by 0x204c (digital output ?)
3833      return;
3834   if (offset == 0x04038 / 4) // size
3835      return;
3836   if (offset == 0x20804 / 4) { // block number for scatter-gather heap that stores sampled audio to be played
3837      if (data >= 1024) {
3838         logerror("Audio_APU: sg block number too high, increase size of voices_heap_blockaddr\n");
3839         apust.memory[offset] = 1023;
3840      }
3841      return;
3842   }
3843   if (offset == 0x20808 / 4) { // block address for scatter-gather heap that stores sampled audio to be played
3844      apust.voices_heap_blockaddr[apust.memory[0x20804 / 4]] = data;
3845      return;
3846   }
3847   if (offset == 0x202f8 / 4) { // voice number for parameters ?
3848      apust.voice_number = data;
3849      return;
3850   }
3851   if (offset == 0x202fc / 4) // 1 when accessing voice parameters 0 otherwise
3852      return;
3853   if (offset == 0x20304 / 4) { // format
3854      /*
3855        bits 28-31 sample format:
3856         0  8-bit pcm
3857         5  16-bit pcm
3858         10 adpcm ?
3859         14 24-bit pcm
3860         15 32-bit pcm
3861        bits 16-20 number of channels - 1:
3862         0  mono
3863         1  stereo
3864      */
3865      return;
3866   }
3867   if (offset == 0x2037c / 4) { // value related to sample rate
3868      INT16 v = (INT16)(data >> 16); // upper 16 bits as a signed 16 bit value
3869      float vv = ((float)v) / 4096.0; // divide by 4096
3870      float vvv = powf(2, vv); // two to the vv
3871      int f = vvv*48000.0; // sample rate
3872      apust.voices_frequency[apust.voice_number] = f;
3873      return;
3874   }
3875   if (offset == 0x203a0 / 4) // start offset of data in scatter-gather heap
3876      return;
3877   if (offset == 0x203a4 / 4) { // first sample to play
3878      apust.voices_position_start[apust.voice_number] = data*1000;
3879      return;
3880   }
3881   if (offset == 0x203dc / 4) { // last sample to play
3882      apust.voices_position_end[apust.voice_number] = data*1000;
3883      return;
3884   }
3885   if (offset == 0x2010c / 4) // voice processor 0 idle 1 not idle ?
3886      return;
3887   if (offset == 0x20124 / 4) { // voice number to activate ?
3888      v = apust.voice_number;
3889      apust.voices_active[v >> 6] |= ((UINT64)1 << (v & 63));
3890      apust.voices_position[v] = apust.voices_position_start[apust.voice_number];
3891      apust.voices_position_increment[apust.voice_number] = apust.voices_frequency[apust.voice_number];
3892      return;
3893   }
3894   if (offset == 0x20128 / 4) { // voice number to deactivate ?
3895      v = apust.voice_number;
3896      apust.voices_active[v >> 6] &= ~(1 << (v & 63));
3897      return;
3898   }
3899   if (offset == 0x20140 / 4) // voice number to ?
3900      return;
3901   if ((offset >= 0x20200 / 4) && (offset < 0x20280 / 4)) // headroom for each of the 32 mixbins
3902      return;
3903   if (offset == 0x20280 / 4) // hrtf headroom ?
3904      return;
33613905}
33623906
33633907READ32_MEMBER( chihiro_state::audio_ac93_r )
r29516r29517
34053949
34063950TIMER_CALLBACK_MEMBER(chihiro_state::audio_apu_timer)
34073951{
3408   int cmd=apust.space->read_dword(apust.memory0_address+0x800+0x10);
3952   int cmd;
3953   int bb, b, v;
3954   UINT64 bv;
3955   UINT32 phys;
3956
3957   cmd=apust.space->read_dword(apust.gpdsp_address+0x800+0x10);
34093958   if (cmd == 3)
3410      apust.space->write_dword(apust.memory0_address+0x800+0x10,0);
3959      apust.space->write_dword(apust.gpdsp_address+0x800+0x10,0);
34113960   /*else
3412       logerror("Audio_APU: unexpected value at address %d\n",apust.memory0_address+0x800+0x10);*/
3961       logerror("Audio_APU: unexpected value at address %d\n",apust.gpdsp_address+0x800+0x10);*/
3962   for (b = 0; b < 4; b++) {
3963      bv = 1;
3964      for (bb = 0; bb < 64; bb++) {
3965         if (apust.voices_active[b] & bv) {
3966            v = bb + (b << 6);
3967            apust.voices_position[v] += apust.voices_position_increment[v];
3968            while (apust.voices_position[v] >= apust.voices_position_end[v])
3969               apust.voices_position[v] = apust.voices_position_start[v] + apust.voices_position[v] - apust.voices_position_end[v] - 1000;
3970            phys = apust.voicedata_address + 0x80 * v;
3971            apust.space->write_dword(phys + 0x58, apust.voices_position[v] / 1000);
3972         }
3973         bv = bv << 1;
3974      }
3975   }
34133976}
34143977
34153978/*
r29516r29517
39024465   if (chihiro_devs.dimmboard != NULL) {
39034466      dimm_board_memory=chihiro_devs.dimmboard->memory(dimm_board_memory_size);
39044467   }
3905   apust.space=&m_maincpu->space();
4468   memset(apust.memory, 0, sizeof(apust.memory));
4469   memset(apust.voices_heap_blockaddr, 0, sizeof(apust.voices_heap_blockaddr));
4470   memset(apust.voices_active, 0, sizeof(apust.voices_active));
4471   memset(apust.voices_position, 0, sizeof(apust.voices_position));
4472   memset(apust.voices_position_start, 0, sizeof(apust.voices_position_start));
4473   memset(apust.voices_position_end, 0, sizeof(apust.voices_position_end));
4474   memset(apust.voices_position_increment, 0, sizeof(apust.voices_position_increment));
4475   apust.space = &m_maincpu->space();
39064476   apust.timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(chihiro_state::audio_apu_timer),this),(void *)"APU Timer");
39074477   apust.timer->enable(false);
39084478   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
trunk/src/emu/cpu/i386/x87ops.inc
r29516r29517
19761976      floatx80 a = ST(0);
19771977      floatx80 b = ST(1);
19781978
1979      m_x87_sw &= ~X87_SW_C0;
1979      m_x87_sw &= ~X87_SW_C2;
19801980
19811981      // TODO: Implement Cx bits
19821982      result = floatx80_rem(a, b);
r29516r29517
20022002      floatx80 a = ST(0);
20032003      floatx80 b = ST(1);
20042004
2005      m_x87_sw &= ~X87_SW_C0;
2005      m_x87_sw &= ~X87_SW_C2;
20062006
20072007      // TODO: Implement Cx bits
20082008      result = floatx80_rem(a, b);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team