.MCALL .MODULE .MODULE DATIME,VERSION=07,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only 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 except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL EDIT HISTORY ; ; Y05.01 CA 31-JAN-83 ADD SY: IN DIR/VOL:ONLY ; ; Y05.02 MBG 23-FEB-83 TOTAL RE-WRITE ; ; V05 (001) 09-Nov-83 Added GTLIN$ bit to startup JSW so DATIME can ; MBG be used from .COM files with ^C following its ; invocation. ; ; 004 JFW 05-Nov-1990 bracket error messages with ;+/;ERROR/.../;- ; ; (005) MBG 05-FEB-91 Modified time conversion to account for time ; setting on 50Hz machines ; 006 JFW 19-Jun-1991 Added AUDIT=YES so resorc /v will work ; ; 007 Tim Shoppa 10-Oct-1996 Modified to accept 4-digit-years ; and to set the right epoch .SBTTL DEFINITIONS ; RT-11 MACROS TO BE USED .MCALL .SCCA, .DATE, .SDTTM .MCALL .GTLIN, .PRINT, .EXIT .MCALL .CSIGE, .GVAL ; SYSCOM LOCATIONS JSW = 44 ;JOB STATUS WORD CHNIF$ = 004000 ;'CHAIN INDIRECT' BIT GTLIN$ = 000010 ;NON-TERMINATING .GTLIN BIT ERRBYT = 52 ;EMT ERROR BYTE ; RMON Fixed offsets CONFIG = 300 ;Configuration word 1 CLK50$ = 000040 ;50-cycle system clock ; CHARACTERS C.LF = 12 ;LINE FEED C.CR = 15 ;CARRIAGE RETURN .SBTTL MAIN PROGRAM ;+ ; ; The purpose of this program is to obtain the date and time from ; the user, pass the information to RT and then ask for the name ; of a command file to process. ; ; Commands to display the volume information for the system volume, ; the date and time are placed in the communications area, along ; with the @file command to process the user's command file if specified. ; ;- .ASECT . = JSW .WORD GTLIN$ .PSECT .CODE. DATIME: .SCCA #AREA,#CCSTAT ;ENABLE ^C TRAPPING MOV #DEFCOM,R0 ;R0->DEFAULT COMMANDS MOV #512,R1 ;R1->COMMUNICATION AREA 10$: MOVB (R0)+,(R1)+ ;LOAD THE COMMANDS BNE 10$ ;KEEP GOING TILL NULL BYTE MOV R1,-(SP) ;SAVE THE CURRENT POINTER .DATE ;GET THE DATE FROM RT TST R0 ;IS IT SET? BNE 20$ ;YES, SO DON'T ASK FOR IT CALL GETDAT ;GO GET A VALID DATE CALL GETTIM ;GET THE TIME .SDTTM #AREA,#TIMBLK ;SET BOTH 20$: MOV (SP)+,R1 ;RESTORE SAVED POINTER 30$: .GTLIN #RESPON,#M.COMQ ;QUERY FOR THE COM FILE TSTB RESPON ;ANY RESPONSE? BEQ 70$ ;NOPE, DO WHAT WE HAVE SO FAR MOV SP,SPSAVE .CSIGE #FILSPC,#DEFEXT,#RESPON ;CHECK THE FILE NAME MOV SPSAVE,SP BCC 50$ CMPB @#ERRBYT,#1 ;NO DEVICE? BNE 31$ ;+ ;ERROR .PRINT #E.NOD ;'NO DEVICE' ;- BR 30$ 31$: CMPB @#ERRBYT,#4 ;FILE NOT FOUND? BNE 32$ ;+ ;ERROR .PRINT #E.FNF ;'FILE NOT FOUND' BR 30$ 32$: .PRINT #E.IVR ;'INVALID RESPONSE' ;- BR 30$ 50$: MOV #RESPON,R0 ;R0->RESPONSE DEC R1 ;BACK UP POINTER MOVB #'@,(R1)+ 60$: MOVB (R0)+,(R1)+ ;MOVE CHARACTER OF FILE NAME BNE 60$ 70$: SUB #512,R1 ;DETERMINE LENGTH OF COMMAND STRING MOV R1,@#510 ; AND PLACE IT IN COMMUNICATIONS AREA BIS #CHNIF$,@#JSW ;TELL KMON WE HAVE COMMANDS FOR IT CLR R0 ;HARD EXIT .EXIT .SBTTL GETDAT - GET DATE FROM USER ;+ ; ; GETDAT ; Prompts the user for the date and parses the response for ; validity. ; ; RETURNS: ; TIMBLK loaded with RT-11 formated date ; ;- GETDAT: .GTLIN #RESPON,#M.DATQ ;QUERY THE USER FOR THE DATE TSTB RESPON ;ANY RESPONSE? BEQ GETDAT ;NOPE, KEEP PROMPTING MOV #RESPON,R1 ;R1->RESPONSE STRING CALL GETNUM ;GET THE DAY BCS 10$ ;UNEXPECTED EOL BEQ 10$ ;WHAT MONTH HAS A DAY '0'? CMPB -1(R1),#'- ;CORRECT DELIMITER? BNE 10$ ;NOPE... CMP R0,#31. ;DOES IT SEEM VALID? BGT 10$ ;NOPE... SWAB R0 ;SWAP AND SHIFT SO DAY NUMBER ASR R0 ; IS IN BITS <09:05> ASR R0 ASR R0 MOV R0,DATE ;SAVE PARTIAL RT FORMAT DATE CALL GETMON ;GET THE MONTH BCS 10$ ;UNEXPECTED EOL CMPB -1(R1),#'- ;CORRECT DELIMITER? BNE 10$ SWAB R0 ;SWAP AND SHIFT MONTH INTO ASL R0 ; BITS <13:10> ASL R0 ADD R0,DATE ;CONTINUE FORMING RT FORMAT DATE CALL GETNUM ;GET THE YEAR TSTB @R1 ;EXPECTED EOL? BNE 10$ CMP R0,#99. ;IS IT A VALID 2-DIGIT YEAR? ;007 BLE 4$ ;007 CMP R0,#2099. ;IS IT A VAILD 4-DIGIT YEAR? ;007 BGT 10$ ;007 SUB #1900.,R0 ;MAYBE 4-DIGIT... BRING IT DOWN ;007 4$: SUB #72.,R0 ;ADJUST IT FOR RT-TYPE ;007 BLT 10$ ;007 5$: CMP R0,#32. ;ADJUST FOR EPOCHS AS NECESSARY ;007 BLT 6$ ;007 ADD #040000,DATE ;BUMP THE AGE BITS ;007 SUB #32.,R0 ;007 BR 5$ ;007 6$: ADD R0,DATE ;YEAR IS OKAY IN BITS <04:00> ; SO COMPLETE RT FORMAT DATE RETURN ;+ ;ERROR 10$: .PRINT #E.IVR ;- BR GETDAT .SBTTL GETTIM - GET TIME FROM USER ;+ ; ; GETTIM ; Prompts the user for the time, parses the response ; for validity, and assembles the hi-order/lo-order ; RT formatted time. If no response, time is left alone. ; ; RETURNS: ; If time is entered: ; TIMHI (TIMBLK+2) = hi-order time word ; TIMLO (TIMBLK+4) = lo-order time word ; If no response: ; TIMHI (TIMBLK+2) = -1 ; ;- GETTIM: CLR HOUR CLR MINUTE CLR SECOND .GTLIN #RESPON,#M.TIMQ ;PROMPT USER FOR TIME MOV #-1,TIMHI ;ASSUME NOT ALTERING TIME TSTB RESPON ;ANY RESPONSE? BEQ 40$ ;NOPE... MOV #RESPON,R0 ;R0->RESPONSE 10$: TSTB @R0 ;END OF STRING? BEQ 20$ ;YES, CONTINUE... CMPB (R0)+,#3 ;^C ENCOUNTERED? BEQ GETTIM ;NOT VALID BR 10$ 20$: MOV #RESPON,R1 ;R1->RESPONSE STRING CALL GETNUM ;ASSEMBLE HOURS CMP R0,#23. ;VALID HOURS? BGT 50$ MOV R0,HOUR ;YES, SAVE IT TSTB @R1 ;END OF STRING? BEQ 30$ CMPB -1(R1),#': ;CORRECT DELIMITER? BNE 50$ CALL GETNUM ;ASSEMBLE MINUTES CMP R0,#59. ;VALID MINUTES? BGT 50$ MOV R0,MINUTE ;YES, SAVE IT TSTB @R1 ;END OF STRING? BEQ 30$ CMPB -1(R1),#': ;CORRECT DELIMITER? BNE 50$ CALL GETNUM ;ASSEMBLE SECONDS TSTB @R1 ;EXPECTED EOL? BNE 50$ CMP R0,#59. ;VALID SECONDS? BGT 50$ MOV R0,SECOND ;SAVE SECONDS ; ; TIME = ((( hour * 60 ) + minutes ) * 60 + seconds ) * clock frequency ; 30$: MOV #60.,R0 MOV HOUR,R1 CLR R2 CALL DMULT ; TIME = (HOUR * 60) MOV #60.,R0 ADD MINUTE,R1 ADC R2 CALL DMULT ; TIME = (TIME + MINUTES) * 60 MOV #60.,-(SP) ;Default to 60 Hz clock .GVAL #AREA,#CONFIG ;Get configuration word BIT #CLK50$,R0 ;On a 50 Hz machine? BEQ 32$ ;Nope... MOV #50.,@SP ;Yes, change the multiplier 32$: MOV (SP)+,R0 ;R0 = Clock frequency multiplier ADD SECOND,R1 ADC R2 CALL DMULT ; TIME = (TIME + SECONDS) * clock MOV R2,TIMBLK+2 ;SET HIGH- MOV R1,TIMBLK+4 ; AND LOW-ORDER TIME 40$: RETURN ;+ ;ERROR 50$: .PRINT #E.IVR ;- BR GETTIM .SBTTL GETNUM - ASSEMBLE A NUMBER FROM STRING ;+ ; ; GETNUM ; Takes successive characters from a buffer, assembling ; a number to be passed back to the caller. ; ; CALL ; R1 -> string ; ; RETURNS ; c-bit = 0 ; R0 = number ; R1 -> byte following delimiter ; c-bit = 1 ; R0 = number ; R1 -> null byte at end of string ; ;- GETNUM: CLR -(SP) ;CLEAR TOTAL 5$: TSTB @R1 ;END OF STRING? BEQ 20$ ;YES, THAT'S NOT GOOD MOVB (R1)+,R0 ;GET A CHARACTER CMPB R0,#'0 ;IS IT A VALID DIGIT? BLO 10$ ;NOPE... CMPB R0,#'9 ;MAYBE, CHECK UPPER LIMIT BHI 10$ ;NOPE... SUB #'0,R0 ;YES, CONVERT TO OCTAL ASL @SP ;MULTIPLY CURRENT TOTAL BY 10. MOV @SP,-(SP) ASL @SP ASL @SP ADD (SP)+,@SP ADD R0,@SP ;ADD THIS DIGIT BR 5$ ;AND GO GET ANOTHER ONE 10$: TST (PC)+ 20$: SEC MOV (SP)+,R0 ;RETURN NUMBER IN R0 RETURN .SBTTL GETMON - MONTH INPUT ROUTINE ;+ ; ; GETMON ; Validates the month name contained in a buffer, returning ; the month number to the caller. ; ; CALL ; R1 -> month string (of the form mmm-) ; ; RETURN ; c-bit = 0 ; R0 = month number (1-12) ; R1 -> byte beyond terminator (-) ; c-bit = 1 ; R0 = undefined ; R1 -> null byte at end of string ; ;- GETMON: MOV #MONTHS,R0 ;R0->MONTH NAMES 10$: MOV R1,-(SP) ;SAVE CURRENT POSITION 20$: MOV @SP,R1 ;RESTORE OLD POSITION MOV #4,R2 ;COUNT OF CHARACTERS TO MATCH 30$: TSTB @R0 ;END OF MONTH NAME STRING? BEQ 60$ ;YES...ERROR TSTB @R1 ;END OF INPUT STRING? BEQ 60$ ;YES...ERROR CMPB (R1)+,(R0)+ ;THIS CHARACTER MATCHES? BNE 20$ ;NOPE... DEC R2 ;MORE CHARACTERS TO MATCH? BGT 30$ ;YES... TST (SP)+ ;POP OFF CURRENT POSITION SUB #MONTHS,R0 ;ADJUST MONTH NAME OFFSET ASR R0 ASR R0 TST (PC)+ ;GOOD RETURN 50$: SEC ;ERROR RETURN RETURN 60$: TST (SP)+ ;POP OFF OLD R1 INFO BR 50$ ; AND TAKE ERROR RETURN MONTHS: .ASCIZ /JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-/ .EVEN .SBTTL DMULT - DOUBLE WORD MULTIPLY ;+ ; ; DMULT ; Multiplies two unsigned integers yielding an unsigned ; double-precision integer. ; ; CALL ; R0 = multiplier ; R1,R2 = multiplicand (lo,hi order) ; ; RETURNS ; R0 = 0 ; R1,R2 = product (low,hi order) ; ;- DMULT: CLR -(SP) ;CLEAR PRODUCT CLR -(SP) 10$: BIT #1,R0 ;LOW-ORDER BIT ON? BEQ 20$ ;NOPE, DON'T DO THE ADD ADD R1,2(SP) ;ADD LOW ORDER ADC @SP ;ADD CARRY ADD R2,@SP ;AND HIGH-ORDER 20$: ROL R1 ;SHIFT MULTIPLICAND LEFT ROL R2 ASR R0 ;WHILE SHIFTING MULTIPLIER RIGHT BNE 10$ MOV (SP)+,R2 ;RETURN HIGH ORDER IN R2 MOV (SP)+,R1 ; AND LOW ORDER IN R1 RETURN .SBTTL MESSAGES .PSECT .TEXT. .NLIST BEX M.DATQ: .ASCII /Date [dd-mmm-yyyy]? /<200> ;007 M.TIMQ: .ASCII /Time [hh:mm:ss] ? /<200> M.COMQ: .ASCII /Startup File [filnam.typ]? /<200> ;+ ;ERROR E.IVR: .ASCIZ /?DATIME-Invalid response/ E.FNF: .ASCIZ /?DATIME-File not found/ E.NOD: .ASCIZ /?DATIME-No device/ ;- DEFCOM: .ASCII "DIR SY:/VOL:ONLY" ; .ASCII "DATE" ; .ASCII "TIME" ; .ASCII "SET TT NOQUIET" .BYTE 0 .EVEN .SBTTL IMPURE DATA AREA .PSECT .DATA. RESPON: .BLKB 134. ;RESPONSE BUFFER .EVEN SPSAVE: .BLKW ;SAVED STACK CCSTAT: .BLKW ;^C STATUS WORD FILSPC: OSPEC: .BLKW 3*5 ;3 OUTPUT FILE-SPEC BLOCKS ISPEC: .BLKW 6*4 ;6 INPUT FILE-SPEC BLOCKS DEFEXT: .RAD50 /COM/ ;DEFAULT INPUT FILE TYPE .WORD 0,0,0 ;DEFAULT OUTPUT FILE TYPES AREA: .BLKW 5 ;EMT AREA HOUR: .BLKW MINUTE: .BLKW SECOND: .BLKW TIMBLK: DATE: .BLKW ;RT FORMAT DATE WORD TIMHI: .BLKW ;HI-ORDER TIME TIMLO: .BLKW ;LO-ORDER TIME .END DATIME