.TITLE ASCRAD .IDENT /V01/ .ENABLE LC ; ; This module converts an ASCII string to RAD50 ; ; Author: V01 25-Jan-80 Phil Stephensen-Payne ; ; Calling Sequence: ; ; This subroutine is called via the standard FORTRAN calling sequence as:- ; ; CALL ASCRAD(ACOUNT,ASCSTR,RADSTR [,STATUS]) ; or ; STATUS = ASCRAD(ACOUNT,ASCSTR,RADSTR) ; ; Where: ; ACOUNT = Number of ASCII characters to translate ; ASCSTR = Address of the input ASCII string ; RADSTR = Address of the output RAD50 array ; STATUS = an optional flag on input ; 0 => period is a terminator (default) ; 1 => period is a valid RAD50 character ; = an optional error return on output ; ; Errors Returned: ; ; STATUS = 0 if the operation was successfully ; = -1 if there was a parameter error ; = number of characters not converted if a non-RAD50 character ; was detected ; ; External References: ; ; This module calls the subroutine PRMCHK ; RADCNT: .WORD 0 ;AMOUNT OF RAD50 WORD TRANSLATED NUMCHR: .WORD 0 ;NUMBER OF INPUT CHARACTERS ; ; ; WORK REGISTERS ARE: ; ; R1 = ADDRESS OF NEXT WORD IN OUTPUT STRING ; R2 = FLAG SAYING IF PERIOD IS VALID CHARACTER ; R3 = RAD50 WORD BUILT UP SO FAR ; R4 = CHARACTER BEING TRANSLATED ; R5 = ADDRESS OF NEXT BYTE IN INPUT STRING ; ; FIRST WE CHECK TO SEE IF THE NUMBER OF PARAMETERS IS VALID (3 OR 4) ; IF IT IS NOT THE ROUTINE EXITS FLAGGING AN ERROR. IF THE NUMBER OF ; PARAMETERS IS THREE THE ROUTINE DEFAULTS TO PERIOD AS INVALID CHARACTER. ; THE ROUTINE THEN STORES THE NECESSARY PARAMETERS. ; ; ASCRAD:: MOV #4,R0 ;FOUR PARAMETERS CALL PRMCHK ;CHECK THEM BCS ASCEND ;If CS parameter error - exit at once ; 10$: CLR R2 ;INITIALISE PERIOD FLAG TST R0 ;FOUR PARAMETERS INPUT? BEQ 20$ ;IF EQ NO - CARRY ON MOVB (R0),R2 ;YES - GET PERIOD FLAG ; 20$: CLR R0 ;Initialise error return CLR NUMCHR ;CLEAR AMOUNT TO CONVERT MOVB @2(R5),NUMCHR ;GET AMOUNT TO CONVERT BEQ ASCEND ;IF EQ NOTHING - NO CONVERSION CLR RADCNT ;INITIALISE COUNTER CLR R3 ;INITIALISE WORD COUNTER MOV 6(R5),R1 ;SET OUTPUT ADDRESS BIT #1,R1 ;WORD ALIGNED? BEQ 25$ ;IF EQ OK - CARRY ON MOV #-1,R0 ;NO - SET ERROR BR ASCEND ;OUTPUT IT ; 25$: MOV 4(R5),R5 ;SET INPUT ADDRESS ; ; THE ROUTINE THEN CHECKS TO SEE WHAT THE NEXT CHARACTER IS. ; IF IT IS INVALID THE ROUTINE BRANCHES TO AN ERROR LABEL TO TERMINATE ; THE ROUTINE. OTHERWISE IT BRANCHES TO A SET OF STATEMENTS TO CALCULATE ; THE RAD50 VALUE OF THE CHARACTER. TO SAVE SPACE, THIS IS DONE BY ; ACCUMULATING THE DIFFERENCES BETWEEN THE RAD50 AND ASCII VALUES (IN ; OCTAL) FOR THE DIFFERENT TYPES. NOTE THAT THE TYPES ARE ARRANGED IN ; DESCENDING ORDER OF FREQUENCY (FOR SPEED OPTIMISATION). ; ; ASCLOP: MOVB (R5)+,R4 ;GET NEXT BYTE FOR TRANSLATION CMPB R4,#'Z ;CHARACTER TOO HIGH? BHI ASCFIN ;YES - INVALID CHARACTER CMPB R4,#'A ;NO - ALPHABETIC? BHIS ASCALP ;YES - TRANSLATE ALPHABETIC CMPB R4,#'9 ;TOO HIGH FOR NUMBERS? BHI ASCFIN ;IF HI YES - ERROR CMPB R4,#'0 ;NO - NUMERIC? BHIS ASCNUM ;IF HIS YES - TRANSLATE NUMERIC CMPB R4,#'$ ;A DOLLAR? BEQ ASCDLR ;YES - TRANSLATE DOLLAR CMPB R4,#' ;A SPACE? BEQ ASCSPC ;YES - TRANSLATE SPACE CMPB R4,#'. ;A DOT? BNE ASCFIN ;IF NE NO - ERROR TST R2 ;DOT VALID? BEQ ASCFIN ;IF EQ NO - ERROR ; ASCDOT: ADD #34-56-33+44,R4 ;RESET FOR .(MINUS $) ASCDLR: ADD #33-44-0+40,R4 ;RESET FOR $(MINUS SPACE) ; ASCSPC: ADD #0-40-36+60,R4 ;RESET FOR SPACE(MINUS NUMERIC) ; ASCNUM: ADD #36-60-1+101,R4 ;RESET FOR NUMERIC (MINUS ALPHA) ; ASCALP: ADD #1-101,R4 ;RESET FOR ALPHA ; ; THE TRANSLATED CHARACTER IS THEN ADDED INTO AN ACCUMULATOR WHICH ; HOLDS ANY PREVIOUS CHARACTERS IN THIS WORD. IF THE CHARACTER INSERTED ; IS THE FIRST OR SECOND, THE ACCUMULATOR IS THEN MULTIPLIED BY 40. TO ; ADJUST FOR CHARACTER POSITION - OTHERWISE THE WORD IS OUTPUT TO THE ; OUTPUT BUFFER. ; IF THERE ARE ANY FURTHER CHARACTERS TO TRANSLATE THE ROUTINE THEN ; BRANCHES BACK TO TRANSLATE THEM. ; ADD R4,R3 ;ADD INTO ACCUMULATOR INC RADCNT ;COUNT VALUES IN WORD CMP RADCNT,#3 ;WORD FULL? BLT 10$ ;IF LT NO - CARRY ON MOV R3,(R1)+ ;OUTPUT WORD CLR R3 ;RESET ACCUMULATOR CLR RADCNT ;RESET COUNT BR 15$ ;OMIT MULTIPLY ; 10$: MUL #40.,R3 ;MULTIPLY UP ; 15$: DEC NUMCHR ;COUNT CHARACTER TRANSLATED BEQ ASCFIN ;IF EQ NO MORE - TERMINATE BR ASCLOP ;ELSE - GET SOME MORE ; ; FINALLY THE ROUTINE ROTATES THE LAST WORD IF IT IS UNFINISHED, AND ; SETS UP THE OUTPUT PARAMETERS. IF ANY CHARACTERS WERE NOT CONVERTED IT ; RETURNS AN ERROR TO THE CALLING ROUTINE. ; ASCFIN: TST RADCNT ;LAST WORD EMPTY? BEQ ASCEND ;IF EQ YES - OMIT ROUNDING CMP RADCNT,#2 ;THIS WORD FINISHED? BEQ 15$ ;IF EQ YES - OMIT MULTIPLY ; 10$: MUL #40.,R3 ;ROTATE THE WORD INC RADCNT ;COUNT VALUE CMP RADCNT,#2 ;WORD FULL? BLT 10$ ;IF LT NO - GO AGAIN ; 15$: MOV R3,(R1)+ ;OUTPUT THE WORD MOV NUMCHR,R0 ; ; ASCEND: RETURN ;TERMINATE THE ROUTINE .END