TLS=6046 TSF=6041 ; Parameter Definition: OUBUF=5000 ; Output buffer starts at 05000. OUCTL=4200 ; and is 2 pages long. OUDEVH=6600 ; Output handler gets loaded at 06600. We ; allow 2 page handlers. INBUF=5400 ; Input buffer starts at 05400 INCTL=0200 ; also 2 pages long. INRECS=1 ; 2 pages = 1 record INDEVH=7000 ; Allow 2 page intput handler at 07000. ORIGIN=6600 ; The subroutines reside at 16600. DCB=7760 ; Device Control Table .FIELD 1 .ORG ORIGIN INFLD=INCTL&70 ; Input Buffer Field OUFLD=OUCTL&70 ; Output Buffer Field IN7400: 7400 IOPEN: 0 ; Initialize Input CLA CMA DCA INCHCT ; Set to read from new device ISZ INEOF ; Force a new input file. TAD [7617] ; Point to CD Input List. DCA INFPTR JMP @IOPEN INEOF: 0 INFPTR: 0 INPTR: 0 ICHAR: 0 ; Input a character. IN7600: 7600 RDF ; Save calling field for return. TAD INCDIF DCA INRTRN INCHAR: CDF INFLD ; Data field to field of buffer ISZ INJMP ; 3 - way unpacking switch ISZ INCHCT ; Input buffer exhausted? INJMPP: JMP INJMP ; No..unpack the next char. TAD INEOF ; Did last read give EOF on this device? SNA CLA JMP INGBUF ; No. Continue Reading. GETNEW: JMS INNEWF ; Yes..get next input if it exists. JMP EOFERR ; Take EOF exit from ICHAR. INGBUF: TAD INCTR ; INCTR holds the current length of ; the input file. When the amount remaining ; to read is less than the size of the ; input buffer, an EOF is signalled. CLL TAD [INRECS] SNL DCA INCTR ; Update remaining length SZL ISZ INEOF ; and signal EOF for next read. CLL CML CMA RTR ; Construct a control word for this RTR ; read from the overflow, if any. RTR ; and the standard control word. TAD [INCTL+1] DCA INCTLW INCDIF: CXF 0 ; Now do a call to the input handler CDF 1 ; We are in field 1, handler in field 0 JMS @INHNDL INCTLW: 0 ; Input Control Word INBUFP: INBUF ; Input buffer address INREC: 0 ; Pointer to input record JMP INERRX INBREC: TAD INREC TAD [INRECS] ; Update pointer into file DCA INREC TAD INCTLW ; Now compute the number of characters AND IN7600 ; in this input buffer CLL RAL TAD INCTLW AND IN7600 CMA DCA INCHCT ; New number of characters. TAD INJMPP ; Reset 3 way switch DCA INJMP TAD INBUFP DCA INPTR ; and buffer pointer JMP INCHAR ; Now read the buffer INERRX: ISZ INEOF ; Set EOF just in case SMA CLA ; If < 0, a physical error JMP INBREC ; EOF on input INERR: CLA CLL CML RAR ; Fatal EOFERR: JMP INRTRN ; Get out INJMP: HLT ; 3 way unpack switch JMP ICHAR1 ; Get 1st of 3 JMP ICHAR2 ; Second ICHAR3: TAD INJMPP DCA INJMP ; Set for first char, next TAD @INPTR ; The third word is made of the high IN200: AND IN7400 ; order four bits of the first CLL RTR ; two. RTR TAD INCTLW RTR RTR ISZ INPTR ; Point to next word JMP INCOMN ; Get out with char in AC ICHAR2: TAD @INPTR AND IN7400 ; Save high order for third word DCA INCTLW ISZ INPTR ICHAR1: TAD @INPTR INCOMN: AND [377] TAD [-232] ; Is it a ^Z (EOF)? SNA JMP GETNEW ; Yes..look at next input TAD [232] ISZ ICHAR ; Take normal return INRTRN: 0 ; CIF CDF n. JMP @ICHAR INNEWF: -1 INCHCT=INNEWF CDF 1 TAD [INDEVH+1] ; Initialize in case we need a new DCA INHNDL ; More input? TAD @INFPTR SNA JMP @INNEWF ; Nope JMS @IN200 ; Call monitor to get handler 1 INHNDL: 0 HLT ; Very bad! TAD @INFPTR AND [7760] ; Get input file length SZA TAD [17] CLL CML RTR RTR ; Negative of file length DCA INCTR ISZ INFPTR ; Point to starting block TAD @INFPTR DCA INREC ; Store in handler call ISZ INFPTR ; Next input. DCA INEOF ; Clear EOF flag. ISZ INNEWF JMP @INNEWF INCTR=IOPEN .PAGE OOPEN: 0 ; Open output file OU7600: 7600 TAD OU7601 ; Point to output file name in CD DCA OUBLK ; area TAD [OUDEVH+1] DCA OUHNDL ; Initialize output device handler TAD @OU7600 ; Pick up output device number AND [17] SNA ; Is there one? JMP ONOFIL ; No..Inhibit output JMS @[200] ; Fetch output handler 1 OUHNDL: 0 HLT ; Bad thing OUENTR: TAD @OU7600 JMS @[200] ; Enter the output file 3 OUBLK: 7601 ; Gets starting block of hole OUELEN: 0 ; Gets size of hole available JMP OEFAIL ; Failure. See what we did. DCA OUCCNT ; Clear closing length DCA @[OUTINH] ; Clear output inhibit JMS @[OUSETP] ; Set up pointers ISZ OOPEN OORETN: CXF 1 JMP @OOPEN ; Return O.K. OEFAIL: TAD @OU7600 ; If length=0, give open error AND [7760] ; If not, make it 0 and try again SNA CLA JMP ONTERR ; Was 0, failed TAD @OU7600 AND [17] ; Make it 0 DCA @OU7600 JMP OUENTR ; and try again ONTERR: CLA CLL CML RAR JMP OORETN ONOFIL: ISZ @[OUTINH] ; Inhibit output JMP OORETN OUTDMP: 0 ; Dump output buffer DCA OUCTLW ; Store control word CDF 1 TAD @[OUTINH] ; Is output inhibited? SZA CLA JMP OUNOWR ; Yep. TAD OUCCNT ; If this is first write, start the SNA ; search forward on DECtape ISZ OUCTLW TAD OUBLK ; Get starting block of this DCA OUREC ; transfer TAD OUCTLW CLL RTL RTL RTL ; Compute of records to output AND [17] TAD OUCCNT ; Update closing length DCA OUCCNT TAD OUCCNT ; See if closing length will be CLL CML ; bigger than the output hole TAD OUELEN SNL SZA CLA JMP @OUTDMP ; Will be too big OUCDIF: CXF 0 CDF 1 JMS @OUHNDL ; Do the write OUCTLW: 0 OUBUF OUREC: 0 SKP ; Error OUNOWR: ISZ OUTDMP ; Take normal return JMP @OUTDMP PTP=0020 OCLOSE: 0 ; Close output file CDF 1 TAD @[OUTINH] ; If output inhibited, close is a NOP. SZA CLA JMP OCISZ ; A NOP JMS @[OTYPE] ; Determine if output is to PTP AND [770] ; If it is, don't output a ^Z. TAD [-PTP] SZA CLA TAD [232] ; Not PTP, output ^Z as EOF JMS @[OCHAR] JMP OCRET ; Error return JMS @[OCHAR] ; Fill with 0 characters JMP OCRET FILLIP: JMS @[OCHAR] ; Fill to boundary with 0 JMP OCRET JMS @[OTYPE] ; If output is directory device, fill SPA CLA ; whole record, else half record TAD [100] TAD [77] AND @[OUDWCT] ; Are we up to boundary yet? SZA CLA JMP FILLIP ; No TAD @[OUDWCT] TAD [OUCTL&3700]; Is there a full write left? SNA JMP NODUMP ; Yes, but don't do it, as ^Z is out. TAD [4000+OUFLD] JMS OUTDMP ; Dump last buffer JMP OCRET NODUMP: TAD @OU7600 ; Get device number JMS @[200] ; Close the output file 4 OU7601: 7601 ; Pointer to file name OUCCNT: 0 ; Closing file length here SKP ; Error OCISZ: ISZ OCLOSE ; Normal return OCRET: CXF 1 ; Restore calling fields JMP @OCLOSE .PAGE OUSETP: 0 ; Initialize output pointers TAD [OUCTL&3700] CIA DCA OUDWCT ; Double word output count TAD [OUBUF] ; Initialize word pointer DCA OUPTR TAD OUJMPE DCA OUJMP ; 3 way unpack switch JMP @OUSETP OCHAR: 0 ; Output character routine AND [377] ; Isolate eight bits DCA OUTEMP RDF ; Get field we were called TAD [CXF 0] ; from DCA OUCRET TAD OUTINH ; Output inhibited? SZA CLA JMP OUCOMN ; Yes, NOP. OUCHAR: CDF OUFLD ; Go to data field of buffer ISZ OUJMP ; Bump character switch OUJMP: HLT ; Get JMP ., JMP .+1, etc. JMP OCHAR1 JMP OCHAR2 OCHAR3: TAD OUTEMP ; Third char CLL RTL ; High order bits go into the RTL ; high order 4 bits or the AND [7400] ; first of two words TAD @OUPOLD DCA @OUPOLD TAD OUTEMP ; The second double word gets CLL RTR ; the low order bits of RTR ; the third char RAR AND [7400] TAD @OUPTR DCA @OUPTR TAD OUJMPE ; Reset character switch DCA OUJMP ISZ OUPTR ; Point to next buffer word ISZ OUDWCT ; Bump double count after ; 2 chars. JMP OUCOMN ; Get out TAD [OUCTL] ; Ready to output a buffer JMS @[OUTDMP] ; Output it JMP OUCRET ; An error JMS OUSETP ; Reset output pointers JMP OUCOMN OCHAR2: TAD OUPTR ; Point to first double word DCA OUPOLD ISZ OUPTR ; Point OUPTR to second OCHAR1: TAD OUTEMP DCA @OUPTR OUCOMN: ISZ OCHAR ; Normal exit OUCRET: HLT JMP @OCHAR OUTEMP: 0 OUPOLD: 0 OUPTR: 0 OUJMPE: JMP OUJMP OUDWCT: 0 OUTINH: 0 OTYPE: 0 ; Otype looks at the output device , RDF TAD [CXF 0] DCA OTRTN CDF 1 TAD @[7600] ; and looks up the DCB word for AND [17] ; that device TAD [DCB-1] DCA OUTEMP TAD @OUTEMP ; Get DCB entry OTRTN: HLT JMP @OTYPE .FIELD 1 .ORG 2000 JMS @[7700] ; Lock monitor into core 10 CALLCD: JMS @[200] ; Call the command decoder 5 0 JMS @[IOPEN] ; Set up input pointers JMS @[OOPEN] ; Open output file SMA CLA ; Error. If AC < 0, it was fatal JMP OK ; Non file structured output JMS TERR .SIXBIT /OPEN FAILED/ OK: JMS @[ICHAR] ; Read a character JMP TSTEOF ; Error, see if EOF. SNA ; Ignore nulls JMP OK JMS @[OCHAR] ; and output the character JMP OUTERR JMP OK ; Continue until EOF. TSTEOF: SMA CLA ; Was it fatal? JMP CLOSE ; No..EOF. Close output JMS TERR .SIXBIT /READ ERROR/ 0 CLOSE: JMS @[OCLOSE] JMP CLERR ; File close failed JMP CALLCD ; New input. OUTERR: JMS TERR .SIXBIT /OUTPUT ERROR/ 0 CLERR: JMS TERR ; Close failure .SIXBIT /CLOSE FAILED/ 0 TERR: 0 ; Routine to print error messages TAD @TERR RTR RTR RTR JMS TYPIT ; Type the character TAD @TERR JMS TYPIT ISZ TERR JMP TERR+1 TYPIT: 0 AND [77] ; Isolate the character SNA JMP CRLF ; 0 terminates it TAD [300] JMS TTYOUT JMP @TYPIT CRLF: TAD [215] JMS TTYOUT TAD [212] JMS TTYOUT JMP CALLCD TTYOUT: 0 TLS TSF JMP .-1 CLA JMP @TTYOUT .END ;$$$$$$$$$$