#include <stdio.h>
#include <math.h>
#include <dos.h>

#define n360    3600         /* scale  3600 -- 360 degree */
#define n180    1800         /* shift  south=1800         */
#define slit    12
#define t_gap   28

#define p824    788

double pi,twopi,phi,sphi,cphi;
double angle,alpha,delta,s0;
int z0,z1,z2,z3;


  int  ia,id,ia0,id0,zza[2],zzd[2],iap,idp,acou,dcou,idumy=0;
  int  aa3[3]={0,32,16};
  int  ad3[3]={0,128,64};

main(ac,av)
int ac; char *av[];
{

  char c;
  int i,j;
  float t,d,t1,d1;
  int gap,dummy,k,p0,p1,p2,p3;
  int time_count,d120,d18;

  wpos(1,0);
  for(i=0;i<22;i++)for(j=0;j<80;j++)printf(" ");

  if(ac>=7){
    sscanf(av[1],"%d",&ia0);    if(ia0>2||ia0<0)ac=1;
    sscanf(av[2],"%d",&zza[0]); if(zza[0]<0)ac=1;
    sscanf(av[3],"%d",&zza[1]); if(zza[1]<0)ac=1;
                                if(zza[0]+zza[1]==0)ac=1;
    ia=ia0;   iap=acou=0;
    sscanf(av[4],"%d",&id0);    if(id0>2||id0<0)ac=1;
    sscanf(av[5],"%d",&zzd[0]); if(zzd[0]<0)ac=1;
    sscanf(av[6],"%d",&zzd[1]); if(zzd[1]<0)ac=1;
                                if(zzd[0]+zzd[1]==0)ac=1;
    id=id0;   idp=dcou=0;
    if(ac>=7)pokeb(0,0x1f3,1);          /* dome on */
  }
  d18=18;                               /* 50928 */
  if(ac>7){ sscanf(av[7],"%d",&i); if(i>0 && i<18)d18=i;  }
  d120=120*18/d18;

  if(ac<7){
printf("\tUsage: disp1 R.A_direct move_s stop_s Dec_direct move_s stop_s [18]\n");
printf("\t       last 18 means 1 second, is default value, as DISP0\n");
printf("\t       you can choise 1~18, no relation with previous 6 paramters\n");
printf("\n\t Ex. disp1 2 3 7 1 1 0\n");
printf("\n\t Ex. disp1 2 3 7 1 1 0 9\n");
printf("\n\t     R.A_direct=0 (no_move);  =2 R.A.++;  =1 R.A.--");
printf("\n\t     Dec_direct=0 (no_move);  =1 Dec.++;  =2 Dec.--");
printf("\n\t     means: R.A move 3 sec. then stop 7 sec. direct is ++");
printf("\n\t            Dec continue move. (no stop)     direct is ++");
printf("\n\n");
printf("\n\t    notice: quit TIT, run on d:smt2>");
printf("\n\t            change control_handler speed to 1 by user");
printf("\n\t            dome_track is still working\n\n");
printf("\n\t      <esc> exit this progam, else telescope cannot stop\n\n");
exit(0);
  }

  time_count=d120/2;
  pi=4.*atan(1.);  twopi=pi+pi;
  phi=(40.+23/60.+36/3600.)*pi/180.;
  sphi=sin(phi); cphi=cos(phi);

l10:       /* get current time_angle & delta position */
  if(ac>=7){
l11:
    acou++; if(acou>zza[iap]){
            acou=0; iap=1-iap; ia=ia0; if(iap==1)ia=0; goto l11; }
l12:
    dcou++; if(dcou>zzd[idp]){
            dcou=0; idp=1-idp; id=id0; if(idp==1)id=0; goto l12; }
    if(idumy)printf("\n\nR.A. %d %d   Dec. %d %d",acou,ia, dcou,id);
    idumy=1;              /* for 1st not display */
    move();
  }
 /* 1 */
  take_4(4);
  d1=z2+z1/60.+z0/3600.;
  if(z3==1)d1+=100.; if(z3==10)d1=-d1;
  take_4(0);
  t1=z3+z2/60.+z1/3600.;
  if(z3>5&&z3<18)printf("\7");      /* beep when angle too large */
 /* dome now position */
  p0=take_dome();
 /* 2 */
  delay50(d18);                /* for get coorect data or if moving */
  take_4(4);
  d=z2+z1/60.+z0/3600.;
  if(z3==1)d+=100.; if(z3==10)d=-d;
  take_4(0);
  t=z3+z2/60.+z1/3600.;
  if(d!=d1||fabs(t-t1)>0.0003)goto l10;
  if(z3>5&&z3<19)printf("\7");

  wpos(3,0);
  tak();                     /* display 4 row & for get s0 */
  angle=t/12.*pi;
  alpha=s0/12.*pi-angle;
  delta=d/180.*pi;
  zen();
  galactic();
  if(keyin()==27){      ia=id=0; move();      exit(0); }

  printf("\nreal_disp--> p0: %04d %4d\n",p0,time_count);
  p1=aa(t,d,&gap);
  t+=0.3;
  p2=aa(t,d,&dummy);  /* get 20 minute_after position */
  if(p1==0){ printf("too low "); goto l10; }
  printf("should_be--> p1: %04d %4d\n",p1,gap);
  printf("20min_late-> p2: %04d\n",p2);
  if(p2 > p1) { p3=p1+gap; if(p2 < p3) { p3=p2; gap=p3-p1; } }
  else {p3=p1-gap; if(p2 > p3) { p3=p2; gap=p1-p3; } }
  printf("will_be----> p3: %04d",p3);
/* get display position */
  dummy=p1-p0; if(dummy<0)dummy=-dummy;
  time_count++;
  k=p3-p0; if(k<0)k=-k; k/=4; if(k>gap)time_count=d120;
  if(time_count<d120)goto l10;
/*  printf("\ndummy gap p0 %d %d %d",dummy,gap,p0); */
  if(dummy<=gap||p2==0||dummy<20)goto l10;
/* turn */
  if(p3 > p0) printf(" ++++%5d",p3-p0);
  if(p3 < p0) printf(" ----%5d",p0-p3);
  s_dome(p3);
  time_count=0;        /* avoid +-moving no stop */
  goto l10;
}

tak()
{
  int seg,off,i,j,k;
  int iy,im,id;
  double d1,d2;
  unsigned t[4];
  long a;
  seg=peek(0,0x22);
  off=peek(0,0x1fc);
  for(i=0;i<4;i++){t[i]=peek(seg,off); off+=2;}
  a=(long)t[1]*0x10000+t[0];      /* beijing time */
  i=a/36000; a%=36000; i-=8;
  j=a/600;   a%=600;  k=a/10;    off=a%10;
  d2=(i+j/60.+k/3600.+off/36000.)/24.;
  asm mov ah,2ah
  asm int 21h
  asm mov iy,cx
  asm mov id,dx
  im=id/256; id%=256;
  if(i>=16)id--;
  printf("UT %d %02d %02d  %02d:%02d:%02d\n",iy,im,id,i,j,k);
  fjd(iy,im,id,&d1);
  d1+=d2;
  printf("JD %0.5lf\n",d1);
  s0=(long)t[3]*0x10000+t[2];      /* sidereal time */
  s0=s0/36000.;
}

aa(t,d,hh)
float t,d;
int *hh;
{
  double delta,hour,sinh,cosh,sinA,cosA,a,h;
  double s_delta,c_delta,s_hour,c_hour;
  int ia;
  delta=d*twopi/360.;
  hour=t*twopi/24.;
  s_delta=sin(delta); c_delta=cos(delta);
  s_hour=sin(hour);   c_hour=cos(hour);
  sinh=sphi*s_delta+cphi*c_delta*c_hour;
  cosh=sqrt(1.-sinh*sinh);
  sinA=c_delta*s_hour/cosh;
  cosA=(sphi*c_delta*c_hour-cphi*s_delta)/cosh;
  h=atan(sinh/cosh);
  a=atan(sinA/cosA);
  if(cosA < 0.) a+=pi;
  if(a > pi )a-=twopi;
  a=a*180./pi;
  a=a*n360/360.+n180+0.5;
  ia=a;
  *hh= (h < 1.57) ? slit/cos(h) : 399;
  if(*hh>399)*hh=399;
/*
   a: unit in display; if a=0 then mean star too low;
   h: dome_slit width in difference high angle;
*/
  return(ia);
}

wpos(x,y)
int x,y;
{
  asm mov dh,x
  asm mov dl,y
  asm mov bh,0
  asm mov ah,2
  asm int 10h
}

s_dome(p1)
int p1;
{
  char a[5];
  int  i;
  i=p1; if(i>=3600)i-=3600;
  sprintf(a,"%04d",i);
  if(peek(0,0x26e)!=0)return;       /* 41205 */
  for(i=0;i<4;i++)pokeb(0,0x2ea+i,a[i]);  pokeb(0,0x2e9,'D');
}

take_dome()     /* [8]+[9]*100 */
{
  char b[5];
  int i;
  for(i=0;i<4;i++)b[i]=peekb(0,0x2fa+i); b[4]=0; sscanf(b,"%d",&i);
  return (i);
}

take_4(int n)     /* zd=0+n,zs=1+n,zm=2+n,zh=3+n */
{
  int off;
  off=0x1e0+n;
  z0=peekb(0,off);
  z1=peekb(0,off+1);
  z2=peekb(0,off+2);
  z3=peekb(0,off+3);
  return;
}

keyin()
{
  asm mov ah,6
  asm mov dl,0ffh
  asm int 21h
  asm mov cx,0ffffh
  asm jz keyin1
  asm mov ah,0
  asm mov cx,ax
keyin1:
  return (_CX);
}

fjd(iy,im,id,d1)
int iy,im,id;
double *d1;
{
  int i,j;
  double d0=2433338.5;
  i=(im+9)*0.09;
  i=(i+iy-1900)*1.75+0.01;
  j=30.56*im;
  j=(iy-1950)*367+id+j-i;
  *d1=d0+j;
}

/* ** GALACTIC  converts celestial coordinates */
galactic()
{
  float a0,theta,l0;
  float x1,x2,xl,xb,cn2;
  cn2=pi/180.;
  a0=282.25*cn2;
  theta=62.6*cn2;
  l0=33.0*cn2;
  x1=cos(delta)*cos(alpha-a0);
  x2=cos(delta)*sin(alpha-a0)*cos(theta)+sin(delta)*sin(theta);
  xl=atan2(x2,x1)+l0;  if(xl<0)xl+=2.0*pi;
  xb=asin(sin(delta)*cos(theta)-cos(delta)*sin(alpha-a0)*sin(theta));
  printf("xl %f\n",xl);
  printf("xb %f\n",xb);
}

zen()
{
  double x,z;
  x=sin(delta)*sphi+cos(delta)*cos(angle)*cphi;
  z=sqrt(1.-x*x);
  z=90.-atan2(x,z)*180./pi;
  x=1./x-1.;
  x=1.+x-x*(0.0018167+x*(0.002875+x*0.0008083));
  printf("Zen  %f\n",z);
  printf("Mass %f\n",x);
}

move()
{
  int i;
  i=aa3[ia]+ad3[id];
  outport(p824,255-i);
}

delay50(int i)
{
  int j,k,m;
  m=0;
  j=peek(0,0x46c);
l10:
  k=peek(0,0x46c);
  if(j==k)goto l10;
  m++;
  if(m>i)return;
  j=k;
  goto l10;
}
