(* Show stack usage and stuff like that           *)
(* F2 Key while someone logged on shows mem usage *)
unit stackuse;
interface
Procedure StackReport; { Reports all sizes in bytes and percentages }
implementation
uses dos,crt,records,detector,openfile;
CONST
 Ssize = 64000; {should match stack size as set by the $M directive }

Procedure Initstack;  { fills unused stack with marker value }
 Assembler;
 ASM
   PUSH SS      { SS = the stack segment }
   POP  ES
   MOV  DI,StackLimit
   MOV  CX,SP    { SP = stack pointer register }
   SUB  CX,DI
   MOV  AL,77    { arbitrary marker value }
   CLD
   REP  STOSB
 END;

Function VirginStack:word;  { finds highest unused byte on stack }
 Assembler;
 ASM
   PUSH SS
   POP  ES
   MOV  DI,StackLimit   { is usually 0 }
   MOV  CX,SP
   SUB  CX,DI
   MOV  AL,77  { marker value, must be the same as in InitStack }
   CLD
   REPE SCASB  { scan empty stack }
   DEC  DI     { adjust for last non-matching byte in the scan }
   MOV  AX,DI
 END;


Procedure StackReport; { Reports all sizes in bytes and percentages }
var xx,yy:byte;
    c:byte;
begin

 if infoit=false then exit;
 xx:=wherex;
 yy:=wherey;
 c:=textattr;
 window(1,1,80,40);
 crt.gotoxy(1,30);
 textattr:=7;
WriteLn('Total Stack = ',Ssize:6, ' bytes   = 100.00 %');
WriteLn('Now used    = ',Ssize-(Sptr-StackLimit):6, ' bytes   = ',(Ssize-(Sptr-StackLimit))/Ssize *100:6:2,' %');
WriteLn('Ever used   = ',Ssize-(VirginStack-StackLimit):6, ' bytes   = ',(Ssize-(VirginStack-StackLimit))/Ssize *100:6:2,' %');
WriteLn('Never used  = ',(VirginStack-StackLimit):6, ' bytes   = ',(VirginStack-StackLimit)/Ssize *100:6:2,' %');
Writeln('Current X   = ',xx);
writeln('Current Y   = ',yy);
writeln('Current Cor = ',c);
Writeln('Max Mem     = ',maxavail);
writeln('Mem Avail   = ',memavail);
{writeln('Files Opened: ');}
window(1,1,80,24);
crt.gotoxy(xx,yy);
textattr:=c;
end;


Procedure UseStack(CNT:WORD); Assembler;  { example stack usage }
 ASM
   MOV  AX,0    {dummy value}
   MOV  CX,CNT
@pushit:        {perform CNT PUSHes}
   PUSH AX
   LOOP @pushit
   MOV  CX,CNT
@poppit:        {perform CNT POPs}
   POP  AX
   LOOP @poppit
 END;



BEGIN

 InitStack;      { prepare stack }
{ UseStack(10); { perform a number of PUSHes and POPs }
 StackReport;    { report stack usage }
END.
