Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-06 - 43,50363/ioruts.mac
There are no other files named ioruts.mac in the archive.
         UNIVERSAL   IOPARM--PARAMETERS FOR THE FOLLOWING ASSEMBLIES
         XPUNGE
HSORG==400000

DEBUG==1 ;NON-ZERO IF DEBUGGING CODE IS GENERATED


;ACCUMULATOR ASSIGNMENTS
F==0     ;FLAGS
         LFQFLG==1B1               ;NEWLINE REQUIRED BEFORE FURTHER OUTPUT.
         RD2FLG==1B2               ;READ TYPE FLAG = 1 IFF READ2.
T==1     ;A TEMP
T2==2    ;A TEMP
T3==3    ;A TEMP
T4==4    ;A TEMP
A5==5
A6==6
A7==7
A10==10
A11==11
A12==12
A13==13
A14==14
R==15    ;SOMETIMES A RETURN ADDRESS OR SECOND PARAMETER
A==16    ;PARAMETERS AND JUNK
P==17    ;STACK CONTROL WORD


OPDEF    GOTO[JRST]
OPDEF    SKIP1[TRNA]
OPDEF    INVOKE[PUSHJ P,]
OPDEF    RETURN[POPJ P,]
OPDEF    SAVE[PUSH P,]
OPDEF    RESTORE[POP P,]


TTY==1   ;TTY I/O CHANNEL NUMBER.


DEFINE ERRMSG(A,B)<
TTCALL 3,[ASCIZ/A'B
/]
EXIT 1,
>       ;EXAMPLE:  ERRMSG(?IMPOSSIBLE LINE NUMBER--NOW IN ACCUMULATOR,\A)

         PRGEND
         TITLE   NUMBER--NUMERIC I/O ROUTINES
         SEARCH  IOPARM
         TWOSEG  HSORG
ENTRY    READ,READ2,READPR,OUTFIX,OUTINT,OUTF.0,OUTF.1,OUTF.2,OUTF.3
EXTERN   INCHR,OUTCHR,OUTSTR

         RELOC HSORG
;READ  --SUBROUTINE TO READ ONE NUMBER FROM ONE LINE FROM THE TTY.
;READ2 --SUBROUTINE TO READ ONE NUMBER FROM PART OF A LINE.
;CALL:   PUSHJ   P,READ
;        (END-OF-FILE RETURN WITH NUMBER IN A)
;        (RETURN WITH SINGLE PRECISION FLOATING POINT IN A)

READ2:   TLOA    F,(RD2FLG)        ;INDICATE READ TYPE.
READ:    TLZ     F,(RD2FLG)
         SAVE    A5
         SAVE    A6
         SAVE    A7
         MOVSI   A5,(1.0)          ;SET INITIAL SIGN.
         CLEAR   A6,               ;SET INITIAL NUMBER.
         CLEAR   A7,               ;SET INITIAL DECIMAL POINT CORRECTION.
         GOTO    READLK

         ;LOOK FOR FIRST DIGIT
READMN:  CAIN    A,"-"             ;IF MINUS SIGN DETECTED,
         MOVN    A5,A5             ;SWITCH THE SIGN.
READLK:  INVOKE  INCHR             ;GET A CHARACTER.
         GOTO    READEF            ;QUIT IF END-OF-FILE
         JSP     R,DIGADD          ;ADD A DIGIT TO THE NUMBER.
         GOTO    READED            ;QUIT IF END OF LINE.
         GOTO    READMN            ;KEEP LOOKING IF NOT DIGIT OR PERIOD.
         GOTO    READFR            ;IF PERIOD, COMPILE A FRACTION.

         ;ASSEMBLE INTEGER PART
READIN:  INVOKE  INCHR             ;GET A CHARACTER.
         GOTO    READEF            ;QUIT IF END OF FILE.
         JSP     R,DIGADD          ;ADD A DIGIT TO THE NUMBER.
         GOTO    READED            ;QUIT IF END OF LINE.
         GOTO    READFN            ;TERMINATE IF END OF NUMBER.
         GOTO    READFR            ;ADD A FRACTION IF A PERIOD.
         GOTO    READIN            ;REPEAT IF A DIGIT.

         ;ASSEMBLE FRACTION PART
READFR:  INVOKE  INCHR             ;GET A CHARACTER.
         GOTO    READEC            ;IF EOF, FINISH NUMBER AND QUIT.
         JSP     R,DIGADD          ;ADD DIGIT TO NUMBER.
         GOTO    READCR            ;IF BREAK OR NON-DIGIT,
         GOTO    READCR            ;CORRECT MAGNITUDE FOR FRACTION.
         GOTO    READCR            ;TREAT A PERIOD AS A DELIMITER.
         AOJA    A7,READFR         ;COUNT DIGITS TO RIGHT OF DECIMAL POINT.

         ;CORRECT FOR DECIMAL POINT
READEC:  SOS     -3(P)             ;CAUSE END OF FILE RETURN.
         MOVEI   A,12              ;SET FALSE BREAK CHARACTER.
READCR:  SOJL    A7,READFN         ;DIVIDE RESULT BY ^D10 ONCE FOR
         FDVRI   A6,(10.0)         ;EACH DIGIT AFTER DECIMAL POINT.
         SOJGE   A7,.-1

         ;IGNORE REMAINDER OF LINE
READFN:  TLNE    F,(RD2FLG)        ; ... ONLY IF TYPE 1 READ.
         GOTO    READED
READNX:  JSP     R,BREAKT          ;IS THIS CHARACTER A BREAK?
         GOTO    READED            ;YES--RETURN TO CALLER.
         INVOKE  INCHR             ;NO--TRY NEXT CHARACTER.
         GOTO    READEF            ;IF EOF, USE THE SPECIAL RETURN.
         GOTO    READNX            ;CONTINUE LOOKING FOR A BREAK.

READED:  AOS     -3(P)             ;CAUSE A NORMAL (SKIP) RETURN.
READEF:  MOVE    A,A6              ;PROVIDE RESULT OF ALL THIS COMPUTATION.
         FMPR    A,A5              ;GIVE IT THE DESIRED SIGN.
         RESTORE A7                ;WE SAVED THESE ABOVE.
         RESTORE A6
         RESTORE A5
         RETURN                    ;THE LAST RESORT.


;READPR--TRIES TO READ TWO NUMBERS FROM ONE LINE.
;CALL:   INVOKE  READPR
;        (END-OF-FILE RETURN)
;        (RETURN WITH FIRST NUMBER IN R, SECOND IN A)
READPR:  INVOKE  READ2
         RETURN
         SAVE    A
         INVOKE  READ
         SKIP1
         AOS     -1(P)
         RESTORE R
         RETURN

;OUTINT--SUBROUTINE TO TYPE A SIGNED INTEGER.
;CALL:   MOVE    A,INTEGER
;        INVOKE  OUTINT
;        (RETURN)
OUTINT:  MOVM    T,A               ;GET MAGNITUDE OF THE INTEGER.
         JUMPGE  A,OUTINX          ;IF NUMBER WAS NEGATIVE,
         SAVE    T                 ;OUTPUT A MINUS SIGN.
         MOVEI   A,"-"             ;IN THIS CASE, IT IS NOT PROPER TO
         INVOKE  OUTCHR            ;ASSUME THAT OUTCHR DOES NOT
         RESTORE T                 ;USE THE TEMPORARY ACCUMULATORS.
OUTINX:  IDIVI   T,^D10            ;EXTRACT THE ONE'S DIGIT.
         SAVE    T2                ;(T2=T+1 CONTAINS THE REMAINDER)
         SKIPE   T                 ;IF THE OTHER DIGITS ARE NOT ZERO,
         INVOKE  OUTINX            ;OUTPUT THEM.
         RESTORE A                 ;NOW OUTPUT THIS ONE:
         ADDI    A,"0"                 ;CONVERT TO ASCII.
         GOTO    OUTCHR                ;GIVE TO OUTPUT ROUTINE.

;NIFTY SUBROUTINES USE BY READ

;TO TEST BREAK CHARACTERS LAST IN BUFFER:
IFE DEBUG,<OPDEF BRKRET[GOTO (R)]>
IFN DEBUG,<OPDEF BRKRET[GOTO BRKTST]
           EXTERN TTYIHD
           BRKTST: SKIPN  TTYIHD+2
                   GOTO   (R)      ;HERE IF BREAK LAST IN BUFFER.
                   SOS     TTYIHD+2
                   ILDB    A,TTYIHD+1
                   JUMPE   A,BRKTST
                   ERRMSG(?BREAK NOT LAST IN TTY BUFFER)>

;BREAKT--TESTS FOR BREAK CHARACTERS
;CALL:   MOVE    A,CHARACTER
;        JSP     R,BREAKT
;        (BREAK RETURN)
;        (OTHER RETURN)

BREAKT:  CAIE    A,7               ;TEST FOR BELL AND ESCAPE.
         CAIN    A,33
         BRKRET
         CAIE    A,175             ;TEST FOR THE OLD ALTMODES.
         CAIN    A,176
         BRKRET
         CAIL    A,12              ;TEST FOR LF,VT,FF.
         CAILE   A,14
         GOTO    1(R)
         BRKRET


;DIGADD--TESTS FOR BREAKS, PERIODS, DIGITS AND ADDS DIGITS TO RUNNING SUM IN A6.
;CALL:   MOVE    A,CHARACTER
;        JSP     R,DIGADD
;        (BREAK RETURN--CHARACTER STILL IN A)
;        (OTHER RETURN--CHARACTER STILL IN A)
;        (PERIOD RETURN--CHARACTER STILL IN A)
;        (DIGIT RETURN--FLOATING POINT DIGIT IN A)

DIGADD:  CAIN    A,"."             ;IF PERIOD, GIVE PERIOD RETURN.
         GOTO    2(R)
         CAIL    A,"0"
         CAILE   A,"9"             ;IS CHARACTER A DIGIT?
         GOTO    BREAKT            ;NO--MUST BE A BREAK OR AN OTHER.
         SUBI    A,"0"             ;YES--CONVERT TO BINARY VALUE.
         FLTR    A,A               ;WE WANT FLOATING POINT ARITHMETIC.
         FMPRI   A6,(10.0)         ;APPEND THE DIGIT TO THE CURRENT NUMBER.
         FADR    A6,A
         GOTO    3(R)              ;GIVE A DIGIT RETURN.
OUTF.3:  MOVEI   R,3               ;OUTPUT FLOATING POINT WITH 3
         GOTO    OUTFIX            ;DIGITS AFTER THE DECIMAL POINT.
OUTF.2:  MOVEI   R,2               ;OUTPUT FLOATING POINT WITH 2
         GOTO    OUTFIX            ;DIGITS AFTER DECIMAL POINT.
OUTF.1:  MOVEI   R,1               ;SAME AS ABOVE BUT ONLY ONE DIGIT.
         GOTO    OUTFIX
OUTF.0:  MOVEI   R,0
         GOTO    OUTFIX


;OUTFIX--SUBROUTINE TO OUTPUT A FLOATING POINT NUMBER IN FIXED POINT FORMAT
;CALL:   MOVE    A,FLOATINGPOINTNUMBER
;        MOVEI   R,NUMBEROFDIGITSAFTERDECIMALPOINT
;        INVOKE  OUTFIX
;        (RETURN)
OUTFIX:  JUMPGE  A,OUTMAG          ;IF NUMBER IS NEGATIVE,
         MOVM    A,A               ;OUTPUT A MINUS SIGN AND
         SAVE    A                 ;USE ITS MAGNITUDE INSTEAD.
         SAVE    R
         MOVEI   A,"-"
         INVOKE  OUTCHR
         RESTORE R
         RESTORE A
OUTMAG:  CAML    A,OUTLRG          ;TEST FOR A NUMBER TOO LARGE.
         GOTO    OUTOVR
         JUMPLE  R,OUTFDG          ;TEST FOR NO FRACTION REQUESTED.
         CAILE   R,^D10            ;LIMIT FRACTION TO TEN PLACES.
         MOVEI   R,^D10
         FIX     T4,A              ;BREAK UP THE NUMBER INTO AN
         FLTR    T,T4              ;INTEGRAL PART AND A FRACTIONAL PART.
         FSBR    A,T               ;SAVE THE INTEGRAL PART AND
         MOVE    T3,R              ;EXTRACT THE REQUIRED PLACES
         FMPRI   A,(10.0)          ;FROM THE FRACTIONAL PART.
         SOJG    T3,.-1
         FIXR    T,A
OUTFRC:  IDIVI   T,^D10            ;THIS CODE PUSHES THE FRACTION
         SAVE    T2                ;DOWN INTO THE STACK.
         SOJLE   R,OUTRND
         INVOKE  OUTFRC
OUTFRX:  RESTORE A                 ;THIS CODE POPS THE FRACTION
         ADDI    A,"0"             ;UP OUT OF THE STACK AND PRINTS IT.
         GOTO    OUTCHR
OUTRND:  ADD     T4,T              ;IF THE FRACTION ROUNDS
         MOVE    A,T4              ;UP TO 1.000, FUDGE IT.
         INVOKE  OUTINT            ;NOW WE CAN OUTPUT THE INTEGER,
         MOVEI   A,"."             ;FRACTION, AND PERIOD.
         INVOKE  OUTCHR
         GOTO    OUTFRX
OUTFDG:  FIXR    A,A               ;IN CASE NO FRACTION REQUESTED.
         GOTO    OUTINT
OUTOVR:  MOVEI   A,[ASCIZ/****/]   ;IN CASE OF OVERFLOW.
         GOTO    OUTSTR
OUTLRG:  1.0E10

         LIT
         PRGEND
         TITLE   ALTFIL--ALTERNATE I/O AID
         SEARCH  IOPARM
         TWOSEG  HSORG
ENTRY    FILINF
EXTERN   FILSPC,FILERR,INCHR,OUTSTR,BRKOUT,ENDMSG,TTYCLS
         RELOC   HSORG

;SETUP OPEN AND LOOKUP BLOCKS (I.E. READ FILE SPECIFICATION):
;ALSO CHECK FOR PROPER I/O MODE:
;CALL:   MOVE    A,OPENBLOCKADDRESS=LOOKUPBLOCKADDRESS-3
;        MOVEI   R,[DEFAULT OPEN AND LOOKUP BLOCK CONTENTS]
;        INVOKE  FILINF
;        (TTY-EOF-RETURN -- FILE SPEC NOT SET)
;        (NORMAL RETURN)
FILINF:  SAVE    A5                ;SAVE SOME USEFUL ACCUMULATORS.
         SAVE    A6
         MOVE    A5,A
         MOVE    A6,R
FILAGN:  MOVEI   A,[ASCIZ/ENTER FILE SPECIFICATION: /]
         INVOKE  OUTSTR
         INVOKE  BRKOUT
         MOVSI   T,(A6)            ;SET DEFAULT ARG BLOCK CONTENTS.
         ORI     T,(A5)
         BLT     T,5(A5)
         GETPPN  T,                ;SET DEFAULT PPN:
         JFCL
         MOVEM   T,6(A5)
         MOVEI   T4,FILINP         ;SET PARAMETERS FOR FILSPC.
         MOVEI   T3,0
         MOVSI   T2,(A5)
         ORI     T2,3(A5)
         JSP     T,FILSPC          ;USE A CONVENIENT FILE SPEC READER.
         GOTO    FILBDS                ;RETURNS HERE IF SYNTAX ERROR.
         JUMPN   T2,FILTMY         ;T2=0 IFF ONLY ONE SPEC GIVEN.
         MOVE    T,1(A5)           ;GET CHARACTERISTICS OF REQUESTED DEVICE.
         DEVCHR  T,
         MOVEI   T2,1
         MOVE    T3,(A5)           ;MAKE SURE IT TAKES REQUESTED I/O MODE.
         LSH     T2,(T3)
         AND     T2,T
         JUMPE   T2,FILBDV
         AOS     -2(P)             ;GIVE SKIP RETURN IF ALL OK.
FILRET:  RESTORE A6
         RESTORE A5
         RETURN

;REQUIRED SUBROUTINES AND GARBAGE:
FILINP:  INVOKE  INCHR             ;TTY INPUT ROUTINE FOR FILSPC.
         GOTO    FILRET                ;PASS BACK EOF RETURNS.
         CAIN    A,15
         GOTO    FILINP            ;IGNORE CARRIAGE RETURNS.
         CAIN    A,12
         MOVEI   A,0               ;REPLACE LINE FEEDS WITH NULS.
         CAIN    A,32              ;CONTROL Z'S MEAN END OF FILE.
         GOTO    FILINP
         MOVE    T2,A              ;PUT CHAR WHERE FILSPEC EXPECTS IT.
         JSP     T4,(T4)           ;RESUME FILSPC
         GOTO    FILINP
FILTMY:  MOVEI   A,[ASCIZ/?ONLY ONE FILE CAN BE SPECIFIED/]
FILTMX:  INVOKE  ENDMSG
FILTMZ:  INVOKE  TTYCLS            ;IGNORE REST OF TTY BUFFER.
         GOTO    FILAGN
FILBDV:  MOVEI   A,[ASCIZ"?I/O DEVICE DOES NOT TAKE REQUESTED I/O MODE!"]
         GOTO    FILTMX
FILBDS:  JSP     T,FILERR          ;IN CASE OF ERROR RETURN FROM FILSPC.
         GOTO    FILTMZ

         LIT
         PRGEND
         TITLE   IORUTS--SOME HANDY TTY I/O ROUTINES.
         SEARCH  IOPARM
         TWOSEG  HSORG
ENTRY    INCHR,TTYINT,TTYCLS,OUTCHR,BRKOUT,WAITTY,OUTSTR,ENDMSG,NEWLIN,PAGE
IFN DEBUG,<ENTRY TTYIHD>

         RELOC   0
TTYOHD:  BLOCK   3                 ;TTY OUTPUT BUFFER HEADER
TTYIHD:  BLOCK   3                 ;TTY INPUT BUFFER HEADER
WATBLK:  BLOCK   2                 ;ARG BLOCK FOR TRMOP. UUO



         RELOC   HSORG
;INCHR --ROUTINE TO GET ONE CHARACTER FROM THE TTY.
;CALL:   INVOKE  INCHR
;        (END-OF-FILE RETURN)
;        (RETURN WITH A CHARACTER IN A)

INCHR:   SOSGE   TTYIHD+2          ;DECREMENT BYTE COUNT.
         GOTO    GETBUF            ;IF BUFFER IS EMPTY, HAVE IT FILLED.
         ILDB    A,TTYIHD+1        ;GET A CHARACTER.
         JUMPE   A,INCHR           ;IF NULL, KEEP TRYING.
         AOS     (P)
         RETURN

GETBUF:  IN      TTY,              ;GET A BUFFER FROM THE MONITOR.
         GOTO    INCHR             ;IF NO ERRORS, RESUME INCHR.
         GETSTS  TTY,A             ;ELSE GET THE TTY STATUS.
         TRNN    A,1B22            ;SEE IF END OF FILE.
         GOTO    TTYIER            ;NO--MUST BE OTHER ERROR.
                                   ;YES--DUMP ALL PENDING OUTPUT.
TTYCLS:  CLOSE   TTY,              ;REINIT THE TTY.
         TLZ     F,(LFQFLG)        ;CLEAR THE NEWLINE FLAG.
         RETURN                    ;GIVE THE END-OF-FILE RETURN.

TTYIER:  ERRMSG(?INP ERR ON TTY.  FILE STATUS IN AC,\A)

TTYINT:  OPEN    TTY,TTYBLK        ;INITIALIZE THE TTY.
         HALT
         INBUF   TTY,1
         OUTBUF  TTY,1
         TLZ     F,(LFQFLG)        ;CLEAR THE NEWLINE FLAG.
         PJOB    T,                ;SET UP THE TTY WAIT DATA.
         TRMNO.  T,
         HALT
         MOVEM   T,WATBLK+1
         MOVEI   T,<.TOSOP==2>
         MOVEM   T,WATBLK
         RETURN                    ;RETURN TO CALLER

TTYBLK:  1       ;TTY OPEN ARGUMENT BLOCK:  MODE=ASCII LINE.
         SIXBIT/TTY/
         TTYOHD,,TTYIHD
;OUTCHR--ROUTINE TO OUTPUT ONE CHARACTER TO THE TTY
;CALL:   MOVE    A,CHARACTER
;        INVOKE  OUTCHR
;        (RETURN)

OUTCHR:  TLZE    F,(LFQFLG)        ;GOTO A NEW LINE IFF REQUIRED.
         INVOKE  OUTCHL
         SOSG    TTYOHD+2          ;ADVANCE BYTE COUNTER.
         INVOKE  BRKOUT            ;OUTPUT THE BUFFER IF FULL.
OUTCHX:  IDPB    A,TTYOHD+1        ;DUMP BYTE INTO BUFFER.
         RETURN                    ;RETURN TO CALLER.
OUTCHL:  SAVE    A                 ;DO THIS TO TYPE A NEWLINE
         INVOKE  NEWLIN            ;WHILE SAVING AC A.
         RESTORE A
         RETURN

BRKOUT:  OUT     TTY,              ;GET AN EMPTY BUFFER FROM THE MONITOR.
         RETURN                    ;IF NO ERRORS, RESUME NORMAL OUTPUT,
         GETSTS  TTY,T     ;ELSE SEND AN APPROPRIATE ERROR MESSAGE AND QUIT.
ERRMSG(?OUTP ERR ON TTY.  FILE STATUS IN AC,\T)


;WAITTY--WAIT UNTIL TTY OUTPUT DONE OR TTY INPUT READY
;CALL:   INVOKE  WAITTY
;        (RETURN)
WAITTY:  INVOKE  BRKOUT            ;GIVE OUTPUT BUFFER TO MONITOR.
WAITTL:  MOVE    T,WATLOC
         TRMOP.  T,                ;SKIP IF OUTPUT NOT DONE.
         RETURN                    ;ELSE END WAIT.
         MOVE    T,WATWRD          ;MARK TIME FOR 1 SECOND.
         HIBER   T,
         HALT
         SKPINL                    ;IF NO INPUT LINE READY,
         GOTO    WAITTL            ;TRY AGAIN.
         RETURN                    ;ELSE END WAIT.
WATLOC:  XWD     2,WATBLK
WATWRD:  EXP     1B13+^D1500
;OUTSTR--SUBROUTINE TO TYPE A STRING OF ASCII CHARACTERS.
;CALL:   MOVEI   A,[ASCIZ/CHARACTER STRING/]
;        INVOKE  OUTSTR
;        (RETURN)
OUTSTR:  SAVE    A7
         MOVSI   A7,(POINT 7,0)    ;CONSTRUCT A BYTE POINTER
         ORI     A7,(A)            ;FOR THE MESSAGE.
         SKIP1
OUTSTX:  INVOKE  OUTCHR            ;OUTPUT A CHARACTER.
         ILDB    A,A7              ;GET THE NEXT CHARACTER.
         JUMPN   A,OUTSTX          ;IF THIS ONE IS NOT NULL, REPEAT.
         RESTORE A7
         RETURN


;ENDMSG--SUBROUTINE TO TYPE A MESSAGE AND A NEW LINE.
;NEWLINE--OUTPUTS A CARRIAGE RETURN AND A LINE FEED.
ENDMSG:  INVOKE  OUTSTR            ;OUTPUT THE MESSAGE.
NEWLIN:  MOVEI   A,LINCHR          ;OUTPUT A CARRIAGE RETURN.
         GOTO    OUTSTR
LINCHR:  BYTE    (7)15,12


;PAGE  --OUTPUTS A FORM FEED.
PAGE:    MOVEI   A,14
         GOTO    OUTCHR


         LIT
         END