.TITLE ASCFNM .IDENT /V01/ .ENABLE LC ; ; This module parses an ASCII filename, and enters the details into a ; filename block. ; ; Author: V01 25-Jan-80 Phil Stephensen-Payne ; ; Calling Sequence: ; ; This subroutine is called via the standard FORTRAN callin sequence as: ; ; CALL ASCFNM(STRING,LENGTH,BLOCK,UIC [,STATUS]) ; or ; STATUS = ASCFNM(STRING,LENGTH,BLOCK,UIC) ; ; Where:- ; STRING = THE ADDRESS OF THE INPUT STRING ; LENGTH = THE LENGTH OF THE INPUT STRING ; BLOCK = THE RSX FILENAME BLOCK ; UIC = A WORD TO HOLD THE UIC ; STATUS = AN OPTIONAL ERROR RETURN ; ; NOTE THAT THE PARTS OF BLOCK & UIC WHICH ARE NOT SPECIFIED ; IN THE STRING ARE LEFT UNCHANGED. ; Errors Returned: ; ; STATUS = 0 if the operation was successful ; = -1 if there was a parameter error ; = +1 if there was a specification error ; ; External References: ; ; This module calls the subroutines ASCBIN, ASCRAD,STFIND & PRMCHK. ; ; MACRO DEFINITIONS ; .MCALL $CALLG ;FORTRAN-COMPATIBLE CALL MACRO .MCALL NBOF$L ;FILENAME BLOCK OFFSETS NBOF$L ;DEFINE FILENAME BLOCK OFFSETS ; ; INTERNAL DATA DEFINITIONS ; RESULT: .WORD ;RESULT OF SUBROUTINES NUMBER: .BLKW 2 ;NUMBER FOR CONVERSIONS POCHAR: .WORD ;OFFSET OF FOUND CHARACTER POCHR1: .WORD ;AND ANOTHER ONE (FOR UICS) NUMCHR: .WORD 1 ;NUMBER OF CHARACTERS FOR SUBROUTINES LENGTH: .WORD ;LENGTH OF STRING IN SEARCH ROUTINES RADIX: .BYTE 8. ;RADIX FOR CONVERSIONS COLN: .BYTE ': ;COLON DOT: .BYTE '. ;PERIOD RBRKT: .BYTE '] ;UIC TERMINATOR SEMIC: .BYTE '; ;SEMI-COLON COMM: .BYTE ', ;COMMA .EVEN ASCFNM:: MOV #5,R0 ;FOUR PARAMETERS CALL PRMCHK ;CHECK THEM BCC 10$ ; If CC parameters OK - carry on ; 5$: JMP ASCEND ;TERMINATE ; 10$: TST (R5)+ ;THROW AWAY NUMBER OF PARAMS MOV (R5)+,R1 ;GET ADDRESS OF STRING MOVB @(R5),R0 ;SIGN-EXTEND STRING LENGTH MOV R0,LENGTH ;AND STORE IT BNE 15$ ;IF NE OK - CARRY ON JMP ASCSUC ;ELSE EXIT WITH DEFAULT ; 15$: TST (R5)+ ;SET TO NEXT PARAMETER BIT #1,(R5) ;WORD-ALIGNED? BEQ 20$ ;IF EQ YES - CARRY ON MOV #-1,R0 ;NO - FLAG ERROR JMP ASCEND ;AND EXIT ; 20$: MOV (R5)+,R4 ;GET ADDRESS OF FILENAME BLOCK $CALLG CNVTUC,#LENGTH,R1 ;Convert to upper case MOV #1,NUMCHR ;LOOK ONLY FOR ONE CHAR $CALLG STFIND,#COLN,#NUMCHR,R1,#LENGTH,#POCHAR,#RESULT ;FIND A COLON IF THERE IS ONE TST POCHAR ;WAS THERE ONE? BLE MID ;IF LE NO - TRY FOR UIC CMP POCHAR,#3 ;AT LEAST THREE CHARS? (E.G. DP:) BLT SPCER1 ;NO - FLAG THE ERROR CMPB (R1),#'A ;YES - IS DEVICE VALID? BLOS SPCER1 ;IF LOS NO - ERROR CMPB (R1),#'Z ;AND SO ON BHI SPCER1 ; MOVB (R1)+,N.DVNM(R4) ;INSERT FIRST BYTE BIS #NB.DEV,N.STAT(R4) ;AND SAY DEVICE GIVEN CMPB (R1),#'A ;KEEP CHECKING BLOS SPCER1 ;IF LOS NO - ERROR CMPB (R1),#'Z ;AND SO ON BHI SPCER1 ; MOVB (R1)+,N.DVNM+1(R4) ;INSERT FIRST BYTE CLR N.UNIT(R4) ;INITIALISE UNIT NUMBER TO ZERO SUB #3,LENGTH ;COUNT DEVICE LENGTH OUT.. SUB #3,POCHAR ;..OF BOTH COUNTS BEQ 30$ ;IF EQ NO UNIT - LEAVE AS ZERO $CALLG ASCBIN,#POCHAR,R1,#RADIX,#NUMBER,#RESULT ;CONVERT UNIT NUMBER TST RESULT ;CONVERSION OK? BNE SPCER1 ;IF NE NO - ERROR TST NUMBER+2 ;NUMBER OVERFLOWED? BNE SPCER1 ;IF NE YES - ERROR MOV NUMBER,N.UNIT(R4) ;NO - STORE UNIT NUMBER ; 30$: ADD POCHAR,R1 ;UPDATE INPUT ADDRESS INC R1 ; SUB POCHAR,LENGTH ;AND LENGTH BGT MID ;IF GT YES - CARRY ON ; ASCSC1: JMP ASCSUC ;ELSE SUCCESS ; SPCER1: JMP SPCERR ;SPECIFICATION ERROR ; MID: CMPB (R1),#'[ ;DIRECTORY? BEQ 40$ ;IF EQ YES - CONVERT DIRECTORY JMP MID2 ;NO - OMIT IT ; 40$: MOV #1,NUMCHR ;LOOK ONLY FOR ONE CHAR $CALLG STFIND,#RBRKT,#NUMCHR,R1,#LENGTH,#POCHAR,#RESULT ;FIND THE OTHER BRACKET TST POCHAR ;FOUND IT? BLE SPCER1 ;IF LE NO - ERROR $CALLG STFIND,#COMM,#NUMCHR,R1,#POCHAR,#POCHR1,#RESULT TST POCHR1 ;FOUND THE COMMA BLE SPCER1 ;NO - REPORT ERROR SUB #2,POCHR1 ;GET ACTUAL LENGTH OF NUMBER BLE SPCER1 ;IT MUST EXIST INC R1 ;RESET R1 TO START DEC POCHAR ;AND TOTAL LENGTH DEC LENGTH ; INC (R5) ;SET TO GROUP CODE $CALLG ASCBIN,#POCHR1,R1,#RADIX,#NUMBER,#RESULT ;CONVERT PART TST RESULT ;OK BNE SPCER1 ;NO - ERROR TST NUMBER+2 ;TOO LARGE? BNE SPCER1 ;IF NE YES - ERROR CMP NUMBER,#256. ;SURE? BHIS SPCER1 ;NO - ERROR MOVB NUMBER,@(R5) ;YES - STORE IT DEC (R5) ;SET TO MEMBER INC POCHR1 ;COUNT THE COMMA ADD POCHR1,R1 ;RESET INPUT ADDRESS SUB POCHR1,POCHAR ;AND GET LENGTH SUB POCHR1,LENGTH ; DEC POCHAR ;ALLOW FOR BRACKET BLE SPCER2 ;IF LE NO ROOM - ERROR $CALLG ASCBIN,#POCHAR,R1,#RADIX,#NUMBER,#RESULT ;CONVERT PART TST RESULT ;OK BNE SPCER2 ;NO - ERROR TST NUMBER+2 ;TOO LARGE? BNE SPCER2 ;IF NE YES - ERROR CMP NUMBER,#128. ;SURE? BHIS SPCER2 ;NO - ERROR MOVB NUMBER,@(R5) ;YES - STORE IT INC POCHAR ;RESET BIS #NB.DIR,N.STAT(R4) ;SET EXPLICIT UIC BIT ADD POCHAR,R1 ;ELSE RESET ADDRESS SUB POCHAR,LENGTH ;AND LENGTH BGT MID2 ;IF GT MORE - CARRY ON ; ASCSC2: JMP ASCSUC ; SPCER2: JMP SPCERR ; MID2: $CALLG STFIND,#DOT,#NUMCHR,R1,#LENGTH,#POCHAR,#RESULT ;LOOK FOR PERIOD $CALLG STFIND,#SEMIC,#NUMCHR,R1,#LENGTH,#NUMBER,#RESULT ;AND SEMICOLON TST NUMBER ;ANY SEMICOLON? BGT 55$ ;IF GT YES - CARRY ON MOV LENGTH,NUMBER ;NO - DEFAULT TO END OF STRING INC NUMBER ; ; 55$: TST POCHAR ;ANY PERIOD? BGT 60$ ;IF GT YES - CARRY ON MOV NUMBER,POCHAR ;NO - FAKE IT ; 60$: DEC POCHAR ;ANY FILENAME? BLE 70$ ;IF LE NO - LEAVE DEFAULT NAME CMP POCHAR,#9. ;FILENAME TOO LONG? BGT SPCERR ;IF GT YES - ERROR MOV R4,R2 ;SET UP FILENAME ADDRESS ADD #N.FNAM,R2 ; CLR (R2)+ ;INITIALISE IT CLR (R2)+ CLR (R2)+ SUB #6,R2 ;RESET IT BIS #NB.NAM,N.STAT(R4) ;SET THE BIT $CALLG ASCRAD,#POCHAR,R1,R2,#RESULT ;CONVERT TO RAD50 TST RESULT ;CONVERSION OK? BNE SPCERR ;IF NE NO - REPORT ERROR ; 70$: INC POCHAR ;COUNT THE PERIOD ADD POCHAR,R1 ;RESET INPUT ADDRESS SUB POCHAR,LENGTH ;AND LENGTH BLE ASCSUC ;IF NO MORE, EXIT SUB POCHAR,NUMBER ;ANY EXTENSION? DEC NUMBER ; BLE 80$ ;IF LE NO - LOOK FOR VERSION CMP NUMBER,#3 ;YES - EXTENSION TOO LARGE? BGT SPCERR ;IF GT YES - RETURN ERROR MOV R4,R2 ;NO - GET EXTENSION OFFSET ADD #N.FTYP,R2 ; BIS #NB.TYP,N.STAT(R4) ;FLAG THE EXPLICIT EXTENSION $CALLG ASCRAD,#NUMBER,R1,R2,#RESULT ;CONVERT THE EXTENSION TST RESULT ;OK? BNE SPCERR ;IF NE NO - REPORT ERROR ; 80$: INC NUMBER ;COUNT SEMI-COLON ADD NUMBER,R1 ;RESET INPUT ADDRESS SUB NUMBER,LENGTH ;CALCULATE LENGTH BLE ASCSUC ;IF LE NO VERSION - EXIT $CALLG ASCBIN,#LENGTH,R1,#RADIX,#NUMBER,#RESULT ;CONVERT VERSION TST RESULT ;ONVERSION OK? BNE SPCERR ;IF NE NO - LOG ERROR TST NUMBER+2 ;VERSION TOO LARGE? BNE SPCERR ;IF NE YES - LOG ERROR MOV NUMBER,N.FVER(R4) ;STORE THE VERSION BIS #NB.VER,N.STAT(R4) ;AND FLAG IT BR ASCSUC ;EXIT ; SPCERR: MOV #1,R0 ;SPECIFICATION ERROR BR ASCEND ; ; ASCSUC: CLR R0 ;SUCCESS ; ASCEND: RETURN .END