/* SEU log display program for new format eltlog and eltlogxx files. */
/* Use for UO-14 files after 04 April 1991.                          */
/* Use for AO-16 and LO-19 files after March 1991.                   */
/* File formatted for tab stops 3, 5, 7, etc                         */
/* Structure contains NO slack bytes.                                */
/* INTEL lsb-first ordering assumed.                                 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "viewlog.h"

struct MEMERR
{
	long time		__attribute__ ((packed));																		/* time of correction				*/
	unsigned short cluster	__attribute__ ((packed));													/* cluster of error					*/
	unsigned short sector	__attribute__ ((packed));																		/* sector w/in cluster			*/
	unsigned short byte	__attribute__ ((packed));																			/* byte w/in sector					*/
	unsigned long fnumber	__attribute__ ((packed));												/* File in which error was	*/
	short severity		__attribute__ ((packed));																	/* 0 none, 1 corrected, 		*/
																								/* 2 very bad.							*/
																								/* 3 seu in program RAM			*/
	char pattern		__attribute__ ((packed));																	/* pattern for type 1				*/
	short function		__attribute__ ((packed));																	/* reason for check					*/
};

/* For MEMERR.function			*/
#define FUNC_WASH 1															
#define FUNC_READ 2

char writebuf[80];

/*------------------------------------------------------------------------
	Funct	:		elogdisp
	Date	:
	Action	:	Displays the error log from the PCE.
	ARGS	:
	RETURNS	:
	GLOBALS	:
------------------------------------------------------------------------*/

int elogdisp(FILE *fp)
{
	struct MEMERR seu;
	char s1[30];

	writetext("SEU LOG:\n\n");
	writetext("     Time             Cluster Sector  Byte  Patrn Type    File     Function\n");
	writetext("-------------------   ------- ------  ----  ----- ----    -------  --------\n");

	while (!feof(fp))
	{
		if (fread(&seu, sizeof(struct MEMERR), 1, fp))
		{
				/* Time, cluster and sector always valid */
				sprintf(s1, asctime(gmtime(&seu.time)));
				s1[strlen(s1)-1] = '\0';

				sprintf(writebuf, "%20.20s  0x%04x  0x%04x  ", s1, seu.cluster, seu.sector);
				writetext(writebuf);

				/* Byte only valid on correctable errors */
				if (seu.severity == 1)
				{
					sprintf(writebuf, "0x%02x  0x%02x  ", seu.byte, seu.pattern & 0xff);
					writetext(writebuf);
				}
				else
				{
					writetext("----- ");
					writetext("----- ");
				}

				switch (seu.severity)
				{
					case 1:
						writetext("Fixed   ");
						break;

					case 2:
						writetext("SEVERE  ");
						break;
				}

				/* During WASH cycles, fnumber has 4 meanings */
				if (seu.function == FUNC_WASH)
				{
					if (seu.fnumber == 0l)
						writetext("Directry ");
					else if (seu.fnumber == -1l)
						writetext("in FAT   ");
					else if (seu.fnumber == -2l)
						writetext("in FREE  ");
					else
					{
						sprintf(writebuf, "%08lx ", seu.fnumber);
						writetext(writebuf);
					}
				}
				/* During READ cycles, fnumber has no meaning */
				else if (seu.function == FUNC_READ)
				{
					if (seu.fnumber < 1l)
						writetext("error    ");
					else
						writetext("unknown  ");
				}
				else
					writetext("bad func ");

				/* Tell which function it was */
				if (seu.function == FUNC_WASH)
					writetext("Wash\n");
				else if (seu.function == FUNC_READ)
					writetext("Read\n");
				else writetext("????\n");

		}
	}

	return(0);
}

