INCLUDE "SS0302S_SSOWNF"
! %RECORDFORMAT SSOWNF(%INTEGER SSMONAD,DIAGMON)
! %EXTRINSICRECORD(SSOWNF) SSOWN
!
!
! Template primitives.
! ======== ==========
!
! The following entities are recognised:
! a) Routine/fn parameters.
! I - Integer, print value in decimal
! i - Integer, print value in hex
! L - Longinteger, print value in decimal
! l - Longinteger, print value in hex
! S - String or stringname
! N - %NAME parameter, integer or longinteger, print decimal
! n - %NAME parameter, integer or longinteger, print hex
! V - Byte vector (records), print first 72 bytes hex if record>72
! F - Integername to be treated as ss error flag, print flag (dec) followed
! by failure message.
!
! b) Function results. (These are template terminators)
! R - Function result, treated as N if integer or longinteger function,
! S if a string function
! r - Function result, treated as n if integer or longinteger function,
! S if a string function
! Q - Integer function result which is to be treated as ss error flag, output
! as F
! U - Function result to be treated as byte vector, i.e. %RECORD()%FN, output
! as V
!
! c) Others.
! 4 - Skip 4 words on stack, e.g. %routinename or %arrayname parameters
! 2 - Skip 2 words on stack, e.g. unwanted %record or other %name parameter.
! - (or anything else) - Skip 1 word on stack, e.g. uninteresting %integer etc.
!
!
CONSTBYTEINTEGERARRAY ONE CASE(0 : 127) = C
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127;
!
CONSTINTEGER MAXLL=132
!
!
RECORDFORMAT HDRF(INTEGER DATAEND,DATASTART,SIZE,TYPE,PASS1,DATETIME, C
NEXTCYC,SEMA)
SYSTEMROUTINESPEC CHOPLDR(STRINGNAME A, INTEGER I)
SYSTEMROUTINESPEC MOVE(INTEGER LEN,FROM,TO)
SYSTEMSTRINGFNSPEC FAILUREMESSAGE(INTEGER I)
SYSTEMSTRING (8)FNSPEC HTOS(INTEGER VALUE,PLACES)
SYSTEMSTRINGFNSPEC ITOS(INTEGER I)
EXTERNALINTEGERFNSPEC DDELAY(INTEGER SECS)
EXTERNALINTEGERFNSPEC UINFI(INTEGER I)
EXTERNALSTRINGFNSPEC DATE
EXTERNALSTRINGFNSPEC TIME
!
stringfn LITOS ( longinteger I )
! Same as ITOS but for long integers
string (1) SIGN
string (63) S
if I < 0 then I = -I and SIGN = "-" else SIGN = ""
S = ""
S = TOSTRING ( I - I // 10 * 10 + '0' ).S and I = I // 10 until I = 0
result = SIGN.S
end ; ! of stringfn LITOS
!
!
{%EXTERNAL}SYSTEMROUTINE WRLOG(STRING (255) ENTRY)
RECORD (HDRF)NAME H
INTEGER FLAG,SSMONAD,ASEMA,LEN,AD,AVAIL,MAXTRIES
SSMONAD=SSOWN_SSMONAD
H==RECORD(SSMONAD)
AD=ADDR(ENTRY)
LEN=BYTEINTEGER(AD); ! Entry length
AD=AD+1; ! 1st byte of ENTRY
MAXTRIES=3
! Try to claim the semaphore
! Construct a descriptor to it
ASEMA=SSMONAD+28; ! Address of the semaphore.
AGAIN:
*LDTB_X'28000001'; ! Load descriptor type and bound
*LDA_ASEMA; ! Load descriptor address
*INCT_(DR ); ! Increment and test descriptor
*JCC_7,<WAIT>; ! Jump to label WAIT on condition code 7 i.e. H_SEMA>0
! Got the semaphore if here.
! See if there is room for ENTRY without wrapround
AVAIL=H_DATAEND-H_NEXTCYC
IF AVAIL>=LEN THEN START
MOVE(LEN,AD,SSMONAD+H_NEXTCYC)
H_NEXTCYC=H_NEXTCYC+LEN
FINISH ELSE START
! Wrapround required
MOVE(AVAIL,AD,SSMONAD+H_NEXTCYC)
H_NEXTCYC=H_DATASTART
MOVE(LEN-AVAIL,AD+AVAIL,SSMONAD+H_NEXTCYC)
H_NEXTCYC=H_NEXTCYC+LEN-AVAIL
H_PASS1=0; ! To show that wrapround has occurred at least once
FINISH
! Now release the semaphore
*LDTB_X'28000001'
*LDA_ASEMA
*LSS_-1; ! Load ACC with -1
*ST_(DR ); ! Store it in H_SEMA
RETURN
WAIT:
RETURN IF MAXTRIES=0; ! Give up meantime - Think about this
! Wait for 1 second then try again
FLAG=DDELAY(1)
MAXTRIES=MAXTRIES-1
->AGAIN
END ; ! OF WRLOG
!
!
{%EXTERNAL}SYSTEMROUTINE SSTRACE(NAME FNRESULT, STRING (63) TEMPLATE)
STRING (63) STEM
INTEGER LNB,LNBHERE,GLA,BASE,J,AD,CH,UC,SIZECODE,ADE,ADR,AVAIL,FN
INTEGER W,W1,I,L
LONGINTEGERNAME LW
BYTEINTEGERARRAY E,R(0:255)
STRINGNAME ENTRY,RES
BYTEINTEGERNAME LE,LR
SWITCH PARMTYPE(0:127)
RETURN IF TEMPLATE="NIL"
FN=0; ! This is set to -1 if E is found in the template
LW==LONGINTEGER(ADDR(W))
ADE=ADDR(E(0))
ENTRY==STRING(ADE)
LE==BYTEINTEGER(ADE)
ADE=ADE+1
ADR=ADDR(R(0))
RES==STRING(ADR)
LR==BYTEINTEGER(ADR)
ADR=ADR+1
E(133)=X'0A'
*STLN_LNBHERE; ! LNB of SSTRACE
LNB=INTEGER(LNBHERE); ! LNB of the routine to be monitored
BASE=LNB+16
GLA=INTEGER(BASE); ! Pointer to GLA
STEM="DT: ".DATE." ".TIME." ".ITOS(UINFI(11))."/".ITOS(UINFI(13)).": "
! Recover routine name
AD=INTEGER(LNB+12)&X'00FFFFFF'+INTEGER(GLA+12)+12
ENTRY=STEM.STRING(AD)
J=0
WHILE J<LENGTH(TEMPLATE) CYCLE
EXIT IF FN#0
BASE=BASE+4
! PRINTSTRING("*BASE* ".HTOS(BASE,8)."
! ")
LE=LE+1
IF J=0 THEN E(LE)=' ' ELSE E(LE)=','
LE=LE-1 IF FN<0
J=J+1
CH=CHARNO(TEMPLATE,J)
UC=ONE CASE(CH)
W=INTEGER(BASE)
W1=INTEGER(BASE+4)
RES=""
->PARMTYPE(UC)
PARMTYPE('U'): ! Result of fn to be treated as byte vector
PARMTYPE('Q'): ! Result of fn to be treated as ss error flag
PARMTYPE('R'): ! Result of function
FN=-1
BASE=LNBHERE+20; ! Fn result is the first parm to SSTRACE
E(LE)=' '
RES="%res="
W=INTEGER(BASE)
W1=INTEGER(BASE+4)
IF UC='Q' THEN UC='F' AND ->PARMTYPE('F') ELSE C
IF UC='U' THEN ->PARMTYPE('V') ELSE ->PARMTYPE('N')
PARMTYPE('4'): ! Skip 4 words i.e. Array or Routinename
! Note that arrays have 2 descriptors one to the array, one to the
! dope vector, whereas routines have a descriptor followed by 2 words
BASE=BASE+12
CONTINUE
PARMTYPE('2'): ! Skip 2 words i.e. Record or unwanted %name param
BASE=BASE+4
CONTINUE
PARMTYPE('F'): ! Subsystem %integername flag params
CH=UC
PARMTYPE('N'): ! Other %name parameters
! Find out what type first
SIZECODE=(W>>27)&7
IF FN#0 AND SIZECODE=3 THEN {%result of stringfn} ->PARMTYPE('S') ELSE C
IF SIZECODE=5 THEN START
! Integername
W=INTEGER(W1)
BASE=BASE+4
->PARMTYPE('I')
FINISH ELSE IF SIZECODE=6 THEN START
! Longintegername
W=INTEGER(W1)
W1=INTEGER(W1+4)
->PARMTYPE('L')
FINISH ELSE START
! Anything else
BASE=BASE+4
CONTINUE
FINISH
PARMTYPE('I'): ! Integer
IF CH=UC THEN RES=RES.ITOS(W) ELSE RES=RES."X".HTOS(W,8)
IF CH='F' THEN START
IF W>0 THEN RES=RES.FAILUREMESSAGE(W) ELSE C
IF W=0 THEN RES=RES." OK"
FINISH
->ADD
PARMTYPE('L'): ! Longinteger
IF CH=UC THEN RES=RES.LITOS(LW) ELSE RES=RES."X".HTOS(W,8)." ".HTOS(W1,8)
BASE=BASE+4
->ADD
PARMTYPE('S'): ! String and stringname
RES=RES.STRING(W1)
BASE=BASE+4
->ADD
PARMTYPE('V'): ! Byteinteger vector (for records)
L=W&X'00FFFFFF'; ! Vector len
L=72 IF L>72
FOR I=0,1,L-1 CYCLE
RES=RES.HTOS(BYTEINTEGER(W1+I),2)
REPEAT
BASE=BASE+4
->ADD
ADD:
!PRINTSTRING("*LE*/*LR* ".ITOS(LE)."/".ITOS(LR)."
!")
WHILE LE+LR>=MAXLL CYCLE
AVAIL=MAXLL-LE
!PRINTSTRING("*AVAIL* ".ITOS(AVAIL)."
!")
MOVE(AVAIL,ADR,ADE+LE)
LE=133
WRLOG(ENTRY)
ENTRY=STEM
CHOPLDR(RES,AVAIL)
REPEAT
ENTRY=ENTRY.RES
PARMTYPE(*):
REPEAT
ENTRY=ENTRY.TOSTRING(10)
WRLOG(ENTRY)
RETURN
END ; ! OF SSTRACE
ENDOFFILE