#pragma message ( "including seq.cc" );
/*****************************************************************************/
/*                                                                           */
/*   Function    : fVectrexEmulate()                                         */
/*                                                                           */
/*   Author      : K.W / C.S.                                                */
/*                                                                           */
/*   Description : This function is the HEART of the emluator. It schedules  */
/*                 and executes all of the functions that make up the        */
/*                 Vectrex emulator. The system is run on an infinite loop   */
/*                 which is only broken if the tQuitFlag==T_TRUE, this is a    */
/*                 global variable and can be set by any module of the user  */
/*                 wants to quit or the error is serious enough. For each    */
/*                 loop the gGblSystemTick variable is incremented. Also     */
/*                 for each loop the tGbl????SystemTickCounters are decreme- */
/*                 nted and when one reaches zero tGbl????SystemTickTotal    */
/*                 is incremented and the f????Tick function is executed.    */
/*                                                                           */
/*                 The debug flags can disable the execution of any of the   */
/*                 tick functions in an individual basis. When the DEBUG     */
/*                 mode is activated the fDoDebug() is called on every       */
/*                 time tGblSystemTick in incrmented.                        */
/*                                                                           */
/*   Accepts     : nothing                                                   */
/*                                                                           */
/*   Returns     : T_TRUE or T_FALSE depending on if an error occured            */
/*                                                                           */
/*****************************************************************************/

{
 /* perhaps one should define limit as the length of the next instruction? */
 #define limit ((T_UWORD)(20))

/*
#ifdef DEBUG_MON
 if(bGblDebugMonitorEnable==T_TRUE)
  fDebugMonitor();
#endif
*/

#ifdef CLAY_ONLY
 SLONG grabticker=0;
#endif

#ifndef DEBUG_MSG

#ifdef SEQUENCER_LINEAR
 #ifdef SEQUENCER_LIGHTPEN
  fDebug(HIGH,("sequencer() - Linear + Lightpen used"));
 #else
  #ifdef SEQUENCER_IMAGER
   fDebug(HIGH,("sequencer() - Linear - Imager used"));
  #else
   fDebug(HIGH,("sequencer() - Linear used"));
  #endif
 #endif
#else
 #ifdef SEQUENCER_LIGHTPEN
  fDebug(HIGH,("sequencer() - Banked + Lightpen used"));
 #else
  #ifdef SEQUENCER_IMAGER
   fDebug(HIGH,("sequencer() - Banked - Imager used"));
  #else
   fDebug(HIGH,("sequencer() - Banked used"));
  #endif
 #endif
#endif

#endif


#ifndef DEBUG_MSG
 firstrun();
 InitTimerHandler();
 while(wGblQuitFlag==EMU_RUN)
#endif
 /****************************/
 /* Start the sequencer loop */
 /****************************/
 {
#if defined SEQUENCER_LIGHTPEN

  /***********************************************************/
  /* Mouse shit... can't do it in the interrupthandler, why? */
  /***********************************************************/
#ifndef DEBUG_MSG
  if (vesa_mouse_changed==T_TRUE)
  {
   vesa_mouse_update();
  }
#endif
  /**********************************************/
  /* if lightpen is active, do a FULL emulation */
  /**********************************************/
  if ((t6522IER&0x02)&&(vesa_mouse_button))
  {
   fAnalogTick();
   #define PIA_TIMER1
   #define PIA_TIMER2
   #define PIA_SHIFT
   #define SEQUENCER_ANALOG_CYCLE_PATCH
   /******************************************************************/
   /* one could optimize this to multi ticks as well... but it's not */
   /* worth the trouble                                              */
   /******************************************************************/
   #include "pia.cc"

   #undef PIA_TIMER1
   #undef PIA_TIMER2
   #undef PIA_SHIFT
   #undef SEQUENCER_ANALOG_CYCLE_PATCH

   #include "singlcpu.cc"
   lwGblSystemTickTotal++;
  }
  else
#endif

#if defined CLAY_ONLY && !defined SEQUENCER_LIGHTPEN
  if (cscreenshots==T_TRUE)
  {
   fAnalogTick();
   #define PIA_TIMER1
   #define PIA_TIMER2
   #define PIA_SHIFT
   #define SEQUENCER_ANALOG_CYCLE_PATCH
   #include "pia.cc"

   #undef PIA_TIMER1
   #undef PIA_TIMER2
   #undef PIA_SHIFT
   #undef SEQUENCER_ANALOG_CYCLE_PATCH

   #include "singlcpu.cc"
   lwGblSystemTickTotal++;
   grabticker--;
  }
  else
#endif
  if (bGblForceSingleProcessor==T_TRUE)
  {
   fAnalogTick();
   #define PIA_TIMER1
   #define PIA_TIMER2
   #define PIA_SHIFT
   #define SEQUENCER_ANALOG_CYCLE_PATCH
   #include "pia.cc"

   #undef PIA_TIMER1
   #undef PIA_TIMER2
   #undef PIA_SHIFT
   #undef SEQUENCER_ANALOG_CYCLE_PATCH

   #include "singlcpu.cc"
   lwGblSystemTickTotal++;
  }
  else
  /*****************************/
  /* look at the readme.txt... */
  /*****************************/
  if (((T_UWORD)((T_UWORD)(u6522Timer1.uCount.tW)+(T_UWORD)1)>(T_UWORD)limit+1)
  && ((u6522Timer2.uCount.tW)>limit+1)
#ifdef SEQUENCER_IMAGER
&&
(/*(bGblGoggleGame==T_TRUE)&&*/
(((T_ULONG)(counter_since_change-lwGblSystemTickTotal))>(T_ULONG)limit+1)&&
(((T_ULONG)(new_ticks-lwGblSystemTickTotal))>(T_ULONG)limit+1))
&&(!tsCPURegisters.tIRQFlag)

#endif

#ifdef ANALOG_CYCLE_PATCH
&& (patch_must_be_applied==0)
#endif


  )
  {
   if ( (!t6522SHFTREGACT) )
   {
    if (i6809status!=CPU_FETCH)
    {
    /*******************/
    /* NO PIA ACTIVITY */
    /*******************/
    #include "multicpu.cc"
    }
    else
    {
     #include "jfctgcpu.cc"
    }
   }
   else
   {
    /******************************/
    /* PIA JUST SHIFTING ACTIVITY */
    /******************************/
    #include "mshftcpu.cc"
   }
  }
  else
  {
   /*********************/
   /* PIA FULL ACTIVITY */
   /*********************/
   do
   {
    #include "msnglcpu.cc"
   }
   while (t1int==T_TRUE);
  }
#ifdef SEQUENCER_IMAGER
  if (lwGblSystemTickTotal>new_ticks)
  {
   static T_UINT imager_value_old=0;
   state=(state+1)%2;
   if (state==0)
   {
    t6522CA1=1; // muesste hier gesetzt werden und im 6522 abgefragt werden!
    t6522IFLG|=E6522IFLG_CA1;
    if (t6522IER&E6522IFLG_CA1)
     tsCPURegisters.tIRQFlag=T_TRUE;
    t6522IRA&=(255-128);
    tKeyWord&=(255-128);    // for psgwin only
    if (imager_value_old!=imager_pulse_ticks)
    {
     T_ULONG ltmp_all=wGblColor1Degrees+wGblColor2Degrees+wGblColor3Degrees;
     imager_value_old=imager_pulse_ticks;
     lwGblWheelTicks=imager_values[imager_pulse_ticks%1000];
     wGblColor1Degrees = (lwGblWheelTicks*wGblColor1Degrees)/ltmp_all;
     wGblColor2Degrees = (lwGblWheelTicks*wGblColor2Degrees)/ltmp_all;
     wGblColor3Degrees = (lwGblWheelTicks*wGblColor3Degrees)/ltmp_all;
     if (lwGblWheelTicks!=(wGblColor1Degrees+wGblColor2Degrees+wGblColor3Degrees))
     {
      wGblColor1Degrees+=lwGblWheelTicks-(wGblColor1Degrees+wGblColor2Degrees+wGblColor3Degrees);
     }
    }
   } //if (state==0)
   new_ticks=lwGblSystemTickTotal+lwGblWheelTicks;

   counter_since_change=lwGblSystemTickTotal-1; //neu
   wheel_color_rotator=0;

  } //if (lwGblSystemTickTotal>new_ticks)
  if (lwGblSystemTickTotal>counter_since_change)
  {
   switch (wGblImagerMode)
   {
//# 0 links einfarbig  \ eigene overlays moeglich
//# 1 rechts einfarbig /
//# 2 rot blau
//# 3 links farbig
//# 4 rechts farbig
//# 5 farbig (chaos)
//# 6 links links, rechts rechts farbig
    case 0: // einfarbig rechts
    {
     counter_since_change=lwGblSystemTickTotal+lwGblWheelTicks;
     if (state==1)
     {
      ImagerColorNow=IMAGER_DRAW_OVERLAY;
     }
     else
     {
      ImagerColorNow=IMAGER_DRAW_NOTHING;
     }
     break;
    }
    case 1: // einfarbig links
    {
     counter_since_change=lwGblSystemTickTotal+lwGblWheelTicks;
     if (state==1)
     {
      ImagerColorNow=IMAGER_DRAW_NOTHING;
     }
     else
     {
      ImagerColorNow=IMAGER_DRAW_OVERLAY;
     }
     break;
    }
    case 2: // rot blau
    {
     counter_since_change=lwGblSystemTickTotal+lwGblWheelTicks;
     if (state==1)
     {
      ImagerColorNow=IMAGER_DRAW_COLOR_13;
     }
     else
     {
      ImagerColorNow=IMAGER_DRAW_COLOR_12;
     }
     break;
    }
    case 3: //mehrfarbig rechts
    {
     if (state==0)
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     else
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     break;
    }
    case 4: //mehrfarbig links
    {
     if (state==1)
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     else
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_NOTHING;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     break;
    }
    case 5: //mehrfarbig chaos
    {
     if (state==0)
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     else
     {
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     break;
    }
    case 6: //mehrfarbig links rechts
    {
     if (state==0)
     {
      wGblImagerXOffset=wGblImagerXOffset1;
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     else
     {
      wGblImagerXOffset=wGblImagerXOffset2;
      if (wheel_color_rotator==0)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_1;
       counter_since_change=lwGblSystemTickTotal+wGblColor1Degrees;
      }
      else if (wheel_color_rotator==1)
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_2;
       counter_since_change=lwGblSystemTickTotal+wGblColor2Degrees;
      }
      else
      {
       ImagerColorNow=IMAGER_DRAW_WHEEL_COLOR_3;
       counter_since_change=lwGblSystemTickTotal+wGblColor3Degrees;
       new_ticks=lwGblSystemTickTotal+wGblColor3Degrees; // for syncronization
      }
      wheel_color_rotator=(wheel_color_rotator+1)%3;
     }
     break;
    }
   }
  }
#endif
  /***********************************/
  /* Emulate the monitor persistance */
  /***********************************/
  if (lwGblSystemTickTotal>lwGblDisplayTickCounter)
  {
   lwGblDisplayTickCounter=lwGblSystemTickTotal+lwGblDisplayTickReload;
   if (bGblDisplayEnable)
   {
//    fDisplayTick();
    #ifdef SEQUENCER_IMAGER
    #define DISPLAY_TICK_IMAGER
    #endif

    #ifdef SEQUENCER_LINEAR
    #define DISPLAY_TICK_LINEAR
    #endif

    #ifdef SEQUENCER_BANKED
    #define DISPLAY_TICK_BANKED
    #endif

    #include "dtick.cc"

    #ifdef SEQUENCER_BANKED
    #undef DISPLAY_TICK_BANKED
    #endif

    #ifdef SEQUENCER_LINEAR
    #undef DISPLAY_TICK_LINEAR
    #endif

    #ifdef SEQUENCER_IMAGER
    #undef DISPLAY_TICK_IMAGER
    #endif

   }
  }
  /****************************************/
  /* Use ... for speed regulator checking */
  /****************************************/
  if (lwGblSystemTickTotal>tick_timeout)
  {
#ifndef DEBUG_MSG
   if (!tTicker--)
   {
    tTicker=KBD_WAIT;
    if (KBDKeyPressed)
    {
     fKBDdokey();
    }
   }
#endif
   while (last_timer_tick==timer_tick)
   {
    /****************************************************/
    /* Pause until timer rollover, check for timeout ?? */
    /****************************************************/
    ;
   }
   last_timer_tick=timer_tick;
   tick_timeout=lwGblSystemTickTotal+lwGblMaxTicks;
  }
#ifdef CLAY_ONLY
  /****************************************/
  /* Use ... for speed regulator checking */
  /****************************************/
  if (cscreenshots==T_TRUE)
  if (grabticker<=0)
  {
   grabticker=lwGblTicksToGrab;
   fIOPrintf(0,0,31,0,1,"      ");
   fIOPrintf(0,20,31,0,1,"        ");
   fIOpcx_write_256pic();
   fIOPrintf(0,0,31,0,1,"Grabs:");
   fIOPrintf(0,20,31,0,1,"%08i",cgrabsdone);
   cgrabsdone++;
  }
#endif
  /*****************************************************************/
  /* Because the interrupt driver keyboard handler doesnt yet      */
  /* exist we must use fIODoKey to poll the keyboard once per loop */
  /* Only do this every 65536 sequence loops as this is a very     */
  /* slow process until I write my own driver                      */
  /*****************************************************************/
/*
#ifdef DEBUG_MSG
  if (KBDKeyPressed)
   fKBDdokey();
#endif
*/
  /****************************************/
  /* Special debugging code for DP sanity */
  /****************************************/
//     if(tsCPURegisters.tDP!=0 && tsCPURegisters.tDP!=0xc8 && tsCPURegisters.tDP!=0xd0)
//     {
//         fFatal("fVectrexEmulate() - Last<%04x> Now<%04x>",iLastAddress,tsCPURegisters.tPC);
//         bGblDebugMonitorEnable=T_TRUE;
//     }
  /*****************************************/
  /* Execute the Debug function if enabled */
  /*****************************************/

/*
#ifdef DEBUG_MON
  if (bGblDebugMonitorEnable)
  {
   bGblStatsValid=T_FALSE;
   fIOSetClipping(-1,-1,-1,-1);
   fSoundMute();
   fKBDbuffering(T_TRUE);
   fDebugMonitor();
   fKBDbuffering(T_FALSE);
   fSoundResume();
  }
#endif
*/
 }
#ifndef DEBUG_MSG
 DoneTimerHandler();
#endif
}
