
/* "Take/Tek2430", a Tek2430 interface to view program,
   Copyright (C) 1987, 1990 California Institute of Technology.
   Original authors: John Tanner, Dave Gillespie, Mass Sivilotti, John Lazzaro
   Unix Port Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425/ CU Boulder/Boulder CO 91125. 


This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (Version 1, Feb 1989).

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* Output from p2c, the Pascal-to-C translator */
/* From input file "tek2430.text" */


#include <p2c/p2c.h>

#define TEK2430_G
#include "tek2430.h"


#define tek2430Addr     722

#define TEK2430_CH      "00"

#define ChannelOne     "CH1"   /* change these to ADD, MUL, etc. */
#define ChannelTwo     "CH2"


#define points_         1022
/*  trace_linestyle = 4;*/
/*  axis_linestyle  = 2;*/
/*  text_linestyle  = 8;*/
#define trace_linestyle  0
#define axis_linestyle  0
#define text_linestyle  0
#define ff_trace_color  2
#define ff_axis_color   2
#define ff_text_color   2

#define till_hscale     31.7
#define till_vscale     66.2


typedef struct trace {
  double *y;
  long yoff, center_point;
  struct trace *next;
} trace;


Static Char xunits[11], yunits[11];
Static double deltax;   /* time interval between subsequent data points */
Static double deltay;   /* voltage difference between y steps */
Static double yoffset;   /* position of GND in screen coordinates */
Static double *ch1x, *ch2x, *ch1y, *ch2y;
Static long center_point;
Static FILE *fffile, *viewFile;
Static Char vmode[81], label_string[81], trace_file_name[81];
Static Char preamble1[256];
Static long center_point1, yoff1;
Static Char preamble2[256];
Static long center_point2, yoff2;
Static double vscale;
Static Char trace_label[256], trace_date[256];
Static trace *append_list;
Static boolean display_graticule;
Static double scaleX, scaleY, syoff;


Void get_tek2430_preamble(chan, points)
long chan, *points;
{
  Char preamble[256];
  long pos, junk;
  Char cmd_str[81];
  Char *STR3;

  P_writestringln((long)tek2430Addr, "DATA ENCDG ASCII");
  sprintf(cmd_str, "DATA SOURCE:CH%ld", chan);
  junk = strlen(cmd_str) + 1;
  cmd_str[junk - 1] = '\0';
/* p2c: tek2430.text, line 112:
 * Note: Modification of string length may translate incorrectly [146] */
  /*     writeln (cmd_str);     */
  P_writestringln((long)tek2430Addr, cmd_str);
  P_writestringln((long)tek2430Addr, "WFMPRE?");
  P_readstring((long)tek2430Addr, preamble);

  /* get deltax*/
  pos = strpos2(preamble, "XINCR:", 1);
  pos += strlen("XINCR:");
  deltax = strtod(preamble + pos - 1, &STR3);
  pos = STR3 - preamble + 1;

  /* get deltay*/
  pos = strpos2(preamble, "YMULT:", 1);
  pos += strlen("YMULT:");
  deltay = strtod(preamble + pos - 1, &STR3);
  pos = STR3 - preamble + 1;

  /* get y-offset*/
  pos = strpos2(preamble, "YOFF:", 1);
  pos += strlen("YOFF:");
  yoffset = strtod(preamble + pos - 1, &STR3);
  pos = STR3 - preamble + 1;

  /*    writeln ('From preamble:  deltax = ',deltax:0,';  deltay = ',deltay:0,
                                ';   yoffset = ',yoffset:0);   */

  /* generate some defaults */
  *points = 1022;
  strcpy(xunits, "SEC");
  strcpy(yunits, "VOLTS");
}


Void get_tek2430_rawtrace(chan, x, y, points)
long chan;
double *x, *y;
long points;
{
  long data_point, junk;
  Char cmd_str[81];

  P_writestringln((long)tek2430Addr, "DATA ENCDG ASCII");
  sprintf(cmd_str, "DATA SOURCE:CH%ld", chan);
  junk = strlen(cmd_str) + 1;
  cmd_str[junk - 1] = '\0';
/* p2c: tek2430.text, line 152:
 * Note: Modification of string length may translate incorrectly [146] */
  /*  writeln (cmd_str);   */
  P_writestringln((long)tek2430Addr, cmd_str);
  P_writestringln((long)tek2430Addr, "CURVE?");
  for (data_point = 1; data_point <= points; data_point++) {
    x[data_point - 1] = data_point;
    /* P_readnumber((long)tek2430Addr, &y[data_point - 1]); */  /* --jl */
  }
}


Void get_tek2430_trace(chan, x, y, points)
long chan;
double *x, *y;
long points;
{
  long data_point;

  get_tek2430_rawtrace(chan, x, y, points);
  for (data_point = 1; data_point <= points; data_point++) {
    x[data_point - 1] = deltax * x[data_point - 1];
    y[data_point - 1] = deltay * (y[data_point - 1] - yoffset);
    /* writeln (data_point:0, '  ', x[data_point], '   ',y[data_point]);  */
  }
}


Char *get_tek2430_trace_id(Result, channel)
Char *Result;
long channel;
{
  Char cmd_str[81], response[81];
  long junk;

  /* Next two lines do anything ??????? */
  sprintf(cmd_str, "DATA SOURCE:CH%ld", channel);
  junk = strlen(cmd_str) + 1;
  cmd_str[junk - 1] = '\0';
/* p2c: tek2430.text, line 183:
 * Note: Modification of string length may translate incorrectly [146] */
  P_writestringln((long)tek2430Addr, "WFM?WFI");
  P_readstring((long)tek2430Addr, response);
  sprintf(cmd_str, "%.*s",
    strlen(response) - strpos2(response, "WFID:\"", 1) - strlen("WFID:\""),
    response + strpos2(response, "WFID:\"", 1) + strlen("WFID:\"") - 1);
  printf("trace id for channel %ld: %s\n", channel, cmd_str);
  return strcpy(Result, cmd_str);
}


Void reset_tek2430()
{
  if (ieeeinit()==-1)
    printf("HPIB board not found\n");
  else
    printf("HPIB board found\n");
}


#define tick_size       6


Void tek2430_ff_start(filename)
Char *filename;
{
  /* start an FF file with the tektronix scope face */
  long i;

  *label_string = '\0';   /* clear label string */
  if (fffile != NULL)
    fffile = freopen(filename, "w", fffile);
  else
    fffile = fopen(filename, "w");
  if (fffile == NULL)
    _EscIO(FileNotFound);
  fprintf(fffile, "F ``%s`[](\n", filename);

  /* write screen */
  fprintf(fffile, "O (%ld)\n", (long)ff_axis_color);
  if (display_graticule != true)
    return;
  /* write horizontal screen lines */
  for (i = 0; i <= 8; i++)
    fprintf(fffile, "L [] ( 0 %0.0f %0.0f %0.0f  )\n",
	    i * (256.0 / 8) * till_vscale, 512 * till_hscale,
	    i * (256.0 / 8) * till_vscale);
  /* tick marks on horizontal axis */
  for (i = -25; i <= 25; i++) {
    if (i % 5 != 0)
      fprintf(fffile, "L [] ( %0.0f %0.0f %0.0f %0.0f )\n",
	      (256 + i * (256.0 / 25.0)) * till_hscale,
	      128 * till_vscale - tick_size * till_hscale,
	      (256 + i * (256.0 / 25.0)) * till_hscale,
	      128 * till_vscale + tick_size * till_hscale);
/* p2c: tek2430.text, line 223:
 * Note: Using % for possibly-negative arguments [317] */
  }

  /* write vertical screen lines */
  for (i = 0; i <= 10; i++)
    fprintf(fffile, "L [] ( %0.0f 0 %0.0f %0.0f )\n",
	    i * 51.2 * till_hscale, i * 51.2 * till_hscale,
	    256 * till_vscale);
  /* tick marks on vertical axis */
  for (i = -20; i <= 20; i++) {
    if (i % 5 != 0)
      fprintf(fffile, "L [] ( %0.0f %0.0f %0.0f %0.0f )\n",
	      (256 - tick_size) * till_hscale,
	      (128 + i * (128.0 / 20.0)) * till_vscale,
	      (tick_size + 256) * till_hscale,
	      (128 + i * (128.0 / 20.0)) * till_vscale);
/* p2c: tek2430.text, line 240:
 * Note: Using % for possibly-negative arguments [317] */
  }
}

#undef tick_size


Void tek2430_add(x, center_point, yoff)
double *x;
long center_point, yoff;
{
  /* add points from (center_point - 253) to (center_point + 257) */
  long i;

  fprintf(fffile, "O (%ld)\n", (long)ff_trace_color);
  fprintf(fffile, "L [] ( ");
  for (i = center_point - 253; i <= center_point + 257; i++) {
    if (i > 0 && i < 1023) {
      fprintf(fffile, "%0.0f %0.0f  ",
	      (i - center_point + 253) * till_hscale,
	      ((x[i - 1] + yoff) * (5.1 / 4) + 128) * till_vscale);
      if (i % 6 == 0)
	fprintf(fffile, "\n     ");
/* p2c: tek2430.text, line 261:
 * Note: Using % for possibly-negative arguments [317] */
    }
  }
  fprintf(fffile, " )\n");
}


Void tek2430_ff_title(label_str)
Char *label_str;
{
  fprintf(fffile, "O (%ld)\n", (long)ff_text_color);
  fprintf(fffile, "T [1 2 2 2 3 7 ](``%s` ", label_str);
  fprintf(fffile, "%0.0f %0.0f )\n", 256 * till_hscale, 286 * till_vscale);
}


Void tek2430_close()
{
  fprintf(fffile, ")\n");
  if (fffile != NULL)
    fclose(fffile);
  fffile = NULL;
}


Void tek2430_addtrace(channel, yoff)
long channel, yoff;
{
  double *x, *y;
  long points;
  double real_center_point;
  Char flush_[81], STR1[81];

  points = 1022;   /* nothing else for now */
  sprintf(label_string + strlen(label_string), "%s; ",
	  get_tek2430_trace_id(STR1, channel));
  x = (double *)Malloc(sizeof(mam_vectorarray));
  y = (double *)Malloc(sizeof(mam_vectorarray));
  get_tek2430_rawtrace(channel, x, y, points);
  /* find the horizontal center position */
  P_writestringln((long)tek2430Addr, "HOR?POS");
  /* P_readnumber((long)tek2430Addr, &real_center_point); */ /* --jl */
  P_readstring((long)tek2430Addr, flush_);   /* try flushing the read buffer*/
  center_point = (long)real_center_point;
  /* add the trace */
  tek2430_add(y, center_point, yoff);
}


Void tek2430_dump_scope(filename)
Char *filename;
{
  Char cmd_str[81];
  Char STR1[8];

  /* open output file */
  tek2430_ff_start(filename);
  /* find out which traces are on */
  P_writestringln((long)tek2430Addr, "VMODE?");
  P_readstring((long)tek2430Addr, cmd_str);
  sprintf(STR1, "%s:ON", ChannelOne);
  if (strpos2(cmd_str, STR1, 1) != 0)
    tek2430_addtrace(1L, yoff1);
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(cmd_str, STR1, 1) != 0)
    tek2430_addtrace(2L, yoff2);
  tek2430_ff_title(label_string);
  tek2430_close();
}


/*   **********************  John Tanner's Stuff *********************  */

Void init_tek2430()
{
  ch1x = (double *)Malloc(sizeof(mam_vectorarray));
  ch1y = (double *)Malloc(sizeof(mam_vectorarray));
  ch2x = (double *)Malloc(sizeof(mam_vectorarray));
  ch2y = (double *)Malloc(sizeof(mam_vectorarray));
  append_list = NULL;
  *vmode = '\0';
  *preamble1 = '\0';
  *preamble2 = '\0';
  display_graticule = true;
}


Static Void scale_from_preamble(preamble_)
Char *preamble_;
{
  Char preamble[256];
  long pos;
  Char *STR1;

  strcpy(preamble, preamble_);
  /* get deltax*/
  pos = strpos2(preamble, "XINCR:", 1);
  pos += strlen("XINCR:");
  deltax = strtod(preamble + pos - 1, &STR1);
  pos = STR1 - preamble + 1;

  /* get deltay*/
  pos = strpos2(preamble, "YMULT:", 1);
  pos += strlen("YMULT:");
  deltay = strtod(preamble + pos - 1, &STR1);
  pos = STR1 - preamble + 1;

  /* get y-offset*/
  pos = strpos2(preamble, "YOFF:", 1);
  pos += strlen("YOFF:");
  yoffset = strtod(preamble + pos - 1, &STR1);
  pos = STR1 - preamble + 1;
}


Void convert_traces(sc_ch1x, sc_ch1y, sc_ch2x, sc_ch2y, pts, trace1th,
		    trace2th)
double **sc_ch1x, **sc_ch1y, **sc_ch2x, **sc_ch2y;
long *pts;
boolean *trace1th, *trace2th;
{
  long data_point;

  *pts = points_;
  *trace1th = false;
  *trace2th = false;

  if (*preamble1 != '\0') {
    *trace1th = true;
    scale_from_preamble(preamble1);
    for (data_point = 1; data_point <= points_; data_point++) {
      (*sc_ch1x)[data_point - 1] = deltax * ch1x[data_point - 1];
      printf("data% .5E\n", (*sc_ch1x)[data_point - 1]);
      (*sc_ch1y)[data_point - 1] = deltay * (ch1y[data_point - 1] - yoffset);
    }
  }

  if (*preamble2 == '\0')
    return;
  *trace2th = true;
  scale_from_preamble(preamble2);
  for (data_point = 1; data_point <= points_; data_point++) {
    (*sc_ch2x)[data_point - 1] = deltax * ch2x[data_point - 1];
    (*sc_ch2y)[data_point - 1] = deltay * (ch2y[data_point - 1] - yoffset);
  }
}


typedef Char monlist[16][4];


Local Const monlist months = {
  "000", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
  "Nov", "Dec", "013", "014", "015"
};


Static Char *get_date_string(Result)
Char *Result;
{
  long pos;
  Char ampm[4];
  datetimerec datetime;
  Char date_string[256];

  sysdate(&datetime.date);
  systime(&datetime.time);

  sprintf(date_string, "%s%3d%5d",
	  months[datetime.date.month], datetime.date.day,
	  datetime.date.year + 1900);
  pos = strlen(date_string) + 1;
  strcpy(ampm, " am");
  if (datetime.time.hour > 11) {
    datetime.time.hour -= 12;
    strcpy(ampm, " pm");
  }
  if (datetime.time.hour == 0)
    datetime.time.hour = 12;
  sprintf(date_string + pos - 1, "%3d:", datetime.time.hour);
  pos = strlen(date_string) + 1;
  if (datetime.time.minute < 10) {
    sprintf(date_string + pos - 1, "0");
    pos = strlen(date_string) + 1;
  }
  sprintf(date_string + pos - 1, "%d%s", datetime.time.minute, ampm);
  pos = strlen(date_string) + 1;
  return strcpy(Result, date_string);
}

Void writescope(lab)
Char *lab; {

  Char buff[256];
  
  sprintf(buff, "output %s; %s \n", TEK2430_CH, lab); 
  ieeewt(buff);
}

Void readscope(lab)
Char *lab; {

  Char buff[256];

  sprintf(buff, "enter %s\n", TEK2430_CH);
  ieeewt(buff);
  ieeerd(buff);
  strcpy(lab,buff);
}

Void readhoriz(val)

double *val;

{
  Char buff[256];

  readscope(buff);
  buff[0] = '0';    buff[1] = '0';    buff[2] = '0';    buff[3] = '0';
  buff[4] = '0';    buff[5] = '0';    buff[6] = '0';    buff[7] = '0';
  buff[8] = '0';    buff[9] = '0';    buff[10] = '0';   buff[11] = '0';
  buff[12] = '0';   buff[13] = '0';   buff[14] = '0';   buff[15] = '0';
  buff[16] = '0';   buff[17] = '0';   buff[18] = '0';   buff[19] = '0';
  *val = atof(buff);

}

Void readtrace(tracenum) 
int tracenum;
{

  Char total[10000];
  Char temp[4];
  int temppos, totpos;
  Char buff[256];
  long datapoint;
 
  writescope("CURVE?");
  sprintf(buff, "enter %s\n", TEK2430_CH);
  ieeewt(buff);
  ieeerd(total);
  temp[0]=' '; temp[1]=' '; temp[2]=' '; temp[3]=' ';
  temppos=0;
  datapoint=0;
  for (totpos=0;totpos <= strlen(total);totpos++){
    switch (total[totpos]){
    case 'C': case 'U': case 'R': case 'V': case 'E': case ' ':
           break;
    case '0': case '1': case '2': case '3': case '4': case '5':
    case '6': case '7': case '8': case '9': case '-':
      temp[temppos]=total[totpos];
      temppos++;
      break;
   case ',': case '\0':
      if (tracenum==1){ 
      ch1y[datapoint]=atof(temp);}
      else{
	ch2y[datapoint]=atof(temp);}
      datapoint++;
      temppos=0;
      temp[0]=' '; temp[1]=' '; temp[2]=' '; temp[3]=' ';
      break; }}
    }

Void capture_traces_from_scope(lab)
Char *lab;
{
  long data_point;
  float tmpfloat;
  double real_center_point;
  Char total[10000];
  Char buff[256];
  Char dummy[20];
  Char STR1[8];
  Char STR2[16];

  sprintf(buff, "clear %s\n", TEK2430_CH);      /* does SDC */
  ieeewt(buff);
  strcpy(trace_label, lab);
  get_date_string(trace_date);
  /* find out which channels are on */
  writescope("DATA ENCDG: ASCII");
  writescope("VMODE?");
  readscope(vmode);
  sprintf(STR1, "%s:ON", ChannelOne);
  if (strpos2(vmode, STR1, 1) != 0) {
    sprintf(STR2, "DATA SOURCE:%s", ChannelOne);
    writescope(STR2);
    writescope("WFMPRE?");
    readscope(preamble1);
/*  Read this channel's horizontal display position.  */
    writescope("HOR?POS");
    readhoriz(&real_center_point);
    center_point1 = (long)real_center_point;
    /* Read this channel's data. */
    yoff1 = 0;
    readtrace(1);

  }
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) == 0)
    return;
  sprintf(STR2, "DATA SOURCE:%s", ChannelTwo);
  /* Read this channel's preamble. */
  writescope(STR2);
  writescope("WFMPRE?");
  readscope(preamble2);
  writescope("HOR?POS");
  readhoriz(&real_center_point);
  center_point2 = (long)real_center_point;
  /* Read this channel's data. */
  yoff2 = 0;
  writescope("CURVE?");
  readtrace(2);
 
}


Void append_traces()
{
  trace *tp;
  Char STR1[8];

  sprintf(STR1, "%s:ON", ChannelOne);
  if (strpos2(vmode, STR1, 1) != 0) {
    tp = (trace *)Malloc(sizeof(trace));
    tp->y = ch1y;
    ch1y = (double *)Malloc(sizeof(mam_vectorarray));
    tp->yoff = yoff1;
    tp->center_point = center_point1;
    tp->next = append_list;
    append_list = tp;
  }
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) != 0) {
    tp = (trace *)Malloc(sizeof(trace));
    tp->y = ch2y;
    ch2y = (double *)Malloc(sizeof(mam_vectorarray));
    tp->yoff = yoff2;
    tp->center_point = center_point2;
    tp->next = append_list;
    append_list = tp;
  }
  *vmode = '\0';
  *preamble1 = '\0';
  *preamble2 = '\0';
}


Void clear_appends()
{
  /* For now the memory is not reclaimed. */
  append_list = NULL;
}


Void read_traces_from_file(trace_file_name)
Char *trace_file_name;
{
  long data_point;
  FILE *tracefile;
  Char *TEMP;
  Char STR1[8];

  tracefile = NULL;
  if (tracefile != NULL)
    tracefile = freopen(trace_file_name, "r", tracefile);
  else
    tracefile = fopen(trace_file_name, "r");
  if (tracefile == NULL)
    _EscIO(FileNotFound);
  fgets(trace_label, 256, tracefile);
  TEMP = strchr(trace_label, '\n');
  if (TEMP != NULL)
    *TEMP = 0;
  fgets(trace_date, 256, tracefile);
  TEMP = strchr(trace_date, '\n');
  if (TEMP != NULL)
    *TEMP = 0;
  /* find out which channels are on */
  fgets(vmode, 81, tracefile);
  TEMP = strchr(vmode, '\n');
  if (TEMP != NULL)
    *TEMP = 0;
  sprintf(STR1, "%s:ON", ChannelOne);
  if (strpos2(vmode, STR1, 1) != 0) {
    fgets(preamble1, 256, tracefile);
    TEMP = strchr(preamble1, '\n');
    if (TEMP != NULL)
      *TEMP = 0;
    /* Read this channel's horizontal display position. */
    fscanf(tracefile, "%ld%*[^\n]", &center_point1);
    getc(tracefile);
    /* Read this channel's vertical display offset. */
    fscanf(tracefile, "%ld%*[^\n]", &yoff1);
    getc(tracefile);
    /* Read this channel's data. */
    for (data_point = 1; data_point <= points_; data_point++) {
      ch1x[data_point - 1] = data_point;
      fscanf(tracefile, "%lg", &ch1y[data_point - 1]);
    }
    fscanf(tracefile, "%*[^\n]");
    getc(tracefile);
  }
  /* Read this channel's preamble. */
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) != 0) {
    fgets(preamble2, 256, tracefile);
    TEMP = strchr(preamble2, '\n');
    if (TEMP != NULL)
      *TEMP = 0;
    /* Read this channel's horizontal display position. */
    fscanf(tracefile, "%ld%*[^\n]", &center_point2);
    getc(tracefile);
    /* Read this channel's vertical display offset. */
    fscanf(tracefile, "%ld%*[^\n]", &yoff2);
    getc(tracefile);
    /* Read this channel's data. */
    for (data_point = 1; data_point <= points_; data_point++) {
      ch2x[data_point - 1] = data_point;
      fscanf(tracefile, "%lg", &ch2y[data_point - 1]);
    }
    fscanf(tracefile, "%*[^\n]");
    getc(tracefile);
  }
  /* Read this channel's preamble. */
  if (tracefile != NULL)
    fclose(tracefile);
  tracefile = NULL;
  if (tracefile != NULL)
    fclose(tracefile);
}


Void write_traces_to_file(trace_file_name)
Char *trace_file_name;
{
  long data_point;
  FILE *tracefile;
  Char STR2[8];

  tracefile = NULL;
  if (tracefile != NULL)
    tracefile = freopen(trace_file_name, "w", tracefile);
  else
    tracefile = fopen(trace_file_name, "w");
  if (tracefile == NULL)
    _EscIO(FileNotFound);
  fprintf(tracefile, "%s\n", trace_label);
  fprintf(tracefile, "%s\n", trace_date);
  /* Record which channels are on. */
  fprintf(tracefile, "%s\n", vmode);
  sprintf(STR2, "%s:ON", ChannelOne);
  if (strpos2(vmode, STR2, 1) != 0) {
    fprintf(tracefile, "%s\n", preamble1);
    /* Write this channel's horizontal display position. */
    fprintf(tracefile, "%12ld\n", center_point1);
    /* Write this channel's vertical display offset. */
    fprintf(tracefile, "%12ld\n", yoff1);
    /* Write this channel's data. */
    for (data_point = 1; data_point <= points_; data_point++) {
      ch1x[data_point - 1] = data_point;
      fprintf(tracefile, "%4.0f ", ch1y[data_point - 1]);
      if ((data_point & 15) == 0 || data_point == points_)
	putc('\n', tracefile);
    }
  }
  /* Write this channel's preamble. */
  sprintf(STR2, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR2, 1) != 0) {
    fprintf(tracefile, "%s\n", preamble2);
    /* Write this channel's horizontal display position. */
    fprintf(tracefile, "%12ld\n", center_point2);
    /* Write this channel's vertical display offset. */
    fprintf(tracefile, "%12ld\n", yoff2);
    /* Write this channel's data. */
    for (data_point = 1; data_point <= points_; data_point++) {
      ch2x[data_point - 1] = data_point;
      fprintf(tracefile, "%4.0f ", ch2y[data_point - 1]);
      if ((data_point & 15) == 0 || data_point == points_)
	putc('\n', tracefile);
    }
  }
  /* Write this channel's preamble. */
  if (tracefile != NULL)
    fclose(tracefile);
  tracefile = NULL;
  if (tracefile != NULL)
    fclose(tracefile);
}


/* Extract the waveform ID label from the preamble. */
Static Char *wfid(Result, preamble)
Char *Result, *preamble;
{
  long first, last;

  first = strpos2(preamble, "WFID:\"", 1) + strlen("WFID:\"");
  last = strpos2(preamble, ",", 1) - 1;
  sprintf(Result, "%.*s", (int)(last - first), preamble + first - 1);
  return Result;
}


Void write_traces_to_ff_file(filename)
Char *filename;
{
  trace *tp;
  Char STR1[8];
  Char STR2[256];
  Char STR3[256];
  Char STR4[256];

  /* open output file */
  tek2430_ff_start(filename);
  sprintf(STR1, "%s:ON", ChannelOne);
  /* find out which traces are on */
  if (strpos2(vmode, STR1, 1) != 0)
    tek2430_add(ch1y, center_point1, yoff1);
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) != 0)
    tek2430_add(ch2y, center_point2, yoff2);
  /* Plot any appended traces. */
  tp = append_list;
  while (tp != NULL) {
    tek2430_add(tp->y, tp->center_point, tp->yoff);
    tp = tp->next;
  }

  /* Plot the waveform ID info as label. */
  if (*preamble1 != '\0' || *preamble2 != '\0') {
    sprintf(STR3, "%s; %s;", wfid(STR2, preamble1), wfid(STR4, preamble2));
    tek2430_ff_title(STR3);
  }
  tek2430_close();
}


Static Void writeViewTrace(x, center_point, yoff, traceNum)
double *x;
long center_point, yoff, *traceNum;
{
  /* add points from (center_point - 253) to (center_point + 257) */
  long i;

  fprintf(viewFile, "1\n");
  fprintf(viewFile, "pairs\n");
  fprintf(viewFile, "%s_%c\n", trace_label, (Char)(*traceNum + 'A'));
  (*traceNum)++;
  fprintf(viewFile, "Sec\n");
  fprintf(viewFile, "Volts\n");
  for (i = 1; i <= points_; i++)
    fprintf(viewFile, "% .5E % .5E\n",
	    (i - 1) * scaleX, (x[i - 1] + yoff) * scaleY);
  putc('\n', viewFile);
}


/* Attempt to parse the x and y scaling values from the preamble wfid. */
Static Void parseXY(s_)
Char *s_;
{
  Char s[256];
  long i;
  Char *STR1;
  Char tmpstr[3];
  Char tmpoff[12];
  long tmpcnt;

  strcpy(s, s_);
  /* Get the time scaling. */
  scaleX = 1.0;
  if (strpos2(s, "ns", 1) != 0) {
    i = strpos2(s, "ns", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'n'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleX = atof(tmpstr);
    scaleX = scaleX*1.0e-9;
  } else if (strpos2(s, "us", 1) != 0) {
    i = strpos2(s, "us", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'u'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleX = atof(tmpstr);
    scaleX = scaleX*1.0e-6;
  } else if (strpos2(s, "ms", 1) != 0) {
    i = strpos2(s, "ms", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'm'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleX = atof(tmpstr);
    scaleX = scaleX*1.0e-3;
  } else if (strpos2(s, "s", 1) != 0) {
    i = strpos2(s, "s", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 's'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleX = atof(tmpstr);
    scaleX = scaleX*1.0;
  }
  scaleX /= 50;   /* The Tek scope has 50 points/division horizontally. */
  /* Get the voltage scaling. */
  scaleY = 1.0;
  if (strpos2(s, "uV", 1) != 0) {
    i = strpos2(s, "uV", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'u'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleY = atof(tmpstr);
    scaleY = scaleY*1.0e-6;

  } else if (strpos2(s, "mV", 1) != 0) {
    i = strpos2(s, "mV", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'm'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleY = atof(tmpstr);
    scaleY = scaleY*1.0e-3;

  } else if (strpos2(s, "V", 1) != 0) {
    i = strpos2(s, "V", 1);
    while (s[i - 1] != ' ' && i > 1)   /* Search for preceding blank */
      i--;
    tmpcnt = 0; tmpstr[0]=tmpstr[1]=tmpstr[2]=' ';
    while (s[i] != 'V'){
      tmpstr[tmpcnt]=s[i];
      i++;tmpcnt++;}
    scaleY = atof(tmpstr);
    scaleY = scaleY*1.0;
  }
  scaleY /= 25;   /* The Tek scope has 50 points/division horizontally. */
 
  /* get offset value?? */
  
  i=0; 
  tmpoff[0]=tmpoff[1]=tmpoff[2]=tmpoff[3]=tmpoff[4]=tmpoff[5]=' ';
  tmpoff[6]=tmpoff[7]=tmpoff[8]=tmpoff[9]=tmpoff[10]=tmpoff[11]=' ';
  while (i < strlen(s)){
    if ((s[i]=='Y') &&(s[i+1]=='O') &&(s[i+2]=='F') && (s[i+3]=='F')){
       i=i+5;tmpcnt=0;
       while (s[i] != ',') {
	tmpoff[tmpcnt]=s[i];
        tmpcnt++; i++;}
      syoff = atof(tmpoff);
      i = strlen(s);}
    i++; }

}


Void write_traces_to_view_file(filename)
Char *filename;
{
  trace *tp;
  long traceNum;
  Char STR1[8];

  traceNum = 0;
  /* open output file */
  if (viewFile != NULL)
    viewFile = freopen(filename, "w", viewFile);
  else
    viewFile = fopen(filename, "w");
  if (viewFile == NULL)
    _EscIO(FileNotFound);
  sprintf(STR1, "%s:ON", ChannelOne);
  /* find out which traces are on */
  if (strpos2(vmode, STR1, 1) != 0) {
    parseXY(preamble1);
    writeViewTrace(ch1y, center_point1, yoff1, &traceNum);
  }
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) != 0) {
    parseXY(preamble2);
    writeViewTrace(ch2y, center_point2, yoff2, &traceNum);
  }
  /* Plot any appended traces. */
  tp = append_list;
  while (tp != NULL) {
    writeViewTrace(tp->y, tp->center_point, tp->yoff, &traceNum);
    tp = tp->next;
  }
  if (viewFile != NULL)
    fclose(viewFile);
  viewFile = NULL;
}


/* DAVE 1/19/88 */
Void get_view_info(chan, npts)
long chan, *npts;
{
  Char STR1[8];

  *npts = 0;
  switch (chan) {

  case 1:
    sprintf(STR1, "%s:ON", ChannelOne);
    if (strpos2(vmode, STR1, 1) != 0)
      *npts = points_;
    break;

  case 2:   /*other channels are NEVER available!*/
    sprintf(STR1, "%s:ON", ChannelTwo);
    if (strpos2(vmode, STR1, 1) != 0)
      *npts = points_;
    break;
  }
}


Void get_view_curve(chan, xvec, yvec)
long chan;
double **xvec, **yvec;
{
  double *chy;
  long i, size, center_point, yoff;

  get_view_info(chan, &size);
  if (size <= 0)
    return;
  switch (chan) {

  case 1:
    parseXY(preamble1);
    chy = ch1y;
    center_point = center_point1;   /*writeViewTrace doesn't use this*/
    yoff = -syoff;   /*  so neither will I*/
    break;

  case 2:
    parseXY(preamble2);
    chy = ch2y;
    center_point = center_point2;
    yoff = -syoff;
    break;
  }
  for (i = 1; i <= size; i++) {
    (*xvec)[i - 1] = (i - 1) * scaleX;
    (*yvec)[i - 1] = (chy[i - 1] + yoff) * scaleY;
  }
}


/* DAVE 1/19/88 */


Void toggle_display_graticule()
{
  if (display_graticule == true)
    display_graticule = false;
  else
    display_graticule = true;
}


#define tick_size       6


Static Void plot_graticule()
{
  long i;

  /* write screen */
  plot_linestyle((long)axis_linestyle);

  if (display_graticule != true)
    return;

  /* write horizontal screen lines */
  for (i = 0; i <= 8; i++)
    plot_line(0L, (long)(vscale * i * 256) / 8, 512L,
	      (long)(vscale * i * 256) / 8);

  /* tick marks on horizontal axis */
  for (i = -25; i <= 25; i++) {
    if (i % 5 != 0) {
/* p2c: tek2430.text, line 780:
 * Note: Using % for possibly-negative arguments [317] */
      plot_line(i * 256 / 25 + 256, (long)(vscale * 128) - tick_size,
		i * 256 / 25 + 256, (long)(vscale * 128) + tick_size);
    }
  }

  /* write vertical screen lines */
  for (i = 0; i <= 10; i++)
    plot_line((long)(i * 51.2), 0L, (long)(i * 51.2), (long)(vscale * 256));

  /* tick marks on vertical axis */
  for (i = -20; i <= 20; i++) {
    if (i % 5 != 0) {
/* p2c: tek2430.text, line 795:
 * Note: Using % for possibly-negative arguments [317] */
      plot_line(256L - tick_size, (long)(vscale * (i * 32 / 5 + 128)),
		tick_size + 256L, (long)(vscale * (i * 32 / 5 + 128)));
    }
  }
}

#undef tick_size


Void set_trace_params(cp1, y1, cp2, y2)
long cp1, y1, cp2, y2;
{
  center_point1 = cp1;
  yoff1 = y1;
  center_point2 = cp2;
  yoff2 = y2;
}


Void get_trace_params(cp1, y1, cp2, y2)
long *cp1, *y1, *cp2, *y2;
{
  *cp1 = center_point1;
  *y1 = yoff1;
  *cp2 = center_point2;
  *y2 = yoff2;
}


Static Void plot_trace(y, center_point, yoff)
double *y;
long center_point, yoff;
{
  /* add points from (center_point - 253) to (center_point + 257) */
  long i;
  boolean first;

  plot_linestyle((long)trace_linestyle);
  first = true;
  for (i = center_point - 253; i <= center_point + 257; i++) {
    if (i > 0 && i < 1023) {
      if (first)
	plot_move(i - center_point + 253,
		  (long)(vscale * ((y[i - 1] + yoff) * (5.1 / 4) + 128)));
      else
	plot_draw(i - center_point + 253,
		  (long)(vscale * ((y[i - 1] + yoff) * (5.1 / 4) + 128)));
      first = false;
    }
  }
}


Static Void plot_title(label_str)
Char *label_str;
{
  plot_linestyle((long)text_linestyle);
  plot_initfonts();
  plot_selfont(2L);
  plot_charsize(10L, plot_height(), 4L);
  plot_centerstring(256L, (long)(vscale * 286), label_str);
  plot_centerstring(256L, (long)(vscale * 316), trace_label);
}


Static Void plot_all_traces()
{
  trace *tp;
  Char STR1[8];
  Char STR2[256];
  Char STR3[256];
  Char STR4[256];

  /* Plot the oscilloscope graticule. */
  plot_graticule();

  sprintf(STR1, "%s:ON", ChannelOne);
  /* Find out which traces are on and plot them. */
  if (strpos2(vmode, STR1, 1) != 0)
    plot_trace(ch1y, center_point1, yoff1);
  sprintf(STR1, "%s:ON", ChannelTwo);
  if (strpos2(vmode, STR1, 1) != 0)
    plot_trace(ch2y, center_point2, yoff2);
  /* Plot any appended traces. */
  tp = append_list;
  while (tp != NULL) {
    plot_trace(tp->y, tp->center_point, tp->yoff);
    tp = tp->next;
  }

  /* Plot the waveform ID info as label. */
  if (*preamble1 != '\0' || *preamble2 != '\0') {
    sprintf(STR3, "%s; %s;", wfid(STR2, preamble1), wfid(STR4, preamble2));
    plot_title(STR3);
  }
  plot_finish();
}


Void write_traces_to_ps_file(filename)
Char *filename;
{
  FILE *ps_file;

  /* open output file */
  ps_file = NULL;
  if (ps_file != NULL)
    ps_file = freopen(filename, "w", ps_file);
  else
    ps_file = fopen(filename, "w");
  if (ps_file == NULL)
    _EscIO(FileNotFound);
  vscale = 1.6;   /* 512/10 = 256/8*vscale */
  plot_initps(&ps_file);
  plot_window(0L, 0L, 512L, 512L);
  plot_all_traces();
  if (ps_file != NULL)
    fclose(ps_file);
  ps_file = NULL;
  if (ps_file != NULL)
    fclose(ps_file);
}


Void display_traces_to_screen()
{
  vscale = 1.2;   /* 512/10 = 256/8*vscale */
  plot_initscreen(0L, 0L, 511L, 389L);
  plot_window(0L, 0L, 512L, 389L);
  plot_all_traces();
}


Void display_traces_to_plotter()
{
  vscale = 1.6;   /* 512/10 = 256/8*vscale */
  plot_init(0L, 'X');
  plot_window(0L, 0L, 512L, 512L);
  plot_all_traces();
}


/* of module */




/* End. */
