.TITLE ASCBIN .IDENT /V01/ .ENABLE LC ; ; This module converts a numeric ASCII strin in any radix from 2 to 36 into ; a binary (doubleword) number ; ; Author: V01 25-Jan-80 Phil Stephensen-Payne ; ; Calling Sequence: ; ; This subroutine is called via the standard FORTRAN calling sequence as: ; ; CALL ASCBIN (NUMCHR,ASCSTR,RADIX,NUMBER [,STATUS]) ; or ; STATUS = ASCBIN (NUMCHR,ASCSTR,RADIX,NUMBER) ; ; Where: ; NUMCHR = Number of ASCII characters to convert ; RADIX = Radix in which the number is held (2-36) ; ASCSTR = Address of input ASCII string ; NUMBER = Output Doubleword Number ; STATUS = Optional error return ; ; Errors returned: ; ; STATUS = 0 if the operation was successful ; = -1 if a parameter error was detected ; = -2 if the converted value overflowed a doubleword ; = number of characters not converted if a non-numeric (in the ; sense of the radix) character was encountered ; ; External references: ; ; This module calls the subroutines PRMCHK & DMUL ; ; SIGN: .BYTE ;SIGN FLAG RADIX: .BYTE ;RADIX NUMCHR: .BYTE ;NUMBER OF CHARACTERS .EVEN NUMBER: .WORD ;ADDRESS OF OUTPUT NUMBER ; ASCBIN:: MOV #5,R0 ;CHECK NUMBER OF PARAMETERS CALL PRMCHK ; BCC 10$ ;IF CC parameters OK - carry on JMP ASCEND ;YES - EXIT IMMEDIATELY ; 10$: MOV #-1,R0 ;INITIALISE TO ERROR BIT #1,8.(R5) ;IS NUMBER WORD-ALIGNED? BEQ 20$ ;IF EQ YES - CARRY ON ; 15$: JMP ASCEND ;NO - RETURN ERROR ; 20$: MOV 8.(R5),NUMBER ;STORE ADDRESS OF NUMBER CLR R0 ;INITIALISE TO SUCCESS MOVB @2(R5),NUMCHR ;GET NUMBER OF CHARACTERS TO CONVERT BEQ ASCCLR ;IF EQ NONE - EXIT IMMEDIATELY MOV 4(R5),R3 ;GET ADDRESS OF INPUT STRING CLRB SIGN ;INITIALISE SIGN FLAG CMPB (R3),#'+ ;LEADING PLUS SIGN? BEQ 30$ ;IF EQ YES - IGNORE IT CMPB (R3),#'- ;LEADING MINUS SIGN? BNE 40$ ;IF NE NO - CARRY ON INCB SIGN ;YES - FLAG IT ; 30$: INC R3 ;COUNT SIGN BYTE DECB NUMCHR ;TWICE BLE ASCCLR ;only a sign - output zero ; 40$: MOVB @6(R5),RADIX ;GET RADIX MOV #-1,R0 ;INITIALISE FOR ERROR CMPB #2,RADIX ;RADIX TOO SMALL? BGT ASCCLR ;IF GT YES - EXIT CMPB #36.,RADIX ;RADIX TOO LARGE? BLO ASCCLR ;IF LO YES - EXIT CLR R0 ;INITIALISE OUTPUT NUMBER CLR R1 ; ; ASCLOP: MOVB (R3)+,R5 ;GET NEXT CHARACTER CMPB R5,#'9 ;ALPHABETIC? BLE 10$ ;IF LE NO - CARRY ON CMPB R5,#'A ;SURE? BLT 40$ ;IF LT NO - ERROR SUB #7,R5 ;RESET TO PSEUDO-NUMERIC ; 10$: SUB #'0,R5 ;RESET TO BINARY MOVB RADIX,R2 ;GET RADIX AS MULTIPLIER CMPB R5,R2 ;GREATER THAN RADIX? BHIS 40$ ;IF HIS YES - TERMINATE CALL DMUL ;MULTIPLY VALUE BCC 30$ ;IF CC OK - CARRY ON ; 25$: MOV #-2,R0 ;NO - SET ERROR RETURN BR ASCCLR ;EXIT ; 30$: ADD R5,R1 ;ADD INPUT CHARACTER TO RUNNING TOTAL ADC R0 ;AND CARRY BMI 25$ ;IF MI OVERFLOW - ERROR DECB NUMCHR ;DECREMENT COUNT BGT ASCLOP ;IF GT MORE TO GO - CARRY ON TSTB SIGN ;MINUS SIGN AROUND? BEQ 40$ ;IF EQ NO - CARRY ON NEG R0 ;YES - NEGATE NUMBER DEC R0 ; NEG R1 ; 40$: MOV NUMBER,R2 ;GET ADDRESS OF OUTPUT MOV R1,(R2)+ ;OUTPUT IT MOV R0,(R2) ; MOVB NUMCHR,R0 ;SET RETURN AS NUMBER OF CHARACTERS UNDONE BR ASCEND ;SET ERROR & RETURN ; ASCCLR: MOV NUMBER,R1 ;GET ADDRESS OF NUMBER CLR (R1)+ ;CLEAR ANSWER CLR (R1) ; ASCEND: RETURN .END