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