.title TIMER .sbttl Elapsed time support routines .ident /091886/ .enabl gbl .nlist bex .enabl lc ; ;+ ;***** ; ; TIMER.MAC contains a set of MACRO callable subroutines ; to provide accurate elapsed time computations using the KWV11 ; Programmable Real Time clock hardware. ; ; Programs must be linked to a "device common" or be ; built as a privileged task to have APR7 mapped to the ; I/O page for access to the KWV11 registers. The display ; routines require the definition of the global symbol ; TI$LUN equal to the logical unit # associated with TI:. ; If no calls to .TMDSP are made, this may be undefined. ; ; Entry points are provided to: ; ; 1) Initialize data structures and clock time base (.TMINI) ; 2) Start KWV11 timer (.TMSTR) ; 2) Stop KWV11 timer and compute elapsed time (.TMSTP) ; 3) Display current and average elapsed time to TI: (.TMDSP) ; ; The KWV clock is operated in a simple counting mode ; (mode 2) starting at 0 with the call to .TMSTR and ; incrementing at a frequency determined by the caller when ; the routines were initialized ; The clock is stopped by calling .TMSTP. Once stopped, ; the current count is returned to the caller as the ; elapsed time from the call to .TMSTR to the call ; to .TMSTP. ; ; The "stop timer" routine accumulates a double precision ; sum of all elapsed times measured for computation of ; an average time by the .TMDSP routine. Any other ; computations based on elapsed time must be handled by ; external routines. ; ; The "display" timer routine may be called to format ; the current and average elapsed times accumulated ; by the timer routines. This runs asynchronously, ; and only allows one active I/O request. If called ; with outstanding I/O to TI:, the routine simply returns ; to the caller. ; ; ;***** ; ; Paul Sorenson ; AEP/Operations Control ; Columbus, OH 43229 ; ;***** ;- KWVCSR = 170420 KWVREG = 170422 KW.MOD = 4 ; bit pattern for timing mode 2 KW.GO = 1 ; go bit KW.MS2 = 1000 ; maintenance ST2 bit ; .psect $idata,rw,d,lcl,rel,con .mcall QIO$,DIR$,ALUN$ CBTARG = 113012 ; display conversion arguments .psect $idata,rw,d,lcl,con,rel ; $TMCUR:: ; current time .blkw 1 $TMAVG:: ; average time .blkw 1 $TMSUM:: ; SUMMED time .BLKW 2 $TMNUM:: ; # OBSERVATIONS .BLKW 1 ; CSR: ; saved clock CSR bits .BLKW 1 ASNLUN: ALUN$ ,TI,0 QIO: ; display QIO DPB QIO$ IO.WVB,TI$LUN,,,TIIOSB,, TIIOSB: .BLKW 2 ; ; *** Display table...very position dependent; "18." corresponds to ; field width set in top 4 bits of CBTARG. Order of CPU mode ; counters in data sections must all agree and match table decriptions ; DISPLY: .ASCII <33>/[f/ ; home cursor .ASCII / Current Average/ .ASCII <33>/[K/ ; erase to end of line .BYTE 12,15 ; vertical format .ASCII <33>/[K/ ; erase to end of line .BYTE 12,15 ; vertical format .ASCII /ELAPSED TIME / ASCCNT: ; start point for ASCII counter fields .blkb 18. ; reserve space for current count .blkb 18. ; reserve space for average count .ASCII <33>/[J/ ; erase to end of screen L.DISP=.-DISPLY .EVEN ; .psect $pcode,ro,i,lcl,rel,con ; .page .sbttl Initialize Timer Routines ; ; *** .TMINI - Initializes the internal data structures used by the ; timing routines. The logical unit "TI$LUN" is assigned to ; TI: for subsequent calls to .TMDSP. The caller must specify ; the KWV11 time base to use for elapsed time counting. ; ; ; MACRO Call Sequence: ; ; CALL .TMINI ; ; with: ; ; R0 = Time base: 1 = 1Mhz ; 2 = 100Khz ; 3 = 10Khz ; 4 = 1Khz ; 5 = 100hz ; ; returns: ; ; Carry bit clear on success ; ; Carry bit set on invalid time base ; ; .TMINI:: ; *** MACRO entry point TST ASNLUN+A.LULU ; asigned lun already ?? BNE 10$ ; branch if yes CLR TIIOSB ; block I/O in .TMDSP MOV #TI$LUN,ASNLUN+A.LULU ; save logical unit for TI: BEQ 10$ ; branch if undefined, no I/O DIR$ #ASNLUN ; assign lun for TI: BCS 9$ ; quit if fails MOV #IS.SUC,TIIOSB ; show no pending I/O BR 10$ 9$: CLR ASNLUN+A.LULU ; keep lun field clear if not assigned 10$: CLR $TMNUM ; init counters CLR $TMSUM CLR $TMSUM+2 CLR CSR ; clear place for CSR TST R0 ; check time base BLE 28$ ; branch if 5, invalid MOV R0,CSR ; save time base ASL CSR ; align argument with ASL CSR ; KWV11 time base bits ASL CSR BIS #KW.MOD!KW.GO,CSR ; OR in control bits CLC ; show success BR 29$ ; and exit 28$: SEC ; show error 29$: RETURN ; return to caller ; .page .sbttl Start Timer ; ; *** .TMSTR - Start timing of event. User specified time base ; OR'd with appropriate KWV11 control bits is written to ; the KWV11 CSR to start the hardware. ; ; ; MACRO Call Sequence: ; ; CALL .TMSTR ; ; (No special arguments required nor return status supplied) ; ; .TMSTR:: ; *** MACRO entry point MOV CSR,@#KWVCSR ; start clock RETURN ; return to caller ; .page .sbttl Stop Timer ; ; *** .TMSTP - Stops timing of an event started by a call to .TMSTR. ; The current KWV clock count is returned to the caller as ; the 16-bit unsigned elapsed time between the calls to ; .TMSTR and .TMSTP ; ; MACRO Call Sequence: ; ; CALL .TMSTP ; ; returns: ; ; R0 = Elapsed time count ; ; .TMSTP:: ; *** MACRO call sequence BIS #KW.MS2,@#KWVCSR ; load register with count via ST2 MOV @#KWVREG,R0 ; get count CLR @#KWVCSR ; clear KWV hardware MOV R0,$TMCUR ; save current count ADD R0,$TMSUM ; accumulate double precision sum ADC $TMSUM+2 INC $TMNUM ; increment # observations RETURN ; done ; .page .sbttl Display Elapsed Time Statistics ; ; *** .TMDSP - Called to format and display the current and average ; values for elapsed time between calling .TMSTR and .TMSTP. ; If there is an active QIO (or no TI: device assignment), ; the calls to .TMDSP is ignored. ; ; MACRO Call Sequence: ; ; CALL .TMDSP ; ; returns: ; Carry clear on success, display queued to TI: ; ; Carry set on failure, I/O pending on TI: ; ; .TMDSP:: ; *** MACRO entry point TST TIIOSB ; I/O still pending ?? BNE 5$ ; no, setup display SEC ; show no display queued BR 29$ ; and exit 5$: CALL $SAVAL ; free all registers MOV $TMNUM,R2 ; get # observations MOV R2,R3 ; compute rounding factor for fixed ASR R3 ; point division... ADC R3 10$: MOV $TMSUM,R1 ; get lo-order sum MOV $TMSUM+2,R0 ; get hi-order sum ADD R3,R1 ; add in rounding factor ADC R0 DIV R2,R0 ; compute average MOV R0,$TMAVG ; save result MOV #ASCCNT,R0 ; get start point for ASCII counts 20$: MOV $TMCUR,R1 ; get current count MOV #CBTARG,R2 ; get conversion parameters CALL $CBTA ; convert binary to ASCII MOV $TMAVG,R1 ; get average count MOV #CBTARG,R2 ; get conversion parameters CALL $CBTA ; convert binary to ASCII DIR$ #QIO ; display results 29$: RETURN ; .page .sbttl Exit Timing Routines ; ; *** .TMEXI - Provided as a means for a task to synchronize ; to any outstanding I/O on TI:....done by brute force ; rather than using an event flag. ; .TMEXI:: TST ASNLUN+A.LULU ; lun assigned to TI: ?? BEQ 5$ ; branch if not, no I/O possible 3$: TST TIIOSB ; pending I/O ?? BEQ 3$ ; branch if yes, loop on it 5$: RETURN ; .end