.TITLE ICNVT .IDENT /V01/ .SBTTL DESCRIPTION ; ; ; COMPONENT: ICNVT ; ; DATE: 11-JUN-79 ; ; AUTHOR: GR JOHNSON ; BATTELLE NORTHWEST ; P O BOX 999 ; RICHLAND WA 99352 ; ; SOURCE: MACRO-11 ; ; CALLER: FORTRAN IV-PLUS ; ; CALLING SEQUENCE: ; ; INT = ICNVT(STRING,[ILEN],[RADIX],[ISW]) ; ; INT = VARIABLE TO RECEIVE THE INTEGER RESULT OF THE ; ASCII CONVERSION. ; ; STRING = VARIABLE OR ARRAY CONTAINING THE ASCII STRING TO ; BE SCANNED FOR CONVERSION. ; ; ILEN = INTEGER VARIABLE TO RECEIVE THE NUMBER OF ASCII ; CHARACTERS SCANNED DURING CONVERSION. ; ; RADIX = OPTIONAL ARGUMENT SPECIFYING THE RADIX (2-16) TO USE ; DURING CONVERSION. (DEFAULT=10) ; ; ISW = VARIABLE TO RECEIVE THE INTEGER STATUS WORD. ; ; 00 = CONVERSION SUCCESSFUL ; -01 = BINARY OVERFLOW ; -02 = DECIMAL OVERFLOW ; ; ; DESCRIPTION: ; ; "ICNVT" CONVERTS AN ASCII STRING TO ITS INTEGER EQUIVALENT USING ; AN OPTIONALLY SPECIFIED RADIX (2-16). THE ASCII STRING IS SCANNED AND ; CONVERTED UNTIL ENCOUNTERING A NON-NUMERIC OR OUT-OF-RANGE CHARACTER. ; LEADING SPACES ARE IGNORED, IMBEDDED SPACES WILL HALT CONVERSION. THE ; ACTUAL NUMBER OF CHARACTERS SCANNED IS OPTIONALLY RETURNED IN "ILEN". ; BINARY OVERFLOW OCCURS IF THE CONVERSION EXCEEDS 177777(8). DECIMAL ; OVERFLOW OCCURS IF RADIX-10 IS SPECIFIED (EXPLICITLY OR BY DEFAULT) AND ; THE INTEGER RESULT EXCEEDS 32767(10). ; ; ; EXAMPLES: ; ; INT1 = ICNVT('1999') ; INT2 = ICNVT('1777',LEN2,8) ; INT3 = ICNVT(' 3FF',LEN3,16) ; INT4 = ICNVT(' 99 ',LEN4) ; INT5 = ICNVT('1999',LEN5,8) ; ; INT1 = 1999 ; INT2 = 1023 LEN2 = 4 ; INT3 = 1023 LEN3 = 4 ; INT4 = 99 LEN4 = 3 ; INT5 = 1 LEN5 = 1 ; ; .SBTTL ENTRY POINT -- FORTRAN INTERFACE TO ASCII/INTEGER CONVERSION ; ; ; .PSECT ; ; ICNVT:: ; ; MOV 2(R5),R1 ; STRING ADDRESS TO R1 CLR R3 ; CLEAR RADIX (R3) CLR R4 ; CLEAR ISW (R4) CMPB #3,(R5) ; THREE ARGUMENTS? BGT 2$ ; NO, USE DEFAULT RADIX TST 6(R5) ; NULL ARGUMENT? BLT 2$ ; YES, USE DEFAULT RADIX MOV @6(R5),R3 ; NO, MOVE RADIX TO R3 ; 2$: JSR PC,C$ICVT ; CALL ASCII TO INTEGER CONVERSION ; BCC 4$ ; BINARY OVERFLOW? MOV #-1,R4 ; YES, SET ISW = -1 BR RTN ; AND RETURN 4$: CMP #10.,R3 ; RADIX-10? BNE RTN ; NO, RETURN WITHOUT ERROR TST R0 ; DECIMAL OVERFLOW? BGE RTN ; NO, RETURN WITHOUT ERROR MOV #-2,R4 ; YES, SET ISW = -2 BR RTN ; AND RETURN ; RTN: CMPB #2,(R5) ; TWO ARGUMENTS? BGT 4$ ; NO, RETURN TO CALLER TST 4(R5) ; NULL ARGUMENT? BLT 2$ ; YES, RETURN WITHOUT ILEN MOV R2,@4(R5) ; NO, RETURN CHARACTER COUNT 2$: CMPB #4,(R5) ; FOUR ARGUMENTS? BGT 4$ ; NO, RETURN WITHOUT ISW TST 10(R5) ; NULL ARGUMENT? BLT 4$ ; YES, RETURN WITHOUT ISW MOV R4,@10(R5) ; NO, RETURN WITH ISW 4$: RTS PC ; RETURN TO CALLER ; .SBTTL ENTRY POINT -- ASCII TO INTEGER CONVERSION ; ; ; REGISTER USAGE: ; ; R0 = INTEGER RESULT ; R1 = ASCII STRING ADDRESS (POINTS TO NEXT CHARACTER UPON RETURN) ; R2 = CHARACTER COUNT ; R3 = RADIX ; ; ; .PSECT ; ; C$ICVT:: ; ; MOV R5,-(SP) ; PRESERVE SCRATCH REGISTERS MOV R4,-(SP) ; MOV R3,-(SP) ; PRESERVE RADIX CLR R5 ; CLEAR SCRATCH REGISTERS CLR R4 ; TST R3 ; TEST RADIX BNE .+6 ; DEFAULT RADIX? MOV #10.,R3 ; YES, SET RADIX = 10. CLR R2 ; CLEAR CHARACTER COUNT ; 2$: CMPB #040,(R1) ; LEADING SPACE? BNE 4$ ; NO, GO CONVERT INC R1 ; YES, POINT TO NEXT CHARACTER INC R2 ; INCREMENT CHARACTER COUNT BR 2$ ; AND CONTINUE SCAN ; 4$: MOVB (R1)+,R0 ; MOVE CHARACTER TO R0 CMPB #101,R0 ; POSSIBLE HEXADECIMAL? BGT .+6 ; NO, SKIP OFFSET SUB #101-072,R0 ; YES, OFFSET TO ':' SUB #060,R0 ; CONVERT CHARACTER TO BINARY BLT 10$ ; RETURN TO CALLER IF LESS THAN ZERO CMP R3,R0 ; LESS THAN RADIX? BLE 10$ ; NO, RETURN TO CALLER INC R2 ; YES, INCREMENT CHARACTER COUNT MUL R3,R4 ; MULTIPLY TEMP RESULT BY RADIX TST R4 ; OVERFLOW? BNE 6$ ; YES, RETURN WITH ERROR ADD R0,R5 ; NO, ADD CURRENT DIGIT BCS 6$ ; RETURN WITH ERROR IF OVERFLOW MOV R5,R4 ; JUSTIFY TEMPORARY RESULT REGISTERS BR 4$ ; CONTINUE CONVERSION ; 6$: SEC ; ERROR; SET 'C-BIT' BR 12$ ; AND RETURN ; 10$: CLC ; SUCCESS; CLEAR 'C-BIT' ; 12$: MOV R5,R0 ; MOVE CONVERTED BINARY TO R0 MOV (SP)+,R3 ; RESTORE RADIX MOV (SP)+,R4 ; RESTORE SCRATCH REGISTERS MOV (SP)+,R5 ; RTS PC ; RETURN TO CALLER .END ;