;: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>
;
;/*  includes for our particular program  */
;#include		"assert.h"
;#include		"memcheck.h"
;#include		"science.h"
;#include		"engineer.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		"MAX186.h"
;#include		"criterr.h"
;
;
;const long ENG_LOGGER_MAX_N_POINTS = ((64L*1024L - sizeof(struct MacTrimpi))/sizeof(short));
	ds	0
	xdef	_ENG_LOGGER_MAX_N_POINTS
_ENG_LOGGER_MAX_N_POINTS:
	dc.l	$7f00
	cseg
;
;//  defined in main.c.  Sets the minimum system clock speed required
;//  for an engineering data read (which pauses the AD7716 processing)
;extern const long MIN_ENG_READ_FREQ;
;
;//  The structs and routines declared here instead of in the .h file
;//  are to be used only by the subroutines in this file.  All interactions
;//  with the engineering data logger are through the subroutines defined
;//  in the .h file.  The data structure written to disk is declared in the
;//	.h file.
;//
;//  Control structure with information describing each channel which
;//  is allocated.  This is information which is not part of the main
;//  data block which is written to disk.
;struct eng_data_record  {
;	time_tt first_point_time;	//  time at which first data point in the data BUFFER was collected
;	time_tt collect_time;		//  time at which we should collect the next data point
;	time_tt last_disk_write;	//  time at which data was last written to disk	
;	long delta_t;				//  time between data points.
;	long n_written;				//  number of data points written to disk
;	short n_data;				//  number of data points in the buffer now
;	char fname[64];				//  name of file to which the data is being written
;	short data[207];			//  actual data; rounds out record to 1024 bytes
;};
;const short eng_logger_max_n_data = 207;
	ds	0
	xdef	_eng_logger_max_n_data
_eng_logger_max_n_data:
	dc.w	207
	cseg
;//const short eng_logger_max_n_data = sizeof (struct eng_data_record->data) / sizeof (short);
;struct MacTrimpi eng_logger_header;
;
;
;//
;//  This is the control struct for engineering data collection.
;struct engineer_logger  {
;	struct eng_data_record* channel_buff[N_ENG_CHANNELS];
;	int engineer_open;			//  This variable is set when the open routine is called,
;								//  and is zero when the engineering logger is closed.
;
;} eng_logger;
;
;//  Routines used only within this file; reads one data point and adds
;//  to buffer for that channel
;void eng_logger_collect_chan (int chan);
;int eng_logger_write_buffer (int chan);
;int eng_logger_write_header (int chan);
;
;
;
;//  eng_logger_power_on_init (void)
;//
;//	Inits which should be executed at power-on.  Set pointers to NULL, and
;//  set the open flag to indicate closed.
;//
;void eng_logger_power_on_init (void)  {
# 80 'engineer.c' 679107535
| .2
	xdef	_eng_logger_power_on_init
_eng_logger_power_on_init:
	movem.l	d2,-(sp)
;	int n;
;	//  no particular reason for this, its just what I expect
;	ASSERT (sizeof (struct eng_data_record) == 512);
~ n d2 "i"
^^^;	ASSERT (ENG_LOGGER_MAX_N_POINTS >= 256);
^;
;	//printf ("Max points per engineering data file is %ld\n", (long)ENG_LOGGER_MAX_N_POINTS);	
;	eng_logger.engineer_open = 0;
^^^	clr.w	_eng_logger+16
;	for (n = 0;  n < N_ENG_CHANNELS;  n++)  {
^	move.l	#0,d2
.10003
;		//  REVIEW
;		//  Suppose the program resets for some reason (power glitch?)
;		//  and the program restarts.  How does this reset the memory
;		//  allocations routines?  how should this affect what we do
;		//  here?
;		eng_logger.channel_buff[n] = NULL;
^^^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	clr.l	(a0,d0.l)
;	}	
^.10001
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10003
.10002
;
;	//  twiddle the hardware
;	MAX186_shutdown (-1);
^^^	move.w	#-1,-(sp)
	jsr	_MAX186_shutdown
;	MAX186_power_up ();
^	jsr	_MAX186_power_up
;	MAX186_power_down ();
^	jsr	_MAX186_power_down
;	MAX186_shutdown (0);
^	clr.w	-(sp)
	jsr	_MAX186_shutdown
;}
^	add.w	#4,sp
.3
	movem.l	(sp)+,d2
	rts
.2
;
;
;
;//  eng_logger_open (void)
;//
;//  This routine should always be called by the user once before any
;//  other engineering logger functions are called.  It used to do work
;//  now it doesn't do anything.  Maybe it will be needed in future.
;//
;void eng_logger_open (void)  {
# 112
| .4
	xdef	_eng_logger_open
_eng_logger_open:
;	time_tt now;
;	int n;
;	
;	//  REVIEW
;	//  eng_logger.engineer_open is probably zero at this point, but it may
;	//  not be if we have reset the program in the middle due to
;	//  some exception or other disastorous error.  Set it to a value
;	//  which is unlikely to occur by accident.
;	ASSERT (eng_logger.engineer_open == 0);
~ ''
~ 1 2 8
~ secs 0 "L"
~ ticks 4 "l"
^^^^^^^^^;	eng_logger.engineer_open = ENGINEER_INCLUDED;
^	move.w	#32518,_eng_logger+16
;}
^.5
	rts
.4
;
;
;//  eng_logger_close (void)
;//
;//  Main purpose is to deallocate memory.  There is no way to fail.
;//
;void eng_logger_close (void)  {
# 130
| .6
	xdef	_eng_logger_close
_eng_logger_close:
	movem.l	d2,-(sp)
;	time_tt start_time;
;	int n;
;
;	//  don't crash if we call this routine even when we aren't open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
~ n d2 "i"
^^^^^	cmp.w	#32518,_eng_logger+16
	beq	.10004
;		ASSERT (eng_logger.engineer_open == 0);
^;		return;
^.7
	movem.l	(sp)+,d2
	rts
;	}	
^;
;	//  free any allocated buffers; because of possible bug in Aztec memory
;	//  routines we are careful to free in the reverse of the allocation order
;	for (n = N_ENG_CHANNELS-1;  n >= 0;  n--)  {
.10004
^^^^	move.l	#3,d2
.10007
;		if (eng_logger.channel_buff[n] != NULL)  {
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10008
;			free (eng_logger.channel_buff[n]);
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),-(sp)
	jsr	_free
;			eng_logger.channel_buff[n] = NULL;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	clr.l	(a0,d0.l)
;		}
^;	}
	add.w	#4,sp
.10008
^.10005
	sub.w	#1,d2
	tst.w	d2
	bge	.10007
.10006
;	eng_logger.engineer_open = 0;
^	clr.w	_eng_logger+16
;}
^	bra	.7
.6
;
;
;
;        
;//  eng_logger_channel_setup ()
;//
;//  Sets up a particular engineering channel.  Allocates memory for the
;//  buffer; inits variables, including the time variable which tells the
;//  collection routine when it is time to take data on this channel next
;//
;//  Channel numbers run from 0 up
;//
;//	Returns: 0 if OK, -1 on failure
;//  Failures: only if out of memory
;//
;int eng_logger_channel_setup (int chan, long delay)  {
# 165
| .8
	xdef	_eng_logger_channel_setup
_eng_logger_channel_setup:
	link	a6,#.9
	movem.l	d2/d3,-(sp)
	move.w	8(a6),d2
	move.l	10(a6),d3
;	int n;
;	time_tt now;
;	ASSERT ((chan >= 0) && (chan < N_ENG_CHANNELS));
~ now -8 ":" 1
~~ chan d2 "i"
~~ delay d3 "l"
^^^;
;	//  don't do anything unless the logger is open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
^^^	cmp.w	#32518,_eng_logger+16
	beq	.10009
;		ASSERT (eng_logger.engineer_open == 0);
^;		return 0;
^	move.l	#0,d0
.10
	movem.l	(sp)+,d2/d3
	unlk	a6
	rts
;	}
^;
;	//  If delay is not positive, then this channel should be turned off.
;	//  Deallocate memory if it was allocated.
;	//  REVIEW
;	//	This prevents us from freeing memory in the reverse of the allocation
;	//  order later on.  This may screw up the Aztec memory routines.
;	if (delay <= 0)  {
.10009
^^^^^^^	tst.l	d3
	bgt	.10010
;		if (eng_logger.channel_buff[chan] != NULL)  {
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10011
;			free (eng_logger.channel_buff[chan]);
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),-(sp)
	jsr	_free
;			eng_logger.channel_buff[chan] = NULL;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	clr.l	(a0,d0.l)
;		}
^;		return 0;
	add.w	#4,sp
.10011
^	move.l	#0,d0
	bra	.10
;	}
^;
;	//  allocate space for the data buffer/control structure, if
;	//  necessary.
;	if (eng_logger.channel_buff[chan] == NULL)  {
.10010
^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	bne	.10012
;		eng_logger.channel_buff[chan] = (struct eng_data_record*)
^;										malloc (sizeof (struct eng_data_record));
	pea	512
	jsr	_malloc
	move.w	d2,d1
	ext.l	d1
	asl.l	#2,d1
	lea	_eng_logger,a0
	move.l	d0,(a0,d1.l)
;		if (eng_logger.channel_buff[chan] == NULL)
^^;			return -1;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	add.w	#4,sp
	bne	.10013
^	move.l	#-1,d0
	bra	.10
;	}  else  {
.10013
^	bra	.10014
.10012
;		//  when we reset a channel rate on an active channel, we just throw out
;		//  the old data.
;		if (eng_logger.channel_buff[chan]->n_data != 0)  {
^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	tst.w	32(a0)
	beq	.10015
;			printf ("%d old data points at the old rate were lost.\n",
^;									eng_logger.channel_buff[chan]->n_data);
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),-(sp)
	pea	.1+0
	jsr	_printf
;		}
^^;	}
	add.w	#6,sp
.10015
^.10014
;	eng_logger.channel_buff[chan]->delta_t = delay;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.l	d3,24(a0)
;	eng_logger.channel_buff[chan]->n_written = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.l	28(a0)
;	eng_logger.channel_buff[chan]->n_data = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.w	32(a0)
;	eng_logger.channel_buff[chan]->last_disk_write = EARLIEST_LOGGER_TIME;	
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#16,a0
	lea	_EARLIEST_LOGGER_TIME,a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
;	eng_logger.channel_buff[chan]->first_point_time = LATEST_LOGGER_TIME;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	lea	_LATEST_LOGGER_TIME,a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
;
;	//  Now compute time at which we should collect the first data point.
;	//  The first collection is set for a couple of seconds after the
;	//  current time.
;	now = logger_time_get_time ();
^^^^^	lea	-8(a6),a0
	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)+
;	now.secs += 5;
^	add.l	#5,-8(a6)
;	eng_logger.channel_buff[chan]->collect_time = now;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#8,a0
	lea	-8(a6),a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
;
;	ASSERT (eng_logger_max_n_data*sizeof(short) == sizeof(eng_logger.channel_buff[chan]->data));
^^;	#ifdef DEBUG
;		for (n = 0;  n < eng_logger_max_n_data;  n++)
;			//  Set data points to an unexpected value so that we can have
;			//  an extra chance to catch screwups if the program fails and
;			//  marks uncollected points as collected
;			eng_logger.channel_buff[chan]->data[n] = 0xABCD;
;	#endif		
;}	
^^^^^^^^	bra	.10
.8
.9	equ	-8
.1
	dc.b	37,100,32,111,108,100,32,100,97,116,97,32,112,111,105
	dc.b	110,116,115,32,97,116,32,116,104,101,32,111,108,100,32
	dc.b	114,97,116,101,32,119,101,114,101,32,108,111,115,116,46
	dc.b	10,0
	ds	0
;	
;
;
;
;//  eng_logger_collect ()
;//
;//  Loops through all eight engineering channels, checks to see if it is
;//  time to collect data from that channel yet, and does so if appropriate
;//	
;//  Returns: 0; could be number of channels collected
;//  Failures: none currently
;//
;int eng_logger_collect (void)  {
# 238
| .12
	xdef	_eng_logger_collect
_eng_logger_collect:
	link	a6,#.13
	movem.l	d2/d3,-(sp)
;	time_tt now;
;	int chan;
;	long orig_freq;
;
;	//  don't do anything unless the logger is open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
~ now -8 ":" 1
~ chan d2 "i"
~ orig_freq d3 "l"
^^^^^^	cmp.w	#32518,_eng_logger+16
	beq	.10016
;		ASSERT (eng_logger.engineer_open == 0);
^;		return 0;
^	move.l	#0,d0
.14
	movem.l	(sp)+,d2/d3
	unlk	a6
	rts
;	}
^;	
;	//  record our initial clock speed in case we need to up it later for
;	//  data collection
;	orig_freq = SimGetFSys ();
.10016
^^^^	jsr	_SimGetFSys
	move.l	d0,d3
;
;	//  collect data from each engineering channel in turn as necessary
;	now = logger_time_get_time ();
^^^	lea	-8(a6),a0
	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)+
;	for (chan = 0;  chan < N_ENG_CHANNELS;  chan++)  {
^	move.l	#0,d2
.10019
;		if (eng_logger.channel_buff[chan] == NULL)
^;			continue;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10017
;		if (ttmcmp (now, eng_logger.channel_buff[chan]->collect_time) < 0)
^^;			continue;
	sub.w	#8,sp
	move.l	sp,a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	add.l	#8,a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	sub.w	#8,sp
	move.l	sp,a0
	lea	-8(a6),a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	jsr	_ttmcmp
	tst.l	d0
	lea	16(sp),sp
	blt	.10017
;		
;		//  time to collect more data from this channel.  But first,
;		//	up the clock speed so that we can process the data as
;		//  quickly as possible
;			
;		//  REVIEW - need to consider how changing frequency will affect
;		//  the baud rates, and adjust as needed.  This frequency change
;		//  is temporarily disabled - during debug the logger is not slowed
;		//  below the max anyway;  note also that this may inject noise into
;		//  the A/D converters
;//		SimSetFSys (16e6);
;		eng_logger_collect_chan (chan);
^^^^^^^^^^^^^	move.w	d2,-(sp)
	jsr	_eng_logger_collect_chan
;	}
^	add.w	#2,sp
.10017
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10019
.10018
;	//  reset clock speed back to original
;	SimSetFSys (orig_freq);
^^	move.l	d3,-(sp)
	jsr	_SimSetFSys
;	//  REVIEW - are we done yet???
;}
^^	add.w	#4,sp
	bra	.14
.12
.13	equ	-8
;
;
;
;
;//  eng_logger_collect_chan ()
;//
;//  Does the actual work of collecting a data point from a particular
;//  channel and adding it to the buffer.  See code for details on how
;//	this routine coordinates with the AD7716
;//
;//  Channel number run from 0 up
;//  
;void eng_logger_collect_chan (chan)  {
# 289
| .15
	xdef	_eng_logger_collect_chan
_eng_logger_collect_chan:
	movem.l	d2,-(sp)
	move.w	8(sp),d2
;	long count;
;
;	//  don't do anything unless the logger is open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
~~ chan d2 "i"
^^^^	cmp.w	#32518,_eng_logger+16
	beq	.10020
;		ASSERT (eng_logger.engineer_open == 0);
^;		return;
^.16
	movem.l	(sp)+,d2
	rts
;	}
^;	ASSERT (eng_logger.channel_buff[chan] != NULL);
.10020
^;	
;	//  make sure we have room in the local buffer for the data
;	if (eng_logger.channel_buff[chan]->n_data >= eng_logger_max_n_data)  {
^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),a0
	cmp.w	_eng_logger_max_n_data,a0
	blt	.10021
;		//  programming failure; the data buffer filled up and was not written
;		//  to disk before this routine was next called.
;		log_printf ("eng_logger_collect_chan: not reading channel %d because buffer is full.\n", chan);
^^^	move.w	d2,-(sp)
	pea	.11+0
	jsr	_log_printf
;		#ifdef DEBUG
;			printf ("Programming error in eng_logger_collect_chan!\n");
;		#endif	
;		//  skip this collection point; set up to collect data
;		//  from this channel next time round
;		eng_logger.channel_buff[chan]->collect_time.secs +=
^^^^^^;								eng_logger.channel_buff[chan]->delta_t;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#8,a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	move.l	24(a1),d0
	add.l	d0,(a0)
;		return;
^^	add.w	#6,sp
	bra	.16
;	}		
^;	
;	//  make sure we have room in the file for the data
;	if (eng_logger.channel_buff[chan]->n_data + eng_logger.channel_buff[chan]->n_written >=
.10021
^^^;																		ENG_LOGGER_MAX_N_POINTS)  {
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),d0
	ext.l	d0
	move.w	d2,d1
	ext.l	d1
	asl.l	#2,d1
	lea	_eng_logger,a0
	move.l	(a0,d1.l),a0
	add.l	28(a0),d0
	cmp.l	_ENG_LOGGER_MAX_N_POINTS,d0
	blt	.10022
^;		//  programming failure; any additional data will overflow the expected maximum file
;		//  size
;		log_printf ("eng_logger_collect_chan: not reading channel %d because file is full.\n", chan);
^^^	move.w	d2,-(sp)
	pea	.11+73
	jsr	_log_printf
;		#ifdef DEBUG
;			printf ("Programming error 2 in eng_logger_collect_chan!\n");
;		#endif	
;		//  skip this collection point; set up to collect data
;		//  from this channel next time round
;		eng_logger.channel_buff[chan]->collect_time.secs +=
^^^^^^;								eng_logger.channel_buff[chan]->delta_t;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#8,a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	move.l	24(a1),d0
	add.l	d0,(a0)
;		return;
^^	add.w	#6,sp
	bra	.16
;	}		
^;
;	//  get the data
;	eng_logger.channel_buff[chan]->data[eng_logger.channel_buff[chan]->n_data] = 
.10022
^^^;													eng_logger_read_channel (chan, 10);
	move.w	#10,-(sp)
	move.w	d2,-(sp)
	jsr	_eng_logger_read_channel
	move.w	d2,d1
	ext.l	d1
	asl.l	#2,d1
	lea	_eng_logger,a0
	move.l	(a0,d1.l),a0
	move.w	32(a0),d1
	ext.l	d1
	add.l	d1,d1
	add.w	#4,sp
	move.w	d0,-(sp)
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	(sp)+,d0
	move.w	d0,98(a0,d1.l)
;
;	//  if this is the very first point collected, then we set the first_point_time
;	if (eng_logger.channel_buff[chan]->n_data ==    0)  {
^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	tst.w	32(a0)
	bne	.10023
;		eng_logger.channel_buff[chan]->first_point_time =
^;				eng_logger.channel_buff[chan]->collect_time;	
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	add.l	#8,a1
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
;//printf ("eng chan %d: first point time set.\n", chan);				
;	}
^^^;	eng_logger.channel_buff[chan]->n_data++;
.10023
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.w	#1,32(a0)
;//printf ("e chan %d: %d (n_data %d, n_written %ld)\n", chan,
;//				eng_logger.channel_buff[chan]->data[eng_logger.channel_buff[chan]->n_data-1],
;//				eng_logger.channel_buff[chan]->n_data,
;//				eng_logger.channel_buff[chan]->n_written);
;	
;	if (eng_logger.channel_buff[chan]->n_data >= eng_logger_max_n_data)  {
^^^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),a0
	cmp.w	_eng_logger_max_n_data,a0
	blt	.10024
;		//  this data record is full
;		printf ("Oops - just filled up data record.\n");
^^	pea	.11+144
	jsr	_printf
;		log_printf ("Oops - just filled up data record.\n");
^	pea	.11+180
	jsr	_log_printf
;	}	
^;	
;	//  set up the next time to collect data from this channel
;	eng_logger.channel_buff[chan]->collect_time.secs +=
	add.w	#8,sp
.10024
^^^;								eng_logger.channel_buff[chan]->delta_t;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#8,a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	move.l	24(a1),d0
	add.l	d0,(a0)
;}
^^	bra	.16
.15
.11
	dc.b	101,110,103,95,108,111,103,103,101,114,95,99,111,108,108
	dc.b	101,99,116,95,99,104,97,110,58,32,110,111,116,32,114
	dc.b	101,97,100,105,110,103,32,99,104,97,110,110,101,108,32
	dc.b	37,100,32,98,101,99,97,117,115,101,32,98,117,102,102
	dc.b	101,114,32,105,115,32,102,117,108,108,46,10,0,101,110
	dc.b	103,95,108,111,103,103,101,114,95,99,111,108,108,101,99
	dc.b	116,95,99,104,97,110,58,32,110,111,116,32,114,101,97
	dc.b	100,105,110,103,32,99,104,97,110,110,101,108,32,37,100
	dc.b	32,98,101,99,97,117,115,101,32,102,105,108,101,32,105
	dc.b	115,32,102,117,108,108,46,10,0,79,111,112,115,32,45
	dc.b	32,106,117,115,116,32,102,105,108,108,101,100,32,117,112
	dc.b	32,100,97,116,97,32,114,101,99,111,114,100,46,10,0
	dc.b	79,111,112,115,32,45,32,106,117,115,116,32,102,105,108
	dc.b	108,101,100,32,117,112,32,100,97,116,97,32,114,101,99
	dc.b	111,114,100,46,10,0
	ds	0
;
;
;
;
;//  eng_logger_read_channel ()
;//
;//  Reads an engineering logger channel
;//  The channel numbers input to this routine run from
;//
;int eng_logger_read_channel (int chan, int n_to_average)  {
# 365
| .18
	xdef	_eng_logger_read_channel
_eng_logger_read_channel:
	movem.l	d2/d3/d4/d5/d6/d7,-(sp)
	move.w	30(sp),d7
;	int value, count;
;	long total;
;	long freq, baud;
;	ASSERT (n_to_average > 0);
~ value d4 "i"
~ count d5 "i"
~ total d3 "l"
~ freq d6 "l"
~ baud d2 "l"
~~ chan 8 "i"
~~ n_to_average d7 "i"
^^^^;
;
;	//  Make sure the clock rate is set at some minimum before we
;	//  wait for the interrupt.  The query time routine will print,
;	//  so we also adjust the baud rate.  If the current clock
;	//  exceed the min, don't bother changing
;	freq = SimGetFSys ();
^^^^^^^	jsr	_SimGetFSys
	move.l	d0,d6
;	if (freq < MIN_ENG_READ_FREQ)  {
^	cmp.l	_MIN_ENG_READ_FREQ,d6
	bge	.10025
;		baud = SerGetBaud (0, 0);
^	clr.l	-(sp)
	clr.l	-(sp)
	jsr	_SerGetBaud
	move.l	d0,d2
;		SimSetFSys (MIN_ENG_READ_FREQ);
^	move.l	_MIN_ENG_READ_FREQ,-(sp)
	jsr	_SimSetFSys
;		SerSetBaud (baud, 0);
^	clr.l	-(sp)
	move.l	d2,-(sp)
	jsr	_SerSetBaud
;	}  else
^	lea	20(sp),sp
	bra	.10026
.10025
;		baud = -1;	
^	move.l	#-1,d2
.10026
;	
;	MAX186_shutdown (-1);
^^	move.w	#-1,-(sp)
	jsr	_MAX186_shutdown
;	sci_logger_pause_data ();
^	jsr	_sci_logger_pause_data
;	MAX186_power_up ();
^	jsr	_MAX186_power_up
;	sci_logger_resume_data ();
^	jsr	_sci_logger_resume_data
;
;	total = 0;	
^^	move.l	#0,d3
;	for (count = 0;  count < n_to_average;  count++)  {
^	move.l	#0,d5
	add.w	#2,sp
	bra	.10030
.10029
;		//  Pause the science logger so that we can take control of the SPI
;		//  interface.  The pause routine takes care of all the timing so as
;		//  to maximize the time available to us here before the science logger
;		//  loses data
;		sci_logger_pause_data ();
^^^^^	jsr	_sci_logger_pause_data
;
;		//  Collect data here
;		//  REVIEW - we probably ought to pause briefly after powering up the
;		//  186 to allow it to stabilize.
;//		value = AtoDReadWord (chan);
;		value = MAX186_read_channel (chan);
^^^^^^	move.w	28(sp),-(sp)
	jsr	_MAX186_read_channel
	move.w	d0,d4
;		sci_logger_resume_data ();
^	jsr	_sci_logger_resume_data
;
;//		printf ("  %d\n", value);
;		if (value == 0x8000)  {
^^^	cmp.w	#32768,d4
	add.w	#2,sp
	bne	.10031
;			//  if we get an error on any one read, return an error
;			total = n_to_average*0x8000;
^^	move.w	d7,d0
	move.l	#15,d1
	asl.w	d1,d0
	move.l	#0,d1
	move.w	d0,d1
	move.l	d1,d3
;			break;
^	bra	.10028
;		}
^;		total += value;
.10031
^	move.w	d4,a0
	add.l	a0,d3
;	}
^.10027
	add.w	#1,d5
.10030
	cmp.w	d7,d5
	blt	.10029
.10028
;	sci_logger_pause_data ();
^	jsr	_sci_logger_pause_data
;	MAX186_power_down ();
^	jsr	_MAX186_power_down
;	MAX186_shutdown (0);
^	clr.w	-(sp)
	jsr	_MAX186_shutdown
;	sci_logger_resume_data ();
^	jsr	_sci_logger_resume_data
;
;	if (baud > 0)  {
^^	tst.l	d2
	add.w	#2,sp
	ble	.10032
;		SimSetFSys (freq);
^	move.l	d6,-(sp)
	jsr	_SimSetFSys
;		SerSetBaud (baud, 0);
^	clr.l	-(sp)
	move.l	d2,-(sp)
	jsr	_SerSetBaud
;	}
^;	return ((short)(total/n_to_average));
	lea	12(sp),sp
.10032
^	move.l	d3,d0
	move.w	d7,a0
	move.l	a0,d1
	jsr	.divs#
.19
	movem.l	(sp)+,d2/d3/d4/d5/d6/d7
	rts
;}	
^.18
;
;
;
;//  eng_logger_disk_switch (void)
;//
;//  Resets variables after a disk switch so that the next write includes
;//  all the header information.
;//
;void eng_logger_disk_switch (void)  {
# 431
| .20
	xdef	_eng_logger_disk_switch
_eng_logger_disk_switch:
	movem.l	d2,-(sp)
;	int chan;
;	//printf ("eng_logger_disk_switch: starting\n");	
;	for (chan = 0;  chan < N_ENG_CHANNELS;  chan++)  {
~ chan d2 "i"
^^^	move.l	#0,d2
.10035
;		if (eng_logger.channel_buff[chan] != NULL)
^;			eng_logger.channel_buff[chan]->n_written = 0;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10036
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.l	28(a0)
;	}		
.10036
^.10033
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10035
.10034
;	//printf ("eng_logger_disk_switch: ending\n");	
;}
^^.21
	movem.l	(sp)+,d2
	rts
.20
;
;
;
;//  eng_logger_disk_request ()
;//
;//	Returns non-zero if the engineering logger would like the disk to be
;//  spun up and the writing subroutine called.  The only time critical point
;//  is when a channel's buffer fills up.  The program must then write the
;//  data to disk before the data logging routine next tries to record a
;//  point, or that point will be skipped.
;//
;//	This routine will request a disk access if there is any data more than
;//  one day old, or if a buffer is full.
;//	
;int eng_logger_disk_request (void)  {
# 454
| .22
	xdef	_eng_logger_disk_request
_eng_logger_disk_request:
	movem.l	d2/d3/d4,-(sp)
;	int request;
;	int chan;
;	long age;
;	
;	//  don't do anything unless the logger is open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
~ request d3 "i"
~ chan d2 "i"
~ age d4 "l"
^^^^^^	cmp.w	#32518,_eng_logger+16
	beq	.10037
;		ASSERT (eng_logger.engineer_open == 0);
^;		return 0;
^	move.l	#0,d0
.23
	movem.l	(sp)+,d2/d3/d4
	rts
;	}
^;	
;	request = 0;
.10037
^^	move.l	#0,d3
;	for (chan = 0;  chan < N_ENG_CHANNELS;  chan++)  {
^	move.l	#0,d2
.10040
;		if (eng_logger.channel_buff[chan] == NULL)
^;			//  channel not active - skip it
;			continue;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10038
;			
;		//  channel is active; check for full and check for stale data
;		//  check if oldest data is more than one day old
;		age = eng_logger.channel_buff[chan]->n_data * eng_logger.channel_buff[chan]->delta_t;
^^^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),d0
	ext.l	d0
	move.w	d2,d1
	ext.l	d1
	asl.l	#2,d1
	lea	_eng_logger,a0
	move.l	(a0,d1.l),a0
	move.l	24(a0),d1
	jsr	.mulu#
	move.l	d0,d4
;		if (age > 86400L)  {
^	cmp.l	#86400,d4
	ble	.10041
;//			printf ("  e_logger has old data.\n");		
;			request++;
^^	add.w	#1,d3
;		}	
^;			
;		//  request disk access if buffer is full		
;		if (eng_logger.channel_buff[chan]->n_data >= eng_logger_max_n_data)  {
.10041
^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),a0
	cmp.w	_eng_logger_max_n_data,a0
	blt	.10042
;//			printf ("  e_logger buffer is full.\n");			
;			request++;
^^	add.w	#1,d3
;		}	
^;		
;		//  request disk access if we have just enough points to make a full
;		//  length file.
;		ASSERT (eng_logger.channel_buff[chan]->n_data+eng_logger.channel_buff[chan]->n_written <= ENG_LOGGER_MAX_N_POINTS);
.10042
^^^^;		if (eng_logger.channel_buff[chan]->n_data + eng_logger.channel_buff[chan]->n_written >=
^;																		ENG_LOGGER_MAX_N_POINTS)  {
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),d0
	ext.l	d0
	move.w	d2,d1
	ext.l	d1
	asl.l	#2,d1
	lea	_eng_logger,a0
	move.l	(a0,d1.l),a0
	add.l	28(a0),d0
	cmp.l	_ENG_LOGGER_MAX_N_POINTS,d0
	blt	.10043
^;//			printf ("  e_logger has just enough data to fill a file.\n");			
;			request++;
^^	add.w	#1,d3
;		}	
^;	}		
.10043
^.10038
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10040
.10039
;	return request;
^	move.w	d3,d0
	bra	.23
;}	
^.22
;
;
;
;//  eng_logger_write_disk (void)
;//
;//  Writes engineering data to disk.  This routine should be called
;//  any time the disk is spun up so as to empty any waiting data.
;//
;//  Returns: 0 if OK
;//			 non-zero on error
;int eng_logger_write_disk (void)  {
# 506
| .24
	xdef	_eng_logger_write_disk
_eng_logger_write_disk:
	movem.l	d2,-(sp)
;	long age;
;	int chan;
;	dword blocks_total, blocks_free;
;
;	#ifdef DEBUG
;	printf ("eng_logger_write_disk(): starting\n");
;	#endif
;
;	//  don't do anything unless the logger is open
;	if (eng_logger.engineer_open != ENGINEER_INCLUDED)  {
~ chan d2 "i"
^^^^^^^^^^	cmp.w	#32518,_eng_logger+16
	beq	.10044
;		ASSERT (eng_logger.engineer_open == 0);
^;		return 0;
^	move.l	#0,d0
.25
	movem.l	(sp)+,d2
	rts
;	}
^;
;	for (chan = 0;  chan < N_ENG_CHANNELS;  chan++)  {
.10044
^^	move.l	#0,d2
.10047
;		#ifdef DEBUG
;		printf ("eng_logger_write_disk: Chan %d\n", chan);	
;		#endif
;		if (eng_logger.channel_buff[chan] == NULL)
^^^^;			//  channel not active - skip it
;			continue;
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	tst.l	(a0,d0.l)
	beq	.10045
;			
;		if (eng_logger.channel_buff[chan]->n_data <= 0)
^^^^;			//  no data to write - skip it
;			continue;	
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	tst.w	32(a0)
	ble	.10045
;//		printf ("e_logger writing channel %d\n", chan);		
;		
;		//  if no points have yet been written, write the header
;		if (eng_logger.channel_buff[chan]->n_written == 0)  {
^^^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	tst.l	28(a0)
	bne	.10048
;			if (eng_logger_write_header (chan) < 0)
^;				return -1;
	move.w	d2,-(sp)
	jsr	_eng_logger_write_header
	tst.w	d0
	add.w	#2,sp
	bge	.10049
^	move.l	#-1,d0
	bra	.25
;		}		
.10049
^;			
;		//  write the data only
;		if (eng_logger_write_buffer (chan) < 0)
.10048
^^^;			return -1;
	move.w	d2,-(sp)
	jsr	_eng_logger_write_buffer
	tst.w	d0
	add.w	#2,sp
	bge	.10050
^	move.l	#-1,d0
	bra	.25
;	}		
.10050
^.10045
	add.w	#1,d2
	cmp.w	#4,d2
	blt	.10047
.10046
;	return 0;
^	move.l	#0,d0
	bra	.25
;}	
^.24
;
;
;
;
;//  eng_logger_write_header
;//
;//  Creates and write to disk a header based on the information in the control
;//  structure.  Creates the file name and stores it in the control structure
;//
;int eng_logger_write_header (int chan)  {
# 555
| .26
	xdef	_eng_logger_write_header
_eng_logger_write_header:
	link	a6,#.27
	movem.l	d2/d3/d4/d5/d6/a3,-(sp)
	move.w	8(a6),d2
;	char filename[64];
;	int result, offset, fd;
;	long msec;
;	struct tm* tm;
;	struct stat stat;
;	extern const float SOFTWARE_VERSION;
;
;	ASSERT (chan >= 0);
~ filename -64 "[64c"
~ result d6 "i"
~ offset d4 "i"
~ fd d3 "i"
~ msec d5 "l"
~ '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
~ 'stat'
~ 'datestr'
~ 4 2 4
~ date 0 "I"
~ time 2 "I"
~ 3 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 ":" 4
~ st_mtime 20 ":" 4
~ st_ctime 24 ":" 4
~ st_blksize 28 "l"
~ st_blocks 32 "l"
~ fattribute 36 "C"
~ stat -102 ":" 3
~~ chan d2 "i"
^^^^^^^^;	ASSERT (chan < N_ENG_CHANNELS);
^;//	printf ("e_logger write header\n");
;	//  start by zeroing the header
;	memset (&eng_logger_header, 0, sizeof (eng_logger_header));
^^^	pea	512
	clr.w	-(sp)
	pea	_eng_logger_header
	jsr	_memset
;
;	//  now init the variables one by one
;	strcpy (eng_logger_header.magicstring, "DATA");
^^^	lea	_eng_logger_header,a0
	lea	.17,a1
.28	move.b	(a1)+,(a0)+
	bne.s	.28
;	sprintf (eng_logger_header.totalhdrs, "1");
^	pea	.17+5
	pea	_eng_logger_header+8
	jsr	_sprintf
;	sprintf (eng_logger_header.abbrev, "GEOSens");
^	pea	.17+7
	pea	_eng_logger_header+11
	jsr	_sprintf
;	sprintf (eng_logger_header.title, "GEOSense Logger Engineering Data");
^	pea	.17+15
	pea	_eng_logger_header+22
	jsr	_sprintf
;	sprintf (eng_logger_header.sampling_period, "%.7f",
^;				(float)eng_logger.channel_buff[chan]->delta_t);
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.l	24(a0),d0
	jsr	.Fflt#
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.17+48
	pea	_eng_logger_header+128
	jsr	_sprintf
;
;	//  The number of bits is set at 15 because of the way which the MAX186 returns
;	//  data to us.  Only the upper 12 are significant.  The lower 3 should be zero				
;	strcpy (eng_logger_header.samplebits, "16");
^^^^^	lea	_eng_logger_header+143,a0
	lea	.17+53,a1
.29	move.b	(a1)+,(a0)+
	bne.s	.29
;	strcpy (eng_logger_header.wordsize, "2");
^	lea	_eng_logger_header+146,a0
	lea	.17+56,a1
.30	move.b	(a1)+,(a0)+
	bne.s	.30
;
;	//  channel number is stored as the station code
;	sprintf (eng_logger_header.stationcode, "%d", chan);
^^^	move.w	d2,-(sp)
	pea	.17+58
	pea	_eng_logger_header+19
	jsr	_sprintf
	lea	60(sp),sp
;	eng_logger_header.typemark = AMPLITUDE;
^	move.b	#65,_eng_logger_header+148
;	eng_logger_header.swapping = UNSWAPPED;
^	move.b	#85,_eng_logger_header+149
;	eng_logger_header.signing = SIGNED;
^	move.b	#83,_eng_logger_header+150
;	eng_logger_header.caltype = CALIBRATED;
^	move.b	#67,_eng_logger_header+151
;
;	//  min and max are set by the MAX186 input range.
;	//  REVIEW - what is the gain of the input buffers?
;	sprintf (eng_logger_header.calmin, "%.8f", -4.096F);
^^^^	move.l	#$d2f1a9fc,-(sp)
	move.l	#$c010624d,-(sp)
	pea	.17+61
	pea	_eng_logger_header+152
	jsr	_sprintf
;	sprintf (eng_logger_header.calmax, "%.8f", 4.096F);
^	move.l	#$d2f1a9fc,-(sp)
	move.l	#$4010624d,-(sp)
	pea	.17+66
	pea	_eng_logger_header+167
	jsr	_sprintf
;	sprintf (eng_logger_header.calunits, "Volts");
^	pea	.17+71
	pea	_eng_logger_header+182
	jsr	_sprintf
;	sprintf (eng_logger_header.recordsize, "512");
^	pea	.17+77
	pea	_eng_logger_header+222
	jsr	_sprintf
;	sprintf (eng_logger_header.sourcevers, "%.4f", SOFTWARE_VERSION);
^	move.l	_SOFTWARE_VERSION,d0
	jsr	.ftod#
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	pea	.17+81
	pea	_eng_logger_header+228
	jsr	_sprintf
	lea	64(sp),sp
;
;	//  now compute the time.  Don't let the msec exceed 999.
;	msec = 1000L * eng_logger.channel_buff[chan]->first_point_time.ticks / GetTickRate ();
^^^	jsr	_GetTickRate
	move.l	d0,d1
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.l	4(a0),d0
	move.l	d1,-(sp)
	move.l	#1000,d1
	jsr	.mulu#
	move.l	(sp)+,d1
	jsr	.divs#
	move.l	d0,d5
;	ASSERT (msec <= 1000);
^;	if (msec >= 1000)  {
^	cmp.l	#1000,d5
	blt	.10051
;		msec = 0;
^	move.l	#0,d5
;		eng_logger.channel_buff[chan]->first_point_time.ticks = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.l	4(a0)
;		eng_logger.channel_buff[chan]->first_point_time.secs += 1;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#1,(a0)
;	}	
^;
;	//  convert time in seconds to the tm structure time
;	tm = localtime (&(eng_logger.channel_buff[chan]->first_point_time.secs));
.10051
^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),-(sp)
	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	.10052
^	lea	10(a3),a0
	add.w	#2000,(a0)
;	else
	bra	.10053
.10052
;		tm->tm_year += 1900;
^^	lea	10(a3),a0
	add.w	#1900,(a0)
.10053
;
;	//  and write data to the MacTrimpi header
;	sprintf (eng_logger_header.year, "%d", tm->tm_year);
^^^	move.w	10(a3),-(sp)
	pea	.17+86
	pea	_eng_logger_header+110
	jsr	_sprintf
;	sprintf (eng_logger_header.month, "%02d", 1+tm->tm_mon);
^	move.w	8(a3),d0
	add.w	#1,d0
	move.w	d0,-(sp)
	pea	.17+89
	pea	_eng_logger_header+104
	jsr	_sprintf
;	sprintf (eng_logger_header.day, "%02d", tm->tm_mday);
^	move.w	6(a3),-(sp)
	pea	.17+94
	pea	_eng_logger_header+107
	jsr	_sprintf
;	sprintf (eng_logger_header.year, "%04d", tm->tm_year);
^	move.w	10(a3),-(sp)
	pea	.17+99
	pea	_eng_logger_header+110
	jsr	_sprintf
;	sprintf (eng_logger_header.hours, "%02d", tm->tm_hour);
^	move.w	4(a3),-(sp)
	pea	.17+104
	pea	_eng_logger_header+115
	jsr	_sprintf
;	sprintf (eng_logger_header.minutes, "%02d", tm->tm_min);
^	move.w	2(a3),-(sp)
	pea	.17+109
	pea	_eng_logger_header+118
	jsr	_sprintf
	lea	60(sp),sp
;	sprintf (eng_logger_header.seconds, "%02d", tm->tm_sec);
^	move.w	(a3),-(sp)
	pea	.17+114
	pea	_eng_logger_header+121
	jsr	_sprintf
;	sprintf (eng_logger_header.msec, "%03ld", msec);
^	move.l	d5,-(sp)
	pea	.17+119
	pea	_eng_logger_header+124
	jsr	_sprintf
;	
;	//  The header information has been filled in.  Now write it to disk.
;	//  Start by creating the file name.  This includes some code to look
;	//  for a new filename if this one already exists, even though this
;	//  should never happen.
;	for (offset = 0;  offset < 10;  offset++)  {
^^^^^^	move.l	#0,d4
	lea	22(sp),sp
.10056
;		//  save the file name for later use; don't save the parts that are easy
;		//  to recreate
;		sprintf (&eng_logger.channel_buff[chan]->fname[0], "\\E%d_%04d\\%02d%02d%02d%02d.ENG", 
^^^;					chan, tm->tm_year,
;					1+tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min+offset);
	move.w	2(a3),d0
	add.w	d4,d0
	move.w	d0,-(sp)
	move.w	4(a3),-(sp)
	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	d2,-(sp)
	pea	.17+125
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),d0
	add.l	#34,d0
	move.l	d0,-(sp)
	jsr	_sprintf
;		strcpy (filename, &eng_logger.channel_buff[chan]->fname[0]);
^^^	lea	-64(a6),a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	add.l	#34,a1
.31	move.b	(a1)+,(a0)+
	bne.s	.31
;		#ifdef DEBUG
;		printf ("eng_logger_write_header: opening %s\n", filename);
;		#endif
;		fd = logger_disk_open (filename, (PO_BINARY|PO_CREAT|PO_WRONLY), PS_IWRITE);
^^^^	move.w	#256,-(sp)
	move.w	#33025,-(sp)
	pea	-64(a6)
	jsr	_logger_disk_open
	move.w	d0,d3
;		if (fd < 0)  {
^	tst.w	d3
	lea	28(sp),sp
	bge	.10057
;			//  If we failed to open, then we assume that other 'offsets' will also
;			//  fail.  Don't bother with additional attempts.
;			log_printf ("eng_logger_write_header: file ('%s') open failure.\n", filename);
^^^	pea	-64(a6)
	pea	.17+156
	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	.17+208
	jsr	_log_printf
;			return -1;
^	move.l	#-1,d0
	lea	18(sp),sp
.32
	movem.l	(sp)+,d2/d3/d4/d5/d6/a3
	unlk	a6
	rts
;		}
^;		critical_error_reset ();
.10057
^	jsr	_critical_error_reset
;		if (pc_fstat (fd, &stat) != 0)  {
^	pea	-102(a6)
	move.w	d3,-(sp)
	jsr	_pc_fstat
	tst.w	d0
	add.w	#6,sp
	beq	.10058
;			//  If we stat failed, then we assume that other 'offsets' will also
;			//  fail.  Don't bother with additional attempts.
;			log_printf ("eng_logger_write_header: file ('%s') fstat failure.\n", filename);
^^^	pea	-64(a6)
	pea	.17+227
	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	.17+280
	jsr	_log_printf
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			po_close (fd);
^	move.w	d3,-(sp)
	jsr	_po_close
;			return -1;
^	move.l	#-1,d0
	lea	20(sp),sp
	bra	.32
;		}
^;		//  If size is 0, then all is well - go to write portion of code
;		if (stat.st_size == 0)
.10058
^^;			break;
	tst.l	-90(a6)
	beq	.10055
;			
;		//  If not zero, try next offset after closing this file			
;		critical_error_reset ();
^^^^	jsr	_critical_error_reset
;		po_close (fd);
^	move.w	d3,-(sp)
	jsr	_po_close
;		log_printf ("eng_logger_write_header: Filename %s already exists\n", filename);
^	pea	-64(a6)
	pea	.17+299
	jsr	_log_printf
;	}
^	lea	10(sp),sp
.10054
	add.w	#1,d4
	cmp.w	#10,d4
	blt	.10056
.10055
;	if (offset >= 10)  {
^	cmp.w	#10,d4
	blt	.10059
;		//  all opened files have already been closed
;		log_printf ("eng_logger_write_header: Aborting after repeated open attempts.\n");
^^	pea	.17+352
	jsr	_log_printf
;		return -1;
^	move.l	#-1,d0
	add.w	#4,sp
	bra	.32
;	}
^;	
;	ASSERT (sizeof (eng_logger_header) == 512);
.10059
^^;	critical_error_reset ();
^	jsr	_critical_error_reset
;	result = po_write (fd, (byte*)&eng_logger_header, sizeof (eng_logger_header));
^	move.w	#512,-(sp)
	pea	_eng_logger_header
	move.w	d3,-(sp)
	jsr	_po_write
	move.w	d0,d6
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	po_flush (fd);
^	move.w	d3,-(sp)
	jsr	_po_flush
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	po_close (fd);
^	move.w	d3,-(sp)
	jsr	_po_close
;
;	if (result != sizeof (eng_logger_header))  {
^^	cmp.w	#512,d6
	lea	12(sp),sp
	beq	.10060
;		//  error writing
;		log_printf ("eng_logger_write_header: file ('%s') write failure.\n", filename);
^^	pea	-64(a6)
	pea	.17+417
	jsr	_log_printf
;		log_printf ("  Tried to write %d, got %d\n", sizeof (eng_logger_header), result);
^	move.w	d6,-(sp)
	pea	512
	pea	.17+470
	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	.17+499
	jsr	_log_printf
;		return -1;
^	move.l	#-1,d0
	lea	28(sp),sp
	bra	.32
;	}
^;	return 0;
.10060
^	move.l	#0,d0
	bra	.32
;}
^.26
.27	equ	-102
.17
	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,76,111,103,103,101,114
	dc.b	32,69,110,103,105,110,101,101,114,105,110,103,32,68,97
	dc.b	116,97,0,37,46,55,102,0,49,54,0,50,0,37,100
	dc.b	0,37,46,56,102,0,37,46,56,102,0,86,111,108,116
	dc.b	115,0,53,49,50,0,37,46,52,102,0,37,100,0,37
	dc.b	48,50,100,0,37,48,50,100,0,37,48,52,100,0,37
	dc.b	48,50,100,0,37,48,50,100,0,37,48,50,100,0,37
	dc.b	48,51,108,100,0,92,69,37,100,95,37,48,52,100,92
	dc.b	37,48,50,100,37,48,50,100,37,48,50,100,37,48,50
	dc.b	100,46,69,78,71,0,101,110,103,95,108,111,103,103,101
	dc.b	114,95,119,114,105,116,101,95,104,101,97,100,101,114,58
	dc.b	32,102,105,108,101,32,40,39,37,115,39,41,32,111,112
	dc.b	101,110,32,102,97,105,108,117,114,101,46,10,0,32,32
	dc.b	69,114,114,111,114,32,37,100,32,61,62,32,37,115,46
	dc.b	10,0,101,110,103,95,108,111,103,103,101,114,95,119,114
	dc.b	105,116,101,95,104,101,97,100,101,114,58,32,102,105,108
	dc.b	101,32,40,39,37,115,39,41,32,102,115,116,97,116,32
	dc.b	102,97,105,108,117,114,101,46,10,0,32,32,69,114,114
	dc.b	111,114,32,37,100,32,61,62,32,37,115,46,10,0,101
	dc.b	110,103,95,108,111,103,103,101,114,95,119,114,105,116,101
	dc.b	95,104,101,97,100,101,114,58,32,70,105,108,101,110,97
	dc.b	109,101,32,37,115,32,97,108,114,101,97,100,121,32,101
	dc.b	120,105,115,116,115,10,0,101,110,103,95,108,111,103,103
	dc.b	101,114,95,119,114,105,116,101,95,104,101,97,100,101,114
	dc.b	58,32,65,98,111,114,116,105,110,103,32,97,102,116,101
	dc.b	114,32,114,101,112,101,97,116,101,100,32,111,112,101,110
	dc.b	32,97,116,116,101,109,112,116,115,46,10,0,101,110,103
	dc.b	95,108,111,103,103,101,114,95,119,114,105,116,101,95,104
	dc.b	101,97,100,101,114,58,32,102,105,108,101,32,40,39,37
	dc.b	115,39,41,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,100,44,32,103,111,116,32
	dc.b	37,100,10,0,32,32,69,114,114,111,114,32,37,100,32
	dc.b	61,62,32,37,115,46,10,0
	ds	0
;
;
;
;//  eng_logger_write_buffer (int chan)
;//
;//	Writes the specified channel buffer to disk.  The disk should already
;//  be powered up.
;//
;int eng_logger_write_buffer (int chan)  {
# 695
| .34
	xdef	_eng_logger_write_buffer
_eng_logger_write_buffer:
	link	a6,#.35
	movem.l	d2/d3/d4/d5,-(sp)
	move.w	8(a6),d2
;	int fd, year, result, n_bytes;
;	char filename[64];
;	
;//	printf ("e_logger write buffer\n");	
;	strcpy (filename, eng_logger.channel_buff[chan]->fname);
~ fd d3 "i"
~ result d5 "i"
~ n_bytes d4 "i"
~ filename -64 "[64c"
~~ chan d2 "i"
^^^^^	lea	-64(a6),a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	add.l	#34,a1
.36	move.b	(a1)+,(a0)+
	bne.s	.36
;
;	//  we shouldn't be creating the file at this stage.  It MUST already
;	//  exist because we MUST have written the header already.  We still
;	//  use the normal disk_open routine because it allows us to add
;	//  the disk partition letter.
;	//  REVIEW - this can fail is a previous write failure causes us to
;	//  switch partitions in the middle of a file.
;	fd = logger_disk_open (filename,  (PO_BINARY|PO_WRONLY), PS_IWRITE);
^^^^^^^^	move.w	#256,-(sp)
	move.w	#32769,-(sp)
	pea	-64(a6)
	jsr	_logger_disk_open
	move.w	d0,d3
;	if (fd < 0)  {
^	tst.w	d3
	add.w	#8,sp
	bge	.10061
;		log_printf ("eng_logger_write_buffer: file ('%s') open failure.\n", filename);
^	pea	-64(a6)
	pea	.33+0
	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	.33+52
	jsr	_log_printf
;		return fd;
^	move.w	d3,d0
	lea	18(sp),sp
.37
	movem.l	(sp)+,d2/d3/d4/d5
	unlk	a6
	rts
;	}
^;
;	//  seek to the end of the file so we don't overwrite any previous data
;	critical_error_reset ();
.10061
^^^	jsr	_critical_error_reset
;	if (po_lseek (fd, 0L, PSEEK_END) < 0)  {
^	move.w	#2,-(sp)
	clr.l	-(sp)
	move.w	d3,-(sp)
	jsr	_po_lseek
	tst.l	d0
	add.w	#8,sp
	bge	.10062
;		log_printf ("eng_logger_write_buffer: file ('%s') lseek failure.\n", filename);
^	pea	-64(a6)
	pea	.33+71
	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	.33+124
	jsr	_log_printf
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		po_close (fd);
^	move.w	d3,-(sp)
	jsr	_po_close
;		return -1;
^	move.l	#-1,d0
	lea	20(sp),sp
	bra	.37
;	}
^;	
;	n_bytes = sizeof(short) * eng_logger.channel_buff[chan]->n_data;
.10062
^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.w	32(a0),d0
	ext.l	d0
	add.l	d0,d0
	move.w	d0,d4
;//	printf ("e_logger write buffer: Writing %d byte block of data\n", n_bytes);
;	critical_error_reset ();
^^	jsr	_critical_error_reset
;	result = po_write (fd, (byte*)&eng_logger.channel_buff[chan]->data[0], n_bytes);
^	move.w	d4,-(sp)
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),d0
	add.l	#98,d0
	move.l	d0,-(sp)
	move.w	d3,-(sp)
	jsr	_po_write
	move.w	d0,d5
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	po_flush (fd);
^	move.w	d3,-(sp)
	jsr	_po_flush
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	po_close (fd);
^	move.w	d3,-(sp)
	jsr	_po_close
;
;	if (result != n_bytes)  {
^^	cmp.w	d4,d5
	lea	12(sp),sp
	beq	.10063
;		log_printf ("eng_logger_write_buffer: file ('%s') write failure.\n", filename);
^	pea	-64(a6)
	pea	.33+143
	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	.33+196
	jsr	_log_printf
;		log_printf ("  Tried to write %d, got %d\n", n_bytes, result);
^	move.w	d5,-(sp)
	move.w	d4,-(sp)
	pea	.33+215
	jsr	_log_printf
;		return -1;
^	move.l	#-1,d0
	lea	26(sp),sp
	bra	.37
;	}
^;
;	eng_logger.channel_buff[chan]->last_disk_write = logger_time_get_time ();
.10063
^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#16,a0
	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)+
;	eng_logger.channel_buff[chan]->n_written += eng_logger.channel_buff[chan]->n_data;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	add.l	#28,a0
	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a1
	move.l	(a1,d0.l),a1
	move.w	32(a1),d0
	ext.l	d0
	add.l	d0,(a0)
;	eng_logger.channel_buff[chan]->n_data = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.w	32(a0)
;	//  if this file has reached the maximum length, then force the start of a new file.
;	#ifdef DEBUG
;	printf ("Wrote %ld points total to '%s'\n", eng_logger.channel_buff[chan]->n_written, filename);
;	#endif
;	if (eng_logger.channel_buff[chan]->n_written >= ENG_LOGGER_MAX_N_POINTS)  {
^^^^^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	move.l	28(a0),a0
	cmp.l	_ENG_LOGGER_MAX_N_POINTS,a0
	blt	.10064
;		eng_logger.channel_buff[chan]->n_written = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#2,d0
	lea	_eng_logger,a0
	move.l	(a0,d0.l),a0
	clr.l	28(a0)
;	}		
^;	return 0;
.10064
^	move.l	#0,d0
	bra	.37
;}
^.34
.35	equ	-64
.33
	dc.b	101,110,103,95,108,111,103,103,101,114,95,119,114,105,116
	dc.b	101,95,98,117,102,102,101,114,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,101,110,103,95
	dc.b	108,111,103,103,101,114,95,119,114,105,116,101,95,98,117
	dc.b	102,102,101,114,58,32,102,105,108,101,32,40,39,37,115
	dc.b	39,41,32,108,115,101,101,107,32,102,97,105,108,117,114
	dc.b	101,46,10,0,32,32,69,114,114,111,114,32,37,100,32
	dc.b	61,62,32,37,115,46,10,0,101,110,103,95,108,111,103
	dc.b	103,101,114,95,119,114,105,116,101,95,98,117,102,102,101
	dc.b	114,58,32,102,105,108,101,32,40,39,37,115,39,41,32
	dc.b	119,114,105,116,101,32,102,97,105,108,117,114,101,46,10
	dc.b	0,32,32,69,114,114,111,114,32,37,100,32,61,62,32
	dc.b	37,115,46,10,0,32,32,84,114,105,101,100,32,116,111
	dc.b	32,119,114,105,116,101,32,37,100,44,32,103,111,116,32
	dc.b	37,100,10,0
	ds	0
;
;
;
;
;
;//  eng_logger_print_file
;//
;//	The engineering logger files are currently written in the MacTrimpi format
;//
;int eng_logger_print_file (int fd)  {
# 762
| .39
	xdef	_eng_logger_print_file
_eng_logger_print_file:
;
;	return MacTrimpi_print_file (fd);
~~ fd 8 "i"
^^	move.w	4(sp),-(sp)
	jsr	_MacTrimpi_print_file
	add.w	#2,sp
.40
	rts
;}
^.39
;
;
;
;
# 768
|
~ _SOFTWARE_VERSION * "f"
~ _eng_logger_write_header * "(i"
~ _eng_logger_write_buffer * "(i"
~ _eng_logger_collect_chan * "(v"
~ 'engineer_logger'
~ 'eng_data_record'
~ 6 8 512
~ first_point_time 0 ":" 1
~ collect_time 8 ":" 1
~ last_disk_write 16 ":" 1
~ delta_t 24 "l"
~ n_written 28 "l"
~ n_data 32 "i"
~ fname 34 "[64c"
~ data 98 "[207i"
~ 5 2 18
~ channel_buff 0 "[4#:" 6
~ engineer_open 16 "i"
~ _eng_logger * ":" 5
~ 'MacTrimpi'
~ 7 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"
~ _eng_logger_header * ":" 7
~ _eng_logger_max_n_data * "i"
~ _MIN_ENG_READ_FREQ * "l"
~ _ENG_LOGGER_MAX_N_POINTS * "l"
~ _critical_error_reset * "(v"
~ _MAX186_read_channel * "(i"
~ _MAX186_power_down * "(v"
~ _MAX186_power_up * "(v"
~ _MAX186_shutdown * "(v"
~ _MacTrimpi_print_file * "(i"
~ _get_errno_string * "(#c"
~ _log_printf * "(i"
~ 'text_log'
~ 8 5 1068
~ filename 0 "[32c"
~ data 32 "[1024c"
~ n_data 1056 "i"
~ n_filled 1058 "i"
~ oldest_data 1060 ":" 1
~ _logger_disk_open * "(i"
~ _get_errno * "(i"
~ 'system_user'
~ 9 4 46
~ task_handle 0 "i"
~ rtfs_errno 2 "i"
~ dfltdrv 4 "i"
~ lcwd 6 "[10#v"
~ PSYSTEM_USER "#:" 9
~ SYSTEM_USER ":" 9
~ 'finode'
~ 'ddrive'
~ 'fatswap'
~ 12 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"
~ 11 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 ":" 12
~ 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'
~ 13 4 14
~ nsegs 0 "i"
~ segindex 2 "i"
~ ncksum 4 "C"
~ segblock 6 "[2L"
~ 10 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 "#:" 11
~ my_block 44 "L"
~ my_index 48 "i"
~ pnext 50 "#:" 10
~ pprev 54 "#:" 10
~ s 58 ":" 13
~ 'drobj'
~ 'dirblk'
~ 15 3 10
~ my_frstblock 0 "L"
~ my_block 4 "L"
~ my_index 8 "i"
~ 'blkbuff'
~ 16 7 532
~ pnext 0 "#:" 16
~ lru 4 "L"
~ pdrive 8 "#:" 11
~ blockno 12 "L"
~ use_count 16 "i"
~ pad_to_4_align 18 "i"
~ data 20 "[512C"
~ 14 5 24
~ pdrive 0 "#:" 11
~ finode 4 "#:" 10
~ blkinfo 8 ":" 15
~ isroot 18 "i"
~ pblkbuff 20 "#:" 16
~ 'pc_file'
~ 17 8 24
~ pobj 0 "#:" 14
~ 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'
~ 18 1 512
~ core 0 "[512C"
~ 'ptable'
~ 'ptable_entry'
~ 20 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"
~ 19 2 66
~ ents 0 "[4:" 20
~ signature 64 "I"
~ PTABLE ":" 19
~ PTABLE_ENTRY ":" 20
~ 'format_dec_tree'
~ 21 3 8
~ sec_p_alloc 0 "I"
~ ents_p_root 2 "I"
~ n_blocks 4 "L"
~ FORMAT_DEC_TREE ":" 21
~ PC_FILE ":" 17
~ DROBJ ":" 14
~ BLKBUFF ":" 16
~ DIRBLK ":" 15
~ FINODE ":" 10
~ SEGDESC ":" 13
~ 'lfninode'
~ 22 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 ":" 22
~ 'dosinode'
~ 23 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 ":" 23
~ DDRIVE ":" 11
~ FATSWAP ":" 12
~ BLOCK_ALLOC ":" 18
~ CLUSTERTYPE "L"
~ 'ide_control'
~ 'ide_drive_desc'
~ ''
~ 'atapi_packet_desc'
~ 'transfer_length'
~ 28 2 2
~ msb 0 "C"
~ lsb 1 "C"
~ 27 8 14
~ op_code 0 "C"
~ lun 1 "C"
~ lba 2 "L"
~ reserved1 6 "C"
~ transfer_length 8 ":" 28
~ reserved2 10 "C"
~ reserved3 11 "C"
~ reserved4 12 "C"
~ 'atapi_mode_sense_packet_desc'
~ 29 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 ":" 28
~ reserved5 10 "C"
~ reserved6 11 "C"
~ reserved7 12 "C"
~ 'atapi_format_unit_packet_desc'
~ 30 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'
~ 31 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'
~ 32 6 12
~ op_code 0 "C"
~ lun 1 "C"
~ reserved1 2 "C"
~ reserved2 3 "C"
~ eject 4 "C"
~ reserved 5 "[7C"
~ 26 5 14
~ generic 0 ":" 27
~ mode_sense 0 ":" 29
~ format 0 ":" 30
~ old_format 0 ":" 31
~ start_stop 0 ":" 32
~ 25 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 ":" 26
~ atapi_packet_size 42 "I"
~ media_descriptor 44 "C"
~ medium_type_code 45 "C"
~ allocation_unit 46 "C"
~ 24 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:" 25
~ 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 "#:" 24
~ IDE_CONTROLLER ":" 24
~ IDE_DRIVE_DESC ":" 25
~ ATAPI_PACKET ":" 26
~ ATAPI_PACKET_DESC ":" 27
~ ATAPI_OLD_FORMAT_UNIT_PACKET_DE ":" 31
~ ATAPI_START_STOP_UNIT_PACKET_DE ":" 32
~ ATAPI_FORMAT_UNIT_PACKET_DESC ":" 30
~ ATAPI_MODE_SENSE_PACKET_DESC ":" 29
~ 'Himawari_format_descriptor'
~ 'Himawari_defect_list_header'
~ 34 4 4
~ reserved 0 "C"
~ control_byte 1 "C"
~ length_msb 2 "C"
~ length_lsb 3 "C"
~ 'Himawari_formattable_capacity_d'
~ 35 3 8
~ number_of_blocks 0 "[4C"
~ reserved 4 "C"
~ block_length 5 "[3C"
~ 33 2 12
~ dlheader 0 ":" 34
~ capacity_descriptor 4 ":" 35
~ HIMAWARI_FORMAT_DESCRIPTOR ":" 33
~ HIMAWARI_FORMATTABLE_CAPACITY_D ":" 35
~ HIMAWARI_DEFECT_LIST_HEADER ":" 34
~ 'himawari_flexible_disk_page'
~ 36 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 ":" 36
~ TRANSFER_LENGTH ":" 28
~ BLOCKT "L"
~ _pc_fstat * "(i"
~ _po_close * "(i"
~ _po_flush * "(i"
~ _po_lseek * "(l"
~ _po_write * "(i"
~ 'fmtparms'
~ 37 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 ":" 37
~ 'freelistinfo'
~ 38 2 8
~ cluster 0 "L"
~ nclusters 4 "l"
~ FREELISTINFO ":" 38
~ 'fileseginfo'
~ 39 2 8
~ block 0 "l"
~ nblocks 4 "l"
~ FILESEGINFO ":" 39
~ STAT ":" 3
~ '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 ":" 4
~ 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_time * "(:" 1
~ EARLIEST_LOGGER_TIME _EARLIEST_LOGGER_TIME ":" 1
~ LATEST_LOGGER_TIME _LATEST_LOGGER_TIME ":" 1
~ _eng_logger_disk_switch * "(v"
~ _eng_logger_print_file * "(i"
~ _eng_logger_read_channel * "(i"
~ _eng_logger_disk_request * "(i"
~ _eng_logger_write_disk * "(i"
~ _eng_logger_collect * "(i"
~ _eng_logger_channel_setup * "(i"
~ _eng_logger_close * "(v"
~ _eng_logger_open * "(v"
~ _eng_logger_power_on_init * "(v"
~ _sci_logger_resume_data * "(v"
~ _sci_logger_pause_data * "(v"
~ _memset * "(#v"
~ ''
~ 41 2 8
~ quot 0 "l"
~ rem 4 "l"
~ ''
~ 42 2 4
~ quot 0 "i"
~ rem 2 "i"
~ _malloc * "(#v"
~ _free * "(v"
~ 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"
~ 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"
~ _SimGetFSys * "(l"
~ _SimSetFSys * "(l"
~ time_tt ":" 1
~ _SerSetBaud * "(l"
~ _SerGetBaud * "(l"
~ 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	_critical_error_reset
	xref	_MAX186_read_channel
	xref	_MAX186_power_down
	xref	_MAX186_power_up
	xref	_MAX186_shutdown
	xref	_MacTrimpi_print_file
	xref	_get_errno_string
	xref	_log_printf
	xref	_logger_disk_open
	xref	_get_errno
	xref	_pc_fstat
	xref	_po_close
	xref	_po_flush
	xref	_po_lseek
	xref	_po_write
	xref	_logger_time_get_time
	xref	_sci_logger_resume_data
	xref	_sci_logger_pause_data
	xref	_memset
	xref	_malloc
	xref	_free
	xref	_sprintf
	xref	_printf
	xref	_GetTickRate
	xref	_ttmcmp
	xref	_SimGetFSys
	xref	_SimSetFSys
	xref	_SerSetBaud
	xref	_SerGetBaud
	xref	_localtime
	xref	.begin
	dseg
	xref	_SOFTWARE_VERSION
	global	_eng_logger,18
	global	_eng_logger_header,512
	xref	_MIN_ENG_READ_FREQ
	end
