; =============================================================================
;
; Litos - Hash list
;
; =============================================================================
CODE_SECTION 32
; ------------- Macro - initialized hash list head
%define HASHHEAD dd 0
; ------------- Macro - initialize hash list head (%1 = pointer to head)
%macro HASHINIT 1
and dword [%1+HASHH_First],byte 0 ; no first entry
%endmacro
; ------------- Macro - initialize hash list array
; %1 = pointer to first hash list head, %2 = number of hash list heads
; It uses registers EAX, EDI and ECX. Direction flag must be up (CLD).
%macro HARRAYINIT 2
lea edi,%1 ; EDI <- pointer to first head
mov ecx,%2 ; ECX <- number of hash list heads
xor eax,eax ; EAX <- 0
rep stosd ; initialize hash list array
%endmacro
; -------------
; -----------------------------------------------------------------------------
; Initialize hash list head
; -----------------------------------------------------------------------------
; INPUT: EBX = hash list head
; -----------------------------------------------------------------------------
HashInit: HASHINIT ebx ; initialize hash list head
ret
; -----------------------------------------------------------------------------
; Check if hash list is empty
; -----------------------------------------------------------------------------
; INPUT: EBX = hash list head
; OUTPUT: ZY = hash list is empty
; -----------------------------------------------------------------------------
HashIsEmpty: cmp dword [ebx+HASHH_First],byte NULL ; is list empty?
ret
; -----------------------------------------------------------------------------
; Initialize node
; -----------------------------------------------------------------------------
; INPUT: EAX = hash list entry
; -----------------------------------------------------------------------------
HLNInit: mov dword [eax+HASHE_Next],NULL ; no next node
mov dword [eax+HASHE_Prev],NULL; no previous next pointer
ret
; -----------------------------------------------------------------------------
; Check if current node is hashed (=precede previous node)
; -----------------------------------------------------------------------------
; INPUT: EAX = current hash list entry
; OUTPUT: ZY = is not hashed, no previous next pointer
; -----------------------------------------------------------------------------
HLNIsHashed: cmp dword [eax+HASHE_Prev],byte NULL ; check prev.pointer
ret
; -----------------------------------------------------------------------------
; Add new entry to begin of hash list
; -----------------------------------------------------------------------------
; INPUT: EAX = new hash list entry
; EBX = hash list head
; -----------------------------------------------------------------------------
HLNAddList: push ecx ; push ECX
mov ecx,[ebx+HASHH_First] ; ECX <- first entry
mov [eax+HASHE_Next],ecx ; link first entry to new one
mov [eax+HASHE_Prev],ebx ; set list as previous pointer
jecxz HLNAddList2 ; no first node
mov [ecx+HASHE_Prev],eax ; link new entry to next entry
HLNAddList2: mov [ebx+HASHH_First],eax ; set new entry as first entry
pop ecx ; pop ECX
ret
; -----------------------------------------------------------------------------
; Add new entry after current one
; -----------------------------------------------------------------------------
; INPUT: EAX = new hash list entry
; EBX = current hash list entry
; -----------------------------------------------------------------------------
HLNAddAfter: push ecx ; push ECX
mov ecx,[ebx+HASHE_Next] ; ECX <- next entry
mov [ebx+HASHE_Next],eax ; link new entry to current one
mov [eax+HASHE_Next],ecx ; link next entry to new one
mov [eax+HASHE_Prev],ebx ; link current to new one
jecxz HLNAddAfter2 ; no next node
mov [ecx+HASHE_Prev],eax ; link new entry to next one
HLNAddAfter2: pop ecx ; pop ECX
ret
; -----------------------------------------------------------------------------
; Add new entry before current one
; -----------------------------------------------------------------------------
; INPUT: EAX = new hash list entry
; EBX = current hash list entry
; -----------------------------------------------------------------------------
HLNAddBefore: push ecx ; push ECX
mov ecx,[ebx+HASHE_Prev] ; ECX <- previous next pointer
mov [eax+HASHE_Next],ebx ; link current node to new one
mov [eax+HASHE_Prev],ecx; link previous node to new one
mov [ebx+HASHE_Prev],eax ; link new node to current one
mov [ecx],eax ; link new node to previous pointer
pop ecx ; pop ECX
ret
; -----------------------------------------------------------------------------
; Delete entry from hash list
; -----------------------------------------------------------------------------
; INPUT: EAX = node
; -----------------------------------------------------------------------------
HLNDelete: push ebx ; push EBX
push ecx ; push ECX
mov ecx,[eax+HASHE_Next] ; ECX <- next node
mov ebx,[eax+HASHE_Prev] ; EBX <- previous next pointer
mov [ebx],ecx ; link next node to previous pointer
jecxz HLNDelete2 ; no next node
mov [ecx+HASHE_Prev],ebx ; link previous pointer to next
HLNDelete2: pop ecx ; pop ECX
pop ebx ; pop EBX
ret
; -----------------------------------------------------------------------------
; Replace old entry by new one
; -----------------------------------------------------------------------------
; INPUT: EAX = new node
; EBX = old node
; -----------------------------------------------------------------------------
HLNReplace: push ecx ; push ECX
push edx ; push EDX
mov ecx,[ebx+HASHE_Next] ; ECX <- next node
mov edx,[ebx+HASHE_Prev] ; EDX <- previous next pointer
mov [eax+HASHE_Next],ecx ; link next node to new one
mov [eax+HASHE_Prev],edx ; link previous pointer to new
jecxz HLNReplace2 ; no next node
mov [ecx+HASHE_Prev],eax ; link new node to next node
HLNReplace2: mov [edx],eax ; link new node to previous pointer
pop edx ; pop EDX
pop ecx ; pop ECX
ret
|