;       CSTAT           Dynamic disk cache status for Alpha's DCACHE.SYS
;       Author:         Irwin M. Goldstein
;       Date written:   10/15/86

       SEARCH  SYS                     ; system macros
       SEARCH  SYSSYM                  ; system symbols
       SEARCH  TRM                     ; terminal symbols
;       COPY    TABMAC                  ; special screen functions macro

;THIS IS TABMAC   |  |
;                 V  V
;
DEFINE  PRTTAB  AA,BB           ;PRINT TAB (#,#)
       MOVB    #AA,D1
       LSLW    D1,#10
       MOVB    #BB,D1
       TCRT
ENDM


;***    Macro  for displaying contents of a register &
;          clearing to end of line

DEFINE  DISPLY  REG
       MOV     REG,D1
       DCVT    0,OT$TRM
       PRTTAB  -1.,9.
ENDM

;***    Offsets into CACHE.BUF:
;           (determined by FIXing CACHE.LIT)

TOTBUF  =       16                      ; total buffers (word)
ULKBUF  =       20                      ; unlocked buffers (word)
LOKBUF  =       22                      ; locked buffers (word)
TOTRED  =       24                      ; total reads (long word)
CACRED  =       30                      ; cache reads (long word)
CASTAT  =       54                      ; cache status (word)

;***    Work area:
;           memory area for saving cache status

       ASECT
       .=0
TBSAV:  BLKW    1                       ; total buffers
UBSAV:  BLKW    1                       ; unlocked buffers
LBSAV:  BLKW    1                       ; locked buffers
TRSAV:  BLKL    1                       ; total reads
DRSAV:  BLKL    1                       ; disk reads
CRSAV:  BLKL    1                       ; cache reads
CSSAV:  BLKW    1                       ; cache status
CRFP:   BLKW    3                       ; cache reads in floating point
TRFP:   BLKW    3                       ; total reads in floating point
MEMSIZ:                                 ; defines size of memory area we need
       PSECT
       .=0

       PHDR    -1,0,PH$REE!PH$REU

;***    Locate CACHE buffer in system memory; If it's not there - error!

       SRCH    BUFNAM,A0               ; get address of cache buffer
       BEQ     CSTAT                   ; buffer located, continue

       TYPECR  <?CACHE not installed>
       EXIT

;***    Initialize:  Set image mode with echo off, allocate workspace:

CSTAT:  JOBIDX  A5                      ; index our JCB
       MOV     JOBTRM(A5),A5           ; get address of terminals status word
       ORW     #T$IMI!T$ECS,@A5        ; set image mode, echo off
       GETIMP  MEMSIZ,A1               ; get some memory for work space

;***    Start display stats; clear workspace & screen, display screen mask:

AGAIN:  CLEAR   @A1,MEMSIZ              ; clear the work space
       PRTTAB  -1,0                    ; clear screen
       PRTTAB  -1,29.                  ; turn cursor off
       PRTTAB  -1,11.                  ; reduced intensity
       TTYL    SCREEN                  ; display status mask
       PRTTAB  -1,12.                  ; normal intensity

;***    Loop until stopped, checking status & updating screen as needed:

LOOP:   CLR     D0                      ; pre-clear display register

;       Display total buffers if they changed from last time:

CHKTB:  MOVW    TOTBUF(A0),D0           ; get total buffers
       CMPW    D0,TBSAV(A1)            ; did they change?
       BEQ     CHKLB                   ;   no - check locked buffers
       MOVW    D0,TBSAV(A1)            ;   yes - save new value
       PRTTAB  3.,22.                  ; position cursor
       DISPLY  D0                      ; display # of buffers

;       Display unlocked buffers if they changed from last time:

CHKUB:  MOVW    ULKBUF(A0),D0           ; get unlocked buffers
       CMPW    D0,UBSAV(A1)            ; did they change?
       BEQ     CHKLB                   ;   no - check locked  buffers
       MOVW    D0,UBSAV(A1)            ;   yes - save new value
       PRTTAB  4.,22.                  ; position cursor
       DISPLY  D0                      ; display # of unlocked buffers

;       Display locked buffers if they changed from last time:

CHKLB:  MOVW    LOKBUF(A0),D0           ; get locked buffers
       CMPW    D0,LBSAV(A1)            ; did they change?
       BEQ     CHKTR                   ;   no - check unlocked buffers
       MOVW    D0,LBSAV(A1)            ;   yes - save new value
       PRTTAB  5.,22.                  ; position cursor
       DISPLY  D0                      ; display # of locked buffers

;       Display efficiency stats if total reads have changed from
;       last time:

;       D2 = total reads
;       D3 = cache reads
;       D4 = disk reads

CHKTR:  MOV     TOTRED(A0),D2           ; get total reads
       CMP     D2,TRSAV(A1)            ; did they change?
       JEQ     CHKCS                   ;   no - check cache status
       MOV     D2,TRSAV(A1)            ;   yes - save new value
       MOV     CACRED(A0),D3           ; get cache reads
       MOV     D2,D4                   ; calculate disk reads by
       SUB     D3,D4                   ;   subtracting cache reads from total reads

       PRTTAB  7.,22.                  ; position cursor
       DISPLY  D2                      ; display total reads

;       Display cache reads if they changed from last time:

       CMP     D3,CRSAV(A1)            ; did cache reads change?
       BEQ     CHKDR                   ;   no - check disk reads
       MOV     D3,CRSAV(A1)            ;   yes - save new value
       PRTTAB  8.,22.                  ; position cursor and
       DISPLY  D3                      ; display cache reads

;       Display disk reads if they changed from last time:

CHKDR:  CMP     D4,DRSAV(A1)            ; disk disk reads change?
       BEQ     CHKHIT                  ;   no - check hit rate
       MOV     D4,DRSAV(A1)            ;   yes - save new value
       PRTTAB  9.,22.                  ; position cursor and
       DISPLY  D4                      ; display disk reads

;       Display the hit rate if total reads have changed:

CHKHIT: LEA     A2,TRFP(A1)             ; index total reads in FP
       LEA     A3,CRFP(A1)             ; index cache reads in FP
       FLTOF   D2,@A2                  ; convert total reads to FP
       FLTOF   D3,@A3                  ; convert cache reads to FP
       FDIV    A2,A3                   ; divide total reads into cache reads
       FPWR    @A3,#2                  ; multiply result by 100 to get %
       PRTTAB  11.,22.                 ; postion cursor
       FCVT    @A3,4,OT$FIX!OT$TRM,1,0 ; display hit rate
       TYPE    %                       ;  as a percentage

;       Redisplay all operation flags if they have changed:

CHKCS:  MOVW    CASTAT(A0),D0           ; get status flags
       CMPW    D0,CSSAV(A1)            ; did they change?
       JEQ     PAUSE                   ;   no - pasue & then loop back for more status
       MOVW    D0,CSSAV(A1)            ;   yes - save new value

       PRTTAB  16.,22.                 ; position cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #0,D0                   ; is cache on?
       BNE     CON                     ;   yes - say so
       LEA     A2,OFFTXT               ;   no - index OFF
CON:    TTYL    @A2                     ; display OFF or ON

       PRTTAB  17.,22.                 ; postion cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #1,D0                   ; is read restriction on?
       BNE     RRON                    ;   yes - say so
       LEA     A2,OFFTXT               ;   no - index OFF
RRON:   TTYL    @A2                     ; display OFF or ON

       PRTTAB  18.,22.                 ; position cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #2,D0                   ; is random restrtiction on?
       BNE     RNRON                   ;   yes - say so
       LEA     A2,OFFTXT               ;   no - index OFF
RNRON:  TTYL    @A2                     ; display OFF or ON

       PRTTAB  19.,22.                 ; position cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #3,D0                   ; is lock restriction on?
       BNE     LRON                    ;   yes - say so
       LEA     A2,OFFTXT               ;   no - index OFF
LRON:   TTYL    @A2                     ; display OFF or ON

       PRTTAB  20.,22.                 ; position cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #4,D0                   ; is MFD locking on?
       BNE     MFDON                   ;   yes - say so
       LEA     A2,OFFTXT               ;   no - index OFF
MFDON:  TTYL    @A2                     ; display OFF or ON

       PRTTAB  21.,22.                 ; position cursor
       LEA     A2,ONTXT                ; index ON
       BTST    #5,D0                   ; is UFD locking on?
       BNE     UFDON                   ;   yes - say so
       LEA     A2,OFFTXT               ;   no index OFF
UFDON:  TTYL    @A2                     ; display OFF or ON

PAUSE:  TCKI                            ; has anything been typed?
       BNE     SNORE                   ;   no - sleep for a while & repeat
       KBD                             ;   yes - get character typed
       CMPB    D1,#27.                 ; ESCape pressed?
       BNE     SNORE                   ;   no - ignore it
       PRTTAB  23.,25.                 ; position cursor at bottom
       TYPESP  <Enter command (Q,R):>  ; display command prompt
       PRTTAB  -1,28.                  ; turn cursor on
       KBD     QUIT                    ; get command
       UCS                             ; convert to upper case
       CMPB    D1,#'Q                  ; quit?
       BEQ     QUIT                    ;   yes - abort
       CMPB    D1,#'R                  ;   no - replot?
       JEQ     AGAIN                   ;     yes - start again!
       PRTTAB  -1,29.                  ;     no - turn cursor off
       PRTTAB  23.,1.                  ;          put cursor before prompt
       PRTTAB  -1,9.                   ;          clear prompt

;***    Sleep for a second, then recheck stats:

SNORE:  SLEEP   #10000.                 ; wait a second
       CTRLC   QUIT                    ; check for abort
       JMP     LOOP                    ; loop back for more status

;***    Exit program: move to bottom of screen & clean up:

QUIT:   PRTTAB  23.,1.                  ; put cursor near the bottom
       PRTTAB  -1,10.                  ; clear to end of screen
       PRTTAB  -1,28.                  ; turn cursor on
       EXIT

;***    Constants:

BUFNAM: RAD50   \CACHE BUF\             ; name of cache buffer module

ONTXT:  ASCIZ   \ON \                   ; text for ON messages
OFFTXT: ASCIZ   \OFF\                   ; text for OFF messages

;***    Status screen:

SCREEN: ASCII   \DISK CACHE STATUS--.\
       BYTE    13.,13.
       ASCII   \      Total buffers:\
       BYTE    13.
       ASCII   \   Unlocked buffers:\
       BYTE    13.
       ASCII   \     Locked buffers:\
       BYTE    13.,13.
       ASCII   \        Total reads:\
       BYTE    13.
       ASCII   \   Reads from cache:\
       BYTE    13.
       ASCII   \    Reads from disk:\
       BYTE    13.,13.
       ASCII   \           Hit rate:\
       BYTE    13.,13.,13.
       ASCII   \OPERATION FLAGS----.\
       BYTE    13.,13.
       ASCII   \           Cache is:\
       BYTE    13.
       ASCII   \   Read restriction:\
       BYTE    13.
       ASCII   \ Random restriction:\
       BYTE    13.
       ASCII   \   Lock restriction:\
       BYTE    13.
       ASCII   \Dynamic MFD locking:\
       BYTE    13.
       ASCII   \Dynamic UFD locking:\
       BYTE    0

       END