/*  pmalloc.h
*
*  Written by Kenny Ng Jan 00'
*
*
*/

#include "datatype.h"

#ifndef __PMALLOC_H__
#define __PMALLOC_H__


#ifdef PC_SIM
#include <malloc.h>

#define qmalloc(x)  (void *) malloc(x)
#define qcalloc(x,y)  (void *) calloc(x,y)
#define qfree(x)    free(x)

#define pmalloc(x)  (void *) malloc(x)
#define pcalloc(x,y)  (void *) calloc(x,y)
#define pfree(x)    free(x)

#else

#define MM_USED 0xffaa0055
#define MM_FREE 0x55aaff00

#define PAGE_SIZE   0x1000      /* 4KB page */
#define PAGE_MASK   0xfffff000  /* 4KB block mask */

/* note: re-ordering of the structure of size_identifier need to 
         modify mm_link[x]'s init. routine!
*/
struct size_identifier
{
    struct size_identifier *pfree_head; /* first free */
    UBYTE nclick;       /* number of click in 4K block */
    UBYTE npages;       /* Number of allocatable click in the block */
    UBYTE npage_need;   /* Number of 4K page required, in power of 2 */
};

struct block_header
{
    UWORD flag;
};

struct free_block_header
{
    UWORD flag;
    struct free_block_header *next;
};

struct page_identifier
{
    struct page_identifier *next;       /* point to next allocated block */
    struct block_header *first_free_click;  /* point to first free click in this block */
    USHORT  npage_order;     /* page order of this block, any value in blocksize[] */
    USHORT  nfree_click;     /* available allocatable unit (click) in the block */
    USHORT  block;           /* physical block number from MMU */
};

#define MM_MAX_ORDER    15 //(sizeof(mm_link) / sizeof(mm_link[0]))  /* number of entry in mm_link */

void *get_pages(WORD size, USHORT *blk);
void free_pages(void *ptr);
void *qmalloc(WORD size);
void qfree(void *__ptr);
void *pmalloc(WORD size);
void pfree(void *__ptr);
void user_mm_init();
void os_mm_init();

#endif
#endif
