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