TITLE IMGSPL - TOPS-20 IMAGEN LASER PRINTER SPOOLER SEARCH MACSYM, MONSYM, ACTSYM SEARCH GLXMAC, QSRMAC, ORNMAC EXTERN .JBOPS .REQUIRE SYS:MACREL SALL COMMENT ^ ; SEQUENCE PACKET PROTOCOL IS USED FOR TERMINAL LINES. ; SERIAL PROTOCOL IS USED FOR TCP DEVICES. ; ; THE SPOOLER USES DEVICE "node-LSRn:" WHERE "n" IS THE UNIT NUMBER ; AND "node" IS THE DESTINATION NODE. ; ; THE /DEVICE: FIELD TO THE OPR START COMMAND IS IGNORED TO ; ALLOW EASY DESTINATION ROUTING. ; ; ACCOUNTING IS DONE WITH THE USAGE% JSYS, WITH THE QUEUE NAME ; SET TO "LSR". DISABLED WITH THE ACCTSW SWITCH. ACCOUNTING ; INFORMATION IS OBTAINED FROM THE PRINTER AND IS UNAVAILABLE ; WITH TCP PRINTERS. ; ; FOR OPEN SHOPS, WHEN THE PRINTER GOES OFF LINE, THE USER ; WHO REQUESTED THE CURRENT JOB IS NOTIFIED BY AN ON-LINE ; MESSAGE. DISABLED WITH THE OFFLSW SWITCH. ; ; FOR TCP PRINTERS, THE DESTINATION IS ASSUMED TO BE EITHER ; A PRINTER OR A REMOTE SERVER. IF IT IS A SERVER, THE ; REMSPL SWITCH MUST BE SET NON-ZERO IFF THE SERVER SENDS ; A HERALD. REMSLP SHOULD BE ZERO IF ACTUAL PRINTERS ARE ; USED. ; ; THE PUNCHED CARD QUEUE IS USED. THE SPOOLER USES THE FOLLOWING IN THE FP BLOCK OF THE EXTERNAL QUEUE ENTRY. !=======================================================! .FPLEN ! LENGTH OF FILE-PARAM AREA ! ! !-------------------------------------------------------! .FPINF !FILE FMT !PAPR FMT!SPACING ! FLAGS ! COPIES ! !-------------------------------------------------------! .FPFST ! STARTING INFORMATION ! !-------------------------------------------------------! .FPFR1 ! FORMWIDTH ! FORMLENGTH ! !-------------------------------------------------------! .FPFR2 ! FLAGS ! LEFTMARGIN ! !=======================================================! FILE FORMAT: .FPFAS==1 ASCII FORMAT .FPFAI==4 TEKTRONIX FORMAT .FPFIM==7 IMPRESS FORMAT .FPF8B==10 DAISY FORMAT PAPER FORMAT: %FPLAR==1 ARROW MODE %FPLAS==2 STRAIGHT ASCII FLAGS IN .FPINF: FP.DEL==1B18 DELETE FILE FP.SPL==1B21 SPOOLED FILE FP.REV==1B24 PAGEREVERSAL FP.COL==1B25 PAGECOLLATION FP.2PG==1B26 TWO FORMS PER PAGE FLAGS IN .FPFR2: FP.SDP==1B0 JOB IS A SCREEN DUMP FP.RUL==1B1 RULES YES FP.OTL==1B2 OUTLINES YES FP.MAN==1B3 MANUAL PAPER FEED TEXT UTILITIES THE TEXT UTILITY USED IS: TEXT (ROUTINE,) WHERE ROUTINE IS THE SUBROUTINE WHICH WILL RECEIVE THE CHARACTERS FROM THE STRING IN AC1. THIS ROUTINE MAY MESS WITH AC1-AC16 AND SHOULD RETURN WITH A POPJ P,. THE STRING MAY USE CODES OF THE FORM "%Xn" WHERE "n" IS 1..5 TO SPECIFY AC1..AC5 AND "X" IS ONE OF THE FOLLOWING: "U" USER NAME STRING FOR USER NUMBER IN AC. "F" FILE NAME FOR JFN IN AC. (DEV, DIR, NAM, TYP, GEN) "f" FILE NAME FOR JFN IN AC. (NAM, TYP, GEN) "N" DECIMAL NUMBER IN AC. "O" OCTAL NUMBER IN AC. "6" SIXBIT WORD IN AC. "T" TIME FOR UDT IN AC. "D" DATE FOR UDT IN AC. "E" ERROR STRING FOR ERROR NUMBER IN AC. "S" STRING WITH POINTER IN AC. "_" ADD CRLF AND QUIT "%" "%" A CRLF IS NOT ADDED TO THE END OF THE STRING UNLESS %_ IS USED. WTO'S WTO'S HAVE THE FORMAT: WTO (,) THE FIRST STRING MUST EXIST, THE SECOND STRING MAY. WTO, WTOJ, LOG, AND ACK ARE DEFINED. WTOR IS NOT. ^ SUBTTL DEFINITIONS ; ACS F==0 A==1 B==2 C==3 D==4 P1==10 P2==11 P3==12 P==17 DBUGSW==0 ;NON-ZERO TO ENABLE DEBUGGING INFORMATION ;SENT TO THE TERMINAL. ACCTSW==-1 ;NON-ZERO TO ENABLE SYSTEM ACCOUNTING. ;NO ACCOUNTING IS DONE FOR TCP PRINTERS. OFFLSW==-1 ;NON-ZERO TO SEND A MESSAGE TO THE JOB ;OWNER WHEN THE PRINTER GOES OFF LINE REMSPL==-1 ;NON-ZERO IF THE OTHER SIDE OF TCP CONNECTIONS ;ARE EXPECTED TO BE REMOTE SPOOLERS SENDING ;A HERALD. %IMG==1 ;MAJOR VERSION %MINOR==0 ;MINOR VERSION %EDIT==0 ;EDIT NUMBER VERSION==<%IMG>B11+<%MINOR>B17+%EDIT IF1,< IFN DBUGSW,< PRINTX Debugging code enabled > IFN ACCTSW,< PRINTX Accouting enabled > IFN OFFLSW,< PRINTX Offline user notification enabled > > .DVTCP==25 ;CAN'T FIND THIS IN MONSYM .DVCHA==26 ;THIS EITHER OBJTYP==.OTCDP ;GALAXY OBJECT TYPE MSGPAG==600 ;PAGE FOR IPCF MESSAGES MSG==MSGPAG*1K ;LOCATION OF IPCF MESSAGES STKLEN==200 ;LENGTH OF STACK PDBLEN==4 ;LENGTH OF PACKET DESCRIPTOR BLOCKS MAXPKT==177 ;MAX PACKET NUMBER PKTLEN==50 ;MAX LENGTH OF INPUT PACKET ; PARAMETERS (TIME IN MSEC) MINWIN==^D116 ;MINIMUM WINDOW SIZE ;ALLOWED FOR THE PRINTER DATSIZ==^D114 ;GOOD LENGTH FOR THE ;DATA PORTION OF A PACKET OSPCNT==40 ;NUMBER OF OUTSTANDING ;(UNACK'D) PACKETS ALLOWED TCPGLX==^D500 ;NUMBER OF CHARACTERS TO SEND TO TCP ;PRINTER BEFORE CHECKING FOR GALAXY MESSAGE TCPSLP==^D10000 ;TIME TO WAIT BEFORE RETRYING A ;FAILED OPENF FOR TCP PRINTER PIDSLP==^D60000 ;TIME TO WAIT BEFORE RESTARTING ;AFTER FAILURE TO SET UP PIDS PRVSLP==^D5000 ;TIME TO WAIT FOR PRIVATE ;QUASAR AND ORION TO START JOBSLP==^D5000 ;TIME TO WAIT FOR NEW JOB WHEN IDLE RSVSLP==^D3000 ;TIME TO WAIT FOR PRINTER TO ;RESPOND TO AN RSVP PACKET NAKSLP==^D3000 ;TIME TO WAIT BETWEEN RECEIVING A ;NAK PACKET AND GIVING A CFIBF WINSLP==^D2000 ;TIME TO WAIT FOR PRINTER BUFFER SIZE ;TOO SMALL AND CHECKING AGAIN CHRSLP==^D1000 ;MAX TIME TO WAIT FOR A MID-PACKET ;CHARACTER TO COME FROM THE PRINTER WRPSLP==^D2000 ;TIME TO WAIT AFTER WRAPAROUND DETECTED EOFSLP==^D5000 ;RSVP DELAY DURING EOF PROCESSING MAXJOB==^D100 ;MAX JOB NUMBER EXPECTED ON THE SYSTEM OFLTMX==554 ;TIME IN UDT FORMAT TO WAIT BEFORE SENDING ;ANOTHER OFF LINE NOTIFICATION. ;2 MINUTES HERE. ; PRINTER FLAGS F%HDR==1B10 ;HEADER IS BEING SENT F%EOF==1B11 ;EOF PACKET SENT F%PAB==1B12 ;TELL PRINTER TO ABORT F%JIP==1B13 ;JOB IN PROGRESS ON PRINTER F%OFL==1B14 ;PRINTER IS OFF LINE F%PGC==1B15 ;PAGE COUNT IS VALID F%TCP==1B16 ;PRINTER IS A TCP HOST F%OPN==1B17 ;TCP CONNECTION OPEN ; LOCAL FLAGS F%FAT==1B0 ;FATAL ERROR F%F1==1B1 F%F2==1B2 F%F3==1B3 ; FILE FLAGS F%IMP==1B20 ;FILE IS IMPRESS F%ASC==1B21 ;FILE IS ASCII F%DSY==1B22 ;FILE IS DIABLO F%TEK==1B23 ;FILE IS TEKTRONIX F%ARO==1B24 ;WANT ASCII ARROW MODE F%CPF==1B25 ;CAN'T PRINT FILE ; JOB FLAGS F%UP== 1B28 ;DEVICE IS STARTED F%JOB==1B29 ;JOB IS ASSIGNED F%REQ==1B30 ;REQUEUE JOB WHEN RELEASING F%SYN==1B32 ;PRINTER ABORTED F%CAN==1B33 ;JOB CANCELED F%LST==1B35 ;LAST FILE IS BEING PROCESSED ; PACKET PARAMETERS PK%BGN==176 ;PACKET BEGIN CHARACTER PK%END==12 ;PACKET END CHARACTER PK%DAT=="1" ;PACKET DATA MARK PK%EOF=="B" ;PACKET END OF FILE MARK PK%QUO==175 ;QUOTE CHARACTER QUO%BP=="A" ;QUOTE ARGUMENT FOR PK%BGN QUO%EP=="B" ;QUOTE ARGUMENT FOR PK%END QUO%QT=="C" ;QUOTE ARGUMENT FOR PK%QUO ; OFFSETS INTO PACKETS .PKLEN==1 ;PACKET LENGTH .TYPE==3 ;PACKET TYPE .PKTNM==4 ;PACKET NUMBER .WINDO==5 ;WINDOW COUNT .PKDAT==7 ;FIRST DATA BYTE .PKTCD==9 ;PACKET ACK CODE .PSTAT==^D11 ;PRINTER STATUS .LSRCT==^D12 ;PAGE COUNT STACK: BLOCK STKLEN ;STACK SPACE DUMPAC: BLOCK 20 ;SAVED AC'S FOR CRASH DUMP DMPSTR: BLOCK 50 ;ERROR STRING FOR DUMP HOSTNM: BLOCK 20 ;LOCAL HOST NAME ; STORAGE FOR GALAXY INTERFACE DEVNAM: BLOCK 20 ;DEVICE NAME DEVPTR: BLOCK 1 ;DEVICE NAME POINTER LSRJFN: BLOCK 1 ;DEVICE JFN NFILES: BLOCK 1 ;NUMBER OF FILES IN REQUEST FILCNT: BLOCK 1 ;LOCAL FILE COUNTER JOBTIM: BLOCK 1 ;TIME JOB WAS STARTED RUNTIM: BLOCK 1 ;RUN TIME WHEN STARTING A JOB JOBCNT: BLOCK 1 ;PAGE COUNT OF THE JOB JOBPRI: BLOCK 1 ;JOB PRIORITY FILPTR: BLOCK 1 ;ADDRESS OF CURRENT FILE PARAMETER BLOCK JOBINF: BLOCK 1K ;CURRENT EXTERNAL QUEUE ENTRY OBJBLK: BLOCK 3 ;OBJECT DESCRIPTOR BLOCK OBJRPT: BLOCK 1 ;REPORT OBJECT BLOCK FLAG WTOADR: BLOCK 1 ;WTO TEMP VARIABLES WTOPTR: BLOCK 1 WTOACS: BLOCK 5 ; IPCF STORAGE MYPID: BLOCK 1 ;LOCAL PID QSRPID: BLOCK 1 ;QUASAR'S PID ORNPID: BLOCK 1 ;ORION'S PID MUTBLK: EXP .MUSPQ ;MUTIL ARG BLOCK EXP -1 ;GET MAX NUMBER OF PIDS FOR THIS JOB EXP ^D15 ;SET TO 15. SNDPDB: BLOCK PDBLEN ;PDB FOR SENDS TO QUASAR AND ORION PAGRCV: EXP IP%CFR!IP%CFV ;PDB FOR PAGE RECEIVES EXP 0 EXP MYPID XWD 1K,MSGPAG SHTRCV: EXP IP%CFR ;PDB FOR SHORT RECEIVES EXP 0 EXP MYPID XWD 1K,MSG PRVPDB: EXP IP%CFS ;PDB FOR PRIVATE SYSTEM SETUP EXP MYPID EXP 0 EXP PRVMSG PRVMSG: EXP .IPCIW ;PACKET TO INFO PRVMS1: BLOCK 1 PRVMS2: BLOCK 50 HELLO: XWD HELLEN,.QOHEL ;HELLO MESSAGE TO QUASAR EXP 0 EXP 0 SIXBIT "IMGSPL" ;PROGRAM NAME XWD %%.QSR,0 ;QUASAR VERSION, FLAGS XWD 1,1 ;NUMBER OF OBJECTS, MAX NUMBER OF JOBS XWD 0,OBJTYP ;OBJECT LIST HELLEN==.-HELLO ; STORAGE FOR FILE OUTPUT ROUTINES INJFN: BLOCK 1 ;JFN OF FILE BEING PRINTED TMPJFN: BLOCK 1 ;TEMP FILE JFN FOR ERRORS FILTIM: BLOCK 1 ;TIME WHEN FILE WAS STARTED PAGCNT: BLOCK 1 ;PAGE COUNT OF FILE ARGBLK: BLOCK 5 ;CHKAC ARGUMENT BLOCK PKTTBL: BLOCK MAXPKT+1 ;PACKET ACK TABLE PACKET: BLOCK 240 ;OUTPUT PACKET BUFFER LSRPKT: BLOCK PKTLEN ;INPUT PACKET BUFFER PKTNUM: BLOCK 1 ;CURRENT PACKET NUMBER LSTACK: BLOCK 1 ;LAST ACK'D PACKET NUMBER HDRTXT: BLOCK 400 ;HEADER BUFFER HDRPTR: BLOCK 1 ;POINTER INTO HDRTXT NOTMSG: BLOCK 50 ;OFFLINE NOTIFICATION MESSAGE NOTPTR: BLOCK 1 ;OFFLINE NOTIFICATION POINTER OFLTIM: BLOCK 1 ;TIME OF LAST NOTIFICATION STSBUF: BLOCK 100 ;STATUS BUFFER STSPTR: BLOCK 1 ;STATUS BUFFER POINTER TXTBUF: BLOCK 100 ;TEXT UTILITY BUFFER SUBTTL MACROS ; SPOOLER STATUS DEFINE STATUS (STR) < JRST [ PUSH P,A MOVE A,[POINT 7,STSBUF] MOVEM A,STSPTR POP P,A TEXT (STSTXT,) CALL CHKPNT JRST .+1 ] > ; FATAL ERROR DEFINE FATAL < CALL [ TXNE F,F%FAT ;;ALREADY LOST? JRST FATAL9 ;;YES EXCH C,(P) ;;RETURN ADDRESS IN C PUSH P,B ;;SAVE THE REST PUSH P,A MOVE B,[POINT 7,STSBUF] MOVEM B,STSPTR ;;INITIALIZE POINTER HRRZS C SOS C ;;ADDRESS OF ERROR IN C MOVEI A,.FHSLF GETER ;;GET LAST ERROR HRRZS B TEXT (STSTXT,) POP P,A ;RESTORE THINGS POP P,B EXCH C,(P) JRST .FATAL ] > ; SPOOLER ERROR DEFINE SPLERR (STR) < CALL [ TXNE F,F%FAT ;;ALREADY LOST? JRST FATAL9 ;;YES EXCH C,(P) ;;RETURN ADDRESS IN C PUSH P,B ;;SAVE THIS MOVE B,[POINT 7,STSBUF] MOVEM B,STSPTR ;;INITIALIZE POINTER POP P,B HRRZS C SOS C ;;ADDRESS OF ERROR IN C TEXT (STSTXT,) POP P,C TEXT (STSTXT,< STR>) JRST .FATAL ] > ; DEBUG INFO DEFINE DBGINF (STR) < IFN DBUGSW,< CALL TEXT. JUMP DBGTXT JUMP [ASCIZ \STR'%_\] > > DBGTXT: PBOUT RET ; TEXT UTILITY DEFINE TEXT (X1,X2) < CALL TEXT. JUMP X1 JUMP [ASCIZ \X2\] > ; WRITE TO OPERATOR DEFINE WTO (X1,X2) < CALL .WTO. JUMP [ASCIZ \X1\] IFB , IFNB , > ; ACKNOWLEDGE OPERATOR DEFINE ACK (X1,X2) < CALL .ACK. JUMP [ASCIZ \X1\] IFB , IFNB , > ; WRITE TO OPERATOR - JOB MESSAGE DEFINE WTOJ (X1,X2) < CALL .WTOJ. JUMP [ASCIZ \X1\] IFB , IFNB , > ; WRITE TO OPERATOR - LOG MESSAGE DEFINE LOG (X1,X2) < CALL .LOG. JUMP [ASCIZ \X1\] IFB , IFNB , > SUBTTL INITIALIZATION ENTVEC: JRST START ;STARTING LOCATION JRST START ;REENTER LOCATION VERSION START: RESET MOVEI A,.FHSLF ;THIS PROCESS SETOB B,C ;ENABLE EVERYTHING EPCAP MOVX A,.MSIIC ;IGNORE STRUCTURE ACCOUNTING MSTR ERJMP .+1 SETZ F, ;NO FLAGS SETZM OBJRPT ;CLEAR REPORT FLAG MOVE P,[IOWD STKLEN,STACK] MOVEI A,3 ;LENGTH OF BLOCK MOVEI B,MUTBLK ;ADDRESS OF BLOCK MUTIL ;BUMP PID QUOTA JFCL ;MAYBE DOESN'T MATTER CALL GETHST ;GET LOCAL HOST NAME MOVEI C,.MUCRE ;CREATE A PID MOVEM C,MSG MOVEI C,.FHSLF ;THIS PROCESS MOVEM C,MSG+1 MOVEI A,3 ;LENGTH MOVEI B,MSG ;ADDRESS MUTIL ;GET IT JRST NOPIDS ;CAN'T MOVE C,MSG+2 ;PICK UP THE PID MOVEM C,MYPID ;STORE IT SKIPN .JBOPS ;PRIVATE SYSTEM? CALL SYSPID ;NO, GET SYSTEM PIDS SKIPE .JBOPS CALL PRVPID ;YES, GET PRIVATE PIDS MOVE A,[HELLO,,MSG] ;GET THE HELLO MESSAGE BLT A,MSG+HELLEN ;MOVE IT INTO THE MESSAGE BUFFER CALL SNDQSR ;SIGN ON ; JRST MAIN SUBTTL MAIN LOOP MAIN: CALL GETMSG ;GET A MESSAGE TXNN F,F%UP ;DEVICE STARTED? JRST MAIN ;NO, GET ANOTHER JRST MAIN2 ;YES, DO SOMETHING MAIN1: MOVEI A,JOBSLP ;WAIT SOME DISMS MAIN2: TXNN F,F%UP ;STILL STARTED? JRST MAIN ;NO, BACK TO THE TOP CALL CHKMSG ;CHECK FOR A MESSAGE TXNN F,F%JOB ;WE HAVE A JOB? JRST MAIN1 ;NO, NOTHING TO DO TXZ F,F%REQ!F%CAN ;RESET THESE CALL DOJOB ;DO THE JOB CALL DOACT ;DO THE ACCOUNTING CALL RELJOB ;RELEASE THE JOB JRST MAIN2 ;LOOP BACK SUBTTL IPCF MESSAGE RECEIVER ; GETMSG - WAITS FOR AND READS A MESSAGE FROM QUASAR OR ORION. ; CHKMSG - LOOKS FOR A MESSAE AND PROCESSES IT IF ONE IS WAITING. ; MESSAGES ARE PROCESSED AS SOON AS THEY ARE READ. CHKMSG: CALL DORPT ;REPORT OBJECT BLOCK TXZA F,F%F1 ;F1 - ON IF WE MUST READ A MESSAGE GETMSG: TXO F,F%F1 TRVAR GETMS1: MOVEI A,PDBLEN ;LENGTH OF PDB MOVEI B,PAGRCV ;TRY FOR A PAGE MOVX C,IP%CFB ;GET THE DONT-BLOCK FLAG TXNE F,F%F1 ;WANT TO WAIT? ANDCAM C,.IPCFL(B) ;YES TXNN F,F%F1 ORM C,.IPCFL(B) MRECV ;GET THE MESSAGE JRST [ CAIN A,IPCFX2 ;NO MESSAGE AVAILABLE? RET ;YES, QUIT NOW CAIE A,IPCF16 ;DATA MODES DIFFERENT? JRST NORECV ;NO, CAN'T CONTINUE MOVEI A,PDBLEN ;SAME LENGTH MOVEI B,SHTRCV ;TRY FOR A SHORT MESSAGE MOVE C,[1K,,MSG];RESET THIS MOVEM C,SHTRCV+.IPCFP MRECV ;GET IT JRST NORECV ;CON'T JRST .+1 ] ;DONTINUE MOVEM A,NXTMSG ;SAVE FLAGS FOR THE NEXT ONE MOVE A,.IPCFS(B) ;GET THE SENDER CAME A,QSRPID ;FROM QUASAR? CAMN A,ORNPID ;OR ORION? SKIPA ;YES JRST GETMS1 ;NO, GET ANOTHER ONE HRRZ A,MSG+.MSTYP ;GET THE MESSAGE TYPE MOVE D,[-TYPNUM,,TYPTAB] GETMS2: HRRZ B,(D) ;GET THE NEXT MESSAGE TYPE CAMN A,B ;A MATCH? JRST GETMS3 ;YES AOBJN D,GETMS2 ;NO, TRY AGAIN JRST GETMS1 ;NOT A MATCH, GET ANOTHER MESSAGE GETMS3: HLRZ A,(D) ;GET THE ROUTINE ADDRESS CALL (A) ;DO IT SKIPE NXTMSG ;IS THERE A MESSAGE WAITING? JRST GETMS1 ;YES, DO IT TOO RET ;DONE NORECV: SPLERR HALTF RET ; GALAXY MESSAGES WE WILL PAY ATTENTION TO TYPTAB: XWD SETUP,.QOSUP ;SETUP OR SHUTDOWN XWD NXTJOB,.QONEX ;NEXT JOB DESCRIPTION XWD ECANCL,.QOABO ;EXEC CANCEL COMMAND XWD OCANCL,.OMCAN ;OPR ABORT COMMAND XWD REQUEU,.OMREQ ;OPR REQUEUE COMMAND XWD CHKPNT,.QORCK ;QUASAR CHECKPOINT REQUEST TYPNUM==.-TYPTAB SUBTTL REPORT OBJECT DESCRIPTOR BLOCK TO TTY DORPT: SKIPN OBJRPT ;WANT THIS? RET ;NO TXNN F,F%UP ;STARTED? JRST [ TEXT (OBJTXT,) RET ] PUSH P,A ;SAVE THESE PUSH P,B MOVE A,OBJBLK+OBJ.UN ;GET THE UNIT NUMBER MOVE B,OBJBLK+OBJ.ND ;GET THE NODE NAME TEXT (OBJTXT,) POP P,B ;RESTORE THINGS POP P,A SETZM OBJRPT ;CLEAR FLAG RET ;DONE OBJTXT: PBOUT ;TEXT ROUTINE FOR OBJECT REPORT RET SUBTTL JOB ABORT REQUESTED BY USER OR OPERATOR ; JOB CANCELED BY THE USER ECANCL: TXO F,F%CAN ;SET CANCEL FLAG RET ;DONE ; JOB ABORTED BY THE OPERATOR OCANCL: TXNN F,F%JOB ;HAVE A JOB? JRST [ WTO (,) RET ] MOVE A,JOBINF+.EQJBB ;GET THE JOB NAME ACK (,) TXO F,F%CAN ;SAY CANCELED TXNE F,F%TCP ;TCP PRINTER? RET ;YES, HANDLE IN TCP CODE CALL RELJOB ;RELEASE THE JOB TXZ F,F%REQ!F%CAN!F%JOB MOVE P,[IOWD STKLEN,STACK] JRST MAIN2 ;RESTART EVERYTHING SUBTTL REQUEUE REQUESTED BY OPERATOR REQUEU: TXOE F,F%REQ ;ALREADY REQUEUED? JRST REQUE1 ;YES MOVE A,JOBINF+.EQJBB ;GET THE JOB NAME ACK (,) RET ;DONE REQUE1: MOVE A,JOBINF+.EQJBB ;GET THE JOB NAME ACK (,) RET SUBTTL NEXT JOB DESCRIPTION NXTJOB: TXOE F,F%JOB ;ALREADY HAVE A JOB? RET ;YES, IGNORE THIS ONE MOVE A,[MSG,,JOBINF] ;GET THE JOB INFORMATION HLRZ B,MSG ;GET THE MESSAGE LENGTH BLT A,JOBINF(B) ;MOVE IT INTO THE JOB INFO BLOCK RET ;DONE SUBTTL DEVICE SETUP AND SHUTDOWN SETUP: MOVE A,MSG+SUP.FL ;GET THE FLAGS TXNE A,SUFSHT ;REALLY A SETUP? JRST SHTDWN ;NO, SHUTDOWN MESSAGE MOVE A,MSG+SUP.TY ;GET THE OBJECT TYPE CAIE A,OBJTYP ;OUR OBJECT TYPE? JRST SETBAD MOVEM A,OBJBLK ;SAVE IT DMOVE A,MSG+SUP.UN ;UNIT AND NODE DMOVEM A,OBJBLK+1 CALL GETDEV ;GET THE DEVICE JRST SETBAD ;CAN'T TXO F,F%UP ;WE'RE UP WTO ;TELL ORION WE'RE OK MOVEI A,%RSUOK ;GET OK CODE SETZM MSG+RSU.CD JRST SETUP1 ;TELL QUASAR WE'RE OK SETBAD: SKIPE A ;ANY ERROR CODE RETURNED? MOVEI A,DIAGX2 ;NO, SAY NOT AVAILABLE WTO (,<%E1>) MOVEM A,MSG+RSU.CD MOVEI A,%RSUNA ;SAY NOT AVAILABLE SETUP1: MOVEM A,MSG+RSU.CO ;STORE THE RESPONSE CODE DMOVE A,OBJBLK ;GET THE OBJECT BLOCK DMOVEM A,MSG+RSU.TY ;STORE IT MOVE A,OBJBLK+2 MOVEM A,MSG+RSU.NO MOVEI A,%LOWER ;SAY LOWER CASE HRLM A,MSG+RSU.DA ;SO QUASAR WILL SCHEDULE FOR US SETZM MSG+RSU.PN ;NO PROTYPE NODE NAME MOVE A,[RSU.SZ,,.QORSU] ;GET HEADER INFORMATION MOVEM A,MSG CALL SNDQSR ;SEND IT TO QUASAR RET ;DONE SHTDWN: TXNE F,F%JOB ;HAVE A JOB? RET ;YES, DON'T SHUTDOWN MOVE A,MSG+SUP.TY ;GET THE OBJECT TYPE CAIE A,OBJTYP ;OUR OBJECT TYPE? RET ;NO, DON'T SHUTDOWN TXZN F,F%UP ;NOT UP NOW RET ;AND WEREN'T UP BEFORE TXNE F,F%TCP ;TCP DEVICE? RET ;YES, NO JFN TO CLOSE MOVE A,LSRJFN ;GET THE JFN CLOSF WTO (,<%E1: Shutting down anyway>) RET ;DONE GETDEV: MOVE A,OBJBLK+OBJ.ND ;GET THE NODE NAME MOVE B,OBJBLK+OBJ.UN ;GET THE UNIT NUMBER MOVE C,[POINT 7,DEVNAM] ;INITIALIZE POINTER MOVEM C,DEVPTR TEXT (DEVTXT,<%61-LSR%O2:>) MOVX A,GJ%SHT ;GET A JFN FOR THE PRINTER HRROI B,DEVNAM GTJFN RET ;CAN'T MOVEM A,LSRJFN ;STORE THE JFN TXO F,F%TCP ;ASSUME TCP DVCHR ;GET DEVICE CHARACTERISTICS LDB A,[POINT 9,B,17] ;GET DEVICE TYPE CAIE A,.DVTCP ;TCP? CAIN A,.DVCHA ;OR CHAOS? JRST GETDV2 ;YES, DON'T OPEN IT TXZ F,F%TCP ;SAY NOT TCP MOVE A,LSRJFN ;GET JFN MOVE B,[FLD(8,OF%BSZ)!OF%WR!OF%RD] OPENF ;OPEN IT JRST [ PUSH P,A ;CAN'T SAVE ERROR CODE MOVE A,LSRJFN ;GET THE JFN RLJFN ;RELEASE IT JFCL POP P,A ;RESTORE ERROR CODE RET ] RFMOD ;GET THE MODE WORD TXZ B,TT%DAM!TT%PGM ;BINARY MODE SFMOD STPAR MOVE B,[525252,,525252] MOVE C,B ;PASS EVERYTHING SFCOC GETDV1: AOS (P) ;GIVE SKIP RETURN RET ;DONE GETDV2: MOVE A,LSRJFN ;GET THE TCP JFN RLJFN ;RELEASE IT JFCL AOS (P) RET ; TEXT ROUTINE TO BUILD DEVICE NAME DEVTXT: IDPB A,DEVPTR ;STORE BYTE PUSH P,DEVPTR MOVEI A,0 IDPB A,DEVPTR ;ASCIZ THE STRING POP P,DEVPTR RET ;DONE SUBTTL JOB CHECKPOINT CHKPNT: PUSH P,A PUSH P,B PUSH P,C MOVE A,JOBINF+.QEITN ;GET THE TASK NAME MOVEM A,MSG+CHE.IT ;STORE IT MOVX A,CH.FCH!CH.FST ;GET SOME FLAGS MOVEM A,MSG+CHE.FL ;STORE IT HRROI A,MSG+CHE.ST ;POINT TO THE STATUS MESSAGE HRROI B,STSBUF ;AND TO THE STATUS STRING SETZ C, SOUT ;WRITE IT OUT IDPB C,A ;ASCIZ IT HRRZS A ;GET ADDRESS OF LAST WORD SUBI A,MSG-1 ;GET THE MESSAGE LENGTH HRLZM A,MSG ;STORE IT MOVEI A,.QOCHE ;GET CHECKPOINT TYPE HRRM A,MSG ;STORE IT CALL SNDQSR ;SEND IT TO QUASAR POP P,C POP P,B POP P,A RET ;DONE SUBTTL DEVICE STATUS UPDATE DEVSTS: DMOVE A,OBJBLK ;GET THE OBJECT BLOCK DMOVEM A,MSG+STU.RB MOVE A,OBJBLK+2 MOVEM A,MSG+STU.RB+2 MOVX A,%ACTIV ;ASSUME DEVICE IS ACTIVE TXNE F,F%OFL ;IS IT OFF LINE? MOVX A,%OFLNE ;YES TXNN F,F%UP ;STARTED? MOVX A,%IDLE ;NO MOVEM A,MSG+STU.CD MOVE A,[STU.SZ,,.QOSTU] ;GET THE HEADER WORD MOVEM A,MSG ;STORE IT CALL SNDQSR ;SEND IT OFF RET ;DONE SUBTTL SNDQSR/SNDORN - SEND A MESSAGE TO QUASAR OR ORION SNDQSR: SKIPA A,QSRPID ;GET QUASAR'S PID SNDORN: MOVE A,ORNPID ;GET ORION'S PID SETZM MSG+1 ;NO FLAGS SETZM MSG+2 ;NO ACK CODE MOVEM A,SNDPDB+.IPCFR ;SAVE RECEIVER PID MOVE A,MYPID ;GET OUR PID MOVEM A,SNDPDB+.IPCFS ;SAVE AS SENDER PID SETZM SNDPDB ;NO FLAGS HLLZ A,MSG ;GET LENGTH OF MESSAGE HRRI A,MSG ;AND ADDRESS MOVEM A,SNDPDB+.IPCFP ;STORE IT MOVEI A,4 ;LENGTH OF PDB MOVEI B,SNDPDB ;ADDRESS OF PDB MSEND ;SEND IT OFF SKIPA RET ;DONE CAIE A,IPCF24 ;INVALID MESSAGE SIZE? SPLERR MOVEM A,SNDPDB+.IPCFL ;TRY SENDING THE PAGE MOVE A,[1K,,MSGPAG] MOVEM A,SNDPDB+.IPCFP MOVEI A,4 ;LOAD THESE AGAIN MOVEI B,SNDPDB MSEND ;SEND IT OFF SKIPA RET ;DONE SPLERR SUBTTL GALAXY INITIALIZATION ; SYSPID - GET PIDS FOR SYSTEM QUASAR AND ORION SYSPID: MOVEI A,3 ;LENGTH OF BLOCK MOVEI B,MSG ;ADDRESS OF BLOCK MOVEI C,.MURSP ;READ FROM PID TABLE MOVEM C,MSG MOVEI C,.SPQSR ;READ QUASAR'S PID MOVEM C,MSG+1 MUTIL ;GET QUASAR'S PID JRST NOPIDS MOVE C,MSG+2 ;GET QUASARS PID MOVEM C,QSRPID ;SAVE IT MOVEI C,.SPOPR ;READ ORION'S PID MOVEM C,MSG+1 MUTIL JRST NOPIDS MOVE C,MSG+2 ;GET ORION'S PID MOVEM C,ORNPID ;SAVE IT RET ;DONE ; PRVPID - GET PIDS FOR PRIVATE QUASAR AND ORION PRVPID: HRROI A,[ASCIZ /QUASAR/] CALL PRVGET MOVEM A,QSRPID HRROI A,[ASCIZ /ORION/] CALL PRVGET MOVEM A,ORNPID RET ; PRVGET - GET PRIVATE PID FOR PROCESS. NAME POINTER IN A. PRVGET: TXZ F,F%F1 PRVGT1: PUSH P,A MOVE P3,[POINT 7,PRVMS2] GJINF MOVE B,(P) TEXT (PRVTXT,<[%U1]%S2>) SETZ A, IDPB A,P3 HRRZS P3 SUBI P3,PRVMSG-1 HRLM P3,PRVPDB+.IPCFP SETZM PRVMS1 MOVEI A,4 MOVEI B,PRVPDB MSEND JRST NOPIDS MOVEI A,4 MOVEI B,SHTRCV MRECV JRST NOPIDS POP P,C MOVE A,MSG+1 LDB B,[POINT 6,SHTRCV,29] CAIE B,76 RET MOVE P3,[POINT 7,STSBUF] TEXT (PRVTXT,<%%SPOOL: Waiting for %S3 to start%_>) SETZ A, IDPB A,P3 HRROI A,STSBUF TXON F,F%F1 PSOUT MOVEI A,PRVSLP DISMS MOVE A,C JRST PRVGT1 PRVTXT: IDPB A,P3 RET NOPIDS: TMSG <%IMGSPL: Having trouble getting pids, will retry> MOVEI A,PIDSLP ;WAIT DISMS JRST START ;START OVER SUBTTL GET LOCAL HOST NAME IFNDEF CHANM, GETHST: MOVX A,GJ%SHT!GJ%OLD ;TRY FOR THE HOST NAME FILE HRROI B,[ASCIZ /SYSTEM:HOSTNAME.TXT/] GTJFN JRST GETHS3 ;NOT FOUND, TRY CHAOS PUSH P,A ;SAVE THE JFN MOVE B,[FLD(7,OF%BSZ)!OF%RD] OPENF ;OPEN IT UP JRST [ POP P,A ;CAN'T, RESTORE JFN RLJFN ;AND RELEASE IT JFCL JRST GETHS3 ] ;AND TRY CHAOS MOVE C,[POINT 7,HOSTNM] GETHS1: BIN ;GET NEXT CHARACTER ERJMP GETHS2 ;END OF FILE CAIE B,.CHSPC ;QUIT ON A SPACE CAIN B,.CHCRT ;OR A RETURN JRST GETHS2 IDPB B,C ;STORE IT JRST GETHS1 ;LOOP BACK GETHS2: POP P,A ;RESTORE THE JFN CLOSF ;CLOSE THE FILE JFCL RET ;DONE GETHS3: SETZ A, ;TRY FOR CHAOS PRIMARY NAME HRROI B,HOSTNM CHANM ERJMP GETHS9 ;NOPE RET ;DONE GETHS9: HRROI A,HOSTNM ;NEITHER HRROI B,[ASCIZ /TOPS-20/] SETZ C, SOUT RET SUBTTL RELEASE THE CURRENT JOB RELJOB: TXZ F,F%JOB ;NO MORE JOBS TXNE F,F%REQ ;IS THIS A REQUEUE? JRST REQJOB ;YES, REQUEUE IT INSTEAD MOVE A,[REL.SZ,,.QOREL] ;GET HEADER WORD MOVEM A,MSG ;STORE IT MOVE A,JOBINF+.EQITN ;GET THE INTERNAL TASK NAME MOVEM A,MSG+REL.IT ;STORE IT SETZM MSG+REL.FL ;NO FALGS SETZM MSG+REL.TX ;NO TEXT MOVE A,[MSG+REL.TX,,MSG+REL.TX+1] BLT A,MSG+REL.SZ ;ZERO THE BLOCK CALL SNDQSR ;SEND IT OFF RET ;DONE REQJOB: MOVE A,[REQ.SZ,,.QOREQ] ;GET THE FUNCTION MOVEM A,MSG ;STORE IT MOVE A,JOBINF+.EQITN ;GET THE TASK NAME MOVEM A,MSG+REQ.IT ;STORE IT MOVX A,RQ.HBO ;HAVE OPR HOLD IT MOVEM A,MSG+REQ.FL CALL SNDORN ;SEND IT OFF RET ;DONE SUBTTL ORION MESSAGES .WTO.: PUSH P,[0] ;NO FLAGS PUSH P,[.OMWTO] ;WTO CODE JRST WTOX .ACK.: PUSH P,[WT.SJI] ;ACK FLAG PUSH P,[.OMACK] ;ACK CODE JRST WTOX .WTOJ.: PUSH P,[WT.JOB] ;JOB FLAG PUSH P,[.OMWTO] ;WTO CODE JRST WTOX .LOG.: PUSH P,[0] ;NO FLAGS PUSH P,[.OMLOG] ;LOG CODE JRST WTOX WTOX: POP P,MSG ;FILL IN THE MESSAGE TYPE POP P,MSG+.OFLAG ;FILL IN THE FLAGS MOVE P1,[1,,WTOACS] ;SAVE CALLERS ACS BLT P1,WTOACS+4 ;SAVE AC1 - AC5 MOVE A,[4,,.WTOBJ] ;START WITH THE OBJECT BLOCK MOVE B,OBJBLK DMOVEM A,MSG+5 DMOVE A,OBJBLK+1 DMOVEM A,MSG+7 MOVEI A,1 ;ONE ARGUMENT SO FAR MOVEM A,MSG+.OARGC ;SAVE IT MOVEI A,MSG+11 ;NEXT FREE ADDRESS MOVEM A,WTOADR ;SAVE IT MOVE A,(P) ;GET THE RETURN ADDRESS HRRZ A,(A) ;GET THE STRING MOVEI B,.WTTYP ;TYPE FIELD CALL WTOTXT ;FILL IT IN MOVE A,(P) ;GET RETURN ADDRESS HRRZ A,1(A) ;GET SECOND STRING MOVEI B,.WTTXT ;TEXT FIELD CALL WTOTXT ;FILL IT IN MOVE A,WTOADR ;GET NEXT FREE ADDRESS SUBI A,MSG ;GET TOTAL ADDRESS HRLM A,MSG ;SAVE IT CALL SNDORN ;SEND IT OFF MOVE P1,[WTOACS,,1] ;RESTORE CALLERS ACS BLT P1,5 RET ;DONE WTOTXT: SKIPN A ;ANY STRING? RET ;NO, DONE AOS MSG+.OARGC ;BUMP THE ARGUMENT COUNT MOVEM B,@WTOADR ;FILL IN NEXT FIELD TYPE PUSH P,WTOADR ;SAVE THIS ADDRESS AOS B,WTOADR ;BUMP FREE ADDRESS HLL B,[POINT 7,0] ;MAKE A STRING POINTER MOVEM B,WTOPTR ;SAVE IT MOVE P2,A ;GET THE STRING MOVE P1,[WTOACS,,1] ;RESTORE CALLERS ACS BLT P1,5 CALL TEXT. ;EXPAND THE TEXT JUMP WTOFIL JUMP (P2) MOVE P1,[1,,WTOACS] ;SAVE CALLERS ACS AGAIN BLT P1,WTOACS+4 SETZ A, ;ASCIZ THE STRING IDPB A,WTOPTR HRRZ B,WTOPTR ;GET LAST ADDRESS USED AOS B ;ADJUST MOVEM B,WTOADR ;SAVE IT POP P,A ;GET FIRST ADDRESS SUB B,A ;GET LENGTH OF FIELD HRLM B,(A) ;FILL IT IN RET ;DONE WTOFIL: IDPB A,WTOPTR ;SAVE THE BYTE RET ;RETURN SUBTTL JOB PROCESSING DOJOB: MOVEI A,.FHSLF ;GET OUR RUN TIME RUNTM MOVNM A,RUNTIM ;SAVE FOR LATER GTAD ;GET CURRENT DATE AND TIME MOVEM A,JOBTIM ;SAVE FOR LATER SETZM JOBCNT ;NO PAGES PRINTED YET SETZM FILCNT ;NO FILES PRINTED YET HRRZ A,JOBINF+.EQSPC ;GET NUMBER OF FILES IN REQUEST MOVEM A,NFILES ;SAVE IT HRRZ A,JOBINF+.EQLEN ;GET LENGTH OF THE EQ HEADER ADDI A,JOBINF ;GET ADDRESS OF FIRST FILE MOVEM A,FILPTR ;SAVE IT MOVE A,JOBINF+.EQOID ;GET THE USER NUMBER MOVE B,JOBINF+.EQJBB ;GET THE JOB NAME MOVE C,JOBINF+.EQRID ;GET THE REQUEST ID WTOJ (,) TXZ F,F%LST!F%OFL ;RESET THESE CALL DEVSTS ;SAY ON LINE DOJOB1: AOS A,FILCNT ;BUMP THE FILE COUNT CAMN A,NFILES ;THIS THE LAST ONE? TXO F,F%LST ;YES, FLAG IT CALL DOFILE ;PRINT THIS FILE MOVE A,FILCNT ;GET THE NUMBER OF FILES PRINTED CAML A,NFILES ;DONE THEM ALL? JRST DOJOB2 ;YES, QUIT MOVE A,FILPTR ;GET POINTER TO LAST FILE HLRZ B,.FPLEN(A) ;GET THE LENGTH OF THE FP ADD A,B ;MOVE TO THE FD HLRZ B,.FDLEN(A) ;GET LENGTH OF THE FD ADD A,B ;MOVE TO NEXT FILE MOVEM A,FILPTR JRST DOJOB1 ;LOOP BACK DOJOB2: SETZM FILCNT ;START OVER HRRZ A,JOBINF+.EQSPC ;GET NUMBER OF FILES IN REQUEST MOVEM A,NFILES ;SAVE IT HRRZ A,JOBINF+.EQLEN ;GET LENGTH OF THE EQ HEADER ADDI A,JOBINF ;GET ADDRESS OF FIRST FILE MOVEM A,FILPTR ;SAVE IT DOJOB3: AOS FILCNT ;BUMP THE FILE COUNT CALL DELFIL ;CHECK FOR DELETION MOVE A,FILCNT ;GET THE NUMBER OF FILES PRINTED CAML A,NFILES ;DONE THEM ALL? JRST DOJOB4 ;YES, QUIT MOVE A,FILPTR ;GET POINTER TO LAST FILE HLRZ B,.FPLEN(A) ;GET THE LENGTH OF THE FP ADD A,B ;MOVE TO THE FD HLRZ B,.FDLEN(A) ;GET LENGTH OF THE FD ADD A,B ;MOVE TO NEXT FILE MOVEM A,FILPTR JRST DOJOB3 ;LOOP BACK DOJOB4: RET ;DONE DELFIL: MOVE D,FILPTR ;POINT TO THE FILE PARAMETER BLOCK MOVE A,.FPFR2(D) ;GET FLAGS TXNE A,FP.SDP ;SCREEN DUMP? JRST DELFL0 ;YES, DELETE IT MOVE A,.FPINF(D) ;GET PARAMETERS TXNN A,FP.SPL!FP.DEL ;/DELETE OR SPOOLED? RET ;NO, DON'T DELETE IT DELFL0: HLRZ B,.FPLEN(D) ;GET LENGTH OF THE FP ADD B,D ;MOVE TO THE FD AOS B ;MOVE TO THE FILE NAME MOVE C,B ;SAVE IT HERE TOO HRROS B ;MAKE IT A POINTER MOVX A,GJ%SHT!GJ%OLD ;GET A JFN AGAIN GTJFN JRST [ LOG (,<%S3: %E1>) RET ] ;QUIT MOVEM A,INJFN ;SAVE THE JFN MOVE D,FILPTR ;POINT TO THE FILE PARAMETER BLOCK MOVE A,.FPFR2(D) ;GET FLAGS TXNE A,FP.SDP ;SCREEN DUMP? JRST DELFL1 ;YES, NO ACCESS CHECK MOVE A,.FPINF(D) ;GET PARAMETERS TXNE A,FP.SPL ;SPOOLED? JRST DELFL1 ;YES, ALWAYS DELETE CALL DLACES ;ACCESS ALLOWED? JRST [ LOG (,<%S3: CHKAC said not to>) JRST DELFL2 ] ;NO LOG (,<%S3>) DELFL1: MOVE A,INJFN ;GET JFN TXO A,DF%EXP ;EXPUNGE ALSO DELF JRST [ LOG (,<%S3: %E1>) JRST DELFL2 ] RET ;DONE DELFL2: MOVE A,INJFN ;GET THE JFN RLJFN ;RELEASE IT JFCL RET ;DONE SUBTTL ACCOUNTING DOACT: MOVE A,JOBINF+.EQOID ;GET THE USER NUMBER MOVE B,JOBINF+.EQJBB ;GET THE JOB NAME MOVE C,JOBINF+.EQRID ;GET THE REQUEST ID TXNE F,F%TCP ;REMOTE JOB? JRST [ WTOJ (,) RET ] MOVE D,JOBCNT ;GET THE PAGE COUNT CAIE D,1 WTOJ (,) CAIN D,1 WTOJ (,) DOACT1: MOVX A,.FHSLF ;THIS FORK RUNTM ;GET OUR RUNTIME ADDM A,RUNTIM ;GET TIME USED LDB A,[POINT 6,JOBINF+.EQSEQ,35] MOVEM A,JOBPRI ;STORE JOB PRIORITY MOVX A,.USENT ;WRITE AN ENTRY MOVEI B,ACTLST ;POINT TO THE LIST IFN ACCTSW,< USAGE ;DO IT ERJMP ACTERR ;RATS >;IFN ACCTSW RET ;DONE ACTERR: SETO A, ;TELL ORION WHAT WENT WRONG WTO (,) RET ;DONE ACTLST: USENT. (.UTOUT,1,1,0) USTAD. (-1) ;CURRENT DATE/TIME USPNM. (,US%IMM) ;PROGRAM NAME USPVR. (%IMG,US%IMM) ;PROGRAM VERSION USAMV. (-1) ;ACCOUNTING MODULE VERSION USNOD. (JOBINF+.EQROB+.ROBND) ;NODE NAME USSRT. (RUNTIM) ;RUN TIME USSDR. (0,US%IMM) ;DISK READS USSDW. (0,US%IMM) ;DISK WRITES USJNM. (JOBINF+.EQJOB) ;JOB NAME USQNM. (,US%IMM) ;QUEUE NAME USSDV. (DEVNAM) ;DEVICE NAME USSSN. (JOBINF+.EQRID) ;JOB SEQUENCE NUMBER USSUN. (PAGCNT) ;TOTAL PAGES PRINTED USSNF. (NFILES) ;TOTAL FILES PROCESSED USCRT. (JOBINF+.EQAFT) ;CREATION DATE/TIME OF REQUEST USSCD. (JOBTIM) ;SCHEDULED DATE/TIME USFRM. (,US%IMM) ;FORMS TYPE USDSP. (,US%IMM) ;DISPOSITION USPRI. (JOBPRI) ;JOB PRIORITY USJNO. (-1) ;JOB NUMBER USTRM. (-1) ;TERMINAL DESIGNATOR USLNO. (-1) ;TTY LINE NUMBER USTXT. (<-1,,[ASCIZ / /]>) ;SYSTEM TEXT USNM2. () ;USER NAME USACT. () ;ACCOUNT STRING POINTER 0 ;END OF LIST SUBTTL FILE OUTPUT - MAIN LOOP DOFILE: GTAD ;GET THE TIME MOVEM A,FILTIM ;STORE IT STATUS CALL OPNFIL ;OPEN THE OUTPUT FILES CALL SETFIL ;SET FILE PARAMETERS CALL FIXHDR ;BUILD A HEADER COMMAND CALL FIXFIL ;FIX THE FILE DBGINF TXNE F,F%TCP ;TCP PRINTER? JRST TCPOUT ;YES, DO DIFERENT CALL CLRTBL ;CLEAR THE PACKET TABLE SETOM LSTACK ;NOTHING ACK'D YET TXZ F,F%SYN ;NO SYNC YET CALL DOSYNC ;SYNC WITH THE PRINTER DBGINF MOVE A,FILTIM ;GET START TIME STATUS TXZ F,F%EOF!F%HDR!F%PAB!F%JIP SETZM PKTNUM ;ZERO THE PACKET NUMBER CALL SNDHDR ;SEND THE HEADER DBGINF
DOFIL1: TXNE F,F%SYN!F%CAN JRST DOFIL3 ;SOMETHING'S WRONG CALL CHKLSR ;CHECK THE PRINTER CALL GETPKT ;GET A PACKET JRST [ MOVEI A,WRPSLP ;WRAP AROUND DISMS DBGINF CALL RSVP ;GOOSE A REPLY MOVEI A,RSVSLP DISMS JRST DOFIL1 ] JRST DOFIL2 ;END OF FILE CALL SNDPKT ;SEND IT OUT JRST DOFIL1 ;LOOP BACK DOFIL2: CALL RSVP ;SEND AN RSVP MOVEI A,RSVSLP DISMS PUSH P,PKTNUM ;SAVE THE PACKET NUMBER CALL CHKLSR ;CHECK THE PRINTER POP P,A ;GET OLD PACKET NUMBER CAME A,PKTNUM ;ANY REDO'S? JRST DOFIL1 ;YES SOS A ;LOOK AT LAST PACKET SENT ANDI A,MAXPKT SKIPL PKTTBL(A) ;LAST ONE ACK'D? JRST [ MOVEI A,EOFSLP ;NO, WAIT SOME DISMS JRST DOFIL2 ] ;TRY AGAIN MOVE A,FILTIM STATUS DBGINF CALL DOEOF ;SEND END OF FILE PACKET MOVE A,INJFN ;GET THE JFN CLOSF ;CLOSE IT JFCL CALL GETCNT ;GET THE PAGE COUNT RET ;DONE DOFIL3: SETO A, ;USE CURRENT TIME TXNE F,F%SYN ;PRINTER ABORT? STATUS TXNE F,F%CAN ;CANCELED? STATUS TXO F,F%PAB ;SET ABORT FLAG CALL RSVP ;TELL PRINTER TO ABORT MOVEI A,RSVSLP DISMS TXZ F,F%PAB ;RESET FLAG CALL DOEOF ;SEND EOF MOVE A,INJFN ;GET INPUT FILE CLOSF ;CLOSE IT JFCL TXNE F,F%CAN ;CANCELED BY USER? CALL GETCNT ;YES, DO ACCOUNTING RET ;DONE SUBTTL FILE OUTPUT - TCP PRINTER TCPOUT: STATUS TCPOT1: CALL CHKMSG ;CHECK FOR GALAXY MESSAGE TXNE F,F%CAN ;STILL GOING? JRST TCPOT8 ;NO MOVX A,GJ%SHT ;GET THE PRINTER HRROI B,DEVNAM GTJFN FATAL MOVEM A,LSRJFN ;SAVE PRINTER JFN MOVE B,[FLD(8,OF%BSZ)!OF%WR!OF%RD] OPENF ;OPEN THE CONNECTION JRST [ PUSH P,A MOVE A,[POINT 7,STSBUF] MOVEM A,STSPTR POP P,A TEXT (STSTXT,) CALL CHKPNT MOVE A,LSRJFN ;CAN'T, GET JFN BACK RLJFN ;RELEASE IT JFCL MOVEI A,TCPSLP DISMS ;WAIT A WHILE JRST TCPOT1 ] ;AND TRY AGAIN TXO F,F%OPN ;SAY CONNECTION OPEN IFN REMSPL,< MOVE A,OBJBLK+OBJ.ND ;GET THE NODE NAME CAMN A,[SIXBIT /LOCAL/] ;LOCAL NODE? JRST TCPOTX ;YES, NO BACKTALK STATUS MOVE D,[POINT 7,PACKET] ;USE THE PACKET BUFFER FOR A WHILE TCPOT0: MOVE A,LSRJFN ;LISTEN TO THE CONNECTION BIN ;GET NEXT BYTE CAIE B,.CHCRT ;RETURN? CAIN B,.CHLFD ;OR LINE FEED? SKIPA ;YES, DON'T STORE IT IDPB B,D ;STORE CHARACTER SIBE ;ANY MORE JRST TCPOT0 ;YES SETZ B, IDPB B,D HRROI A,PACKET LOG (,<%S1>) >;IFN REMSPL TCPOTX: MOVE A,FILTIM STATUS TXZ F,F%EOF!F%HDR!F%PAB!F%JIP CALL CHKMSG ;CHECK FOR GALAXY MESSAGE TXNE F,F%CAN ;STILL GOING? JRST TCPOT8 ;NO MOVE A,LSRJFN ;GET THE PRINTER MOVE B,[POINT 7,HDRTXT] ;POINT TO THE HEADER IBP B ;SKIP TO GOOD STUFF SETZ C, SOUT ;SEND IT ERJMP TCPOT8 TCPOT2: MOVEI C,TCPGLX ;CHECK GALAXY EVERY NOW AND THEN CALL CHKMSG TXNE F,F%CAN ;STILL GOING? JRST TCPOT8 ;NO TCPOT3: MOVE A,INJFN ;GET NEXT INPUT BYTE BIN ERJMP TCPOT4 ;END OF FILE TXNE F,F%ARO ;ARROW MODE? CALL CHKARO ;YES, CHECK CHARACTER MOVE A,LSRJFN ;SEND IT TO THE PRINTER BOUT ERJMP TCPOT8 SOSLE C JRST TCPOT3 ;LOOP BACK JRST TCPOT2 ;CHECK GALAXY TCPOT4: MOVE A,LSRJFN ;END OF FILE HRROI B,[ASCIZ //] SETZ C, SOUTR ;FLUSH EVERYTHING STATUS MOVE A,LSRJFN CLOSF ;CLOSE THE CONNECTION JFCL MOVE A,INJFN ;CLOSE THE INPUT FILE CLOSF JFCL TXZ F,F%OPN ;CONNECTION NOT OPENED RET ;DONE TCPOT8: SETO A, ;CURRENT TIME TXNN F,F%CAN ;ERROR? STATUS TXNE F,F%CAN ;CANCELED? STATUS MOVE A,LSRJFN ;GET THE JFN TXO A,CZ%ABT ;KEEP THE JFN AND ABORT THE CONNECTION TXZE F,F%OPN ;WAS CONNECTION OPEN? CLOSF ;YES, CLOSE IT JFCL RET SUBTTL FILE OUTPUT - PRINTER STATUS ; CHKLSR - CHECKS THE PRINTERS PROGRESS CHKLSR: CALL CHKMSG ;CHECK FOR A GALAXY MESSAGE CALL CHKPKT ;ANY PACKETS WAITING? RET ;NO, ASSUME EVERYTHING OK CALL RCVPKT ;GET THE PACKET JRST CHKLSR ;CAN'T DBGINF DMOVE A,LSRPKT+.TYPE ;GET THE PACKET TYPE CAIE A,"S" ;STATUS PACKET? JRST CHKLSR ;NO, TRY AGAIN CAIN B,"i" ;INFO? JRST LSRINF ;YES CAIN B,"n" ;NAK? JRST LSRNAK ;YES CAIN B,"s" ;SYNC? TXO F,F%SYN ;YES, MARK IT CAIN B,"#" ;ACCOUNTING RESPONSE? JRST LSRPGC ;YES JRST CHKLSR ;NONE OF THESE, TRY FOR ANOTHER LSRNAK: MOVEI A,LSRPKT+.PKTCD ;GET THE PACKET CODE CALL GETHEX ;GET THE NUMBER CALL RELPKT ;RELEASE OK'D PACKETS AOS A ;BUMP TO BAD ONE ANDI A,MAXPKT ;TRIM IT DOWN CALL REDOPK ;RESEND THE PACKET MOVEI A,NAKSLP ;WAIT A WHILE DISMS MOVE A,LSRJFN ;GET THE JFN CFIBF ;CLEAR ALL NAK PACKETS JRST CHKLSR ;TRY AGAIN LSRINF: MOVEI A,LSRPKT+.PKTCD ;GET THE PACKET CODE CALL GETHEX ;GET THE NUMBER CALL RELPKT ;RELEASE OK'D PACKETS LSRWND: MOVEI A,LSRPKT+.WINDO ;GET THE WINDOW SIZE CALL GETHEX ;TOP HALF LSH A,8 ;MOVE IT OVER MOVE B,A ;SAVE IT MOVEI A,LSRPKT+.WINDO+2 ;BOTTOM HALF CALL GETHEX OR A,B ;GET WINDOW SIZE CAIGE A,MINWIN ;ENOUGH FOR ANOTHER PACKET? JRST LSRWAT ;NO, WAIT SOME MOVE A,LSRPKT+.PSTAT ;GET STATUS CODE SUBI A," " ;SUBTRACT THE SPACE TXNE A,17 ;PRINTER OK? CALL OFFLIN ;NO, SAY OFFLINE TXNN A,17 ;ON LINE? CALL ONLINE ;YES, SAY SO TXZ F,F%JIP ;SAY NO JOB IN PROGRESS TXNE A,1B30!1B31 ;JOB IN PROGRESS? TXO F,F%JIP ;YES JRST CHKLSR ;CHECK AGAIN LSRWAT: CALL RSVP ;SEND AN RSVP PACKET MOVEI A,WINSLP ;WAIT A WHILE DISMS JRST CHKLSR ;CHECK AGAIN LSRPGC: MOVEI A,LSRPKT+.LSRCT ;POINT TO THE NUMBER CALL GETHEX ;GET TOP HALF MOVE B,A ;SAVE IT MOVEI A,LSRPKT+.LSRCT+2 CALL GETHEX ;GET BOTTOM HALF LSH B,8 ;MOVE THINGS OVER OR A,B ;GET WHOLE NUMBER MOVEM A,PAGCNT ;SAVE THE COUNT TXO F,F%PGC ;SAY NUMBER IS VALID JRST CHKLSR ;TRY FOR ANOTHER ; CHKPKT - CHECKS FOR A PACKET FROM THE PRINTER. ; RETURNS +1 IF ONE IS THERE, + 2 IF NOT. CHKPKT: MOVE A,LSRJFN ;GET PRINTER JFN SIBE ;INPUT BUFFER EMPTY? AOS (P) ;NO, GIVE SKIP RETURN RET ;DONE ; RCVPKT - RECEIVES A PACKET FROM THE PRINTER. ; RETURNS +2 IF GOOD PACKET IS READ. RCVPKT: MOVE D,[-PKTLEN,,LSRPKT] RCVPK1: MOVE A,LSRJFN ;GET THE PRINTER SIBE ;ANYTHING THERE? SKIPA ;YES JRST [ MOVEI A,CHRSLP ;NO, WAIT DISMS MOVE A,LSRJFN SIBE ;STILL EMPTY? JRST .+1 ;NO RET ] ;YES BIN ;GET NEXT BYTE CAIN B,PK%BGN ;PACKET BEGIN CHARACTER? MOVE D,[-PKTLEN,,LSRPKT] ;YES, RESET COUNTER MOVEM B,(D) ;SAVE BYTE CAIN B,PK%END ;END OF PACKET? JRST RCVPK2 ;YES AOBJN D,RCVPK1 ;NO, TRY AGAIN RET ;TOO LONG, QUIT RCVPK2: SETZM 1(D) ;END THE PACKET MOVE A,LSRPKT ;GET FIRST CHARACTER CAIE A,PK%BGN ;LOOK GOOD? RET ;NO MOVE A,LSRPKT+.PKLEN ;GET LENGTH CAIE A,"1" ;RIGHT? RET ;NO MOVE A,LSRPKT+.PKLEN+1 ;LOW DIGIT OF LENGTH CAIE A,"1" ;"1" FOR STATUS CAIN A,"5" ;"5" FOR ACCOUNTING SKIPA ;OK RET ;BAD MOVE A,LSRPKT+.TYPE ;PACKET TYPE CAIE A,"S" ;STATUS? RET ;NO MOVE B,[-4,,LSRPKT+.WINDO] RCVPK3: MOVE A,(B) ;CHECK WINDOW SIZE CALL ISNUM RET AOBJN B,RCVPK3 MOVE A,LSRPKT+.PKTCD ;ACK CODE CAIL A,"0" ;0..7 CAILE A,"7" RET MOVE A,LSRPKT+.PKTCD+1 CALL ISNUM RET MOVE B,[-4,,LSRPKT+.LSRCT] MOVE A,LSRPKT+.TYPE+1 ;GET TYPE CAIN A,"#" ;ACCOUNTING RESPONSE? ADDI B,4 ;YES, SKIP COUNT RCVPK4: MOVE A,(B) CALL ISNUM RET AOBJN B,RCVPK4 MOVE A,(B) ;CHECK FOR END CAIE A,PK%END RET AOS(P) ;LOOKS GOOD RET ; ISNUM - RETURNS +2 IF THE CHARACTER IN A IS A HEX DIGIT ISNUM: CAIL A,"0" CAILE A,"9" SKIPA ;NOT A DIGIT JRST ISNUM1 CAIL A,"A" CAILE A,"F" RET ;NOT A LETTER ISNUM1: AOS (P) RET ; OFFLIN - PROCESS AN OFF LINE SIGNAL FROM THE PRINTER OFFLIN: PUSH P,A TXOE F,F%OFL ;ALREADY OFF LINE? JRST OFFLN1 ;YES CALL DEVSTS ;TELL QUASAR WTO ;TELL ORION GTAD ;GET CURRENT TIME MOVEM A,OFLTIM ;SAVE IT CALL OFLNOT ;NOTIFY USER DBGINF < Printer is off line> POP P,A RET ;DONE OFFLN1: GTAD ;GET CURRENT TIME SUB A,OFLTIM ;GET TIME SINCE LAST NOTIFICATION CAIG A,OFLTMX ;BEEN TOO LONG? JRST OFFLN2 ;NO ADDM A,OFLTIM ;SAVE NEW TIME CALL OFLNOT ;NOTIFY AGAIN OFFLN2: POP P,A RET ; ONLINE - PROCESS AN ON LINE SIGNAL FROM THE PRINTER ONLINE: TXZN F,F%OFL ;OFF LINE BEFORE? RET ;NO PUSH P,A CALL DEVSTS ;TELL QUASAR POP P,A DBGINF < Printer is on line> RET ;DONE ; DOSYNC - SEND A SYNC PACKET TO THE PRINTER. ; RETURNS AFTER THE PRINTER HAS RETURNED A SYNC. DOSYNC: STATUS DOSYN1: MOVE A,[SYNCPK,,PACKET] ;GET THE SYNC PACKET BLT A,PACKET+SYNCLN ;PUT IN BUFFER MOVEI A,SYNCLN ;GET THE LENGTH CALL SNDPKT ;SEND IT OFF MOVEI A,RSVSLP ;WAIT DISMS CALL CHKLSR ;CHECK THE PRINTER TXZN F,F%SYN ;RECEIVE SYNC? JRST DOSYN1 ;NO STATUS RET ;DONE SYNCPK: EXP PK%BGN ;BEGIN PACKET EXP "1","1" ;LENGTH EXP "S" ;STATUS EXP "s" ;SYNC REQUEST EXP "F","F","F","F" ;WINDOW SIZE EXP "F","F" ;PACKET CODE EXP " " ;ERROR TYPE EXP 0,0,0,0 ;CHECKSUM EXP PK%END ;END OF PACKET SYNCLN==.-SYNCPK ; RSVP - SEND AN RSVP PACKET. RSVP: DBGINF MOVE A,[RSVPPK,,PACKET] ;GET THE RSVP PACKET BLT A,PACKET+RSVPLN ;PUT IN BUFFER MOVEI A,0 ;GET ABORT CODE TXNE F,F%PAB ;NEED TO TELL PRINTER TO ABORT? MOVEM A,PACKET+.PSTAT ;YES MOVEI A,RSVPLN ;GET THE LENGTH CALL SNDPKT ;SEND IT OFF RET ;DONE RSVPPK: EXP PK%BGN ;BEGIN PACKET EXP "1","1" ;LENGTH EXP "S" ;STATUS EXP "r" ;SYNC REQUEST EXP "F","F","F","F" ;WINDOW SIZE EXP "F","F" ;PACKET CODE EXP " " ;ERROR TYPE EXP 0,0,0,0 ;CHECKSUM EXP PK%END ;END OF PACKET RSVPLN==.-RSVPPK SUBTTL FILE OUTPUT - PACKET SENDING ; SNDPKT - SENDS A PACKET TO THE PRINTER. ; PACKET IS IN THE PACKET BUFFER, LENGTH IN A. SNDPKT: MOVE B,PKTNUM DBGINF CALL CHKSUM ;COMPUTE THE CHECKSUM MOVN C,A ;GET THE LENGTH IN C MOVE A,LSRJFN ;GET PRINTER JFN MOVE B,[POINT 36,PACKET] SOUT ;WRITE IT OUT RET ;DONE ; CHKSUM - COMPUTES CHECKSUM FOR THE PACKET BUFFER. ; LENGTH OF PACKET IN A. CHKSUM: PUSH P,A ;SAVE LENGTH SUBI A,5 ;CHOP OFF CHECKSUM BYTES AND END CHAR MOVN D,A ;NEGATE INTO D HRLZS D ;PUT IN LEFT HALF HRRI D,PACKET ;GET ADDRESS OF BUFFER SETZ B, ;B IS THE CHECKSUM CHKSM1: LSH B,1 ;LEFT SHIFT ONE TXZE B,1B19 ;OVERFLOW? TXO B,1B35 ;YES, ROTATE IT ADD B,(D) ;ADD IN THIS BYTE ANDI B,177777 ;TRIM DOWN TO 16 BITS AOBJN D,CHKSM1 ;LOOP BACK LSH B,1 ;ROTATE ONCE MORE TXZE B,1B19 ;OVERFLOW? TXO B,1B35 ;YES, ROTATE IT ADDI B,PK%END ;ACCOUNT FOR END CHARACTER ANDI B,177777 ;TRIM IT DOWN MOVE A,D ;GET ADDRESS OF WHERE TO PUT IT HLL A,[POINT 36,0] ;MAKE IT A POINTER MOVE C,[NO%LFL!NO%ZRO!FLD(4,NO%COL)!FLD(^D16,NO%RDX)] NOUT ;ADD IT TO THE PACKET IN HEX FATAL ;CAN'T MOVEI B,PK%END IDPB B,A ;NOUT ZEROED THE END CHAR POP P,A ;GET LENGTH BACK RET ;DONE ; GETHEX - READS TWO BYTE ASCII HEX NUMBER ; A POINTS TO TEXT, NUMBER RETURNED IN A. GETHEX: PUSH P,B ;SAVE THIS MOVE B,(A) ;GET THE FIRST CHARACTER CAIL B,"A" ;LETTER? SUBI B,7 ;YES, ADJUST SUBI B,"0" ;CONVERT TO BINARY LSH B,4 ;MOVE IT OVER PUSH P,B ;SAVE IT MOVE B,1(A) ;GET SECOND CHARACTER CAIL B,"A" ;LETTER? SUBI B,7 ;YES, ADJUST SUBI B,"0" ;CONVERT TO BINARY POP P,A ;GET FIRST PART OR A,B ;GET FULL BYTE POP P,B RET ;DONE SUBTTL FILE OUTPUT - FINISH UP ; DOEOF - SENDS EOF TO THE PRINTER AND WAITS FOR IT ; TO FINISH THE JOB. DOEOF: TRVAR TXO F,F%EOF ;SAY SENDING EOF CALL SNDEOF ;SEND THE EOF PACKET MOVEI A,^D10 ;10 TIMES MAX THROUGH FIRST LOOP MOVEM A,EOFCTR DOEOF1: CALL RSVP ;SEND AN RSVP MOVEI A,RSVSLP DISMS CALL CHKLSR ;CHECK THE PRINTER TXNE F,F%JIP ;JOB IN PROGRESS? JRST DOEOF2 ;YES MOVEI A,EOFSLP ;NOT PRINTING YET DISMS SOSLE EOFCTR ;BUMP COUNTER JRST DOEOF1 ;TRY AGAIN WTO (,) DOEOF2: CALL CHKMSG ;CHECK FOR ABORT CALL RSVP ;SEND AN RSVP MOVEI A,RSVSLP DISMS CALL CHKLSR ;CHECK THE PRINTER TXNN F,F%JIP ;STILL PRINTING? JRST DOEOF3 ;NO MOVEI A,EOFSLP ;WAIT A WHILE DISMS JRST DOEOF2 ;TRY AGAIN DOEOF3: TXZ F,F%EOF ;NO EOF IN PROGRESS NOW RET ;ALL DONE ; SNDEOF - SENDS AN EOF PACKET SNDEOF: MOVE A,[EOFPKT,,PACKET] ;GET THE EOF PACKET BLT A,PACKET+EOFLEN ;PUT IN BUFFER MOVE B,PKTNUM ;GET PACKET NUMBER MOVE A,[POINT 36,PACKET+.PKTNM] MOVE C,[NO%LFL!NO%ZRO!FLD(2,NO%COL)!FLD(^D16,NO%RDX)] NOUT ;ADD IT TO THE PACKET IN HEX FATAL ;CAN'T MOVEI B,PK%EOF ;NOUT CLEARED THIS IDPB B,A MOVEI A,EOFLEN ;GET THE LENGTH CALL SNDPKT ;SEND IT OFF DBGINF RET ;DONE EOFPKT: EXP PK%BGN ;BEGIN PACKET EXP "0","C" ;LENGTH EXP "D" ;DATA EXP 0,0 ;PACKET NUMBER EXP PK%EOF ;END OF FILE MARK EXP 0,0,0,0 ;CHECKSUM EXP PK%END ;END OF PACKET EOFLEN==.-EOFPKT SUBTTL FILE OUTPUT - PACKET MANAGEMENT ; RELPKT - RELEASE ACK'D PACKETS. ; HIGHEST ACK'D PACKET NUMBER IN A. RELPKT: DBGINF CAMN A,LSTACK ;SAME AS LAST TIME? RET ;YES SKIPGE PKTTBL(A) ;ALREADY ACK'D? RET ;YES EXCH A,LSTACK ;GET LAST ACKED ONE AOS A ;MOVE TO NEXT ONE ANDI A,MAXPKT ;TRIM IT DOWN RELPK1: SETOM PKTTBL(A) ;ACK THIS ONE CAMN A,LSTACK ;REACHED THE END? JRST RELPK2 ;YES AOS A ;MOVE TO NEXT ONE ANDI A,MAXPKT ;TRIM IT DOWN JRST RELPK1 ;NO, DO IT RELPK2: RET ;DONE ; CLRTBL - CLEARS THE PACKET TABLE CLRTBL: DBGINF SETOM PKTTBL MOVE A,[PKTTBL,,PKTTBL+1] BLT A,PKTTBL+MAXPKT RET ; GETPKT - GETS THE NEXT PACKET TO BE SENT ; RETURNS +3 WITH LENGTH IN A ; +2 IF AT EOF ; +1 IF WRAPAROUND WAIT IS NEEDED ; ; GETPKX - GETS THE NEXT PACKET TO BE SENT WITHOUT ; CHECKING FOR EOF OR WRAPAROUND, RETURNS +1 GETPKT: MOVE B,PKTNUM ;GET LAST PACKET NUMBER AOS B ;BUMP TO NEXT ONE HRLI B,- GETPK0: AND B,[-1,,MAXPKT] ;TRIM PACKET NUMBER SKIPL PKTTBL(B) ;THIS ONE FREE RET ;NO, QUIT AOBJN B,GETPK0 ;LOOP BACK AOS (P) ;SKIP AT LEAST ONE ON RETURN TXNE F,F%HDR ;SENDING THE HEADER? JRST [ LDB A,HDRPTR ;YES, GET LAST BYTE SEEN JUMPN A,GETPK1 ;SKIP IF NOT AT END RET ] ;END OF HEADER MOVE A,INJFN ;GET THE INPUT FILE GTSTS ;GET FILE STATUS TXNE B,GS%EOF ;AT END OF FILE? RET ;YES GETPK1: AOS (P) ;RETURN +3 CALL GETPKX ;GET THE PACKET AOS B,PKTNUM ;BUMP THE PACKET NUMBER ANDI B,MAXPKT ;TRIM IT DOWN MOVEM B,PKTNUM RET ;DONE GETPKX: MOVE A,[DATINI,,PACKET] ;GET DATA PACKET INITIALIZATION BLT A,PACKET+DATLEN ;MOVE INTO THE PACKET BUFFER MOVE A,[POINT 36,PACKET+.PKTNM] MOVE B,PKTNUM ;GET THE NUMBER MOVE C,[NO%LFL!NO%ZRO!FLD(2,NO%COL)!FLD(^D16,NO%RDX)] NOUT ;ADD IT TO THE PACKET IN HEX FATAL ;CAN'T MOVEI C,PK%DAT ;NOUT CLEARED THIS IDPB C,A MOVE C,B ;SAVE PACKET NUMBER MOVE A,INJFN ;GET THE INPUT FILE RFPTR ;GET THE POINTER FATAL TXNE F,F%HDR ;IS THIS THE HEADER? MOVE B,HDRPTR ;YES MOVEM B,PKTTBL(C) ;MARK PACKET DBGINF CALL FILPKT ;FILL IN THE DATA PUSH P,A ;SAVE LENGTH MOVE B,A ;AND PUT IT HERE MOVE A,[POINT 36,PACKET+.PKLEN] MOVE C,[NO%LFL!NO%ZRO!FLD(2,NO%COL)!FLD(^D16,NO%RDX)] NOUT ;ADD LENGTH FATAL ;CAN'T MOVEI B,"D" ;NOUT CLEARED THIS IDPB B,A POP P,A ;GET LENGTH BACK MOVEI B,PK%END ;GET END OF PACKET CHARACTER MOVEM B,PACKET-1(A) ;FILL IT IN RET ;DONE ; DATA PACKET HEADER DATINI: EXP PK%BGN ;BEGIN PACKET EXP 0,0 ;LENGTH EXP "D" ;DATA PACKET EXP PK%DAT ;NOT EOF DATLEN==.-DATINI ;LENGTH ; FILPKT - FILLS IN A DATA PACKET ; OVERALL LENGTH OF PACKET IS RETURNED IN A FILPKT: MOVE D,[-DATSIZ,,0] FILPK1: TXNE F,F%HDR ;SENDING HEADER? JRST [ ILDB B,HDRPTR ;YES, GET NEXT BYTE JUMPE B, FILPK3 ;END OF HEADER JRST FILPK2 ] MOVE A,INJFN ;GET THE INPUT FILE BIN ;GET NEXT CHARACTER ERJMP FILPK3 ;END OF FILE FILPK2: MOVEI C,PK%QUO ;GET A QUOTE CHARACTER CAIN B,PK%BGN ;PACKET BEGIN? JRST [ MOVEM C,PACKET+.PKDAT(D) MOVEI B,QUO%BP AOBJN D,.+1 JRST .+1 ] CAIN B,PK%END ;PACKET END? JRST [ MOVEM C,PACKET+.PKDAT(D) MOVEI B,QUO%EP AOBJN D,.+1 JRST .+1 ] CAIN B,PK%QUO ;QUOTE CHARACTER? JRST [ MOVEM C,PACKET+.PKDAT(D) MOVEI B,QUO%QT AOBJN D,.+1 JRST .+1 ] TXNE F,F%ARO ;ARROW MODE? CALL CHKARO ;YES, CHECK CHARACTER MOVEM B,PACKET+.PKDAT(D) AOBJN D,FILPK1 ;LOOP BACK FILPK3: HRRZ A,D ;GET END LENGTH ADDI A,.PKDAT+5 ;ACCOUNT FOR OVERHEAD RET ;DONE ; CHKARO - CHECK FOR ASCII ARROW MODE CHKARO: CAIL B," " ;CONTROL CHARACTER? RET ;NO, RETURN CAIE B,.CHBSP ;^H? CAIN B,.CHTAB ;OR TAB? RET ;YES CAIE B,.CHLFD ;LINE FEED? CAIN B,.CHFFD ;OR FORM FEED? RET ;YES CAIN B,.CHCRT ;RETURN? RET ;YES CAIN B,.CHESC ;ESCAPE? JRST [ MOVEI B,"$" RET ] PUSH P,B ;SAVE CHARACTER MOVEI B,"^" ;GET THE ARROW TXNE F,F%TCP ;TCP DEVICE? JRST CHKAR1 ;YES MOVEM B,PACKET+.PKDAT(D) AOBJN D,.+1 JRST CHKAR2 CHKAR1: MOVE A,LSRJFN ;GET TCP JFN BOUT ;OUTPUT THE ARROW ERJMP .+1 CHKAR2: POP P,B ;GET CHARACTER BACK ADDI B,100 ;MAKE IT A LETTER RET ;DONE ; REDOPK - RESEND A PACKET, PACKET NUMBER IN A. REDOPK: DBGINF TXNE F,F%EOF ;EOF PACKET SENT? JRST [ CALL SNDEOF ;YES, RESEND IT DBGINF RET ] ;AND QUIT TXNE F,F%HDR ;THIS THE HEADER? JRST [ DBGINF MOVEM A,PKTNUM ;RESET PACKET NUMBER MOVE A,PKTTBL(A) MOVEM A,HDRPTR ;RESET TEXT POINTER CALL CLRTBL ;CLEAR THE PACKET TABLE CALL GETPKX ;GET PACKET CALL SNDPKT ;SEND IT OFF RET ] ;DONE SKIPGE B,PKTTBL(A) ;ANYTHING THERE? RET ;NO, SOMETHING ELSE WRONG STATUS DBGINF MOVEM A,PKTNUM ;STORE NEW PACKET NUMBER MOVE A,INJFN SFPTR ;SET FILE TO RIGHT SPOT FATAL CALL CLRTBL ;CLEAR THE PACKET TABLE MOVE A,FILTIM ;RESET THE STATUS STATUS RET ;DONE SUBTTL FILE OUTPUT - GET INPUT FILE ; OPNFIL - OPENS THE INPUT FILE OPNFIL: TXZ F,F%CPF ;ASSUME EVERYTHING OK MOVE D,FILPTR ;POINT TO THE FILE PARAMETER BLOCK HLRZ B,.FPLEN(D) ;GET LENGTH OF THE FP ADD B,D ;MOVE TO THE FD AOS B ;MOVE TO THE FILE NAME MOVE C,B ;SAVE IT IN CASE OF ERROR HRROS B ;MAKE IT A POINTER MOVX A,GJ%SHT!GJ%OLD!GJ%DEL GTJFN ;GET A JFN ON IT JRST [ LOG (,<%S3: %E1>) CALL OPNTMP ;GET A TEMP FILE TEXT (TMP,) SETZM INJFN ;SAY WE NEVER GOT IT CALL CLSTMP TXO F,F%CPF ;MARK IT RET ] ;QUIT MOVEM A,INJFN ;SAVE THE JFN PUSH P,C ;SAVE FILE NAME POINTER MOVE A,.FPINF(D) ;GET FLAGS TXNE A,FP.SPL ;SPOOLED FILE? JRST OPNFL1 ;YES, NO ACCESS CHECK CALL RDACES ;CHECK USER ACCESS TO THIS FILE JRST [ LOG (,<%S3: Read access required>) MOVE A,INJFN RLJFN ;RELEASE THE JFN JFCL CALL OPNTMP ;GET A TEMP FILE TEXT (TMP,) SETZM INJFN ;SAY WE DON'T HAVE IT CALL CLSTMP TXO F,F%CPF ;MARK IT ADJSP P,-1 ;BALANCE THE STACK RET ] ;QUIT OPNFL1: MOVE A,INJFN ;GET THE JFN MOVE B,[1,,.FBBYV] ;GET THE IO FLAGS MOVEI C,D GTFDB POP P,C ;RESTORE THE NAME POINTER LDB A,[POINT 6,D,11] ;PICK UP THE BYTE SIZE MOVE B,[FLD(7,OF%BSZ)!OF%RD] CAIN A,8 ;EIGHT BIT BYTES? MOVE B,[FLD(8,OF%BSZ)!OF%RD] MOVE A,INJFN ;GET THE JFN OPENF ;OPEN THE FILE JRST [ LOG (,<%S3: %E1>) CALL OPNTMP ;GET A TEMP FILE TEXT (TMP,) CALL CLSTMP TXO F,F%CPF ;MARK IT RET ] ;QUIT RET ;DONE ; OPNTMP - OPEN THE ERROR MESSAGE FILE OPNTMP: PUSH P,A PUSH P,B MOVX A,GJ%SHT!GJ%NEW!GJ%FOU HRROI B,[ASCIZ /PS:IMGSPL-ERROR.FILE/] GTJFN SPLERR MOVEM A,TMPJFN MOVE B,[FLD(7,OF%BSZ)!OF%WR] OPENF SPLERR POP P,B POP P,A RET ; CLOSE TEMP FILE CLSTMP: MOVE A,TMPJFN ;GET TEH JFN TXO A,CO%NRJ ;KEEP THE JFN CLOSF SPLERR SKIPE A,INJFN ;GET REAL INPUT FILE RLJFN ;RELEASE IT IF IT'S THERE JFCL MOVE A,TMPJFN ;GET TEMP JFN MOVE B,[FLD(7,OF%BSZ)!OF%RD] OPENF ;OPEN TEMP FILE FOR READ SPLERR MOVEM A,INJFN ;SAVE JFN RET ;DONE ; TEXT ROUTINE FOR TEMP FILES TMP: MOVE B,A ;GET BYTE MOVE A,TMPJFN ;GET JFN BOUT ;WRITE IT OUT RET ;DONE ; SETFIL - SET LOCAL FILE FLAGS SETFIL: TXZ F,F%IMP!F%ASC!F%TEK!F%DSY!F%ARO MOVE D,FILPTR ;POINT TO THE FILE BLOCKS TXNE F,F%CPF ;PROBLEMS WITH THE FILE? JRST [ SETZM .FPINF(D) ;YES, ZAP FILE TYPE RET ] ;AND QUIT LDB A,[POINT 6,.FPINF(D),5] CAIN A,.FPFAS ;ASCII FORMAT? TXO F,F%ASC CAIN A,.FPFIM ;BINARY? TXO F,F%IMP CAIN A,.FPFAI ;TEK? TXO F,F%TEK CAIN A,.FPF8B ;DAISY? TXO F,F%DSY TXNN F,F%IMP!F%ASC!F%DSY!F%TEK TXO F,F%IMP ;DEFAULT TO IMPRESS TXNN F,F%ASC ;ASCII FILE? RET ;NO, SKIP THIS LDB A,[POINT 6,.FPINF(D),11] CAIN A,%FPLAR ;ARROW MODE REQUESTED? TXO F,F%ARO ;YES RET ;DONE SUBTTL FILE OUTPUT - REMOVE OLD STYLE IMPRINT-10 HEADERS FIXFIL: TXNE F,F%CPF ;FILE OK SO FAR? RET ;NO, DON'T DO THIS TXNN F,F%IMP ;IMPRESS FILE? RET ;NO MOVE A,INJFN ;LOOK AT THE FILE BIN ;GET FIRST BYTE CAIL B,"0" ;A DIGIT CAILE B,"9" JRST [ SETZ B, ;NO, IT'S OK SFPTR ;RESET POINTER JFCL RET ] ;DONE BIN ;FLUSH STRING JUMPN B,.-1 MOVE B,[POINT 1,PACKET] ;FLUSH 8 MORE MOVNI C,8 SIN RET ;DONE SUBTTL FILE OUTPUT - ACCESS CHECKING ; RDACES - CHECKS ACCESS TO THE FILE FOR PRINTING ; DLACES - CHECK ACCESS TO THE FILE FOR /DELETE DLACES: SKIPA A,[.CKAAP] ;WANT APPEND ACCESS FOR DELETE RDACES: MOVX A,.CKARD ;WANT READ ACCESS MOVEM A,ARGBLK+.CKAAC MOVE A,JOBINF+.EQSEQ ;GET EXTERNAL VALUES TXNE A,QE.PRV ;USER ENABLED? JRST CHKAC1 ;YES SETZM A,ARGBLK+.CKAEC ;NO MOVE A,INJFN ;GET THE JFN MOVEM A,ARGBLK+.CKAUD MOVE A,JOBINF+.EQOID ;SET THE USER NUMBER MOVEM A,ARGBLK+.CKALD HRROI A,JOBINF+.EQCON ;SET DIRECTORY POINTER MOVEM A,ARGBLK+.CKACD MOVEI A,5 ;LENGTH OF ARGUMENT BLOCK TXO A,CK%JFN ;SAY WE HAVE A JFN MOVEI B,ARGBLK ;ADDRESS OF ARGUMENT BLOCK CHKAC JRST CHKAC1 ;FAILED, ASSUME OK SKIPE A ;ACCESS ALLOWED? CHKAC1: AOS (P) ;YES, SKIP RETURN RET ;DONE SUBTTL FILE OUTPUT - HEADER BUILDING ; FIXHDR - BUILD THE HEADER STRING FIXHDR: MOVE A,[POINT 7,HDRTXT] MOVEM A,HDRPTR ;SET THINGS UP SETO A, IDPB A,HDRPTR ;INSURE A NON-ZERO BYTE MOVE C,FILPTR ;GET FILE FLAGS MOVE B,.FPFR2(C) TXNE B,FP.SDP ;THIS A SCREEN DUMP? JRST [ TEXT (HEADER,<@DOCUMENT(Language Impress, Name "Screendump")>) RET ] MOVE A,JOBINF+.EQOID ;USER NUMBER TXNE F,F%IMP TEXT (HEADER,<@DOCUMENT(Language Impress, Owner "%U1">) TXNE F,F%ASC!F%CPF TEXT (HEADER,<@DOCUMENT(Language Printer, Owner "%U1">) TXNE F,F%TEK TEXT (HEADER,<@DOCUMENT(Language Tektronix, Owner "%U1">) TXNE F,F%DSY TEXT (HEADER,<@DOCUMENT(Language Daisy, Owner "%U1">) SETO B, TEXT (HEADER,<, Date "%D2 %T2">) MOVE B,INJFN ;JFN MOVE A,.FPINF(C) ;GET FLAGS TXNN A,FP.SPL ;SPOOLED? TEXT (HEADER,<, Name "%f2">) TXNE A,FP.SPL JRST [ MOVE B,JOBINF+.EQJBB TEXT (HEADER,<, Name "Spooled %62 job">) JRST .+1 ] HLRZ B,.FPLEN(C) ;STEP TO FILE NAME ADD B,C AOS B HRROS B TXNE A,F%CPF ;SOMETHING WRONG? TEXT (HEADER,<, Name "%S2">) HRROI B,HOSTNM TXNE F,F%TCP ;ON A TCP PRINTER? TEXT (HEADER,<, Host "%S2">) LDB B,[POINT 9,.FPINF(C),35] CAILE B,1 ;WANT MORE THAN ONE COPY? JRST [ TEXT (HEADER,<, Copies %N2>) MOVE A,.FPINF(C) TXNE A,FP.COL ;WANT PAGE COLLATION? TEXT (HEADER,<, Pagecollation Yes>) JRST .+1 ] MOVE A,.FPINF(C) ;GET FILE INFO BITS TXNE A,FP.REV ;WANT PAGE REVERSAL? TEXT (HEADER,<, Pagereversal Yes>) TXNE A,FP.COL ;COLLATION ON? JRST [ TXNN A,FP.REV ;YES, FORCE REVERSE OFF IF SPECIFIED TEXT (HEADER,<, Pagereversal No>) JRST .+1 ] TXNE F,F%LST ;THIS THE LAST FILE? TEXT (HEADER,<, Jobheader Yes>) TXNN F,F%LST TEXT (HEADER,<, Jobheader No>) MOVE A,.FPFR2(C) ;WANT MANUAL PAPER FEED? TXNE A,FP.MAN TEXT (HEADER,<, Inputbin Manual>) TXNE F,F%IMP ;THIS AN IMPRESS FILE? JRST FIXHD1 ;YES, SKIP THE REST HRRZ B,.FPFR1(C) ;GET THE LINES PER PAGE SKIPE B ;DEFAULT? TEXT (HEADER,<, Formlength %N2>) HLRZ B,.FPFR1(C) ;GET FORMWIDTH SKIPE B ;DEFAULT? TEXT (HEADER,<, Formwidth %N2>) HRRZ B,.FPFR2(C) ;GET LEFT MARGIN SKIPE B ;DEFAULT? TEXT (HEADER,<, Leftmargin %N2>) MOVE B,.FPINF(C) TXNE B,FP.2PG ;WANT TO FORMS? TEXT (HEADER,<, Formsperpage 2>) MOVE B,.FPFR2(C) TXNE B,FP.RUL ;WANT RULES? TEXT (HEADER,<, Rules>) TXNE B,FP.OTL ;WANT OUTLINES? TEXT (HEADER,<, Outlines>) FIXHD1: TEXT (HEADER,<)>) ;END THE HEADER RET ;DONE ; TEXT ROUTINE FOR HEADERS HEADER: IDPB A,HDRPTR SETZ A, PUSH P,HDRPTR IDPB A,HDRPTR POP P,HDRPTR RET SUBTTL FILE OUTPUT - SEND HEADER ; SNDHDR - SENDS THE HEADER SNDHDR: MOVE A,[POINT 7,HDRTXT] ;POINT TO THE BUFFER MOVEM A,HDRPTR ;SAVE THE POINTER IBP HDRPTR ;SKIP PAST NON-ZERO BYTE TXO F,F%HDR ;SAY SENDING HEADER SNDHD1: CALL CHKLSR ;CHECK THINGS CALL GETPKT ;GET A PACKET JRST SNDHD1 ;WRAP AROUND JRST SNDHD2 ;END OF HEADER CALL SNDPKT ;SEND IT OUT JRST SNDHD1 ;LOOP BACK SNDHD2: CALL RSVP ;SEND AN RSVP MOVEI A,RSVSLP DISMS CALL CHKLSR ;GET STATUS MOVE A,PKTNUM ;GET PACKET NUMBER SOS A ;GET ACTUAL NUMBER ANDI A,MAXPKT ;NOT NEEDED HERE SKIPGE PKTTBL(A) ;HEADER ACK'D? JRST SNDHD3 ;YES MOVEI A,RSVSLP ;NO, WAIT SOME DISMS JRST SNDHD1 ;LOOK AGAIN, CHECK FOR NAKS SNDHD3: TXZ F,F%HDR ;NO LONGER SENDING HEADER RET ;DONE SUBTTL FILE OUTPUT - ACCOUNTING ; GETCNT - GETS THE PAGE COUNT FOR THE FILE GETCNT: TXZ F,F%PGC ;COUNT NOT VALID NOW DBGINF GETCT1: MOVE A,[PGCPKT,,PACKET] ;GET THE REQUEST PACKET BLT A,PACKET+PGCLEN ;PUT IN BUFFER MOVEI A,PGCLEN ;GET THE LENGTH CALL SNDPKT ;SEND IT OFF MOVEI A,RSVSLP ;WAIT FOR REPLY DISMS CALL CHKLSR ;CHECK THE PRINTER TXZN F,F%PGC ;GET THE COUNT? JRST GETCT1 ;NO MOVE A,PAGCNT ;YES, GET THE COUNT ADDM A,JOBCNT ;ADD IT IN STATUS DBGINF RET ;DONE PGCPKT: EXP PK%BGN ;BEGIN PACKET EXP "1","1" ;LENGTH EXP "S" ;STATUS EXP "a" ;SYNC REQUEST EXP "F","F","F","F" ;WINDOW SIZE EXP "F","F" ;PACKET CODE EXP " " ;ERROR TYPE EXP 0,0,0,0 ;CHECKSUM EXP PK%END ;END OF PACKET PGCLEN==.-PGCPKT SUBTTL FILE OUTPUT - CHECKPOINT ; STSTXT - TEXT ROUTINE FOR STATUS STSTXT: IDPB A,STSPTR SETZ A, PUSH P,STSPTR IDPB A,STSPTR POP P,STSPTR RET SUBTTL TEXT UTILITY TEXT.: MOVEM P,TXTBUF ;SAVE THE STACK POINTER TRVAR > PUSH P,P1 MOVEI P1,TXTACS ;GET ADDRESS OF SAVED AC BUFFER HRLI P1,1 ;MAKE BLT POINTER BLT P1,4+TXTACS ;SAVE AC1 - AC5 POP P,P1 ;RESTORE THIS MOVE C,TXTBUF ;GET STACK POINTER MOVE C,(C) ;POINT TO ARGS HRRZ A,(C) ;GET ROUTINE ADDRESS MOVEM A,TXTRTN ;SAVE IT MOVEI B,@1(C) ;GET STRING ADDRESS HLL B,[POINT 7,0] ;MAKE IT A POINTER MOVEM B,TXTPTR TEXT1: ILDB A,TXTPTR ;GET NEXT BYTE TEXT1A: JUMPE A,TXTEND ;END ON A ZERO BYTE CAIN A,"%" ;SOME THING SPECIAL? JRST TEXT2 ;YES TEXT1B: CALL @TXTRTN ;PROCESS THIS CHARACTER JRST TEXT1 ;LOOP BACK TXTEN1: MOVEI A,.CHCRT ;END OF STRING, SEND A CRLF CALL @TXTRTN MOVEI A,.CHLFD ;SEND A LF CALL @TXTRTN TXTEND: HRLI 5,TXTACS ;GET POINTER TO THE ACS HRRI 5,A ;MAKE BLT POINTER BLT 5,5 ;RESTORE RET ;ALL DONE ; HERE TO PROCESS THE "%" CHARACTER TEXT2: ILDB A,TXTPTR ;GET ARGUMENT CAIN A,"U" ;USER NAME? JRST TEXT.U CAIN A,"F" ;FILE NAME? JRST TXT.FF CAIN A,"f" JRST TXT.FS CAIN A,"N" ;DECIMAL NUMBER? JRST TEXT.N CAIN A,"O" ;OCTAL NUMBER? JRST TEXT.O CAIN A,"6" ;SIXBIT WORD? JRST TEXT.6 CAIN A,"E" ;ERROR STRING? JRST TEXT.E CAIN A,"T" ;TIME? JRST TEXT.T CAIN A,"D" ;DATE? JRST TEXT.D CAIN A,"S" ;STRING? JRST TEXT.S CAIN A,"_" ;CRLF AND QUIT? JRST TXTEN1 CAIN A,"%" ;A "%"? JRST TEXT1B JRST TEXT1A ;NONE OF THESE, PROCESS THE CHARACTER ; GETAC - RETURNS THE VALUE IN B FOR THE NEXT AC NUMBER. GETAC: ILDB A,TXTPTR ;GET THE CHARACTER CAIL A,"1" ;TOO LOW? CAILE A,"5" ;OR TOO HIGH? JRST GETAC1 ;YES SUBI A,"1" ;CONVERT TO BINARY AND SUBTRACT ONE MOVEI B,TXTACS ;GET POINTER TO AC BUFFER ADD B,A ;GET ADDRESS OF THE ONE WE WANT MOVE B,(B) ;GET THE VALUE RET ;RETURN IT GETAC1: ADJSP P,-1 ;BAD VALUE, BALANCE THE STACK JRST TEXT1A ;PROCESS THIS ONE ; "U" - USER NAME TEXT.U: CALL GETAC ;GET THE NUMBER HRROI A,TXTBUF ;POINT TO THE TEXT BUFFER DIRST ;WRITE IT OUT JRST TEXT1 ;CAN'T JRST TXTOUT ;SEND THE BUFFER ; "F" - FILE NAME TXT.FS: SKIPA C,[JS%NAM!JS%TYP!JS%GEN!JS%PAF] TXT.FF: MOVX C,JS%DEV!JS%DIR!JS%NAM!JS%TYP!JS%GEN!JS%PAF CALL GETAC ;GET THE JFN HRROI A,TXTBUF JFNS ;WRITE IT OUT ERJMP TEXT1 ;FAILED JRST TXTOUT ;SEND THE BUFFER ; "N" - DECIMAL NUMBER ; "O" - OCTAL NUMBER TEXT.N: SKIPA C,[^D10] ;DECIMAL TEXT.O: MOVEI C,10 ;OCTAL CALL GETAC ;GET THE NUMBER HRROI A,TXTBUF NOUT ;WRITE IT OUT JRST TEXT1 JRST TXTOUT ;SEND IT OUT ; "6" - SIXBIT WORD TEXT.6: CALL GETAC ;GET THE WORD MOVEI C,6 ;SEE HOW MANY CHATACTERS TO PRINT TRNE B,77 JRST TEXT60 MOVEI C,5 TRNE B,7700 JRST TEXT60 MOVEI C,4 TRNE B,77000 JRST TEXT60 MOVEI C,3 TLNE B,77 JRST TEXT60 MOVEI C,2 TLNE B,7700 JRST TEXT60 MOVEI C,1 TLNN B,770000 RET ;NOTHING THERE TEXT60: PUSH P,B ;SAVE THE WORD PUSH P,C ;SND THE COUNT PUSH P,[POINT 6,-2(P)] ;SAVE A POINTER TEXT6A: ILDB A,(P) ;GET THE NEXT BYTE ADDI A,40 ;CONVERT TO ASCII CALL @TXTRTN ;PROCESS IT SOSLE -1(P) ;ANY LEFT? JRST TEXT6A ;YES, DO THEM ADJSP P,-3 ;FLUSH THE STACK JRST TEXT1 ;DONE ; "E" - ERROR STRING TEXT.E: CALL GETAC ;GET THE ERROR NUMBER HRLI B,.FHSLF ;THIS FORK HRROI A,TXTBUF ;POINT TO THE BUFFER SETZ C, ;NO LIMIT ERSTR ;WRITE IT OUT JRST TEXT1 ;CANT JRST TEXT1 JRST TXTOUT ;SEND IT OUT ; "T" - TIME ; "D" - DATE TEXT.T: SKIPA C,[OT%NDA!] ;TIME ONLY TEXT.D: MOVX C,OT%NTM ;DATE ONLY CALL GETAC ;GET THE TIME HRROI A,TXTBUF ;POINT TO THE BUFFER ODTIM ;OUTPUT IT JRST TXTOUT ;SEND IT OUT ; "S" - STRING TEXT.S: CALL GETAC ;GET THE STRING ADDRESS HLL B,[POINT 7,0] ;MAKE IT A POINTER PUSH P,B ;SAVE IT JRST TXTOT1 ;JOIN COPY CODE TXTOUT: SETZ B, ;ASCIZ THE STRING IDPB B,A PUSH P,[POINT 7,TXTBUF] ;SAVE A POINTER TXTOT1: ILDB A,(P) ;GET NEXT CHARACTER JUMPE A,TXTOT2 ;END ON A ZERO BYTE CALL @TXTRTN ;PROCESS IT JRST TXTOT1 ;LOOP BACK TXTOT2: SETZM TXTBUF ;ZERO THE BUFFER ADJSP P,-1 ;BALANCE THE STACK JRST TEXT1 ;LOOP BACK SUBTTL USER OFFLINE NOTIFICATION OFLNOT: IFE OFFLSW,< RET > JFCL ;SO FILDDT AND DISABLE EASY TXNE F,F%TCP ;TCP PRINTER? RET ;YES, DO NOTHING MOVE A,FILPTR ;POINT TO CURRENT FP MOVE B,.FPFR2(A) ;GET FLAGS MOVE D,.FPINF(A) ;MORE FLAGS TXNE B,FP.SDP ;THIS A SCREEN DUMP? RET ;YES, DO NOTHING MOVE B,[POINT 7,NOTMSG] MOVEM B,NOTPTR HLRZ B,.FPLEN(A) ;GET LENGTH OF THE FP ADD B,A ;MOVE TO THE FD AOS B ;MOVE TO THE FILE NAME MOVE A,OBJBLK+OBJ.UN ;GET THE UNIT NUMBER MOVE C,JOBINF+.EQJBB ;GET JOB NAME TXNN D,FP.SPL ;SPOOLED? TEXT (OFLTXT,< [Laser printer %O1 offline while printing %S2]%_>) TXNE D,FP.SPL TEXT (OFLTXT,< [Laser printer %O1 offline while printing %63 job]%_>) SETZ A, IDPB A,NOTPTR ;END THHE STRING MOVE P1,[-MAXJOB,,0] ;MAKE JOB POINTER OFLNT1: HRRZ A,P1 ;GET THE JOB NUMBER MOVE B,[-2,,P2] ;GET TWO WORDS, PUT IN P2 AND P3 MOVX C,.JITNO ;GET USER AND TERMINAL NUMBER GETJI ;TRY FOR IT JRST OFLNT2 ;NO SUCH JOB CAME P3,JOBINF+.EQOID ;RIGHT USER? JRST OFLNT2 ;NO HRRZS P2 CAMN P2,[0,,-1] ;DETACHED? JRST OFLNT2 ;YES MOVE A,P2 ;GET THE TERMINAL NUMBER TXO A,.TTDES ;MAKE IT A DEVICE DESIGNATOR MOVX B,.MORNT ;GET SYSTEM-MESSAGES BIT MTOPR ERJMP OFLNT2 CAIE C,.MOSMY ;RECEIVE? JRST OFLNT2 ;NO HRROI B,NOTMSG ;POINT TO THE MESSAGE TTMSG ;SEND IT OUT ERJMP .+1 ;IGNORE ERRORS OFLNT2: AOBJN P1,OFLNT1 ;LOOP BACK RET ;DONE OFLTXT: IDPB A,NOTPTR RET SUBTTL FATAL ERRORS LITSPC: LIT ;SAVE LITERALS IN DUMP .FATAL: TXO F,F%FAT ;MARK FATAL ERROR SEEN MOVEM 17,DUMPAC+17 ;SAVE THE AC'S MOVE 17,[0,,DUMPAC] BLT 17,DUMPAC+16 HRROI A,STSBUF ;POINT TO THE STRING WTO (,<%S1>) HRROI A,DMPSTR ;COPY THE STRING HRROI B,STSBUF SETZ C, SOUT SETO A, STATUS FATAL1: MOVX A,GJ%SHT!GJ%NEW!GJ%FOU HRROI B,[ASCIZ /IMGSPL-CRASH.DUMP/] GTJFN JRST [ TMSG HALTF ] HRLI A,.FHSLF ;THIS PROCESS MOVE B,[-1000,,0] ;SAVE EVERYTHING SSAVE ERJMP [TMSG JRST .+1] RESET ;RELEASE EVERYTHING HALTF ;QUIT JRST .-1 FATAL9: TMSG JRST FATAL1 END <3,,ENTVEC>