Index: subsystems/ntvdm/clock.c
===================================================================
--- subsystems/ntvdm/clock.c	(revision 66215)
+++ subsystems/ntvdm/clock.c	(working copy)
@@ -17,7 +17,6 @@
 // #include "clock.h"
 
 #include "hardware/cmos.h"
-#include "hardware/ps2.h"
 #include "hardware/pit.h"
 #include "hardware/video/vga.h"
 
@@ -54,13 +53,146 @@
 static DWORD LastClockUpdate;
 static DWORD LastVerticalRefresh;
 
-static DWORD LastIrq1Tick = 0, LastIrq12Tick = 0;
-
 #ifdef IPS_DISPLAY
     static DWORD LastCyclePrintout;
     static ULONGLONG Cycles = 0;
 #endif
 
+
+/* static DWORD LastIrq1Tick = 0, LastIrq12Tick = 0; */
+
+/* Hardware Clocks */
+
+typedef void (*HwClock)(VOID); // Hardware Clock Prototipe;
+
+typedef struct _HARDWARE_CLOCKS
+{
+    CHAR *Label;
+    USHORT Id;
+    USHORT Cycles;
+    DWORD LastTick;
+    HwClock timerFunction;
+    BOOLEAN Paused;
+    struct _HARDWARE_CLOCKS *nextTimer;
+} HARDWARE_CLOCKS, *PHARDWARE_CLOCKS;
+
+static PHARDWARE_CLOCKS HardwareClockList = NULL; // linked List of timers
+
+PHARDWARE_CLOCKS findInHardwareList(USHORT clockID){
+    PHARDWARE_CLOCKS temp;
+    if(HardwareClockList == NULL)
+        {return NULL;}
+    else{
+        if (HardwareClockList->Id == clockID){return HardwareClockList;}
+    }
+    temp = HardwareClockList->nextTimer;
+    while (temp != NULL){
+        if (temp->Id == clockID){return temp;}
+        temp=temp->nextTimer;
+    }
+    return NULL;
+}
+
+PHARDWARE_CLOCKS  LastInHardwareList(){
+    PHARDWARE_CLOCKS temp;
+    if(HardwareClockList == NULL)
+        {return NULL;}
+    temp = HardwareClockList;
+    while (temp->nextTimer != NULL){
+        temp=temp->nextTimer;
+    }
+    return temp;
+}
+
+USHORT ClockSubscriveHardware(char *Label, USHORT Cycles, HwClock timerFunction){
+    PHARDWARE_CLOCKS last = LastInHardwareList();
+    USHORT hID = 1; 
+    if (last == NULL){
+        HardwareClockList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HARDWARE_CLOCKS));
+        HardwareClockList->Label = Label;
+        HardwareClockList->Id = hID;
+        HardwareClockList->LastTick=CurrentTickCount;
+        HardwareClockList->Cycles=Cycles;
+        HardwareClockList->timerFunction = timerFunction;
+        HardwareClockList->Paused=0;
+        HardwareClockList->nextTimer = NULL;
+        return 0;
+    }else{
+        last->nextTimer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HARDWARE_CLOCKS));
+        hID =  last->Id +1;
+        last = last->nextTimer;
+        last->Label = Label;
+        last->Id = hID;
+        last->LastTick=CurrentTickCount;
+        last->Cycles=Cycles;
+        last->timerFunction = timerFunction;
+        last->Paused=0;
+        last->nextTimer = NULL;
+    }
+    return hID;
+}
+
+void ClockUnSubscriveHardware(USHORT ClockID){
+    PHARDWARE_CLOCKS current,temp;
+    if(HardwareClockList == NULL)
+        {return ;}
+    else{
+        if (HardwareClockList->Id == ClockID)
+        {  
+            temp=HardwareClockList;
+            HardwareClockList=temp->nextTimer;
+            HeapFree(GetProcessHeap(),0,temp);
+            return;
+        }
+    }
+    current = HardwareClockList;
+    while (current->nextTimer != NULL){
+        temp=current->nextTimer;
+        if (temp->Id == ClockID)
+        {
+            current->nextTimer = temp->nextTimer;
+            HeapFree(GetProcessHeap(),0,temp);
+            return;
+        }
+        current=current->nextTimer;
+    }
+}
+
+void PauseHardware(USHORT ClockID,BOOLEAN Paused){
+    PHARDWARE_CLOCKS temp=findInHardwareList(ClockID);
+    if(temp != NULL){
+        temp->Paused=Paused;
+    }
+}
+
+void HardwareClocksUpdate(){
+    PHARDWARE_CLOCKS current= HardwareClockList;
+    while(current != NULL){
+        if ((CurrentTickCount - current->LastTick) >= current->Cycles)
+        {
+            current->timerFunction();
+            current->LastTick = CurrentTickCount;
+            /*DPRINT1("Hardware Tick for %s\n",current->Label);*/
+        }
+        current = current->nextTimer;
+    }
+}
+
+void HardwareClocksDispose(){
+    PHARDWARE_CLOCKS current= HardwareClockList;
+    PHARDWARE_CLOCKS temp;
+    if(current != NULL){
+        while(current->nextTimer != NULL){
+            temp=current->nextTimer;
+            current->nextTimer = temp->nextTimer;
+            HeapFree(GetProcessHeap(),0,temp);
+        }
+        HeapFree(GetProcessHeap(),0,HardwareClockList);
+    }
+}
+
+
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 VOID ClockUpdate(VOID)
@@ -134,7 +266,12 @@
         VgaRefreshDisplay();
         LastVerticalRefresh = CurrentTickCount;
     }
-
+    
+    /* Horizontal retrace occurs as fast as possible */
+    VgaHorizontalRetrace();
+    
+    HardwareClocksUpdate();
+    /*
     if ((CurrentTickCount - LastIrq1Tick) >= IRQ1_CYCLES)
     {
         GenerateIrq1();
@@ -146,10 +283,8 @@
         GenerateIrq12();
         LastIrq12Tick = CurrentTickCount;
     }
+    */
 
-    /* Horizontal retrace occurs as fast as possible */
-    VgaHorizontalRetrace();
-
     /* Continue CPU emulation */
     for (i = 0; VdmRunning && CpuRunning && (i < STEPS_PER_CYCLE); i++)
     {
@@ -197,3 +332,7 @@
 
     return TRUE;
 }
+
+void ClockDispose(VOID){
+    HardwareClocksDispose();
+}
Index: subsystems/ntvdm/clock.h
===================================================================
--- subsystems/ntvdm/clock.h	(revision 66215)
+++ subsystems/ntvdm/clock.h	(working copy)
@@ -14,7 +14,17 @@
 
 VOID ClockUpdate(VOID);
 BOOLEAN ClockInitialize(VOID);
+VOID ClockDispose(VOID);
 
+/* Hardware Clocks Emulation */
+
+
+typedef void (*HwClock)(VOID); // Hardware Clock Prototipe;
+
+USHORT ClockSubscriveHardware(char *Label, USHORT Cycles, HwClock timerFunction);
+void ClockUnSubscriveHardware(USHORT ClockID);
+void PauseHardware(USHORT ClockID,BOOLEAN Paused);
+
 #endif // _CLOCK_H_
 
 /* EOF */
Index: subsystems/ntvdm/hardware/ps2.c
===================================================================
--- subsystems/ntvdm/hardware/ps2.c	(revision 66215)
+++ subsystems/ntvdm/hardware/ps2.c	(working copy)
@@ -12,6 +12,7 @@
 #define NDEBUG
 
 #include "emulator.h"
+#include "clock.h"
 #include "io.h"
 #include "ps2.h"
 #include "pic.h"
@@ -49,6 +50,10 @@
 // static BYTE InputBuffer  = 0x00; // PS/2 Input  Buffer
 static BYTE OutputBuffer = 0x00; // PS/2 Output Buffer
 
+
+static USHORT HardwareTimer1 = 0;
+static USHORT HardwareTimer12 = 0;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 static VOID PS2SendCommand(PPS2_PORT Port, BYTE Command)
@@ -379,6 +384,7 @@
         /* Generate an IRQ 1 if there is data ready in the output queue */
         if (PS2PortQueueRead(0)) PicInterruptRequest(1);
     }
+    /*DPRINT1("IRQ1\n");*/
 }
 
 VOID GenerateIrq12(VOID)
@@ -389,6 +395,7 @@
         /* Generate an IRQ 12 if there is data ready in the output queue */
         if (PS2PortQueueRead(1)) PicInterruptRequest(12);
     }
+    /*DPRINT1("IRQ12\n");*/
 }
 
 BOOLEAN PS2Initialize(VOID)
@@ -409,12 +416,15 @@
     /* Register the I/O Ports */
     RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
     RegisterIoPort(PS2_DATA_PORT   , PS2ReadPort, PS2WritePort);
-
+    HardwareTimer1 = ClockSubscriveHardware("IRQ1", 16, &GenerateIrq1);
+    HardwareTimer12 = ClockSubscriveHardware("IRQ12", 16, &GenerateIrq12);
     return TRUE;
 }
 
 VOID PS2Cleanup(VOID)
 {
+    ClockUnSubscriveHardware(HardwareTimer1);
+    ClockUnSubscriveHardware(HardwareTimer12);
     CloseHandle(Ports[1].QueueMutex);
     CloseHandle(Ports[0].QueueMutex);
 }
