'
'************* ADT Global Variable Declaration ************* 
'
'note: These Declarations must be included for any program 
'      using ADT.
'
'Lvo's:
'
   Global _LVOALLOCMEM,_LVOFREEMEM
'
'Defines:
'
   Global MEMF_ANY,MEMF_PUBLIC,MEMF_CHIP,MEMF_FAST,MEMF_CLEAR,NULL
'
'Types:
'
   Global WORD,UWORD,BYTE,UBYTE,LONG,ULONG,APTR
'
'************* ADT Data Type Global Declaration *************  
'
'note:  You Must declare your Data Type Def'n (ie. _LIST_STRUCT(4) ) 
'       Global, and it is Strongly Urged that you declare a Global 
'       Variable that is equal to the Varptr(of you data type def'n) 
'       ie. _LIST_TYPE = Varptr( _LIST_STRUCT(0) ).... It is Also
'       suggested that you make Defines (globals) for accessing the
'       fields inside a structure (data type), this will make it your
'       code more readable/less prone to errors and easier to edit your
'       datatype in the future.
'
' Place Your Definitions here... 
'
'ie. Dim _LIST_STRUCT(4) --> Global _LIST_STRUCT(),_LIST_TYPE,...
'

'
' List Definition... 
'
   Dim _LIST_STRUCT(4)
   Global _LIST_STRUCT(),_LIST_TYPE
   ' Defines for accessing the fields in the structure... 
   Global X_FIELD,Y_FIELD,_NEXT_FIELD

   Dim _LIST_INFO_STRUCT(4)
   Global _LIST_INFO_STRUCT(),_LIST_INFO_TYPE
   Global NUM_NODES_FIELD,HEAD_FIELD,TAIL_FIELD


   _INITIALIZE_ADTS

'
'****************  Abstract Data Type Routines  **************** 
'
' Put your ADT Definitions in here...
'
Procedure _ADT_DEFS
'
' Your ADT Definitions... ie. STRUCT Def's and Global Defs should
' go in here...
'

'
' struct List {        -->  _LIST_STRUCT[0] = Total Struct Size = 2*UWORD + List = 8 bytes 
'                           _LIST_STRUCT[1] = # of Fields = 3
'        UWORD x;           _LIST_STRUCT[2] = Offset to Fist Element   (x)  = 0    
'        UWORD y;           _LIST_STRUCT[3] = Offset to Second Element (y)  = UWORD   = 2    
'        List *next_node;   _LIST_STRUCT[4] = Offset to Third Element(List*)= 2*UWORD = 4  
'
'    } 
'
'    x = Field #1  //  y = Field #2  //  next_node = Field #3  
'
'
   '
   ' Set up the List Struct...  
   '
   _LIST_STRUCT(0)=2*UWORD+APTR
   _LIST_STRUCT(1)=3
   _LIST_STRUCT(2)=0 : Rem         x
   _LIST_STRUCT(3)=UWORD : Rem     y
   _LIST_STRUCT(4)=2*UWORD : Rem   next 

   _LIST_TYPE=Varptr(_LIST_STRUCT(0)) : Rem This Sets the List Type....

   '
   ' this is just a easy way to remeber where the fields are... also good 
   ' incase you change your struct definition...  
   '
   X_FIELD=1 : Y_FIELD=2 : _NEXT_FIELD=3


'
'   struct List_Info {       -->  _LIST_INFO_STRUCT(0) = UWORD + 2*APTR = 10 bytes 
'                                 _LIST_INFO_STRUCT(1) = 3 
'         UWORD # of nodes;       _LIST_INFO_STRUCT(2) = 0 
'         List *head_of_list;     _LIST_INFO_STRUCT(3) = UWORD = 2 
'         List *tail_of_list;     _LIST_INFO_STRUCT(4) = UWORD + APTR = 6
'
'    } 
'

   'set up the struct...

    _LIST_INFO_STRUCT(0)=UWORD+2*APTR
    _LIST_INFO_STRUCT(1)=3
    _LIST_INFO_STRUCT(2)=0
    _LIST_INFO_STRUCT(3)=UWORD
    _LIST_INFO_STRUCT(4)=UWORD+APTR

    _LIST_INFO_TYPE=Varptr(_LIST_INFO_STRUCT(0))

    NUM_NODES_FIELD=1 : HEAD_FIELD=2 : TAIL_FIELD=3

'
'
End Proc
'
' These Are the Routines that you are to use to work with  
' structures...
'
Procedure _CREATE[_DATA_TYPE,_MEMORY_TYPE]
'
'  Description:  Will Allocate the Mem Needed for a new instance   
'                of a Data Type. 
'
'  Parameters:   _DATA_TYPE = Must Be a Pointer to A Data Type 
'                             Definition.  eg. if your data type 
'                             definition (you know the Array) is 
'                             _LIST_ADT() then you would pass  
'                             Varptr(_LIST_ADT(0)) into the _DATA_TYPE 
'                             parameter.  When Making a new Data Type  
'                             you should always create a new global that 
'                             equals this and ends with _TYPE.  For example  
'                             Global _LIST_TYPE : _LIST_TYPE=Varptr(_LIST_ADT(0))  
'
'              _MEMORY_TYPE = This should be equal to the type of memory that
'                             should be allocated for this DataType... see the 
'                             MEMF_* globals.. note: multiple selections are 
'                             made by ORing or Adding Flags togther for  
'                             example to use CHIP memory and have it cleared 
'                             (to 0's) you would use: MEMF_CHIP+MEMF_CLEAR.  
'
'  Returns:    _PTR = this will point to newly allocated block of memory 
'                     (will equal NULL ie. 0 on Error... meaning there is
'                      not enough memory to meet your request )
'
'  Side Effects: Memory is allocated... it must be Freed By you... using 
'                _FREEMEM[]... 
'
'  
    _ALLOCMEM[Leek(_DATA_TYPE),_MEMORY_TYPE]

    _PTR=Param

'
End Proc[_PTR]
Procedure _DESTROY[_DATA_TYPE,_PTR]
'
' basically just a wrapper for _FREEMEM[]
'

   _FREEMEM[_PTR,Leek(_DATA_TYPE)]

'
End Proc
Procedure _SET_FIELD[_DATA_TYPE,_PTR,_FIELD,_VAL]
'
'  Description:  This will set a field inside a data type.  For example
'                if you had a Linked list type then: 
'                   _SET_FIELD[_LIST_TYPE,list,X_FIELD,20]  --> list->x = 20 
'                As you can see you must also specify what data type 
'                you are using so that it knows how to use the generic or
'                void _PTR... it is Strongly Suggested that when creating a
'                new Data Type you define this Function for that data type 
'                see Example Linked List Datatype --> "_SET_LIST_FIELD"
'
'  Parameters:   _DATA_TYPE = see _CREATE[]
'                _PTR       = pointer to the instance of your data type..
'                             (returned form _CREATE[])
'                _FIELD     = the Field that you are accesing in the structure 
'                             or data type... they are counted in order of 
'                             appearance starting from 1.
'                _VAL       = the value you are setting the field to equal to. 
'
'  Returns:      nothing.
'
'
   If(_DATA_TYPE<>0 and _PTR<>0)

      _SIZE_OF_FIELD[_DATA_TYPE,_FIELD] : _OFFSET_TO_FIELD=Leek(_DATA_TYPE+(_FIELD+1)*4)

      If Param=BYTE
                              Poke _PTR+_OFFSET_TO_FIELD,_VAL
      Else 
            If Param=WORD
                              Doke _PTR+_OFFSET_TO_FIELD,_VAL
            Else 

               If Param=APTR
                              Loke _PTR+_OFFSET_TO_FIELD,_VAL
               End If 

            End If 

      End If 

   End If 
'
End Proc
Procedure _GET_FIELD[_DATA_TYPE,_PTR,_FIELD]
'
'  Description:  This will get a field inside a data type.  For example
'                if you had a Linked list type then: 
'                   _GET_FIELD[_LIST_TYPE,list,X_FIELD]  --> val = list->x   
'                As you can see you must also specify what data type 
'                you are using so that it knows how to use the generic or
'                void _PTR... it is Strongly Suggested that when creating a
'                new Data Type you define this Function for that data type 
'                see Example Linked List Datatype --> "_GET_LIST_FIELD"
'
'  Parameters:   _DATA_TYPE = see _CREATE[]
'                _PTR       = pointer to the instance of your data type..
'                             (returned form _CREATE[])
'                _FIELD     = the Field that you are accesing in the structure 
'                             or data type... they are counted in order of 
'                             appearance starting from 1.
'
'
'  Returns:      _VAL       = the value you are getting..  
'
'
   If(_DATA_TYPE<>0 and _PTR<>0)

      _SIZE_OF_FIELD[_DATA_TYPE,_FIELD] : _OFFSET_TO_FIELD=Leek(_DATA_TYPE+(_FIELD+1)*4)

      If Param=BYTE
                              _VAL=Peek(_PTR+_OFFSET_TO_FIELD)
      Else 
            If Param=WORD
                              _VAL=Deek(_PTR+_OFFSET_TO_FIELD)
            Else 

               If Param=APTR
                              _VAL=Leek(_PTR+_OFFSET_TO_FIELD)
               End If 

            End If 

      End If 

   End If 
'
End Proc[_VAL]
'
' Below Are Routines that Are Used by the ADT Procedures...
'
Procedure _INITIALIZE_ADTS
'
'  This will Set Up and Intialize Everything to do with the ADT... 
'
   ' This Procedure Initializes all The ADT Global Variable Declaration 
   ' vars...  
   _LVOS_AND_DEFINES

   ' This Procedure is Where you Should Put your Data Type Def's... 
   _ADT_DEFS

'
End Proc
Procedure _LVOS_AND_DEFINES
'
' Set Up the Globals...
'

   _LVOALLOCMEM=-198 : _LVOFREEMEM=-210
   _LVOOPENLIB=-552 : _LVOCLOSELIB=-414

   '/* mem requirements for AllocMem() */'  
   'Add (or OR) them together to get 2 or more options
   MEMF_ANY=0
   MEMF_PUBLIC=1 : Rem ** means mean block can't move once alloced
   MEMF_CHIP=2
   MEMF_FAST=4
   MEMF_CLEAR=65536
   '
   'type sizes in bytes 
   '
   WORD=2 : UWORD=2 : BYTE=1 : UBYTE=1 : LONG=4 : ULONG=4 : APTR=4 : NULL=0
'
End Proc
Procedure _SIZE_OF_FIELD[_DATA_TYPE,_FIELD]
'
'  Figures out the Size of a Data Filed... 1,2,or4 bytes.... 
'
'  NOTE: _FIELD + 1 = to the spot in the list struct where the offset
'                     for this field is stored.. ie: spots 0 & 1 are used
'                     for control info.. so FIELD #1 is actually the 2nd 
'                     Element in the Struct Array. 
'
'
'  _DATA_TYPE --> points to Structure Array Definition... eg. _LIST_STRUCT 
'  
'                  this makes it a generic routine that will work for any
'                  data structure....
'

  'if(_field<> the last field in the struct )
   If(_FIELD<>Leek(_DATA_TYPE+1*4))

      'size = (the offset of the next field) - (the offset to current field) 
       _SIZE=Leek(_DATA_TYPE+((_FIELD+1)+1)*4)-Leek(_DATA_TYPE+(_FIELD+1)*4)

   Else 

      'size = (the total size of the struct) - (the offset to current field) 
      _SIZE=Leek(_DATA_TYPE+0*4)-Leek(_DATA_TYPE+(_FIELD+1)*4)

   End If 

'
End Proc[_SIZE]
Procedure _ALLOCMEM[BYTESIZE,REQUIREMENTS]
'
   Dreg(0)=BYTESIZE : Dreg(1)=REQUIREMENTS

   _PTR=Execall(_LVOALLOCMEM)

'
End Proc[_PTR]
Procedure _FREEMEM[MEMORY_PTR,BYTESIZE]
'
   Areg(1)=MEMORY_PTR : Dreg(0)=BYTESIZE

   RESULT=Execall(_LVOFREEMEM)

'
End Proc[RESULT]
'
'**************************************************************

