#ifdef ANTI_ALIASING
#define EMU_FULL_ANALOG 1
#endif
#pragma message ( "including anatick.cc" );
 /*****************************************************************************/
/*                                                                           */
/*   Function    : fAnalogTick()                                             */
/*                                                                           */
/*   Author      : K.W                                                       */
/*                                                                           */
/*   Description : This function emulates the analog functions of the        */
/*                 vectrex. These functions produce the X,Y,Z deflection     */
/*                 signals for the CRT and the COMPARE signal for the        */
/*                 jostick AtoD system. The registers and values it needs    */
/*                 are taken from the 6522A Port A and B registers. The      */
/*                 value on port A is used as the DAC value an port B        */
/*                 is used for a number of the control lines that drive      */
/*                 the block such as SW,SEL0,SEL1,RAMP,BLANK.                */
/*                                                                           */
/*   Accepts     : WORD tNoOfTicks, the number of unit cycles to run         */
/*                                                                           */
/*   Returns     : nothing                                                   */
/*                                                                           */
/*****************************************************************************/
//void fAnalogTick(void)
{
 static T_SLONG lX2;
 static T_SLONG lY2;
 static T_SCHAR lXSampleHold_last=0;
 static T_SCHAR lYSampleHold_last=0;
#ifdef EMU_FULL_ANALOG
 static T_LONG drift_ticks=0;
 static T_LONG dac_offset_ticks=0;
 static T_LONG intensity_drift=0;
#endif
 T_WORD draw_now=T_FALSE;


 fDebug(LOW,("fAnalogTick() - Processing analog event"));
 lwTickMark=lwGblSystemTickTotal-lwTickMark;
 if (tSIGDEF_ZEROB)
 {
  if (!tLastRamp)
  {
   lSIGDEF_XOUTPUT=lSIGDEF_XOUTPUT+lXSampleHold*lwTickMark;
   lSIGDEF_YOUTPUT=lSIGDEF_YOUTPUT+lYSampleHold*lwTickMark;
  }
 }
 else
 {
#ifdef EMU_FULL_ANALOG
  drift_ticks=0;
  dac_offset_ticks=lwGblSystemTickTotal;
#endif
  // software integrator offsets
  lSIGDEF_XOUTPUT=(((T_SLONG)tIntegratorOffset)<<14)>>7;
  lSIGDEF_YOUTPUT=(((T_SLONG)tIntegratorOffset)<<14)>>7;
#ifdef EMU_FULL_ANALOG
  lSIGDEF_XOUTPUT+=wGblXIntegrator;
  lSIGDEF_YOUTPUT+=wGblYIntegrator;
  lSIGDEF_XOUTPUT+=integrator_offset_x;
  lSIGDEF_YOUTPUT+=integrator_offset_y;
#endif
 }
#ifdef EMU_FULL_ANALOG
 // this emulates hardware deficiencies
 // the drift values are in optimal state both 0
 drift_ticks+=lwTickMark;
 if (drift_ticks>20)
 {
  while (drift_ticks>0)
  {
   lSIGDEF_XOUTPUT+=wGblXDrift;
   lSIGDEF_YOUTPUT+=wGblYDrift;
   drift_ticks-=20;
  }
 }
#endif

 lwTickMark=lwGblSystemTickTotal;
 /*********************************/
 /* Emulate zero/ramping circuits */
 /*********************************/
 /*****************************/
 /* Emulate blanking circuits */
 /*****************************/
 if (tSIGDEF_BLANKB) /* ZOUTPUT on */
 {
  tSIGDEF_ZOUTPUT=tZSampleHold;
  /***************************/
  /* PEN just 'switched' on? */
  /***************************/
  if (tOldBlank!=tSIGDEF_BLANKB)
  {
   lX1=lSIGDEF_XOUTPUT;
   lY1=lSIGDEF_YOUTPUT;
#ifdef EMU_FULL_ANALOG
   drift_ticks=0;
   lX1+=(dac_offset*((T_SLONG)lwGblSystemTickTotal-dac_offset_ticks)*5/100);
   lY1+=(dac_offset*((T_SLONG)lwGblSystemTickTotal-dac_offset_ticks)*5/100);
   lSIGDEF_XOUTPUT=lX1;
   lSIGDEF_YOUTPUT=lY1;
   dac_offset_ticks=lwGblSystemTickTotal;
#endif
   tBright=tSIGDEF_ZOUTPUT;
   tOldBlank=tSIGDEF_BLANKB;
  }
  else
  {
   if (tOldBlank)
   {
    if ((lXSampleHold_last!=lXSampleHold)||(lYSampleHold_last!=lYSampleHold))
    {
     draw_now=T_TRUE;
    }
#ifdef LIGHTPEN
    /*******************************************************/
    /* 'drawing' right now, might check for ramp==1 too... */
    /*******************************************************/
    if (vesa_mouse_button)
    {
     if (((labs(lSIGDEF_XOUTPUT-vmouse_x)<0x100)&&(labs(lSIGDEF_YOUTPUT-vmouse_y)<0x100)))
     {
      fDebug(HIGH,("fAnalogTick() - Correct Lightpen position reached PC=<%04x>",tsCPURegisters.tPC));
      /*********************/
      /* set bit 2 on d00d */
      /*********************/
      t6522IFLG|=E6522IFLG_CA1;
      if ((t6522IER&0x02)&& !tsCPURegisters.uCC.sCC.bI)
      {
       fDebug(HIGH,("f6522Tick() - IRQ asserted by 6522 CA1 Reg at PC=<%04x>",tsCPURegisters.tPC));
       tsCPURegisters.tIRQFlag=T_TRUE;
      }
     }
    }
#endif
   }
  }
  lXSampleHold_last=lXSampleHold;
  lYSampleHold_last=lYSampleHold;
 }
 else /* ZOUTPUT off */
 {
  tSIGDEF_ZOUTPUT=0;
  /*******************************************************************/
  /* Check for a vector draw completion and signal it to the display */
  /*******************************************************************/
  if (tOldBlank!=tSIGDEF_BLANKB)//||((tSIGDEF_RAMPB)&&(tSIGDEF_RAMPB!=tLastRamp)))
  {
//    fDisplayLineDraw(lX1,lY1,lSIGDEF_XOUTPUT,lSIGDEF_YOUTPUT,tBright);
   tOldBlank=tSIGDEF_BLANKB;
   draw_now=T_TRUE;
  }
 }
 if (draw_now==T_TRUE)
 {
  lX2=lSIGDEF_XOUTPUT;
  lY2=lSIGDEF_YOUTPUT;

#ifdef EMU_FULL_ANALOG
  drift_ticks=0;
  lX2+=(dac_offset*((T_SLONG)lwGblSystemTickTotal-dac_offset_ticks)*5/100);
  lY2+=(dac_offset*((T_SLONG)lwGblSystemTickTotal-dac_offset_ticks)*5/100);
  lSIGDEF_XOUTPUT=lX2;
  lSIGDEF_YOUTPUT=lY2;
  dac_offset_ticks=lwGblSystemTickTotal;

  while (lwGblSystemTickTotal-intensity_drift>4500000)
  {
   if (tZSampleHold)
    tZSampleHold--;
   intensity_drift+=4500000;
  }



#endif

#ifdef ANALOG_IMAGER
 #define DISPLAY_TICK_IMAGER
  if (wGblImagerMode==6)
  {
   lX1+=wGblImagerXOffset;
   lX2+=wGblImagerXOffset;
  }
#define MAX_X (22000+wGblImagerXOffset)
#define MIN_X (-22000+wGblImagerXOffset)
#define MAX_Y (22000)
#define MIN_Y (-22000)
#else

#define MAX_X (22000)
#define MIN_X (-22000)
#define MAX_Y (22000)
#define MIN_Y (-22000)

#endif


if (lX1>MAX_X)
{
 if (lX2>MAX_X)
  goto n_t_d;
 if (lY1>MAX_Y)
 {
  if (lY2>MAX_Y)
   goto n_t_d;
  if (lY1-MAX_Y>lX1-MAX_X)
  {
   // y
   lX1-=(lY1-MAX_Y)*(lX1-lX2)/(lY1-lY2);
   lY1=MAX_Y;
  }
  else
  { // x
   lY1-=(lX1-MAX_X)*(lY1-lY2)/(lX1-lX2);
   lX1=MAX_X;
  }
 }
 else if (lY1<MIN_Y)// if (lY1>MAX_Y)
 {
  if (lY2<MIN_Y)
   goto n_t_d;
  if (MIN_Y-lY1>lX1-MAX_X)
  {
   // y
   lX1-=(MIN_Y-lY1)*(lX1-lX2)/(lY2-lY1);
   lY1=MIN_Y;
  }
  else
  { // x
   lY1+=(MAX_X-lX1)*(lY2-lY1)/(lX1-lX2);
   lX1=MAX_X;
  }
 }
 else // if (lY1<MIN_Y)// if (lY1>MAX_Y)
 { // x
  if (lY1<lY2)
   lY1+=(MAX_X-lX1)*(lY2-lY1)/(lX1-lX2);
  else
   lY1-=(MAX_X-lX1)*(lY1-lY2)/(lX1-lX2);
  lX1=MAX_X;
 }
} // if (lX1>MAX_X)
else if (lX1<MIN_X) // if (lX1>MAX_X)
{
 if (lX2<MIN_X)
  goto n_t_d;
 if (lY1>MAX_Y)
 {
  if (lY2>MAX_Y)
   goto n_t_d;
  if (lY1-MAX_Y>MIN_X-lX1)
  {
   // y
   lX1+=(lY1-MAX_Y)*(lX2-lX1)/(lY1-lY2);
   lY1=MAX_Y;
  }
  else
  { // x
   lY1-=(MIN_X-lX1)*(lY1-lY2)/(lX2-lX1);
   lX1=MIN_X;
  }
 }
 else if (lY1<MIN_Y)// if (lY1>MAX_Y)
 {
  if (lY2<MIN_Y)
   goto n_t_d;
  if (MIN_Y-lY1>MIN_X-lX1)
  {
   // y
   lX1+=(MIN_Y-lY1)*(lX2-lX1)/(lY2-lY1);
   lY1=MIN_Y;
  }
  else
  { // x
/*** */
   lY1+=(MIN_X-lX1)*(lY2-lY1)/(lX2-lX1);
   lX1=MIN_X;
  }
 }
 else // if (lY1<MIN_Y)// if (lY1>MAX_Y)
 { // x
  if (lY1<lY2)
   lY1+=(MIN_X-lX1)*(lY2-lY1)/(lX2-lX1);
  else
   lY1-=(MIN_X-lX1)*(lY1-lY2)/(lX2-lX1);
  lX1=MIN_X;
 }
} // else // if (lX1>MAX_X)
if (lX2>MAX_X)
{
 if (lY2>MAX_Y)
 {
  if (lY1>MAX_Y)
   goto n_t_d;
  if (lY2-MAX_Y>lX2-MAX_X)
  {
   // y
   lX2-=(lY2-MAX_Y)*(lX2-lX1)/(lY2-lY1);
   lY2=MAX_Y;
  }
  else
  { // x
   lY2-=(lX2-MAX_X)*(lY2-lY1)/(lX2-lX1);
   lX2=MAX_X;
  }
 }
 else if (lY2<MIN_Y)// if (lY2>MAX_Y)
 {
  if (lY1<MIN_Y)
   goto n_t_d;
  if (MIN_Y-lY2>lX2-MAX_X)
  {
   // y
   lX2-=(MIN_Y-lY2)*(lX2-lX1)/(lY1-lY2);
   lY2=MIN_Y;
  }
  else
  { // x
   lY2+=(lX2-MAX_X)*(lY1-lY2)/(lX2-lX1);
   lX2=MAX_X;
  }
 }
 else // if (lY2<MIN_Y)// if (lY2>MAX_Y)
 { // x
  if (lY2<lY1)
   lY2+=(lX2-MAX_X)*(lY1-lY2)/(lX2-lX1);
  else
   lY2-=(lX2-MAX_X)*(lY2-lY1)/(lX2-lX1);
  lX2=MAX_X;
 }
} // if (lX2>MAX_X)
else if (lX2<MIN_X) // if (lX2>MAX_X)
{
 if (lY2>MAX_Y)
 {
  if (lY1>MAX_Y)
   goto n_t_d;
  if (lY2-MAX_Y>MIN_X-lX2)
  {
   // y
   lX2+=(lY2-MAX_Y)*(lX1-lX2)/(lY2-lY1);
   lY2=MAX_Y;
  }
  else
  { // x
   lY2-=(MIN_X-lX2)*(lY2-lY1)/(lX1-lX2);
   lX2=MIN_X;
  }
 }
 else if (lY2<MIN_Y)// if (lY2>MAX_Y)
 {
  if (lY1<MIN_Y)
   goto n_t_d;
  if (MIN_Y-lY2>MIN_X-lX2)
  {
   // y
   lX2+=(MIN_Y-lY2)*(lX1-lX2)/(lY1-lY2);
   lY2=MIN_Y;
  }
  else
  { // x
   lY2+=(MIN_X-lX2)*(lY1-lY2)/(lX1-lX2);
   lX2=MIN_X;
  }
 }
 else // if (lY2<MIN_Y)// if (lY2>MAX_Y)
 { // x
  if (lY2<lY1)
   lY2+=(MIN_X-lX2)*(lY1-lY2)/(lX1-lX2);
  else
   lY2-=(MIN_X-lX2)*(lY2-lY1)/(lX1-lX2);
  lX2=MIN_X;
 }
} // else // if (lX2>MAX_X)
if (lY1>MAX_Y)
{
 if (lY2>MAX_Y)
  goto n_t_d;
  // y
 if (lX1<lX2)
  lX1+=(MAX_Y-lY1)*(lX2-lX1)/(lY1-lY2);
 else
  lX1-=(MAX_Y-lY1)*(lX1-lX2)/(lY1-lY2);
 lY1=MAX_Y;
} // if (lY1>MAX_Y)
else if (lY1<MIN_Y) // if (lY1>MAX_Y)
{
 if (lY2<MIN_Y)
  goto n_t_d;
 if (lX1<lX2)
  lX1+=(MIN_Y-lY1)*(lX2-lX1)/(lY2-lY1);
 else
  lX1-=(MIN_Y-lY1)*(lX1-lX2)/(lY2-lY1);
 lY1=MIN_Y;
} // else // if (lY1>MAX_Y)

if (lY2>MAX_Y)
{
 // Y
 if (lX2<lX1)
  lX2+=(lY2-MAX_Y)*(lX1-lX2)/(lY2-lY1);
 else
  lX2-=(lY2-MAX_Y)*(lX2-lX1)/(lY2-lY1);
 lY2=MAX_Y;
} // if (lY2>MAX_Y)
else if (lY2<MIN_Y) // if (lY2>MAX_Y)
{
 // y
 if (lX2<lX1)
  lX2+=(MIN_Y-lY2)*(lX1-lX2)/(lY1-lY2);
 else
  lX2-=(MIN_Y-lY2)*(lX2-lX1)/(lY1-lY2);
 lY2=MIN_Y;
} // else // if (lY2>MAX_Y)

#undef MAX_X
#undef MIN_X
#undef MAX_Y
#undef MIN_Y

//t_printf(0,"\nLine:x1:%i, y1:%i, x2:%i, y2:%i",lX1,lY1,lX2,lY2);

   #ifdef ANALOG_TICK_LINEAR_SHIFT
   #define DISPLAY_LINE_LINEAR_SHIFT
   #include "dline.cc"
   #undef DISPLAY_LINE_LINEAR_SHIFT
   #endif

   #ifdef ANALOG_TICK_LINEAR_DIV
   #define DISPLAY_LINE_LINEAR_DIV
   #include "dline.cc"
   #undef DISPLAY_LINE_LINEAR_DIV
   #endif

   #ifdef ANALOG_TICK_BANKED_SHIFT
   #define DISPLAY_LINE_BANKED_SHIFT
   #include "dline.cc"
   #undef DISPLAY_LINE_BANKED_SHIFT
   #endif

   #ifdef ANALOG_TICK_BANKED_DIV
   #define DISPLAY_LINE_BANKED_DIV
   #include "dline.cc"
   #undef DISPLAY_LINE_BANKED_DIV
   #endif

#ifdef ANALOG_IMAGER
 #undef DISPLAY_TICK_IMAGER
#endif
n_t_d:

  // this is only for the special changed case if
  // midline dac changes occur
  lX1=lSIGDEF_XOUTPUT;
  lY1=lSIGDEF_YOUTPUT;
  tBright=tSIGDEF_ZOUTPUT;
 }

 /**********************************/
 /* Convert DAC to a signed number */
 /**********************************/
 lXSampleHold=(T_SCHAR)tSIGDEF_DACBUS;//DAC_lookup[tSIGDEF_DACBUS];
 tLastRamp=tSIGDEF_RAMPB;
 /******************************/
 /* Emulate switching circuits */
 /******************************/
 if (!tSIGDEF_SAMPHOLD) // Only use analog switch if enabled
 {
  switch (tSIGDEF_AMUXSEL)
  {
   case 0: /* Y AXIS */
    lYSampleHold=(T_SCHAR)tSIGDEF_DACBUS;
    break;
   case 4: /* Z AXIS - BRIGHT */
    tZSampleHold=(T_SCHAR)tSIGDEF_DACBUS;
#ifdef EMU_FULL_ANALOG
    intensity_drift=lwGblSystemTickTotal;
#endif
    break;
   case 2: /* ZERO OFFSET - Appparently for calibration only */
    tIntegratorOffset=(T_SCHAR)tSIGDEF_DACBUS;
    break;
   case 6: /* SOUND */
    break;
   default:
    fDebug(VERROR,("fAnalogTick() Illegal analog mux setting"));
    break;
  }
 }
}
#ifdef ANTI_ALIASING
#undef EMU_FULL_ANALOG
#endif
