#ifndef _FLAT_H
#define _FLAT_H


#ifndef FLAT_USES_MALLOC
#define FLAT_USES_MALLOC        FALSE
#endif



#include "../types/types.h"             /* Bit32 Bit16 Bit8 */


#if defined(__unix__) || FLAT_USES_MALLOC
#   define align(boundary,pointer)   (void *)((((Bit32)pointer) + (boundary - 1)) & (~(Bit32)(boundary-1)))
#   define flat_init(x)
#   define flat_exit()
#   define flat_alloc(x) malloc(x)
#   define flat_free(x) free(x)
#   if defined(__unix__)
#       define flat_remaining() 0
#   else
#       include <alloc.h>
#       define flat_remaining() coreleft()
#   endif
#else
#   define flat_free(x)

#ifdef __cplusplus
extern "C" {
#else
#define inline
#endif

// global variables
//
extern Bit8 *flat_pool;
extern Bit8 *flat_free;
extern Bit32 flat_start;
extern Bit32 flat_length;



// non-inline functions
//
extern void *flat_alloc( Bit32 length );
#ifdef __cplusplus
extern void flat_init( int is_verbose_wanted = TRUE );
#else
extern void flat_init( int is_verbose_wanted );
#endif
extern void flat_exit( void );



// forces a pointer forward until it is aligned on
// an N byte boundary, where N is a power of 2
//
inline void *align( unsigned boundary, void *pointer )
{
    return (void *)((((Bit32)pointer) + (boundary - 1)) & (~(Bit32)(boundary-1)));
}



inline Bit32 flat_remaining( void )
{
    return flat_length - (flat_free - flat_pool);
}



inline Bit32 flat_to_physical( void *address )
{
    return flat_start + ((Bit8 *)address - flat_pool);
}



inline Bit8 *physical_to_flat( Bit32 address )
{
    return flat_pool + address - flat_start;
}

#ifdef __cplusplus
}           // extern "C"
#endif

#endif      /* not UNIX */



#endif      /* not included yet */
