home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / queue.asm < prev    next >
Assembly Source File  |  1995-06-25  |  3KB  |  127 lines

  1.  
  2. ;put into the public domain by Russell Nelson, nelson@crynwr.com
  3.  
  4. ; here we define a queue of variable-sized objects.  Each object is preceded
  5. ; by the length of the object.  If the length is zero, then the next real item
  6. ; is found at queue_begin.  Queue_push doesn't check to see if you're pushing
  7. ; an item that simply will not fit on the queue.
  8.  
  9.  
  10. queue_length    dw    10000,?        ;length of the queue.
  11. queue_tail    dw    ?        ;points after the last item in the queue.
  12. queue_head    dw    ?        ;points to the first item in the queue.
  13. queue_end    dw    ?        ;points to the end of the queue, but
  14.                     ;there is room for one more event after
  15.                     ;this one.
  16.  
  17.   if 0
  18. queue_dump:
  19.     mov    ax,offset queue_begin
  20.     call    wordout
  21.     mov    al,' '
  22.     call    chrout
  23.  
  24.     mov    ax,queue_tail
  25.     call    wordout
  26.     mov    al,' '
  27.     call    chrout
  28.  
  29.     mov    ax,queue_head
  30.     call    wordout
  31.     mov    al,' '
  32.     call    chrout
  33.  
  34.     mov    ax,queue_end
  35.     call    wordout
  36.     call    crlf
  37.     ret
  38.   endif
  39.  
  40.  
  41. queue_init:
  42. ;initialize the queue.
  43.     mov    bx,offset queue_begin
  44.     mov    queue_head,bx
  45.     mov    queue_tail,bx
  46.     add    bx,queue_length
  47.     sub    bx,2            ;we may go past end by as much as 2.
  48.     mov    queue_end,bx        ;initialize the head of the queue.
  49.     ret
  50.  
  51.  
  52. queue_pull:
  53. ;exit with nc, si,cx describing next item on queue,
  54. ;  or cy if no more items.
  55.  
  56. queue_pull_0:
  57.     mov    si,queue_head        ;load si, cx.
  58.     cmp    si,queue_tail        ;quit when we hit the tail.
  59.     je    queue_pull_2
  60.     mov    cx,code:[si]        ;get this one's length.
  61.     jcxz    queue_pull_1        ;zero means wrap around.
  62.     add    si,2            ;advance si to next.
  63.     add    si,cx
  64.     xchg    si,queue_head        ;update queue_head.
  65.     add    si,2
  66.     clc
  67.     ret
  68. queue_pull_1:
  69.     mov    queue_head,offset queue_begin    ;wrap around to beginning.
  70.     jmp    queue_pull_0
  71. queue_pull_2:
  72.     stc
  73.     ret
  74.  
  75.  
  76. queue_push:
  77. ;enter with cx = number of bytes that we require in the queue.
  78. ;exit with nc, di -> data part of our entry,
  79. ;  or cy if there isn't room.
  80. ;this code is slightly suboptimal in that if there isn't enough room at the
  81. ;end of the queue to hold the current item, it will wrap the queue tail around.
  82. ;if it then runs into the queue head, the space at the end is now wasted.
  83. ;You may wish to discard old entries rather than new.  If that is the case,
  84. ;then if queue_push returns cy, call queue_pull and try again.
  85. queue_push_0:
  86.     mov    di,queue_tail        ;get the pointer.
  87.     cmp    di,queue_head        ;if the tail is before the head,
  88.     jb    queue_push_2        ;  we just compare.
  89.     add    di,2            ;leave room for the count.
  90.     add    di,cx
  91.     jmp    short queue_push_4
  92. queue_push_2:
  93. ;we get here if the tail *was* before the head.
  94.     add    di,2            ;leave room for the count.
  95.     add    di,cx
  96.     cmp    di,queue_head        ;is the tail now after the head?
  97.     ja    queue_push_3        ;yes, we don't have room.
  98. queue_push_4:
  99.     cmp    di,queue_end        ;time to wrap?
  100.     jbe    queue_push_1        ;not yet.
  101.  
  102.     mov    di,queue_tail
  103.     mov    word ptr code:[di],0    ;make a zero-length event here.
  104.  
  105.     mov    queue_tail,offset queue_begin
  106.     jmp    queue_push_0
  107.  
  108. queue_push_3:
  109.     stc
  110.     ret
  111.  
  112. queue_push_1:
  113.     xchg    di,queue_tail        ;update the tail and get new pointer.
  114.     mov    code:[di],cx        ;store the length of this entry here.
  115.     add    di,2
  116.     clc
  117.     ret
  118.  
  119.  
  120. queue_unpush:
  121. ;call with si -> same value returned by queue_push.
  122.     sub    si,2
  123.     mov    queue_tail,si        ;throw this one back.
  124.     ret
  125.  
  126.  
  127.