;: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        <tpu332.h>              /* 68332 Time Processing Unit Definitions */
;#include        <dio332.h>              /* 68332 Digital I/O Port Pin Definitions */
;#include        <tt8pic.h>              /* Model 8 PIC Parallel Slave Port Definitions */
;#include        <tt8lib.h>              /* definitions and prototypes for Model 8 library */
;
;//  general C includes
;#include        <stdio.h>
;#include        <stdlib.h>
;#include		<string.h>
;#include        <ctype.h>
;
;//  disk related includes
;#include		<pcdisk.h>
;
;//  data logger related includes
;#include		"ASSERT.h"
;#include		"logdisk.h"
;#include		"criterr.h"
;#include		"text_log.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		"logtime.h"
;#include		"misc.h"
;#include		"science.h"
;
;//  This is the number of times that we cycle power and retry a disk on failure.
;//  The low level disk software also implements retries at that level (without
;//  a power cycle) in addition to this retry
;#define MAX_RETRIES 1
;
;
;//  local subroutines not for general use	
;int logger_disk_test_drive (char drive_char);
;void logger_show_drive_status (char* path);
;
;
;//  This array contains the list available drives, one at a time
;//  The drives will be used in the order listed
;struct disk_info  {
;	short partition_char;	//  letter of drive
;	short usable;				//  non-zero if full
;	short errno;			//  errno which caused us to switch from
;							//  this partition
;	unsigned long partition_size;	//  total number of blocks (512 bytes) on drive
;	unsigned long free_size;		//  number of unused blocks on drive
;	unsigned int cluster_size;		//  number of bytes in a sector
;};
;
;//  The following array is modified at startup to reflect which disks are actually
;//  present and their parameters.  The code starts with four slots because the LP1
;//  can have up to two controllers, each with up to two drives on it.  Slots with
;//  a null drive character are unused
;struct disk_info partitions[] = {
	dseg
	ds	0
	xdef	_partitions
_partitions:
;	{'\0', 1, 0, 0L, 0L, 0L},
	ds.b	0
	dc.w	0
	dc.w	1
	dc.w	0
	dc.l	$0000
	dc.l	$0000
	dc.w	0
;	{'\0', 1, 0, 0L, 0L, 0L},
	ds.b	0
	dc.w	0
	dc.w	1
	dc.w	0
	dc.l	$0000
	dc.l	$0000
	dc.w	0
;#if (IDE_DRIVESPERCONTROLLER == 2)				
;	//  if only 1 drive per controller, then only 2 drives possible
;	{'\0', 1, 0, 0L, 0L, 0L},
	ds.b	0
	dc.w	0
	dc.w	1
	dc.w	0
	dc.l	$0000
	dc.l	$0000
	dc.w	0
;	{'\0', 1, 0, 0L, 0L, 0L}
	ds.b	0
	dc.w	0
	dc.w	1
	dc.w	0
	dc.l	$0000
	dc.l	$0000
	dc.w	0
;#endif	
;};
	cseg
;const int n_partition_slots = sizeof (partitions) / sizeof (struct disk_info);
	ds	0
	xdef	_n_partition_slots
_n_partition_slots:
	dc.w	4
	cseg
;int current_partition;
;int n_partitions;
;
;
;//  logger_disk_power_on_init
;//  User callable
;//
;//  This routine should be called once when the logger is powered on to
;//  init various parts of the array which these routine use
;//
;void logger_disk_power_on_init (void)  {
# 76 'logdisk.c' 679114994
| .2
	xdef	_logger_disk_power_on_init
_logger_disk_power_on_init:
	movem.l	d2,-(sp)
;	int n;
;	extern char wd[];
;	
;	printf ("Disk initialization.\n");
~ n d2 "i"
^^^^	pea	.1+0
	jsr	_printf
;	printf ("Testing for %d possible disks.\n", n_partition_slots);
^	move.w	_n_partition_slots,-(sp)
	pea	.1+22
	jsr	_printf
;	critical_error_logging (0);			//  don't print out failure info
^	clr.w	-(sp)
	jsr	_critical_error_logging
;	critical_error_set_n_tries (1);     //  don't retry at all
^	move.w	#1,-(sp)
	jsr	_critical_error_set_n_tries
;	n_partitions = 0;
^	clr.w	_n_partitions
;
;#if (IDE_DRIVESPERCONTROLLER == 2)
;	//  Test drives A and B;  if there are two drives per controller, then they share
;	//  a power supply
;	printf ("Testing drive A (Master disk on controller 1)\n");
^^^^^	pea	.1+54
	jsr	_printf
;	disk_power_on ("A:");
^	pea	.1+101
	jsr	_disk_power_on
;	if (logger_disk_test_drive ('A'))  {
^	move.b	#65,-(sp)
	jsr	_logger_disk_test_drive
	tst.w	d0
	lea	24(sp),sp
	beq	.10001
;		printf ("Testing drive B (Slave disk on controller 1)\n");
^	pea	.1+104
	jsr	_printf
;		logger_disk_test_drive ('B');
^	move.b	#66,-(sp)
	jsr	_logger_disk_test_drive
;	}  else
^	add.w	#6,sp
	bra	.10002
.10001
;		printf ("Slave disk B cannot be accessed because master A is not present.\n");
^	pea	.1+150
	jsr	_printf
	add.w	#4,sp
.10002
;	disk_power_off ("A:");
^	pea	.1+216
	jsr	_disk_power_off
;		
;	//  And the same for C and D
;
;	printf ("Testing drive C (Master disk on controller 2)\n");
^^^^	pea	.1+219
	jsr	_printf
;	disk_power_on ("C:");
^	pea	.1+266
	jsr	_disk_power_on
;	if (logger_disk_test_drive ('C'))  {
^	move.b	#67,-(sp)
	jsr	_logger_disk_test_drive
	tst.w	d0
	lea	14(sp),sp
	beq	.10003
;		printf ("Testing drive D (Slave disk on controller 2)\n");
^	pea	.1+269
	jsr	_printf
;		logger_disk_test_drive ('D');
^	move.b	#68,-(sp)
	jsr	_logger_disk_test_drive
;	}  else
^	add.w	#6,sp
	bra	.10004
.10003
;		printf ("Slave disk D cannot be accessed because master C is not present.\n");
^	pea	.1+315
	jsr	_printf
	add.w	#4,sp
.10004
;	disk_power_off ("C:");
^	pea	.1+381
	jsr	_disk_power_off
;#else
;	printf ("Testing drive A (Master disk on controller 1)\n");
;	disk_power_on ("A:");
;	logger_disk_test_drive ('A')	
;	disk_power_off ("A:");
;		
;	printf ("Testing drive B (Master disk on controller 2)\n");
;	disk_power_on ("B:");
;	logger_disk_test_drive ('B')	
;	disk_power_off ("B:");
;#endif
;
;	//  mark all unused slots as unusable
;	for (n = n_partitions;  n < n_partition_slots;  n++)  {
^^^^^^^^^^^^^^	move.w	_n_partitions,d2
	add.w	#4,sp
	bra	.10008
.10007
;		partitions[n].partition_char = '\0';
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	clr.w	(a0,d0.l)
;		partitions[n].partition_size = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+6,a0
	clr.l	(a0,d0.l)
;		partitions[n].free_size = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+10,a0
	clr.l	(a0,d0.l)
;		partitions[n].cluster_size = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+14,a0
	clr.w	(a0,d0.l)
;		partitions[n].errno = 0;
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+4,a0
	clr.w	(a0,d0.l)
;	}	
^.10005
	add.w	#1,d2
.10008
	cmp.w	_n_partition_slots,d2
	blt	.10007
.10006
;
;	//  restore normal error handling
;	critical_error_logging (1);			//  print and log all failures
^^^	move.w	#1,-(sp)
	jsr	_critical_error_logging
;	critical_error_set_n_tries (3);     //  retry twice on failure
^	move.w	#3,-(sp)
	jsr	_critical_error_set_n_tries
;
;	//  start writing data to the first partition
;	current_partition = 0;
^^^	clr.w	_current_partition
;	if (current_partition < n_partitions)
^;		wd[0] = partitions[current_partition].partition_char;
	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	add.w	#4,sp
	bge	.10009
^	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.b	1(a0,d0.l),_wd
;	else
	bra	.10010
.10009
;		wd[0] = 'A';
^^	move.b	#65,_wd
.10010
;	wd[1] = ':';
^	move.b	#58,_wd+1
;	wd[2] = '\\';
^	move.b	#92,_wd+2
;	wd[3] = 0;	
^	clr.b	_wd+3
;	return;
^.3
	movem.l	(sp)+,d2
	rts
;}
^.2
.1
	dc.b	68,105,115,107,32,105,110,105,116,105,97,108,105,122,97
	dc.b	116,105,111,110,46,10,0,84,101,115,116,105,110,103,32
	dc.b	102,111,114,32,37,100,32,112,111,115,115,105,98,108,101
	dc.b	32,100,105,115,107,115,46,10,0,84,101,115,116,105,110
	dc.b	103,32,100,114,105,118,101,32,65,32,40,77,97,115,116
	dc.b	101,114,32,100,105,115,107,32,111,110,32,99,111,110,116
	dc.b	114,111,108,108,101,114,32,49,41,10,0,65,58,0,84
	dc.b	101,115,116,105,110,103,32,100,114,105,118,101,32,66,32
	dc.b	40,83,108,97,118,101,32,100,105,115,107,32,111,110,32
	dc.b	99,111,110,116,114,111,108,108,101,114,32,49,41,10,0
	dc.b	83,108,97,118,101,32,100,105,115,107,32,66,32,99,97
	dc.b	110,110,111,116,32,98,101,32,97,99,99,101,115,115,101
	dc.b	100,32,98,101,99,97,117,115,101,32,109,97,115,116,101
	dc.b	114,32,65,32,105,115,32,110,111,116,32,112,114,101,115
	dc.b	101,110,116,46,10,0,65,58,0,84,101,115,116,105,110
	dc.b	103,32,100,114,105,118,101,32,67,32,40,77,97,115,116
	dc.b	101,114,32,100,105,115,107,32,111,110,32,99,111,110,116
	dc.b	114,111,108,108,101,114,32,50,41,10,0,67,58,0,84
	dc.b	101,115,116,105,110,103,32,100,114,105,118,101,32,68,32
	dc.b	40,83,108,97,118,101,32,100,105,115,107,32,111,110,32
	dc.b	99,111,110,116,114,111,108,108,101,114,32,50,41,10,0
	dc.b	83,108,97,118,101,32,100,105,115,107,32,68,32,99,97
	dc.b	110,110,111,116,32,98,101,32,97,99,99,101,115,115,101
	dc.b	100,32,98,101,99,97,117,115,101,32,109,97,115,116,101
	dc.b	114,32,67,32,105,115,32,110,111,116,32,112,114,101,115
	dc.b	101,110,116,46,10,0,67,58,0
	ds	0
;
;
;
;
;
;int logger_disk_test_drive (char drive_char)  {
# 149
| .5
	xdef	_logger_disk_test_drive
_logger_disk_test_drive:
	link	a6,#.6
	movem.l	d2/d3/d4,-(sp)
	move.b	8(a6),d4
;	dword total_blocks, free_blocks;
;	char path[8];
;	ASSERT (n_partitions < n_partition_slots);
~ total_blocks -4 "L"
~ free_blocks -8 "L"
~ path -16 "[8c"
~~ drive_char d4 "c"
^^^;
;	path[0] = drive_char;
^^	move.b	d4,-16(a6)
;	path[1] = ':';
^	move.b	#58,-15(a6)
;	path[2] = 0;
^	clr.b	-14(a6)
;	
;	//  Test whether there is actually a drive available for this partition
;	//  If the drive is not present, then pc-free will fail, and total_blocks
;	//  and free_blocks will remain at -1
;	total_blocks = free_blocks = -1;
^^^^^	move.l	#-1,-8(a6)
	move.l	#-1,-4(a6)
;	critical_error_reset ();
^	jsr	_critical_error_reset
;	pc_free (path, &total_blocks, &free_blocks);
^	pea	-8(a6)
	pea	-4(a6)
	pea	-16(a6)
	jsr	_pc_free
;	if (total_blocks != -1)  {
^	cmp.l	#-1,-4(a6)
	lea	12(sp),sp
	beq	.10011
;		ASSERT (total_blocks > 0);
^;		partitions[n_partitions].partition_char = drive_char;
^	move.b	d4,d0
	ext.w	d0
	move.w	_n_partitions,d1
	ext.l	d1
	asl.l	#4,d1
	lea	_partitions,a0
	move.w	d0,(a0,d1.l)
;		partitions[n_partitions].partition_size = total_blocks;
^	move.w	_n_partitions,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+6,a0
	move.l	-4(a6),(a0,d0.l)
;		partitions[n_partitions].free_size = free_blocks;
^	move.w	_n_partitions,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+10,a0
	move.l	-8(a6),(a0,d0.l)
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		partitions[n_partitions].cluster_size = pc_cluster_size (path);
^	pea	-16(a6)
	jsr	_pc_cluster_size
	move.w	_n_partitions,d1
	ext.l	d1
	asl.l	#4,d1
	lea	_partitions+14,a0
	move.w	d0,(a0,d1.l)
;		partitions[n_partitions].errno = 0;
^	move.w	_n_partitions,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+4,a0
	clr.w	(a0,d0.l)
;		partitions[n_partitions].usable = 1;
^	move.w	_n_partitions,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+2,a0
	move.w	#1,(a0,d0.l)
;		printf ("Drive %c has %ld total blocks, %ld of which are free\n",
^;									drive_char, total_blocks, free_blocks);
	move.l	-8(a6),-(sp)
	move.l	-4(a6),-(sp)
	move.b	d4,d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.4+0
	jsr	_printf
;		if (((float)free_blocks/(float)total_blocks) < 0.90)  {
^^	move.l	-8(a6),d0
	jsr	.Fflu#
	lea	18(sp),sp
	move.l	d0,-(sp)
	move.l	-4(a6),d0
	jsr	.Fflu#
	move.l	d0,d1
	move.l	(sp)+,d0
	jsr	.Fdiv#
	jsr	.ftod#
	move.l	#$cccccccd,d3
	move.l	#$3feccccc,d2
	jsr	.Pcmp#
	bge	.10012
;			printf ("Drive %c has an unexpectedly large portion of its data space already\n", drive_char);
^	move.b	d4,d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.4+54
	jsr	_printf
;			printf ("filled.  Please verify that this is what you expected!\n");
^	pea	.4+124
	jsr	_printf
;		}
^;		n_partitions++;
	lea	10(sp),sp
.10012
^	add.w	#1,_n_partitions
;		return 1;
^	move.l	#1,d0
.7
	movem.l	(sp)+,d2/d3/d4
	unlk	a6
	rts
;	}  else  {
^.10011
;		printf ("Drive %c did not respond and will not be used or tested again\n", drive_char);
^	move.b	d4,d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.4+180
	jsr	_printf
;		return 0;
^	move.l	#0,d0
	add.w	#6,sp
	bra	.7
;	}
^;	//  cannot get here
;	printf ("logger_disk_test_drive error\n");
^^	pea	.4+243
	jsr	_printf
;	return 0;
^	move.l	#0,d0
	add.w	#4,sp
	bra	.7
;}	
^.5
.6	equ	-16
.4
	dc.b	68,114,105,118,101,32,37,99,32,104,97,115,32,37,108
	dc.b	100,32,116,111,116,97,108,32,98,108,111,99,107,115,44
	dc.b	32,37,108,100,32,111,102,32,119,104,105,99,104,32,97
	dc.b	114,101,32,102,114,101,101,10,0,68,114,105,118,101,32
	dc.b	37,99,32,104,97,115,32,97,110,32,117,110,101,120,112
	dc.b	101,99,116,101,100,108,121,32,108,97,114,103,101,32,112
	dc.b	111,114,116,105,111,110,32,111,102,32,105,116,115,32,100
	dc.b	97,116,97,32,115,112,97,99,101,32,97,108,114,101,97
	dc.b	100,121,10,0,102,105,108,108,101,100,46,32,32,80,108
	dc.b	101,97,115,101,32,118,101,114,105,102,121,32,116,104,97
	dc.b	116,32,116,104,105,115,32,105,115,32,119,104,97,116,32
	dc.b	121,111,117,32,101,120,112,101,99,116,101,100,33,10,0
	dc.b	68,114,105,118,101,32,37,99,32,100,105,100,32,110,111
	dc.b	116,32,114,101,115,112,111,110,100,32,97,110,100,32,119
	dc.b	105,108,108,32,110,111,116,32,98,101,32,117,115,101,100
	dc.b	32,111,114,32,116,101,115,116,101,100,32,97,103,97,105
	dc.b	110,10,0,108,111,103,103,101,114,95,100,105,115,107,95
	dc.b	116,101,115,116,95,100,114,105,118,101,32,101,114,114,111
	dc.b	114,10,0
	ds	0
;
;
;
;//  logger_disk_open
;//
;//	This is a essentially the po_open command with some extras which
;//  are special to the data logger.
;//
;//  The routine must do the following:
;//		Assign a partition letter to the path which was passed
;//		Power the associated drive up
;//		Try to open the file.  If successful, return fd
;//		If not, check errno to figure out why
;//			If the path doesn't yet exist, create it and try again
;//			If there is no space, try the next drive
;//			If the drive isn't responding, power it down and up, and try
;//				one more time.  Then try the next drive.
;//			
;//  The return values from this routine are the same as those of the
;//  po_open routine
;//
;//	Requirements:
;//		open file if possible and return fd
;//		on failure, check errno for reason.
;//			If no path, create it
;//			If no device, power down, then up, and try one more time.  If still bad
;//				move to next drive.  If no next drive, shut down logger
;//			If file already exists, choose new name (?)
;//			If no space, move to next disk
;//		
;PCFD logger_disk_open (char* filename, unsigned int flag, unsigned int mode)  {
# 219
| .9
	xdef	_logger_disk_open
_logger_disk_open:
	link	a6,#.10
	movem.l	d2/d3/d4/d5,-(sp)
	move.w	12(a6),d4
	move.w	14(a6),d5
;	//  the EMAXPATH variable is part of the disk drive header files
;	char path[EMAXPATH];
;	PCFD fd;
;	int index;
;	long free;
;	int n;
;	extern const long DISK_FREQ;
;
;	//  Don't allow the user to specify the partition.  We want to keep control
;	//  of that in this subroutine so we can switch when one gets full
;	ASSERT (filename[1] != ':');
~ path -260 "[260c"
~ fd d2 "i"
~ n d3 "i"
~~ filename 8 "#c"
~~ flag d4 "I"
~~ mode d5 "I"
^^^^^^^^^^^;	ASSERT (current_partition >= 0);
^;	ASSERT (current_partition <= n_partitions);
^;	ASSERT (SimGetFSys () == DISK_FREQ);
^;	if (current_partition >= n_partitions)  {
^	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	blt	.10013
;		//  we are out of disk partitions!
;		return -1;
^^	move.l	#-1,d0
.11
	movem.l	(sp)+,d2/d3/d4/d5
	unlk	a6
	rts
;	}	
^;
;	//  Combine the partition char with the file name to create the full path name
;	sprintf (path, "%c:%s", (char)partitions[current_partition].partition_char, filename);
.10013
^^^	move.l	8(a6),-(sp)
	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.8+0
	pea	-260(a6)
	jsr	_sprintf
;
;	//  make sure the disk is powered on, and if not, turn it on
;	#ifdef DEBUG
;	if (is_disk_power_on (path) == 0)
;		printf ("Failing on path '%s', partition %d\n", path, current_partition);
;	ASSERT (is_disk_power_on (path) != 0);
;	#endif
;	
;	//  try the open
;	critical_error_reset ();
^^^^^^^^^^	jsr	_critical_error_reset
;	#ifdef DEBUG
;	printf ("logger_disk_open: trying %s\n", path);
;	#endif
;	fd = po_open (path, flag, mode);
^^^^	move.w	d5,-(sp)
	move.w	d4,-(sp)
	pea	-260(a6)
	jsr	_po_open
	move.w	d0,d2
;	if (fd >= 0)  {
^	tst.w	d2
	lea	22(sp),sp
	blt	.10014
;		//  This ASSERT could be removed if necessary.  It is here because
;		//  the current code opens only a single file at once, and closes that
;		//  file when it is done.  Any fd other than 0 would indicate that we
;		//  had forgotten to close a file.
;		#ifdef DEBUG
;			if (fd != 0)  {
;				printf ("logger_disk_open: Unexpected file descriptor value of %d\n", fd);
;			}	
;			ASSERT (fd == 0);
;			printf ("logger_disk_open: opened '%s'\n", path);
;		#endif	
;		return fd;
^^^^^^^^^^^^	move.w	d2,d0
	bra	.11
;	}	
^;	log_printf ("logger_disk_open: Failed to open '%s'\n", path);		
.10014
^	pea	-260(a6)
	pea	.8+6
	jsr	_log_printf
;	log_printf ("  Errno %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	.8+45
	jsr	_log_printf
;		
;	//  All is not well.  Try to figure out why
;	switch (get_errno ())  {
^^^	jsr	_get_errno
	lea	18(sp),sp
	bra	.10015
;		case PEDEVICE:
^.10017
;			//  The disk drive isn't there!	 But it should be, so try a few
;			//  more times, then move to the next partition
;			for (n = 0;  n < MAX_RETRIES;  n++)  {
^^^	move.l	#0,d3
.10020
;				log_printf ("Disk not present; cycle power; try again\n");			
^	pea	.8+65
	jsr	_log_printf
;				disk_power_off (path);
^	pea	-260(a6)
	jsr	_disk_power_off
;            	DelayMilliSecs (500L);
^	pea	500
	jsr	_DelayMilliSecs
;				disk_power_on (path);
^	pea	-260(a6)
	jsr	_disk_power_on
;            	DelayMilliSecs (500L);
^	pea	500
	jsr	_DelayMilliSecs
;				critical_error_reset ();
^	jsr	_critical_error_reset
;				fd = po_open (path, flag, mode);
^	move.w	d5,-(sp)
	move.w	d4,-(sp)
	pea	-260(a6)
	jsr	_po_open
	move.w	d0,d2
;				if (fd >= 0)
^;					return fd;
	tst.w	d2
	lea	28(sp),sp
	blt	.10021
^	move.w	d2,d0
	bra	.11
;			}
.10021
^.10018
	add.w	#1,d3
	cmp.w	#1,d3
	blt	.10020
.10019
;			//  we have failed multiple times.  Return error and let the upper level code
;			//  move to the next partition
;        	return -1;
^^^	move.l	#-1,d0
	bra	.11
;			
;        case PENOENT:
^^.10022
;        	//  The path isn't there.  Create the full path - this isn't an unexpected
;        	//  error for certain paths through the code
;        	log_printf ("  Creating directory for '%s'\n", path);
^^^	pea	-260(a6)
	pea	.8+107
	jsr	_log_printf
;        	logger_disk_make_dir (path);
^	pea	-260(a6)
	jsr	_logger_disk_make_dir
;			critical_error_reset ();
^	jsr	_critical_error_reset
;			fd = po_open (path, flag, mode);
^	move.w	d5,-(sp)
	move.w	d4,-(sp)
	pea	-260(a6)
	jsr	_po_open
	move.w	d0,d2
;			return fd;
^	move.w	d2,d0
	lea	20(sp),sp
	bra	.11
;        	
;        case PEACCES:
^^.10023
;        	//  attempt to open a read-only or special file	
;        	//  should probably try a new file name.  How do we tell the calling
;        	//  routine of this?
;        	return -1;
^^^^	move.l	#-1,d0
	bra	.11
;        	
;        case PEMFILE:
^^.10024
;        	//  too many files already open
;        	//  This indicates a serious programming error, as we should
;        	//  be closing files as we finish with them	
;        	log_printf ("  PEMFILE errno should never happen.\n");
^^^^	pea	.8+138
	jsr	_log_printf
;        	//  REVIEW
;        	//  what should we do here for error recovery?
;        	ASSERT (0);
^^^;        	return -1;
^	move.l	#-1,d0
	add.w	#4,sp
	bra	.11
;        	
;        case PENOSPC:
^^.10025
;        	//  out of space on this drive/partition
;        	//  should switch to the next drive or partition
;			log_printf ("  PENOSPC error should never happen\n");
^^^	pea	.8+176
	jsr	_log_printf
;			return -1;
^	move.l	#-1,d0
	add.w	#4,sp
	bra	.11
;			
;		default:
^^.10026
;			disk_power_off (path);
^	pea	-260(a6)
	jsr	_disk_power_off
;        	log_printf ("  Unknown error %d should never happen.\n", get_errno());
^	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.8+213
	jsr	_log_printf
;			ASSERT (0);
^;	}
^	lea	10(sp),sp
	bra	.10016
.12
.10015
	sub.w	#2,d0
	beq	.10022
	sub.w	#11,d0
	beq	.10023
	sub.w	#11,d0
	beq	.10024
	sub.w	#4,d0
	beq	.10025
	sub.w	#3,d0
	beq	.10017
	bra	.10026
.10016
;	ASSERT (0);
^;	return -1;
^	move.l	#-1,d0
	bra	.11
;}
^.9
.10	equ	-260
.8
	dc.b	37,99,58,37,115,0,108,111,103,103,101,114,95,100,105
	dc.b	115,107,95,111,112,101,110,58,32,70,97,105,108,101,100
	dc.b	32,116,111,32,111,112,101,110,32,39,37,115,39,10,0
	dc.b	32,32,69,114,114,110,111,32,37,100,32,61,62,32,39
	dc.b	37,115,39,10,0,68,105,115,107,32,110,111,116,32,112
	dc.b	114,101,115,101,110,116,59,32,99,121,99,108,101,32,112
	dc.b	111,119,101,114,59,32,116,114,121,32,97,103,97,105,110
	dc.b	10,0,32,32,67,114,101,97,116,105,110,103,32,100,105
	dc.b	114,101,99,116,111,114,121,32,102,111,114,32,39,37,115
	dc.b	39,10,0,32,32,80,69,77,70,73,76,69,32,101,114
	dc.b	114,110,111,32,115,104,111,117,108,100,32,110,101,118,101
	dc.b	114,32,104,97,112,112,101,110,46,10,0,32,32,80,69
	dc.b	78,79,83,80,67,32,101,114,114,111,114,32,115,104,111
	dc.b	117,108,100,32,110,101,118,101,114,32,104,97,112,112,101
	dc.b	110,10,0,32,32,85,110,107,110,111,119,110,32,101,114
	dc.b	114,111,114,32,37,100,32,115,104,111,117,108,100,32,110
	dc.b	101,118,101,114,32,104,97,112,112,101,110,46,10,0
	ds	0
;
;
;
;//  This routine includes a number of printf statements that are useful for debugging.
;//  They are not #ifdef'ed because I consider this partition switching code important
;//  enough to always print the info.  In the case of an actual deployment, this info
;//  is lost, but the power wasted is insignificant, so I don't worry.  During land based
;//  testing, we always get the info, which will be useful is something isn't working
;//  properly.
;//
;int logger_disk_next_partition (void)  {
# 341
| .15
	xdef	_logger_disk_next_partition
_logger_disk_next_partition:
	link	a6,#.16
;	dword blocks_total, blocks_free;
;	
;	//  check to see if we are already out of disk partitions
;	if (current_partition >= n_partitions)
~ blocks_total -4 "L"
~ blocks_free -8 "L"
^^^^;		return -1;
	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	blt	.10027
^	move.l	#-1,d0
.17
	unlk	a6
	rts
;	printf ("logger_disk_next_partition: Finished with disk partition '%c:'\n",
.10027
^;		(char)partitions[current_partition].partition_char);
	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.14+0
	jsr	_printf
;	printf ("This is partition number %d\n", current_partition);		
^^	move.w	_current_partition,-(sp)
	pea	.14+64
	jsr	_printf
;	
;	log_printf ("logger_disk_next_partition: Finished with disk partition '%c:'\n",
^^;			(char)partitions[current_partition].partition_char);
	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.14+93
	jsr	_log_printf
;	if (get_errno() != 0)
^^;		log_printf ("  Errno %d => '%s'\n", get_errno(), get_errno_string (-1));
	jsr	_get_errno
	tst.w	d0
	lea	18(sp),sp
	beq	.10028
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.14+157
	jsr	_log_printf
;	else
	lea	10(sp),sp
	bra	.10029
.10028
;		log_printf ("  No disk error was encountered\n");	
^^	pea	.14+177
	jsr	_log_printf
	add.w	#4,sp
.10029
;
;	if (get_errno() != 0)
^^;		printf ("  Errno %d => '%s'\n", get_errno(), get_errno_string (-1));
	jsr	_get_errno
	tst.w	d0
	beq	.10030
^	move.w	#-1,-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	jsr	_get_errno
	move.w	d0,-(sp)
	pea	.14+210
	jsr	_printf
;	else
	lea	10(sp),sp
	bra	.10031
.10030
;		printf ("  No disk error was encountered\n");	
^^	pea	.14+230
	jsr	_printf
	add.w	#4,sp
.10031
;
;	partitions[current_partition].errno = get_errno ();
^^	jsr	_get_errno
	move.w	_current_partition,d1
	ext.l	d1
	asl.l	#4,d1
	lea	_partitions+4,a0
	move.w	d0,(a0,d1.l)
;	partitions[current_partition].free_size = blocks_free;
^	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+10,a0
	move.l	-8(a6),(a0,d0.l)
;	partitions[current_partition].usable = 0;
^	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+2,a0
	clr.w	(a0,d0.l)
;
;	blocks_total = blocks_free = -1;
^^	move.l	#-1,-8(a6)
	move.l	#-1,-4(a6)
;	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
;	log_printf ("  At finish, %ld free blocks remained.\n", blocks_free);
^	move.l	-8(a6),-(sp)
	pea	.14+263
	jsr	_log_printf
;	printf ("  At finish, %ld free blocks remained.\n", blocks_free);
^	move.l	-8(a6),-(sp)
	pea	.14+303
	jsr	_printf
;
;    //  depower current disk, switch partitions, and repower disk if it exists
;	logger_disk_power_disk_off ();
^^^	jsr	_logger_disk_power_disk_off
;	
;	
;	printf ("Switching partitions\n");	
^^^	pea	.14+343
	jsr	_printf
;	current_partition++;
^	add.w	#1,_current_partition
;	if (current_partition >= n_partitions)  {
^	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	lea	32(sp),sp
	blt	.10032
;		//  we are out of partitions.  Because of the importance of the data,
;		//  spend some time re-checking each disk for free space.  In the unlikely
;		//  event of a coding error having incorrectly closed down a disk this
;		//  might allow us to find it again.
;		log_printf ("Out of disk space.  Should recheck all disks.\n");		
^^^^^	pea	.14+365
	jsr	_log_printf
;		printf ("Out of disk space.  Should recheck all disks.\n");		
^	pea	.14+412
	jsr	_printf
;		return -1;
^	move.l	#-1,d0
	add.w	#8,sp
	bra	.17
;	}
^;	printf ("About to power on disk\n");
.10032
^	pea	.14+459
	jsr	_printf
;	logger_disk_power_disk_on ();
^	jsr	_logger_disk_power_disk_on
;	log_printf ("Disk partition changed successfully\n");
^	pea	.14+483
	jsr	_log_printf
;	printf ("Disk partition changed successfully\n");
^	pea	.14+520
	jsr	_printf
;	printf ("This is now partition '%c:'\n",
^;		(char)partitions[current_partition].partition_char);
	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),d0
	ext.w	d0
	move.w	d0,-(sp)
	pea	.14+557
	jsr	_printf
;	printf ("This is partition number %d\n", current_partition);		
^^	move.w	_current_partition,-(sp)
	pea	.14+586
	jsr	_printf
;	printf ("logger_disk_next_partition done\n");
^	pea	.14+615
	jsr	_printf
;#ifdef CREATE_DIRS	
;	sci_logger_setup_partition ();
^^	jsr	_sci_logger_setup_partition
;#endif	
;	return 0;
^^	move.l	#0,d0
	lea	28(sp),sp
	bra	.17
;}
^.15
.16	equ	-8
.14
	dc.b	108,111,103,103,101,114,95,100,105,115,107,95,110,101,120
	dc.b	116,95,112,97,114,116,105,116,105,111,110,58,32,70,105
	dc.b	110,105,115,104,101,100,32,119,105,116,104,32,100,105,115
	dc.b	107,32,112,97,114,116,105,116,105,111,110,32,39,37,99
	dc.b	58,39,10,0,84,104,105,115,32,105,115,32,112,97,114
	dc.b	116,105,116,105,111,110,32,110,117,109,98,101,114,32,37
	dc.b	100,10,0,108,111,103,103,101,114,95,100,105,115,107,95
	dc.b	110,101,120,116,95,112,97,114,116,105,116,105,111,110,58
	dc.b	32,70,105,110,105,115,104,101,100,32,119,105,116,104,32
	dc.b	100,105,115,107,32,112,97,114,116,105,116,105,111,110,32
	dc.b	39,37,99,58,39,10,0,32,32,69,114,114,110,111,32
	dc.b	37,100,32,61,62,32,39,37,115,39,10,0,32,32,78
	dc.b	111,32,100,105,115,107,32,101,114,114,111,114,32,119,97
	dc.b	115,32,101,110,99,111,117,110,116,101,114,101,100,10,0
	dc.b	32,32,69,114,114,110,111,32,37,100,32,61,62,32,39
	dc.b	37,115,39,10,0,32,32,78,111,32,100,105,115,107,32
	dc.b	101,114,114,111,114,32,119,97,115,32,101,110,99,111,117
	dc.b	110,116,101,114,101,100,10,0,32,32,65,116,32,102,105
	dc.b	110,105,115,104,44,32,37,108,100,32,102,114,101,101,32
	dc.b	98,108,111,99,107,115,32,114,101,109,97,105,110,101,100
	dc.b	46,10,0,32,32,65,116,32,102,105,110,105,115,104,44
	dc.b	32,37,108,100,32,102,114,101,101,32,98,108,111,99,107
	dc.b	115,32,114,101,109,97,105,110,101,100,46,10,0,83,119
	dc.b	105,116,99,104,105,110,103,32,112,97,114,116,105,116,105
	dc.b	111,110,115,10,0,79,117,116,32,111,102,32,100,105,115
	dc.b	107,32,115,112,97,99,101,46,32,32,83,104,111,117,108
	dc.b	100,32,114,101,99,104,101,99,107,32,97,108,108,32,100
	dc.b	105,115,107,115,46,10,0,79,117,116,32,111,102,32,100
	dc.b	105,115,107,32,115,112,97,99,101,46,32,32,83,104,111
	dc.b	117,108,100,32,114,101,99,104,101,99,107,32,97,108,108
	dc.b	32,100,105,115,107,115,46,10,0,65,98,111,117,116,32
	dc.b	116,111,32,112,111,119,101,114,32,111,110,32,100,105,115
	dc.b	107,10,0,68,105,115,107,32,112,97,114,116,105,116,105
	dc.b	111,110,32,99,104,97,110,103,101,100,32,115,117,99,99
	dc.b	101,115,115,102,117,108,108,121,10,0,68,105,115,107,32
	dc.b	112,97,114,116,105,116,105,111,110,32,99,104,97,110,103
	dc.b	101,100,32,115,117,99,99,101,115,115,102,117,108,108,121
	dc.b	10,0,84,104,105,115,32,105,115,32,110,111,119,32,112
	dc.b	97,114,116,105,116,105,111,110,32,39,37,99,58,39,10
	dc.b	0,84,104,105,115,32,105,115,32,112,97,114,116,105,116
	dc.b	105,111,110,32,110,117,109,98,101,114,32,37,100,10,0
	dc.b	108,111,103,103,101,114,95,100,105,115,107,95,110,101,120
	dc.b	116,95,112,97,114,116,105,116,105,111,110,32,100,111,110
	dc.b	101,10,0
	ds	0
;
;
;
;
;char* logger_disk_get_partition (void)  {
# 405
| .19
	xdef	_logger_disk_get_partition
_logger_disk_get_partition:
;	static char part[4];
	bss	.10033,4
;	if (current_partition < n_partitions)  {
~ part .10033 "[4c"
^^	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	bge	.10034
;		part[0] = (char)partitions[current_partition].partition_char;
^	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.b	1(a0,d0.l),.10033
;		part[1] = ':';
^	move.b	#58,.10033+1
;		part[2] = '\\';
^	move.b	#92,.10033+2
;		part[3] = '\0';
^	clr.b	.10033+3
;	}  else  {
^	bra	.10035
.10034
;		part[0] = '\0';
^	clr.b	.10033
;	}
^.10035
;	return (&part[0]);
^	lea	.10033,a0
	move.l	a0,d0
.20
	rts
;}		
^.19
;	        
;	
;
;
;int logger_disk_make_dir (const char* filename)  {
# 421
| .21
	xdef	_logger_disk_make_dir
_logger_disk_make_dir:
	link	a6,#.22
	movem.l	d2/d3,-(sp)
;	char dir[EMAXPATH];
;	int index, n;
;
;	//  make a copy of the path since we will be modifying it
;	strncpy (dir, filename, sizeof(dir));
~ dir -260 "[260c"
~ index d2 "i"
~ n d3 "i"
~~ filename 8 "#c"
^^^^^	pea	260
	move.l	8(a6),-(sp)
	pea	-260(a6)
	jsr	_strncpy
;	dir[sizeof(dir)-1] = '\0';
^	clr.b	-1(a6)
;	
;	//  Now delete the file name from the end of the path, leaving only
;	//  the directory name
;	index = strlen (dir) - 1;
^^^^	lea	-260(a6),a0
	move.l	a0,d0
.23	tst.b	(a0)+
	bne.s	.23
	sub.l	d0,a0
	sub.l	#1,a0
	sub.l	#1,a0
	move.w	a0,d2
;	while (index > 0)  {
^	lea	12(sp),sp
.10036
	tst.w	d2
	ble	.10037
;		if (dir[index] == '\\')
^;			break;
	lea	-260(a6),a0
	cmp.b	#92,(a0,d2.w)
	beq	.10037
;		index--;
^^	sub.w	#1,d2
;	}
^	bra	.10036
.10037
;	dir[index+1] = '\0';
^	lea	-260(a6),a0
	clr.b	1(a0,d2.w)
;	
;	#ifdef DEBUG
;	printf ("logger_disk_make_dir: testing for '%s'\n", dir);
;	critical_error_reset ();
;	if (pc_isdir(dir) != FALSE)  {
;		printf ("Directory is '%s'\n", dir);
;	}
;	critical_error_reset ();
;	ASSERT (pc_isdir(dir) == FALSE);
;	#endif
;
;	for (n = 0;  dir[n] != '\0';  n++)  {
^^^^^^^^^^^^	move.l	#0,d3
	bra	.10041
.10040
;		if (dir[n] != '\\')
^;			continue;
	lea	-260(a6),a0
	cmp.b	#92,(a0,d3.w)
	bne	.10038
;			
;		//  temporarily overwrite the \.  Then verify that the path exists, and
;		//  if not, create it.  Any failure is a hard failure.  Log it and give
;		//  up
;		dir[n] = '\0';
^^^^^^	lea	-260(a6),a0
	clr.b	(a0,d3.w)
;//		printf ("logger_disk_make_dir: about to test dir %s\n", dir);		
;		critical_error_reset ();
^^	jsr	_critical_error_reset
;		#ifdef DEBUG
;		printf ("logger_disk_make_dir: testing for dir '%s'\n", dir);	
;		#endif
;		if (pc_isdir (dir) == FALSE)  {
^^^^	pea	-260(a6)
	jsr	_pc_isdir
	tst.w	d0
	add.w	#4,sp
	bne	.10042
;			#ifdef DEBUG
;			printf ("logger_disk_make_dir: about to make dir %s\n", dir);		
;			#endif
;			critical_error_reset ();
^^^^	jsr	_critical_error_reset
;			#ifdef DEBUG
;			printf ("logger_disk_make_dir: making dir '%s'\n", dir);	
;			#endif
;			if (pc_mkdir (dir) == FALSE)  {
^^^^	pea	-260(a6)
	jsr	_pc_mkdir
	tst.w	d0
	add.w	#4,sp
	bne	.10043
;				log_printf ("logger_disk_make_dir: Couldn't create directory '%s'.\n", dir);
^	pea	-260(a6)
	pea	.18+0
	jsr	_log_printf
;				log_printf ("  Errno %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	.18+55
	jsr	_log_printf
;				return -1;
^	move.l	#-1,d0
	lea	18(sp),sp
.24
	movem.l	(sp)+,d2/d3
	unlk	a6
	rts
;			}
^;			#ifdef DEBUG
;			else
;				printf ("logger_disk_make_dir: made '%s'\n", dir);
;			#endif	
;		}
.10043
^^^^^;		#ifdef DEBUG			
;		else
;			printf ("path '%s' already exists.\n", dir);
;		#endif	
;		dir[n] = '\\';
.10042
^^^^^	lea	-260(a6),a0
	move.b	#92,(a0,d3.w)
;	}
^.10038
	add.w	#1,d3
.10041
	lea	-260(a6),a0
	tst.b	(a0,d3.w)
	bne	.10040
.10039
;	return 0;
^	move.l	#0,d0
	bra	.24
;}
^.21
.22	equ	-260
.18
	dc.b	108,111,103,103,101,114,95,100,105,115,107,95,109,97,107
	dc.b	101,95,100,105,114,58,32,67,111,117,108,100,110,39,116
	dc.b	32,99,114,101,97,116,101,32,100,105,114,101,99,116,111
	dc.b	114,121,32,39,37,115,39,46,10,0,32,32,69,114,114
	dc.b	110,111,32,37,100,32,61,62,32,37,115,10,0
	ds	0
;		
;
;
;//  logger_disk_cluster_size (char* path)
;//
;//  Returns the cluster size of the drive on which the given
;//  path will write
;//
;//	This is important because the the standard DOS file system uses
;//  16 bit numbers to specify which file is using which blocks.  For
;//  large disks, the number of blocks quickly exceeds 2^16, and the
;//  file system therefore allocates blocks in groups called clusters.
;//  Therefore, in order to efficiently use the disk without wasting space
;//  we must choose a file size that fills a cluster as completely as
;//  possible.  If we don't do this, the unused part of the cluster is
;//  lost.
;//
;long logger_disk_cluster_size (char* path)  {
# 505
| .26
	xdef	_logger_disk_cluster_size
_logger_disk_cluster_size:
;	critical_error_reset ();
~~ path 8 "#c"
^	jsr	_critical_error_reset
;	return pc_cluster_size (path);
^	move.l	4(sp),-(sp)
	jsr	_pc_cluster_size
	ext.l	d0
	add.w	#4,sp
.27
	rts
;}
^.26
;
;
;
;
;
;//  logger_disk_power_disk_off (void)  {
;//
;//  Turns off the power to the current disk
;//
;void logger_disk_power_disk_off (void)  {
# 518
| .28
	xdef	_logger_disk_power_disk_off
_logger_disk_power_disk_off:
	link	a6,#.29
	movem.l	d2,-(sp)
;	short fd;
;	char path[16];
;	char trash[128];
;
;	strcpy (path, logger_disk_get_partition ());
~ fd d2 "i"
~ path -16 "[16c"
~ trash -144 "[128c"
^^^^^	lea	-16(a6),a0
	move.l	a0,-(sp)
	jsr	_logger_disk_get_partition
	move.l	d0,a0
	move.l	(sp)+,a1
.30	move.b	(a0)+,(a1)+
	bne.s	.30
;	//  don't do anything if the current disk is non-existent
;	if (path[0] == '\0')
^^;		return;
	tst.b	-16(a6)
	bne	.10044
^.31
	movem.l	(sp)+,d2
	unlk	a6
	rts
;	strcat (path, "LOG.TXT");
.10044
^	pea	.25+0
	pea	-16(a6)
	jsr	_strcat
;//	printf ("logger_disk_power_disk_off: opening '%s'\n", path);		
;
;	//  REVIEW
;	//  This is a temporary kluge which is inserted to insure that the disk
;	//  actually flushes the data from its internal buffers to the disk
;	//  itself.  Some disks apparently don't do the write immediately.  By
;	//  forcing a seek we force the disk to actually flush the buffer first
;	//	
;	//  This sequence tries to insure that all of the data which has been written to the
;	//  disk's buffer has actually been flushed out to the disk.  It isn't clear from
;	//  any spec what is necessary to do this, but I can make some guesses.  First, I hope
;	//  that any drive actually processes data in the order the requests are received, so
;	//  I open a file, which probably doesn't exist, in the root directory, and hope that
;	//  this forces the flush of previously queued data.  Second, I hope that any drive makes
;	//  a reasonable effort to move data out to the disk, and that if I give it half a second
;	//  of delay this will be enough.  These measures may NOT be enough.  Who knows?  If
;	//  the file system starts producing unexpected errors, try something else here to see
;	//  if that fixes the problems.
;	//  SJM 3/7/99
;	
;	critical_error_reset ();
^^^^^^^^^^^^^^^^^^^^
^	jsr	_critical_error_reset
;	fd = po_open (path, (PO_BINARY|PO_RDWR), PS_IWRITE);
^	move.w	#256,-(sp)
	move.w	#32770,-(sp)
	pea	-16(a6)
	jsr	_po_open
	move.w	d0,d2
;	if (fd >= 0)  {
^	tst.w	d2
	lea	16(sp),sp
	blt	.10045
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		po_lseek (fd, 0L, PSEEK_SET);
^	clr.w	-(sp)
	clr.l	-(sp)
	move.w	d2,-(sp)
	jsr	_po_lseek
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		po_read (fd, (byte*)trash, sizeof(trash));
^	move.w	#128,-(sp)
	pea	-144(a6)
	move.w	d2,-(sp)
	jsr	_po_read
;		critical_error_reset ();
^	jsr	_critical_error_reset
;		po_close (fd);
^	move.w	d2,-(sp)
	jsr	_po_close
;	}
^;
;	//  now actually depower the disk
;	disk_power_off (path);
	lea	18(sp),sp
.10045
^^^	pea	-16(a6)
	jsr	_disk_power_off
;	return;
^	add.w	#4,sp
	bra	.31
;}
^.28
.29	equ	-144
.25
	dc.b	76,79,71,46,84,88,84,0
	ds	0
;
;
;
;
;void logger_disk_power_disk_on (void)  {
# 567
| .33
	xdef	_logger_disk_power_disk_on
_logger_disk_power_disk_on:
	link	a6,#.34
;	char path[8];
;	
;	//  This is my own addition to the file system calls.  It completely resets the
;	//  systems knowledge of the disk system and forces a re-read of all pertinent
;	//  info.  This may be important when switching disks.
;	pc_file_system_reset ();
~ path -8 "[8c"
^^^^^^	jsr	_pc_file_system_reset
;	strcpy (path, logger_disk_get_partition ());
^	lea	-8(a6),a0
	move.l	a0,-(sp)
	jsr	_logger_disk_get_partition
	move.l	d0,a0
	move.l	(sp)+,a1
.35	move.b	(a0)+,(a1)+
	bne.s	.35
;	if (path[0] != '\0')  {
^	tst.b	-8(a6)
	beq	.10046
;		disk_power_on (path);
^	pea	-8(a6)
	jsr	_disk_power_on
;	}
^;#ifdef DEBUG	
;	else
;		printf ("logger_disk_power_disk_on: No disk to power on	\n");
;#endif		
;}
	add.w	#4,sp
.10046
^^^^^.36
	unlk	a6
	rts
.33
.34	equ	-8
;		
;
;
;
;
;void logger_disk_show_status (void)  {
# 588
| .37
	xdef	_logger_disk_show_status
_logger_disk_show_status:
;	int n;
;	
;	printf ("The system checked for %d disks at power-up.\n", n_partition_slots);
^^^	move.w	_n_partition_slots,-(sp)
	pea	.32+0
	jsr	_printf
;	//  obviously not necessary, but we have plenty of code space
;	if (n_partitions == 1)
^^;		printf ("There was 1 disk that responded.\n");
	cmp.w	#1,_n_partitions
	add.w	#6,sp
	bne	.10047
^	pea	.32+46
	jsr	_printf
;	else	
	add.w	#4,sp
	bra	.10048
.10047
;		printf ("There were %d disks that responded.\n", n_partitions);
^^	move.w	_n_partitions,-(sp)
	pea	.32+80
	jsr	_printf
	add.w	#6,sp
.10048
;
;#if (IDE_DRIVESPERCONTROLLER == 2)
;	disk_power_on ("A:");
^^^	pea	.32+117
	jsr	_disk_power_on
;	logger_show_drive_status ("A:");
^	pea	.32+120
	jsr	_logger_show_drive_status
;	logger_show_drive_status ("B:");
^	pea	.32+123
	jsr	_logger_show_drive_status
;	disk_power_off ("A:");
^	pea	.32+126
	jsr	_disk_power_off
;	disk_power_on ("C:");
^	pea	.32+129
	jsr	_disk_power_on
;	logger_show_drive_status ("C:");
^	pea	.32+132
	jsr	_logger_show_drive_status
;	logger_show_drive_status ("D:");
^	pea	.32+135
	jsr	_logger_show_drive_status
;	disk_power_off ("D:");
^	pea	.32+138
	jsr	_disk_power_off
;#else	
;	disk_power_on ("A:");
;	logger_show_drive_status ("A:");
;	disk_power_off ("A:");
;	disk_power_on ("B:");
;	logger_show_drive_status ("B:");
;	disk_power_off ("B:");
;#endif
;		
;	if (current_partition >= n_partitions)  {
^^^^^^^^^^	move.w	_current_partition,d0
	cmp.w	_n_partitions,d0
	lea	32(sp),sp
	blt	.10049
;		printf ("All disks are currently full, and the data logger is disabled\n");
^	pea	.32+141
	jsr	_printf
;		#ifdef DEBUG
;		for (n = 0;  n < n_partitions;  n++)
;			ASSERT (partitions[n].usable == 0);
;		#endif
;	}  else  {
^^^^^	add.w	#4,sp
	bra	.10050
.10049
;		ASSERT (partitions[current_partition].usable != 0);
^;		printf ("Data is currently being written to disk %d which is assigned drive char %c\n",
^;									current_partition+1, partitions[current_partition].partition_char);
	move.w	_current_partition,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),-(sp)
	move.w	_current_partition,d0
	add.w	#1,d0
	move.w	d0,-(sp)
	pea	.32+204
	jsr	_printf
;	}									
^^	add.w	#8,sp
.10050
;}										
^.38
	rts
.37
.32
	dc.b	84,104,101,32,115,121,115,116,101,109,32,99,104,101,99
	dc.b	107,101,100,32,102,111,114,32,37,100,32,100,105,115,107
	dc.b	115,32,97,116,32,112,111,119,101,114,45,117,112,46,10
	dc.b	0,84,104,101,114,101,32,119,97,115,32,49,32,100,105
	dc.b	115,107,32,116,104,97,116,32,114,101,115,112,111,110,100
	dc.b	101,100,46,10,0,84,104,101,114,101,32,119,101,114,101
	dc.b	32,37,100,32,100,105,115,107,115,32,116,104,97,116,32
	dc.b	114,101,115,112,111,110,100,101,100,46,10,0,65,58,0
	dc.b	65,58,0,66,58,0,65,58,0,67,58,0,67,58,0
	dc.b	68,58,0,68,58,0,65,108,108,32,100,105,115,107,115
	dc.b	32,97,114,101,32,99,117,114,114,101,110,116,108,121,32
	dc.b	102,117,108,108,44,32,97,110,100,32,116,104,101,32,100
	dc.b	97,116,97,32,108,111,103,103,101,114,32,105,115,32,100
	dc.b	105,115,97,98,108,101,100,10,0,68,97,116,97,32,105
	dc.b	115,32,99,117,114,114,101,110,116,108,121,32,98,101,105
	dc.b	110,103,32,119,114,105,116,116,101,110,32,116,111,32,100
	dc.b	105,115,107,32,37,100,32,119,104,105,99,104,32,105,115
	dc.b	32,97,115,115,105,103,110,101,100,32,100,114,105,118,101
	dc.b	32,99,104,97,114,32,37,99,10,0
	ds	0
;
;
;
;void logger_show_drive_status (char* path)  {
# 631
| .40
	xdef	_logger_show_drive_status
_logger_show_drive_status:
	link	a6,#.41
	movem.l	d2/d3/a3,-(sp)
	move.l	8(a6),a3
;	dword blocks_free, blocks_total;
;	long nfree;
;	int n;
;	
;	for (n = 0;  n < n_partitions;  n++)
~ blocks_free -4 "L"
~ blocks_total -8 "L"
~ nfree d3 "l"
~ n d2 "i"
~~ path a3 "#c"
^^^^^	move.l	#0,d2
	bra	.10054
.10053
;		if ((char)partitions[n].partition_char == path[0])
^;			break;
	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.b	1(a0,d0.l),d0
	cmp.b	(a3),d0
	beq	.10052
;	if (n >= n_partitions)
.10051
	add.w	#1,d2
.10054
	cmp.w	_n_partitions,d2
	blt	.10053
.10052
^^;		return;
	cmp.w	_n_partitions,d2
	blt	.10055
^.42
	movem.l	(sp)+,d2/d3/a3
	unlk	a6
	rts
;				
;	printf ("Drive %d is assigned drive character %c.\n", n+1, (char)partitions[n].partition_char);
.10055
^^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions,a0
	move.w	(a0,d0.l),d0
	ext.w	d0
	move.w	d0,-(sp)
	move.w	d2,d0
	add.w	#1,d0
	move.w	d0,-(sp)
	pea	.39+0
	jsr	_printf
;	printf ("  It has %ld blocks of 512 bytes each.\n", partitions[n].partition_size);
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+6,a0
	move.l	(a0,d0.l),-(sp)
	pea	.39+42
	jsr	_printf
;	printf ("  These blocks are allocated in clusters of %u bytes each.\n", partitions[n].cluster_size);
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+14,a0
	move.w	(a0,d0.l),-(sp)
	pea	.39+82
	jsr	_printf
;	blocks_free = blocks_total = -1;
^	move.l	#-1,-8(a6)
	move.l	#-1,-4(a6)
;
;	critical_error_reset ();
^^	jsr	_critical_error_reset
;	nfree = pc_free (path, &blocks_total, &blocks_free);
^	pea	-4(a6)
	pea	-8(a6)
	move.l	a3,-(sp)
	jsr	_pc_free
	move.l	d0,d3
;	if (blocks_free != -1)  {
^	cmp.l	#-1,-4(a6)
	lea	34(sp),sp
	beq	.10056
;		printf ("  There are %ld free blocks on this drive.\n", blocks_free);
^	move.l	-4(a6),-(sp)
	pea	.39+142
	jsr	_printf
;	}  else  {
^	add.w	#8,sp
	bra	.10057
.10056
;		printf ("  This drive did not respond.\n");
^	pea	.39+186
	jsr	_printf
;	}
^	add.w	#4,sp
.10057
;
;	if (partitions[n].usable != 0)
^^;		printf ("  This drive is currently available for data storage.\n");
	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+2,a0
	tst.w	(a0,d0.l)
	beq	.10058
^	pea	.39+217
	jsr	_printf
;	else  {
	add.w	#4,sp
	bra	.10059
.10058
^;		printf ("  This drive is no longer available for data storage.\n");	
^	pea	.39+272
	jsr	_printf
;		printf ("  It was disabled when a write returned error number %d.\n", partitions[n].errno);
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+4,a0
	move.w	(a0,d0.l),-(sp)
	pea	.39+327
	jsr	_printf
;		printf ("  This error is '%s'.\n", get_errno_string (partitions[n].errno));
^	move.w	d2,d0
	ext.l	d0
	asl.l	#4,d0
	lea	_partitions+4,a0
	move.w	(a0,d0.l),-(sp)
	jsr	_get_errno_string
	add.w	#2,sp
	move.l	d0,-(sp)
	pea	.39+385
	jsr	_printf
;	}
^	lea	18(sp),sp
.10059
;	return;
^	bra	.42
;}	
^.40
.41	equ	-8
.39
	dc.b	68,114,105,118,101,32,37,100,32,105,115,32,97,115,115
	dc.b	105,103,110,101,100,32,100,114,105,118,101,32,99,104,97
	dc.b	114,97,99,116,101,114,32,37,99,46,10,0,32,32,73
	dc.b	116,32,104,97,115,32,37,108,100,32,98,108,111,99,107
	dc.b	115,32,111,102,32,53,49,50,32,98,121,116,101,115,32
	dc.b	101,97,99,104,46,10,0,32,32,84,104,101,115,101,32
	dc.b	98,108,111,99,107,115,32,97,114,101,32,97,108,108,111
	dc.b	99,97,116,101,100,32,105,110,32,99,108,117,115,116,101
	dc.b	114,115,32,111,102,32,37,117,32,98,121,116,101,115,32
	dc.b	101,97,99,104,46,10,0,32,32,84,104,101,114,101,32
	dc.b	97,114,101,32,37,108,100,32,102,114,101,101,32,98,108
	dc.b	111,99,107,115,32,111,110,32,116,104,105,115,32,100,114
	dc.b	105,118,101,46,10,0,32,32,84,104,105,115,32,100,114
	dc.b	105,118,101,32,100,105,100,32,110,111,116,32,114,101,115
	dc.b	112,111,110,100,46,10,0,32,32,84,104,105,115,32,100
	dc.b	114,105,118,101,32,105,115,32,99,117,114,114,101,110,116
	dc.b	108,121,32,97,118,97,105,108,97,98,108,101,32,102,111
	dc.b	114,32,100,97,116,97,32,115,116,111,114,97,103,101,46
	dc.b	10,0,32,32,84,104,105,115,32,100,114,105,118,101,32
	dc.b	105,115,32,110,111,32,108,111,110,103,101,114,32,97,118
	dc.b	97,105,108,97,98,108,101,32,102,111,114,32,100,97,116
	dc.b	97,32,115,116,111,114,97,103,101,46,10,0,32,32,73
	dc.b	116,32,119,97,115,32,100,105,115,97,98,108,101,100,32
	dc.b	119,104,101,110,32,97,32,119,114,105,116,101,32,114,101
	dc.b	116,117,114,110,101,100,32,101,114,114,111,114,32,110,117
	dc.b	109,98,101,114,32,37,100,46,10,0,32,32,84,104,105
	dc.b	115,32,101,114,114,111,114,32,105,115,32,39,37,115,39
	dc.b	46,10,0
	ds	0
;
;
;
;
;//  logger_disk_final_flush ()
;//
;//  Flushes the text log to the disk if possible.  This is not
;//  foolproof - it fails if the disks were abandoned because they were
;//  bad.  However, if they were abandoned because of a space limitation,
;//  then we know there is enough space left for the small amount of
;//  data in the text log, and we want to capture it.  This routine
;//  temporarily tweakes the current partition for the write, then
;//  marks us as out of partitions again.
;//
;void logger_disk_final_flush (void)  {
# 678
| .44
	xdef	_logger_disk_final_flush
_logger_disk_final_flush:
	movem.l	d2/d3/d4/d5,-(sp)
;	long freq, baud;
;	int freq_change;
;	int result;
;	ASSERT (current_partition == n_partitions);
~ freq d3 "l"
~ baud d4 "l"
~ freq_change d5 "i"
~ result d2 "i"
^^^^;	printf ("logger_disk_final_flush\n");
^	pea	.43+0
	jsr	_printf
;	freq = SimGetFSys ();
^	jsr	_SimGetFSys
	move.l	d0,d3
;	baud = SerGetBaud (0L, 0L);
^	clr.l	-(sp)
	clr.l	-(sp)
	jsr	_SerGetBaud
	move.l	d0,d4
;	if (freq != DISK_FREQ)  {
^	cmp.l	_DISK_FREQ,d3
	lea	12(sp),sp
	beq	.10060
;		SimSetFSys (DISK_FREQ);
^	move.l	_DISK_FREQ,-(sp)
	jsr	_SimSetFSys
;		SerSetBaud (baud, 0L);
^	clr.l	-(sp)
	move.l	d4,-(sp)
	jsr	_SerSetBaud
;		freq_change = 1;
^	move.l	#1,d5
;	} else
^	lea	12(sp),sp
	bra	.10061
.10060
;		freq_change = 0;
^	move.l	#0,d5
.10061
;	
;	while (current_partition > 0)  {
^^.10062
	tst.w	_current_partition
	ble	.10063
;		current_partition--;
^	sub.w	#1,_current_partition
;		printf ("logger_disk_final_flush: trying partition %d\n", current_partition); 		
^	move.w	_current_partition,-(sp)
	pea	.43+25
	jsr	_printf
;		logger_disk_power_disk_on ();
^	jsr	_logger_disk_power_disk_on
;		result = log_flush (NULL);
^	clr.l	-(sp)
	jsr	_log_flush
	move.w	d0,d2
;		logger_disk_power_disk_off ();
^	jsr	_logger_disk_power_disk_off
;		
;		if (result == 0)
^^;			break;
	tst.w	d2
	lea	10(sp),sp
	beq	.10063
;	}	
^^	bra	.10062
.10063
;	current_partition = n_partitions;
^	move.w	_n_partitions,_current_partition
;	printf ("logger_disk_final_flush: done\n");	
^	pea	.43+71
	jsr	_printf
;	//  be sure to restore the frequency and baud if needed
;	if (freq_change)  {
^^	tst.w	d5
	add.w	#4,sp
	beq	.10064
;		SimSetFSys (freq);
^	move.l	d3,-(sp)
	jsr	_SimSetFSys
;		SerSetBaud (baud, 0L);
^	clr.l	-(sp)
	move.l	d4,-(sp)
	jsr	_SerSetBaud
;	}
^;	return;
	lea	12(sp),sp
.10064
^.45
	movem.l	(sp)+,d2/d3/d4/d5
	rts
;}
^.44
.43
	dc.b	108,111,103,103,101,114,95,100,105,115,107,95,102,105,110
	dc.b	97,108,95,102,108,117,115,104,10,0,108,111,103,103,101
	dc.b	114,95,100,105,115,107,95,102,105,110,97,108,95,102,108
	dc.b	117,115,104,58,32,116,114,121,105,110,103,32,112,97,114
	dc.b	116,105,116,105,111,110,32,37,100,10,0,108,111,103,103
	dc.b	101,114,95,100,105,115,107,95,102,105,110,97,108,95,102
	dc.b	108,117,115,104,58,32,100,111,110,101,10,0
	ds	0
;	
;		
;
# 713
|
~ _DISK_FREQ * "l"
~ _wd * "[0c"
~ _n_partitions * "i"
~ _current_partition * "i"
~ _n_partition_slots * "i"
~ 'disk_info'
~ 1 6 16
~ partition_char 0 "i"
~ usable 2 "i"
~ errno 4 "i"
~ partition_size 6 "L"
~ free_size 10 "L"
~ cluster_size 14 "I"
~ _partitions * "[4:" 1
~ _logger_show_drive_status * "(v"
~ _logger_disk_test_drive * "(i"
~ _sci_logger_setup_partition * "(v"
~ _get_errno_string * "(#c"
~ _log_printf * "(i"
~ _log_flush * "(i"
~ 'text_log'
~ ''
~ 3 2 8
~ secs 0 "L"
~ ticks 4 "l"
~ 2 5 1068
~ filename 0 "[32c"
~ data 32 "[1024c"
~ n_data 1056 "i"
~ n_filled 1058 "i"
~ oldest_data 1060 ":" 3
~ EARLIEST_LOGGER_TIME _EARLIEST_LOGGER_TIME ":" 3
~ LATEST_LOGGER_TIME _LATEST_LOGGER_TIME ":" 3
~ _critical_error_set_n_tries * "(v"
~ _critical_error_logging * "(v"
~ _critical_error_reset * "(v"
~ _logger_disk_make_dir * "(i"
~ _logger_disk_final_flush * "(v"
~ _logger_disk_next_partition * "(i"
~ _logger_disk_get_partition * "(#c"
~ _logger_disk_show_status * "(v"
~ _logger_disk_cluster_size * "(l"
~ _logger_disk_power_disk_off * "(v"
~ _logger_disk_power_disk_on * "(v"
~ _logger_disk_open * "(i"
~ _logger_disk_power_on_init * "(v"
~ _get_errno * "(i"
~ 'system_user'
~ 4 4 46
~ task_handle 0 "i"
~ rtfs_errno 2 "i"
~ dfltdrv 4 "i"
~ lcwd 6 "[10#v"
~ PSYSTEM_USER "#:" 4
~ SYSTEM_USER ":" 4
~ _pc_file_system_reset * "(v"
~ 'finode'
~ 'ddrive'
~ 'fatswap'
~ 7 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"
~ 6 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 ":" 7
~ 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'
~ 8 4 14
~ nsegs 0 "i"
~ segindex 2 "i"
~ ncksum 4 "C"
~ segblock 6 "[2L"
~ 5 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 "#:" 6
~ my_block 44 "L"
~ my_index 48 "i"
~ pnext 50 "#:" 5
~ pprev 54 "#:" 5
~ s 58 ":" 8
~ 'drobj'
~ 'dirblk'
~ 10 3 10
~ my_frstblock 0 "L"
~ my_block 4 "L"
~ my_index 8 "i"
~ 'blkbuff'
~ 11 7 532
~ pnext 0 "#:" 11
~ lru 4 "L"
~ pdrive 8 "#:" 6
~ blockno 12 "L"
~ use_count 16 "i"
~ pad_to_4_align 18 "i"
~ data 20 "[512C"
~ 9 5 24
~ pdrive 0 "#:" 6
~ finode 4 "#:" 5
~ blkinfo 8 ":" 10
~ isroot 18 "i"
~ pblkbuff 20 "#:" 11
~ 'datestr'
~ 12 2 4
~ date 0 "I"
~ time 2 "I"
~ 'pc_file'
~ 13 8 24
~ pobj 0 "#:" 9
~ 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'
~ 14 1 512
~ core 0 "[512C"
~ 'ptable'
~ 'ptable_entry'
~ 16 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"
~ 15 2 66
~ ents 0 "[4:" 16
~ signature 64 "I"
~ PTABLE ":" 15
~ PTABLE_ENTRY ":" 16
~ 'format_dec_tree'
~ 17 3 8
~ sec_p_alloc 0 "I"
~ ents_p_root 2 "I"
~ n_blocks 4 "L"
~ FORMAT_DEC_TREE ":" 17
~ PC_FILE ":" 13
~ DROBJ ":" 9
~ BLKBUFF ":" 11
~ DIRBLK ":" 10
~ FINODE ":" 5
~ SEGDESC ":" 8
~ 'lfninode'
~ 18 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 ":" 18
~ 'dosinode'
~ 19 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 ":" 19
~ DDRIVE ":" 6
~ FATSWAP ":" 7
~ BLOCK_ALLOC ":" 14
~ CLUSTERTYPE "L"
~ 'ide_control'
~ 'ide_drive_desc'
~ ''
~ 'atapi_packet_desc'
~ 'transfer_length'
~ 24 2 2
~ msb 0 "C"
~ lsb 1 "C"
~ 23 8 14
~ op_code 0 "C"
~ lun 1 "C"
~ lba 2 "L"
~ reserved1 6 "C"
~ transfer_length 8 ":" 24
~ reserved2 10 "C"
~ reserved3 11 "C"
~ reserved4 12 "C"
~ 'atapi_mode_sense_packet_desc'
~ 25 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 ":" 24
~ reserved5 10 "C"
~ reserved6 11 "C"
~ reserved7 12 "C"
~ 'atapi_format_unit_packet_desc'
~ 26 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'
~ 27 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'
~ 28 6 12
~ op_code 0 "C"
~ lun 1 "C"
~ reserved1 2 "C"
~ reserved2 3 "C"
~ eject 4 "C"
~ reserved 5 "[7C"
~ 22 5 14
~ generic 0 ":" 23
~ mode_sense 0 ":" 25
~ format 0 ":" 26
~ old_format 0 ":" 27
~ start_stop 0 ":" 28
~ 21 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 ":" 22
~ atapi_packet_size 42 "I"
~ media_descriptor 44 "C"
~ medium_type_code 45 "C"
~ allocation_unit 46 "C"
~ 20 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:" 21
~ 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 "#:" 20
~ IDE_CONTROLLER ":" 20
~ IDE_DRIVE_DESC ":" 21
~ ATAPI_PACKET ":" 22
~ ATAPI_PACKET_DESC ":" 23
~ ATAPI_OLD_FORMAT_UNIT_PACKET_DE ":" 27
~ ATAPI_START_STOP_UNIT_PACKET_DE ":" 28
~ ATAPI_FORMAT_UNIT_PACKET_DESC ":" 26
~ ATAPI_MODE_SENSE_PACKET_DESC ":" 25
~ 'Himawari_format_descriptor'
~ 'Himawari_defect_list_header'
~ 30 4 4
~ reserved 0 "C"
~ control_byte 1 "C"
~ length_msb 2 "C"
~ length_lsb 3 "C"
~ 'Himawari_formattable_capacity_d'
~ 31 3 8
~ number_of_blocks 0 "[4C"
~ reserved 4 "C"
~ block_length 5 "[3C"
~ 29 2 12
~ dlheader 0 ":" 30
~ capacity_descriptor 4 ":" 31
~ HIMAWARI_FORMAT_DESCRIPTOR ":" 29
~ HIMAWARI_FORMATTABLE_CAPACITY_D ":" 31
~ HIMAWARI_DEFECT_LIST_HEADER ":" 30
~ 'himawari_flexible_disk_page'
~ 32 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 ":" 32
~ TRANSFER_LENGTH ":" 24
~ BLOCKT "L"
~ _disk_power_off * "(v"
~ _disk_power_on * "(v"
~ _pc_cluster_size * "(i"
~ _pc_isdir * "(i"
~ _pc_free * "(l"
~ _po_close * "(i"
~ _po_lseek * "(l"
~ _po_read * "(i"
~ _po_open * "(i"
~ _pc_mkdir * "(i"
~ 'fmtparms'
~ 33 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 ":" 33
~ 'freelistinfo'
~ 34 2 8
~ cluster 0 "L"
~ nclusters 4 "l"
~ FREELISTINFO ":" 34
~ 'fileseginfo'
~ 35 2 8
~ block 0 "l"
~ nblocks 4 "l"
~ FILESEGINFO ":" 35
~ 'stat'
~ 36 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 ":" 12
~ st_mtime 20 ":" 12
~ st_ctime 24 ":" 12
~ st_blksize 28 "l"
~ st_blocks 32 "l"
~ fattribute 36 "C"
~ STAT ":" 36
~ 'dstat'
~ 37 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 ":" 37
~ DATESTR ":" 12
~ 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"
~ _strcat * "(#c"
~ _strncpy * "(#c"
~ ''
~ 38 2 8
~ quot 0 "l"
~ rem 4 "l"
~ ''
~ 39 2 4
~ quot 0 "i"
~ rem 2 "i"
~ ldiv_t ":" 38
~ div_t ":" 39
~ '__stdio'
~ 40 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 ":" 40
~ fpos_t "l"
~ va_list "#c"
~ ''
~ 41 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 ":" 41
~ UeeErr "c"
~ _DelayMilliSecs * "(v"
~ _SimGetFSys * "(l"
~ _SimSetFSys * "(l"
~ time_tt ":" 3
~ _SerSetBaud * "(l"
~ _SerGetBaud * "(l"
~ XmdmErr "c"
~ FlashErr "c"
~ ''
~ 42 4 24
~ eSR 0 "I"
~ ePC 2 "L"
~ vectofs 6 "I"
~ states 8 "[8I"
~ ''
~ 43 4 20
~ preamble 0 "[4I"
~ jump 8 "I"
~ target 10 "L"
~ postamble 14 "[3I"
~ ExcCFramePtr "#:" 43
~ ExcCFrame ":" 43
~ ExcStackFrame ":" 42
~ 'tm'
~ 44 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"
~ time_t "L"
~ clock_t "L"
~ wchar_t "c"
~ ptrdiff_t "l"
~ size_t "L"
~ PSPErr "c"
~ _PRAM "[8I"
~ bool "c"
~ vfptr "#(v"
~ ptr "#c"
~ ulpv "#L"
~ ulong "L"
~ uspv "#I"
~ unsint "I"
~ ushort "I"
~ ucpv "#C"
~ uchar "C"
	xref	_sci_logger_setup_partition
	xref	_get_errno_string
	xref	_log_printf
	xref	_log_flush
	xref	_critical_error_set_n_tries
	xref	_critical_error_logging
	xref	_critical_error_reset
	xref	_get_errno
	xref	_pc_file_system_reset
	xref	_disk_power_off
	xref	_disk_power_on
	xref	_pc_cluster_size
	xref	_pc_isdir
	xref	_pc_free
	xref	_po_close
	xref	_po_lseek
	xref	_po_read
	xref	_po_open
	xref	_pc_mkdir
	xref	_strcat
	xref	_strncpy
	xref	_sprintf
	xref	_printf
	xref	_DelayMilliSecs
	xref	_SimGetFSys
	xref	_SimSetFSys
	xref	_SerSetBaud
	xref	_SerGetBaud
	xref	.begin
	dseg
	xref	_DISK_FREQ
	xref	_wd
	global	_n_partitions,2
	global	_current_partition,2
	end
