diff --git a/MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs b/MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs
index 0bb1eb9..72efe19 100644
--- a/MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs
+++ b/MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs
@@ -149,7 +149,7 @@ namespace cpu.m68000
                 X = (value & 0x0010) != 0;
             }
         }
-        public int Interrupt { get; set; }
+        public int Interrupt;// { get; set; }
 
         // Memory Access        
         public Func<int, sbyte> ReadOpByte, ReadByte;
diff --git a/MAME.Unity/Assets/Plugins/UMAME/emu/EmuTimer.cs b/MAME.Unity/Assets/Plugins/UMAME/emu/EmuTimer.cs
index 2fc4189..5cfd531 100644
--- a/MAME.Unity/Assets/Plugins/UMAME/emu/EmuTimer.cs
+++ b/MAME.Unity/Assets/Plugins/UMAME/emu/EmuTimer.cs
@@ -330,7 +330,8 @@ namespace MAME.Core
                 callback_timer_modified = false;
                 callback_timer = timer;
                 callback_timer_expire_time = timer.expire;
-                if (was_enabled && (timer.action != null && timer.action != Cpuexec.null_callback))
+                //if (was_enabled && (timer.action != null && timer.action != Cpuexec.null_callback))
+                if (was_enabled && (timer.action != null && timer.func != "boost_callback"))
                 {
                     timer.action();
                 }
diff --git a/MAME.Unity/Assets/Plugins/UMAME/emu/Motion.cs b/MAME.Unity/Assets/Plugins/UMAME/emu/Motion.cs
index 1a32963..ad8b266 100644
--- a/MAME.Unity/Assets/Plugins/UMAME/emu/Motion.cs
+++ b/MAME.Unity/Assets/Plugins/UMAME/emu/Motion.cs
@@ -1,4 +1,5 @@
 using MAME.Core;
+using System;
 
 namespace MAME.Core
 {
@@ -58,9 +59,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = (y * Video.fullwidth) + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             red = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff0000) >> 16) * bright / 0xff);
                             green = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff00) >> 8) * bright / 0xff);
                             blue = (int)((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff) * bright / 0xff);
@@ -73,9 +76,11 @@ namespace MAME.Core
 
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = (y * Video.fullwidth) + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             Video.bitmapcolorRect[target_i] = (int)Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]];
                         }
                     }
@@ -138,9 +143,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             if (Video.bitmapbase[Video.curbitmap][i] < 0x100)
                             {
                                 red = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff0000) >> 16) * bright / 0xff);
@@ -159,9 +166,11 @@ namespace MAME.Core
                 {
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             if (Video.bitmapbase[Video.curbitmap][i] < 0x100)
                             {
                                 Video.bitmapcolorRect[target_i] = (int)Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]];
@@ -216,9 +225,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             red = ((Video.bitmapbaseN[Video.curbitmap][i] & 0xff0000) >> 16) * bright / 0xff;
                             green = ((Video.bitmapbaseN[Video.curbitmap][i] & 0xff00) >> 8) * bright / 0xff;
                             blue = (Video.bitmapbaseN[Video.curbitmap][i] & 0xff) * bright / 0xff;
@@ -230,9 +241,11 @@ namespace MAME.Core
                 {
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             Video.bitmapcolorRect[target_i] = (int)(0xff000000 | (uint)Video.bitmapbaseN[Video.curbitmap][i]);
                         }
                     }
@@ -280,9 +293,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             red = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff0000) >> 16) * bright / 0xff);
                             green = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff00) >> 8) * bright / 0xff);
                             blue = (int)((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff) * bright / 0xff);
@@ -294,9 +309,11 @@ namespace MAME.Core
                 {
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             Video.bitmapcolorRect[target_i] = (int)Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]];
                         }
                     }
@@ -345,9 +362,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             red = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff0000) >> 16) * bright / 0xff);
                             green = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff00) >> 8) * bright / 0xff);
                             blue = (int)((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff) * bright / 0xff);
@@ -359,9 +378,11 @@ namespace MAME.Core
                 {
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             Video.bitmapcolorRect[target_i] = (int)Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]];
                         }
                     }
@@ -410,9 +431,11 @@ namespace MAME.Core
                     byte bright = 0xa7;
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             red = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff0000) >> 16) * bright / 0xff);
                             green = (int)(((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff00) >> 8) * bright / 0xff);
                             blue = (int)((Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]] & 0xff) * bright / 0xff);
@@ -424,9 +447,11 @@ namespace MAME.Core
                 {
                     for (y = startY; y < endY; y++)
                     {
+                        int stepIndex = y * Video.fullwidth;
                         for (x = startX; x < endX; x++, target_i++)
                         {
-                            i = y * Video.fullwidth + x;
+                            //i = y * Video.fullwidth + x;
+                            i = stepIndex + x;
                             Video.bitmapcolorRect[target_i] = (int)Palette.entry_color[Video.bitmapbase[Video.curbitmap][i]];
                         }
                     }
diff --git a/MAME.Unity/Assets/Plugins/UMAME/mame/neogeo/Video.cs b/MAME.Unity/Assets/Plugins/UMAME/mame/neogeo/Video.cs
index c9a4c45..ddd4815 100644
--- a/MAME.Unity/Assets/Plugins/UMAME/mame/neogeo/Video.cs
+++ b/MAME.Unity/Assets/Plugins/UMAME/mame/neogeo/Video.cs
@@ -370,11 +370,13 @@ namespace MAME.Core
             neogeo_scanline_param = 0;
             EmuTimer.timer_adjust_periodic(sprite_line_timer, Video.video_screen_get_time_until_pos(0, 0), Attotime.ATTOTIME_NEVER);
         }
+        readonly static int[] pix_offsets = new int[] { 0x10, 0x18, 0x00, 0x08 };
+        static int[] garouoffsets = new int[32];
         private static void draw_fixed_layer(int iBitmap, int scanline)
         {
             int i, j, x, y;
-            int[] garouoffsets = new int[32], pix_offsets = new int[] { 0x10, 0x18, 0x00, 0x08 };
             byte[] gfx_base;
+            //int[] garouoffsets = new int[32], pix_offsets = new int[] { 0x10, 0x18, 0x00, 0x08 };
             int addr_mask;
             int gfx_offset, char_pens_offset;
             byte data;
diff --git a/MAME.Unity/Assets/Plugins/UMAME/sound/AY8910.cs b/MAME.Unity/Assets/Plugins/UMAME/sound/AY8910.cs
index 53466df..12783c3 100644
--- a/MAME.Unity/Assets/Plugins/UMAME/sound/AY8910.cs
+++ b/MAME.Unity/Assets/Plugins/UMAME/sound/AY8910.cs
@@ -70,14 +70,34 @@ namespace MAME.Core
         {
             return ay8910info.regs[6] & 0x1f;
         }
+
+        //private int TONE_VOLUME(int chan)
+        //{
+        //    return ay8910info.regs[8 + chan] & 0x0f;
+        //}
+
+        //private int TONE_ENVELOPE(int chan)
+        //{
+        //    return (ay8910info.regs[8 + chan] >> 4) & 1;
+        //}
+
+        //用常量优化海量访问
+
+        private const int TONE_VOLUME_REG_OFFSET = 8;
+        private const int TONE_VOLUME_VOLUME_MASK = 0x0f;
         private int TONE_VOLUME(int chan)
         {
-            return ay8910info.regs[8 + chan] & 0x0f;
+            return ay8910info.regs[TONE_VOLUME_REG_OFFSET + chan] & TONE_VOLUME_VOLUME_MASK;
         }
+
+        private const int TONE_ENVELOPE_REG_OFFSET = 8;
+        private const int TONE_ENVELOPE_MOVE = 4;
+        private const int TONE_ENVELOPE_VOLUME_MASK = 0x01;
         private int TONE_ENVELOPE(int chan)
         {
-            return (ay8910info.regs[8 + chan] >> 4) & 1;
+            return (ay8910info.regs[TONE_ENVELOPE_REG_OFFSET + chan] >> TONE_ENVELOPE_MOVE) & TONE_ENVELOPE_VOLUME_MASK;
         }
+
         private int ENVELOPE_PERIOD()
         {
             return ay8910info.regs[11] | (ay8910info.regs[12] << 8);