home *** CD-ROM | disk | FTP | other *** search
-
- * This file: pipe v0.01
-
- * (c) 1990 by The DM
-
- XDEF f_push
- XDEF f_pull
- XDEF f_clear
-
- XREF _LVOAllocMem
- XREF _LVOFreeMem
-
- MAXDEPTH EQU 254
-
- SECTION pipe,CODE
-
- * error = f_push(value)
- * Z d0
-
- * Will push d0.l to dynamically allocated linked list of memory
- * that represents pipe (fifo). Pointers _Head and _Tail should be
- * initialized to 0 before first call. Define MAXDEPTH to # of
- * longwords to be stored in one chunk of memory.
- * If Z is set (result zero) no memory was left.
-
- * All registers are preserved.
-
- * Structure:
- *
- * LONG next ; points to previous structure
- * WORD used ; offset from beginning, points to 1st used long.
- * WORD free ; offset from beginning, points to 1st free long.
- * LONG data [0] ; 1st longword of data
- * ...
- * LONG data [MAXDEPTH-1]
-
-
- f_push:
- movem.l a0-a2/a6/d0-d2,-(a7)
- move.l d0,d2
- move.l _Head,a0
- move.l a0,d0
- bne.s 1$
-
- * This is first time we are called so
- bsr.s _push1
- beq.s 3$ ; error, no memory
- move.l a0,_Tail ; this pointer also needs to be initialized
- 1$:
- cmp.w #(MAXDEPTH*4)+4+2+2,6(a0)
- bcs.s 4$
-
- * This hunk is full, allocate next one
- move.l a0,a2
- bsr.s _push1
- beq.s 3$ ; error, no memory!
- move.l a0,(a2) ; link hunks
- 4$:
- move.w 6(a0),d0 ; free
- move.l d2,0(a0,d0.w)
- addq.w #4,6(a0) ; result is nonzero
- 3$: ; if brach here, result is zero
- movem.l (a7)+,a0-a2/a6/d0-d2
- rts
-
- * Here we allocate one block.
- * nextblock/a0 , Z/error = _push1 ()
- _push1:
- move.l #(MAXDEPTH*4)+4+2+2,d0
- moveq #0,d1
- move.l $4,a6
- jsr _LVOAllocMem(a6)
- tst.l d0
- beq.s 2$
-
-
- move.l d0,a0
- clr.l (a0) ; next field set to zero
- move.w #8,4(a0) ; used initialized to 4 (offset)
- move.w #8,6(a0) ; free initialized to 8 (offset)
- move.l a0,_Head ; result is nonzero
- 2$: ; if branch here, result is zero
- rts ; if error, Z will be set
-
-
- * value = f_pull ()
- * d0
-
- * Will pull d0.l from dynamically allocated linked list of memory
- * that represents pipe. If client is trying to pull from empty
- * pipe, -1 will be returned and Z will be set.
- * Will automagically deallocate any memory.
-
- * NOTE: if you do not pull everything you have pushed, memory
- * will be lost!
-
- f_pull:
- movem.l a0-a2/a6/d1-d2,-(a7)
- move.l _Tail,a2
- moveq #-1,d0
- move.l a2,d1
- beq.s 1$ ; Pipe is empty
-
- addq.w #4,4(a2)
- move.w 4(a2),d0
- move.l -4(a2,d0.w),d2 ; Pipe contains at least one value
- * ^^ This is because I just accidentally incremented d0
-
- cmp.w 6(a2),d0 ; if used == free, time to free this block
- bne.s 2$
-
- * Done with this block, deallocate it and move to next
- move.l a2,a1
- move.l (a1),a2
- move.l #(MAXDEPTH*4)+4+2+2,d0
- move.l $4,a6
- jsr _LVOFreeMem(a6)
- move.l a2,_Tail
- bne.s 2$ ; if this was last block,
- clr.l _Head ; clear _Head as well.
- 2$:
- move.l d2,d0
- moveq #-1,d1 ; this is surely nonzero
- 1$:
- movem.l (a7)+,a0-a2/a6/d1-d2
- rts
-
-
- * f_clear ()
-
- * Will deallocate our pipe quickly, cleanly and completely in case there
- * is no need to process the remaining stuff in the pipe.
-
- f_clear:
- movem.l a0-a2/a6/d0-d1,-(a7)
- move.l _Tail,a2
- move.l $4,a6
- 1$:
- move.l a2,a1
- move.l a2,d0
- beq.s 2$
-
- * This block is valid, deallocate it & back up
- move.l (a1),a2
- move.l #(MAXDEPTH*4)+4+2+2,d0
- jsr _LVOFreeMem(a6)
- bra.s 1$
- 2$:
- * Ups! Almost forget:
- clr.l _Head
- clr.l _Tail
- movem.l (a7)+,a0-a2/a6/d0-d1
- rts
-
- * In order to save space, these are right here in program segment...
-
- _Head: dc.l 0 ; initialized to zero!
- _Tail: dc.l 0
- END
-