#include		"memcheck.h"

/*  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>

/*  disk includes  */
#include		<pcdisk.h>

#include		"misc.h"
#include		"ASSERT.h"


struct errno_string  {
	int errno;
	char* string;
};
struct errno_string errno_strings[] =  {
	PEBADF, "Invalid file descriptor",
	PENOENT, "File or path not found",
	PEMFILE, "Too many files open",
	PEEXIST, "Exclusive access requested on already existing file",
	PEACCES, "Attempt to open read only or special file",
	PEINVAL, "Seek to negative file pointer attempted",
	PENOSPC, "Write failed, presumable because of no space",
	PESHARE, "Open failed due to sharing violation",
	PEDEVICE, "No valid disk present",
};
char* get_errno_string (int err)  {
	int n;
	static char sbuff[64];
	const int n_strings = sizeof (errno_strings) / sizeof (struct errno_string);
	
	ASSERT (n_strings == 9);    
	
	if (err < 0)
		err = get_errno ();
    for (n = 0;  n < n_strings;  n++)  {
    	if (err == errno_strings[n].errno)
    		return errno_strings[n].string;
    }
    
    sprintf (sbuff, "Errno %d has no known string", err);
    return sbuff;
}
    		




long mem_find_max_malloc (void)  {
	size_t total_allocation, next_size;
	char* pointers[32];
	int n;
	extern long _mbot, _mtop, _mcur;
	
//	printf ("mem_find_max_malloc: start\n");
//	printf ("bottom is 0x%08lX, top is 0x%08lX, current is 0x%08lX\n", _mbot, _mtop, _mcur);
	
	ASSERT ((sizeof(pointers)/sizeof(char*)) == 32);
	for (n = 0;  n < sizeof(pointers)/sizeof(char*);  n++)
		pointers[n] = NULL;
		
	n = 0;
	total_allocation = 0;
	next_size = 1024L*1024L;
	do  {
//		printf ("malloc of pointer %d\n", n);	
		pointers[n] = (char*) malloc (next_size);
		if (pointers[n] != NULL)  {
			total_allocation += next_size;
//			printf ("  Allocated %ld bytes to block %d (address 0x%lX)\n", next_size, n, (long)pointers[n]);
//			printf ("    Total is now %ld\n", total_allocation);		
			n++;
		}  else  {
//			printf ("couldn't alloc size %ld\n", next_size);
			;
		}
		next_size /= 2;
	}  while (next_size >= 256);
		
	//  free in the reverse of the allocation order; this shouldn't
	//  matter, but who knows?
	n--;
	while (n >= 0)  {
		ASSERT (pointers[n] != NULL);
		free (pointers[n]);
		pointers[n] = NULL;
		n--;
	}
	#ifdef DEBUG
	for (n = 0;  n < (sizeof(pointers)/sizeof(char*)); n++)  {
		ASSERT (pointers[n] == NULL);
	}	
	#endif	
	
/*	
	for (n = 0;  n < sizeof(pointers)/sizeof(char*);  n++)  {
		if (pointers[n] != NULL)  {
//printf ("About to free 0x%lX\n", (long)pointers[n]);		
			free (pointers[n]);
			pointers[n] = NULL;
		}	
	}
*/	
//	printf ("mem_find_max_malloc: stop\n");
//	printf ("bottom is 0x%08lX, top is 0x%08lX, current is 0x%08lX\n", _mbot, _mtop, _mcur);
//	printf ("mem_find_max_malloc: Total allocation = %ld\n", total_allocation);
	return (total_allocation);
}
