/OS/8 I/O SUBROUTINES /THIS IS A SET OF GENERALISED I/O ROUTINES /FOR USE UNDER THE OS/8 SYSTEM. /THE ROUTINES WORK MOST EFFICIENTLY CALLED FROM FIELD 1, /SINCE FIELD CHANGES ARE NOT NECESSARY. /THE ROUTINES ASSUME UP TO 9 INPUT FILES /AND A SINGLE OUTPUT FILE. /NOTE - THE ROUTINES ASSUME THAT THE COMMAND DECODER /HAS ALREADY BEEN CALLED AND THAT THE USR HAS BEEN /LOCKED IN CORE BY THE CALLING PROGRAM. /THE SUBROUTINES AND THEIR FUNCTIONS. /IOINIT - INPUT/OUTPUT INITIALISATION ROUTINE /CALL SEQUENCE: / CIF 10 / JMS I (IOINIT / ERROR RETURN / NORMAL RETURN /ERRORS: / AC<0 NO ROOM FOR OUTPUT FILE / AC>=0 NO OUTPUT FILE SPECIFICATION INPUT / THERE ARE NO ERRORS ASSOCIATED WITH INPUT /NORMAL: / NEXT CALL TO ICHAR WILL READ FROM THE / FIRST FILE IN THE CD INPUT LIST / (FIRST) OUTPUT FILE HAS BEEN OPENED / NO ACTION IF THE OUTPUTDEVICE IS A / NON-FILE-STRUCTURED DEVICE /ICHAR - CHARACTER INPUT ROUTINE. /CALL SEQUENCE: / CIF 10 / JMS ICHAR / ERROR RETURN / NORMAL RETURN /ERRORS: / IF AC>0, AN EOF ON INPUT HAS OCCURRED. / NO MORE INPUT IS AVAILABLE. / IF AC<0, A DEVICE ERROR HAS OCCURRED. /NORMAL: / 8 BIT CHARACTER IS IN THE AC. /OCHAR - CHARACTER OUTPUT ROUTINE. /CALL SEQUENCE: / TAD CHAR /8 BIT CHARACTER / CIF 10 / JMS OCHAR / ERROR RETURN / NORMAL RETURN /ERRORS: / AC<0 IMPLIES A FATAL ERROR. / AC > OR = 0 IMPLIES THAT THE HOLE ALLOTTED / FOR OUTPUT WAS EXCEEDED. /NORMAL: / AC=0. THE CHARACTER HAS BEEN PUT INTO THE / DEVICE OUTPUT BUFFER. /IOPEN - INPUT INITIALISE ROUTINE. /CALL SEQUENCE: - ONLY CALL THIS FROM FIELD 1 / JMS IOPEN / NORMAL RETURN /ERROR: / NO POSSIBLE ERRORS, SETTING POINTERS ONLY /NORMAL: /INPUT POINTERS RESET. /THE NEXT CALL TO ICHAR WILL READ FROM THE /FIRST DEVICE IN THE COMMAND DECODER INPUT LIST. /OOPEN - OUTPUT INITIALISE ROUTINE. /CALL SEQUENCE: - ONLY CALL THIS FROM FIELD 1 / JMS OOPEN / ERROR RETURN / NORMAL RETURN /ERRORS: / IF AC>=0, NO OUTPUT DEVICE WAS SPECIFIED / IF AC<0, HOLE ALLOTTED FOR OUTPUT WAS EXCEEDED /NORMAL: / AN OUTPUT FILE HAS BEEN OPENED. / NO ACTION IF THE OUTPUT WAS A# / NON-FILE STRUCTURED DEVICE. /OCLOSE - OUTPUT CLOSE ROUTINE. /CALL SEQUENCE: / CIF 10 / JMS OCLOSE / ERROR RETURN / NORMAL RETURN /ERRORS: /EITHER THE CLOSING LENGTH IS TOO LARGE FOR /THE SPACE ALLOTTED OR AN OUTPUT ERROR HAS /OCCURRED. /NORMAL: /THE OUTPUT FILE IS NOW A PERMANENT FILE /ON THE OUTPUT DEVICE. /TYPICAL USAGE /1 LOCK USR IN CORE (USR FUNCTION 10) /2 CALL THE COMMAND DECODER TO GET I/O NAMES /3 CALL IOINIT TO SETUP THE FILE I/O /4 CALL ICHAR AND OCHAR AS NECESSARY /5 CALL OCLOSE TO FINALISE THE OUTPUT FILE /6 MANAGE ERROR AND INCORRECT CD INPUT HANDLING /PARAMETER BLOCK /EDIT AS APPROPRIATE TO SUIT USER APPLICATION /OUTPUT BUFFER ADDRESS FIELD 0 OUBUF=5600 /OUTPUT BUFFER @ 05600-06177 /INPUT BUFFER ADDRESS FIELD 0 INBUF=6200 /INPUT BUFFER @ 06200-06577 /OUTPUT HANDLER ADDRESS FIELD 0 OUDEVH=6600 /2-PAGE OUTPUT HANDLER @ 06600-07177 /INPUT HANDLER ADDRESS FIELD 0 INDEVH=7200 /2 PAGE INPUT HANDLER @ 07200-07577 /OUTPUT BUFFER CONTROL WORD OUCTL=4200 /OP HANDLER CAN BE 2 PAGES LONG /INPUT BUFFER CONTROL WORD INCTL=0200 /IP ALSO 2 PAGES LONG /NUMBER OF RECORDS IN BUFFER INRECS=1 /2 PAGES == 1 RECORD /START OF SUBROUTINES /ASSUME AND MOST EFFICIENT IN FIELD 1 /NEED TO ADD CIF ETC IF CHANGED ORIGIN=7000 /SUBROUTINES RESIDE AT 17000-17577 DCB=7760 /DEVICE CONTROL TABLE /TOTAL MEMORY ALLOCATION IS FIELD 0 - 05600-07577 / FIELD 1 - 17000-17577 FIELD 1 *ORIGIN INFLD=INCTL&70 /INPUT BUFFER FIELD OUFLD=OUCTL&70 /OUTPUT BUFFER FIELD IN7400, 7400 IOPEN, 0 /SUBROUTINE TO INITIALISE INPUT CLA CMA DCA INCHCT /SET TO READ FROM NEW DEVICE ISZ INEOF /FORCE NEW INPUT FILE TAD (7617 /POINT TO CD INPUT LIST DCA INFPTR JMP I IOPEN INEOF, 0 INFPTR, 0 INPTR, 0 ICHAR, 0 /SUBROUTINE TO FETCH A CHAR IN7600, 7600 /IS CLA RDF /GET CALLING FIELD TAD INCDIF DCA INRTRN /FOR THE RETURN INCHAR, CDF INFLD /DF TO FIELD OF BUFFER ISZ INJMP /3-WAY UNPACKING SWITCH ISZ INCHCT /INPUT BUFFER EXHAUSTED? INJMPP, JMP INJMP /NO, FETCH NEXT TAD INEOF /DID LAST READ GIVE EOF? SNA CLA JMP INGBUF /NO, KEEP READING GETNEW, JMS INNEWF /YES, WANT NEXT FILE IF ANY JMP EOFERR /EOF ERROR EXIT INGBUF, TAD INCTR /INCTR HOLDS CURRENT LENGTH OF /NPUT FILE. WHEN AMOUNT REMAINING /TO READ IS LESS THAN SIZE OF 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 RTR /FOR THIS READ FROM THE RTR /OVERFLOW, IF ANY, TAD (INCTL+1 DCA INCTLW INCDIF, CIF CDF 0 /NOW CALL INPUT HANDLER CDF 10 /WE ARE FIELD 1, HANDLER IN FIELD 0 JMS I INHNDL INCTLW, 0 /INPUT CONTROL WORD INBUFP, INBUF /INPUT BUFFER ADDRESS INREC, 0 /POINTER TO INPUT RECORD JMP INERRX /FAIL RETURN INBREC, TAD INREC TAD (INRECS /UPDATE POINTER INTO FILE DCA INREC TAD INCTLW /COMPUTE NUMBER OF CHARS AND IN7600 /IN THIS INPUT BUFFER CLL RAL TAD INCTLW AND IN7600 CMA DCA INCHCT /NEW NUMBER OF CHARS TAD INJMPP /RESET 3-WAY SWITCH DCA INJMP TAD INBUFP DCA INPTR /AND BUFFER POINTER JMP INCHAR /GO READ THE BUFFER INERRX, ISZ INEOF /SET EOF JUST IN CASE SMA CLA /IF <0 A PHYSICAL ERROR JMP INBREC /OTHERWISE EOF ON INPUT INERR, CLA CLL CML RAR /FATAL EOFERR, JMP INRTRN /ABORT INJMP, HLT /3-WAY UNPACK SWITCH JMP ICHAR1 /GET 1ST OF 3 JMP ICHAR2 /2ND ICHAR3, TAD INJMPP /3RD DCA INJMP /IT WILL BE 1ST NEXT TIME TAD I INPTR /3RD CHAR IS HIGH ORDER IN200, AND IN7400 /4 BITS OF WORDS 1 AND 2 CLL RTR RTR TAD INCTLW RTR RTR ISZ INPTR /POINT TO NEXT WORD JMP INCOMN /LEAVE WITH AC=CHAR ICHAR2, TAD I INPTR /WE WANT 2ND CHAR AND IN7400 /SAVE HIGH ORDER FOR 3RD CHAR DCA INCTLW ISZ INPTR ICHAR1, TAD I INPTR /WE WANT 1ST CHAR INCOMN, AND (377 /CHARS 1,2 ARE 8 LOW BITS TAD (-232 /IS IT A ^Z? (=EOF) SNA JMP GETNEW /YES - MOVE TO NEXT INPUT FILE TAD (232 /RESTORE CHAR ISZ ICHAR /AND TAKE NORMAL RETURN INRTRN, 0 /BECOMES CIF CDF N JMP I ICHAR INNEWF, -1 INCHCT=INNEWF CDF 10 TAD (INDEVH+1 /INITIALISE IN CASE WE DCA INHNDL /NEED ANOTHER INPUT FILE TAD I INFPTR SNA JMP I INNEWF /NOPE - NO MORE JMS I IN200 /CALL MONITOR FOR NEW HANDLER 1 INHNDL, 0 HLT /VERY BAD ERROR TAD I 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 I INFPTR DCA INREC /STORE IN HANDLER CALL ISZ INFPTR /READY FOR NEXT FILE IF ANY DCA INEOF /CLEAR EOF FLAG ISZ INNEWF JMP I INNEWF /GOOD RETURN INCTR=IOPEN PAGE OOPEN, 0 /OPEN OUTPUT FILE SUBROUTINE OU7600, 7600 /CLA TAD OU7601 /POINT TO OUTPUT FILE FROM CD DCA OUBLK TAD (OUDEVH+1 DCA OUHNDL /INITIALISE OUTPUT DEV HANDLER TAD I OU7600 /PICK UP OP DEVICE NUMBER AND (17 SNA /ISW THERE ONE? JMP ONDFIL /NO, INHIBIT OUTPUT JMS I (200 /FETCH ITS OUTPUT HANDLER 1 OUHNDL, 0 HLT /NASTY FAILURE OUENTR, TAD I OU7600 JMS I (200 /ENTER OUTPUT FILE 3 OUBLK, 7601 /GETS STARTING BLOCK OF HOLE OUELEN, 0 /BECOMES SIZE OF HOLE AVAILABLE JMP OEFAIL /FAILURE BUT WHY? DCA OUCCNT /CLEAR CLOSING LENGTH DCA I (OUTINH /CLEAR OUTPUT INHIBIT JMS I (OUSETP /SET UP POINTERS ISZ OOPEN /ALL WAS WELL OORETN, CDF CIF 10 JMP I OOPEN /GOOD RETURN OEFAIL, TAD I OU7600 /IF LENGTH=0 GIVE AN OPEN ERROR AND (7760 /OTHERWISE MAKE IT 0 AND RETRY SNA CLA JMP ONTERR /WAS 0 SO FAILED TAD I OU7600 AND (17 /MAKE IT 0 DCA I OU7600 JMP OUENTR /AND RETRY ONTERR, CLA CLL CML RAR JMP OORETN ONDFIL, ISZ I (OUTINH /INHIBIT OUTPUT JMP OORETN OUTDMP, 0 /DUMP OUTPUT BUFFER DCA OUCTLW /STORE CONTROL WORD CDF 10 TAD I (OUTINH /IS OUTPUT INHIBITED? SZA CLA JMP OUNOWR /YES! TAD OUCCNT /IF THIS IS FIRST WRITE, START SNA /THE SEARCH FORWARDS ON DECTAPE ISZ OUCTLW TAD OUBLK /GET STARTING BLOCK DCA OUREC /FOR THIS 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 IT WILL BE BIGGER CLL CML /THAN AVAILABLE HOLE TAD OUELEN SNL SZA CLA JMP I OUTDMP /YES SO NO ROOM FOR WRITE OUCDIF, CIF CDF 0 CDF 10 JMS I OUHNDL /DO THE WRITE OUCTLW, 0 OUBUF OUREC, 0 SKP /SOME ERROR HAPPENED OUNOWR, ISZ OUTDMP /OK, TAKE NORMAL RETURN JMP I OUTDMP /DONE WITH WRITE PTP=0020 OCLOSE, 0 /CLOSE OUTPUT FILE RDF /FETCH FIELD OF CALLING ROUTINE TAD (CDF CIF /MAKE THE RETURN FIELD INSTRUCTION DCA OCRET /READY TO RETURN CDF 10 TAD I (OUTINH /IF OUTPUT INHIBITED, CLOSE IS NO-OP SZA CLA JMP OCISZ /ITS A NO-OP JMS I (DTYPE /SEE IF ITS THE PTP AND (770 /AND IF SO DON'T END WITH ^Z TAD (-PTP SZA CLA TAD (232 /NOT THE PTP, ^ FOR EOF JMS I (OCHAR /OUTPUT IT JMP OCRET /SOMETHING WENT WRONG FILLIP, JMS I (OCHAR /FILL TO BOUNDARY WITH 0 JMP OCRET JMS I (DTYPE /IF ITS A DIRECTORY DEVICE FILL SPA CLA /WHOLE RECORD, ELSE HALF RECORD TAD (100 TAD (77 AND I (OUDWCT /REACHED BOUNDARY YET? SZA CLA JMP FILLIP /NO, CONTINUE TO FILL TAD I (OUDWCT TAD (OUCTL&3700 /IS THERE A FULL WRITE LEFT? SNA JMP NODUMP /YES BUT DON'T DO IT AS ^Z HAS GONE TAD (4000+OUFLD JMS OUTDMP /DUMP LAST BUFFER JMP OCRET NODUMP, TAD I OU7600 /GET DEVICE NUMBER JMS I (200 /AND CLOSE THE FILE 4 OU7601, 7601 /POINTER TO FILENAME OUCCNT, 0 /CLOSING FILE LENGTH GOES HERE SKP /ERROR OCISZ, ISZ OCLOSE /OK, TAKE NORMAL RETURN OCRET, CDF CIF 10 /MAKE SURE IF=DF=HERE JMP I OCLOSE /AND DEPART PAGE OUSETP, 0 /INITIALISE OUTPUT POINTERS TAD (OUCTL&3700 CIA DCA OUDWCT /DOUBLE-WORD OUTPUT COUNT TAD (OUBUF DCA OUPTR /INITIALISE WORD POINTER TAD OUJMPE DCA OUJMP /AND THE 3-WAY PACK SWITCH JMP I OUSETP OCHAR, 0 /ROUTINE TO OUTPUT 1 CHAR AND (377 /JUST 8 BITS DCA OUTEMP RDF TAD (CIF CDF 0 /GET FIELD WE WERE CALLED FROM DCA OUCRET /FOR THE RETURN TAD OUTINH /ARE WE INHIBITED? SZA CLA JMP OUCOMN /YES MEANS NO-OP OUCHAR, CDF OUFLD /SWITCH TO BUFFER DATA FIELD ISZ OUJMP /BUMP THE 3-WAY SWITCH OUJMP, HLT /BECOMES JMP ., JMP .+1 OR JMP .+2 JMP OCHAR1 JMP OCHAR2 OCHAR3, TAD OUTEMP /3RD CHAR TO GO CLL RTL /HIGH ORDER BITS GO INTO THE RTL /HIGH ORDER 4 BITS OF THE AND (7400 /FIRST OF THE 2-WORD BLOCK TAD I OUPOLD DCA I OUPOLD TAD OUTEMP /AND THE LOW ORDER 4 BITS CLL RTR /GO INTO THE HIGH ORDER BITS RTR /OF THE SECOND OF THE RAR /2-WORD BLOCK AND (7400 TAD I OUPTR DCA I OUPTR TAD OUJMPE /RESET THE 3-WAY SWITCH DCA OUJMP ISZ OUPTR /POINT TO THE NEXT BUFFER WORD ISZ OUDWCT /BUMP THE 2-WORD COUNT /AFTER 3 CHARACTERS JMP OUCOMN /WE'RE DONE TAD (OUCTL /WE'VE FILLED THE BUFFER JMS I (OUTDMP /SO OUTPUT IT JMP OUCRET /SOMETHING WENT WRONG JMS OUSETP /OK, RESET OUTPUT POINTERS JMP OUCOMN /AND WE'RE DONE OCHAR2, TAD OUPTR /2ND CHARACTER OF 2-WORD DCA OUPOLD /BLOCK SO KEEP THE POINTER ISZ OUPTR /AND POINT TO THE 2ND WORD OCHAR1, TAD OUTEMP /1ST CHARACTER OR CONTINUE 2ND DCA I OUPTR /PUT IT IN THE CORRECT SLOT OUCOMN, ISZ OCHAR /NORMAL EXIT OUCRET, HLT /BECOMES FIELD CHANGE JMP I OCHAR OUTEMP, 0 OUPOLD, 0 OUPTR, 0 OUJMPE, JMP OUJMP /3-WAY SWITCH OUDWCT, 0 OUTINH, 0 DTYPE, 0 /TO LOOK AT OP DEVICE # RDF /GET CALLING FIELD TAD (CDF CIF 0 DCA OTRTN /SO WE CAN GET BACK CDF 10 /THEN FROM FIELD 1 AND (7600 /LOOKS UP DCB WORD FROM THAT AND (17 /DEVICE TAD (DCB-1 DCA OUTEMP TAD I OUTEMP /NOW FETCH DCB ENTRY OTRTN, HLT /BECOMES FIELD CHANGE JMP I DTYPE /RETURN WITH THE DCB ENTRY IOINIT, 0 /INPUT AND OUTPUT INITIALISATION ROUTINE RDF /GET THE CALLING FIELD TAD (CDF CIF /AND MAKE A FIELD CHANGE DCA IOIRET /FOR THE RETURN CDF CIF 10 /MAKE SURE WE'RE HERE JMS I (IOPEN /INITIALISE THE INPUT POINTERS /THIS FUNCTION CANNOT FAIL JMS I (OOPEN /INITIALISE THE OUTPUT POINTERS JMP IOIRET /ERROR - TAKE THE FIRST RETURN WITH /AC=ERROR CONDITION FROM OOPEN ISZ IOINIT /OTHERWISE THE SUCCESSFUL EXIT IOIRET, HLT /BECOMES CIF CDF CALLING FIELD JMP I IOINIT $$$$$$