;****************************************************************************
;* Copyright 1991 MBARI                                                     *
;****************************************************************************
;* Summary  : List management routines for OASIS Microcontroller            *
;* Filename : list.s                                                        *
;* Author   : Robert Herlien                                                *
;* Project  : OASIS Mooring Controller                                      *
;* Created  : 11/10/91                                                      *
;****************************************************************************
;* Modification History:                                                    *
;* $Header: /usr/tiburon/.cvsroot/micro/lib/list.s,v 1.1.1.1 1997/05/02 17:15:59 pean Exp $
;* $Log: list.s,v $
;* Revision 1.1.1.1  1997/05/02 17:15:59  pean
;* Initial release of the microcontroller software after Tiburon
;* Moolpool Dive to test IView, Lapboxes, modified Power can
;* GF/5V using bus capacitance mode.
;*
;Revision 1.1  92/05/14  09:21:08  09:21:08  pean (Andrew Pearce 408-647-3746)
;Initial revision
;
;*
;****************************************************************************
;
$TITLE("List Management Routines")
;
LIST        MODULE
;
;*****************************************************************************
;
PUBLIC  list_init       ;Init linked list
PUBLIC  list_head       ;Get first node off linked list
PUBLIC  list_add        ;Add node to end of linked list
PUBLIC  list_get        ;Get given node from linked list

;******************** 80C196KB Internal Register Map. ************************
;
; There are 256 registers mapped at addresses 0000H to 0100H. Registers from
; address 0000H to 0019H are pre-defined special purpose registers (SFR).
; Registers from 001AH to 0100H are user definable.
;----------------------------------------------------------------------------
R0          EQU 00H:WORD        ;Zero register as word
SP          EQU 18H:WORD        ;Stack pointer
plmreg      EQU 1CH:WORD        ;PLMREG is return register
tmp2        EQU plmreg+2:WORD   ;Scratch registers
tmp4        EQU plmreg+4:WORD
tmp6        EQU plmreg+6:WORD

;******************** List Head Structure *********************************
;
HEAD        EQU 0       ;Pointer to first item on list
TAIL        EQU 2       ;Pointer to last item on list

;******************** Node Structure *********************************
;
NEXT        EQU 0       ;Pointer to next item on list
PREV        EQU 2       ;Pointer to previous item on list

            CSEG

;*****************************************************************************
; LIST_INIT - Initialize Linked List
;
; Void list_init( LstHead *lp );
;
list_init:
    ld  plmreg, 2[SP]
    st  R0, HEAD[plmreg]
    st  R0, TAIL[plmreg]
    ret

;*****************************************************************************
; LIST_HEAD - Delete and return head of linked list
;
; Node *list_head( LstHead *lp );
;
list_head:
    ld  tmp2, 2[SP]
    ld  plmreg, HEAD[tmp2]
    cmp plmreg, R0
    je  lhret

    ld  tmp4, NEXT[plmreg]
    st  tmp4, HEAD[tmp2]
    cmp tmp4, R0
    je  lh2
    st  R0, PREV[tmp4]
    ret
lh2:
    st  R0, TAIL[tmp2]
lhret:
    ret

;*****************************************************************************
; LIST_ADD - Add a node to the end of a linked list
;
; Void *list_add( LstHead *lp, Node *np );
;
list_add:
    ld  tmp2, 2[SP]
    ld  plmreg, 4[SP]
    ld  tmp4, TAIL[tmp2]
    st  R0, NEXT[plmreg]
    st  tmp4, PREV[plmreg]
    st  plmreg, TAIL[tmp2]
    cmp tmp4, R0
    je  la1
    st  plmreg, NEXT[tmp4]
    ret
la1:
    st  plmreg, HEAD[tmp2]
    ret

;*****************************************************************************
; LIST_GET - Delete and return a given node from linked list
;
; Node *list_get( LstHead *lp, Node *np );
;
list_get:
    ld  tmp2, 2[SP]
    ld  plmreg, 4[SP]
lg1:
    ld  tmp4, NEXT[plmreg]
    ld  tmp6, PREV[plmreg]
    cmp tmp6, R0
    je  lg2
    st  tmp4, NEXT[tmp6]
    sjmp    lg3
lg2:
    st  tmp4, HEAD[tmp2]
lg3:
    cmp tmp4, R0
    je  lg4
    st  tmp6, PREV[tmp4]
    ret
lg4:
    st  tmp6, TAIL[tmp2]
    ret

    END
