.TITLE SPY -- AN RSX ACCOUNTING TASK .IDENT ^02.2^ ; ; YALE UNIVERSITY -- DEPT OF MOLECULAR BIOCHEMISTRY AND BIOPHYSICS ; BOX 1937 YALE STATION -- ROOM 200 KLINE BIOLOGY TOWER ; NEW HAVEN, CT. 06511 ; ; THIS WORK WAS MADE POSSIBLE BY NIH GRANT #USPHS-GM-22778-03 ; AND BY W.E.R.M.S. ; ; VERSION 02 FEB. 13, 1978 A. PERLO ; VERSION 2 IS A COMPLETE REWRITE OF VERSION 1, INCORPORATING ; TERMINAL TRACKING AND SYSTEM TRACKING IN ADDITRION TO TASK ; TRACKING. ; CREDIT IS DUE TO GREG BASSETT OF DEC, FROM WHOM I BORROWED ; ALMOST INTACT THE SYSTEM TRACKING CODE, AND SOME OF THE CONCEPTS ; USED IN THE TERMINAL TRACKING CODE. THESE CONCEPTS WERE FOUND ; IN HIS PROGRAM ACCLOG, RELEASED BY DECUS. ; ; VERSION 02.1 APRIL 4, 1978 ; FIXED END OF ATL RECOGNITION IN RPTTSK FOR V3.1 ; ; VERSION 02.2 JULY 19,1978 ; FIXED SYSTEM-USER-NULL COUNTER IN CLKCOD FOR ; FOR RSX VERSION 3.1 ; .SBTTL MACROS AND DEFINITIONS ; ; DEFINITIONS: ; MAXTSK = 16. ;MAXIMUM NUMBER OF TASKS REPORTABLE (LIMITS ; SIZE OF SPYRC2 BUFFER) MINCHR = 5. ;MINIMUM NUMBER OF INPUT CHARACTERS REQUIRED TO ; INDICATE AN ACTIVE TERMINAL. SPYLUN = 1 ;LUN TO USE FOR FILE STIME = 5. ;NUMBER OF MINUTES BETWEEN REPORTS PMODE = 30000 ;INDICATES USER MODE IN PSW $$CVEC = 100 ;LINE FREQUENCY CLOCK INTERRUPT VECTOR ADDRESS ; ; DEFINITION MACROS ; .MCALL TCBDF$,PCBDF$,HDRDF$ .MCALL HWDDF$,UCBDF$,DCBDF$,SCBDF$ TCBDF$ PCBDF$ HDRDF$ HWDDF$ UCBDF$ DCBDF$ SCBDF$ .MCALL CALL,CALLR,RETURN ; ; CALL EXECUTIVE MACROS ; .MCALL DSAR$S,ENAR$S,ASTX$S ;AST MACROS .MCALL DIR$,MRKT$,SPND$S,EXIT$S,GTIM$S .MCALL QIOW$ ; ; I/O MACROS ; .MCALL FSRSZ$,FDBDF$,FDAT$A,FDOP$A,NMBLK$ .MCALL OPEN$,CLOSE$,OFID$A,PUT$ ; ; LOCALLY-DEFINED MACROS ; .MACRO MSG STRING ; MOV #STRING,QDIR+Q.IOPL MOV #L'STRING,QDIR+Q.IOPL+2 DIR$ #QDIR .ENDM .SBTTL LOCAL DATA AND BUFFER AREA .PSECT ; ; I/O DATA BASE ; FSRSZ$ 1 ;1 BUFFER SPYFDB: FDBDF$ ;DEFINE AN FDB FDAT$A R.VAR,FD.BLK ;FILE ATTRIBUTES FDOP$A SPYLUN,SPYDDS,,FO.APD SPYDDS: .WORD 0,0 ;TKB SPECIFIES DEVICE .WORD SZ2,SPYDIR ;UIC SPYDIR .WORD SZ1,SPYNAM ;NAME SPECIFIED BY SPYNAM SPYNAM: .ASCII /SPY.DAT/ SZ1=.-SPYNAM SPYDIR: .ASCII /[6,10]/ SZ2=.-SPYDIR .EVEN ; ;DIRECTIVES: ; MDIR: MRKT$ ,STIME,3,TMO ;AST AT TMO IN STIME MINUTES QDIR: QIOW$ IO.WBT,2,1,,,, ; ; LOCAL VARIABLES IMPURE AREA FOR TT TRACKING AND SYSTEM TRACKING ; BASEAD: .WORD 0 ;HOLDS START OF INTERRUPT HANDLING CODE NUNITS: .WORD 0 ;NUMBER OF TT UNITS IN SYSTEM BUFSIZ: .WORD 0 ;SIZE OF CORE BLOCK USED FOR INTRPT HANDLNG CODE CLKAD: .WORD 0 ;ADDR OF START OF CLOCK INTERRUPT CODE ; ;ERROR MESSAGES ; MSG1: .ASCII /SPY ENCOUNTERED ERROR# / ERRCOD: .BYTE 60 .ASCII /. SPY IS DEAD./ LMSG1 = .-MSG1 MSG2: .ASCII /SPY: NORMAL EXIT/ LMSG2 = .-MSG2 .EVEN ; ;BUFFERS ; SPYRC1: ;TYPE 1 REC WRITTEN WHENEVER ANY ACTIVITY ; (ACTIVE TASKS OR TERMINALS) PRESENT. .WORD 3 ;FOR FTN - THIS IS BOTH 1ST AND LAST PHYS REC ; IN LOGICAL RECORD (SEE F4P OTS REF. CH. 3) DATE: .BLKB 5 ;YR,MO,DA,HR,MIN NTASKS: .BLKB ;NUMBER OF TASKS RECORDED SYST: .BLKW 3 ;NUMBER OF TICS FOR SYSTEM,USER,NULL TERMS: .BLKW ;MASK WORD SHOWING ACTIVE TERMINALS LREC1 = .-SPYRC1 ; SPYRC2: ;FOLLOWS SPYRC1 IF NTASKS .NE. 0 .WORD 3 ;FTN-COMPATABILITY .BLKW MAXTSK ; 3 WORDS FOR EACH TASK REPORTED .BLKW MAXTSK ; 1ST AND LAST 3 CHARS OF NAME IN R50 (2 WORDS) .BLKW MAXTSK ; FOLLOWED BY GROUP AND USER ID (2 BYTES) ; (USER IS LOW, GRP HIGH BYTE) .SBTTL PROGRAM INITIATION ; ; THIS IS THE SPY STARTUP CODE. IT MERELY CALLS ALL THE MERRY ; SPYLETS' INITIATION CODES, CHECKS FOR ERRORS, AND GOES TO ; SLEEP, ALLOWING THE AST ROUTINES TO DO THE ACTUAL WORK. WHEN ; IT WAKES UP AGAIN, IT IS ONLY TO EXIT. ; .ENABL LSB SPY:: CALL SETFIL ;SET UP FILE BCS 25$ DIR$ #MDIR ;START TIMER FOR 2 MINUTES BCS 30$ CALL SETTSK ;SET UP FOR TASK TRACKING BCS 15$ CALL SETSYS ;SET UP FOR SSTEM STATS BCS 10$ CALL SETTT ;SET UP FOR TT TRACKING BCS 5$ SPND$S ;GO TO SLEEP SPYDON: MSG MSG2 ; "SPY: NORMAL EXIT." SPYOUT: CALL FINTT ;DIS-ENTANGLE THE TT'S CALL FINSYS ;DIS-ENTANGLE SYSTEM TRACKING CALL FINTSK ;DIS-ENTANGLE TASK TRACKING EXIT$S ; ;ERROR PROCESSING ; ERR9: INCB ERRCOD ;ERROR 9 -- FILE OPEN FAIL IN TMO ERR8: INCB ERRCOD ;ERROR 8 -- FILE FAILURE IN TMO ERR7: INCB ERRCOD ;ERROR 7 -- MKTM$ FAILURE IN TMO HANDLER 5$: INCB ERRCOD ;ERROR 6 -- SETTT FAILURE 10$: INCB ERRCOD ;ERROR 5 -- UNABLE TO SET UP SYSTEM TRACKING 15$: INCB ERRCOD ;ERROR 4 -- UNABLE TO SET UP TASK TRACKING ERR3: INCB ERRCOD ;ERROR 3 -- CURRENTLY UNUSED 25$: INCB ERRCOD ;ERROR 2 -- UNABLE TO SET UP FILES 30$: INCB ERRCOD ;ERROR 1 -- UNABL TO START TIMER MSG MSG1 ;"SPY ENCOUNTERED ERROR# N ..." BR SPYOUT .DSABL LSB .SBTTL TMO - TIMEOUT AST CODE ; ; THIS CODE IS ENTERRED EVERY 5 MINUTES VIA AN AST FROM A MRKT$. ; IT IS THE CODE THAT ACTUALLY COLLECTS DATA AND WRITES IT OUT TO THE ; SPY.DAT FILE FOR PERMANENT RECORDING. IT ALSO SETS UP ANOTHER ; 5-MINUTE TIMEOUT. ; BEFORE EXITING, THE TOP WORD OF THE STACK MUST BE POPPED. ; TMO: DSAR$S ;LOCK OUT OTHER AST'STILL WE'RE DONE DIR$ #MDIR ;KICK AGAIN IN 5 MINUTES BCS ERR7 ;IF ERROR, WE DIE MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) CALL RPTTIM ;FILL IN TIME OF DAY CALL RPTTSK ;REPORT TASKS CALL RPTSYS ;REPORT SYSTEM STATUS CALL RPTTT ;REPORT TT ACTIVITY CALL REPORT ;TELL IT ALL TO SPY.DAT BCS ERR8 ;IF REPORTING FAILURE MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 TST (SP)+ ENAR$S ;ENABLE AST'S ASTX$S ;DEPART MODESTLY IF POSSIBLE .SBTTL FILE HANDLING ROUTINES: SETFIL,REPORT SETFIL: ;SET UP FOR FILE PROCESSING OPEN$ #SPYFDB ;OPEN THE FILE TO GET ITS ID BCC 5$ ;IF OPEN WAS A SUCCESS MOVB #FO.WRT,F.FACC(R0) ;ASSUME NO SUCH FILE: OPEN A NEW ONE CMPB #IE.NSF,F.ERR(R0) ;FAILURE BECAUSE OF NO SUCH FILE? BEQ SETFIL ;IF SO, OPEN IT AS NEW SEC ;INDICATE ERROR BR 20$ 5$: CLOSE$ #SPYFDB ;NOW CLOSE IT - WE DON'T WANT IT NOW. 20$: RETURN ; ; REPORT - ; THIS SUBROUTINE MAKES ANY NECESSARY REPORTS. ; REPORT: TSTB NTASKS ;ANYTHING TO REPORT BGT 10$ ;BRANCH IF YES TST TERMS ;ANYTHING TO REPORT BEQ 40$ ;BRANCH IF NOT 10$: OFID$A #SPYFDB,,,,,, ;OPEN THE FILE BCS ERR9 MOV #1,R2 ;ERROR FLAG - ASSUME ERROR PUT$ #SPYFDB,#SPYRC1,#LREC1 ;WRITE OUT FIRST REC BCS 15$ MOVB NTASKS,R1 ;GET NUMBER OF TASKS IN BUF BEQ 12$ ;IF NONE, THERE'S NOTHING TO WRITE MUL #6,R1 ;6 BYTES FOR EACH TASK IN BUF ADD #2,R1 ;PLUS 2 BYTES FOR FORTRAN-COMPATABILITY WORD PUT$ #SPYFDB,#SPYRC2,R1 ;WRITE IT OUT BCS 15$ 12$: CLR R2 ;INDICATE NO ERRORS SO FAR 15$: CLOSE$ #SPYFDB ;CLOSE THE FILE BCS 80$ TST R2 ;ANY ERRORS? BNE 80$ ;YES 40$: CLC BR 90$ 80$: SEC 90$: RETURN .SBTTL TASK TRACKING ROUTINES: SETTSK,FINTSK,RPTTSK ; SETTSK: FINTSK: CLC ;DUMMIES RETURN ; RPTTSK: CALL $LOCKL ;LOCK SYSTEM LISTS MOV #SPYRC2+2,R0 ;LET R0 -> REPORTING BUFFER CLRB -(SP) ;USE FOR TASK COUNTER MOV $ACTHD,R2 ;R2 -> TCB OF NEXT ACTIVE TASK 10$: BIT #TS.OUT,T.STAT(R2) ;IF ITS NOT IN CORE BNE 20$ ;WE DON'T WANT IT REPORTED BIT #T3.PRV,T.ST3(R2) ;AND IF IT IS PRIVILEDGED BNE 20$ ;WE DON'T WANT IT REPORTED MOV T.NAM(R2),(R0)+ ;FETCH FIRST 3 LATTERS OF TSKNAME MOV T.NAM+2(R2),(R0)+ ;AND REST OF NAME MOV T.PCB(R2),R1 ;LET R1->PCB MOV P.HDR(R1),R1 ;NOW LET R1-> TASK HEADER MOV H.CUIC(R1),(R0)+;REPORT CURRENT UIC OF TASK INC @SP ;INCREMENT TASK COUNT CMP @SP,#MAXTSK ;DO WE HAVE ROOM FOR MORE? BGE 40$ ;I NOT, FORGET THE REST 20$: MOV T.ACTL(R2),R2 ;MOVE UP ACTIVE TASK LIST TST T.ACTL(R2) ;ARE WE AT NULL TASK? ;V02.1 BNE 10$ ;IF THERE ARE ANY MORE, DO IT AGAIN 40$: MOVB (SP)+,NTASKS ;GET NTASKS CALL $UNLKL ;UNLOCK SYSTEM LISTS CLC RETURN .SBTTL TT TRACKING ROUTINES: SETTT,FINTT,RPTTT ; ; THE IDEA HERE IS TO KEEP ACOUNT EVERY TIME SOMETHING IS TYPED ON ; A TERMINAL. TO DO THIS, FOR EACH TT, WE STEAL THE TT INPUT INTERRUPT ; AND INCREMENT A COUNTER, THEN RETURN TO THE NORMAL TT DRIVER ; INTERRUPTPROCESSOR. ; THE ACTUAL CODE TO PROCESS THE STOLEN INTERRUPT IS VERY SHORT. ; ONE COPY OF IT IS STASHED IN THE EXEC'S POOL SPACE FOR EACH TT, MAKING ; IT IMPERVIOUS TO THE CHECKPOINTABILITY OF SPY. ; .SBTTL ...SETTT - SET UP INTERRUPT BLOCKS ; SETTT: CLR BASEAD ;INIDCATE NO CORE BLOCK FOUND YET ; ; FIND TERMINAL DCB ; MOV #.TT0,R4 ;LET R4 -> UCB FOR TT0 MOV U.DCB(R4),R4 ;NOW LET R4 -> DCB FOR TTDRV ; ; FIND OUT HOW MANY WE HAVE ; MOVB D.UNIT+1(R4),R5 ;GET HI UNIT NUMBER MOVB D.UNIT(R4),R2 ;AND LOW UNIT# SUB R2,R5 INC R5 ;R5 NOW HAS NUMBER OF TT'S ; ; ALLOCATE SPACE FOR INTERRUPT CODE ; MOV #CODEND-CODE,R1 ;GET SPACE NEEDED PER UNIT MUL R5,R1 ;TIMES NUMBER OF UNITS MOV R5,NUNITS ;SAVE NUMBER OF UNITS MOV R1,BUFSIZ ;SAVE TOTAL SPACE NEEDED CALL $SWSTK,5$ ;SWITCH TO SYSTEM STACK TO ALOCB CALL $ALOCB ;;ALLOCATE CORE BLOCK: RETURNS WE HOPE ;; WITH R0->CORE BLOCK ALLOCATED BCS 4$ ;;IF WE FAILED MOV R0,BASEAD ;;SAVE BLOCK ADDR 4$: RETURN ;;FROM SYSTEM STACK 5$: MOV BASEAD,R0 ;PICK UP BLOCK ADDR AGAIN BEQ 45$ ;IF NO BLOCK WAS FOUND ; ; SET UP INTERRUPT THEFT CODE FOR EACH TT ; MOV D.UCBL(R4),-(SP);SAVE UCB LANGTH MOV D.UCB(R4),R4 ;LET R4 -> UCB MOV #VECAD-CODE,R1 ;GET OFFSET OF VECAD IN CODE BLOCK ASR R1 ;CONVERT TO WORDS ; ; AT THIS POINT: ; R0 -> FREE PART OF CORE BLOCK ; R1 == # WORDS OF CODE TO TRANSFER ; R4 -> NEXT UCB ; R5 == # OF UNITS LEFT TO SET UP ; @SP = LENGTH OF UCB 10$: MOV R1,R3 ;USE R3 FOR COUNTER MOV R0,-(SP) ;SAVE ADDR OF START OF INTRPT BLOCK MOV #CODE,R2 ;R2 -> CODE BLOCK 15$: MOV (R2)+,(R0)+ ;TRANSFER CODE TO INTERRUPT BLOCK SOB R3,15$ MOV U.SCB(R4),R3 ;LET R3 -> SCB MOVB S.VCT(R3),R3 ;NOW R3 HAS INTRPT VEC/4 ASL R3 ASL R3 ;NOW R3 HAS INTRPT VEC ADDR MOV R3,(R0)+ ;SAVE IT MOV @R3,(R0)+ ;SAVE ADDR OF TT INTERRUPT RTN MOV (SP)+,@R3 ;STEAL THE INTERRUPT! ADD @SP,R4 ;R4 -> NEXT UCB (IF ANY) DEC R5 ;WERE THERE ANY MORE? BGT 10$ ;YES -- SET UP THE NEXT ; TST (SP)+ ;CLEAN STACK CLC ;INDICATE SUCCESS BR 50$ 45$: SEC ;INDICATE FAILURE 50$: RETURN ; ; INTERRUPT HANDLING CODE BLOCK ; ; ONE OF THESE BLOCKS OF CODE IS SET UP IN THE ;ALLOCATED CORE BLOCK FOR EACH TT PRESENT. THE TT VECTOR IS POINTED ;DIRECTLY TO OUR CODE BLOCK. AFTER INCREMENTING THE IO COUNTER, ;WE MUST TRANSFER CONTROL TO THE ORIGINAL TTDRV INTERRUPT LOCATION. ;HOWEVER, WE MUST ALSO PASS TO TTDRV THE UNSULIED PS WHICH WAS LOADED ;AT INTERRUPT TIME. IT IS FOR THIS REASON THAT WE FAKE AN RTI. ; CODE: MOV @#PS,-(SP) ;SAVE PS INC IOCNT ;RECORD THE EVENT MOV IVEC,-(SP) ;SET UP FOR RTI RTI ;POPS CONTENTS OF IVEC INTO PC, AND ; RESTORES PS INTO THE PS IOCNT: .WORD 0 ;NUMBER OF EVENTS ENCOUNTERED VECAD: .BLKW ;ADDRESS OF UNIT'S INTERRUPT VEC IVEC: .BLKW ;ADDRESS OF TTDRV'S INTERRUPT ROUTINE CODEND = . .SBTTL ...FINTT -- RESTORE TT INTERRUPTS AND FREE CORE BLOCK ; FINTT: MOV BASEAD,R0 ;R0 -> START OF INTERRUPT CODE BLOCKS. BEQ 15$ ;IF NONE, THERE'S NOTHING TO FIN MOV R0,R1 ;COPY IT TST -(R1) ;POINT TO CORE BLOCK -2 MOV NUNITS,R2 ;R2 HOLDS NUMBER OF UNITS TO RESTORE 10$: ADD #CODEND-CODE,R1 ;R1->IVEC OF NEXT UNIT MOV @R1,@-(R1) ;RESTORE TT INTERRUPT TST (R1)+ ;POINT BACK TO IVEC SOB R2,10$ ;AND GO FOR NEXT UNIT ; MOV BUFSIZ,R1 ;SET UP FOR DEALCB CALL $SWSTK,15$ ;SWITCH TO SYSTEM STACK CALLR $DEACB ;;FREE BLOCK AND RETURN TO USER STACK 15$: RETURN ;RETURN TO CALLER ; .SBTTL ...RPTTT -- REPORT ON TT USAGE RPTTT: MOV BASEAD,R0 ;R0 -> START OF INTERRUPT BLOCK ADD #IOCNT-CODE,R0 ;NOW R0 -> FIRST UNIT'S IO COUNT MOV NUNITS,R1 ;R1 HAS NUMBER OF UNITS LEFT TO TEST MOV #1,R2 ;R2 HAS BIT MASK FOR CURRENT UNIT CLR TERMS ;NO TERMINAL ACTIVITY FOUND YET 10$: CMP @R0,#MINCHR ;HAS MINIMAL INPUT TAKEN PLACE? BLO 12$ ;NO BIS R2,TERMS ;YES - INDICATE ACTIVITY FOR THIS TERM 12$: ASL R2 ;PREPARE BIT MASK FOR NEXT TERMINAL CLR @R0 ;ZERO THE IO COUNT ADD #CODEND-CODE,R0 ;R0 -> NEXT UNIT'S IO COUNT SOB R1,10$ ;ALWAYS ASSUMING THERE IS A NEXT TERMINAL RETURN .SBTTL SYSTEM STATUS TRACKING ; ; THIS IS DONE IN A MANNER SIMILAR TO (BUT EASIER THAN) ; THE TT TRACKING. FOR EVERY CLOCK TICK, WE STEAL THE CLOCK ; INTERRUPT, AND EXAMINE SYSTEM STATUS FOR NULL TASK, USER OR KERNEL. ; WE INCREMENT THE APPROPRIATE COUNTER, AND RETURN CONTROL TO THE NORMAL ; CLOCK INTERRUPT ROUTINE. ; .SBTTL ...SETSYS -- SET UP FOR SYSTEM TRACKING ; ; WE SNARF UP A CORE BLOCK FROM THE EXECUTIVE POOL, AND STASH ; OUR INTERRUPT HANDLING CODE IN IT. ; SETSYS: MOV #CLKEND-CLKCOD,R1 ;GET LENGTH OF CODE NEEDED CALL $SWSTK,5$ ;SWITCH TO SYSTEM STACK CALL $ALOCB ;ALLOCATE A CORE BLOCK WE HOPE BCS 4$ ;IF WE FAILED MOV R0,CLKAD ;SAVE CORE BLOCK ADDRESS 4$: RETURN ;FROM SYSTEM STACK TO 5$ 5$: SEC ;ASSUME ERROR MOV CLKAD,R0 ;PICK UP CORE BLOCK ADDRESS BEQ 40$ ;IF NONE, WE ARE IN ERROR MOV #CLKEND-CLKCOD,R1 ;PICK UP LENGTH OF CODE BLOCK IN BYTES ASR R1 ;SWITCH TO WORDS MOV #CLKCOD,R2 ;LET R2 -> CODE BLOCK 10$: MOV (R2)+,(R0)+ ;TRANSFER CODE TO CORE BLOCK SOB R1,10$ ;LOOP TILL DONE MOV CLKAD,@#$$CVEC ;STEAL THE INTERRUPT CLC ;A SUCCESSFUL SNATCH! 40$: RETURN ; ; CLOCK INTERRUPT CODE. ; NOTE: THIS CODE HAS BEEN MODIFIED TO TEST FOR NULL TASK ; FIRST, FOR HOPEFUL COMPATABILITY WITH V3.1 ; CLKCOD: TSTB @#$CURPRI ;IS CURRENT PRI 0 (NULL TASK)? BNE 10$ ;NO INC NULTIM ;YES BR 40$ 10$: BIT #PMODE,@#PS ;KERNAL MODE? BNE 20$ ;NO - USER INC KNLTIM BR 40$ 20$: INC USRTIM 40$: JMP @#$CKINT ;JUMP TO SYSTEM'S INTRPT ROUTINE KNLTIM: .BLKW USRTIM: .BLKW NULTIM: .BLKW CLKEND = . .SBTTL ...RPTSYS -- REPORT SYSTEM STSTUS RPTSYS: MOV CLKAD,R0 ;R0 -> START OF CLOCK INTRPT CODE ADD #KNLTIM-CLKCOD,R0 ;R0 -> KNLTIM MOV #SYST,R1 ;R1 -> SYSTEM STATUS REPORTING BUFFER MOV #3,R2 ;3 COUNTS TO REPORT 10$: MOV @R0,(R1)+ ;GET COUNT CLR (R0)+ ;RESET COUNT SOB R2,10$ ;LOOP TILL DONE RETURN ; .SBTTL ...FINSYS -- CLEAN UP SYSTEM TRACKING FINSYS: MOV CLKAD,R0 ;PICK UP CORE BLOCK ADDR BEQ 15$ ;SKIP IT IF THERE IS NONE MOV #$CKINT,@#$$CVEC;RESTORE STANDARD CLOCK INTRPT VECTOR MOV #CLKEND-CLKCOD,R1 ;GET LENGTH OF CORE BLOCK CALL $SWSTK,15$ ;SWITCH TO SYSTEM STACK CALLR $DEACB ;DEALLOCATE BLOCK AND RETURN TO 15$ 15$: RETURN .SBTTL RPTTIM - TIME REPORTING SUBROUTINE ; RPTTIM: GTIM$S #SPYRC2 ;USE SPYRC2 AS TEMP TIME BUFFER MOV #DATE,R0 ;R0 -> DATE MOVB G.TIYR+SPYRC2,(R0)+ ;GET YEAR MOVB G.TIMO+SPYRC2,(R0)+ ;GET MONTH MOVB G.TIDA+SPYRC2,(R0)+ ;GET DAY MOVB G.TIHR+SPYRC2,(R0)+ ;GET HOUR MOVB G.TIMI+SPYRC2,(R0)+ ;GET MINUTE RETURN ; .END SPY