Input loop is part of Short Circuit's Console Program Basics selection.
Task

Read from a text stream either word-by-word or line-by-line until the stream runs out of data.

The stream will have an unknown amount of data on it.




 
        TITLE Input Loop
 
COMMENT !
       Input-loop example, PDP-10 assembly language, kjx 2022.
           Assembler: MACRO-10   Operating system: TOPS-20
 
   This program opens the file "test.txt" and prints it's contents.
 
   Note that the PDP-10 is a word-addressable machine with 36bit words,
   and text-files use 7bit ASCII. That means one word fits 5 characters
   and the buffer length of 20 (octal!) makes room for 80 (decimal) char-
   acters.
 
   The system-call used, SIN%, can also read until a specific character
   (like CR) is seen, so reading one-line-at-a-time is also possible with
   minimal changes.  
!
 
        SEARCH MONSYM,MACSYM
        .REQUIRE SYS:MACREL
 
        STDAC.                          ;Define standard register names.
 
        ;;
        ;; Buffers and data:
        ;;
 
        PDLLEN==20
PDL:    BLOCK PDLLEN                    ;Callstack (for ERCAL later).
 
        MAXBUF==20                      ;Use 20 36bit words for buffer.
        MAXCHR==MAXBUF*5                ;One 36bit words fits 5 7bit bytes.
IN.BUF: BLOCK MAXBUF                    ;Buffer for lines read from file.
 
IN.JFN: BLOCK 1                         ;Space for file-descriptor (JFN)
 
        ;;
        ;; Execution begins here:
        ;;
 
GO::    RESET%                          ;Initialize process.
        MOVE  P,[IOWD PDLLEN,PDL]       ;Initialize stack.
 
        ;;
        ;; To open a file, we first have to get a file-handle (JFN):
        ;;
 
        MOVX  T1,GJ%OLD+GJ%SHT          ;Flags go into T1:
                                        ; GJ%OLD = File already exists.
                                        ; GJ%SHT = Short system call.
        HRROI T2,[ASCIZ /test.txt/]     ;File name goes to T2.
        GTJFN%                          ;Get a JFN for this file.
          ERJMPS ERROR                  ;  On error jump to ERROR.
        MOVEM T1,IN.JFN                 ;Save the JFN.
 
        ;;
        ;; Now we can open the file:
        ;;
 
        HRRZ  T1,IN.JFN                 ;Right half-word of JFN into T1 +
                                        ;zero out left half to get rid of
					;flags returned by GTJFN%.
        MOVX  T2,FLD(7,OF%BSZ)+OF%RD    ;7bit characters, read-only.
        OPENF%                          ;Open file.
          ERJMPS ERROR                  ;  On error jump to ERROR.
 
        ;;
        ;; Now we're reading MAXCHR 7bit bytes from that file
        ;; into IN.BUF and print that. If we'll see EOF, Q1 is
        ;; set to 1, and the loop is exited.
        ;;
 
        SETZ  Q1                        ;Clear Q1 (we use that as an EOF marker)
        DO.
          MOVE  T1,IN.JFN               ;Read from IN.JFN (opened file)
          HRROI T2,IN.BUF               ;and write into IN.BUF.
          MOVNI T3,MAXCHR               ;Read maximum of MAXCHR characters.
          SIN%                          ;Read string from file.
            ERCAL [ MOVE  T1,IN.JFN     ;  Error occured...
                    GTSTS%              ;  Get file status.
                    TXNN  T2,GS%EOF     ;  End-of-file reached?
                      JRST ERROR        ;    No: Something else happened...
                    MOVEI Q1,1          ;  Yes: Set Q1 to 1.
                    RET ]               ;  Continue.
          MOVEI T1,.PRIOU               ;Write to standard output.
          HRROI T2,IN.BUF               ;Buffer to write.
          ADDI  T3,MAXCHR               ;Substract chars read from
          MOVN  T3,T3                   ;maximum buffer length.
          SOUT%                         ;Print string.
          CAIN  Q1,1                    ;Is Q1 == 1?
            JRST ENDPRG                 ;  Yes: EOF was found above.
          LOOP.                         ;Q1 is 0, so no EOF, continue.
        ENDDO.
 
        ;;
        ;; ENDPRG: Close file and halt.
        ;;
 
ENDPRG: HRRZ  T1,IN.JFN                 ;Put JFN into T1.
        CLOSF%                          ;Close that file.
          ERJMPS ERROR                  ;  Go print error-msgs on error.
        HALTF%                          ;Halt program.
        JRST  GO                        ;Allow for 'continue'-command.
 
        ;;
        ;; ERROR: Print standardized error-message and halt.
        ;;
 
ERROR:  MOVEI T1,.PRIOU                 ;Print error on terminal (.PRIOU)
        MOVE  T2,[.FHSLF,,-1]           ;Own process, most recent error.
        SETZ  T3,                       ;No limit on size of message.
        ERSTR%                          ;Print that error message.
          JFCL                          ;  Ignore errors from ERSTR.
          JFCL                          ;  dito.
        HALTF%                          ;Stop program.
        JRST GO                         ;Allow for continuation.
 
        END GO
 