/*
   SIOTracer - simple trace / debug printer module

   Copyright (C) 2002 Matthias Reichl <hias@horus.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

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

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

#include "SIOTracer.h"
#include "AbstractSIOHandler.h"

SIOTracer* SIOTracer::fInstance = 0;

SIOTracer::SIOTracer()
	: fTraceCommands(false),
	  fTraceCommandResults(false),
	  fTraceDataBlocks(false),
	  fFile(stdout)
{
}

SIOTracer::~SIOTracer()
{
}

void SIOTracer::TraceCommandFrame(
	const SIO_command_frame &frame,
	const char *prefix)
{
	if (fTraceCommands) {
		if (prefix) {
			fprintf(fFile,"%s",prefix);
		}
		fprintf(fFile,"frame [ %02x %02x %02x %02x ]\n",
			frame.device_id, frame.command, frame.aux1, frame.aux2);
		fflush(fFile);
	}
}

void SIOTracer::TraceDataBlock(
	int len,
	const unsigned char* block,
	const char *prefix)
{
	if (fTraceDataBlocks) {
		if (prefix) {
			fprintf(fFile,"%s",prefix);
		}
		fprintf(fFile,"data block length = %d bytes\n", len);

		int i;
		for (i=0;i<len;i++) {
			fprintf(fFile,"%02x ",block[i]);
			if (i % 16 == 15) {
				fprintf(fFile,"\n");
			}
		}
		if (len % 16 != 0) {
			fprintf(fFile,"\n");
		}
		fflush(fFile);
	}
}

void SIOTracer::TraceDecodedPercomBlock(
	const unsigned char* block, /* 12 bytes long */
	const char *prefix)
{
	if (fTraceDataBlocks) {
		if (prefix) {
			fprintf(fFile,"%s", prefix);
		}
		fprintf(fFile,"PercomBlock [ %d sides %d tracks %d sectors = %d total %d bytes/sec ",
			block[4] + 1, block[0],
		       	256*block[2] + block[3],
			(block[4] + 1) * block[0] * (256*block[2] + block[3]),
		       	256*block[6] + block[7]);
		switch (block[5]) {
		case 0:
			fprintf(fFile, "FM");
			break;
		case 4:
			fprintf(fFile,"MFM");
			break;
		default:
			fprintf(fFile, "illegal density %d", block[5]);
			break;
		}
		fprintf(fFile,"]\n");
		fflush(fFile);
	}
}

void SIOTracer::TraceCommandOK()
{
	if (fTraceCommandResults) {
		fprintf(fFile,"command OK\n");
		fflush(fFile);
	}
}

void SIOTracer::TraceCommandError(int returncode)
{
	if (fTraceCommandResults) {
		fprintf(fFile,"command ERROR: ");
		switch (returncode) {
		case AbstractSIOHandler::eWriteProtected:
			fprintf(fFile, "write protected\n");
			break;
		case AbstractSIOHandler::eUnsupportedCommand:
			fprintf(fFile, "unsupported command\n");
			break;
		case AbstractSIOHandler::eInvalidPercomConfig:
			fprintf(fFile, "invalid percom config\n");
			break;
		case AbstractSIOHandler::eIllegalSectorNumber:
			fprintf(fFile, "illegal sector number\n");
			break;
		case AbstractSIOHandler::eImageError:
			fprintf(fFile, "disk image error\n");
			break;
		default:
			fprintf(fFile, "%d\n", returncode);
		}
		fflush(fFile);
	}
}

