.PSECT DCNT .TITLE DCNT - DISK ACCOUNTING MAINTENANCE .IDENT /781002/ ; ; THIS CODE HAS BEEN DEVELOPED BY THE COMPUTING ; GROUP OF THE ATMOSPHERIC SCIENCES DIVISION, ; ALBERTA RESEARCH. ; ; VERSION: WK01.03 ; WRITTEN BY: W. KORENDYK ; DATE WRITTEN: 8-AUG-78 ; 19-SEP-78 (SYNTACTICAL ALTERATIONS) ; ; RELATED DOCUMENTATION: ; ; ; MODIFICATIONS: ; ; CODE NAME DATE ; 001 H.R. TUMBLIN 21-JAN-79 MODIFIED FOR IAS V2.0 .SBTTL >PREDEFINITIONS ;+ ; ; DCNT -- THIS IS THE MAINTENANCE PROGRAM FOR THE ASD DISK ; ACCOUNTING PACKAGE. ITS USE IS SIMILAR TO THE RSX ; ACCOUNTING MAINTENANCE PROGRAM, SO SHOULD BE SELF- ; EXPLANATORY FOR THE MOST PART. ; ;- .MCALL QIOW$,EXIT$S,C$C,PUSH,POP ; ; TILUN=5 TIEVF=23. ESC=33 ; READ: QIOW$ IO.RVB,TILUN,TIEVF,,RDSTAT,, RDBUF: .BLKW 10. RDSTAT: .BLKW 2 ; .SBTTL >MAIN LINE CODE .PSECT .enabl lsb START: TINIT TILUN,TIEVF ;INIT FOR TERMINAL I/O FINIT$ ;AND FILE I/O ; 2$: TTYOUT #PRE1,#LPRE1 ;TASK IDENTIFICATION TTYOUT #PRE2,#LPRE2 ;OUTPUT THE PREAMBLE READ ,EXIT ;FIND OUT WHAT HE WANTS MOV #DTAB,R0 ;GET THE PARSE TABLE MOV #RDBUF,R1 ;GET START OF READ STRING 3$: CMPB (R1),(R0)+ ;COMPARE IT BEQ 4$ ;IF EQ, THEN HE WANTS THIS TSTB (R0) ;END OF THE PARSE TABLE? BNE 3$ ;IF NE, THEN NO, THERE IS MORE CALL ERRPFX ;ERROR PREFIX PSTR ^*/UNRECOGNIZED COMMAND/* BR 2$ ;START OVER ; 4$: SUB #DTAB+1,R0 ;GET WHICH PARSE CHAR IT WAS ASL R0 ;AS A WORD DISPLACEMENT CALL @DTAB2(R0) ;AND CALL THE HANDLER BR 2$ ;START OVER ; EXIT: PSTR ^*/Operation Complete/* EXIT$S PRETXT PRE1: .ASCII /H//J/ .ASCII /Disk Accounting Maintenance Program V2.0/ .ASCII LPRE1 =.-PRE1 ; PRE2: .ASCII /The available options are:/ .ASCII /C - Create file,/ .ASCII /E - Examine file,/ .ASCII /L - List file,/ .ASCII /M - Modify file,/ .ASCII /R - Reset file./ .ASCII /CTRL-Z - Exit/ .ASCII /Type an ESC to leave any prompt/ .ASCII /** Enter option > _/<10> LPRE2 =.-PRE2 PSTTXT .dsabl lsb .SBTTL >THE NON-PRIVILEGED DISPLAY ;+ ; ; LSTALL -- ROUTINE WHICH PRINTS AN ALL DEVICE SUMMARY ON ; THE TERMINAL, FOR THE SPECIFIC USER. ; ;- LSTALL: PUSH ; MOV #DEVTAB,R5 ;POINT TO THE DEVICE TABLE 1$: CALL FILLIN ;FILL IN FOR THE FIRST DEVICE BCS 10$ ;TABLE WAS EMPTY OPNS$R #DAFFDB ;OPEN THE DAF BCS 9$ ;YECH, FILE NO GOOD CALL REDDAF ;READ IN THE DISK ACCOUNTING FILE CLOSE$ ,IOERR ;CLOSE THE DAF CALL GTUIC ;GET THE LOGIN UIC CALL LOCATE ;FIND THE RECORD IN THE ACCOUNT FILE BCS 9$ ;NOT FOUND CALL PRTHED ;PRINT THE ACCOUNTING HEADER, CALL PRTRH ;THE RECORD HEADER, CALL PRTREC ;AND THIS RECORD 9$: CMP (R5)+,(R5)+ ;POINT TO THE NEXT DEVICE BR 1$ ;AND SUMMARIZE THE ACCOUNT 10$: POP ; RESTORE REGISTERS RETURN ; .SBTTL >FILL IN THE DAF NAME ;+ ; ; FILLIN -- ROUTINE TO CORRECTLY FILL IN THE DSDS OF ; THE DISK ACCOUNTING FILE FOR THE APPROPRIATE DEVICE. ; ; INPUTS: R5 = ADDRESS OF THE TWO WORD DEVICE DESCRIPTOR ; ; OUTPUTS: CARRY SET IFF THE DESCRIPTOR WAS NULL ; ;- FILLIN: PUSH ;THE REGISTERS WE CORRUPT MOV R5,CDEV ;REMEMBER WHO'S CURRENT MOV (R5)+,R0 ;GET LENGTH OF DEVICE NAME STRING DEC R0 ;LESS THE ': BLE 4$ ;IT WAS NULL MOV (R5)+,R1 ;GET THE STRING ADDRESS MOV #FILDV,R2 ;WHERE IT GOES MOV R0,-(SP) ;REMEMBER THIS FOR A SEC. 1$: MOVB (R1)+,(R2)+ ;MOV IT IN SOB R0,1$ ; MOV #4,R1 ;MAX SIZE OF DEVICE NAME SUB (SP)+,R1 ;LESS THE SIZE WE MOVED BLE 3$ ; 2$: TSTB -(R2) ;POINT TO THE NUMBER MOVB (R2)+,(R2) ;MOVE IT DOWN MOVB #'0,-(R2) ;AND PRECEDE IT WITH A '0. 3$: CLC ;INDICATE SUCCESS BR 5$ ; 4$: SEC ; 5$: POP ; RESTORE REGISTERS RETURN ; .SBTTL >READ IN THE ENTIRE DAF .enabl lsb ;+ ; ; REDDAF -- ROUTINE TO READ THE ACCOUNTING FILE, ; IN ITS ENTIRETY, INTO THE DAF INFO BUFFER. ; ; INPUT: R0 = FDB ADDRESS OF THE DAF ; ; OUTPUT: CARRY SET IFF THERE WAS TROUBLE OPENING THE FILE ; ;- REDDAF: PUSH ;SAVE REGISTERS WE CORRUPT MOV #DAFINF,R1 ;THIS IS WHERE TO PUT THE FILE READ$ ,R1,,,,,,IOERR ;READ IN THE FIRST BLOCK WAIT$ ,,,IOERR ;AND WAIT FOR IT MOV DAF.SZ(R1),R2 ;GET NUMBER OF RECORDS IN FILE CMP #SZ.DAF+1,R2 ;OPPOSED TO WHAT WE CAN HOLD BGE 10$ ;IS ACCEPTABLE ERROR 10$: INC R2 ;INCLUDE GLOBAL RECORD MUL #DF.LRC,R2 ;TOTAL NUMBER OF BYTES DIV #512.,R2 ;NUMBER OF BLOCKS TST R3 ;WAS THERE A REMAINDER? BEQ 11$ ;IF EQ, THEN NO INC R2 ;YES, SO READ IN EOF BLOCK 11$: DEC R2 ;ALREADY HAVE FIRST BLOCK BLE 13$ ;IF LE, THEN NO MORE TO GET 12$: ADD #512.,R1 ;NEXT POSITION IN INFO BUFFER READ$ ,R1,,,,,,IOERR ;READ IN THE NEXT BLOCK WAIT$ ,,,IOERR ;WAIT FOR IT SOB R2,12$ ;AND GO FOR MORE IF NEED BE 13$: ;REFERENCE LABEL 20$: POP ; RETURN ; .dsabl lsb .SBTTL >WRITE OUT THE NEW DAF ;+ ; ; WRTDAF -- ROUTINE TO WRITE THE CONTENTS OF THE DAF INFO BUFFER ; BACK TO THE DAF. ; ; INPUT: R0 = ADDRESS OF THE DAF FDB. ; ; ;- WRTDAF: PUSH ;SAVE SOME REGISTERS MOV #1,F.BKVB+2(R0) ;POINT TO THE FIRST FILE BLOCK MOV #DAFINF,R1 ;THE STUF TO BE WRITTEN MOV DAF.SZ(R1),R2 ;GET THE SIZE OF FILE INC R2 ;INCLUDING GLOBAL RECORD MUL #DF.LRC,R2 ;AS A BYTE COUNT DIV #512.,R2 ;AND THEN BLOCK COUNT TST R3 ;EXTRA BLOCK? BEQ 1$ ;IS NOT NEEDED INC R2 ; 1$: WRITE$ ,R1,,,,,,IOERR ;WRITE A BLOCK WAIT$ ,,,IOERR ;WAIT FOR IT (WE'RE IN NO HURRY) ADD #512.,R1 ;POINT TO SECOND BLOCK SOB R2,1$ ;AND SEND IT IF THERE POP ; RETURN ; .SBTTL >GET THE CURRENT LOGON UIC ;+ ; GTUIC -- ROUTINE TO RETURN THE CURRENT USER'S LOGON UIC. ; ; OUTPUT: R1 = THE LOGON UIC ; ;- GTUIC:; MOV $TKTCB,R1 ;GET THE TCB ADDRESS ; MOV T.UCB(R1),R1 ;THEN THE TI: UCB ; MOV U.LUIC(R1),R1 ;AND FINALLY THE L-UIC RETURN .SBTTL >LOCATE USER IN THE DAF ;+ ; ; LOCATE -- ROUTINE WHICH LOCATES THE RECORD FOR THE SPECIFIED ; UIC IN THE DAF INFO BUFFER. ; ; INPUT: R1 = THE UIC TO LOOK FOR ; ; OUTPUT: R0 = THE ADDRESS OF THE ACCOUNTING RECORD ; CARRY CLEAR IFF THE RECORD IS FOUND ; ;- LOCATE: PUSH R2 ; SAVE THIS MOV #DAFINF,R0 ;POINT TO THE GOBAL RECORD MOV DAF.SZ(R0),R2 ;GET TOTAL NUMBER OF RECORDS BEQ 99$ ;THE FILE IS EMPTY 10$: ADD #DF.LRC,R0 ;POINT TO NEXT ACCOUNTING RECORD CMP R1,DF.UIC(R0) ;CHECK OUT THE UICS BEQ 100$ ;IF EQ, THEN WE FOUND IT SOB R2,10$ ;TRY SOME MORE RECORDS 99$: SEC ;COULDN'T FIND BR 101$ ;LEAVE 100$: CLC ;INDICATE SUCCESS 101$: POP R2 ; RETURN ; .SBTTL >TERMINAL OUTPUT OF DAF HEADER RECORD ;+ ; ; PRTHED -- ROUTINE TO PRINT TO THE TERMINAL, A LINE DESCRIPTION ; OF THE HEADER (IE. GLOBAL) RECORD. ; ; ;- PRTHED: PUSH R1 ;SAVE THIS REGISTER CALL SETHD1 ; FILL IN THE OUTPUT BUFFER TTYOUT #MESOUT,R1 ; SEND IT TO THE TERMINAL CALL SETHD2 ; FILL IN THE OUTPUT BUFFER TTYOUT #MESOUT,R1 ; SEND IT TO THE TERMINAL POP R1 RETURN ; .SBTTL >TERMINAL OUTPUT OF THE ACCOUNT RECORD ;+ ; ; PRTREC -- ROUTINE TO PRINT TO THE TERMINAL, A LINE DESCRIPTION ; OF THE ACCOUNTING RECORD SPECIFIED. ; ; INPUT: R0 = ADDRESS OF THE RECORD ; ;- PRTREC: PUSH R1 ;SAVE REGISTER CALL SETREC ; FILL IN THE OUTPUT BUFFER TTYOUT #MESOUT,R1 ; SEND TO THE TERMINAL POP R1 RETURN ;+ ; ; PRTRH -- ROUTINE TO PRINT TO THE TERMINAL, A TWO LINE RECORD ; HEADER. ; ;- PRTRH: PUSH R1 ;SAVE A REGISTER CALL SETRH1 ; FILL THE LISTING BUFFER TTYOUT #MESOUT,R1 ; SEND TO THE TERMINAL CALL SETRH2 ; AND THE SECOND HALF TTYOUT #MESOUT,R1 ; POP R1 RETURN ; .SBTTL >LISTING OF ACCOUNT HEADER ;+ ; ; SETRH -- ROUTINE TO FILL IN LISTING BUFFER WITH THE RECORD HEADER. ; ; OUTPUT: R1 LENGTH OF RESULTING LISTING STRING ; ;- SETRH2: MOV #RECIN3,R1 BR SET SETRH1: MOV #RECIN1,R1 SET: PUSH MOV #MESOUT,R0 MOV #MESARG,R2 CALL $EDMSG POP RETURN ; ; PRETXT RECIN1: .ASCIZ /%2N%15SCurrently used %5SMaximum allotted%4SBlock-hours of/ RECIN3:.ASCII /%N UIC%10S Disk Space %5S Disk Space %5SDisk Space Used/ .ASCIZ "%N" PSTTXT .SBTTL >BUILD LISTING OF DAF HEADER RECORD ;+ ; ; SETHED -- ROUTINE TO FILL IN THE LISTING BUFFER WITH THE ; DESCRIPTION OF THE HEADER (IE. GLOBAL) RECORD. ; ; OUTPUT: R1 = LENGTH OF THE RESULTING LISTING (@MESOUT) ; ;- .MCALL GTIM$S SETHD1: PUSH R0 ;SAVE SOME REGISTERS MOV CDEV,R0 ; GET CURRENT DEVICE MOV #MESARG,R1 ; PLACE FOR MESSAGE ARGUMENTS MOV (R0)+,(R1)+ ; MOVE IN THE DEVICE MOV (R0)+,(R1)+ ; DESCRIPTOR. GTIM$S R1 ; GET THE CURRENT TIME IN THERE MOV #HEDIN1,R1 ; POINT TO THE FIRST BIT CALL SET ; AND FILL IT IN POP R0 ; THAT IS ALL RETURN ; ; SETHD2: PUSH ;SAVE SOME REGISTERS MOV #MESARG,R1 ; PLACE FOR ARGUMENTS MOV #DAFINF,R0 ; POINT TO THE GLOBAL RECORD MOVB DF.HR(R0),R2 ;AND MOVE IN ALL THE OTHER STUFF MOV R2,(R1)+ ; MOVB DF.MI(R0),R2 ; MINUTES MOV R2,(R1)+ ; MOV DF.YR(R0),(R1)+ ; YEAR MOVB DF.MO(R0),R2 ; MONTH MOV R2,(R1)+ ; MOVB DF.DA(R0),R2 ; DAY MOV R2,(R1)+ ; MOV DF.MIN(R0),-(SP) ;ELAPSED TIME MOV DF.MIN+2(R0),-(SP) MOV SP,(R1)+ ; MOV #HEDIN2,R1 ; FROM CALL SET ; CMP (SP)+,(SP)+ ; POP RETURN ; ; PRETXT HEDIN1: .ASCIZ /%2NAccounting summary of %VA taken on %Y at %3Z/ HEDIN2: .ASCII /%2NAccounting began %2Z %Y./ .ASCIZ / Total accounted time of %T minutes.%N/ LHEDIN =.-HEDIN1 PSTTXT MESOUT: .BLKB 150. ;THIS SHOULD BE BIG ENOUGH .EVEN MESARG: .BLKW 20. ;DITTO .SBTTL >LISTING OF ACCOUNT RECORD ;+ ; ; SETREC -- ROUTINE TO FILL IN THE OUTPUT BUFFER WITH THE ; LISTING OF THE RECORD INFORMATION. ; ; INPUT: R0 = ADDRESS OF THE RECORD ; ; OUTPUT: R1 = LENGTH OF THE LISTING (@MESOUT) ; ;- SETREC: PUSH ;SAVE REGISTERS MOV #MESARG,R1 ;WHERE TO PUT EDMSG ARGS. MOV R0,(R1) ; ADD #DF.UIC+1,(R1) ; MOV (R1)+,(R1) ; DEC (R1)+ ;THE UIC CMP DF.CDC+2(R0),DF.MDC+2(R0) BLT 2$ ;HE IS WITHIN HIS LIMITS BGT 1$ ;HE IS NOT CMP DF.CDC(R0),DF.MDC(R0) BLOS 2$ ; 1$: MOVB #'*,OVER ; MOVB #'*,OVER+1 ; BR 3$ ; 2$: MOVB #40,OVER ; MOVB #40,OVER+1 ; 3$: MOV SP,R3 ;REMEMBER THIS MOV DF.CDC(R0),-(SP) ;THE CURRENT DISK SPACE COUNT MOV DF.CDC+2(R0),-(SP) MOV SP,(R1)+ ;THIS IS WHERE IT IS MOV DF.MDC(R0),-(SP) ;THE MAXIMUM DISK SPACE COUNT MOV DF.MDC+2(R0),-(SP) MOV SP,(R1)+ ;THIS IS WHERE IT IS MOV DF.DBH(R0),-(SP) ;THE NUMBER DISK BLOCK-HOURS MOV DF.DBH+2(R0),-(SP) MOV SP,(R1)+ ;THIS IS WHERE IT IS MOV #RECIN2,R1 ; WHERE TO GET IT CALL SET ; MAKE THE LINE MOV R3,SP ; RESTORE THE STACK POP ; RETURN ; ; PRETXT RECIN2: .ASCII /[%B,%B]/ OVER: .ASCII /** %5S%10<%T%10>%10S%10<%T%10>%10S%T/<0> PSTTXT .SBTTL >FIND OUT WHICH DEVICE .enabl lsb ;+ ; ; GTDEV -- ROUTINE TO READ THE DEVICE SPECIFICATION FROM ; THE TERMINAL, AND COMPARE TO THE LIST OF ACCOUNTABLE ; DEVICES. IFTHE DEVICE IS FOUND, THEN THE DSDS OF THE ; DAF IS ALTERED TO SPECIFY THAT ACCOUNTING FILE. ; ; OUTPUTS: CARRY CLEAR IFF THE DSDS IS PROPERLY SET UP ; ;- GTDEV: PUSH ;WE USE A LOT OF REGISTERS 1$: TTYOUT #GDVM,#LGDVM ;ISSUE THE PREAMBLE READ #5,100$ ;READ STRING, LEAVE ON ERROR CMPB #ESC,RDSTAT+1 ;WAS TERMINATOR AN ESC? BEQ 100$ ;IF EQ, THEN LEAVE MOV RDSTAT+2,R3 ;GET STRING LENGTH CMP #2,R3 ;AND CHECK THE RANGE BLO 2$ ;IF LO, THEN OK CALL SYNTAX ;SYNTAX (CATCH-ALL) ERROR BR 1$ ;TRY AGAIN 2$: MOV #DEVTAB,R5 ;GET LIST OF ACCOUNTED DEVICES 3$: MOV #RDBUF,R2 ;THE STRING MOV (R5),R1 ;THE LENGTH OF DEVICE NAME MOV 2(R5),R0 ;AND ADDRESS OF DEVICE STRING 4$: CMPB (R0)+,(R2)+ ;ARE THE DIFFERENT? BNE 5$ ;IF NE, THEN YES, TRY NEXT DEVICE SOB R1,4$ ;HOW 'BOUT REST OF STRING CALL FILLIN ;WE GOT IT, FILL IN DSDS CLC ;INDICATE SUCCESS BR 101$ ;AND LEAVE 5$: CMP (R5)+,(R5)+ ;POINT TO NEXT ACCOUNATBLE DEVICE TST (R5) ;IS THERE SOMETHING THERE? BNE 3$ ;IF NE, THEN YES PSTR ^*/Device not accountable by package/* BR 1$ ;TRY OVER 100$: SEC ;INDICATE FAILURE 101$: POP RETURN ; ; ; PRETXT GDVM: .ASCII /Please enter the name of the disk (DDn:) / LGDVM =.-GDVM PSTTXT .dsabl lsb .SBTTL >FILL IN THE GLOBAL RECORD ;+ ; ; GLBREC -- ROUTINE TO FILL IN THE GLOBAL RECORD OF THE DAF ; ;- GLBREC: PUSH R0 ; MOV #DAFINF,R0 ;ADDRESS OF THE FIRST RECORD CLR DF.MIN(R0) ;ZERO ELLAPSED TIME CLR DF.MIN+2(R0) ; CLR DAF.SZ(R0) ;NO RECORDS CLR DF.YR(R0) ;ZERO ABSOLUTE TIME POP R0 ; RETURN .SBTTL >INITIALIZE ACCOUNTING RECORD ;+ ; ; INIREC -- ROUTINE TO INITIALIZE THE ACCOUNTING RECORD. ; ; INPUT: R2 = ADDRESS OF THE RECORD ; ;- INIREC: CLR DF.CDC(R2) ;INITIALIZE THE RECORD MOV DF.CDC(R2),DF.CDC+2(R2) MOV DF.CDC(R2),DF.DBH(R2) MOV DF.CDC(R2),DF.DBH+2(R2) RETURN .SBTTL >CONVERSION TO UPPER CASE ;+ ; ; UPCASE -- ROUTINE TO CONVERT THE READ IN STRING TO UPPER CASE. ; ;- UPCASE: PUSH MOV #RDBUF,R0 ;GET INPUT STRING MOV R0,R1 ;AS OUTPUT STRING MOV RDSTAT+2,R2 ;AND ITS LENGTH BEQ 1$ ;NOTHING THERE CALL $CVTUC ;CONVERT TO UPPER CASE 1$: POP RETURN .SBTTL >FIND OUT WHICH UIC TO ACCOUNT ;+ ; ; GTWHO -- ROUTINE TO READ IN THE UIC FROM THE TERMINAL ; ; OUTPUTS: CARRY CLEAR IFF UIC WAS GIVEN ; R1 = THE UIC ; ;- GTWHO: PUSH ; 1$: TTYOUT #WHOM,#LWHOM ;ASK FOR THE UIC READ #9.,2$ ;READ HIS REPLY CMPB #ESC,RDSTAT+1 ;IF TERMINATED WITH AN ESC, BEQ 2$ ;THEN HE IS DONE MOV RDSTAT+2,WHO ;GET LENGTH OF STRING MOV #RDBUF,WHO+2 ;AND THE STRING ADDRESS MOV #WHO,R2 ;ADDRESS OF UIC DESCRIPTOR MOV #UIC,R3 ;AND WHERE IT GOES CALL .ASCPP ;CONVERT IT BCC 3$ ;OKAY. CALL SYNTAX ;SYNTAX ERROR BR 1$ ;TRY AGAIN 2$: SEC ;INDICATE FAILURE 3$: MOV UIC,R1 ;GET THE UIC POP ; RETURN ; ; ; PRETXT WHOM: .ASCII /Enter the UIC to account ([n,n]) / LWHOM =.-WHOM PSTTXT ; WHO: .BLKW 2 ;UIC DESCRIPTOR UIC: .WORD 0 ;THE UIC .SBTTL >GET THE MAXIMUM DISK COUNT ;+ ; ; GTMDC -- ROUTINE TO GET THE MAXIMUM ALLOTED DISK SPACE VALUE ; AND INSERT INTO THE CURRENT RECORD. ; ; INPUT: R2 = ADDRESS OF THE CURRENT RECORD ; ; NOTE: AN ESC OR INVALID NUMBER, LEAVES THE ENTRY UNCHANGED ; ;- GTMDC: PUSH ; TTYOUT #MDCM,#LMDCM ;ASK HIM READ #10.,1$ ;READ IN THE NUMBER CMPB #ESC,RDSTAT+1 ;TERMINATED WITH AN ESC? BEQ 1$ ;IF YES, IGNORE MOV #TMPMDC,R3 ;WHERE TO PUT IT MOV RDSTAT+2,R4 ;AND SIZE OF THE NUMBER MOV #RDBUF,R5 ;GET STRING ADDRESS CALL .DD2CT ;CONVERT IT BCS 1$ ;IF ERROR, IGNORE MOV (R3)+,DF.MDC+2(R2) ;AND HIGH WORD. MOV (R3)+,DF.MDC(R2) ;MOVE IN LOW WORD, 1$: POP ; RETURN ; TMPMDC: .BLKW 2 ; ; ; PRETXT MDCM: .ASCII /What is his maximum disk space allotment (n) / LMDCM =.-MDCM PSTTXT .SBTTL >MISCELLANEOUS ERROR ROUTINES ;+ ; ; SYNTAX -- THE CATCH-ALL ERROR MESSAGE HANDLER. WHEN IN DOUBT, IT IS ; A SYNTAX ERROR. ; ;- SYNTAX: CALL ERRPFX ; ERROR PREFIX PSTR ^*/SYNTAX ERROR/* RETURN ;+ ; ; DAFULL -- ROUTINE TO TELL USER THAT THE DAF IS FULL. ; ;- DAFULL: CALL ERRPFX PSTR ^*/FILE IS FULL./* RETURN .SBTTL >COMMAND TABLE .PSECT DATA ;+ ; ; DTAB -- TABLE OF ACCEPTIBLE COMMANDS FOR THE MAINTENANCE ; OF THE ASD DISK ACCOUNTING PACKAGE. ; ; ;- DTAB: .BYTE 'C .BYTE 'E .BYTE 'L .BYTE 'M .BYTE 'R .BYTE 'S .BYTE 0 .EVEN ; DTAB2: .WORD CREATE ;CREATE A FILE .WORD EXAMIN ;EXAMINE AN ENTRY .WORD LIST ;LIST ENTIRE FILE .WORD MODIFY ;MODIFY AN ENTRY .WORD ZERO ;ZERO THE FILE .WORD LSTALL ;LIST ALL DEVICES .WORD 0 ; ; ; .PSECT .SBTTL >CREATE A DAF .enabl lsb ;+ ; ; CREATE -- ROUTINE TO CREATE A DAF (DISK ACCOUNTING FILE) ; AND FILL IN THE UICS. ; ;- CREATE: PUSH ;SAVE THINGS TTYOUT #CREM,#LCREM ;PUT OUT THE WARNING CALL GTDEV ;FIND OUT WHICH DEVICE BCS 200$ ;JUST LEAVE CALL GLBREC ;FILL IN THE GLOBAL RECORD MOV #DAFINF,R2 ;RECORD POINTER 5$: ADD #DF.LRC,R2 ;POINT TO NEW ACCOUNT RECORD 10$: CALL GTWHO ;GET THE UIC TO ACCOUNT BCS 100$ ;THAT IS ALL CALL LOCATE ;CHECK IF ALREADY THERE BCS 6$ ;IF CS, THEN NOT THERE PSTR ^*/ACCOUNT ALREADY EXISTS/* BR 10$ ;TRY FOR ANOTHER 6$: CMP DAFINF+DAF.SZ,#SZ.DAF ;IS THE DAF FULL? BLT 7$ ;IF LT, THEN NO CALL DAFULL ;TELL HIM DAF IS FULL BR 100$ ;AND STOP WITH THIS FILE 7$: INC DAFINF+DAF.SZ ;ONE MORE RECORD IN DAF MOV R1,DF.UIC(R2) ;OF THIS UIC CALL GTMDC ;GET HIS MAXIMUM ALLOCATION CALL INIREC ;ZERO REMAINDER OF RECORD BR 5$ ;TRY FOR ANOTHER UIC 100$: OPEN$W #DAFFDB,,,,,,IOERR ;OPEN THE DAF CALL WRTDAF ;FILL IT UP CLOSE$ ,IOERR ;CLOSE IT 200$: POP RETURN ; ; ; PRETXT CREM: .ASCII /The file that you will create now will REPLACE THE/ .ASCII /CURRENT ACCOUNTING FILE. So please be sure of what/ .ASCII /you do. To leave current account file intact, type/ .ASCII /CTRL-Z in response to the first prompt./ LCREM =.-CREM PSTTXT .dsabl lsb .SBTTL >MODIFY DAF ENTRIES .enabl lsb ;+ ; ; MODIFY -- ROUTINE TO ALLOW FOR THE MODIFICATION/INSERTION ; OF ACCOUNTING RECORDS. ; ;- MODIFY: PUSH 1$: CALL GTDEV ;FIND OUT WHICH DEVICE BCS 200$ ;JUST LEAVE CALL GTWHO ;WHICH UIC BCS 200$ ;NO UIC OPNS$U #DAFFDB,,,,,,IOERR CALL REDDAF ;READ IN THE DAF CALL LOCATE ;LOCATE THE UIC BCS 5$ ;NOT FOUND, SO INSERT IT MOV R0,R2 ;POINT TO THE RECORD BR 10$ ;SEE WHAT TO DO WITH IT 5$: PSTR ^*/INSERTING NEW ENTRY FOR ACCOUNTING/* MOV #DAFINF,R2 ;GET ADDRESS OF THE INFO INC DAF.SZ(R2) ;INCLUDE THIS NEW RECORD TO COUNT MOV DAF.SZ(R2),R3 ;THEN FULL SIZE ;(WITH GLOBAL RECORD) MUL #DF.LRC,R3 ;AS A BYTE COUNT ADD R3,R2 ;THERE WE ARE MOV R1,DF.UIC(R2) ;SO PUT IN THE NEW UIC CALL INIREC ;INITIALIZE THE RECORD MOV R2,R0 ;AND POINT TO IT SO WE CAN 10$: CALL PRTREC ;SHOW HIM WHAT IT IS NOW CALL GTMDC ;GET THE MDC MOV #DAFFDB,R0 ;GET BACK DAF FDB CALL WRTDAF ;WRITE BACK THE FILE CLOSE$ ,IOERR ;AND CLOSE IT BR 1$ ;AND GO BACK 200$: POP RETURN ; .dsabl lsb .SBTTL >EXAMINE DAF ENTRIES .enabl lsb ;+ ; ; EXAMIN -- ROUTINE TO ENABLE THE EXAMINATION OF SPECIFIC DAF ENTRIES. ; ;- EXAMIN: PUSH 1$: CALL GTDEV ;FIND OUT WHICH DEVICE TO EXAMINE BCS 10$ ;THERE AIN'T ONE OPNS$R #DAFFDB,,,,,,IOERR CALL REDDAF ;AND READ IT IN CLOSE$ ,IOERR ;AND LET THE DAF BE CALL PRTHED ;OUTPUT THE HEADER RECORD 4$: CALL GTWHO ;FIND OUT WHICH UIC BCS 1$ ;HE'S DONE WITH THIS DEVICE CALL LOCATE ;TRY TO FIND IT BCC 5$ ;WE DID PSTR ^*/ACCOUNT ENTRY NOT FOUND/* BR 4$ ;TRY FOR ANOTHER ONE 5$: CALL PRTRH ;THE RECORD HEADER CALL PRTREC ;SHOW HIM THIS RECORD BR 4$ ;TRY FOR ANOTHER ONE 10$: POP ;GO BACK TO THE OPTIONS RETURN ; .dsabl lsb .SBTTL >ZERO THE DAF ;+ ; ; ZERO -- DCNT COMMAND TO ALLOW FOR THE EMPTYING OF THE DAF ; WITHOUT LOSING THE UIC'S THAT ARE TO BE ACCOUNTED. ; ;- ZERO: PUSH ;SAVE THESE REGISTERS TTYOUT #ZMES,#LZMES ; GIVE INTRODUCTORY MESSAGE 1$: CALL GTDEV ; FIND OUT WHICH DEVICE BCS 100$ ; IF CS, HE DOESN'T WANT ONE OPNS$U #DAFFDB,,,,,,IOERR CALL REDDAF ; READ IN THE DAF MOV #DAFINF,R1 ; POINT TO THE INFO CLR DF.YR(R1) ; CLEAR THE DATE CLR DF.MIN(R1) ; ZERO TOTAL ACCOUNTED TIME CLR DF.MIN+2(R1) ; MOV DAF.SZ(R1),R2 ; GET THE NUMBER OF RECORDS BEQ 10$ ; IF EQ, THEN NOTHING THERE 5$: ADD #DF.LRC,R1 ; POINT TO A RECORD CLR DF.CDC(R1) ; AND EMPTY THE RECORD'S CLR DF.CDC+2(R1) ; CURRENT DISK COUNT, CLR DF.DBH(R1) ; AMOUNT OF TOTAL BLOCK HOURS, CLR DF.DBH+2(R1) ; AND SOB R2,5$ ; 10$: CALL WRTDAF ; WRITE BACK THE DAF CLOSE$ ,IOERR ; AND CLOSE THE FILE BR 1$ ; SEE IF HE WANTS TO DO MORE 100$: POP ;THAT IS ALL RETURN ; ; ; PRETXT ZMES: .ASCII /If you continue, EACH ACCOUNTING RECORD WILL BE EMPTIED./ .ASCII /There will be no way to retrieve that information once/ .ASCII /the file has been zeroed. If you wish to retain the current/ .ASCII /accounting information, enter a CTRL-Z in response to the/ .ASCII /first prompt./ LZMES =.-ZMES PSTTXT .SBTTL >CREATE A LISTING FILE OF THE DAF .enabl lsb ;+ ; ; LIST -- IS A DCNT OPTION WHICH ALLOWS FOR THE CREATION OF A ; READABLE LISTING FILE OF THE DAF. ; ;- .MCALL CSI$,FDOP$R LIST: PUSH ;SAVE SOME REGISTERS L.1: CALL GTDEV ;FIND OUT WHICH DEVICE TO LIST BCC L.2 ;ALL OKAY, CONTINUE JMP L.100 ;THERE AIN'T ONE L.2: TTYOUT #ASKFL,#LASKFL ;ASK FILE NAME READ #20.,L.100 ;GET HIS ANSWER MOV RDSTAT+2,R1 ;GET LENGTH OF STRING BGT L.3 ;THERE IS SOMETHING THERE FDOP$R #OTFIL,,#TIDSDS ;USE TI: DSDS BR L.5 ;OPEN THE FILE L.3: CSI1 #CSIBLK,#RDBUF,R1,CS1ERR ;COMPRESS IT INTO CSI BLOCK CSI2 ,OUTPUT,,CS2ERR ;AND GET THE DSDS FDOP$R #OTFIL,,#CSIBLK+C.DSDS ;AND USE IT L.5: OPEN$W #OTFIL,,,,,,IOERR ;OPEN THE FILE OPNS$R #DAFFDB,,,,,,IOERR ;OPEN THE DAF CALL REDDAF ;READ IT IN CLOSE$ ,IOERR ;DONE WITH IT CALL SETHD1 ;LIST OF GLOBAL RECORD PUT$ #OTFIL,#MESOUT,R1,IOERR ;SEND IT CALL SETHD2 ;REST OF GLOBAL RECORD PUT$ ,,R1,IOERR ;SEND IT CALL SETRH1 ;RECORD HEADING PUT$ ,,R1,IOERR ;SEND IT CALL SETRH2 ;RECORD HEADING PUT$ ,,R1,IOERR ;SEND IT MOV #DAFINF,R0 ;WHERE THE INFO IS MOV DAF.SZ(R0),R2 ;HOW MUCH THERE IS BEQ L.11 ;NOTHING THERE CALL L.10 ;ITERATE L.11: CLOSE$ #OTFIL,IOERR ;DONE WITH THIS FILE JMP L.1 ;SEE IF THERE IS MORE L.100: POP ;ALL DONE RETURN ; ; L.10: ADD #DF.LRC,R0 ;POINT TO A RECORD CALL SETREC ;LIST IT MOV R0,-(SP) ;SAVE FROM FCS PUT$ #OTFIL,#MESOUT,R1,IOERR ;SEND RECORD INFO MOV (SP)+,R0 ;GET BACK INFO POINTER SOB R2,L.10 ;PROCESS REMAINDER OF BUFFER RETURN ;RETURN TO MAIN STUFF ; ; PRETXT ASKFL: .ASCII /Enter listing file name > / LASKFL =.-ASKFL PSTTXT .dsabl lsb .SBTTL STORAGES FOR THE LIST ROUTINE. ; FLUN=1 FEVF=1 OTFIL: FDBDF$ FDAT$A R.VAR,,150.,1.,-1. FDRC$A ,MESOUT,150. FDOP$A FLUN,TIDSDS,DFNMBK FDBF$A FEVF ; TIDSDS: .WORD LTI,TI .WORD 0,0 .WORD 0,0 TI: .ASCII /TI:/ LTI =.-TI .EVEN ; DFNMBK: NMBLK$ DISK,LST,,SY,0 ; CSI$ .EVEN CSIBLK: .BLKB C.SIZE .EVEN ; FSRSZ$ 1 ;FILE STORAGES ; .END START