Previous 199869 Revisions Next

r23892 Sunday 23rd June, 2013 at 22:08:50 UTC by Carl
chihiro: few updates to the i386 processor and chihiro driver. [Samuele Zannoli]
- adds lots of mmx and sse opcodes to the i386 processor
- adds the fcomip x87 opcode
- adds a "UINT8 *memory(UINT32 &size)" method to the naomi_gdrom_board device that returns the size and a pointer to the decrypted gdrom data (used by chihiro)
Then for the chihiro driver:
- adds basic stuff for the Nvidia audio APU
- adds the "chihiro curthread" debugger command, shows information about the current active thread
- adds the "chihiro irq,<number>" debugger command, to generate an interrupt with irq number 0-15 by hand
- adds more patches to let the software run even if usb is not implemented
- adds the Chihiro Type 1 baseboard/mediaboard features to let the system load the gdrom games
- adds incomplete save state support
- adds support to the Nvidia 3d accelerator to draw primitives where the vertex data is not stored in a vertex buffer but contained in the command stream

i386: don't take an smi until current instruction is complete (nw)
[src/emu/cpu/i386]i386.c i386ops.h i386priv.h pentops.c x87ops.c
[src/mame/drivers]chihiro.c
[src/mame/machine]naomigd.h

trunk/src/mame/drivers/chihiro.c
r23891r23892
377377#define LOG_PCI
378378//#define LOG_OHCI
379379//#define LOG_NV2A
380#define LOG_BASEBOARD
380381
381382class nv2a_renderer; // forw. dec.
382383struct nvidia_object_data
r23891r23892
387388class chihiro_state : public driver_device
388389{
389390public:
390   chihiro_state(const machine_config &mconfig, device_type type, const char *tag)
391      : driver_device(mconfig, type, tag),
392      m_maincpu(*this, "maincpu") { }
391   chihiro_state(const machine_config &mconfig, device_type type, const char *tag)   :
392     driver_device(mconfig, type, tag),
393     nvidia_nv2a(NULL),
394     debug_irq_active(false),
395     m_maincpu(*this, "maincpu") { }
393396
394397   DECLARE_READ32_MEMBER( geforce_r );
395398   DECLARE_WRITE32_MEMBER( geforce_w );
r23891r23892
397400   DECLARE_WRITE32_MEMBER( usbctrl_w );
398401   DECLARE_READ32_MEMBER( smbus_r );
399402   DECLARE_WRITE32_MEMBER( smbus_w );
403   DECLARE_READ32_MEMBER( mediaboard_r );
404   DECLARE_WRITE32_MEMBER( mediaboard_w );
405   DECLARE_READ32_MEMBER( audio_apu_r );
406   DECLARE_WRITE32_MEMBER( audio_apu_w );
407   DECLARE_READ32_MEMBER( audio_ac93_r );
408   DECLARE_WRITE32_MEMBER( audio_ac93_w );
400409   DECLARE_READ32_MEMBER( dummy_r );
401410   DECLARE_WRITE32_MEMBER( dummy_w );
402411
r23891r23892
404413   int smbus_pic16lc(int command,int rw,int data);
405414   int smbus_cx25871(int command,int rw,int data);
406415   int smbus_eeprom(int command,int rw,int data);
416   void baseboard_ide_event(int type,UINT8 *read,UINT8 *write);
417   UINT8 *baseboard_ide_dimmboard(UINT32 lba);
418   void dword_write_le(UINT8 *addr,UINT32 d);
419   void word_write_le(UINT8 *addr,UINT16 d);
420   void debug_generate_irq(int irq,bool active);
407421
408422   void vblank_callback(screen_device &screen, bool state);
409423   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
410424
411   struct chihiro_devices {
412      pic8259_device    *pic8259_1;
413      pic8259_device    *pic8259_2;
414      bus_master_ide_controller_device *ide;
415   } chihiro_devs;
416
417   nv2a_renderer *nvidia_nv2a;
418425   virtual void machine_start();
419426   DECLARE_WRITE_LINE_MEMBER(chihiro_pic8259_1_set_int_line);
420427   DECLARE_READ8_MEMBER(get_slave_ack);
421428   DECLARE_WRITE_LINE_MEMBER(chihiro_pit8254_out0_changed);
422429   DECLARE_WRITE_LINE_MEMBER(chihiro_pit8254_out2_changed);
423430   IRQ_CALLBACK_MEMBER(irq_callback);
431   TIMER_CALLBACK_MEMBER(audio_apu_timer);
432
433   struct chihiro_devices {
434      pic8259_device    *pic8259_1;
435      pic8259_device    *pic8259_2;
436      bus_master_ide_controller_device    *ide;
437      naomi_gdrom_board *dimmboard;
438   } chihiro_devs;   
439   struct smbus_state {
440      int status;
441      int control;
442      int address;
443      int data;
444      int command;
445      int rw;
446      int (*devices[128])(chihiro_state &chs,int command,int rw,int data);
447      UINT32 words[256/4];
448   } smbusst;
449   struct apu_state {
450      UINT32 memory0_sgaddress;
451      UINT32 memory0_sgblocks;
452      UINT32 memory0_address;
453      UINT32 memory1_sgaddress;
454      UINT32 memory1_sgblocks;
455      emu_timer *timer;
456      address_space *space;
457   } apust;
458   struct ac97_state {
459      UINT32 mixer_regs[0x80/4];
460      UINT32 controller_regs[0x38/4];
461   } ac97st;
462   UINT8 pic16lc_buffer[0xff];
463   nv2a_renderer *nvidia_nv2a;
464   bool debug_irq_active;
465   int debug_irq_number;
466   UINT8 *dimm_board_memory;
467   UINT32 dimm_board_memory_size;
468   int usbhack_counter;
424469   required_device<cpu_device> m_maincpu;
425470};
426471
r23891r23892
459504      objectdata->data=this;
460505      combiner.used=0;
461506      combiner.lock=osd_lock_alloc();
507      enabled_vertex_attributes=0;
508      memset(words_vertex_attributes,0,sizeof(words_vertex_attributes));
462509   }
463510   DECLARE_READ32_MEMBER( geforce_r );
464511   DECLARE_WRITE32_MEMBER( geforce_w );
r23891r23892
472519   int geforce_commandkind(UINT32 word);
473520   UINT32 geforce_object_offset(UINT32 handle);
474521   void geforce_read_dma_object(UINT32 handle,UINT32 &offset,UINT32 &size);
475   void geforce_exec_method(address_space &space,UINT32 channel,UINT32 subchannel,UINT32 method,UINT32 data);
522   void geforce_exec_method(address_space &space,UINT32 channel,UINT32 subchannel,UINT32 method,UINT32 address,int &countlen);
476523   void combiner_initialize_registers(UINT32 argb8[6]);
477524   void combiner_initialize_stage(int stage_number);
478525   void combiner_initialize_final();
r23891r23892
500547   void computedilated(void);
501548   void putpixtex(int xp,int yp,int up,int vp);
502549   int toggle_register_combiners_usage();
550   void savestate_items();
503551
504552   struct {
505553      UINT32 regs[0x80/4];
r23891r23892
625673      int used;
626674      osd_lock *lock;
627675   } combiner;
676   int enabled_vertex_attributes;
677   int words_vertex_attributes[16];
628678   bitmap_rgb32 fb;
629679   UINT32 dilated0[16][2048];
630680   UINT32 dilated1[16][2048];
r23891r23892
656706      TEX2=11,
657707      TEX3=12
658708   };
709   enum NV2A_VTXBUF_TYPE {
710      FLOAT=2,
711      UBYTE=4,
712      USHORT=5
713   };
659714   enum NV2A_TEX_FORMAT {
660715      L8=0x0,
661716      I8=0x1,
r23891r23892
692747   };
693748};
694749
695UINT32 nv2a_renderer::dilate0(UINT32 value,int bits) // dilate first "bits" bits in "value"
696{
697   UINT32 x,m1,m2,m3;
698   int a;
699
700   x = value;
701   for (a=0;a < bits;a++)
702   {
703      m2 = 1 << (a << 1);
704      m1 = m2 - 1;
705      m3 = (~m1) << 1;
706      x = (x & m1) + (x & m2) + ((x & m3) << 1);
707   }
708   return x;
709}
710
711UINT32 nv2a_renderer::dilate1(UINT32 value,int bits) // dilate first "bits" bits in "value"
712{
713   UINT32 x,m1,m2,m3;
714   int a;
715
716   x = value;
717   for (a=0;a < bits;a++)
718   {
719      m2 = 1 << (a << 1);
720      m1 = m2 - 1;
721      m3 = (~m1) << 1;
722      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
723   }
724   return x;
725}
726
727void nv2a_renderer::computedilated(void)
728{
729   int a,b;
730
731   for (b=0;b < 16;b++)
732      for (a=0;a < 2048;a++) {
733         dilated0[b][a]=dilate0(a,b);
734         dilated1[b][a]=dilate1(a,b);
735      }
736   for (b=0;b < 16;b++)
737      for (a=0;a < 16;a++)
738         dilatechose[(b << 4) + a]=(a < b ? a : b);
739}
740
741750/* jamtable instructions for Chihiro (different from console)
742751St.     Instr.       Comment
7437520x01    POKEPCI      PCICONF[OP2] := OP1
r23891r23892
976985   }
977986}
978987
988static void curthread_command(running_machine &machine, int ref, int params, const char **param)
989{
990   address_space &space=machine.firstcpu->space();
991   UINT64 fsbase;
992   UINT32 kthrd,topstack,tlsdata;
993   offs_t address;
994   cpuinfo cpu_info;
995
996   CPU_GET_INFO_NAME(i386)((legacy_cpu_device *)machine.firstcpu,CPUINFO_INT_REGISTER + 44,&cpu_info);
997   fsbase=cpu_info.i;
998   address=(offs_t)fsbase+0x28;
999   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
1000   {
1001      debug_console_printf(machine,"Address is unmapped.\n");
1002      return;
1003   }
1004   kthrd=space.read_dword_unaligned(address);
1005   debug_console_printf(machine,"Current thread is %08X\n",kthrd);
1006   address=(offs_t)kthrd+0x1c;
1007   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
1008      return;
1009    topstack=space.read_dword_unaligned(address);
1010   debug_console_printf(machine,"Current thread stack top is %08X\n",topstack);
1011   address=(offs_t)kthrd+0x28;
1012   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
1013      return;
1014    tlsdata=space.read_dword_unaligned(address);
1015   if (tlsdata == 0)
1016      address=(offs_t)topstack-0x210-8;
1017   else
1018       address=(offs_t)tlsdata-8;
1019   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
1020      return;
1021   debug_console_printf(machine,"Current thread function is %08X\n",space.read_dword_unaligned(address));
1022}
1023
1024static void generate_irq_command(running_machine &machine, int ref, int params, const char **param)
1025{
1026   UINT64 irq;
1027   chihiro_state *chst=machine.driver_data<chihiro_state>();
1028
1029   if (params < 1)
1030      return;
1031   if (!debug_command_parameter_number(machine, param[0], &irq))
1032      return;
1033   if (irq > 15)
1034      return;
1035   if (irq == 2)
1036      return;
1037   chst->debug_generate_irq((int)irq,true);
1038}
1039
9791040static void nv2a_combiners_command(running_machine &machine, int ref, int params, const char **param)
9801041{
9811042   int en;
r23891r23892
9951056   debug_console_printf(machine,"  chihiro dump_string,<address> -- Dump _STRING object at <address>\n");
9961057   debug_console_printf(machine,"  chihiro dump_process,<address> -- Dump _PROCESS object at <address>\n");
9971058   debug_console_printf(machine,"  chihiro dump_list,<address>[,<offset>] -- Dump _LIST_ENTRY chain starting at <address>\n");
1059   debug_console_printf(machine,"  chihiro curthread -- Print information about current thread\n");
1060   debug_console_printf(machine,"  chihiro irq,<number> -- Generate interrupt with irq number 0-15\n");
9981061   debug_console_printf(machine,"  chihiro nv2a_combiners -- Toggle use of register combiners\n");
9991062   debug_console_printf(machine,"  chihiro help -- this list\n");
10001063}
r23891r23892
10111074      dump_process_command(machine,ref,params-1,param+1);
10121075   else if (strcmp("dump_list",param[0]) == 0)
10131076      dump_list_command(machine,ref,params-1,param+1);
1077   else if (strcmp("curthread",param[0]) == 0)
1078      curthread_command(machine,ref,params-1,param+1);
1079   else if (strcmp("irq",param[0]) == 0)
1080      generate_irq_command(machine,ref,params-1,param+1);
10141081   else if (strcmp("nv2a_combiners",param[0]) == 0)
10151082      nv2a_combiners_command(machine,ref,params-1,param+1);
10161083   else
10171084      help_command(machine,ref,params-1,param+1);
10181085}
10191086
1087/*
1088 * Graphics
1089 */
1090
1091UINT32 nv2a_renderer::dilate0(UINT32 value,int bits) // dilate first "bits" bits in "value"
1092{
1093   UINT32 x,m1,m2,m3;
1094   int a;
1095
1096   x = value;
1097   for (a=0;a < bits;a++)
1098   {
1099      m2 = 1 << (a << 1);
1100      m1 = m2 - 1;
1101      m3 = (~m1) << 1;
1102      x = (x & m1) + (x & m2) + ((x & m3) << 1);
1103   }
1104   return x;
1105}
1106
1107UINT32 nv2a_renderer::dilate1(UINT32 value,int bits) // dilate first "bits" bits in "value"
1108{
1109   UINT32 x,m1,m2,m3;
1110   int a;
1111
1112   x = value;
1113   for (a=0;a < bits;a++)
1114   {
1115      m2 = 1 << (a << 1);
1116      m1 = m2 - 1;
1117      m3 = (~m1) << 1;
1118      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
1119   }
1120   return x;
1121}
1122
1123void nv2a_renderer::computedilated(void)
1124{
1125   int a,b;
1126
1127   for (b=0;b < 16;b++)
1128      for (a=0;a < 2048;a++) {
1129         dilated0[b][a]=dilate0(a,b);
1130         dilated1[b][a]=dilate1(a,b);
1131      }
1132   for (b=0;b < 16;b++)
1133      for (a=0;a < 16;a++)
1134         dilatechose[(b << 4) + a]=(a < b ? a : b);
1135}
1136
10201137int nv2a_renderer::geforce_commandkind(UINT32 word)
10211138{
10221139   if ((word & 0x00000003) == 0x00000002)
r23891r23892
11461263      up=(extent.param[4].start+(float)x*extent.param[4].dpdx)*(float)(objectdata.data->texture[0].sizeu-1); // x coordinate of texel in texture
11471264      vp=extent.param[5].start*(float)(objectdata.data->texture[0].sizev-1); // y coordinate of texel in texture
11481265      to=(objectdata.data->dilated0[objectdata.data->texture[0].dilate][up]+objectdata.data->dilated1[objectdata.data->texture[0].dilate][vp]); // offset of texel in texture memory
1149      a4r4g4b4=*(((UINT16 *)objectdata.data->texture[0].buffer)+to); // get texel color
1150      *((UINT32 *)objectdata.data->fb.raw_pixptr(scanline,xp))=convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
1266      if (objectdata.data->texture[0].format == 6) {
1267         *((UINT32 *)objectdata.data->fb.raw_pixptr(scanline,xp))=*(((UINT32 *)objectdata.data->texture[0].buffer)+to); // get texel color
1268      } else {
1269         a4r4g4b4=*(((UINT16 *)objectdata.data->texture[0].buffer)+to); // get texel color
1270         *((UINT32 *)objectdata.data->fb.raw_pixptr(scanline,xp))=convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
1271      }
11511272      x--;
11521273   }
11531274}
r23891r23892
11821303            up=(extent.param[4+n*2].start+(float)x*extent.param[4+n*2].dpdx)*(float)(objectdata.data->texture[n].sizeu-1);
11831304            vp=extent.param[5+n*2].start*(float)(objectdata.data->texture[n].sizev-1);
11841305            to=(objectdata.data->dilated0[objectdata.data->texture[n].dilate][up]+objectdata.data->dilated1[objectdata.data->texture[n].dilate][vp]);
1185            color[n+2]=*(((UINT16 *)objectdata.data->texture[n].buffer)+to);
1186            color[n+2]=convert_a4r4g4b4_a8r8g8b8(color[n+2]);
1306            if (texture[n].format == 6) {
1307               color[n+2]=*(((UINT32 *)objectdata.data->texture[n].buffer)+to);
1308            } else {
1309               color[n+2]=*(((UINT16 *)objectdata.data->texture[n].buffer)+to);
1310               color[n+2]=convert_a4r4g4b4_a8r8g8b8(color[n+2]);
1311            }
11871312         }
11881313      }
11891314      // 2: compute
r23891r23892
13531478}
13541479#endif
13551480
1356void nv2a_renderer::geforce_exec_method(address_space & space,UINT32 chanel,UINT32 subchannel,UINT32 method,UINT32 data)
1481void nv2a_renderer::geforce_exec_method(address_space & space,UINT32 chanel,UINT32 subchannel,UINT32 method,UINT32 address,int &countlen)
13571482{
1358   UINT32 maddress=method*4;
1483   UINT32 maddress;
1484   UINT32 data;
1485
1486   maddress=method*4;
1487   data=space.read_dword(address);
13591488   channel[chanel][subchannel].object.method[method]=data;
1360   if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
1361      method=method+0;
1362   if (maddress == 0x1d70) {
1363      // with 1d70 write the value at offest [1d6c] inside dma object [1a4]
1364      UINT32 offset,base;
1365      UINT32 dmahand,dmaoff,smasiz;
1366
1367      offset=channel[chanel][subchannel].object.method[0x1d6c/4];
1368      dmahand=channel[chanel][subchannel].object.method[0x1a4/4];
1369      geforce_read_dma_object(dmahand,dmaoff,smasiz);
1370      base=dmaoff;
1371      space.write_dword(base+offset,data);
1372   }
1373   if (maddress == 0x1d94) {
1374      // clear framebuffer
1375      if (data & 0xf0) {
1376         // clear colors
1377         UINT32 color=channel[chanel][subchannel].object.method[0x1d90/4];
1378         fb.fill(color & 0xffffff);
1379         printf("clearscreen\n\r");
1380      }
1381      if (data & 0x03) {
1382         // clear stencil+zbuffer
1383      }
1384   }
1385   // Texture Units
1386   if ((maddress >= 0x1b00) && (maddress < 0x1c00)) {
1387      int unit;//,off;
1388
1389      unit=(maddress >> 6) & 3;
1390      //off=maddress & 0xc0;
1391      maddress=maddress & ~0xc0;
1392      if (maddress == 0x1b00) {
1393      UINT32 offset;//,base;
1394      //UINT32 dmahand,dmaoff,dmasiz;
1395
1396         offset=data;
1397         texture[unit].buffer=space.get_read_ptr(offset);
1398      /*if (dma0 != 0) {
1399          dmahand=channel[channel][subchannel].object.method[0x184/4];
1400          geforce_read_dma_object(dmahand,dmaoff,smasiz);
1401      } else if (dma1 != 0) {
1402          dmahand=channel[channel][subchannel].object.method[0x188/4];
1403          geforce_read_dma_object(dmahand,dmaoff,smasiz);
1404      }*/
1405   }
1406      if (maddress == 0x1b04) {
1407         //int dma0,dma1,cubic,noborder,dims,mipmap;
1408         int basesizeu,basesizev,basesizew,format;
1409
1410         //dma0=(data >> 0) & 1;
1411         //dma1=(data >> 1) & 1;
1412         //cubic=(data >> 2) & 1;
1413         //noborder=(data >> 3) & 1;
1414         //dims=(data >> 4) & 15;
1415         //mipmap=(data >> 19) & 1;
1416         format=(data >> 8) & 255;
1417         basesizeu=(data >> 20) & 15;
1418         basesizev=(data >> 24) & 15;
1419         basesizew=(data >> 28) & 15;
1420         texture[unit].sizeu=1 << basesizeu;
1421         texture[unit].sizev=1 << basesizev;
1422         texture[unit].sizew=1 << basesizew;
1423         texture[unit].dilate=dilatechose[(basesizeu << 4)+basesizev];
1424         texture[unit].format=format;
1425      }
1426      if (maddress == 0x1b0c) {
1427         // enable texture
1428         int enable;
1429
1430         enable=(data >> 30) & 1;
1431         texture[unit].enabled=enable;
1432      }
1433   }
14341489   if (maddress == 0x1810) {
14351490      // draw vertices
14361491      int offset,count,type;
r23891r23892
14621517#ifdef LOG_NV2A
14631518         printf(" %08X %08X\n\r",channel[chanel][subchannel].object.method[0x1720/4+n],channel[chanel][subchannel].object.method[0x1760/4+n]);
14641519#endif
1465         tmp=channel[chanel][subchannel].object.method[0x1760/4+n];
1520         tmp=channel[chanel][subchannel].object.method[0x1760/4+n]; // VTXBUF_FMT
14661521         //vtxbuf_kind[n]=tmp & 15;
14671522         //vtxbuf_size[n]=(tmp >> 4) & 15;
14681523         vtxbuf_stride[n]=(tmp >> 8) & 255;
1469         tmp=channel[chanel][subchannel].object.method[0x1720/4+n];
1524         tmp=channel[chanel][subchannel].object.method[0x1720/4+n]; // VTXBUF_OFFSET
14701525         if (tmp & 0x80000000)
14711526            vtxbuf_address[n]=(tmp & 0x0fffffff)+dmaoff[1];
14721527         else
r23891r23892
15191574         float z[3],w[3];
15201575         UINT32 c[3];
15211576
1522         printf("draw triangle\n\r");
1577         //printf("draw triangle\n\r");
15231578         // put first 2 vertices data in elements 0,1 of arrays
15241579         for (m=0;m < 2;m++) {
15251580            *((UINT32 *)(&xy[m].x))=space.read_dword(vtxbuf_address[0]+(m+offset)*vtxbuf_stride[0]+0);
r23891r23892
15711626            w[1]=w[2];
15721627         }
15731628      } else {
1574         type=type+0; // dummy, you can put a breakpoint here while debugging
1629         logerror("Unsupported primitive %d for method 0x1810\n",type);
15751630      }
1631      countlen--;
15761632   }
1577   if (maddress == 0x1e60)
1633   if (maddress == 0x1818) {
1634      int n,m,u,vwords;
1635      int vattrpos[16];
1636      int type;
1637      render_delegate renderspans;
1638
1639      if (((channel[chanel][subchannel].object.method[0x1e60/4] & 7) > 0) && (combiner.used != 0)) {
1640         renderspans=render_delegate(FUNC(nv2a_renderer::render_register_combiners),this);
1641      } else if (texture[0].enabled) {
1642         renderspans=render_delegate(FUNC(nv2a_renderer::render_texture_simple),this);
1643      } else
1644         renderspans=render_delegate(FUNC(nv2a_renderer::render_color),this);
1645      vwords=0;
1646      for (n=0;n < 16;n++) {
1647         vattrpos[n]=vwords;
1648         if ((enabled_vertex_attributes & (1 << n)) != 0)
1649            vwords += words_vertex_attributes[n];
1650      }
1651      // vertices are taken from the next words, not from a vertex buffer
1652      // first send primitive type with 17fc
1653      // then countlen number of dwords with 1818
1654      // end with 17fc primitive type 0
1655      // at 1760 16 words specify the vertex format:for each possible vertex attribute the number of components (0=not present) and type of each
1656      if ((countlen % vwords) != 0) {
1657         logerror("Method 0x1818 got %d words, at least %d were expected\n",countlen,(countlen/vwords+1)*vwords);
1658         countlen=0;
1659         return;
1660      }
1661      type=channel[chanel][subchannel].object.method[0x17fc/4];
1662      if (type == nv2a_renderer::TRIANGLE_FAN) {
1663         vertex_t xy[3];
1664         float z[3],w[3];
1665         UINT32 c[3];
1666
1667         // put first 2 vertices data in elements 0,1 of arrays
1668         for (m=0;m < 2;m++) {
1669            // consider only attributes: position,color0,texture 0-3
1670            // position
1671            *((UINT32 *)(&xy[m].x))=space.read_dword(address+vattrpos[0]*4+0);
1672            *((UINT32 *)(&xy[m].y))=space.read_dword(address+vattrpos[0]*4+4);
1673            *((UINT32 *)(&z[m]))=space.read_dword(address+vattrpos[0]*4+8);
1674            *((UINT32 *)(&w[m]))=space.read_dword(address+vattrpos[0]*4+12);
1675            // color
1676            c[m]=space.read_dword(address+vattrpos[3]*4+0); // color
1677            xy[m].p[0]=c[m] & 0xff; // b
1678            xy[m].p[1]=(c[m] & 0xff00) >> 8;  // g
1679            xy[m].p[2]=(c[m] & 0xff0000) >> 16;  // r
1680            xy[m].p[3]=(c[m] & 0xff000000) >> 24;  // a
1681            // texture 0-3
1682            for (u=0;u < 4;u++) {
1683               xy[m].p[4+u*2]=0;
1684               xy[m].p[5+u*2]=0;
1685               if (texture[u].enabled) {
1686                  *((UINT32 *)(&xy[m].p[4+u*2]))=space.read_dword(address+vattrpos[9+u]*4+0);
1687                  *((UINT32 *)(&xy[m].p[5+u*2]))=space.read_dword(address+vattrpos[9+u]*4+4);
1688               }
1689            }
1690            address=address+vwords*4;
1691            countlen=countlen-vwords;
1692         }
1693         if (countlen <= 0) {
1694            logerror("Method 0x1818 missing %d words to draw a complete primitive\n",-countlen+vwords);
1695            countlen=0;
1696            return;
1697         }
1698         for (n=2;countlen > 0;n++) {
1699            // put vertex n data in element 2 of arrays
1700            // position
1701            *((UINT32 *)(&xy[2].x))=space.read_dword(address+vattrpos[0]*4+0);
1702            *((UINT32 *)(&xy[2].y))=space.read_dword(address+vattrpos[0]*4+4);
1703            *((UINT32 *)(&z[2]))=space.read_dword(address+vattrpos[0]*4+8);
1704            *((UINT32 *)(&w[2]))=space.read_dword(address+vattrpos[0]*4+12);
1705            // color
1706            c[2]=space.read_dword(address+vattrpos[3]*4+0); // color
1707            xy[2].p[0]=c[2] & 0xff; // b
1708            xy[2].p[1]=(c[2] & 0xff00) >> 8;  // g
1709            xy[2].p[2]=(c[2] & 0xff0000) >> 16;  // r
1710            xy[2].p[3]=(c[2] & 0xff000000) >> 24;  // a
1711            // texture 0-3
1712            for (u=0;u < 4;u++) {
1713               xy[2].p[4+u*2]=0;
1714               xy[2].p[5+u*2]=0;
1715               if (texture[u].enabled) {
1716                  *((UINT32 *)(&xy[2].p[4+u*2]))=space.read_dword(address+vattrpos[9+u]*4+0);
1717                  *((UINT32 *)(&xy[2].p[5+u*2]))=space.read_dword(address+vattrpos[9+u]*4+4);
1718               }
1719            }
1720            address=address+vwords*4;
1721            countlen=countlen-vwords;
1722            if (countlen < 0) {
1723               logerror("Method 0x1818 missing %d words to draw a complete primitive\n",-countlen);
1724               countlen=0;
1725               return;
1726            }
1727            // draw triangle
1728            render_triangle(fb.cliprect(),renderspans,4+4*2,xy[0],xy[1],xy[2]); // 012
1729            wait();
1730            // move element 2 to 1
1731            xy[1]=xy[2];
1732            z[1]=z[2];
1733            w[1]=w[2];
1734         }
1735      } else {
1736         logerror("Unsupported primitive %d for method 0x1818\n",type);
1737      }
1738   }
1739   if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
1740      countlen--;
1741   if (maddress == 0x1d70) {
1742      // with 1d70 write the value at offest [1d6c] inside dma object [1a4]
1743      UINT32 offset,base;
1744      UINT32 dmahand,dmaoff,smasiz;
1745
1746      offset=channel[chanel][subchannel].object.method[0x1d6c/4];
1747      dmahand=channel[chanel][subchannel].object.method[0x1a4/4];
1748      geforce_read_dma_object(dmahand,dmaoff,smasiz);
1749      base=dmaoff;
1750      space.write_dword(base+offset,data);
1751      countlen--;
1752   }
1753   if (maddress == 0x1d94) {
1754      // clear framebuffer
1755      if (data & 0xf0) {
1756         // clear colors
1757         UINT32 color=channel[chanel][subchannel].object.method[0x1d90/4];
1758         fb.fill(color & 0xffffff);
1759         //printf("clearscreen\n\r");
1760      }
1761      if (data & 0x03) {
1762         // clear stencil+zbuffer
1763      }
1764      countlen--;
1765   }
1766   // Texture Units
1767   if ((maddress >= 0x1b00) && (maddress < 0x1c00)) {
1768      int unit;//,off;
1769
1770      unit=(maddress >> 6) & 3;
1771      //off=maddress & 0xc0;
1772      maddress=maddress & ~0xc0;
1773      if (maddress == 0x1b00) {
1774         UINT32 offset;//,base;
1775         //UINT32 dmahand,dmaoff,dmasiz;
1776
1777         offset=data;
1778         texture[unit].buffer=space.get_read_ptr(offset);
1779         /*if (dma0 != 0) {
1780            dmahand=channel[channel][subchannel].object.method[0x184/4];
1781            geforce_read_dma_object(dmahand,dmaoff,smasiz);
1782         } else if (dma1 != 0) {
1783            dmahand=channel[channel][subchannel].object.method[0x188/4];
1784            geforce_read_dma_object(dmahand,dmaoff,smasiz);
1785         }*/
1786      }
1787      if (maddress == 0x1b04) {
1788         //int dma0,dma1,cubic,noborder,dims,mipmap;
1789         int basesizeu,basesizev,basesizew,format;
1790
1791         //dma0=(data >> 0) & 1;
1792         //dma1=(data >> 1) & 1;
1793         //cubic=(data >> 2) & 1;
1794         //noborder=(data >> 3) & 1;
1795         //dims=(data >> 4) & 15;
1796         //mipmap=(data >> 19) & 1;
1797         format=(data >> 8) & 255;
1798         basesizeu=(data >> 20) & 15;
1799         basesizev=(data >> 24) & 15;
1800         basesizew=(data >> 28) & 15;
1801         texture[unit].sizeu=1 << basesizeu;
1802         texture[unit].sizev=1 << basesizev;
1803         texture[unit].sizew=1 << basesizew;
1804         texture[unit].dilate=dilatechose[(basesizeu << 4)+basesizev];
1805         texture[unit].format=format;
1806      }
1807      if (maddress == 0x1b0c) {
1808         // enable texture
1809         int enable;
1810
1811         enable=(data >> 30) & 1;
1812         texture[unit].enabled=enable;
1813      }
1814      countlen--;
1815   }
1816   if ((maddress >= 0x1760) && (maddress < 0x17A0)) {
1817      int bit=method-0x1760/4;
1818
1819      data=data & 255;
1820      if (data > 15)
1821         enabled_vertex_attributes |= (1 << bit);
1822      else
1823         enabled_vertex_attributes &= ~(1 << bit);
1824      switch (data & 15) {
1825         case 0:
1826            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
1827            break;
1828         case nv2a_renderer::FLOAT:
1829            words_vertex_attributes[bit]=(data >> 4);
1830            break;
1831         case nv2a_renderer::UBYTE:
1832            words_vertex_attributes[bit]=(((data >> 4) + 3) & 15) >> 2;
1833            break;
1834         case nv2a_renderer::USHORT:
1835            words_vertex_attributes[bit]=(((data >> 4) + 1) & 15) >> 1;
1836            break;
1837         default:
1838            words_vertex_attributes[bit]=0;
1839      }
1840   }
1841   if (maddress == 0x1e60) {
15781842      combiner.stages=data & 15;
1843      countlen--;
1844   }
15791845   if (maddress == 0x0288) {
15801846      combiner.final.mapin_rgbD_input=data & 15;
15811847      combiner.final.mapin_rgbD_component=(data >> 4) & 1;
r23891r23892
15891855      combiner.final.mapin_rgbA_input=(data >> 24) & 15;
15901856      combiner.final.mapin_rgbA_component=(data >> 28) & 1;
15911857      combiner.final.mapin_rgbA_mapping=(data >> 29) & 7;
1858      countlen--;
15921859   }
15931860   if (maddress == 0x028c) {
15941861      combiner.final.color_sum_clamp=(data >> 7) & 1;
r23891r23892
16011868      combiner.final.mapin_rgbE_input=(data >> 24) & 15;
16021869      combiner.final.mapin_rgbE_component=(data >> 28) & 1;
16031870      combiner.final.mapin_rgbE_mapping=(data >> 29) & 7;
1871      countlen--;
16041872   }
16051873   if (maddress == 0x1e20) {
16061874      combiner_argb8_float(data,combiner.final.register_constantcolor0);
1875      countlen--;
16071876   }
16081877   if (maddress == 0x1e24) {
16091878      combiner_argb8_float(data,combiner.final.register_constantcolor1);
1879      countlen--;
16101880   }
16111881   if ((maddress >= 0x0260) && (maddress < 0x0280)) {
16121882      int n;
r23891r23892
16241894      combiner.stage[n].mapin_aA_input=(data >> 24) & 15;
16251895      combiner.stage[n].mapin_aA_component=(data >> 28) & 1;
16261896      combiner.stage[n].mapin_aA_mapping=(data >> 29) & 7;
1897      countlen--;
16271898   }
16281899   if ((maddress >= 0x0ac0) && (maddress < 0x0ae0)) {
16291900      int n;
r23891r23892
16411912      combiner.stage[n].mapin_rgbA_input=(data >> 24) & 15;
16421913      combiner.stage[n].mapin_rgbA_component=(data >> 28) & 1;
16431914      combiner.stage[n].mapin_rgbA_mapping=(data >> 29) & 7;
1915      countlen--;
16441916   }
16451917   if ((maddress >= 0x0a60) && (maddress < 0x0a80)) {
16461918      int n;
16471919
16481920      n=(maddress-0x0a60) >> 2;
16491921      combiner_argb8_float(data,combiner.stage[n].register_constantcolor0);
1922      countlen--;
16501923   }
16511924   if ((maddress >= 0x0a80) && (maddress < 0x0aa0)) {
16521925      int n;
16531926
16541927      n=(maddress-0x0a80) >> 2;
16551928      combiner_argb8_float(data,combiner.stage[n].register_constantcolor1);
1929      countlen--;
16561930   }
16571931   if ((maddress >= 0x0aa0) && (maddress < 0x0ac0)) {
16581932      int n;
r23891r23892
16671941      combiner.stage[n].mapout_a_bias=(data >> 15) & 1;
16681942      combiner.stage[n].mapout_a_scale=(data >> 16) & 3;
16691943      //combiner.=(data >> 27) & 7;
1944      countlen--;
16701945   }
16711946   if ((maddress >= 0x1e40) && (maddress < 0x1e60)) {
16721947      int n;
r23891r23892
16811956      combiner.stage[n].mapout_rgb_bias=(data >> 15) & 1;
16821957      combiner.stage[n].mapout_rgb_scale=(data >> 16) & 3;
16831958      //combiner.=(data >> 27) & 7;
1959      countlen--;
16841960   }
16851961}
16861962
r23891r23892
16901966   return combiner.used;
16911967}
16921968
1969void nv2a_renderer::savestate_items()
1970{
1971}
1972
16931973void nv2a_renderer::combiner_argb8_float(UINT32 color,float reg[4])
16941974{
16951975   reg[0]=(float)(color & 0xff)/255.0;
r23891r23892
23132593{
23142594   chihiro_state *chst=machine().driver_data<chihiro_state>();
23152595
2316   printf("vblank_callback\n\r");
2596   //printf("vblank_callback\n\r");
23172597   if (state == true)
23182598      pcrtc[0x100/4] |= 1;
23192599   else
r23891r23892
23342614   UINT32 *dst=(UINT32 *)bitmap.raw_pixptr(0,0);
23352615   UINT32 *src=(UINT32 *)fb.raw_pixptr(0,0);
23362616
2337   printf("updatescreen\n\r");
2617   //printf("updatescreen\n\r");
23382618   memcpy(dst,src,bitmap.rowbytes()*bitmap.height());
23392619   return 0;
23402620}
23412621
2622void chihiro_state::debug_generate_irq(int irq,bool active)
2623{
2624   int state;
2625
2626   if (active)
2627   {
2628      debug_irq_active=true;
2629      debug_irq_number=irq;
2630      state=1;
2631   }
2632   else
2633   {
2634      debug_irq_active=false;
2635      state=0;
2636   }
2637   switch (irq)
2638   {
2639   case 0:
2640      chihiro_devs.pic8259_1->ir0_w(state);
2641      break;
2642   case 1:
2643      chihiro_devs.pic8259_1->ir1_w(state);
2644      break;
2645   case 3:
2646      chihiro_devs.pic8259_1->ir3_w(state);
2647      break;
2648   case 4:
2649      chihiro_devs.pic8259_1->ir4_w(state);
2650      break;
2651   case 5:
2652      chihiro_devs.pic8259_1->ir5_w(state);
2653      break;
2654   case 6:
2655      chihiro_devs.pic8259_1->ir6_w(state);
2656      break;
2657   case 7:
2658      chihiro_devs.pic8259_1->ir7_w(state);
2659      break;
2660   case 8:
2661      chihiro_devs.pic8259_2->ir0_w(state);
2662      break;
2663   case 9:
2664      chihiro_devs.pic8259_2->ir1_w(state);
2665      break;
2666   case 10:
2667      chihiro_devs.pic8259_2->ir2_w(state);
2668      break;
2669   case 11:
2670      chihiro_devs.pic8259_2->ir3_w(state);
2671      break;
2672   case 12:
2673      chihiro_devs.pic8259_2->ir4_w(state);
2674      break;
2675   case 13:
2676      chihiro_devs.pic8259_2->ir5_w(state);
2677      break;
2678   case 14:
2679      chihiro_devs.pic8259_2->ir6_w(state);
2680      break;
2681   case 15:
2682      chihiro_devs.pic8259_2->ir7_w(state);
2683      break;
2684   }
2685}
2686
23422687void chihiro_state::vblank_callback(screen_device &screen, bool state)
23432688{
23442689   nvidia_nv2a->vblank_callback(screen,state);
r23891r23892
23592704      ret=x;
23602705   }
23612706   if ((offset >= 0x00101000/4) && (offset < 0x00102000/4)) {
2362      logerror("NV_2A: read STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,ret);
2707      //logerror("NV_2A: read STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,ret);
23632708   } else if ((offset >= 0x00002000/4) && (offset < 0x00004000/4)) {
23642709      ret=pfifo[offset-0x00002000/4];
23652710      // PFIFO.CACHE1.STATUS or PFIFO.RUNOUT_STATUS
23662711      if ((offset == 0x3214/4) || (offset == 0x2400/4))
23672712         ret=0x10;
2368      logerror("NV_2A: read PFIFO[%06X] value %08X\n",offset*4-0x00002000,ret);
2713      //logerror("NV_2A: read PFIFO[%06X] value %08X\n",offset*4-0x00002000,ret);
23692714   } else if ((offset >= 0x00700000/4) && (offset < 0x00800000/4)) {
23702715      ret=ramin[offset-0x00700000/4];
2371      logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
2716      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
23722717   } else if ((offset >= 0x00400000/4) && (offset < 0x00402000/4)) {
2373      logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
2718      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
23742719   } else if ((offset >= 0x00600000/4) && (offset < 0x00601000/4)) {
23752720      ret=pcrtc[offset-0x00600000/4];
2376      logerror("NV_2A: read PCRTC[%06X] value %08X\n",offset*4-0x00600000,ret);
2721      //logerror("NV_2A: read PCRTC[%06X] value %08X\n",offset*4-0x00600000,ret);
23772722   } else if ((offset >= 0x00000000/4) && (offset < 0x00001000/4)) {
23782723      ret=pmc[offset-0x00000000/4];
2379      logerror("NV_2A: read PMC[%06X] value %08X\n",offset*4-0x00000000,ret);
2724      //logerror("NV_2A: read PMC[%06X] value %08X\n",offset*4-0x00000000,ret);
23802725   } else if ((offset >= 0x00800000/4) && (offset < 0x00900000/4)) {
23812726      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
23822727      int chanel,subchannel,suboffset;
r23891r23892
23872732      suboffset=suboffset & 0x7ff;
23882733      if (suboffset < 0x80/4)
23892734         ret=channel[chanel][subchannel].regs[suboffset];
2390      logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
2735      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
23912736      return ret;
2392   } else
2393      logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
2737   } else ;
2738      //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
23942739   return ret;
23952740}
23962741
23972742WRITE32_MEMBER( nv2a_renderer::geforce_w )
23982743{
23992744   if ((offset >= 0x00101000/4) && (offset < 0x00102000/4)) {
2400      logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
2745      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
24012746   } else if ((offset >= 0x00002000/4) && (offset < 0x00004000/4)) {
24022747      COMBINE_DATA(pfifo+offset-0x00002000/4);
2403      logerror("NV_2A: read PFIFO[%06X]=%08X\n",offset*4-0x00002000,data & mem_mask); // 2210 pfifo ramht & 1f0 << 12
2748      //logerror("NV_2A: read PFIFO[%06X]=%08X\n",offset*4-0x00002000,data & mem_mask); // 2210 pfifo ramht & 1f0 << 12
24042749   } else if ((offset >= 0x00700000/4) && (offset < 0x00800000/4)) {
24052750      COMBINE_DATA(ramin+offset-0x00700000/4);
2406      logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
2751      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
24072752   } else if ((offset >= 0x00400000/4) && (offset < 0x00402000/4)) {
2408      logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
2753      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
24092754   } else if ((offset >= 0x00600000/4) && (offset < 0x00601000/4)) {
24102755      COMBINE_DATA(pcrtc+offset-0x00600000/4);
2411      logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
2756      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
24122757   } else if ((offset >= 0x00000000/4) && (offset < 0x00001000/4)) {
24132758      COMBINE_DATA(pmc+offset-0x00000000/4);
2414      logerror("NV_2A: write PMC[%06X]=%08X\n",offset*4-0x00000000,data & mem_mask);
2759      //logerror("NV_2A: write PMC[%06X]=%08X\n",offset*4-0x00000000,data & mem_mask);
24152760   } else if ((offset >= 0x00800000/4) && (offset < 0x00900000/4)) {
24162761      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
24172762      int chanel,subchannel,suboffset;
r23891r23892
24242769      chanel=(suboffset >> (16-2)) & 31;
24252770      subchannel=(suboffset >> (13-2)) & 7;
24262771      suboffset=suboffset & 0x7ff;
2427      logerror("NV_2A: write channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,data & mem_mask);
2772      //logerror("NV_2A: write channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,data & mem_mask);
24282773      if (suboffset >= 0x80/4)
24292774         return;
24302775      COMBINE_DATA(&channel[chanel][subchannel].regs[suboffset]);
24312776      if ((suboffset == 0x40/4) || (suboffset == 0x44/4)) { // DMA_PUT or DMA_GET
24322777         UINT32 *dmaput,*dmaget;
24332778         UINT32 cmd,cmdtype;
2779         int countlen;
24342780
24352781         dmaput=&channel[chanel][subchannel].regs[0x40/4];
24362782         dmaget=&channel[chanel][subchannel].regs[0x44/4];
24372783         //printf("dmaget %08X dmaput %08X\n\r",*dmaget,*dmaput);
2784         if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000))
2785            *dmaget = *dmaput;
24382786         while (*dmaget != *dmaput) {
24392787            cmd=space.read_dword(*dmaget);
24402788            *dmaget += 4;
r23891r23892
24722820                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
24732821#endif
24742822                     while (count > 0) {
2475                        geforce_exec_method(space,chanel,subchannel,method,space.read_dword(*dmaget));
2823                        countlen=1;
2824                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
24762825                        count--;
24772826                        method++;
24782827                        *dmaget += 4;
r23891r23892
25042853                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
25052854#endif
25062855                     while (count > 0) {
2507                        geforce_exec_method(space,chanel,subchannel,method,space.read_dword(*dmaget));
2508                        count--;
2509                        *dmaget += 4;
2856                        countlen=count;
2857                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
2858                        *dmaget += 4*(count-countlen);
2859                        count=countlen;
25102860                     }
25112861                  }
25122862                  break;
r23891r23892
25332883                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
25342884#endif
25352885                     while (count > 0) {
2536                        geforce_exec_method(space,chanel,subchannel,method,space.read_dword(*dmaget));
2537                        count--;
2538                        *dmaget += 4;
2886                        countlen=count;
2887                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
2888                        *dmaget += 4*(count-countlen);
2889                        count=countlen;
25392890                     }
25402891                  }
25412892                  break;
r23891r23892
25442895            }
25452896         }
25462897      }
2547   } else
2548      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
2898   } else ;
2899//      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
25492900}
25502901
25512902READ32_MEMBER( chihiro_state::geforce_r )
r23891r23892
25612912static UINT32 geforce_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
25622913{
25632914#ifdef LOG_PCI
2564   logerror("  bus:1 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
2915//   logerror("  bus:1 device:NV_2A function:%d register:%d mask:%08X\n",function,reg,mem_mask);
25652916#endif
25662917   return 0;
25672918}
r23891r23892
25692920static void geforce_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
25702921{
25712922#ifdef LOG_PCI
2572   logerror("  bus:1 function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
2923//   logerror("  bus:1 device:NV_2A function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
25732924#endif
25742925}
25752926
r23891r23892
26052956READ32_MEMBER( chihiro_state::usbctrl_r )
26062957{
26072958   if (offset == 0) { /* hack needed until usb (and jvs) is implemented */
2608      chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6a79f,0x01);
2609      chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6a7a0,0x00);
2959      if (usbhack_counter == 0) {
2960         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6a79f,0x01);
2961         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6a7a0,0x00);
2962         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b575,0x00);
2963         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b576,0x00);
2964         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b5af,0x75);
2965         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b78a,0x75);
2966         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b7ca,0x00);
2967         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x6b7b8,0x00);
2968         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x8f5b2,0x75);
2969         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x79a9e,0x74);
2970         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x79b80,0x74);
2971         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x79b97,0x74);
2972      }
2973      // after game loaded
2974      if (usbhack_counter == 1) {
2975         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x12e4cf,0x01);
2976         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x12e4d0,0x00);
2977         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x4793e,0x01);
2978         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x4793f,0x00);
2979         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x47aa3,0x01);
2980         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x47aa4,0x00);
2981         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x14f2b6,0x84);
2982         chihiro_devs.pic8259_1->machine().firstcpu->space(0).write_byte(0x14f2d1,0x75);
2983      }
2984      usbhack_counter++;
26102985   }
26112986#ifdef LOG_OHCI
26122987   if (offset >= 0x54/4)
r23891r23892
26283003}
26293004
26303005/*
3006 * Audio
3007 */
3008
3009READ32_MEMBER( chihiro_state::audio_apu_r )
3010{
3011   logerror("Audio_APU: read from %08X mask %08X\n",0xfe800000+offset*4,mem_mask);
3012   if (offset == 0x20010/4)
3013      return 0x20+4+8+0x48+0x80;
3014   return 0;
3015}
3016
3017WRITE32_MEMBER( chihiro_state::audio_apu_w )
3018{
3019   logerror("Audio_APU: write at %08X mask %08X value %08X\n",0xfe800000+offset*4,mem_mask,data);
3020   if (offset == 0x2040/4)
3021      apust.memory0_sgaddress=data;
3022   if (offset == 0x20d4/4) {
3023      apust.memory0_sgblocks=data;
3024      apust.memory0_address=apust.space->read_dword(apust.memory0_sgaddress);
3025      apust.timer->enable();
3026      apust.timer->adjust(attotime::from_msec(1),0,attotime::from_msec(1));
3027   }
3028   if (offset == 0x2048/4)
3029      apust.memory1_sgaddress=data;
3030   if (offset == 0x20dc/4)
3031      apust.memory1_sgblocks=data;
3032}
3033
3034READ32_MEMBER( chihiro_state::audio_ac93_r )
3035{
3036   UINT32 ret=0;
3037
3038   logerror("Audio_AC3: read from %08X mask %08X\n",0xfec00000+offset*4,mem_mask);
3039   if (offset < 0x80/4)
3040   {
3041      ret=ac97st.mixer_regs[offset];
3042   }
3043   if ((offset >= 0x100/4) && (offset <= 0x138/4))
3044   {
3045      offset=offset-0x100/4;
3046      if (offset == 0x18/4)
3047      {
3048         ac97st.controller_regs[offset] &= ~0x02000000; // REGRST: register reset
3049      }
3050      if (offset == 0x30/4)
3051      {
3052         ac97st.controller_regs[offset] |= 0x100; // PCRDY: primary codec ready
3053      }
3054      if (offset == 0x34/4)
3055      {
3056         ac97st.controller_regs[offset] &= ~1; // CAS: codec access semaphore
3057      }
3058      ret=ac97st.controller_regs[offset];
3059   }
3060   return ret;
3061}
3062
3063WRITE32_MEMBER( chihiro_state::audio_ac93_w )
3064{
3065   logerror("Audio_AC3: write at %08X mask %08X value %08X\n",0xfec00000+offset*4,mem_mask,data);
3066   if (offset < 0x80/4)
3067   {
3068      COMBINE_DATA(ac97st.mixer_regs+offset);
3069   }
3070   if ((offset >= 0x100/4) && (offset <= 0x138/4))
3071   {
3072      offset=offset-0x100/4;
3073      COMBINE_DATA(ac97st.controller_regs+offset);
3074   }
3075}
3076
3077TIMER_CALLBACK_MEMBER(chihiro_state::audio_apu_timer)
3078{
3079   int cmd=apust.space->read_dword(apust.memory0_address+0x800+0x10);
3080   if (cmd == 3)
3081      apust.space->write_dword(apust.memory0_address+0x800+0x10,0);
3082   /*else
3083      logerror("Audio_APU: unexpected value at address %d\n",apust.memory0_address+0x800+0x10);*/
3084}
3085
3086/*
26313087 * dummy for non connected devices
26323088 */
26333089
26343090static UINT32 dummy_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
26353091{
26363092#ifdef LOG_PCI
2637   logerror("  bus:0 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
3093//   logerror("  bus:0 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
26383094#endif
26393095   return 0;
26403096}
r23891r23892
26423098static void dummy_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
26433099{
26443100#ifdef LOG_PCI
2645   logerror("  bus:0 function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
3101   if (reg >= 16) logerror("  bus:0 function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
26463102#endif
26473103}
26483104
r23891r23892
26673123   virtual int  write_sector(UINT32 lba, const void *buffer);
26683124protected:
26693125   // device-level overrides
3126   virtual void device_start();
26703127   virtual void device_reset();
3128   UINT8 read_buffer[0x20];
3129   UINT8 write_buffer[0x20];
3130   chihiro_state *chihirosystem;
26713131};
26723132
26733133//**************************************************************************
r23891r23892
26873147}
26883148
26893149//-------------------------------------------------
3150//  device_start - device-specific startup
3151//-------------------------------------------------
3152
3153void ide_baseboard_device::device_start()
3154{
3155   ata_mass_storage_device::device_start();
3156   chihirosystem=machine().driver_data<chihiro_state>();
3157   // savestates
3158   save_item(NAME(read_buffer));
3159   save_item(NAME(write_buffer));
3160}
3161
3162//-------------------------------------------------
26903163//  device_reset - device-specific reset
26913164//-------------------------------------------------
26923165
r23891r23892
27093182   int off;
27103183   UINT8 *data;
27113184
3185   /*
3186   It assumes there are 4 "partitions", the size of the first one depends on bits 3-0 of io port 40f4:
3187    Value    Size lba
3188      0   0x40000-0x8000
3189        ...
3190      4   0x400000-0x8000
3191    The size of the second one is always 0x8000 sectors, and is used as a special communication area
3192   This is a list of the partitions in the minimum size case:
3193    Name          Start lba  Size lba Size
3194    \??\mbfs:     0x0        0x38000  112MB
3195    \??\mbcom:    0x38000    0x8000   16MB
3196    \??\mbrom0:   0x8000000  0x800    1MB
3197    \??\mbrom1:   0x8000800  0x800    1MB
3198   This is a list of the partitions in the maximum size case:
3199    Name          Start lba  Size lba Size
3200    \??\mbfs:     0x0        0x3f8000 2032MB
3201    \??\mbcom:    0x3f8000   0x8000   16MB
3202    \??\mbrom0:   0x8000000  0x800    1MB
3203    \??\mbrom1:   0x8000800  0x800    1MB
3204   */
27123205   logerror("baseboard: read sector lba %08x\n",lba);
2713   off=(lba&0x7ff)*512;
2714   data=memregion(":others")->base();
2715   memcpy(buffer,data+off,512);
3206   if (lba >= 0x08000000) {
3207      off=(lba&0x7ff)*512;
3208      data=memregion(":others")->base();
3209      memcpy(buffer,data+off,512);
3210      return 1;
3211   }
3212   if (lba >= 0xf8000) {
3213      memset(buffer,0,512);
3214      lba=lba-0xf8000;
3215      if (lba == 0x4800)
3216         memcpy(buffer,read_buffer,0x20);
3217      else if (lba == 0x4801)
3218         memcpy(buffer,write_buffer,0x20);
3219      return 1;
3220   }
3221   // in a type 1 chihiro this gets data from the dimm board memory
3222   data=chihirosystem->baseboard_ide_dimmboard(lba);
3223   if (data != NULL)
3224      memcpy(buffer,data,512);
27163225   return 1;
27173226}
27183227
27193228int ide_baseboard_device::write_sector(UINT32 lba, const void *buffer)
27203229{
27213230   logerror("baseboard: write sector lba %08x\n",lba);
3231   if (lba >= 0xf8000) {
3232      lba=lba-0xf8000;
3233      if (lba == 0x4800)
3234         memcpy(read_buffer,buffer,0x20);
3235      else if (lba == 0x4801) {
3236         memcpy(write_buffer,buffer,0x20);
3237         // call chihiro driver
3238         chihirosystem->baseboard_ide_event(3,read_buffer,write_buffer);
3239      }
3240   }
27223241   return 1;
27233242}
27243243
27253244/*
3245 * Chihiro Type 1 baseboard
3246 */
3247
3248void chihiro_state::dword_write_le(UINT8 *addr,UINT32 d)
3249{
3250   addr[0]=d & 255;
3251   addr[1]=(d >> 8) & 255;
3252   addr[2]=(d >> 16) & 255;
3253   addr[3]=(d >> 24) & 255;
3254}
3255
3256void chihiro_state::word_write_le(UINT8 *addr,UINT16 d)
3257{
3258   addr[0]=d & 255;
3259   addr[1]=(d >> 8) & 255;
3260}
3261
3262void chihiro_state::baseboard_ide_event(int type,UINT8 *read_buffer,UINT8 *write_buffer)
3263{
3264   int c;
3265
3266   if ((type != 3) || ((write_buffer[0] == 0) && (write_buffer[1] == 0)))
3267      return;
3268#ifdef LOG_BASEBOARD
3269   logerror("Baseboard sector command:\n");
3270   for (int a=0;a < 32;a++)
3271      logerror(" %02X",write_buffer[a]);
3272   logerror("\n");
3273#endif
3274   // response
3275   // second word 8001 (8000+counter), first word=first word of written data (command ?), second dword ?
3276   read_buffer[0]=write_buffer[0];
3277   read_buffer[1]=write_buffer[1];
3278   read_buffer[2]=0x01; // write_buffer[2];
3279   read_buffer[3]=0x80; // write_buffer[3] | 0x80;
3280   c=write_buffer[2]+(write_buffer[3] << 8); // 0001 0101 0103
3281   switch (c)
3282   {
3283      case 0x0001:
3284         // second dword
3285         dword_write_le(read_buffer+4,0x00f00000); // ?
3286         break;
3287      case 0x0100:
3288         // second dword third dword
3289         dword_write_le(read_buffer+4,5); // game data loading phase
3290         dword_write_le(read_buffer+8,0); // completion %
3291         break;
3292      case 0x0101:
3293         // third word fourth word
3294         word_write_le(read_buffer+4,0xca); // ?
3295         word_write_le(read_buffer+6,0xcb); // ?
3296         break;
3297      case 0x0102:
3298         // second dword
3299         dword_write_le(read_buffer+4,0); // bit 16 develop. mode
3300         break;
3301      case 0x0103:
3302         // dwords 1 3 4
3303         memcpy(read_buffer+4,"-abc-abc12345678",16); // ?
3304         break;
3305   }
3306   // clear
3307   write_buffer[0]=write_buffer[1]=write_buffer[2]=write_buffer[3]=0;
3308   // irq 10 active
3309   chihiro_devs.pic8259_2->ir2_w(1);
3310}
3311
3312UINT8 *chihiro_state::baseboard_ide_dimmboard(UINT32 lba)
3313{
3314   // return pointer to memory containing decrypted gdrom data (contains an image of a fatx partition)
3315   if (chihiro_devs.dimmboard != NULL)
3316      return dimm_board_memory+lba*512;
3317   return NULL;
3318}
3319
3320/*
27263321 * PIC & PIT
27273322 */
27283323
r23891r23892
27473342   {
27483343      r = chihiro_devs.pic8259_1->acknowledge();
27493344   }
3345   if (debug_irq_active)
3346      debug_generate_irq(debug_irq_number,false);
27503347   return r;
27513348}
27523349
27533350WRITE_LINE_MEMBER(chihiro_state::chihiro_pit8254_out0_changed)
27543351{
2755   if ( machine().device<pic8259_device>("pic8259_1") )
3352   if ( chihiro_devs.pic8259_1 )
27563353   {
2757      machine().device<pic8259_device>("pic8259_1")->ir0_w(state);
3354      chihiro_devs.pic8259_1->ir0_w(state);
27583355   }
27593356}
27603357
r23891r23892
27863383 * SMbus devices
27873384 */
27883385
2789static UINT8 pic16lc_buffer[0xff];
2790
27913386int smbus_callback_pic16lc(chihiro_state &chs,int command,int rw,int data)
27923387{
27933388   return chs.smbus_pic16lc(command, rw, data);
r23891r23892
28653460 * SMbus controller
28663461 */
28673462
2868struct smbus_state {
2869   int status;
2870   int control;
2871   int address;
2872   int data;
2873   int command;
2874   int rw;
2875   int (*devices[128])(chihiro_state &chs,int command,int rw,int data);
2876   UINT32 words[256/4];
2877} smbusst;
2878
28793463void chihiro_state::smbus_register_device(int address,int (*handler)(chihiro_state &chs,int command,int rw,int data))
28803464{
28813465   if (address < 128)
r23891r23892
29373521      smbusst.command = data;
29383522}
29393523
3524READ32_MEMBER( chihiro_state::mediaboard_r )
3525{
3526   UINT32 r;
3527
3528   logerror("I/O port read %04x mask %08X\n",offset*4+0x4000,mem_mask);
3529   r=0;
3530   if ((offset == 7) && ACCESSING_BITS_16_31)
3531      r=0x10000000;
3532   if ((offset == 8) && ACCESSING_BITS_0_15)
3533      r=0x000000a0;
3534   if ((offset == 8) && ACCESSING_BITS_16_31)
3535      r=0x42580000;
3536   if ((offset == 9) && ACCESSING_BITS_0_15)
3537      r=0x00004d41;
3538   if ((offset == 0x3c) && ACCESSING_BITS_0_15)
3539      r=0x00000000; // bits 15-0 0 if media board present
3540   if ((offset == 0x3d) && ACCESSING_BITS_0_15)
3541      r=0x00000002; // bits 3-0 size of dimm board memory. Must be 2
3542   return r;
3543}
3544
3545WRITE32_MEMBER( chihiro_state::mediaboard_w )
3546{
3547   logerror("I/O port write %04x mask %08X value %08X\n",offset*4+0x4000,mem_mask,data);
3548   // irq 10
3549   if ((offset == 0x38) && ACCESSING_BITS_8_15)
3550      chihiro_devs.pic8259_2->ir2_w(0);
3551}
3552
29403553static ADDRESS_MAP_START( xbox_map, AS_PROGRAM, 32, chihiro_state )
29413554   AM_RANGE(0x00000000, 0x07ffffff) AM_RAM // 128 megabytes
29423555   AM_RANGE(0xf0000000, 0xf0ffffff) AM_RAM
29433556   AM_RANGE(0xfd000000, 0xfdffffff) AM_RAM AM_READWRITE(geforce_r, geforce_w)
29443557   AM_RANGE(0xfed00000, 0xfed003ff) AM_READWRITE(usbctrl_r, usbctrl_w)
3558   AM_RANGE(0xfe800000, 0xfe85ffff) AM_READWRITE(audio_apu_r, audio_apu_w)
3559   AM_RANGE(0xfec00000, 0xfec001ff) AM_READWRITE(audio_ac93_r, audio_ac93_w)
29453560   AM_RANGE(0xff000000, 0xffffffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x00f80000)
29463561ADDRESS_MAP_END
29473562
r23891r23892
29513566   AM_RANGE(0x00a0, 0x00a3) AM_DEVREADWRITE8("pic8259_2", pic8259_device, read, write, 0xffffffff)
29523567   AM_RANGE(0x01f0, 0x01f7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, read_cs0, write_cs0)
29533568   AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write)
3569   AM_RANGE(0x4000, 0x40ff) AM_READWRITE(mediaboard_r, mediaboard_w)
29543570   AM_RANGE(0x8000, 0x80ff) AM_READWRITE(dummy_r, dummy_w)
29553571   AM_RANGE(0xc000, 0xc0ff) AM_READWRITE(smbus_r, smbus_w)
29563572   AM_RANGE(0xff60, 0xff67) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w)
r23891r23892
29643580   nvidia_nv2a=auto_alloc(machine(), nv2a_renderer(machine()));
29653581   memset(pic16lc_buffer,0,sizeof(pic16lc_buffer));
29663582   pic16lc_buffer[0]='B';
2967   pic16lc_buffer[4]=2; // A/V connector, 2=vga
3583   pic16lc_buffer[4]=0; // A/V connector, 2=vga
29683584   smbus_register_device(0x10,smbus_callback_pic16lc);
29693585   smbus_register_device(0x45,smbus_callback_cx25871);
29703586   smbus_register_device(0x54,smbus_callback_eeprom);
r23891r23892
29723588   chihiro_devs.pic8259_1 = machine().device<pic8259_device>( "pic8259_1" );
29733589   chihiro_devs.pic8259_2 = machine().device<pic8259_device>( "pic8259_2" );
29743590   chihiro_devs.ide = machine().device<bus_master_ide_controller_device>( "ide" );
3591   chihiro_devs.dimmboard=machine().device<naomi_gdrom_board>("rom_board");
3592   if (chihiro_devs.dimmboard != NULL) {
3593      dimm_board_memory=chihiro_devs.dimmboard->memory(dimm_board_memory_size);
3594   }
3595   apust.space=&machine().firstcpu->space();
3596   apust.timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(chihiro_state::audio_apu_timer),this),(void *)"APU Timer");
3597   apust.timer->enable(false);
29753598   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
29763599      debug_console_register_command(machine(),"chihiro",CMDFLAG_NONE,0,1,4,chihiro_debug_commands);
3600   usbhack_counter=0;
3601   // savestates
3602   save_item(NAME(debug_irq_active));
3603   save_item(NAME(debug_irq_number));
3604   save_item(NAME(smbusst.status));
3605   save_item(NAME(smbusst.control));
3606   save_item(NAME(smbusst.address));
3607   save_item(NAME(smbusst.data));
3608   save_item(NAME(smbusst.command));
3609   save_item(NAME(smbusst.rw));
3610   save_item(NAME(smbusst.words));
3611   save_item(NAME(pic16lc_buffer));
3612   save_item(NAME(usbhack_counter));
3613   nvidia_nv2a->savestate_items();
29773614}
29783615
29793616static SLOT_INTERFACE_START(ide_baseboard)
r23891r23892
29943631   MCFG_PCI_BUS_LEGACY_DEVICE(1, "HUB Interface - ISA Bridge", dummy_pci_r, dummy_pci_w)
29953632   MCFG_PCI_BUS_LEGACY_DEVICE(2, "OHCI USB Controller 1", dummy_pci_r, dummy_pci_w)
29963633   MCFG_PCI_BUS_LEGACY_DEVICE(3, "OHCI USB Controller 2", dummy_pci_r, dummy_pci_w)
3634   MCFG_PCI_BUS_LEGACY_DEVICE(4, "MCP Networking Adapter", dummy_pci_r, dummy_pci_w)
3635   MCFG_PCI_BUS_LEGACY_DEVICE(5, "MCP APU", dummy_pci_r, dummy_pci_w)
3636   MCFG_PCI_BUS_LEGACY_DEVICE(6, "AC`97 Audio Codec Interface", dummy_pci_r, dummy_pci_w)
3637   MCFG_PCI_BUS_LEGACY_DEVICE(9, "IDE Controller", dummy_pci_r, dummy_pci_w)
29973638   MCFG_PCI_BUS_LEGACY_DEVICE(30, "AGP Host to PCI Bridge", dummy_pci_r, dummy_pci_w)
29983639   MCFG_PCI_BUS_LEGACY_ADD("agpbus", 1)
29993640   MCFG_PCI_BUS_LEGACY_SIBLING("pcibus")
r23891r23892
30143655   MCFG_SCREEN_UPDATE_DRIVER(chihiro_state,screen_update_callback)
30153656   MCFG_SCREEN_VBLANK_DRIVER(chihiro_state,vblank_callback)
30163657
3017
30183658   MCFG_PALETTE_LENGTH(65536)
30193659MACHINE_CONFIG_END
30203660
30213661static MACHINE_CONFIG_DERIVED( chihirogd, chihiro_base )
3022   MCFG_NAOMI_GDROM_BOARD_ADD("rom_board", ":gdrom", "pic", NULL, NOOP)
3662   MCFG_NAOMI_GDROM_BOARD_ADD("rom_board", ":gdrom", ":pic", NULL, NOOP)
30233663MACHINE_CONFIG_END
30243664
30253665#define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \
r23891r23892
30383678   ROM_LOAD16_WORD_SWAP_BIOS( 0,  "ic11_24lc024.bin", 0x202000, 0x80, CRC(8dc8374e) SHA1(cc03a0650bfac4bf6cb66e414bbef121cba53efe) ) \
30393679   ROM_LOAD16_WORD_SWAP_BIOS( 0,  "pc20_g24lc64.bin", 0x202080, 0x2000, CRC(7742ab62) SHA1(82dad6e2a75bab4a4840dc6939462f1fb9b95101) ) \
30403680   ROM_LOAD16_WORD_SWAP_BIOS( 0,  "ver1305.bin", 0x204080, 0x200000, CRC(a738ea1c) SHA1(45d94d0c39be1cb3db9fab6610a88a550adda4e9) )
3681
30413682ROM_START( chihiro )
30423683   CHIHIRO_BIOS
30433684
r23891r23892
32533894GAME( 2002, hotd3,    chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "The House of the Dead III (GDX-0001)", GAME_NO_SOUND|GAME_NOT_WORKING )
32543895GAME( 2003, crtaxihr, chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Crazy Taxi High Roller (Rev B) (GDX-0002B)", GAME_NO_SOUND|GAME_NOT_WORKING )
32553896GAME( 2003, vcop3,    chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Virtua Cop 3 (Rev A) (GDX-0003A)", GAME_NO_SOUND|GAME_NOT_WORKING )
3256GAME( 2003, outr2,    chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Out Run 2 (Rev A) (GDX-0004A)", GAME_NO_SOUND|GAME_NOT_WORKING )
3897GAME( 2003, outr2,    chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Out Run 2 (Rev A) (GDX-0004A)", GAME_NO_SOUND|GAME_NOT_WORKING|GAME_SUPPORTS_SAVE )
32573898GAME( 2004, mj2,      chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Sega Network Taisen Mahjong MJ 2 (Rev C) (GDX-0006C)", GAME_NO_SOUND|GAME_NOT_WORKING )
32583899GAME( 2004, ollie,    chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Sega",      "Ollie King (GDX-0007)", GAME_NO_SOUND|GAME_NOT_WORKING )
32593900GAME( 2004, wangmid,  chihiro, chihirogd,    chihiro, driver_device, 0, ROT0, "Namco",     "Wangan Midnight Maximum Tune (Export) (Rev B) (GDX-0009B)", GAME_NO_SOUND|GAME_NOT_WORKING )
trunk/src/mame/machine/naomigd.h
r23891r23892
1414
1515   static void static_set_tags(device_t &device, const char *_image_tag, const char *_pic_tag);
1616
17   UINT8 *memory(UINT32 &size) { size = dimm_data_size; return dimm_data; }
18
1719protected:
1820   virtual void device_start();
1921   virtual void device_reset();
trunk/src/emu/cpu/i386/i386priv.h
r23891r23892
306306   UINT8 b[32];
307307};
308308
309union X87_REG {
310   UINT64 i;
311   double f;
309union MMX_REG {
310   UINT32 d[2];
311   INT32  i[2];
312   UINT16 w[4];
313   INT16  s[4];
314   UINT8  b[8];
315   INT8   c[8];
316   float  f[2];
317   UINT64 q;
318   INT64  l;
312319};
313320
314typedef UINT64 MMX_REG;
315
316321union XMM_REG {
322   UINT8  b[16];
323   UINT16 w[8];
317324   UINT32 d[4];
318   UINT16 w[8];
319   UINT8 b[16];
320325   UINT64 q[2];
321   float f[4];
326   INT8   c[16];
327   INT16  s[8];
328   INT32  i[4];
329   INT64  l[2];
330   float  f[4];
331   double  f64[2];
322332};
323333
324334struct i386_state
r23891r23892
434444   vtlb_state *vtlb;
435445
436446   bool smm;
447   bool smi;
448   bool smi_latched;
437449   bool nmi_masked;
438450   bool nmi_latched;
439451   UINT32 smbase;
r23891r23892
496508#define SetSZPF16(x)        {cpustate->ZF = ((UINT16)(x)==0);  cpustate->SF = ((x)&0x8000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
497509#define SetSZPF32(x)        {cpustate->ZF = ((UINT32)(x)==0);  cpustate->SF = ((x)&0x80000000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
498510
499#define MMX(n)              cpustate->fpu_reg[(n)].i
511#define MMX(n)              (*((MMX_REG *)(&cpustate->x87_reg[(n)].low)))
500512#define XMM(n)              cpustate->sse_reg[(n)]
501513
502514/***********************************************************************************/
r23891r23892
866878   }
867879   return value;
868880}
881
869882INLINE UINT32 READ32PL0(i386_state *cpustate,UINT32 ea)
870883{
871884   UINT32 value;
trunk/src/emu/cpu/i386/i386ops.h
r23891r23892
298298   { 0x08,     OP_2BYTE|OP_I486,           I486OP(invd),                   I486OP(invd),               },
299299   { 0x09,     OP_2BYTE|OP_I486,           I486OP(wbinvd),                 I486OP(wbinvd),             },
300300   { 0x0B,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(ud2),                 PENTIUMOP(ud2),             },
301   { 0x10,     OP_2BYTE|OP_SSE,            SSEOP(movups_r128_rm128),       SSEOP(movups_r128_rm128),   },
302   { 0x11,     OP_2BYTE|OP_SSE,            SSEOP(movups_rm128_r128),       SSEOP(movups_rm128_r128),   },
303   { 0x12,     OP_2BYTE|OP_SSE,            SSEOP(movlps_r128_m64),         SSEOP(movlps_r128_m64),     },
304   { 0x13,     OP_2BYTE|OP_SSE,            SSEOP(movlps_m64_r128),         SSEOP(movlps_m64_r128),     },
305   { 0x14,     OP_2BYTE|OP_SSE,            SSEOP(unpcklps_r128_rm128),     SSEOP(unpcklps_r128_rm128), },
306   { 0x15,     OP_2BYTE|OP_SSE,            SSEOP(unpckhps_r128_rm128),     SSEOP(unpckhps_r128_rm128), },
307   { 0x16,     OP_2BYTE|OP_SSE,            SSEOP(movhps_r128_m64),         SSEOP(movhps_r128_m64),     },
308   { 0x17,     OP_2BYTE|OP_SSE,            SSEOP(movhps_m64_r128),         SSEOP(movhps_m64_r128),     },
309   { 0x18,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(prefetch_m8),         PENTIUMOP(prefetch_m8),     },
301310   { 0x20,     OP_2BYTE|OP_I386,           I386OP(mov_r32_cr),             I386OP(mov_r32_cr),         },
302311   { 0x21,     OP_2BYTE|OP_I386,           I386OP(mov_r32_dr),             I386OP(mov_r32_dr),         },
303312   { 0x22,     OP_2BYTE|OP_I386,           I386OP(mov_cr_r32),             I386OP(mov_cr_r32),         },
r23891r23892
307316   { 0x26,     OP_2BYTE|OP_I386,           I386OP(mov_tr_r32),             I386OP(mov_tr_r32),         },
308317   { 0x28,     OP_2BYTE|OP_SSE,            SSEOP(movaps_r128_rm128),       SSEOP(movaps_r128_rm128),   },
309318   { 0x29,     OP_2BYTE|OP_SSE,            SSEOP(movaps_rm128_r128),       SSEOP(movaps_rm128_r128),   },
319   { 0x2a,     OP_2BYTE|OP_SSE,            SSEOP(cvtpi2ps_r128_rm64),      SSEOP(cvtpi2ps_r128_rm64),  },
320   { 0x2b,     OP_2BYTE|OP_SSE,            SSEOP(movntps_m128_r128),       SSEOP(movntps_m128_r128),   },
321   { 0x2c,     OP_2BYTE|OP_SSE,            SSEOP(cvttps2pi_r64_r128m64),   SSEOP(cvttps2pi_r64_r128m64),},
322   { 0x2d,     OP_2BYTE|OP_SSE,            SSEOP(cvtps2pi_r64_r128m64),    SSEOP(cvtps2pi_r64_r128m64),},
323   { 0x2e,     OP_2BYTE|OP_SSE,            SSEOP(ucomiss_r128_r128m32),    SSEOP(ucomiss_r128_r128m32),},
324   { 0x2f,     OP_2BYTE|OP_SSE,            SSEOP(comiss_r128_r128m32),      SSEOP(comiss_r128_r128m32),   },
310325   { 0x30,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(wrmsr),               PENTIUMOP(wrmsr),           },
311326   { 0x31,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(rdtsc),               PENTIUMOP(rdtsc),           },
312327   { 0x32,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(rdmsr),               PENTIUMOP(rdmsr),           },
328   { 0x40,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovo_r16_rm16),      PENTIUMOP(cmovo_r32_rm32),   },
329   { 0x41,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovno_r16_rm16),      PENTIUMOP(cmovno_r32_rm32),   },
330   { 0x42,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovb_r16_rm16),      PENTIUMOP(cmovb_r32_rm32),   },
331   { 0x43,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovae_r16_rm16),      PENTIUMOP(cmovae_r32_rm32),   },
332   { 0x44,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmove_r16_rm16),      PENTIUMOP(cmove_r32_rm32),   },
333   { 0x45,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovne_r16_rm16),      PENTIUMOP(cmovne_r32_rm32),   },
334   { 0x46,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovbe_r16_rm16),      PENTIUMOP(cmovbe_r32_rm32),   },
335   { 0x47,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmova_r16_rm16),      PENTIUMOP(cmova_r32_rm32),   },
336   { 0x48,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovs_r16_rm16),      PENTIUMOP(cmovs_r32_rm32),   },
337   { 0x49,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovns_r16_rm16),      PENTIUMOP(cmovns_r32_rm32),   },
338   { 0x4a,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovp_r16_rm16),      PENTIUMOP(cmovp_r32_rm32),   },
339   { 0x4b,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovnp_r16_rm16),      PENTIUMOP(cmovnp_r32_rm32),   },
340   { 0x4c,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovl_r16_rm16),      PENTIUMOP(cmovl_r32_rm32),   },
341   { 0x4d,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovge_r16_rm16),      PENTIUMOP(cmovge_r32_rm32),   },
342   { 0x4e,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovle_r16_rm16),      PENTIUMOP(cmovle_r32_rm32),   },
343   { 0x4f,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmovg_r16_rm16),      PENTIUMOP(cmovg_r32_rm32),   },
344   { 0x50,     OP_2BYTE|OP_SSE,            SSEOP(movmskps_r16_r128),       SSEOP(movmskps_r32_r128),   },
345   { 0x51,     OP_2BYTE|OP_SSE,            SSEOP(sqrtps_r128_rm128),       SSEOP(sqrtps_r128_rm128),   },
346   { 0x52,     OP_2BYTE|OP_SSE,            SSEOP(rsqrtps_r128_rm128),      SSEOP(rsqrtps_r128_rm128),  },
347   { 0x53,     OP_2BYTE|OP_SSE,            SSEOP(rcpps_r128_rm128),        SSEOP(rcpps_r128_rm128),    },
348   { 0x54,     OP_2BYTE|OP_SSE,            SSEOP(andps_r128_rm128),        SSEOP(andps_r128_rm128),    },
349   { 0x55,     OP_2BYTE|OP_SSE,            SSEOP(andnps_r128_rm128),       SSEOP(andnps_r128_rm128),   },
350   { 0x56,     OP_2BYTE|OP_SSE,            SSEOP(orps_r128_rm128),         SSEOP(orps_r128_rm128),     },
351   { 0x57,     OP_2BYTE|OP_SSE,            SSEOP(xorps),                   SSEOP(xorps),               },
313352   { 0x58,     OP_2BYTE|OP_SSE,            SSEOP(addps),                   SSEOP(addps),               },
314353   { 0x59,     OP_2BYTE|OP_SSE,            SSEOP(mulps),                   SSEOP(mulps),               },
354   { 0x5a,     OP_2BYTE|OP_SSE,            SSEOP(cvtps2pd_r128_r128m64),   SSEOP(cvtps2pd_r128_r128m64),},
355   { 0x5b,     OP_2BYTE|OP_SSE,            SSEOP(cvtdq2ps_r128_rm128),     SSEOP(cvtdq2ps_r128_rm128), },
356   { 0x5c,     OP_2BYTE|OP_SSE,            SSEOP(subps),                   SSEOP(subps),               },
357   { 0x5d,     OP_2BYTE|OP_SSE,            SSEOP(minps),                   SSEOP(minps),               },
358   { 0x5e,     OP_2BYTE|OP_SSE,            SSEOP(divps),                   SSEOP(divps),               },
359   { 0x5f,     OP_2BYTE|OP_SSE,            SSEOP(maxps),                   SSEOP(maxps),               },
360   { 0x60,     OP_2BYTE|OP_MMX,            MMXOP(punpcklbw_r64_r64m32),    MMXOP(punpcklbw_r64_r64m32),},
361   { 0x61,     OP_2BYTE|OP_MMX,            MMXOP(punpcklwd_r64_r64m32),    MMXOP(punpcklwd_r64_r64m32),},
362   { 0x62,     OP_2BYTE|OP_MMX,            MMXOP(punpckldq_r64_r64m32),    MMXOP(punpckldq_r64_r64m32),},
363   { 0x63,     OP_2BYTE|OP_MMX,            MMXOP(packsswb_r64_rm64),       MMXOP(packsswb_r64_rm64),   },
364   { 0x64,     OP_2BYTE|OP_MMX,            MMXOP(pcmpgtb_r64_rm64),        MMXOP(pcmpgtb_r64_rm64),    },
365   { 0x65,     OP_2BYTE|OP_MMX,            MMXOP(pcmpgtw_r64_rm64),        MMXOP(pcmpgtw_r64_rm64),    },
366    { 0x66,     OP_2BYTE|OP_MMX,            MMXOP(pcmpgtd_r64_rm64),        MMXOP(pcmpgtd_r64_rm64),    },
367    { 0x67,     OP_2BYTE|OP_MMX,            MMXOP(packuswb_r64_rm64),       MMXOP(packuswb_r64_rm64),   },
368   { 0x68,     OP_2BYTE|OP_MMX,            MMXOP(punpckhbw_r64_rm64),      MMXOP(punpckhbw_r64_rm64),  },
369   { 0x69,     OP_2BYTE|OP_MMX,            MMXOP(punpckhwd_r64_rm64),      MMXOP(punpckhwd_r64_rm64),  },
370   { 0x6a,     OP_2BYTE|OP_MMX,            MMXOP(punpckhdq_r64_rm64),      MMXOP(punpckhdq_r64_rm64),  },
371   { 0x6b,     OP_2BYTE|OP_MMX,            MMXOP(packssdw_r64_rm64),       MMXOP(packssdw_r64_rm64),   },
372   { 0x6e,     OP_2BYTE|OP_MMX,            MMXOP(movd_r64_rm32),           MMXOP(movd_r64_rm32),       },
373   { 0x6f,     OP_2BYTE|OP_MMX,            MMXOP(movq_r64_rm64),           MMXOP(movq_r64_rm64),       },
374   { 0x70,     OP_2BYTE|OP_MMX,            MMXOP(pshufw_r64_rm64_i8),      MMXOP(pshufw_r64_rm64_i8),  },
375   { 0x71,     OP_2BYTE|OP_MMX,            MMXOP(group_0f71),              MMXOP(group_0f71),          },
376   { 0x72,     OP_2BYTE|OP_MMX,            MMXOP(group_0f72),              MMXOP(group_0f72),          },
377   { 0x73,     OP_2BYTE|OP_MMX,            MMXOP(group_0f73),              MMXOP(group_0f73),          },
315378   { 0x74,     OP_2BYTE|OP_CYRIX,          I386OP(cyrix_unknown),          I386OP(cyrix_unknown),      },
379   { 0x74,     OP_2BYTE|OP_MMX,            MMXOP(pcmpeqb_r64_rm64),        MMXOP(pcmpeqb_r64_rm64),    },
380   { 0x75,     OP_2BYTE|OP_MMX,            MMXOP(pcmpeqw_r64_rm64),        MMXOP(pcmpeqw_r64_rm64),    },
381   { 0x76,     OP_2BYTE|OP_MMX,            MMXOP(pcmpeqd_r64_rm64),        MMXOP(pcmpeqd_r64_rm64),    },
316382   { 0x77,     OP_2BYTE|OP_MMX,            MMXOP(emms),                    MMXOP(emms),                },
383   { 0x7e,     OP_2BYTE|OP_MMX,            MMXOP(movd_rm32_r64),           MMXOP(movd_rm32_r64),       },
384   { 0x7f,     OP_2BYTE|OP_MMX,            MMXOP(movq_rm64_r64),           MMXOP(movq_rm64_r64),       },
317385   { 0x80,     OP_2BYTE|OP_I386,           I386OP(jo_rel16),               I386OP(jo_rel32),           },
318386   { 0x81,     OP_2BYTE|OP_I386,           I386OP(jno_rel16),              I386OP(jno_rel32),          },
319387   { 0x82,     OP_2BYTE|OP_I386,           I386OP(jc_rel16),               I386OP(jc_rel32),           },
r23891r23892
376444   { 0xBF,     OP_2BYTE|OP_I386,           I386OP(invalid),                I386OP(movsx_r32_rm16),     },
377445   { 0xC0,     OP_2BYTE|OP_I486,           I486OP(xadd_rm8_r8),            I486OP(xadd_rm8_r8),        },
378446   { 0xC1,     OP_2BYTE|OP_I486,           I486OP(xadd_rm16_r16),          I486OP(xadd_rm32_r32),      },
379   { 0xc6,     OP_2BYTE|OP_SSE,            SSEOP(shufps),                  SSEOP(shufps),              },
447   { 0xC2,     OP_2BYTE|OP_SSE,            SSEOP(cmpps_r128_rm128_i8),      SSEOP(cmpps_r128_rm128_i8), },
448   { 0xC3,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(movnti_m16_r16),      PENTIUMOP(movnti_m32_r32),  },
449   { 0xC4,     OP_2BYTE|OP_SSE,            SSEOP(pinsrw_r64_r16m16_i8),    SSEOP(pinsrw_r64_r32m16_i8),},
450   { 0xC5,     OP_2BYTE|OP_SSE,            SSEOP(pextrw_r16_r64_i8),       SSEOP(pextrw_r32_r64_i8),   },
451   { 0xC6,     OP_2BYTE|OP_SSE,            SSEOP(shufps),                  SSEOP(shufps),              },
380452   { 0xC7,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(cmpxchg8b_m64),       PENTIUMOP(cmpxchg8b_m64),   },
381453   { 0xC8,     OP_2BYTE|OP_I486,           I486OP(bswap_eax),              I486OP(bswap_eax),          },
382454   { 0xC9,     OP_2BYTE|OP_I486,           I486OP(bswap_ecx),              I486OP(bswap_ecx),          },
r23891r23892
386458   { 0xCD,     OP_2BYTE|OP_I486,           I486OP(bswap_ebp),              I486OP(bswap_ebp),          },
387459   { 0xCE,     OP_2BYTE|OP_I486,           I486OP(bswap_esi),              I486OP(bswap_esi),          },
388460   { 0xCF,     OP_2BYTE|OP_I486,           I486OP(bswap_edi),              I486OP(bswap_edi),          },
461   { 0xD1,     OP_2BYTE|OP_MMX,            MMXOP(psrlw_r64_rm64),          MMXOP(psrlw_r64_rm64),      },
462   { 0xD2,     OP_2BYTE|OP_MMX,            MMXOP(psrld_r64_rm64),          MMXOP(psrld_r64_rm64),      },
463   { 0xD3,     OP_2BYTE|OP_MMX,            MMXOP(psrlq_r64_rm64),          MMXOP(psrlq_r64_rm64),      },
464   { 0xD4,     OP_2BYTE|OP_MMX,            MMXOP(paddq_r64_rm64),          MMXOP(paddq_r64_rm64),      },
465   { 0xD5,     OP_2BYTE|OP_MMX,            MMXOP(pmullw_r64_rm64),         MMXOP(pmullw_r64_rm64),     },
466   { 0xD7,     OP_2BYTE|OP_SSE,            SSEOP(pmovmskb_r16_r64),        SSEOP(pmovmskb_r32_r64),    },
467   { 0xD8,     OP_2BYTE|OP_MMX,            MMXOP(psubusb_r64_rm64),        MMXOP(psubusb_r64_rm64),    },
468   { 0xD9,     OP_2BYTE|OP_MMX,            MMXOP(psubusw_r64_rm64),        MMXOP(psubusw_r64_rm64),    },
469   { 0xDA,     OP_2BYTE|OP_SSE,            SSEOP(pminub_r64_rm64),         SSEOP(pminub_r64_rm64),     },
470   { 0xDB,     OP_2BYTE|OP_MMX,            MMXOP(pand_r64_rm64),           MMXOP(pand_r64_rm64),       },
471   { 0xDC,     OP_2BYTE|OP_MMX,            MMXOP(paddusb_r64_rm64),        MMXOP(paddusb_r64_rm64),    },
472   { 0xDD,     OP_2BYTE|OP_MMX,            MMXOP(paddusw_r64_rm64),        MMXOP(paddusw_r64_rm64),    },
473   { 0xDE,     OP_2BYTE|OP_SSE,            SSEOP(pmaxub_r64_rm64),         SSEOP(pmaxub_r64_rm64),     },
474   { 0xDF,     OP_2BYTE|OP_MMX,            MMXOP(pandn_r64_rm64),          MMXOP(pandn_r64_rm64),      },
475   { 0xE0,     OP_2BYTE|OP_SSE,            SSEOP(pavgb_r64_rm64),          SSEOP(pavgb_r64_rm64),      },
476   { 0xE1,     OP_2BYTE|OP_MMX,            MMXOP(psraw_r64_rm64),          MMXOP(psraw_r64_rm64),      },
477   { 0xE2,     OP_2BYTE|OP_MMX,            MMXOP(psrad_r64_rm64),          MMXOP(psrad_r64_rm64),      },
478   { 0xE3,     OP_2BYTE|OP_SSE,            SSEOP(pavgw_r64_rm64),          SSEOP(pavgw_r64_rm64),      },
479   { 0xE4,     OP_2BYTE|OP_SSE,            SSEOP(pmulhuw_r64_rm64),        SSEOP(pmulhuw_r64_rm64),    },
480   { 0xE5,     OP_2BYTE|OP_MMX,            MMXOP(pmulhw_r64_rm64),         MMXOP(pmulhw_r64_rm64),     },
481   { 0xE7,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(movntq_m64_r64),      PENTIUMOP(movntq_m64_r64),  },
482   { 0xE8,     OP_2BYTE|OP_MMX,            MMXOP(psubsb_r64_rm64),         MMXOP(psubsb_r64_rm64),     },
483   { 0xE9,     OP_2BYTE|OP_MMX,            MMXOP(psubsw_r64_rm64),         MMXOP(psubsw_r64_rm64),     },
484   { 0xEA,     OP_2BYTE|OP_SSE,            SSEOP(pminsw_r64_rm64),         SSEOP(pminsw_r64_rm64),     },
485   { 0xEB,     OP_2BYTE|OP_MMX,            MMXOP(por_r64_rm64),            MMXOP(por_r64_rm64),        },
486   { 0xEC,     OP_2BYTE|OP_MMX,            MMXOP(paddsb_r64_rm64),         MMXOP(paddsb_r64_rm64),     },
487   { 0xED,     OP_2BYTE|OP_MMX,            MMXOP(paddsw_r64_rm64),         MMXOP(paddsw_r64_rm64),     },
488   { 0xEE,     OP_2BYTE|OP_SSE,            SSEOP(pmaxsw_r64_rm64),         SSEOP(pmaxsw_r64_rm64),     },
489   { 0xEF,     OP_2BYTE|OP_MMX,            MMXOP(pxor_r64_rm64),           MMXOP(pxor_r64_rm64),       },
490   { 0xF1,     OP_2BYTE|OP_MMX,            MMXOP(psllw_r64_rm64),          MMXOP(psllw_r64_rm64),      },
491   { 0xF2,     OP_2BYTE|OP_MMX,            MMXOP(pslld_r64_rm64),          MMXOP(pslld_r64_rm64),      },
492   { 0xF3,     OP_2BYTE|OP_MMX,            MMXOP(psllq_r64_rm64),          MMXOP(psllq_r64_rm64),      },
493   { 0xF4,     OP_2BYTE|OP_SSE,            SSEOP(pmuludq_r64_rm64),        SSEOP(pmuludq_r64_rm64),    },
494   { 0xF5,     OP_2BYTE|OP_MMX,            MMXOP(pmaddwd_r64_rm64),        MMXOP(pmaddwd_r64_rm64),    },
495   { 0xF6,     OP_2BYTE|OP_SSE,            SSEOP(psadbw_r64_rm64),         SSEOP(psadbw_r64_rm64),     },
496   { 0xf7,     OP_2BYTE|OP_PENTIUM,        PENTIUMOP(maskmovq_r64_r64),    PENTIUMOP(maskmovq_r64_r64),},
497   { 0xF8,     OP_2BYTE|OP_MMX,            MMXOP(psubb_r64_rm64),          MMXOP(psubb_r64_rm64),      },
498   { 0xF9,     OP_2BYTE|OP_MMX,            MMXOP(psubw_r64_rm64),          MMXOP(psubw_r64_rm64),      },
499   { 0xFA,     OP_2BYTE|OP_MMX,            MMXOP(psubd_r64_rm64),          MMXOP(psubd_r64_rm64),      },
500   { 0xFB,     OP_2BYTE|OP_SSE,            SSEOP(psubq_r64_rm64),          SSEOP(psubq_r64_rm64),      },
501   { 0xFC,     OP_2BYTE|OP_MMX,            MMXOP(paddb_r64_rm64),          MMXOP(paddb_r64_rm64),      },
502   { 0xFD,     OP_2BYTE|OP_MMX,            MMXOP(paddw_r64_rm64),          MMXOP(paddw_r64_rm64),      },
503   { 0xFE,     OP_2BYTE|OP_MMX,            MMXOP(paddd_r64_rm64),          MMXOP(paddd_r64_rm64),      },
389504   /* F3 0F ?? */
390   { 0x2C,     OP_3BYTEF3|OP_SSE,          SSEOP(cvttss2si),               SSEOP(cvttss2si),           }
505   { 0x10,     OP_3BYTEF3|OP_SSE,          SSEOP(movss_r128_rm128),      SSEOP(movss_r128_rm128),   },
506   { 0x11,     OP_3BYTEF3|OP_SSE,          SSEOP(movss_rm128_r128),      SSEOP(movss_rm128_r128),   },
507   { 0x12,     OP_3BYTEF3|OP_SSE,          SSEOP(movsldup_r128_rm128),      SSEOP(movsldup_r128_rm128),   },
508   { 0x16,     OP_3BYTEF3|OP_SSE,          SSEOP(movshdup_r128_rm128),      SSEOP(movshdup_r128_rm128),   },
509   { 0x2A,     OP_3BYTEF3|OP_SSE,          SSEOP(cvtsi2ss_r128_rm32),      SSEOP(cvtsi2ss_r128_rm32),  },
510   { 0x2C,     OP_3BYTEF3|OP_SSE,          SSEOP(cvttss2si_r32_r128m32),   SSEOP(cvttss2si_r32_r128m32),},
511   { 0x2D,     OP_3BYTEF3|OP_SSE,          SSEOP(cvtss2si_r32_r128m32),   SSEOP(cvtss2si_r32_r128m32),},
512   { 0x51,     OP_3BYTEF3|OP_SSE,          SSEOP(sqrtss_r128_r128m32),      SSEOP(sqrtss_r128_r128m32),   },
513   { 0x52,     OP_3BYTEF3|OP_SSE,          SSEOP(rsqrtss_r128_r128m32),   SSEOP(rsqrtss_r128_r128m32),},
514   { 0x53,     OP_3BYTEF3|OP_SSE,          SSEOP(rcpss_r128_r128m32),      SSEOP(rcpss_r128_r128m32),  },
515   { 0x58,     OP_3BYTEF3|OP_SSE,          SSEOP(addss),                   SSEOP(addss),               },
516   { 0x59,     OP_3BYTEF3|OP_SSE,          SSEOP(mulss),                   SSEOP(mulss),               },
517   { 0x5A,     OP_3BYTEF3|OP_SSE,          SSEOP(cvtss2sd_r128_r128m32),   SSEOP(cvtss2sd_r128_r128m32),},
518   { 0x5B,     OP_3BYTEF3|OP_SSE,          SSEOP(cvttps2dq_r128_rm128),   SSEOP(cvttps2dq_r128_rm128),},
519   { 0x5C,     OP_3BYTEF3|OP_SSE,          SSEOP(subss),                   SSEOP(subss),               },
520   { 0x5D,     OP_3BYTEF3|OP_SSE,          SSEOP(minss_r128_r128m32),      SSEOP(minss_r128_r128m32),  },
521   { 0x5E,     OP_3BYTEF3|OP_SSE,          SSEOP(divss),                   SSEOP(divss),               },
522   { 0x5F,     OP_3BYTEF3|OP_SSE,          SSEOP(maxss_r128_r128m32),      SSEOP(maxss_r128_r128m32),   },
523   { 0x6F,     OP_3BYTEF3|OP_SSE,          SSEOP(movdqu_r128_rm128),      SSEOP(movdqu_r128_rm128),   },
524   { 0x70,     OP_3BYTEF3|OP_SSE,          SSEOP(pshufhw_r128_rm128_i8),   SSEOP(pshufhw_r128_rm128_i8),},
525   { 0x7E,     OP_3BYTEF3|OP_SSE,          SSEOP(movq_r128_r128m64),      SSEOP(movq_r128_r128m64),   },
526   { 0x7F,     OP_3BYTEF3|OP_SSE,          SSEOP(movdqu_rm128_r128),      SSEOP(movdqu_rm128_r128),   },
527   { 0xB8,     OP_3BYTEF3|OP_PENTIUM,      PENTIUMOP(popcnt_r16_rm16),      PENTIUMOP(popcnt_r32_rm32),   },
528   { 0xC2,     OP_3BYTEF3|OP_SSE,          SSEOP(cmpss_r128_r128m32_i8),   SSEOP(cmpss_r128_r128m32_i8),},
529   { 0xD6,     OP_3BYTEF3|OP_SSE,          SSEOP(movq2dq_r128_r64),      SSEOP(movq2dq_r128_r64),   },
530   { 0xE6,     OP_3BYTEF3|OP_SSE,          SSEOP(cvtdq2pd_r128_r128m64),   SSEOP(cvtdq2pd_r128_r128m64)}
391531};
trunk/src/emu/cpu/i386/pentops.c
r23891r23892
11// Pentium+ specific opcodes
22
3/* return the single precision floating point number represented by the 32 bit value */
4INLINE float FPU_INT32_SINGLE(UINT32 value)
3extern flag float32_is_nan( float32 a ); // since its not defined in softfloat.h
4
5INLINE void MMXPROLOG(i386_state *cpustate)
56{
6   float v;
7   //cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
8   cpustate->x87_tw = 0; // tag word = 0
9}
710
8   v=*((float *)&value);
9   return v;
11INLINE void READMMX(i386_state *cpustate,UINT32 ea,MMX_REG &r)
12{
13   r.q=READ64(cpustate, ea);
1014}
1115
12INLINE UINT32 FPU_SINGLE_INT32(X87_REG value)
16INLINE void WRITEMMX(i386_state *cpustate,UINT32 ea,MMX_REG &r)
1317{
14   float fs=(float)value.f;
15   UINT32 v;
18   WRITE64(cpustate, ea, r.q);
19}
1620
17   v=*((UINT32 *)(&fs));
18   return v;
21INLINE void READXMM(i386_state *cpustate,UINT32 ea,XMM_REG &r)
22{
23   r.q[0]=READ64(cpustate, ea);
24   r.q[1]=READ64(cpustate, ea+8);
1925}
2026
21INLINE void MMXPROLOG(i386_state *cpustate)
27INLINE void WRITEXMM(i386_state *cpustate,UINT32 ea,XMM_REG &r)
2228{
23   //cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
24   cpustate->x87_tw = 0; // tag word = 0
29   WRITE64(cpustate, ea, r.q[0]);
30   WRITE64(cpustate, ea+8, r.q[1]);
2531}
2632
33INLINE void READXMM_LO64(i386_state *cpustate,UINT32 ea,XMM_REG &r)
34{
35   r.q[0]=READ64(cpustate, ea);
36}
37
38INLINE void WRITEXMM_LO64(i386_state *cpustate,UINT32 ea,XMM_REG &r)
39{
40   WRITE64(cpustate, ea, r.q[0]);
41}
42
43INLINE void READXMM_HI64(i386_state *cpustate,UINT32 ea,XMM_REG &r)
44{
45   r.q[1]=READ64(cpustate, ea);
46}
47
48INLINE void WRITEXMM_HI64(i386_state *cpustate,UINT32 ea,XMM_REG &r)
49{
50   WRITE64(cpustate, ea, r.q[1]);
51}
52
2753static void PENTIUMOP(rdmsr)(i386_state *cpustate)          // Opcode 0x0f 32
2854{
2955   UINT64 data;
r23891r23892
6490   CYCLES(cpustate,CYCLES_RDTSC);
6591}
6692
67static void I386OP(cyrix_unknown)(i386_state *cpustate)     // Opcode 0x0f 74
68{
69   logerror("Unemulated 0x0f 0x74 opcode called\n");
70
71   CYCLES(cpustate,1);
72}
73
74static void PENTIUMOP(cmpxchg8b_m64)(i386_state *cpustate)  // Opcode 0x0f c7
75{
76   UINT8 modm = FETCH(cpustate);
77   if( modm >= 0xc0 ) {
78      report_invalid_modrm(cpustate, "cmpxchg8b_m64", modm);
79   } else {
80      UINT32 ea = GetEA(cpustate, modm, 0);
81      UINT64 value = READ64(cpustate,ea);
82      UINT64 edx_eax = (((UINT64) REG32(EDX)) << 32) | REG32(EAX);
83      UINT64 ecx_ebx = (((UINT64) REG32(ECX)) << 32) | REG32(EBX);
84
85      if( value == edx_eax ) {
86         WRITE64(cpustate,ea, ecx_ebx);
87         cpustate->ZF = 1;
88         CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_T);
89      } else {
90         REG32(EDX) = (UINT32) (value >> 32);
91         REG32(EAX) = (UINT32) (value >>  0);
92         cpustate->ZF = 0;
93         CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_F);
94      }
95   }
96}
97
98INLINE void READXMM(i386_state *cpustate,UINT32 ea,XMM_REG &r)
99{
100   r.q[0]=READ64(cpustate, ea);
101   r.q[1]=READ64(cpustate, ea+8);
102}
103INLINE void WRITEXMM(i386_state *cpustate,UINT32 ea,XMM_REG &r)
104{
105   WRITE64(cpustate, ea, r.q[0]);
106   WRITE64(cpustate, ea+8, r.q[1]);
107}
108
109static void SSEOP(sse_group0fae)(i386_state *cpustate)  // Opcode 0f ae
110{
111   UINT8 modm = FETCH(cpustate);
112   if( modm == 0xf8 ) {
113      logerror("Unemulated SFENCE opcode called\n");
114      CYCLES(cpustate,1); // sfence instruction
115   } else if( modm == 0xf0 ) {
116      CYCLES(cpustate,1); // mfence instruction
117   } else if( modm == 0xe8 ) {
118      CYCLES(cpustate,1); // lfence instruction
119   } else if( modm < 0xc0 ) {
120      UINT32 ea;
121      switch ( (modm & 0x38) >> 3 )
122      {
123         case 2: // ldmxcsr m32
124            ea = GetEA(cpustate, modm, 0);
125            cpustate->mxcsr = READ32(cpustate, ea);
126            break;
127         case 3: // stmxcsr m32
128            ea = GetEA(cpustate, modm, 0);
129            WRITE32(cpustate, ea, cpustate->mxcsr);
130            break;
131         case 7: // clflush m8
132            GetNonTranslatedEA(cpustate, modm, NULL);
133            break;
134         default:
135            report_invalid_modrm(cpustate, "sse_group0fae", modm);
136      }
137   } else {
138      report_invalid_modrm(cpustate, "sse_group0fae", modm);
139   }
140}
141
14293static void PENTIUMOP(ud2)(i386_state *cpustate)    // Opcode 0x0f 0b
14394{
14495   i386_trap(cpustate, 6, 0, 0);
r23891r23892
229180
230181   CHANGE_PC(cpustate,cpustate->eip);
231182   cpustate->nmi_masked = false;
183   if(cpustate->smi_latched)
184   {
185      pentium_smi(cpustate);
186      return;
187   }
232188   if(cpustate->nmi_latched)
233189   {
234190      cpustate->nmi_latched = false;
r23891r23892
236192   }
237193}
238194
239static void SSEOP(cvttss2si)(i386_state *cpustate) // Opcode f3 0f 2c
195static void PENTIUMOP(prefetch_m8)(i386_state *cpustate)    // Opcode 0x0f 18
240196{
197   UINT8 modrm = FETCH(cpustate);
198   UINT32 ea = GetEA(cpustate,modrm,0);
199   CYCLES(cpustate,1+(ea & 1)); // TODO: correct cycle count
200}
201
202static void PENTIUMOP(cmovo_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 40
203{
204   UINT16 src;
205   UINT8 modrm = FETCH(cpustate);
206
207   if (cpustate->OF == 1) {
208      if( modrm >= 0xc0 ) {
209         src = LOAD_RM16(modrm);
210         STORE_REG16(modrm, src);
211         CYCLES(cpustate,1); // TODO: correct cycle count
212      } else {
213         UINT32 ea = GetEA(cpustate,modrm,0);
214         src = READ16(cpustate,ea);
215         STORE_REG16(modrm, src);
216         CYCLES(cpustate,1); // TODO: correct cycle count
217      }
218   }
219}
220
221static void PENTIUMOP(cmovo_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 40
222{
241223   UINT32 src;
224   UINT8 modrm = FETCH(cpustate);
225
226   if (cpustate->OF == 1) {
227      if( modrm >= 0xc0 ) {
228         src = LOAD_RM32(modrm);
229         STORE_REG32(modrm, src);
230         CYCLES(cpustate,1); // TODO: correct cycle count
231      } else {
232         UINT32 ea = GetEA(cpustate,modrm,0);
233         src = READ32(cpustate,ea);
234         STORE_REG32(modrm, src);
235         CYCLES(cpustate,1); // TODO: correct cycle count
236      }
237   }
238}
239
240static void PENTIUMOP(cmovno_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 41
241{
242   UINT16 src;
243   UINT8 modrm = FETCH(cpustate);
244
245   if (cpustate->OF == 0) {
246      if( modrm >= 0xc0 ) {
247         src = LOAD_RM16(modrm);
248         STORE_REG16(modrm, src);
249         CYCLES(cpustate,1); // TODO: correct cycle count
250      } else {
251         UINT32 ea = GetEA(cpustate,modrm,0);
252         src = READ16(cpustate,ea);
253         STORE_REG16(modrm, src);
254         CYCLES(cpustate,1); // TODO: correct cycle count
255      }
256   }
257}
258
259static void PENTIUMOP(cmovno_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 41
260{
261   UINT32 src;
262   UINT8 modrm = FETCH(cpustate);
263
264   if (cpustate->OF == 0) {
265      if( modrm >= 0xc0 ) {
266         src = LOAD_RM32(modrm);
267         STORE_REG32(modrm, src);
268         CYCLES(cpustate,1); // TODO: correct cycle count
269      } else {
270         UINT32 ea = GetEA(cpustate,modrm,0);
271         src = READ32(cpustate,ea);
272         STORE_REG32(modrm, src);
273         CYCLES(cpustate,1); // TODO: correct cycle count
274      }
275   }
276}
277
278static void PENTIUMOP(cmovb_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 42
279{
280   UINT16 src;
281   UINT8 modrm = FETCH(cpustate);
282
283   if (cpustate->CF == 1) {
284      if( modrm >= 0xc0 ) {
285         src = LOAD_RM16(modrm);
286         STORE_REG16(modrm, src);
287         CYCLES(cpustate,1); // TODO: correct cycle count
288      } else {
289         UINT32 ea = GetEA(cpustate,modrm,0);
290         src = READ16(cpustate,ea);
291         STORE_REG16(modrm, src);
292         CYCLES(cpustate,1); // TODO: correct cycle count
293      }
294   }
295}
296
297static void PENTIUMOP(cmovb_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 42
298{
299   UINT32 src;
300   UINT8 modrm = FETCH(cpustate);
301
302   if (cpustate->CF == 1) {
303      if( modrm >= 0xc0 ) {
304         src = LOAD_RM32(modrm);
305         STORE_REG32(modrm, src);
306         CYCLES(cpustate,1); // TODO: correct cycle count
307      } else {
308         UINT32 ea = GetEA(cpustate,modrm,0);
309         src = READ32(cpustate,ea);
310         STORE_REG32(modrm, src);
311         CYCLES(cpustate,1); // TODO: correct cycle count
312      }
313   }
314}
315
316static void PENTIUMOP(cmovae_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 43
317{
318   UINT16 src;
319   UINT8 modrm = FETCH(cpustate);
320
321   if (cpustate->CF == 0) {
322      if( modrm >= 0xc0 ) {
323         src = LOAD_RM16(modrm);
324         STORE_REG16(modrm, src);
325         CYCLES(cpustate,1); // TODO: correct cycle count
326      } else {
327         UINT32 ea = GetEA(cpustate,modrm,0);
328         src = READ16(cpustate,ea);
329         STORE_REG16(modrm, src);
330         CYCLES(cpustate,1); // TODO: correct cycle count
331      }
332   }
333}
334
335static void PENTIUMOP(cmovae_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 43
336{
337   UINT32 src;
338   UINT8 modrm = FETCH(cpustate);
339
340   if (cpustate->CF == 0) {
341      if( modrm >= 0xc0 ) {
342         src = LOAD_RM32(modrm);
343         STORE_REG32(modrm, src);
344         CYCLES(cpustate,1); // TODO: correct cycle count
345      } else {
346         UINT32 ea = GetEA(cpustate,modrm,0);
347         src = READ32(cpustate,ea);
348         STORE_REG32(modrm, src);
349         CYCLES(cpustate,1); // TODO: correct cycle count
350      }
351   }
352}
353
354static void PENTIUMOP(cmove_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 44
355{
356   UINT16 src;
357   UINT8 modrm = FETCH(cpustate);
358
359   if (cpustate->ZF == 1) {
360      if( modrm >= 0xc0 ) {
361         src = LOAD_RM16(modrm);
362         STORE_REG16(modrm, src);
363         CYCLES(cpustate,1); // TODO: correct cycle count
364      } else {
365         UINT32 ea = GetEA(cpustate,modrm,0);
366         src = READ16(cpustate,ea);
367         STORE_REG16(modrm, src);
368         CYCLES(cpustate,1); // TODO: correct cycle count
369      }
370   }
371}
372
373static void PENTIUMOP(cmove_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 44
374{
375   UINT32 src;
376   UINT8 modrm = FETCH(cpustate);
377
378   if (cpustate->ZF == 1) {
379      if( modrm >= 0xc0 ) {
380         src = LOAD_RM32(modrm);
381         STORE_REG32(modrm, src);
382         CYCLES(cpustate,1); // TODO: correct cycle count
383      } else {
384         UINT32 ea = GetEA(cpustate,modrm,0);
385         src = READ32(cpustate,ea);
386         STORE_REG32(modrm, src);
387         CYCLES(cpustate,1); // TODO: correct cycle count
388      }
389   }
390}
391
392static void PENTIUMOP(cmovne_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 45
393{
394   UINT16 src;
395   UINT8 modrm = FETCH(cpustate);
396
397   if (cpustate->ZF == 0) {
398      if( modrm >= 0xc0 ) {
399         src = LOAD_RM16(modrm);
400         STORE_REG16(modrm, src);
401         CYCLES(cpustate,1); // TODO: correct cycle count
402      } else {
403         UINT32 ea = GetEA(cpustate,modrm,0);
404         src = READ16(cpustate,ea);
405         STORE_REG16(modrm, src);
406         CYCLES(cpustate,1); // TODO: correct cycle count
407      }
408   }
409}
410
411static void PENTIUMOP(cmovne_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 45
412{
413   UINT32 src;
414   UINT8 modrm = FETCH(cpustate);
415
416   if (cpustate->ZF == 0) {
417      if( modrm >= 0xc0 ) {
418         src = LOAD_RM32(modrm);
419         STORE_REG32(modrm, src);
420         CYCLES(cpustate,1); // TODO: correct cycle count
421      } else {
422         UINT32 ea = GetEA(cpustate,modrm,0);
423         src = READ32(cpustate,ea);
424         STORE_REG32(modrm, src);
425         CYCLES(cpustate,1); // TODO: correct cycle count
426      }
427   }
428}
429
430static void PENTIUMOP(cmovbe_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 46
431{
432   UINT16 src;
433   UINT8 modrm = FETCH(cpustate);
434
435   if ((cpustate->CF == 1) || (cpustate->ZF == 1)) {
436      if( modrm >= 0xc0 ) {
437         src = LOAD_RM16(modrm);
438         STORE_REG16(modrm, src);
439         CYCLES(cpustate,1); // TODO: correct cycle count
440      } else {
441         UINT32 ea = GetEA(cpustate,modrm,0);
442         src = READ16(cpustate,ea);
443         STORE_REG16(modrm, src);
444         CYCLES(cpustate,1); // TODO: correct cycle count
445      }
446   }
447}
448
449static void PENTIUMOP(cmovbe_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 46
450{
451   UINT32 src;
452   UINT8 modrm = FETCH(cpustate);
453
454   if ((cpustate->CF == 1) || (cpustate->ZF == 1)) {
455      if( modrm >= 0xc0 ) {
456         src = LOAD_RM32(modrm);
457         STORE_REG32(modrm, src);
458         CYCLES(cpustate,1); // TODO: correct cycle count
459      } else {
460         UINT32 ea = GetEA(cpustate,modrm,0);
461         src = READ32(cpustate,ea);
462         STORE_REG32(modrm, src);
463         CYCLES(cpustate,1); // TODO: correct cycle count
464      }
465   }
466}
467
468static void PENTIUMOP(cmova_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 47
469{
470   UINT16 src;
471   UINT8 modrm = FETCH(cpustate);
472
473   if ((cpustate->CF == 0) && (cpustate->ZF == 0)) {
474      if( modrm >= 0xc0 ) {
475         src = LOAD_RM16(modrm);
476         STORE_REG16(modrm, src);
477         CYCLES(cpustate,1); // TODO: correct cycle count
478      } else {
479         UINT32 ea = GetEA(cpustate,modrm,0);
480         src = READ16(cpustate,ea);
481         STORE_REG16(modrm, src);
482         CYCLES(cpustate,1); // TODO: correct cycle count
483      }
484   }
485}
486
487static void PENTIUMOP(cmova_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 47
488{
489   UINT32 src;
490   UINT8 modrm = FETCH(cpustate);
491
492   if ((cpustate->CF == 0) && (cpustate->ZF == 0)) {
493      if( modrm >= 0xc0 ) {
494         src = LOAD_RM32(modrm);
495         STORE_REG32(modrm, src);
496         CYCLES(cpustate,1); // TODO: correct cycle count
497      } else {
498         UINT32 ea = GetEA(cpustate,modrm,0);
499         src = READ32(cpustate,ea);
500         STORE_REG32(modrm, src);
501         CYCLES(cpustate,1); // TODO: correct cycle count
502      }
503   }
504}
505
506static void PENTIUMOP(cmovs_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 48
507{
508   UINT16 src;
509   UINT8 modrm = FETCH(cpustate);
510
511   if (cpustate->SF == 1) {
512      if( modrm >= 0xc0 ) {
513         src = LOAD_RM16(modrm);
514         STORE_REG16(modrm, src);
515         CYCLES(cpustate,1); // TODO: correct cycle count
516      } else {
517         UINT32 ea = GetEA(cpustate,modrm,0);
518         src = READ16(cpustate,ea);
519         STORE_REG16(modrm, src);
520         CYCLES(cpustate,1); // TODO: correct cycle count
521      }
522   }
523}
524
525static void PENTIUMOP(cmovs_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 48
526{
527   UINT32 src;
528   UINT8 modrm = FETCH(cpustate);
529
530   if (cpustate->SF == 1) {
531      if( modrm >= 0xc0 ) {
532         src = LOAD_RM32(modrm);
533         STORE_REG32(modrm, src);
534         CYCLES(cpustate,1); // TODO: correct cycle count
535      } else {
536         UINT32 ea = GetEA(cpustate,modrm,0);
537         src = READ32(cpustate,ea);
538         STORE_REG32(modrm, src);
539         CYCLES(cpustate,1); // TODO: correct cycle count
540      }
541   }
542}
543
544static void PENTIUMOP(cmovns_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 49
545{
546   UINT16 src;
547   UINT8 modrm = FETCH(cpustate);
548
549   if (cpustate->SF == 0) {
550      if( modrm >= 0xc0 ) {
551         src = LOAD_RM16(modrm);
552         STORE_REG16(modrm, src);
553         CYCLES(cpustate,1); // TODO: correct cycle count
554      } else {
555         UINT32 ea = GetEA(cpustate,modrm,0);
556         src = READ16(cpustate,ea);
557         STORE_REG16(modrm, src);
558         CYCLES(cpustate,1); // TODO: correct cycle count
559      }
560   }
561}
562
563static void PENTIUMOP(cmovns_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 49
564{
565   UINT32 src;
566   UINT8 modrm = FETCH(cpustate);
567
568   if (cpustate->SF == 0) {
569      if( modrm >= 0xc0 ) {
570         src = LOAD_RM32(modrm);
571         STORE_REG32(modrm, src);
572         CYCLES(cpustate,1); // TODO: correct cycle count
573      } else {
574         UINT32 ea = GetEA(cpustate,modrm,0);
575         src = READ32(cpustate,ea);
576         STORE_REG32(modrm, src);
577         CYCLES(cpustate,1); // TODO: correct cycle count
578      }
579   }
580}
581
582static void PENTIUMOP(cmovp_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4a
583{
584   UINT16 src;
585   UINT8 modrm = FETCH(cpustate);
586
587   if (cpustate->PF == 1) {
588      if( modrm >= 0xc0 ) {
589         src = LOAD_RM16(modrm);
590         STORE_REG16(modrm, src);
591         CYCLES(cpustate,1); // TODO: correct cycle count
592      } else {
593         UINT32 ea = GetEA(cpustate,modrm,0);
594         src = READ16(cpustate,ea);
595         STORE_REG16(modrm, src);
596         CYCLES(cpustate,1); // TODO: correct cycle count
597      }
598   }
599}
600
601static void PENTIUMOP(cmovp_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4a
602{
603   UINT32 src;
604   UINT8 modrm = FETCH(cpustate);
605
606   if (cpustate->PF == 1) {
607      if( modrm >= 0xc0 ) {
608         src = LOAD_RM32(modrm);
609         STORE_REG32(modrm, src);
610         CYCLES(cpustate,1); // TODO: correct cycle count
611      } else {
612         UINT32 ea = GetEA(cpustate,modrm,0);
613         src = READ32(cpustate,ea);
614         STORE_REG32(modrm, src);
615         CYCLES(cpustate,1); // TODO: correct cycle count
616      }
617   }
618}
619
620static void PENTIUMOP(cmovnp_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4b
621{
622   UINT16 src;
623   UINT8 modrm = FETCH(cpustate);
624
625   if (cpustate->PF == 0) {
626      if( modrm >= 0xc0 ) {
627         src = LOAD_RM16(modrm);
628         STORE_REG16(modrm, src);
629         CYCLES(cpustate,1); // TODO: correct cycle count
630      } else {
631         UINT32 ea = GetEA(cpustate,modrm,0);
632         src = READ16(cpustate,ea);
633         STORE_REG16(modrm, src);
634         CYCLES(cpustate,1); // TODO: correct cycle count
635      }
636   }
637}
638
639static void PENTIUMOP(cmovnp_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4b
640{
641   UINT32 src;
642   UINT8 modrm = FETCH(cpustate);
643
644   if (cpustate->PF == 0) {
645      if( modrm >= 0xc0 ) {
646         src = LOAD_RM32(modrm);
647         STORE_REG32(modrm, src);
648         CYCLES(cpustate,1); // TODO: correct cycle count
649      } else {
650         UINT32 ea = GetEA(cpustate,modrm,0);
651         src = READ32(cpustate,ea);
652         STORE_REG32(modrm, src);
653         CYCLES(cpustate,1); // TODO: correct cycle count
654      }
655   }
656}
657
658static void PENTIUMOP(cmovl_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4c
659{
660   UINT16 src;
661   UINT8 modrm = FETCH(cpustate);
662
663   if (cpustate->SF != cpustate->OF) {
664      if( modrm >= 0xc0 ) {
665         src = LOAD_RM16(modrm);
666         STORE_REG16(modrm, src);
667         CYCLES(cpustate,1); // TODO: correct cycle count
668      } else {
669         UINT32 ea = GetEA(cpustate,modrm,0);
670         src = READ16(cpustate,ea);
671         STORE_REG16(modrm, src);
672         CYCLES(cpustate,1); // TODO: correct cycle count
673      }
674   }
675}
676
677static void PENTIUMOP(cmovl_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4c
678{
679   UINT32 src;
680   UINT8 modrm = FETCH(cpustate);
681
682   if (cpustate->SF != cpustate->OF) {
683      if( modrm >= 0xc0 ) {
684         src = LOAD_RM32(modrm);
685         STORE_REG32(modrm, src);
686         CYCLES(cpustate,1); // TODO: correct cycle count
687      } else {
688         UINT32 ea = GetEA(cpustate,modrm,0);
689         src = READ32(cpustate,ea);
690         STORE_REG32(modrm, src);
691         CYCLES(cpustate,1); // TODO: correct cycle count
692      }
693   }
694}
695
696static void PENTIUMOP(cmovge_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4d
697{
698   UINT16 src;
699   UINT8 modrm = FETCH(cpustate);
700
701   if (cpustate->SF == cpustate->OF) {
702      if( modrm >= 0xc0 ) {
703         src = LOAD_RM16(modrm);
704         STORE_REG16(modrm, src);
705         CYCLES(cpustate,1); // TODO: correct cycle count
706      } else {
707         UINT32 ea = GetEA(cpustate,modrm,0);
708         src = READ16(cpustate,ea);
709         STORE_REG16(modrm, src);
710         CYCLES(cpustate,1); // TODO: correct cycle count
711      }
712   }
713}
714
715static void PENTIUMOP(cmovge_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4d
716{
717   UINT32 src;
718   UINT8 modrm = FETCH(cpustate);
719
720   if (cpustate->SF == cpustate->OF) {
721      if( modrm >= 0xc0 ) {
722         src = LOAD_RM32(modrm);
723         STORE_REG32(modrm, src);
724         CYCLES(cpustate,1); // TODO: correct cycle count
725      } else {
726         UINT32 ea = GetEA(cpustate,modrm,0);
727         src = READ32(cpustate,ea);
728         STORE_REG32(modrm, src);
729         CYCLES(cpustate,1); // TODO: correct cycle count
730      }
731   }
732}
733
734static void PENTIUMOP(cmovle_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4e
735{
736   UINT16 src;
737   UINT8 modrm = FETCH(cpustate);
738
739   if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF)) {
740      if( modrm >= 0xc0 ) {
741         src = LOAD_RM16(modrm);
742         STORE_REG16(modrm, src);
743         CYCLES(cpustate,1); // TODO: correct cycle count
744      } else {
745         UINT32 ea = GetEA(cpustate,modrm,0);
746         src = READ16(cpustate,ea);
747         STORE_REG16(modrm, src);
748         CYCLES(cpustate,1); // TODO: correct cycle count
749      }
750   }
751}
752
753static void PENTIUMOP(cmovle_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4e
754{
755   UINT32 src;
756   UINT8 modrm = FETCH(cpustate);
757
758   if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF)) {
759      if( modrm >= 0xc0 ) {
760         src = LOAD_RM32(modrm);
761         STORE_REG32(modrm, src);
762         CYCLES(cpustate,1); // TODO: correct cycle count
763      } else {
764         UINT32 ea = GetEA(cpustate,modrm,0);
765         src = READ32(cpustate,ea);
766         STORE_REG32(modrm, src);
767         CYCLES(cpustate,1); // TODO: correct cycle count
768      }
769   }
770}
771
772static void PENTIUMOP(cmovg_r16_rm16)(i386_state *cpustate)    // Opcode 0x0f 4f
773{
774   UINT16 src;
775   UINT8 modrm = FETCH(cpustate);
776
777   if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF)) {
778      if( modrm >= 0xc0 ) {
779         src = LOAD_RM16(modrm);
780         STORE_REG16(modrm, src);
781         CYCLES(cpustate,1); // TODO: correct cycle count
782      } else {
783         UINT32 ea = GetEA(cpustate,modrm,0);
784         src = READ16(cpustate,ea);
785         STORE_REG16(modrm, src);
786         CYCLES(cpustate,1); // TODO: correct cycle count
787      }
788   }
789}
790
791static void PENTIUMOP(cmovg_r32_rm32)(i386_state *cpustate)    // Opcode 0x0f 4f
792{
793   UINT32 src;
794   UINT8 modrm = FETCH(cpustate);
795
796   if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF)) {
797      if( modrm >= 0xc0 ) {
798         src = LOAD_RM32(modrm);
799         STORE_REG32(modrm, src);
800         CYCLES(cpustate,1); // TODO: correct cycle count
801      } else {
802         UINT32 ea = GetEA(cpustate,modrm,0);
803         src = READ32(cpustate,ea);
804         STORE_REG32(modrm, src);
805         CYCLES(cpustate,1); // TODO: correct cycle count
806      }
807   }
808}
809
810static void PENTIUMOP(movnti_m16_r16)(i386_state *cpustate) // Opcode 0f c3
811{
812   UINT8 modrm = FETCH(cpustate);
813   if( modrm >= 0xc0 ) {
814      // unsupported by cpu
815      CYCLES(cpustate,1);     // TODO: correct cycle count
816   } else {
817      // since cache is not implemented
818      UINT32 ea = GetEA(cpustate, modrm, 0);
819      WRITE16(cpustate,ea,LOAD_RM16(modrm));
820      CYCLES(cpustate,1);     // TODO: correct cycle count
821   }
822}
823
824static void PENTIUMOP(movnti_m32_r32)(i386_state *cpustate) // Opcode 0f c3
825{
826   UINT8 modrm = FETCH(cpustate);
827   if( modrm >= 0xc0 ) {
828      // unsupported by cpu
829      CYCLES(cpustate,1);     // TODO: correct cycle count
830   } else {
831      // since cache is not implemented
832      UINT32 ea = GetEA(cpustate, modrm, 0);
833      WRITE32(cpustate,ea,LOAD_RM32(modrm));
834      CYCLES(cpustate,1);     // TODO: correct cycle count
835   }
836}
837
838static void I386OP(cyrix_unknown)(i386_state *cpustate)     // Opcode 0x0f 74
839{
840   logerror("Unemulated 0x0f 0x74 opcode called\n");
841
842   CYCLES(cpustate,1);
843}
844
845static void PENTIUMOP(cmpxchg8b_m64)(i386_state *cpustate)  // Opcode 0x0f c7
846{
847   UINT8 modm = FETCH(cpustate);
848   if( modm >= 0xc0 ) {
849      report_invalid_modrm(cpustate, "cmpxchg8b_m64", modm);
850   } else {
851      UINT32 ea = GetEA(cpustate, modm, 0);
852      UINT64 value = READ64(cpustate,ea);
853      UINT64 edx_eax = (((UINT64) REG32(EDX)) << 32) | REG32(EAX);
854      UINT64 ecx_ebx = (((UINT64) REG32(ECX)) << 32) | REG32(EBX);
855
856      if( value == edx_eax ) {
857         WRITE64(cpustate,ea, ecx_ebx);
858         cpustate->ZF = 1;
859         CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_T);
860      } else {
861         REG32(EDX) = (UINT32) (value >> 32);
862         REG32(EAX) = (UINT32) (value >>  0);
863         cpustate->ZF = 0;
864         CYCLES(cpustate,CYCLES_CMPXCHG_REG_MEM_F);
865      }
866   }
867}
868
869static void PENTIUMOP(movntq_m64_r64)(i386_state *cpustate) // Opcode 0f e7
870{
871   //MMXPROLOG(cpustate); // TODO: check if needed
872   UINT8 modrm = FETCH(cpustate);
873   if( modrm >= 0xc0 ) {
874      CYCLES(cpustate,1);     // unsupported
875   } else {
876      // since cache is not implemented
877      UINT32 ea = GetEA(cpustate, modrm, 0);
878      WRITEMMX(cpustate, ea, MMX((modrm >> 3) & 0x7));
879      CYCLES(cpustate,1);     // TODO: correct cycle count
880   }
881}
882
883static void PENTIUMOP(maskmovq_r64_r64)(i386_state *cpustate)  // Opcode 0f f7
884{
885   int s,m,n;
886   UINT8 modm = FETCH(cpustate);
887   UINT32 ea = GetEA(cpustate, 7, 0); // ds:di/edi/rdi register
888   MMXPROLOG(cpustate);
889   s=(modm >> 3) & 7;
890   m=modm & 7;
891   for (n=0;n <= 7;n++)
892      if (MMX(m).b[n] & 127)
893         WRITE8(cpustate, ea+n, MMX(s).b[n]);
894}
895
896static void PENTIUMOP(popcnt_r16_rm16)(i386_state *cpustate)    // Opcode f3 0f b8
897{
898   UINT16 src;
899   UINT8 modrm = FETCH(cpustate);
900   int n,count;
901
902   if( modrm >= 0xc0 ) {
903      src = LOAD_RM16(modrm);
904   } else {
905      UINT32 ea = GetEA(cpustate,modrm,0);
906      src = READ16(cpustate,ea);
907   }
908   count=0;
909   for (n=0;n < 16;n++) {
910      count=count+(src & 1);
911      src=src >> 1;
912   }
913   STORE_REG16(modrm, count);
914   CYCLES(cpustate,1); // TODO: correct cycle count
915}
916
917static void PENTIUMOP(popcnt_r32_rm32)(i386_state *cpustate)    // Opcode f3 0f b8
918{
919   UINT32 src;
920   UINT8 modrm = FETCH(cpustate);
921   int n,count;
922
923   if( modrm >= 0xc0 ) {
924      src = LOAD_RM32(modrm);
925   } else {
926      UINT32 ea = GetEA(cpustate,modrm,0);
927      src = READ32(cpustate,ea);
928   }
929   count=0;
930   for (n=0;n < 32;n++) {
931      count=count+(src & 1);
932      src=src >> 1;
933   }
934   STORE_REG32(modrm, count);
935   CYCLES(cpustate,1); // TODO: correct cycle count
936}
937
938INLINE INT8 SaturatedSignedWordToSignedByte(INT16 word)
939{
940   if (word > 127)
941      return 127;
942   if (word < -128)
943      return -128;
944   return (INT8)word;
945}
946
947INLINE UINT8 SaturatedSignedWordToUnsignedByte(INT16 word)
948{
949   if (word > 255)
950      return 255;
951   if (word < 0)
952      return 0;
953   return (UINT8)word;
954}
955
956INLINE INT16 SaturatedSignedDwordToSignedWord(INT32 dword)
957{
958   if (dword > 32767)
959      return 32767;
960   if (dword < -32768)
961      return -32768;
962   return (INT16)dword;
963}
964
965static void MMXOP(group_0f71)(i386_state *cpustate)  // Opcode 0f 71
966{
967   UINT8 modm = FETCH(cpustate);
968   UINT8 imm8 = FETCH(cpustate);
969   MMXPROLOG(cpustate);
970   if( modm >= 0xc0 ) {
971      switch ( (modm & 0x38) >> 3 )
972      {
973         case 2: // psrlw
974            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] >> imm8;
975            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] >> imm8;
976            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] >> imm8;
977            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] >> imm8;
978            break;
979         case 4: // psraw
980            MMX(modm & 7).s[0]=MMX(modm & 7).s[0] >> imm8;
981            MMX(modm & 7).s[1]=MMX(modm & 7).s[1] >> imm8;
982            MMX(modm & 7).s[2]=MMX(modm & 7).s[2] >> imm8;
983            MMX(modm & 7).s[3]=MMX(modm & 7).s[3] >> imm8;
984            break;
985         case 6: // psllw
986            MMX(modm & 7).w[0]=MMX(modm & 7).w[0] << imm8;
987            MMX(modm & 7).w[1]=MMX(modm & 7).w[1] << imm8;
988            MMX(modm & 7).w[2]=MMX(modm & 7).w[2] << imm8;
989            MMX(modm & 7).w[3]=MMX(modm & 7).w[3] << imm8;
990            break;
991         default:
992            report_invalid_modrm(cpustate, "mmx_group0f71", modm);
993      }
994   }
995}
996
997static void MMXOP(group_0f72)(i386_state *cpustate)  // Opcode 0f 72
998{
999   UINT8 modm = FETCH(cpustate);
1000   UINT8 imm8 = FETCH(cpustate);
1001   MMXPROLOG(cpustate);
1002   if( modm >= 0xc0 ) {
1003      switch ( (modm & 0x38) >> 3 )
1004      {
1005         case 2: // psrld
1006            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] >> imm8;
1007            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] >> imm8;
1008            break;
1009         case 4: // psrad
1010            MMX(modm & 7).i[0]=MMX(modm & 7).i[0] >> imm8;
1011            MMX(modm & 7).i[1]=MMX(modm & 7).i[1] >> imm8;
1012            break;
1013         case 6: // pslld
1014            MMX(modm & 7).d[0]=MMX(modm & 7).d[0] << imm8;
1015            MMX(modm & 7).d[1]=MMX(modm & 7).d[1] << imm8;
1016            break;
1017         default:
1018            report_invalid_modrm(cpustate, "mmx_group0f72", modm);
1019      }
1020   }
1021}
1022
1023static void MMXOP(group_0f73)(i386_state *cpustate)  // Opcode 0f 73
1024{
1025   UINT8 modm = FETCH(cpustate);
1026   UINT8 imm8 = FETCH(cpustate);
1027   MMXPROLOG(cpustate);
1028   if( modm >= 0xc0 ) {
1029      switch ( (modm & 0x38) >> 3 )
1030      {
1031         case 2: // psrlq
1032            MMX(modm & 7).q=MMX(modm & 7).q >> imm8;
1033            break;
1034         case 6: // psllq
1035            MMX(modm & 7).q=MMX(modm & 7).q << imm8;
1036            break;
1037         default:
1038            report_invalid_modrm(cpustate, "mmx_group0f73", modm);
1039      }
1040   }
1041}
1042
1043static void MMXOP(psrlw_r64_rm64)(i386_state *cpustate)  // Opcode 0f d1
1044{
1045   MMXPROLOG(cpustate);
1046   UINT8 modrm = FETCH(cpustate);
1047   if( modrm >= 0xc0 ) {
1048      int count=(int)MMX(modrm & 7).q;
1049      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1050      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1051      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1052      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1053   } else {
1054      MMX_REG src;
1055      UINT32 ea = GetEA(cpustate, modrm, 0);
1056      READMMX(cpustate, ea, src);
1057      int count=(int)src.q;
1058      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
1059      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
1060      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
1061      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
1062   }
1063   CYCLES(cpustate,1);     // TODO: correct cycle count
1064}
1065
1066static void MMXOP(psrld_r64_rm64)(i386_state *cpustate)  // Opcode 0f d2
1067{
1068   MMXPROLOG(cpustate);
1069   UINT8 modrm = FETCH(cpustate);
1070   if( modrm >= 0xc0 ) {
1071      int count=(int)MMX(modrm & 7).q;
1072      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1073      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1074   } else {
1075      MMX_REG src;
1076      UINT32 ea = GetEA(cpustate, modrm, 0);
1077      READMMX(cpustate, ea, src);
1078      int count=(int)src.q;
1079      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
1080      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
1081   }
1082   CYCLES(cpustate,1);     // TODO: correct cycle count
1083}
1084
1085static void MMXOP(psrlq_r64_rm64)(i386_state *cpustate)  // Opcode 0f d3
1086{
1087   MMXPROLOG(cpustate);
1088   UINT8 modrm = FETCH(cpustate);
1089   if( modrm >= 0xc0 ) {
1090      int count=(int)MMX(modrm & 7).q;
1091      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1092   } else {
1093      MMX_REG src;
1094      UINT32 ea = GetEA(cpustate, modrm, 0);
1095      READMMX(cpustate, ea, src);
1096      int count=(int)src.q;
1097      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
1098   }
1099   CYCLES(cpustate,1);     // TODO: correct cycle count
1100}
1101
1102static void MMXOP(paddq_r64_rm64)(i386_state *cpustate)  // Opcode 0f d4
1103{
1104   MMXPROLOG(cpustate);
1105   UINT8 modrm = FETCH(cpustate);
1106   if( modrm >= 0xc0 ) {
1107      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+MMX(modrm & 7).q;
1108   } else {
1109      MMX_REG src;
1110      UINT32 ea = GetEA(cpustate, modrm, 0);
1111      READMMX(cpustate, ea, src);
1112      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+src.q;
1113   }
1114   CYCLES(cpustate,1);     // TODO: correct cycle count
1115}
1116
1117static void MMXOP(pmullw_r64_rm64)(i386_state *cpustate)  // Opcode 0f d5
1118{
1119   MMXPROLOG(cpustate);
1120   UINT8 modrm = FETCH(cpustate);
1121   if( modrm >= 0xc0 ) {
1122      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) & 0xffff;
1123      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) & 0xffff;
1124      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) & 0xffff;
1125      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) & 0xffff;
1126   } else {
1127      MMX_REG src;
1128      UINT32 ea = GetEA(cpustate, modrm, 0);
1129      READMMX(cpustate, ea, src);
1130      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) & 0xffff;
1131      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) & 0xffff;
1132      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) & 0xffff;
1133      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) & 0xffff;
1134   }
1135   CYCLES(cpustate,1);     // TODO: correct cycle count
1136}
1137
1138static void MMXOP(psubusb_r64_rm64)(i386_state *cpustate)  // Opcode 0f d8
1139{
1140   int n;
1141   MMXPROLOG(cpustate);
1142   UINT8 modrm = FETCH(cpustate);
1143   if( modrm >= 0xc0 ) {
1144      for (n=0;n < 8;n++)
1145         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 7).b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-MMX(modrm & 7).b[n];
1146   } else {
1147      MMX_REG src;
1148      UINT32 ea = GetEA(cpustate, modrm, 0);
1149      READMMX(cpustate, ea, src);
1150      for (n=0;n < 8;n++)
1151         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-src.b[n];
1152   }
1153   CYCLES(cpustate,1);     // TODO: correct cycle count
1154}
1155
1156static void MMXOP(psubusw_r64_rm64)(i386_state *cpustate)  // Opcode 0f d9
1157{
1158   int n;
1159   MMXPROLOG(cpustate);
1160   UINT8 modrm = FETCH(cpustate);
1161   if( modrm >= 0xc0 ) {
1162      for (n=0;n < 4;n++)
1163         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < MMX(modrm & 7).w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-MMX(modrm & 7).w[n];
1164   } else {
1165      MMX_REG src;
1166      UINT32 ea = GetEA(cpustate, modrm, 0);
1167      READMMX(cpustate, ea, src);
1168      for (n=0;n < 4;n++)
1169         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-src.w[n];
1170   }
1171   CYCLES(cpustate,1);     // TODO: correct cycle count
1172}
1173
1174static void MMXOP(pand_r64_rm64)(i386_state *cpustate)  // Opcode 0f db
1175{
1176   MMXPROLOG(cpustate);
1177   UINT8 modrm = FETCH(cpustate);
1178   if( modrm >= 0xc0 ) {
1179      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & MMX(modrm & 7).q;
1180   } else {
1181      MMX_REG src;
1182      UINT32 ea = GetEA(cpustate, modrm, 0);
1183      READMMX(cpustate, ea, src);
1184      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & src.q;
1185   }
1186   CYCLES(cpustate,1);     // TODO: correct cycle count
1187}
1188
1189static void MMXOP(paddusb_r64_rm64)(i386_state *cpustate)  // Opcode 0f dc
1190{
1191   int n;
1192   MMXPROLOG(cpustate);
1193   UINT8 modrm = FETCH(cpustate);
1194   if( modrm >= 0xc0 ) {
1195      for (n=0;n < 8;n++)
1196         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-MMX(modrm & 7).b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+MMX(modrm & 7).b[n];
1197   } else {
1198      MMX_REG src;
1199      UINT32 ea = GetEA(cpustate, modrm, 0);
1200      READMMX(cpustate, ea, src);
1201      for (n=0;n < 8;n++)
1202         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+src.b[n];
1203   }
1204   CYCLES(cpustate,1);     // TODO: correct cycle count
1205}
1206
1207static void MMXOP(paddusw_r64_rm64)(i386_state *cpustate)  // Opcode 0f dd
1208{
1209   int n;
1210   MMXPROLOG(cpustate);
1211   UINT8 modrm = FETCH(cpustate);
1212   if( modrm >= 0xc0 ) {
1213      for (n=0;n < 4;n++)
1214         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-MMX(modrm & 7).w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+MMX(modrm & 7).w[n];
1215   } else {
1216      MMX_REG src;
1217      UINT32 ea = GetEA(cpustate, modrm, 0);
1218      READMMX(cpustate, ea, src);
1219      for (n=0;n < 4;n++)
1220         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+src.w[n];
1221   }
1222   CYCLES(cpustate,1);     // TODO: correct cycle count
1223}
1224
1225static void MMXOP(pandn_r64_rm64)(i386_state *cpustate)  // Opcode 0f df
1226{
1227   MMXPROLOG(cpustate);
1228   UINT8 modrm = FETCH(cpustate);
1229   if( modrm >= 0xc0 ) {
1230      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & MMX(modrm & 7).q;
1231   } else {
1232      MMX_REG src;
1233      UINT32 ea = GetEA(cpustate, modrm, 0);
1234      READMMX(cpustate, ea, src);
1235      MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & src.q;
1236   }
1237   CYCLES(cpustate,1);     // TODO: correct cycle count
1238}
1239
1240static void MMXOP(psraw_r64_rm64)(i386_state *cpustate)  // Opcode 0f e1
1241{
1242   MMXPROLOG(cpustate);
1243   UINT8 modrm = FETCH(cpustate);
1244   if( modrm >= 0xc0 ) {
1245      int count=(int)MMX(modrm & 7).q;
1246      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1247      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1248      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1249      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1250   } else {
1251      MMX_REG src;
1252      UINT32 ea = GetEA(cpustate, modrm, 0);
1253      READMMX(cpustate, ea, src);
1254      int count=(int)src.q;
1255      MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
1256      MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
1257      MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
1258      MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
1259   }
1260   CYCLES(cpustate,1);     // TODO: correct cycle count
1261}
1262
1263static void MMXOP(psrad_r64_rm64)(i386_state *cpustate)  // Opcode 0f e2
1264{
1265   MMXPROLOG(cpustate);
1266   UINT8 modrm = FETCH(cpustate);
1267   if( modrm >= 0xc0 ) {
1268      int count=(int)MMX(modrm & 7).q;
1269      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1270      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1271   } else {
1272      MMX_REG src;
1273      UINT32 ea = GetEA(cpustate, modrm, 0);
1274      READMMX(cpustate, ea, src);
1275      int count=(int)src.q;
1276      MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
1277      MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
1278   }
1279   CYCLES(cpustate,1);     // TODO: correct cycle count
1280}
1281
1282static void MMXOP(pmulhw_r64_rm64)(i386_state *cpustate)  // Opcode 0f e5
1283{
1284   MMXPROLOG(cpustate);
1285   UINT8 modrm = FETCH(cpustate);
1286   if( modrm >= 0xc0 ) {
1287      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) >> 16;
1288      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) >> 16;
1289      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) >> 16;
1290      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) >> 16;
1291   } else {
1292      MMX_REG src;
1293      UINT32 ea = GetEA(cpustate, modrm, 0);
1294      READMMX(cpustate, ea, src);
1295      MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) >> 16;
1296      MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) >> 16;
1297      MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) >> 16;
1298      MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) >> 16;
1299   }
1300   CYCLES(cpustate,1);     // TODO: correct cycle count
1301}
1302
1303static void MMXOP(psubsb_r64_rm64)(i386_state *cpustate)  // Opcode 0f e8
1304{
1305   int n;
1306   MMXPROLOG(cpustate);
1307   UINT8 modrm = FETCH(cpustate);
1308   if( modrm >= 0xc0 ) {
1309      for (n=0;n < 8;n++)
1310         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)MMX(modrm & 7).c[n]);
1311   } else {
1312      MMX_REG s;
1313      UINT32 ea = GetEA(cpustate, modrm, 0);
1314      READMMX(cpustate, ea, s);
1315      for (n=0;n < 8;n++)
1316         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)s.c[n]);
1317   }
1318   CYCLES(cpustate,1);     // TODO: correct cycle count
1319}
1320
1321static void MMXOP(psubsw_r64_rm64)(i386_state *cpustate)  // Opcode 0f e9
1322{
1323   int n;
1324   MMXPROLOG(cpustate);
1325   UINT8 modrm = FETCH(cpustate);
1326   if( modrm >= 0xc0 ) {
1327      for (n=0;n < 4;n++)
1328         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)MMX(modrm & 7).s[n]);
1329   } else {
1330      MMX_REG s;
1331      UINT32 ea = GetEA(cpustate, modrm, 0);
1332      READMMX(cpustate, ea, s);
1333      for (n=0;n < 4;n++)
1334         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)s.s[n]);
1335   }
1336   CYCLES(cpustate,1);     // TODO: correct cycle count
1337}
1338
1339static void MMXOP(por_r64_rm64)(i386_state *cpustate)  // Opcode 0f eb
1340{
1341   MMXPROLOG(cpustate);
1342   UINT8 modrm = FETCH(cpustate);
1343   if( modrm >= 0xc0 ) {
1344      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | MMX(modrm & 7).q;
1345   } else {
1346      MMX_REG s;
1347      UINT32 ea = GetEA(cpustate, modrm, 0);
1348      READMMX(cpustate, ea, s);
1349      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | s.q;
1350   }
1351   CYCLES(cpustate,1);     // TODO: correct cycle count
1352}
1353
1354static void MMXOP(paddsb_r64_rm64)(i386_state *cpustate)  // Opcode 0f ec
1355{
1356   int n;
1357   MMXPROLOG(cpustate);
1358   UINT8 modrm = FETCH(cpustate);
1359   if( modrm >= 0xc0 ) {
1360      for (n=0;n < 8;n++)
1361         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)MMX(modrm & 7).c[n]);
1362   } else {
1363      MMX_REG s;
1364      UINT32 ea = GetEA(cpustate, modrm, 0);
1365      READMMX(cpustate, ea, s);
1366      for (n=0;n < 8;n++)
1367         MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)s.c[n]);
1368   }
1369   CYCLES(cpustate,1);     // TODO: correct cycle count
1370}
1371
1372static void MMXOP(paddsw_r64_rm64)(i386_state *cpustate)  // Opcode 0f ed
1373{
1374   int n;
1375   MMXPROLOG(cpustate);
1376   UINT8 modrm = FETCH(cpustate);
1377   if( modrm >= 0xc0 ) {
1378      for (n=0;n < 4;n++)
1379         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)MMX(modrm & 7).s[n]);
1380   } else {
1381      MMX_REG s;
1382      UINT32 ea = GetEA(cpustate, modrm, 0);
1383      READMMX(cpustate, ea, s);
1384      for (n=0;n < 4;n++)
1385         MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)s.s[n]);
1386   }
1387   CYCLES(cpustate,1);     // TODO: correct cycle count
1388}
1389
1390static void MMXOP(pxor_r64_rm64)(i386_state *cpustate)  // Opcode 0f ef
1391{
1392   MMXPROLOG(cpustate);
1393   UINT8 modrm = FETCH(cpustate);
1394   if( modrm >= 0xc0 ) {
1395      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ MMX(modrm & 7).q;
1396   } else {
1397      MMX_REG s;
1398      UINT32 ea = GetEA(cpustate, modrm, 0);
1399      READMMX(cpustate, ea, s);
1400      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ s.q;
1401   }
1402   CYCLES(cpustate,1);     // TODO: correct cycle count
1403}
1404
1405static void MMXOP(psllw_r64_rm64)(i386_state *cpustate)  // Opcode 0f f1
1406{
1407   MMXPROLOG(cpustate);
1408   UINT8 modrm = FETCH(cpustate);
1409   if( modrm >= 0xc0 ) {
1410      int count=(int)MMX(modrm & 7).q;
1411      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1412      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1413      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1414      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1415   } else {
1416      MMX_REG s;
1417      UINT32 ea = GetEA(cpustate, modrm, 0);
1418      READMMX(cpustate, ea, s);
1419      int count=(int)s.q;
1420      MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
1421      MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
1422      MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
1423      MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
1424   }
1425   CYCLES(cpustate,1);     // TODO: correct cycle count
1426}
1427
1428static void MMXOP(pslld_r64_rm64)(i386_state *cpustate)  // Opcode 0f f2
1429{
1430   MMXPROLOG(cpustate);
1431   UINT8 modrm = FETCH(cpustate);
1432   if( modrm >= 0xc0 ) {
1433      int count=(int)MMX(modrm & 7).q;
1434      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1435      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1436   } else {
1437      MMX_REG s;
1438      UINT32 ea = GetEA(cpustate, modrm, 0);
1439      READMMX(cpustate, ea, s);
1440      int count=(int)s.q;
1441      MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
1442      MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
1443   }
1444   CYCLES(cpustate,1);     // TODO: correct cycle count
1445}
1446
1447static void MMXOP(psllq_r64_rm64)(i386_state *cpustate)  // Opcode 0f f3
1448{
1449   MMXPROLOG(cpustate);
1450   UINT8 modrm = FETCH(cpustate);
1451   if( modrm >= 0xc0 ) {
1452      int count=(int)MMX(modrm & 7).q;
1453      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1454   } else {
1455      MMX_REG s;
1456      UINT32 ea = GetEA(cpustate, modrm, 0);
1457      READMMX(cpustate, ea, s);
1458      int count=(int)s.q;
1459      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
1460   }
1461   CYCLES(cpustate,1);     // TODO: correct cycle count
1462}
1463
1464static void MMXOP(pmaddwd_r64_rm64)(i386_state *cpustate)  // Opcode 0f f5
1465{
1466   MMXPROLOG(cpustate);
1467   UINT8 modrm = FETCH(cpustate);
1468   if( modrm >= 0xc0 ) {
1469      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]+
1470                            (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1];
1471      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]+
1472                            (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3];
1473   } else {
1474      MMX_REG s;
1475      UINT32 ea = GetEA(cpustate, modrm, 0);
1476      READMMX(cpustate, ea, s);
1477      MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)s.s[0]+
1478                            (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)s.s[1];
1479      MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)s.s[2]+
1480                            (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)s.s[3];
1481   }
1482   CYCLES(cpustate,1);     // TODO: correct cycle count
1483}
1484
1485static void MMXOP(psubb_r64_rm64)(i386_state *cpustate)  // Opcode 0f f8
1486{
1487   int n;
1488   MMXPROLOG(cpustate);
1489   UINT8 modrm = FETCH(cpustate);
1490   if( modrm >= 0xc0 ) {
1491      for (n=0;n < 8;n++)
1492         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - MMX(modrm & 7).b[n];
1493   } else {
1494      MMX_REG s;
1495      UINT32 ea = GetEA(cpustate, modrm, 0);
1496      READMMX(cpustate, ea, s);
1497      for (n=0;n < 8;n++)
1498         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - s.b[n];
1499   }
1500   CYCLES(cpustate,1);     // TODO: correct cycle count
1501}
1502
1503static void MMXOP(psubw_r64_rm64)(i386_state *cpustate)  // Opcode 0f f9
1504{
1505   int n;
1506   MMXPROLOG(cpustate);
1507   UINT8 modrm = FETCH(cpustate);
1508   if( modrm >= 0xc0 ) {
1509      for (n=0;n < 4;n++)
1510         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - MMX(modrm & 7).w[n];
1511   } else {
1512      MMX_REG s;
1513      UINT32 ea = GetEA(cpustate, modrm, 0);
1514      READMMX(cpustate, ea, s);
1515      for (n=0;n < 4;n++)
1516         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - s.w[n];
1517   }
1518   CYCLES(cpustate,1);     // TODO: correct cycle count
1519}
1520
1521static void MMXOP(psubd_r64_rm64)(i386_state *cpustate)  // Opcode 0f fa
1522{
1523   int n;
1524   MMXPROLOG(cpustate);
1525   UINT8 modrm = FETCH(cpustate);
1526   if( modrm >= 0xc0 ) {
1527      for (n=0;n < 2;n++)
1528         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - MMX(modrm & 7).d[n];
1529   } else {
1530      MMX_REG s;
1531      UINT32 ea = GetEA(cpustate, modrm, 0);
1532      READMMX(cpustate, ea, s);
1533      for (n=0;n < 2;n++)
1534         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - s.d[n];
1535   }
1536   CYCLES(cpustate,1);     // TODO: correct cycle count
1537}
1538
1539static void MMXOP(paddb_r64_rm64)(i386_state *cpustate)  // Opcode 0f fc
1540{
1541   int n;
1542   MMXPROLOG(cpustate);
1543   UINT8 modrm = FETCH(cpustate);
1544   if( modrm >= 0xc0 ) {
1545      for (n=0;n < 8;n++)
1546         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + MMX(modrm & 7).b[n];
1547   } else {
1548      MMX_REG s;
1549      UINT32 ea = GetEA(cpustate, modrm, 0);
1550      READMMX(cpustate, ea, s);
1551      for (n=0;n < 8;n++)
1552         MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + s.b[n];
1553   }
1554   CYCLES(cpustate,1);     // TODO: correct cycle count
1555}
1556
1557static void MMXOP(paddw_r64_rm64)(i386_state *cpustate)  // Opcode 0f fd
1558{
1559   int n;
1560   MMXPROLOG(cpustate);
1561   UINT8 modrm = FETCH(cpustate);
1562   if( modrm >= 0xc0 ) {
1563      for (n=0;n < 4;n++)
1564         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + MMX(modrm & 7).w[n];
1565   } else {
1566      MMX_REG s;
1567      UINT32 ea = GetEA(cpustate, modrm, 0);
1568      READMMX(cpustate, ea, s);
1569      for (n=0;n < 4;n++)
1570         MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + s.w[n];
1571   }
1572   CYCLES(cpustate,1);     // TODO: correct cycle count
1573}
1574
1575static void MMXOP(paddd_r64_rm64)(i386_state *cpustate)  // Opcode 0f fe
1576{
1577   int n;
1578   MMXPROLOG(cpustate);
1579   UINT8 modrm = FETCH(cpustate);
1580   if( modrm >= 0xc0 ) {
1581      for (n=0;n < 2;n++)
1582         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + MMX(modrm & 7).d[n];
1583   } else {
1584      MMX_REG s;
1585      UINT32 ea = GetEA(cpustate, modrm, 0);
1586      READMMX(cpustate, ea, s);
1587      for (n=0;n < 2;n++)
1588         MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + s.d[n];
1589   }
1590   CYCLES(cpustate,1);     // TODO: correct cycle count
1591}
1592
1593static void MMXOP(emms)(i386_state *cpustate) // Opcode 0f 77
1594{
1595   cpustate->x87_tw = 0xffff; // tag word = 0xffff
1596   // TODO
1597   CYCLES(cpustate,1);     // TODO: correct cycle count
1598}
1599
1600static void MMXOP(movd_r64_rm32)(i386_state *cpustate) // Opcode 0f 6e
1601{
1602   MMXPROLOG(cpustate);
1603   UINT8 modrm = FETCH(cpustate);
1604   if( modrm >= 0xc0 ) {
1605      MMX((modrm >> 3) & 0x7).d[0]=LOAD_RM32(modrm);
1606   } else {
1607      UINT32 ea = GetEA(cpustate, modrm, 0);
1608      MMX((modrm >> 3) & 0x7).d[0]=READ32(cpustate, ea);
1609   }
1610   MMX((modrm >> 3) & 0x7).d[1]=0;
1611   CYCLES(cpustate,1);     // TODO: correct cycle count
1612}
1613
1614static void MMXOP(movq_r64_rm64)(i386_state *cpustate) // Opcode 0f 6f
1615{
1616   MMXPROLOG(cpustate);
1617   UINT8 modrm = FETCH(cpustate);
1618   if( modrm >= 0xc0 ) {
1619      MMX((modrm >> 3) & 0x7).l=MMX(modrm & 0x7).l;
1620   } else {
1621      UINT32 ea = GetEA(cpustate, modrm, 0);
1622      READMMX(cpustate, ea, MMX((modrm >> 3) & 0x7));
1623   }
1624   CYCLES(cpustate,1);     // TODO: correct cycle count
1625}
1626
1627static void MMXOP(movd_rm32_r64)(i386_state *cpustate) // Opcode 0f 7e
1628{
1629   MMXPROLOG(cpustate);
1630   UINT8 modrm = FETCH(cpustate);
1631   if( modrm >= 0xc0 ) {
1632      STORE_RM32(modrm, MMX((modrm >> 3) & 0x7).d[0]);
1633   } else {
1634      UINT32 ea = GetEA(cpustate, modrm, 0);
1635      WRITE32(cpustate, ea, MMX((modrm >> 3) & 0x7).d[0]);
1636   }
1637   CYCLES(cpustate,1);     // TODO: correct cycle count
1638}
1639
1640static void MMXOP(movq_rm64_r64)(i386_state *cpustate) // Opcode 0f 7f
1641{
1642   MMXPROLOG(cpustate);
1643   UINT8 modrm = FETCH(cpustate);
1644   if( modrm >= 0xc0 ) {
1645      MMX(modrm & 0x7)=MMX((modrm >> 3) & 0x7);
1646   } else {
1647      UINT32 ea = GetEA(cpustate, modrm, 0);
1648      WRITEMMX(cpustate, ea, MMX((modrm >> 3) & 0x7));
1649   }
1650   CYCLES(cpustate,1);     // TODO: correct cycle count
1651}
1652
1653static void MMXOP(pcmpeqb_r64_rm64)(i386_state *cpustate) // Opcode 0f 74
1654{
1655   int c;
1656   MMXPROLOG(cpustate);
1657   UINT8 modrm = FETCH(cpustate);
1658   if( modrm >= 0xc0 ) {
1659      int s,d;
1660      s=modrm & 0x7;
1661      d=(modrm >> 3) & 0x7;
1662      for (c=0;c <= 7;c++)
1663         MMX(d).b[c]=(MMX(d).b[c] == MMX(s).b[c]) ? 0xff : 0;
1664   } else {
1665      MMX_REG s;
1666      int d=(modrm >> 3) & 0x7;
1667      UINT32 ea = GetEA(cpustate, modrm, 0);
1668      READMMX(cpustate, ea, s);
1669      for (c=0;c <= 7;c++)
1670         MMX(d).b[c]=(MMX(d).b[c] == s.b[c]) ? 0xff : 0;
1671   }
1672   CYCLES(cpustate,1);     // TODO: correct cycle count
1673}
1674
1675static void MMXOP(pcmpeqw_r64_rm64)(i386_state *cpustate) // Opcode 0f 75
1676{
1677   MMXPROLOG(cpustate);
1678   UINT8 modrm = FETCH(cpustate);
1679   if( modrm >= 0xc0 ) {
1680      int s,d;
1681      s=modrm & 0x7;
1682      d=(modrm >> 3) & 0x7;
1683      MMX(d).w[0]=(MMX(d).w[0] == MMX(s).w[0]) ? 0xffff : 0;
1684      MMX(d).w[1]=(MMX(d).w[1] == MMX(s).w[1]) ? 0xffff : 0;
1685      MMX(d).w[2]=(MMX(d).w[2] == MMX(s).w[2]) ? 0xffff : 0;
1686      MMX(d).w[3]=(MMX(d).w[3] == MMX(s).w[3]) ? 0xffff : 0;
1687   } else {
1688      MMX_REG s;
1689      int d=(modrm >> 3) & 0x7;
1690      UINT32 ea = GetEA(cpustate, modrm, 0);
1691      READMMX(cpustate, ea, s);
1692      MMX(d).w[0]=(MMX(d).w[0] == s.w[0]) ? 0xffff : 0;
1693      MMX(d).w[1]=(MMX(d).w[1] == s.w[1]) ? 0xffff : 0;
1694      MMX(d).w[2]=(MMX(d).w[2] == s.w[2]) ? 0xffff : 0;
1695      MMX(d).w[3]=(MMX(d).w[3] == s.w[3]) ? 0xffff : 0;
1696   }
1697   CYCLES(cpustate,1);     // TODO: correct cycle count
1698}
1699
1700static void MMXOP(pcmpeqd_r64_rm64)(i386_state *cpustate) // Opcode 0f 76
1701{
1702   MMXPROLOG(cpustate);
1703   UINT8 modrm = FETCH(cpustate);
1704   if( modrm >= 0xc0 ) {
1705      int s,d;
1706      s=modrm & 0x7;
1707      d=(modrm >> 3) & 0x7;
1708      MMX(d).d[0]=(MMX(d).d[0] == MMX(s).d[0]) ? 0xffffffff : 0;
1709      MMX(d).d[1]=(MMX(d).d[1] == MMX(s).d[1]) ? 0xffffffff : 0;
1710   } else {
1711      MMX_REG s;
1712      int d=(modrm >> 3) & 0x7;
1713      UINT32 ea = GetEA(cpustate, modrm, 0);
1714      READMMX(cpustate, ea, s);
1715      MMX(d).d[0]=(MMX(d).d[0] == s.d[0]) ? 0xffffffff : 0;
1716      MMX(d).d[1]=(MMX(d).d[1] == s.d[1]) ? 0xffffffff : 0;
1717   }
1718   CYCLES(cpustate,1);     // TODO: correct cycle count
1719}
1720
1721static void MMXOP(pshufw_r64_rm64_i8)(i386_state *cpustate) // Opcode 0f 70
1722{
1723   MMXPROLOG(cpustate);
1724   UINT8 modrm = FETCH(cpustate);
1725   if( modrm >= 0xc0 ) {
1726      MMX_REG t;
1727      int s,d;
1728      UINT8 imm8 = FETCH(cpustate);
1729      s=modrm & 0x7;
1730      d=(modrm >> 3) & 0x7;
1731      t.q=MMX(s).q;
1732      MMX(d).w[0]=t.w[imm8 & 3];
1733      MMX(d).w[1]=t.w[(imm8 >> 2) & 3];
1734      MMX(d).w[2]=t.w[(imm8 >> 4) & 3];
1735      MMX(d).w[3]=t.w[(imm8 >> 6) & 3];
1736   } else {
1737      MMX_REG s;
1738      int d=(modrm >> 3) & 0x7;
1739      UINT32 ea = GetEA(cpustate, modrm, 0);
1740      UINT8 imm8 = FETCH(cpustate);
1741      READMMX(cpustate, ea, s);
1742      MMX(d).w[0]=s.w[imm8 & 3];
1743      MMX(d).w[1]=s.w[(imm8 >> 2) & 3];
1744      MMX(d).w[2]=s.w[(imm8 >> 4) & 3];
1745      MMX(d).w[3]=s.w[(imm8 >> 6) & 3];
1746   }
1747   CYCLES(cpustate,1);     // TODO: correct cycle count
1748}
1749
1750static void MMXOP(punpcklbw_r64_r64m32)(i386_state *cpustate) // Opcode 0f 60
1751{
1752   MMXPROLOG(cpustate);
1753   UINT8 modrm = FETCH(cpustate);
1754   if( modrm >= 0xc0 ) {
1755      UINT32 t;
1756      int s,d;
1757      s=modrm & 0x7;
1758      d=(modrm >> 3) & 0x7;
1759      t=MMX(d).d[0];
1760      MMX(d).b[0]=t & 0xff;
1761      MMX(d).b[1]=MMX(s).b[0];
1762      MMX(d).b[2]=(t >> 8) & 0xff;
1763      MMX(d).b[3]=MMX(s).b[1];
1764      MMX(d).b[4]=(t >> 16) & 0xff;
1765      MMX(d).b[5]=MMX(s).b[2];
1766      MMX(d).b[6]=(t >> 24) & 0xff;
1767      MMX(d).b[7]=MMX(s).b[3];
1768   } else {
1769      UINT32 s,t;
1770      int d=(modrm >> 3) & 0x7;
1771      UINT32 ea = GetEA(cpustate, modrm, 0);
1772      s = READ32(cpustate, ea);
1773      t=MMX(d).d[0];
1774      MMX(d).b[0]=t & 0xff;
1775      MMX(d).b[1]=s & 0xff;
1776      MMX(d).b[2]=(t >> 8) & 0xff;
1777      MMX(d).b[3]=(s >> 8) & 0xff;
1778      MMX(d).b[4]=(t >> 16) & 0xff;
1779      MMX(d).b[5]=(s >> 16) & 0xff;
1780      MMX(d).b[6]=(t >> 24) & 0xff;
1781      MMX(d).b[7]=(s >> 24) & 0xff;
1782   }
1783   CYCLES(cpustate,1);     // TODO: correct cycle count
1784}
1785
1786static void MMXOP(punpcklwd_r64_r64m32)(i386_state *cpustate) // Opcode 0f 61
1787{
1788   MMXPROLOG(cpustate);
1789   UINT8 modrm = FETCH(cpustate);
1790   if( modrm >= 0xc0 ) {
1791      UINT16 t;
1792      int s,d;
1793      s=modrm & 0x7;
1794      d=(modrm >> 3) & 0x7;
1795      t=MMX(d).w[1];
1796      MMX(d).w[0]=MMX(d).w[0];
1797      MMX(d).w[1]=MMX(s).w[0];
1798      MMX(d).w[2]=t;
1799      MMX(d).w[3]=MMX(s).w[1];
1800   } else {
1801      UINT32 s;
1802      UINT16 t;
1803      int d=(modrm >> 3) & 0x7;
1804      UINT32 ea = GetEA(cpustate, modrm, 0);
1805      s = READ32(cpustate, ea);
1806      t=MMX(d).w[1];
1807      MMX(d).w[0]=MMX(d).w[0];
1808      MMX(d).w[1]=s & 0xffff;
1809      MMX(d).w[2]=t;
1810      MMX(d).w[3]=(s >> 16) & 0xffff;
1811   }
1812   CYCLES(cpustate,1);     // TODO: correct cycle count
1813}
1814
1815static void MMXOP(punpckldq_r64_r64m32)(i386_state *cpustate) // Opcode 0f 62
1816{
1817   MMXPROLOG(cpustate);
1818   UINT8 modrm = FETCH(cpustate);
1819   if( modrm >= 0xc0 ) {
1820      int s,d;
1821      s=modrm & 0x7;
1822      d=(modrm >> 3) & 0x7;
1823      MMX(d).d[0]=MMX(d).d[0];
1824      MMX(d).d[1]=MMX(s).d[0];
1825   } else {
1826      UINT32 s;
1827      int d=(modrm >> 3) & 0x7;
1828      UINT32 ea = GetEA(cpustate, modrm, 0);
1829      s = READ32(cpustate, ea);
1830      MMX(d).d[0]=MMX(d).d[0];
1831      MMX(d).d[1]=s;
1832   }
1833   CYCLES(cpustate,1);     // TODO: correct cycle count
1834}
1835
1836static void MMXOP(packsswb_r64_rm64)(i386_state *cpustate) // Opcode 0f 63
1837{
1838   MMXPROLOG(cpustate);
1839   UINT8 modrm = FETCH(cpustate);
1840   if( modrm >= 0xc0 ) {
1841      int s,d;
1842      s=modrm & 0x7;
1843      d=(modrm >> 3) & 0x7;
1844      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
1845      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
1846      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
1847      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
1848      MMX(d).c[4]=SaturatedSignedWordToSignedByte(MMX(s).s[0]);
1849      MMX(d).c[5]=SaturatedSignedWordToSignedByte(MMX(s).s[1]);
1850      MMX(d).c[6]=SaturatedSignedWordToSignedByte(MMX(s).s[2]);
1851      MMX(d).c[7]=SaturatedSignedWordToSignedByte(MMX(s).s[3]);
1852   } else {
1853      MMX_REG s;
1854      int d=(modrm >> 3) & 0x7;
1855      UINT32 ea = GetEA(cpustate, modrm, 0);
1856      READMMX(cpustate, ea, s);
1857      MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
1858      MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
1859      MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
1860      MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
1861      MMX(d).c[4]=SaturatedSignedWordToSignedByte(s.s[0]);
1862      MMX(d).c[5]=SaturatedSignedWordToSignedByte(s.s[1]);
1863      MMX(d).c[6]=SaturatedSignedWordToSignedByte(s.s[2]);
1864      MMX(d).c[7]=SaturatedSignedWordToSignedByte(s.s[3]);
1865   }
1866   CYCLES(cpustate,1);     // TODO: correct cycle count
1867}
1868
1869static void MMXOP(pcmpgtb_r64_rm64)(i386_state *cpustate) // Opcode 0f 64
1870{
1871   int c;
1872   MMXPROLOG(cpustate);
1873   UINT8 modrm = FETCH(cpustate);
1874   if( modrm >= 0xc0 ) {
1875      int s,d;
1876      s=modrm & 0x7;
1877      d=(modrm >> 3) & 0x7;
1878      for (c=0;c <= 7;c++)
1879         MMX(d).b[c]=(MMX(d).c[c] > MMX(s).c[c]) ? 0xff : 0;
1880   } else {
1881      MMX_REG s;
1882      int d=(modrm >> 3) & 0x7;
1883      UINT32 ea = GetEA(cpustate, modrm, 0);
1884      READMMX(cpustate, ea, s);
1885      for (c=0;c <= 7;c++)
1886         MMX(d).b[c]=(MMX(d).c[c] > s.c[c]) ? 0xff : 0;
1887   }
1888   CYCLES(cpustate,1);     // TODO: correct cycle count
1889}
1890
1891static void MMXOP(pcmpgtw_r64_rm64)(i386_state *cpustate) // Opcode 0f 65
1892{
1893   int c;
1894   MMXPROLOG(cpustate);
1895   UINT8 modrm = FETCH(cpustate);
1896   if( modrm >= 0xc0 ) {
1897      int s,d;
1898      s=modrm & 0x7;
1899      d=(modrm >> 3) & 0x7;
1900      for (c=0;c <= 3;c++)
1901         MMX(d).w[c]=(MMX(d).s[c] > MMX(s).s[c]) ? 0xffff : 0;
1902   } else {
1903      MMX_REG s;
1904      int d=(modrm >> 3) & 0x7;
1905      UINT32 ea = GetEA(cpustate, modrm, 0);
1906      READMMX(cpustate, ea, s);
1907      for (c=0;c <= 3;c++)
1908         MMX(d).w[c]=(MMX(d).s[c] > s.s[c]) ? 0xffff : 0;
1909   }
1910   CYCLES(cpustate,1);     // TODO: correct cycle count
1911}
1912
1913static void MMXOP(pcmpgtd_r64_rm64)(i386_state *cpustate) // Opcode 0f 66
1914{
1915   int c;
1916   MMXPROLOG(cpustate);
1917   UINT8 modrm = FETCH(cpustate);
1918   if( modrm >= 0xc0 ) {
1919      int s,d;
1920      s=modrm & 0x7;
1921      d=(modrm >> 3) & 0x7;
1922      for (c=0;c <= 1;c++)
1923         MMX(d).d[c]=(MMX(d).i[c] > MMX(s).i[c]) ? 0xffffffff : 0;
1924   } else {
1925      MMX_REG s;
1926      int d=(modrm >> 3) & 0x7;
1927      UINT32 ea = GetEA(cpustate, modrm, 0);
1928      READMMX(cpustate, ea, s);
1929      for (c=0;c <= 1;c++)
1930         MMX(d).d[c]=(MMX(d).i[c] > s.i[c]) ? 0xffffffff : 0;
1931   }
1932   CYCLES(cpustate,1);     // TODO: correct cycle count
1933}
1934
1935static void MMXOP(packuswb_r64_rm64)(i386_state *cpustate) // Opcode 0f 67
1936{
1937   MMXPROLOG(cpustate);
1938   UINT8 modrm = FETCH(cpustate);
1939   if( modrm >= 0xc0 ) {
1940      int s,d;
1941      s=modrm & 0x7;
1942      d=(modrm >> 3) & 0x7;
1943      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
1944      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
1945      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
1946      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
1947      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(MMX(s).s[0]);
1948      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(MMX(s).s[1]);
1949      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(MMX(s).s[2]);
1950      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(MMX(s).s[3]);
1951   } else {
1952      MMX_REG s;
1953      int d=(modrm >> 3) & 0x7;
1954      UINT32 ea = GetEA(cpustate, modrm, 0);
1955      READMMX(cpustate, ea, s);
1956      MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(MMX(d).s[0]);
1957      MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(MMX(d).s[1]);
1958      MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(MMX(d).s[2]);
1959      MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(MMX(d).s[3]);
1960      MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(s.s[0]);
1961      MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(s.s[1]);
1962      MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(s.s[2]);
1963      MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(s.s[3]);
1964   }
1965   CYCLES(cpustate,1);     // TODO: correct cycle count
1966}
1967
1968static void MMXOP(punpckhbw_r64_rm64)(i386_state *cpustate) // Opcode 0f 68
1969{
1970   MMXPROLOG(cpustate);
1971   UINT8 modrm = FETCH(cpustate);
1972   if( modrm >= 0xc0 ) {
1973      int s,d;
1974      s=modrm & 0x7;
1975      d=(modrm >> 3) & 0x7;
1976      MMX(d).b[0]=MMX(d).b[4];
1977      MMX(d).b[1]=MMX(s).b[4];
1978      MMX(d).b[2]=MMX(d).b[5];
1979      MMX(d).b[3]=MMX(s).b[5];
1980      MMX(d).b[4]=MMX(d).b[6];
1981      MMX(d).b[5]=MMX(s).b[6];
1982      MMX(d).b[6]=MMX(d).b[7];
1983      MMX(d).b[7]=MMX(s).b[7];
1984   } else {
1985      MMX_REG s;
1986      int d=(modrm >> 3) & 0x7;
1987      UINT32 ea = GetEA(cpustate, modrm, 0);
1988      READMMX(cpustate, ea, s);
1989      MMX(d).b[0]=MMX(d).b[4];
1990      MMX(d).b[1]=s.b[4];
1991      MMX(d).b[2]=MMX(d).b[5];
1992      MMX(d).b[3]=s.b[5];
1993      MMX(d).b[4]=MMX(d).b[6];
1994      MMX(d).b[5]=s.b[6];
1995      MMX(d).b[6]=MMX(d).b[7];
1996      MMX(d).b[7]=s.b[7];
1997   }
1998   CYCLES(cpustate,1);     // TODO: correct cycle count
1999}
2000
2001static void MMXOP(punpckhwd_r64_rm64)(i386_state *cpustate) // Opcode 0f 69
2002{
2003   MMXPROLOG(cpustate);
2004   UINT8 modrm = FETCH(cpustate);
2005   if( modrm >= 0xc0 ) {
2006      int s,d;
2007      s=modrm & 0x7;
2008      d=(modrm >> 3) & 0x7;
2009      MMX(d).w[0]=MMX(d).w[2];
2010      MMX(d).w[1]=MMX(s).w[2];
2011      MMX(d).w[2]=MMX(d).w[3];
2012      MMX(d).w[3]=MMX(s).w[3];
2013   } else {
2014      MMX_REG s;
2015      int d=(modrm >> 3) & 0x7;
2016      UINT32 ea = GetEA(cpustate, modrm, 0);
2017      READMMX(cpustate, ea, s);
2018      MMX(d).w[0]=MMX(d).w[2];
2019      MMX(d).w[1]=s.w[2];
2020      MMX(d).w[2]=MMX(d).w[3];
2021      MMX(d).w[3]=s.w[3];
2022   }
2023   CYCLES(cpustate,1);     // TODO: correct cycle count
2024}
2025
2026static void MMXOP(punpckhdq_r64_rm64)(i386_state *cpustate) // Opcode 0f 6a
2027{
2028   MMXPROLOG(cpustate);
2029   UINT8 modrm = FETCH(cpustate);
2030   if( modrm >= 0xc0 ) {
2031      int s,d;
2032      s=modrm & 0x7;
2033      d=(modrm >> 3) & 0x7;
2034      MMX(d).d[0]=MMX(d).d[1];
2035      MMX(d).d[1]=MMX(s).d[1];
2036   } else {
2037      MMX_REG s;
2038      int d=(modrm >> 3) & 0x7;
2039      UINT32 ea = GetEA(cpustate, modrm, 0);
2040      READMMX(cpustate, ea, s);
2041      MMX(d).d[0]=MMX(d).d[1];
2042      MMX(d).d[1]=s.d[1];
2043   }
2044   CYCLES(cpustate,1);     // TODO: correct cycle count
2045}
2046
2047static void MMXOP(packssdw_r64_rm64)(i386_state *cpustate) // Opcode 0f 6b
2048{
2049   MMXPROLOG(cpustate);
2050   UINT8 modrm = FETCH(cpustate);
2051   if( modrm >= 0xc0 ) {
2052      int s,d;
2053      s=modrm & 0x7;
2054      d=(modrm >> 3) & 0x7;
2055      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2056      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2057      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(MMX(s).i[0]);
2058      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(MMX(s).i[1]);
2059   } else {
2060      MMX_REG s;
2061      int d=(modrm >> 3) & 0x7;
2062      UINT32 ea = GetEA(cpustate, modrm, 0);
2063      READMMX(cpustate, ea, s);
2064      MMX(d).s[0]=SaturatedSignedDwordToSignedWord(MMX(d).i[0]);
2065      MMX(d).s[1]=SaturatedSignedDwordToSignedWord(MMX(d).i[1]);
2066      MMX(d).s[2]=SaturatedSignedDwordToSignedWord(s.i[0]);
2067      MMX(d).s[3]=SaturatedSignedDwordToSignedWord(s.i[1]);
2068   }
2069   CYCLES(cpustate,1);     // TODO: correct cycle count
2070}
2071
2072static void SSEOP(sse_group0fae)(i386_state *cpustate)  // Opcode 0f ae
2073{
2074   UINT8 modm = FETCH(cpustate);
2075   if( modm == 0xf8 ) {
2076      logerror("Unemulated SFENCE opcode called\n");
2077      CYCLES(cpustate,1); // sfence instruction
2078   } else if( modm == 0xf0 ) {
2079      CYCLES(cpustate,1); // mfence instruction
2080   } else if( modm == 0xe8 ) {
2081      CYCLES(cpustate,1); // lfence instruction
2082   } else if( modm < 0xc0 ) {
2083      UINT32 ea;
2084      switch ( (modm & 0x38) >> 3 )
2085      {
2086         case 2: // ldmxcsr m32
2087            ea = GetEA(cpustate, modm, 0);
2088            cpustate->mxcsr = READ32(cpustate, ea);
2089            break;
2090         case 3: // stmxcsr m32
2091            ea = GetEA(cpustate, modm, 0);
2092            WRITE32(cpustate, ea, cpustate->mxcsr);
2093            break;
2094         case 7: // clflush m8
2095            GetNonTranslatedEA(cpustate, modm, NULL);
2096            break;
2097         default:
2098            report_invalid_modrm(cpustate, "sse_group0fae", modm);
2099      }
2100   } else {
2101      report_invalid_modrm(cpustate, "sse_group0fae", modm);
2102   }
2103}
2104
2105static void SSEOP(cvttps2dq_r128_rm128)(i386_state *cpustate) // Opcode f3 0f 5b
2106{
2107   UINT8 modrm = FETCH(cpustate);
2108   if( modrm >= 0xc0 ) {
2109      XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM(modrm & 0x7).f[0];
2110      XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM(modrm & 0x7).f[1];
2111      XMM((modrm >> 3) & 0x7).i[2]=(INT32)XMM(modrm & 0x7).f[2];
2112      XMM((modrm >> 3) & 0x7).i[3]=(INT32)XMM(modrm & 0x7).f[3];
2113   } else {
2114      XMM_REG src;
2115      UINT32 ea = GetEA(cpustate, modrm, 0);
2116      READXMM(cpustate, ea, src);
2117      XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f[0];
2118      XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f[1];
2119      XMM((modrm >> 3) & 0x7).i[2]=(INT32)src.f[2];
2120      XMM((modrm >> 3) & 0x7).i[3]=(INT32)src.f[3];
2121   }
2122   CYCLES(cpustate,1);     // TODO: correct cycle count
2123}
2124
2125static void SSEOP(cvtss2sd_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 5a
2126{
2127   UINT8 modrm = FETCH(cpustate);
2128   if( modrm >= 0xc0 ) {
2129      XMM((modrm >> 3) & 0x7).f64[0] = XMM(modrm & 0x7).f[0];
2130   } else {
2131      XMM_REG s;
2132      UINT32 ea = GetEA(cpustate, modrm, 0);
2133      s.d[0] = READ32(cpustate, ea);
2134      XMM((modrm >> 3) & 0x7).f64[0] = s.f[0];
2135   }
2136   CYCLES(cpustate,1);     // TODO: correct cycle count
2137}
2138
2139static void SSEOP(cvttss2si_r32_r128m32)(i386_state *cpustate) // Opcode f3 0f 2c
2140{
2141   INT32 src;
2422142   UINT8 modrm = FETCH(cpustate); // get mordm byte
2432143   if( modrm >= 0xc0 ) { // if bits 7-6 are 11 the source is a xmm register (low doubleword)
244      src = XMM(modrm & 0x7).d[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)];
2144      src = (INT32)XMM(modrm & 0x7).f[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)];
2452145   } else { // otherwise is a memory address
2146      XMM_REG t;
2462147      UINT32 ea = GetEA(cpustate, modrm, 0);
247      src = READ32(cpustate, ea);
2148      t.d[0] = READ32(cpustate, ea);
2149      src = (INT32)t.f[0];
2482150   }
249   STORE_REG32(modrm, (INT32)FPU_INT32_SINGLE(src));
250   // TODO
2151   STORE_REG32(modrm, (UINT32)src);
2512152   CYCLES(cpustate,1);     // TODO: correct cycle count
2522153}
2532154
2155static void SSEOP(cvtss2si_r32_r128m32)(i386_state *cpustate) // Opcode f3 0f 2d
2156{
2157   INT32 src;
2158   UINT8 modrm = FETCH(cpustate);
2159   if( modrm >= 0xc0 ) {
2160      src = (INT32)XMM(modrm & 0x7).f[0];
2161   } else {
2162      XMM_REG t;
2163      UINT32 ea = GetEA(cpustate, modrm, 0);
2164      t.d[0] = READ32(cpustate, ea);
2165      src = (INT32)t.f[0];
2166   }
2167   STORE_REG32(modrm, (UINT32)src);
2168   CYCLES(cpustate,1);     // TODO: correct cycle count
2169}
2170
2171static void SSEOP(cvtsi2ss_r128_rm32)(i386_state *cpustate) // Opcode f3 0f 2a
2172{
2173   UINT8 modrm = FETCH(cpustate);
2174   if( modrm >= 0xc0 ) {
2175      XMM((modrm >> 3) & 0x7).f[0] = (INT32)LOAD_RM32(modrm);
2176   } else {
2177      UINT32 ea = GetEA(cpustate, modrm, 0);
2178      XMM((modrm >> 3) & 0x7).f[0] = (INT32)READ32(cpustate, ea);
2179   }
2180   CYCLES(cpustate,1);     // TODO: correct cycle count
2181}
2182
2183static void SSEOP(cvtpi2ps_r128_rm64)(i386_state *cpustate) // Opcode 0f 2a
2184{
2185   UINT8 modrm = FETCH(cpustate);
2186   MMXPROLOG(cpustate);
2187   if( modrm >= 0xc0 ) {
2188      XMM((modrm >> 3) & 0x7).f[0] = MMX(modrm & 0x7).i[0];
2189      XMM((modrm >> 3) & 0x7).f[1] = MMX(modrm & 0x7).i[1];
2190   } else {
2191      MMX_REG r;
2192      UINT32 ea = GetEA(cpustate, modrm, 0);
2193      READMMX(cpustate, ea, r);
2194      XMM((modrm >> 3) & 0x7).f[0] = r.i[0];
2195      XMM((modrm >> 3) & 0x7).f[1] = r.i[1];
2196   }
2197   CYCLES(cpustate,1);     // TODO: correct cycle count
2198}
2199
2200static void SSEOP(cvttps2pi_r64_r128m64)(i386_state *cpustate) // Opcode 0f 2c
2201{
2202   UINT8 modrm = FETCH(cpustate);
2203   MMXPROLOG(cpustate);
2204   if( modrm >= 0xc0 ) {
2205      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2206      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2207   } else {
2208      XMM_REG r;
2209      UINT32 ea = GetEA(cpustate, modrm, 0);
2210      READXMM(cpustate, ea, r);
2211      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2212      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2213   }
2214   CYCLES(cpustate,1);     // TODO: correct cycle count
2215}
2216
2217static void SSEOP(cvtps2pi_r64_r128m64)(i386_state *cpustate) // Opcode 0f 2d
2218{
2219   UINT8 modrm = FETCH(cpustate);
2220   MMXPROLOG(cpustate);
2221   if( modrm >= 0xc0 ) {
2222      MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
2223      MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
2224   } else {
2225      XMM_REG r;
2226      UINT32 ea = GetEA(cpustate, modrm, 0);
2227      READXMM(cpustate, ea, r);
2228      XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
2229      XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
2230   }
2231   CYCLES(cpustate,1);     // TODO: correct cycle count
2232}
2233
2234static void SSEOP(cvtps2pd_r128_r128m64)(i386_state *cpustate) // Opcode 0f 5a
2235{
2236   UINT8 modrm = FETCH(cpustate);
2237   if( modrm >= 0xc0 ) {
2238      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).f[0];
2239      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).f[1];
2240   } else {
2241      MMX_REG r;
2242      UINT32 ea = GetEA(cpustate, modrm, 0);
2243      READMMX(cpustate, ea, r);
2244      XMM((modrm >> 3) & 0x7).f64[0] = (double)r.f[0];
2245      XMM((modrm >> 3) & 0x7).f64[1] = (double)r.f[1];
2246   }
2247   CYCLES(cpustate,1);     // TODO: correct cycle count
2248}
2249
2250static void SSEOP(cvtdq2ps_r128_rm128)(i386_state *cpustate) // Opcode 0f 5b
2251{
2252   UINT8 modrm = FETCH(cpustate);
2253   if( modrm >= 0xc0 ) {
2254      XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).i[0];
2255      XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).i[1];
2256      XMM((modrm >> 3) & 0x7).f[2] = (float)XMM(modrm & 0x7).i[2];
2257      XMM((modrm >> 3) & 0x7).f[3] = (float)XMM(modrm & 0x7).i[3];
2258   } else {
2259      XMM_REG r;
2260      UINT32 ea = GetEA(cpustate, modrm, 0);
2261      READXMM(cpustate, ea, r);
2262      XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0];
2263      XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1];
2264      XMM((modrm >> 3) & 0x7).f[2] = (float)r.i[2];
2265      XMM((modrm >> 3) & 0x7).f[3] = (float)r.i[3];
2266   }
2267   CYCLES(cpustate,1);     // TODO: correct cycle count
2268}
2269
2270static void SSEOP(cvtdq2pd_r128_r128m64)(i386_state *cpustate) // Opcode f3 0f e6
2271{
2272   UINT8 modrm = FETCH(cpustate);
2273   if( modrm >= 0xc0 ) {
2274      XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).i[0];
2275      XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).i[1];
2276   } else {
2277      MMX_REG s;
2278      UINT32 ea = GetEA(cpustate, modrm, 0);
2279      READMMX(cpustate, ea, s);
2280      XMM((modrm >> 3) & 0x7).f64[0] = (double)s.i[0];
2281      XMM((modrm >> 3) & 0x7).f64[1] = (double)s.i[1];
2282   }
2283   CYCLES(cpustate,1);     // TODO: correct cycle count
2284}
2285
2286static void SSEOP(movss_r128_rm128)(i386_state *cpustate) // Opcode f3 0f 10
2287{
2288   UINT8 modrm = FETCH(cpustate);
2289   if( modrm >= 0xc0 ) {
2290      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2291   } else {
2292      UINT32 ea = GetEA(cpustate, modrm, 0);
2293      XMM((modrm >> 3) & 0x7).d[0] = READ32(cpustate, ea);
2294   }
2295   CYCLES(cpustate,1);     // TODO: correct cycle count
2296}
2297
2298static void SSEOP(movss_rm128_r128)(i386_state *cpustate) // Opcode f3 0f 11
2299{
2300   UINT8 modrm = FETCH(cpustate);
2301   if( modrm >= 0xc0 ) {
2302      XMM(modrm & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0];
2303   } else {
2304      UINT32 ea = GetEA(cpustate, modrm, 0);
2305      WRITE32(cpustate, ea, XMM((modrm >> 3) & 0x7).d[0]);
2306   }
2307   CYCLES(cpustate,1);     // TODO: correct cycle count
2308}
2309
2310static void SSEOP(movsldup_r128_rm128)(i386_state *cpustate) // Opcode f3 0f 12
2311{
2312   UINT8 modrm = FETCH(cpustate);
2313   if( modrm >= 0xc0 ) {
2314      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
2315      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[0];
2316      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[2];
2317      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[2];
2318   } else {
2319      XMM_REG src;
2320      UINT32 ea = GetEA(cpustate, modrm, 0);
2321      READXMM(cpustate, ea, src);
2322      XMM((modrm >> 3) & 0x7).d[0] = src.d[0];
2323      XMM((modrm >> 3) & 0x7).d[1] = src.d[0];
2324      XMM((modrm >> 3) & 0x7).d[2] = src.d[2];
2325      XMM((modrm >> 3) & 0x7).d[3] = src.d[2];
2326   }
2327   CYCLES(cpustate,1);     // TODO: correct cycle count
2328}
2329
2330static void SSEOP(movshdup_r128_rm128)(i386_state *cpustate) // Opcode f3 0f 16
2331{
2332   UINT8 modrm = FETCH(cpustate);
2333   if( modrm >= 0xc0 ) {
2334      XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[1];
2335      XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[1];
2336      XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[3];
2337      XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[3];
2338   } else {
2339      XMM_REG src;
2340      UINT32 ea = GetEA(cpustate, modrm, 0);
2341      READXMM(cpustate, ea, src);
2342      XMM((modrm >> 3) & 0x7).d[0] = src.d[1];
2343      XMM((modrm >> 3) & 0x7).d[1] = src.d[1];
2344      XMM((modrm >> 3) & 0x7).d[2] = src.d[3];
2345      XMM((modrm >> 3) & 0x7).d[3] = src.d[3];
2346   }
2347   CYCLES(cpustate,1);     // TODO: correct cycle count
2348}
2349
2542350static void SSEOP(movaps_r128_rm128)(i386_state *cpustate) // Opcode 0f 28
2552351{
2562352   UINT8 modrm = FETCH(cpustate);
r23891r23892
2602356      UINT32 ea = GetEA(cpustate, modrm, 0);
2612357      READXMM(cpustate, ea, XMM((modrm >> 3) & 0x7));
2622358   }
2359   CYCLES(cpustate,1);     // TODO: correct cycle count
2632360}
2642361
2652362static void SSEOP(movaps_rm128_r128)(i386_state *cpustate) // Opcode 0f 29
r23891r23892
2712368      UINT32 ea = GetEA(cpustate, modrm, 0);
2722369      WRITEXMM(cpustate, ea, XMM((modrm >> 3) & 0x7));
2732370   }
2371   CYCLES(cpustate,1);     // TODO: correct cycle count
2742372}
2752373
2374static void SSEOP(movups_r128_rm128)(i386_state *cpustate) // Opcode 0f 10
2375{
2376   UINT8 modrm = FETCH(cpustate);
2377   if( modrm >= 0xc0 ) {
2378      XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
2379   } else {
2380      UINT32 ea = GetEA(cpustate, modrm, 0);
2381      READXMM(cpustate, ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2382   }
2383   CYCLES(cpustate,1);     // TODO: correct cycle count
2384}
2385
2386static void SSEOP(movups_rm128_r128)(i386_state *cpustate) // Opcode 0f 11
2387{
2388   UINT8 modrm = FETCH(cpustate);
2389   if( modrm >= 0xc0 ) {
2390      XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
2391   } else {
2392      UINT32 ea = GetEA(cpustate, modrm, 0);
2393      WRITEXMM(cpustate, ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
2394   }
2395   CYCLES(cpustate,1);     // TODO: correct cycle count
2396}
2397
2398static void SSEOP(movlps_r128_m64)(i386_state *cpustate) // Opcode 0f 12
2399{
2400   UINT8 modrm = FETCH(cpustate);
2401   if( modrm >= 0xc0 ) {
2402      // unsupported by cpu
2403      CYCLES(cpustate,1);     // TODO: correct cycle count
2404   } else {
2405      UINT32 ea = GetEA(cpustate, modrm, 0);
2406      READXMM_LO64(cpustate, ea, XMM((modrm >> 3) & 0x7));
2407      CYCLES(cpustate,1);     // TODO: correct cycle count
2408   }
2409}
2410
2411static void SSEOP(movlps_m64_r128)(i386_state *cpustate) // Opcode 0f 13
2412{
2413   UINT8 modrm = FETCH(cpustate);
2414   if( modrm >= 0xc0 ) {
2415      // unsupported by cpu
2416      CYCLES(cpustate,1);     // TODO: correct cycle count
2417   } else {
2418      UINT32 ea = GetEA(cpustate, modrm, 0);
2419      WRITEXMM_LO64(cpustate, ea, XMM((modrm >> 3) & 0x7));
2420      CYCLES(cpustate,1);     // TODO: correct cycle count
2421   }
2422}
2423
2424static void SSEOP(movhps_r128_m64)(i386_state *cpustate) // Opcode 0f 16
2425{
2426   UINT8 modrm = FETCH(cpustate);
2427   if( modrm >= 0xc0 ) {
2428      // unsupported by cpu
2429      CYCLES(cpustate,1);     // TODO: correct cycle count
2430   } else {
2431      UINT32 ea = GetEA(cpustate, modrm, 0);
2432      READXMM_HI64(cpustate, ea, XMM((modrm >> 3) & 0x7));
2433      CYCLES(cpustate,1);     // TODO: correct cycle count
2434   }
2435}
2436
2437static void SSEOP(movhps_m64_r128)(i386_state *cpustate) // Opcode 0f 17
2438{
2439   UINT8 modrm = FETCH(cpustate);
2440   if( modrm >= 0xc0 ) {
2441      // unsupported by cpu
2442      CYCLES(cpustate,1);     // TODO: correct cycle count
2443   } else {
2444      UINT32 ea = GetEA(cpustate, modrm, 0);
2445      WRITEXMM_HI64(cpustate,ea, XMM((modrm >> 3) & 0x7));
2446      CYCLES(cpustate,1);     // TODO: correct cycle count
2447   }
2448}
2449
2450static void SSEOP(movntps_m128_r128)(i386_state *cpustate) // Opcode 0f 2b
2451{
2452   UINT8 modrm = FETCH(cpustate);
2453   if( modrm >= 0xc0 ) {
2454      // unsupported by cpu
2455      CYCLES(cpustate,1);     // TODO: correct cycle count
2456   } else {
2457      // since cache is not implemented
2458      UINT32 ea = GetEA(cpustate, modrm, 0);
2459      WRITEXMM(cpustate, ea, XMM((modrm >> 3) & 0x7));
2460      CYCLES(cpustate,1);     // TODO: correct cycle count
2461   }
2462}
2463
2464static void SSEOP(movmskps_r16_r128)(i386_state *cpustate) // Opcode 0f 50
2465{
2466   UINT8 modrm = FETCH(cpustate);
2467   if( modrm >= 0xc0 ) {
2468      int b;
2469      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2470      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2471      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2472      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2473      STORE_REG16(modrm, b);
2474   }
2475   CYCLES(cpustate,1);     // TODO: correct cycle count
2476}
2477
2478static void SSEOP(movmskps_r32_r128)(i386_state *cpustate) // Opcode 0f 50
2479{
2480   UINT8 modrm = FETCH(cpustate);
2481   if( modrm >= 0xc0 ) {
2482      int b;
2483      b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
2484      b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
2485      b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
2486      b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
2487      STORE_REG32(modrm, b);
2488   }
2489   CYCLES(cpustate,1);     // TODO: correct cycle count
2490}
2491
2492static void SSEOP(movq2dq_r128_r64)(i386_state *cpustate) // Opcode f3 0f d6
2493{
2494   MMXPROLOG(cpustate);
2495   UINT8 modrm = FETCH(cpustate);
2496   if( modrm >= 0xc0 ) {
2497      XMM((modrm >> 3) & 0x7).q[0] = MMX(modrm & 7).q;
2498      XMM((modrm >> 3) & 0x7).q[1] = 0;
2499   }
2500   CYCLES(cpustate,1);     // TODO: correct cycle count
2501}
2502
2503static void SSEOP(movdqu_r128_rm128)(i386_state *cpustate) // Opcode f3 0f 6f
2504{
2505   MMXPROLOG(cpustate);
2506   UINT8 modrm = FETCH(cpustate);
2507   if( modrm >= 0xc0 ) {
2508      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2509      XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1];
2510   } else {
2511      UINT32 ea = GetEA(cpustate, modrm, 0);
2512      READXMM(cpustate, ea, XMM((modrm >> 3) & 0x7));
2513   }
2514   CYCLES(cpustate,1);     // TODO: correct cycle count
2515}
2516
2517static void SSEOP(movdqu_rm128_r128)(i386_state *cpustate) // Opcode f3 0f 7f
2518{
2519   MMXPROLOG(cpustate);
2520   UINT8 modrm = FETCH(cpustate);
2521   if( modrm >= 0xc0 ) {
2522      XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
2523      XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1];
2524   } else {
2525      UINT32 ea = GetEA(cpustate, modrm, 0);
2526      WRITEXMM(cpustate, ea, XMM((modrm >> 3) & 0x7));
2527   }
2528   CYCLES(cpustate,1);     // TODO: correct cycle count
2529}
2530
2531static void SSEOP(movq_r128_r128m64)(i386_state *cpustate) // Opcode f3 0f 7e
2532{
2533   MMXPROLOG(cpustate);
2534   UINT8 modrm = FETCH(cpustate);
2535   if( modrm >= 0xc0 ) {
2536      XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
2537      XMM((modrm >> 3) & 0x7).q[1] = 0;
2538   } else {
2539      UINT32 ea = GetEA(cpustate, modrm, 0);
2540      XMM((modrm >> 3) & 0x7).q[0] = READ64(cpustate,ea);
2541      XMM((modrm >> 3) & 0x7).q[1] = 0;
2542   }
2543   CYCLES(cpustate,1);     // TODO: correct cycle count
2544}
2545
2546static void SSEOP(pmovmskb_r16_r64)(i386_state *cpustate) // Opcode 0f d7
2547{
2548   //MMXPROLOG(cpustate);
2549   UINT8 modrm = FETCH(cpustate);
2550   if( modrm >= 0xc0 ) {
2551      int b;
2552      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2553      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2554      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2555      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2556      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2557      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2558      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2559      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2560      STORE_REG16(modrm, b);
2561   }
2562   CYCLES(cpustate,1);     // TODO: correct cycle count
2563}
2564
2565static void SSEOP(pmovmskb_r32_r64)(i386_state *cpustate) // Opcode 0f d7
2566{
2567   //MMXPROLOG(cpustate);
2568   UINT8 modrm = FETCH(cpustate);
2569   if( modrm >= 0xc0 ) {
2570      int b;
2571      b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
2572      b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
2573      b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
2574      b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
2575      b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
2576      b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
2577      b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
2578      b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
2579      STORE_REG32(modrm, b);
2580   }
2581   CYCLES(cpustate,1);     // TODO: correct cycle count
2582}
2583
2584static void SSEOP(xorps)(i386_state *cpustate) // Opcode 0f 57
2585{
2586   UINT8 modrm = FETCH(cpustate);
2587   if( modrm >= 0xc0 ) {
2588      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ XMM(modrm & 0x7).d[0];
2589      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ XMM(modrm & 0x7).d[1];
2590      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ XMM(modrm & 0x7).d[2];
2591      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ XMM(modrm & 0x7).d[3];
2592   } else {
2593      XMM_REG src;
2594      UINT32 ea = GetEA(cpustate, modrm, 0);
2595      READXMM(cpustate, ea, src);
2596      XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ src.d[0];
2597      XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ src.d[1];
2598      XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ src.d[2];
2599      XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ src.d[3];
2600   }
2601   CYCLES(cpustate,1);     // TODO: correct cycle count
2602}
2603
2762604static void SSEOP(addps)(i386_state *cpustate) // Opcode 0f 58
2772605{
2782606   UINT8 modrm = FETCH(cpustate);
r23891r23892
2902618      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + src.f[2];
2912619      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + src.f[3];
2922620   }
2621   CYCLES(cpustate,1);     // TODO: correct cycle count
2932622}
2942623
295static void SSEOP(mulps)(i386_state *cpustate) // Opcode 0f 59
2624static void SSEOP(sqrtps_r128_rm128)(i386_state *cpustate) // Opcode 0f 51
2962625{
2972626   UINT8 modrm = FETCH(cpustate);
2982627   if( modrm >= 0xc0 ) {
2628      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
2629      XMM((modrm >> 3) & 0x7).f[1] = sqrt(XMM(modrm & 0x7).f[1]);
2630      XMM((modrm >> 3) & 0x7).f[2] = sqrt(XMM(modrm & 0x7).f[2]);
2631      XMM((modrm >> 3) & 0x7).f[3] = sqrt(XMM(modrm & 0x7).f[3]);
2632   } else {
2633      XMM_REG src;
2634      UINT32 ea = GetEA(cpustate, modrm, 0);
2635      READXMM(cpustate, ea, src);
2636      XMM((modrm >> 3) & 0x7).f[0] = sqrt(src.f[0]);
2637      XMM((modrm >> 3) & 0x7).f[1] = sqrt(src.f[1]);
2638      XMM((modrm >> 3) & 0x7).f[2] = sqrt(src.f[2]);
2639      XMM((modrm >> 3) & 0x7).f[3] = sqrt(src.f[3]);
2640   }
2641   CYCLES(cpustate,1);     // TODO: correct cycle count
2642}
2643
2644static void SSEOP(rsqrtps_r128_rm128)(i386_state *cpustate) // Opcode 0f 52
2645{
2646   UINT8 modrm = FETCH(cpustate);
2647   if( modrm >= 0xc0 ) {
2648      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
2649      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(XMM(modrm & 0x7).f[1]);
2650      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(XMM(modrm & 0x7).f[2]);
2651      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(XMM(modrm & 0x7).f[3]);
2652   } else {
2653      XMM_REG src;
2654      UINT32 ea = GetEA(cpustate, modrm, 0);
2655      READXMM(cpustate, ea, src);
2656      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(src.f[0]);
2657      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(src.f[1]);
2658      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(src.f[2]);
2659      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(src.f[3]);
2660   }
2661   CYCLES(cpustate,1);     // TODO: correct cycle count
2662}
2663
2664static void SSEOP(rcpps_r128_rm128)(i386_state *cpustate) // Opcode 0f 53
2665{
2666   UINT8 modrm = FETCH(cpustate);
2667   if( modrm >= 0xc0 ) {
2668      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
2669      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / XMM(modrm & 0x7).f[1];
2670      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / XMM(modrm & 0x7).f[2];
2671      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / XMM(modrm & 0x7).f[3];
2672   } else {
2673      XMM_REG src;
2674      UINT32 ea = GetEA(cpustate, modrm, 0);
2675      READXMM(cpustate, ea, src);
2676      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / src.f[0];
2677      XMM((modrm >> 3) & 0x7).f[1] = 1.0 / src.f[1];
2678      XMM((modrm >> 3) & 0x7).f[2] = 1.0 / src.f[2];
2679      XMM((modrm >> 3) & 0x7).f[3] = 1.0 / src.f[3];
2680   }
2681   CYCLES(cpustate,1);     // TODO: correct cycle count
2682}
2683
2684static void SSEOP(andps_r128_rm128)(i386_state *cpustate) // Opcode 0f 54
2685{
2686   UINT8 modrm = FETCH(cpustate);
2687   if( modrm >= 0xc0 ) {
2688      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0];
2689      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1];
2690   } else {
2691      XMM_REG src;
2692      UINT32 ea = GetEA(cpustate, modrm, 0);
2693      READXMM(cpustate, ea, src);
2694      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
2695      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
2696   }
2697   CYCLES(cpustate,1);     // TODO: correct cycle count
2698}
2699
2700static void SSEOP(andnps_r128_rm128)(i386_state *cpustate) // Opcode 0f 55
2701{
2702   UINT8 modrm = FETCH(cpustate);
2703   if( modrm >= 0xc0 ) {
2704      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0];
2705      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1];
2706   } else {
2707      XMM_REG src;
2708      UINT32 ea = GetEA(cpustate, modrm, 0);
2709      READXMM(cpustate, ea, src);
2710      XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
2711      XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
2712   }
2713   CYCLES(cpustate,1);     // TODO: correct cycle count
2714}
2715
2716static void SSEOP(orps_r128_rm128)(i386_state *cpustate) // Opcode 0f 56
2717{
2718   UINT8 modrm = FETCH(cpustate);
2719   if( modrm >= 0xc0 ) {
2720      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0];
2721      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1];
2722   } else {
2723      XMM_REG src;
2724      UINT32 ea = GetEA(cpustate, modrm, 0);
2725      READXMM(cpustate, ea, src);
2726      XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0];
2727      XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1];
2728   }
2729   CYCLES(cpustate,1);     // TODO: correct cycle count
2730}
2731
2732static void SSEOP(mulps)(i386_state *cpustate) // Opcode 0f 59 ????
2733{
2734   UINT8 modrm = FETCH(cpustate);
2735   if( modrm >= 0xc0 ) {
2992736      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
3002737      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * XMM(modrm & 0x7).f[1];
3012738      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * XMM(modrm & 0x7).f[2];
r23891r23892
3092746      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * src.f[2];
3102747      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * src.f[3];
3112748   }
2749   CYCLES(cpustate,1);     // TODO: correct cycle count
3122750}
3132751
2752static void SSEOP(subps)(i386_state *cpustate) // Opcode 0f 5c
2753{
2754   UINT8 modrm = FETCH(cpustate);
2755   if( modrm >= 0xc0 ) {
2756      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
2757      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - XMM(modrm & 0x7).f[1];
2758      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2];
2759      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - XMM(modrm & 0x7).f[3];
2760   } else {
2761      XMM_REG src;
2762      UINT32 ea = GetEA(cpustate, modrm, 0);
2763      READXMM(cpustate, ea, src);
2764      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
2765      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - src.f[1];
2766      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - src.f[2];
2767      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - src.f[3];
2768   }
2769   CYCLES(cpustate,1);     // TODO: correct cycle count
2770}
2771
2772INLINE float sse_min_single(float src1, float src2)
2773{
2774   /*if ((src1 == 0) && (src2 == 0))
2775      return src2;
2776   if (src1 = SNaN)
2777      return src2;
2778   if (src2 = SNaN)
2779      return src2;*/
2780   if (src1 < src2)
2781      return src1;
2782   return src2;
2783}
2784
2785static void SSEOP(minps)(i386_state *cpustate) // Opcode 0f 5d
2786{
2787   UINT8 modrm = FETCH(cpustate);
2788   if( modrm >= 0xc0 ) {
2789      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
2790      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
2791      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
2792      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
2793   } else {
2794      XMM_REG src;
2795      UINT32 ea = GetEA(cpustate, modrm, 0);
2796      READXMM(cpustate, ea, src);
2797      XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
2798      XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
2799      XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
2800      XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
2801   }
2802   CYCLES(cpustate,1);     // TODO: correct cycle count
2803}
2804
2805static void SSEOP(divps)(i386_state *cpustate) // Opcode 0f 5e
2806{
2807   UINT8 modrm = FETCH(cpustate);
2808   if( modrm >= 0xc0 ) {
2809      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
2810      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / XMM(modrm & 0x7).f[1];
2811      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / XMM(modrm & 0x7).f[2];
2812      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / XMM(modrm & 0x7).f[3];
2813   } else {
2814      XMM_REG src;
2815      UINT32 ea = GetEA(cpustate, modrm, 0);
2816      READXMM(cpustate, ea, src);
2817      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
2818      XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / src.f[1];
2819      XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / src.f[2];
2820      XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / src.f[3];
2821   }
2822   CYCLES(cpustate,1);     // TODO: correct cycle count
2823}
2824
2825INLINE float sse_max_single(float src1, float src2)
2826{
2827   /*if ((src1 == 0) && (src2 == 0))
2828      return src2;
2829   if (src1 = SNaN)
2830      return src2;
2831   if (src2 = SNaN)
2832      return src2;*/
2833   if (src1 > src2)
2834      return src1;
2835   return src2;
2836}
2837
2838static void SSEOP(maxps)(i386_state *cpustate) // Opcode 0f 5f
2839{
2840   UINT8 modrm = FETCH(cpustate);
2841   if( modrm >= 0xc0 ) {
2842      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
2843      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
2844      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
2845      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
2846   } else {
2847      XMM_REG src;
2848      UINT32 ea = GetEA(cpustate, modrm, 0);
2849      READXMM(cpustate, ea, src);
2850      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
2851      XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
2852      XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
2853      XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
2854   }
2855   CYCLES(cpustate,1);     // TODO: correct cycle count
2856}
2857
2858static void SSEOP(maxss_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 5f
2859{
2860   UINT8 modrm = FETCH(cpustate);
2861   if( modrm >= 0xc0 ) {
2862      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
2863   } else {
2864      XMM_REG src;
2865      UINT32 ea = GetEA(cpustate, modrm, 0);
2866      src.d[0]=READ32(cpustate, ea);
2867      XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
2868   }
2869   CYCLES(cpustate,1);     // TODO: correct cycle count
2870}
2871
2872static void SSEOP(addss)(i386_state *cpustate) // Opcode f3 0f 58
2873{
2874   UINT8 modrm = FETCH(cpustate);
2875   if( modrm >= 0xc0 ) {
2876      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
2877   } else {
2878      XMM_REG src;
2879      UINT32 ea = GetEA(cpustate, modrm, 0);
2880      READXMM(cpustate, ea, src);
2881      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
2882   }
2883   CYCLES(cpustate,1);     // TODO: correct cycle count
2884}
2885
2886static void SSEOP(subss)(i386_state *cpustate) // Opcode f3 0f 5c
2887{
2888   UINT8 modrm = FETCH(cpustate);
2889   if( modrm >= 0xc0 ) {
2890      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
2891   } else {
2892      XMM_REG src;
2893      UINT32 ea = GetEA(cpustate, modrm, 0);
2894      READXMM(cpustate, ea, src);
2895      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
2896   }
2897   CYCLES(cpustate,1);     // TODO: correct cycle count
2898}
2899
2900static void SSEOP(mulss)(i386_state *cpustate) // Opcode f3 0f 5e
2901{
2902   UINT8 modrm = FETCH(cpustate);
2903   if( modrm >= 0xc0 ) {
2904      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
2905   } else {
2906      XMM_REG src;
2907      UINT32 ea = GetEA(cpustate, modrm, 0);
2908      READXMM(cpustate, ea, src);
2909      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
2910   }
2911   CYCLES(cpustate,1);     // TODO: correct cycle count
2912}
2913
2914static void SSEOP(divss)(i386_state *cpustate) // Opcode 0f 59
2915{
2916   UINT8 modrm = FETCH(cpustate);
2917   if( modrm >= 0xc0 ) {
2918      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
2919   } else {
2920      XMM_REG src;
2921      UINT32 ea = GetEA(cpustate, modrm, 0);
2922      READXMM(cpustate, ea, src);
2923      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
2924   }
2925   CYCLES(cpustate,1);     // TODO: correct cycle count
2926}
2927
2928static void SSEOP(rcpss_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 53
2929{
2930   UINT8 modrm = FETCH(cpustate);
2931   if( modrm >= 0xc0 ) {
2932      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
2933   } else {
2934      XMM_REG s;
2935      UINT32 ea = GetEA(cpustate, modrm, 0);
2936      s.d[0]=READ32(cpustate, ea);
2937      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / s.f[0];
2938   }
2939   CYCLES(cpustate,1);     // TODO: correct cycle count
2940}
2941
2942static void SSEOP(sqrtss_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 51
2943{
2944   UINT8 modrm = FETCH(cpustate);
2945   if( modrm >= 0xc0 ) {
2946      XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
2947   } else {
2948      XMM_REG s;
2949      UINT32 ea = GetEA(cpustate, modrm, 0);
2950      s.d[0]=READ32(cpustate, ea);
2951      XMM((modrm >> 3) & 0x7).f[0] = sqrt(s.f[0]);
2952   }
2953   CYCLES(cpustate,1);     // TODO: correct cycle count
2954}
2955
2956static void SSEOP(rsqrtss_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 52
2957{
2958   UINT8 modrm = FETCH(cpustate);
2959   if( modrm >= 0xc0 ) {
2960      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
2961   } else {
2962      XMM_REG s;
2963      UINT32 ea = GetEA(cpustate, modrm, 0);
2964      s.d[0]=READ32(cpustate, ea);
2965      XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(s.f[0]);
2966   }
2967   CYCLES(cpustate,1);     // TODO: correct cycle count
2968}
2969
2970static void SSEOP(minss_r128_r128m32)(i386_state *cpustate) // Opcode f3 0f 5d
2971{
2972   UINT8 modrm = FETCH(cpustate);
2973   if( modrm >= 0xc0 ) {
2974      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < XMM(modrm & 0x7).f[0] ? XMM((modrm >> 3) & 0x7).f[0] : XMM(modrm & 0x7).f[0];
2975   } else {
2976      XMM_REG s;
2977      UINT32 ea = GetEA(cpustate, modrm, 0);
2978      s.d[0] = READ32(cpustate, ea);
2979      XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < s.f[0] ? XMM((modrm >> 3) & 0x7).f[0] : s.f[0];
2980   }
2981   CYCLES(cpustate,1);     // TODO: correct cycle count
2982}
2983
2984static void SSEOP(comiss_r128_r128m32)(i386_state *cpustate) // Opcode 0f 2f
2985{
2986   float32 a,b;
2987   UINT8 modrm = FETCH(cpustate);
2988   if( modrm >= 0xc0 ) {
2989      a = XMM((modrm >> 3) & 0x7).d[0];
2990      b = XMM(modrm & 0x7).d[0];
2991   } else {
2992      XMM_REG src;
2993      UINT32 ea = GetEA(cpustate, modrm, 0);
2994      READXMM(cpustate, ea, src);
2995      a = XMM((modrm >> 3) & 0x7).d[0];
2996      b = src.d[0];
2997   }
2998   cpustate->OF=0;
2999   cpustate->SF=0;
3000   cpustate->AF=0;
3001   if (float32_is_nan(a) || float32_is_nan(b))
3002   {
3003      cpustate->ZF = 1;
3004      cpustate->PF = 1;
3005      cpustate->CF = 1;
3006   }
3007   else
3008   {
3009      cpustate->ZF = 0;
3010      cpustate->PF = 0;
3011      cpustate->CF = 0;
3012      if (float32_eq(a, b))
3013         cpustate->ZF = 1;
3014      if (float32_lt(a, b))
3015         cpustate->CF = 1;
3016   }
3017   // should generate exception when at least one of the operands is either QNaN or SNaN
3018   CYCLES(cpustate,1);     // TODO: correct cycle count
3019}
3020
3021static void SSEOP(ucomiss_r128_r128m32)(i386_state *cpustate) // Opcode 0f 2e
3022{
3023   float32 a,b;
3024   UINT8 modrm = FETCH(cpustate);
3025   if( modrm >= 0xc0 ) {
3026      a = XMM((modrm >> 3) & 0x7).d[0];
3027      b = XMM(modrm & 0x7).d[0];
3028   } else {
3029      XMM_REG src;
3030      UINT32 ea = GetEA(cpustate, modrm, 0);
3031      READXMM(cpustate, ea, src);
3032      a = XMM((modrm >> 3) & 0x7).d[0];
3033      b = src.d[0];
3034   }
3035   cpustate->OF=0;
3036   cpustate->SF=0;
3037   cpustate->AF=0;
3038   if (float32_is_nan(a) || float32_is_nan(b))
3039   {
3040      cpustate->ZF = 1;
3041      cpustate->PF = 1;
3042      cpustate->CF = 1;
3043   }
3044   else
3045   {
3046      cpustate->ZF = 0;
3047      cpustate->PF = 0;
3048      cpustate->CF = 0;
3049      if (float32_eq(a, b))
3050         cpustate->ZF = 1;
3051      if (float32_lt(a, b))
3052         cpustate->CF = 1;
3053   }
3054   // should generate exception when at least one of the operands is SNaN
3055   CYCLES(cpustate,1);     // TODO: correct cycle count
3056}
3057
3143058static void SSEOP(shufps)(i386_state *cpustate) // Opcode 0f 67
3153059{
3163060   UINT8 modrm = FETCH(cpustate);
r23891r23892
3413085      XMM(d).d[2]=src.d[m3];
3423086      XMM(d).d[3]=src.d[m4];
3433087   }
3088   CYCLES(cpustate,1);     // TODO: correct cycle count
3443089}
3453090
346static void MMXOP(emms)(i386_state *cpustate) // Opcode 0f 77
3091static void SSEOP(unpcklps_r128_rm128)(i386_state *cpustate) // Opcode 0f 14
3473092{
348   cpustate->x87_tw = 0xffff; // tag word = 0xffff
349   // TODO
3093   UINT8 modrm = FETCH(cpustate);
3094   int s,d;
3095   s=modrm & 0x7;
3096   d=(modrm >> 3) & 0x7;
3097   if( modrm >= 0xc0 ) {
3098      XMM(d).d[3]=XMM(s).d[1];
3099      XMM(d).d[2]=XMM(d).d[1];
3100      XMM(d).d[1]=XMM(s).d[0];
3101      //XMM(d).d[0]=XMM(d).d[0];
3102   } else {
3103      XMM_REG src;
3104      UINT32 ea = GetEA(cpustate, modrm, 0);
3105      READXMM(cpustate, ea, src);
3106      XMM(d).d[3]=src.d[1];
3107      XMM(d).d[2]=XMM(d).d[1];
3108      XMM(d).d[1]=src.d[0];
3109   }
3503110   CYCLES(cpustate,1);     // TODO: correct cycle count
3513111}
3112
3113static void SSEOP(unpckhps_r128_rm128)(i386_state *cpustate) // Opcode 0f 15
3114{
3115   UINT8 modrm = FETCH(cpustate);
3116   int s,d;
3117   s=modrm & 0x7;
3118   d=(modrm >> 3) & 0x7;
3119   if( modrm >= 0xc0 ) {
3120      XMM(d).d[0]=XMM(d).d[2];
3121      XMM(d).d[1]=XMM(s).d[2];
3122      XMM(d).d[2]=XMM(d).d[3];
3123      XMM(d).d[3]=XMM(s).d[3];
3124   } else {
3125      XMM_REG src;
3126      UINT32 ea = GetEA(cpustate, modrm, 0);
3127      READXMM(cpustate, ea, src);
3128      XMM(d).d[0]=XMM(d).d[2];
3129      XMM(d).d[1]=src.d[2];
3130      XMM(d).d[2]=XMM(d).d[3];
3131      XMM(d).d[3]=src.d[3];
3132   }
3133   CYCLES(cpustate,1);     // TODO: correct cycle count
3134}
3135
3136INLINE bool sse_issingleordered(float op1, float op2)
3137{
3138   // TODO: true when at least one of the two source operands being compared is a NaN
3139   return (op1 != op1) || (op1 != op2);
3140}
3141
3142INLINE bool sse_issingleunordered(float op1, float op2)
3143{
3144   // TODO: true when neither source operand is a NaN
3145   return !((op1 != op1) || (op1 != op2));
3146}
3147
3148INLINE void sse_predicate_compare_single(UINT8 imm8, XMM_REG d, XMM_REG s)
3149{
3150   switch (imm8 & 7)
3151   {
3152   case 0:
3153      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3154      d.d[1]=d.f[1] == s.f[1] ? 0xffffffff : 0;
3155      d.d[2]=d.f[2] == s.f[2] ? 0xffffffff : 0;
3156      d.d[3]=d.f[3] == s.f[3] ? 0xffffffff : 0;
3157      break;
3158   case 1:
3159      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3160      d.d[1]=d.f[1] < s.f[1] ? 0xffffffff : 0;
3161      d.d[2]=d.f[2] < s.f[2] ? 0xffffffff : 0;
3162      d.d[3]=d.f[3] < s.f[3] ? 0xffffffff : 0;
3163      break;
3164   case 2:
3165      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3166      d.d[1]=d.f[1] <= s.f[1] ? 0xffffffff : 0;
3167      d.d[2]=d.f[2] <= s.f[2] ? 0xffffffff : 0;
3168      d.d[3]=d.f[3] <= s.f[3] ? 0xffffffff : 0;
3169      break;
3170   case 3:
3171      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3172      d.d[1]=sse_issingleunordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3173      d.d[2]=sse_issingleunordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3174      d.d[3]=sse_issingleunordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3175      break;
3176   case 4:
3177      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3178      d.d[1]=d.f[1] != s.f[1] ? 0xffffffff : 0;
3179      d.d[2]=d.f[2] != s.f[2] ? 0xffffffff : 0;
3180      d.d[3]=d.f[3] != s.f[3] ? 0xffffffff : 0;
3181      break;
3182   case 5:
3183      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3184      d.d[1]=d.f[1] < s.f[1] ? 0 : 0xffffffff;
3185      d.d[2]=d.f[2] < s.f[2] ? 0 : 0xffffffff;
3186      d.d[3]=d.f[3] < s.f[3] ? 0 : 0xffffffff;
3187      break;
3188   case 6:
3189      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3190      d.d[1]=d.f[1] <= s.f[1] ? 0 : 0xffffffff;
3191      d.d[2]=d.f[2] <= s.f[2] ? 0 : 0xffffffff;
3192      d.d[3]=d.f[3] <= s.f[3] ? 0 : 0xffffffff;
3193      break;
3194   case 7:
3195      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3196      d.d[1]=sse_issingleordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
3197      d.d[2]=sse_issingleordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
3198      d.d[3]=sse_issingleordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
3199      break;
3200   }
3201}
3202
3203INLINE void sse_predicate_compare_single_scalar(UINT8 imm8, XMM_REG d, XMM_REG s)
3204{
3205   switch (imm8 & 7)
3206   {
3207   case 0:
3208      s.d[0]=s.f[0] == s.f[0] ? 0xffffffff : 0;
3209      break;
3210   case 1:
3211      d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
3212      break;
3213   case 2:
3214      d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
3215      break;
3216   case 3:
3217      d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3218      break;
3219   case 4:
3220      d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
3221      break;
3222   case 5:
3223      d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
3224      break;
3225   case 6:
3226      d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
3227      break;
3228   case 7:
3229      d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
3230      break;
3231   }
3232}
3233
3234static void SSEOP(cmpps_r128_rm128_i8)(i386_state *cpustate) // Opcode 0f c2
3235{
3236   UINT8 modrm = FETCH(cpustate);
3237   if( modrm >= 0xc0 ) {
3238      int s,d;
3239      UINT8 imm8 = FETCH(cpustate);
3240      s=modrm & 0x7;
3241      d=(modrm >> 3) & 0x7;
3242      sse_predicate_compare_single(imm8, XMM(d), XMM(s));
3243   } else {
3244      int d;
3245      XMM_REG s;
3246      UINT32 ea = GetEA(cpustate, modrm, 0);
3247      UINT8 imm8 = FETCH(cpustate);
3248      READXMM(cpustate, ea, s);
3249      d=(modrm >> 3) & 0x7;
3250      sse_predicate_compare_single(imm8, XMM(d), s);
3251   }
3252   CYCLES(cpustate,1);     // TODO: correct cycle count
3253}
3254
3255static void SSEOP(cmpss_r128_r128m32_i8)(i386_state *cpustate) // Opcode f3 0f c2
3256{
3257   UINT8 modrm = FETCH(cpustate);
3258   if( modrm >= 0xc0 ) {
3259      int s,d;
3260      UINT8 imm8 = FETCH(cpustate);
3261      s=modrm & 0x7;
3262      d=(modrm >> 3) & 0x7;
3263      sse_predicate_compare_single_scalar(imm8, XMM(d), XMM(s));
3264   } else {
3265      int d;
3266      XMM_REG s;
3267      UINT32 ea = GetEA(cpustate, modrm, 0);
3268      UINT8 imm8 = FETCH(cpustate);
3269      s.d[0]=READ32(cpustate, ea);
3270      d=(modrm >> 3) & 0x7;
3271      sse_predicate_compare_single_scalar(imm8, XMM(d), s);
3272   }
3273   CYCLES(cpustate,1);     // TODO: correct cycle count
3274}
3275
3276static void SSEOP(pinsrw_r64_r16m16_i8)(i386_state *cpustate) // Opcode 0f c4
3277{
3278   MMXPROLOG(cpustate);
3279   UINT8 modrm = FETCH(cpustate);
3280   if( modrm >= 0xc0 ) {
3281      UINT8 imm8 = FETCH(cpustate);
3282      UINT16 v = LOAD_RM16(modrm);
3283      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3284   } else {
3285      UINT32 ea = GetEA(cpustate, modrm, 0);
3286      UINT8 imm8 = FETCH(cpustate);
3287      UINT16 v = READ16(cpustate, ea);
3288      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3289   }
3290   CYCLES(cpustate,1);     // TODO: correct cycle count
3291}
3292
3293static void SSEOP(pinsrw_r64_r32m16_i8)(i386_state *cpustate) // Opcode 0f c4
3294{
3295   MMXPROLOG(cpustate);
3296   UINT8 modrm = FETCH(cpustate);
3297   if( modrm >= 0xc0 ) {
3298      UINT8 imm8 = FETCH(cpustate);
3299      UINT16 v = (UINT16)LOAD_RM32(modrm);
3300      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3301   } else {
3302      UINT32 ea = GetEA(cpustate, modrm, 0);
3303      UINT8 imm8 = FETCH(cpustate);
3304      UINT16 v = READ16(cpustate, ea);
3305      MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
3306   }
3307   CYCLES(cpustate,1);     // TODO: correct cycle count
3308}
3309
3310static void SSEOP(pextrw_r16_r64_i8)(i386_state *cpustate) // Opcode 0f c5
3311{
3312   //MMXPROLOG(cpustate);
3313   UINT8 modrm = FETCH(cpustate);
3314   if( modrm >= 0xc0 ) {
3315      UINT8 imm8 = FETCH(cpustate);
3316      STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3317   } else {
3318      //UINT8 imm8 = FETCH(cpustate);
3319      report_invalid_modrm(cpustate, "pextrw_r16_r64_i8", modrm);
3320   }
3321   CYCLES(cpustate,1);     // TODO: correct cycle count
3322}
3323
3324static void SSEOP(pextrw_r32_r64_i8)(i386_state *cpustate) // Opcode 0f c5
3325{
3326   //MMXPROLOG(cpustate);
3327   UINT8 modrm = FETCH(cpustate);
3328   if( modrm >= 0xc0 ) {
3329      UINT8 imm8 = FETCH(cpustate);
3330      STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
3331   } else {
3332      //UINT8 imm8 = FETCH(cpustate);
3333      report_invalid_modrm(cpustate, "pextrw_r32_r64_i8", modrm);
3334   }
3335   CYCLES(cpustate,1);     // TODO: correct cycle count
3336}
3337
3338static void SSEOP(pminub_r64_rm64)(i386_state *cpustate) // Opcode 0f da
3339{
3340   int n;
3341   MMXPROLOG(cpustate);
3342   UINT8 modrm = FETCH(cpustate);
3343   if( modrm >= 0xc0 ) {
3344      for (n=0;n < 8;n++)
3345         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3346   } else {
3347      MMX_REG s;
3348      UINT32 ea = GetEA(cpustate, modrm, 0);
3349      READMMX(cpustate, ea, s);
3350      for (n=0;n < 8;n++)
3351         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3352   }
3353   CYCLES(cpustate,1);     // TODO: correct cycle count
3354}
3355
3356static void SSEOP(pmaxub_r64_rm64)(i386_state *cpustate) // Opcode 0f de
3357{
3358   int n;
3359   MMXPROLOG(cpustate);
3360   UINT8 modrm = FETCH(cpustate);
3361   if( modrm >= 0xc0 ) {
3362      for (n=0;n < 8;n++)
3363         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
3364   } else {
3365      MMX_REG s;
3366      UINT32 ea = GetEA(cpustate, modrm, 0);
3367      READMMX(cpustate, ea, s);
3368      for (n=0;n < 8;n++)
3369         MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
3370   }
3371   CYCLES(cpustate,1);     // TODO: correct cycle count
3372}
3373
3374static void SSEOP(pavgb_r64_rm64)(i386_state *cpustate) // Opcode 0f e0
3375{
3376   int n;
3377   MMXPROLOG(cpustate);
3378   UINT8 modrm = FETCH(cpustate);
3379   if( modrm >= 0xc0 ) {
3380      for (n=0;n < 8;n++)
3381         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)MMX(modrm & 0x7).b[n] + 1) >> 1;
3382   } else {
3383      MMX_REG s;
3384      UINT32 ea = GetEA(cpustate, modrm, 0);
3385      READMMX(cpustate, ea, s);
3386      for (n=0;n < 8;n++)
3387         MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)s.b[n] + 1) >> 1;
3388   }
3389   CYCLES(cpustate,1);     // TODO: correct cycle count
3390}
3391
3392static void SSEOP(pavgw_r64_rm64)(i386_state *cpustate) // Opcode 0f e3
3393{
3394   int n;
3395   MMXPROLOG(cpustate);
3396   UINT8 modrm = FETCH(cpustate);
3397   if( modrm >= 0xc0 ) {
3398      for (n=0;n < 4;n++)
3399         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)MMX(modrm & 0x7).w[n] + 1) >> 1;
3400   } else {
3401      MMX_REG s;
3402      UINT32 ea = GetEA(cpustate, modrm, 0);
3403      READMMX(cpustate, ea, s);
3404      for (n=0;n < 4;n++)
3405         MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)s.w[n] + 1) >> 1;
3406   }
3407   CYCLES(cpustate,1);     // TODO: correct cycle count
3408}
3409
3410static void SSEOP(pmulhuw_r64_rm64)(i386_state *cpustate)  // Opcode 0f e4
3411{
3412   MMXPROLOG(cpustate);
3413   UINT8 modrm = FETCH(cpustate);
3414   if( modrm >= 0xc0 ) {
3415      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)MMX(modrm & 7).w[0]) >> 16;
3416      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)MMX(modrm & 7).w[1]) >> 16;
3417      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)MMX(modrm & 7).w[2]) >> 16;
3418      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)MMX(modrm & 7).w[3]) >> 16;
3419   } else {
3420      MMX_REG s;
3421      UINT32 ea = GetEA(cpustate, modrm, 0);
3422      READMMX(cpustate, ea, s);
3423      MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)s.w[0]) >> 16;
3424      MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)s.w[1]) >> 16;
3425      MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)s.w[2]) >> 16;
3426      MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)s.w[3]) >> 16;
3427   }
3428   CYCLES(cpustate,1);     // TODO: correct cycle count
3429}
3430
3431static void SSEOP(pminsw_r64_rm64)(i386_state *cpustate) // Opcode 0f ea
3432{
3433   int n;
3434   MMXPROLOG(cpustate);
3435   UINT8 modrm = FETCH(cpustate);
3436   if( modrm >= 0xc0 ) {
3437      for (n=0;n < 4;n++)
3438         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3439   } else {
3440      MMX_REG s;
3441      UINT32 ea = GetEA(cpustate, modrm, 0);
3442      READMMX(cpustate, ea, s);
3443      for (n=0;n < 4;n++)
3444         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3445   }
3446   CYCLES(cpustate,1);     // TODO: correct cycle count
3447}
3448
3449static void SSEOP(pmaxsw_r64_rm64)(i386_state *cpustate) // Opcode 0f ee
3450{
3451   int n;
3452   MMXPROLOG(cpustate);
3453   UINT8 modrm = FETCH(cpustate);
3454   if( modrm >= 0xc0 ) {
3455      for (n=0;n < 4;n++)
3456         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
3457   } else {
3458      MMX_REG s;
3459      UINT32 ea = GetEA(cpustate, modrm, 0);
3460      READMMX(cpustate, ea, s);
3461      for (n=0;n < 4;n++)
3462         MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
3463   }
3464   CYCLES(cpustate,1);     // TODO: correct cycle count
3465}
3466
3467static void SSEOP(pmuludq_r64_rm64)(i386_state *cpustate) // Opcode 0f f4
3468{
3469   MMXPROLOG(cpustate);
3470   UINT8 modrm = FETCH(cpustate);
3471   if( modrm >= 0xc0 ) {
3472      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)MMX(modrm & 0x7).d[0];
3473   } else {
3474      MMX_REG s;
3475      UINT32 ea = GetEA(cpustate, modrm, 0);
3476      READMMX(cpustate, ea, s);
3477      MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)s.d[0];
3478   }
3479   CYCLES(cpustate,1);     // TODO: correct cycle count
3480}
3481
3482static void SSEOP(psadbw_r64_rm64)(i386_state *cpustate) // Opcode 0f f6
3483{
3484   int n;
3485   INT32 temp;
3486   MMXPROLOG(cpustate);
3487   UINT8 modrm = FETCH(cpustate);
3488   if( modrm >= 0xc0 ) {
3489      temp=0;
3490      for (n=0;n < 8;n++)
3491         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)MMX(modrm & 0x7).b[n]);
3492      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3493   } else {
3494      MMX_REG s;
3495      UINT32 ea = GetEA(cpustate, modrm, 0);
3496      READMMX(cpustate, ea, s);
3497      temp=0;
3498      for (n=0;n < 8;n++)
3499         temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
3500      MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
3501   }
3502   CYCLES(cpustate,1);     // TODO: correct cycle count
3503}
3504
3505static void SSEOP(psubq_r64_rm64)(i386_state *cpustate)  // Opcode 0f fb
3506{
3507   MMXPROLOG(cpustate);
3508   UINT8 modrm = FETCH(cpustate);
3509   if( modrm >= 0xc0 ) {
3510      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - MMX(modrm & 7).q;
3511   } else {
3512      MMX_REG s;
3513      UINT32 ea = GetEA(cpustate, modrm, 0);
3514      READMMX(cpustate, ea, s);
3515      MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - s.q;
3516   }
3517   CYCLES(cpustate,1);     // TODO: correct cycle count
3518}
3519
3520static void SSEOP(pshufhw_r128_rm128_i8)(i386_state *cpustate) // Opcode f3 0f 70
3521{
3522   UINT8 modrm = FETCH(cpustate);
3523   if( modrm >= 0xc0 ) {
3524      XMM_REG t;
3525      int s,d;
3526      UINT8 imm8 = FETCH(cpustate);
3527      s=modrm & 0x7;
3528      d=(modrm >> 3) & 0x7;
3529      t.q[0]=XMM(s).q[1];
3530      XMM(d).q[0]=XMM(s).q[0];
3531      XMM(d).w[4]=t.w[imm8 & 3];
3532      XMM(d).w[5]=t.w[(imm8 >> 2) & 3];
3533      XMM(d).w[6]=t.w[(imm8 >> 4) & 3];
3534      XMM(d).w[7]=t.w[(imm8 >> 6) & 3];
3535   } else {
3536      XMM_REG s;
3537      int d=(modrm >> 3) & 0x7;
3538      UINT32 ea = GetEA(cpustate, modrm, 0);
3539      UINT8 imm8 = FETCH(cpustate);
3540      READXMM(cpustate, ea, s);
3541      XMM(d).q[0]=s.q[0];
3542      XMM(d).w[4]=s.w[4 + (imm8 & 3)];
3543      XMM(d).w[5]=s.w[4 + ((imm8 >> 2) & 3)];
3544      XMM(d).w[6]=s.w[4 + ((imm8 >> 4) & 3)];
3545      XMM(d).w[7]=s.w[4 + ((imm8 >> 6) & 3)];
3546   }
3547   CYCLES(cpustate,1);     // TODO: correct cycle count
3548}
trunk/src/emu/cpu/i386/x87ops.c
r23891r23892
37623762   CYCLES(cpustate, 4);
37633763}
37643764
3765void x87_fcomip_sti(i386_state *cpustate, UINT8 modrm)
3766{
3767   int i = modrm & 7;
3768
3769   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3770   {
3771      x87_set_stack_underflow(cpustate);
3772      cpustate->ZF = 1;
3773      cpustate->PF = 1;
3774      cpustate->CF = 1;
3775   }
3776   else
3777   {
3778      cpustate->x87_sw &= ~X87_SW_C1;
3779
3780      floatx80 a = ST(0);
3781      floatx80 b = ST(i);
3782
3783      if (floatx80_is_nan(a) || floatx80_is_nan(b))
3784      {
3785         cpustate->ZF = 1;
3786         cpustate->PF = 1;
3787         cpustate->CF = 1;
3788         cpustate->x87_sw |= X87_SW_IE;
3789      }
3790      else
3791      {
3792         cpustate->ZF = 0;
3793         cpustate->PF = 0;
3794         cpustate->CF = 0;
3795
3796         if (floatx80_eq(a, b))
3797            cpustate->ZF = 1;
3798
3799         if (floatx80_lt(a, b))
3800            cpustate->CF = 1;
3801      }
3802   }
3803
3804   if (x87_check_exceptions(cpustate))
3805      x87_inc_stack(cpustate);
3806
3807   CYCLES(cpustate, 4); // TODO: correct cycle count
3808}
3809
37653810void x87_fcompp(i386_state *cpustate, UINT8 modrm)
37663811{
37673812   if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
r23891r23892
46514696         switch (modrm)
46524697         {
46534698            case 0xe0: ptr = x87_fstsw_ax;      break;
4699            case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fcomip_sti;    break;
46544700         }
46554701      }
46564702
trunk/src/emu/cpu/i386/i386.c
r23891r23892
3131static void i386_trap_with_error(i386_state* cpustate, int irq, int irq_gate, int trap_level, UINT32 err);
3232static void i286_task_switch(i386_state* cpustate, UINT16 selector, UINT8 nested);
3333static void i386_task_switch(i386_state* cpustate, UINT16 selector, UINT8 nested);
34static void pentium_smi(i386_state* cpustate);
3435
3536#define FAULT(fault,error) {cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error); return;}
3637#define FAULT_EXP(fault,error) {cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,trap_level+1,error); return;}
r23891r23892
12241225
12251226static void i386_check_irq_line(i386_state *cpustate)
12261227{
1228   if(!cpustate->smm && cpustate->smi)
1229   {
1230      pentium_smi(cpustate);
1231      return;
1232   }
1233
12271234   /* Check if the interrupts are enabled */
12281235   if ( (cpustate->irq_state) && cpustate->IF )
12291236   {
r23891r23892
29872994   static const int regs32[8] = {EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI};
29882995   i386_state *cpustate = get_safe_token(device);
29892996
2997   assert((sizeof(XMM_REG)/sizeof(double)) == 2);
2998
29902999   build_cycle_table(device->machine());
29913000
29923001   for( i=0; i < 256; i++ ) {
r23891r23892
30143023   cpustate->direct = &cpustate->program->direct();
30153024   cpustate->io = &device->space(AS_IO);
30163025   cpustate->vtlb = vtlb_alloc(device, AS_PROGRAM, 0, tlbsize);
3026   cpustate->smi = false;
30173027
30183028   device->save_item(NAME( cpustate->reg.d));
30193029   device->save_item(NAME(cpustate->sreg[ES].selector));
r23891r23892
30703080   device->save_item(NAME(cpustate->performed_intersegment_jump));
30713081   device->save_item(NAME(cpustate->mxcsr));
30723082   device->save_item(NAME(cpustate->smm));
3083   device->save_item(NAME(cpustate->smi_latched));
3084   device->save_item(NAME(cpustate->smi));
30733085   device->save_item(NAME(cpustate->nmi_masked));
30743086   device->save_item(NAME(cpustate->nmi_latched));
30753087   device->save_item(NAME(cpustate->smbase));
r23891r23892
31713183   cpustate->idtr.base = 0;
31723184   cpustate->idtr.limit = 0x3ff;
31733185   cpustate->smm = false;
3186   cpustate->smi_latched = false;
31743187   cpustate->nmi_masked = false;
31753188   cpustate->nmi_latched = false;
31763189
r23891r23892
32043217   UINT32 old_flags = get_flags(cpustate);
32053218
32063219   if(cpustate->smm)
3207      return; // TODO: latch
3220      return;
32083221
32093222   cpustate->cr[0] &= ~(0x8000000d);
32103223   set_flags(cpustate, 2);
32113224   if(!cpustate->smiact.isnull())
32123225      cpustate->smiact(true);
32133226   cpustate->smm = true;
3227   cpustate->smi_latched = false;
32143228
32153229   // save state
32163230   WRITE32(cpustate, cpustate->cr[4], smram_state+SMRAM_IP5_CR4);
r23891r23892
37773791   cpustate->eflags_mask = 0x00077fd7;
37783792   cpustate->eip = 0xfff0;
37793793   cpustate->smm = false;
3794   cpustate->smi_latched = false;
37803795   cpustate->nmi_masked = false;
37813796   cpustate->nmi_latched = false;
37823797
r23891r23892
38923907   cpustate->eip = 0xfff0;
38933908   cpustate->mxcsr = 0x1f80;
38943909   cpustate->smm = false;
3910   cpustate->smi_latched = false;
38953911   cpustate->smbase = 0x30000;
38963912   cpustate->nmi_masked = false;
38973913   cpustate->nmi_latched = false;
r23891r23892
39383954   switch (state)
39393955   {
39403956      case CPUINFO_INT_INPUT_STATE+INPUT_LINE_SMI:
3941         if(state)
3942            pentium_smi(cpustate);
3957         if(!cpustate->smi && state && cpustate->smm)
3958            cpustate->smi_latched = true;
3959         cpustate->smi = state;
39433960         break;
39443961      case CPUINFO_INT_REGISTER + X87_CTRL:           cpustate->x87_cw = info->i;     break;
39453962      case CPUINFO_INT_REGISTER + X87_STATUS:         cpustate->x87_sw = info->i;     break;
r23891r23892
40264043   cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
40274044   cpustate->eip = 0xfff0;
40284045   cpustate->smm = false;
4046   cpustate->smi_latched = false;
40294047   cpustate->nmi_masked = false;
40304048   cpustate->nmi_latched = false;
40314049
r23891r23892
41494167   cpustate->eip = 0xfff0;
41504168   cpustate->mxcsr = 0x1f80;
41514169   cpustate->smm = false;
4170   cpustate->smi_latched = false;
41524171   cpustate->smbase = 0x30000;
41534172   cpustate->nmi_masked = false;
41544173   cpustate->nmi_latched = false;
r23891r23892
42534272   cpustate->eip = 0xfff0;
42544273   cpustate->mxcsr = 0x1f80;
42554274   cpustate->smm = false;
4275   cpustate->smi_latched = false;
42564276   cpustate->smbase = 0x30000;
42574277   cpustate->nmi_masked = false;
42584278   cpustate->nmi_latched = false;
r23891r23892
43574377   cpustate->eip = 0xfff0;
43584378   cpustate->mxcsr = 0x1f80;
43594379   cpustate->smm = false;
4380   cpustate->smi_latched = false;
43604381   cpustate->smbase = 0x30000;
43614382   cpustate->nmi_masked = false;
43624383   cpustate->nmi_latched = false;
r23891r23892
44614482   cpustate->eip = 0xfff0;
44624483   cpustate->mxcsr = 0x1f80;
44634484   cpustate->smm = false;
4485   cpustate->smi_latched = false;
44644486   cpustate->smbase = 0x30000;
44654487   cpustate->nmi_masked = false;
44664488   cpustate->nmi_latched = false;
r23891r23892
45674589   cpustate->eip = 0xfff0;
45684590   cpustate->mxcsr = 0x1f80;
45694591   cpustate->smm = false;
4592   cpustate->smi_latched = false;
45704593   cpustate->smbase = 0x30000;
45714594   cpustate->nmi_masked = false;
45724595   cpustate->nmi_latched = false;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team