home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 437a.lha / Mandel_v1.0 / source / pipe.asm < prev   
Encoding:
Assembly Source File  |  1990-11-09  |  4.2 KB  |  160 lines

  1.  
  2. * This file: pipe v0.01
  3.  
  4. * (c) 1990 by The DM
  5.  
  6.    XDEF     f_push
  7.    XDEF     f_pull
  8.    XDEF     f_clear
  9.  
  10.    XREF     _LVOAllocMem
  11.    XREF     _LVOFreeMem
  12.  
  13. MAXDEPTH    EQU   254
  14.  
  15.    SECTION  pipe,CODE
  16.  
  17. * error = f_push(value)
  18. *   Z            d0
  19.  
  20. * Will push d0.l to dynamically allocated linked list of memory
  21. * that represents pipe (fifo). Pointers _Head and _Tail should be
  22. * initialized to 0 before first call. Define MAXDEPTH to # of
  23. * longwords to be stored in one chunk of memory.
  24. * If Z is set (result zero) no memory was left.
  25.  
  26. * All registers are preserved.
  27.  
  28. * Structure:
  29. *
  30. * LONG next       ; points to previous structure
  31. * WORD used       ; offset from beginning, points to 1st used long.
  32. * WORD free       ; offset from beginning, points to 1st free long.
  33. * LONG data [0]   ; 1st longword of data
  34. * ...
  35. * LONG data [MAXDEPTH-1]
  36.  
  37.  
  38. f_push:
  39.          movem.l  a0-a2/a6/d0-d2,-(a7)
  40.          move.l   d0,d2
  41.          move.l   _Head,a0
  42.          move.l   a0,d0
  43.          bne.s    1$
  44.  
  45. * This is first time we are called so
  46.          bsr.s    _push1
  47.          beq.s    3$          ; error, no memory
  48.          move.l   a0,_Tail    ; this pointer also needs to be initialized
  49. 1$:
  50.          cmp.w    #(MAXDEPTH*4)+4+2+2,6(a0)
  51.          bcs.s    4$
  52.  
  53. * This hunk is full, allocate next one
  54.          move.l   a0,a2
  55.          bsr.s    _push1
  56.          beq.s    3$          ; error, no memory!
  57.          move.l   a0,(a2)     ; link hunks
  58. 4$:
  59.          move.w   6(a0),d0    ; free
  60.          move.l   d2,0(a0,d0.w)
  61.          addq.w   #4,6(a0)    ; result is nonzero
  62. 3$:                           ; if brach here, result is zero
  63.          movem.l  (a7)+,a0-a2/a6/d0-d2
  64.          rts
  65.  
  66. * Here we allocate one block.
  67. * nextblock/a0 , Z/error = _push1 ()
  68. _push1:
  69.          move.l   #(MAXDEPTH*4)+4+2+2,d0
  70.          moveq    #0,d1
  71.          move.l   $4,a6
  72.          jsr      _LVOAllocMem(a6)
  73.          tst.l    d0
  74.          beq.s    2$
  75.  
  76.  
  77.          move.l   d0,a0
  78.          clr.l    (a0)        ; next field set to zero
  79.          move.w   #8,4(a0)    ; used initialized to 4 (offset)
  80.          move.w   #8,6(a0)    ; free initialized to 8 (offset)
  81.          move.l   a0,_Head    ; result is nonzero
  82. 2$:                           ; if branch here, result is zero
  83.          rts                  ; if error, Z will be set
  84.  
  85.  
  86. * value = f_pull ()
  87. *  d0
  88.  
  89. * Will pull d0.l from dynamically allocated linked list of memory
  90. * that represents pipe. If client is trying to pull from empty
  91. * pipe, -1 will be returned and Z will be set.
  92. * Will automagically deallocate any memory.
  93.  
  94. * NOTE: if you do not pull everything you have pushed, memory
  95. * will be lost!
  96.  
  97. f_pull:
  98.          movem.l  a0-a2/a6/d1-d2,-(a7)
  99.          move.l   _Tail,a2
  100.          moveq    #-1,d0
  101.          move.l   a2,d1
  102.          beq.s    1$          ; Pipe is empty
  103.  
  104.          addq.w   #4,4(a2)
  105.          move.w   4(a2),d0
  106.          move.l   -4(a2,d0.w),d2  ; Pipe contains at least one value
  107. *                 ^^ This is because I just accidentally incremented d0
  108.  
  109.          cmp.w    6(a2),d0       ; if used == free, time to free this block
  110.          bne.s    2$
  111.  
  112. * Done with this block, deallocate it and move to next
  113.          move.l   a2,a1
  114.          move.l   (a1),a2
  115.          move.l   #(MAXDEPTH*4)+4+2+2,d0
  116.          move.l   $4,a6
  117.          jsr      _LVOFreeMem(a6)
  118.          move.l   a2,_Tail
  119.          bne.s    2$             ; if this was last block,
  120.          clr.l    _Head          ; clear _Head as well.
  121. 2$:
  122.          move.l   d2,d0
  123.          moveq    #-1,d1         ; this is surely nonzero
  124. 1$:
  125.          movem.l  (a7)+,a0-a2/a6/d1-d2
  126.          rts
  127.  
  128.  
  129. * f_clear ()
  130.  
  131. * Will deallocate our pipe quickly, cleanly and completely in case there
  132. * is no need to process the remaining stuff in the pipe.
  133.  
  134. f_clear:
  135.          movem.l  a0-a2/a6/d0-d1,-(a7)
  136.          move.l   _Tail,a2
  137.          move.l   $4,a6
  138. 1$:
  139.          move.l   a2,a1
  140.          move.l   a2,d0
  141.          beq.s    2$
  142.  
  143. * This block is valid, deallocate it & back up
  144.          move.l   (a1),a2
  145.          move.l   #(MAXDEPTH*4)+4+2+2,d0
  146.          jsr      _LVOFreeMem(a6)
  147.          bra.s    1$
  148. 2$:
  149. * Ups! Almost forget:
  150.          clr.l    _Head
  151.          clr.l    _Tail
  152.          movem.l  (a7)+,a0-a2/a6/d0-d1
  153.          rts
  154.  
  155. * In order to save space, these are right here in program segment...
  156.  
  157. _Head:   dc.l  0     ; initialized to zero!
  158. _Tail:   dc.l  0
  159.    END
  160.