#include "OCCAM2C.LNT"
#define   OCCAM2C_LNT_RESTORE_F
/*{{{  File banner*/
/***********************************************************
 *  Project : GPMIMD ESPRIT P5404
 *  Authors : Mark Debbage, Mark Hill and Sean Wykes
 *            University of Southampton
 *
 *    Title : Prototype Source File for generated C
 *   System : Occam 2 C
 * Filename : Occam2C.c
 *  Version : 1.4
 *     Date : 1/31/94
 **********************************************************/
/*}}}  */
/*{{{  Header*/
/******************************************************************************
 * File name          : Occam2c.c
 * Owner              : OyT
 * Module Description : SPOC template file
 * Document name(s)   :
 * Main project name  : RIFT/GL-100 (800620UN)
 * Sub  project name  : DSP CPU S.W (800821UN)
 *
 * Copyright Autronica AS 1996-97
 * 7005 TRONDHEIM, NORWAY
 *
 * Ver. yy-mm-dd Author Approved Description
 * ---- -------- ------ -------- ----------------------------------------------
 * 0.01                          See banner above
 * 1.24 20Aug98  OyT             lint-ed
 * 1.24 02Dec98  OyT             GLKDSP=1044: SETERR involves no lineNo and fileName
 ******************************************************************************/
/*}}}  */
/*{{{  Things removed or added by Teig*/
/*
   CALL_NAG_F90
   USE_SPOC_ISERVER
   USE_NONBLOCKING_SOCKETS
   GENPROTO (Inserted again 25.Feb.1997)
   LIBRARY_UNIT (Inserted again 25.Feb.1997)
   signal.h
   sys/time.h
   USESIGTIMER
   NO_INT64
   NO_REAL64
   OCCAM_MAIN
   __GNUC__
   main(void) instead of main(....)
   DEFAULT_MEMSIZE_IN_INTS removed
   << PARAMETERS >> field removed
   SocketEvent:
     // static int SocketEvent = false;
     // while(CURTASK != NoTask || TimerEvent || SocketEvent)
   SHOWTASKING test, it was not defined
   TIMER is not zeroed at power-up
   "#ifndef NO_DEBUG" annd all code within have been removed
   For analysis of system behaviour in emulator:
     idle_ms, idle_max_ms, timer_int_tick added
     Reset_idle_max_ms added
   survivalFromLastRun added
   "DINT1" DMA1 interrupt handled (17Apr98)
   PC-lint done (Aug98)
*/
/*}}}  */
/*{{{  Insert SWITCHES*/
<<SWITCHES>>
// occ2c SoftwDes.occ -mn -d
// Here are these switches, clipped from a generated C-file:
// #define BYTES_PER_WORD 4
// #define TERMINATE_ON_ERROR
// #define CHECK_CONVERSIONS
// #define CHECK_ARRAYS
// #define CHECK_RANGES
// #define NO_DEBUG
// #define FASTGOTOS
// #define SOURCE LITTLE
// To remove lint e750 "local macro not referenced":
#ifdef BYTES_PER_WORD
#endif
#ifdef TERMINATE_ON_ERROR
#endif
#ifdef CHECK_CONVERSIONS
#endif
#ifdef CHECK_ARRAYS
#endif
#ifdef CHECK_RANGES
#endif
#ifdef NO_DEBUG
#endif
#ifdef FASTGOTOS
#endif
#ifdef SOURCE
#endif
/*}}}  */
/*{{{  defines*/
#define BITS_PER_WORD (BYTES_PER_WORD * 8) // 32 Teig
#define FAST_SHIFTS // To avoid side-effect warning 666 from PC-lint
// #define DEBUG_COUNT_PROCESS_SCHEDULES // Teig
/*}}}  */
/*{{{  includes*/
#ifdef GENPROTO
// makedep doesn't understand the ifdef!
// #include <stdio.h>
#endif
#include "Occam2C.h"
#include "C_RefOcc.inc" // Teig
/*}}}  */
/*{{{  Insert data struct tree*/
/*lint -save -e793 ANSI limit of 127 'structure members' exceeded processing is unaffected */
/*lint ++flb       Force it to be considereded as a library, so that "local structure member not referenced" (754)
		   is suppressed during module wrap-up */
<<HEADER>>
//
/*lint --flb    */
/*lint -restore */
/*}}}  */
/*{{{  statics*/
#if (defined GENPROTO) || !(defined LIBRARY_UNIT)
/*{{{  statics for GLK-100*/
	jmp_buf STOPP_env;
	tTask  *QFP[NUM_PRIORITY_LEVELS];
	tTask  *QBP[NUM_PRIORITY_LEVELS];
	tTask  *CURTASK;
	tTask  *QTM;
	tTimer  TIMER;
static  int     TimerEvent = false;
// DMA Interrupt 1 at interrupt vector EA+012 handling:
static tTask  *DINT1TASK = NoTask;  // Teig
static int     DINT1Event = false;  // Teig
static CHAN   *DINT1EventChannel;   // Teig Same name in "O_RawDri.inc"
// The Texas emulator won't see these values if we don't initialize them:
static int idle_ms = 0;             // Teig
static int idle_max_ms = 0;         // Teig
static int timer_int_tick = false;  // Teig
static int survivalFromLastRun = 0; // Teig
#define NUM_BREAKPOINT (27 + 1) // 1 extra for "default" // Teig
static  int breakpointCnt[NUM_BREAKPOINT] = {0}; // Teig
#define DUAL_PORT_SURVIVAL_TO_LON (int *) 0x810080 // 0x8080 on Lon (See "DualPort.c")
// Pointer to a single byte in dual-port, situated in righmost byte of int32:
static int *survivalToDualPort_ptr = DUAL_PORT_SURVIVAL_TO_LON;
// Nice for debugger, and we don't have to "read,bitor,write" with dual-port, only "write":
static int  survivalToDualPort_copy = 0;
#define TOP_OF_STACK_TST_VALUE (int)0xf0e1d2c3 // Something unique!
static int *topOfStackPtr = 0;
static int schedCnt = 0; // ifdef DEBUG_COUNT_PROCESS_SCHEDULES
/*}}}  */
#endif
#ifdef GENPROTO
/*{{{  seterr*/
void seterr(char *M,int L,char *F) {}
/*}}}  */
/*{{{  struct Prototypes*/
struct Prototypes
{
  char *Proto;
  char *Define;
  int Space;
};
/*}}}  */
/*{{{  static struct Prototypes Table[] =*/
static struct Prototypes Table[] =
{
<<PROTOTYPES>>
 {NULL,NULL,0}
} ;
/*}}}  */
/*{{{  int main(int argc, char**argv)*/
int main(int argc, char**argv)
{
  char *name;
  FILE *f;
  int fcnt;
  CheckPrimitiveSizes();
  if (argc<2)
  {
    name="<<NAME>>.hdr";
    f=fopen(name,"w");
  }
  else
  {
    name = argv[argc-1];
    if (name[0]=='-')
    {
      name = "stdout";
      f=stdout;
    }
    else
    {
      f=fopen(name,"w");
    }
  }
  fcnt=argc-1;
  if (f==NULL)
    { fprintf(stderr,"Fatal - could not open file %s\n",name);exit(-1); }
  else
  {
    int arg;
    int i;
    fprintf(f,"#ifndef __<<NAME>>_INCLUDES__\n");
    fprintf(f,"#define __<<NAME>>_INCLUDES__\n");
    for(arg = 1; arg < fcnt; ++arg)
    {
      FILE *fh = fopen(argv[arg],"r");
      if (fh == NULL) { fprintf(stderr,"Fatal - could not read file %s\n",name); exit(-1); }
      while(!feof(fh))
      {
	char line[256];
	if (fgets(line,256,fh) == NULL) break;
	if (line[0] == '#')
	  if (strncmp(line,"#define WS",10)!=0) continue;
	fputs(line,f);
      }
      fclose(fh);
    }      
    i = 0;
    while (Table[i].Proto!=NULL)
    {
      if (Table[i].Define != NULL)
      {
	fprintf(f,"typedef struct SF_%s tSF_%s;\n",Table[i].Define,Table[i].Define);
	fprintf(f,"#define WS_%s (%d)\n",Table[i].Define,Table[i].Space);
      }
      fprintf(f,"%s\n",Table[i].Proto);
      i++;
    }
    fprintf(f,"#endif\n");
    if (f!=stdout) fclose(f);
  }
  return(0);
}     
/*}}}  */
#endif
/*}}}  */
#ifndef LIBRARY_UNIT
/*{{{  Reset_idle_max_ms*/
static int Reset_idle_max_ms (void)
{
   int old;
   {
      old = idle_max_ms;
      idle_max_ms = 0;
      return (old);
   }
}
/*}}}  */
/*{{{  Set_survivalFromLastRun, Get_survivalFromLastRun*/
int Get_survivalFromLastRun (void)
{
   return (survivalFromLastRun);
}
void Set_survivalFromLastRun (const int SurvivalFromLastRun)
{
   survivalFromLastRun = SurvivalFromLastRun;
}
/*}}}  */
/*{{{  Set_survivalToDualPort, Set_survivalToDualPort_AndCopy*/
// Dual-port access without hardware semaphore Ping-Pong
// is acceptable under the following conditions:
//
// 1. No read/read conflict
//    We don't have any read/read situation at all
// 2. No write/read conflict
//    DSP writes when it wants to. The address is exclusive.
//    Lon-controller reads in the phase when it is holding DSP reset.
//    -> No conflict
void Set_survivalToDualPort (const int SurvivalToDualPort)
{
    // This procedure is used during a controlled shutdown
    // Right-most byte only:
    // We "bitor" with a copy instead of "read,bitor,write"
    // Dual-port access without hardware semaphore Ping-Pong:
    *survivalToDualPort_ptr = SurvivalToDualPort | survivalToDualPort_copy;
}
void Set_survivalToDualPort_AndCopy (const int SurvivalToDualPort_copy)
{
    // This procedure is used to leave _something_ in case of a _missing_ controlled shutdown,
    // followed by a reset initiated by the Lon-controller
    // Right-most byte only:
    // Dual-port access without hardware semaphore Ping-Pong:
    *survivalToDualPort_ptr = SurvivalToDualPort_copy;
    survivalToDualPort_copy = SurvivalToDualPort_copy;
}
/*}}}  */
/*{{{  c_int09 Timer interrupt*/
/*
 * OBSERVE: For linker to find the timer interrupt, name c_int09 MUST be used!
 */
// Texas wants us to do it wihout "extern", but this costs us
// lint filters (714  = not referenced) and (765 = could be made static)
// See "options.lnt",
//
// extern void
// c_int09 (void);
void
c_int09 (void) // If static, the linker will not see it!
{
   // This timer interrupt routine takes som 92-100 clock ticks.
   // With 1 ms (20 000 clock ticks) this is an overhead of some 0.5%
   TIMER = TIMER + 1;
   timer_int_tick = true; // Also used at power-up!
   if (QTM != NoTask && AFTER(TIMER,QTM->comms.timer.time))
   {
      TimerEvent = true;
   }
}
/*}}}  */
/*{{{  c_int12_signal_if - From DMA channel 1 interrupt*/
/*
 *  Called from "Ser_Port.c"
 *  Exported in "DINT1.h"
 */
void c_int12_signal_if (void)
{
   if (DINT1TASK != NoTask)
   {
      DINT1Event = true;
   }
}
/*}}}  */
/*{{{  BlinkAndLeaveOn*/
void BlinkAndLeaveOn (const int NoOfBlinks)
{
   int blinks;
   for (blinks = 0; blinks < NoOfBlinks; blinks++)
   {
      #define OneSecond 714000
      int cnt = 0;
      Write_DSP_LEDs (0x00);
      for (cnt = 0; cnt < OneSecond; cnt++) {}
      Write_DSP_LEDs (0x11);
      for (cnt = 0; cnt < OneSecond; cnt++) {}
   }
}
/*}}}  */
/*{{{  LON_Synch_Breakpoint etc.*/
//
//
// 1. Now press the GLK-100 push-button to reset
//    LON-controller.
// 2. Stare at the "SystemError" LED, and hit "F5"
//    when it goes off!
// PRECONDITION:
//    Both connections from reset-logic and Lon-controller
//    to DSP reset-pin must be broken!
void LON_Synch_Breakpoint (void)
{
}
//
//
// 1. You did not hit "F5" accurately enough
// 2. The LON-controller isn't working properly
// 3. The PRECONDITION above hasn't been met
// TRY:
//    Restart emulator and LON-controller again and
//    be more accurate (count to 4.5)!
void LON_Synch_Error_TryAgain (void)
{
}
/*}}}  */
/*{{{  Breakpoint*/
static void InitBreakpointCnt (void)
{
   int i;
   for (i=0; i < NUM_BREAKPOINT; i++)
   {
      breakpointCnt[i] = 0;
   }
   i = breakpointCnt[0]; // For lint, to avoid e551 on breakpointCnt
}
//
//
//  Be sure to set a breakpoint at BPException below!
//
void Breakpoint (const int BreakpointNo)
{
   switch (BreakpointNo)
   {
      case 0:
	 breakpointCnt[0]++;
	 break; // BpException
      case 1:
	 breakpointCnt[1]++;
	 break; // BpViewLastException
      case 2:
	 breakpointCnt[2]++;
	 break; // BpAny
      case 3:
	 breakpointCnt[3]++;
	 break; // BpSpecial
      case 4:
	 breakpointCnt[4]++;
	 break; // BpCMain
      case 5:
	 breakpointCnt[5]++;
	 break; // BpOccamTopLevel
      case 6:
	 breakpointCnt[6]++;
	 break; // BpDualPortDriver
      case 7:
	 breakpointCnt[7]++;
	 break; // BpDualPortComIn
      case 8:
	 breakpointCnt[8]++;
	 break; // BpDualPortComOut
      case 9:
	 breakpointCnt[9]++;
	 break; // BpDualPortEventIn
      case 10:
	 breakpointCnt[10]++;
	 break; // BpDualPortEventOut
      case 11:
	 breakpointCnt[11]++;
	 break; // BpInMergePackets
      case 12:
	 breakpointCnt[12]++;
	 break; // BpOutSplitToPackets
      case 13:
	 breakpointCnt[13]++;
	 break; // BpClientLogOn
      case 14:
	 breakpointCnt[14]++;
	 break; // BpMessageRouter
      case 15:
	 breakpointCnt[15]++;
	 break; // BpAlbumMonitor
      case 16:
	 breakpointCnt[16]++;
	 break; // BpCurveServer
      case 17:
	 breakpointCnt[17]++;
	 break; // BpFileServer
      case 18:
	 breakpointCnt[18]++;
	 break; // BpFileServerCmdInt
      case 19:
	 breakpointCnt[19]++;
	 break; // BpFlashDriver
      case 20:
	 breakpointCnt[20]++;
	 break; // BpAlarmServer
      case 21:
	 breakpointCnt[21]++;
	 break; // BpVolumeServer
      case 22:
	 breakpointCnt[22]++;
	 break; // BpUllCalc
      case 23:
	 breakpointCnt[23]++;
	 break; // BpRawDriver
      case 24:
	 breakpointCnt[24]++;
	 break; // BpEventRouter
      case 25:
	 breakpointCnt[25]++;
	 break; // BpCodeChecksum
      case 26:
	 breakpointCnt[26]++;
	 break; // BpAlbumErr
      default:
	 breakpointCnt[27]++;
	 SETERR (MSG_CASE);
   }
}
//
//
//
//
//
//
//
//
//
//
//
//
/*}}}  */
/*{{{  Error handling*/
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
static void DONE_SETERR (void) {}
void seterr (char *Message, int LineNo, char *FileName)
{
  int firstChar = (int) Message[0];
  Set_survivalToDualPort (firstChar);
  Breakpoint(0);
  BlinkAndLeaveOn(60);
  SETERR_PROCEED;
} /*lint !e715 FileName, LineNo (line _) not referenced */
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// GLKDSP=1044: seterr_ is new
void seterr_ (char *Message)
{
  seterr (Message,__LINE__,__FILE__); // Always h e r e
}
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
/*}}}  */
/*{{{  Init_Timer*/
static void Init_Timer (void)
{
  // TIMER = 0; // Teig: If we don't initialize it, we get random start-times!
  QTM = NoTask;
  TimerEvent = false;
}
/*}}}  */
/*{{{  Set_DINT1EventChannel*/
static void Set_DINT1EventChannel (CHAN *chan)
{
   DINT1EventChannel = chan;
   DINT1TASK = CURTASK;
}
/*}}}  */
/*{{{  Init_Scheduler*/
static void Init_Scheduler (void)
{
  int i;
  for(i = 0; i < NUM_PRIORITY_LEVELS; ++i)
     QFP[i] = (QBP[i] = NoTask);
  CURTASK = NoTask;
  Init_Timer();
}
/*}}}  */
/*{{{  Scheduler*/
static void Scheduler (void)
{
   if (setjmp(STOPP_env))
   {
      DeSchedule((tTaskMode) 0);
   }
   while(CURTASK != NoTask || TimerEvent || DINT1Event)
   {
      int pri;
      /*{{{  if (DINT1Event)*/
      if (DINT1Event)
      {
	 int data = 1;
	 if (ChanOut4_InterruptEvent (DINT1EventChannel, &data, DINT1TASK) == 1)
	 {
	    DINT1Event = false;
	    // If, for some reason ChanOut4_InterruptEvent fails to find a receiving task,
	    // let's just continue until it finds one. We do this by keeping DINT1Event true.
	    // This is perfectly sound, the receiving task may be processing some other
	    // request, or may have this guard disabled.
	 }
	 else
	 {
	    DINT1Event = true; // Just so that we have something to stop on in the debugger
	 }
      }
      /*}}}  */
      /*{{{  if (TimerEvent)*/
      // No "else if" here! We want to accept timeouts even if DINT1Event hasn't been cleared!
      if (TimerEvent)
      {
	 TimerEvent = false;
	 while(QTM != NoTask && AFTER(TIMER,QTM->comms.timer.time))
	 {
	    if (QTM->AltMode == Waiting_p) QTM->AltMode = TReady_p;
	    ReSchedule(QTM);
	 }
      }
      /*}}}  */
      for (pri = 0; pri < NUM_PRIORITY_LEVELS; ++pri)
      {
	 if ((CURTASK=QFP[pri]) != NoTask) // Assignemt of CURTASK is here!
	 {
	    // lint 534: Ignoring return value of
	    // lint 746: call to unidentified function not made in the presence of a prototype
	    // Next task is scheduled through this point
	    CURTASK->Func (CURTASK->FP); /*lint !e534 !e746 See above */
	    #ifdef DEBUG_COUNT_PROCESS_SCHEDULES
	      schedCnt++;
	    #endif
	    if (*topOfStackPtr != TOP_OF_STACK_TST_VALUE)
	    {
	      SETERR(MSG_STACK_OVERFLOW);
	    }
	    break;
	 }
      }
      /*{{{  Idle*/
      if (CURTASK == NoTask && QTM != NoTask)
      {
	 idle_ms = 0;
	 while((TimerEvent==0) && (DINT1Event==0))
	 {
	    // Teig
	    // Observe that timer interrupt latency is
	    // increased a little with this code:
	    Set_survivalToDualPort(1);
	    if (timer_int_tick == true)
	    {
	       idle_ms++;
	       timer_int_tick = false;
	       if (idle_ms > idle_max_ms)
	       {
		  idle_max_ms = idle_ms;
	       }
	    }
	 }
      }
      /*}}}  */
   }
   SETERR(MSG_TA); /* Teig */
}
/*}}}  */
/*{{{  Start_Process*/
void Start_Process(register tTask *task, register tFuncPtr Func, register void *FP, register char *name,int Priority)
{
   static int NextTaskId = 0;
   task->FP = FP;
   task->Func = Func;
   task->state = EXEC_p;
   task->name = name;
   task->Parent = CURTASK;
   task->Children = 0;
   task->Next = NoTask;
   task->AltMode = NotAlting_p;
   task->TaskId = NextTaskId++;
   // (INT) decoration to avoid lint -e641 Converting enum to int
   task->TaskPriority = (CURTASK != NoTask && CURTASK->TaskPriority == (INT)HighPriority) ? (INT)HighPriority : Priority;
   ((tHeader *)FP)->ProcName = name;
   if (Priority < 0 || Priority >= NUM_PRIORITY_LEVELS) SETERR(MSG_PRI);
   if (QFP[task->TaskPriority])
      QBP[task->TaskPriority]->Next = task;
   else
      QFP[task->TaskPriority] = task;
   QBP[task->TaskPriority] = task;
   if (CURTASK != NoTask) CURTASK->Children++;
   else CURTASK = task;
}
/*}}}  */
/*{{{  int main (void)*/
//
//
// 1. Now press "F5" and wait 5 seconds for LON synch. point.
int main (void)
{
   void *FP = NULL;
   tTask main_t;
   const uint32_a NoOfInt32s = sizeof(tSF_<<MAIN>>);
   uint32_a       missing;
   unsigned int   stackStart, stackSize;
   bool_a         ramTstErr;
   int            testTimerNow;
   {
      tSF_<<MAIN>> *MAINFP=(tSF_<<MAIN>> *)Malloc32(NoOfInt32s, &missing);
      // --------------------------------------------------------------------
      // File "occam2c.lnt" must be used, else lint will complain:
      // We must use it for an already existing value:
      testTimerNow = OCCAM2C_LNT_USED_AVOID_e766_F;
      // --------------------------------------------------------------------
      // Problems with "restart" in debugger and timer:
      testTimerNow = 1;
      // Set it to zero instead if you want to avoid Timer test Seterr
      // --------------------------------------------------------------------
      /*{{{  External ram test*/
      if (RamTstUsage_ms() == TRUE) /*lint !e641 Converting enum to int */
      {
	 // Don't do it if running in emulator!
	 ramTstErr = FALSE; // OK until otherwise proven
	 ramTstErr = X0_RamTstErr (ramTstErr);
	 ramTstErr = X1_RamTstErr (ramTstErr);
	 ramTstErr =  Y_RamTstErr (ramTstErr);
	 if (ramTstErr == TRUE)
	 {
	    // was s e t e r r (MSG_EXRAM_ERR,__LINE__,__FILE__);
	    SETERR (MSG_EXRAM_ERR);
	 }
      }
      /*}}}  */
      /*{{{  Initialize stack test value*/
      stackStart = Get_StackStart();
      stackSize  = Get_StackSize(); // Referenced to SP in c_int00
      //   Margin                                          0x100
      // + In main (here) stack has grown since c_int00 by 0x01c
      // - Growth of stack in Get_StackStart is            0x002
      // -------------------------------------------------------
      // = SubtractBy                                      0x11a
      // =======================================================
      stackSize = stackSize - 0x11a;
      topOfStackPtr  = (int *)(stackStart + stackSize);
      *topOfStackPtr = TOP_OF_STACK_TST_VALUE;
      /*}}}  */
      Set_survivalToDualPort_AndCopy(0);
      InitBreakpointCnt();
      InitBusStrobes(); // In "cpureg.c"
      /*{{{  malloc error handling*/
      if (MAINFP==NULL)
      {
	 // was s e t e r r (MSG_MALLOC,__LINE__,__FILE__);
	 SETERR (MSG_MALLOC);
	 /* fprintf(stderr,"Error - Malloc of %s bytes for occam workspace failed\n",sizeof(tSF_<<MAIN>>)); */
      }
      /*}}}  */
      CheckPrimitiveSizes(); // In occam2c.h
      /*{{{  Start and check timer interrupt*/
      {
	 if (CodeIsRunningInRam() == 1) // In "RamTst.c"
	 {
	    // We need to do this for programs booted to external RAM via booting mechanism:
	    ReallocateVectors(); // In "cpureg.c"
	 }
      }
      {
	 int cnt;
	 const INT OccamHighAndLowPriTime_1000uS = 1000; // 1mS
	 InitTimer0Int(OccamHighAndLowPriTime_1000uS);   // In "cpureg.c"
	 if (testTimerNow == 1)
	 {
	    /*{{{  Test timer*/
	    //---------------------------------------------------------------------------
	    #define o0 // o2 or o0                                                     //
										       //
	    #ifdef o2 // Rather: non-specified "o"-option, is it "o2"?                 //
	    #define cnt1 400                                                           //
	    #define cnt2 171                                                           //
	    #endif                                                                     //
										       //
	    #ifdef o0                                                                  //
	    #define cnt1 800                                                           //
	    #define cnt2 500                                                           //
	    #endif                                                                     //
										       //
	    // Question to you: is optimalization in debug and flash versions alike?   //
	    // They must be! (See m_gl100.mak)                                         //
										       //
	    // Unspecified compiler optimalization level (=o2?)  ********              //
	    // Compiler optimalization level (=o0)                         ********    //
	    // ---------- Accumulated time: --------------------     0 us              //
	    for (cnt = 0; cnt < cnt1; cnt++) {} // -------------                       //
	    // ---------- Accumulated time: --------------------   767 us              //
	    if (timer_int_tick != false)                                               //
	    {                                                                          //
	       // Observe that compiler optimalization level will                      //
	       // affect this measurement!                                             //
	       // was s e t e r r (MSG_TIMER,__LINE__,__FILE__);                       //
	       SETERR (MSG_TIMER);                   // Too fast!                      //
	       // Set testTimerNow to 0 first in "main" if you want to avoid it!       //
	    }                                                                          //
	    // ---------- Accumulated time: --------------------   768 us              //
	    for (cnt = 0; cnt < cnt2; cnt++) {} // --------------                      //
	    // ---------- Accumulated time: --------------------  1100 ms   1080 ms    //
	    if (timer_int_tick == false)                                               //
	    {                                                                          //
	       // Observe that compiler optimalization level will                      //
	       // affect this measurement!                                             //
	       // was s e t e r r (MSG_TIMER,__LINE__,__FILE__);                       //
	       SETERR (MSG_TIMER);                   // Too slow!                      //
	       // Set testTimerNow to 0 first in "main" if you want to avoid it!       //
	    }                                                                          //
	    //--------------------------------------------------------------------------
	    /*}}}  */
	 }
      }
      /*}}}  */
      Init_Scheduler();
      STARTP(&main_t,<<MAIN>>,MAINFP,"<<MAIN>>",(INT)LowPriority);
      Scheduler();
      return 0;
   }
}
/*}}}  */
#endif
#ifndef GENPROTO
/*{{{  Insert DEBUG*/
<<DEBUG>>
/*}}}  */
/*{{{  Insert CODE*/
<<CODE>>
/*}}}  */
#endif
#include "OCCAM2C.LNT" // To catch restore's