ON 20030910@12:12:32 PM at page: http://www.piclist.com/techref/member/AM-vima-Y84/index.htm AM-vima-Y84 Aubrey McIntosh Code:
(* Aubrey McIntosh, Ph.D.
 * Written de novo on Sept 10, 2003
 * Highly similarity to 'producer consumer' studies in 
 * Software Practice and Experience, N. Wirth, mid 70s expected
 *
 * A FIFO.
 * +
 *   Multiple FIFOs
 *   Fixed size for software simplicity.
 *   0 offset for buffer for efficiency.
 *   The presence of all status in buffer structure allows any number to be used.
 * -
 *   All buffers are the same size.
 *   Powers of two are recommended.
 *
 *   And a Stack. :-)
 *
 *  Some language hints:
 *  the '*' marker means to put the symbol into the .inc file, and it is read/write accessible.
 *  the '-' marker means to put the symbol into the .inc file, but never write to it.
 *  the 'VAR' parameter means to put the item's address on the call stack.
 *  with these definitions, a compiler will let you declare a Buf, but not know where any
 *  field is except for read-only access to the 'result' at Buf+10
 *)
 
MODULE PICQueue;

  CONST
  	BufSize* = 8;
  	FullPut* = 1;
  	EmptyRead* = 2;
  	
  TYPE
  	Buf* = RECORD
  			buf : ARRAY BufSize OF CHAR;
  			nextIn, 
  			thisOut : SHORTINT;
  			result- : SET
  		END;
  
  VAR
  	SystemVariableStack- : Buf;
  	
  PROCEDURE Add* ( ch : CHAR; VAR this : Buf );
  BEGIN
  	IF Available (this) <= BufSize
  	THEN
  		INCL ( this.result, FullPut );
  		RETURN	(*Return, do not clobber existing data. *)
  	END;
  	this.buf [this.nextIn] := ch;
  	this.nextIn := (this.nextIn+1) MOD BufSize
  END Add;
  
  PROCEDURE Fetch* ( VAR this : Buf ) : CHAR;
  	VAR ch : CHAR;
  BEGIN
  	IF 0 = Available (this)
  	THEN
  		INCL (this.result, EmptyRead);
  		RETURN "!"		(* Return, do not break correctness of Buf data *)
  	END;
  	ch := this.buf [this.thisOut];
  	this.thisOut := (this.thisOut+1) MOD BufSize;
  	RETURN ch
  END Fetch;
  
  
  PROCEDURE Available* (VAR this : Buf) : SHORTINT;
  BEGIN
  	RETURN ( BufSize + this.nextIn - this.thisOut ) MOD BufSize
  END Available;
  
  (* Add and Push are the same. *)
  
  PROCEDURE Pop* ( VAR this : Buf ) : CHAR;
  BEGIN
  	IF this.nextIn = 0 
  	THEN
  		INCL (this.result, EmptyRead);
  		HALT (42)		(*  A hard error.  Let the WDT kick in. *)
  	END;
  	(* Please look at your clocks and remember:  
  	 * 11 MOD 12 --> 11
  	 * 12 MOD 12 --> 0
  	 * -1 MOD 12 --> 11
  	 *)
  	this.nextIn := (this.nextIn-1) MOD BufSize;
  	RETURN this.buf [this.nextIn]
  END Pop;
  
  PROCEDURE Init* (VAR this : Buf);
  BEGIN
  	this.nextIn := 0;
  	this.thisOut := 0;
  	this.result := {}
  END Init;
  
BEGIN
	Init( SystemVariableStack )
END PICQueue.

Compiler.Compile *\s