etisserant@0: FUNCTION_BLOCK STACK_INT etisserant@0: VAR_INPUT PUSH, POP: BOOL R_EDGE; (* Basic stack operations *) etisserant@0: R1 : BOOL ; (* Over-riding reset *) etisserant@0: IN : INT ; (* Input to be pushed *) etisserant@0: N : INT ; (* Maximum depth after reset *) etisserant@0: END_VAR etisserant@0: VAR_OUTPUT EMPTY : BOOL := 1 ; (* Stack empty *) etisserant@0: OFLO : BOOL := 0 ; (* Stack overflow *) etisserant@0: OUT : INT := 0 ; (* Top of stack data *) etisserant@0: END_VAR etisserant@0: VAR STK : ARRAY[0..127] OF INT; (* Internal stack *) etisserant@0: NI : INT :=128 ; (* Storage for N upon reset *) etisserant@0: PTR : INT := -1 ; (* Stack pointer *) etisserant@0: END_VAR etisserant@0: (* Function Block body *) etisserant@0: IF R1 THEN etisserant@0: OFLO := 0; EMPTY := 1; PTR := -1; etisserant@0: NI := LIMIT (MN:=1,IN:=N,MX:=128); OUT := 0; etisserant@0: ELSIF POP & NOT EMPTY THEN etisserant@0: OFLO := 0; PTR := PTR-1; EMPTY := PTR < 0; etisserant@0: IF EMPTY THEN OUT := 0; etisserant@0: ELSE OUT := STK[PTR]; etisserant@0: END_IF ; etisserant@0: ELSIF PUSH & NOT OFLO THEN etisserant@0: EMPTY := 0; PTR := PTR+1; OFLO := (PTR = NI); etisserant@0: IF NOT OFLO THEN OUT := IN ; STK[PTR] := IN; etisserant@0: ELSE OUT := 0; etisserant@0: END_IF ; etisserant@0: END_IF ; etisserant@0: etisserant@0: END_FUNCTION_BLOCK