home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 13.ddi / QUEUE.ZIP / LIST.ASM next >
Encoding:
Assembly Source File  |  1992-06-10  |  5.6 KB  |  222 lines

  1. ;--------------------------------
  2. ;-- Define Linked-List objects --
  3. ;--------------------------------
  4.  
  5. MODEL SMALL
  6. LOCALS
  7.  
  8. ;** Define Linked-List object **
  9.  
  10. INCLUDE list.aso
  11. INCLUDE node.aso
  12.  
  13. ;** Create instance of Linked-List virtual method table **
  14.  
  15. DATASEG
  16.  
  17. TBLINST
  18.  
  19. ;** Define some macros for use by the methods **
  20. ;** These are used by the methods for storing and loading double registers **
  21.  
  22. ;Load two 16-bit registers from an address in specified segment
  23. loadptr macro r2,r1, addr
  24.     mov r2,word ptr [addr+2]
  25.     mov r1,word ptr [addr]
  26.     endm
  27.  
  28. ;Store two 16-bit registers to an address in specified segment
  29. storeptr macro addr, r2,r1
  30.     mov word ptr [addr+2],r2
  31.     mov word ptr [addr],r1
  32.     endm
  33.  
  34. ;Check to see if two 16-bit registers are both set to 0
  35. ;(r1 cannot be ax)
  36. isnullptr macro r2,r1
  37.     ifdifi <r1>,<ax>
  38.       mov ax,r2
  39.       or ax,r1
  40.     else
  41.       push bx
  42.       push r2
  43.       pop bx
  44.       or bx,ax
  45.       pop bx
  46.     endif
  47.     endm
  48.  
  49. ;** Linked-List methods **
  50.  
  51. CODESEG
  52.  
  53. ;Construct a Linked-List object
  54. ;This is the method "list|construct"
  55. ;This must be a static method.
  56. ;Returns DX:AX pointing to linked-list object, null if none.
  57. ;Object is allocated but not yet initialized.
  58. list_construct PROC PASCAL FAR
  59. USES ds
  60.     ;-- Allocate the Linked-List object --
  61.     mov bx,list_size
  62.     mov ah,48h
  63.     int 21h
  64.     jc @@err
  65.     mov dx,ax
  66.     sub ax,ax
  67.     ret
  68. @@err:    sub dx,dx
  69.     sub ax,ax
  70.     ret
  71. ENDP
  72.  
  73.  
  74. ;Destroy a Linked-List object.
  75. ;This is the method "list|destroy"
  76. list_destroy PROC PASCAL FAR
  77. ARG @@list:dword
  78.     ;-- deallocate memory for list --
  79.     mov es,word ptr @@list+2
  80.     mov ah,49h
  81.     int 21h
  82.     ret
  83. ENDP
  84.  
  85. ;Initialize a Linked-List object.
  86. ;This is the method "list|init"
  87. ;This must be a static method!
  88. list_init PROC PASCAL FAR
  89. ARG @@list:dword
  90. USES ds,bx
  91.     lds bx,@@list
  92.     ;-- Initialize any virtual method table for the object at ds:bx --
  93.     TBLINIT ds:bx
  94.     ;-- Initialize the object's data --
  95.     sub ax,ax
  96.     storeptr ds:bx.list_head, ax,ax
  97.     storeptr ds:bx.list_tail, ax,ax
  98.     ret
  99. ENDP
  100.  
  101. ;Deinitialize a Linked-List object.
  102. ;This is the method "list|deinit"
  103. list_deinit PROC PASCAL FAR
  104. ARG @@list:dword
  105.     ;does nothing.
  106.     ret
  107. ENDP
  108.  
  109.  
  110. ;Insert a node into the Linked-List object.
  111. ;This is the method "list|insert".
  112. list_insert PROC PASCAL NEAR
  113. ARG    @@list:dword,\            ;Pointer to list object
  114.     @@new:dword,\            ;Pointer to new node to insert
  115.     @@old:dword            ;Pointer to node to insert before
  116. USES ds,es,bx,cx,dx,si,di
  117.  
  118.     les di,@@new                ;es:di = new
  119.     lds si,@@old                ;ds:si = old
  120.     ;-- First, adjust backward links --
  121.     isnullptr ds,si                ;old = null?
  122.     jz @@a
  123.     ;-- there is an old node to insert before
  124.     loadptr dx,bx,ds:si.node_prev        ;prev <- old.prev
  125.     storeptr ds:si.node_prev,es,di        ;old.prev <- new
  126.     jmp short @@b
  127. @@a:    ;-- there is no old node to insert before - insert at end
  128.     push ds si                ;(save old)
  129.      lds si,@@list                ;(get list object)
  130.      loadptr dx,bx,ds:si.list_tail        ;prev <- tail
  131.      storeptr ds:si.list_tail,es,di        ;tail <- new
  132.     pop si ds                ;(recall old)
  133. @@b:    ;-- Next, adjust forward links --
  134.     isnullptr dx,bx                ;prev = null?
  135.     jz @@c
  136.     ;-- there is a prev node to insert after
  137.     push ds                    ;(save old)
  138.      mov ds,dx                ;(ds:bx = prev)
  139.      storeptr ds:bx.node_next,es,di        ;prev.next <- new
  140.     pop ds                    ;(recall old)
  141.     jmp short @@d
  142. @@c:    ;-- there is no prev node to insert after - insert at start
  143.     push ds si                ;(save old)
  144.      lds si,@@list                ;(ds:si = list object)
  145.      storeptr ds:si.list_head,es,di        ;head <- new
  146.     pop si ds                ;(recall old)
  147. @@d:    ;-- Finally set pointers in this node
  148.     storeptr es:di.node_prev,dx,bx        ;new.prev <- prev
  149.     storeptr es:di.node_next,ds,si        ;new.next <- old
  150.     ret
  151. ENDP
  152.  
  153. ;Append a node at the end of a Linked-List object.
  154. ;This is the virtual method "list|append".
  155. list_append PROC PASCAL NEAR
  156. ARG    @@list:dword,\
  157.     @@new:dword
  158. USES ds,bx,es,di
  159.     mov ax,@Data
  160.     mov ds,ax
  161.     les di,@@list
  162.     sub ax,ax
  163.     call es:di method list:insert uses ds:bx pascal,es di,@@new,ax ax
  164.     ret
  165. ENDP
  166.  
  167. ;Remove a node from a Linked-List object.
  168. ;This is the virtual method "list|remove"
  169. ;This simply unlinks the node from the list; the node itself must be
  170. ;delete by calling the node|deinit method.
  171. list_delete PROC PASCAL NEAR
  172. ARG    @@list:dword,\            ;pointer to linked-list object
  173.     @@node:dword            ;pointer to node to delete
  174. USES ds,es,si,di
  175.  
  176.     lds si,@@node            ;ds:si = node
  177.     les di,ds:[si.node_prev]    ;es:di = prev
  178.     lds si,ds:[si.node_next]    ;ds:si = next
  179.     ;-- First change next node's previous pointer
  180.     isnullptr ds,si            ;next = 0?
  181.     jz @@a                ; yes - skip
  182.     storeptr ds:si.node_prev,es,di    ;  no - next.prev <- prev
  183.     jmp short @@b            ;    and skip...
  184. @@a:    push ds si            ;(save next)
  185.     lds si,@@list            ;(list object)
  186.     storeptr ds:si.list_tail,es,di    ;tail <- prev
  187.     pop si ds            ;(recall next)
  188. @@b:    ;-- Now change previous node's next pointer
  189.     isnullptr es,di            ;prev = 0?
  190.     jz @@c                ; yes - skip
  191.     storeptr es:di.node_next,ds,si    ;  no - prev.next <- next
  192.     jmp short @@d            ;    and done...
  193. @@c:    lds di,@@list            ;(list object)
  194.     storeptr ds:di.list_head,ds,si    ;head <- next
  195. @@d:    ret
  196. ENDP
  197.  
  198. ;Return a pointer to the first node in the list
  199. ;This is the virtual method "list|first"
  200. ;Returns DX:AX pointing to first node in list (null if none)
  201. list_first PROC PASCAL NEAR
  202. ARG    @@list:dword            ;pointer to linked-list object
  203. USES ds,si
  204.     lds si,@@list
  205.     loadptr dx,ax, ds:si.list_head
  206.     ret
  207. ENDP
  208.  
  209. ;Return a pointer to the last node in the list
  210. ;This is the virtual method "list|last"
  211. ;Pass:    pointer to object
  212. ;Ret:    DX:AX points to last node in list (null if none)
  213. list_last PROC PASCAL NEAR
  214. ARG    @@list:dword            ;pointer to linked-list object
  215. USES ds,si
  216.     lds si,@@list
  217.     loadptr dx,ax, ds:si.list_tail
  218.     ret
  219. ENDP
  220.  
  221. END
  222.