; Subroutine to convert signed or unsigned binary text ; to correspondingly signed or unsigned binary longword. ; Calling is analogous to LIB$CVT_DTB, LIB$CVT_OTB, and LIB$CVT_HTB, ; as are returned error codes. ; John Lavagnino ; Smithsonian Astrophysical Observatory ; 60 Garden Street ; Cambridge, Massachusetts 02138 ; 617-498-7389 or FTS 830-7389 ; ret-status = CVTBTB ( length, address, value ) ; length = length of text string (passed by value, not address) ; address = address of text string ; value = longword to receive translated value. ; This may be used for both signed and unsigned integers. Signed integers ; may have up to 31 digits, with an optional +/- sign in front. Unsigned ; integers may have up to 32 digits -- obviously they aren't any different ; from positive signed integers except for the 32-digit case. ; If the input is too large, an integer overflow trap does NOT occur: ; the obscure error code 0 is returned, and nothing is output, that's all. ; Written for RDPAR, to help it understand binary entry. ; Written for: ; VAX-11/780 ; VAX/VMS Rev 2.3 ; VAX-11 MACRO Rev 2.45 ; November 2, 1981 JL .TITLE CVTBTB Binary text -> binary longword .SUBTITLE Subroutine CVTBTB .IDENT /1.0/ .PSECT $CODE, PIC, SHR, NOWRT, LONG LENGTH = 4 ADDRESS = 8 VALUE = 12 .ENTRY CVTBTB, ^M < IV, R2, R3, R5 > CLRL R5 ; Clear our output value. ; Get length and address of text string. ; Note that the length is passed by value, not address. MOVL LENGTH(AP), R2 ; Get length of numeral BEQL LAB ; If zero, return a value of 0. MOVL ADDRESS(AP), R3 ; Get address of numeral BEQL ERROR ; If zero, something's wrong here. ; Check number of characters: must be 32 or less. (31 digits plus sign for ; signed quantities, 32 digits for unsigned quantities.) ; Use unsigned comparison to trap negative lengths also. CMPL R2, #32 ; 32 or less? BGTRU ERROR ; No -- branch off. ; Handle sign. CLRL R0 ; Clear negative-number flag. MOVB (R3)+, R1 ; Get first character. CMPB R1, #^A/+/ ; Is first character a + sign? BEQLU ENDL ; Yes. No change needed in flag. CMPB R1, #^A/-/ ; Well, is it a - sign then? BNEQU L1 ; No. Skip down. INCL R0 ; Yes, it's -. Set negation flag. BRB ENDL ; Go to end of loop, to dec. length. ; Main conversion loop: shift our working value to the left to multiply it ; by 2, get next character, make LSB a 1 if character is 1, do nothing if ; it's 0, take error if anything else. Then go back and do the same again ; if there are more characters. ; BISL2 is used instead of INCL to set lowest bit to 1 so that this will work ; properly for 32-bit unsigned quantities. ROTL is used instead of ASHL ; to avoid getting integer-overflow errors. LOOP: ROTL #1, R5, R5 ; Multiply what we've got by 2. MOVB (R3)+, R1 ; Get next character in input string. L1: CMPB R1, #^A/0/ ; Is it a zero? BEQLU ENDL ; Yes, go to end of loop. CMPB R1, #^A/1/ ; Is it a one, then? BNEQU ERROR ; No -- illegal character. BISL2 #1, R5 ; Set lowest bit to 1. ENDL: SOBGTR R2, LOOP ; Loop back, if more characters. ; All characters of input numeral have been used. Now negate the result if ; there was a - sign. BLBC R0, LAB ; Skip negation if no - sign found. MNEGL R5, R5 ; Negate our value. ; Successful completion: output result and return. LAB: MOVL R5, @VALUE(AP) ; Output our value. MOVL #1, R0 ; Set R0 for "success". RET ; Error handler: no value is returned, only a 0 in R0, as ; the three Run-Time Library functions which this is modeled on do. ERROR: CLRL R0 ; Clear R0: signifying error. RET ; Return to calling program. .END