.TITLE DSKACN - DISK ACCOUNTING .IDENT /V2.0/ .ENABL LC .NLIST BEX,ME,CND ; ; THIS CODE HAS BEEN DEVELOPED BY THE COMPUTING ; GROUP OF THE ATMOSPHERIC SCIENCES DIVISION, ; ALBERTA RESEARCH. ; ; THERE IS EXPLICITLY NO COPYRIGHT ON THIS SOFTWARE, ; AND ITS DISTRIBUTION IS ENCOURAGED. NO RESPONSIBILITY ; NOR GUARANTEE IS MADE OR ASSUMED BY THE AUTHOR, OR ; BY ALBERTA RESEARCH. ; ; SUGGESTIONS OR CHANGES ARE INVITED, AND WILL BE ; DISTRIBUTED TO OTHER USERS OF THIS SOFTWARE THROUGH ; THE DECUS IAS/RSX SPECIAL INTEREST GROUP. ; ; ; VERSION: WK03.01 ; WRITTEN BY: W. KORENDYK ; DATE WRITTEN: 12-AUG-78 ; ; RELATED DOCUMENTATION: ; ; ; MODIFICATIONS: ; ; CODE NAME DATE ; ;+ ; ; DISK ACCOUNTING -- THIS IS THE ENTIRE DISK ACCOUNTING PACKAGE USED ; AT THE ATMOSPHERIC SCIENCES DIVISION, ALBERTA RESEARCH. ; ; FOR THE PROPER USE, THE TABLE AT THE BOTTOM OF THIS PAGE MUST CONTAIN ; THE ASCII NAME OF ALL THE DISKS THAT ARE TO BE ACCOUNTED. THE ACCOUNTING ; FILES ARE MAINTAINED ON "LB0:[1,2]ACCNTXXXX.SYS;1" WHERE THE "XXXX" ; REPRESENTS THE NAME OF THE DISK WHIH THAT FILE ACCOUNTS. PORTIONS OF ; CODE THAT ARE OF INTEREST ARE THE TABLE BELOW, AND THE RESCHEDULING ; TIME INTERVAL (ON THE SECOND LAST PAGE OF CODE). ; ;- .MCALL GTIM$S,GTSK$,RUN$,DIR$ TILUN=5 TIEVF=23. .psect data,d,rw,rel RUN: RUN$ DSKACN,GEN,150.,1,1,1,4 ; Run every hour GTSK: GTSK$ DAFINF ; Get task info. .SBTTL >MAIN CODE .PSECT START:: TINIT TILUN,TIEVF ;PREPARE FOR TERMINAL OUTPUT FINIT$ ;AND FILE I/O ; ; BEFORE DOING ANYTHING, RE-REQUEST ACTIVATION OF US... ; DIR$ #GTSK,DIRERR ; Get task parameters MOV DAFINF+G.TSTN,RUN+R.UNTN ; Set task name MOV DAFINF+G.TSTN+2,RUN+R.UNTN+2 ; Set task name MOV #DF.TIM,RUN+R.UNSM ; Set schedule interval MOV #DF.SUN,RUN+R.UNSU ; Set schedule units DIR$ #RUN,DIRERR ; And request us again ; MOV #DEVTAB,R0 ; GET DEVICE TABLE 1$: MOV (R0)+,R1 ; LENGTH OF FIRST DEVICE STRING BEQ 10$ ; IF EQ, THEN NOT THERE MOV R1,DSDS ; REPLACE DEVICE LENGTH OF INDEX FILE MOV (R0)+,R2 ; ADDRESS OF THE DEVICE NAME MOV R2,DSDS+2 ; AND REPLACE DEVICE OF INDEX FILE NAME MOV R1,-(SP) ; REMEMBER THE LENGTH MOV #OUTDV,R3 ; TO PUT INTO THE FULL MESSAGE. 2$: MOVB (R2)+,(R3)+ ; MOVE IT IN THERE SOB R1,2$ ; MOVB #'.,(R3)+ ; END THE SENTENCE MOVB #40,(R3)+ ; AND DELIMIT IT MOV #OUTDV,R2 ; START OF THE STRING MOV #FILDV,R3 ; TO GO HERE MOV (SP),R1 ; OF THAT LENGTH DEC R1 ; LESS THE ": 3$: MOVB (R2)+,(R3)+ ; MOVE IT OVER SOB R1,3$ ; MOV #5,R1 ; MAX SIZE OF THE DEVICE NAME SUB (SP)+,R1 ; LESS THE SIZE WE MOVED BLE 5$ ; 4$: TSTB -(R3) ; POINT TO THE NUMBER MOVB (R3)+,(R3) ; PUSH IT UP MOVB #'0,-(R3) ; AND PRECEDE WITH '0 5$: ; REFERENCE LABEL CALL DAF ; GO AND UPDATE ACCOUNT FILE BR 1$ ; AND THEN TO THE NEXT DISK 10$: ; REFERENCE LABEL EXIT: EXIT$S .SBTTL >ACCOUNT FILE MAINTAINENCE .ENABL LSB ; ; THIS PORTION OF DSK UPDATES THE DISK SPACE ACCOUNTIN FILE. ; IT READS IN THE DAF, AND UPDATES THE CURRENT DISK SPACE ; USAGE. IT THEN FINDS ALL LOGGED ON USERS, CHECKS IF THEY ; EXCEED THEIR LIMITS, AND IF SO, ISSUES A WARNING MESSAGE. ; DAF: PUSH ; MOV #DAFINF,R1 ;POINT TO DAF INFO BUFFER OPNS$U #DAFFDB, ;OPEN THE DAF, STILL LET IT READ BCC 200$ ;OPENED OKAY CMPB #IE.NSF,F.ERR(R0) ;WAS THERE A FILE? BNE 198$ ;YES, SOMETHING ELSE WRONG CALL NODAF ;ISSUE WARNING JMP END ;AND IGNORE THE REST 198$: CALL IOERR ;AN ERROR 200$: READ$ ,R1,,,,,,IOERR ;READ THE INFO WAIT$ ,,,IOERR ;AND WAIT FOR IT ; MOV DAF.SZ(R1),R2 ;GET THE SIZE CMP #SZ.DAF+1,R2 ;COMPARE SIZES BGE 201$ ;IT ALL WILL FIT CALL NOFIT ;IT DON'T FIT 201$: INC R2 ;INCLUDE GLOBAL REC. MUL #DF.LRC,R2 ;GET FULL BYTE COUNT DIV #512.,R2 ;AS A BLOCK COUNT TST R3 ;ANY REMAINDER? BEQ 202$ ;IF EQ, NO INC R2 ;ADD A FULL BLOCK 202$: MOV R2,FILSZ ;REMEMBER THE SIZE OF DAF SUB #1,R2 ;LESS BLOCK WE ALREADY HAVE BLE 204$ ;IF LE, WE HAVE IT ALL 203$: ADD #512.,R1 ;NEXT POSITION IN INFO BUFF. READ$ #DAFFDB,R1,,,,,,IOERR ;READ IT IN WAIT$ #DAFFDB,,,IOERR ;AND WAIT FOR IT SOB R2,203$ ;FOR THE REMAINING BLOCKS 204$: ;REFERENCE LABEL .DSABL LSB ; ; UPDATE THE GLOBAL INFO RECORD... ; MOV #DAFINF,R0 ;GET POINTER TO INFO ADD #DF.TIM,DF.MIN(R0) ;AND UPDATE THE ADC DF.MIN+2(R0) ; ELLAPSED TIME TST DF.YR(R0) ;IS THERE A BEGINNING TIME? BNE 209$ ;YES, SO BYPASS SUB #20,SP ; FILLING IN THE START TIME MOV SP,R1 ;POINT TO BUFFER GTIM$S R1,DIRERR ;GET TIME INFO MOV G.TIYR(R1),DF.YR(R0) ;GET THE YEAR MOVB G.TIMO(R1),DF.MO(R0) ; MONTH MOVB G.TIDA(R1),DF.DA(R0) ; DAY MOVB G.TIHR(R1),DF.HR(R0) ; HOUR MOVB G.TIMI(R1),DF.MI(R0) ; MINUTE ADD #20,SP ;RELEASE BUFFER ; ; CLEAR OUT THE PREVIOUS CURRENT INFORMATION... ; 209$: MOV DAF.SZ(R0),R1 ;GET THE SIZE BEQ 230$ ;THIS FILE IS EMPTY 210$: ADD #DF.LRC,R0 ;POINT TO NEXT RECORD CLR DF.CDC(R0) ;CLEAR THE CURRENT CLR DF.CDC+2(R0) ; BLOCK USAGE COUNT SOB R1,210$ ;FOR ALL RECORDS ; ; AND FILL IN WITH NEW INFORMATION... ; MOV #ACTEST,R5 ;THE FILL'ER IN'ER CALL BLKSPC ;AND GO ACCESS INDEX FILE ; ; FIND OUT WHO ALL IS LOGGED ON... ; MOV #TERBLK,R3 ;TERMINAL DESCRIPTION BLOCK ; CLR 2(R3) ;START WITH TT0: ;220$: CALL GTUCB ;GET THE TERMINAL'S UCB ; BCS 225$ ;IF CS, THEN NO MORE TERMS AVAIL. ; BIT #U2.LOG,U.CW2(R1) ;LOGGED IN? ; BNE 223$ ;IF NE, NO ; MOV U.LUIC(R1),R1 ;GET THE LOGGIN UIC ; CALL LOCATE ;FIND IT IN DAF INFO BUFF. ; BCS 223$ ;IF CS, NO FINDIE ; CMP DF.CDC+2(R0),DF.MDC+2(R0) ; BGT 221$ ;TOO MUCH SPACE USED ; BLT 223$ ;IS OKAY ; CMP DF.CDC(R0),DF.MDC(R0) ; ; BLE 223$ ;STILL OKAY ;221$: CALL FULMSG ;OUTPUT THE WARNING ;223$: INC 2(R3) ;TRY THE NEXT ; BR 220$ ; TERMINAL. 225$: ;REFERENCE LABEL ; ; CALCULATE THE "COST" TO EACH USER... ; MOV #DAFINF,R0 ;POINT TO GLOBAL RECORD MOV DAF.SZ(R0),R1 ;GET NUMBER OF UIC RECORDS 226$: ADD #DF.LRC,R0 ;POINT TO NEXT UIC RECORD CALL COST ;CALCULATE THE COST SOB R1,226$ ;AND ON TO THE NEXT ; ; AND FINALLY WRITE OUT THE NEW DAF... ; 230$: MOV #1,DAFFDB+F.BKVB+2 ;WRITE TO BLOCK #1 MOV #DAFINF,R1 ;POINT TO THE INFO MOV FILSZ,R2 ;AND GET NO. OF BLKS 232$: WRITE$ #DAFFDB,R1,,,,,,IOERR ;WRITE OUT A BLOCK WAIT$ #DAFFDB,,,IOERR ;AND WAIT FOR IT ADD #512.,R1 ;POINT TO THE NEXT SOB R2,232$ ;AND WRITE IT IF NEC. CLOSE$ #DAFFDB,IOERR ;CLOSE THE FILE END: POP R0 ;AND STOP RETURN ; .SBTTL >NO DAF ;+ ; ; NODAF -- DESIRED DAF DOES NOT EXIST ; ;- .MCALL TTYOUT NODAF: CALL ERRPFX PSTR ^*/MISSING ACCOUNT FILE FOR /* TTYOUT DSDS+2,DSDS PSTR ^*/./* RETURN .SBTTL >NO FIT ;+ ; ; NOFIT -- NOT ENOUGH SPACE FOR DAF INFO ; ;- NOFIT: CALL ERRPFX PSTR ^*/INSUFFICIENT BUFFER SPACE/* JMP DIE .SBTTL >DISK ACCOUNTING WARNING MESAGE ;+ ; ; FULMSG -- ROUTINE TO ISSUE THE MESSAGE TO THE LOGGED ON ; USER THAT HE HAS EXCEEDED HIS ALLOTED DISK SPACE ; ALLOCATION ; ; INPUTS: (R3) = TERMINAL MNEUMONIC (IN ASCII) ; 2(R3) = TERMINAL UNIT NUMBER ; ;- BEL=7 TLUN=3 TEVF=3 .MCALL ALUN$S,QIOW$S FULMSG: ALUN$S #TLUN,(R3),2(R3) QIOW$S #IO.WBT,#TLUN,#TEVF,,,,<#MESS,#LMESS> RETURN ; .ENABL LC .NLIST BEX MESS: .ASCII / ***** WARNING ***** WARNING *****/ .ASCII /You have use more than your allotted disk/ .ASCII /space on / OUTDV: .ASCII /DM00: Please delete some files./ LMESS =.-MESS .EVEN .DSABL LC .LIST BEX .SBTTL >BLKSPC - SCAN INDEX.SYS ;+ ; ; BLKSPC -- ROUTINE TO SCAN THE INDEX.SYS FILE OF THE ; SYSTEM DEVICE AND COUNT UP THE NUMBER OF BLOCKS ; USED BY THE SPECIFIED UIC. ; ; INPUTS: R5 = ROUTINE TO CALL FOR TESTING THE UIC ; IUIC = THE UIC TO TEST ; ; OUTPUTS: CALLS THE TEST ROUTINE WITH R1=THE HEADER UIC ; ;- BLKSPC: PUSH MOV #STATUS,INXFDB+F.STBK ;FILL IN STATUS BLOCK OPNS$R #INXFDB,,,,,,IOERR ;OPEN THE INDEX FILE MOV #STATUS+6,R3 ;GET EOF BLK INFO MOV (R3)+,F.HIBK(R0) ; INTO THE HIGH BLOCK MOV (R3),F.HIBK+2(R0) ; COUNT OF FDB, ADD #1,(R3) ;INC TO EOF BLOCK ADC -(R3) ; NUMBER, MOV (R3)+,F.EFBK(R0) ;AND PUT INTO EOF BLOCK MOV (R3),F.EFBK+2(R0) ; INTO FDB. MOV #2,F.BKVB+2(R0) ;POINT TO HOME BLOCK READ$ #INXFDB,#BUFFR1,#512.,,#INXEF1,,,IOERR ;AND READ IT WAIT$ #INXFDB,#INXEF1,,IOERR ; MOV BUFFR1+H.IBSZ,R1 ;GET INDEX BITMAP SIZE ADD #3,R1 ;SKIP OVER BOOTSTRAP BLOCK, ; HOME BLOCK, AND INDEX ; FILE BITMAP. MOV R1,INXFDB+F.BKVB+2 ;POINT TO INDEX FILE HEADER READ$ #INXFDB,#BUFFR1,#512.,,#INXEF1,,,IOERR ;AND READ IT WAIT$ #INXFDB,#INXEF1,,IOERR ; MOV #BUFFR1,R4 ; CALL GETBLK ;GET # BLOCKS IN INDEX FILE SUB R1,R2 ;LESS THE OTHER STUFF DEC R2 ; MOV R2,R3 ;READY FOR THE DIVISION CLR R2 ; DIV #NBLKS,R2 ;NUMBER OF READS TO DO MOV R3,-(SP) ;REMEBER WHAT'S LEFT OVER .MACRO DEBLK,BUFFER MOV BUFFER,R4 CALL DEBLK .ENDM ; ; NOW POINTING TO FILE HEADER FOLLOWING THE INDEX FILE HEADER, ; SO READ DOWN THE LIST. ; 10$: READ$ #INXFDB,#BUFFR1,#<512.*NBLKS>,,#INXEF1,,,IOERR 11$: DEC R2 ;ANYMORE? BLE 16$ ;NO READ$ ,#BUFFR2,,,#INXEF2,,,IOERR WAIT$ ,#INXEF1,,IOERR DEBLK #BUFFR1 DEC R2 ;ANY MORE? BLE 15$ ;NO READ$ ,#BUFFR1,,,#INXEF1,,,IOERR WAIT$ ,#INXEF2,,IOERR DEBLK #BUFFR2 BR 11$ ;AND ITERATE 15$: WAIT$ ,#INXEF2,,IOERR DEBLK #BUFFR2 BR 20$ ;THAT IS ALL 16$: WAIT$ ,#INXEF1,,IOERR DEBLK #BUFFR1 20$: MOV (SP)+,R3 ;NUMBER OF BLOCKS LEFT BLE 25$ ;DONE MOV R3,R2 ; ASH #11,R2 ;NUMBER OF BYTES READ$ ,#BUFFR1,R2,,#INXEF1,,,IOERR WAIT$ ,#INXEF1,,IOERR ; MOV #BUFFR1,R4 ; 21$: MOV H.FOWN(R4),R1 ; CALL @R5 ; ADD #512.,R4 ; SOB R3,21$ ; 25$: CLOSE$ ,IOERR ;CLOSE THE INDEX FILE POP RETURN ; DEBLK: MOV #NBLKS,R3 ; 1$: MOV H.FOWN(R4),R1 ;GET THIS FILE'S OWNER CALL @R5 ;AND TEST IT ADD #512.,R4 ;NEXT HEADER SOB R3,1$ ;IF THERE IS ONE RETURN .SBTTL >GETBLK - COUNT BLOCKS ;+ ; ; GETBLK -- ROUTINE TO DETERMINE THE NUMBER OF BLOCKS ; ALLOCATED BY A SPECIFIC FILE. ; ; INPUTS: R4 = ADDRESS OF THE FILE HEADER ; ; OUTPUTS: R2 = NUMBER OF BLOCKS ; ;- GETBLK: PUSH MOV R4,R0 ;MAKE EASIER TO ACCESS CLR R2 ;CLR COUNT ; TST H.FNUM(R0) ;IS THIS HEADER USED? BEQ 20$ ;NO, SO IGNORE MOVB H.MPOF(R0),R1 ;GET MAP AREA OFFSET ASL R1 ;AND CONVERT TO BYTE OFFSET ADD R1,R0 ;ADJUST POINTER TO MAP AREA MOVB M.USE(R0),R1 ;GET # OF WORDS OF RETRIEVAL PTRS. BIC #177400,R1 ;MASK OUT THE SIGN EXTEND ASR R1 ;EACH POINTER CONSISTS OF 2 WORDS BLE 20$ ;0 BLOCKS ALLOCATED - EXIT!!! ADD #M.RTRV,R0 ;MOVE TO START OF RETRIEVAL PTRS. 2$: MOVB 1(R0),R3 ;GET BLOCK COUNT-1 BIC #177400,R3 ;CLEAR UPPER BYTE (SBE) INC R3 ;GET BLOCK COUNT ADD R3,R2 ;ADD TO TOTAL CMP (R0)+,(R0)+ ;MOVE TO NEXT RETRIEVAL POINTER SOB R1,2$ ;IF THERE ARE MORE 20$: POP RETURN .SBTTL >GENERAL ACCOUNTING TEST ;+ ; ; ACTEST -- GENERAL ACCOUNTING TEST ROUTINE FOR THE ; BLOCK SPACE USAGE COUNTING ; ; INPUTS: R1 = UIC OF THE HEADER (IE. OF THE FILE) ; ;- ACTEST: PUSH CALL LOCATE ;LOCATE THE UIC BCS 10$ ;NO FINDIE CALL GETBLK ;GET THE SIZE ADD R2,DF.CDC(R0) ;ADD TO THE CURRENT ADC DF.CDC+2(R0) ; COUNT 10$: POP RETURN ; ; .SBTTL >CALCULATE COST ;+ ; ; COST -- ROUTINE TO DETERMINE THE COST TO THE ; USER IN DISK BLOCK HOURS. ; ; ALGORITHM: BLOCKS * HR/MIN * DURATION = ; ; = BLOCKS * DF.TIM / 60. ; ; INPUTS: R0 = ADDRESS OF UIC RECORD ; ; NOTE THIS ROUTINE IS BASED ON THE ASSUMPTION THAT THE ; TOTAL DISK BLOCK HOURS FOR THIS TIME PERIOD WILL ; NEVER XCEED A ONE WORD INTEGER. ; ; NOTE THAT THE CALCULATIONS BELOW FORCE A TRUNCATION ; OF THE BLOCKS USED IN THE TIME PERIOD. ; ;- COST: PUSH MOV DF.CDC(R0),CST MOV DF.CDC+2(R0),CST+2 MUL12 #DF.TIM,CST,R3 MOV CST,R5 MOV CST+2,R4 DIV #60.,R4 ADD R4,DF.DBH(R0) ADC DF.DBH+2(R0) POP RETURN ; ; CST: .WORD 0,0,0 .SBTTL >LOCATE THE UIC IN DAF INFO ;+ ; ; LOCATE -- ROUTINE WHICH LOCATES THE UIC IN THE ; DAF INFO BLOCK. ; ; INPUTS: R1 = UIC ; ; OUTPUTS: R0 = START OF THE RECORD ; IF NOT FOUND, CARRY IS SET ; ;- LOCATE: PUSH R2 MOV #DAFINF,R0 ;GET INFO START MOV DAF.SZ(R0),R2 ;AND NO. OF RECORDS 10$: ADD #DF.LRC,R0 ;POINT TO THE RECORD CMP DF.UIC(R0),R1 ;DO UICS MATCH? BEQ 100$ ;YES THEY DO SOB R2,10$ ;GO DO THE RES SEC ;COULDN'T FIND BR 101$ ;LEAVE 100$: CLC ;INDICATE SUCCESS 101$: POP R2 RETURN .SBTTL >GET THE UCB ;+ ; ; GTUCB -- ROUTINE TO OBTAIN THE ADDRESS OF THE ; DESIRED UCB. ; ; INPUTS: R3 = ADDRESS OF 2-WORD TERMINAL DESCRIP. ; (R3) = ASCII MNEUMONIC ; 2(R3) = UNIT NUMBER ; ; USAGE REQUIRES THE TASK TO BE PRIVILEGED ; ; OUTPUTS: R1 = ADDRESS OF THE UCB ; R2 = ADDRESS OF THE DCB ; R3 = UNCHANGED ; ;- GTUCB:; ENTER R0,R3,R4,R5 ; CMP 2(R3),#256. ;UNIT IN RANGE? ; BLO 10$ ;YES, PROCEED ; SEC ;NO IT AIN'T ; BR 100$ ;FERGET IT ; ;10$: CALL $SWSTK,100$ ;SWITCH TO SYSTEM STATE ; MOV $DEVHD,R2 ;GET ADDRESS OF DEVICE TABLE ;12$: CMP (R3),D.NAM(R2) ;IS THIS THE DEVICE? ; BEQ 20$ ;YES IT IS ;15$: MOV D.LNK(R2),R2 ;NO, POINT TO NEXT DCB ; BNE 12$ ;GOT ONE ; BEQ 50$ ;END OF DEVICES, ERROR ;20$: MOV 2(R3),R5 ;GET THE UNIT NUMBER ; CMPB R5,D.UNIT(R2) ;IS UNIT ON THIS DCB? ; BLO 15$ ;NO ; CMPB R5,D.UNIT+1(R2) ;MAYBE? ; BHI 15$ ;NO ; MOVB D.UNIT(R2),R4 ;GET FIRST UNIT NUMBER ; MOV D.UCB(R2),R1 ;GET FIRST UCB ADDRESS ; SUB R4,R5 ;COMPUTE RELATIVE UNIT NUMBER ; BEQ 45$ ;FOUND IT! ;30$: ADD D.UCBL(R2),R1 ;NO, POINT TO NEXT UCB ; DEC R5 ;FOUND IT YET? ; BNE 30$ ;NO, LOOP ;45$: MOV R1,4(SP) ;SET USER R1 ; MOV R2,6(SP) ;SET USER R2 ; RETURN ;RETURN TO USER STATE ;50$: MOV @$HEADR,R3 ;GET USER SP ; INCB 6(R3) ;SET CARRY IN USER PS ; RETURN ;RETURN TO USER STATE ; ;100$: LEAVE RETURN .SBTTL >REMAINING STORE .MCALL GMCR$ ; ; INDEX FILE FDB ; INXLUN =1 INXEF1 =1 INXEF2 =3 NBLKS =6 ;THE NUMBER OF HEADERS TO READ AT A TIME ; INXFDB: FDBDF$ FDRC$A FD.RWM FDBK$A BUFFR1,<512.*NBLKS>,,INXEF1 FDOP$A INXLUN,DSDS ; ; DSDS: .WORD LDEV,DEV ;DEVICE .WORD LUIC,UIC ;UIC .WORD LFIL,FIL ;FILENAME ; DEV: .ASCII /DB0:/ LDEV =.-DEV UIC: .ASCII /[0,0]/ LUIC =.-UIC FIL: .ASCII /INDEXF.SYS;0/ LFIL =.-FIL .EVEN ; IUIC: .WORD 0 FAKDS: .BLKW 2 GMCR: GMCR$ .EVEN ; STATUS: .BLKW 5 COUNT: .BLKW 2 BUFFR1: .BLKB 512.*NBLKS BUFFR2: .BLKB 512.*NBLKS ; FILSZ: .WORD 0 ;REMEMBER THE FILE SIZE ; TERBLK: .ASCII /TI/ ;MNEUMONIC .WORD 0 ;UNIT ; FSRSZ$ 0 ;FILE STORAGES ; .END START