// this is Malban's "C" optimized version of print_sync
// (remember to set the project options to -O3 and no_frame_pointer)
#include <vectrex.h>

#define int16_t long int
#define int8_t int
#define sint16_t signed long int
#define sint8_t signed int
#define uint16_t unsigned long int
#define uint8_t unsigned int

#define ZERO_DELAY 5

void draw_synced_list_c(const signed char *u,
                        sint8_t y,
                        sint8_t x,
                        uint8_t scaleMove,
                        uint8_t scaleList) {

  do {
      // resync / startsync
      dp_VIA_shift_reg = 0;// all output is BLANK

      // move to zero
      dp_VIA_cntl = (unsigned int)0xcc;// zero the integrators
      dp_VIA_port_a = 0;// reset integrator offset
      dp_VIA_port_b = (int)0b10000010;

      dp_VIA_t1_cnt_lo = scaleMove;
      // delay, till beam is at zero
      // volatile - otherwise delay loop does not work with -O
      for (volatile signed int b=ZERO_DELAY; b>0; b--);
      dp_VIA_port_b= (int)0b10000011;

      // move to "location"
      dp_VIA_port_a = y;// y pos to dac
      dp_VIA_cntl = (unsigned int)0xce;// disable zero, disable all blank
      dp_VIA_port_b = 0;// mux enable, dac to -> integrator y (and x)
      dp_VIA_port_b = 1;// mux disable, dac only to x
      dp_VIA_port_a = x;// dac -> x
      dp_VIA_t1_cnt_hi=0;// start timer

      // this can be done before the wait loop
      // since it only fills the latch, not the actual timer!
      dp_VIA_t1_cnt_lo = scaleList;
      u+=3;

      // moving test for yx == 0 into the move delay
      if ((*(u-2)!=0) || (*(u-1)!=0))
        {
          while ((dp_VIA_int_flags & 0x40) == 0); // wait till timer finishes

          // internal moveTo
          dp_VIA_port_a = *(u-2);// y pos to dac
          dp_VIA_cntl = (unsigned int)0xce;// disable zero, disable all blank
          dp_VIA_port_b = 0;// mux enable, dac to -> integrator y (and x)
          dp_VIA_port_b = 1;// mux disable, dac only to x
          dp_VIA_port_a = *(u-1);// dac -> x
          dp_VIA_t1_cnt_hi=0;// start timer
          while ((dp_VIA_int_flags & 0x40) == 0); // wait till timer finishes
        }
      else
        {
          while ((dp_VIA_int_flags & 0x40) == 0); // wait till timer finishes
        }

      while (1)
        {
          if (*u<0) // draw line
            {
              // draw a vector
              dp_VIA_port_a = *(1+u);// y pos to dac
              dp_VIA_port_b = 0;// mux enable, dac to -> integrator y (and x)
              dp_VIA_port_b=1;// mux disable, dac only to x
              dp_VIA_port_a = *(2+u);// dac -> x
              dp_VIA_t1_cnt_hi=0;// start timer
              dp_VIA_shift_reg = (unsigned int)0xff;// draw complete line

              if (scaleList>10)
                {
                  while ((dp_VIA_int_flags & 0x40) == 0); // wait till timer finishes
                }
              dp_VIA_shift_reg = 0;// all output is BLANK
            }
          else if (*u == 0) // moveTo
            {
              if ((*(u+1)!=0) || (*(u+2)!=0))
                {
                  // internal moveTo
                  dp_VIA_port_a = *(1+u);// y pos to dac
                  dp_VIA_cntl = (unsigned int)0xce;// disable zero, disable all blank
                  dp_VIA_port_b = 0;// mux enable, dac to -> integrator y (and x)
                  dp_VIA_port_b =1;// mux disable, dac only to x
                  dp_VIA_port_a = *(2+u);// dac -> x
                  dp_VIA_t1_cnt_hi=0;// start timer
                  while ((dp_VIA_int_flags & 0x40) == 0); // wait till timer finishes
                }
            }
          else
            {
              break;
            }
          u+=3;
        }
  } while (*u != 2);
}
