#ifndef _MEMORY_H
#define _MEMORY_H

#include "ktypes.h"

/* ----------------------------------------------------- */

// The MEMORY unit defines the organization of main memory
// within the KBOX machine. Although this seems almost
// trivial at first glance, there are some special
// considerations to keep in mind.

// Main memory is indeed a simple array of klunks
// of a specified size! Hence the two declarations
// immediately following these comments.

// However, we must keep track of static memory
// as it is either initialized or reserved.
// This requires a memory_map identifying the names of
// variables allocated space in memory, their location in
// memory, and the amount of space set aside for them.

// We need the information found in the memory map to:

//	retrieve information from memory by name
//	store information into memory by name

// Lastly, we need to keep track of last memory location
// assigned so that we know what location in memory
// is the next one available.

// Hence, main memory is actually a triple:
//	actual memory storage
//      a memory map
//      next available address

// Support methods for memory include:

//	_DEFINE				display
//	_RESERVE			displayStack

//			memoryAddress
//			peek
//			poke

/* ----------------------------------------------------- */

#define MAXMEM	1000000
typedef klunk	storageType [MAXMEM];	// array of klunks

/* ----------------------------------------------------- */

typedef struct mapEntry* mapPtr;

struct mapEntry
{
  char*		name;		// identifier
  long long	address;	// base address in memory
  long long	size;		// size in 64-bit klunks
  mapPtr	next;
};

void		addEntry	(char*,long long,long long);

/* ----------------------------------------------------- */

struct memoryType
{
  storageType	data;		// klunk storage area
  mapPtr	info;		// memory map
  long long	nextAddress;	// next available address
};

struct memoryType MEMORY;

/* ----------------------------------------------------- */

void		initializeMemory(void);
long long	getNextAddress	(void);

void		_DEFINE		(char*,klunk);
void		_RESERVE	(char*,long long);

long long	memoryAddress	(char* ident);

klunk		peek		(long long);
void		poke		(long long,klunk);

void		displayMemory	(void);
void		displayMap	(void);
void		displayNext	(void);
void		displayStack	(long long);

void		reverseDisplay	(mapPtr);

/* ----------------------------------------------------- */

#endif
