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