/*
 *  dumpmem.c
 *  inspired by /diag/dumpmem on my S2 TiVo
 *  
 *
 *  Created by Steve White on Sun Dec 22 2002.
 *  Copyright (c) 2002 Steve White. All rights reserved.
 *
 */

#include <sys/mman.h>

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

void asciiView(char *data, int howMany);

int main(int argc, char **argv) {
	char *memory;
	int devmem, length, address;
	int pos=0;
	int i=1;

	if (argc != 3) {
		printf("%s: not enough parameters\n", argv[0]);
		printf("usage: %s memory-offset length-bytes\n", argv[0]);
		return EXIT_FAILURE;
	}

	address = strtol(argv[1], NULL, 16);
	length  = atoi(argv[2]);

	devmem = open("/dev/mem", O_RDONLY|O_SYNC);
	if (devmem == -1) {
		printf("Error opening /dev/mem\n");
		return EXIT_FAILURE;
	}

	memory = mmap(NULL, length, PROT_READ, MAP_SHARED, devmem, address);
	close(devmem);

	printf("%08x: ", address);
	while (pos < length) {
		printf("%02x ", memory[pos]&0xff);
		pos++, i++;

		if (i > 16) {
			asciiView(&memory[pos-16], 16);
			if (pos < length) {
				printf("\n%08x: ", address+pos);
				i = 1;
			}
		}
	}

	if (i <= 16) {
		pos = pos-i+1;
		for ( ; i<=16; i++)
			printf("   ");

		asciiView(&memory[pos], length-pos);
	}

	printf("\n");
	return EXIT_SUCCESS;
}

void asciiView(char *data, int howMany) {
	int i;

	for (i=0; i<howMany; i++) {
		if (data[i] > 32 && data[i] < 126) {
			printf("%c", data[i]);
		} else {
			printf(".");
		}
	}
}
