/*
 * printhex.c  -  Print a hex memory dump
 *
 * Copyright (C) 1998-2003 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  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
 *  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.
 *
 * $Id: printhex.c,v 1.4 2003/01/25 23:29:43 gkminix Exp $
 */

#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include "romcheck.h"



/*
 * Some useful defines
 */
#define MAXLINES	16	/* number of lines to print on one screen */
#define LINESIZE	16	/* number of hex values per line */



/*
 * Print one line of hex code
 */
static void printline(seg)
unsigned int seg;
{
  static unsigned char buf[LINESIZE + 1];
  int i;

  /* Fill buffer from rom memory */
  movedata(seg, 0, __get_ds(), buf, LINESIZE);

  /* Print buffer in hex and convert it into a printable string */
  printf("%04X0  ", seg);
  for (i = 0; i < LINESIZE; i++) {
	printf(" %02X", buf[i] & 0xff);
	if (buf[i] > 0x7f || !isprint(buf[i] & 0xff))
		buf[i] = '.';
  }
  buf[LINESIZE] = '\0';
  printf("   %s\n", buf);
}



/*
 * Print a rom area or the whole memory as a hex dump.
 */
void printhex(sip)
struct scaninfo *sip;
{
  unsigned int memstart, memend;
  unsigned int curpos, i;
  int index;
  char c;

  /* Ask the user about which area to print */
  printf("\n\n");
  index = readint("Enter rom area number, 0 for whole memory",
							0, sip->signum, 0);
  if (index > 0) {
	index--;
	memstart = sip->sigsegs[index];
	memend = sip->sigsegs[index] + sip->sigsize[index];
  } else {
	memstart = readhex("Enter start segment",
					STARTSEG, ENDSEG - 1, STARTSEG);
	memend = readhex("Enter end segment",
					memstart + 1, ENDSEG, memstart + 1);
  }
  curpos = memstart;

  /* Print one page of output and ask user what to do next */
  while (TRUE) {
	printf("\n\n");
	for (i = curpos; i < (curpos + MAXLINES) && i < memend; i++)
		printline(i);
	printf("\nPress <q> to exit");
	if (i < (memend - 1))
		printf(", <space> or <e> to continue");
	if (curpos > memstart)
		printf(", <b> or <t> to go back");
	do {
		c = waitchar();
		switch (c) {
			case 'q':
				putchar('\n');
				return;
			case 'b':
				if (curpos > memstart) {
					if ((curpos - memstart) < MAXLINES)
						curpos = memstart;
					else
						curpos -= MAXLINES;
				} else
					c = '\0';	/* invalid command */
				break;
			case 't':
				if (curpos > memstart)
					curpos = memstart;
				else
					c = '\0';	/* invalid command */
				break;
			case ' ':
				if (i < (memend - 1))
					curpos = i;
				else
					c = '\0';	/* invalid command */
				break;
			case 'e':
				if (i < (memend - 1)) {
					if ((memend - memstart) < MAXLINES)
						curpos = memstart;
					else
						curpos = memend - MAXLINES;
				} else
					c = '\0';	/* invalid command */
				break;
			default:
				c = '\0';		/* invalid command */
				break;
		}
	} while (!c);
  }
}



syntax highlighted by Code2HTML, v. 0.9.1