/*
================================ COPYRIGHT ================================
The contents of this file are subject to the VTech Informations Ltd. License
of VT-OS Ver. 1.1 operating system (the "License"); you may not use this 
file except in compliance with the License.  
 
Software distributed under the License is distributed on an "AS IS" basis, 
WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License 
for the specific language governing rights and limitations under the License.
 
The Original Code is VT-OS Ver. 1.1 Operating System, released 
on October 1st, 1999

The Initial Developer of the Original Code is VTech Informations Ltd.  All 
codes are Copyright (C) VTech Informations Ltd. 1999.  All Rights Reserved.
===========================================================================
*/

/*
===========================================================================
File        :   mmu.h
Author(s)   :   Kenny Ng
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   header file for Memory Manager
Revision    :   1.1
Note        :   None
===========================================================================
*/              
                

#ifndef __MMU_H__
#define __MMU_H__

#include "datatype.h"
#include "tmrapi.h"

typedef UWORD DatabaseID;
typedef USHORT AppID;
typedef UWORD Err;
typedef USHORT BlockType;
typedef UWORD RecordID;

#ifdef PC_SIM 
   #include <stdio.h> 
   #include <malloc.h>
   #include <string.h>
   #include <stdlib.h>
   #include <dos.h>
   #include <conio.h>
   #include <time.h>
   #define HUGE huge
#endif

#if defined(PR31700) || defined(PR32000)
  #include "print.h"	/* printf */
  #include "uart.h"
  #ifndef NULL
  #define NULL 0
  #endif
  #define HUGE
#endif

#include "dm_os.h"
#include "dm_user.h"
#include "kernel.h"

#include "datatype.h"

enum _dbopenmode { OPEN_RW, OPEN_RO, OPEN_EX };
typedef enum _dbopenmode DBOpenMode;

enum _attribute {ATTR_CLR, ATTR_SET, ATTR_UNCHG};
typedef enum _attribute Attribute;

#define QUICK_SORT_RECORD       20

#define PMALLOC_WARNING		3

#define mod(x,y)         (UWORD)(x-(x/y)*y)                 /* x mod y */
#define MatEntryPerBlock (BLOCK_SIZE / sizeof(MAT))  /* no. of MAT entry per block */

/*
field size     32       16       4        1       11
	   |   ID   |  Next  |  Type  |  Frag  |  Res  |
*/
#define SetBlockType(attribute, type)  (attribute = (attribute & 0x0FFF) | type)
#define BlockType(attribute)	(attribute & 0xF000)
#define IsBlockFree(attribute)  ((USHORT)(attribute & 0xF000) == (USHORT) MAT_BLOCK_FREE)

#define IsFragment(attribute)	((USHORT)(attribute & 0x0800) == 0x0800)

#define UpdateMATCRC(matp)      (matp->mat[matp->total_entry].id = MemoryMATCheckSum(matp))

#define SBlockMat(sblock)       (sblock>>16)
#define SBlockBlock(sblock)     ((USHORT) (sblock & 0x0000FFFF))
UWORD SBlockAddr(UWORD sblock);
#define MakeSBlock(num, block)  ((((UWORD)(num) << 16) & 0xFFFF0000) | (((UWORD) block) & 0x0000FFFF))

/* define the record id for category entry */
#define MakeCatRecID(cat)	( 0x80000000 | ( (UWORD)cat & 0x000000FF) )

/* determine if the record is a cat chunk and archive chunk */
#define NormRec(rec_ptr)	( ((rec_ptr->rec_id & 0x80000000) == 0x00000000) \
				  && (((rec_ptr->attribute) & 0x04) == (BYTE) 0x00))

#define NormRecID(rec_id)	((rec_id & 0x80000000) == 0x00000000)

#define CatRecID(rec_id)        ((rec_id & 0x80000000) && !((rec_id & 0x0fffff00)))
 
/* Check fragment flag of a record */
#define FragRec(rec_ptr)	((rec_ptr->attribute) & 0x20)
#define SetRecFrag(rec_ptr)	((rec_ptr->attribute) |= 0x20)
#define ClrRecFrag(rec_ptr)	((rec_ptr->attribute) &= 0xDF)

#define IsRecSecret(rec_ptr)	((BYTE)((rec_ptr->attribute) & 0x10) == (BYTE)0x10)
#define SetRecSecret(rec_ptr)   ((rec_ptr->attribute) |= 0x10)  /* upate mat after the operation */
#define ClrRecSecret(rec_ptr)   ((rec_ptr->attribute) &= 0xEF)  /* upate mat after the operation */

#define IsRecLock(rec_ptr)	((BYTE)((rec_ptr->attribute) & 0x08) == (BYTE)0x08)
#define SetRecLock(rec_ptr)	((rec_ptr->attribute) |= 0x08)  /* upate mat after the operation */
#define ClrRecLock(rec_ptr)	((rec_ptr->attribute) &= 0xF7)  /* upate mat after the operation */

#define SetRecArchive(rec_ptr)  ((rec_ptr->attribute) |= 0x04)

/* Decode the FieldSize, field_ptr will move to first char in the field*/
#define DeFieldSize(field_ptr, size, byte_use) {size = 0;               \
						byte_use = 0;           \
				    do {                                \
				      (size) |=  ((((UWORD)(*field_ptr)) >> 1) & 0x0000007F) << ((byte_use++) * 7);\
				      } while (!((*field_ptr++) & 0x01));}

/* Encode the FieldSize and number of byte use to represent it*/
/* output:  word - encoded data, byte_use - no. of byte in word that is valid for the representation */
/*          size - always 0							*/
#define EnFieldSize(word, size, byte_use) { byte_use = 0;				     \
				      do {                                  \
				       *(BYTE*)((BYTE*)(&word) + byte_use++) = ((BYTE) size) << 1;      \
				       size >>= 7;			     \
				       }				     \
				       while(size != 0);                     \
				       *(BYTE*)((BYTE*)(&word) + byte_use - 1) |= 0x01; }


#define size_t  UWORD

#define DATA_CAT_MAX	255
#define DATA_CAT_MAX_LEN        30

#define APP_TYPE_DRV	1
#define APP_TYPE_APP	2
#define APP_TYPE_ALL    0xff

#define USER_MEM_BASE	0x10000000	/* virtual address start for application */
#define INT_MEM_BASE    0x30000000      
#define SYS_MEM_BASE    0x40000000      /* virtual address start for system dynamic memory */

#define BLOCK_SIZE	4096	   /* 4kbyte per block */
#define HALF_BLOCK_SIZE  2048
#define BLOCK_SIZE_MINUS_1 4095
#define PTR_ALIGIN_MASK 0xFFFFF000 /* 4k mask */

#define DM_OS		1
#define DM_USER		2
#define DM_DRV      3

#define FREE_MEM_BLOCK_LIMIT         50   /* at least 200K (50 * 4k) free memory for application, if memory less than 128K, cannot create any more database record */

#define TOTAL_SLOT	1       /* 1 slots in system for RAM card */
#define MAX_BANK_PER_SLOT	5  /* each slot can max contains 5 bank */
#define MEM_INFO_ADDR	0x80000024

#define PC_SIM_MEM_SIZE 81440  /* 64kbyte for simulation of PDA RAM in PC */
#define DATA_CMP_SIZE	30      /* only first 30 bytes of a record with compare when sorting */

#define DBHEADER_SIZE           sizeof(DBHeader)
#define RECHEADER_SIZE		sizeof(RecordHeader)
#define DB_MAX_INFO_LEN		100         /* max length in db header info field */
#define CAT_NAME_LEN		30

#define SORT_TEXT_MODE  (USHORT) 0x8000
#define SORT_BIN_MODE   (USHORT) 0x0000

#define DB_OWNER_NOCHG		(AppID)  0xFFFF
#define DB_VER_NOCHG            (USHORT) 0xFFFF

#define SEEK_BOF        (UWORD) 0xFFFFFFFF
#define SEEK_EOF	(UWORD) 0xFFFFFFFE
#define READ_RELATIVE	(UWORD) 0xFFFFFFFF
#define READ_TO_END	(UWORD) 0xFFFFFFFF

#define MAX_USER_DM_CHUNK        10000
#define MAX_OS_DM_CHUNK          10000

/* constant for MMU */
/* MAT block type */
#define MAT_BLOCK_FREE	    0x0000
#define MAT_BLOCK_PRG_RES   0x1000
#define MAT_BLOCK_DB_REC    0x2000
#define MAT_BLOCK_REC	    0x3000
#define MAT_BLOCK_OSDMA	    0x4000
#define MAT_BLOCK_APPDMA    0x5000
#define MAT_BLOCK_APP_DATA  0x6000  /* bss data block */
#define MAT_BLOCK_INT_DATA  0x7000  /* interrupt routine .bss .data  block */
#define MAT_BLOCK_APP_DATA_MODE1  0x8000  /* bss data block */
#define MAT_BLOCK_MAT_END   0xF000
#define MAT_BLOCK_PG_TABLE  0xE000

/* constant for DM */
#define DB_NO_SORT	    0xFFFF
#define DATA_CHUNK_END	    0x00000000

/* error code for MMU */
#define ERR_MEM_INV_PARAM 	100
#define ERR_MEM_NO_MEM	  	101
#define ERR_MEM_INV_BLOCK	102
#define ERR_MEM_INV_BTYPE	103
#define ERR_MEM_INV_SRC		104
#define ERR_MEM_INV_DEST	105
#define ERR_MEM_INV_CHKSUM	106
#define ERR_MEM_CROSS_LINK	107
#define ERR_MEM_BLOCK_FREE	108
#define ERR_MEM_BOB		109
#define ERR_MEM_EOB		110
#define ERR_MEM_ID_MISS		111
#define ERR_MEM_NO_CON_MEM	112
#define ERR_MEM_INV_TYPE	113
#define ERR_MEM_NO_SPACE	114
#define ERR_MEM_NOT_SET		115
#define ERR_APP_MISS		116
#define ERR_APP_ACTIVE		117

#define ERR_DATA_DB_EXIST	120
#define ERR_DATA_DB_LOCK	121
#define ERR_DATA_NO_SPACE	122
#define ERR_DATA_DB_BUSY	123
#define ERR_DATA_DB_MISS	124
#define ERR_DATA_DB_NOT_OPEN	125
#define ERR_DATA_NO_MEM		126
#define ERR_DATA_INV_RECID	127
#define ERR_DATA_INV_FIELD	128
#define ERR_DATA_NOT_FOUND	129
#define ERR_DATA_INV_PARAM	130
#define ERR_DATA_REC_NOT_OPEN	131
#define ERR_DATA_DB_RO		132
#define ERR_DATA_RECORD_BUSY	133
#define ERR_DATA_EOR		134
#define ERR_DATA_BOR		135
#define ERR_DATA_INV_RECNUM	136
#define ERR_DATA_CAT_NOT_SET	137
#define ERR_DATA_CAT_FULL	138

typedef struct MAT_STRUCT
{
	UWORD id;               /* DBID / Prog ID */
	USHORT next;            /* next block, if linked */
	USHORT attribute;	/* | Type | Fragment | Res | */
} MAT;

typedef struct MATINFO_STRUCT
{
	UWORD base_addr;	/* base address for the MAT */
        SHORT total_entry;     /* total entry in the MAT, excl. BLOCK_MAT_END */
	MAT *mat;
} MatInfoList;


typedef struct MEM_BANK_MAP_STRUCT
{
	UWORD base_addr;
	UWORD bank_size;
	USHORT mat_start_index;
} MemBankMap;


typedef struct DB_HEADER_STRUCT
{
	UWORD length;
	DatabaseID dbid;
	USHORT version;
	AppID owner;
	RecordID next_rec_id;
	UWORD create_date;
	UWORD backup_date;
} DBHeader;

typedef struct REC_HEADER_STRUCT
{
	UWORD size;
	RecordID rec_id;
	UWORD modi_date;
	USHORT total_field;
	BYTE cat;
	BYTE attribute;
} RecordHeader;

/* Structure: SORTABLELNK
   used by DBINFOLNK to keep sort table */
struct SORTABLELNK
{
	USHORT sort_field;		/* field to sort */
	USHORT total_entry;
	UWORD *rec_id;
        UBYTE *cat;
	struct SORTABLELNK *next_table;
};
typedef struct SORTABLELNK SortTableLnk;

/* Structure: APPLNK
   used by DBINFOLNK to record the database open mode of applications */
struct APPLNK
{
	AppID app;			/* Application ID */
	BYTE open_mode;			/* open mode: OPEN_RO, OPEN_RW or OPEN_EX */
	USHORT sort_field;			/* sort field */
	struct APPLNK *next_app;		/* point to next app. or NULL */
};
typedef struct APPLNK AppLnk;

/* Structure: APPINFOLNK
   used by RECINFOLNK to maintain Apps. that open the record */
struct APPINFOLNK
{
	USHORT last_field;
        USHORT last_cache_block;
        AppID  app;
        UWORD  last_cache_offset;
        USHORT last_cache_num_block;
	UWORD  last_pos;
	struct APPINFOLNK *next_app;
};
typedef struct APPINFOLNK AppInfoLnk;

/* Structure: RECINFOLNK
   used by DBINFOLNK to maintain opened records */
struct RECINFOLNK
{
	RecordID rec_id;
	BYTE modi;			/* Modi flag for App. to chk if rec. chg. by another App. */
	struct APPINFOLNK *app_info;		/* information about Apps. that open this record */
	struct RECINFOLNK *next_rec;		/* point to next record or NULL */
};
typedef struct RECINFOLNK RecInfoLnk;

struct CATNAMELNK
{
        UBYTE cat_num;  /* cat number */
        UBYTE name[DATA_CAT_MAX_LEN];  /* cat name */
};
typedef struct CATNAMELNK CatNameLnk;

struct CATINFOLNK
{
        USHORT total_entry;      /* total entry */
        struct CATNAMELNK *catname;  /* cat name table */
};
typedef struct CATINFOLNK CatInfoLnk;

/* structure: DBINFOLNK
   structrure of OpenedDBTable
   use to maintain the opened database */
struct DBINFOLNK
{
	DatabaseID dbid;		/* database ID */
	UWORD  next_record_id;		/* Next record id */
	struct SORTABLELNK *sort_table; /* Sort table */
	struct APPLNK *app_mode;	/* structure about application that use the DB */
	struct RECINFOLNK *record;	/* structure about opened record */
	struct DBINFOLNK *next_db;	/* point to next opened DB or NULL */
    AppID  ex_app;                  /* AppID that open the DB exclusively, = 0x0000 if not opened ex.*/
    struct CATINFOLNK *cat_lnk;     /* Category name and sort table */
};
typedef struct DBINFOLNK DBInfo;

struct DB_CACHE
{
	BYTE enable;
    BYTE valid;
	USHORT field_num;
	DatabaseID dbid;
	RecordID rec_id;
	UWORD field_last_sblock;
	UWORD field_start_sblock;
	UWORD rec_last_sblock;
	UWORD rec_total_block;
	UWORD rec_size;
    UWORD rb_sblock;
    RecordID rb_rec_id;
    RecordHeader *rb_rec_ptr;
};
typedef struct DB_CACHE _DBCache;

typedef struct _DM_FIELD_BUFFER
{
	BYTE *data;
	UWORD byte_read;
} DmFieldBuffer;

typedef struct _DM_FIELD_ARRAY
{
	USHORT	total_entry;
	DmFieldBuffer *data_array;
} DmFieldArray;

/*
struct DB_GETREC_CACHE
{
        DatabaseID dbid;
        RecordID rec_id;
        RecordHeader *rec_ptr;
        UWORD sblock;
};
typedef struct DB_GETREC_CACHE _DBRecCache;
*/
typedef AppLnk* AppLnkPtr;
typedef AppInfoLnk* AppInfoLnkPtr;
typedef RecInfoLnk* RecInfoLnkPtr;
typedef DBInfo* OpenedDBPtr;
typedef SortTableLnk* SortTableLnkPtr;

#ifdef PC_SIM
#ifdef OLD_MEM_MODEL
   extern BYTE sim_mem[PC_SIM_MEM_SIZE];		/* pointer of PC simulated memory */
#else
   extern BYTE sim_mem[4][PC_SIM_MEM_SIZE];		/* pointer of PC simulated memory */
#endif
   extern BYTE DM_MEM[16384];
   extern BYTE OS_MEM[16384];
   #define str_len(x)	strlen(x)
#endif

   extern OpenedDBPtr opendb_table;
   extern DatabaseID next_dbid;
   extern MatInfoList  mat_info[TOTAL_SLOT];
   extern USHORT dmos_first_block;
   extern USHORT dmuser_first_block;
   extern UBYTE dmuser_slot;
   extern UBYTE dmos_slot;
   extern UWORD *user_dynamic_mem_address;        /* start address of dynamic memory pool */
   extern WORD user_dynamic_mem_size;
   extern UWORD *os_dynamic_mem_address;        /* start address of dynamic memory pool */
   extern WORD os_dynamic_mem_size;
   extern UWORD *sys_page_table;
   extern UWORD *app_page_table;
   extern UBYTE mmu_data[DATA_CMP_SIZE];

#ifdef OLD_MEM_MODEL
#define BlockAddr(mat, block)   (mat->base_addr + (((UWORD)(block+1)) << 12))
#define BlockAddr1(mat, block)  (mat.base_addr + (((UWORD)(block+1)) << 12))
#else
UWORD BlockAddr(MatInfoList*, USHORT);
UWORD BlockAddr1(MatInfoList, USHORT);
#endif

#define str_len(x)  strlen(x)

/* prototype */
UWORD _rtm2date32(RTM);
RTM _date322rtm(UWORD);
void MMUInit();
void _valid_ptr(UWORD*, BYTE**, UWORD, RecordHeader*);
void *MemoryGetMatPtr(USHORT blk);
void MemoryGetPageTable(UWORD **sys_table, UWORD **app_table, UWORD **int_table);
void MemoryClrBlockData(MatInfoList*, USHORT);
UWORD MemoryTotalSysMem(UWORD *sys_used);
void MemoryUpdateCheckSum();
Err MemoryMemInfo(USHORT, UWORD*, UWORD*);
Err MemoryBuildMAT(void);
Err MemorySetMATFragment(MatInfoList *mat, USHORT block, BOOLEAN flag);
Err MemoryCheckMAT(MatInfoList *mat);
Err MemoryReadData(MatInfoList *mat, USHORT block, UWORD offset, UWORD num_byte,
		   BYTE *buffer);
Err MemoryShiftData(MatInfoList *mat, USHORT block, UWORD src_pos,
		    UWORD dest_pos, UWORD num_byte);
Err MemoryPrevBlock(MatInfoList *mat, USHORT block, USHORT *prev);
Err MemoryNextBlock(MatInfoList*, USHORT, USHORT*);
Err MemoryLastBlock(MatInfoList *mat, USHORT block, USHORT *last);
Err MemoryNewBlock(MatInfoList *mat, USHORT num_block, UWORD id, BlockType type, USHORT prev_block, USHORT *new_block);
Err MemoryInsertBlock(MatInfoList *mat, USHORT block, USHORT num_block, USHORT *new_block);
Err MemoryReleaseBlock(MatInfoList *mat, USHORT block, BOOLEAN check_link, BOOLEAN check_back_link);
Err MemoryReleaseBlock2(USHORT block, BOOLEAN check_link, BOOLEAN check_back_link);
Err MemoryCopyData(MatInfoList *mat, USHORT src_block, USHORT src_offset,
		   USHORT dest_block, USHORT dest_offset, UWORD num_byte);
Err MemoryMoveBlock(MatInfoList *mat, USHORT src_block, USHORT dest_block);
Err MemoryFindStartBlock(MatInfoList *mat, UWORD dbid, USHORT *block);
Err MemoryGetConBlock(MatInfoList *mat, USHORT num_block, UWORD id, BlockType type, USHORT prev_block, USHORT *new_block);
Err MemoryPageTableAppend(UBYTE type, AppID app, UWORD phy_addr);
Err MemoryDMAInfo(MatInfoList* mat, UBYTE type, AppID app, USHORT *total_block, USHORT *last_block);
void *MemoryDMANew(UBYTE type, USHORT num_block, USHORT *blk_num);
Err MemoryAppStartBlock(AppID app_id, MatInfoList **mat, USHORT *start_block);
Err MemoryShiftData(MatInfoList *mat, USHORT block, UWORD src_pos,
		    UWORD dest_pos, UWORD num_byte);
Err MemoryInstallProg(BYTE *name, UWORD size, UBYTE attr, UBYTE run_spec, UWORD reserved, UWORD res_offset, AppID *appid, UBYTE **data, UWORD **ptable);
Err MemoryClearAppDM(AppID app);
Err MemoryPageTableInit(UWORD **sys_table, UWORD **app_table, UWORD **int_table);
UWORD MemoryDMAStart(AppID app, UBYTE type);
UWORD MemoryMATCheckSum(MatInfoList*);
UWORD MemoryDataCheckSum();
UWORD MemoryBlockFreeSpace(MatInfoList *mat, USHORT block);
USHORT MemoryGroupUsage(MatInfoList *mat, UWORD id);
USHORT MemoryTotalFree();
USHORT MemoryTotalFreeBlock(MatInfoList *mat);
BOOLEAN MemoryGetSpace(MatInfoList*, USHORT, UWORD, BOOLEAN, USHORT*, UWORD*);
BOOLEAN MemoryCheck();
BOOLEAN MemoryGetSpace(MatInfoList *mat, USHORT block, UWORD size, BOOLEAN con,
		   USHORT *new_block, UWORD *offset);
BOOLEAN MemoryResolveBlock(UWORD addr, USHORT *block, USHORT *mat_num);
BlockType MemoryBlockType(MatInfoList *mat, USHORT block);
Err MemoryRegFlashProg(BYTE *name, UWORD prog_address, UWORD prog_size,
   UWORD res_offset, UWORD data_bss_size, UBYTE attr,  UBYTE run_spec, AppID *appid,
    UWORD **ptable);
Err DataReadFieldSysMem(DatabaseID dbid, RecordID rec_id, USHORT field_num, UWORD start_pos, UWORD num_byte, BYTE **buffer, UWORD *byte_read);
BOOLEAN DataFindDB(BYTE*, DatabaseID*);
BOOLEAN DataIsExclusive(DatabaseID, AppID*);
BOOLEAN DataGetDBPtr(DatabaseID, OpenedDBPtr*, AppLnkPtr*);
BOOLEAN DataGetRecordPtr(DatabaseID, RecordID, OpenedDBPtr*, RecInfoLnkPtr*, AppInfoLnkPtr*, USHORT*, UWORD*);
BOOLEAN DataFreeSortTable(DatabaseID, USHORT);
BOOLEAN DataIsRecordChange(DatabaseID, RecordID, BYTE *);
BOOLEAN DataIsRecordOpen(DatabaseID dbid, RecordID rec_id, USHORT *last_read_field,
			  UWORD *read_pointer);
BOOLEAN DataGetRecordPtr(DatabaseID dbid, RecordID rec_id, OpenedDBPtr *db_ptr,
		     RecInfoLnkPtr *rec_ptr, AppInfoLnkPtr *app_ptr, USHORT *last_field, UWORD *read_pointer);
BOOLEAN DataIsRecordChange(DatabaseID dbid, RecordID rec_id, BYTE *modi);
BOOLEAN DataGetDBPtr(DatabaseID dbid, OpenedDBPtr *dbinfo_ptr, AppLnkPtr *app_ptr);
Err DataReadBDataUp(UWORD sblock, UWORD offset, UWORD num_byte, BYTE *buffer, BYTE **read_ptr, BYTE **write_ptr, UWORD *last_sblock);
Err DataNewDB(BYTE*, USHORT, BYTE*, DatabaseID*);
Err DataOpenDB(DatabaseID, USHORT, DBOpenMode);
Err DataBuildSortTable(UWORD, USHORT, SortTableLnkPtr*, RecordID*);
Err DataNewRecord(DatabaseID, BYTE, USHORT, RecordID*);
Err DataRecordInfo(DatabaseID dbid, RecordID rec_id, UWORD *rec_size, UBYTE *cat,
		   Attribute *secret, Attribute *lock, RTM *modi_date);
Err DataRecIDtoNum(DatabaseID, RecordID, UWORD*);
Err DataSortData(DatabaseID, RecordID, UBYTE cat, SortTableLnkPtr*, BOOLEAN, UWORD*);
Err DataTotalRecord(DatabaseID, UWORD *);
Err DataOpenRecord(DatabaseID, UWORD, RecordID*, BYTE*);
Err DataRecordBlock(UWORD, RecordID, UWORD*, RecordHeader**);
Err DataSetRecordAttribute(DatabaseID, RecordID, Attribute, Attribute, BYTE);
Err DataCloseRecord(DatabaseID, RecordID);
Err DataWriteField(DatabaseID, RecordID, USHORT, UWORD, BYTE*);
Err DataFieldInfo(UWORD, RecordID, USHORT, UWORD*, UWORD*, UWORD*, USHORT*, UWORD*, BOOLEAN*);
Err DataOpenNextRecord(DatabaseID, RecordID, BOOLEAN, RecordID*, BYTE*);
Err DataOpenPrevRecord(DatabaseID, RecordID, BOOLEAN, RecordID*, BYTE*);
Err DataWriteBData(UWORD, UWORD, UWORD, BYTE*);
Err DataResizeField(DatabaseID, RecordID, USHORT,UWORD);
Err DataResizeField2(DatabaseID, RecordID, USHORT,UWORD);
Err DataWriteField(DatabaseID, RecordID, USHORT, UWORD, BYTE*);
Err DataReadBData(UWORD, UWORD, UWORD, BYTE*, BYTE**, BYTE**, UWORD *);
Err DataCopyBData(UWORD*, UWORD, UWORD*, UWORD, UWORD, RecordHeader*, BYTE**, BYTE**);
Err DataGetField(DatabaseID, RecordID, USHORT, BYTE**, UWORD*);
Err DataUpdateSortTable(DatabaseID, RecordID, USHORT);
Err DataNumtoRecID(DatabaseID, UWORD, RecordID*);
Err DataDBInfo(DatabaseID, USHORT*, AppID*, RTM*, RTM*, BYTE*, BYTE*);
Err DataSetDBInfo(DatabaseID, USHORT, AppID, RTM*);
Err DataDBSize(DatabaseID, USHORT*, UWORD*);
Err DataTotalField(DatabaseID, RecordID, USHORT*);
Err DataTotalRecord(DatabaseID dbid, UWORD *total_rec);
Err DataCloseDB(DatabaseID);
Err DataDeleteDB(DatabaseID);
Err DataFieldSize(DatabaseID, RecordID, USHORT, UWORD*);
Err DataSeekField(DatabaseID, RecordID, USHORT, WORD);
Err DataReadField(DatabaseID, RecordID, USHORT, UWORD, UWORD, BYTE**, UWORD*);
Err DataFindRecord(DatabaseID, USHORT, UWORD, BYTE*, RecordID*);
Err DataMoveCat(DatabaseID, UBYTE, UBYTE);
Err DataDeleteRecord(DatabaseID, RecordID, BOOLEAN);
Err DataDeleteRecordAction(UWORD, RecordHeader*, BOOLEAN);
Err DataCategoryNextFree(DatabaseID dbid, UBYTE *next_free);
Err DataCategoryName(DatabaseID , UBYTE , BYTE*);
Err DataCategorySetName(DatabaseID , UBYTE , BYTE*);
Err DataNumtoRecID(DatabaseID dbid, UWORD rec_num, RecordID *rec_id);
Err DataRecIDtoNum(DatabaseID dbid, RecordID rec_id, UWORD *rec_num);
Err DataUpdateField(DatabaseID dbid, RecordID rec_id, USHORT field_num,
		       UWORD num_byte, BYTE *buffer);
Err DataGetDBSortField(DatabaseID, USHORT*);
Err DataNewRecordWithID(DatabaseID dbid, RecordID rec_id, BYTE cat, USHORT num_field);
Err DataRecordInfo(DatabaseID dbid, RecordID rec_id, UWORD *rec_size, UBYTE *cat,
		   Attribute *secret, Attribute *lock, RTM *modi_date);
UBYTE *DataRecordData(UWORD, RecordID, USHORT);
UBYTE DataCategorySort(DatabaseID dbid, UBYTE cat[]);
BOOLEAN DataIsDBOpen(DatabaseID dbid, UBYTE *open_mode, USHORT *sort_field);
void DataUpdateModiDate(RecordHeader *ptr);
Err DataReasignRecID(DatabaseID dbid, UWORD offset, RecordID exclude_recid);
Err DataQuickFieldInfo(DatabaseID dbid, UWORD sblock, RecordID rec_id, USHORT field, UWORD *size, UWORD *start_sblock,
	                   UWORD *first_offset, USHORT *num_block, UWORD *last_size, BOOLEAN *frag);
	                   
Err 	DataGetAllField(DatabaseID dbid, RecordID rec_id, DmFieldArray *field_array);
Err 	DataReadSeqField(RecordHeader **rec_ptr, UWORD *sblock, UWORD *rec_seg_offset, DmFieldBuffer *field_array);
void    DataFreeFieldArray(DmFieldArray field_array);                    
#endif
