Trailing-Edge
-
PDP-10 Archives
-
decuslib20-10
-
decus/20-186/imgspl.mac
There is 1 other file named imgspl.mac in the archive. Click here to see a list.
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,<STRING>)
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 (<FIRST STRING>,<SECOND STRING>)
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 <SYSTEM>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,<STR>)
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,<?IMGSPL Fatal error at %O3: %E2>)
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,<?IMGSPL Fatal error at %O3%_>)
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 <X2>,<JUMP 0>
IFNB <X2>,<JUMP [ASCIZ \X2\]>
>
; ACKNOWLEDGE OPERATOR
DEFINE ACK (X1,X2) <
CALL .ACK.
JUMP [ASCIZ \X1\]
IFB <X2>,<JUMP 0>
IFNB <X2>,<JUMP [ASCIZ \X2\]>
>
; WRITE TO OPERATOR - JOB MESSAGE
DEFINE WTOJ (X1,X2) <
CALL .WTOJ.
JUMP [ASCIZ \X1\]
IFB <X2>,<JUMP 0>
IFNB <X2>,<JUMP [ASCIZ \X2\]>
>
; WRITE TO OPERATOR - LOG MESSAGE
DEFINE LOG (X1,X2) <
CALL .LOG.
JUMP [ASCIZ \X1\]
IFB <X2>,<JUMP 0>
IFNB <X2>,<JUMP [ASCIZ \X2\]>
>
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 <NXTMSG>
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 <?IMGSPL Can't receive IPCF messages: %E1>
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,<IMGSPL - Not started%_>)
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,<IMGSPL - Node %62, Unit %O1%_>)
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 (<Say What?>,<No job to abort>)
RET ]
MOVE A,JOBINF+.EQJBB ;GET THE JOB NAME
ACK (<Aborting>,<Job %61 aborting>)
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 (<Job requeued>,<Job %61 requeued>)
RET ;DONE
REQUE1: MOVE A,JOBINF+.EQJBB ;GET THE JOB NAME
ACK (<Job Not Requeued>,<Job %61 finishing up>)
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 <Started> ;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 (<Not available>,<%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 (<Can't release printer>,<%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 <?IMGSPL Send to Quasar or Orion failed: %E1>
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 <?IMGSPL Send to Quasar or Orion failed: %E1>
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,<OPDEF CHANM [JSYS 460]>
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 (<Begin>,<job %62, Req #%N3 for %U1>)
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 (<Can't delete file>,<%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 (<Can't delete file>,<%S3: CHKAC said not to>)
JRST DELFL2 ] ;NO
LOG (<Deleting file>,<%S3>)
DELFL1: MOVE A,INJFN ;GET JFN
TXO A,DF%EXP ;EXPUNGE ALSO
DELF
JRST [ LOG (<Can't delete file>,<%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 (<End>,<job %62, Req #%N3 for %U1 (TCP printer)>)
RET ]
MOVE D,JOBCNT ;GET THE PAGE COUNT
CAIE D,1
WTOJ (<End>,<job %62, Req #%N3 for %U1 (%N4 pages)>)
CAIN D,1
WTOJ (<End>,<job %62, Req #%N3 for %U1 (%N4 page)>)
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 (<Accounting Error>,<USAGE%% failed: %E1>)
RET ;DONE
ACTLST: USENT. (.UTOUT,1,1,0)
USTAD. (-1) ;CURRENT DATE/TIME
USPNM. (<SIXBIT/IMGSPL/>,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. (<SIXBIT /LSR/>,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. (<SIXBIT /LETTER/>,US%IMM) ;FORMS TYPE
USDSP. (<SIXBIT/NORMAL/>,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. (<POINT 7,JOBINF+.EQOWN>) ;USER NAME
USACT. (<POINT 7,JOBINF+.EQACT>) ;ACCOUNT STRING POINTER
0 ;END OF LIST
SUBTTL FILE OUTPUT - MAIN LOOP
DOFILE: GTAD ;GET THE TIME
MOVEM A,FILTIM ;STORE IT
STATUS <Printing, Started at %T1>
CALL OPNFIL ;OPEN THE OUTPUT FILES
CALL SETFIL ;SET FILE PARAMETERS
CALL FIXHDR ;BUILD A HEADER COMMAND
CALL FIXFIL ;FIX THE FILE
DBGINF <Starting file>
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 <Sync Received>
MOVE A,FILTIM ;GET START TIME
STATUS <Printing, Started at %T1>
TXZ F,F%EOF!F%HDR!F%PAB!F%JIP
SETZM PKTNUM ;ZERO THE PACKET NUMBER
CALL SNDHDR ;SEND THE HEADER
DBGINF <Header Sent>
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 <Wrap around wait>
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 <Printing, started at %T1>
DBGINF <Sending EOF packet>
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 <Printer problem, aborted at %T1>
TXNE F,F%CAN ;CANCELED?
STATUS <Canceled at %T1>
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 <Waiting for printer>
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,<Waiting for printer, %E1>)
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 <Waiting for remote spooler>
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 (<Signon to remote spooler>,<%S1>)
>;IFN REMSPL
TCPOTX: MOVE A,FILTIM
STATUS <Sending file, Started at %T1>
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 <Transfer complete>
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 <Aborted due to connection error at %T1>
TXNE F,F%CAN ;CANCELED?
STATUS <Canceled at %T1>
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 <Received packet>
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 <Offline> ;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 <Requesting Sync>
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 <Sync received>
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 <Sending RSVP>
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 <Sending packet # %O2, Length %O1>
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 <EOFCTR>
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 (<Could be trouble>,<F%%JIP never came on in DOEOF1 loop>)
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 <EOF packet SENT>
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 <RELPKT called with %O1>
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 <Clearing packet table>
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,-<MAXPKT+1-OSPCNT>
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 <Building packet %O3 (FP = %O2)>
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 <REDOPK called with %O1>
TXNE F,F%EOF ;EOF PACKET SENT?
JRST [ CALL SNDEOF ;YES, RESEND IT
DBGINF <Resending EOF packet>
RET ] ;AND QUIT
TXNE F,F%HDR ;THIS THE HEADER?
JRST [ DBGINF <Resending packet # %O1 (Header)>
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 <Resending packet %O1>
DBGINF <Resending packet # %O1 (FP reset to %O2)>
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 <Printing, Started at %T1>
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 (<Can't print file>,<%S3: %E1>)
CALL OPNTMP ;GET A TEMP FILE
TEXT (TMP,<Can't print %S3: %E1>)
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 (<Can't print file>,<%S3: Read access required>)
MOVE A,INJFN
RLJFN ;RELEASE THE JFN
JFCL
CALL OPNTMP ;GET A TEMP FILE
TEXT (TMP,<Can't print %S3: Read access required>)
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 (<Can't print file>,<%S3: %E1>)
CALL OPNTMP ;GET A TEMP FILE
TEXT (TMP,<Can't print %S3: %E1>)
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:<SPOOL>IMGSPL-ERROR.FILE/]
GTJFN
SPLERR <Can't get temp file: %E1>
MOVEM A,TMPJFN
MOVE B,[FLD(7,OF%BSZ)!OF%WR]
OPENF
SPLERR <Can't open temp file: %E1>
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 <Can't close temp file: %E1>
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 <Can't open temp file for read: %E1>
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 <Getting page count>
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 <Pages printed: %N1>
DBGINF <Pages printed: %N1>
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 <TXTRTN,TXTPTR,<TXTACS,5>>
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 (<Imgspl Crash>,<%S1>)
HRROI A,DMPSTR ;COPY THE STRING
HRROI B,STSBUF
SETZ C,
SOUT
SETO A,
STATUS <Spooler crash at %T1>
FATAL1: MOVX A,GJ%SHT!GJ%NEW!GJ%FOU
HRROI B,[ASCIZ /IMGSPL-CRASH.DUMP/]
GTJFN
JRST [ TMSG <?IMGSPL Can't get JFN for dump file>
HALTF ]
HRLI A,.FHSLF ;THIS PROCESS
MOVE B,[-1000,,0] ;SAVE EVERYTHING
SSAVE
ERJMP [TMSG <?IMGSPL Save failed>
JRST .+1]
RESET ;RELEASE EVERYTHING
HALTF ;QUIT
JRST .-1
FATAL9: TMSG <?IMGSPL ERROR WITHIN AN ERROR>
JRST FATAL1
END <3,,ENTVEC>