Google
 

Trailing-Edge - PDP-10 Archives - BB-L288A-RM - swskit-utilities/felog.mac
There is 1 other file named felog.mac in the archive. Click here to see a list.
; FELOG - Data logging for FE device and CAL11. UUO

;
;		   COPYRIGHT (c) 1977,1978,1979,1980
;                    DIGITAL EQUIPMENT CORPORATION
;
;     This software is furnished under a license and may  be  used
;     and copied only in accordance with the terms of such license
;     and with the inclusion of the above copyright notice.   This
;     software  or any other copies thereof may not be provided or
;     otherwise made available to any other person.  No  title  to
;     and ownership of the software is hereby transferred.
;
;     The information  in  this  software  is  subject  to  change
;     without  notice  and should not be construed as a commitment
;     by DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL assumes no responsibility for the use or reliability
;     of  its  software  on  equipment  which  is  not supplied by
;     DIGITAL.
;
;	TITLE	FELOG - DN60 transaction logger
	SUBTTL	Symbols and definitions


	SALL				; Clean listings
	.DIRECTIVE FLBLST		; Only first word of multiword text

	SEARCH	GLXMAC			; Get symbols from GALAXY
	SEARCH	D60UNV			; Get symbols from FE interface

	PROLOGUE (FELOG)		; Init the galaxy symbols

	XP	FLGVER,	1		; Version number
	XP	FLGMIN,	0		; Minor version number
	XP	FLGEDT,	100		; Edit number
	XP	FLGWHO,	0		; Who last edited

	%%.FLG==<VRSN. (FLG)>		; Set version number

; Print information to log during compilation

Define VOUTX ($S1,$S2,$S3,$S4)
 <TITLE $S1 $S2'$S3'('$S4')
  PRINTX $S1 $S2'$S3'('$S4')>

IF1,<
 IFN <FLGMIN>,<VOUTX (FELOG - DN60 transaction logger,\FLGVER,\"<"A"+FLGMIN>,\FLGEDT)>
 IFE <FLGMIN>,<VOUTX (FELOG - DN60 transaction logger,\FLGVER,,\FLGEDT)>
    > ;End IF1

IF2,<Printx Pass 2.>

	EXTERNAL LOGFLG			; D60JSY logging flags

TOPS20 <
	EXTERNAL RCVHDR			; Transmit and receive headers
	EXTERNAL XMTHDR			;  in D60JSY
    > ;End if TOPS20
	SUBTTL	TOPS10 type log data structure

; This describes the data structure format for FELOG recording for
; TOPS10.  The data stream in the data file is terminated by a block
; that has a zero flag and length word.
;
; Each block is divided into three sections; header, CAL11. block and
; data. Only the first two need exist. The data section only exists on
; "BEFORE" entries for write functions and "AFTER" entries for
; read functions.


;	+-------------------------------------------------------+
;	!           Flags           !          Length           !
;	!-------------------------------------------------------!
;	!                  Time in UDT format                   !
;	!=======================================================!
;	!    Byte pointer to data   !            N/U            !
;	!-------------------------------------------------------!
;	!        Port number        !        .C11QU (2)         !
;	!-------------------------------------------------------!
;	!        Line number        !       Device number       !
;	!-------------------------------------------------------!
;	!  Number of bytes in data  !  .C11QU subfunction code  !
;	!-------------------------------------------------------!
;	! Number of words in buffer !      Buffer address       !
;	!-------------------------------------------------------!
;	! Bytes/word !           Position of first byte         !
;	!-------------------------------------------------------!
;	!Number of bytes transfered !        Result code        !
;	!=======================================================!
;	!                                                       !
;	\                 Data (if applicable)                  \
;	!                                                       !
;	+-------------------------------------------------------+
	SUBTTL	TOPS20 type log data structure

; This describes the data structure format for FELOG recording for
; TOPS20.  The data stream in the data file is terminated by a block
; that has a zero flag and length word.
;
; Each block is divided into three sections; header, transaction header
; and data. Only the first two need exist. The data section only exists
; on "BEFORE" entries for write functions and "AFTER" entries for
; read functions. The result code is applicable only on "AFTER" entries.

;	+-------------------------------------------------------+
;	!           Flags           !          Length           !
;	!-------------------------------------------------------!
;	!                  Time in UDT format                   !
;	!=======================================================!
;	!   Byte pointer for data   !            N/U            !
;	!-------------------------------------------------------!
;	!                      Port number                      !
;	!-------------------------------------------------------!
;	!Result code !  Function  !Line number !Dev number !    !
;	!-------------------------------------------------------!
;	!     Data byte count     !             N/U             !
;	!=======================================================!
;	!                                                       !
;	\                 Data (if applicable)                  \
;	!                                                       !
;	+-------------------------------------------------------+
	SUBTTL	MARK data file entry

; This entry creates a "MARK" in the data file stream that can be searched
;	for.  This entry is created by the routine WRTMRK.  The mark location
;	number is passed to it in register S1.

;	+-------------------------------------------------------+
;	!           Flags           !          Length           !
;	!-------------------------------------------------------!
;	!                  Time in UDT format                   !
;	!=======================================================!
;	!               Mark location number/name               !
;	!-------------------------------------------------------!
;	!                Incremental mark number                !
;	+-------------------------------------------------------+
	SUBTTL	FELOG -- Main logging routine

; Routine - FELOG
;
; Function - To log, in either TOPS10 or TOPS20 format, the current transfer
;	to/from the DN60.  The type of log event that opccurs depends on
;	the function and the phase (before/after).  The actual data logged
;	is described above with the data block formats.
;
; Parameters -
;
;	P1/	FEI%O argument block address
;	P2/	Handle list entry address
;
;    TOPS20 -
;	T4/	Flags,,Transaction header address
;	XMTHDR/	Transmit header (GLOBAL) 
;	RCVHDR/	Receive header (GLOBAL) 
;    TOPS10 -
;	T4/	Flags,,CAL11. block address


FELOG::	$SAVE	<TF,S1,S2,T1,T2,T3,P1,P2>

	$CALL	CHKSTA			; Check state of logging
	 JUMPF	.POPJ			;  Not logging .. just return
	$CALL	CALCLN			; Calculate length of block
	$CALL	WRTHDR			; Write block header
	$CALL	WRTTRN			; Write transaction block
	$CALL	WRTDAT			; Write data portion (if needed)
	$RET				; Return
; Routine - CALCLN
;
; Function - To calculate the length of the data portion of the message.
;	This value is specified only for "AFTER" Reads and "BEFORE" writes.
;	The byte pointer in PNTSAV assumes (which should always be true) that
;	the previous call to FELOG stored the correct byte pointer.
;
; Parameters -
;
;	P1/	FEI%O argument block address
;	T4/	Flags,,CAL11. argument block address (TOPS10)
;
; Returns -
;
;	T1/	Address of data buffer
;	T2/	Number of words in data buffer

CALCLN:	SETZ	T2,			; Clear length of data buffer
	LOAD	S1,(P1),ARG$FC		; Get function code
	TXNN	T4,PHSBEF		; Check for "BEFORE" entry
	 JRST	CLCAFT			;  No .. must be "AFTER"
	LOAD	T1,(P1),ARG$PT		; Get pointer to data
	MOVEM	T1,PNTSAV		; Save last pointer seen
	TRNE	S1,1			; Check for Write function
	 $RET				;  No .. read .. just return
TOPS10 <LOAD	T2,(T4),C$NBT>		; Number of bytes to transfer
	JRST	CLCGO

CLCAFT:	TRNN	S1,1			; Check for Read function
	 $RET				;  No .. write .. just return
	MOVE	T1,PNTSAV		; Get pointer to data
TOPS10 <LOAD	T2,(T4),C$BXF>		; Get number of bytes transfered

CLCGO:
TOPS20 <LOAD	T2,(T4),HDRBC>		; Get number of bytes in transfer
	JUMPE	T2,.POPJ		; If no bytes transfered .. just return

	LOAD	S2,T1,BP.SIZ		; Get size of bytes
	LOAD	S1,T1,BP.POS		; Get position of first byte
	HRRZ	T1,T1			; Get base address of buffer

	MOVEI	T3,4			; Default to 4 bytes per word
	CAIE	S2,^d8			; Check if it's correct
	 MOVEI	T3,5			;  No .. assume it's ASCII then
	IDIV	S1,S2			; Find number of bytes in first word
	SKIPN	S1			; Check if any
	 AOS	T1			;  No .. move onto next word
	ADD	T2,T3			; Calculate number of words
	SUBI	T2,1(S1)		; by dividing by number of bytes
	IDIV	T2,T3			; in word, also taking into
	AOS	T2			; account bytes non-aligned in 1st word
	$RET
; Routine - WRTHDR
;
; Function - To stamp the entry with time, phase and entry length.
;	For the format see the entry descriptions above.
;
; Parameters -
;
;	T2/	Length of data portion in words

WRTHDR:	MOVE	S1,T2			; Get length into RH
	ADDI	S1,FIXLEN		; Add length of total header block
	HLL	S1,T4			; Put flags into LH
	$CALL	LOGWRT			; Write first word in entry
	$CALL	I%NOW			; Get current time
	PJRST	LOGWRT			; Write into entry and return
; Routine - WRTTRN
;;
; Function - To write the transaction header.  This consists of either the
;	CAL11. argument block, or the port number and XMT/RCV header.
;
; Parameters -
;
;	P2/	Handle list entry address
;	T4/	Flags

WRTTRN:	MOVE	S1,PNTSAV		; Get byte pointer to data
	$CALL	LOGWRT			; Only need left half, but write it all

TOPS20 <LOAD	S1,(P2),H$PRT		; Get port number
	$CALL	LOGWRT			; Write it out
	MOVE	S1,(T4)			; Get first 4 bytes of header
	$CALL	LOGWRT			; Write it
	MOVE	S1,1(T4)		; Get last 2 bytes of header
	PJRST	LOGWRT			; Write it and return
    > ;End if TOPS20

TOPS10 <MOVE	T3,T4			; Get address of CAL11. block
	HRLI	T3,-C$SIZ		; Get size of block
TRNLP:	MOVE	S1,0(T3)		; Get next word in block
	$CALL	LOGWRT			; Log it
	AOBJN	T3,TRNLP		; Loop until all copied
	$RET
    > ;End it TOPS10
; Routine - WRTDAT
;
; Function - To write the data buffer portion of an entry if needed.
;	The "need" is determined by the length of the data buffer in words.
;	i.e. if zero - it is not needed.
;
; Parameters -
;
;	T1/	Address of data buffer
;	T2/	Length of data buffer in words

WRTDAT:	JUMPE	T2,.POPJ		; If no words .. don't write them
	MOVN	T2,T2			; Get negative length
	HRL	T1,T2			; Make AOBJN loop pointer
WRTD.1:	MOVE	S1,0(T1)		; Get next word in buffer
	$CALL	LOGWRT			; Write it to log
	AOBJN	T1,WRTD.1		; Loop until data buffer exhausted
	$RET
; Routine - WRTMRK
;
; Function - This is a global routine that allows a "MARK" to be put into
;	the data log file.
;
; Parameters -
;
;	S1/	Mark location number/name.
;
;	If the mark number has any bits on in the upper 6 bits, it is
;	interpreted as being a SIXBIT location name.

WRTMRK::$SAVE	<S1,S2,P1>		; Save needed registers

	MOVE	P1,S1			; Save mark location
	$CALL	CHKSTA			; Check logging status
	 JUMPF	.POPJ			;  If off .. just return
	MOVE	S1,[PHSMRK+4]		; "MARK" entry 3 words long
	$CALL	LOGWRT			; Write the mark entry
	$CALL	I%NOW			; Get current time
	$CALL	LOGWRT			; Put into entry
	MOVE	S1,P1			; Get mark location back
	$CALL	LOGWRT			; Write it out
	AOS	S1,MRKCNT		; Get mark number
	PJRST	LOGWRT			; Write it and return
; Routine - WRTSKD
;
; Function - To log all tasks as they get scheduled in IBMSPL.  This allows
;	the analysis of tasks scheduling efficiency.  To use this routine
;	a hook into IBMSPL must be made with DDT at OKSCHD:
;
;	GET IBMSPL				; Loaded with FELOG
;	DDT
;	OKSCHD/	HRRZM S2,CURATE  $<
;	PAT../	PUSHJ P,WRTSKD$>
;
;	Then LOGFLG must be set to the appropriate non-zero value.
;
; Parameters -
;
;	TK/	Task block address
;	T2/	Flags task was woken on
;	T3/	Wakeup time task was scheduled for

	TK==15				; Define task block pointer register

WRTSKD::$SAVE	<S1,S2>			; Save needed registers

	$CALL	CHKSTA			; Check logging status
	 JUMPF	.POPJ			;  If off .. just return
	MOVE	S1,[PHSSKD+5]		; "MARK" entry 4 words long
	$CALL	LOGWRT			; Write the mark entry
	$CALL	I%NOW			; Get current time
	$CALL	LOGWRT
	MOVE	S1,TK			; Get task block address
	$CALL	LOGWRT
	MOVE	S1,T2			; Get task woken flags
	$CALL	LOGWRT
	MOVE	S1,T3			; Get task wakeup time
	PJRST	LOGWRT			; Write and return
; Routine - LOGWRT
;
; Function - To write a word into the log buffer and output the buffer
;	to the actual log file when the buffer is full.
;
; Parameters -
;
;	S1/	Word to write to log file
;	LOGPTR/	AOBJN pointer into log buffer

LOGWRT:	MOVE	S2,LOGPTR		; Get pointer into log buffer
	MOVEM	S1,0(S2)		; Store word into buffer
	AOBJP	S2,LOGOUT		; Check for buffer full
	MOVEM	S2,LOGPTR		; Store pointer to log buffer
	$RET				; Return

LOGOUT:	HRRZ	S2,LOGPTR		; Get last address used in buffer
	SUB	S2,LOGBUF		; Calculate words in buffer
	HRLZI	S2,1(S2)		; Point into left half
	JUMPE	S2,LOGCOM		; If no words in buffer .. ignore
	HRR	S2,LOGBUF		; Point to start of buffer (RH)
	MOVE	S1,LOGIFN		; GALAXY IFN for log file
	$CALL	F%OBUF			; Write out the buffer
	 JUMPF	[$STOP CWL,<Can't write to log file>]
LOGCOM:	MOVE	S1,LOGHLD		; Reset pointer to log buffer
	MOVEM	S1,LOGPTR		; Store pointer to log buffer
	$RET				; Return
; Routine - LOGOPN
;
; Function - To open the log file.
;
; Parameters - none
;
; Notes -
;
;	The file LOG:FELOG.DAT is used for logging unless the device LOG:
;	doesn't exist.  If LOG: doesn't exist the file DSK:FELOG.DAT is used.


LOGOPN:	DMOVE	S1,[EXP 2,LOGFOB]	; Point to FOB for LOG: file
	$CALL	F%OOPN			; Try to open file
	 JUMPF	[DMOVE	S1,[EXP 2,DSKFOB]
		 $CALL	F%OOPN		; Didn't find the LOG: device .. so try
		  JUMPF	LOGERR		;  DSK: .. die if DSK: not found either
		 JRST	.+1]		; Continue on with log file opening
	MOVEM	S1,LOGIFN		; Store IFN pointing to log file
	SETOM	FEFLG			; Set flag saying log file is open
	$CALL	M%GPAG			; Get a buffer page
	MOVEM	S1,LOGBUF		; Save address of buffer
	HRLI	S1,-1000		; Make AOBJN pointer
	MOVEM	S1,LOGPTR		; Initialize pointer for LOGWRT
	MOVEM	S1,LOGHLD		; Save another copy for LOGWRT
	MOVE	S1,[%%.FLG]		; Get FELOG version number
	$CALL	LOGWRT			; Write it as first word in file
	$RET				; Return

LOGERR:	$STOP	COL,<Can't open log file on either LOG: or DSK:>
; Routine - LOGCLS
;
; Function - This routine closes the log file after writing any data that
;	has been logged into the buffer but not previously output.

LOGCLS:	SETZM	S1			; Stick a 0 word at end of stream
	$CALL	LOGWRT			; Write it out
	$CALL	LOGOUT			; Insure that buffer has been flushed
	SETZM	FEFLG			; Clear the log file open flag
	MOVE	S1,LOGIFN		; Get GALAXY log file IFN
	PJRST	F%REL			; Release and close log file and return
	SUBTTL	CHKSTA -- Check and change logger state

; Routine - CHKSTA
;
; Function - To compare the state in LOGFLG against the current state
;	in FEFLG.  If the state is to be changed, the log file is either
;	opened or closed.
;
; Returns - True if logging is now on
;	    False if logging is off

CHKSTA:	SKIPL	LOGFLG			; Check if logging to be on
	 JRST	[SKIPN FEFLG		;  No .. check if already off
		  $RETF			;    Yes .. just say so by false return
		 $CALL LOGCLS		;   Close log file
		 $RETF]			;  And return logging off flag
	SKIPN	FEFLG			; Check if already on
	 $CALL	LOGOPN			;  No .. so open log file
	$RETT				; Now say logging is on
	SUBTTL	Data area

FEFLG:	BLOCK	1			; 0 = not logging, -1 = logging
PNTSAV:	BLOCK	1			; Last data byte pointer seen
MRKCNT:	BLOCK	1			; Incremental count of "MARK"s

LOGIFN:	EXP	0
LOGFOB:	LOGFDB
	EXP	^D36
LOGFDB:
TOPS10 <XWD	6,0
	SIXBIT	/LOG/
	SIXBIT	/FELOG/
	SIXBIT	/DAT/
	EXP	0
	EXP	0
    >;end if TOPS10
TOPS20 <XWD	4,0
	ASCIZ	/LOG:FELOG.DAT/
    >;end if TOPS20

DSKFOB:	DSKFDB
	EXP	^D36
DSKFDB:
TOPS10 <XWD	6,0
	SIXBIT	/DSK/
	SIXBIT	/FELOG/
	SIXBIT	/DAT/
	EXP	0
	EXP	0
    >;end if TOPS10
TOPS20 <XWD	4,0
	ASCIZ	/DSK:FELOG.DAT/
    >;end if TOPS20

LOGVER:	%%.FLG				; Set a word with version number in it.
LOGPTR:	BLOCK	1			; AOBJN pointer to next word in buffer
LOGHLD:	BLOCK	1			; Copy of LOGPTR to restore after writes
LOGBUF:	BLOCK	1			; Address of log buffer

	XLIST				; Put literals here w/o listing
	LIT
	LIST
	END
; Local Modes:
; Mode:MACRO
; Comment Column:40
; Comment Start:;
; End: