.TITLE CRU .IDENT /X01.00/ .SBTTL INTRODUCTION ; ; AUTHOR: GILBERT J. DELEEUW ; DATE: MAY 3, 1984 ; NAME: CONVERT, COMPRESS AND RESTORE UTILITY ; FUNCTION: CONVERTS CARRIAGE CONTROL AND RECORD TYPES, ; REMOVES UNNECESSARY CHARACTERS FROM TEXT FILES, ; SELECTS SUBSET OF PAGES FROM TEXT FILES, ; ALLOWS FILES TO BE COMPRESSED FOR BACKUP AND ; RESTORES FILES WHEN NEEDED. ; ; ALGORITHM 1: NON-DESTRUCTIVE COMPRESSION FOR TEXT FILE INCLUDES REMOVING ; ANY TRAILING BLANKS, AND CONVERTING SPACES TO TABS WHERE ; IT WILL SAVE CHARACTERS (ASSUMES STANDARD 8 COLUMN TABS). ; FILES ARE ALSO CONVERTED TO LISTING FORMAT CONTROL (FD.CR). ; ; ALGORITHM 2: DATA FILE COMPRESSION USES IMBEDDED CONTROL BYTES WHICH ; CONTAIN A CHARACTER COUNT AND BIT FLAG WHICH INDICATES ; WHETHER THE BYTE FOLLOWING IS REPEATED, OR WHETHER THE ; BYTE(S) FOLLOWING ARE DATA VALUES. ANY TIME THERE ARE ; THREE OR MORE SUCCESSIVE IDENTICAL BYTES IN THE UNCOMPRESSED ; RECORD, THEY ARE CONVERTED TO A CONTROL BYTE PLUS ONE BYTE ; TO CONTAIN THE VALUE. ; ; .MCALL FHDOF$,FINIT$ .MCALL GCML$,GCMLB$,GCMLD$,RCML$ .MCALL CSI$,CSI$1,CSI$2,CSI$SW,CSI$SV,CSI$ND .MCALL ALUN$S,DIR$,QIOW$,EXST$S .MCALL NMBLK$,FDBDF$,FSRSZ$ .MCALL FDAT$R,FDRC$A,FDOP$A,FDBF$A .MCALL OPEN$R,OPEN$,GET$,PUT$,CLOSE$,DELET$,PRINT$ ; ; DEFINE OFFSETS CSI$ FHDOF$ GCMLD$ ; ; LUN PARAMETERS LGCL=1 LINP=2 LOUT=3 LTRM=5 ; ; MAXIMUM RECORD SIZE UBSZ=512. FBSZ=2560. ; ; SWITCH MASK VALUES ; INPUT MASKS DEMSK==000001 ;DELETE INPUT FILE AFTER PROCESSING UCMSK==000002 ;UNCOMPRESS INPUT RECORDS ; ; OUTPUT MASKS CCMSK==000004 ;CARRIAGE CONTROL CMMSK==000010 ;COMPRESS OUTPUT CSMSK==000020 ;CONVERT SPACES TO TABS FLAG CTMSK==000040 ;CONVERT TABS TO SPACES FOMSK==000100 ;FILE ORGANIZATION LOMSK==000200 ;LOG FILE NAME NCMSK==000400 ;INPUT RECORD HANDLING FLAG PDMSK==001000 ;PADD FLAG PGMSK==002000 ;PAGE NUMBER MASK PSMSK==004000 ;PAGE SIZE MASK RTMSK==010000 ;REMOVE TRAILING BLANKS FLAG SPMSK==020000 ;SPOOL FLAG TRMSK==040000 ;TRUNCATE FLAG ; ; INPUT PROCESSING FLAGS APFLG=010000 ;APPEND RECORD FLAG BUFLG=020000 NRFLG=040000 ;NO READ FLAG (RECORD ALREADY THERE) OPFLG=100000 ;OUTPUT FILE OPEN FLAG ; ; DATA AREAS ; COMMAND STRING DATA AREA CSIBLK: .BLKB C.SIZE ; ; GET COMMAND LINE AREA GCLBLK: GCMLB$ 4,CRU,,LGCL ; ; CONSTANTS FOR PROCESSING SWITCHES LIST: .ASCII /LIST/ FTN0: .ASCII /FTN/<0> NONE: .ASCII /NONE/ .EVEN ; ; ; Work variables MKWD:: .WORD 0 CFLG:: .WORD 0 CCTYP:: .ASCII / / .EVEN CMPRM:: .WORD 0 FOCH:: .ASCII /V/ .BYTE 0 PDCH:: .ASCII / / .EVEN PDSZ:: .WORD 80. PGST:: .WORD 0 PGND:: .WORD 0 PAGE:: .WORD 0 PSIZ:: .WORD 0 LINE:: .WORD 0 SPDV:: .ASCII /LP/ .EVEN SPUN:: .WORD 0 SPFO:: .WORD 0 SPCO:: .WORD 1 TRSZ:: .WORD 80. ; ; DISPATCH TABLES CRTN: .WORD 0 GRTN: .WORD 0 PRTN: .WORD 0 ; ; SWITCH TABLES INSWT: CSI$SW DE,DEMSK,MKWD,SET,NEG ;DELETE SWITCH CSI$SW UC,UCMSK,MKWD,SET,NEG ;UNCOMPACT SWITCH OUSWT: CSI$SW CC,CCMSK,MKWD,SET,,CCVTB ;RECORD ATRRIBUTES SWITCH CSI$SW CM,CMMSK,MKWD,SET,NEG,CMVTB ;COMPACT SWITCH CSI$SW CS,CSMSK,MKWD,SET,NEG ;CONVERT SPACES TO TABS CSI$SW CT,CTMSK,MKWD,SET,NEG ;CONVERT TABS TO SPACES CSI$SW FO,FOMSK,MKWD,SET,,FOVTB ;FILE ORGINAZATION SWITCH CSI$SW LO,LOMSK,MKWD,SET,NEG ;LOG FILE NAME CSI$SW NC,NCMSK,MKWD,SET,NEG ;NO CONVERSION OF INPUT RECORDS CSI$SW PD,PDMSK,MKWD,SET,NEG,PDVTB ;PADD CHARACTER SWITCH CSI$SW PG,PGMSK,MKWD,SET,,PGVTB ;PAGE SELECT SWITCH CSI$SW PS,PSMSK,MKWD,SET,,PSVTB ;PAGE SIZE SWITCH CSI$SW RT,RTMSK,MKWD,SET,NEG ;REMOVE TRAILING BLANKS CSI$SW SP,SPMSK,MKWD,SET,NEG,SPVTB ;SPOOL OUTPUT FILE CSI$SW TR,TRMSK,MKWD,SET,,TRVTB ;TRUNCATE SWITCH CSI$ND CCVTB: CSI$SV ASCII,CCTYP,4 ;RECORD ATTRIBUTE TYPE CSI$ND CMVTB: CSI$SV DECIMAL,CMPRM,2 ;COMPRESSION PARAMETER CSI$ND FOVTB: CSI$SV ASCII,FOCH,2 ;FILE ORGANIZATION CHARACTER CSI$SV DECIMAL,FDBOU+F.RSIZ,2 ;RECORD SIZE VALUE TABLE CSI$ND PDVTB: CSI$SV OCTAL,PDCH,2 ;PADD CHARACTER VALUE TABLE CSI$SV DECIMAL,PDSZ,2 ;PADD LENGTH FOR VAR CSI$ND PGVTB: CSI$SV DECIMAL,PGST,2 ;START PAGE CSI$SV DECIMAL,PGND,2 ;END PAGE CSI$ND PSVTB: CSI$SV DECIMAL,PSIZ,2 ;PAGE SIZE CSI$ND SPVTB: CSI$SV ASCII,SPDV,2 ;DEVICE NAME CSI$SV DECIMAL,SPUN,2 ;UNIT NUMBER CSI$SV DECIMAL,SPFO,2 ;FORM NUMBER CSI$SV DECIMAL,SPCO,2 ;COPIES CSI$ND TRVTB: CSI$SV DECIMAL,TRSZ,2 ;TRUNCATE SIZE CSI$ND .EVEN ; ; QIO FOR MESSAGES TO TERMINAL TYPE: QIOW$ IO.WLB,LTRM,5,,,,<0,0,40> .EVEN ; ; INPUT RECORD BUFFER ISIZ: .WORD 0 IADR: .WORD 0 IBUF: .BLKB UBSZ ; ; OUTPUT WORK BUFFERS OSIZ: .WORD UBSZ OADR: .WORD OBUF .BLKB 4 OBUF: .BLKB UBSZ .BLKB 8. WBUF: .BLKB UBSZ .BLKB 6 ; ; FILE DESCRIPTOR BLOCKS DFNBI: NMBLK$ ,DAT,0,SY,0 .EVEN DFNBO: NMBLK$ ,DAT,0,SY,0 .EVEN ; FDBIN: FDBDF$ FDRC$A ,IBUF,UBSZ FDOP$A LINP,CSIBLK+C.DSDS,DFNBI,FO.RD,FA.DLK FDBF$A LINP,FBSZ,1 .EVEN ; FDBOU: FDBDF$ FDRC$A ,OBUF,UBSZ FDOP$A LOUT,CSIBLK+C.DSDS,DFNBO, FDBF$A LOUT,FBSZ,1 .EVEN ; ; FILE STORAGE REGION ; NOTE: GCML REQUIRES 1 RECORD I/O AND 512 BYTES FSRSZ$ 3,<2*FBSZ+512.> .EVEN ; ; MISC ERRORS .ENABL LC MSG: .ASCII !CRU -- ! .BLKB 72. MSG1: .ASCII !Record to large for available buffers!<12> MSG1L=.-MSG1 MSG2: .ASCII !Failed to spool output file!<12> MSG2L=.-MSG2 MSG3: .ASCII !Blocks read: Blocks written: ! MSG3L=.-MSG3 ; ; SYNTAX ERROR MESSAGE SYNM1: .ASCII !Command Syntax Error!<12> SYNM1L=.-SYNM1 ; ; SWITCH MESSAGES SWCM1: .ASCII !Illegal carriage control type!<12> SWCM1L=.-SWCM1 SWCM2: .ASCII !Illegal file organization type!<12> SWCM2L=.-SWCM2 SWCM3: .ASCII !Illegal record size or record size not specified!<12> SWCM3L=.-SWCM3 SWCM4: .ASCII !Fixed length output incompatible with compression!<12> SWCM4L=.-SWCM4 SWCM5: .ASCII !Illegal pad/truncate length!<12> SWCM5L=.-SWCM5 SWCM6: .ASCII !Input records are fixed length!<12> SWCM6L=.-SWCM6 SWCM7: .ASCII !Invalid page range specified!<12> SWCM7L=.-SWCM7 .EVEN .DSABL LC ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; PROGRAM ENTRY POINT START: FINIT$ ; ; ASSIGN LUNS TO TERMINAL ALUN$S #LGCL,#"TI,#0 ALUN$S #LTRM,#"TI,#0 ; ; SET GCML TO KEEP COMMAND FILE OPEN BICB #GE.CLO,GCLBLK+G.MODE BR GETCML ; ; QIO TRMMSG: MOV #7,R0 ;LENGTH OF STRING MOV #MSG,R1 ;ADDRESS OF STRING CALL CONCAT ;CONCATENATE STRINGS MOV R0,TYPE+Q.IOPL+2 ;LENGTH OF MESSAGE MOV R1,TYPE+Q.IOPL ;ADDRESS OF MESSAGE DIR$ #TYPE ; ; CLOSE INPUT FILE ERCLOS: CLOSE$ #FDBIN,CLSERR ; ; INITIALIZE DEFAULTS GETCML: CALL CRUDFT ;SET DEFAULTS CLR FDBOU+F.RSIZ ;DEFAULT RECORD SIZE ; ; GET A COMMAND LINE GCML$ #GCLBLK ;GET COMMAND LINE BCC CSI ;COMMAND LINE ERROR? CALL GCLMSG ;PROCESS ERROR BR TRMMSG ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; TEST FOR ZERO LENGTH LINE CSI: TST G.CMLD(R0) BEQ GETCML ; ; COMMAND SYNTACTIC ANALYZER CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD BCC CSIN ;TEST SYNTAX CALL CSISYN ;ERROR MESSAGE BR GETCML ;RESTART ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; COMMAND SEMANTIC PARSER CSIN: CSI$2 #CSIBLK,INPUT,#INSWT ;GET INPUT FILE BCC 10$ ;TEST SYNTAX CALL CSISYN ;ERROR MESSAGE BR GETCML ;RESTART ; ; CHECK FOR ERRORS 10$: CALL CSIMSG BCS TRMMSG ; ; SAVE ADDRESS OF FILE NAME STRING MOV C.FILD(R0),TYPE+Q.IOPL+2 MOV C.FILD+2(R0),TYPE+Q.IOPL ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; OPEN THE INPUT FILE OPNI: OPEN$R #FDBIN BCC CSOU ; ; OPEN ERROR ON INPUT FILE CALL IOMSG BR TRMMSG ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; PARSE OUTPUT FILE NAME CSOU: CSI$2 #CSIBLK,OUTPUT,#OUSWT BCC 10$ ;CHECK SYNTAX CALL CSISYN ;ERROR MESSAGE BR ERCLOS ;RESTART ; ; CHECK FOR ERRORS 10$: CALL CSIMSG BCS TRMMSG ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; PROCESS SWITCHES MOV MKWD,R1 ;GET MASK WORD FOR EFFICIENCY ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; CARRIAGE CONTROL CCSW: MOVB #FD.CR,FDBOU+F.RATT ;DEFAULT TO LIST CC MOV #CRUPGL,PRTN ;DEFAULT PAGE CONTROL BIT #CCMSK,R1 ;OUTPUT CC SPECIFIED? BEQ FOSW ;NOT SPECIFIED ; ; /CC:LIST MOV #4,R2 ;LENGTH OF COMPARE MOV #CCTYP,R3 ;ADDRESS OF STRING MOV #LIST,R4 ;STRING "LIST"0 CALL STRCMP ;COMPARE STRINGS BEQ FOSW ;MATCH? ; ; /CC:FTN MOVB #FD.FTN,FDBOU+F.RATT ;SET TO FORTRAN CC MOV #CRUPGF,PRTN ;FORTRAN PAGE CONTROL MOV #4.,R2 ;LENGTH OF COMPARE MOV #CCTYP,R3 ;ADDRESS OF STRING MOV #FTN0,R4 ;STRING "FTN"0 CALL STRCMP ;COMPARE STRINGS BEQ FOSW ;MATCH? ; ; /CC:NONE CLRB FDBOU+F.RATT ;INTERNAL FORMAT CONTROL MOV #CRUPGN,PRTN ;INTERNAL PAGE CONTROL MOV #4.,R2 ;LENGTH OF COMPARE MOV #CCTYP,R3 ;ADDRESS OF STRING MOV #NONE,R4 ;STRING "NONE"0 CALL STRCMP ;COMPARE STRINGS BEQ FOSW ;MATCH? ; ; ILLEGAL CARRIAGE CONTROL SPECIFICATION MOV #SWCM1 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM1L,R2 ;LENGTH OF MESSAGE BR SWERR ;SEND MESSAGE ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FILE ORGANIZATION SWITCH FOSW: MOVB #R.VAR,FDBOU+F.RTYP ;DEFAULT RECORD TYPE BIT #FOMSK,R1 ;SWITCH ENTERED? BEQ CMSW ;NO PROCESSING ; ; /FO:V CMP #'V,FOCH ;VARIABLE LENGTH RECORDS? BEQ CMSW ;YES ; ; /FO:F MOVB #R.FIX,FDBOU+F.RTYP ;FIXED RECORDS CMP #'F,FOCH ;FIXED LENGTH RECORDS? BEQ RSCK ;YES ; ; ILLEGAL FILE ORGANIZATION MOV #SWCM2 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM2L,R2 ;LENGTH OF MESSAGE BR SWERR ;SEND MESSAGE ; ; RECORD SIZE CHECK RSCK: TST FDBOU+F.RSIZ ;MUST BE GREATER THAN ZERO BLT 10$ ;NO CMP #UBSZ,FDBOU+F.RSIZ ;MUST BE LESS THAN MAX BUF BGE CMSW ;YES ; ; ILLEGAL RECORD SIZE 10$: MOV #SWCM3 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM3L,R2 ;LENGTH OF MESSAGE BR SWERR ;SEND MESSAGE ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; OUTPUT DATA COMPRESSION SWITCH CMSW: BIT #CMMSK,R1 ;COMPRESSION DESIRED? BEQ PDSW ;NO CMPB #R.VAR,FDBOU+F.RTYP ;VARIABLE LENGTH RECORDS? BEQ PDSW ;NO ; ; INPUT FILE MUST HAVE VARIABLE LENGTH RECORDS MOV #SWCM4 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM4L,R2 ;LENGTH OF MESSAGE BR SWERR ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; PADD SWITCH PDSW: BIT #PDMSK,R1 ;PADD SPECIFIED? BEQ UCSW ;NO CMPB #R.FIX,FDBOU+F.RTYP ;FIXED LENGTH RECORDS? BEQ 10$ ;YES TST PDSZ ;LEGAL PADD LENGTH? BLE 10$ ;NO CMP #UBSZ,PDSZ ;MUST BE LESS THAN MAX BUF BGE UCSW ;YES ; ; ILLEGAL PADD LENGTH 10$: MOV #SWCM5 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM5L,R2 ;LENGTH OF MESSAGE BR SWERR ;SEND MESSAGE ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; UNCOMPRESS SWITCH UCSW: BIT #UCMSK,R1 ;UNCOMPRESS SPECIFIED BEQ NCSW ;NO CMPB #R.VAR,FDBIN+F.RTYP ;VARIABLE LENGTH RECORDS? BEQ NCSW ; ; ILLEGAL FILE TYPE FOR UNCOMPRESS 10$: MOV #SWCM6 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM6L,R2 ;LENGTH OF MESSAGE ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Transfer switch errors SWERR: JMP TRMMSG ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; NC SWITCH - AND SET GET ROUTINE ADDRESS NCSW: MOV #PRCSS,GRTN ;NO CC PROCESSING? BIT #NCMSK,R1 ;NC SWITCH ENTERED? BNE PGSW ;YES ; ; TRY FTN MOV #GETFC,GRTN ;GET ROUTINE FOR FORTRAN CMPB #FD.FTN,FDBIN+F.RATT ;FORTRAN CARRIAGE CONTROL? BEQ PGSW ;YES ; ; LIST CARRIAGE CONTROL MOV #CVTCC,GRTN ;GO TO CONVERT CC AFTER GET? CMPB #FD.CR,FDBIN+F.RATT ;LIST CARRIAGE CONTROL? BEQ PGSW ;YES CMPB #R.FIX,FDBIN+F.RTYP ;FIXED LENGTH INPUT RECORDS? BEQ PGSW ;YES ; ; NO CARRIAGE CONTROL MOV #GETNC,GRTN ;NO CARRIAGE CONTROL ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; PAGE SELECT SWITCH PGSW: BIT #PGMSK,R1 ;PAGE RANGE SELECTED? BEQ TRSW ;NO ; ; TEST END PAGE TST PGND ;TEST END PAGE BEQ TRSW ;NO SPECIFIED ; ; TEST FOR VALID RANGE INC PGND ;INCREMENT END PAGE CMP PGND,PGST ;END HIGHER THAN START? BHI TRSW ;YES ; ; PAGE SPECIFICATION ERROR MOV #SWCM7 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM7L,R2 ;LENGTH OF MESSAGE BR SWERR ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; TRUNCATE SWITCH TRSW: BIT #TRMSK,R1 ;TRUNCATE SPECIFIED? BEQ IDFNB ;NO CMPB #R.FIX,FDBOU+F.RTYP ;FIXED LENGTH RECORDS? BEQ 10$ ;YES TST TRSZ ;LEGAL TRUNCATE LENGTH? BLE 10$ ;NO CMP #UBSZ,TRSZ ;MUST BE LESS THAN MAX BUF BGE IDFNB ;YES ; ; ILLEGAL PADD LENGTH 10$: MOV #SWCM5 ,R3 ;ADDRESS OF MESSAGE MOV #SWCM5L,R2 ;LENGTH OF MESSAGE BR SWERR ;SEND MESSAGE ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; COPY INPUT FILE NAME TO DFNBO IDFNB: MOV #>,R2 ;SIZE TO COPY MOV #FDBIN+F.FNB+N.FNAM,R3 ;START AT FILE NAME MOV #DFNBO+N.FNAM,R4 ;ADDRESS FOR OUTPUT DFNB 10$: MOV (R3)+,(R4)+ ;COPY WORD SOB R2,10$ ;LOOP ; ; NOW SET UP VERSION AND STATUS BYTES CLR DFNBO+N.FVER ;CLEAR VERSION NUMBER MOV #,DFNBO+N.STAT ; ; INITIALIZE FLAGS BIC #,CFLG ; ; GET CARRIAGE CONTROL CONVERSION ROUTINE MOV #FDBOU,R0 ;SUPPLY OUTPUT FDB ADDRESS MOV #FDBIN,R1 ;SUPPLY INPUT FDB ADDRESS CALL CRUCC ;GET CC CONVERSION ROUTINE ADDRESS MOV R2,CRTN ;RETURNED IN R2 ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; COPY LOOP COPY: BIT #NRFLG,CFLG ;NO READ FLAG BEQ GET ;NO ; ; RETRIEVE POINTERS TO CURRENT SEGMENT MOV ISIZ,R2 ;CURRENT LENGTH MOV IADR,R3 ;STARTING ADDRESS BR GO ;AND INTO NORMAL PROCESS ; ; GET RECORD - FD.CR OR /NC GET: GET$ #FDBIN,,,GETERR ;GET RECORD ; ; COPY RECORD DESCRIPTOR TO REGISTERS MOV F.NRBD(R0),R2 MOV F.NRBD+2(R0),R3 ; ; UNCOMPRESS IF REQUESTED BIT #UCMSK,MKWD ;TEST FOR UNCOMPRESS BEQ OPNO ;FLAG CLEAR? CALL ALLOC ;GET OUTPUT BUFFER CALL CRUUCR ;CALL UNCOMPRESS ROUTINE BCC OPNO ;SUCCESSFUL JMP PRCERR ;PROCESSING ERROR ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; OPEN FILE FOR OUTPUT OPNO: BIT #OPFLG,CFLG ;FILE OPEN? BNE GO ;YES ; ; Opening fixed length record? CMPB #R.FIX,FDBOU+F.RTYP ;FIXED RECORDS? BNE 10$ ;NO ; ; Check record size TST FDBOU+F.RSIZ ;RECORD SIZE SPECIFIED? BNE 10$ ;YES MOV R2,FDBOU+F.RSIZ ;SET TO FIRST RECORD SIZE ; ; Open output file 10$: OPEN$ #FDBOU ;OPEN OUTPUT FILE BCC 20$ ;TEST FOR OPEN ERROR ; ; ERROR OPENING OUTPUT FILE CALL IOMSG JMP TRMMSG ; ; Set open flag 20$: BIS #OPFLG,CFLG ;FLAG OUTPUT FILE OPEN ; ; LOG NAME BIT #LOMSK,MKWD ;LOG? BEQ GO ;NO DIR$ #TYPE ;LOG NAME ON SCREEN ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; SUCCESSFUL GET GO: JMP @GRTN ;PROCESS RECORD ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FORTRAN CARRIAGE CONTROL GETFC: BIC #NRFLG,CFLG ;CLEAR NO READ FLAG ; ; MOVING RECORD TO USER BUFFER? BIT #APFLG,CFLG ;APPENDING? BNE APPFC ;YES ; ; CHECK CARRIAGE CONTROL CHARACTER 10$: TST R2 ;NULL RECORD? BEQ CVTCC ;YES CMPB #'$,(R3) ;CHECK FIRST CHARACTER BNE CVTCC ;PROCESS RECORD ; ; SET UP INTERNAL BUFFER 11$: CALL APPND ;APPEND TO USER BUFFER BR GET ;GET NEXT RECORD ; ; APPEND MODE APPFC: TST R2 ;NULL RECORD? BEQ 20$ ;YES MOVB (R3),R1 ;GET CC BEQ 10$ ;NULL? CMPB #'+,R1 ;PLUS? BNE 20$ ;NO ; ; APPEND NEW RECORD TO RECORD IN USER BUFFER 10$: DEC R2 ;REMOVE NULL FROM LENGTH INC R3 ;POINT TO RECORD CALL APPND ;APPEND TO PREVIOUS RECORD ; ; TEST FOR NULL CC TSTB R1 ;NULL CC BEQ GET ;GET ANOTHER RECORD MOVB #' ,(R3) ;CONVERT CC TO SPACE BIC #APFLG,CFLG ;CLEAR APPEND BIT BR CVTCC ;PROCESS RECORD ; ; RECORDS CANNOT BE COMBINED 20$: BIS #NRFLG,CFLG ;NO READ NEXT TIME MOV R2,ISIZ ;STORE LENGTH MOV R3,IADR ;STORE ADDRESS BIC #APFLG,CFLG ;NOT APPENDING MOV OSIZ,R2 ;GET LENGTH MOV OADR,R3 ;GET ADDRESS BR CVTCC ;PROCESS RECORD ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; NO CARRIAGE CONTROL GETNC: BIC #NRFLG,CFLG ;CLEAR NO READ FLAG TST R2 ;NULL RECORD? BEQ GET ;YES ; ; SET UP REGISTERS MOV R2,R4 ;COPY LENGTH MOV R3,R5 ;COPY ADDRESS CLR R2 ;COUNTER BR 12$ ;INTO LOOP ; ; TEST FOR CR, OR FF 10$: CMPB #14,(R5) ;FF? BEQ 18$ ; 12$: INC R2 ;INCREMENT OUTPUT COUNT CMPB #15,(R5)+ ;CR? BEQ 16$ ; SOB R4,12$ ;DECREMENT INPUT COUNT ; ; USE APPEND MODE 14$: CALL APPND ;COPY TO USER BUFFER BR GET ;READ NEXT RECORD ; ; CR FOUND 16$: DEC R4 ;SHOW CHARACTER USED BEQ 20$ ;NO CHARACTERS LEFT ; ; STORE DESCRIPTOR TO REMAINING BUFFER 18$: MOV R4,ISIZ ;STORE LENGTH MOV R5,IADR ;STORE ADDRESS BIS #NRFLG,CFLG ;SET FLAG FOR NO READ ; ; COPY MODE CURRENTLY IN USE? 20$: BIT #APFLG,CFLG ;APPEND MODE? BEQ CVTCC ;COPY BUFFER CALL APPND ;APPEND TO USER BUFFER BIC #APFLG,CFLG ;CLEAR APPEND FLAG ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; PROCESS RECORD CVTCC: ; ; CONVERT CARRIAGE CONTROL MOV #FDBOU,R0 ;REQUIRES OUTPUT FDB ADDRESS CALL @CRTN ; ; PROCESS RECORD PRCSS: ; ; PAGE SELECTION? BIT #PGMSK,MKWD ;SELECT PAGES? BEQ 10$ ;NO CALL @PRTN ;CHECK PAGE NUMBER BLO 90$ ;IF PAGE NOT SELECTED BHI 10$ ;NO JMP OKFIN ;CLOSE FILES ; ; REMOVE TABS? 10$: BIT #CTMSK,MKWD ;CHECK REMOVE TABS FLAG BEQ 20$ ;NO CALL ALLOC ;GET OUTPUT BUFFER CALL CRUSPC ;REPLACE TABS WITH SPACES BCS PRCERR ;PROCESSING ERROR? ; ; REPLACE SPACES WITH TABS 20$: BIT #CSMSK,MKWD ;CHECK USE TABS FLAG BEQ 30$ ;NO CALL CRUTAB ;PROCESS TABS ; ; VARIABLE LENGTH RECORDS? 30$: CMPB #R.VAR,FDBOU+F.RTYP ;VARIABLE LENGTH RECORDS? BNE FIXED ;NO ; ; TRUNCATE RECORD? BIT #TRMSK,MKWD ;TEST FLAG BEQ 40$ ;NO ; ; TRUNCATE LENGTH CMP TRSZ,R2 ;RECORD LONGER THAN DESIRED? BGE 40$ ;NO - THEN SKIP MOV TRSZ,R2 ;NEW LENGTH ; ; PADD LENGTH 40$: BIT #PDMSK,MKWD ;PADD RECORD? BEQ 50$ ;NO CMP R2,PDSZ ;PADD CHARACTERS REQUIRED? BGE 50$ ;NO CALL ALLOC ;GET OUTPUT BUFFER CALL CRUPAD ;PADD/TRUNCATE RECORD BCS PRCERR ;PROCESSING ERROR ; ; REMOVE TRAILING BLANKS 50$: BIT #RTMSK,MKWD ;REMOVE TRAILING BLANKS? BEQ 60$ ;NO CALL CRURTB ;REMOVE TRAILAING BLANKS ; ; COMPRESSION DESIRED? 60$: BIT #CMMSK,MKWD ;COMPRESS OUTPUT? BEQ 70$ ;NO CALL ALLOC ;ALLOCATE OUTPUT BUFFER MOV CMPRM,R1 ;COMPRESS PARAMETER CALL CRUCRB ;COMPACT RECORD BUFFER BCS PRCERR ;PROCESSING ERROR ; ; STORE RECORD 70$: PUT$ #FDBOU,R3,R2,PUTERR ; ; GET NEXT RECORD 90$: JMP COPY ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; PROCESSING FOR FIXED LENGTH RECORDS FIXED: CMP R2,FDBOU+F.RSIZ ;RECORD SIZE EQUAL? BEQ 50$ ;YES BGT 30$ ;REC GREATER THAN IRSZ ; ; PADD RECORD 20$: MOV FDBOU+F.RSIZ,PDSZ ;SET PADD LENGTH CALL ALLOC ;ALLOCATE RECORD BUFFER CALL CRUPAD ;PADD RECORD BCS PRCERR ;PROCESSING ERROR BR 50$ ;PUT RECORD ; ; TRUNCATE RECORD 30$: MOV FDBOU+F.RSIZ,R2 ;TRUNCATE RECORD ; ; PUT RECORD 50$: PUT$ #FDBOU,R3,,PUTERR 60$: JMP COPY ;LOOP ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; PROCESS ERROR HANDLING ; PRCERR: MOV #MSG1,R3 ;ADDRESS OF MESSAGE MOV #MSG1L,R2 ;LENGTH OF MESSAGE BR ERCLO ;CLOSE FILES ; GETERR: CMPB #IS.SUC,F.ERR(R0) ;ERROR? BNE GETEOF ;NO ; ; NOT AN ERROR CLR R2 ;NULL RECORD MOV #IBUF,R3 ;ADDRESS JMP GO ; ; TEST FOR EOF GETEOF: CMPB #IE.EOF,F.ERR(R0) ;EOF? BEQ OKFIN ;YES - SO NO ERROR ; ; GET ERROR CALL IOMSG BR ERCLO ; PUTERR: CALL IOMSG ;ERROR MESSAGE BR ERCLO ; CLSERR: MOV R0,-(SP) ;SAVE ADDRESS OF FDB MOV #7,R0 ;LENGTH OF STRING MOV #MSG,R1 ;ADDRESS OF STRING CALL CONCAT ;CONCATENATE STRINGS MOV R0,TYPE+Q.IOPL+2 ;LENGTH OF MESSAGE MOV R1,TYPE+Q.IOPL ;ADDRESS OF MESSAGE MOV (SP)+,R0 ;RESTORE ADDRESS OF FDB DIR$ #TYPE ;OUTPUT PENDING MESSAGE ; CLSHRR: CALL IOMSG ;ERROR MESSAGE MOV #7,R0 ;LENGTH OF STRING MOV #MSG,R1 ;ADDRESS OF STRING CALL CONCAT ;CONCATENATE STRINGS MOV R0,TYPE+Q.IOPL+2 ;LENGTH OF MESSAGE MOV R1,TYPE+Q.IOPL ;ADDRESS OF MESSAGE DIR$ #TYPE ;TYPE ON TERMINAL EXST$S #2 ;HARD ERROR ; ERCLO: CLOSE$ #FDBOU,CLSERR ;CLOSE OUTPUT FILE CLOSE$ #FDBIN,CLSERR ;CLOSE INPUT FILE JMP TRMMSG ;RESTART ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FLUSH ANY INTERNAL BUFFERS OKFIN: BIT #APFLG,CFLG ;BUFFERS EMPTY? BEQ OKLOG ;YES ; ; FLUSH BUFFER BIC #APFLG,CFLG ;CLEAR FLAG JMP CVTCC ; ; LOG RESULTS IF SELECTED OKLOG: BIT #LOMSK,MKWD ;LOGGING? BEQ OKCLO ;NO ; ; SHOW USER BLOCK USAGE MOV #' ,R5 ;SPACE CHARACTER MOV #MSG3+18.,R0 ;ADDRESS OF INPUT BLOCK STRING MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOV FDBIN+F.EFBK+2,R1 ;NUMBER OF BLOCKS CLR R2 ;SUPPRESS LEADING ZEROS CALL $CBDMG ;CONVERT ; MOV #' ,R5 ;SPACE CHARACTER MOV #MSG3+41.,R0 ;ADDRESS OF OUTPUT BLOCK STRING MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOVB R5,-(R0) ;SPACE CHARACTER MOV FDBOU+F.EFBK+2,R1 ;NUMBER OF BLOCKS CLR R2 ;SUPPRESS LEADING ZEROS CALL $CBDMG ;CONVERT ; ; Write summary message MOV #MSG3,TYPE+Q.IOPL MOV #MSG3L,TYPE+Q.IOPL+2 DIR$ #TYPE ; ; Close handling OKCLO: BIT #SPMSK,MKWD ;SPOOL OUTPUT FILE BEQ 10$ ;NO ; ; SET UP MESSAGE IN CASE OF ERROR MOV #MSG2 ,R3 ;ADDRESS OF MESSAGE MOV #MSG2L,R2 ;LENGTH OF MESSAGE PRINT$ #FDBOU,CLSERR,,SPDV,SPUN,,SPFO,SPCO BR 20$ ;SUCCESSFUL ; ; CLOSE OUTPUT FILE 10$: CLOSE$ #FDBOU,CLSHRR ;CLOSE OUTPUT FILE ; ; DELETE INPUT FILE? 20$: BIT #DEMSK,MKWD BEQ 30$ DELET$ #FDBIN JMP GETCML ; ; CLOSE INPUT FILE 30$: CLOSE$ #FDBIN,CLSHRR JMP GETCML ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ALLOCATE SUBROUTINE ALLOC:: MOV #UBSZ,R4 ;COPY OUTPUT SIZE BITB #BUFLG,CFLG ;TEST FOR CURRENT BUFFER BNE 10$ ;CLEAR IF NOT IN OBUF ; ; RETURN OBUF ADDRESS MOV #OBUF,R5 ;ADDRESS OF FREE BUFFER BIS #BUFLG,CFLG ;SHOW OBUF IN USE RTS PC ;RETURN TO CALLER ; ; RETURN WBUF ADDRESS 10$: MOV #WBUF,R5 ;ADDRESS OF FREE BUFFER BIC #BUFLG,CFLG ;SHOW OBUF BEING FREED RTS PC ;RETURN TO CALLER ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; APPEND SUBROUTINE ; APPND: BIT #APFLG,CFLG ;DESCRIPTOR INITIALIZED? BNE 10$ ; CALL ALLOC ;ALLOCATE BUFFER BIS #APFLG,CFLG ;SHOW INITIALIZED CLR R4 ;CLEAR OUTPUT LENGTH BR 15$ ;SKIP TO INPUT DESCRIPTOR ; ; SET UP REGISTERS FOR COPY 10$: MOV OSIZ,R4 ;LENGTH OF OUTPUT MOV OADR,R5 ;ADDRESS OF OUTPUT ; ; TEST FOR NULL LENGTH 15$: TST R2 ;ANY CHARACTERS TO APPEND? BLE 25$ ;NO ; ; APPEND LOOP 20$: CMP #UBSZ,R4 ;OVERFLOW? BLE 80$ ; MOVB (R3)+,(R5)+ ;MOVE A CHARACTER INC R4 ;INCREMENT OUTPUT COUNT SOB R2,20$ ; ; ; STORE LENGTH OF RESULT 25$: MOV R4,OSIZ ;STORE LENGTH OF RESULT MOV R4,R2 ;COPY TO CURRENT REGISTER MOV R5,OADR ;STORE CURRENT POINTER MOV #OBUF,R3 ;COPY TO CURRENT REGISTER 30$: CLC ;CLEAR CARRY RTS PC ;BACK TO CALLER ; ; RECORD TOO BIG ERROR 80$: MOVB #IE.DAO,F.ERR(R0) ;STORE ERROR CODE SEC ;SET CARRY RTS PC ;BACK TO CALLER ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; GENERATE SYNTAX ERROR MESSAGE CSISYN: MOV #SYNM1 ,R3 ;ADDRESS OF MESSAGE MOV #SYNM1L,R2 ;LENGTH OF MESSAGE MOV #7,R0 ;LENGTH OF STRING MOV #MSG,R1 ;ADDRESS OF STRING CALL CONCAT ;CONCATENATE STRINGS MOV R0,TYPE+Q.IOPL+2 ;LENGTH OF MESSAGE MOV R1,TYPE+Q.IOPL ;ADDRESS OF MESSAGE DIR$ #TYPE ;TYPE MESSAGE ON TERMINAL ; ; SHOW PART OF COMMAND LINE IN ERROR MOV #CSIBLK,R0 ;ADDRESS OF CSI BLOCK MOV C.FILD+2(R0),TYPE+Q.IOPL ;ADDR OF OFFENDING SEGMENT MOV C.FILD(R0),TYPE+Q.IOPL+2 ;LENGTH DIR$ #TYPE ;TYPE ON TERMINAL ; ; LINE FEED CLR TYPE+Q.IOPL+2 ;ZERO LENGTH RECORD DIR$ #TYPE ;TYPE ZERO LENGTH RECORD RTS PC ;DONE ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = .END START