diff -ur src30/amiga/DispKbd.c arcem/amiga/DispKbd.c
--- src30/amiga/DispKbd.c	2011-09-04 19:46:16.997730493 +0100
+++ arcem/amiga/DispKbd.c	2011-09-11 17:43:14.880000000 +0100
@@ -2,6 +2,7 @@
 /* Some code based on DispKbd.c for other platforms                              */
 
 #include <string.h>
+#include <limits.h>
 
 #include "../armdefs.h"
 #include "armarc.h"
@@ -45,6 +46,9 @@
 static ULONG OldMouseX = 0;
 static ULONG OldMouseY = 0;
 
+static int redraw_miny = INT_MAX;
+static int redraw_maxy = 0; 
+
 
 void writepixel(struct RastPort *,ULONG,ULONG,ULONG);
 void ChangeDisplayMode(ARMul_State *,long,long,int);
@@ -421,6 +421,8 @@
 {
 	row->width = count>>3;
 	*outoffset = 0;
+	redraw_miny = MIN(redraw_miny,row->y);
+	redraw_maxy = MAX(redraw_maxy,row->y);
 	return RowBuffer;
 }
 
@@ -582,6 +590,15 @@
 static void
 PDD_Name(Host_PollDisplay)(ARMul_State *state)
 {
+	if(redraw_miny <= redraw_maxy)
+	{
+		IGraphics->BltBitMap(friend.BitMap,0,redraw_miny,
+				window->RPort->BitMap,0,redraw_miny,
+				HD.Width,(redraw_maxy-redraw_miny)+1,0x0C0,0xff,NULL);
+		redraw_miny = INT_MAX;
+		redarw_maxy = 0;
+	}
+
 	pdd_refreshmouse(state);
 }
 
diff -ur src30/arch/archio.c arcem/arch/archio.c
--- src30/arch/archio.c	2011-09-04 19:46:16.909729349 +0100
+++ arcem/arch/archio.c	2011-09-09 23:17:55.400000000 +0100
@@ -21,6 +21,7 @@
 #endif
 #include "keyboard.h"
 #include "displaydev.h"
+#include "sound.h"
 
 /*#define IOC_TRACE*/
 
@@ -139,12 +140,11 @@
 GetCurrentTimerVal(ARMul_State *state,int toget)
 {
   long timeSinceLastUpdate = ARMul_Time - ioc.TimersLastUpdated;
-  long scaledTimeSlip = (((unsigned long long) timeSinceLastUpdate) * ioc.IOCRate)>>16;
+  long scaledTimeSlip = (((unsigned long long) timeSinceLastUpdate) * ioc.IOCRate + ioc.TimerFracBit)>>16;
   long tmpL;
   int result;
 
-  tmpL = ioc.TimerInputLatch[toget];
-  if (tmpL == 0) tmpL = 1;
+  tmpL = ioc.TimerInputLatch[toget]+1;
   result = ioc.TimerCount[toget] - (scaledTimeSlip % tmpL);
   if (result < 0) result += tmpL;
 
@@ -171,9 +171,8 @@
   CycleDiff nextTrigger = ioc.InvIOCRate; /* a.k.a. 65536 IOC cycles from now */
 
   /* ----------------------------------------------------------------- */
-  tmpL = ioc.TimerInputLatch[0];
-  if (tmpL == 0) tmpL = 1;
-  if (ioc.TimerCount[0] <= scaledTimeSlip) {
+  tmpL = ioc.TimerInputLatch[0]+1;
+  if (ioc.TimerCount[0] < scaledTimeSlip) {
     KBD.TimerIntHasHappened++;
     ioc.IRQStatus |= IRQA_TM0;
     IO_UpdateNirq(state);
@@ -183,14 +182,13 @@
   if (ioc.TimerCount[0] < 0) ioc.TimerCount[0] += tmpL;
 
   if (ioc.Timer0CanInt) {
-    tmpL = (((unsigned long long) ioc.TimerCount[0]) * ioc.InvIOCRate) >> 16;
+    tmpL = (((unsigned long long) (ioc.TimerCount[0]+1)) * ioc.InvIOCRate) >> 16;
     if (tmpL < nextTrigger) nextTrigger = tmpL;
   }
 
   /* ----------------------------------------------------------------- */
-  tmpL = ioc.TimerInputLatch[1];
-  if (tmpL == 0) tmpL = 1;
-  if (ioc.TimerCount[1] <= scaledTimeSlip) {
+  tmpL = ioc.TimerInputLatch[1]+1;
+  if (ioc.TimerCount[1] < scaledTimeSlip) {
     ioc.IRQStatus |= IRQA_TM1;
     IO_UpdateNirq(state);
     ioc.Timer1CanInt = 0; /* Because its just caused one which hasn't cleared yet */
@@ -199,20 +197,22 @@
   if (ioc.TimerCount[1] < 0) ioc.TimerCount[1] += tmpL;
 
   if (ioc.Timer1CanInt) {
-    tmpL = (((unsigned long long) ioc.TimerCount[1]) * ioc.InvIOCRate) >> 16;
+    tmpL = (((unsigned long long) (ioc.TimerCount[1]+1)) * ioc.InvIOCRate) >> 16;
     if (tmpL < nextTrigger) nextTrigger = tmpL;
   }
 
   /* ----------------------------------------------------------------- */
   if (ioc.TimerInputLatch[2]) {
-    ioc.TimerCount[2] -= (scaledTimeSlip % ioc.TimerInputLatch[2]);
-    if(ioc.TimerCount[2] < 0) ioc.TimerCount[2] += ioc.TimerInputLatch[2];
+    tmpL = ioc.TimerInputLatch[2]+1;
+    ioc.TimerCount[2] -= (scaledTimeSlip % tmpL);
+    if(ioc.TimerCount[2] < 0) ioc.TimerCount[2] += tmpL;
   }
 
   /* ----------------------------------------------------------------- */
   if (ioc.TimerInputLatch[3]) {
-    ioc.TimerCount[3] -= (scaledTimeSlip % ioc.TimerInputLatch[3]);
-    if(ioc.TimerCount[3] < 0) ioc.TimerCount[3] += ioc.TimerInputLatch[3];
+    tmpL = ioc.TimerInputLatch[3]+1;
+    ioc.TimerCount[3] -= (scaledTimeSlip % tmpL);
+    if(ioc.TimerCount[3] < 0) ioc.TimerCount[3] += tmpL;
   }
 
   ioc.TimersLastUpdated = nowtime;
@@ -649,6 +649,9 @@
             {
               ioc.IOEBControlReg = data;
               (DisplayDev_Current->IOEBCRWrite)(state,data);
+#ifdef SOUND_SUPPORT
+              Sound_SoundFreqUpdated(state);
+#endif
             }
             break;
 
diff -ur src30/arch/newsound.c arcem/arch/newsound.c
--- src30/arch/newsound.c	2011-09-04 19:46:16.909729349 +0100
+++ arcem/arch/newsound.c	2011-09-10 01:51:11.270000000 +0100
@@ -30,7 +30,7 @@
 
 #define MAX_BATCH_SIZE 1024
 
-int Sound_BatchSize = 1; /* How many DMA fetches to try to do at once */
+int Sound_BatchSize = 1; /* How many 16*2 sample batches to try to do at once */
 unsigned long Sound_DMARate; /* How many cycles between DMA fetches */
 Sound_StereoSense eSound_StereoSense = Stereo_LeftRight;
 int Sound_FudgeRate = 0;
@@ -114,7 +114,7 @@
               stepSize = (64 * scale) / 16;
               break;
       case 7: chordBase = 127*scale;
-              stepSize = (120 * scale) / 16;
+              stepSize = (128 * scale) / 16;
               break;
       /* End of chord 7 is 247 * scale. */
 
@@ -130,9 +130,6 @@
     } else {
       soundTable[i] = sample;
     }
-    if (i == 128) {
-      soundTable[i] = 0xFFFF;
-    }
   }
 }
 
@@ -330,13 +327,36 @@
   /* How many DMA fetches are possible? */
   int avail = 0;
   if(MEMC.ControlReg & (1 << 11))
+  {
+    /* Trigger any pending buffer swap */
+    if(MEMC.Sptr > MEMC.SendC)
+    {
+      /* Have the next buffer addresses been written? */
+      if (MEMC.NextSoundBufferValid == 1) {
+        /* Yes, so change to the next buffer */
+        ARMword swap;
+  
+        MEMC.Sptr = MEMC.Sstart;
+        MEMC.SstartC = MEMC.Sstart;
+  
+        swap = MEMC.SendC;
+        MEMC.SendC = MEMC.SendN;
+        MEMC.SendN = swap;
+  
+        ioc.IRQStatus |= IRQB_SIRQ; /* Take sound interrupt on */
+        IO_UpdateNirq(state);
+  
+        MEMC.NextSoundBufferValid = 0;
+      } else {
+        /* Otherwise wrap to the beginning of the buffer */
+        MEMC.Sptr = MEMC.SstartC;
+      }
+    }
     avail = ((MEMC.SendC+16)-MEMC.Sptr)>>4;
-  if(avail > Sound_BatchSize)
-    avail = Sound_BatchSize;
-  /* Work out when to reschedule the event
-     This is slightly wrong, since we time it based around how long it takes
-     to process this data, but if we finish a buffer we trigger the swap
-     immediately instead of at the start of the next event */
+    if(avail > Sound_BatchSize<<log2numchan)
+      avail = Sound_BatchSize<<log2numchan;
+  }
+  /* Work out when to reschedule the event */
   int next = Sound_DMARate*(avail?avail:Sound_BatchSize)+Sound_FudgeRate;
   /* Clamp to a safe minimum value */
   if(next < 100)
@@ -352,29 +372,6 @@
 #endif
   /* Update DMA stuff */
   MEMC.Sptr += avail<<4;
-  if(MEMC.Sptr > MEMC.SendC)
-  {
-    /* Have the next buffer addresses been written? */
-    if (MEMC.NextSoundBufferValid == 1) {
-      /* Yes, so change to the next buffer */
-      ARMword swap;
-
-      MEMC.Sptr = MEMC.Sstart;
-      MEMC.SstartC = MEMC.Sstart;
-
-      swap = MEMC.SendC;
-      MEMC.SendC = MEMC.SendN;
-      MEMC.SendN = swap;
-
-      ioc.IRQStatus |= IRQB_SIRQ; /* Take sound interrupt on */
-      IO_UpdateNirq(state);
-
-      MEMC.NextSoundBufferValid = 0;
-    } else {
-      /* Otherwise wrap to the beginning of the buffer */
-      MEMC.Sptr = MEMC.SstartC;
-    }
-  }
 }
 
 int Sound_Init(ARMul_State *state)
diff -ur src30/arch/paldisplaydev.c arcem/arch/paldisplaydev.c
--- src30/arch/paldisplaydev.c	2011-09-04 19:46:16.909729349 +0100
+++ arcem/arch/paldisplaydev.c	2011-09-08 20:55:28.910000000 +0100
@@ -624,10 +624,15 @@
 #ifdef DEBUG_VIDCREGS
       fprintf(stderr,"VIDC stereo image reg write val=0x%x\n",val);
 #endif
-      VIDC.StereoImageReg[(addr==0x60)?7:((addr-0x64)/4)]=val & 7;
+      val &= 7;
+      addr = ((addr-0x64)>>2)&0x7;
+      if(VIDC.StereoImageReg[addr] != val)
+      {
+        VIDC.StereoImageReg[addr] = val;
 #ifdef SOUND_SUPPORT
-      Sound_StereoUpdated(state);
+        Sound_StereoUpdated(state);
 #endif
+      }
       break;
 
     case 0x80:
@@ -746,10 +751,14 @@
 #ifdef DEBUG_VIDCREGS
       fprintf(stderr,"VIDC Sound freq register val=%d\n",val);
 #endif
-      VIDC.SoundFreq=val & 0xff;
+      val &= 0xff;
+      if(VIDC.SoundFreq != val)
+      {
+        VIDC.SoundFreq=val;
 #ifdef SOUND_SUPPORT
-      Sound_SoundFreqUpdated(state);
+        Sound_SoundFreqUpdated(state);
 #endif
+      }
       break;
 
     case 0xe0:
diff -ur src30/arch/sound.h arcem/arch/sound.h
--- src30/arch/sound.h	2011-09-04 19:46:16.905728605 +0100
+++ arcem/arch/sound.h	2011-09-11 18:24:30.730000000 +0100
@@ -4,7 +4,7 @@
 /* TODO Needs to be made 16 bit on any platform. */
 typedef unsigned short int SoundData;
 
-extern int Sound_BatchSize; /* How many DMA fetches to attempt to do at once */
+extern int Sound_BatchSize; /* How many 16*2 sample batches to attempt to deliver to the platform code at once */
 extern unsigned long Sound_DMARate; /* How many cycles between DMA fetches */
 extern int Sound_FudgeRate; /* Extra fudge factor applied to Sound_DMARate */
 
diff -ur src30/arch/stddisplaydev.c arcem/arch/stddisplaydev.c
--- src30/arch/stddisplaydev.c	2011-09-04 19:46:16.909729349 +0100
+++ arcem/arch/stddisplaydev.c	2011-09-08 20:55:32.430000000 +0100
@@ -1423,10 +1423,15 @@
 #ifdef DEBUG_VIDCREGS
       fprintf(stderr,"VIDC stereo image reg write val=0x%x\n",val);
 #endif
-      VIDC.StereoImageReg[(addr==0x60)?7:((addr-0x64)/4)]=val & 7;
+      val &= 7;
+      addr = ((addr-0x64)>>2)&0x7;
+      if(VIDC.StereoImageReg[addr] != val)
+      {
+        VIDC.StereoImageReg[addr] = val;
 #ifdef SOUND_SUPPORT
-      Sound_StereoUpdated(state);
+        Sound_StereoUpdated(state);
 #endif
+      }
       break;
 
     case 0x80:
@@ -1545,10 +1550,14 @@
 #ifdef DEBUG_VIDCREGS
       fprintf(stderr,"VIDC Sound freq register val=%d\n",val);
 #endif
-      VIDC.SoundFreq=val & 0xff;
+      val &= 0xff;
+      if(VIDC.SoundFreq != val)
+      {
+        VIDC.SoundFreq=val;
 #ifdef SOUND_SUPPORT
-      Sound_SoundFreqUpdated(state);
+        Sound_SoundFreqUpdated(state);
 #endif
+      }
       break;
 
     case 0xe0:
