;:ts=8
	far	code
	far	data
;//  TT8 specific includes
;#include        <TT8.h>                 // Tattletale Model 8 Definitions
;#include        <tat332.h>              // 68332 Tattletale (7,8) Hardware Definitions
;#include        <sim332.h>              // 68332 System Integration Module Definitions
;#include        <qsm332.h>              // 68332 Queued Serial Module Definitions
;#include        <dio332.h>              // 68332 Digital I/O Port Pin Definitions
;#include        <tt8lib.h>              // definitions and prototypes for Model 8 library
;
;// general C includes
;#include        <stdio.h>
;#include        <stdlib.h>
;#include		<string.h>
;#include		<time.h>
;
;//  includes for our particular program
;#include		"assert.h"
;#include		"memcheck.h"
;#include		"ad7716.h"
;#include		"power.h"
;#include		"science.h"
;#include		"logtime.h"
	dseg
	ds	0
_LATEST_LOGGER_TIME:
	ds.b	0
	dc.l	$ffffffff
	dc.l	$0000
	cseg
	dseg
	ds	0
_EARLIEST_LOGGER_TIME:
	ds.b	0
	dc.l	$0000
	dc.l	$0000
	cseg
;#include		"logdisk.h"
;#include		"text_log.h"
;#include		"misc.h"
;#include		"MacTrimp.h"
;#include        "power.h"
;#include		"criterr.h"
;#include		"logger.h"
;
;
;//  includes for the disk routines
;#include		<pcdisk.h>
;
;static int disk_error = 0;
	dseg
	ds	0
_disk_error:
	dc.w	0
	cseg
;
;//  these routines and structures are intended for internal use only;
;//  routines intended for general use are declared in the .h file
;int sci_logger_buffer_init (int chan_n, int buffer_n, long size, int trigger);
;void sci_logger_buffer_delete (void);
;void sci_logger_buffer_empty (int buffer_n);
;void sci_logger_add_point (int n, long value);
;void sci_logger_trigger_on (short channel);
;void sci_logger_trigger_off (short channel);
;void sci_logger_power_on (void);
;void sci_logger_power_off (void);
;int sci_logger_compute_n (void);
;void sci_logger_preview_ASCII (int n);
;void sci_logger_preview_binary (int n);
;int sci_logger_write_file (int n);
;int sci_logger_write_buffer (int fd, int n_buff, long n_points);
;void sci_logger_set_header_time (int n);
;float sci_logger_value_to_voltage (short n, long value);
;#ifdef DEBUG
;void sci_logger_assert_file_size (char* fname, int buffer);
;void sci_logger_dump_data (void);
;#endif
;
;//  Default values for short and long term averages
;#define		DEFAULT_T_STA			0.50
;#define		DEFAULT_T_LTA           1000.0
;#define		DEFAULT_GAIN			2.50
;
;/*  struct science_buffer
; *
; *  There is one of these structures allocated for each active science
; *  channel.  The data pointer is NULL if no space is allocated.  If it
; *  is NULL, then no other variables in this structure are valid or have
; *  any meaning.
;*/ 
;struct science_buffer  {
;	struct MacTrimpi disk_header;
;						//  header data for this particular science buffer
;						//  this header data is updated whenever the logger
;						//  triggers, or when it completes a write to disk
;	#ifdef SHORT_SCIENCE_DATA
;		short* data;	//  pointer to start of science data circular buffer
;	#endif
;	#ifdef LONG_SCIENCE_DATA	
;		long* data;		//  pointer to start of science data circular buffer
;	#endif	
;	long n_data;		//  length of the data buffer (number of points)
;	long newest_data;	//  index of the newest point in the data buffer
;
;	float gain;			//  current gain of this channel
;	short channel_num;	//  A/D channel number from which this data came.
;
;	float t_pre_event;	//  Requested length of the pre-event data record in seconds.
;						//  This number is passed to us by the user
;	long n_pre_event;	//	Actual length of the pre-event data record in points.
;						//  This number is calculated from the user's time and the
;						//  current sample rate.  It may be reduced from the expected
;						//  value if the number exceeds the length of the science buffer
;	float t_post_event;	//  length of the post-event data record in seconds
;	long n_post_event;	//	length of the post-event data record in poitns
;	float t_STA;		//  length of short term average in seconds
;	long n_STA;			//  number of points in the STA
;	float t_LTA;		//  length of long term average in seconds
;	long n_LTA;			//  number of points in the LTA
;
;	float STA;			//  calculated value of short term average
;	float LTA;			//  calculated value of long term average
;	short trigger_chan;	//  non-zero if this particular channel should be
;						//  allowed to trigger the system.
;						//  Does not reflect at all on other channels
;	short chans_to_trigger;	//  when this channel is triggered, it forces other channels
;							//  to trigger as well; this specifies which other channels
;							//  are to be triggered.
;	float trigger_level;	//  ratio of STA/LTA at which we will trigger
;	short trigger_state;	//  can take on values of WAITING, TRIGGERED, or POST_EVENT
;	short trigger_request;	//  set non-zero whenever any channel requests that this
;							//  channel trigger
;	long n_post_event_left;		//  number of points remaining to collect in a
;								//  post event sequence
;	long n_waiting_to_write;	//  number of data point available to write to disk
;								//  Note that the data may be non-contiguous if the
;								//  buffer was wrapped around, as it often will be
;	long total_to_write;		//  total number of points which will be written to
;								//  disk as part of the current write cycle.  This data
;								//  is used to interpolate to update the start times of
;								//  files when multiple files are required to dump the
;								//  current data.  This is equal to n_waiting_to_write
;								//  when the write cycle start.
;	long n_written;				//  number of data points already written to disk
;								//  as part of the current file.
;	long total_written;			//  total number of points written to disk (any file)
;								//  during the current write cycle;
;	//  REVIEW - we probably have unnecessary code in here in that we force
;	//  next_to_write to be -1 if there are no data points waiting.  We could
;	//  just let it float
;    long next_to_write;			//  index of the next data point to write to disk.
;                        		//  this is set to -1 if we are not writing
;	double rate;				//  The calculated rate based on the above two parameters
;								//  and the number of points waiting.
;	time_tt start_time;			//  Time at which first point in buffer was collected
;								//  This time is set when we trigger ON and updated when
;								//  we write all data from the buffer to disk
;	time_tt end_time;			//  Time at which the last point in the buffer was/
;								//  collected.  This time is set when we actually go
;								//  to write the data to disk.
;	time_tt next_write_time;	//  Time at which the data pointed at by the index
;								//  next_to_write was collected.
;};
;
;
;
;
;
;
;/*  struct science_logger
; *
; *  holds the data related to the overall science logging operation.  A
; *  separate structure holds the data refering to a particular channel
; *
;*/
;struct science_logger {
;	struct science_buffer channel[N_SCI_CHANNELS];
;	int logger_open_flag;		//  non-zero if the logger is opened
;	int n_channels;				//  total number of channels being saved
;	int current_buffer;			//  science_buffer index to use when storing
;								//  the next piece of data to arrive
;	int ASCII_preview_chan;		//  channel to dump in ASCII when previewing data
;	int binary_preview_chan;	//  channel number to dump in binary when previewing data
;	long disk_threshold;		//  maximum number of points to accumulate
;								//  in the disk buffer before requesting a disk
;								//  access
;	long max_points_per_file;	//  maximum number of points to write to a data file
;	unsigned long n_collected;	//  counts initial points collected
;	int data_started;			//  non-zero if data is flowing
;};
;struct science_logger sci_logger;
;
;
;
;//  possible values of trigger_flag
;#define		WAITING		0
;#define		TRIGGERED	1
;#define		POST_EVENT	2
;//  The next few subroutines are error checking routines used during debug only.
;//  If the variable DEBUG is defined, they execute, otherwise they are defined
;//  as NOOP.  These must be the first routines in this file to insure that the
;//  'defines' work correctly.  These routines are not designed for error checking
;//  variables that the user enters.  That code is spread throughout the file.
;//  Rather, they are designed to insure that the internal variables
;//  describing what the code should do are all self-consistent, and that they
;//  won't crash the system when the code executes.  If an error is discovered,
;//  the code will abort and print an error message.  The routine
;//  sci_logger_assert_valid() should be callable at the start or finish of any
;//  of these routines without printing an error message.
;//
;#ifdef DEBUG
;void SCI_VALIDITY_FAILURE (void* exp, unsigned line1, unsigned line2);
;void sci_logger_assert_valid(unsigned calling_line);
;//  This is essentially a special version of ASSERT that allows us to print out
;//  two line numbers.  It is used only here for the sci_logger_assert_valid routine.
;//  It is useful because it allows us to print both the line number of the assert
;//  which failed and the line number from which we called the assert_valid routine.
;//  We don't bother to print the file name, because it is used only within this file
;//
;void SCI_VALIDITY_FAILURE (void* exp, unsigned line1, unsigned line2)  {
;	fflush (stdout);
;	fflush (stderr);
;	printf ("\n\n***************************************\n");
;	printf ("Science logger validity failure: %s @\n", (char*)exp);
;	printf ("  line %d, called from line %d\n", line1, line2);
;	printf ("***************************************\n");
;	sci_logger_dump_data ();
;	fflush (stdout);
;    fflush (stderr);
;	exit (-1);
;}
;#define TEST_VALID(exp) \
;	    ( (exp) ? (void) 0 : SCI_VALIDITY_FAILURE (#exp, __LINE__, calling_line) )
;//  sci_logger_assert_valid(void)
;//  Internal use only
;//  Debugging use only
;//
;//  This routine checks the internal consistency of the science logger
;//  data structure in every way that I can think of.  It should be updated
;//  any time the logger code is changed.
;//  If the variable DEBUG is not defined, then this subroutine is defined
;//	so as to be a NOOP.  See code immediately following the #else.
;//
;void sci_logger_assert_valid(unsigned calling_line)  {
;	int n, buffer;
;
;	TEST_VALID (sizeof (struct MacTrimpi) == 512);
;	if (sci_logger.logger_open_flag == 0)  {
;		//  not open.  make sure no data is allocated
;		for (n = 0;  n < N_SCI_CHANNELS;  n++)
;			TEST_VALID (sci_logger.channel[n].data == NULL);
;		return;
;	}
;	//  a value other than 0 or 1 would imply that a pointer went awry
;	TEST_VALID (sci_logger.logger_open_flag == 1);
;
;	//  if we get here, then we are open.  start by testing the variables
;	//  in the general science logger struct.  Most of these should be
;	//  obvious
;	TEST_VALID (sci_logger.n_channels >= 0);
;	if (sci_logger.n_channels > 0)
;		TEST_VALID (sci_logger.current_buffer < sci_logger.n_channels);
;	else
;		TEST_VALID (sci_logger.current_buffer == 0);	
;	TEST_VALID (sci_logger.n_channels <= N_SCI_CHANNELS);
;	TEST_VALID (sci_logger.current_buffer >= 0);
;	TEST_VALID (sci_logger.max_points_per_file > 1024);
;	//  The max is choosen arbitrarily.  This is about 136 minutes at
;	//  128 samples/second.  Increase it if you want.
;	TEST_VALID (sci_logger.max_points_per_file <= 1048576L);
;//	TEST_VALID (sci_logger.conversion_rate >= -1.0);
;	//  current limit, but no reason not to extend it higher
;//	TEST_VALID (sci_logger.conversion_rate < 258);
;	TEST_VALID (sci_logger.binary_preview_chan >= -1);
;	#ifdef REVA
;	TEST_VALID (sci_logger.binary_preview_chan <= N_SCI_CHANNELS);
;	TEST_VALID (sci_logger.binary_preview_chan != 0);
;	#endif
;	#ifdef REVB
;	TEST_VALID (sci_logger.binary_preview_chan < N_SCI_CHANNELS);
;	#endif
;	
;	TEST_VALID (sci_logger.ASCII_preview_chan >= -1);
;	#ifdef REVA
;	TEST_VALID (sci_logger.ASCII_preview_chan <= N_SCI_CHANNELS);
;	TEST_VALID (sci_logger.ASCII_preview_chan != 0);
;	#endif
;	#ifdef REVB
;	TEST_VALID (sci_logger.ASCII_preview_chan < N_SCI_CHANNELS);
;	#endif	
;
;	//  then test the variables in the individual science buffer structs
;	for (buffer = 0;  buffer < N_SCI_CHANNELS;  buffer++)  {
;		if (buffer >= sci_logger.n_channels)  {
;			//  If the channel is not in use, data should be NULL, and all
;			//  other variables are undefined and irrelavent
;			TEST_VALID (sci_logger.channel[buffer].data == NULL);
;			continue;
;		}
;
;		//  in use channels should have data allocated.  We could narrow this further
;		//  for use on the TT8 in that the pointer should point into RAM, which has
;		//  a limited and known range.
;		TEST_VALID (sci_logger.channel[buffer].data != NULL);
;		//  strictly, n_data must be > 0;  we arbitrarily up this to 512
;		TEST_VALID (sci_logger.channel[buffer].n_data >= 512);
;		TEST_VALID (sci_logger.channel[buffer].newest_data >= -1);
;		TEST_VALID (sci_logger.channel[buffer].newest_data < sci_logger.channel[buffer].n_data);
;		TEST_VALID (sci_logger.channel[buffer].n_waiting_to_write >= 0);
;		TEST_VALID (sci_logger.channel[buffer].n_waiting_to_write < sci_logger.channel[buffer].n_data);
;
;		if (sci_logger.channel[buffer].n_waiting_to_write > 0)
;			TEST_VALID (sci_logger.channel[buffer].next_to_write >= 0);
;		else
;			TEST_VALID (sci_logger.channel[buffer].next_to_write == -1);
;		TEST_VALID (sci_logger.channel[buffer].next_to_write < sci_logger.channel[buffer].n_data);
;		TEST_VALID (sci_logger.channel[buffer].channel_num < N_SCI_CHANNELS);
;		TEST_VALID (sci_logger.channel[buffer].channel_num >= 0);
;		
;		TEST_VALID (sci_logger.channel[buffer].t_pre_event >= 0);
;		TEST_VALID (sci_logger.channel[buffer].n_pre_event < sci_logger.channel[buffer].n_data);
;		TEST_VALID (sci_logger.channel[buffer].t_post_event >= 0);
;		TEST_VALID (sci_logger.channel[buffer].t_STA >= 0);
;		TEST_VALID (sci_logger.channel[buffer].t_LTA >= 0);
;		TEST_VALID (sci_logger.channel[buffer].STA >= 0);
;		TEST_VALID (sci_logger.channel[buffer].LTA >= 0);
;
;		//  can change this next one when we extend the logger to more channels
;		TEST_VALID ((sci_logger.channel[buffer].chans_to_trigger&0xFFF0) == 0);
;		TEST_VALID ((sci_logger.channel[buffer].trigger_state == POST_EVENT) ||
;					(sci_logger.channel[buffer].trigger_state == TRIGGERED ) ||
;					(sci_logger.channel[buffer].trigger_state == WAITING   )   );
;		//  not intrinsically important, but it may indicate the failure
;		//  of a pointer which led to an overwrite.
;		TEST_VALID ((sci_logger.channel[buffer].trigger_request == 0) ||
;					(sci_logger.channel[buffer].trigger_request == 1)   );
;	}
;}
;#else
;	#define sci_logger_assert_valid(exp) ((void)0)
;#endif
;
;
;
;
;//  sci_logger_power_on_init ()
;//  User callable
;//
;//	Inits variables to a known state when the logger is first powered
;//  on.  Note that 'power on' refers to the main computer, NOT to the
;//  science logger A/D converters.  We should therefore be sure that the
;//  outputs connected to converter digital lines are held low so that we
;//  don't accidently power the A/D or associated chips through the logic
;//  lines.
;//
;void sci_logger_power_on_init (void)  {
# 335 'science.c' 678929709
| .2
	xdef	_sci_logger_power_on_init
_sci_logger_power_on_init:
	movem.l	d2,-(sp)
;	int n;
;
;	#ifndef SHORT_SCIENCE_DATA
;		#ifndef LONG_SCIENCE_DATA
;			printf ("You must define either SHORT_SCIENCE_DATA or LONG_SCIENCE_DATA\n");
;			printf ("at compile time.\n");
;			ResetToMon ();
;		#endif
;	#endif		
;	#ifdef SHORT_SCIENCE_DATA
;		#ifdef LONG_SCIENCE_DATA
;			printf ("You must define only one of SHORT_SCIENCE_DATA or LONG_SCIENCE_DATA\n");
;			printf ("at compile time.\n");
;			ResetToMon ();
;		#endif
;	#endif		
;	
;	sci_logger.logger_open_flag = 0;
~ n d2 "i"
^^^^^^^^^^^^^^^^^^	clr.w	_sci_logger+2552
;	sci_logger.data_started = 0;
^	clr.w	_sci_logger+2574
;	for (n = 0;  n < N_SCI_CHANNELS;  n++)
^	move.l	#0,d2
.10003
;		sci_logger.channel[n].data = NULL;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	clr.l	(a0,d0.l)
.10001
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10003
.10002
;	sci_logger_assert_valid(__LINE__);
^;	
;	//  make sure the gain hardware is inited
;	PConfOutp (E, 3);
^^^;			PConfOutpE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa15
;	PConfOutp (E, 5);
^;			PConfOutpE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa15
;	PConfOutp (E, 6);
^;			PConfOutpE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa15
;	PConfOutp (E, 7);
^;			PConfOutpE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa15
;	PClear (E, 3);
^;			PClearE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa11
;	PClear (E, 5);
^;			PClearE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa11
;	PClear (E, 6);
^;			PClearE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa11
;	PClear (E, 7);
^;			PClearE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa11
;}
^.3
	movem.l	(sp)+,d2
	rts
.2
;
;		
;//  sci_logger_open ()
;//  User callable
;//
;//	This routine must be called before any other of the science logger routines
;//  are called.  It performs various memory allocations and initializations.
;//
;//	Returns: 0 if OK, negative otherwise.
;//  Failures: can fail only if memory allocations in the AD7716 init
;//		routine fails.
;//
;int sci_logger_open (void)  {
# 381
| .4
	xdef	_sci_logger_open
_sci_logger_open:
;	sci_logger_assert_valid(__LINE__);
^;    ASSERT (sci_logger.logger_open_flag == 0);
^;
;	//  first set the variable which tells other routines that the
;	//  logger is opened.  Without this, most of them will not respond
;	sci_logger.logger_open_flag = 1;
^^^^	move.w	#1,_sci_logger+2552
;	sci_logger.data_started = 0;
^	clr.w	_sci_logger+2574
;	
;	sci_logger.n_channels = 0;
^^	clr.w	_sci_logger+2554
;	sci_logger.current_buffer = 0;
^	clr.w	_sci_logger+2556
;	sci_logger.ASCII_preview_chan = -1;
^	move.w	#-1,_sci_logger+2558
;	sci_logger.binary_preview_chan = -1;
^	move.w	#-1,_sci_logger+2560
;	sci_logger.n_collected = 0;
^	clr.l	_sci_logger+2570
;	
;	//  Arbitrarily choosen file length.  Change it if you want, but for maximum disk
;	//  efficiency, make sure it remains an integer multiple of the length of a disk
;	//  allocation unit.  The standard disk allocation unit for big disks under the
;	//  FAT16 file system is 32k.  The standard disk allocation unit for FAT32 if
;	//  formatted by Windows is 4k.  However, if formatted using the routines that
;	//  come with the data logger it will be 32k.  This is done because I assume we
;	//  are always writting relatively large files, and because the file system will
;	//  be somewhat more efficient if we allocate disk in relatively large chunks.
;	#ifdef SHORT_SCIENCE_DATA
;		sci_logger.max_points_per_file = (SCIENCE_FILE_LENGTH-sizeof(struct MacTrimpi))/sizeof (short);
^^^^^^^^^^^	move.l	#261888,_sci_logger+2566
;	#endif
;	#ifdef LONG_SCIENCE_DATA	
;		sci_logger.max_points_per_file = (SCIENCE_FILE_LENGTH-sizeof(struct MacTrimpi))/sizeof (long);
;	#endif	
;
;	//  REVIEW - should we have a default conversion rate???
;	
;	//  turns power on and configures the port pins which control the
;	//  channel gain
;	sci_logger_power_on ();
^^^^^^^^^^	jsr	_sci_logger_power_on
;
;	//  Initialize the AD7716 interface, which sets the buffer length
;    //  A buffer length of 24576 points stores approximately 63 seconds
;    //	of data at 128 Hz if we are saving three channels.  The required
;    //  length is set by the time which we may go without collecting
;    //  data from the buffer.  In normal operation, this will be the time
;    //  required to write the full buffer to disk.  63 seconds appears
;    //  to be considerable overkill
;//	if (AD7716_open (4608L) < 0)  {
;	if (AD7716_open (AD7716_BUFFER_LENGTH) < 0)  {
^^^^^^^^^^	pea	49152
	jsr	_AD7716_open
	tst.w	d0
	add.w	#4,sp
	bge	.10004
;		sci_logger_power_off ();
^	jsr	_sci_logger_power_off
;		sci_logger.logger_open_flag = 0;
^	clr.w	_sci_logger+2552
;		return -1;
^	move.l	#-1,d0
.5
	rts
;	}
^;	sci_logger_assert_valid(__LINE__);
.10004
^;	return 0;
^	move.l	#0,d0
	bra	.5
;}
^.4
;
;
;	
;	
;	
;//  sci_logger_close
;//  User callable
;//
;//  This routine is called when the user is done with the science logger.
;//  It closes the low level interface to the AD, and returns all memory to
;//  the system.  The only science logger routine which can be called after
;//  this is the open routine.
;//
;//	NOTE: we do not flush the buffers to disk before closing the logger.
;//  If the user wants any data saved, call the disk_write routine first
;//
;void sci_logger_close (void)  {
# 449
| .6
	xdef	_sci_logger_close
_sci_logger_close:
;	sci_logger_assert_valid(__LINE__);
^;	//  NOOP if already closed
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10005
^.7
	rts
;
;	//  try to delete buffers in the reverse of the allocation order
;	sci_logger_buffer_delete ();
.10005
^^^	jsr	_sci_logger_buffer_delete
;
;	AD7716_close ();
^^	jsr	_AD7716_close
;	
;	//  turns power off and configures the port pins which control the
;	//  channel gain as outputs low so that we can avoid powering
;	//  the analog section through these outputs
;	sci_logger_power_off ();
^^^^^	jsr	_sci_logger_power_off
;	sci_logger.logger_open_flag = 0;
^	clr.w	_sci_logger+2552
;	
;	sci_logger_assert_valid(__LINE__);
^^;}
^	bra	.7
.6
;
;
;
;
;//  User callable
;int sci_logger_is_open (void)  {
# 473
| .8
	xdef	_sci_logger_is_open
_sci_logger_is_open:
;	ASSERT ((sci_logger.logger_open_flag == 0) || (sci_logger.logger_open_flag == 1));
^;	
;	return sci_logger.logger_open_flag;
^^	move.w	_sci_logger+2552,d0
.9
	rts
;}	
^.8
;
;
;
;
;
;//  sci_logger_activate_chans
;//  User callable
;//
;//  Sets which channels are recorded.  Each recorded channel is also triggered
;//  under the current code.  This is a user callable routine.
;//
;//  Arguments: bit pattern representing which channels are to be active.
;//	Returns: 0 if OK, negative on failure
;//	Failures: only on memory allocation errors in the channel_setup subroutine
;//
;//	NOTE that we do not restart the data stream at the end of this routine
;//
;int sci_logger_activate_chans (int record_chans)  {
# 495
| .10
	xdef	_sci_logger_activate_chans
_sci_logger_activate_chans:
	link	a6,#.11
	movem.l	d2/d3/d4/d5/d6/d7/a3/a4,-(sp)
	move.w	8(a6),d7
;	int trigger_chans, channel_bit;
;	int n, chan, n_chans;
;	long buffer_size;
;	sci_logger_assert_valid(__LINE__);
~ trigger_chans -2 "i"
~ channel_bit d6 "i"
~ n a3 "i"
~ chan d5 "i"
~ n_chans a4 "i"
~ buffer_size d4 "l"
~~ record_chans d7 "i"
^^^^;
;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10006
^	move.l	#0,d0
.12
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7/a3/a4
	unlk	a6
	rts
;	
;	//  Before setting new channels we have to turn off the data stream and
;	//  clear the buffers so that we can avoid mismatches when we change
;	//  which channels are included in the data stream
;	sci_logger_stop_data ();
.10006
^^^^^	jsr	_sci_logger_stop_data
;	sci_logger_buffer_delete ();
^	jsr	_sci_logger_buffer_delete
;
;	//  now tell the 7716 which channels to pass on to us
;	AD7716_set_channels (record_chans);
^^^	move.w	d7,-(sp)
	jsr	_AD7716_set_channels
;	
;	//  for now every recorded channel is a trigger channel
;	trigger_chans = record_chans;
^^^	move.w	d7,-2(a6)
;
;	//  count the number of channels so we can decide how much memory to
;	//  allocate to each.  It is important that other big users of memory
;	//  already have allocated what they need.  In particular, make sure
;	//  the AD7716 has grabbed its buffer already
;	n_chans = 0;
^^^^^^	sub.l	a4,a4
;	for (n = 0;  n < N_SCI_CHANNELS;  n++)  {
^	sub.l	a3,a3
	add.w	#2,sp
.10009
;		channel_bit = 0x01 << n;
^	move.w	a3,d0
	move.l	#1,d6
	asl.w	d0,d6
;		if (record_chans & channel_bit)
^;			n_chans++;
	move.w	d7,d0
	and.w	d6,d0
	beq	.10010
^	add.w	#1,a4
;	}
.10010
^.10007
	add.w	#1,a3
	cmp.w	#4,a3
	blt	.10009
.10008
;	buffer_size = mem_find_max_malloc ();
^	jsr	_mem_find_max_malloc
	move.l	d0,d4
;	//  don't use the last of the memory, as other routines may want some
;	//  small amount.  Hold back 3 k.
;	buffer_size -= 3*1024;
^^^	sub.l	#3072,d4
;
;	printf ("Total memory available for science buffers is %ld\n", buffer_size);
^^	move.l	d4,-(sp)
	pea	.1+0
	jsr	_printf
;	if (n_chans > 0)
^;		buffer_size /= n_chans;
	move.w	a4,d0
	add.w	#8,sp
	ble	.10011
^	move.l	d4,d0
	move.w	a4,d1
	ext.l	d1
	jsr	.divs#
	move.l	d0,d4
;	#ifdef SHORT_SCIENCE_DATA
;		buffer_size /= sizeof (short);
.10011
^^	lsr.l	#1,d4
;	#endif
;	#ifdef LONG_SCIENCE_DATA	
;		buffer_size /= sizeof (long);
;	#endif
;	//  Buffer size must be a multiple of 4 only because of the special
;	//  malloc routines which we use during debugging.  These routines
;	//  add space at each end of the buffer to use for error checking
;	//  so as to catch memory overuns.
;	if ((buffer_size%4) != 0)
^^^^^^^^^;		buffer_size -= (buffer_size%4);
	move.l	d4,d0
	move.l	#4,d1
	jsr	.mods#
	beq	.10012
^	move.l	d4,d0
	move.l	#4,d1
	jsr	.mods#
	sub.l	d0,d4
;	printf ("Each active science channel has a buffer which is %.1f seconds long\n",
.10012
^;								(float)(buffer_size/sci_logger_get_conversion_rate ()));
	jsr	_sci_logger_get_conversion_rate
	move.l	d1,d3
	move.l	d0,d2
	move.l	d4,d0
	jsr	.Pflt#
	jsr	.Pdiv#
	jsr	.dtof#
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.1+51
	jsr	_printf
;	printf ("at the current conversion rate.\n");
^^	pea	.1+120
	jsr	_printf
;
;	//  n_channels is zeroed by the bufer_delete routine
;	ASSERT (sci_logger.n_channels == 0);
^^^;	for (chan = 0;  chan < N_SCI_CHANNELS;  chan++)  {
^	move.l	#0,d5
	lea	16(sp),sp
.10015
;		channel_bit = 0x01 << chan;
^	move.l	#1,d6
	asl.w	d5,d6
;		if (record_chans & channel_bit)  {
^	move.w	d7,d0
	and.w	d6,d0
	beq	.10016
;			//  REVIEW - kinda a kluge which we do so that a trigger on any channel
;			//  will trigger all other channels.  This info not available at the
;			//  lower level of "buffer_init"
;			sci_logger.channel[sci_logger.n_channels].chans_to_trigger = record_chans;
^^^^	move.w	_sci_logger+2554,d0
	muls.w	#638,d0
	lea	_sci_logger+572,a0
	move.w	d7,(a0,d0.l)
;
;			//  this channel is active.  Init a buffer for the incoming data
;			if (sci_logger_buffer_init (chan, sci_logger.n_channels++,
^^^;											 buffer_size, trigger_chans&channel_bit) != 0)  {
	move.w	-2(a6),d0
	and.w	d6,d0
	move.w	d0,-(sp)
	move.l	d4,-(sp)
	move.w	_sci_logger+2554,d0
	add.w	#1,_sci_logger+2554
	move.w	d0,-(sp)
	move.w	d5,-(sp)
	jsr	_sci_logger_buffer_init
	tst.w	d0
	lea	10(sp),sp
	beq	.10017
^;				//  if we failed, delete all previous buffers
;				sci_logger_buffer_delete ();
^^	jsr	_sci_logger_buffer_delete
;				return -1;
^	move.l	#-1,d0
	bra	.12
;			}
^;			printf ("Science channel %d initialized\n", chan);
.10017
^	move.w	d5,-(sp)
	pea	.1+153
	jsr	_printf
;		}  else  {
^	add.w	#6,sp
	bra	.10018
.10016
;			//  trigger bit shouldn't be set unless channel bit is
;			ASSERT ((trigger_chans&channel_bit) == 0);
^^;			;
^;		}	
^.10018
;	}
^.10013
	add.w	#1,d5
	cmp.w	#4,d5
	blt	.10015
.10014
;
;	sci_logger.current_buffer = 0;      	//  1st data point goes to buffer 0
^^	clr.w	_sci_logger+2556
;	sci_logger_set_binary_preview (-1);		//  all data preview turned off
^	move.w	#-1,-(sp)
	jsr	_sci_logger_set_binary_preview
;	sci_logger_set_ASCII_preview (-1);
^	move.w	#-1,-(sp)
	jsr	_sci_logger_set_ASCII_preview
;	
;	//  REVIEW - where should the threshold be set - this algorithm allows 5 seconds
;	sci_logger.disk_threshold = buffer_size - 5*sci_logger_get_conversion_rate ();
^^^	jsr	_sci_logger_get_conversion_rate
	move.l	#$00000000,d3
	move.l	#$40140000,d2
	jsr	.Pmul#
	move.l	d1,d3
	move.l	d0,d2
	move.l	d4,d0
	jsr	.Pflt#
	jsr	.Psub#
	jsr	.Pfix#
	move.l	d0,_sci_logger+2562
;	if (sci_logger.disk_threshold < 0)
^;		sci_logger.disk_threshold = buffer_size/2;
	tst.l	_sci_logger+2562
	add.w	#4,sp
	bge	.10019
^	move.l	d4,d0
	move.l	#2,d1
	jsr	.divs#
	move.l	d0,_sci_logger+2562
;
;	sci_logger_assert_valid(__LINE__);
.10019
^^;	return 0;
^	move.l	#0,d0
	bra	.12
;}
^.10
.11	equ	-2
.1
	dc.b	84,111,116,97,108,32,109,101,109,111,114,121,32,97,118
	dc.b	97,105,108,97,98,108,101,32,102,111,114,32,115,99,105
	dc.b	101,110,99,101,32,98,117,102,102,101,114,115,32,105,115
	dc.b	32,37,108,100,10,0,69,97,99,104,32,97,99,116,105
	dc.b	118,101,32,115,99,105,101,110,99,101,32,99,104,97,110
	dc.b	110,101,108,32,104,97,115,32,97,32,98,117,102,102,101
	dc.b	114,32,119,104,105,99,104,32,105,115,32,37,46,49,102
	dc.b	32,115,101,99,111,110,100,115,32,108,111,110,103,10,0
	dc.b	97,116,32,116,104,101,32,99,117,114,114,101,110,116,32
	dc.b	99,111,110,118,101,114,115,105,111,110,32,114,97,116,101
	dc.b	46,10,0,83,99,105,101,110,99,101,32,99,104,97,110
	dc.b	110,101,108,32,37,100,32,105,110,105,116,105,97,108,105
	dc.b	122,101,100,10,0
	ds	0
;
;
;
;
;//  sci_logger_set_ASCII_preview (int channel)
;//  User callable
;//
;//	This is a user callable routine.  It specifies which data channel is to
;//  be returned for previewing in ASCII format.
;//
;void sci_logger_set_ASCII_preview (int channel)  {
# 598
| .14
	xdef	_sci_logger_set_ASCII_preview
_sci_logger_set_ASCII_preview:
	movem.l	d2,-(sp)
	move.w	8(sp),d2
;	sci_logger_assert_valid(__LINE__);
~~ channel d2 "i"
^;
;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^^;		return;
	tst.w	_sci_logger+2552
	bne	.10020
^.15
	movem.l	(sp)+,d2
	rts
;	
;	//  negative channel number turns off preview
;	if (channel < 0)  {
.10020
^^^	tst.w	d2
	bge	.10021
;		sci_logger.ASCII_preview_chan = -1;
^	move.w	#-1,_sci_logger+2558
;		return;
^	bra	.15
;	}
^;
;	//  REVIEW - not yet enabled for 8 channel hardware; somewhat complicated
;	//  because we will need to include the A/D address bits
;	if (channel >= 4)
.10021
^^^^;		return;
	cmp.w	#4,d2
	blt	.10022
^	bra	.15
;	sci_logger.ASCII_preview_chan = channel;
.10022
^	move.w	d2,_sci_logger+2558
;	sci_logger_assert_valid(__LINE__);
^;	return;
^	bra	.15
;}	
^.14
;
;
;
;
;//  sci_logger_set_ASCII_preview (int channel)
;//  User callable
;//
;//	This is a user callable routine.  It specifies which data channel is to
;//  be returned for previewing in binary format.
;//
;void sci_logger_set_binary_preview (int channel)  {
# 629
| .16
	xdef	_sci_logger_set_binary_preview
_sci_logger_set_binary_preview:
	movem.l	d2,-(sp)
	move.w	8(sp),d2
;	sci_logger_assert_valid(__LINE__);
~~ channel d2 "i"
^;
;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^^;		return;
	tst.w	_sci_logger+2552
	bne	.10023
^.17
	movem.l	(sp)+,d2
	rts
;	
;	if (channel < 0)  {
.10023
^^	tst.w	d2
	bge	.10024
;		sci_logger.binary_preview_chan = -1;
^	move.w	#-1,_sci_logger+2560
;		return;
^	bra	.17
;	}
^;
;	//  REVIEW - not yet enabled for 8 channel hardware; somewhat complicated
;	//  because we will need to include the A/D address bits
;	if (channel >= 4)
.10024
^^^^;		return;
	cmp.w	#4,d2
	blt	.10025
^	bra	.17
;	sci_logger.binary_preview_chan = channel;
.10025
^	move.w	d2,_sci_logger+2560
;	sci_logger_assert_valid(__LINE__);
^;	return;
^	bra	.17
;}	
^.16
;
;
;
;
;//  sci_logger_start_data (void)
;//  User callable
;//
;//  This routine inits the A/D converter and starts the data flow.
;//  Make sure that sci_logger_open() was called first.  This routine
;//  is user callable
;//
;//	Returns: 0 if all is OK; negative on failure
;//  Failures: Only if we cannot init the A/D.
;//
;void sci_logger_start_data (void)  {
# 663
| .18
	xdef	_sci_logger_start_data
_sci_logger_start_data:
;	sci_logger_assert_valid(__LINE__);
^;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10026
^.19
	rts
;
;	//  verify that power is on and QSPI set up
;	ASSERT (1);
.10026
^^^;	
;	//  REVIEW
;	//  delete this when debugging is complete
;//	AD7716_critical_data_dump ();
;
;	//  reset will empty the buffers and reset the actual A/D chip
;	AD7716_start_data ();
^^^^^^^	jsr	_AD7716_start_data
;	sci_logger.data_started = 1;
^	move.w	#1,_sci_logger+2574
;	sci_logger_assert_valid(__LINE__);
^;}
^	bra	.19
.18
;
;
;
;
;//  sci_logger_stop_data ()
;//  User callable
;//
;//  Stops the data collection routines; resets the buffers; the next
;//  start will not produce contiguous data with the current data.  The A/D
;//  hardware does not actually stop; it can't.  Rather, we just stop listening
;//  to it.  User callable.
;//
;void sci_logger_stop_data (void)  {
# 693
| .20
	xdef	_sci_logger_stop_data
_sci_logger_stop_data:
	movem.l	d2,-(sp)
;	int n;
;	sci_logger_assert_valid(__LINE__);
~ n d2 "i"
^^;
;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^^;		return;
	tst.w	_sci_logger+2552
	bne	.10027
^.21
	movem.l	(sp)+,d2
	rts
;
;	//  first stop the low-level routines
;	AD7716_stop_data ();
.10027
^^^	jsr	_AD7716_stop_data
;	
;	//  now empty the local buffers for the science logger
;//printf ("Stopdata empties %d buffers.\n", sci_logger.n_channels);	
;	for (n = 0;  n < sci_logger.n_channels;  n++)
^^^^	move.l	#0,d2
	bra	.10031
.10030
;		sci_logger_buffer_empty (n);
^	move.w	d2,-(sp)
	jsr	_sci_logger_buffer_empty
	add.w	#2,sp
.10028
	add.w	#1,d2
.10031
	cmp.w	_sci_logger+2554,d2
	blt	.10030
.10029
;//printf ("Done.\n");		
;	
;	sci_logger.data_started = 0;
^^^	clr.w	_sci_logger+2574
;	sci_logger_assert_valid(__LINE__);
^;	return;
^	bra	.21
;}
^.20
;
;
;
;//  sci_logger_pause_data ()
;//  User callable
;//
;//  Used to temporarily pause the collection of data from the science A/D
;//  when we expect to resume shortly.  The user should call sci_logger_resume()
;//  as quickly as possible in order to insure that no data is lost.  This
;//  routine is called when the user needs to usurp the QSPI interface for
;//  use with other peripherals.  User callable.
;//
;void sci_logger_pause_data (void)  {
# 726
| .22
	xdef	_sci_logger_pause_data
_sci_logger_pause_data:
;	sci_logger_assert_valid(__LINE__);
^;
;	//  REVIEW - suppose the logger is open, but the data isn't flowing
;
;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag != 0)
^^^^^;		AD7716_pause_data ();
	tst.w	_sci_logger+2552
	beq	.10032
^	jsr	_AD7716_pause_data
;}
.10032
^.23
	rts
.22
;
;
;
;
;//  sci_logger_resume_data ()
;//  User callable
;//
;//  Resumes data collection where it left off when sci_logger_pause was
;//  called.  Does not check to insure that no data was lost.
;//
;void sci_logger_resume_data (void)  {
# 745
| .24
	xdef	_sci_logger_resume_data
_sci_logger_resume_data:
;	//  Don't call the assert_valid routine at the start because we are
;	//  in a hurry to restore the interrupt handler.
;	//  Don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag != 0)
^^^^;		AD7716_resume_data ();
	tst.w	_sci_logger+2552
	beq	.10033
^	jsr	_AD7716_resume_data
;	sci_logger_assert_valid(__LINE__);
.10033
^;}
^.25
	rts
.24
;
;			       
;
;
;//  sci_logger_buffer_init (int chan_n, int buffer_n, long size, int trigger)
;//  Internal use only
;//
;//  Initializes a buffer for a particular one of the available
;//  science channels.  This includes allocating memory for the data
;//  buffer and initing variables such as the STA and LTA.
;//
;//  Arguments: chan_n = the channel number to init; range >= 0 to < N_SCI_CHANNELS
;//			   buffer_n = the buffer number to use for this channel
;//	           size = the number of points to store in the buffer
;//			   trigger: non-zero if we should calculate triggering for
;//						this channel
;//  Returns: 0 if OK, negative on failure
;//  Failures: can fail only if the allocation of space fails
;// 
;int sci_logger_buffer_init (int chan_n, int buffer_n, long size, int trigger)  {
# 772
| .26
	xdef	_sci_logger_buffer_init
_sci_logger_buffer_init:
	movem.l	d2/d3/d4,-(sp)
	move.w	16(sp),d3
	move.w	18(sp),d2
	move.l	20(sp),d4
;	ASSERT ((buffer_n >= 0) && (buffer_n < N_SCI_CHANNELS));
~~ chan_n d3 "i"
~~ buffer_n d2 "i"
~~ size d4 "l"
~~ trigger 16 "i"
^;	ASSERT (sci_logger.channel[buffer_n].data == NULL);
^;	ASSERT (sci_logger.logger_open_flag == 1);
^;	ASSERT (chan_n >= 0);
^;	ASSERT (chan_n < N_SCI_CHANNELS);
^;	//  the assert valid routine will not pass here because we are in the
;	//  middle of allocating the data structures, and the variables are not
;	//  yet self-consistent
;
;	#ifdef DEBUG
;	printf ("channel %d turned on; buffer %d used\n", chan_n, buffer_n);
;	#endif
;
;	//  allocate space for the circular buffer
;	#ifdef SHORT_SCIENCE_DATA
;		sci_logger.channel[buffer_n].data = (short *)malloc (sizeof(short)*size);
^^^^^^^^^^^	move.l	d4,d0
	add.l	d0,d0
	move.l	d0,-(sp)
	jsr	_malloc
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+512,a0
	move.l	d0,(a0,d1.l)
;	#endif
;	#ifdef LONG_SCIENCE_DATA	
;		sci_logger.channel[buffer_n].data = (long *)malloc (sizeof(long)*size);
;	#endif	
;
;//	printf ("sci_logger: just malloc'd 0x%lX\n", (long)sci_logger.channel[buffer_n].data);	
;	if (sci_logger.channel[buffer_n].data == NULL)  {
^^^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	tst.l	(a0,d0.l)
	add.w	#4,sp
	bne	.10034
;		printf ("Apparent programming error: could not allocate memory.\n");
^	pea	.13+0
	jsr	_printf
;		log_printf ("sci_logger_buffer_init: ");
^	pea	.13+56
	jsr	_log_printf
;		log_printf ("Failed to allocate space for science channel %d\n", chan_n);
^	move.w	d3,-(sp)
	pea	.13+81
	jsr	_log_printf
;		return -1;
^	move.l	#-1,d0
	lea	14(sp),sp
.27
	movem.l	(sp)+,d2/d3/d4
	rts
;	}
^;	sci_logger.channel[buffer_n].n_data = size;
.10034
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	d4,(a0,d0.l)
;	//  REVIEW
;	//  why do we have this half-assed init of some variables to default
;	//  values.  if we keep, shouldn't we do this using the standard
;	//  routines?
;	sci_logger.channel[buffer_n].t_STA = DEFAULT_T_STA;
^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+546,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$3f000000,(a1)
;	sci_logger.channel[buffer_n].t_LTA = DEFAULT_T_LTA;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+554,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$447a0000,(a1)
;	sci_logger.channel[buffer_n].t_pre_event = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+530,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$00000000,(a1)
;	sci_logger.channel[buffer_n].t_post_event = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+538,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$00000000,(a1)
;	sci_logger_compute_n ();
^	jsr	_sci_logger_compute_n
;	sci_logger.channel[buffer_n].channel_num = chan_n;	
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	d3,(a0,d0.l)
;
;	//  non-zero if we are triggering on this channel
;	sci_logger.channel[buffer_n].trigger_chan = trigger;
^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+570,a0
	move.w	24(sp),(a0,d0.l)
;	#ifdef DEBUG
;	printf ("Channel %d is %striggered\n", chan_n, ((trigger != 0) ? "":"not "));
;	#endif
;
;//if (trigger == 0)
;//	printf ("channel %d on buffer %d is NOT triggered.\n", chan_n, buffer_n);	
;//else
;//	printf ("triggering will be calculated for channel %d on buffer %d.\n", chan_n, buffer_n);	
;
;	//  mark the buffer as empty and set default gain
;	sci_logger_buffer_empty (buffer_n);
^^^^^^^^^^^	move.w	d2,-(sp)
	jsr	_sci_logger_buffer_empty
;	sci_logger_set_gain (chan_n, DEFAULT_GAIN);
^	move.l	#$40200000,-(sp)
	move.w	d3,-(sp)
	jsr	_sci_logger_set_gain
;	
;	//  The maximum number of points to write is choosen so that the total
;	//  file length, including the 512 byte header, will equal 128 blocks of
;	//  512 bytes each.  For a 2 GigByte disk, this is the minimum allocation
;	//  unit.  This therefore should also be the minimum file length.
;
;	//  REVIEW - we could probably change this to force the logger to save
;	//  data in complete disk allocation units (clusters).
;	return 0;
^^^^^^^^^	move.l	#0,d0
	add.w	#8,sp
	bra	.27
;}
^.26
.13
	dc.b	65,112,112,97,114,101,110,116,32,112,114,111,103,114,97
	dc.b	109,109,105,110,103,32,101,114,114,111,114,58,32,99,111
	dc.b	117,108,100,32,110,111,116,32,97,108,108,111,99,97,116
	dc.b	101,32,109,101,109,111,114,121,46,10,0,115,99,105,95
	dc.b	108,111,103,103,101,114,95,98,117,102,102,101,114,95,105
	dc.b	110,105,116,58,32,0,70,97,105,108,101,100,32,116,111
	dc.b	32,97,108,108,111,99,97,116,101,32,115,112,97,99,101
	dc.b	32,102,111,114,32,115,99,105,101,110,99,101,32,99,104
	dc.b	97,110,110,101,108,32,37,100,10,0
	ds	0
;
;
;//  sci_logger_buffer_empty
;//  Internal use only
;//
;//  Marks a buffer as being empty of data
;//
;void sci_logger_buffer_empty (int buffer_n)  {
# 844
| .29
	xdef	_sci_logger_buffer_empty
_sci_logger_buffer_empty:
	movem.l	d2/d3,-(sp)
	move.w	12(sp),d2
;	long n;
;
;	//  REVIEW - are the following necessary?
;	ASSERT (sci_logger.channel[buffer_n].data != NULL);
~ n d3 "l"
~~ buffer_n d2 "i"
^^^^;	ASSERT (sci_logger.logger_open_flag == 1);
^;	if (sci_logger.channel[buffer_n].data == NULL)
^;		return;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	tst.l	(a0,d0.l)
	bne	.10035
^.30
	movem.l	(sp)+,d2/d3
	rts
;	if (sci_logger.logger_open_flag == 0)
.10035
^;		return;	
	tst.w	_sci_logger+2552
	bne	.10036
^	bra	.30
;
;	sci_logger.channel[buffer_n].newest_data = -1;
.10036
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.l	#-1,(a0,d0.l)
;	sci_logger.channel[buffer_n].STA = 0.0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+562,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$00000000,(a1)
;	sci_logger.channel[buffer_n].LTA = 0.0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+566,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	#$00000000,(a1)
;	sci_logger.n_collected = 0;
^	clr.l	_sci_logger+2570
;
;	sci_logger.channel[buffer_n].next_to_write = -1;
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	#-1,(a0,d0.l)
;	sci_logger.channel[buffer_n].n_waiting_to_write = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	clr.l	(a0,d0.l)
;	sci_logger.channel[buffer_n].n_written = -1;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	move.l	#-1,(a0,d0.l)
;	
;	sci_logger.channel[buffer_n].trigger_state = WAITING;
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	clr.w	(a0,d0.l)
;	sci_logger.channel[buffer_n].trigger_request = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	clr.w	(a0,d0.l)
;
;	//  Fill the buffer with the starting value
;	for (n = 0;  n < sci_logger.channel[buffer_n].n_data; n++)
^^^	move.l	#0,d3
	bra	.10040
.10039
;		sci_logger.channel[buffer_n].data[n] = 0x0;
^	move.l	d3,d0
	add.l	d0,d0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+512,a0
	move.l	(a0,d1.l),a0
	clr.w	(a0,d0.l)
.10037
	add.l	#1,d3
.10040
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	(a0,d0.l),d0
	cmp.l	d3,d0
	bgt	.10039
.10038
;}	
^	bra	.30
.29
;
;
;
;
;//  sci_logger_buffer_delete (int buffer_n)
;//  Internal use only
;//
;//	Deletes all memory associated with all of the science buffers.
;//  In debug mode, sets various variables to illegal values in the
;//  hopes that we will catch the error if we later try to use this
;//  memory without re-allocating it.  Internal use only.
;//
;void sci_logger_buffer_delete (void)  {
# 883
| .31
	xdef	_sci_logger_buffer_delete
_sci_logger_buffer_delete:
	movem.l	d2,-(sp)
;	int buffer_n;
;	ASSERT (sci_logger.logger_open_flag == 1);
~ buffer_n d2 "i"
^^;
;	//  We are careful to free memory in the reverse of the allocation
;	//  order because of a possible bug in the Aztec memory routines
;	for (buffer_n = N_SCI_CHANNELS-1;  buffer_n >= 0;  buffer_n--)  {
^^^^	move.l	#3,d2
.10043
;		if (sci_logger.channel[buffer_n].data == NULL)
^;			continue;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	tst.l	(a0,d0.l)
	beq	.10041
;		#ifdef DEBUG
;			sci_logger.channel[buffer_n].n_data = -2;
;			sci_logger.channel[buffer_n].newest_data = -2;
;			sci_logger.channel[buffer_n].STA = -1.0;
;			sci_logger.channel[buffer_n].LTA = -1.0;
;			sci_logger.channel[buffer_n].n_STA = -1;
;			sci_logger.channel[buffer_n].n_LTA = -1;
;			sci_logger.channel[buffer_n].channel_num = 0xCC;
;			sci_logger.channel[buffer_n].trigger_chan = 0xCC;
;			sci_logger.channel[buffer_n].next_to_write = -2;
;			sci_logger.channel[buffer_n].n_waiting_to_write = -2;
;			sci_logger.channel[buffer_n].n_written = -2;
;		#endif
;//		printf ("sci_logger: about to free 0x%lX\n", (long)sci_logger.channel[buffer_n].data);	
;		ASSERT (sci_logger.channel[buffer_n].data != NULL);
^^^^^^^^^^^^^^^^;		free (sci_logger.channel[buffer_n].data);
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	move.l	(a0,d0.l),-(sp)
	jsr	_free
;		sci_logger.channel[buffer_n].data = NULL;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	clr.l	(a0,d0.l)
;	}
^	add.w	#4,sp
.10041
	sub.w	#1,d2
	tst.w	d2
	bge	.10043
.10042
;	sci_logger.n_channels = 0;
^	clr.w	_sci_logger+2554
;	sci_logger.current_buffer = 0;
^	clr.w	_sci_logger+2556
;	return;
^.32
	movem.l	(sp)+,d2
	rts
;}
^.31
;			
;
;
;
;/*  int sci_logger_collect (int max_to_collect)
; *  User callable
; *
; *  Transfers data out of the AD7716's SPI buffer and into the science
; *  data buffers.  This includes conversion of the data to a long and
; *	the calculation of the STA and LTA appropriate for this particular
; *  channel.  User callable
; *
; *	Arguments: max_to_collect is the maximum number of points to pull
; *				from the buffer before returning.  The routine may return
; *				after pulling fewer if there are not enough in the
; *				buffer. This allows for a sort of cooperative timesharing to
; *				prevent this routine from taking too much time in a single
; *				block.
; *	Returns: number of points read
; *  Failures: none
; *
;*/
;int sci_logger_collect (int max_to_collect)  {
# 936
| .33
	xdef	_sci_logger_collect
_sci_logger_collect:
	link	a6,#.34
	movem.l	d2/d3/d4,-(sp)
	move.w	8(a6),d4
;	int n, buff;
;	long value;
;//	int trigger;
;
;	sci_logger_assert_valid(__LINE__);
~ n d3 "i"
~ buff d2 "i"
~ value -4 "l"
~~ max_to_collect d4 "i"
^^^^^;	//  don't respond if the logger isn't open
;	if (sci_logger.logger_open_flag == 0)
^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10044
^	move.l	#0,d0
.35
	movem.l	(sp)+,d2/d3/d4
	unlk	a6
	rts
;
;	//  try to always collect data in sets as they were collected
;	//  from the A/D converter
;	max_to_collect *= sci_logger.n_channels;
.10044
^^^^	muls.w	_sci_logger+2554,d4
;	for (n = 0;  n < max_to_collect;  n++)  {
^	move.l	#0,d3
	bra	.10048
.10047
;		//  returns 0 if data was available
;		if (AD7716_get_data_point (&value) != 0)
^^;			break;
	pea	-4(a6)
	jsr	_AD7716_get_data_point
	tst.w	d0
	add.w	#4,sp
	bne	.10046
;
;		//  If we got a point, then add it to the appropriate buffer
;		sci_logger_add_point (sci_logger.current_buffer, value);
^^^^	move.l	-4(a6),-(sp)
	move.w	_sci_logger+2556,-(sp)
	jsr	_sci_logger_add_point
;		
;		//  update the current buffer number
;		sci_logger.current_buffer++;
^^^	add.w	#1,_sci_logger+2556
;		if (sci_logger.current_buffer < sci_logger.n_channels)
^;			continue;
	move.w	_sci_logger+2556,d0
	cmp.w	_sci_logger+2554,d0
	add.w	#6,sp
	blt	.10045
;			
;		//  We ONLY get to this point each time we have been through all the
;		//  active science channels once.
;		//  Reset the current buffer counter, so additional points go to
;		//  the correct buffers
;		sci_logger.current_buffer = 0;
^^^^^^^	clr.w	_sci_logger+2556
;
;		//  It is difficult to properly calculate triggering when we are
;		//  first turned on, because the algorithm we use for the STA and
;		//  LTA give spurious results until we have at least a few times
;		//  n_STA and n_LTA worth of point accumulated.  This doesn't
;		//  really matter, except that it makes logger demonstrations look bad
;		//  when the instrument shows false triggers.  So this code is really 
;		//  here more for demos than real use.  It checks to see if we have
;		//  accumulated more than a few seconds of data, and if so, it arbitrarily
;		//  sets the long term average to the short term average.  This too can
;		//  give spurious results, but it is the easiest solution, and the flaws
;		//  in the approach aren't really important
;		if (sci_logger.n_collected < 6*sci_logger.channel[0].n_STA)  {
^^^^^^^^^^^^^	move.l	_sci_logger+550,d0
	move.l	d0,d1
	lsl.l	#1,d0
	add.l	d1,d0 
	lsl.l	#1,d0
	cmp.l	_sci_logger+2570,d0
	bls	.10049
;			sci_logger.n_collected++;
^	add.l	#1,_sci_logger+2570
;			continue;
^	bra	.10045
;		}	
^;
;		if (sci_logger.n_collected == 6*sci_logger.channel[0].n_STA)  {
.10049
^^	move.l	_sci_logger+550,d0
	move.l	d0,d1
	lsl.l	#1,d0
	add.l	d1,d0 
	lsl.l	#1,d0
	cmp.l	_sci_logger+2570,d0
	bne	.10050
;			sci_logger.n_collected++;
^	add.l	#1,_sci_logger+2570
;			for (buff = 0;  buff < sci_logger.n_channels;  buff++)  {
^	move.l	#0,d2
	bra	.10054
.10053
;				sci_logger.channel[buff].LTA = sci_logger.channel[buff].STA;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+562,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+566,a0
	move.l	d0,a2
	add.l	a0,a2
	move.l	(a1),(a2)
;				sci_logger.channel[buff].trigger_request = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	clr.w	(a0,d0.l)
;			}	
^.10051
	add.w	#1,d2
.10054
	cmp.w	_sci_logger+2554,d2
	blt	.10053
.10052
;			continue;
^	bra	.10045
;		}		
^;
;		//  VERY IMPORTANT
;		//  REVIEW
;		//  When we complete the data collection on a particular channel, we must
;		//  immediately stop data collection and return so that the main routines 
;		//  can call the disk write routines and dump the data.  If we don't do this,
;		//  then the next few points might retrigger the logger and overwrite the
;		//	header data which may not have yet been flushed to disk
;
;		//  now go through each active channel and see if any channel requested
;		//  that it be triggered.  Adjust the data stream state as appropriate
;		for (buff = 0;  buff < sci_logger.n_channels;  buff++)  {
.10050
^^^^^^^^^^^^	move.l	#0,d2
	bra	.10058
.10057
;			switch (sci_logger.channel[buff].trigger_state)  {
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	move.w	(a0,d0.l),d0
	bra	.10059
;				case TRIGGERED:
^.10061
;					if (sci_logger.channel[buff].trigger_request == 0)
^;						sci_logger_trigger_off (sci_logger.channel[buff].channel_num);
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	tst.w	(a0,d0.l)
	bne	.10062
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	jsr	_sci_logger_trigger_off
;					break;
	add.w	#2,sp
.10062
^	bra	.10060
;				
;				case WAITING:
^^.10063
;					if (sci_logger.channel[buff].trigger_request)
^;						sci_logger_trigger_on (sci_logger.channel[buff].channel_num);
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	tst.w	(a0,d0.l)
	beq	.10064
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	jsr	_sci_logger_trigger_on
;					break;	
	add.w	#2,sp
.10064
^	bra	.10060
;			
;				case POST_EVENT:
^^.10065
;					if (sci_logger.channel[buff].trigger_request)
^;						sci_logger_trigger_on (sci_logger.channel[buff].channel_num);
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	tst.w	(a0,d0.l)
	beq	.10066
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	jsr	_sci_logger_trigger_on
;					else  {
	add.w	#2,sp
	bra	.10067
.10066
^;						if (sci_logger.channel[buff].n_post_event_left <= 0)  {
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+582,a0
	tst.l	(a0,d0.l)
	bgt	.10068
;							#ifdef DEBUG
;								printf ("Switched from post-event to waiting.\n");					
;							#endif
;							sci_logger.channel[buff].trigger_state = WAITING;
^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	clr.w	(a0,d0.l)
;						}	
^;					}
.10068
^.10067
;					break;	
^	bra	.10060
;					
;				default:
^^.10069
;					#ifdef DEBUG
;						printf ("Unknown value for trigger flag.\n");
;						ASSERT (0);
;					#endif
;					sci_logger.channel[buff].trigger_state = WAITING;
^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	clr.w	(a0,d0.l)
;			}
^	bra	.10060
.10059
	tst.w	d0
	beq	.10063
	sub.w	#1,d0
	beq	.10061
	sub.w	#1,d0
	beq	.10065
	bra	.10069
.10060
;			//  reset the trigger request flag for the next loop through the buffer
;			sci_logger.channel[buff].trigger_request = 0;
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	clr.w	(a0,d0.l)
;		}	
^.10055
	add.w	#1,d2
.10058
	cmp.w	_sci_logger+2554,d2
	blt	.10057
.10056
;	}
^.10045
	add.w	#1,d3
.10048
	cmp.w	d4,d3
	blt	.10047
.10046
;	
;	#ifdef DEBUG
;	sci_logger_assert_valid(__LINE__);
;	AD7716_assert_valid (-1);
;	#endif	
;
;	//  return the number of points processed		
;	return n;
^^^^^^^^	move.w	d3,d0
	bra	.35
;}
^.33
.34	equ	-4
;
;
;
;
;/*  sci_logger_add_point (int n, long value)
; *  Internal use only
; *
; *	Adds a single point to the requested science buffer, including the
; *	calculation of LTA and STA as apppropriate.  Internal use only
; *
; *  Arguments: n = the channel number to add this point to
; *			   value = the value to add to this channel
; *	Returns: none
; *  Failures: none
; *
;*/
;void sci_logger_add_point (int n, long value)  {
# 1064
| .36
	xdef	_sci_logger_add_point
_sci_logger_add_point:
	movem.l	d2/d3/d4/d5,-(sp)
	move.w	20(sp),d2
	move.l	22(sp),d3
;	int m, k;
;	ASSERT (sci_logger.channel[n].data != NULL);
~ m d4 "i"
~ k d5 "i"
~~ n d2 "i"
~~ value d3 "l"
^^;	ASSERT (sci_logger.logger_open_flag == 1);
^;
;	#ifdef DEBUG
;//	if (sci_logger.channel[n].channel_num != AD7716_get_channel_num (value))  {
;//		printf ("Impending assertion failure.\n");
;//		printf ("'newest_data' = %ld\n", sci_logger.channel[n].newest_data);
;//		printf ("channel buffer index = %d\n", n);
;//		printf ("offending value = 0x%08lX\n", value);
;//	}	
;	#endif					
;
;//	printf ("Latest value = 0x%08lX\n", value);
;//	printf ("channel_num = 0x%04X\n", sci_logger.channel[n].channel_num);
;//	printf ("value = 0x%08lX\n", value);
;//	for (nn = 0;  nn < 8;  nn++)
;//		printf ("SPIRCV[%d] = 0x%04X\n", nn, shit[nn]);
;//	ASSERT (n == 0);
;//	ASSERT (sci_logger.channel[0].channel_num == 0);
;	
;	//  verify that the channel number from the A/D matches the channel
;	//  number of the software buffer.
;	#ifdef DEBUG	
;	if (sci_logger.channel[n].channel_num != AD7716_get_channel_num (value))  {
;		printf ("buffer %d\n", n);
;		printf ("data 0x%08lX\n", value);
;		printf ("newest_data = %ld\n", sci_logger.channel[n].newest_data);
;	} 
;	ASSERT (sci_logger.channel[n].channel_num == AD7716_get_channel_num (value));
;    #endif
;
;	//  Compute the index of the next newest point.
;	//  Wrap around when we reach the end of the buffer.
;	sci_logger.channel[n].newest_data += 1;
^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	#1,(a1)
;	if (sci_logger.channel[n].newest_data >= sci_logger.channel[n].n_data)
^;		sci_logger.channel[n].newest_data = 0;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+516,a1
	move.l	(a0,d0.l),d0
	cmp.l	(a1,d1.l),d0
	blt	.10070
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	clr.l	(a0,d0.l)
;	#ifdef SHORT_SCIENCE_DATA
;		//  data passed to this routine is 24 bit data in a 32 bit word
;		value = (value >> 8);
.10070
^^^	asr.l	#8,d3
;		sci_logger.channel[n].data[sci_logger.channel[n].newest_data] = (short)value;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.l	(a0,d0.l),d0
	add.l	d0,d0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+512,a0
	move.l	(a0,d1.l),a0
	move.w	d3,(a0,d0.l)
;	#endif
;	#ifdef LONG_SCIENCE_DATA	
;		sci_logger.channel[n].data[sci_logger.channel[n].newest_data] = value;
;	#endif	
;
;	//  This allows us to call a subroutine which dumps data from a particular
;	//  channel for the user to check out.
;	if (sci_logger.channel[n].channel_num == sci_logger.ASCII_preview_chan)
^^^^^^^^;		sci_logger_preview_ASCII (n);
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	_sci_logger+2558,d0
	bne	.10071
^	move.w	d2,-(sp)
	jsr	_sci_logger_preview_ASCII
;	if (sci_logger.channel[n].channel_num == sci_logger.binary_preview_chan)  {
	add.w	#2,sp
.10071
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	_sci_logger+2560,d0
	bne	.10072
;		//  In binary preview mode, always push a 16 bit number to the user, cause preview
;		//  certainly doesn't need high resolution.  Treat long and short science data
;		//  differently so that we get only the most signficant bits
;		//
;		//  Don't call a subroutine because speed is important
;		#ifdef SHORT_SCIENCE_DATA
;			SerPutByte ((char)((value >> 8)&0xFF));
^^^^^^^	move.l	d3,d0
	asr.l	#8,d0
	and.l	#255,d0
	ext.w	d0
	move.w	d0,-(sp)
	jsr	_SerPutByte
;			SerPutByte ((char)(value & 0xFF));
^	move.l	d3,d0
	and.l	#255,d0
	ext.w	d0
	move.w	d0,-(sp)
	jsr	_SerPutByte
;		#endif
;		#ifdef LONG_SCIENCE_DATA
;			SerPutByte ((char)((value >> 16)&0xFF));
;			SerPutByte ((char)((value >> 8)&0xFF));
;		#endif
;//		sci_logger_preview_binary (n);
;	}	
^^^^^^^;
;	//  if this channel is triggered, then we need to update the number of points
;	//  waiting
;	if (sci_logger.channel[n].trigger_state != WAITING)  {
	add.w	#4,sp
.10072
^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	tst.w	(a0,d0.l)
	beq	.10073
;		//  REVIEW - what is this????
;		//  Not waiting, yet n_waiting... == 0?
;		if (sci_logger.channel[n].n_waiting_to_write++ == 0)
^^^;			sci_logger.channel[n].next_to_write = sci_logger.channel[n].newest_data;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	move.l	(a0,d0.l),d1
	add.l	#1,(a0,d0.l)
	tst.l	d1
	bne	.10074
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+602,a1
	move.l	(a0,d0.l),(a1,d1.l)
;		
;		//  if this channel is in the post event phase, then we decrement the
;		//  number of points left to collect in post event
;		if (sci_logger.channel[n].trigger_state == POST_EVENT)
.10074
^^^^;			sci_logger.channel[n].n_post_event_left--;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	cmp.w	#2,(a0,d0.l)
	bne	.10075
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+582,a0
	sub.l	#1,(a0,d0.l)
;	}	
.10075
^;	
;	if (sci_logger.channel[n].trigger_level == 0)  {
.10073
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+574,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	jsr	.Ftst#
	bne	.10076
;		//  Should actually mark all other active channels as triggered
;		//  as well, but lets modify the way it works in the interest
;		//  of speed.  
;		sci_logger.channel[n].trigger_request = 1;
^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	move.w	#1,(a0,d0.l)
;	}  else  {	
^	bra	.10077
.10076
;		//  if this channel is one on which we are triggering, then calculate the STA and LTA
;		if (sci_logger.channel[n].trigger_chan)  {
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+570,a0
	tst.w	(a0,d0.l)
	beq	.10078
;			sci_logger.channel[n].STA += (labs (value) - sci_logger.channel[n].STA) / 
^;															((float)sci_logger.channel[n].n_STA);
	move.l	d3,-(sp)
	jsr	_labs
	jsr	.Fflt#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+562,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fsub#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+550,a0
	move.l	(a0,d1.l),d1
	add.w	#4,sp
	move.l	d0,-(sp)
	move.l	d1,d0
	jsr	.Fflt#
	move.l	d0,d1
	move.l	(sp)+,d0
	jsr	.Fdiv#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+562,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fadd#
	move.l	d0,(a1)
;		
;			sci_logger.channel[n].LTA += (labs (value) - sci_logger.channel[n].LTA) /
^^^;															((float)sci_logger.channel[n].n_LTA);
	move.l	d3,-(sp)
	jsr	_labs
	jsr	.Fflt#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+566,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fsub#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+558,a0
	move.l	(a0,d1.l),d1
	add.w	#4,sp
	move.l	d0,-(sp)
	move.l	d1,d0
	jsr	.Fflt#
	move.l	d0,d1
	move.l	(sp)+,d0
	jsr	.Fdiv#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+566,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fadd#
	move.l	d0,(a1)
;			ASSERT (sci_logger.channel[n].LTA >= 0.0);
^^;			ASSERT (sci_logger.channel[n].STA >= 0.0);
^;			if (sci_logger.channel[n].STA >
^;				(sci_logger.channel[n].trigger_level*sci_logger.channel[n].LTA))  {
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+574,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+566,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fmul#
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+562,a0
	move.l	d1,a1
	add.l	a0,a1
	move.l	(a1),d1
	jsr	.Fcmp#
	bge	.10079
^;				//  this channel is showing a trigger.  Loop through all channels
;				//  which it triggers, and mark them as requesting a trigger.  Later
;				//  after we have been through the data from all the channels once,
;				//  we will actually go through the channels and untrigger those which
;				//  are not requesting a trigger.  Although this is complex, it allows
;				//  triggering from multiple sources.
;//				printf ("Trigger request on %d\n", n);			
;				for (m = 0;  m < N_SCI_CHANNELS;  m++)  {
^^^^^^^^	move.l	#0,d4
.10082
;					if ((0x01 << m) & sci_logger.channel[n].chans_to_trigger)  {
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+572,a0
	move.l	#1,d1
	asl.w	d4,d1
	move.w	(a0,d0.l),d0
	and.w	d1,d0
	beq	.10083
;						for (k = 0;  k < sci_logger.n_channels;  k++)  {
^	move.l	#0,d5
	bra	.10087
.10086
;							if (sci_logger.channel[k].channel_num == m)  {
^	move.w	d5,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	d4,d0
	bne	.10088
;//								printf ("t %d\n", k);						
;								sci_logger.channel[k].trigger_request = 1;
^^	move.w	d5,d0
	muls.w	#638,d0
	lea	_sci_logger+580,a0
	move.w	#1,(a0,d0.l)
;							}							
^;						}
.10088
^.10084
	add.w	#1,d5
.10087
	cmp.w	_sci_logger+2554,d5
	blt	.10086
.10085
;					}
^;				}
.10083
^.10080
	add.w	#1,d4
	cmp.w	#4,d4
	blt	.10082
.10081
;			}
^;		}	
.10079
^;	}
.10078
^.10077
;
;	sci_logger_assert_valid(__LINE__);
^^;	return;
^.37
	movem.l	(sp)+,d2/d3/d4/d5
	rts
;}
^.36
;
;
;
;
;//  sci_logger_preview_ASCII
;//  Internal use only
;//
;//	Prints out an occasional value so the user can verify the operation
;//  of the data logger.  Internal use only
;//
;void sci_logger_preview_ASCII (int n)  {
# 1197
| .38
	xdef	_sci_logger_preview_ASCII
_sci_logger_preview_ASCII:
	movem.l	d2/d3,-(sp)
	move.w	12(sp),d2
;	static long preview_count = 0;
	dseg
	ds	0
.39
	dc.l	$0000
	cseg
;	long value;
;	ASSERT (sci_logger.logger_open_flag == 1);
~ preview_count .39 "l"
~ value d3 "l"
~~ n d2 "i"
^^^;	
;	if ( ((preview_count++)%100) == 0)  {
^^	move.l	.39,d0
	add.l	#1,.39
	move.l	#100,d1
	jsr	.mods#
	bne	.10089
;//		printf ("%ld: 0x%08lX\n", AD7716_get_icount(), value);
;//		printf ("%ld: %ld\n", AD7716_get_icount(), value);
;		value = sci_logger.channel[n].data[sci_logger.channel[n].newest_data];
^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.l	(a0,d0.l),d0
	add.l	d0,d0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+512,a0
	move.l	(a0,d1.l),a0
	move.w	(a0,d0.l),d0
	ext.l	d0
	move.l	d0,d3
;		printf ("%ld: %f", AD7716_get_icount(), sci_logger_value_to_voltage (n, value));
^	move.l	d3,-(sp)
	move.w	d2,-(sp)
	jsr	_sci_logger_value_to_voltage
	add.w	#6,sp
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	jsr	_AD7716_get_icount
	move.l	d0,-(sp)
	pea	.28+0
	jsr	_printf
;		printf ("    STA: %f    LTA: %f\n",
^;					sci_logger_value_to_voltage (n, sci_logger.channel[n].STA),
;						sci_logger_value_to_voltage (n, sci_logger.channel[n].LTA));
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+566,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	jsr	.Ffix#
	move.l	d0,-(sp)
	move.w	d2,-(sp)
	jsr	_sci_logger_value_to_voltage
	add.w	#6,sp
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+562,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	jsr	.Ffix#
	move.l	d0,-(sp)
	move.w	d2,-(sp)
	jsr	_sci_logger_value_to_voltage
	add.w	#6,sp
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.28+8
	jsr	_printf
;	}	
^^^;	return;
	lea	36(sp),sp
.10089
^.40
	movem.l	(sp)+,d2/d3
	rts
;}		
^.38
.28
	dc.b	37,108,100,58,32,37,102,0,32,32,32,32,83,84,65
	dc.b	58,32,37,102,32,32,32,32,76,84,65,58,32,37,102
	dc.b	10,0
	ds	0
;
;
;
;
;//  sci_logger_preview_binary
;//  Internal use only
;//
;//	Prints out data in binary for graphing by the user program.  This
;//  obviously will not work with a standard terminal program.
;//
;void sci_logger_preview_binary (int n)  {
# 1223
| .42
	xdef	_sci_logger_preview_binary
_sci_logger_preview_binary:
	movem.l	d2/d3,-(sp)
	move.w	12(sp),d3
;	long value;
;	ASSERT (sci_logger.logger_open_flag == 1);
~ value d2 "l"
~~ n d3 "i"
^^;
;	value = sci_logger.channel[n].data[sci_logger.channel[n].newest_data];
^^	move.w	d3,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.l	(a0,d0.l),d0
	add.l	d0,d0
	move.w	d3,d1
	muls.w	#638,d1
	lea	_sci_logger+512,a0
	move.l	(a0,d1.l),a0
	move.w	(a0,d0.l),d0
	ext.l	d0
	move.l	d0,d2
;	printf ("%c%c", (char)((value&0xFF00) >> 8), (char)(value&0xFF));
^	move.l	d2,d0
	and.l	#255,d0
	ext.w	d0
	move.w	d0,-(sp)
	move.l	d2,d0
	and.l	#65280,d0
	asr.l	#8,d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.41+0
	jsr	_printf
;	fflush (stdout);
^	pea	__iob+22
	jsr	_fflush
;	return;
^	lea	12(sp),sp
.43
	movem.l	(sp)+,d2/d3
	rts
;}		
^.42
.41
	dc.b	37,99,37,99,0
	ds	0
;
;
;
;float sci_logger_value_to_voltage (short n, long value)  {
# 1235
| .45
	xdef	_sci_logger_value_to_voltage
_sci_logger_value_to_voltage:
;	#ifdef SHORT_SCIENCE_DATA
;		return (2.5F/sci_logger.channel[n].gain)*value/(float)0x8000;
~~ n 8 "i"
~~ value 10 "l"
^^	move.w	4(sp),d0
	muls.w	#638,d0
	lea	_sci_logger+524,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d1
	move.l	#$40200000,d0
	jsr	.Fdiv#
	move.l	d0,-(sp)
	move.l	10(sp),d0
	jsr	.Fflt#
	move.l	d0,d1
	move.l	(sp)+,d0
	jsr	.Fmul#
	move.l	#$47000000,d1
	jsr	.Fdiv#
.46
	rts
;	#endif
;	#ifdef LONG_SCIENCE_DATA
;		return (2.5F/sci_logger.channel[n].gain)*value/(float)0x800000;
;	#endif
;}		
^^^^^.45
;
;
;
;//  sci_logger_trigger_on ()
;//  Internal use only
;//
;//  This routine is called to force the data logger to begin recording data when
;//  the trigger calculation routines determine that an interesting event has occured
;//
;//  The three phases are waiting for an event, triggered (saving data), and post event
;//	(not triggered, but still saving additional data for a fixed length of time).
;//
;//	This routine should not be called if the logger is already triggered.
;//  If this routine is called during the "post event" phase, then the new data will
;//  	be added to the old as a single record.
;//	If this routine is called during the waiting phase, then a block of data from the
;//  	buffer is marked for saving, and additional data will be saved until the
;//		sci_logger_trigger_off () routine is called.
;//
;void sci_logger_trigger_on (short channel)  {
# 1262
| .47
	xdef	_sci_logger_trigger_on
_sci_logger_trigger_on:
	link	a6,#.48
	movem.l	d2/d3/d4/d5/d6/d7,-(sp)
;	extern const float SOFTWARE_VERSION;
;	double delta;
;	int n;
;	long temp;
;	long delta_secs, delta_ticks;
;	#ifdef DEBUG
;	time_tt time_temp;
;	#endif
;
;	ASSERT (sci_logger.logger_open_flag == 1);
~ delta -8 "d"
~ n d4 "i"
~ temp d5 "l"
~ delta_secs d6 "l"
~ delta_ticks d7 "l"
~~ channel 8 "i"
^^^^^^^^^^;	sci_logger_assert_valid(__LINE__);
^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10090
^.49
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7
	unlk	a6
	rts
;		
;	//  figure out which buffer corresponds to this channel number
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
.10090
^^^	move.l	#0,d4
	bra	.10094
.10093
;		if (sci_logger.channel[n].channel_num == channel)
^;			break;
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	8(a6),d0
	beq	.10092
;	}
^^.10091
	add.w	#1,d4
.10094
	cmp.w	_sci_logger+2554,d4
	blt	.10093
.10092
;	#ifdef DEBUG
;	printf ("Trigger_on (chan %d, buffer %d) called\n", channel, n);
;	#endif
;	ASSERT (n < sci_logger.n_channels);
^^^^;	//  impossible event
;//	if (n >= sci_logger.n_channels)
;//		return;
;	
;//	printf ("buffer %d; STA = %f;  LTA = %f;  trigger_level = %f\n",
;//			n, sci_logger.channel[n].STA, sci_logger.channel[n].LTA, sci_logger.channel[n].trigger_level);
;//	printf ("newest data = %ld\n", sci_logger.channel[n].newest_data);
;	
;	//  don't call this routine if we are already triggered
;	ASSERT (sci_logger.channel[n].trigger_state != TRIGGERED);
^^^^^^^^^^;	//  impossible event
;	if (sci_logger.channel[n].trigger_state == TRIGGERED)
^^;		return;
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	cmp.w	#1,(a0,d0.l)
	bne	.10095
^	bra	.49
;	
;	if (sci_logger.channel[n].trigger_state == POST_EVENT)  {
.10095
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	cmp.w	#2,(a0,d0.l)
	bne	.10096
;		//  we are in the post event collection phase, and have re-triggered
;		//  Everything is still set up; we need only reset the trigger flag
;		sci_logger.channel[n].trigger_state = TRIGGERED;
^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	move.w	#1,(a0,d0.l)
;		return;
^	bra	.49
;	}
^;	
;	//  If we aren't triggered, and we aren't in the post event, then we must
;	//  be waiting.  Each channel is set up individually for saving.
;	ASSERT (sci_logger.channel[n].trigger_state == WAITING);
.10096
^^^^;	sci_logger.channel[n].trigger_state = TRIGGERED;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	move.w	#1,(a0,d0.l)
;
;	//  start by determining which data point in the buffer is the first one
;	//  we should write.
;//	printf ("n_pre_event for buffer %d is %ld\n", n, sci_logger.channel[n].n_pre_event);
;	//  NOTE - if we trigger before we have accululated at least
;	//  n_pre_event points in the buffer, then some of the data will be
;	//  whatever was in the buffer when the space was allocated, or whatever
;	//  we wrote into the buffer in the buffer_empty routine.
;	temp = sci_logger.channel[n].newest_data - sci_logger.channel[n].n_pre_event;
^^^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+534,a1
	move.l	(a0,d0.l),d5
	sub.l	(a1,d1.l),d5
;	if (temp < 0)
^;		temp += sci_logger.channel[n].n_data;
	tst.l	d5
	bge	.10097
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	add.l	(a0,d0.l),d5
;	#ifdef DEBUG
;	printf ("Newest data is %ld\n", sci_logger.channel[n].newest_data);
;	printf ("n_pre_event is %ld\n", sci_logger.channel[n].n_pre_event);
;	printf ("next_to_write is %ld\n", sci_logger.channel[n].next_to_write);
;	#endif
;
;	sci_logger.channel[n].next_to_write = temp;
.10097
^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	d5,(a0,d0.l)
;	ASSERT (temp >= 0);
^;	ASSERT (temp < sci_logger.channel[n].n_data);
^;		
;	sci_logger.channel[n].n_waiting_to_write = 1 + sci_logger.channel[n].n_pre_event;
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+534,a0
	move.l	(a0,d0.l),d0
	add.l	#1,d0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+586,a0
	move.l	d0,(a0,d1.l)
;	sci_logger.channel[n].n_written = 0;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	clr.l	(a0,d0.l)
;
;	//  Compute the time of the first data point in the buffer.  Start by getting
;	//  the time of the newest point in the data buffer
;	//  Don't execute this sequence until the variable next_to_write is set
;	sci_logger.channel[n].start_time = AD7716_get_data_point_time ();
^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	a1,-(sp)
	jsr	_AD7716_get_data_point_time
	move.l	d0,a0
	move.l	(sp)+,a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;	#ifdef DEBUG
;	time_temp = logger_time_get_time ();
;	printf ("Current time: %s", logger_time_get_string (&time_temp));
;	printf ("Last data point time: %s", logger_time_get_string (&sci_logger.channel[n].start_time));
;	#endif
;	
;//	printf ("sci_...header_time: start at %s",
;//			logger_time_get_string (&sci_logger.channel[n].disk_header.start_time));
;
;	delta = sci_logger.channel[n].newest_data - sci_logger.channel[n].next_to_write;
^^^^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+602,a1
	move.l	(a0,d0.l),d0
	sub.l	(a1,d1.l),d0
	jsr	.Pflt#
	move.l	d1,-4(a6)
	move.l	d0,-8(a6)
;	if (delta < 0)
^;		delta += sci_logger.channel[n].n_data;
	move.l	-4(a6),d1
	move.l	-8(a6),d0
	jsr	.Ptst#
	bge	.10098
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	(a0,d0.l),d0
	jsr	.Pflt#
	move.l	-4(a6),d3
	move.l	-8(a6),d2
	jsr	.Padd#
	move.l	d1,-4(a6)
	move.l	d0,-8(a6)
;	#ifdef DEBUG
;	printf ("Number of points waiting is %ld\n", (long)delta);		
;	#endif	
;	delta /= AD7716_get_conversion_rate ();
.10098
^^^^	jsr	_AD7716_get_conversion_rate
	move.l	d1,d3
	move.l	d0,d2
	move.l	-4(a6),d1
	move.l	-8(a6),d0
	jsr	.Pdiv#
	move.l	d1,-4(a6)
	move.l	d0,-8(a6)
;	delta_secs = (long)delta;
^	move.l	-4(a6),d1
	move.l	-8(a6),d0
	jsr	.Pfix#
	move.l	d0,d6
;	delta_ticks = (long)(0.5F + ((delta-delta_secs) * GetTickRate ()));
^	jsr	_GetTickRate
	jsr	.Pflt#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	-4(a6),d1
	move.l	-8(a6),d0
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	d6,d0
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Psub#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	move.l	#$00000000,d3
	move.l	#$3fe00000,d2
	jsr	.Padd#
	jsr	.Pfix#
	move.l	d0,d7
;	#ifdef DEBUG
;	printf ("Delta time is %lf\n", delta);	
;	printf ("Delta secs is %ld\n", delta_secs);	
;	printf ("Delta ticks is %ld (= 0.%ld sec)\n", delta_ticks, delta_ticks*25);	
;//	printf ("delta_secs = %ld\n", delta_secs);
;//	printf ("delta_ticks = %ld\n", delta_ticks);	
;	#endif
;	sci_logger.channel[n].start_time.secs -= delta_secs;
^^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a1
	add.l	a0,a1
	sub.l	d6,(a1)
;	sci_logger.channel[n].start_time.ticks -= delta_ticks;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+618,a0
	move.l	d0,a1
	add.l	a0,a1
	sub.l	d7,(a1)
;	if (sci_logger.channel[n].start_time.ticks < 0)  {
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+618,a0
	tst.l	(a0,d0.l)
	bge	.10099
;		sci_logger.channel[n].start_time.ticks += GetTickRate ();
^	jsr	_GetTickRate
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+618,a0
	move.l	d1,a1
	add.l	a0,a1
	add.l	d0,(a1)
;		ASSERT (sci_logger.channel[n].start_time.ticks >= 0);
^;		sci_logger.channel[n].start_time.secs -= 1;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a1
	add.l	a0,a1
	sub.l	#1,(a1)
;	}
^;	sci_logger.channel[n].next_write_time = sci_logger.channel[n].start_time;
.10099
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a2
	add.l	a0,a2
	move.l	(a2)+,(a1)+
	move.l	(a2)+,(a1)+
;	#ifdef DEBUG
;	printf ("Next write time: %s", logger_time_get_string (&sci_logger.channel[n].next_write_time));
;	#endif
;	
;//	printf ("sci_...header_time: %s",
;//				logger_time_get_string (&sci_logger.channel[n].disk_header.start_time));
;
;	//  zero the header
;	memset (&sci_logger.channel[n].disk_header, 0,
^^^^^^^^^;			sizeof (sci_logger.channel[n].disk_header));
	pea	512
	clr.w	-(sp)
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_memset
;	strcpy (sci_logger.channel[n].disk_header.magicstring, "DATA");
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger,a0
	move.l	d0,a1
	add.l	a0,a1
	lea	.44,a0
.50	move.b	(a0)+,(a1)+
	bne.s	.50
;	sprintf (sci_logger.channel[n].disk_header.totalhdrs, "1");
^	pea	.44+5
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+8,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.abbrev, "GEOSens");
^	pea	.44+7
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+11,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.title, "GEOSense Science Channel %d",
^;														sci_logger.channel[n].channel_num);
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	pea	.44+15
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+22,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	//  The sampling period is now calculated and set just before we write
;	//  this channel to disk and is based on the actual average sampling rate over
;	//  the entire time that the data was being added to the buffer
;//	sprintf (sci_logger.channel[n].disk_header.sampling_period, "%.8f",
;//									(float)(1.0F/sci_logger_get_conversion_rate()));
;//	ASSERT (sci_logger.channel[n].disk_header.sampling_period[sizeof(sci_logger.channel[n].disk_header.sampling_period)-1] == '\0');
;	#ifdef SHORT_SCIENCE_DATA
;		sprintf (sci_logger.channel[n].disk_header.samplebits, "16");
^^^^^^^^^	pea	.44+43
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+143,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;		sprintf (sci_logger.channel[n].disk_header.wordsize, "2");
^	pea	.44+46
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+146,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
	lea	52(sp),sp
;    #endif
;    #ifdef LONG_SCIENCE_DATA
;		sprintf (sci_logger.channel[n].disk_header.samplebits, "24");
;		sprintf (sci_logger.channel[n].disk_header.wordsize, "4");
;	#endif	
;	sci_logger.channel[n].disk_header.typemark = AMPLITUDE;
^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+148,a0
	move.b	#65,(a0,d0.l)
;	sci_logger.channel[n].disk_header.swapping = UNSWAPPED;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+149,a0
	move.b	#85,(a0,d0.l)
;	sci_logger.channel[n].disk_header.signing = SIGNED;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+150,a0
	move.b	#83,(a0,d0.l)
;	sci_logger.channel[n].disk_header.caltype = CALIBRATED;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+151,a0
	move.b	#67,(a0,d0.l)
;	sprintf (sci_logger.channel[n].disk_header.calmin, "%.8f",
^;								(-2.5/sci_logger.channel[n].gain));
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+524,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	#$00000000,d1
	move.l	#$c0040000,d0
	jsr	.Pdiv#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.44+48
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+152,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.calmax, "%.8f",
^^;								(2.5/sci_logger.channel[n].gain));
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+524,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	#$00000000,d1
	move.l	#$40040000,d0
	jsr	.Pdiv#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.44+53
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+167,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.calunits, "Volts");
^^	pea	.44+58
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+182,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.recordsize, "512");
^	pea	.44+64
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+222,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.sourcevers, "%.4f", SOFTWARE_VERSION);
^	move.l	_SOFTWARE_VERSION,d0
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.44+68
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+228,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
	lea	64(sp),sp
;	
;	//  Finally, convert the time which is stored as a time_tt varible into
;	//  the MacTrimpi header format
;	sci_logger_set_header_time (n);
^^^^	move.w	d4,-(sp)
	jsr	_sci_logger_set_header_time
;
;	sci_logger_assert_valid(__LINE__);
^^;}
^	add.w	#2,sp
	bra	.49
.47
.48	equ	-8
.44
	dc.b	68,65,84,65,0,49,0,71,69,79,83,101,110,115,0
	dc.b	71,69,79,83,101,110,115,101,32,83,99,105,101,110,99
	dc.b	101,32,67,104,97,110,110,101,108,32,37,100,0,49,54
	dc.b	0,50,0,37,46,56,102,0,37,46,56,102,0,86,111
	dc.b	108,116,115,0,53,49,50,0,37,46,52,102,0
	ds	0
;
;
;
;
;//  sci_logger_set_header_time
;//
;//	Uses the time stored in the "next_write_time" variable to set
;//  the MacTrimpi header variables which specify the time.
;//
;//	As noted in the routine AD7716_get_data_point_time (), this routine
;//  introduces some inaccuracies caused by the uncertainty in the real
;//  conversion rate.  Those inaccuracies increase as the length of
;//  the pre-event length increases.
;//
;void sci_logger_set_header_time (int n)  {
# 1434
| .52
	xdef	_sci_logger_set_header_time
_sci_logger_set_header_time:
	link	a6,#.53
	movem.l	d2/d3/d4/d5/a3,-(sp)
	move.w	8(a6),d4
;	long delta_secs, delta_ticks, msec;
;	double delta;
;	time_tt p1_time;
;	struct tm* tm;
;	ASSERT (n >= 0);
~ msec d5 "l"
~ ''
~ 1 2 8
~ secs 0 "L"
~ ticks 4 "l"
~ p1_time -8 ":" 1
~ 'tm'
~ 2 10 20
~ tm_sec 0 "i"
~ tm_min 2 "i"
~ tm_hour 4 "i"
~ tm_mday 6 "i"
~ tm_mon 8 "i"
~ tm_year 10 "i"
~ tm_wday 12 "i"
~ tm_yday 14 "i"
~ tm_isdst 16 "i"
~ tm_hsec 18 "i"
~ tm a3 "#:" 2
~~ n d4 "i"
^^^^^;	ASSERT (n <= N_SCI_CHANNELS);
^;		
;	//  Now compute the time of the first point.  Note that our
;	//  internal clock has 25 uSec resolution, but the header clock
;	//  has only mSec resolution.  If necessary, round up to the
;	//  next second.
;	p1_time = sci_logger.channel[n].next_write_time;	
^^^^^^	lea	-8(a6),a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
;	msec = 0.5 + (1000L * p1_time.ticks / GetTickRate ());
^	jsr	_GetTickRate
	move.l	d0,d1
	move.l	-4(a6),d0
	move.l	d1,-(sp)
	move.l	#1000,d1
	jsr	.mulu#
	move.l	(sp)+,d1
	jsr	.divs#
	jsr	.Pflt#
	move.l	#$00000000,d3
	move.l	#$3fe00000,d2
	jsr	.Padd#
	jsr	.Pfix#
	move.l	d0,d5
;	if (msec >= 1000)  {
^	cmp.l	#1000,d5
	blt	.10100
;		msec = 0;
^	move.l	#0,d5
;		p1_time.ticks = 0;
^	clr.l	-4(a6)
;		p1_time.secs += 1;
^	add.l	#1,-8(a6)
;	}	
^;
;	//  convert time to the tm structure time
;	tm = localtime (&(p1_time.secs));
.10100
^^^	pea	-8(a6)
	jsr	_localtime
	move.l	d0,a3
;	if (tm->tm_year < 70)
^;		tm->tm_year += 2000;
	cmp.w	#70,10(a3)
	add.w	#4,sp
	bge	.10101
^	lea	10(a3),a0
	add.w	#2000,(a0)
;	else
	bra	.10102
.10101
;		tm->tm_year += 1900;
^^	lea	10(a3),a0
	add.w	#1900,(a0)
.10102
;
;	sprintf (sci_logger.channel[n].disk_header.year, "%d", tm->tm_year);
^^	move.w	10(a3),-(sp)
	pea	.51+0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+110,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.month, "%02d", 1+tm->tm_mon);
^	move.w	8(a3),d0
	add.w	#1,d0
	move.w	d0,-(sp)
	pea	.51+3
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+104,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.day, "%02d", tm->tm_mday);
^	move.w	6(a3),-(sp)
	pea	.51+8
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+107,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.year, "%d", tm->tm_year);
^	move.w	10(a3),-(sp)
	pea	.51+13
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+110,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.hours, "%02d", tm->tm_hour);
^	move.w	4(a3),-(sp)
	pea	.51+16
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+115,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	sprintf (sci_logger.channel[n].disk_header.minutes, "%02d", tm->tm_min);
^	move.w	2(a3),-(sp)
	pea	.51+21
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+118,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
	lea	60(sp),sp
;	sprintf (sci_logger.channel[n].disk_header.seconds, "%02d", tm->tm_sec);
^	move.w	(a3),-(sp)
	pea	.51+26
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+121,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	//  need to convert ticks to milliseconds
;	sprintf (sci_logger.channel[n].disk_header.msec, "%03ld", msec);
^^	move.l	d5,-(sp)
	pea	.51+31
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+124,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;	return;
^	lea	22(sp),sp
.54
	movem.l	(sp)+,d2/d3/d4/d5/a3
	unlk	a6
	rts
;}
^.52
.53	equ	-8
.51
	dc.b	37,100,0,37,48,50,100,0,37,48,50,100,0,37,100
	dc.b	0,37,48,50,100,0,37,48,50,100,0,37,48,50,100
	dc.b	0,37,48,51,108,100,0
	ds	0
;
;	
;
;
;
;//  sci_logger_trigger_off ()
;//  Internal use only
;//
;//	See the description of the trigger algorithms at the trigger_on() routine.
;//  When we turn the trigger off we first set it to POST_EVENT, and then
;//	set a counter to the length of the desired post event data block.
;//  This counter will be decremented each time we add a new point 
;//  with the add_point() routine.  When the counter reaches zero, we mark
;//  the trigger as off.
;//
;void sci_logger_trigger_off (short channel)  {
# 1487
| .56
	xdef	_sci_logger_trigger_off
_sci_logger_trigger_off:
	movem.l	d2,-(sp)
;	int n;
;	sci_logger_assert_valid(__LINE__);
~ n d2 "i"
~~ channel 8 "i"
^^;	ASSERT (sci_logger.logger_open_flag == 1);
^;	//  impossible event
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10103
^.57
	movem.l	(sp)+,d2
	rts
;
;	//  figure out which buffer corresponds to this channel number
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
.10103
^^^	move.l	#0,d2
	bra	.10107
.10106
;		if (sci_logger.channel[n].channel_num == channel)
^;			break;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	8(sp),d0
	beq	.10105
;	}
^^.10104
	add.w	#1,d2
.10107
	cmp.w	_sci_logger+2554,d2
	blt	.10106
.10105
;	ASSERT (n < sci_logger.n_channels);
^;	//  impossible event
;	if (n >= sci_logger.n_channels)
^^;		return;
	cmp.w	_sci_logger+2554,d2
	blt	.10108
^	bra	.57
;	
;//	printf ("Trigger_off (chan %d) called\n", channel);
;//	printf ("buffer %d; STA = %f;  LTA = %f;  trigger_level = %f\n",
;//		n, sci_logger.channel[n].STA, sci_logger.channel[n].LTA, sci_logger.channel[n].trigger_level);
;	
;	sci_logger.channel[n].n_post_event_left = sci_logger.channel[n].n_post_event;
.10108
^^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+542,a0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+582,a1
	move.l	(a0,d0.l),(a1,d1.l)
;//	printf ("  post event length is %ld points\n", sci_logger.channel[n].n_post_event_left);
;	if (sci_logger.channel[n].n_post_event_left > 0)
^^;		sci_logger.channel[n].trigger_state = POST_EVENT;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+582,a0
	tst.l	(a0,d0.l)
	ble	.10109
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	move.w	#2,(a0,d0.l)
;	else
	bra	.10110
.10109
;		sci_logger.channel[n].trigger_state = WAITING;
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	clr.w	(a0,d0.l)
.10110
;	sci_logger_assert_valid(__LINE__);
^;}
^	bra	.57
.56
;
;
;
;
;
;//  Internal use only
;void sci_logger_power_on (void)  {
# 1523
| .58
	xdef	_sci_logger_power_on
_sci_logger_power_on:
;	ASSERT (sci_logger.logger_open_flag == 1);
^;	sci_logger_assert_valid(__LINE__);
^;	if (sci_logger.logger_open_flag == 0)
^;		return;
	tst.w	_sci_logger+2552
	bne	.10111
^.59
	rts
;
;	//  make sure all the I/O lines are configured so that we are not
;	//  powering the ADC through any of the logic lines.  This is redundant
;	//  because it was done at power up, but do it again to be sure
;	#ifdef REVB
;	PConfInp (F,2);     //  1211 data ready
;	#endif
;	PConfInp (F,4);		//  7716 data ready
.10111
^^^^^^^^;			PConfInpF4
	dc.w	$8b8
	dc.w	$4
	dc.w	$fa1f
	dc.w	$8b8
	dc.w	$4
	dc.w	$fa1d
;	PConfOutp(E,0);		//  AD7716 TFS on the ADC module
^;			PConfOutpE0
	dc.w	$8b8
	dc.w	$0
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$0
	dc.w	$fa15
;	PClear(E,0);
^;			PClearE0
	dc.w	$8b8
	dc.w	$0
	dc.w	$fa11
;	PConfOutp(E,1);		//  ADC Reset line on the ADC module
^;			PConfOutpE1
	dc.w	$8b8
	dc.w	$1
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$1
	dc.w	$fa15
;	PClear(E,1);
^;			PClearE1
	dc.w	$8b8
	dc.w	$1
	dc.w	$fa11
;
;    //  Then apply power to the circuits
;	AnalogPowerON ();
^^^	jsr	_AnalogPowerON
;	SensorPowerON ();
^	jsr	_SensorPowerON
;	
;	//  Then reconfigure the gain bits to the default state (low gain)
;	PConfOutp (E, 3);
^^^;			PConfOutpE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa15
;	PConfOutp (E, 5);
^;			PConfOutpE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa15
;	PConfOutp (E, 6);
^;			PConfOutpE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa15
;	PConfOutp (E, 7);
^;			PConfOutpE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa15
;	PSet (E, 3);
^;			PSetE3
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa11
;	PSet (E, 5);
^;			PSetE5
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa11
;	PSet (E, 6);
^;			PSetE6
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa11
;	PSet (E, 7);
^;			PSetE7
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa11
;}
^	bra	.59
.58
;
;
;
;//  Internal use only
;void sci_logger_power_off (void)  {
# 1559
| .60
	xdef	_sci_logger_power_off
_sci_logger_power_off:
;	ASSERT (sci_logger.logger_open_flag == 1);
^;	sci_logger_assert_valid(__LINE__);
^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10112
^.61
	rts
;
;	//  make sure the pins connected to digital control lines on the science
;	//  logger are pulled low so that we don't power this section through
;	//  these pins.  The configuration as an output is redundant, but can't hurt.
;	PConfOutp (E, 3);
.10112
^^^^^;			PConfOutpE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa15
;	PConfOutp (E, 5);
^;			PConfOutpE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa15
;	PConfOutp (E, 6);
^;			PConfOutpE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa15
;	PConfOutp (E, 7);
^;			PConfOutpE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa15
;	PClear (E, 3);
^;			PClearE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa11
;	PClear (E, 5);
^;			PClearE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa11
;	PClear (E, 6);
^;			PClearE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa11
;	PClear (E, 7);
^;			PClearE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa11
;
;	SensorPowerOFF ();
^^	jsr	_SensorPowerOFF
;	AnalogPowerOFF ();
^	jsr	_AnalogPowerOFF
;}
^	bra	.61
.60
;
;
;
;
;//  sci_logger_compute_n ()
;//  Internal use only
;//
;//	Computes and stores all paramaters which depend on the conversion
;//  rate.  Because of the way this routine is called it sometimes does
;//  more computation then necessary, but it is only used when the user
;//  is doing setup, so we don't really care.  Internal use only.
;//
;//	Errors: none returned, but...
;//		We don't allow the pre-event length to get too large because we
;//		don't want the internal buffer to overflow before we can write
;//		the data to disk.  If it gets to long, we truncate the number,
;//		but not the requested time.  This way, if the user later reduces
;//		the conversion rate we can recompute the number and perhaps give
;//		the requested length.  It is up to the user to call the self-test
;//		routine before quitting to insure that all is copesetic.
;//
;int sci_logger_compute_n ()  {
# 1602
| .62
	xdef	_sci_logger_compute_n
_sci_logger_compute_n:
	movem.l	d2/d3/d4/d5/d6/d7,-(sp)
;	long max_n_pre_event;
;	int n, ret;
;	float DISK_DELAY;
;	DISK_DELAY = 15.0;
~ max_n_pre_event d5 "l"
~ n d4 "i"
~ ret d6 "i"
~ DISK_DELAY d7 "f"
^^^^	move.l	#$41700000,d7
;	ASSERT (sci_logger.logger_open_flag == 1);
^;	
;	ret = 0;				
^^	move.l	#0,d6
;	for (n = 0; n < sci_logger.n_channels; n++)  {
^	move.l	#0,d4
	bra	.10116
.10115
;		//  REVIEW - rename the 15 second magic number
;		//  compute a maximum allowed length of the pre_event data which by subtracting
;		//  15 seconds
;		max_n_pre_event = sci_logger.channel[n].n_data -
^^^^;				DISK_DELAY*sci_logger_get_conversion_rate ();
	jsr	_sci_logger_get_conversion_rate
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	d7,d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	move.l	d1,d3
	move.l	d0,d2
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	(a0,d0.l),d0
	jsr	.Pflt#
	jsr	.Psub#
	jsr	.Pfix#
	move.l	d0,d5
;		sci_logger.channel[n].n_pre_event =
^^;			sci_logger.channel[n].t_pre_event * sci_logger_get_conversion_rate ();
	jsr	_sci_logger_get_conversion_rate
	move.w	d4,d2
	muls.w	#638,d2
	lea	_sci_logger+530,a0
	move.l	d2,a1
	add.l	a0,a1
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	jsr	.Pfix#
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+534,a0
	move.l	d0,(a0,d1.l)
;		if (sci_logger.channel[n].n_pre_event > max_n_pre_event)  {
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+534,a0
	move.l	(a0,d0.l),d0
	cmp.l	d5,d0
	ble	.10117
;			sci_logger.channel[n].n_pre_event = max_n_pre_event;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+534,a0
	move.l	d5,(a0,d0.l)
;			ret = -1;
^	move.l	#-1,d6
;		}
^;		//  post-event length can be as long as we want, since we don't store
;		//  it in advance
;		sci_logger.channel[n].n_post_event =
.10117
^^^;			sci_logger.channel[n].t_post_event * sci_logger_get_conversion_rate ();
	jsr	_sci_logger_get_conversion_rate
	move.w	d4,d2
	muls.w	#638,d2
	lea	_sci_logger+538,a0
	move.l	d2,a1
	add.l	a0,a1
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	jsr	.Pfix#
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+542,a0
	move.l	d0,(a0,d1.l)
;		sci_logger.channel[n].n_STA =
^^;			sci_logger.channel[n].t_STA * sci_logger_get_conversion_rate ();
	jsr	_sci_logger_get_conversion_rate
	move.w	d4,d2
	muls.w	#638,d2
	lea	_sci_logger+546,a0
	move.l	d2,a1
	add.l	a0,a1
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	jsr	.Pfix#
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+550,a0
	move.l	d0,(a0,d1.l)
;		sci_logger.channel[n].n_LTA =
^^;			sci_logger.channel[n].t_LTA  * sci_logger_get_conversion_rate ();
	jsr	_sci_logger_get_conversion_rate
	move.w	d4,d2
	muls.w	#638,d2
	lea	_sci_logger+554,a0
	move.l	d2,a1
	add.l	a0,a1
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	jsr	.Pfix#
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+558,a0
	move.l	d0,(a0,d1.l)
;#ifdef DEBUG
;//		printf ("Channel %d: n_data = %ld\n", n, sci_logger.channel[n].n_data);
;//		printf (" max_n_pre_event = %ld\n", max_n_pre_event);
;//		printf (" t_pre_event = %f -> n_pre_event = %ld\n",
;//					sci_logger.channel[n].t_pre_event, sci_logger.channel[n].n_pre_event);
;//		printf (" t_post_event = %f -> n_post_event = %ld\n",
;//					sci_logger.channel[n].t_post_event, sci_logger.channel[n].n_post_event);
;//		printf (" t_STA = %f -> n_STA = %ld\n",
;//					sci_logger.channel[n].t_STA, sci_logger.channel[n].n_STA);
;//		printf (" t_LTA = %f -> n_LTA = %ld\n",
;//					sci_logger.channel[n].t_LTA, sci_logger.channel[n].n_LTA);
;#endif										
;	}
^^^^^^^^^^^^^^.10113
	add.w	#1,d4
.10116
	cmp.w	_sci_logger+2554,d4
	blt	.10115
.10114
;
;	return ret;
^^	move.w	d6,d0
.63
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7
	rts
;}	
^.62
;
;
;
;	
;//  sci_logger_set_pre_event (float t)
;//  User callable
;//
;//  Sets the pre-event length in seconds.  The pre-event length 
;//  in samples must be reset if we change the conversion rate.
;//  User callable.
;//
;//	Arguments:
;//		t = pre-event length in seconds
;//  Returns: negative on failure
;//	
;int sci_logger_set_pre_event (float t)  {
# 1661
| .64
	xdef	_sci_logger_set_pre_event
_sci_logger_set_pre_event:
	movem.l	d2/d3,-(sp)
	move.l	12(sp),d3
;	int n;
;	ASSERT (t >= 0);
~ n d2 "i"
~~ t d3 "f"
^^;	sci_logger_assert_valid(__LINE__);
^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10118
^	move.l	#0,d0
.65
	movem.l	(sp)+,d2/d3
	rts
;	if (t < 0)
.10118
^;		return -1;
	move.l	d3,d0
	jsr	.Ftst#
	bge	.10119
^	move.l	#-1,d0
	bra	.65
;		
;	for (n = 0; n < sci_logger.n_channels; n++)  {
.10119
^^	move.l	#0,d2
	bra	.10123
.10122
;		sci_logger.channel[n].t_pre_event = t;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+530,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	d3,(a1)
;	}
^.10120
	add.w	#1,d2
.10123
	cmp.w	_sci_logger+2554,d2
	blt	.10122
.10121
;	//  the sci_logger_compute_n() routine recalculates all parameters
;	//  which depend on both a time and the conversion rate, such as the
;	//  n_pre_event which we changed here.
;	sci_logger_assert_valid(__LINE__);
^^^^;	return sci_logger_compute_n ();
^	jsr	_sci_logger_compute_n
	bra	.65
;}
^.64
;
;
;
;//  sci_logger_set_post_event (float t)
;//  User callable
;//
;//	Sets post event data logging length as we did pre-event; can return
;//  non-zero only if a previous set_pre_event failed.
;//
;int sci_logger_set_post_event (float t)  {
# 1689
| .66
	xdef	_sci_logger_set_post_event
_sci_logger_set_post_event:
	movem.l	d2,-(sp)
;	int n;
;	ASSERT (t >= 0);
~ n d2 "i"
~~ t 8 "f"
^^;	sci_logger_assert_valid(__LINE__);
^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10124
^	move.l	#0,d0
.67
	movem.l	(sp)+,d2
	rts
;	
;	for (n = 0; n < sci_logger.n_channels; n++)  {
.10124
^^	move.l	#0,d2
	bra	.10128
.10127
;		sci_logger.channel[n].t_post_event = t;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+538,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	8(sp),(a1)
;	}
^.10125
	add.w	#1,d2
.10128
	cmp.w	_sci_logger+2554,d2
	blt	.10127
.10126
;	sci_logger_assert_valid(__LINE__);
^;	return (sci_logger_compute_n ());
^	jsr	_sci_logger_compute_n
	bra	.67
;}
^.66
;
;
;
;//  User callable
;int sci_logger_set_STA_time (float t)  {
# 1707
| .68
	xdef	_sci_logger_set_STA_time
_sci_logger_set_STA_time:
	movem.l	d2/d3,-(sp)
	move.l	12(sp),d3
;	int n;
;	ASSERT (t >= 0);
~ n d2 "i"
~~ t d3 "f"
^^;	if (sci_logger.logger_open_flag == 0)
^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10129
^	move.l	#0,d0
.69
	movem.l	(sp)+,d2/d3
	rts
;	if (t < 0)
.10129
^;		return -1;
	move.l	d3,d0
	jsr	.Ftst#
	bge	.10130
^	move.l	#-1,d0
	bra	.69
;	
;	for (n = 0; n < sci_logger.n_channels; n++)  {
.10130
^^	move.l	#0,d2
	bra	.10134
.10133
;		sci_logger.channel[n].t_STA = t;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+546,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	d3,(a1)
;	}
^.10131
	add.w	#1,d2
.10134
	cmp.w	_sci_logger+2554,d2
	blt	.10133
.10132
;	sci_logger_assert_valid(__LINE__);
^;	return sci_logger_compute_n ();
^	jsr	_sci_logger_compute_n
	bra	.69
;}
^.68
;
;
;
;//  User callable
;int sci_logger_set_LTA_time (float t)  {
# 1725
| .70
	xdef	_sci_logger_set_LTA_time
_sci_logger_set_LTA_time:
	movem.l	d2/d3,-(sp)
	move.l	12(sp),d3
;	int n;
;	ASSERT (t >= 0);
~ n d2 "i"
~~ t d3 "f"
^^;	sci_logger_assert_valid(__LINE__);
^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10135
^	move.l	#0,d0
.71
	movem.l	(sp)+,d2/d3
	rts
;	if (t < 0)
.10135
^;		return -1;
	move.l	d3,d0
	jsr	.Ftst#
	bge	.10136
^	move.l	#-1,d0
	bra	.71
;	
;	for (n = 0; n < sci_logger.n_channels; n++)  {
.10136
^^	move.l	#0,d2
	bra	.10140
.10139
;		sci_logger.channel[n].t_LTA = t;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+554,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	d3,(a1)
;	}
^.10137
	add.w	#1,d2
.10140
	cmp.w	_sci_logger+2554,d2
	blt	.10139
.10138
;	sci_logger_assert_valid(__LINE__);
^;	return sci_logger_compute_n ();
^	jsr	_sci_logger_compute_n
	bra	.71
;}
^.70
;
;
;
;
;
;//  sci_logger_set_conversion_rate ()
;//  User callable
;//
;//  Calls the AD7716 subroutines to set the basic conversion
;//  rate used by the software.  This routine can be called even
;//  when the logger is closed so that we can use the low level
;//  routines to verify the validity of the requested rate
;//
;//	Argument: floating point number which is the requested rate
;//	Returns: floating point number which is the conversion rate
;//		closest to the requested rate
;//	Failures: if the requested rate is not within 1% of a known rate
;double sci_logger_set_conversion_rate (float rate)  {
# 1758
| .72
	xdef	_sci_logger_set_conversion_rate
_sci_logger_set_conversion_rate:
	link	a6,#.73
	movem.l	d2/d3/d4,-(sp)
;	short restart;
;	double true_rate;
;	sci_logger_assert_valid(__LINE__);
~ restart d4 "i"
~ true_rate -8 "d"
~~ rate 8 "f"
^^^;
;	//  stop the data flow and empty buffers when we change rates.
;	restart = sci_logger.data_started;
^^^	move.w	_sci_logger+2574,d4
;	sci_logger_stop_data ();
^	jsr	_sci_logger_stop_data
;
;	//  Start by verifying that the conversion rate is legal and setting
;	//  the conversion rate using the low-level routines
;	true_rate = AD7716_set_conversion_rate (rate);
^^^^	move.l	8(a6),-(sp)
	jsr	_AD7716_set_conversion_rate
	move.l	d1,-4(a6)
	move.l	d0,-8(a6)
;	
;//	printf ("AD7716_set convert returns %f\n", true_rate);
;	if (true_rate > 0)  {
^^^	move.l	-4(a6),d1
	move.l	-8(a6),d0
	jsr	.Ptst#
	add.w	#4,sp
	ble	.10141
;		if (sci_logger.logger_open_flag != 0)  {
^	tst.w	_sci_logger+2552
	beq	.10142
;			//  many variables are passed from the user as times, but used internally
;			//  as a number of points.  These variables must be adjusted whenever the
;			//  conversion rate changes.
;			sci_logger_compute_n ();
^^^^	jsr	_sci_logger_compute_n
;		}
^;	}	
.10142
^;	if (restart)
.10141
^;		sci_logger_start_data ();
	tst.w	d4
	beq	.10143
^	jsr	_sci_logger_start_data
;	sci_logger_assert_valid(__LINE__);
.10143
^;	//  choose new clock rate to accomodate new data rate, if needed
;	logger_set_clock_rate (-1);
^^	pea	-1
	jsr	_logger_set_clock_rate
;	return true_rate;	
^	move.l	-4(a6),d1
	move.l	-8(a6),d0
	add.w	#4,sp
.74
	movem.l	(sp)+,d2/d3/d4
	unlk	a6
	rts
;}
^.72
.73	equ	-8
;
;
;
;
;short sci_logger_set_averaging (short n_average)  {
# 1791
| .75
	xdef	_sci_logger_set_averaging
_sci_logger_set_averaging:
	movem.l	d2/d3,-(sp)
;	short restart;
;	short result;
;
;	//  stop the data flow and empty buffers when we change the
;	//  effective conversion rate
;	restart = sci_logger.data_started;
~ restart d2 "i"
~ result d3 "i"
~~ n_average 8 "i"
^^^^^^	move.w	_sci_logger+2574,d2
;	sci_logger_stop_data ();
^	jsr	_sci_logger_stop_data
;
;	//  try to change the averaging
;	result = AD7716_set_averaging (n_average);
^^^	move.w	12(sp),-(sp)
	jsr	_AD7716_set_averaging
	move.w	d0,d3
;
;	//  choose new clock rate to accomodate new data rate, if needed
;	logger_set_clock_rate (-1);
^^^	pea	-1
	jsr	_logger_set_clock_rate
;	
;	//  restart the science data if appropriate
;	if (restart)
^^^;		sci_logger_start_data ();
	tst.w	d2
	add.w	#6,sp
	beq	.10144
^	jsr	_sci_logger_start_data
;	sci_logger_assert_valid(__LINE__);
.10144
^;	return result;
^	move.w	d3,d0
.76
	movem.l	(sp)+,d2/d3
	rts
;}
^.75
;
;
;
;
;
;//  sci_logger_get_conversion_rate ()
;//  User callable
;//
;//	Returns the current conversion rate in samples/second.
;//	
;double sci_logger_get_conversion_rate (void)  {
# 1822
| .77
	xdef	_sci_logger_get_conversion_rate
_sci_logger_get_conversion_rate:
;	if (sci_logger.logger_open_flag == 0)
^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10145
^	move.l	#$00000000,d1
	move.l	#$00000000,d0
.78
	rts
;
;	return AD7716_get_conversion_rate ();
.10145
^^	jsr	_AD7716_get_conversion_rate
	bra	.78
;}
^.77
;
;
;
;
;//  sci_logger_set_gain
;//  User callable
;//
;//	Sets the gain applied to a particular channel.  Allowed values
;//  are 2.5 and 25; the user must be within 1% of these values for
;//  this routine to recognize them
;//
;int sci_logger_set_gain (int channel, float gain)  {
# 1839
| .79
	xdef	_sci_logger_set_gain
_sci_logger_set_gain:
	movem.l	d2/d3/d4/d5/d6/d7,-(sp)
	move.w	28(sp),d7
;	float normal_gain;
;	int gain_bit;
;	int n;
;	sci_logger_assert_valid(__LINE__);
~ normal_gain d5 "f"
~ gain_bit d4 "i"
~ n d6 "i"
~~ channel d7 "i"
~~ gain 10 "f"
^^^^;	ASSERT (channel >= 0);
^;	ASSERT (channel < N_SCI_CHANNELS);
^;	
;	//  make sure the requested gain is a known legal value
;	normal_gain = gain / 2.50F;
^^^	move.l	30(sp),d0
	move.l	#$40200000,d1
	jsr	.Fdiv#
	move.l	d0,d5
;	if ((normal_gain > 0.99)	&&
^;		(normal_gain < 1.01)   )
;		gain_bit = 1;
	move.l	d5,d0
	jsr	.ftod#
	move.l	#$7ae147ae,d3
	move.l	#$3fefae14,d2
	jsr	.Pcmp#
	ble	.10146
	move.l	d5,d0
	jsr	.ftod#
	move.l	#$c28f5c29,d3
	move.l	#$3ff028f5,d2
	jsr	.Pcmp#
	bge	.10146
^^	move.l	#1,d4
;	else  {
	bra	.10147
.10146
^;		if ((normal_gain > 9.9 )	&&
^;			(normal_gain < 10.1)   )
;			gain_bit = 0;
	move.l	d5,d0
	jsr	.ftod#
	move.l	#$cccccccd,d3
	move.l	#$4023cccc,d2
	jsr	.Pcmp#
	ble	.10148
	move.l	d5,d0
	jsr	.ftod#
	move.l	#$33333333,d3
	move.l	#$40243333,d2
	jsr	.Pcmp#
	bge	.10148
^^	move.l	#0,d4
;		else
	bra	.10149
.10148
;			//  unknown gain requested
;			return -1;
^^^	move.l	#-1,d0
.80
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7
	rts
.10149
;	}
^.10147
;
;	//  if gain is OK, enter it into the setup table
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
^^^	move.l	#0,d6
	bra	.10153
.10152
;		if (sci_logger.channel[n].channel_num == channel)  {
^	move.w	d6,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	d7,d0
	bne	.10154
;			//  this buffer has the channel number of the channel whose
;			//  gain we are setting
;			sci_logger.channel[n].gain = gain;
^^^	move.w	d6,d0
	muls.w	#638,d0
	lea	_sci_logger+524,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	30(sp),(a1)
;		}
^;	}
.10154
^.10150
	add.w	#1,d6
.10153
	cmp.w	_sci_logger+2554,d6
	blt	.10152
.10151
;	
;	//  now that we have verified that the gain is legal, check to see
;	//  if the logger is open.  Don't twiddle the hardware bits unless
;	//  the logger is open.  When the logger is closed the power is off,
;	//  and we want the output bits to be set low so that we don't accidently
;	//  power circuitry through these logic lines
;	if (sci_logger.logger_open_flag == 0)  {
^^^^^^^	tst.w	_sci_logger+2552
	bne	.10155
;		sci_logger_assert_valid(__LINE__);
^;		return 0;
^	move.l	#0,d0
	bra	.80
;	}	
^;
;	//  if logger is open, adjust the gain control lines immediately
;	switch (channel)  {
.10155
^^^	move.w	d7,d0
	bra	.10156
;		case 3:
^.10158
;			//  set the output port pin which controls the gain for this channel
;			//  to reflect the value of the gain bit
;			PConfOutp (E, 7);
^^^;			PConfOutpE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa15
;			if (gain_bit)
^;				PSet (E, 7);
	tst.w	d4
	beq	.10159
^;			PSetE7
	dc.w	$8f8
	dc.w	$7
	dc.w	$fa11
;			else
	bra	.10160
.10159
;				PClear (E, 7);
^^;			PClearE7
	dc.w	$8b8
	dc.w	$7
	dc.w	$fa11
.10160
;			break;
^	bra	.10157
;
;		case 2:
^^.10161
;			PConfOutp (E, 6);
^;			PConfOutpE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa15
;			if (gain_bit)
^;				PSet (E, 6);
	tst.w	d4
	beq	.10162
^;			PSetE6
	dc.w	$8f8
	dc.w	$6
	dc.w	$fa11
;			else
	bra	.10163
.10162
;				PClear (E, 6);
^^;			PClearE6
	dc.w	$8b8
	dc.w	$6
	dc.w	$fa11
.10163
;			break;
^	bra	.10157
;
;		case 1:
^^.10164
;			PConfOutp (E, 5);
^;			PConfOutpE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa15
;			if (gain_bit)
^;				PSet (E, 5);
	tst.w	d4
	beq	.10165
^;			PSetE5
	dc.w	$8f8
	dc.w	$5
	dc.w	$fa11
;			else
	bra	.10166
.10165
;				PClear (E, 5);
^^;			PClearE5
	dc.w	$8b8
	dc.w	$5
	dc.w	$fa11
.10166
;			break;
^	bra	.10157
;
; 		case 0:
^^.10167
;			PConfOutp (E, 3);
^;			PConfOutpE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa17
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa15
;			if (gain_bit)
^;				PSet (E, 3);
	tst.w	d4
	beq	.10168
^;			PSetE3
	dc.w	$8f8
	dc.w	$3
	dc.w	$fa11
;			else
	bra	.10169
.10168
;				PClear (E, 3);
^^;			PClearE3
	dc.w	$8b8
	dc.w	$3
	dc.w	$fa11
.10169
;			break;
^	bra	.10157
;
;		default:
^^.10170
;			//  don't pass bad channel numbers to this routine
;			printf ("Error: Requested gain change on channel %d\n", channel);
^^	move.w	d7,-(sp)
	pea	.55+0
	jsr	_printf
;			ASSERT (0);
^;			return -1;
^	move.l	#-1,d0
	add.w	#6,sp
	bra	.80
;	}
^.81
	dc.w	.10167-.82-2
	dc.w	.10164-.82-2
	dc.w	.10161-.82-2
	dc.w	.10158-.82-2
.10156
	cmp.w	#4,d0
	bcc	.10170
	add.w	d0,d0
	move.w	.81(pc,d0.w),d0
.82
	jmp	(pc,d0.w)
.10157
;	
;	sci_logger_assert_valid(__LINE__);
^^;	return 0;
^	move.l	#0,d0
	bra	.80
;}
^.79
.55
	dc.b	69,114,114,111,114,58,32,82,101,113,117,101,115,116,101
	dc.b	100,32,103,97,105,110,32,99,104,97,110,103,101,32,111
	dc.b	110,32,99,104,97,110,110,101,108,32,37,100,10,0
	ds	0
;
;
;//  User callable
;void sci_logger_set_trigger_level (short channel, float level)  {
# 1929
| .84
	xdef	_sci_logger_set_trigger_level
_sci_logger_set_trigger_level:
	movem.l	d2/d3/d4,-(sp)
	move.w	16(sp),d3
	move.l	18(sp),d4
;	int n;
;	sci_logger_assert_valid(__LINE__);
~ n d2 "i"
~~ channel d3 "i"
~~ level d4 "f"
^^;
;	if (sci_logger.logger_open_flag == 0)
^^;		return;
	tst.w	_sci_logger+2552
	bne	.10171
^.85
	movem.l	(sp)+,d2/d3/d4
	rts
;
;	if (channel < 0)  {
.10171
^^	tst.w	d3
	bge	.10172
;		for (n = 0;  n < sci_logger.n_channels;  n++)
^	move.l	#0,d2
	bra	.10176
.10175
;			sci_logger.channel[n].trigger_level = level;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+574,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	d4,(a1)
.10173
	add.w	#1,d2
.10176
	cmp.w	_sci_logger+2554,d2
	blt	.10175
.10174
;	}  else  {
^	bra	.10177
.10172
;		for (n = 0;  n < sci_logger.n_channels;  n++)  {
^	move.l	#0,d2
	bra	.10181
.10180
;			if (sci_logger.channel[n].channel_num == channel)
^;				sci_logger.channel[n].trigger_level = level;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),d0
	cmp.w	d3,d0
	bne	.10182
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+574,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	d4,(a1)
;		}		
.10182
^.10178
	add.w	#1,d2
.10181
	cmp.w	_sci_logger+2554,d2
	blt	.10180
.10179
;	}			
^.10177
;	sci_logger_assert_valid(__LINE__);
^;}		
^	bra	.85
.84
;
;
;
;
;
;//  sci_logger_disk_request ()
;//  User callable
;//
;//  Checks each data buffer to see if there is more than a certain amount of data
;//  waiting to be dumped to the disk.  If any channel exceeds the threshold, returns
;//  non-zero to request a disk access.
;//
;int sci_logger_disk_request (void)  {
# 1959
| .86
	xdef	_sci_logger_disk_request
_sci_logger_disk_request:
	movem.l	d2,-(sp)
;	int n;
;	sci_logger_assert_valid(__LINE__);
~ n d2 "i"
^^;	
;	if (sci_logger.logger_open_flag == 0)
^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10183
^	move.l	#0,d0
.87
	movem.l	(sp)+,d2
	rts
;
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
.10183
^^	move.l	#0,d2
	bra	.10187
.10186
;		//  if any one channel has lots of data waiting then we must request
;		//  the disk be turned on
;		if (sci_logger.channel[n].n_waiting_to_write > sci_logger.disk_threshold)  {
^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	move.l	(a0,d0.l),d0
	cmp.l	_sci_logger+2562,d0
	ble	.10188
;//			printf ("  sci logger has enough data waiting.\n");			
;			return 1;
^^	move.l	#1,d0
	bra	.87
;		}	
^;
;		//  if any channel is no longer triggered but has data waiting we must
;		//  request a disk access immediately.  If we fail to do this, then we
;		//  run the risk of overwriting the header information if this channel
;		//  were to re-trigger before the data was written.  This may result
;		//  in many quick disk spin-ups (and the associated power penalty) if
;		//  a number of channels with different trigger levels or post-event
;		//  lengths complete at unrelated times.
;		if (sci_logger.channel[n].trigger_state == WAITING)  {
.10188
^^^^^^^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+578,a0
	tst.w	(a0,d0.l)
	bne	.10189
;			if (sci_logger.channel[n].n_waiting_to_write > 0)  {
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	tst.l	(a0,d0.l)
	ble	.10190
;//				printf ("  sci logger waiting with data present\n");
;				return 1;
^^	move.l	#1,d0
	bra	.87
;			}	
^;		}
.10190
^;	}
.10189
^.10184
	add.w	#1,d2
.10187
	cmp.w	_sci_logger+2554,d2
	blt	.10186
.10185
;	
;	return 0;
^^	move.l	#0,d0
	bra	.87
;}
^.86
;
;
;
;
;
;//  sci_logger_write_disk ()
;//  Uuser callable
;//
;//  This routine is called each time the disk is spun up so that the
;//  science logger can have a chance to dump all available data to the
;//  disk.  This routine may be called even when there is no data waiting.
;//
;int sci_logger_write_disk (void)  {
# 2003
| .88
	xdef	_sci_logger_write_disk
_sci_logger_write_disk:
	link	a6,#.89
	movem.l	d2/d3/d4/d5,-(sp)
;	int n;
;	time_tt ltime;
;	long dt;
;	double period;
;	
;	sci_logger_assert_valid(__LINE__);
~ n d4 "i"
~ ltime -8 ":" 1
~ dt d5 "l"
~ period -16 "d"
^^^^^^;	#ifdef DEBUG
;	printf ("sci_logger_write_disk(): starting\n");
;	#endif
;	
;	if (sci_logger.logger_open_flag == 0)
^^^^^;		return 0;
	tst.w	_sci_logger+2552
	bne	.10191
^	move.l	#0,d0
.90
	movem.l	(sp)+,d2/d3/d4/d5
	unlk	a6
	rts
;
;	//  Start by noting the time of the most recently acquired data point
;	//  in the buffers.  All buffers will have the same time.
;	ltime = AD7716_get_data_point_time ();
.10191
^^^^	lea	-8(a6),a0
	move.l	a0,-(sp)
	jsr	_AD7716_get_data_point_time
	move.l	d0,a0
	move.l	(sp)+,a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;	#ifdef DEBUG
;	printf ("Most recent data point time: %s", logger_time_get_string (&ltime));	
;	#endif
;	
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
^^^^^	move.l	#0,d4
	bra	.10195
.10194
;		//  For each buffer, start by setting the end time if there is
;		//  data waiting in this buffer.  Then calculate the actual period
;		//  as based on all of the data waiting in the buffer.
;		//  REVIEW
;		//  This could result in an inaccurate period if we don't have enough
;		//  data points in the buffer.  This could happen if some other system
;		//  has triggered the disk write or if we had independently triggered
;		//  science channels with differing numbers of points in them
;		if (sci_logger.channel[n].n_waiting_to_write > 0)  {
^^^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	tst.l	(a0,d0.l)
	ble	.10196
;			sci_logger.channel[n].end_time = ltime;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+622,a0
	move.l	d0,a1
	add.l	a0,a1
	lea	-8(a6),a0
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;			
;			//  calculate how many clock ticks elapsed from the start to the
;			//  end of the data.
;			dt = ttmcmp (sci_logger.channel[n].end_time, sci_logger.channel[n].start_time);
^^^^	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+622,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	jsr	_ttmcmp
	move.l	d0,d5
;			sci_logger.channel[n].total_to_write = sci_logger.channel[n].newest_data -
^;													 sci_logger.channel[n].next_to_write + 1;
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+520,a0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+602,a1
	move.l	(a0,d0.l),d0
	sub.l	(a1,d1.l),d0
	add.l	#1,d0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+590,a0
	move.l	d0,(a0,d1.l)
;			if (sci_logger.channel[n].total_to_write < 0)
^^;				sci_logger.channel[n].total_to_write += sci_logger.channel[n].n_data;
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+590,a0
	tst.l	(a0,d0.l)
	lea	16(sp),sp
	bge	.10197
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+590,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	(a0,d0.l),d0
	add.l	d0,(a1)
;			ASSERT (sci_logger.channel[n].total_to_write == sci_logger.channel[n].n_waiting_to_write);	
.10197
^;			sci_logger.channel[n].total_written = 0;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+598,a0
	clr.l	(a0,d0.l)
;			//  then the period as measured in clock ticks
;			period = (double)dt / ((double)(sci_logger.channel[n].total_to_write - 1));
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+590,a0
	move.l	(a0,d0.l),d0
	sub.l	#1,d0
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	d5,d0
	jsr	.Pflt#
	jsr	.Pdiv#
	move.l	d1,-12(a6)
	move.l	d0,-16(a6)
;			//  and finally the period in seconds.			
;			period /= GetTickRate ();
^^	jsr	_GetTickRate
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	-12(a6),d1
	move.l	-16(a6),d0
	jsr	.Pdiv#
	move.l	d1,-12(a6)
	move.l	d0,-16(a6)
;			sprintf (sci_logger.channel[n].disk_header.sampling_period, "%.11lf", period);
^	move.l	-12(a6),-(sp)
	move.l	-16(a6),-(sp)
	pea	.83+0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+128,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;
;			#ifdef DEBUG
;			printf ("\n\nBuffer %d has data.\n", n);		
;			printf ("Start time: %s", logger_time_get_string (&sci_logger.channel[n].start_time));	
;			printf ("Total elapsed ticks is %ld\n", (long)dt);			
;			printf ("Total points to write is %ld\n", sci_logger.channel[n].total_to_write);
;			printf ("Total buffer length is %ld\n", sci_logger.channel[n].n_data);
;			printf ("period is %lf\n", period);			
;			printf ("Sampling period is %s\n", sci_logger.channel[n].disk_header.sampling_period);
;			#endif
;		}								
^^^^^^^^^^^;	
;		//  Then write out the data from the buffer.  The write_file
;		//  routine can only write a single file.  If the data is too
;		//  long to fit within a single file, then we must call it
;		//  multiple times in order to dump all of the data.
;		while (sci_logger.channel[n].n_waiting_to_write > 0)  {
	lea	16(sp),sp
.10196
^^^^^^.10198
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	tst.l	(a0,d0.l)
	ble	.10199
;			if (sci_logger_write_file (n) != 0)  {
^	move.w	d4,-(sp)
	jsr	_sci_logger_write_file
	tst.w	d0
	add.w	#2,sp
	beq	.10200
;				//  REVIEW
;				//  Error writing to disk - how do we handle this????
;				return -1;
^^^	move.l	#-1,d0
	bra	.90
;			}
^;		}		
.10200
^	bra	.10198
.10199
;	}		
^.10192
	add.w	#1,d4
.10195
	cmp.w	_sci_logger+2554,d4
	blt	.10194
.10193
;	//  Don't check for overflow here, but rather check in main.  By checking in
;	//  main we can be sure that all the disk accesses are complete.  We can also
;	//  read a few points before checking for the overflow (which is latched) thus
;	//  insuring that the overflow doesn't occur between the time we check and the
;	//  time we can next read points
;//	sci_logger_overflow_check ();
;	
;	//  make sure we haven't screwed up the structures
;	sci_logger_assert_valid(__LINE__);
^^^^^^^^^;	return 0;
^	move.l	#0,d0
	bra	.90
;}
^.88
.89	equ	-16
.83
	dc.b	37,46,49,49,108,102,0
	ds	0
;
;
;
;
;void sci_logger_overflow_check (void)  {
# 2089
| .92
	xdef	_sci_logger_overflow_check
_sci_logger_overflow_check:
	link	a6,#.93
	movem.l	d2,-(sp)
;	int n;
;	time_tt ltime;
;	long value;
;
;	if (AD7716_check_for_overflow ())  {
~ n d2 "i"
~ ltime -8 ":" 1
~ value -12 "l"
^^^^^	jsr	_AD7716_check_for_overflow
	tst.w	d0
	beq	.10201
;		//  we took too long writing the data, and the AD7716 routines internal
;		//  buffer overflowed, resulting in a loss of data.  The start time for
;		//  each buffer point is therefore incorrect.  We must fix this.
;		log_printf ("sci_logger_overflow_check: AD7716 buffer overflow.\n  data lost @");
^^^^	pea	.91+0
	jsr	_log_printf
;		ltime = logger_time_get_time ();
^	lea	-8(a6),a0
	add.w	#4,sp
	move.l	a0,-(sp)
	jsr	_logger_time_get_time
	move.l	d0,a0
	move.l	(sp)+,a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;		log_printf ("%s", logger_time_get_string (&ltime));
^	pea	-8(a6)
	jsr	_logger_time_get_string
	add.w	#4,sp
	move.l	d0,-(sp)
	pea	.91+65
	jsr	_log_printf
;		printf ("The input data buffer overflowed and science data was lost.\n");
^	pea	.91+68
	jsr	_printf
;		ASSERT (sci_logger.current_buffer == 0);
^;		
;		//  empty out the current buffer
;		for (n = 0;  n < sci_logger.n_channels;  n++)  {
^^^	move.l	#0,d2
	lea	12(sp),sp
	bra	.10205
.10204
;			#ifdef DEBUG
;				printf ("Buffer %d had %ld points waiting.\n", n, sci_logger.channel[n].n_waiting_to_write);
;			#endif			
;			sci_logger_buffer_empty (n);
^^^^	move.w	d2,-(sp)
	jsr	_sci_logger_buffer_empty
;		}	
^	add.w	#2,sp
.10202
	add.w	#1,d2
.10205
	cmp.w	_sci_logger+2554,d2
	blt	.10204
.10203
;		
;		for (n = 0;  n < sci_logger.n_channels;  n++)  {
^^	move.l	#0,d2
	bra	.10209
.10208
;			//  returns 0 if data was available
;			//  This ASSERT is from an old version of the code in which this routine
;			//  was called only after all the data had been written to disk.  In the
;			//  current version we can call this at any time, and in fact we call it
;			//  only after first reading a few points from the 7716.  By reading a few
;			//  points first we insure that the overflow doesn't occur between the end
;			//  of this routine and the next call to the read routines.  In this version
;			//  we explicitly flush the buffer above.
;			ASSERT (sci_logger.channel[n].n_waiting_to_write == 0);
^^^^^^^^^;			while (AD7716_get_data_point (&value) != 0)
^.10210
	pea	-12(a6)
	jsr	_AD7716_get_data_point
	tst.w	d0
	add.w	#4,sp
	beq	.10211
;				{;}
^	bra	.10210
.10211
;				
;			//  Once we get a point, add it to the appropriate buffer
;			sci_logger_add_point (sci_logger.current_buffer, value);
^^^	move.l	-12(a6),-(sp)
	move.w	_sci_logger+2556,-(sp)
	jsr	_sci_logger_add_point
;		
;			//  update the current buffer number
;			sci_logger.current_buffer++;
^^^	add.w	#1,_sci_logger+2556
;		}
^	add.w	#6,sp
.10206
	add.w	#1,d2
.10209
	cmp.w	_sci_logger+2554,d2
	blt	.10208
.10207
;
;		sci_logger.current_buffer = 0;
^^	clr.w	_sci_logger+2556
;		ltime = AD7716_get_data_point_time ();
^	lea	-8(a6),a0
	move.l	a0,-(sp)
	jsr	_AD7716_get_data_point_time
	move.l	d0,a0
	move.l	(sp)+,a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;		for (n = 0;  n < sci_logger.n_channels;  n++)  {
^	move.l	#0,d2
	bra	.10215
.10214
;			sci_logger.channel[n].start_time = ltime;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a1
	add.l	a0,a1
	lea	-8(a6),a0
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;			sci_logger.channel[n].next_write_time = ltime;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	lea	-8(a6),a0
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;			sci_logger.channel[n].n_written = 0;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	clr.l	(a0,d0.l)
;			//  now that the next_write_time variable is correct, call the routine
;			//  which updates the header variables.
;			sci_logger_set_header_time (n);
^^^	move.w	d2,-(sp)
	jsr	_sci_logger_set_header_time
;		}	
^	add.w	#2,sp
.10212
	add.w	#1,d2
.10215
	cmp.w	_sci_logger+2554,d2
	blt	.10214
.10213
;		AD7716_clear_overflow ();
^	jsr	_AD7716_clear_overflow
;	}
^;}
.10201
^.94
	movem.l	(sp)+,d2
	unlk	a6
	rts
.92
.93	equ	-12
.91
	dc.b	115,99,105,95,108,111,103,103,101,114,95,111,118,101,114
	dc.b	102,108,111,119,95,99,104,101,99,107,58,32,65,68,55
	dc.b	55,49,54,32,98,117,102,102,101,114,32,111,118,101,114
	dc.b	102,108,111,119,46,10,32,32,100,97,116,97,32,108,111
	dc.b	115,116,32,64,0,37,115,0,84,104,101,32,105,110,112
	dc.b	117,116,32,100,97,116,97,32,98,117,102,102,101,114,32
	dc.b	111,118,101,114,102,108,111,119,101,100,32,97,110,100,32
	dc.b	115,99,105,101,110,99,101,32,100,97,116,97,32,119,97
	dc.b	115,32,108,111,115,116,46,10,0
	ds	0
;
;
;
;
;
;char sci_logger_month_name[12][4] = {
	dseg
	xdef	_sci_logger_month_name
_sci_logger_month_name:
;	"JAN",
	dc.b	74
	dc.b	65
	dc.b	78
	dc.b	0
;	"FEB",
	dc.b	70
	dc.b	69
	dc.b	66
	dc.b	0
;	"MAR",
	dc.b	77
	dc.b	65
	dc.b	82
	dc.b	0
;	"APR",
	dc.b	65
	dc.b	80
	dc.b	82
	dc.b	0
;	"MAY",
	dc.b	77
	dc.b	65
	dc.b	89
	dc.b	0
;	"JUN",
	dc.b	74
	dc.b	85
	dc.b	78
	dc.b	0
;	"JUL",
	dc.b	74
	dc.b	85
	dc.b	76
	dc.b	0
;	"AUG",
	dc.b	65
	dc.b	85
	dc.b	71
	dc.b	0
;	"SEP",
	dc.b	83
	dc.b	69
	dc.b	80
	dc.b	0
;	"OCT",
	dc.b	79
	dc.b	67
	dc.b	84
	dc.b	0
;	"NOV",
	dc.b	78
	dc.b	79
	dc.b	86
	dc.b	0
;	"DEC",
	dc.b	68
	dc.b	69
	dc.b	67
	dc.b	0
;};	
	cseg
;
;
;void sci_logger_make_dir_name (char* buff, int channel, int year, int month, int day)  {
# 2166
| .96
	xdef	_sci_logger_make_dir_name
_sci_logger_make_dir_name:
;	ASSERT (month >= 1);
~~ buff 8 "#c"
~~ channel 12 "i"
~~ year 14 "i"
~~ month 16 "i"
~~ day 18 "i"
^;	ASSERT (month <= 12);
^;	ASSERT (day >= 1);
^;	ASSERT (day <= 31);
^;	ASSERT (year >= 1970);
^;	sprintf (buff, "\\S%d_%4d\\%s%d\\", channel, year, sci_logger_month_name[month-1], day);
^	move.w	14(sp),-(sp)
	move.w	14(sp),d0
	sub.w	#1,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_sci_logger_month_name,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	move.w	16(sp),-(sp)
	move.w	16(sp),-(sp)
	pea	.95+0
	move.l	18(sp),-(sp)
	jsr	_sprintf
;	#ifdef DEBUG
;		printf ("sci_logger_make_dir_name: dir name = %s\n", buff);	
;	#endif	
;	return;
^^^^	lea	18(sp),sp
.97
	rts
;}
^.96
.95
	dc.b	92,83,37,100,95,37,52,100,92,37,115,37,100,92,0
	ds	0
;
;
;
;//  sci_logger_write_file (int buffer)
;//
;//  Writes one file to disk from the specified buffer.  The maximum length
;//  of a file is specifed by sci_logger.max_points_per_file, which as initialized
;//  at startup.  If there are more points then this waiting to be written, then
;//  this routine will not write all of the points to disk.  This routine should be
;//  called repeatedly until the number of points waiting is 0
;//
;int sci_logger_write_file (int buffer)  {
# 2189
| .99
	xdef	_sci_logger_write_file
_sci_logger_write_file:
	link	a6,#.100
	movem.l	d2/d3/d4/d5/d6/d7/a3/a4,-(sp)
	move.w	8(a6),d4
;	int fd, result, len;
;	long n_to_write, max_to_write, last_point;
;	long total_ticks, delta_ticks, delta_secs;
;	char filename[64];
;	int year, month, day, hour, min;
;	double dtemp;
;
;	#ifdef DEBUG
;	printf ("\nsci_logger_write_file: Writing file from buffer %d\n", buffer);
;	#endif
;	
;	//  Start by making file name, which is based on the date and time
;	//  months are numbered from 0, so add one before making name
;	year = atoi (sci_logger.channel[buffer].disk_header.year);
~ fd d5 "i"
~ result d7 "i"
~ len -2 "i"
~ n_to_write d6 "l"
~ max_to_write a4 "l"
~ last_point -6 "l"
~ total_ticks -10 "l"
~ delta_ticks a3 "l"
~ delta_secs -14 "l"
~ filename -78 "[64c"
~ year -80 "i"
~ month -82 "i"
~ day -84 "i"
~ hour -86 "i"
~ min -88 "i"
~ dtemp -96 "d"
~~ buffer d4 "i"
^^^^^^^^^^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+110,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_atoi
	move.w	d0,-80(a6)
;	month = atoi (sci_logger.channel[buffer].disk_header.month);
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+104,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_atoi
	move.w	d0,-82(a6)
;	day = atoi (sci_logger.channel[buffer].disk_header.day);
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+107,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_atoi
	move.w	d0,-84(a6)
;	hour = atoi (sci_logger.channel[buffer].disk_header.hours);
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+115,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_atoi
	move.w	d0,-86(a6)
;	min = atoi (sci_logger.channel[buffer].disk_header.minutes);
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+118,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	jsr	_atoi
	move.w	d0,-88(a6)
;//	Original file naming convention:
;//	sprintf (filename, "\\SCIENCE\\CHANNEL%d\\%4d\\%02d%02d%02d%02d.SCI", 
;//					sci_logger.channel[buffer].channel_num,
;//					year, month, day, hour, min);
;//
;//  New convention with improved tree structure which minimizes the number of
;//  directories that the software must read and therefore maximizes the speed:
;//	sprintf (filename, "\\S%d_%4d\\%s%d\\S%d_%02d%02d.SCI", 
;//					sci_logger.channel[buffer].channel_num, year,
;//					sci_logger_month_name[month-1], day,
;//					sci_logger.channel[buffer].channel_num, hour, min);
;//
;//  Another change to separate the directory name from the file name so that we
;//  can conveniently pre-create all necessary directories  
;	sci_logger_make_dir_name (filename, sci_logger.channel[buffer].channel_num, year, month, day);
^^^^^^^^^^^^^^^	move.w	-84(a6),-(sp)
	move.w	-82(a6),-(sp)
	move.w	-80(a6),-(sp)
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	pea	-78(a6)
	jsr	_sci_logger_make_dir_name
;	len = strlen (filename);
^	lea	-78(a6),a0
	move.l	a0,d0
.101	tst.b	(a0)+
	bne.s	.101
	sub.l	d0,a0
	sub.l	#1,a0
	move.w	a0,-2(a6)
;	sprintf (&filename[len], "S%d_%02d%02d.SCI", sci_logger.channel[buffer].channel_num, hour, min);
^	move.w	-88(a6),-(sp)
	move.w	-86(a6),-(sp)
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	pea	.98+0
	move.w	-2(a6),a0
	lea	-78(a6),a1
	add.l	a1,a0
	move.l	a0,-(sp)
	jsr	_sprintf
;	
;	#ifdef DEBUG
;	printf ("Filename %s\n", filename);
;	#endif
;
;	//  now open the file for writing
;	//  REVIEW - we really ought to check to make sure the file doesn't
;	//  yet exist.  (if the header needs writing).  Note that if the file
;	//  does exist this code will tack the new data on to the end of the
;	//  file, preventing data loss, but producing a screwed up format.
;	//  REVIEW - we should verify that the disk power is on
;	fd = logger_disk_open (filename, (PO_BINARY|PO_CREAT|PO_WRONLY), PS_IWRITE);
^^^^^^^^^^^^	move.w	#256,-(sp)
	move.w	#33025,-(sp)
	pea	-78(a6)
	jsr	_logger_disk_open
	lea	54(sp),sp
	move.w	d0,d5
;	if (fd < 0)  {
^	tst.w	d5
	bge	.10216
;		log_printf ("sci_logger_write_file: file ('%s') open failure.\n", filename);
^	pea	-78(a6)
	pea	.98+17
	jsr	_log_printf
;		log_printf ("  Error %d => %s.\n", get_errno (), get_errno_string(-1));
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.98+67
	jsr	_log_printf
;		return -1;
^	move.l	#-1,d0
	lea	18(sp),sp
.102
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7/a3/a4
	unlk	a6
	rts
;	}
^;	//  seek to the end of the file so we don't overwrite any previous data
;	critical_error_reset ();
.10216
^^	jsr	_critical_error_reset
;	if (po_lseek (fd, 0L, PSEEK_END) < 0)  {
^	move.w	#2,-(sp)
	clr.l	-(sp)
	move.w	d5,-(sp)
	jsr	_po_lseek
	tst.l	d0
	add.w	#8,sp
	bge	.10217
;		log_printf ("sci_logger_write_file: file ('%s') lseek failure.\n", filename);
^	pea	-78(a6)
	pea	.98+86
	jsr	_log_printf
;		log_printf ("  Error %d => %s.\n", get_errno (), get_errno_string(-1));
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.98+137
	jsr	_log_printf
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		po_close (fd);
^	move.w	d5,-(sp)
	jsr	_po_close
;		return -1;
^	move.l	#-1,d0
	lea	20(sp),sp
	bra	.102
;	}
^;			
;	if (sci_logger.channel[buffer].n_written == 0)  {
.10217
^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	tst.l	(a0,d0.l)
	bne	.10218
;		//  if no points have yet been written to this file then
;		//  write a header.
;		#ifdef DEBUG
;		printf ("Writing header to file.\n");		
;		#endif
;		ASSERT (sizeof (sci_logger.channel[buffer].disk_header) == 512);
^^^^^^;		critical_error_reset ();
^	jsr	_critical_error_reset
;		result = po_write (fd, (byte*)&sci_logger.channel[buffer].disk_header, 
^;									sizeof (sci_logger.channel[buffer].disk_header));
	move.w	#512,-(sp)
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger,a0
	add.l	a0,d0
	move.l	d0,-(sp)
	move.w	d5,-(sp)
	jsr	_po_write
	move.w	d0,d7
;		if (result != sizeof (sci_logger.channel[buffer].disk_header))  {
^^	cmp.w	#512,d7
	add.w	#8,sp
	beq	.10219
;			//  error writing
;			log_printf ("sci_logger_write_file: file ('%s') header write failure.\n", filename);
^^	pea	-78(a6)
	pea	.98+156
	jsr	_log_printf
;			log_printf ("  Tried to write %d, got %d\n",
^;					sizeof (sci_logger.channel[buffer].disk_header), result);
	move.w	d7,-(sp)
	pea	512
	pea	.98+214
	jsr	_log_printf
;			log_printf ("  Error %d => %s.\n", get_errno (), get_errno_string(-1));
^^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.98+243
	jsr	_log_printf
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			po_close (fd);
^	move.w	d5,-(sp)
	jsr	_po_close
;			return -1;
^	move.l	#-1,d0
	lea	30(sp),sp
	bra	.102
;		}
^;	}
.10219
^;	critical_error_reset ();
.10218
^	jsr	_critical_error_reset
;	po_flush (fd);
^	move.w	d5,-(sp)
	jsr	_po_flush
;		
;//printf ("The newest point in the buffer is %ld\n", sci_logger.channel[buffer].newest_data);
;//printf ("The buffer size is %ld\n", sci_logger.channel[buffer].n_data);
;//printf ("The first point to write is %ld\n", sci_logger.channel[buffer].next_to_write);
;//printf ("The number of points waiting is %ld\n", sci_logger.channel[buffer].n_waiting_to_write);
;//printf ("The last point to write is therefore %ld\n", last_point);
;//fflush (stdout);	
;
;	for (;;)  {
^^^^^^^^^	add.w	#2,sp
.10222
;		//  if no points to write, we're done.  Update time to indicate at next
;		//  point
;		if (sci_logger.channel[buffer].n_waiting_to_write <= 0)  {
^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	tst.l	(a0,d0.l)
	bgt	.10223
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			po_flush (fd);
^	move.w	d5,-(sp)
	jsr	_po_flush
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			po_close   (fd);
^	move.w	d5,-(sp)
	jsr	_po_close
;			#ifdef DEBUG
;			printf ("Wrote %ld points total to '%s'.\n",
;					sci_logger.channel[buffer].n_written, filename);
;	        #endif
;			sci_logger.channel[buffer].next_write_time = sci_logger.channel[buffer].end_time;
^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+622,a0
	move.l	d0,a2
	add.l	a0,a2
	move.l	(a2)+,(a1)+
	move.l	(a2)+,(a1)+
;			dtemp = ttmcmp (sci_logger.channel[buffer].end_time,
^;									sci_logger.channel[buffer].start_time);
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+622,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	jsr	_ttmcmp
	jsr	.Pflt#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;
;			dtemp /= (double)(sci_logger.channel[buffer].total_to_write - 1);
^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+590,a0
	move.l	(a0,d0.l),d0
	sub.l	#1,d0
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	-92(a6),d1
	move.l	-96(a6),d0
	jsr	.Pdiv#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;			dtemp += 0.5;
^	move.l	-92(a6),d1
	move.l	-96(a6),d0
	move.l	#$00000000,d3
	move.l	#$3fe00000,d2
	jsr	.Padd#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;			sci_logger.channel[buffer].next_write_time.ticks += (long)dtemp;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+634,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	-92(a6),d1
	move.l	-96(a6),d0
	jsr	.Pfix#
	add.l	d0,(a1)
;			if (sci_logger.channel[buffer].next_write_time.ticks >= GetTickRate ())  {
^	jsr	_GetTickRate
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+634,a0
	cmp.l	(a0,d1.l),d0
	lea	20(sp),sp
	bgt	.10224
;				sci_logger.channel[buffer].next_write_time.ticks -= GetTickRate ();
^	jsr	_GetTickRate
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+634,a0
	move.l	d1,a1
	add.l	a0,a1
	sub.l	d0,(a1)
;				sci_logger.channel[buffer].next_write_time.secs += 1;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	#1,(a1)
;			}
^;			sci_logger.channel[buffer].start_time = sci_logger.channel[buffer].next_write_time;
.10224
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a2
	add.l	a0,a2
	move.l	(a2)+,(a1)+
	move.l	(a2)+,(a1)+
;			#ifdef DEBUG
;			printf ("New start time: %s", logger_time_get_string (&sci_logger.channel[buffer].next_write_time));
;			printf ("\n");
;			#endif
;			return 0;
^^^^^	move.l	#0,d0
	bra	.102
;		}	
^;	
;		//  start by calculating how many points we should write.  Start with
;		//  the largest possible number, and reduce it as necessary
;		n_to_write = sci_logger.channel[buffer].n_waiting_to_write;
.10223
^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	move.l	(a0,d0.l),d6
;		
;		//  don't write more than the maximum number of points per file to this file
;		max_to_write = sci_logger.max_points_per_file - sci_logger.channel[buffer].n_written;
^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	move.l	_sci_logger+2566,a4
	sub.l	(a0,d0.l),a4
;		ASSERT (max_to_write > 0);
^;		if (n_to_write > max_to_write)
^;			n_to_write = max_to_write;
	cmp.l	a4,d6
	ble	.10225
^	move.l	a4,d6
;		
;		//  Data to write must be contiguous.  Don't try to write so much data
;		//  that we wrap around the end of the buffer
;		last_point = sci_logger.channel[buffer].next_to_write + n_to_write;
.10225
^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	(a0,d0.l),d0
	add.l	d6,d0
	move.l	d0,-6(a6)
;		if (last_point >= sci_logger.channel[buffer].n_data)
^;			n_to_write = sci_logger.channel[buffer].n_data - sci_logger.channel[buffer].next_to_write;
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.l	(a0,d0.l),d0
	cmp.l	-6(a6),d0
	bgt	.10226
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+516,a0
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+602,a1
	move.l	(a0,d0.l),d6
	sub.l	(a1,d1.l),d6
;
;		//  The number of bytes written must fit into an unsigned 16 bit integer.
;		//  The maximum numbers listed here conveniently correspond to a 64k file
;		//  length with a 512 byte header, as well as fitting into the unsigned
;		//  16 bit integer size.
;		#ifdef SHORT_SCIENCE_DATA
;			if (n_to_write > 32512)
.10226
^^^^^^^;				n_to_write = 32512;
	cmp.l	#32512,d6
	ble	.10227
^	move.l	#32512,d6
;    	#endif
;		#ifdef LONG_SCIENCE_DATA
;			if (n_to_write > 16256)
;				n_to_write = 16128;
;    	#endif
;    	#ifdef DEBUG
;		printf ("About to write %ld point block to fd %d\n", n_to_write, fd);    	
;		#endif
;
;		if (sci_logger_write_buffer (fd, buffer, n_to_write) != 0)  {
.10227
^^^^^^^^^^	move.l	d6,-(sp)
	move.w	d4,-(sp)
	move.w	d5,-(sp)
	jsr	_sci_logger_write_buffer
	tst.w	d0
	add.w	#8,sp
	beq	.10228
;			//  REVIEW - should think about error handling
;			log_printf ("sci_logger_write_file: file ('%s') buffer write failure.\n", filename);
^^	pea	-78(a6)
	pea	.98+262
	jsr	_log_printf
;			log_printf ("  Tried to write %ld to fd %d, got %d\n", n_to_write, fd, result);
^	move.w	d7,-(sp)
	move.w	d5,-(sp)
	move.l	d6,-(sp)
	pea	.98+320
	jsr	_log_printf
;			log_printf ("  Error %d => %s.\n", get_errno (), get_errno_string(-1));
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.98+359
	jsr	_log_printf
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			po_close (fd);
^	move.w	d5,-(sp)
	jsr	_po_close
;			return -1;
^	move.l	#-1,d0
	lea	32(sp),sp
	bra	.102
;		}
^;		#ifdef DEBUG
;			sci_logger_assert_file_size (filename, buffer);
;		#endif	
;			
;		if (sci_logger.channel[buffer].n_written >= sci_logger.max_points_per_file)  {
.10228
^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	move.l	(a0,d0.l),d0
	cmp.l	_sci_logger+2566,d0
	blt	.10229
;			#ifdef DEBUG
;			printf ("Wrote %ld points total to '%s'.\n",
;					sci_logger.channel[buffer].n_written, filename);
;			printf ("File length maxed out; updating time\n");			
;	        #endif
;			critical_error_reset ();
^^^^^^	jsr	_critical_error_reset
;			po_close (fd);
^	move.w	d5,-(sp)
	jsr	_po_close
;			sci_logger.channel[buffer].n_written = 0;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	clr.l	(a0,d0.l)
;			//  update time of next_to_write and the header time
;			total_ticks = ttmcmp (sci_logger.channel[buffer].end_time,
^^;									sci_logger.channel[buffer].start_time);
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+622,a1
	move.l	d0,a2
	add.l	a1,a2
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	jsr	_ttmcmp
	move.l	d0,-10(a6)
;
;			dtemp = (double)sci_logger.channel[buffer].total_written;
^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+598,a0
	move.l	(a0,d0.l),d0
	jsr	.Pflt#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;			dtemp /= (double)(sci_logger.channel[buffer].total_to_write - 1);
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+590,a0
	move.l	(a0,d0.l),d0
	sub.l	#1,d0
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	-92(a6),d1
	move.l	-96(a6),d0
	jsr	.Pdiv#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;			dtemp *= total_ticks;
^	move.l	-10(a6),d0
	jsr	.Pflt#
	move.l	-92(a6),d3
	move.l	-96(a6),d2
	jsr	.Pmul#
	move.l	d1,-92(a6)
	move.l	d0,-96(a6)
;			delta_ticks = (long)(0.5 + dtemp);
^	move.l	-92(a6),d1
	move.l	-96(a6),d0
	move.l	#$00000000,d3
	move.l	#$3fe00000,d2
	jsr	.Padd#
	jsr	.Pfix#
	move.l	d0,a3
;			
;			delta_secs = delta_ticks/GetTickRate ();
^^	jsr	_GetTickRate
	move.l	d0,d1
	move.l	a3,d0
	jsr	.divs#
	move.l	d0,-14(a6)
;			#ifdef DEBUG
;			printf ("Total delta ticks (start to end of buffer) ticks %ld\n", total_ticks);									
;			printf ("Total delta ticks (start to end of file) %ld\n", delta_ticks);											
;			printf ("Delta secs %ld\n", delta_secs);			
;			#endif
;			delta_ticks -= (delta_secs*GetTickRate());
^^^^^^	jsr	_GetTickRate
	move.l	-14(a6),d1
	jsr	.mulu#
	sub.l	d0,a3
;			ASSERT (delta_ticks >= 0);
^;			ASSERT (delta_ticks < GetTickRate ());
^;			sci_logger.channel[buffer].next_write_time = sci_logger.channel[buffer].start_time;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+614,a0
	move.l	d0,a2
	add.l	a0,a2
	move.l	(a2)+,(a1)+
	move.l	(a2)+,(a1)+
;			#ifdef DEBUG
;			printf ("Delta ticks is %ld (= 0.%ld sec)\n", delta_ticks, delta_ticks*25);	
;			printf ("Orig start time: %s", logger_time_get_string (&sci_logger.channel[buffer].next_write_time));
;			#endif
;			sci_logger.channel[buffer].next_write_time.secs += delta_secs;
^^^^^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	-14(a6),d0
	add.l	d0,(a1)
;			sci_logger.channel[buffer].next_write_time.ticks += delta_ticks;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+634,a0
	move.l	d0,a1
	add.l	a0,a1
	move.l	a3,d0
	add.l	d0,(a1)
;			if (sci_logger.channel[buffer].next_write_time.ticks >= GetTickRate ())  {
^	jsr	_GetTickRate
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+634,a0
	cmp.l	(a0,d1.l),d0
	lea	18(sp),sp
	bgt	.10230
;				sci_logger.channel[buffer].next_write_time.ticks -= GetTickRate ();
^	jsr	_GetTickRate
	move.w	d4,d1
	muls.w	#638,d1
	lea	_sci_logger+634,a0
	move.l	d1,a1
	add.l	a0,a1
	sub.l	d0,(a1)
;				sci_logger.channel[buffer].next_write_time.secs += 1;
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+630,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	#1,(a1)
;			}
^;			#ifdef DEBUG
;			printf ("New start time: %s", logger_time_get_string (&sci_logger.channel[buffer].next_write_time));
;			printf ("\n");
;			#endif
;			//  now that the next_write_time variable is correct, call the routine
;			//  which updates the header variables.
;			sci_logger_set_header_time (buffer);
.10230
^^^^^^^	move.w	d4,-(sp)
	jsr	_sci_logger_set_header_time
;			return 0;
^	move.l	#0,d0
	add.w	#2,sp
	bra	.102
;		}
^;	}	
.10229
^.10220
	bra	.10222
;	return 0;
^	move.l	#0,d0
	bra	.102
;}
^.99
.100	equ	-96
.98
	dc.b	83,37,100,95,37,48,50,100,37,48,50,100,46,83,67
	dc.b	73,0,115,99,105,95,108,111,103,103,101,114,95,119,114
	dc.b	105,116,101,95,102,105,108,101,58,32,102,105,108,101,32
	dc.b	40,39,37,115,39,41,32,111,112,101,110,32,102,97,105
	dc.b	108,117,114,101,46,10,0,32,32,69,114,114,111,114,32
	dc.b	37,100,32,61,62,32,37,115,46,10,0,115,99,105,95
	dc.b	108,111,103,103,101,114,95,119,114,105,116,101,95,102,105
	dc.b	108,101,58,32,102,105,108,101,32,40,39,37,115,39,41
	dc.b	32,108,115,101,101,107,32,102,97,105,108,117,114,101,46
	dc.b	10,0,32,32,69,114,114,111,114,32,37,100,32,61,62
	dc.b	32,37,115,46,10,0,115,99,105,95,108,111,103,103,101
	dc.b	114,95,119,114,105,116,101,95,102,105,108,101,58,32,102
	dc.b	105,108,101,32,40,39,37,115,39,41,32,104,101,97,100
	dc.b	101,114,32,119,114,105,116,101,32,102,97,105,108,117,114
	dc.b	101,46,10,0,32,32,84,114,105,101,100,32,116,111,32
	dc.b	119,114,105,116,101,32,37,100,44,32,103,111,116,32,37
	dc.b	100,10,0,32,32,69,114,114,111,114,32,37,100,32,61
	dc.b	62,32,37,115,46,10,0,115,99,105,95,108,111,103,103
	dc.b	101,114,95,119,114,105,116,101,95,102,105,108,101,58,32
	dc.b	102,105,108,101,32,40,39,37,115,39,41,32,98,117,102
	dc.b	102,101,114,32,119,114,105,116,101,32,102,97,105,108,117
	dc.b	114,101,46,10,0,32,32,84,114,105,101,100,32,116,111
	dc.b	32,119,114,105,116,101,32,37,108,100,32,116,111,32,102
	dc.b	100,32,37,100,44,32,103,111,116,32,37,100,10,0,32
	dc.b	32,69,114,114,111,114,32,37,100,32,61,62,32,37,115
	dc.b	46,10,0
	ds	0
;
;
;
;
;int sci_logger_write_buffer (int fd, int n_buff, long n_points)  {
# 2413
| .104
	xdef	_sci_logger_write_buffer
_sci_logger_write_buffer:
	movem.l	d2/d3/d4/d5/d6/d7,-(sp)
	move.w	28(sp),d6
	move.w	30(sp),d2
	move.l	32(sp),d3
;	long first_point;
;	unsigned int n_bytes, result;
;
;	ASSERT (sci_logger.logger_open_flag == 1);
~ first_point d7 "l"
~ n_bytes d4 "I"
~ result d5 "I"
~~ fd d6 "i"
~~ n_buff d2 "i"
~~ n_points d3 "l"
^^^^;	ASSERT (fd >= 0);
^;	ASSERT ((n_buff >= 0) && (n_buff < N_SCI_CHANNELS));
^;	
;	//  for convenience only
;	first_point = sci_logger.channel[n_buff].next_to_write;
^^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	(a0,d0.l),d7
;	#ifdef DEBUG
;	printf ("sci_logger_write_buffer: Writing %ld points starting from %ld.\n", n_points, first_point);	
;	#endif
;	ASSERT ((first_point >= 0) && (first_point < sci_logger.channel[n_buff].n_data));
^^^^;	ASSERT ((first_point+n_points) <= sci_logger.channel[n_buff].n_data);
^;
;//  printf ("Writing %ld point block of data starting from %ld\n", n_to_write, first_point);
;	#ifdef SHORT_SCIENCE_DATA
;		ASSERT (n_points < 32767);
^^^^;		n_bytes = n_points * sizeof (short);
^	move.l	d3,d0
	add.l	d0,d0
	move.w	d0,d4
;   	#endif
;	#ifdef LONG_SCIENCE_DATA
;		ASSERT (n_points < 16383);
;		n_bytes = n_points * sizeof (long);
;   	#endif
;
;	critical_error_reset ();
^^^^^^^	jsr	_critical_error_reset
;	result = po_write (fd, (byte*)&sci_logger.channel[n_buff].data[first_point], n_bytes);
^	move.w	d4,-(sp)
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+512,a0
	move.l	d7,d1
	add.l	d1,d1
	add.l	(a0,d0.l),d1
	move.l	d1,-(sp)
	move.w	d6,-(sp)
	jsr	_po_write
	move.w	d0,d5
;	if (result != n_bytes)  {
^	cmp.w	d4,d5
	add.w	#8,sp
	beq	.10231
;		log_printf ("sci_logger_write_buffer: Error writing data to disk.\n");
^	pea	.103+0
	jsr	_log_printf
;		log_printf ("  Error: %s\n", get_errno_string(-1));
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	pea	.103+54
	jsr	_log_printf
;		log_printf ("  Tried %u, got %u\n", n_bytes, result);
^	move.w	d5,-(sp)
	move.w	d4,-(sp)
	pea	.103+67
	jsr	_log_printf
;		#ifdef DEBUG
;		printf ("First point is %ld; address is 0x%08lX, n_bytes is 0x%04X\n",
;						first_point,
;						(long)&sci_logger.channel[n_buff].data[first_point],
;						n_bytes);
;		printf ("Start of buffer is at 0x%08lX\n", 
;						(long)&sci_logger.channel[n_buff].data[0]);
;		#endif
;		critical_error_reset ();
^^^^^^^^^	jsr	_critical_error_reset
;		po_flush (fd);
^	move.w	d6,-(sp)
	jsr	_po_flush
;		return -1;
^	move.l	#-1,d0
	lea	22(sp),sp
.105
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7
	rts
;	}
^;	critical_error_reset ();
.10231
^	jsr	_critical_error_reset
;	po_flush (fd);
^	move.w	d6,-(sp)
	jsr	_po_flush
;
;	sci_logger.channel[n_buff].next_to_write += n_points;
^^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	d3,(a1)
;	ASSERT (sci_logger.channel[n_buff].next_to_write <= sci_logger.channel[n_buff].n_data);
^;	if (sci_logger.channel[n_buff].next_to_write >= sci_logger.channel[n_buff].n_data)
^;		sci_logger.channel[n_buff].next_to_write = 0;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.w	d2,d1
	muls.w	#638,d1
	lea	_sci_logger+516,a1
	move.l	(a0,d0.l),d0
	cmp.l	(a1,d1.l),d0
	add.w	#2,sp
	blt	.10232
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	clr.l	(a0,d0.l)
;	sci_logger.channel[n_buff].n_written += n_points;
.10232
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+594,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	d3,(a1)
;	sci_logger.channel[n_buff].total_written += n_points;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+598,a0
	move.l	d0,a1
	add.l	a0,a1
	add.l	d3,(a1)
;	sci_logger.channel[n_buff].n_waiting_to_write -= n_points;
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	move.l	d0,a1
	add.l	a0,a1
	sub.l	d3,(a1)
;	#ifdef DEBUG
;	printf ("Updated next_to_write is %ld\n", sci_logger.channel[n_buff].next_to_write);
;	printf ("n_written %ld\n", sci_logger.channel[n_buff].n_written);
;	printf ("total_written %ld\n", sci_logger.channel[n_buff].total_written);
;	printf ("n_waiting_to_write %ld\n", sci_logger.channel[n_buff].n_waiting_to_write);
;	#endif
;
;	ASSERT (sci_logger.channel[n_buff].n_waiting_to_write >= 0);
^^^^^^^^;	//  REVIEW - why is this here?
;	//  how does it line up with our need to track the next to write as we
;	//  empty out the buffer on a continuously triggered channel?
;	if (sci_logger.channel[n_buff].n_waiting_to_write <= 0)
^^^^;		sci_logger.channel[n_buff].next_to_write = -1;
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	tst.l	(a0,d0.l)
	bgt	.10233
^	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+602,a0
	move.l	#-1,(a0,d0.l)
;	return 0;
.10233
^	move.l	#0,d0
	bra	.105
;}
^.104
.103
	dc.b	115,99,105,95,108,111,103,103,101,114,95,119,114,105,116
	dc.b	101,95,98,117,102,102,101,114,58,32,69,114,114,111,114
	dc.b	32,119,114,105,116,105,110,103,32,100,97,116,97,32,116
	dc.b	111,32,100,105,115,107,46,10,0,32,32,69,114,114,111
	dc.b	114,58,32,37,115,10,0,32,32,84,114,105,101,100,32
	dc.b	37,117,44,32,103,111,116,32,37,117,10,0
	ds	0
;
;
;
;//  sci_logger_setup_partition (void)
;//
;//  This subroutine creates the directories that the science logger expects
;//  to need to store data in on the current partition.  It is not strictly
;//  necessary to call this routine, but it may improve performance by putting
;//  the directory names at the start of the file structure.
;//
;void sci_logger_setup_partition (void)  {
# 2492
| .107
	xdef	_sci_logger_setup_partition
_sci_logger_setup_partition:
	link	a6,#.108
	movem.l	d2/d3/d4/d5/d6/d7/a3,-(sp)
;	dword blocks_total, blocks_free;
;	long blocks_per_day, n_days, n;
;	struct tm* tp;
;	time_tt now;
;	int chan;
;	char dirname[128];
;
;	logger_disk_power_disk_on ();
~ blocks_total -4 "L"
~ blocks_free -8 "L"
~ blocks_per_day d6 "l"
~ n_days d4 "l"
~ n d7 "l"
~ tp a3 "#:" 2
~ now -16 ":" 1
~ chan d5 "i"
~ dirname -144 "[128c"
^^^^^^^^	jsr	_logger_disk_power_disk_on
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	pc_free(logger_disk_get_partition(), &blocks_total, &blocks_free);
^	pea	-8(a6)
	pea	-4(a6)
	jsr	_logger_disk_get_partition
	move.l	d0,-(sp)
	jsr	_pc_free
;	
;	#ifdef SHORT_SCIENCE_DATA
;		//               bytes/conversion * seconds/day * conversions/second divided by bytes/block
;		blocks_per_day = 2.0 * 86400L * sci_logger_get_conversion_rate () * sci_logger_get_n_channels () / 512.0;
^^^^	jsr	_sci_logger_get_conversion_rate
	lea	12(sp),sp
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	jsr	_sci_logger_get_n_channels
	move.w	d0,d1
	ext.l	d1
	move.l	d1,d0
	jsr	.Pflt#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	move.l	#$00000000,d3
	move.l	#$41051800,d2
	jsr	.Pmul#
	move.l	#$00000000,d3
	move.l	#$40800000,d2
	jsr	.Pdiv#
	jsr	.Pfix#
	move.l	d0,d6
;	#endif	
;	#ifdef LONG_SCIENCE_DATA
;		blocks_per_day = 4.0 * 86400L * sci_logger_get_conversion_rate() * sci_logger_get_n_channels () / 512.0;
;	#endif
;	
;	if (blocks_per_day == 0)  {
^^^^^^	tst.l	d6
	bne	.10234
;		printf ("sci_logger_setup_partition: Unexpected failure to calculate disk requirements\n");
^	pea	.106+0
	jsr	_printf
;		logger_disk_power_disk_off ();
^	jsr	_logger_disk_power_disk_off
;		return;
^	add.w	#4,sp
.109
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7/a3
	unlk	a6
	rts
;	}		
^;	
;	n_days = blocks_free / blocks_per_day;
.10234
^^	move.l	-8(a6),d0
	move.l	d6,d1
	jsr	.divu#
	move.l	d0,d4
;	n_days += 2;
^	add.l	#2,d4
;	printf ("There is room on this disk for approximately %ld days data\n", n_days);
^	move.l	d4,-(sp)
	pea	.106+79
	jsr	_printf
;	
;	now = logger_time_get_time ();
^^	lea	-16(a6),a0
	add.w	#8,sp
	move.l	a0,-(sp)
	jsr	_logger_time_get_time
	move.l	d0,a0
	move.l	(sp)+,a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
;	//  anything greater than 1000 just not reasonable
;	ASSERT (n_days < 1000);
^^;	for (n = 0;  n < n_days;  n++)  {
^	move.l	#0,d7
	bra	.10238
.10237
;//		printf ("day %ld\n", n);		
;		for (chan = 0;  chan < sci_logger_get_n_channels();  chan++)  {
^^	move.l	#0,d5
	bra	.10242
.10241
;//			printf ("  chan %d\n", chan);		
;			tp = localtime (&now.secs);
^^	pea	-16(a6)
	jsr	_localtime
	move.l	d0,a3
;			if (tp->tm_year < 70)
^;				tp->tm_year += 2000;
	cmp.w	#70,10(a3)
	add.w	#4,sp
	bge	.10243
^	lea	10(a3),a0
	add.w	#2000,(a0)
;			else
	bra	.10244
.10243
;				tp->tm_year += 1900;
^^	lea	10(a3),a0
	add.w	#1900,(a0)
.10244
;			sci_logger_make_dir_name (dirname, sci_logger.channel[chan].channel_num,
^;												 tp->tm_year, 1+tp->tm_mon, tp->tm_mday);
	move.w	6(a3),-(sp)
	move.w	8(a3),d0
	add.w	#1,d0
	move.w	d0,-(sp)
	move.w	10(a3),-(sp)
	move.w	d5,d0
	muls.w	#638,d0
	lea	_sci_logger+528,a0
	move.w	(a0,d0.l),-(sp)
	pea	-144(a6)
	jsr	_sci_logger_make_dir_name
;			critical_error_reset ();
^^	jsr	_critical_error_reset
;			if (pc_isdir(dirname) == FALSE)  {
^	pea	-144(a6)
	jsr	_pc_isdir
	tst.w	d0
	lea	16(sp),sp
	bne	.10245
;				printf ("Making directory '%s'\n", dirname);			
^	pea	-144(a6)
	pea	.106+139
	jsr	_printf
;				strcat (dirname, "fname");
^	pea	.106+162
	pea	-144(a6)
	jsr	_strcat
;				logger_disk_make_dir (dirname);
^	pea	-144(a6)
	jsr	_logger_disk_make_dir
;			}	
^;		}
	lea	20(sp),sp
.10245
^.10239
	add.w	#1,d5
.10242
	jsr	_sci_logger_get_n_channels
	cmp.w	d5,d0
	bgt	.10241
.10240
;		//  add one day to the current time and create next batch of directories
;		now.secs += 86400L;
^^	add.l	#86400,-16(a6)
;	}
^.10235
	add.l	#1,d7
.10238
	cmp.l	d4,d7
	blt	.10237
.10236
;	printf ("All necessary directories created\n");
^	pea	.106+168
	jsr	_printf
;}
^	add.w	#4,sp
	bra	.109
.107
.108	equ	-144
.106
	dc.b	115,99,105,95,108,111,103,103,101,114,95,115,101,116,117
	dc.b	112,95,112,97,114,116,105,116,105,111,110,58,32,85,110
	dc.b	101,120,112,101,99,116,101,100,32,102,97,105,108,117,114
	dc.b	101,32,116,111,32,99,97,108,99,117,108,97,116,101,32
	dc.b	100,105,115,107,32,114,101,113,117,105,114,101,109,101,110
	dc.b	116,115,10,0,84,104,101,114,101,32,105,115,32,114,111
	dc.b	111,109,32,111,110,32,116,104,105,115,32,100,105,115,107
	dc.b	32,102,111,114,32,97,112,112,114,111,120,105,109,97,116
	dc.b	101,108,121,32,37,108,100,32,100,97,121,115,32,100,97
	dc.b	116,97,10,0,77,97,107,105,110,103,32,100,105,114,101
	dc.b	99,116,111,114,121,32,39,37,115,39,10,0,102,110,97
	dc.b	109,101,0,65,108,108,32,110,101,99,101,115,115,97,114
	dc.b	121,32,100,105,114,101,99,116,111,114,105,101,115,32,99
	dc.b	114,101,97,116,101,100,10,0
	ds	0
;
;
;
;
;#ifdef DEBUG
;void sci_logger_assert_file_size (char* fname, int buffer)  {
;	long temp;
;	STAT pstat;
;	#ifdef SHORT_SCIENCE_DATA
;		const short word_length = sizeof (short);
;	#endif
;	#ifdef LONG_SCIENCE_DATA
;		const short word_length = sizeof (long);
;	#endif
;	
;	critical_error_reset ();
;	if (pc_stat(fname, &pstat) != 0)  {
;		printf ("Couldn't stat '%s': %s\n", fname, get_errno_string (-1));
;		return;
;	}
;	temp = pstat.st_size - sizeof (sci_logger.channel[buffer].disk_header);
;	if ((temp%word_length) != 0)  {
;		printf ("File '%s':\n", fname);
;		printf ("  Length is %ld (not a multiple of data length!)\n", pstat.st_size);
;		printf ("  Number of points written is %ld\n",
;							sci_logger.channel[buffer].n_written);
;	}
;	temp /= word_length;
;	if (temp != sci_logger.channel[buffer].n_written)  {
;		printf ("Critical error!\n");
;		printf ("File '%s':\n", fname);
;		printf ("  Length of file is %ld\n", pstat.st_size);
;		printf ("  But number of points written is %ld\n",
;							sci_logger.channel[buffer].n_written);
;	}						
;}
;#endif		
;
;
;
;//  sci_logger_print_file
;//
;//  prints out a science file in an ASCII format
;//
;int sci_logger_print_file (int fd)  {
# 2592
| .111
	xdef	_sci_logger_print_file
_sci_logger_print_file:
;	return MacTrimpi_print_file (fd);
~~ fd 8 "i"
^	move.w	4(sp),-(sp)
	jsr	_MacTrimpi_print_file
	add.w	#2,sp
.112
	rts
;}	
^.111
;
;
;
;
;//  sci_logger_self_test (void)
;//
;//  Tests as much as possible of the data logger, including the
;//  following:
;//		1) should perform all internal consistency checks of the
;//				assert_valid routine, but should produce an error
;//				message instead of a program abort in the event of
;//				a failure.
;//		2) should verify that the specified gain is matched by the
;//				hardware setup
;//		3) should verify that the AD7716 is responding - i.e., that it
;//				interrupts and gives us data which at least has the
;//				channel numbers correct
;//
;//
;int sci_logger_self_test (void)  {
# 2614
| .113
	xdef	_sci_logger_self_test
_sci_logger_self_test:
	movem.l	d2/d3/d4/d5,-(sp)
;	int n;
;	long temp;
;	
;	//  make sure the logger is open
;	if (sci_logger.logger_open_flag == 0)  {
~ n d4 "i"
~ temp d5 "l"
^^^^^	tst.w	_sci_logger+2552
	bne	.10246
;		printf ("The science logger is suspended.\n");
^	pea	.110+0
	jsr	_printf
;		return -1;
^	move.l	#-1,d0
	add.w	#4,sp
.114
	movem.l	(sp)+,d2/d3/d4/d5
	rts
;//		return SCI_LOGGER_NOT_OPEN;
;	}
^^;		
;
;	//  if we get here, then we are open.  start by testing the variables
;	//  in the general science logger struct
;	if (sci_logger.n_channels <= 0)  {
.10246
^^^^^	tst.w	_sci_logger+2554
	bgt	.10247
;		printf ("There are no active channels.\n");
^	pea	.110+34
	jsr	_printf
;  		return -2;
^	move.l	#-2,d0
	add.w	#4,sp
	bra	.114
;//		return SCI_LOGGER_NO_ACTIVE_CHANS;
;	}
^^;
;	//  then test the variables in the individual science buffer structs
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
.10247
^^^	move.l	#0,d4
	bra	.10251
.10250
;		temp = sci_logger.channel[n].t_pre_event * sci_logger_get_conversion_rate ();
^	jsr	_sci_logger_get_conversion_rate
	move.w	d4,d2
	muls.w	#638,d2
	lea	_sci_logger+530,a0
	move.l	d2,a1
	add.l	a0,a1
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	(a1),d0
	jsr	.ftod#
	move.l	d1,d3
	move.l	d0,d2
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	jsr	.Pmul#
	jsr	.Pfix#
	move.l	d0,d5
;		if (sci_logger.channel[n].n_pre_event != temp)  {
^	move.w	d4,d0
	muls.w	#638,d0
	lea	_sci_logger+534,a0
	move.l	(a0,d0.l),d0
	cmp.l	d5,d0
	beq	.10252
;			printf ("The pre-event length is too long to fit the buffer.\n");
^	pea	.110+65
	jsr	_printf
;			return -3;
^	move.l	#-3,d0
	add.w	#4,sp
	bra	.114
;//			return SCI_LOGGER_PRE_EVENT;
;		}
^^;	}
.10252
^.10248
	add.w	#1,d4
.10251
	cmp.w	_sci_logger+2554,d4
	blt	.10250
.10249
;	return 0;
^	move.l	#0,d0
	bra	.114
;}		
^.113
.110
	dc.b	84,104,101,32,115,99,105,101,110,99,101,32,108,111,103
	dc.b	103,101,114,32,105,115,32,115,117,115,112,101,110,100,101
	dc.b	100,46,10,0,84,104,101,114,101,32,97,114,101,32,110
	dc.b	111,32,97,99,116,105,118,101,32,99,104,97,110,110,101
	dc.b	108,115,46,10,0,84,104,101,32,112,114,101,45,101,118
	dc.b	101,110,116,32,108,101,110,103,116,104,32,105,115,32,116
	dc.b	111,111,32,108,111,110,103,32,116,111,32,102,105,116,32
	dc.b	116,104,101,32,98,117,102,102,101,114,46,10,0
	ds	0
;
;
;
;int sci_logger_get_n_channels (void)  {
# 2648
| .116
	xdef	_sci_logger_get_n_channels
_sci_logger_get_n_channels:
;	return sci_logger.n_channels;
^	move.w	_sci_logger+2554,d0
.117
	rts
;}
^.116
;
;
;
;void sci_logger_show_status (void)  {
# 2654
| .118
	xdef	_sci_logger_show_status
_sci_logger_show_status:
	movem.l	d2,-(sp)
;	int n;
;
;	if (sci_logger_is_open() == 0)
~ n d2 "i"
^^^;		return;
	jsr	_sci_logger_is_open
	tst.w	d0
	bne	.10253
^.119
	movem.l	(sp)+,d2
	rts
;		
;	printf ("There are %ld points waiting.\n", AD7716_get_n_waiting ());
.10253
^^	jsr	_AD7716_get_n_waiting
	move.l	d0,-(sp)
	pea	.115+0
	jsr	_printf
;	printf ("The conversion rate is");
^	pea	.115+31
	jsr	_printf
;	fflush (stdout);
^	pea	__iob+22
	jsr	_fflush
;	printf (" %.9lf\n", sci_logger_get_conversion_rate ());
^	jsr	_sci_logger_get_conversion_rate
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.115+54
	jsr	_printf
;	printf ("Each channel has a buffer length of %ld points.\n", sci_logger.channel[0].n_data); 
^	move.l	_sci_logger+516,-(sp)
	pea	.115+62
	jsr	_printf
;	for (n = 0;  n < sci_logger.n_channels;  n++)  {
^	move.l	#0,d2
	lea	36(sp),sp
	bra	.10257
.10256
;		printf ("Channel %d has %ld points waiting for storage to disk\n",
^;										n, sci_logger.channel[n].n_waiting_to_write);
	move.w	d2,d0
	muls.w	#638,d0
	lea	_sci_logger+586,a0
	move.l	(a0,d0.l),-(sp)
	move.w	d2,-(sp)
	pea	.115+111
	jsr	_printf
;	}
^^	lea	10(sp),sp
.10254
	add.w	#1,d2
.10257
	cmp.w	_sci_logger+2554,d2
	blt	.10256
.10255
;}	
^	bra	.119
.118
.115
	dc.b	84,104,101,114,101,32,97,114,101,32,37,108,100,32,112
	dc.b	111,105,110,116,115,32,119,97,105,116,105,110,103,46,10
	dc.b	0,84,104,101,32,99,111,110,118,101,114,115,105,111,110
	dc.b	32,114,97,116,101,32,105,115,0,32,37,46,57,108,102
	dc.b	10,0,69,97,99,104,32,99,104,97,110,110,101,108,32
	dc.b	104,97,115,32,97,32,98,117,102,102,101,114,32,108,101
	dc.b	110,103,116,104,32,111,102,32,37,108,100,32,112,111,105
	dc.b	110,116,115,46,10,0,67,104,97,110,110,101,108,32,37
	dc.b	100,32,104,97,115,32,37,108,100,32,112,111,105,110,116
	dc.b	115,32,119,97,105,116,105,110,103,32,102,111,114,32,115
	dc.b	116,111,114,97,103,101,32,116,111,32,100,105,115,107,10
	dc.b	0
	ds	0
;
;	
;
;
;#ifdef DEBUG
;void sci_logger_dump_data (void)  {	
;	int n;
;
;	printf ("\nsci_logger.n_channels = %d\n", sci_logger.n_channels);
;	printf ("sci_logger.current_buffer = %d\n", sci_logger.current_buffer);
;	printf ("sci_logger.ASCII_preview_chan = %d\n", sci_logger.ASCII_preview_chan);
;	printf ("sci_logger.binary_preview_chan = %d\n", sci_logger.binary_preview_chan);
;	printf ("sci_logger.disk_threshold = %ld\n", sci_logger.disk_threshold);
;	printf ("sci_logger.max_points_per_file = %ld\n", sci_logger.max_points_per_file);
;	printf ("sci_logger.logger_open_flag = %d\n", sci_logger.logger_open_flag);
;	printf ("sci_logger.n_collected = %ld\n", sci_logger.n_collected);
;
;	for (n = 0;  n < N_SCI_CHANNELS;  n++)  {
;		if (sci_logger.channel[n].data == NULL)  {
;			printf ("Buffer %d is not in use.\n", n);
;			continue;
;		}
;		
;		printf ("Buffer %d is active\n", n);
;		printf ("  n_data = %ld\n", sci_logger.channel[n].n_data);
;		printf ("  newest_data = %ld\n", sci_logger.channel[n].newest_data);
;		printf ("  gain = %f\n", sci_logger.channel[n].gain);
;		printf ("  channel_num = %d\n", sci_logger.channel[n].channel_num);
;		printf ("  t_pre_event = %f\n", sci_logger.channel[n].t_pre_event);
;		printf ("  n_pre_event = %ld\n", sci_logger.channel[n].n_pre_event);
;		printf ("  t_post_event = %f\n", sci_logger.channel[n].t_post_event);
;		printf ("  n_post_event = %ld\n", sci_logger.channel[n].n_post_event);
;		printf ("  t_STA = %f\n", sci_logger.channel[n].t_STA);
;		printf ("  n_STA = %ld\n", sci_logger.channel[n].n_STA);
;		printf ("  t_LTA = %f\n", sci_logger.channel[n].t_LTA);
;		printf ("  n_LTA = %ld\n", sci_logger.channel[n].n_LTA);
;		printf ("  STA = %f\n", sci_logger.channel[n].STA);
;		printf ("  LTA = %f\n", sci_logger.channel[n].LTA);
;		printf ("  trigger_chan = 0x%04X\n", sci_logger.channel[n].trigger_chan);
;		printf ("  chans_to_trigger = 0x%04X\n", sci_logger.channel[n].chans_to_trigger);
;		printf ("  trigger_level = %f\n", sci_logger.channel[n].trigger_level);
;		printf ("  trigger_state = %d\n", sci_logger.channel[n].trigger_state);
;		printf ("  trigger_request = %d\n", sci_logger.channel[n].trigger_request);
;		printf ("  n_post_event_left = %ld\n", sci_logger.channel[n].n_post_event_left);
;		printf ("  n_waiting_to_write = %ld\n", sci_logger.channel[n].n_waiting_to_write);
;		printf ("  n_written = %ld\n", sci_logger.channel[n].n_written);
;		printf ("  next_to_write = %ld\n", sci_logger.channel[n].next_to_write);
;	}
;	return;
;}	
;#endif
;
# 2720
|
~ _sci_logger_month_name * "[12[4c"
~ _SOFTWARE_VERSION * "f"
~ 'science_logger'
~ 'science_buffer'
~ 'MacTrimpi'
~ 5 25 512
~ magicstring 0 "[8c"
~ totalhdrs 8 "[3c"
~ abbrev 11 "[8c"
~ stationcode 19 "[3c"
~ title 22 "[82c"
~ month 104 "[3c"
~ day 107 "[3c"
~ year 110 "[5c"
~ hours 115 "[3c"
~ minutes 118 "[3c"
~ seconds 121 "[3c"
~ msec 124 "[4c"
~ sampling_period 128 "[15c"
~ samplebits 143 "[3c"
~ wordsize 146 "[2c"
~ typemark 148 "c"
~ swapping 149 "c"
~ signing 150 "c"
~ caltype 151 "c"
~ calmin 152 "[15c"
~ calmax 167 "[15c"
~ calunits 182 "[40c"
~ recordsize 222 "[6c"
~ sourcevers 228 "[9c"
~ fill 237 "[275c"
~ 4 31 638
~ disk_header 0 ":" 5
~ data 512 "#i"
~ n_data 516 "l"
~ newest_data 520 "l"
~ gain 524 "f"
~ channel_num 528 "i"
~ t_pre_event 530 "f"
~ n_pre_event 534 "l"
~ t_post_event 538 "f"
~ n_post_event 542 "l"
~ t_STA 546 "f"
~ n_STA 550 "l"
~ t_LTA 554 "f"
~ n_LTA 558 "l"
~ STA 562 "f"
~ LTA 566 "f"
~ trigger_chan 570 "i"
~ chans_to_trigger 572 "i"
~ trigger_level 574 "f"
~ trigger_state 578 "i"
~ trigger_request 580 "i"
~ n_post_event_left 582 "l"
~ n_waiting_to_write 586 "l"
~ total_to_write 590 "l"
~ n_written 594 "l"
~ total_written 598 "l"
~ next_to_write 602 "l"
~ rate 606 "d"
~ start_time 614 ":" 1
~ end_time 622 ":" 1
~ next_write_time 630 ":" 1
~ 3 10 2576
~ channel 0 "[4:" 4
~ logger_open_flag 2552 "i"
~ n_channels 2554 "i"
~ current_buffer 2556 "i"
~ ASCII_preview_chan 2558 "i"
~ binary_preview_chan 2560 "i"
~ disk_threshold 2562 "l"
~ max_points_per_file 2566 "l"
~ n_collected 2570 "L"
~ data_started 2574 "i"
~ _sci_logger * ":" 3
~ _sci_logger_value_to_voltage * "(f"
~ _sci_logger_set_header_time * "(v"
~ _sci_logger_write_buffer * "(i"
~ _sci_logger_write_file * "(i"
~ _sci_logger_preview_binary * "(v"
~ _sci_logger_preview_ASCII * "(v"
~ _sci_logger_compute_n * "(i"
~ _sci_logger_power_off * "(v"
~ _sci_logger_power_on * "(v"
~ _sci_logger_trigger_off * "(v"
~ _sci_logger_trigger_on * "(v"
~ _sci_logger_add_point * "(v"
~ _sci_logger_buffer_empty * "(v"
~ _sci_logger_buffer_delete * "(v"
~ _sci_logger_buffer_init * "(i"
~ disk_error _disk_error "i"
~ _logger_set_clock_rate * "(v"
~ _critical_error_reset * "(v"
~ _MacTrimpi_print_file * "(i"
~ _get_errno_string * "(#c"
~ _mem_find_max_malloc * "(l"
~ _log_printf * "(i"
~ 'text_log'
~ 6 5 1068
~ filename 0 "[32c"
~ data 32 "[1024c"
~ n_data 1056 "i"
~ n_filled 1058 "i"
~ oldest_data 1060 ":" 1
~ _logger_disk_make_dir * "(i"
~ _logger_disk_get_partition * "(#c"
~ _logger_disk_power_disk_off * "(v"
~ _logger_disk_power_disk_on * "(v"
~ _logger_disk_open * "(i"
~ _get_errno * "(i"
~ 'system_user'
~ 7 4 46
~ task_handle 0 "i"
~ rtfs_errno 2 "i"
~ dfltdrv 4 "i"
~ lcwd 6 "[10#v"
~ PSYSTEM_USER "#:" 7
~ SYSTEM_USER ":" 7
~ 'finode'
~ 'ddrive'
~ 'fatswap'
~ 10 7 300
~ n_to_swap 0 "I"
~ n_blocks_used 2 "I"
~ n_blocks_total 4 "I"
~ pdirty 6 "[32C"
~ block_0_is_valid 38 "i"
~ data_map 40 "[256C"
~ data_array 296 "#C"
~ 9 37 484
~ opencount 0 "i"
~ volume_serialno 2 "L"
~ volume_label 6 "[14C"
~ drv_serial_number 20 "[62C"
~ partition_base 82 "L"
~ partition_size 86 "L"
~ partition_type 90 "C"
~ current_power_count 92 "L"
~ bytespcluster 96 "I"
~ byte_into_cl_mask 98 "L"
~ fasize 102 "I"
~ rootblock 104 "L"
~ firstclblock 108 "L"
~ driveno 112 "I"
~ maxfindex 114 "L"
~ fatblock 118 "L"
~ secproot 122 "I"
~ fat_is_dirty 124 "i"
~ fat_swap_structure 126 ":" 10
~ bootaddr 426 "L"
~ oemname 430 "[9c"
~ bytspsector 440 "I"
~ secpalloc 442 "C"
~ log2_secpalloc 444 "I"
~ secreserved 446 "I"
~ numfats 448 "C"
~ numroot 450 "I"
~ numsecs 452 "L"
~ mediadesc 456 "C"
~ secpfat 458 "L"
~ secptrk 462 "I"
~ numhead 464 "I"
~ numhide 466 "L"
~ free_contig_base 470 "L"
~ free_contig_pointer 474 "L"
~ known_free_clusters 478 "l"
~ infosec 482 "I"
~ 'segdesc'
~ 11 4 14
~ nsegs 0 "i"
~ segindex 2 "i"
~ ncksum 4 "C"
~ segblock 6 "[2L"
~ 8 18 72
~ fname 0 "[8C"
~ fext 8 "[3C"
~ fattribute 11 "C"
~ resarea 12 "[8C"
~ fclusterhi 20 "I"
~ ftime 22 "I"
~ fdate 24 "I"
~ fcluster 26 "I"
~ fsize 28 "L"
~ alloced_size 32 "L"
~ opencount 36 "i"
~ openflags 38 "i"
~ my_drive 40 "#:" 9
~ my_block 44 "L"
~ my_index 48 "i"
~ pnext 50 "#:" 8
~ pprev 54 "#:" 8
~ s 58 ":" 11
~ 'drobj'
~ 'dirblk'
~ 13 3 10
~ my_frstblock 0 "L"
~ my_block 4 "L"
~ my_index 8 "i"
~ 'blkbuff'
~ 14 7 532
~ pnext 0 "#:" 14
~ lru 4 "L"
~ pdrive 8 "#:" 9
~ blockno 12 "L"
~ use_count 16 "i"
~ pad_to_4_align 18 "i"
~ data 20 "[512C"
~ 12 5 24
~ pdrive 0 "#:" 9
~ finode 4 "#:" 8
~ blkinfo 8 ":" 13
~ isroot 18 "i"
~ pblkbuff 20 "#:" 14
~ 'datestr'
~ 15 2 4
~ date 0 "I"
~ time 2 "I"
~ 'pc_file'
~ 16 8 24
~ pobj 0 "#:" 12
~ flag 4 "I"
~ fptr 6 "L"
~ fptr_cluster 10 "L"
~ fptr_block 14 "L"
~ needs_flush 18 "i"
~ is_free 20 "i"
~ at_eof 22 "i"
~ 'block_alloc'
~ 17 1 512
~ core 0 "[512C"
~ 'ptable'
~ 'ptable_entry'
~ 19 8 16
~ boot 0 "C"
~ s_head 1 "C"
~ s_cyl 2 "I"
~ p_typ 4 "C"
~ e_head 5 "C"
~ e_cyl 6 "I"
~ r_sec 8 "L"
~ p_size 12 "L"
~ 18 2 66
~ ents 0 "[4:" 19
~ signature 64 "I"
~ PTABLE ":" 18
~ PTABLE_ENTRY ":" 19
~ 'format_dec_tree'
~ 20 3 8
~ sec_p_alloc 0 "I"
~ ents_p_root 2 "I"
~ n_blocks 4 "L"
~ FORMAT_DEC_TREE ":" 20
~ PC_FILE ":" 16
~ DROBJ ":" 12
~ BLKBUFF ":" 14
~ DIRBLK ":" 13
~ FINODE ":" 8
~ SEGDESC ":" 11
~ 'lfninode'
~ 21 8 32
~ lfnorder 0 "C"
~ lfname1 1 "[10C"
~ lfnattribute 11 "C"
~ lfnres 12 "C"
~ lfncksum 13 "C"
~ lfname2 14 "[12C"
~ lfncluster 26 "I"
~ lfname3 28 "[4C"
~ LFNINODE ":" 21
~ 'dosinode'
~ 22 9 32
~ fname 0 "[8C"
~ fext 8 "[3C"
~ fattribute 11 "C"
~ resarea 12 "[8C"
~ fclusterhi 20 "I"
~ ftime 22 "I"
~ fdate 24 "I"
~ fcluster 26 "I"
~ fsize 28 "L"
~ DOSINODE ":" 22
~ DDRIVE ":" 9
~ FATSWAP ":" 10
~ BLOCK_ALLOC ":" 17
~ CLUSTERTYPE "L"
~ 'ide_control'
~ 'ide_drive_desc'
~ ''
~ 'atapi_packet_desc'
~ 'transfer_length'
~ 27 2 2
~ msb 0 "C"
~ lsb 1 "C"
~ 26 8 14
~ op_code 0 "C"
~ lun 1 "C"
~ lba 2 "L"
~ reserved1 6 "C"
~ transfer_length 8 ":" 27
~ reserved2 10 "C"
~ reserved3 11 "C"
~ reserved4 12 "C"
~ 'atapi_mode_sense_packet_desc'
~ 28 11 14
~ op_code 0 "C"
~ lun 1 "C"
~ pc_code_page 2 "C"
~ reserved1 3 "C"
~ reserved2 4 "C"
~ reserved3 5 "C"
~ reserved4 6 "C"
~ transfer_length 8 ":" 27
~ reserved5 10 "C"
~ reserved6 11 "C"
~ reserved7 12 "C"
~ 'atapi_format_unit_packet_desc'
~ 29 5 12
~ op_code 0 "C"
~ defect_list_format 1 "C"
~ track_number 2 "C"
~ interleave 3 "[2C"
~ reserved 5 "[7C"
~ 'atapi_old_format_unit_packet_de'
~ 30 7 12
~ op_code 0 "C"
~ reserved1 1 "C"
~ medium 2 "C"
~ reserved2 3 "[3C"
~ control_byte 6 "C"
~ track_number 7 "C"
~ reserved3 8 "[4C"
~ 'atapi_start_stop_packet_desc'
~ 31 6 12
~ op_code 0 "C"
~ lun 1 "C"
~ reserved1 2 "C"
~ reserved2 3 "C"
~ eject 4 "C"
~ reserved 5 "[7C"
~ 25 5 14
~ generic 0 ":" 26
~ mode_sense 0 ":" 28
~ format 0 ":" 29
~ old_format 0 ":" 30
~ start_stop 0 ":" 31
~ 24 17 48
~ num_heads 0 "C"
~ sec_p_track 1 "C"
~ sec_p_cyl 2 "I"
~ num_cylinders 4 "I"
~ max_multiple 6 "C"
~ supports_lba 8 "i"
~ total_lba 10 "L"
~ enable_mapping 14 "i"
~ media_changed 16 "i"
~ volume_start 18 "L"
~ volume_end 22 "L"
~ protocol 26 "C"
~ atapi_packet 28 ":" 25
~ atapi_packet_size 42 "I"
~ media_descriptor 44 "C"
~ medium_type_code 45 "C"
~ allocation_unit 46 "C"
~ 23 29 138
~ opencount 0 "i"
~ register_file_address 2 "#I"
~ interrupt_number 6 "i"
~ controller_number 8 "i"
~ command_complete 10 "i"
~ error_code 12 "I"
~ timer 14 "I"
~ block_size 16 "C"
~ sectors_remaining 18 "I"
~ user_address 20 "#C"
~ drive 24 "[2:" 24
~ vo_write_precomp 120 "C"
~ vo_sector_count 121 "C"
~ vo_sector_number 122 "C"
~ vo_cyl_low 123 "C"
~ vo_cyl_high 124 "C"
~ vo_drive_head 125 "C"
~ vo_feature 126 "C"
~ vo_command 127 "C"
~ vo_dig_out 128 "C"
~ vi_error 129 "C"
~ vi_sector_count 130 "C"
~ vi_sector_number 131 "C"
~ vi_cyl_low 132 "C"
~ vi_cyl_high 133 "C"
~ vi_drive_head 134 "C"
~ vi_status 135 "C"
~ vi_alt_status 136 "C"
~ vi_drive_addr 137 "C"
~ PIDE_CONTROLLER "#:" 23
~ IDE_CONTROLLER ":" 23
~ IDE_DRIVE_DESC ":" 24
~ ATAPI_PACKET ":" 25
~ ATAPI_PACKET_DESC ":" 26
~ ATAPI_OLD_FORMAT_UNIT_PACKET_DE ":" 30
~ ATAPI_START_STOP_UNIT_PACKET_DE ":" 31
~ ATAPI_FORMAT_UNIT_PACKET_DESC ":" 29
~ ATAPI_MODE_SENSE_PACKET_DESC ":" 28
~ 'Himawari_format_descriptor'
~ 'Himawari_defect_list_header'
~ 33 4 4
~ reserved 0 "C"
~ control_byte 1 "C"
~ length_msb 2 "C"
~ length_lsb 3 "C"
~ 'Himawari_formattable_capacity_d'
~ 34 3 8
~ number_of_blocks 0 "[4C"
~ reserved 4 "C"
~ block_length 5 "[3C"
~ 32 2 12
~ dlheader 0 ":" 33
~ capacity_descriptor 4 ":" 34
~ HIMAWARI_FORMAT_DESCRIPTOR ":" 32
~ HIMAWARI_FORMATTABLE_CAPACITY_D ":" 34
~ HIMAWARI_DEFECT_LIST_HEADER ":" 33
~ 'himawari_flexible_disk_page'
~ 35 17 32
~ page_code 0 "C"
~ page_length 1 "C"
~ transfer_rate_msb 2 "C"
~ transfer_rate_lsb 3 "C"
~ number_of_heads 4 "C"
~ sectors_per_track 5 "C"
~ bytes_per_cylinder_msb 6 "C"
~ bytes_per_cylinder_lsb 7 "C"
~ number_of_cylinders_msb 8 "C"
~ number_of_cylinders_lsb 9 "C"
~ reserved1 10 "[10C"
~ motor_off_delay 20 "C"
~ swp_swpp 21 "C"
~ reserved2 22 "[6C"
~ medium_rotation_rate_msb 28 "C"
~ medium_rotation_rate_lsb 29 "C"
~ reserved3 30 "[2C"
~ HIMAWARI_FLEXIBLE_DISK_PAGE ":" 35
~ TRANSFER_LENGTH ":" 27
~ BLOCKT "L"
~ _pc_isdir * "(i"
~ _pc_free * "(l"
~ _po_close * "(i"
~ _po_flush * "(i"
~ _po_lseek * "(l"
~ _po_write * "(i"
~ 'fmtparms'
~ 36 15 52
~ oemname 0 "[9c"
~ secpalloc 9 "C"
~ secreserved 10 "I"
~ numfats 12 "C"
~ secpfat 14 "L"
~ fmttype 18 "C"
~ numhide 20 "L"
~ numroot 24 "I"
~ mediadesc 26 "C"
~ secptrk 28 "I"
~ numhead 30 "I"
~ numcyl 32 "I"
~ physical_drive_no 34 "C"
~ binary_volume_label 36 "L"
~ text_volume_label 40 "[12c"
~ FMTPARMS ":" 36
~ 'freelistinfo'
~ 37 2 8
~ cluster 0 "L"
~ nclusters 4 "l"
~ FREELISTINFO ":" 37
~ 'fileseginfo'
~ 38 2 8
~ block 0 "l"
~ nblocks 4 "l"
~ FILESEGINFO ":" 38
~ 'stat'
~ 39 12 38
~ st_dev 0 "i"
~ st_ino 2 "i"
~ st_mode 4 "L"
~ st_nlink 8 "i"
~ st_rdev 10 "i"
~ st_size 12 "L"
~ st_atime 16 ":" 15
~ st_mtime 20 ":" 15
~ st_ctime 24 ":" 15
~ st_blksize 28 "l"
~ st_blocks 32 "l"
~ fattribute 36 "C"
~ STAT ":" 39
~ 'dstat'
~ 40 14 578
~ fname 0 "[9c"
~ fext 9 "[4c"
~ lfname 13 "[256C"
~ filename 269 "[15c"
~ fattribute 284 "C"
~ ftime 286 "I"
~ fdate 288 "I"
~ fsize 290 "L"
~ driveno 294 "i"
~ pname 296 "[9C"
~ pext 305 "[4C"
~ path 309 "[260c"
~ pobj 570 "#v"
~ pmom 574 "#v"
~ DSTAT ":" 40
~ DATESTR ":" 15
~ PCFD "i"
~ UNICODE "I"
~ IOADDRESS "#I"
~ PFCBYTE "#C"
~ PFCCHAR "#c"
~ PFVOID "#v"
~ PFCHAR "#c"
~ PFDWORD "#L"
~ PFLONG "#l"
~ PFWORD "#I"
~ PFINT "#i"
~ PFBYTE "#C"
~ BOOLEAN "i"
~ dword "L"
~ word "I"
~ byte "C"
~ PSPErr "c"
~ _PRAM "[8I"
~ _logger_time_get_string * "(#c"
~ _logger_time_get_time * "(:" 1
~ EARLIEST_LOGGER_TIME _EARLIEST_LOGGER_TIME ":" 1
~ LATEST_LOGGER_TIME _LATEST_LOGGER_TIME ":" 1
~ _sci_logger_show_status * "(v"
~ _sci_logger_is_open * "(i"
~ _sci_logger_self_test * "(i"
~ _sci_logger_print_file * "(i"
~ _sci_logger_setup_partition * "(v"
~ _sci_logger_make_dir_name * "(v"
~ _sci_logger_write_disk * "(i"
~ _sci_logger_overflow_check * "(v"
~ _sci_logger_disk_request * "(i"
~ _sci_logger_get_n_channels * "(i"
~ _sci_logger_set_binary_preview * "(v"
~ _sci_logger_set_ASCII_preview * "(v"
~ _sci_logger_collect * "(i"
~ _sci_logger_set_LTA_time * "(i"
~ _sci_logger_set_STA_time * "(i"
~ _sci_logger_set_post_event * "(i"
~ _sci_logger_set_pre_event * "(i"
~ _sci_logger_set_gain * "(i"
~ _sci_logger_set_trigger_level * "(v"
~ _sci_logger_activate_chans * "(i"
~ _sci_logger_get_conversion_rate * "(d"
~ _sci_logger_set_averaging * "(i"
~ _sci_logger_set_conversion_rate * "(d"
~ _sci_logger_resume_data * "(v"
~ _sci_logger_pause_data * "(v"
~ _sci_logger_stop_data * "(v"
~ _sci_logger_start_data * "(v"
~ _sci_logger_close * "(v"
~ _sci_logger_open * "(i"
~ _sci_logger_power_on_init * "(v"
~ _SensorPowerOFF * "(v"
~ _SensorPowerON * "(v"
~ _AnalogPowerOFF * "(v"
~ _AnalogPowerON * "(v"
~ _AD7716_get_n_waiting * "(l"
~ _AD7716_get_icount * "(L"
~ _AD7716_clear_overflow * "(v"
~ _AD7716_check_for_overflow * "(i"
~ _AD7716_get_data_point_time * "(:" 1
~ _AD7716_get_data_point * "(i"
~ _AD7716_resume_data * "(v"
~ _AD7716_pause_data * "(v"
~ _AD7716_stop_data * "(v"
~ _AD7716_start_data * "(v"
~ _AD7716_set_channels * "(v"
~ _AD7716_get_conversion_rate * "(d"
~ _AD7716_set_averaging * "(i"
~ _AD7716_set_conversion_rate * "(d"
~ _AD7716_close * "(v"
~ _AD7716_open * "(i"
~ _memset * "(#v"
~ _strcat * "(#c"
~ ''
~ 41 2 8
~ quot 0 "l"
~ rem 4 "l"
~ _labs * "(l"
~ ''
~ 42 2 4
~ quot 0 "i"
~ rem 2 "i"
~ _malloc * "(#v"
~ _free * "(v"
~ _atoi * "(i"
~ ldiv_t ":" 41
~ div_t ":" 42
~ '__stdio'
~ 43 8 22
~ _bp 0 "#C"
~ _bend 4 "#C"
~ _buff 8 "#C"
~ _flags 12 "I"
~ _unit 14 "c"
~ _bytbuf 15 "C"
~ _buflen 16 "L"
~ _tmpnum 20 "I"
~ _sprintf * "(i"
~ _printf * "(i"
~ _fflush * "(i"
~ __iob * "[0:" 43
~ FILE ":" 43
~ fpos_t "l"
~ va_list "#c"
~ ''
~ 44 13 46
~ libVersion 0 "l"
~ ramBase 4 "#c"
~ ramSize 8 "l"
~ ramWaits 12 "i"
~ flashBase 14 "#c"
~ flashSize 18 "l"
~ flashWaits 22 "i"
~ heapBot 24 "#v"
~ heapTop 28 "#v"
~ heapCur 32 "#v"
~ statusReg 36 "I"
~ vectorBase 38 "#v"
~ stackPtr 42 "#v"
~ infoAction "c"
~ TT8info ":" 44
~ UeeErr "c"
~ _GetTickRate * "(l"
~ _ttmcmp * "(l"
~ time_tt ":" 1
~ _SerPutByte * "(v"
~ XmdmErr "c"
~ FlashErr "c"
~ ''
~ 45 4 24
~ eSR 0 "I"
~ ePC 2 "L"
~ vectofs 6 "I"
~ states 8 "[8I"
~ ''
~ 46 4 20
~ preamble 0 "[4I"
~ jump 8 "I"
~ target 10 "L"
~ postamble 14 "[3I"
~ ExcCFramePtr "#:" 46
~ ExcCFrame ":" 46
~ ExcStackFrame ":" 45
~ _localtime * "(#:" 2
~ time_t "L"
~ clock_t "L"
~ wchar_t "c"
~ ptrdiff_t "l"
~ size_t "L"
~ bool "c"
~ vfptr "#(v"
~ ptr "#c"
~ ulpv "#L"
~ ulong "L"
~ uspv "#I"
~ unsint "I"
~ ushort "I"
~ ucpv "#C"
~ uchar "C"
	xref	_logger_set_clock_rate
	xref	_critical_error_reset
	xref	_MacTrimpi_print_file
	xref	_get_errno_string
	xref	_mem_find_max_malloc
	xref	_log_printf
	xref	_logger_disk_make_dir
	xref	_logger_disk_get_partition
	xref	_logger_disk_power_disk_off
	xref	_logger_disk_power_disk_on
	xref	_logger_disk_open
	xref	_get_errno
	xref	_pc_isdir
	xref	_pc_free
	xref	_po_close
	xref	_po_flush
	xref	_po_lseek
	xref	_po_write
	xref	_logger_time_get_string
	xref	_logger_time_get_time
	xref	_SensorPowerOFF
	xref	_SensorPowerON
	xref	_AnalogPowerOFF
	xref	_AnalogPowerON
	xref	_AD7716_get_n_waiting
	xref	_AD7716_get_icount
	xref	_AD7716_clear_overflow
	xref	_AD7716_check_for_overflow
	xref	_AD7716_get_data_point_time
	xref	_AD7716_get_data_point
	xref	_AD7716_resume_data
	xref	_AD7716_pause_data
	xref	_AD7716_stop_data
	xref	_AD7716_start_data
	xref	_AD7716_set_channels
	xref	_AD7716_get_conversion_rate
	xref	_AD7716_set_averaging
	xref	_AD7716_set_conversion_rate
	xref	_AD7716_close
	xref	_AD7716_open
	xref	_memset
	xref	_strcat
	xref	_labs
	xref	_malloc
	xref	_free
	xref	_atoi
	xref	_sprintf
	xref	_printf
	xref	_fflush
	xref	_GetTickRate
	xref	_ttmcmp
	xref	_SerPutByte
	xref	_localtime
	xref	.begin
	dseg
	xref	_SOFTWARE_VERSION
	global	_sci_logger,2576
	xref	__iob
	end
