Index: trunk/MagicSoft/Cosy/.cosyrc
===================================================================
--- trunk/MagicSoft/Cosy/.cosyrc	(revision 808)
+++ trunk/MagicSoft/Cosy/.cosyrc	(revision 808)
@@ -0,0 +1,11 @@
+#
+# -85.0 , +310.0
+#
+MinAz[Deg]:   -30.0
+MaxAz[Deg]:  +375.0
+
+#
+# 
+#
+MinZd[Deg]:   -70.0
+MaxZd[Deg]:   +70.0
Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 807)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 808)
@@ -3,4 +3,7 @@
  2001/05/25 - Thomas Bretz:
  
+    * .cosyrc:
+      - added
+      
     * MCosy.[h,cc]:
       - changed the error handling os SetPosition
Index: trunk/MagicSoft/Cosy/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/MCosy.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/MCosy.cc	(revision 808)
@@ -6,13 +6,13 @@
 
 #include <TROOT.h>
+#include <TEnv.h>
 #include <TSystem.h>
 #include <TApplication.h>
 
 #include "MGCosy.h"
+#include "Slalib.h"
 
 #include "macs.h"
 #include "timer.h"
-#include "slalib.h"
-#include "slamac.h"
 #include "shaftencoder.h"
 
@@ -59,4 +59,6 @@
 ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
 {
+    // CorrectTarget [se]
+
     // src [se]
     // dst [rad]
@@ -71,5 +73,5 @@
 
     if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
-        return dst;
+        return dst*(16384.0/D2PI);
 
     const float fZdMin = -67;
@@ -119,4 +121,5 @@
         min = dist;
     }
+    cout << "Shortest Zd: " << ret.Zd() << "  Az:" << ret.Az() << endl;
     return ret*(16384.0/360.0);
 }
@@ -160,8 +163,9 @@
 
     cout << "Positioning to Target:" << endl;
-//    cout << "Source        Alt: " << src.Alt()  << "se  Az:" << src.Az()  << "se  ->  Alt: " << srcd.Alt() << kDEG << " Az:" << srcd.Az() << kDEG << endl;
-//    cout << "Shortest Dest Alt: " << dest.Alt() << "se  Az:" << dest.Az()   << "se  ->  Alt: " << sed.Alt()  << kDEG << " Az:" << sed.Az()  << kDEG << endl;
-
-    for (int i=0; i<10; i++)
+    //cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
+    //cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
+    cout << "Shortest Dest Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
+
+    for (int i=0; i<10 && !StopWaitingForSDO(); i++)
     {
         //
@@ -242,13 +246,14 @@
         cout << "SDO..." << flush;
 
-        while (fMac1->IsPositioning() || fMac2->IsPositioning())
-        {
-            if (StopWaitingForSDO())
-                return FALSE;
-
+        while (fMac1->IsPositioning() || fMac2->IsPositioning() && !StopWaitingForSDO())
             usleep(1);
-        }
 
         cout << "done." << endl;
+    }
+
+    if (StopWaitingForSDO())
+    {
+        fMac1->HandleError();
+        fMac2->HandleError();
     }
 
@@ -259,4 +264,6 @@
 void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
 {
+    Slalib sla;
+
     //
     // Position to actual position
@@ -265,6 +272,6 @@
     t.GetTime();
 
-    RaDec pm;
-    ZdAz dest = RaDec2ZdAz(t.GetMjd(), dst, pm);
+    sla.Set(t.GetMjd());
+    ZdAz dest = sla.CalcZdAz(dst);
 
     if (!SetPosition(dest))
@@ -273,7 +280,4 @@
         return;
     }
-
-    if (StopWaitingForSDO())
-        return;
 
     //
@@ -299,4 +303,5 @@
     fMac2->SetAcceleration(0.90*fMac2->GetVelRes());
     fMac2->SetDeceleration(0.90*fMac2->GetVelRes());
+
     fMac1->SetAcceleration(0.90*fMac1->GetVelRes());
     fMac1->SetDeceleration(0.90*fMac1->GetVelRes());
@@ -315,4 +320,7 @@
     fTracking = kTRUE;
 
+    ofstream fout("cosy.pos");
+    fout << "   Mjd/10ms    Offset/RE Deviation/RE V/RE/MIN/4" << endl;
+
     //
     // We want to reach the theoretical position exactly in about 0.5s
@@ -330,5 +338,6 @@
         // Request theoretical Position for a time in the future (To+dt) from CPU
         //
-        dest = CorrectTarget(GetSePos(), RaDec2ZdAz(t.GetMjd()+dt/(60*60*24), dst, pm));
+        sla.Set(t.GetMjd()+dt/(60*60*24));
+        dest = CorrectTarget(GetSePos(), sla.CalcZdAz(dst));
 
         fMac2->RequestSDO(0x6004);
@@ -392,19 +401,22 @@
         // calculate control deviation - for the moment for convinience
         //
-        if (fMac1->GetTime()-s > 1)
-        {
-            ZdAz dest0=CorrectTarget(GetSePos(),
-                                     RaDec2ZdAz(fMac2->GetMjd(), dst, pm));
+
+        //if (fMac1->GetTime()-s > 1)
+        {
+            const double mjd = fMac2->GetMjd();
+            sla.Set(mjd);
+            ZdAz dest0=CorrectTarget(GetSePos(), sla.CalcZdAz(dst));
             dest0 *= kGearRatio;
             dest0 -= GetRePos()+offset;
             dest0.Round();
-            cout << "Control deviation: ";
-            cout << setw(4) << (int)fOffset.Zd() << " ";
-            cout << setw(4) << (int)fOffset.Az() << " re ";
-
-            cout << setw(4) << dest0.Zd() << " ";
-            cout << setw(4) << dest0.Az() << " re    V: ";
-            cout << setw(4) << vt.Zd()    << " ";
-            cout << setw(4) << vt.Az()    << " re/min/4" << endl;
+            //cout << "Control deviation: ";
+            fout << setprecision(15) << setw(15) << mjd*60.*60.*24. << " ";
+            fout << setw(4) << (int)fOffset.Zd() << " ";
+            fout << setw(4) << (int)fOffset.Az() << " ";
+
+            fout << setw(4) << dest0.Zd() << " ";
+            fout << setw(4) << dest0.Az() << " ";
+            fout << setw(4) << vt.Zd()    << " ";
+            fout << setw(4) << vt.Az() << endl;
             s = (int)fMac1->GetTime();
         }
@@ -427,61 +439,10 @@
 
     cout << "Tracking stopped." << endl;
-}
-
-ZdAz MCosy::RaDec2ZdAz(const double mjd, const RaDec &dst, const RaDec &pm)
-{
-    int status;
-
-    //
-    // calculate observers location (goe)
-    //
-    double fPhi, fElong;
-    slaDaf2r(51, 38, 48.0, &fPhi,   &status);
-    slaDaf2r( 9, 56, 36.0, &fElong, &status);
-
-    // cout << "fPhi:   51ø38'48.0\" = " <<  360.0/D2PI*fPhi << endl;
-    // cout << "fElong:  9ø56'36.0\" = " <<  360.0/D2PI*fElong << endl;
-
-    //
-    // ----- calculate star independent parameters ----------
-    //
-    double fAmprms[21];
-    double fAoprms[14];
-    slaMappa(2000.0, mjd, fAmprms);
-    slaAoppa(mjd, 0,                 // mjd, UT1-UTC
-             fElong, fPhi, 148,      // gttingen long, lat, height
-             0, 0,                   // polar motion x, y-coordinate (radians)
-             273.155, 1013.25, 0.5,  // temp, pressure, humidity
-             0.2, 0.0065,            // wavelength, tropo lapse rate
-             fAoprms);
-
-    //
-    // ---- Mean to apparent ----
-    //
-    double r=0, d=0;
-    slaMapqkz(dst.Ra(), dst.Dec(), (double*)fAmprms, &r, &d);
-    //
-    // Doesn't work - don't know why
-    //
-    //    slaMapqk(dst.Ra(), dst.Dec(), pm.Ra(), pm.Dec(),        // ra, dec (rad), r, d (rad)
-    //             0, 0, fAmprms, &r, &d);
-    //
-
-    //
-    // -- apparent to observed --
-    //
-    double r1=0;  // ra
-    double d1=0;  // dec
-    double h0=0;  // ha
-
-    double az, zd;
-    slaAopqk (r, d, fAoprms,
-              &az,    // observed azimuth (radians: N=0,E=90)
-              &zd,    // observed zenith distance (radians)
-              &h0,    // observed hour angle (radians)
-              &d1,    // observed declination (radians)
-              &r1);   // observed right ascension (radians)
-
-    return ZdAz(zd, az);
+
+    if (StopWaitingForSDO())
+    {
+        fMac1->HandleError();
+        fMac2->HandleError();
+    }
 }
 
@@ -490,4 +451,8 @@
     switch (msg)
     {
+    case WM_WAIT:
+        cout << "Wait for execution of Proc: done." << endl;
+        return NULL;
+
     case WM_STOP:
         cout << "Stopping  positioning." << endl;
@@ -514,9 +479,13 @@
         {
             cout << "WM_POLARIS: START" << endl;
+            Slalib sla;
+
             Timer t;
             t.GetTime();
 
+            sla.Set(t.GetMjd());
+
             RaDec rd(37.94, 89.2644);
-            ZdAz za=MCosy::RaDec2ZdAz(t.GetMjd(), rd*D2PI/360.0)*16384.0/D2PI;
+            ZdAz za=sla.CalcZdAz(rd*D2PI/360.0)*16384.0/D2PI;
 
             cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
@@ -537,4 +506,5 @@
         {
             ZdAz dest = *((ZdAz*)mp);
+
             SetPosition(dest*D2PI/360.0);
         }
@@ -561,5 +531,41 @@
     //
     Network::Start();
+
+    const int res = fMac3->GetVelRes();
+
+    fMac3->SetVelocity(res);
+    fMac3->SetAcceleration(res);
+    fMac3->SetDeceleration(res);
+
+    fMac3->SetSyncMode();
+
+    fMac1->SetHome(250000);
+    fMac2->SetHome(250000);
     PostMsg(WM_PRESET, 0, 0);
+    PostMsg(WM_WAIT,   0, 0);
+
+    fMac1->ReqPos();
+    fMac2->ReqPos();
+
+    const ZdAz repos=GetRePos();
+    cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
+
+    TEnv env(".cosyrc");
+
+    cout << Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)) << " < Az < "
+        << Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)) << "RE" << endl;
+    cout << env.GetValue("MinAz[Deg]", -1.0) << " < Az < "
+        << env.GetValue("MaxAz[Deg]", +1.0) << kDEG << endl;
+    cout << Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)) << "RE < Zd < "
+        << Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
+
+    fMac1->SetNegEndswitch(Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)));
+    fMac1->SetPosEndswitch(Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)));
+
+/*
+    fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)));
+    fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)));
+*/
+    fMac3->SetSyncMode();
 /*
     cout << "PostMsg(WM_PRESET)" << endl;
@@ -584,4 +590,5 @@
     setpriority(PRIO_PROCESS, 0, 10);
 
+    Slalib sla;
     while (1)
     {
@@ -592,5 +599,4 @@
             usleep(1);
 
-        RaDec pm;
         ZdAz sollalt; // [se]
         ZdAz sollaz;  // [se]
@@ -641,5 +647,6 @@
                 // calculate were we should be
                 //
-                sollalt = CorrectTarget(ist, RaDec2ZdAz(t, fRaDec, pm));
+                sla.Set(t);
+                sollalt = CorrectTarget(ist, sla.CalcZdAz(fRaDec));
 
                 old.Zd(ist.Zd());
@@ -659,5 +666,6 @@
                 // calculate were we should be
                 //
-                sollaz = CorrectTarget(ist, RaDec2ZdAz(t, fRaDec, pm));
+                sla.Set(t);
+                sollaz = CorrectTarget(ist, sla.CalcZdAz(fRaDec));
 
                 old.Az(ist.Az());
@@ -724,4 +732,5 @@
     fMac1=new Macs(1, lout);
     fMac2=new Macs(2, lout);
+    fMac3=new Macs(3, lout);
     fAlt1=new ShaftEncoder(4, lout);
     fAlt2=new ShaftEncoder(5, lout);
@@ -733,4 +742,5 @@
     SetNode(fMac1);
     SetNode(fMac2);
+    SetNode(fMac3);
     SetNode(fAlt1);
     SetNode(fAlt2);
@@ -756,4 +766,5 @@
     delete fMac1;
     delete fMac2;
+    delete fMac3;
 
     delete fWin;
Index: trunk/MagicSoft/Cosy/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/MCosy.h	(revision 807)
+++ trunk/MagicSoft/Cosy/MCosy.h	(revision 808)
@@ -13,4 +13,5 @@
 #define WM_STOP      0x1003
 #define WM_POLARIS   0x1004
+#define WM_WAIT      0x1005
 
 class ShaftEncoder;
@@ -27,4 +28,5 @@
     Macs *fMac1;
     Macs *fMac2;
+    Macs *fMac3;
 
     MGCosy *fWin;
@@ -60,5 +62,5 @@
 
     static ZdAz CorrectTarget(const ZdAz &src, const ZdAz &dst);
-    static ZdAz RaDec2ZdAz(const double mjd, const RaDec &pos, const RaDec &pm=RaDec(0,0));
+//    static ZdAz RaDec2ZdAz(const double mjd, const RaDec &pos, const RaDec &pm=RaDec(0,0));
 };
 
Index: trunk/MagicSoft/Cosy/Makefile
===================================================================
--- trunk/MagicSoft/Cosy/Makefile	(revision 807)
+++ trunk/MagicSoft/Cosy/Makefile	(revision 808)
@@ -92,4 +92,5 @@
            catalog/SaoFile.cc \
            catalog/StarCatalog.cc \
+           catalog/Slalib.cc \
            videodev/Camera.cc \
            videodev/Filter.cc \
Index: trunk/MagicSoft/Cosy/Starguider.cc
===================================================================
--- trunk/MagicSoft/Cosy/Starguider.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/Starguider.cc	(revision 808)
@@ -293,5 +293,5 @@
 }
 
-void Starguider::Execute(const unsigned long n, char *img, struct timeval *tm)
+void Starguider::Execute(const unsigned long n, byte *img, struct timeval *tm)
 {
 
@@ -329,5 +329,5 @@
         if (fDisplay->IsEntryChecked(IDM_kCatalog))
         {
-            char cimg[768*576];
+            byte cimg[768*576];
 
             XY xy = fCRaDec->GetCoordinates();
Index: trunk/MagicSoft/Cosy/Starguider.h
===================================================================
--- trunk/MagicSoft/Cosy/Starguider.h	(revision 807)
+++ trunk/MagicSoft/Cosy/Starguider.h	(revision 808)
@@ -60,5 +60,5 @@
     // Execution of one frame - this function may be overloaded!
     //
-    void Execute(const unsigned long n, char *img, struct timeval *tm);
+    void Execute(const unsigned long n, byte *img, struct timeval *tm);
 };
 
Index: trunk/MagicSoft/Cosy/aposs/Magic.m
===================================================================
--- trunk/MagicSoft/Cosy/aposs/Magic.m	(revision 807)
+++ trunk/MagicSoft/Cosy/aposs/Magic.m	(revision 808)
@@ -3,5 +3,5 @@
 /*-------------------------------------------------------------------------*/
 
-DIM errlist[9]           
+DIM errlist[9] /* idx 1=number of valid entries */           
 
 /* ----------------------------------------------------------------------- */
@@ -10,7 +10,22 @@
 /*                                                                         */
 kVERSION    = 0   /*                                                       */
-kSUBVERSION = 50  /*                                                       */
+kSUBVERSION = 62  /*                                                       */
 /*                                                                         */
 /*  HISTORY:                                                               */
+/*                                                                         */
+/*   * V0.62:                                                              */
+/*       - changed handling of 0x2000/1/2 added /3                         */
+/*                                                                         */
+/*   * V0.61:                                                              */
+/*       - corrected problems with the error handling                      */
+/*                                                                         */
+/*   * V0.60:                                                              */
+/*       - introduced syncronisation                                       */
+/*                                                                         */
+/*   * V0.52:                                                              */
+/*       - changed the handling of the endswitch error (unknown switch)    */
+/*                                                                         */
+/*   * V0.51:                                                              */
+/*       - made errlist working                                            */
 /*                                                                         */
 /*   * V0.50:                                                              */
@@ -65,6 +80,7 @@
 /*   0x1800 x rw Enable PDO1 (Axe Status, Position)                        */
 /*   0x2000 0 rw Maximum positioning error                                 */
-/*          1 rw Negative Software Endswitch                               */
-/*          2 rw Positive Software Endswitch                               */
+/*          1 rw Negative Software Endswitch Value (Set=Enable)            */
+/*          2 rw Positive Software Endswitch Value (Set=Enable)            */
+/*          3 rw Enable/Disable Software Endswitch                         */
 /*   0x2002 x rw Velocity                                                  */
 /*   0x2003 0 wo Acceleration                                              */
@@ -76,8 +92,9 @@
 /*   0x3006 0 wo Velocity Mode 'strt', 'stop'                              */
 /*          1 wo VelMode Velocity                                          */
+/*   0x3007 x wo Syncronisation 'sync'                                     */
 /*   0x3008 x wo Nowait 'on', 'off'                                        */
 /*   0x6000 x rw Rotation Direction                                        */
 /*   0x6002 x rw Velocity Resolution                                       */
-/*   0x6003 0 wo Define present position as origin                         */
+/*   0x6003 0 wo Define present position as origin ('set')                 */
 /*          1 wo Define new origin (0=delete)                              */
 /*          2 rw Home Offset                                               */
@@ -99,4 +116,6 @@
 SET ENCODERTYPE   0          /* Incremental Encoder                        */
 SET ENCODER     500          /* Encoder has 500 Ticks                      */
+SET MENCODERTYPE  0          /* Incremental Encoder (Master)               */
+SET MENCODER    500          /* Encoder has 500 Ticks (Master)             */
 SET VELMAX     3600          /* Motor: Maximum rounds per minute           */
 SET POSERR     1500          /* Maximum tolarable Position error (qc) 0.1° */
@@ -112,4 +131,15 @@
 
 /*----------------*/
+/* syncronisation */
+/*----------------*/                                                       
+SET MENCODERTYPE   0         /* Incremental Encoder (Master)               */
+SET MENCODER     500         /* Encoder has 500 Ticks (Master)             */
+SET SYNCFACTM      1         /* Master Sync Velocity factor                */
+SET SYNCFACTS      1         /* Slave Sync Velocity factor                 */
+SET SYNCPOSOFFS    0         /* Sync Position offset between M/S           */
+SET SYNCACCURACY  50         /* When to set Accuracy Flag                  */
+SET REVERS         0         /* How to handle reversation of vel           */
+
+/*----------------*/
 /*    Inputs      */
 /*----------------*/
@@ -181,5 +211,5 @@
 /*-------------------------------------------------------------------------*/
 /* ON CANMSG GOSUB PROC_CANMSG */
-i = 8
+i = 9
 while (i) do
    errlist[i] = 0
@@ -197,4 +227,5 @@
 
    PRINT "Starting Mainloop..."
+   
    MAINLOOP:
       rc = CANIN sdorx 0 0 canhi canlo
@@ -225,8 +256,8 @@
 */
       if (idx == 0x1003 and subidx == 0 and sdoval == 0) then
-         i = 0
-         while (i<9) do
+         i = 9
+         while (i) do
             errlist[i] = 0
-            i = i + 1
+            i = i - 1
          endwhile
       elseif (idx == 0x1010 and sdoval == 's'<<24|'a'<<16|'v'<<8|'e') then 
@@ -244,17 +275,12 @@
               SET POSERR sdoval
            elseif (subidx == 1) then  
-              if ((sdoval>>30)&1) then
-                 SET NEGLIMIT    sdoval & 0x3fffffff
-                 SET SWNEGLIMACT 1
-              else
-                 SET SWNEGLIMACT 0
-              endif 
+              SET NEGLIMIT    sdoval 
+              SET SWNEGLIMACT      1 
            elseif (subidx == 2) then
-              if ((sdoval>>31)&1) then
-                 SET POSLIMIT    sdoval & 0x3fffffff
-                 SET SWPOSLIMACT 1
-              else
-                 SET SWPOSLIMACT 0
-              endif 
+              SET POSLIMIT    sdoval 
+              SET SWPOSLIMACT      1
+           elseif (subidx == 3) then
+              SET SWNEGLIMACT sdoval&1
+              SET SWPOSLIMACT (sdoval>>1)&1
            endif  
       elseif (idx == 0x2002) then
@@ -306,4 +332,6 @@
             CVEL sdoval
          endif
+      elseif (idx == 0x3007 and sdoval == 's'<<24|'y'<<16|'n'<<8|'c') then 
+         SYNCP
       elseif (idx == 0x3008) then
          if (sdoval == 'o'<<24|'n'<<16) then 
@@ -325,10 +353,8 @@
             SET POSDRCT 1
          endif
-/*    elseif (idx == 0x6001) then
-         SET ENCODER sdoval*/
       elseif (idx == 0x6002) then
          SET VELRES sdoval
       elseif (idx == 0x6003) then
-         if (subidx == 0) then
+         if (subidx == 0 and sdoval == 's'<<24|'e'<<16|'t'<<8) then
             DEF ORIGIN   
          elseif (subidx == 1) then
@@ -383,5 +409,5 @@
       if (idx == 0x1003) then
          if (subidx >=0 and subidx<=9) then
-            sdoval = errlist[subidx]
+            sdoval = errlist[subidx-1]
          endif
       elseif (idx == 0x1004) then
@@ -422,4 +448,6 @@
            elseif (subidx == 2) then
               sdoval = GET POSLIMIT | (GET SWPOSLIMACT) << 31
+           elseif (subidx == 3) then
+              sdoval = (GET SWNEGLIMACT) | ((GET SWPOSLIMACT)<<1)
            endif
       elseif (idx == 0x2001) then
@@ -514,47 +542,76 @@
    SUBPROG PROC_ERROR
       MOTOR STOP
-      errinf = 0
 
       /* Tell the bus that an error occured */
       CANOUT pdo2 0 0
       
-      i = errlist[0] + 1        
-      while (i>1) do
+      i = errlist[1] + 1              /* Fill status of array       */
+      while (i>2) do                  /* shift errors by one        */
          errlist[i] = errlist[i-1]
          i = i - 1
-      endwhile  
-      errlist[1] = ERRNO
-      if (errlist[0]<8) then
-         errlist[0] = errlist[0] + 1
-      endif
-
+      endwhile                        /* set new errornumber        */
+      errlist[2] = ERRNO
+      if (errlist[1]<8) then          /* write new size if enhanced */
+         errlist[1] = errlist[1] + 1
+      endif     
+
+      errinf = 0
+     
       /* check if the error is repairable and repair */
-      if (errlist[1]==6) then
+      if (errlist[2]==6) then
         PRINT "No home forced!"
         ERRCLR
-      elseif (errlist[1]==8) then
-        PRINT "Schleppabstand überschritten"
+      elseif (errlist[2]==8) then
+        PRINT "Control deviation overflow."
         ERRCLR
         errinf = 0xaffe
-      elseif (errlist[1]==9) then
+      elseif (errlist[2]==9) then
         PRINT "Did'n find zero index."
         ERRCLR
-      elseif (errlist[1]==25) then
-         lsw = -(GET I_POSLIMITSW)
-         if (IN lsw == 0) then
+      elseif (errlist[2]==11) then    
+         poslsw = GET POSLIMIT
+         neglsw = GET NEGLIMIT
+         if ((GET SWNEGLIMACT) and APOS<=neglsw) then
+            PRINT "Negative software endswitch (", neglsw, ") activated at position ", APOS
+            SET SWNEGLIMACT 0
+            ERRCLR
+            CVEL  (vres%100)    
+            ACC   (10*vres%100) 
+            DEC   (10*vres%100) 
+            POSA neglsw + 100
+            SET SWNEGLIMACT 1   
+            errinf = -1
+         elseif ((GET SWPOSLIMACT) and APOS>=poslsw) then
+            PRINT "Positive software endswitch (", poslsw, ") activated at position ", APOS
+            SET SWPOSLIMACT 0
+            ERRCLR
+            CVEL  (vres%100)    /*   1% */
+            ACC   (10*vres%100) /*  10% */
+            DEC   (10*vres%100) /*  10% */
+            POSA poslsw - 100
+            SET SWPOSLIMACT 1
+            errinf = 1
+         else     
+            PRINT "Software endswitch activated - command skipped. Pos: ", APOS
+            ERRCLR
+         endif
+      elseif (errlist[2]==25) then    
+         /* FIXME: To handle this correct you must make sure,
+                   that the endswitch numbers are negative    */
+         poslsw = -(GET I_POSLIMITSW)
+         neglsw = -(GET I_NEGLIMITSW)
+         if (IN poslsw == 0) then
             PRINT "Positive endswitch activated at position ", APOS
             SET I_POSLIMITSW 0
             ERRCLR
-            CVEL  (vres%100) /* 1% */
-            ACC   (10*vres%100)
-            DEC   (10*vres%100)
+            CVEL  (vres%100)    /*   1% */
+            ACC   (10*vres%100) /*  10% */
+            DEC   (10*vres%100) /*  10% */
             CSTART
-            WHILE (IN lsw == 0) DO ENDWHILE
+            WHILE (IN poslsw == 0) DO ENDWHILE
             CSTOP
-            SET I_POSLIMITSW -lsw
+            SET I_POSLIMITSW -poslsw
             errinf = 1
-         endif
-         lsw = -(GET I_NEGLIMITSW)
-         if (IN lsw == 0) then
+         elseif (IN neglsw == 0) then
             PRINT "Negative endswitch activated at position ", APOS
             SET I_NEGLIMITSW 0
@@ -564,21 +621,19 @@
             ACC   (10*vres%100)  /* 10% */
             DEC   (10*vres%100)  /* 10% */
-            OUT 1 1
-            MOTOR ON
             CSTART
-            WHILE (IN lsw == 0) DO ENDWHILE
+            WHILE (IN poslsw == 0) DO ENDWHILE
             CSTOP
-            SET I_NEGLIMITSW -lsw
+            SET I_NEGLIMITSW -poslsw
             errinf = -1
          endif
-      elseif (errlist[1]==84) then
+      elseif (errlist[2]==84) then
          PRINT "Too many (>12) ON TIME interrupts."
          ERRCLR
       ELSE
-        PRINT "Error Function Called: ERRNO=", errlist[1]
+        PRINT "Error Function Called: ERRNO=", errlist[2]
       endif
 
 	    /* tell the bus what exactly happened */
-      CANOUT pdo2 errlist[1] errinf
+      CANOUT pdo2 errlist[2] errinf
    RETURN
 
Index: trunk/MagicSoft/Cosy/base/timer.h
===================================================================
--- trunk/MagicSoft/Cosy/base/timer.h	(revision 807)
+++ trunk/MagicSoft/Cosy/base/timer.h	(revision 808)
@@ -34,4 +34,8 @@
     double GetMjd();
 
+    int H() const { return fHor; }
+    int M() const { return fMin; }
+    int S() const { return fSec; }
+
     const char *GetTimeStr();
 
Index: trunk/MagicSoft/Cosy/candrv/network.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/network.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/candrv/network.cc	(revision 808)
@@ -166,2 +166,10 @@
 }
 
+bool Network::HasError()
+{
+    for (int i=0; i<32; i++)
+        if (fNodes[i] && fNodes[i]->HasError())
+            return true;
+
+    return false;
+}
Index: trunk/MagicSoft/Cosy/candrv/network.h
===================================================================
--- trunk/MagicSoft/Cosy/candrv/network.h	(revision 807)
+++ trunk/MagicSoft/Cosy/candrv/network.h	(revision 808)
@@ -30,4 +30,6 @@
     virtual void Start();
     virtual void Stop();
+
+    bool HasError();
 };
 
Index: trunk/MagicSoft/Cosy/candrv/nodedrv.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 808)
@@ -6,5 +6,5 @@
 #include "network.h"
 
-NodeDrv::NodeDrv(BYTE_t nodeid, ostream &out) : Log(out), fNetwork(NULL), fId(32)
+NodeDrv::NodeDrv(BYTE_t nodeid, ostream &out) : Log(out), fNetwork(NULL), fId(32), fError(0)
 {
     if (nodeid>31)
Index: trunk/MagicSoft/Cosy/candrv/nodedrv.h
===================================================================
--- trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 807)
+++ trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 808)
@@ -13,4 +13,11 @@
     BYTE_t   fId;
 
+    int fError;
+
+protected:
+    void SetError(int err) { fError = err; }
+    void DelError()        { fError = 0; }
+    int  GetError()        { return fError; }
+
 public:
     NodeDrv(BYTE_t nodeid, ostream &out=cout);
@@ -21,4 +28,6 @@
     virtual void InitDevice(Network *net);
     virtual void StopDevice() = 0;
+
+    bool HasError()        { return fError; }
 
     virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, struct timeval *tv);
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 808)
@@ -16,14 +16,4 @@
 
     //
-    // calculate observers location (goe)
-    //
-    int status;
-    slaDaf2r(51, 38, 48.0, &fPhi,   &status);
-    slaDaf2r( 9, 56, 36.0, &fElong, &status);
-
-    cout << "fPhi:   51ø38'48.0\" = " <<  360.0/D2PI*fPhi << endl;
-    cout << "fElong:  9ø56'36.0\" = " <<  360.0/D2PI*fElong << endl;
-
-    //
     // read index file
     //
@@ -78,5 +68,5 @@
     cout << "  Az: " << fAltAz.Az() << endl;
 
-    fRaDec = AltAz2RaDec(fAltAz);
+    fRaDec = sla.CalcRaDec(fAltAz);
 
     cout << "Ra: " << 360.0/D2PI*fRaDec.Ra();
@@ -87,65 +77,10 @@
 }
 
-RaDec StarCatalog::AltAz2RaDec(const AltAz &altaz) const
-{
-    //
-    // -- observed to apparent --
-    //  Workaraound for slalib: discard const
-    //
-    double r=0, d=0;
-    slaOapqk ("A", altaz.Az(), DPI/2-altaz.Alt(), (double*)fAoprms, &r, &d);
-
-    //
-    // -- apparent to mean --
-    //  Workaraound for slalib: discard const
-    //
-    double ra, dec;
-    slaAmpqk(r, d, (double*)fAmprms, &ra, &dec);
-
-    return RaDec(ra, dec);
-}
-
-AltAz StarCatalog::RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const
-{
-    //
-    // ---- Mean to apparent ----
-    //
-
-    double r=0, d=0;
-    slaMapqkz(radec.Ra(), radec.Dec(), (double*)fAmprms, &r, &d);
-    //
-    // Doesn't work - don't know why
-    //
-    //    slaMapqk (radec.Ra(), radec.Dec(), rdpm.Ra(), rdpm.Dec(),
-    //              0, 0, (double*)fAmprms, &r, &d);
-    //
-
-    //
-    // -- apparent to observed --
-    //
-    double r1=0;  // ra
-    double d1=0;  // dec
-    double h0=0;  // ha
-
-    double zd;
-    double az;
-    slaAopqk (r, d, (double*)fAoprms,
-              &az,    // observed azimuth (radians: N=0,E=90)
-              &zd,    // observed zenith distance (radians) [-pi/2, pi/2]
-              &h0,    // observed hour angle (radians)
-              &d1,    // observed declination (radians)
-              &r1);   // observed right ascension (radians)
-
-    return AltAz(DPI/2-zd, az);
-}
-
-void StarCatalog::SetRaDec(const RaDec &radec, const RaDec &rdpm)
+void StarCatalog::SetRaDec(const RaDec &radec)
 {
     fRaDec = radec;
     fRaDec *= D2PI/360.0;
 
-    RaDec pm = rdpm * D2PI/360.0;
-
-    fAltAz = RaDec2AltAz(fRaDec, pm);
+    fAltAz = sla.CalcAltAz(fRaDec);
 
     cout << "Alt: " << 360.0/D2PI*fAltAz.Alt() << "  ";
@@ -158,5 +93,5 @@
 void StarCatalog::CalcAltAzRange()
 {
-    char fAlt0[180];
+    byte fAlt0[180];
 
     for (int h=0; h<180; h++)
@@ -248,5 +183,5 @@
     // check whether altaz north- or south-pole is in the visible region
     //
-    char img[768*576];
+    byte img[768*576];
     if (DrawAltAz(0, img, 90, 0))
     {
@@ -263,4 +198,5 @@
     cout << "fAltMax: " << setw(3) << fAltMax << endl;
 }
+
 void StarCatalog::CalcRaDecRange()
 {
@@ -268,5 +204,5 @@
     // calculate range to search in
     //
-    char fDec[180];
+    byte fDec[180];
 
     for (int h=0; h<180; h++)
@@ -279,4 +215,6 @@
     double de0, de1;
 
+    const double phi   = sla.GetPhi();
+    const double alpha = sla.GetAlpha();
     //
     // scan horizontal border
@@ -286,10 +224,10 @@
         double dx, dy;
         slaDh2e(DPI-x*fPixSize, -fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha0, &de0);
+        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha0, &de0);
 
         slaDh2e(DPI-x*fPixSize, +fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha1, &de1);
-
-        const int h0 = ((int)(360.0/D2PI*(fAlpha-ha0))+360)%360;
+        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha1, &de1);
+
+        const int h0 = ((int)(360.0/D2PI*(alpha-ha0))+360)%360;
         const int d0 = (int)(360.0/D2PI*de0);
 
@@ -299,5 +237,5 @@
             fDec[d0+90] = kTRUE;
 
-        const int h1 = ((int)(360.0/D2PI*(fAlpha-ha1))+360)%360;
+        const int h1 = ((int)(360.0/D2PI*(alpha-ha1))+360)%360;
         const int d1 = (int)(360.0/D2PI*de1);
 
@@ -315,10 +253,10 @@
         double dx, dy;
         slaDh2e(DPI-fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha0, &de0);
+        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha0, &de0);
 
         slaDh2e(DPI+fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, fPhi, &ha1, &de1);
-
-        const int h0 = ((int)(360.0/D2PI*(fAlpha-ha0))+360)%360;
+        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha1, &de1);
+
+        const int h0 = ((int)(360.0/D2PI*(alpha-ha0))+360)%360;
         const int d0 = (int)(360.0/D2PI*de0);
 
@@ -328,5 +266,5 @@
             fDec[d0+90] = kTRUE;
 
-        const int h1 = ((int)(360.0/D2PI*(fAlpha-ha1))+360)%360;
+        const int h1 = ((int)(360.0/D2PI*(alpha-ha1))+360)%360;
         const int d1 = (int)(360.0/D2PI*de1);
 
@@ -364,5 +302,5 @@
     // check whether radec north- or south-pole is in the visible region
     //
-    char img[768*576];
+    byte img[768*576];
     if (DrawRaDec(0, img, 0, 90))
     {
@@ -380,5 +318,5 @@
 }
 
-void StarCatalog::DrawSCAltAz(char *img, const int color)
+void StarCatalog::DrawSCAltAz(byte *img, const int color)
 {
     //
@@ -414,5 +352,5 @@
 }
 
-void StarCatalog::DrawSCRaDec(char *img, const int color)
+void StarCatalog::DrawSCRaDec(byte *img, const int color)
 {
     //
@@ -446,30 +384,7 @@
         }
     }
-
-//    DrawRaDec(color, img, 37.953, 89.2641, 10);
-}
-
-
-void StarCatalog::SetMjd(const double mjd)
-{
-    fMjd   = mjd;
-    fAlpha = slaGmst(mjd) + fElong;
-
-    cout << "UTC: " << mjd << endl;
-
-    //
-    // ----- calculate star independent parameters ----------
-    //
-    slaMappa(2000.0, fMjd, fAmprms);
-    slaAoppa(fMjd, 0,                // mjd, UT1-UTC
-             fElong, fPhi, 148,      // gttingen long, lat, height
-             0, 0,                   // polar motion x, y-coordinate (radians)
-             273.155, 1013.25, 0.5,  // temp, pressure, humidity
-             0.2, 0.0065,            // wavelength, tropo lapse rate
-             fAoprms);
-
-}
-
-void StarCatalog::DrawCross(char *img, const int x, const int y)
+}
+
+void StarCatalog::DrawCross(byte *img, const int x, const int y)
 {
     for (int dx=-4; dx<5; dx++)
@@ -480,5 +395,5 @@
 }
 
-void StarCatalog::GetImg(char *img, char *cimg, const double utc,
+void StarCatalog::GetImg(byte *img, byte *cimg, const double utc,
                          const RaDec &radec)
 {
@@ -486,7 +401,7 @@
     memset(cimg, 0, 768*576);
 
-    SetMjd(utc);
-
-    SetRaDec(radec, RaDec());
+    sla.Set(utc);
+    //fAlpha = sla.GetAlpha();
+    SetRaDec(radec);
 
     DrawSCAltAz(cimg, 2<<4);
@@ -498,5 +413,5 @@
 }
 
-void StarCatalog::GetImg(char *img, char *cimg, const double utc,
+void StarCatalog::GetImg(byte *img, byte *cimg, const double utc,
                          const AltAz &altaz)
 {
@@ -504,6 +419,6 @@
     memset(cimg, 0, 768*576);
 
-    SetMjd(utc);
-
+    sla.Set(utc);
+    //fAlpha = sla.GetAlpha();
     SetAltAz(altaz);
 
@@ -516,5 +431,5 @@
 }
 
-void StarCatalog::DrawCircle(int color, char *img, int xx, int yy, int size)
+void StarCatalog::DrawCircle(int color, byte *img, int xx, int yy, int size)
 {
     for (int x=xx-size; x<xx+size+1; x++)
@@ -537,5 +452,5 @@
 }
 
-Bool_t StarCatalog::DrawAltAz(const int color, char *img, double alt, double az, int size)
+Bool_t StarCatalog::DrawAltAz(const int color, byte *img, double alt, double az, int size)
 {
     //
@@ -571,15 +486,15 @@
 }
 
-Bool_t StarCatalog::Draw(const int color, char *img, const AltAz &altaz)
+Bool_t StarCatalog::Draw(const int color, byte *img, const AltAz &altaz)
 {
     return DrawAltAz(color, img, altaz.Alt(), altaz.Az());
 }
 
-Bool_t StarCatalog::Draw(const int color, char *img, const SaoFile *sao)
+Bool_t StarCatalog::Draw(const int color, byte *img, const SaoFile *sao)
 {
     //
     // ---- mean to observed ---
     //
-    AltAz altaz=RaDec2AltAz(sao->GetRaDec(), sao->GetRaDecPm()) * 360.0/D2PI;
+    AltAz altaz=sla.CalcAltAz(sao->GetRaDec()) * 360.0/D2PI;
 
     if (sao->MagV() > fLimitMag)
@@ -594,5 +509,5 @@
 }
 
-Bool_t StarCatalog::DrawRaDec(const int color, char *img, double ra, double dec, int size)
+Bool_t StarCatalog::DrawRaDec(const int color, byte *img, double ra, double dec, int size)
 {
     //
@@ -605,5 +520,5 @@
     // radec[rad] -> hadec[rad]
     //
-    const double ha = fAlpha-ra;
+    const double ha = sla.GetAlpha()-ra;
 
     //
@@ -611,5 +526,5 @@
     //
     double alt, az;
-    slaDe2h(ha, dec, fPhi, &az, &alt);
+    slaDe2h(ha, dec, sla.GetPhi(), &az, &alt);
 
     //
@@ -622,10 +537,10 @@
 }
 
-Bool_t StarCatalog::Draw(const int color, char *img, const RaDec &radec)
+Bool_t StarCatalog::Draw(const int color, byte *img, const RaDec &radec)
 {
     return DrawRaDec(color, img, radec.Ra(), radec.Dec());
 }
 
-void StarCatalog::CalcImg(char *img)
+void StarCatalog::CalcImg(byte *img)
 {
 
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.h
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 807)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 808)
@@ -8,6 +8,11 @@
 #include "SaoFile.h"
 #endif
+#ifndef SLALIB_H
+#include "Slalib.h"
+#endif
 
 #include "coord.h"
+
+typedef unsigned char byte;
 
 class StarCatalog
@@ -18,6 +23,8 @@
     int      fEntries;
 
-    double   fPhi;      // location of observatory
-    double   fElong;
+    Slalib   sla;
+
+//    double   fPhi;      // location of observatory
+//    double   fElong;
 
     double   fPixSize;  // [rad/pix] size of one pixel
@@ -28,5 +35,5 @@
 
     AltAz    fAltAz;    // [rad]
-    char     fAz0[360];
+    byte     fAz0[360];
     int      fAltMin;
     int      fAltMax;
@@ -34,37 +41,37 @@
 
     RaDec    fRaDec;    // [rad]
-    char     fRa0[360];
+    byte     fRa0[360];
     int      fRaCnt;
     int      fDecMin;
     int      fDecMax;
 
-    double   fAlpha;
-    double   fMjd;
-    double   fAmprms[21];
-    double   fAoprms[14];
+//    double   fAlpha;
+//    double   fMjd;
+//    double   fAmprms[21];
+//    double   fAoprms[14];
 
-    void DrawCross(char *img, const int x, const int y);
-    void DrawCircle(int color, char *img, int xx, int yy, int size);
+    void DrawCross(byte *img, const int x, const int y);
+    void DrawCircle(int color, byte *img, int xx, int yy, int size);
 
-    Bool_t DrawAltAz(const int color, char *img, double alt, double az, int size=0);
-    Bool_t DrawRaDec(const int color, char *img, double ra,  double dec, int size=0);
+    Bool_t DrawAltAz(const int color, byte *img, double alt, double az,  int size=0);
+    Bool_t DrawRaDec(const int color, byte *img, double ra,  double dec, int size=0);
 
-    Bool_t Draw(const int color, char *img, const AltAz &altaz);
-    Bool_t Draw(const int color, char *img, const RaDec &radec);
-    Bool_t Draw(const int color, char *img, const SaoFile *sao);
+    Bool_t Draw(const int color, byte *img, const AltAz &altaz);
+    Bool_t Draw(const int color, byte *img, const RaDec &radec);
+    Bool_t Draw(const int color, byte *img, const SaoFile *sao);
 
-    void   CalcImg(char *);
+    void   CalcImg(byte *);
 
+    void   SetRaDec(const RaDec &radec);
     void   SetAltAz(const AltAz &altaz);
-    void   SetMjd(const double mjd);
-    void   DrawSCAltAz(char *img, const int color);
-    void   DrawSCRaDec(char *img, const int color);
-    void   SetRaDec(const RaDec &radec, const RaDec &rdpm);
-
+//    void   SetMjd(const double mjd);
+    void   DrawSCAltAz(byte *img, const int color);
+    void   DrawSCRaDec(byte *img, const int color);
+  
     void   CalcRaDecRange();
     void   CalcAltAzRange();
 
-    RaDec  AltAz2RaDec(const AltAz &altaz) const;
-    AltAz  RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const;
+//    RaDec  AltAz2RaDec(const AltAz &altaz) const;
+//    AltAz  RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const;
 
 public:
@@ -72,7 +79,7 @@
     virtual ~StarCatalog();
 
-    void   GetImg(char *img, char *cimg, const double utc,
+    void   GetImg(byte *img, byte *cimg, const double utc,
                   const RaDec &radec);
-    void   GetImg(char *img, char *cimg, const double utc,
+    void   GetImg(byte *img, byte *cimg, const double utc,
                   const AltAz &altaz);
 
Index: trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 808)
@@ -10,5 +10,5 @@
     : NodeDrv(nodeid, out), fMacId(2*nodeid+1),
     fPos(0), fPosTime(0.0), fPdoPos(0), fPdoTime(0.0),
-    fPosActive(0), fRpmActive(0), fError(FALSE)
+    fPosActive(0), fRpmActive(0)
 {
 }
@@ -115,11 +115,10 @@
     RequestSDO(0x2004);
     WaitForSdo(0x2004);
-
-
-*/
+    */
+
     lout << "- Requesting Mac Software Version of " << (int)GetId() << endl;
     RequestSDO(0x100a);
     WaitForSdo(0x100a);
-    //    
+
     SetRpmMode(FALSE);
 
@@ -131,5 +130,5 @@
 
 
-    SetHome(250000);
+//    SetHome(250000);
 
 //    lout << "- Requesting SDO 0x2001 of " << (int)GetId() << endl;
@@ -195,7 +194,11 @@
     WaitForSdo(0x6003, 2);
 
+    // home also defines the zero point of the system
     SendSDO(0x3001, string('h','o','m','e'));       // home
     WaitForSdo(0x3001);
     lout << "- Home position of #" << (int)GetId() << " reached. " << endl;
+
+    SendSDO(0x6003, 0, string('s','e','t'));       // home
+    WaitForSdo(0x6003, 0);
 }
 
@@ -208,5 +211,5 @@
 void Macs::SetAcceleration(LWORD_t acc)
 {
-    SendSDO(0x2003, 0, acc);     // acceleration
+    SendSDO(0x2003, 0, acc);  // acceleration
     WaitForSdo(0x2003, 0);
 }
@@ -214,5 +217,5 @@
 void Macs::SetDeceleration(LWORD_t dec)
 {
-    SendSDO(0x2003, 1, dec);     // acceleration
+    SendSDO(0x2003, 1, dec);  // acceleration
     WaitForSdo(0x2003, 1);
 }
@@ -223,5 +226,4 @@
     // SetRpmMode(FALSE) stop the motor, but lets the position control unit on
     //
-
     SendSDO(0x3006, 0, mode ? string('S','T','R','T') : string('S','T','O','P'));
     WaitForSdo(0x3006, 0);
@@ -250,4 +252,11 @@
     WaitForSdo(0x3008);
 }
+
+void Macs::SetSyncMode()
+{
+    lout << "- Setting Sync Mode #" << (int)GetId() << endl;
+    SendSDO(0x3007, string('S', 'Y', 'N', 'C'));
+    WaitForSdo(0x3007);
+}
 /*
 void Macs::ReqAxEnd()
@@ -283,10 +292,25 @@
     LWORDS_t errinf = (data[4]<<24) | (data[5]<<16) | (data[6]<<8) | data[7];
 
+    //
+    // errnum==0 gives a sudden information that something happened. Now the
+    // microcontroller is running inside its interrup procedure which
+    // stopped the normal program. The interrupt procedure should try to clear
+    // the error state of the hardware. This should never create a new error!
+    //
     if (!errnum)
     {
         cout << "Mac #" << (int)GetId() << " reports Error occursion." << endl;
-        fError = TRUE;
+        SetError(-1);
         return;
     }
+
+    //
+    // Now the error is handled by the hardware now it is the software part
+    // to react on it. The Error flag now is set to the correct value.
+    //
+    if (GetError()>0)
+        cout << "Mac #" << (int)GetId() << " WARNING! Error #" << GetError() << " unhandled by software." << endl;
+
+    SetError(errnum);
 
     cout << "Mac #" << (int)GetId() << " reports: ";
@@ -305,18 +329,26 @@
         return;
 
+    case 11:
     case 25:
         switch (errinf)
         {
+        case -1:
+            cout << "Negative";
+            break;
         case 1:
             cout << "Positive";
-            break;
-        case 2:
-            cout << "Negative";
             break;
         default:
             cout << "-unknown-";
         }
-        cout << " endswitch activated." << endl;
-        fError = FALSE;
+        switch (errnum)
+        {
+        case 11:
+            cout << " software endswitch activated." << endl;
+            break;
+        case 25:
+            cout << " hardware endswitch activated." << endl;
+            break;
+        }
         return;
 
@@ -330,4 +362,43 @@
 }
 
+void Macs::HandleError()
+{
+    //
+    // If there is no error we must not handle anything
+    //
+    if (!HasError())
+        return;
+
+    //
+    // If the program got into the: HandleError state before the hardware
+    // has finished handeling the error we have to wait for the hardware
+    // handeling the error
+    //
+    // FIXME: Timeout???
+    //
+    while (GetError()<0)
+        usleep(1);
+
+    //
+    // After this software and hardware should be in a state so that
+    // we can go on working 'as usual' Eg. Initialize a Display Update
+    //
+    cout << "Mac #" << (int)GetId() << " Handling Error #" << GetError() << endl;
+    switch (GetError())
+    {
+    case  6: // home
+    case  8: // control dev
+    case  9: // zero idx
+    case 84: // ON TIME
+        // Stop program?
+        return;
+
+    case 11: // software endswitch
+    case 25: // hardware endswitch
+        DelError();
+        return;
+    }
+}
+
 double Macs::GetTime()
 {
@@ -350,2 +421,22 @@
 }
 
+/*   0x2000 0 rw Maximum positioning error     */
+/*          1 rw Negative Software Endswitch   */
+/*          2 rw Positive Software Endswitch   */
+void Macs::SetNegEndswitch(LWORDS_t val)
+{
+    SendSDO(0x2000, 1, (LWORD_t)val);
+    WaitForSdo(0x2000, 1);
+}
+
+void Macs::SetPosEndswitch(LWORDS_t val)
+{
+    SendSDO(0x2000, 2, (LWORD_t)val);
+    WaitForSdo(0x2000, 2);
+}
+
+void Macs::EnableEndswitches(bool neg, bool pos)
+{
+    SendSDO(0x2000, 3, (LWORD_t)(neg|(pos<<1)));
+    WaitForSdo(0x2000, 3);
+}
Index: trunk/MagicSoft/Cosy/devdrv/macs.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 807)
+++ trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 808)
@@ -21,6 +21,4 @@
     BYTE_t   fPosActive;
     BYTE_t   fRpmActive;
-
-    int      fError;      // Indicater for error state
 
     LWORD_t string(BYTE_t b0=0, BYTE_t b1=0, BYTE_t b2=0, BYTE_t b3=0)
@@ -58,7 +56,12 @@
     void SetVelocity(LWORD_t vel);
     void SetNoWait(BYTE_t flag=TRUE);
+    void SetSyncMode();
     void SetRpmMode(BYTE_t mode=TRUE);
     void SetRpmVelocity(LWORDS_t cvel);
     void SetPDO1On(BYTE_t flag=TRUE);
+    void SetPosEndswitch(LWORDS_t val);
+    void SetNegEndswitch(LWORDS_t val);
+
+    void EnableEndswitches(bool neg=true, bool pos=true);
 
     void StartRelPos(LWORDS_t pos);
@@ -79,7 +82,7 @@
     LWORDS_t GetPos()    { return fPos; }
     LWORDS_t GetVel()    { return fVel; }
-    LWORD_t  GetVelRes() { return fVelRes; }
+    LWORD_t  GetVelRes() { return fVelRes; } // Velocity units (would be 100 for %)
 
-    int      HasError() { return fError; }
+    void HandleError();
 };
 
Index: trunk/MagicSoft/Cosy/gui/MGCoordinate.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCoordinate.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGCoordinate.cc	(revision 808)
@@ -25,5 +25,5 @@
 MGCoordinate::MGCoordinate(const TGWindow* p,
                            const Bool_t flag, const char *txt,
-                           const UInt_t deg, const UInt_t min, const UInt_t sec)
+                           const Int_t deg, const UInt_t min, const UInt_t sec)
 : TGFrame(p, 114, flag?76:46, kSunkenFrame|kFixedSize), fDeg(deg), fMin(min), fSec(sec)
 {
@@ -131,5 +131,8 @@
 Double_t MGCoordinate::GetVal() const
 {
-    return (Double_t)(60*(60*fDeg+fMin)+fSec)/3600;
+    const Int_t deg = fDeg<0 ? -fDeg : fDeg;
+    const Int_t sgn = fDeg<0 ? -1 : 1;
+
+    return (Double_t)sgn*(60*(60*deg+fMin)+fSec)/3600;
 }
 
@@ -139,5 +142,5 @@
 }
 
-void MGCoordinate::Set(TGLabel *label, UInt_t val)
+void MGCoordinate::Set(TGLabel *label, Int_t val)
 {
     char txt[20];
@@ -148,5 +151,5 @@
 }
 
-void MGCoordinate::Set(TGTextEntry *entry, UInt_t val)
+void MGCoordinate::Set(TGTextEntry *entry, Int_t val)
 {
     char txt[20];
@@ -184,9 +187,9 @@
 
 
-Bool_t MGCoordinate::Set(TGLabel *label, UInt_t &val, TGTextEntry *entry)
-{
-    UInt_t newval = atoi(entry->GetText());
-
-    Bool_t ok = (entry == fTextEntryDeg || newval<60);
+Bool_t MGCoordinate::Set(TGLabel *label, Int_t &val, TGTextEntry *entry)
+{
+    Int_t newval = atoi(entry->GetText());
+
+    Bool_t ok = (entry == fTextEntryDeg || (newval>=0 && newval<60));
 
     if (ok)
Index: trunk/MagicSoft/Cosy/gui/MGCoordinate.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCoordinate.h	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGCoordinate.h	(revision 808)
@@ -20,7 +20,7 @@
 class MGCoordinate : public TGFrame
 {
-    UInt_t fDeg;
-    UInt_t fMin;
-    UInt_t fSec;
+    Int_t fDeg;
+    Int_t fMin;
+    Int_t fSec;
 
     MGList fList;
@@ -36,12 +36,12 @@
     TGLabel     *fLabel;
 
-    void   Set(TGLabel     *label, const UInt_t val);
-    void   Set(TGTextEntry *entry, const UInt_t val);
-    Bool_t Set(TGLabel     *label, UInt_t &val, TGTextEntry *label);
+    void   Set(TGLabel     *label, const Int_t val);
+    void   Set(TGTextEntry *entry, const Int_t val);
+    Bool_t Set(TGLabel     *label, Int_t &val, TGTextEntry *label);
 
 public:
     MGCoordinate(const TGWindow* p,
                  const Bool_t flag=kTRUE, const char *txt="Coordinates:",
-                 const UInt_t deg=0, const UInt_t min=0, const UInt_t sec=0);
+                 const Int_t deg=0, const UInt_t min=0, const UInt_t sec=0);
     ~MGCoordinate();
 
Index: trunk/MagicSoft/Cosy/gui/MGCoordinates.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCoordinates.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGCoordinates.cc	(revision 808)
@@ -14,6 +14,6 @@
                              const Bool_t flag,
                              const char *txt1, const char *txt2,
-                             const UInt_t deg1, const UInt_t min1, const UInt_t sec1,
-                             const UInt_t deg2, const UInt_t min2, const UInt_t sec2)
+                             const Int_t deg1, const UInt_t min1, const UInt_t sec1,
+                             const Int_t deg2, const UInt_t min2, const UInt_t sec2)
 : TGFrame(p, 234, 76, kFixedSize)
 {
Index: trunk/MagicSoft/Cosy/gui/MGCoordinates.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCoordinates.h	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGCoordinates.h	(revision 808)
@@ -27,6 +27,6 @@
                   const char *txt1="Coordinate1:",
                   const char *txt2="Coordinate2:",
-                  const UInt_t deg1=0, const UInt_t min1=0, const UInt_t sec1=0,
-                  const UInt_t deg2=0, const UInt_t min2=0, const UInt_t sec2=0);
+                  const Int_t deg1=0, const UInt_t min1=0, const UInt_t sec1=0,
+                  const Int_t deg2=0, const UInt_t min2=0, const UInt_t sec2=0);
     ~MGCoordinates();
 
Index: trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 808)
@@ -16,4 +16,6 @@
 #include "MGList.h"
 #include "MGCoordinates.h"
+
+#include "Slalib.h"
 
 #define IDM_EXIT 1
@@ -242,9 +244,12 @@
                     t.GetTime();
 
+                    Slalib sla;
+                    sla.Set(t.GetMjd());
+
                     XY xy = fCoord->GetCoordinates();
                     RaDec rd(xy.X(), xy.Y());
 
                     cout << "Ra/Dec: " << rd.Ra() << kDEG << " " << rd.Dec() << kDEG << endl;
-                    ZdAz aa=MCosy::RaDec2ZdAz(t.GetMjd(), rd*D2PI/360.0)*360.0/D2PI;
+                    ZdAz aa=sla.CalcZdAz(rd*D2PI/360.0)*360.0/D2PI;
                     cout << "Zd/Az: " << aa.Zd() << kDEG << " " << aa.Az() << kDEG << endl;
                 }
Index: trunk/MagicSoft/Cosy/gui/MGImage.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 808)
@@ -195,6 +195,6 @@
 
 
-#include <TGClient.h>
-void MGImage::DrawImg(const char *buffer)
+//#include <TGClient.h>
+void MGImage::DrawImg(const byte *buffer)
 {
     if (pthread_mutex_trylock((pthread_mutex_t*)fMuxPixmap))
@@ -205,5 +205,5 @@
         for (UInt_t x=0; x<fWidth; x++)
         {
-            const unsigned char col = buffer[y*fWidth+x];
+            const byte col = buffer[y*fWidth+x];
 
             fBody[y][x*2]   = fColors[col][0];
@@ -306,5 +306,5 @@
 }
 
-void MGImage::DrawColImg(const char *gbuf, const char *cbuf)
+void MGImage::DrawColImg(const byte *gbuf, const byte *cbuf)
 {
     if (pthread_mutex_trylock((pthread_mutex_t*)fMuxPixmap))
@@ -315,5 +315,5 @@
         for (UInt_t x=0; x<fWidth; x++)
         {
-            const unsigned char ccol = cbuf[y*fWidth+x];
+            const byte ccol = cbuf[y*fWidth+x];
 
             if (ccol)
@@ -324,5 +324,5 @@
             else
             {
-                const unsigned char gcol = gbuf[y*fWidth+x];
+                const byte gcol = gbuf[y*fWidth+x];
                 fBody[y][x*2]   = fColors[gcol][0];
                 fBody[y][x*2+1] = fColors[gcol][1];
Index: trunk/MagicSoft/Cosy/gui/MGImage.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 807)
+++ trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 808)
@@ -9,4 +9,6 @@
 
 #include <TGFrame.h>
+
+typedef unsigned char byte;
 
 class MGImage : public TGFrame
@@ -38,6 +40,6 @@
     void MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h);
 
-    void DrawImg(const char *buffer);
-    void DrawColImg(const char *gbuf, const char *cbuf);
+    void DrawImg(const byte *buffer);
+    void DrawColImg(const byte *gbuf, const byte *cbuf);
 };
 
Index: trunk/MagicSoft/Cosy/videodev/Camera.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 808)
@@ -188,5 +188,5 @@
 
 void Camera::Execute(const unsigned long n,
-                     char *img,
+                     byte *img,
                      struct timeval *tm)
 {
@@ -247,5 +247,5 @@
             if (!StartGrab(i&1))
                 break;
-            Execute(i, fImg, &fTime);
+            Execute(i, (byte*)fImg, &fTime);
             i++;
         }
@@ -254,10 +254,10 @@
         {
             LoopStep(i);
-            Execute(i, fImg, &fTime);
+            Execute(i, (byte*)fImg, &fTime);
             i++;
         }
 
         LoopStep(i);
-        Execute(i, fImg, &fTime);
+        Execute(i, (byte*)fImg, &fTime);
         i++;
 
Index: trunk/MagicSoft/Cosy/videodev/Camera.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 808)
@@ -4,4 +4,6 @@
 #include <pthread.h>
 #include <sys/time.h>
+
+typedef unsigned char byte;
 
 class Camera
@@ -85,5 +87,5 @@
     //
     virtual void Execute(const unsigned long n,
-                         char *img, struct timeval *tm);
+                         byte *img, struct timeval *tm);
 
     //
Index: trunk/MagicSoft/Cosy/videodev/Filter.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Filter.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Filter.cc	(revision 808)
@@ -6,5 +6,5 @@
 void Filter::DrawBox(const int x1, const int y1,
                      const int x2, const int y2,
-                     char *buffer, const int col)
+                     byte *buffer, const int col)
 {
     for (int x=x1; x<x2+1; x++)
@@ -13,5 +13,5 @@
 }
 
-void Filter::MarkPoint(const int x, const int y, char *buffer, const int col)
+void Filter::MarkPoint(const int x, const int y, byte *buffer, const int col)
 {
     DrawBox(x-8, y, x-5, y, buffer, col);
@@ -22,5 +22,5 @@
 }
 
-float Filter::Mean(const char *buffer, const int offset, int *min, int *max)
+float Filter::Mean(const byte *buffer, const int offset, int *min, int *max)
 {
     double mean = 0.0;
@@ -35,12 +35,12 @@
         for (int y=offset; y<576-offset; y++)
         {
-            unsigned char val = (unsigned char)buffer[y*768+x];
+            byte val = buffer[y*768+x];
 
             mean += val;
 
-            if (*max<val)
+            if (val>*max)
                 *max = val;
 
-            if (*min>val)
+            if (val<*min)
                 *min = val;
         }
@@ -51,5 +51,5 @@
 }
 
-float Filter::SDev(const char *buffer, const int offset, const double mean)
+float Filter::SDev(const byte *buffer, const int offset, const double mean)
 {
     //
@@ -61,5 +61,5 @@
         for (int y=offset; y<576-offset; y++)
         {
-            const float val = mean - (unsigned char)buffer[y*768+x];
+            const float val = mean - buffer[y*768+x];
 
             sdev += val*val;
@@ -71,5 +71,5 @@
 }
 
-int Filter::GetMeanPosition(const char *bitmap, const int x, const int y,
+int Filter::GetMeanPosition(const byte *bitmap, const int x, const int y,
                             const int box)
 {
@@ -82,5 +82,5 @@
         for (int dy=y-box; dy<y+box+1; dy++)
         {
-            const unsigned char m = (unsigned char)bitmap[dy*768+dx]; // desc->buffer[3*(x+y*768)]; //
+            const byte m = bitmap[dy*768+dx]; // desc->buffer[3*(x+y*768)]; //
 
             sumx += m*dx;
@@ -95,5 +95,5 @@
 }
 
-void Filter::Execute(char *img)
+void Filter::Execute(byte *img)
 {
     const int offset = 10;
@@ -115,4 +115,8 @@
             if (img[y*768+x]>cut)
                 continue;
+
+            //
+            // FIXME: Create LOOKUP Table!
+            //
 
             img[y*768+x] = 0;
@@ -169,5 +173,5 @@
     int points=0;
 
-    char marker[768*576];
+    byte marker[768*576];
     memset(marker, 0, 768*576);
 
Index: trunk/MagicSoft/Cosy/videodev/Filter.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Filter.h	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Filter.h	(revision 808)
@@ -1,4 +1,6 @@
 #ifndef FILTER_H
 #define FILTER_H
+
+typedef unsigned char byte;
 
 class Filter
@@ -6,21 +8,21 @@
     static void  DrawBox(const int x1, const int y1,
                          const int x2, const int y2,
-                         char *buffer, const int col);
+                         byte *buffer, const int col);
 
     static void  MarkPoint(const int x, const int y,
-                           char *buffer, const int col);
+                           byte *buffer, const int col);
 
-    static float Mean(const char *buffer, const int offset,
+    static float Mean(const byte *buffer, const int offset,
                       int *min, int *max);
 
-    static float SDev(const char *buffer, const int offset,
+    static float SDev(const byte *buffer, const int offset,
                       const double mean);
 
-    static int   GetMeanPosition(const char *bitmap,
+    static int   GetMeanPosition(const byte *bitmap,
                                  const int x, const int y,
                                  const int box);
 
 public:
-    static void Execute(char *img);
+    static void Execute(byte *img);
 };
 
Index: trunk/MagicSoft/Cosy/videodev/Writer.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Writer.cc	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Writer.cc	(revision 808)
@@ -9,5 +9,5 @@
 #include "timer.h"
 
-void Writer::Png(const char *fname, const char *buf,
+void Writer::Png(const char *fname, const byte *buf,
                  struct timeval *date)
 {
@@ -106,5 +106,5 @@
 }
 
-void Writer::Ppm(const char *fname, const char *img)
+void Writer::Ppm(const char *fname, const byte *img)
 {
     cout << "Writing PPM '" << fname << "'" << endl;
@@ -121,5 +121,5 @@
     //
     fout << "P6\n768 576\n255\n";
-    for (char const *buf = img; buf < img+768*576; buf++)
+    for (byte const *buf = img; buf < img+768*576; buf++)
         fout << *buf << *buf << *buf;
 }
Index: trunk/MagicSoft/Cosy/videodev/Writer.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Writer.h	(revision 807)
+++ trunk/MagicSoft/Cosy/videodev/Writer.h	(revision 808)
@@ -3,4 +3,6 @@
 
 #include <sys/time.h>
+
+typedef unsigned char byte;
 
 class Writer;
@@ -10,6 +12,6 @@
 public:
 
-    static void Ppm(const char *fname, const char *img);
-    static void Png(const char *fname, const char *buf, struct timeval *date);
+    static void Ppm(const char *fname, const byte *img);
+    static void Png(const char *fname, const byte *buf, struct timeval *date);
 };
 
