Trailing-Edge
-
PDP-10 Archives
-
BB-4172G-BM
-
language-sources/lptspl.mac
There are 45 other files named lptspl.mac in the archive. Click here to see a list.
TITLE LPTSPL - TOPS10/TOPS20 LINE PRINTER DRIVER
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979
; DIGITAL EQUIPMENT CORPORATION
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
;
SEARCH GLXMAC ;SEARCH GALAXY PARAMETERS
PROLOGUE(LPTSPL)
SEARCH QSRMAC ;SEARCH QUASAR PARAMETERS
SEARCH ORNMAC ;SEARCH ORION/OPR PARAMETERS
SEARCH D60UNV ;SEARCH FOR DN60 SYMBOLS
.DIRECT FLBLST
IF1,<
TOPS20 <PRINTX ASSEMBLING GALAXY-20 LPTSPL>
TOPS10 <PRINTX ASSEMBLING GALAXY-10 LPTSPL>
> ;END IF1
IF2,<PRINTX BEGIN ASSEMBLER PASS # 2.>
SALL ;SUPPRESS MACRO EXPANSIONS
;VERSION INFORMATION
LPTVER==104 ;MAJOR VERSION NUMBER
LPTMIN==0 ;MINOR VERSION NUMBER
LPTEDT==2650 ;EDIT LEVEL
LPTWHO==0 ;WHO LAST PATCHED
%LPT==<BYTE (3)LPTWHO(9)LPTVER(6)LPTMIN(18)LPTEDT>
;STORE VERSION NUMBER IN JOBVER
LOC 137
.JBVER::EXP %LPT
RELOC 0
SUBTTL RJE SUPPORT DEFINITIONS
;IF WE HAVE RJE,,GET SIMULATION PACKAGE (TOPS20)
TOPS20 <
IFN FTRJE,<.REQUIRE NURD.REL> ;LOAD THE DN200 I/O PACKAGE
>
;IF WE HAVE DN60,,GET DN60 I/O PACKAGE
IFN FTDN60,<.REQUIRE D60JSY.REL ;LOAD THE DN60 I/O PACKAGE
D60ERR ;GENERATE ERROR SYMBOLS
PHASE 0
OPRPTR:! BLOCK 1 ;OPR MESSAGE BYTE POINTER
OPRBCT:! BLOCK 1 ;OPR MESSAGE BYTE COUNT
OPRLEN:! ;OPR MESSAGE HEADER LENGTH
OPRTXT:! ;OPR MESSAGE TEXT
DEPHASE
> ;END FTDN60 CONDITIONAL
SUBTTL Revision History
COMMENT \
2550 Delete all references to user name and job number.
Replace them with ^R Library $Text Function.
2551 Add code to support new QUASAR device status message.
2552 Add RJE support
2553 Fix a Restart page count bug by not including the job
headers and trailers in the final page count.
2554 Replace ERRSTP ITEXT with LPERR ITEXT. Make sure when LPT comes
online or goes offline, the status is updated. Add a check to
ACTEND so that if the request had an invalid account string,
no USAGE entry is made.
2555 Fix a bug in which INPOPN was doing a LOAD S1,EQ.PRV to get
the users privilge bits. This translated to MOVE S1,400
and 400 was SPLDIR (which was never 0). Given this, the
JUMPN S1,INPO.1 always jumped to INPO.1 and avoided the
access check. The LOAD was changed to LOAD S1,.EQSEQ(J),EQ.PRV.
2556 Changed the IB to conform to the new IB/PIB structure.
2557 Fix a bug in OUTOUT which caused to stack to be out of phase.
Basic re-write of OUTOUT, elimination of OUTINT, and
modification of $SOUT.
2560 Change the scheduler loop to use P1 instead of T2.
Change the scheduler loop so that at MAIN.1 it
checks to see if the stream status needs to be updated,
and if so, it sends a status update and checkpoint
message to QUASAR.
2561 Delete the flag bit HDRTRL and the supporting code.
2562 Add Calls to S%SIXB & S%TBLK for WTOR response parsing.
Move the call to FILDIS from ENDJOB to QRELEASE.
2563 Fix line count for narrow forms.
Fix DEVOUT to save S1 across OUTOUT call
Add code to cut off the header/trailer line at 'J$FWID' Length
2564 Add DN60 Support.
2565 Add 'Ignore Structure Accounting' MSTR JSYS.
2566 Change the $WTOR's for killing OPR requests from $WTOR to $KWTOR.
2567 Add spooling to mag tape support
2570 Fix a page count problem (on restarts).
Spell cancelled right (canceled)
2571 Spell Canceling correctly
add 40 (decimal) words to the context PDL
2572 Fix a bug in which it was possible for LPTSPL to set the output
blocked scheduling bit and then deschedule for a page limit
exceeded error. When this happened, LPTSPL would wait for
the output done interrupt, which, of course, would never come.
2573 Clear J$RNPP IN DOJOB Just before checkpointing the next file
Clear J$RNPP and checkpoint the number of copies in FILE.1
2574 If a job is cancelled while in OPR response wait from LODVFU or
LODRAM then zero J$FORM to force the next job to go through
new forms processing.
2575 Add DN60 operator response support (What a Crock !!)
2576 Delete FTRMTE feature test.
2577 At OUTERR move the PUSHJ P,.SAVET & MOVE T4,STREAM to OUTE.1
under TOPS-10 conditional.
Change the scheduler so that for both TOPS-10 & TOPS-20 we
check to see if we processed a message and if so, dont sleep.
Change OPRCHK so that as long as the output succeeds, we
continue printing operator messages.
For TOPS-10 make OUTDMP call OUTOUT BUFNUM+1 times.
Add Spooling to Tape support for TOPS-10.
2600 Make LPTSPL sleep forever by removing the 60 second timer.
2601 TOPS10 - Detect EOF on spool to magtape. Ask OPR to mount next reel
2602 Fix a bug in SHUTIN code. Get a new stack pointer if shutting
down from 'IN STREAM' context.
2603 Fix a bug - reverse the compare in S$VFU which checks for
optical VFU.
2604 Fix a bug - In OUTGET, if the default RAM and VFU are already set,
then, dont set them.
2605 Fix a bug - if printing either the banner or header pages, dont
flush the buffers in KILL or OACCAN.
2606 Add code to send a form feed if the printer VFU is ok and
we are about to load the VFU.
2607 Delete the TOPS-20 mag tape code that assigns/deassigns the tape drive.
Also make sure that the mat tape is not already assigned to anyone.
2610 Delete the RAM variable from the forms default macro and add
J$FRAM.
2611 Change IPCF send/recieve quotas from max to 20.
2612 Change DN60 D60OPN parameters for new port/line handle.
2613 Fix a bug - prevent LPTSPL from deleting DN60'S link'd list.
2614 Delete the Send/Recieve Quotas from the PIB.
2615 Make OUTREL do a CLOSE instead of a RESDV. if we are spooling to tape
2616 Pick up non-existant printer status bits on the -20.
2617 Fix a bug in TAPGET; The correct value returned by the DVCHR for
unassigned devices is -1,,unit # - Not -1.
2620 In SHUTDN, After the call to FNDOBJ check to see that the object
was actually found, and if not, just return.
In OPDINI, add a SETZM FMOPN and a $RETT at the end of the routine.
In OPEN.6 add a SETOM J$LINK(J) to indicate that there is no DN60
operator message list.
In CLOSE.6, change the MOVE S1,J$LINK(J) to a SKIPL S1,J$LINK(J) so
that we dont delete a list which may not exist.
2621 TOPS-10: Delete the call to F%FCHN and use the stream number as the
channel number.
2622 Fix a job restart problem which allows -pages to be printed.
2623 Fix a -10 problem caused by converting to extended channels in the
library. Must re-write the load VFU and RAM sections for front
end lint printers
2624 Fix a -10 problem - Clear the PSF%DO and PSF%OB bits in the
OUTGET routine since we may wait forever after resetting the channel.
Change all occurances of DC3 output to CRLF except for the ruler.
2625 Add a CRLF to the end of the header page file info line.
2626 Fix a bug in the /REPORT: code for COBOL report files.
2627 Fix a bug in deleting files. Make F%DEL use an in your behalf FOB.
2630 Delete the support for the old forms parameters.
2631 Convert DN60 support to new SETUP message format.
2632 Rework the Backspace /pages support to fix U.S. Railways QAR.
2633 Finally get the backspace code right.
2634 Add 8 bit input support. Also, make output byte sizes variable by
adding J$LBTZ to keep track of output byte size.
2635 Add /FILE:ELEVEN support to print MACY11 files as standard ascii
Requires that a new FP bit or field be defined for 8-BIT
2636 TOPS20 QAR (20-00608) Add code to OUTREL so that when closing
a device other then the line printer, we write out
trailing tape marks.
2637 Fix a bug in which the ABORT bit was being lit in the NXTJOB code,
before the forms were set up. This caused the request to be trashed
without the headers or trailers being printed
2640 Fix a bug - Make the TAPGET OPENF open the device in 7 bit Mode.
2641 Fix Another bug - make OUTGET open device for 8 bit bytes.
2642 Make PICTURE put out line feeds, not DC3's.
2643 Fix a bug in OUTERR code so that is the OUTFLS call fails, then
send a Response-to-Setup message to QUASAR before shutting down.
2644 Add support for /RAM: in LPFORM.INI for -10 & -20.
2645 Fix an accounting problem in which usage accounting was being done
twice.
2646 Fix QAR # 20-00805 such that multiple ALIGN commands do not
add to the sleep time of previous ALIGN commands
2647 Add a SETZM T1 to the .MONOP MTOPR call in OUTDMP.
Add a .MONOP MTOPR call to TAPGET to wait for I/O to finish or
if a TTY, set the TTY page width to infinite.
2650 Fix BACKSPACE FILES problem. Just make it backspace to the beginning
of the current file.
\ ;End of Revision History
SUBTTL AC and I/O Channel Definitions
;ACCUMULATOR DEFINITIONS
M==12 ;IPCF MESSAGE ADDRESS
S==13 ;STATUS FLAGS
E==14 ;POINTS TO CURRENT FILE
J==15 ;JOB CONTEXT POINTER
C==16 ;HOLDS A CHARACTER - ALMOST NEVER PRESERVED
SYSPRM ERRVFU,DF.LVE,MO%LVF
SUBTTL Parameters
;PARAMETERS WHICH MAY BE CHANGED AT ASSEMBLY TIME
ND PDSIZE,100 ;SIZE OF PUSHDOWN LIST
ND LPTERR,2 ;NUMBER OF LPT I/O ERRS BEFORE QUITTING
ND LOGPAG,12 ;PAGE LIMIT FOR LOG IF OVER QUOTA
;CONSTANT PARAMETERS
XP MSBSIZ,30 ;SIZE OF A MESSAGE BLOCK
XP AFDSIZ,10 ;ALIGN FILE FD SIZE.
;CHECKPOINT BLOCK OFFSETS
XP CKFIL,0 ;NUMBER OF FILES PRINTED
XP CKCOP,1 ;NUMBER OF COPIES OF LAST FILE
XP CKPAG,2 ;NUMBER OF PAGES OF LAST COPY
XP CKTPP,3 ;TOTAL PAGES PRINTED
XP CKFLG,4 ;FLAGS
XP CKFREQ,1B0 ;JOB WAS REQUEUED BY OPR
XP CKFCHK,1B1 ;JOB WAS CHECKPOINTED
SYSPRM BUFNUM,4,1 ;NUMBER OF BUFFERS
SYSPRM BUFSPC,1000,1000 ;SPACE ALLOCATED FOR BUFFERS
SYSPRM BUFSIZ,<1000/BUFNUM>,<1000/BUFNUM>
;SIZE OF EACH BUFFER
SYSPRM BUFCHR,<BUFSIZ-3>*5,<BUFSIZ*4>
;NUMBER OF CHARS PER BUFFER
BUFSPC==BUFNUM*BUFSIZ
SYSPRM NPRINT,17,1 ;NUMBER OF DEVICES THIS SPOOLER HANDLES
SYSPRM ACCTSW,0,-1 ;ACCOUNTING -1=YES,0=NO
SYSPRM RAMNOR,SIXBIT/LP96/,SIXBIT/LP96/
SUBTTL MACROS
DEFINE LP(SYM,VAL,FLAG),<
IF1,<
XLIST
IFNDEF J...X,<J...X==1000>
IFDEF SYM,<PRINTX ?PARAM SYM USED TWICE>
SYM==J...X
J...X==J...X+VAL
IFNDEF ...BP,<...BP==1B0>
IFNDEF ...WP,<...WP==0>
REPEAT VAL,<
IFIDN <FLAG><Z>,<LPZ(\...WP,...BP)>
...BP==...BP_<-1>
IFE ...BP,<
...BP==1B0
...WP==...WP+1
> ;;END IFE ...BP
> ;;END REPEAT VAL
LIST
SALL
> ;END IF1
IF2,<
.XCREF
J...X==SYM
.CREF
SYM==J...X
> ;END IF2
> ;END DEFINE LP
DEFINE LPZ(A,B),<
IFNDEF ...Z'A,<...Z'A==B>
IFDEF ...Z'A,<...Z'A==...Z'A!B>
> ;END DEFINE LPZ
SUBTTL Special Forms Handling Parameters
;FORMS SWITCHES:
; BANNER:NN NUMBER OF JOB HEADERS
; TRAILER:NN NUMBER OF JOB TRAILERS
; HEADER:NN NUMBER OF FILE HEADERS (PICTURE PAGES)
; LINES:NN NUMBER OF LINES PER PAGE
; WIDTH:NN NUMBER OF CHARACTERS PER LINE
; ALIGN:SS NAME OF ALIGN FILE
; ALCNT:NN NUMBER OF TIMES TO PRINT ALIGN FILE
; ALSLP:NN NUMBER OF SECS TO SLEEP BETWEEN COPIES OF ALIGN
; RIBBON:SS RIBBON TYPE
; TAPE:SS VFU CONTROL TAPE
; VFU:SS (SAME AS /TAPE)
; RAM:SS TRANSLATION RAM TO USE
; DRUM:SS DRUM TYPE
; CHAIN:SS CHAIN TYPE (DRUM/CHAIN ARE THE SAME)
; NOTE:AA TYPE NOTE TO THE OPERATOR
;IN THE ABOVE AND BELOW EXPLANATIONS:
; NN IS A DECIMAL NUMBER
; SS IS A 1-6 CHARACTER STRING
; AA IS A STRING OF 1 TO 50 CHARACTERS
; OO IS AN OCTAL NUMBER
;LOCATION SPECIFIERS
; ALL ALL LINEPRINTERS
; CENTRAL ALL LINEPRINTERS AT THE CENTRAL SITE
; REMOTE ALL REMOTE LINEPRINTERS
; LPTOOO LINEPRINTER OOO ONLY
;NOTE: LPTSPL WILL USE THE FIRST ENTRY WHICH MEETS THE LOCATION
; SPECIFICATION FOR ITS LINEPRINTER.
DEFINE F,<
FF BANNER,2
FF TRAILER,2
FF HEADER,2
FF LINES,^D60
FF WIDTH,^D132
FF ALIGN,0
FF ALCNT,5
FF ALSLP,7
FF RIBBON,FRMNOR
FF TAPE,FRMNOR
FF VFU,FRMNOR
FF DRUM,FRMNOR
FF CHAIN,FRMNOR
FF NOTE,0
FF RAM,-1
>
;GENERATE TABLE OF SWITCH NAMES
DEFINE FF(A,B),<
XLIST
<<SIXBIT /A/>&777777B17>+S$'A
LIST
SALL
>
FFNAMS: F
;GENERATE TABLE OF DEFAULT PARAMTERS
DEFINE FF(X,Y),<
XLIST
D$'X: EXP Y
LIST
SALL
>
FFDEFS: F
F$NSW==.-FFDEFS
PURGE D$VFU,D$CHAI
F$CL1==^D60 ;WIDTH CLASS ONE IS 1 TO F$CL1
F$CL2==^D100 ;WIDTH CLASS TWO IS F$CL1 TO F$CL2
SUBTTL Flag Definitions
ARROW==1B0 ;ARROW MODE IN EFFECT
SUPFIL==1B1 ;NO USER FORM CONTROL
DSKOPN==1B2 ;DISK DATA READ GOING ON
RQB==1B3 ;JOB HAS BEEN REQUED
SUPJOB==1B4 ;SUPPRESS /JOB
ABORT==1B5 ;THE SHIP IS SINKING
FCONV==1B6 ;THE NEXT CHAR IS FORTRAN FORMAT DATA
NEWLIN==1B7 ;FLAG FOR THE BEGINING OF LINE
SKPFIL==1B8 ;SKIP FUTURE COPIES OF THIS FILE COMPLETELY
GOODBY==1B9 ;IN JOB TERMINATION SEQUENCE
FBPTOV==1B10 ;SPACING PAGE TABLE OVERFLOW BIT.
FORWRD==1B11 ;FORWARD SPACING REQUEST IN PROGRESS.
INTRPT==1B12 ;STREAM IS CONNECTED TO THE INTERRUPT SYSTEM
BANHDR==1B14 ;PRINTING BANNER/HEADER PAGES
VFULOD==1B15 ;VFU LOAD IS IN PROGRESS
SUBTTL Job Parameter Area
LP J$$BEG,0 ;BEGINNING OF PARAMETER AREA
;REQUEST PARAMETERS
LP J$RFLN,1 ;NUMBER OF FILES IN REQUEST
LP J$RLIM,1,Z ;JOB LIMIT IN PAGES
LP J$RTIM,1 ;START TIME OF JOB
LP J$RLFS,1,Z ;ADR OF LOG FILE SPEC
LP J$RNFP,1,Z ;NUMBER OF FILES PRINTED
LP J$RNCP,1,Z ;NUMBER OF COPIES OF CURRENT FILE
LP J$RNPP,1,Z ;NUMBER OF PAGES IN CURRENT COPY PRINTED
LP J$RACS,20 ;CONTEXT ACS
LP J$RPDL,^D100 ;CONTEXT PUSHDOWN LIST
;LPT PARAMETERS
LP J$LBUF,1 ;ADDRESS OF LPT BUFFER
LP J$LBFR,PAGSIZ ;LINE PRINTER BUFFER
LP J$LBRH,1 ;BUFFER RING HEADER
LP J$LBPT,1 ;BYTE POINTER
LP J$LBCT,1 ;BYTE COUNT
LP J$LDEV,1 ;ACTUAL OUTPUT DEVICE NAME
LP J$LERR,1 ;LPT ERROR DOWNCOUNTER
LP J$LRAM,1 ;DEFAULT RAM FILE NAME (LP64 or LP96)
LP J$LLCL,1 ;-1 IF UPPER/LOWER CASE PRINTER
LP J$LDVF,1 ;-1 IF DAVFU ON PRINTER
LP J$LPCR,1 ;-1 IF DEVICE HAS A PAGE CNTR
LP J$LREM,1 ; 0 = LOCAL LPT
;-1 = DEC TYPE REMOTE LPT
;+1 = DN60 TYPE REMOTE LPT
LP J$DCND,CN$SIZ ;DN60 LINE CONDITIONING BLOCK
LP J$DFLG,1 ;DN60 FLAG WORD
LP J$D6OP,1 ;DN60 OPERATOR CONSOLE ID
LP J$LINK,1 ;DN60 OPERATORS MSG LIST ID
LP J$OMSG,1 ;DN60 OPERATOR MESSAGE AVAILABLE FLAG
LP J$OFLN,1 ;DN60 PRINTER IS OFFLINE FLAG
LP J$LCLS,1 ;LPT CONTROLLER CLASS
LP J$LIOA,1 ;-1 IF WE ARE IN A SOUT OR OUT
LP J$LLPT,1 ;-1 IF DEVICE REALLY IS A LPT
LP J$LIOS,1 ;LPT IO ERROR STATUS
LP J$MTAP,1 ;SIXBIT MAG TAPE DEVICE NAME
LP J$LCHN,1 ;LPT I/O CHANNEL
LP J$LBTZ,1 ;LPT OUTPUT BYTE SIZE
TOPS20 <
LP J$LSTG,2 ;DEVICE NAME STRING
LP J$LIBC,1 ;INITIAL BYTE COUNT
LP J$LIBP,1 ;INITIAL BYTE POINTER
> ;END TOPS20 CONDITIONAL
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;CURRENT FORMS PARAMETERS
DEFINE FF(X,Y),<
LP J$F'X,1
>
LP J$FCUR,0 ;START OF FORMS PARAMS
F ;CURRENT FORMS PARAMS
LP J$FORM,1 ;CURRENT FORMS TYPE
LP J$FPFM,1 ;PREVIOUS FORMS TYPE
LP J$PDRU,1 ;PREVIOUS LOADED DRUM
LP J$PRIB,1 ;PREVIOUS LOADED RIBBON
LP J$PTAP,1 ;PREVIOUS LOADED CARRAIGE CONTROL TAPE
LP J$FMSP,1,Z ;FORMS WTO/WTOR PAGE ADDRESS
LP J$FWCL,1 ;CURRENT WIDTH CLASS
LP J$FLVT,1 ;CURRENTLY 'LOADED' VFU TYPE
LP J$FLRM,1 ;CURRENTLY 'LOADED' TRANSLATION RAM
LP J$FVIF,1 ;IFN OF VFU FILE ON -10
LP J$FBYT,1,Z ;VFU INPUT BYTE COUNT.
LP J$FPTR,1 ;VFU INPUT BYTE POINTER.
LP J$LVFF,1 ;FIRST TIME THROUGH FLAG FOR LPT VFU'S
LP J$FNBK,16 ;OPERATOR NOTE BLOCK
IF2,< PURGE J$FVFU,J$FCHA ;DON'T USE THESE >
;ALIGN FILE PARAMETERS
LP J$APRG,1 ;-1 IF ALIGN IS IN PROGRESS
LP J$AIFN,1 ;ALIGN FILE IFN
LP J$ABYT,1 ;ALIGN BUFFER BYTE COUNT.
LP J$APTR,1 ;ALIGN BUFFER BYTE POINTER.
LP J$ASLP,1,Z ;SECONDS TO SLEEP
LP J$ACNT,1,Z ;LOOP COUNT
LP J$AFD,AFDSIZ ;THE FD FOR THE ALIGN FILE
;MISCELLANY
LP J$XTOP,1 ;WE ARE AT TOP OF FORM
LP J$XFOB,FOB.SZ ;A FILE OPEN BLOCK
LP J$XPOS,1 ;CURRENT VERTICAL POSITION
LP J$XHBF,<45> ;BUFFER TO BUILD HEADER LINE
LP J$XCOD,<^D55> ;COMPILE A ROUTINE TO CHECK
; FOR MATCH ON /REPORT
LP J$XFRC,1 ;FORTRAN CHARACTER REPEAT COUNT
LP J$XTBF,50 ;$TEXT BUFFER FOR OUTPUT DEVICE
LP J$XTBP,1 ;BYTE POINTER FOR J$XTBF.
LP J$RESP,2,Z ;OPERATOR RESPONSE BUFFER.
LP J$WTOR,^D50 ;WTOR MESSAGE BUFFER.
;ACCOUNTING PARAMETERS.
LP J$APRT,1,Z ;PAGE COUNT.
LP J$ADRD,1,Z ;DISK BLOCKS READ.
LP J$APRI,1,Z ;JOBS PRIORITY
LP J$ARTM,1,Z ;JOBS RUN TIME (CPU)
LP J$ASEQ,1,Z ;JOBS SEQUENCE NUMBER
LP J$AFXC,1,Z ;TOTAL FILES PRINTED (FILES*COPIES)
;FORWARD SPACE / BACK SPACE PARAMETERS
LP J$FBPT,1 ;CURRENT PAGE TABLE POSITION
LP J$FPAG,PAGSIZ ;BACKSPACE PAGE TABLE
LP J$FCBC,1,Z ;CURRENT INPUT BUFFER BYTE COUNT
LP J$FTBC,1,Z ;TOTAL INPUT BYTE COUNT
LP J$FPIG,1,Z ;NUMBER OF PAGES TO IGNORE
;DISK FILE PARAMETERS
LP J$DIFN,1 ;THE IFN
LP J$DFDA,1 ;THE FD ADDRESS
LP J$DBPT,1 ;BUFFER BYTE POINTER
LP J$DBCT,1,Z ;BUFFER BYTE COUNT
;LOG FILE PARAMETERS
LP J$GBUF,^D10 ;ADDRESS OF LOG FILE BUFFERS
LP J$GBFR,PAGSIZ ;FIRST LOG FILE BUFFER
LP J$GNLN,1,Z ;NUMBER OF LINES WRITTEN IN LOG
LP J$GIBC,1,Z ;INTERNAL LOG BYTE COUNT
LP J$GIBP,1,Z ;INTERNAL LOG BYTE POINTER
LP J$GINP,1,Z ;NUMBER OF INTERNAL LOG PAGES
;PICTURE BLOCKS
LP J$PUSR,10 ;USER NAME
LP J$PNOT,4 ;/NOTE
LP J$PFL1,10 ;FIRST LINE OF FILE NAME
LP J$PFL2,12 ;SECOND LINE OF FILE NAME
LP J$PFLS,1 ;BLOCKSIZE FOR FILENAME
LP J$$END,1 ;END OF PARAMETER AREA
J$$LEN==J$$END-J$$BEG ;LENGTH OF PARAMETER AREA
;NOW GENERATE A BIT TABLE OF WHICH WORDS IN THE JOB DATA PAGE TO ZERO
; ON A NEW JOB
ZTABLE: ;PUT TABLE HERE
DEFINE ZTAB(A),<
IFNDEF ...Z'A,<...Z'A==0>
EXP ...Z'A
> ;END DEFINE ZTAB
Z==0
REPEAT <J$$LEN+^D35>/^D36,<
XLIST
ZTAB(\Z)
Z==Z+1
LIST
> ;END REPEAT
SUBTTL Random Impure Storage
PDL: BLOCK PDSIZE ;PUSHDOWN LIST
MESSAG: BLOCK 1 ;ADDRESS OF MESSAGE JUST RECEIVED
BLKADR: BLOCK 1 ;IPCF MSG BLK ADDR SAVE AREA
ACTFLG: BLOCK 1 ;-1 IF DOING ACCOUNTING
TEXTBP: BLOCK 1 ;BYTE POINTER FOR DEPBP
SAB: BLOCK SAB.SZ ;A SEND ARGUMENT BLOCK
MSGBLK: BLOCK MSBSIZ ;A BLOCK TO BUILD MESSAGES IN.
FOB: BLOCK FOB.SZ ;A FILE OPEN BLOCK
FMOPN: BLOCK 1 ;SET TO -1 WHEN LPFORM IN OPEN
FMIFN: BLOCK 1 ;THE IFN FOR LPFORM.INI
FMBYT: BLOCK 1 ;LPFORM.INI INPUT BYTE COUNT
FMPTR: BLOCK 1 ;LPFORM.INI INPUT BYTE POINTER.
LPCNF: BLOCK 10 ;SYSNAME
JOBITS: BLOCK 1 ;SAVE JOB STATUS BITS FLAG.
STRSEQ: EXP 4000 ;STREAM SEQ #'S (START AT 4000)
SCHEDL: -NPRINT,,0 ;STREAM SCHEDULING DATA
SLEEPT: BLOCK 1 ;SLEEP TIME FOR SCHEDULING.
CNTSTA: BLOCK 1 ;NUMBER OF THE CENTRAL STATION
RUTINE: BLOCK 1 ;MESSAGE PROCESSING ROUTINE ADDRESS.
TOPS20 <
SPLDIR: BLOCK 1 ;DIRECTORY NUMBER OF PS:<SPOOL>
> ;END TOPS20 CONDITIONAL
SUBTTL Resident JOB Database
STREAM: BLOCK 1 ;CURRENT STREAM NUMBER
JOBPAG: BLOCK NPRINT ;ADDRESS OF A FOUR PAGE BLOCK
; ONE FOR REQUEST, ONE FOR JOB PARAMS
; ONE FOR LPT BUFFER, ONE FOR LOG BUFFER
JOBOBA: BLOCK NPRINT ;TABLE OF OBJECT BLOCK ADDRESSES
JOBSTW: BLOCK NPRINT ;JOB STATUS WORD
JOBACT: BLOCK NPRINT ;-1 IF STREAM IS ACTIVE, 0 OTHERWISE
JOBOBJ: BLOCK 3*NPRINT ;LIST OF SETUP OBJECTS
JOBWKT: BLOCK NPRINT ;JOB WAKE TIME (FOR ALIGN)
JOBCHK: BLOCK NPRINT ;STREAM CHECKPOINT FLAG. (-1=YES,,0=NO)
JOBWAC: BLOCK NPRINT ;STREAM WTOR ACK CODE.
;SCHEDULER FLAGS
PSF%OB==1B1 ;OUTPUT BLOCKED
PSF%DO==1B2 ;DEVICE IS OFF-LINE
PSF%ST==1B3 ;STOPPED BY OPERATOR
PSF%OR==1B4 ;OPERATOR RESPONSE WAIT
PSF%AL==1B5 ;ALIGNMENT TIMER WAIT STATE.
PSF%OO==1B6 ;WAITING FOR 2780/3780 OPERATOR OUTPUT
DEFINE $DSCHD(FLAGS),<
PUSHJ P,DSCHD
XLIST
JUMP [EXP FLAGS]
LIST
SALL
> ;END DEFINE $DSCHD
SUBTTL IB and HELLO message blocks
TOPS10 <INTVEC==VECTOR>
TOPS20 <INTVEC==:LEVTAB,,CHNTAB>
IB: $BUILD IB.SZ ;
$SET(IB.PRG,,%%.MOD) ;SET UP PROGRAM NAME
$SET(IB.INT,,INTVEC) ;SET UP INTERRUPT VECTOR ADDRESS
$SET(IB.PIB,,PIB) ;SET UP PIB ADDRESS
$SET(IB.FLG,IP.STP,1) ;STOPCODES TO ORION
$EOB ;
PIB: $BUILD PB.MNS ;
$SET(PB.HDR,PB.LEN,PB.MNS) ;PIB LENGTH,,0
$SET(PB.FLG,IP.PSI,1) ;PSI ON
$SET(PB.INT,IP.CHN,0) ;INTERRUPT CHANNEL
$EOB ;
HELLO: $BUILD HEL.SZ ;
$SET(.MSTYP,MS.TYP,.QOHEL) ;MESSAGE TYPE
$SET(.MSTYP,MS.CNT,HEL.SZ) ;MESSAGE LENGTH
$SET(HEL.NM,,<'LPTSPL'>) ;PROGRAM NAME
$SET(HEL.FL,HEFVER,%%.QSR) ;QUASAR VERSION
$SET(HEL.NO,HENNOT,1) ;NUMBER OF OBJ TYPES
$SET(HEL.NO,HENMAX,NPRINT) ;MAX NUMBER OF JOBS
$SET(HEL.OB,,.OTLPT) ;LPT OBJECT TYPE
$EOB ;
OACERR: BLOCK 1 ;'OUTGET' ROUTINE RETURN CODE
SETMSG: [ASCIZ/Started/]
[ASCIZ/Not available right now/]
[ASCIZ/Does not exist/]
LIMSG: ASCIZ/
Type 'Respond <Number> ABORT' to Abort the Job
Type 'Respond <Number> IGNORE' to Ignore the Error/
SUBTTL $TEXT Utilities
DEPBP: IDPB S1,TEXTBP ;DEPOSIT THE BYTE
$RETT ;AND RETURN
;OPERATING SYSTEM DEPENDENT ITEXTS
;LOG FILE STAMPS
LPMSG: ITEXT(<^C/[-1]/ LPMSG >)
LPDAT: ITEXT(<^C/[-1]/ LPDAT >)
LPOPR: ITEXT(<^C/[-1]/ LPOPR >)
LPEND: ITEXT(<^C/[-1]/ LPEND >)
LPERR: ITEXT(<^C/[-1]/ LPERR ? >)
DATMON: ITEXT(< Date ^H/[-1]/ Monitor: ^T/LPCNF/ ^T7C*/0(T4)/>)
SUBTTL LPTSPL - Multiple Line Printer Spooler.
LPTSPL: RESET ;AS USUAL.
MOVE P,[IOWD PDSIZE,PDL] ;SET UP THE STACK.
MOVEI S1,IB.SZ ;GET THE IB SIZE.
MOVEI S2,IB ;ADDRESS OF THE IB.
PUSHJ P,I%INIT ;SET UP THE WORLD.
PUSHJ P,INTINI ;SET UP THE INTERRUPT SYSTEM.
SETOM ACTFLG ;TURN ON ACCOUNTING.
IFE ACCTSW,<
SETZM ACTFLG ;UNLESS HE DOESNT WANT IT.
>
PUSHJ P,OPDINI ;GET OPERATING SYSTEM INFO.
PUSHJ P,OPNFRM ;OPEN LPFORM.INI
PUSHJ P,I%ION ;TURN ON INTERRUPTS.
MOVEI T1,HELLO ;GET ADDRESS OF HELLO MESSAGE.
PUSHJ P,SNDQSR ;SAY HI TO QUASAR.
MOVSI P1,-NPRINT ;SET UP STREAM COUNTER.
;FALL THROUGH TO MAIN LOOP.
SUBTTL Idle Loop
MAIN: PUSHJ P,OPRCHK ;CHECK FOR DN60 OPERATOR MESSAGES
SKIPN JOBACT(P1) ;IS THE STREAM ACTIVE ???
JRST MAIN.2 ;NO,,GET THE NEXT STREAM.
HRRZM P1,STREAM ;RUNNABLE STREAM!!!
MOVE J,JOBPAG(P1) ;YES, GET JOB PAGE
PUSHJ P,CHKTIM ;SEE IF ITS TIME TO GET THE STREAM UP..
SKIPN JOBCHK(P1) ;DO WE WANT TO UPDATE THE JOB STATUS ??
JRST .+3 ;NO,,THEN SKIP THIS
PUSHJ P,UPDTST ;SEND A DEVICE STATUS MESSAGE
PUSHJ P,CHKPNT ;SEND A CHECKPOINT MESSAGE
SKIPE JOBSTW(P1) ;IS THE STREAM BLOCKED ???
JRST MAIN.2 ;YES,,GET THE NEXT STREAM.
MOVEM P1,SCHEDL ;SAVE THE SCHEDULING STREAM.
MOVSI 17,J$RACS(J) ;ELSE SETUP TO
BLT 17,17 ;GET SOME ACS
POPJ P, ;AND RETURN
MAIN.1: MOVE P1,SCHEDL ;GET THE LAST SCHEDULED STREAM.
SKIPN JOBCHK(P1) ;DO WE WANT TO UPDATE THE JOB STATUS ??
JRST .+3 ;NO,,THEN SKIP THIS
PUSHJ P,UPDTST ;YES,,SEND A DEVICE STATUS MESSAGE
PUSHJ P,CHKPNT ;YES,,SEND A CHECKPOINT MESSAGE
PUSHJ P,CHKTIM ;SET THE WAKEUP TIMER
MAIN.2: AOBJN P1,MAIN ;LOOP BACK FOR SOME MORE.
PUSHJ P,CHKQUE ;CHECK FOR INCOMMING MESSAGES.
SKIPE MESSAGE ;DID WE PROCESS A MESSAGE ???
JRST MAIN.3 ;YES,,CONTINUE PROCESSING
MOVE S1,SLEEPT ;NO,,PICK UP SLEEP TIME.
TOPS20 <
SKIPE JOBACT ;CHECK IF STREAM ACTIVE..
SKIPE JOBSTW ;ANY BLOCKING CONDITIONS
>;END TOPS20 CONDITIONAL
PUSHJ P,I%SLP ;ELSE,,GO WAIT
MAIN.3: MOVE P,[IOWD PDSIZE,PDL] ;RESET THE STACK POINTER.
SETZM SLEEPT ;SLEEP FOREVER
MOVSI P1,-NPRINT ;GET LOOP AC.
JRST MAIN ;KEEP ON PROCESSING.
SUBTTL CHKTIM - ROUTINE TO WAKE UP A STREAM AT A FUTURE TIME.
CHKTIM: MOVE S1,JOBSTW(P1) ;GET THE STREAMS SCHEDULING BITS
TXNN S1,PSF%AL ;IS IT WAITING ???
$RETT ;NO,,JUST RETURN
PUSHJ P,I%NOW ;YES,,GET CURRENT TIME.
SUB S1,JOBWKT(P1) ;CALCULATE THE NUMBER
IDIVI S1,3 ; OF SECONDS TO WAKE-UP.
JUMPGE S1,CHKT.1 ;IF TIME IS UP,,WAKE UP STREAM.
MOVMS S1 ;GET ABSOLUTE VALUE OF SECONDS.
CAILE S1,^D60 ;IF WAKE UP TIME IS GREATER THEN
MOVEI S1,^D60 ; 60 SECS,, THEN MAKE IT 60 SECS.
CAMGE S1,SLEEPT ;IF WAKE UP TIME IS LESS THEN
MOVEM S1,SLEEPT ;CURRENT WAKE UP TIME,,THEN RESET IT.
$RETF ;DO NOT WAKE UP THE JOB.
CHKT.1: MOVX S1,PSF%AL ;PICK UP ALIGN BLOCK BIT.
SKIPLE J$LREM(J) ;IS THIS A DN60 LPT ???
TXO S1,PSF%DO ;YES,,INCLUDE DEVICE OFFLINE
ANDCAM S1,JOBSTW(P1) ;TURN OFF STREAM WAIT STATE BIT.
$RETT ;WAKE UP THE STREAM.
SUBTTL Deschedule Process
;DSCHD is called by the $DSCHD macro to cause the "current" stream to
; be un-scheduled. The call is:
;
; $DSCHD(flags)
;
;which generates:
;
; PUSHJ P,DSCHD
; JUMP [EXP flags]
DSCHD: MOVEM 0,J$RACS(J) ;SAVE AC 0
MOVEI 0,J$RACS+1(J) ;PLACE TO PUT AC 1
HRLI 0,1 ;SETUP THE BLT POINTER
BLT 0,J$RACS+17(J) ;SAVE AWAY THE ACS
HRRZ S1,0(P) ;GET ADDRESS OF "JUMP [FLAGS]"
MOVE S1,@0(S1) ;GET THE FLAGS
MOVE S2,STREAM ;GET THE STREAM NUMBER
IORM S1,JOBSTW(S2) ;SET THE FLAGS
MOVE P,[IOWD PDSIZE,PDL] ;RESET THE STACK POINTER.
JRST MAIN.1 ;AND CONTINUE SCHEDULING.
SUBTTL NEXTJOB Message from QUASAR
NXTJOB: HRR S1,J ;GET 0,,DEST
HRL S1,M ;GET SOURCE,,DEST
LOAD S2,.MSTYP(M),MS.CNT ;GET LENGTH OF MESSAGE
ADDI S2,-1(J) ;GET ADR OF END OF BLT
BLT S1,(S2) ;BLT THE DATA
MOVE S1,STREAM ;GET STREAM NUMBER
SETOM JOBACT(S1) ;MAKE THE STREAM ACTIVE
SETOM JOBCHK(S1) ;CHECKPOINT FIRST CHANCE WE GET !!!
MOVX S2,PSF%OB+PSF%ST+PSF%OR+PSF%AL ;GET LOTS OF BITS
ANDCAM S2,JOBSTW(S1) ;CLEAR THEM
MOVEI S1,J$RPDL-1(J) ;POINT TO CONTEXT PDL
HRLI S1,-^D100 ;AND THE LENGTH
PUSH S1,[EXP DOJOB] ;PUSH THE FIRST ADR ON THE STACK
MOVEM S1,J$RACS+P(J) ;AND STORE THE PDL
SETZB S,J$RACS+S(J) ;CLEAR FLAGS AC
LOAD S1,.EQSPC(J),EQ.NUM ;GET NUMBER OF FILES
MOVEM S1,J$RFLN(J) ;STORE IT
MOVEI S1,J$$BEG(J) ;PREPARE TO ZERO SELECTED WORDS JOB AREA
MOVSI S2,-<J$$LEN+^D35>/^D36 ;AOBJN POINTER TO BIT TABLE
NXTJ.2: MOVEI T1,^D36 ;BIT COUNTER FOR THIS WORD
MOVE T2,ZTABLE(S2) ;GET A WORD FROM BIT TABLE
NXTJ.3: JUMPE T2,NXTJ.4 ;DONE IF REST OF WORD IS ZERO
JFFO T2,.+1 ;FIND THE FIRST 1 BIT
ADD S1,T3 ;MOVE UP TO THE CORRESPONDING WORD
SETZM 0(S1) ;AND ZERO IT
SUB T1,T3 ;REDUCE BITS LEFT IN THIS WORD
LSH T2,0(T3) ;SHIFT OFFENDING BIT TO BIT 0
TLZ T2,(1B0) ;AND GET RID OF IT
JRST NXTJ.3 ;AND LOOP
NXTJ.4: ADD S1,T1 ;ACCOUNT FOR THE REST OF THE WORD
AOBJN S2,NXTJ.2 ;AND LOOP
$TEXT(LOGCHR,<^M^J^I/LPDAT/LPTSPL version ^V/[%LPT]/ ^T/LPCNF/>)
MOVE S1,STREAM ;GET THE STREAM NUMBER
$TEXT(LOGCHR,<^I/LPDAT/Job ^W/.EQJOB(J)/ sequence #^D/.EQSEQ(J),EQ.SEQ/ on ^B/@JOBOBA(S1)/ at ^H/[-1]/>)
SKIPN T2,.EQCHK+CKFLG(J) ;GET THE CHECKPOINT FLAGS
JRST NXTJ.5 ;AND JUMP IF NEW JOB
MOVEI T1,[ASCIZ /system failure/]
TXNE T2,CKFREQ ;WAS IT A REQUEUE
MOVEI T1,[ASCIZ /requeue by operator/]
$TEXT(LOGCHR,<^I/LPMSG/Job being restarted after ^T/0(T1)/>)
NXTJ.5: LOAD S1,.EQSEQ(J),EQ.IAS ;IS THIS AN INVALID REQUEST ???
SKIPE S1 ;IS THIS AN INVALID REQUEST ???
$TEXT (LOGCHR,<^I/LPERR/Invalid Account String Specified (^T/.EQACT(J)/)>)
GETLIM T1,.EQLIM(J),OLIM ;GET PAGE LIMIT
MOVEM T1,J$RLIM(J) ;SAVE IT
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
PUSHJ P,ACTBEG ;GO SETUP THE ACCOUNTING PARMS
PUSHJ P,I%NOW ;GET TIME OF DAY
MOVEM S1,J$RTIM(J) ;SAVE IT AWAY
MOVE S1,STREAM ;GET STREAM NUMBER.
$WTOJ (Begin,<^R/.EQJBB(J)/>,@JOBOBA(S1))
PUSHJ P,TBFINI ;INITIALIZE THE BUFFER
PUSHJ P,CHKLPT ;GO MAKE SURE THE DEVICE IS ONLINE
$RETT ;AND RETURN
SUBTTL Do the Job
DOJOB: PUSHJ P,FORMS ;GET FORMS MOUNTED
JUMPF ENDREQ ;CANT DO IT,,END THE REQUEST
LOAD S1,.EQSEQ(J),EQ.IAS ;GET INVALID ACCOUNT STRING BIT
STORE S1,S,ABORT ;SAVE IT AS THE ABORT BIT
TXO S,BANHDR ;LITE 'PRINTING BANNERS' FLAG
PUSHJ P,JOBHDR ;PRINT THE BANNER
TXZ S,BANHDR ;CLEAR 'PRINTING BANNERS' FLAG
LOAD E,.EQLEN(J),EQ.LOH ;GET LENGTH OF HEADER
ADD E,J ;POINT TO FIRST FILE
SETZM J$RNFP(J) ;ZAP THE # OF FILES PRINTED
SKIPN .EQCHK+CKFLG(J) ;IS THIS A RESTARTED JOB?
JRST DOJO.4 ;NO, SKIP ALL THIS STUFF
MOVE T1,.EQCHK+CKFIL(J) ;YES, GET NUMBER OF FILES DONE
MOVEM T1,J$RNFP(J) ;STORE FOR NEXT CHECKPOINT
DOJO.1: SOJL T1,DOJO.2 ;DECREMENT AND JUMP IF SKIPED ENUF
LOAD S1,.FPINF(E),FP.FCY ;GET THE COPIES IN THIS REQUEST
ADDM S1,J$AFXC(J) ;ADD TO THE TOTAL COUNT
PUSHJ P,NXTFIL ;BUMP E TO NEXT SPEC
JUMPF DOJO.7 ;FINISH OFF IF DONE
JRST DOJO.1 ;LOOP SOME MORE
DOJO.2: MOVE S1,.EQCHK+CKCOP(J) ;GET NUMBER OF COPIES PRINTED
MOVEM S1,J$RNCP(J) ;SAVE FOR NEXT CHECKPOINT
ADDM S1,J$AFXC(J) ;ADD TO THE TOTAL FILE COUNT
MOVE S1,.EQCHK+CKTPP(J) ;GET THE TOTAL PAGES PRINTED.
SUBI S1,5 ;MAKE SURE WE DONT SCREW THINGS UP
SKIPGE S1 ;ALSO MAKE SURE WE ARE NOT NEGATIVE
SETZM S1 ;YES,,MAKE IT 0
MOVEM S1,J$APRT(J) ;AND SAVE IT
MOVE S1,.EQCHK+CKPAG(J) ;GET CHKPNT'ED PAGE
SUBI S1,5 ;MAKE SURE WE DONT MISS ANYTHING !!
SKIPGE S1 ;ALSO MAKE SURE WE ARE NOT NEGATIVE
SETZM S1 ;YES,,MAKE IT 0
MOVEM S1,J$RNPP(J) ;AND SAVE IT.
DOJO.4: LOAD S1,.FPFST(E) ;GET /START PARAMETER
MOVEM S1,J$FPIG(J) ;SAVE FOR FIRST COPY
PUSHJ P,FILE ;NO, PRINT THE FILE
TXNE S,RQB ;HAVE WE BEEN REQUEUED?
JRST ENDJOB ;YES, END NOW!!
AOS J$RNFP(J) ;BUMP THE FILE COUNT BY 1.
SETZM J$RNPP(J) ;CLEAR THE PAGES PER FILE COUNT
PUSHJ P,CHKPNT ;TAKE A CHECKPOINT
PUSHJ P,NXTFIL ;BUMP TO NEXT FILE
JUMPT DOJO.4 ;AND LOOP
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
DOJO.7: SKIPN E,J$RLFS(J) ;GET ADR OF LOG-SPEC
JRST ENDJOB ;NO, FINISH JOB
MOVE S1,J$APRT(J) ;GET NUMBER OF PAGES PRINTED
ADDI S1,LOGPAG ;ADD IN GUARANTEED LOG LIMIT
CAMLE S1,J$RLIM(J) ;DOES HE HAVE AT LEAST THAT MANY?
MOVEM S1,J$RLIM(J) ;NO, GIVE HIM THAT MANY
TXZ S,ABORT ;CLEAR ABORT FLAG
PUSHJ P,FILE ;PRINT THE FILE
JRST ENDJOB ;AND FINISH UP
SUBTTL NXTFIL - FIND AND RETURN THE NEXT FILE IN THE NEXTJOB MSG
NXTFIL: SETZM J$RNCP(J) ;CLEAR COPIES PRINTED
SOSG J$RFLN(J) ;DECREMENT FILE COUNT
$RETF ;NO MORE, DONE
LOAD S1,.FPLEN(E),FP.LEN ;GET THE FP LENGTH
ADD E,S1 ;BUMP TO THE FD
LOAD S1,.FDLEN(E),FD.LEN ;GET THE FD LENGTH
ADD E,S1 ;BUMP TO THE NEXT FP
LOAD S1,.FPINF(E),FP.FLG ;GET LOG FILE FLAG
JUMPE S1,.RETT ;RETURN IF NOT THE LOG FILE
MOVEM E,J$RLFS(J) ;SAVE ADDRESS OF LOG FILE SPEC
JRST NXTFIL ;AND LOOP
SUBTTL FILDIS - ROUTINE TO KEEP/DELETE PRINTED SPOOL FILES.
FILDIS: LOAD E,.EQLEN(J),EQ.LOH ;GET THE HEADER LENGTH.
ADD E,J ;POINT TO FIRST FILE .
LOAD T1,.EQSPC(J),EQ.NUM ;GET THE NUMBER OF FILES.
FILD.1: LOAD T2,.FPINF(E) ;GET THE FILE INFO BITS.
LOAD S2,.FPLEN(E),FP.LEN ;GET THE FILE INFO LENGTH.
ADD E,S2 ;POINT TO FILE SPEC.
MOVEM E,J$XFOB+FOB.FD(J) ;SAVE THE FD ADDRESS IN THE FOB
LOAD S2,.FPLEN(E),FD.LEN ;GET THE FD LENGTH.
ADD E,S2 ;POINT TO NEXT FILE.
MOVEI S1,FOB.SZ ;GET THE FOB LENGTH
MOVEI S2,J$XFOB(J) ;AND THE FOB ADDRESS
TXNE T2,FP.SPL+FP.DEL ;SPOOL FILE or /DELETE ???
PUSHJ P,F%DEL ;YES,,DELETE THE FILE.
SOJG T1,FILD.1 ;GO PROCESS THE NEXT FILE.
$RETT ;RETURN.
SUBTTL Print a File
FILE: TXNE S,ABORT ;ARE WE IN TROUBLE ???
$RETT ;YES,,JUST RETURN.
PUSHJ P,INPOPN ;OPEN THE INPUT FILE UP
JUMPF .POPJ ;LOSE, RETURN
$TEXT(LOGCHR,<^I/LPMSG/Starting File ^F/@J$DFDA(J)/>)
FILE.1: PUSHJ P,INPREW ;REWIND THE INPUT FILE
PUSHJ P,CHKPNT ;TAKE A CHECKPOINT
PUSHJ P,SETLST ;SETUP /REPORT CODE IF NECESSARY
TXZ S,FORWRD ;CLEAR FORWARD SPACE BIT
TXO S,BANHDR ;LITE 'PRINTING HEADERS' FLAG
PUSHJ P,HEAD ;PRINT THE HEADER
TXZ S,BANHDR ;CLEAR 'PRINTING HEADERS' FLAG
MOVEI S1,LPTERR ;GET NUMBER OF DEVICE ERRORS ALLOWED
MOVEM S1,J$LERR(J) ;AND SAVE IT
SOSLE J$FPIG(J) ;SUBTRACT 1 PAGE FROM STARTING PAGE #.
TXO S,FORWRD ;STILL POSITIVE,,TURN ON FORWARD BIT.
TXNE S,ABORT!SKPFIL!RQB ;DO WE REALLY WANT TO DO THIS ???
JRST FILE.2 ;NO,,CLEAN UP THE MESS.
PUSHJ P,FILOUT ;PRINT THE FILE
TXNE S,ABORT!SKPFIL!RQB ;ABORTED OR SKIPPED OR REQUEUED?
JRST FILE.2 ;YES, CONTINUE ON
LOAD T1,.FPFST(E) ;GET /START PARAMETER.
MOVEM T1,J$FPIG(J) ;SAVE STARTING POINT FOR THIS COPY.
AOS S1,J$RNCP(J) ;INCREMENT AND LOAD COPIES WORD
AOS J$AFXC(J) ;ADD 1 TO THE TOTAL FILE COUNT
LOAD S2,.FPINF(E),FP.FCY ;GET TOTAL NUMBER TO PRINT
CAMGE S1,S2 ;PRINTED ENOUGH?
JRST FILE.1 ;AND LOOP
FILE.2: MOVE S1,J$DIFN(J) ;GET THE IFN
PUSHJ P,F%REL ;RELEASE IT
$TEXT (LOGCHR,<^I/LPMSG/Finished File ^F/@J$DFDA(J)/>)
TXZ S,DSKOPN+SKPFIL+SUPFIL ;CLEAR LOTS OF BITS
POPJ P, ;AND RETURN
SUBTTL ENDJOB - END OF JOB PROCESSOR.
ENDJOB: TXO S,GOODBY ;FLAG EOJ SEQUENCE
TXZ S,FORWRD ;TURN OFF THE FORWARD SPACING BIT.
$TEXT (LOGCHR,<^I/LPEND/Summary:^D5/J$APRT(J)/ Pages of Output>)
TOPS10 <
$TEXT (LOGCHR,<^I/LPEND/ ^D5/J$ADRD(J)/ Disk Blocks Read>)
> ;END TOPS10 CONDITIONAL
TOPS20 <
MOVE S1,J$ADRD(J) ;GET THE NUMBER OF I/O REQUESTS
IMULI S1,SZ.BUF ;CALC NUMBER OF WORDS PROCESSED
IDIVI S1,PAGSIZ ;CALC NUMBER OF PAGES PROCESSED
SKIPE S2 ;ANY REMAINDER ???
ADDI S1,1 ;YES,,ADD 1 PAGE
MOVEM S1,J$ADRD(J) ;SAVE THE # 0F PAGES FOR ACCOUNTING
$TEXT (LOGCHR,<^I/LPEND/ ^D5/J$ADRD(J)/ Disk Pages Read>)
MOVX S1,.FHSLF ;LOAD FORK HANDLE
RUNTM ;GET RUNTIME
ADD S1,J$ARTM(J) ;GET CPU TIME USED
IDIVI S1,^D1000 ;CONVERT TO SECONDS
$TEXT (LOGCHR,<^I/LPEND/ ^D3R /S1/.^D3L0/S2/ Seconds CPU Time Used>)
> ;END TOPS20 CONDITIONAL
PUSHJ P,JOBTRL ;PRINT THE JOB TRAILERS.
PUSHJ P,OUTEOF ;FORCE ALL DATA OUT
ENDREQ: PUSHJ P,QRELEASE ;GO SEND THE RELEASE/REQUEUE MSG.
SETZM J$RACS+S(J) ;CLEAR ALL THE STATUS BITS.
MOVE S1,STREAM ;GET STREAM NUMBER
SETZM JOBACT(S1) ;NOT BUSY
JRST MAIN.3 ;RETURN TO THE SCHEDULER.
SUBTTL QRELEASE - ROUTINE TO SEND A REQUEUE/RELEASE MSG TO QUASAR.
QRELEA: MOVE S1,STREAM ;GET THE STREAM NUMBER.
$WTOJ (End,<^R/.EQJBB(J)/>,@JOBOBA(S1)) ;TELL THE OPERATOR.
SKIPE J$LREM(J) ;IF THIS IS A LOCAL LPT,,SKIP LOGGING
$LOG (Printed ^D/J$APRT(J)/ Pages,,@JOBOBA(S1)) ;LOG # OF PAGES
MOVEI S1,MSBSIZ ;GET BLOCK LENGTH
MOVEI S2,MSGBLK ;AND THE ADDRESS
PUSHJ P,.ZCHNK ;ZERO THE BLOCK
TXNE S,RQB ;IS THIS A REQUEUE?
JRST RELE.1 ;YES
PUSHJ P,FILDIS ;GO CLEAN UP THE SPOOL FILES.
PUSHJ P,ACTEND ;GO DO THE ACCOUNTING
MOVEI T1,MSGBLK ;GET ADDRESS OF THE BLOCK
LOAD S1,.EQITN(J) ;GET THE ITN
STORE S1,REL.IT(T1) ;STORE IT
MOVX S1,REL.SZ ;NO, GET RELEASE MESSAGE SIZE
MOVX S2,.QOREL ;AND FUNCTION
JRST RELE.2 ;AND MEET AT THE PASS
RELE.1: MOVEI T1,MSGBLK ;GET ADDRESS OF THE BLOCK
LOAD S1,.EQITN(J) ;GET THE ITN
STORE S1,REQ.IT(T1) ;STORE IT
LOAD S1,J$RNFP(J) ;GET NUMBER OF FILES PRINTED
STORE S1,REQ.IN+CKFIL(T1) ;STORE IT
LOAD S1,J$RNCP(J) ;GET COPIES PRINTED
STORE S1,REQ.IN+CKCOP(T1) ;STORE IT
LOAD S1,J$RNPP(J) ;GET PAGES PRINTED
STORE S1,REQ.IN+CKPAG(T1) ;AND STORE IT
LOAD S1,J$APRT(J) ;GET TOTAL PAGES PRINTED.
STORE S1,REQ.IN+CKTPP(T1) ;STORE IT
MOVX S1,CKFREQ ;GET REQEUE BIT
STORE S1,REQ.IN+CKFLG(T1) ;STORE IT
MOVX S1,RQ.HBO ;GET HOLD BY OPERATOR
STORE S1,REQ.FL(T1) ;STORE IN FLAG WORD
MOVX S1,REQ.SZ ;GET SIZE
MOVX S2,.QOREQ ;AND FUNCTION
RELE.2: STORE S1,.MSTYP(T1),MS.CNT ;STORE SIZE
STORE S2,.MSTYP(T1),MS.TYP ;AND CODE
PUSHJ P,SNDQSR ;SEND IT TO QUASAR
$RETT ;AND RETURN.
SUBTTL CHKQUE - ROUTINE TO RECIEVE AND SCHEDULE IPCF MESSAGES
CHKQUE: SETZM MESSAG ;NO MESSAGE YET
PUSHJ P,C%RECV ;RECEIVE A MESSAGE
JUMPF .POPJ ;RETURN,,NOTHING THERE.
SETZM BLKADR ;CLEAR THE IPCF MSG BLK ADDR SAVE AREA
LOAD S2,MDB.SI(S1) ;GET SPECIAL INDEX WORD
TXNN S2,SI.FLG ;IS THERE AN INDEX THERE?
JRST CHKQ.1 ;NO, IGNORE IT
ANDX S2,SI.IDX ;AND OUT THE INDEX
CAIE S2,SP.OPR ;IS IT FROM OPR?
CAIN S2,SP.QSR ;IS IT FROM QUASAR?
JRST CHKQ.2 ;YES, CONTINUE ON
CHKQ.1: PUSHJ P,C%REL ;RELEASE THE MESSAGE
POPJ P, ;RETURN TO THE SCHEDULER.
CHKQ.2: LOAD M,MDB.MS(S1),MD.ADR ;GET THE MESSAGE ADDRESS
MOVEM M,MESSAG ;SAVE IT AWAY
LOAD S2,.MSTYP(M),MS.TYP ;GET THE MESSAGE TYPE
MOVSI S1,-NMSGT ;MAKE AOBJN POINTER FOR MSG TYPES
CHKQ.3: HRRZ T1,MSGTAB(S1) ;GET A MESSAGE TYPE
CAMN S2,T1 ;MATCH?
JRST CHKQ.4 ;YES, WIN
AOBJN S1,CHKQ.3 ;NO, LOOP
PJRST C%REL ;NO,,RELEASE THE MESSAGE
CHKQ.4: HLRZ T2,MSGTAB(S1) ;PICK UP THE PROCESSING ROUTINE ADDRESS.
MOVEM T2,RUTINE ;SAVE THE ROUTINE ADDRESS.
PUSHJ P,CHKOBJ ;GO FIND THE OBJECT BLOCK.
JUMPF CHKQ.1 ;NOT THERE,,JUST DELETE IT
PUSHJ P,@RUTINE ;DISPATCH THE MESSAGE PROCESSOR.
SKIPN JOBITS ;DO WE WANT TO SAVE THE STATUS BITS ??
MOVEM S,J$RACS+S(J) ;YES,,SAVE THE STATUS BITS.
SETZM JOBITS ;CLEAR THE FLAG (DEFAULT TO ALWAYS SAVE)
PUSHJ P,C%REL ;RELEASE THE MESSAGE
POPJ P, ;RETURN TO THE SCHEDULER.
MSGTAB: XWD KILL,.QOABO ;ABORT MESSAGE
XWD CHKPNT,.QORCK ;REQUEST-FOR-CHECKPOINT
XWD NXTJOB,.QONEX ;NEXTJOB
XWD SETUP,.QOSUP ;SETUP/SHUTDOWN
XWD OACCON,.OMCON ;OPERATOR CONTINUE REQUEST.
XWD OACRSP,.OMRSP ;OPERATOR WTOR RESPONSE.
XWD OACREQ,.OMREQ ;OPERATOR REQUEUE REQUEST.
XWD OACCAN,.OMCAN ;OPERATOR CANCEL REQUEST.
XWD OACPAU,.OMPAU ;OPERATOR PAUSE/STOP REQUEST.
XWD OACFWS,.OMFWS ;OPERATOR FORWARD SPACE REQUEST.
XWD OACALI,.OMALI ;OPERATOR ALIGN REQUEST.
XWD OACSUP,.OMSUP ;OPERATOR SUPPRESS REQUEST.
XWD OACBKS,.OMBKS ;OPERATOR BACKSPACE REQUEST.
XWD QSRNWA,.QONWA ;QUASAR NODE-WENT-AWAY MESSAGE
XWD OPRD60,.OMDSP ;DN60 OPERATOR RESPONSE MESSAGE
NMSGT==.-MSGTAB
SUBTTL - CHKOBJ - ROUTINE TO VALIDATE QUASAR/ORION/OPR MSG OBJ BLKS.
;CALL: S1/OFFSET INTO MSGTAB
; S2/MESSAGE TYPE
;
;RET: STREAM/STREAM NUMBER
; J/DATA BASE ADDRESS
; S/STATUS BITS
CHKOBJ: CAIE S2,.OMRSP ;IS THIS AN OPERATOR RESPONSE ???
CAIN S2,.QOSUP ;IS THIS A SETUP/SHUTDOWN MESSAGE ??
$RETT ;YES,,JUST RETURN NOW.
CAIN S2,.OMDSP ;IS THIS A DN60 OPERATOR RESPONSE ???
$RETT ;YES,,JUST RETURN NOW.
CAIL S2,.OMOFF ;IS THIS AN OPR/ORION MSG ??
JRST CHKO.1 ;YES,,GO SET UP THE OBJ SEARCH.
XCT MSGOBJ(S1) ;GET THE OBJ BLK ADDRESS.
JRST CHKO.2 ;LETS MEET AT THE PASS.
CHKO.1: PUSHJ P,GETBLK ;GET A MESSAGE BLOCK
JUMPF .RETF ;NO MORE,,THATS AN ERROR
CAIE T1,.OROBJ ;IS THIS THE OBJECT BLOCK ???
JRST CHKO.1 ;NO,,GET THE NEXT MSG BLOCK
MOVE S1,T3 ;GET THE BLOCK DATA ADDRESS IN S1.
CHKO.2: PUSHJ P,FNDOBJ ;GO FIND THE OBJECT BLOCK.
JUMPF .RETF ;NOT THERE,,THATS AN ERROR.
$RETT ;RETURN.
MSGOBJ: MOVEI S1,ABO.TY(M) ;GET ABORT MSG OBJ ADDRESS.
MOVEI S1,RCK.TY(M) ;GET CHECKPOINT MSG OBJ ADDRESS.
MOVEI S1,.EQROB(M) ;GET NEXTJOB MSG OBJ ADDRESS.
SUBTTL GETBLK - ROUTINE TO BREAK DOWN AN IPCF MSG INTO ITS DATA BLOCKS
;CALL: M/ MESSAGE ADDRESS
;
;RET: T1/ BLOCK TYPE
; T2/ BLOCK LENGTH
; T3/ BLOCK DATA ADDRESS
GETBLK: SOSGE .OARGC(M) ;SUBTRACT 1 FROM THE BLOCK COUNT
$RETF ;NO MORE,,RETURN
SKIPN S1,BLKADR ;GET THE PREVIOUS BLOCK ADDRESS
MOVEI S1,.OHDRS+ARG.HD(M) ;NONE THERE,,GET FIRST BLOCK ADDRESS
LOAD T1,ARG.HD(S1),AR.TYP ;GET THE BLOCK TYPE
LOAD T2,ARG.HD(S1),AR.LEN ;GET THE BLOCK LENGTH
MOVEI T3,ARG.DA(S1) ;GET THE BLOCK DATA ADDRESS
ADD S1,T2 ;POINT TO THE NEXT MESSAGE BLOCK
MOVEM S1,BLKADR ;SAVE IT FOR THE NEXT CALL
$RETT ;RETURN TO THE CALLER
SUBTTL User CANCEL Request
KILL: TXNE S,GOODBY+ABORT ;CHECK SOME BITS
$RETT ;IF WE LEAVING, IGNORE IT ANYWAY
$TEXT(LOGCHR,<^I/LPMSG/Job canceled by user ^U/ABO.ID(M)/>)
MOVE S1,STREAM ;GET THE STREAM NUMBER.
MOVX S2,PSF%OR ;GET OPR RESP WAIT BIT
TDNE S2,JOBSTW(S1) ;ARE WE WAITING FOR THE OPERATOR ???
$KWTOR (JOBWAC(S1)) ;YES,,KILL THE WTOR
ANDCAM S2,JOBSTW(S1) ;ZAP THE OPR WAIT BIT
$WTOJ (<Canceled by User ^U/ABO.ID(M)/>,<^R/.EQJBB(J)/>,@JOBOBA(S1))
TXO S,ABORT ;LITE THE ABORT BIT
PUSHJ P,INPFEF ;FORCE END OF FILE
TXNE S,BANHDR ;ARE WE PRINTING BANNER/HEADER PAGES ???
$RETT ;YES,,JUST RETURN
PUSHJ P,OUTFLS ;NO,,FLUSH THE OUTPUT BUFFERS
JUMPF SHUTND ;CANT,,SHUT IT DOWN !!!
$RETT ;RETURN
SUBTTL QSRNWA - ROUTINE TO SHUTDOWN A STREAN WHOSE NODE HAS DROPPED
QSRNWA: MOVE S1,STREAM ;GET OUR STREAM NUMBER
MOVX S2,PSF%OR ;GET OPR RESP WAIT BIT
TDNE S2,JOBSTW(S1) ;ARE WE WAITING FOR THE OPERATOR ???
$KWTOR (JOBWAC(S1)) ;YES,,KILL THE WTOR
MOVE S1,J$DIFN(J) ;GET THE JFN
TXNE S1,DSKOPN ;IS THE SPOOL FILE OPEN ???
PUSHJ P,F%REL ;YES,,CLOSE IT
MOVX S1,%RSUNA ;GET NOT AVAILABLE RIGHT NOW BITS
PUSHJ P,RSETUP ;TELL QUASAR HE CAN HAVE THE OBJ BACK
PUSHJ P,SHUTND ;SHUT THE STREAM DOWN
$RETT ;AND RETURN
SUBTTL Request for Checkpoint
CHKPNT: MOVEI T1,MSGBLK ;LOAD THE ADDRESS OF THE MESSAGE BLK.
MOVX S1,CH.FCH!CH.FST ;GET CHECKPOINT AND STATUS FLAGS
STORE S1,CHE.FL(T1) ;AND STORE THEM
MOVE S1,J$RNFP(J) ;GET NUMBER OF FILES
MOVEM S1,CHE.IN+CKFIL(T1) ;STORE IT
MOVE S1,J$RNCP(J) ;GET NUMBER OF COPIES
MOVEM S1,CHE.IN+CKCOP(T1) ;AND STORE IT
MOVE S1,J$RNPP(J) ;GET NUMBER OF PAGES
MOVEM S1,CHE.IN+CKPAG(T1) ;AND STORE IT
MOVE S1,J$APRT(J) ;NUMBER OF PAGES PRINTED
MOVEM S1,CHE.IN+CKTPP(T1) ;AND STORE IT
LOAD S1,.EQITN(J) ;GET JOBS ITN
MOVEM S1,MSGBLK+CHE.IT ;AND STORE IT
MOVX S1,CKFCHK ;CHKPOINT FLAG
MOVEM S1,CHE.IN+CKFLG(T1) ;STORE IT
MOVEI S1,CHE.ST(T1) ;GET ADDRESS OF STATUS AREA
HRLI S1,(POINT 7,0) ;MAKE IT A BYTE POINTER
MOVEM S1,TEXTBP ;SAVE BYTE POINTER
$TEXT(DEPBP,<Started at ^C/J$RTIM(J)/, printed ^D/J$APRT(J)/ of ^D/J$RLIM(J)/ pages^0>)
HRRZ S1,TEXTBP ;GET THE BYTE POINTER
SUBI S1,MSGBLK-1 ;SUBTRACT START POINT
STORE S1,.MSTYP(T1),MS.CNT ;SAVE THE LENGTH
MOVX S1,.QOCHE ;GET THE FUNCTION CODE
STORE S1,.MSTYP(T1),MS.TYP
PJRST SNDQSR ;AND SEND IT
SUBTTL UPDTST - ROUTINE TO SEND STATUS UPDATES TO QUASAR
UPDTST: PUSHJ P,.SAVE1 ;SAVE P1
MOVE S1,STREAM ;GET THE STREAM NUMBER
MOVE S2,JOBSTW(S1) ;GET THE JOBS STATUS WORD
SETZM JOBCHK(S1) ;CLEAR THE UPDATE FLAG
MOVX P1,%RESET ;DEFAULT TO RESET
SKIPE J$APRG(J) ;ARE WE ALIGNING FORMS ???
MOVX P1,%ALIGN ;YES,,SAY SO
TXNE S2,PSF%OR ;ARE WE WAITING FOR OPR RESPONSE ???
MOVX P1,%OREWT ;YES,,SAY SO
TXNE S2,PSF%ST ;ARE WE STOPPED ???
MOVX P1,%STOPD ;YES,,SAY SO
TXNE S2,PSF%DO ;ARE WE OFFLINE ???
MOVX P1,%OFLNE ;YES,,SAY SO
TXNE S2,PSF%OO ;ARE WE WAITING FOR OPERATOR OUTPUT ???
MOVX P1,%OPRWT ;YES,,SAY SO
MOVEI T1,MSGBLK ;GET THE MESSAGE BLOCK ADDRESS
MOVEM P1,STU.CD(T1) ;SAVE THE STATUS
HRLZ P1,JOBOBA(S1) ;GET THE OBJECT BLOCK ADDRESS
HRRI P1,STU.RB(T1) ;GET DESTINATION ADDRESS
BLT P1,STU.RB+OBJ.SZ-1(T1) ;COPY THE OBJ BLK OVER TO THE MSG
MOVX S1,STU.SZ ;GET THE MESSAGE LENGTH
STORE S1,.MSTYP(T1),MS.CNT ;SAVE IT
MOVX S1,.QOSTU ;GET THE MESSAGE TYPE
STORE S1,.MSTYP(T1),MS.TYP ;SAVE IT
PUSHJ P,SNDQSR ;SEND IT OFF TH QUASAR
$RETT ;AND RETURN
SUBTTL SETUP/SHUTDOWN Message
SETUP: LOAD S1,SUP.FL(M) ;GET THE FLAGS
TXNE S1,SUFSHT ;IS IT A SHUTDOWN?
JRST SHUTDN ;IF SO,,SHUT IT DOWN !!!
SETZ T2, ;CLEAR A LOOP REG
SETU.1: SKIPN JOBPAG(T2) ;A FREE STREAM?
JRST SETU.2 ;YES!!
CAIGE T2,NPRINT-1 ;NO, LOOP THRU THEM ALL?
AOJA T2,SETU.1 ;NO, KEEP GOING
$STOP(TMS,Too many setups)
SETU.2: MOVEM T2,STREAM ;SAVE THE STREAM NUMBER
MOVEI S1,J$$END ;GET THE LPT DATA BASE LENGTH
ADDI S1,PAGSIZ-1 ;ROUND UP TO NEXT HIGHEST PAGE
IDIVI S1,PAGSIZ ;GET NUMBER OF PAGES IN S1
PUSHJ P,M%AQNP ;ALLOCATE THEM
PG2ADR S1 ;CONVERT TO AN ADDRESS
MOVEM S1,JOBPAG(T2) ;AND SAVE IT
MOVE J,S1 ;PUT IT IN J
SETZM JOBSTW(T2) ;CLEAR THE JOB STATUS WORD
MOVEM J,J$RACS+J(J) ;SAVE J AWAY
MOVEI S1,J$LBFR(J) ;LPT BUFFER ADDRESS
MOVEM S1,J$LBUF(J) ;STORE IT
MOVEI S1,J$GBFR(J) ;LOG FILE BUFFER PAGE (FIRST)
MOVEM S1,J$GBUF(J) ;SAVE IT AWAY
MOVE S2,T2 ;COPY OVER THE STREAM NUMBER
IMULI T2,OBJ.SZ ;GET OFFSET OF OBJECT BLOCK
ADDI T2,JOBOBJ ;ADD IN THE BASE
MOVEM T2,JOBOBA(S2) ;STORE OBJECT ADDRESS
MOVE S2,T2 ;GET DESTINATION OF BLT INTO S2
HRLI S2,SUP.TY(M) ;MAKE A BLT POINTER
BLT S2,OBJ.SZ-1(T2) ;BLT THE OBJECT BLOCK
SETZM J$LREM(J) ;DEFAULT TO LOCAL LPT
MOVE S1,SUP.NO(M) ;GET THIS GUYS NODE NAME
CAMN S1,CNTSTA ;IS IT A LOCAL LPT ???
JRST SETU.3 ;YES,,SKIP THIS
SKIPN SUP.CN(M) ;IS THIS A DN60 REMOTE ???
JRST [SETOM J$LREM(J) ;NO,,MUST BE DN200 - SET DN200 FLAG
JRST SETU.4 ] ;AND CONTINUE PROCESSING
HRLI S1,SUP.CN(M) ;DN60,,GET LINE CONDITIONING BLK ADDRESS
HRRI S1,J$DCND(J) ; AND WHERE TO PUT IT
BLT S1,J$DCND+CN$SIZ-1(J) ;COPY IT OVER
MOVEI S1,1 ;GET A 1 (DN60 FLAG)
MOVEM S1,J$LREM(J) ;MAKE THIS A DN60 REMOTE
MOVE S1,SUP.ST(M) ;GET THE DN60 FLAG WORD
MOVEM S1,J$DFLG(J) ;SAVE IT FOR LATER
JRST SETU.4 ;GO SETUP OUTPUT DEVICE
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
SETU.3: MOVE S1,SUP.ST(M) ;GET A POSSIBLE MAG TAPE DEVICE NAME
LOAD S2,SUP.FL(M),SPLTAP ;GET THE SPOOL-TO-TAPE BIT
SKIPE S2 ;ARE WE SPOOLING TO TAPE ???
MOVEM S1,J$MTAP(J) ;YES,,SAVE THE DEVICE NAME
SETU.4: SETOM J$LCHN(J) ;INDICATE NO OUTPUT CHANNEL YET.
PUSHJ P,OUTGET ;GET THE OUTPUT DEVICE
PUSH P,S1 ;SAVE THE RESPONSE CODE
PUSHJ P,RSETUP ;SEND THE RESPONSE TO SETUP MSG.
POP P,T2 ;GET THE RESPONSE CODE BACK
MOVE S1,STREAM ;GET STREAM NUMBER
AOS S2,STRSEQ ;ADD 1 TO THE STREAM SEQ #, PUT IN S2.
MOVEM S2,JOBWAC(S1) ;SAVE IT AS THE OPR WTOR ACK CODE.
$WTO (<^T/@SETMSG(T2)/>,,@JOBOBA(S1)) ;TELL THE OPR WHATS GOING ON.
CAIE T2,%RSUOK ;ALL IS OK?
JRST SHUTDN ;NO, SHUT IT DOWN
$RETT ;RETURN
SUBTTL SHUTDN - ROUTINE TO SHUT DOWN A LINE-PRINTER
SHUTDN: MOVEI S1,SUP.TY(M) ;GET THE OBJECT BLOCK ADDRESS
PUSHJ P,FNDOBJ ;FIND THE OBJECT BLOCK
JUMPF .RETT ;NO OBJECT,,THEN NOTHING TO SHUT DOWN
SHUTND: SKIPA T4,[EXP 0] ;INDICATE 'OUT OF STREAM' CONTEXT
SHUTIN: SETOM T4 ;INDICATE 'IN STREAM' CONTEXT
SKIPL J$LCHN(J) ;DO WE HAVE AN OUTPUT CHANNEL ???
PUSHJ P,OUTREL ;YES,,RELEASE THE OBJECT
MOVE S1,J$DIFN(J) ;GET THE SPOOL FILE IFN
TXZE S,DSKOPN ;IS THERE A FILE OPEN ???
PUSHJ P,F%REL ;YES,,CLOSE IT
SKIPE T4 ;ARE WE IN STREAM CONTEXT ???
MOVE P,[IOWD PDSIZE,PDL] ;YES,,GET A NEW STACK POINTER
MOVEI S1,J$$END ;GET THE LPT DATA BASE LENGTH
ADDI S1,PAGSIZ-1 ;ROUND UP TO NEXT HIGHEST PAGE
IDIVI S1,PAGSIZ ;GET NUMBER OF PAGES IN S1
MOVE S2,J ;GET THE JOBPAG ADDRESS
ADR2PG S2 ;CONVERT TO A PAGE NUMBER
PUSHJ P,M%RLNP ;RETURN THEM
PUSHJ P,M%CLNC ;GET RID OF UNWANTED PAGES.
SETOM JOBITS ;SAY WE DONT WANT TO SAVE STATUS BITS.
MOVE S1,STREAM ;GET OUR STREAM NUMBER
SETZM JOBPAG(S1) ;CLEAR THE PAGE WORD
SETZM JOBACT(S1) ;AND THE ACTIVE WORD
JUMPE T4,.RETT ;'OUT OF STREAM',,JUST RETURN
JRST MAIN.3 ;'IN STREAM',,RETURN TO THE SCHEDULER
SUBTTL RSETUP - ROUTINE TO SEND A RESPONSE-TO-SETUP MSG TO QUASAR
RSETUP: MOVE T2,S1 ;SAVE THE SETUP CONDITION CODE.
MOVEI S1,RSU.SZ ;GET MESSAGE LENGTH
MOVEI S2,MSGBLK ;AND THE ADDRESS OF THE BLOCK
PUSHJ P,.ZCHNK ;ZERO IT OUT
MOVEI T1,MSGBLK ;GET THE BLOCK ADDRESS
MOVX S1,RSU.SZ ;GET MESSAGE SIZE
STORE S1,.MSTYP(T1),MS.CNT ;STORE IT
MOVX S1,.QORSU ;GET FUNCTION CODE
STORE S1,.MSTYP(T1),MS.TYP ;STORE IT
MOVE S1,STREAM ;GET STREAM NUMBER
MOVS S1,JOBOBA(S1) ;GET OBJADR,,0
HRRI S1,RSU.TY(T1) ;AND PLACE TO MOVE IT TO
BLT S1,RSU.TY+OBJ.SZ-1(T1) ;AND MOVE THE OBJECT BLOCK
STORE T2,RSU.CO(T1) ;STORE THE RESPONSE CODE
MOVX S1,OBDLLC ;GET LOWER-CASE BIT
SKIPL J$LLCL(J) ;IS PRINT LOWER CASE?
MOVX S1,OBDLUC ;NO, LOAD THE UPPER CASE FLAG
STORE S1,RSU.DA(T1) ;STORE THE DEVICE ATRRIBUTES
PUSHJ P,SNDQSR ;AND SEND THE MESSAGE
$RETT ;RETURN.
SUBTTL OACRSP - OPERATOR RESPONSE TO A WTOR PROCESSOR.
OACRSP: MOVE S2,.MSCOD(M) ;GET WTOR ACK CODE.
MOVSI S1,-NPRINT ;CREATE AOBJN AC.
RESP.1: CAME S2,JOBWAC(S1) ;COMPARE ACK CODES..
JRST [AOBJN S1,RESP.1 ;NOT EQUAL,,CHECK NEXT STREAM.
$RETT ] ;NOT THERE,,FLUSH THE MSG.
MOVX S2,PSF%OR ;GET "OPERATOR-RESPONSE" WAIT BIT
ANDCAM S2,JOBSTW(S1) ;AND CLEAR IT
SETOM JOBCHK(S1) ;CHECKPOINT NEXT SCHEDULING PASS
MOVE J,JOBPAG(S1) ;GET THE STREAM DB ADDRESS.
MOVE S,J$RACS+S(J) ;GET THE STREAM STATUS BITS.
DMOVE S1,.OHDRS+ARG.DA(M) ;GET THE OPERATORS RESPONSE.
DMOVEM S1,J$RESP(J) ;AND SAVE IT.
$RETT ;AND RETURN
SUBTTL OACCAN - Operator CANCEL request.
OACCAN: PUSHJ P,.SAVE1 ;SAVE P1 FOR A MINUTE
MOVE P1,STREAM ;GET STREAM NUMBER.
$ACK (Aborting,<^R/.EQJBB(J)/>,@JOBOBA(P1),.MSCOD(M)) ;TELL THE OPR.
SETZM J$APRG(J) ;ALIGNMENT NOT SCHEDULED,,NOT ACTIVE !!
SETZM JOBWKT(P1) ;SET WAKE UP TIME TO NOW.
SETZM RSNFLG ;SHOW NO REASON GIVEN.
MOVX S1,PSF%OR ;GET OPR RESP WAIT BIT
TDNE S1,JOBSTW(P1) ;ARE WE WAITING FOR THE OPERATOR ???
$KWTOR (JOBWAC(P1)) ;YES,,KILL THE WTOR
ANDCAM S1,JOBSTW(P1) ;ZAP THE OPR WAIT BIT
OACC.0: PUSHJ P,GETBLK ;GET A MESSAGE BLOCK
JUMPF OACC.2 ;NO MORE,,FINISH UP
CAIN T1,.ORREA ;IS THIS THE REASON BLOCK ???
MOVEM T3,RSNFLG ;YES,,SAVE THE REASON ADDRESS
CAIE T1,.CANTY ;IS THIS THE CANCEL TYPE BLOCK ???
JRST OACC.0 ;NO,,SKIP IT AND GET NEXT BLOCK
;YES...
MOVE S1,0(T3) ;LOAD THE CANCEL TYPE.
CAIE S1,.CNPRG ;IS IT /PURGE ???
JRST OACC.0 ;NO,,PROCESS THE NEXT MSG BLK
MOVE S1,J$DIFN(J) ;GET THE FILE IFN.
TXZE S,DSKOPN ;DONT CLOSE IF ITS NOT OPEN.
PUSHJ P,F%REL ;ELSE,,CLOSE IT OUT.
MOVEM S,J$RACS+S(J) ;SAVE THE 'S' AC WITH NEW DSKOPN BITS
PUSHJ P,OUTFLS ;FLUSH THE OUTPUT BUFFERS
JUMPF SHUTND ;CANT,,SHUT IT DOWN
PUSHJ P,SENDFF ;OUTPUT A FORM FEED FOR NEXT JOB
SETZM JOBACT(P1) ;STREAM IS NO LONGER ACTIVE
PUSHJ P,QRELEASE ;RELEASE THE REQUEST
PUSHJ P,OUTEOF ;OUTPUT AN EOF
$RETT ;AND RETURN
OACC.2: $TEXT(LOGCHR,<^I/LPOPR/Job Aborted by the Operator>)
SKIPE RSNFLG ;WAS A REASON GIVEN ???
$TEXT (LOGCHR,<^I/LPOPR/ REASON: ^T/@RSNFLG/>) ;YES,,SAY SO
SKIPN RSNFLG ;WAS A REASON GIVEN ???
$TEXT (LOGCHR,<^I/LPOPR/ No reason given>) ;NO,,SAY SO
TXO S,ABORT ;TELL LPTSPL WE ARE LEAVING.
TXNE S,GOODBY ;ARE WE ON OUR WAY OUT ???
$RETT ;YES,,JUST RETURN
PUSHJ P,INPFEF ;FORCE SPOOL FILE EOF
TXNE S,BANHDR ;ARE WE PRINTING BANNER/HEADER PAGES ???
$RETT ;YES,,JUST RETURN
PUSHJ P,OUTFLS ;NO,,FLUSH THE OUTPUT BUFFERS
JUMPF SHUTND ;CANT,,SHUT IT DOWN
$RETT ;FUNCTION COMPLETE !!!
RSNFLG: 0,,0
SUBTTL OACSUP - Operator SUPPRESS request.
OACSUP: TXNE S,ABORT+RQB+GOODBY ;ARE WE ON OUR WAY OUT ???
PJRST TOOBAD ;YES,,SKIP THIS.
OACS.0: PUSHJ P,GETBLK ;GET A MESSAGE BLOCK
JUMPF .RETT ;NO MORE,,JUST RETURN
CAIN T1,.SUPFL ;IS IT SUPPRESS FILE ???
PJRST OACS.1 ;YES,,THEN GO PROCESS IT AND RETURN
CAIN T1,.SUPJB ;IS IT SUPPRESS JOB ???
JRST OACS.2 ;YES,,THEN GO PROCESS IT AND RETURN
CAIE T1,.SUPST ;IS IT STOP SUPPRESSION ???
JRST OACS.0 ;NO,,GO PROCESS NEXT MSG BLOCK
TXZ S,SUPJOB!SUPFIL ;TURN OFF SUPPRESS FILE AND JOB BIT
$TEXT (LOGCHR,<^I/LPOPR/Operator stopped carriage control supression>)
MOVE S1,STREAM ;GET STREAM NUMBER.
$ACK (Carriage control activated,<^R/.EQJBB(J)/>,@JOBOBA(S1),.MSCOD(M))
$RETT ;RETURN NOW
OACS.1: TXO S,SUPFIL ;TURN ON SUPPRESS FILE BIT.
TXZ S,SUPJOB ;TURN OFF SUPPRESS JOB BIT.
MOVEI S1,[ASCIZ/this file/] ;GET THIS FILE MSG.
JRST OACS.3 ;LETS MEET AT THE PASS
OACS.2: TXO S,SUPJOB ;TURN ON SUPPRESS JOB BIT.
TXZ S,SUPFIL ;TURN OFF SUPPRESS FILE BIT.
MOVEI S1,[ASCIZ/this job/] ;GET THIS JOB MSG.
OACS.3: $TEXT(LOGCHR,<^I/LPOPR/Operator suppressed carriage control for rest of ^T/0(S1)/>)
MOVE S1,STREAM ;GET STREAM NUMBER.
$ACK (Carriage control suppressed,<^R/.EQJBB(J)/>,@JOBOBA(S1),.MSCOD(M))
$RETT ;RETURN NOW
SUBTTL OACPAU - Operator PAUSE request.
OACPAU: MOVX S2,PSF%ST ;LOAD THE STOP BIT
MOVE S1,STREAM ;GET THE STREAM NUMBER
IORM S2,JOBSTW(S1) ;SET IT
$ACK (Stopped,,@JOBOBA(S1),.MSCOD(M)) ;TELL THE OPERATOR.
SETOM JOBCHK(S1) ;SAY WE WANT A CHECKPOINT TAKEN.
$RETT ;AND RETURN
SUBTTL OACCON - Operator CONTINUE request.
OACCON: MOVE S1,STREAM ;GET THE STREAM NUMBER
MOVX S2,PSF%ST ;LOAD THE BITS
ANDCAM S2,JOBSTW(S1) ;CLEAR IT
$ACK (Continued,,@JOBOBA(S1),.MSCOD(M)) ;TELL THE OPERATOR.
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT.
$RETT ;AND RETURN
SUBTTL OACREQ - Operator REQUEUE request.
OACREQ: TXNE S,GOODBY ;IS IT TOO LATE FOR THIS ???
PJRST TOOBAD ;YES,,TOUGH LUCK !!!
PUSHJ P,INPFEF ;FORCE AN INPUT EOF
TXO S,RQB+ABORT ;LITE THE REQUEUE+ABORT BITS
$TEXT(LOGCHR,<^I/LPOPR/Job requeued by the the operator>)
MOVE S1,STREAM ;GET THE STREAM NUMBER
$ACK (Requeued,<^R/.EQJBB(J)/>,@JOBOBA(S1),.MSCOD(M)) ;TELL OPR
MOVX S2,PSF%OR ;GET OPR RESP WAIT BIT
TDNE S2,JOBSTW(S1) ;ARE WE WAITING FOR THE OPERATOR ???
$KWTOR (JOBWAC(S1)) ;YES,,KILL THE WTOR
ANDCAM S2,JOBSTW(S1) ;ZAP THE OPR WAIT BIT
OACR.0: PUSHJ P,GETBLK ;GET A MESSAGE BLOCK
JUMPF .RETT ;NO MORE,,RETURN
CAIN T1,.REQTY ;IS THIS THE REQUEST TYPE BLOCK ???
JRST OACR.1 ;YES,,GO PROGESS IT
CAIN T1,.ORREA ;IS THIS THE REASON BLOCK ???
$TEXT (LOGCHR,<^I/LPOPR/Requeue reason is: ^T/0(T3)/.>)
JRST OACR.0 ;PROCESS THE NEXT MSG BLOCK
OACR.1: MOVE S1,0(T3) ;PICK UP THE REQUEUE CODE.
SETZ S2, ;ZERO AC 2
CAXN S1,.RQCUR ;/CURRENT?
JRST OACR.3 ;YES, DO IT
SETZM J$RNPP(J) ;CLEAR CURRENT PAGE NUMBER
CAXN S1,.RQBCP ;BEGINNING OF COPY?
MOVEI S2,[ASCIZ /current copy/]
JUMPN S2,OACR.2 ;AND CONTINUE ON
SETZM J$RNCP(J) ;CLEAR CURRENT COPY NUMBER
CAXN S1,.RQBFL ;FROM BEGINING OF FILE?
MOVEI S2,[ASCIZ /current file/]
JUMPN S2,OACR.2 ;AND CONTINUE ON
SETZM J$RNFP(J) ;CLEAR FILE COUNT
MOVEI S2,[ASCIZ /job/] ;FROM BEGINNING OF JOB
OACR.2: $TEXT(LOGCHR,<^I/LPOPR/Job will restart at the beginning of the ^T/0(S2)/>)
JRST OACR.0 ;GO PROCESS THE NEXT MSG BLOCK.
OACR.3: $TEXT(LOGCHR,<^I/LPOPR/Job will restart at the current position>)
MOVNI S1,2 ;LOAD -2
ADDM S1,J$RNPP(J) ;INSURE NO LOSSAGE OF DATA
ADDM S1,J$APRT(J) ;HERE ALSO
SKIPGE J$RNPP(J) ;MAKE SURE WE DIDN'T SCREW THINGS UP
SETZM J$RNPP(J) ;YES,,ZERO THE PAGES PER COPY
SKIPGE J$APRT(J) ;CHECK HERE ALSO
SETZM J$APRT(J) ;NO GOOD,,SET IT TO ZERO
JRST OACR.0 ;GO PROCESS THE NEXT MSG BLOCK
SUBTTL OACALI - Routine to process Operator ALIGN request.
; J$APRG(J) :: [?,,-1] = ALIGN IN PROGRESS.
; [-1,,?] = ALIGN NEEDS TO BE SCHEDULED.
OACALI: TXNE S,ABORT+RQB+GOODBY ;ARE WE ON OUR WAY OUT ???
PJRST TOOBAD ;YES,,SKIP THIS.
SETZM FDADDR ;RESET ALIGN FD ADDRESS.
OALI.0: PUSHJ P,GETBLK ;GET A MESSAGE DATA BLOCK
JUMPF OALI.1 ;NO MORE,,CONTINUE PROCESSING
MOVE S1,0(T3) ;GET THE FIRST DATA WORD IN THE BLOCK
MOVEI T3,-1(T3) ;POINT TO THE BLOCK HEADER
CAIN T1,.ALPAU ;IS THIS THE /PAUSE BLOCK ???
MOVEM S1,J$ASLP(J) ;YES,,SAVE THE SLEEP TIME
CAIN T1,.ALRPT ;IS THE THE /REPEAT-COUNT BLOCK ???
MOVEM S1,J$ACNT(J) ;YES,,SAVE THE REPEAT-COUNT
CAIN T1,.CMIFI ;IS THIS THE FILE-SPEC BLOCK ???
MOVEM T3,FDADDR ;SAVE THE FD ADDRESS
CAIN T1,.ALSTP ;IS THIS THE /STOP BLOCK ???
PJRST OALI.6 ;YES,,GO PROCESS IT AND RETURN
JRST OALI.0 ;NONE OF THESE,,TRY NEXT BLOCK
OALI.1: SKIPN J$APRG(J) ;ARE WE ALREADY ALIGNING ???
JRST OALI.2 ;NO,,THEN WE'RE OK
MOVE S1,STREAM ;YES,,GET STREAM NUMBER.
$ACK (ALIGN already in progress,,@JOBOBA(S1),.MSCOD(M))
$RETT ;RETURN NOW.
OALI.2: MOVEI S1,FOB.SZ ;PICK UP FOB SIZE.
MOVEI S2,J$XFOB(J) ;PICK UP FOB ADDRESS.
PUSHJ P,.ZCHNK ;ZERO OUT THE FOB BLOCK.
MOVEI S1,7 ;PICK UP ASCII BYTE SIZE
STORE S1,J$XFOB+FOB.CW(J),FB.BSZ ;AND SAVE IT IN FOB.
SKIPN S1,FDADDR ;SKIP FD GEN IF USER SPECIFIED.
PUSHJ P,BLDLFD ;GO BUILD THE ALIGN FD.
STORE S1,J$XFOB+FOB.FD(J) ;AND SAVE ITS ADDRESS IN FOB.
MOVEI S1,FOB.SZ ;PICK UP THE FOB SIZE.
MOVEI S2,J$XFOB(J) ;PICK UP THE FOB ADDRESS.
PUSHJ P,F%IOPN ;OPEN THE ALIGN FILE.
JUMPF OALI.3 ;IF AN ERROR, RETURN WITH WTO.
MOVEM S1,J$AIFN(J) ;SAVE THE FILE ID.
SKIPG S1,J$ACNT(J) ;PICK UP USER DEFINED REPEAT-COUNT.
SKIPLE S1,J$FALC(J) ;ELSE PICK UP LPFORM.INI REPEAT-CNT.
SKIPA ;SKIP DEFAULT.
MOVE S1,D$ALCN ;PICK UP THE DEFAULT REPEAT COUNT.
MOVEM S1,J$ACNT(J) ;SAVE THE REPEAT-COUNT.
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
SKIPG S1,J$ASLP(J) ;PICK UP USER SLEEP TIME.
SKIPLE S1,J$FALS(J) ;ELSE, PICK UP LPFORM.INI SLEEP-TIME.
SKIPA ;SKIP THE DEFAULT.
MOVE S1,D$ALSL ;PICK UP THE DEFUALT SLEEP-TIME.
IMULI S1,3 ;CONVERT TO UNIVERSAL TIME.
MOVEM S1,J$ASLP(J) ;AND SAVE IT.
SETOM J$APRG(J) ;SHOW WE ARE DOING AN ALIGN,
; AND THAT IT NEEDS TO BE SCHEDULED.
MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (Alignment Scheduled,,@JOBOBA(S1)) ;TELL THE OPERATOR.
SETOM JOBCHK(S1) ;SAY WE WANT A CHECKPOINT.
$RETT ;RETURN.
OALI.3: MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (<^E/[-1]/>,<Cannot read ALIGN file ^F/@J$XFOB+FOB.FD(J)/>,@JOBOBA(S1))
$RETT
OALI.6: SKIPE J$APRG(J) ;ARE WE ALREADY ALIGNING ???
JRST OALI.7 ;IF SO,,CONTINUE PROCESSING.
MOVE S1,STREAM ;GET STREAM NUMBER
$ACK (</STOP Illegal>,Alignment not in Progress,@JOBOBA(S1),.MSCOD(M))
$RETT
OALI.7: MOVE S1,J$AIFN(J) ;GET THE ALIGN IFN.
SETOB S2,J$ABYT(J) ;SET ALIGN FILE BYTE COUNT TO -1.
PUSHJ P,F%POS ;POSITION TO ALIGN EOF.
SETZM J$ACNT(J) ;SET REPEAT-COUNT TO 0.
MOVE S1,STREAM ;GET STREAM NUMBER
$ACK (Alignment Discountinued,,@JOBOBA(S1),.MSCOD(M))
$RETT ;AND RETURN
FDADDR: 0,,0
SUBTTL OACFWS - OPERATOR FORWARD SPACE COMMAND PROCESSOR.
OACFWS: TXNE S,ABORT+RQB+GOODBY ;ARE WE ON OUR WAY OUT ???
PJRST TOOBAD ;YES,,SKIP THIS.
MOVE S1,STREAM ;GET THE STREAM NUMBER.
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT.
OACF.0: PUSHJ P,GETBLK ;GET A MESSAGE BLOCK
JUMPF .RETT ;NO MORE,,RETURN
CAIN T1,.SPPAG ;IS THIS FORWARD SPACE PAGES ???
PJRST FSPACE ;YES,,DO IT
CAIN T1,.SPCPY ;IS THIS FORWARD SPACE COPIES ???
PJRST FCOPYS ;YES,,DO IT
CAIN T1,.SPFIL ;IS THIS FORWARD SPACE 1 FILE ???
PJRST FFILES ;YES,,DO IT
JRST OACF.0 ;NONE OF THESE,,TRY NEXT BLOCK
FSPACE: TXNN S,DSKOPN ;IS THERE A SPOOL FILE OPEN ???
$RETT ;NO,,JUST IGNORE THIS
TXO S,FORWRD ;TURN ON FORWARD SPACE BIT.
MOVE S2,0(T3) ;PICK UP # OF PAGES TO FSPACE.
MOVEM S2,J$FPIG(J) ;SAVE THE VALUE.
MOVE S1,STREAM ;PICK UP THE STREAM NUMBER.
$ACK (<Forward spaced ^D/S2/ Pages>,,@JOBOBA(S1),.MSCOD(M))
$TEXT (LOGCHR,<^I/LPMSG/File ^F/@J$DFDA(J)/ Forward spaced ^D/J$FPIG(J)/ Pages>)
$RETT ;AND RETURN
FCOPYS: MOVE S2,0(T3) ;PICK UP THE # OF COPIES TO FSPACE.
ADDM S2,J$RNCP(J) ;ADD TO # OF COPIES ALREADY PRINTED.
$TEXT (LOGCHR,<^I/LPMSG/File ^F/J$DFDA(J)/ Forward spaced ^D/S2/ Copies>)
MOVE S1,STREAM ;PICK UP THE STREAM NUMBER.
$ACK (<Forward Spaced ^D/S2/ Copies>,,@JOBOBA(S1),.MSCOD(M))
PUSHJ P,INPFEF ;FORCE AN END-OF-FILE.
$RETT ;AND RETURN
FFILES: MOVE S1,STREAM ;PICK UP THE STREAM NUMBER
$ACK (Forward Spaced 1 File,,@JOBOBA(S1),.MSCOD(M))
$TEXT (LOGCHR,<^I/LPMSG/File ^F/J$DFDA(J)/ Skipped by Operator>)
PUSHJ P,INPFEF ;FORCE AN END OF FILE
TXO S,SKPFIL ;TURN ON SKIP FILE FLAG
$RETT ;AND RETURN
SUBTTL - BACK SPACE operator action routine.
OACBKS: TXNE S,ABORT+RQB+GOODBY ;ARE WE ON OUR WAY OUT ???
PJRST TOOBAD ;YES,,SKIP THIS.
MOVE S1,STREAM ;GET THE STREAM NUMBER.
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT.
OACB.0: PUSHJ P,GETBLK ;GET A MESSAGE DATA BLOCK
JUMPF .RETT ;NO MORE,,JUST RETURN
MOVE S1,T3 ;GET THE DATA ADDRESS IN S1.
CAIN T1,.SPPAG ;IS THIS BACKSPACE 'PAGES' ???
PJRST BSPACE ;YES,,GO PROCESS IT
CAIN T1,.SPCPY ;IS IT BACKSPACE COPIES ???
PJRST BCOPYS ;YES,,GO PROCESS IT
CAIN T1,.SPFIL ;IS IT BACKSPACE FILES ???
PJRST BFILES ;YES,,GO PROCESS IT
JRST OACB.0 ;NONE OF THESE,,TRY NEXT BLOCK
BSPACE: MOVE T1,0(S1) ;PICK UP THE NUMBER OF PAGES TO BSPACE.
MOVE S1,STREAM ;PICK UP STREAM NUMBER.
$ACK (<Backspaced ^D/T1/ Pages>,,@JOBOBA(S1),.MSCOD(M))
$TEXT (LOGCHR,<^I/LPMSG/File ^F/@J$DFDA(J)/ Backspaced ^D/T1/ Pages>)
TXNN S,DSKOPN ;IS THE SPOOL FILE OPEN ???
$RETT ;NO,,JUST RETURN.
SETOM J$DBCT(J) ;RESET THE INPUT BYTE COUNT
SETZM J$FPIG(J) ;ZERO THE FORWARD SPACE PAGE COUNTER
SETZM J$FCBC(J) ;CLEAR THE CURRENT INPUT BUFFER BYTE CNT
MOVE S1,J$FLIN(J) ;GET LINES PER PAGE
MOVEM S1,J$XPOS(J) ;RESET THE PAGE POSITION TO TOP OF PAGE
MOVX S1,.CHFFD ;GET A FORM FEED
MOVEM S1,J$RACS+C(J) ;CONVERT NXT CHAR TO FORM FEED
MOVE S1,J$RNPP(J) ;GET THE # OF PAGES PRINTED SO FAR.
SUB S1,T1 ;CALC DESTINATION PAGE NUMBER
SKIPGE S1 ;CAN'T BE NEGATIVE
SETZM S1 ;IF SO,,MAKE IT ZERO
MOVEM S1,J$RNPP(J) ;RESET PAGE POINTER FOR THIS FILE
JUMPLE S1,BSPA.2 ;MORE THEN WE PRINTED,,JUST REWIND FILE
CAXLE T1,PAGSIZ ;REQUESTING MORE THEN WE'RE TRACKING ??
JRST BSPA.2 ;YES,,REWIND THE FILE
MOVE S2,J$FBPT(J) ;GET THE PAGE TABLE ENTRY POINTER
SUBI S2,J$FPAG(J) ;CALC INDEX TO CURRENT PAGE
SUBI S2,1(T1) ;CALC INDEX TO NEW PAGE
JUMPGE S2,BSPA.1 ;IF POSITIVE,,THEN NO PROBLEM
TXNN S,FBPTOV ;ELSE CHECK FOR PAGE TABLE OVERFLOW
JRST BSPA.2 ;NO,,HMMMMM,,JUST REWIND THE FILE
ADDI S2,J$FPAG+PAGSIZ(J) ;GET TABLE ENTRY FROM THE TOP
SKIPA ;SKIP NON OVERFLOW PATH
BSPA.1: ADDI S2,J$FPAG(J) ;GET TABLE ENTRY FROM THE BOTTOM
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
MOVEI S1,1(S2) ;POINT TO NEXT PAGE TBL ENTRY
MOVEM S1,J$FBPT(J) ;AND MAKE THIS THE CUR TBL ENTRY ADDR
MOVE S2,0(S2) ;PICK UP THE LISTING PAGE ADDRESS
MOVEM S2,J$FTBC(J) ;AND MAKE THIS THE TOTAL BUFR BYTE COUNT
MOVE S1,J$DIFN(J) ;GET THE SPOOL FILE IFN
PUSHJ P,F%POS ;POSITION TO THAT PAGE IN THE FILE
$RETT ;AND RETURN
BSPA.2: PUSH P,S1 ;SAVE THE DESTINATION PAGE #
PUSHJ P,INPREW ;REWIND THE SPOOL FILE
POP P,S1 ;RESTORE DESTINATION PAGE NUMBER
JUMPLE S1,.RETT ;IF NO SLACK DATA,,SKIP FORWARD SPACE
MOVEM S1,J$FPIG(J) ;SAVE THE # OF PAGES TO FORWARD SPACE
TXO S,FORWRD ;LITE FORWARD SPACE BIT
$RETT ;RETURN
SUBTTL BACKSPACE 'COPIES' AND 'FILES'
BCOPYS: MOVE S2,J$RNCP(J) ;PICK UP # OF COPIES ALREADY PRINTED.
MOVE T1,0(S1) ;PICK UP # OF COPIES TO BSPACE.
SUB S2,T1 ;SUBTRACT # OF COPIES TO BSPACE.
MOVEM S2,J$RNCP(J) ;SAVE THE NEW COPIES VALUE.
$TEXT (LOGCHR,<^I/LPMSG/File ^F/@J$DFDA(J)/ Backspaced ^D/T1/ Copies>)
MOVE S1,STREAM ;PICK UP STREAM NUMBER.
$ACK (<Backspaced ^D/T1/ Copies>,,@JOBOBA(S1),.MSCOD(M))
PUSHJ P,INPFEF ;FORCE END OF FILE.
$RETT ;RETURN.
BFILES: PUSHJ P,INPFEF ;FORCE AN END-OF-FILE
SOS J$RNCP(J) ;ADD 1 COPY TO THE FILE COPY COUNT
MOVE S1,STREAM ;GET OUR STREAM NUMBER
$ACK (<Backspaced Current File>,,@JOBOBA(S1),.MSCOD(M))
LOAD S1,.FPLEN(E),FP.LEN ;GET THE FP LENGTH
ADD S1,E ;POINT TO THE FD
$TEXT (LOGCHR,<^I/LPMSG/Backspaced to Beginning of ^F/0(S1)/>)
$RETT
PAGES: 0,,0
SUBTTL DN60 OPERATOR CONSOLE OUTPUT SUPPORT ROUTINES
;CALL: M/ The Operator Message Address
;
;RET: True Always
IFE FTDN60,<
OPRD60: $RETT ;SHOULD NOT HAPPEN
OPRCHK: $RETT ;JUST RETURN
>
IFN FTDN60,<
OPRD60: SETOM JOBITS ;DONT SAVE THE STATUS BITS
MOVX T1,.OTLPT ;GET LINE PRINTER OBJECT TYPE
SETZM T2 ;GET UNIT 0
MOVE T3,.MSCOD(M) ;GET NODE NAME
MOVEI S1,T1 ;POINT TO THIS OBJECT BLOCK
PUSHJ P,FNDOBJ ;FIND IT IN OUR DATA BASE
JUMPT OPRD.2 ;ITS THERE,,CONTINUE ON
$WTO(<No Operator Console for IBM Remote '^W/.MSCOD(M)/'>,,,<$WTFLG(WT.SJI)>)
$RETT ;NOT FOUND,,TELL LOCAL OPR AND EXIT
OPRD.2: PUSHJ P,.SAVE2 ;SAVE P1 AND P2 FOR A MINUTE
MOVE S1,J$LINK(J) ;GET THE OPR MSG LIST ID
PUSHJ P,L%LAST ;POSITION TO LAST ENTRY
LOAD S2,.MSTYP(M),MS.CNT ;GET THE MESSAGE LENGTH
SUBI S2,.OHDRS ;SUBTRACT ALL HEADER LENGTHS
ADDI S2,OPRLEN+2 ;ADD OUR HEADER+TIME STAMP LENGTH
MOVE S1,J$LINK(J) ;GET THE OPR MSG LIST ID
PUSHJ P,L%CENT ;CREATE AN ENTRY IN THE LIST
MOVE P1,S2 ;SAVE THE ENTRY ADDRESS
MOVEI P2,.OHDRS(M) ;POINT TO THE FIRST MESSAGE BLOCK
LOAD T1,.OARGC(M) ;GET THE BLOCK COUNT
MOVEI S1,OPRTXT(P1) ;GET THE TEXT ADDRESS
HRLI S1,(POINT 7,0) ;MAKE IT A BYTE POINTER
MOVEM S1,TEXTBP ;SAVE IT FOR $TEXT
OPRD.3: LOAD S1,ARG.HD(P2),AR.TYP ;GET THE BLOCK TYPE
CAXN S1,.ORDSP ;IS IT A DISPLAY BLOCK ???
$TEXT (DEPBP,<^C/ARG.DA(P2)/ ^T/ARG.DA+1(P2)/>) ;YES,,GEN THE DISPLAY
CAXN S1,.CMTXT ;IS IT A TEXT BLOCK ???
$TEXT (DEPBP,<^T/ARG.DA(P2)/>) ;YES,,GEN THE DISPLAY
LOAD S1,ARG.HD(P2),AR.LEN ;GET THIS BLOCK LENGTH
ADD P2,S1 ;POINT TO THE NEXT BLOCK
SOJG T1,OPRD.3 ;PROCESS ALL MESSAGE BLOCKS
HRROI S1,OPRTXT(P1) ;GEN BYTE PTR TO MSG TEXT
MOVEM S1,OPRPTR(P1) ;SAVE IT IN THE LIST
HRRZ S1,TEXTBP ;GET THE LAST TEXT ADDRESS
SUBI S1,OPRTXT-1(P1) ;CALC THE TEXT LENGTH
IMULI S1,5 ;CALC THE NUMBER OF BYTES
MOVNM S1,OPRBCT(P1) ;SAVE THE -BYTE COUNT
SETOM J$OMSG(J) ;FLAG THAT THE STATION HAS A MESSAGE
$RETT ;AND RETURN
SUBTTL OPRCHK - ROUTINE TO CHECK FOR DN60 OPR MSGS AND SEND THEM
;CALL: P1/ THE STREAM WE ARE CHECKING
;RET: True Always
OPRCHK: SKIPN J,JOBPAG(P1) ;IS THIS STREAM SETUP ???
$RETT ;NO,,JUST RETURN
MOVEI S1,3 ;GET 3 SECONDS
MOVEM S1,SLEEPT ; AND SAVE IT FOR THE SCHEDULER
SKIPN J$OMSG(J) ;AND IS THERE AN OPR MESSAGE WAITING ?
$RETT ;NO TO EITHER,,JUST RETURN
PUSHJ P,.SAVE1 ;SAVE P1 FOR A MINUTE
HRRZM P1,STREAM ;HERE ALSO
OPRC.0: MOVE S1,J$LINK(J) ;GET THE OPR MSG LIST ID
PUSHJ P,L%FIRST ;GET THE FIRST MESSAGE ON THE CHAIN
JUMPF OPRC.3 ;NONE THERE,,CLEAN UP AND RETURN
MOVE P1,S2 ;SAVE THE MSG ADDRESS
MOVE S1,J$D6OP(J) ;GET THE OPR'S CONSOLE ID
MOVE S2,OPRPTR(P1) ;GET THE POINTER TO THE TEXT
MOVE T1,OPRBCT(P1) ;GET THE TEXT BYTE COUNT
PUSHJ P,D60SOUT## ;OUTPUT THE OPERATOR MESSAGE
JUMPT OPRC.2 ;IF OK,,DELETE THIS MSG,,TRY NEXT
CAXE S1,D6DOL ;IS THE ERROR 'DEVICE OFFLINE'
CAXN S1,D6NBR ; OR IS IT A NON-BLOCKING RETURN
JRST OPRC.1 ;YES,,THEN HE WINS
CAXN S1,D6CGO ;IS ERROR 'CANT GET OUTPUT PERMISSION' ?
$RETT ;YES,,JUST RETURN
$WTO (<Fatal DN60 Error #^O/S1/>,,,<$WTFLG(WT.SJI)>) ;TELL LOCAL OPR
MOVX S1,%RSUDE ;GET 'DOES NOT EXIST' SETUP CODE
PUSHJ P,RSETUP ;TELL QUASAR WHATS GOING ON
PUSHJ P,SHUTND ;SHUT EVERYTHING DOWN !!!
$RETT ;AND RETURN
OPRC.1: MOVEM S2,OPRPTR(P1) ;SAVE THE NEW TEXT POINTER
MOVEM T1,OPRBCT(P1) ;SAVE THE NEW TEXT BYTE COUNT
CAXN S1,D6NBR ;WAS THE ERROR 'NON-BLOCKING RETURN' ???
JRST OPRC.0 ;YES,,GO TRY OUTPUT AGAIN
MOVX S1,PSF%OO ;GET 'OPERATOR OUTPUT WAIT' BITS
MOVE S2,STREAM ;GET THIS STREAM NUMBER
IORM S1,JOBSTW(S2) ;LITE 'OPERATOR OUTPUT WAIT'
$RETT ;RETURN, WAIT 3 SECONDS & RETRY
OPRC.2: MOVE S1,J$LINK(J) ;GET OPR MSG LIST ID
PUSHJ P,L%DENT ;DELETE THE CURRENT MESSAGE
JRST OPRC.0 ;AND GO PROCESS THE NEXT
OPRC.3: MOVX S1,PSF%OO ;GET 'OPERATOR OUTPUT WAIT' BITS
MOVE S2,STREAM ;GET OUR STREAM NUMBER
ANDCAM S1,JOBSTW(S2) ;CLEAR 'OPERATOR OUTPUT WAIT' BITS
SETZM J$OMSG(J) ;CLEAR MSGS WAITING FLAG
MOVE S1,J$D6OP(J) ;GET THE OPERATOR CONSOLE ID
PUSHJ P,D60EOF## ;TURN THE LINE AROUND
$RETT ;AND RETURN
>
SUBTTL BLDL - CREATE A 10/20 FD FOR THE ALIGN FILE.
BLDLFD:
TOPS10 <
MOVEI S1,FDMSIZ ;PICK UP 10 FD SIZE.
STORE S1,J$AFD+.FDLEN(J),FD.LEN ;SAVE IN FD.
MOVSI S1,'SYS' ;PICK UP STRUCTURE NAME.
MOVEM S1,J$AFD+.FDSTR(J) ;SAVE IN FD.
MOVE S1,J$FALI(J) ;PICK UP FILE NAME (FORMS TYPE).
MOVEM S1,J$AFD+.FDNAM(J) ;SAVE IN FD.
MOVSI S1,'ALP' ;PICK UP FILE EXT.
MOVEM S1,J$AFD+.FDEXT(J) ;SAVE IN FD.
MOVEI S1,J$AFD(J) ;PICK UP FD ADDRESS.
$RETT ;RETURN. . . . . . . . . .
> ;END TOPS10 CONDITIONAL
TOPS20 <
MOVEI S1,AFDSIZ ;GET THE FD LENGTH
STORE S1,J$AFD+.FDLEN(J),FD.LEN ;SAVE IT
$TEXT (<-1,,J$AFD+.FDSTG(J)>,<SYS:^W/J$FALI(J)/.ALP^0>)
MOVEI S1,J$AFD(J) ;PICK UP FD ADDRESS.
$RETT ;RETURN. . . . . . . . . .
> ;END TOPS20 CONDITIONAL
SUBTTL ALIGN Processor.
ALIGN: TXNE S,GOODBY!ABORT ;ARE WE LEAVING ???
JRST ALIG.5 ;RETURN.
MOVE S1,J$AIFN(J) ;GET THE IFN
PUSHJ P,F%REW ;REWIND THE FILE
SETZM J$XTOP(J) ;CLEAR TOP OF FORM FLAG
PUSHJ P,SENDFF ;SEND A FORM-FEED
ALIG.1: SOSGE J$ABYT(J) ;DECREMENT THE BYTE COUNT
JRST ALIG.3 ;IF BUFFER EMPTY,,GET NEXT BUFFER.
ILDB C,J$APTR(J) ;PICK UP THE ALIGN BYTE.
PUSHJ P,DEVOUT ;PUT IT OUT....
JRST ALIG.1 ;GO GET NEXT BYTE.
ALIG.2: PUSHJ P,OUTDMP ;FORCE OUT THE BUFFER
SOSLE J$ACNT(J) ;COUNT DOWN
JRST ALIG.4 ;IF AGAIN,,SET UP SLEEP TIME.
SETZM J$XTOP(J) ;CLEAR TOP OF FORM
PUSHJ P,SENDFF ;GO TO TOP OF FORM
ALIG.5: MOVE S1,J$AIFN(J) ;PICK UP ALIGN IFN.
PUSHJ P,F%REL ;CLOSE THE ALIGN FILE.
SETZM J$APRG(J) ;INDICATE NO ALIGN IN PROGRESS.
SETZM J$ASLP(J) ;CLEAR THIS SLEEP TIME
SETZM J$ACNT(J) ;AND THIS REPEAT COUNT
MOVE S1,STREAM ;GET THE STREAM NUMBER.
SETOM JOBCHK(S1) ;SAY WE WANT TO CHECKPOINT.
$RETT ;AND RETURN
ALIG.3: MOVE S1,J$AIFN(J) ;GET ALIGN IFN.
PUSHJ P,F%IBUF ;GET AN ALIGN BUFFER.
JUMPF ALIG.2 ;IF NO MORE,,SLEEP A WHILE.
MOVEM S1,J$ABYT(J) ;SAVE THE # OF BYTES.
MOVEM S2,J$APTR(J) ;SAVE THE BYTE POINTER.
JRST ALIG.1 ;KEEP ON PROCESSING.
ALIG.4: MOVE S2,STREAM ;PICK UP STREAM NUMBER.
PUSHJ P,I%NOW ;GET CURRENT TIME.
ADD S1,J$ASLP(J) ;ADD /PAUSE VALUE.
MOVEM S1,JOBWKT(S2) ;SAVE WAKE UP TIME FOR STREAM.
$DSCHD (PSF%AL) ;SHOW STREAM BLOCKED FOR ALIGNMENT.
JRST ALIGN ;WHEN RETURN,,CONTINUE.
SUBTTL FNDOBJ - ROUTINE TO FIND THE OBJ BLK IN THE DATA BASE.
FNDOBJ: MOVE T1,.ROBTY(S1) ;GET OBJECT TYPE
MOVE T2,.ROBAT(S1) ;GET UNIT NUMBER
MOVE T3,.ROBND(S1) ;AND NODE NUMBER
SETZ T4, ;CLEAR AN INDEX REGISTER
FNDO.1: MOVE S2,T4 ;GET THE INDEX
IMULI S2,3 ;MULTIPLY BY OBJECT BLCK SIZE
CAMN T1,JOBOBJ+OBJ.TY(S2) ;COMPARE
CAME T2,JOBOBJ+OBJ.UN(S2) ;COMPARE
JRST FNDO.2 ;NOPE
CAMN T3,JOBOBJ+OBJ.ND(S2) ;COMPARE
JRST FNDO.3 ;WIN, SETUP THE CONTEXT
FNDO.2: ADDI T4,1 ;INCREMENT
CAIL T4,NPRINT ;THE END OF THE LINE?
$RETF ;YES,,RETURN 'OBJECT NOT THERE'
JRST FNDO.1 ;OK, LOOP
FNDO.3: MOVEM T4,STREAM ;SAVE STREAM NUMBER
SKIPN J,JOBPAG(T4) ;GET ADDRESS OF DATA
$RETF ;UNLESS ITS NOT REALLY SETUP THEN RETURN
MOVE S,J$RACS+S(J) ;GET HIS 'S'
$RETT ;AND RETURN
SUBTTL SNDQSR - ROUTINE TO SEND A MESASGE TO QUASAR.
SNDQSR: MOVX S1,SP.QSR ;GET QUASAR FLAG
TXO S1,SI.FLG ;SET SPECIAL INDEX FLAG
STORE S1,SAB+SAB.SI ;AND STORE IT
SETZM SAB+SAB.PD ;CLEAR THE PID WORD
LOAD S1,.MSTYP(T1),MS.CNT ;GET THE MESSAGE LENGTH
STORE S1,SAB+SAB.LN ;SAVE IT
STORE T1,SAB+SAB.MS ;SAVE THE MESSAGE ADDRESS
MOVEI S1,SAB.SZ ;LOAD THE SIZE
MOVEI S2,SAB ;AND THE ADDRESS
PUSHJ P,C%SEND ;SEND THE MESSAGE
JUMPT .RETT ;AND RETURN
$STOP(QSF,Send to QUASAR FAILED)
SUBTTL CHKLPT - ROUTINE TO MAKE SURE THE DEVICE IS ONLINE
CHKLPT:
TOPS20 <
SKIPE S1,JOBSTW ;ARE ANY STATUS BITS SET ???
TXNN S1,PSF%DO ;IF SO,,IS IT DEVICE OFFLINE ???
$RETT ;NO TO EITHER,,JUST RETURN
$WTO (<^T/BELL/>,,@JOBOBA) ;TELL OPR DEVICE IS OFFLINE
PUSHJ P,UPDTST ;SEND A STATUS UPDATE
SETOM JOBCHK ;INDICATE WE WANT ANOTHER WHEN WE CAN
> ;END TOPS20 CONDITIONAL
$RETT ;RETURN
SUBTTL TOOBAD - ROUTINE TO RESPOND TO THE OPERATOR IF HIS REQUEST IS TOO LATE.
TOOBAD: MOVE S1,STREAM ;GET THE STREAM NUMBER.
$ACK (Print Request Completed,<^R/.EQJBB(J)/>,@JOBOBA(S1),.MSCOD(M))
$RETT
SUBTTL LOGCHR -- Type a character in the log file
LOGCHR: CAIE S1,.CHLFD ;IS IT A LINE-FEED
CAIN S1,23 ;OR A DC 3?
AOS J$GNLN(J) ;YES, COUNT ANOTHER LINE
LOGC.1: SOSGE J$GIBC(J) ;IS THERE ROOM?
JRST LOGC.2 ;NO, GET ANOTHER PAGE
IDPB S1,J$GIBP(J) ;YES, DEPOSIT THE CHARACTER
$RETT ;AND RETURN
LOGC.2: PUSH P,S1 ;SAVE THE CHARACTER FOR A MINUTE
PUSHJ P,LOGBUF ;GET ANOTHER PAGE
POP P,S1 ;RESTORE THE CHARACTER
JRST LOGC.1 ;AND TRY AGAIN
SUBTTL LOGBUF -- Get a buffer page for LOG
LOGBUF: PUSHJ P,.SAVE1 ;SAVE P1
AOS P1,J$GINP(J) ;INCREMENT BUFFER PAGE COUNT
CAIN P1,1 ;IS THIS THE FIRST PAGE?
JRST [MOVE S1,J$GBUF(J) ;YES, USE THE PRE-ALLOCATED PAGE
JRST LOGB.1] ;AND CONTINUE ON
CAIL P1,^D10 ;NO, WITHIN RANGE?
$STOP(TML,TOO MANY LOG BUFFERS REQUIRED) ;NO,,COMMIT SUICIDE
PUSHJ P,M%GPAG ;GET A PAGE
ADDI P1,-1(J) ;POINT TO LOCATION IN J$GBUF
MOVEM S1,J$GBUF(P1) ;STORE THE ADDRESS
LOGB.1: HRLI S1,(POINT 7,0) ;MAKE A BYTE POINTER
MOVEM S1,J$GIBP(J) ;AND STORE IT
MOVEI S1,<5*1000>-1 ;GET A COUNT
MOVEM S1,J$GIBC(J) ;STORE IT
POPJ P, ;AND RETURN
SUBTTL SYSTEM ACCOUNTING ROUTINES
TOPS10 <
ACTBEG: $RETT ;JUST RETURN
ACTEND: $RETT ;HERE ALSO
> ;END TOPS10 CONDITIONAL
TOPS20 <
ACTBEG: MOVX S1,.FHSLF ;GET FORK HANDLE
RUNTM ;GET MY RUNTIME
MOVNM S1,J$ARTM(J) ;REMEMBER IT NEGATED
LOAD S1,.EQSEQ(J),EQ.SEQ ;GET SEQUENCE NUMBER
STORE S1,J$ASEQ(J) ;STORE IT
LOAD S1,.EQSEQ(J),EQ.PRI ;GET EXTERNAL PRIORITY
STORE S1,J$APRI(J) ;STORE IT
$RETT ;RETURN
ACTEND: MOVX S1,.FHSLF ;LOAD FORK HANDLE
RUNTM ;GET RUNTIME
ADDM S1,J$ARTM(J) ;STORE IT
SKIPN ACTFLG ;ARE WE DOING ACCT?
$RETT ;NO,,RETURN NOW.
LOAD S1,.EQSEQ(J),EQ.IAS ;GET THE INVALID ACCT STRING BIT
JUMPN S1,.RETT ;IF LIT,,THEN JUST RETURN
MOVX S1,.USENT ;WRITE AN ENTRY
MOVEI S2,ACTLST ;POINT TO THE LIST
USAGE ;DO THE JSYS
ERJMP ACTE.1 ;ON AN ERROR,,TELL THE OPERATOR
$RETT ;ELSE RETURN
ACTE.1: MOVE S1,STREAM ;GET THIS STREAM NUMBER
$WTO (System Accounting Failure,<^R/.EQJBB(J)/>,@JOBOBA(S1))
$RETT ;RETURN
;ACCOUNT PARAMETER BLOCK DEFINED ON THE NEXT PAGE
SEARCH ACTSYM ;SEARCH THE ACCOUNTING UNV
ACTLST: USENT. (.UTOUT,1,1)
USJNO. (-1) ;JOB NUMBER
USTAD. (-1) ;CURRENT DATE/TIME
USTRM. (-1) ;TERMINAL DESIGNATOR
USLNO. (-1) ;TTY LINE NUMBER
USPNM. (<SIXBIT/LPTSPL/>,US%IMM) ;PROGRAM NAME
USPVR. (%LPT,US%IMM) ;PROGRAM VERSION
USAMV. (-1) ;ACCOUNTING MODULE VERSION
USNOD. (-1) ;NODE NAME
USACT. (<POINT 7,.EQACT(J) ;ACCOUNT STRING POINTER>)
USSRT. (J$ARTM(J)) ;RUN TIME
USSDR. (J$ADRD(J)) ;DISK READS
USSDW. (0,US%IMM) ;DISK WRITES
USJNM. (.EQJOB(J)) ;JOB NAME
USQNM. (<SIXBIT /LPT/>,US%IMM) ;QUEUE NAME
USSDV. (J$LDEV(J)) ;DEVICE NAME
USSSN. (J$ASEQ(J)) ;JOB SEQUENCE NUMBER
USSUN. (J$APRT(J)) ;TOTAL PAGES PRINTED
USSNF. (J$AFXC(J)) ;TOTAL FILES PROCESSED
USCRT. (.EQAFT(J)) ;CREATION DATE/TIME OF REQUEST
USSCD. (J$RTIM(J)) ;SCHEDULED DATE/TIME
USFRM. (J$FORM(J)) ;FORMS TYPE
USDSP. (<SIXBIT/NORMAL/>,US%IMM) ;DISPOSITION
USTXT. (<-1,,[ASCIZ / /]>) ;SYSTEM TEXT
USPRI. (J$APRI(J)) ;JOB PRIORITY
USNM2. (<POINT 7,.EQOWN(J) ;USER NAME>)
0 ;END OF LIST
> ;END TOPS20 CONDITIONAL
SUBTTL INPOPN -- Routine to open the input file
;INPOPN IS CALLED WITH AC "E" POINTING TO THE FP AREA FOR THE FILE
; TO BE OPENED.
INPOPN: MOVEI S1,FOB.SZ ;GET THE FOB SIZE
MOVEI S2,J$XFOB(J) ;AND THE FOR ADDRESS
PUSHJ P,.ZCHNK ;ZERO IT OUT
LOAD S1,.FPLEN(E),FP.LEN ;GET THE FP LENGTH
ADD S1,E ;GET THE FD ADDRESS
MOVEM S1,J$DFDA(J) ;SAVE THE ADDRESS
STORE S1,J$XFOB+FOB.FD(J) ;SAVE IN THE FOB
MOVEI S1,7 ;LOAD PROBABLE (7 BIT) BYTE SIZE
LOAD T1,.FPINF(E),FP.FFF ;GET /FILE:
LOAD T2,.FPINF(E),FP.FPF ;GET /PRINT:
CAXN T1,.FPF8B ;WAS IT /FILE:8-BIT???
MOVEI S1,^D8 ;YES,,LOAD 8 BIT BYTE SIZE
CAXN T1,.FPF11 ;WAS IT /FILE:ELEVEN???
MOVEI S1,^D36 ;YES,,LOAD 36 BIT BYTE SIZE
CAIE T1,.FPFCO ;/FILE:COBOL?
CAIN T2,%FPLOC ;OR /PRINT:OCTAL?
MOVEI S1,^D36 ;YES, USE FULL WORDS
STORE S1,J$XFOB+FOB.CW(J),FB.BSZ ;AND SAVE THE BYTE SIZE
LOAD S1,.EQSEQ(J),EQ.PRV ;GET THE USERS PRIVILGE BITS
JUMPN S1,INPO.1 ;IF SET, AVOID ACCESS CHECK
LOAD S1,.FPINF(E),FP.SPL ;LIKEWISE IF SPOOLED
JUMPN S1,INPO.1 ; ...
TOPS10 <
MOVE S1,.EQOID(J) ;GET THE PPN
STORE S1,J$XFOB+FOB.US(J) ;AND SAVE IT
> ;END TOPS10 CONDITIONAL
TOPS20 <
HRROI S1,.EQOWN(J) ;GET THE OWNERS NAME
STORE S1,J$XFOB+FOB.US(J) ;SAVE IT
HRROI S1,.EQCON(J) ;GET CONNECTED DIRECTORY
STORE S1,J$XFOB+FOB.CD(J) ;AND SAVE IT
> ;END TOPS20 CONDITIONAL
INPO.1: MOVEI S1,FOB.SZ ;GET FOB SIZE
MOVEI S2,J$XFOB(J) ;AND ADDRESS
PUSHJ P,F%IOPN ;OPEN THE FILE
JUMPF INPO.2 ;JUMP IF FAILED
MOVEM S1,J$DIFN(J) ;ELSE, SAVE THE IFN
TXO S,DSKOPN ;INDICATE THE FILE IS OPEN.
$RETT ;AND RETURN
INPO.2: $TEXT(LOGCHR,<^I/LPERR/Can't access file ^F/@J$DFDA(J)/, ^E/[-1]/>)
ZERO .FPINF(E),FP.DEL ;CLEAR THE 'DELETE FILE' BIT
TXZ S,DSKOPN ;INDICATE THE FILE IS NOT OPEN.
$RETF ;AND RETURN
SUBTTL INPBUF -- Read a buffer from the input file
INPBUF: MOVE S1,J$DIFN(J) ;GET THE IFN
PUSHJ P,F%IBUF ;GET A BUFFERFUL
JUMPF INPERR ;LOSE
MOVEM S1,J$DBCT(J) ;SAVE THE BYTE COUNT
MOVEM S2,J$DBPT(J) ;AND THE BYTE POINTER
AOS J$ADRD(J) ;ADD 1 TO BUFFER READ COUNT.
EXCH S1,J$FCBC(J) ;GET OLD BUFR BYTE CNT AND SAVE NEW
ADDM S1,J$FTBC(J) ;BUMP TOTAL BYTES PROCESSED
$RETT ;THEN RETURN.
SUBTTL INPBYT -- Read a byte from the input file
INPBYT: SOSGE J$DBCT(J) ;MAKE SURE THERE IS DATA IN THE BUFFER.
JRST INPB.1 ;IF NOT,,GET ANOTHER BUFFER.
ILDB C,J$DBPT(J) ;PICK UP A BYTE FROM THE BUFFER.
$RETT ;AND RETURN.
INPB.1: PUSHJ P,INPBUF ;READ THE NEXT BUFFER.
JUMPF .RETF ;NO MORE,,RETURN.
JRST INPBYT ;ELSE GET THE NEXT BYTE.
SUBTTL INPERR -- Handle an input failure
INPERR: CAXN S1,EREOF$ ;WAS IT EOF?
$RETF ;WAS JUST RETURN
$TEXT(LOGCHR,<^I/LPERR/Error reading input file - ^E/[-1]/>)
TXO S,SKPFIL ;SKIP THE REST OF THE FILE
$RETF ;AND RETURN
SUBTTL INPFEF -- Force end-of-file on next input
INPFEF: TXNN S,DSKOPN ;IS THE SPOOL FILE OPEN ???
$RETT ;NO,,JUST RETURN
MOVE S1,J$DIFN(J) ;GET THE IFN
SETOB S2,J$DBCT(J) ;CLEAR BYTE COUNT AND SET EOF POS
PUSHJ P,F%POS ;AND POSITION IT
$RETT ;AND RETURN
SUBTTL INPREW -- Rewind the input file
INPREW: MOVE S1,J$DIFN(J) ;GET THE IFN
PUSHJ P,F%REW ;REWIND IT
SETOM J$DBCT(J) ;AND SET THE BYTE COUNT
SETZM J$RNPP(J) ;AND SET PAGE 0
MOVEI S1,J$FPAG(J) ;GET THE PAGE COUNTER TABLE ADDRESS
MOVEM S1,J$FBPT(J) ;AND SAVE IT.
SETZM J$FCBC(J) ;CLEAR CURRENT INPUT BUFFER BYTE COUNT
SETZM J$FTBC(J) ;CLEAR TOTAL INPUT BYTE COUNT
TXZ S,FBPTOV ;CLEAR PAGE TABLE OVERFLOW BIT
MOVX S1,PAGSIZ ;GET THE TABLE LENGTH.
MOVEI S2,J$FPAG(J) ;GET THE START ADDRESS.
PJRST .ZCHNK ;RETURN, ZEROING THE PAGE TABLE
SUBTTL FORMS -- Setup Forms for a job
FORMS: GETLIM S1,.EQLIM(J),FORM ;GET THE FORMS TYPE
CAMN S1,J$FORM(J) ;OR ARE FORMS EXACTLY THE SAME?
$RETT ;YES,,VFU AND RAM MUST BE SAME TO !!!
MOVE S2,[POINT 7,J$WTOR(J)] ;GET POINTER TO WTOR BUFFER.
MOVEM S2,TEXTBP ;AND SAVE IT FOR DEPBP.
SKIPN S2,J$FORM(J) ;GET FORMS TYPE
MOVX S2,FRMNOR ;USE NORMAL IF NULL
XOR S1,S2 ;GET COMMON PART
AND S1,[EXP FRMSK1] ;AND IT WITH THE IMPORTANT PART
GETLIM S2,.EQLIM(J),FORM ;GET FORMS TYPE
EXCH S2,J$FORM(J) ;SAVE IT
MOVEM S2,J$FPFM(J) ;SAVE OLD ONES
SKIPE S1 ;NO NEED TO CHANGE FORMS.
$TEXT (DEPBP,<Please load forms type '^W/J$FORM(J)/'>)
FORM.1: MOVE S1,J$FDRU(J) ;GET THE CURRENT DRUM TYPE
MOVEM S1,J$PDRU(J) ;AND SAVE IT
MOVE S1,J$FRIB(J) ;GET THE CURRENT RIBBON TYPE
MOVEM S1,J$PRIB(J) ;AND SAVE IT
MOVE S1,J$FTAP(J) ;GET THE CURRENT CARRIAGE CONTROL TAPE
MOVEM S1,J$PTAP(J) ;AND SAVE IT
MOVE S1,J$LRAM(J) ;GET THE DEFAULT RAM FILE NAME
MOVEM S1,J$FRAM(J) ;AND MAKE IT THE CURRENT RAM TYPE
HRLZI S1,-F$NSW ;GET NEGATIVE SWITCH TABLE LEN
MOVEI T1,J$FCUR(J) ;POINT TO CURRENT FORMS PARAMS
FORM.2: MOVE S2,FFDEFS(S1) ;GET A DEFAULT
CAME S2,[-1] ;IS THIS SUPPOSED TO BE DEFAULTED ???
MOVEM S2,(T1) ;YES,,SAVE IT
ADDI T1,1 ;INCREMENT NEW PARAM STORE CTR
AOBJN S1,FORM.2 ;AND LOOP
MOVEI T1,3 ;START AT THREE
MOVEM T1,J$FWCL(J) ;STORE IT
MOVE T1,J$FWID(J) ;GET THE WIDTH
CAIG T1,F$CL2 ;LE CLASS 2 LIMIT?
SOS J$FWCL(J) ;YES, SOS ONCE
CAIG T1,F$CL1 ;LE CLASS 1 LIMIT
SOS J$FWCL(J) ;YES, SOS AGAIN
GETLIM T1,.EQLIM(J),FORM ;FORMS NAME
MOVEM T1,J$FALI(J) ;SAVE IT AS DEFAULT ALIGN FILE NAME
FORM.3: PUSHJ P,FRMINI ;READ THE LPFORM.INI FILE.
SKIPE J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
$RETT ;YES,,JUST RETURN NOW !!
MOVE S1,TEXTBP ;GET THE WTOR BYTE POINTER.
CAMN S1,[POINT 7,J$WTOR(J)] ;IS THERE A MESSAGE FOR THE OPERATOR ??
JRST FORM.5 ;NO,,TRY LOADING VFU AND RAM
$TEXT (DEPBP,<^T/ENDRSP/^0>) ;ADD THE RESPONSE TO THE END
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
FORM.4: MOVE S1,STREAM ;GET STREAM NUMBER
$WTOR (,<^T/J$WTOR(J)/>,@JOBOBA(S1),JOBWAC(S1)) ;SEND THE WTOR.
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT.
$DSCHD (PSF%OR) ;WAIT FOR OPERATOR RESPONSE.
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED OR REQUEUED ???
$RETF ;YES,,RETURN NOW
MOVEI S1,CONANS ;POINT TO THE CONTINUE ANSWER BLOCK
HRROI S2,J$RESP(J) ;POINT TO THE ANSWER
PUSHJ P,S%TBLK ;DO WE MATCH ???
TXNE S2,TL%NOM+TL%AMB ;DID WE FIND IT OK ???
JRST FORM.4 ;NO,,STUPID OPERATOR SO TRY AGAIN
FORM.5: PUSHJ P,LODRAM ;TRY TO LOAD THE RAM
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED ???
$RETF ;YES,,RETURN NOW
PUSHJ P,LODVFU ;TRY TO LOAD THE VFU
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED ???
$RETF ;YES,,RETURN NOW
$RETT ;NO,,HE WINS SO FAR !!!
ENDRSP: ASCIZ /Type 'Respond <number> CONTINUE' When Ready/
FRMINI: SKIPN FMOPN ;IS LPFORM OPEN?
POPJ P, ;NO, JUST RETURN
MOVE S1,FMIFN ;YES, GET THE IFN
PUSHJ P,F%REW ;REWIND IT
SETZM FMBYT ;SET FILE BYTE COUNT TO 0
FRMIN1: PUSHJ P,FH$SIX ;GET THE FORMS NAME
JUMPF .RETT ;EOF!!
GETLIM T2,.EQLIM(J),FORM ;GET FORMS
CAMN T1,T2 ;MATCH??
JRST FRMIN2 ;YES!!
FRMI1A: PUSHJ P,FH$EOL ;NO, FIND NEXT LINE
JUMPF .RETT ;EOF!!
JRST FRMIN1 ;AND LOOP
FRMIN2: CAIN C,"/" ;BEGINNING OF SWITCH?
JRST FRMIN5 ;YES, LOCATOR IS "ALL"
CAIN C,":" ;BEGINNING OF LOCATOR?
JRST FRMIN3 ;YES, GO GET IT
CAIN C,.CHLFD ;EOL?
JRST FRMIN1 ;YES, GO THE NEXT LINE
PUSHJ P,FH$CHR ;ELSE, GET A CHARACTER
JUMPF .RETT ;EOF
JRST FRMIN2 ;AND LOOP
FRMIN3: PUSHJ P,FH$SIX ;GET A LOCATOR
JUMPF .RETT ;EOF!!
JUMPE T1,FRMI3A ;MAYBE PAREN??
JRST FRMIN4 ;AE S2,TL%NOM+TL%
FRMI3A: CAIN C,"/" ;A SWITCH?
JRST FRMIN5 ;YES!
CAIE C,"(" ;A LIST?
JRST FRMIN9 ;NO, ERROR
FRMIN4: HLRZ T2,T1 ;GET THE FIRST THREE CHARS
CAIN T2,'ALL' ;IS IT "ALL"?
JRST FRMIN5 ;YES, STOP CHECKING
CAIN T2,'LOC' ;IS IT LOCAL?
SKIPGE J$LREM(J) ;YES, ARE WE?
SKIPA ;NO, NO
JRST FRMIN5 ;YES, YES!
CAIN T2,'REM' ;DOES IT SAY "REMOTE"?
SKIPL J$LREM(J) ;YES, ARE WE REMOTE
SKIPA ;NO!!!
JRST FRMIN5 ;YES!!
CAIE T2,'LPT' ;IS IT "LPT"
JRST FRMI4B ;NO, TRY ONE LAST THING
CAMN T1,J$LDEV(J) ;COMPARE TO OUR DEVNAM
JRST FRMIN5 ;MATCH!!
FRMI4B: CAIN C,.CHLFD ;BREAK ON EOL?
JRST FRMIN1 ;YES, GET NEXT LINE
CAIE C,"/" ;IS IT A SLASH?
CAIN C,")" ;NO, CLOSE PAREN?
JRST FRMI1A ;YES, GET THE NEXT LINE
PUSHJ P,FH$SIX ;ELSE, GET THE NEXT LOCATOR
JUMPF .RETT ;EOF, RETURN
JUMPE T1,FRMIN9 ;BAD FORMAT
JRST FRMIN4 ;AND LOOP AROUND
;GET HERE IF THIS LINE IS FOR US
FRMIN5: CAIN C,.CHLFD ;WAS THE LAST CHARACTER A LINEFEED?
POPJ P, ;YES, RETURN
CAIN C,"/" ;ARE WE AT THE BEGINNING OF A SWITCH?
JRST FRMI5A ;YES, DO IT!
PUSHJ P,FH$CHR ;NO, GET A CHARACTER
JUMPF .RETT ;EOF!!
JRST FRMIN5 ;AND LOOP AROUND
FRMI5A: PUSHJ P,FH$SIX ;GET THE SWITCH
JUMPF .RETT ;EOF!!
JUMPN T1,FRMIN6 ;JUMP IF WE'VE GOT SOMETHING
CAIN C,.CHLFD ;EOL?
POPJ P, ;YES, RETURN
JRST FRMIN5 ;ELSE, KEEP TRYING
FRMIN6: MOVE T4,T1 ;SAVE SWITCH NAME FOR LATTER
HLLZS T1 ;GET FIRST THREE CHARACTERS OF SWITCH
MOVSI T2,-F$NSW ;MAKE AOBJN POINTER
FRMIN7: HLLZ T3,FFNAMS(T2) ;GET A SWITCH NAME
CAMN T3,T1 ;MATCH??
JRST FRMIN8 ;YES, DISPATCH
AOBJN T2,FRMIN7 ;NO, LOOP
MOVE T4,T1 ;GET SWITCH NAME
MOVE S1,STREAM ;GET THE STREAM NUMBER.
$WTOJ (LPFORM.INI Error,<Unrecognized switch ^W/T1/ found.>,@JOBOBA(S1))
JRST FRMIN5 ;AND LOOP
FRMIN8: HRRZ T3,FFNAMS(T2) ;GET DISPATCH ADDRESS
PUSHJ P,(T3) ;GO!!
JRST FRMIN5 ;AND LOOP
FRMIN9: MOVE S1,STREAM ;GET THE STREAM NUMBER.
$WTOJ (Bad format in LPFORM.INI,,@JOBOBA(S1))
POPJ P, ;AND RETURN
SUBTTL Forms Switch Subroutines
S$BANN: PUSHJ P,FH$DEC ;GET DECIMAL ARGUMENT
MOVEM T1,J$FBAN(J) ;STORE IT
POPJ P, ;AND RETURN
S$TRAI: PUSHJ P,FH$DEC ;GET DECIMAL ARGUMENT
MOVEM T1,J$FTRA(J) ;STORE IT
POPJ P, ;AND RETURN
S$HEAD: PUSHJ P,FH$DEC ;GET A DECIMAL ARGUMENT
MOVEM T1,J$FHEA(J) ;STORE IT
POPJ P, ;AND RETURN
S$LINE: PUSHJ P,FH$DEC ;GET DECIMAL ARGMENT
MOVEM T1,J$FLIN(J) ;STORE IT
POPJ P, ;AND RETURN
S$WIDT: PUSHJ P,FH$DEC ;GET DECIMAL ARGUMENT
MOVEM T1,J$FWID(J) ;SAVE IT
MOVEI T2,3 ;ASSUME WIDTH CLASS 3
MOVEM T2,J$FWCL(J) ;SAVE WIDTH CLASS
CAIG T1,F$CL2 ;LE CLASS 2 LIMIT?
SOS J$FWCL(J) ;YES, DECREMENT
CAIG T1,F$CL1 ;LE CLASS 1 LIMIT
SOS J$FWCL(J) ;YES, DECREMENT AGAIN!
POPJ P, ;AND RETURN
S$RIBB: PUSHJ P,FH$SIX ;GET SIXBIT ARGUMENT
JUMPF .RETT ;EOF
MOVEM T1,J$FRIB(J) ;SAVE IT
CAME T1,J$PRIB(J) ;SKIP IF NOT CHANGED
$TEXT (DEPBP,<Load Ribbon type '^W/J$FRIB(J)/'>)
POPJ P, ;AND RETURN
S$DRUM:
S$CHAI: PUSHJ P,FH$SIX ;GET SIXBIT ARG
JUMPF .RETT ;EOF!!
MOVEM T1,J$FDRU(J) ;SAVE IT
CAME T1,J$PDRU(J) ;SKIP IF NOT CHANGED
$TEXT (DEPBP,<Load DRUM (CHAIN) type '^W/J$FDRU(J)/'>)
POPJ P, ;AND RETURN
S$NOTE: MOVE T1,[POINT 7,J$FNBK(J)]
SETZ T2, ;CLEAR THE COUNTER
S$NOT1: PUSHJ P,FH$CHR ;GET A CHARACTER
JUMPF S$NOT2 ;EOF, FINISH UP!!
CAIGE C,40 ;MAKE SURE ITS GREATER THAN SPACE
JRST S$NOT2 ;ITS NOT!, FINISH UP
CAIN C,"/" ;ALSO STOP ON SLASH
JRST S$NOT2 ;IT IS!!
IDPB C,T1 ;DEPOSIT IT
CAIGE T2,^D49 ;LOOP FOR 50 CHARACTERS
AOJA T2,S$NOT1 ;INCR AND LOOP
S$NOT2: $TEXT (DEPBP,<Note: ^T/J$FNBK(J)/>) ;ADD THE MSG TO WTOR.
$RETT ;RETURN.
S$ALCN: PUSHJ P,FH$DEC ;GET DECIMAL ARG
MOVEM T1,J$FALC(J) ;STORE IT
POPJ P, ;RETURN
S$ALSL: PUSHJ P,FH$DEC ;GET DECIMAL ARG
MOVEM T1,J$FALS(J) ;SAVE IT
POPJ P, ;AND RETURN
S$ALIG: CAIN C,"/" ;ARE WE AT THE BEGINNING OF A SWITCH ??
PJRST OALI.2 ;YES,,JUST USE FORMS NAME AS ALIGN FILE
PUSHJ P,FH$SIX ;GET THE ALIGN FILENAME ARGUMENT
SKIPE T1 ;SKIP IF NOTHING THERE
MOVEM T1,J$FALI(J) ;SAVE THE ALIGN FILENAME
PUSHJ P,OALI.2 ;SCHEDULE THE FORMS ALIGNMENT
POPJ P, ;AND RETURN
S$VFU:
S$TAPE: PUSHJ P,FH$SIX ;GET SIXBIT ARGUMENT
JUMPF .RETT ;EOF
MOVEM T1,J$FTAP(J) ;SAVE IT
CAME T1,J$PTAP(J) ;ARE OLD AND NEW THE SAME?
SKIPE J$LDVF(J) ;OR DOES DEVICE HAVE A DAVFU?
$RETT ;OLD=NEW OR SOFTWARE VFU,,RETURN
$TEXT (DEPBP,<Load CARRIAGE CONTROL TAPE '^W/J$FTAP(J)/'>)
$RETT
S$RAM: PUSHJ P,FH$SIX ;GET THE SIXBIT ARGUMENT
JUMPF .RETT ;EOF
MOVEM T1,J$FRAM(J) ;SAVE IT
$RETT ;AND RETURN
SUBTTL LODVFU -- Load the Vertical Forms Unit
LODVFU: SKIPN J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
SKIPN J$LDVF(J) ;OR DOES THIS PRINTER HAVE A VFU ???
$RETT ;TO TAPE OR NO VFU,,JUST RETURN.
MOVE S1,J$FTAP(J) ;GET NECESSARY VFU TYPE
CAMN S1,J$FLVT(J) ;IS IT IN THERE ALREADY?
$RETT ;YES, RETURN
MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (Loading VFU with '^W/J$FTAP(J)/',,@JOBOBA(S1))
TOPS20 <
$TEXT(<-1,,J$XTBF(J)>,<SYS:^W/J$FTAP(J)/.VFU^0>)
LODV.2: MOVX S1,GJ%OLD+GJ%SHT ;SHORT, OLD FILE ONLY
HRROI S2,J$XTBF(J) ;POINT TO STRING
GTJFN ;GO GET THE JFN FOR THE FILE
ERJMP NOVFU ;ERROR,,LETS TRY SOMETHING ELSE
LODV.3: MOVE T3,S1 ;COPY THE JFN OVER
MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVX S2,.MOLVF ;GET LOAD VFU FUNCTION
MOVEI T1,T2 ;ADDRESS OF ARG BLOCK
MOVEI T2,2 ;LENGTH OF ARG BLOCK
PUSHJ P,$MTOPR ;LOAD THE VFU
MOVE S1,T3 ;GET THE VFU JFN ONCE MORE
RLJFN ;RELEASE IT
JFCL ;IGNORE ANY ERRORS
JUMPF LODV.4 ;CANT LOAD VFU,,GO FIND OUT WHY.
MOVE T1,J$FTAP(J) ;GET THE VFU TYPE
MOVEM T1,J$FLVT(J) ;SAVE AS CURRENTLY LOADED
POPJ P, ;AND RETURN
LODV.4: MOVX S1,.FHSLF ;GET MY HANDLE
GETER ;GET THE LAST ERROR CODE
HRRZS S2,S2 ;GET JUST THE ERROR CODE
CAXE S2,MTOX17 ;IS THE ERROR 'DEVICE OFFLINE' ???
JRST NOVF.1 ;NO,,LETS TRY SOME OTHER
PUSHJ P,OUTWON ;SAY 'DEVICE OFFLINE'
JRST LODV.2 ;AND TRY AGAIN
> ;END TOPS20 CONDITIONAL
SUBTTL TOPS10 VFU LOADING ROUTINES
TOPS10 <
PUSHJ P,OUTFLS ;FLUSH THE OUTPUT BUFFERS
JUMPF SHUTIN ;CANT,,SHUT IT DOWN
TXO S,VFULOD ;FLAG THE FACT WE'RE LOADING THE VFU
;ON SYSTEM STARTUP, SEE IF THE VFU IS VALID AND IF SO THROW OUT A
;FORM FEED. IF NOT, ASK OPR TO ALIGN FORMS BEFORE LOADING VFU.
SKIPE J$LVFF(J) ;IS THIS THE FIRST TIME THROUGH ???
JRST LODV.0 ;NO,,SKIP THIS
SETOM J$LVFF(J) ;RESET THE FIRST TIME THROUGH FLAG
MOVE T1,[2,,T2] ;GET THE DEVOP. PARAMETERS
MOVX T2,.DFRDS ;GET 'READ DEVICE STATUS' FUNCTION CODE
MOVE T3,J$LDEV(J) ;GET THE SIXBIT DEVICE NAME
DEVOP. T1, ;GET THE DEVICE STATUS
$STOP (LDF,Line Printer Device Status DEVOP. Failed) ;SHOULD'NT HAPPEN
TXNE T1,DF.LVE ;DOES THE LPT HAVE A GOOD VFU ???
JRST LOD.0A ;NO,,DONT OUTPUT FORM FEED
MOVX C,.CHFFD ;GET FORM FEED CODE
PUSHJ P,DEVOUT ;PUT IT OUT
PUSHJ P,OUTDMP ;ALIGN THE FORMS ON THE PRINTER
JRST LODV.0 ;AND GO RELOAD THE VFU
LOD.0A: MOVE S1,STREAM ;GET OUR STREAM NUMBER
$WTOR(<Align Forms and Put Online>,<^T/ENDRSP/>,@JOBOBA(S1),JOBWAC(S1))
SETOM JOBCHK(S1) ;TAKE A CHECKPOINT WHEN WE CAN
$DSCHD (PSF%OR) ;WAIT FOR THE OPERATOR RESPONSE
TXNE S,ABORT+RQB ;ARE WE STILL IN BUSINESS ???
JRST [SETZM J$FORM(J) ;NO,,ZAP THE LOADED FORMS TYPE
TXZ S,VFULOD ;CLEAR THE VFU LOAD FLAG
$RETT ] ;AND RETURN
MOVEI S1,CONANS ;GET THE ANSWER BLOCK ADDRESS
HRROI S2,J$RESP(J) ;POINT TO THE OPERATORS RESPONSE
$CALL S%TBLK ;CHECK ONE AGAINST THE OTHER
TXNE S2,TL%NOM+TL%AMB ;DO THEY MATCH ???
JRST LOD.0A ;NO,,STUPID OPERATOR - TRY AGAIN !!
LODV.0: LOAD S1,J$LCLS(J) ;GET THE PRINTER CONTROLLER CLASS
CAXN S1,.DFS20 ;FRONT END LPT ???
JRST LODV.4 ;YES,,DO THINGS A LITTLE DIFFERENTLY
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
MOVE S1,J$FTAP(J) ;GET FILENAME
STORE S1,VFUFD+.FDNAM ;AND STORE IN THE FD
MOVEI S1,FOB.SZ ;GET THE FOB SIZE
MOVEI S2,FOB ;AND FOB ADDRESS
PUSHJ P,.ZCHNK ;AND ZERO IT
MOVEI S1,VFUFD ;GET FD ADDRESS
STORE S1,FOB+FOB.FD ;STORE
MOVEI S1,7 ;GET 7 BIT BYTE SIZE
STORE S1,FOB+FOB.CW,FB.BSZ ;AND STORE
MOVEI S1,FOB.SZ ;GET FOB SIZE
MOVEI S2,FOB ;AND FOB ADDRESS
PUSHJ P,F%IOPN ;SETUP TO READ IT
JUMPF NOVFU ;FILE NOT THERE,,HE LOSES !!!
MOVEM S1,J$FVIF(J) ;ELSE,,SAVE THE IFN
MOVE T1,[2,,T2] ;ARGS FOR DEVOP
MOVX T2,.DFENV ;ENABLE VFU LOAD
MOVE T3,J$LDEV(J) ;FOR I/O DEVICE
DEVOP. T1, ;DO IT
JRST NODAVF ;ASSUME NO DAVFU
LODV.1: SOSGE J$FBYT(J) ;CHECK AND SEE IF DATA IS IN BUFFER.
JRST LODV.3 ;IF NOT,,GET NEXT BUFFER.
ILDB C,J$FPTR(J) ;PICK UP A BYTE.
PUSHJ P,DEVOUT ;WRITE IT OUT.
JRST LODV.1 ;GO GET ANOTHER.
LODV.2: PUSHJ P,OUTDMP ;FORCE OUT THE BUFFERS
MOVE T1,[2,,T2] ;LOAD ARG POINTER
MOVX T2,.DFDVL ;DISABLE VFU LOAD
MOVE T3,J$LCHN(J) ;AND CHANNEL NUMBER
DEVOP. T1, ;DO IT!
JRST NODAVF ;LOSE
MOVE S1,J$FVIF(J) ;GET THE IFN
PUSHJ P,F%REL ;RELEASE IT
MOVE T1,J$FTAP(J) ;GET TAPE NAME
MOVEM T1,J$FLVT(J) ;SAVE AS TYPE LOADED
TXZ S,VFULOD ;CLEAR THE VFU LOAD FLAG
PUSHJ P,OUTFLS ;FLUSH THE OUTPUT BUFFERS
JUMPF SHUTIN ;CANT,,SHUT IT DOWN
$RETT ;OK,,JUST RETURN
LODV.3: MOVE S1,J$FVIF(J) ;GET VFU IFN.
PUSHJ P,F%IBUF ;GET ANOTHER BUFFER.
JUMPF LODV.2 ;IF NO MORE,,RETURN
MOVEM S1,J$FBYT(J) ;SAVE THE BYTE COUNT
MOVEM S2,J$FPTR(J) ;SAVE THE BYTE POINTER.
JRST LODV.1 ;CONTINUE PROCESSING.
VFUFD: $BUILD FDMSIZ
$SET(.FDLEN,FD.LEN,VFUFDL) ;FD LENGTH
$SET(.FDEXT,,<SIXBIT/VFU/>) ;FILENAME EXTENSION
$SET(.FDSTR,,<SIXBIT/SYS/>) ;FILE STRUCTURE
$EOB
VFUFDL==.-VFUFD ;FD LENGTH
;FOR FRONT END LINE PRINTERS, WE MUST DO THINGS A LITTLE DIFFERENTLY !!
LODV.4: OPEN 17,VFUFOB ;OPEN THE STRUCTURE
JRST NOVFU ;CANT,,TRY SOMETHING ELSE
MOVE S1,J$FTAP(J) ;GET THE VFU WE WANT
MOVEM S1,VLKUP+0 ;SAVE IN THE LOOKUP BLOCK
MOVSI S1,'VFU' ;GET THE EXTENSION
MOVEM S1,VLKUP+1 ;SAVE IN THE LOOKUP BLOCK
SETZM VLKUP+2 ;CLEAR 3'RD WORD OF LOOKUP BLOCK
SETZM VLKUP+3 ;CLEAR 4'TH WORD OF LOOKUP BLOCK
LOOKUP 17,VLKUP ;FIND THE FILE WE WANT
JRST VDON.2 ;NOT THERE,,TRY SOMETHING ELSE
PUSHJ P,M%GPAG ;GET A PAGE FOR A BUFFER
MOVE T4,S1 ;SAVE THE ADDRESS FOR LATER
MOVEI T1,-1(S1) ;GET BUFFER ADDRESS-1
HLL T1,VLKUP+3 ;GET -FILE LENGTH,,BUFFER ADDR-1
SETZM T2 ;END CCW
IN 17,T1 ;READ THE VFU FILE
SKIPA ;CONTINUE ON SUCCESSFUL RETURN
JRST VDON.1 ;AN ERROR,,TRY SOMETHING ELSE
HLRO T3,VLKUP+3 ;GET -FILE LENGTH
MOVMS T3 ;WANT POSITIVE LENGTH
IMULI T3,5 ;CALC NUMBER OF VFU BYTES
MOVEI T1,.DFLV2 ;WANT LOAD VFU FUNCTION
MOVE T2,J$LCHN(J) ;WANT LPT CHANNEL NUMBER
MOVE S1,[4,,T1] ;GET ARG COUNT,,BLOCK ADDRESS
SETZM S2 ;FLAG S2 (IF 0 THEN VFU LOADED OK)
DEVOP. S1, ;LOAD THE VFU
VDON.1: SETOM S2 ;FLAG THAT VFU LOAD FAILED
MOVE T1,S2 ;SAVE THE VFU LOAD FLAG
MOVE S1,T4 ;GET THE BUFFER ADDRESS BACK
PUSHJ P,M%RPAG ;RELEASE THE PAGE
VDON.2: MOVEI S1,17 ;GET THE CHANNEL NUMBER
RESDV. S1, ;WIPE IT OUT
JFCL ;IGNORE ANY ERROR RELEASING THE DEVICE
JUMPN T1,NOVF.1 ;LOAD FAILED,,TRY SOMETHING ELSE
MOVE S1,J$FTAP(J) ;GET THE VFU TYPE WE JUST LOADED
MOVEM S1,J$FLVT(J) ;SAVE IT AS LOADED VFU TYPE
TXZ S,VFULOD ;CLEAR THE VFU LOAD FLAG
PUSHJ P,OUTFLS ;FLUSH THE OUTPUT BUFFERS
JUMPF SHUTIN ;CANT,,SHUT IT DOWN
$RETT ;OK,,RETURN
VFUFOB: .IODMP ;DUMP MODE I/O
SIXBIT/SYS/ ;FILE ON SYS:
0,,0 ;DUMP MODE (NO BUFFERS)
VLKUP: BLOCK 4 ;LOOKUP BLOCK
> ;END TOPS10 CONDITIONAL
SUBTTL HERE IF VFU FILE THAT WE ARE LOOKING FOR IS NOT AROUND
NOVFU: MOVE T1,J$FTAP(J) ;TYPE WE TRIED TO LOAD
CAME T1,D$TAPE ;IS IT THE DEFAULT
JRST NOVF.1 ;NO, GIVE UP
TOPS10 <
MOVE T1,[2,,T2] ;ARGS FOR DEVOP
MOVEI T2,.DFLLV ;LOAD HARDWARE VFU
MOVE T3,J$LCHN(J) ;FOR CHANNEL
DEVOP. T1, ;DO IT
JRST NOVF.1 ;LOSE
MOVE T1,D$TAPE ;GET NAME OF NORMAL
MOVEM T1,J$FLVT(J) ;STORE IT
MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (Error loading VFU,Loaded hardware VFU instead.,@JOBOBA(S1))
TXZ S,VFULOD ;CLEAR THE VFU LOAD FLAG
$RETT ;AND RETURN
;HERE WHEN DEVOP FAILS...CLEAR DAVFU FLAG AND RETURN
NODAVF: SETZM J$LDVF(J) ;CLEAR THE FLAG
MOVE S1,J$FTAP(J) ;GET THE FORMS TYPE.
MOVEM S1,J$FLVT(J) ; AND SAVE THEM AS LAST USED.
POPJ P, ;AND RETURN
> ;END TOPS10 CONDITIONAL
NOVF.1: MOVE S1,STREAM ;GET STREAM NUMBER
$WTOR (,<^I/VFUI1/^J^M^T/VFUI2/>,@JOBOBA(S1),JOBWAC(S1))
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT.
$DSCHD (PSF%OR) ;WAIT FOR THE REPLY.
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED OR REQUEUED ??
JRST [SETZM J$FORM(J) ;YES,,ZAP THE LOADED FORMS TYPE
TXZ S,VFULOD ;CLEAR THE VFU LOAD FLAG
$RETT ] ;AND RETURN
HRROI S1,J$RESP(J) ;GET THE OPERATORS RESPONSE
PUSHJ P,S%SIXB ;CONVERT IT TO SIXBIT
MOVEM S2,J$FTAP(J) ;SAVE THE FORMS TYPE
JRST LODVFU ;TRY LOADING AGAIN.
VFUI1: ITEXT (<VFU Error, can't load VFU '^W/J$FTAP(J)/'>)
VFUI2: ASCIZ /Respond with VFU type to continue/
SUBTTL LODRAM - ROUTINE TO LOAD THE TRANSLATION RAM
LODRAM: SKIPN J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
SKIPE J$LREM(J) ;OR IS THIS A REMOTE LPT ???
$RETT ;YES,,RETURN NOW !!!
MOVE S1,J$FRAM(J) ;GET THE RAM WE WANT
CAMN S1,J$FLRM(J) ;IS IT IN THERE ALREADY ???
$RETT ;YES,,RETURN NOW !!!
TOPS20 <
MOVE S1,STREAM ;GET OUR STREAM NUMBER
$WTO (Loading RAM with '^W/J$FRAM(J)/',,@JOBOBA(S1))
$TEXT (<-1,,J$XTBF(J)>,<SYS:^W/J$FRAM(J)/.RAM^0>) ;GEN RAM FILE NAME
LODR.1: MOVX S1,GJ%OLD+GJ%SHT ;SHORT, OLD FILE ONLY
HRROI S2,J$XTBF(J) ;POINT TO FILE NAME
GTJFN ;GET A JFN FOR THE TRANSLATION RAM
ERJMP NORAM ;CANT GET A JFN,,TRY SOMETHING ELSE
LODR.2: MOVE T3,S1 ;SAVE THE JFN
MOVE S1,J$LCHN(J) ;GET THE PRINTER JFN
MOVX S2,.MOLTR ;WANT 'LOAD RAM' MTOPR FUNCTION
MOVEI T1,T2 ;GET ARG BLOCK ADDRESS
MOVEI T2,2 ;GET ARG BLOCK LENGTH
PUSHJ P,$MTOPR ;GO DO THE MTOPR
MOVE S1,T3 ;GET THE JFN BACK
RLJFN ;RELEASE IT
JFCL ;IGNORE ANY ERRORS
JUMPF LODR.3 ;COULD NOT LOAD RAM,,FIND OUT WHY
MOVE S1,J$FRAM(J) ;GET THE RAM TYPE WE LOADED
MOVEM S1,J$FLRM(J) ;SAVE IT
$RETT ;AND RETURN
LODR.3: MOVX S1,.FHSLF ;GET MY HANDLE
GETER ;GET THE LAST ERROR
HRRZS S2,S2 ;GET JUST THE ERROR CODE
CAXE S2,MTOX17 ;IS THE ERROR 'LPT OFFLINE' ???
JRST NORAM ;NO,,LETS TRY SOME OTHER
PUSHJ P,OUTWON ;WAIT FOR THE LPT TO COME ONLINE
JRST LODR.1 ;AND TRY AGAIN
> ;END TOPS20 CONDITIONAL
TOPS10 <
MOVE S1,J$LCLS(J) ;GET THE CONTROLLER CLASS
CAIE S1,.DFS20 ;IS THIS A CONSOLE FRONT END LPT ???
$RETT ;NO,,THEN WE DONT LOAD THE RAM
MOVE S1,STREAM ;GET OUR STREAM NUMBER
$WTO (Loading RAM with '^W/J$FRAM(J)/',,@JOBOBA(S1))
OPEN 17,RAMFOB ;OPEN THE STRUCTURE
JRST NORAM ;CANT,,TRY SOMETHING ELSE
MOVE S1,J$FRAM(J) ;GET THE RAM WE WANT
MOVEM S1,RLKUP+0 ;SAVE IN THE LOOKUP BLOCK
MOVSI S1,'RAM' ;GET THE EXTENSION
MOVEM S1,RLKUP+1 ;SAVE IN THE LOOKUP BLOCK
SETZM RLKUP+2 ;CLEAR 3'RD WORD OF LOOKUP BLOCK
SETZM RLKUP+3 ;CLEAR 4'TH WORD OF LOOKUP BLOCK
LOOKUP 17,RLKUP ;FIND THE FILE WE WANT
JRST RDON.2 ;NOT THERE,,TRY SOMETHING ELSE
PUSHJ P,M%GPAG ;GET A PAGE FOR A BUFFER
MOVE T4,S1 ;SAVE THE ADDRESS FOR LATER
MOVEI T1,-1(S1) ;GET BUFFER ADDRESS-1
HLL T1,RLKUP+3 ;GET -FILE LENGTH,,BUFFER ADDR-1
SETZM T2 ;END CCW
IN 17,T1 ;READ THE RAM FILE
SKIPA ;CONTINUE ON SUCCESSFUL RETURN
JRST RDON.1 ;AN ERROR,,TRY SOMETHING ELSE
HLRO T3,RLKUP+3 ;GET -FILE LENGTH
MOVMS T3 ;WANT POSITIVE LENGTH
LSH T3,2 ;CONVERT TO 8 BIT BYTE COUNT
MOVEI T1,.DFLR2 ;WANT LOAD RAM FUNCTION
MOVE T2,J$LCHN(J) ;WANT LPT CHANNEL NUMBER
MOVE S1,[4,,T1] ;GET ARG COUNT,,BLOCK ADDRESS
SETZM S2 ;FLAG S2 (IF 0 THEN RAM LOADED OK)
DEVOP. S1, ;LOAD THE RAM
RDON.1: SETOM S2 ;INDICATE RAM LOAD ERROR
MOVE T1,S2 ;SAVE THE RAM LOAD FLAG
MOVE S1,T4 ;GET THE BUFFER ADDRESS BACK
PUSHJ P,M%RPAG ;RELEASE THE PAGE
RDON.2: MOVEI S1,17 ;GET OUR CHANNEL NUMBER
RESDV. S1, ;WIPE IT OUT
JFCL ;IGNORE ANY ERROR RELEASING THE DEVICE
JUMPN T1,NORAM ;IF AN ERROR,,GO TRY SOMETHING ELSE
MOVE S1,J$FRAM(J) ;GET THE RAM TYPE WE JUST LOADED
MOVEM S1,J$FLRM(J) ;SAVE IT AS LOADED RAM TYPE
$RETT ;AND RETURN
RAMFOB: .IODMP ;DUMP MODE I/O
SIXBIT/SYS/ ;FILE ON SYS:
0,,0 ;DUMP MODE (NO BUFFERS)
RLKUP: BLOCK 4 ;LOOKUP BLOCK
> ;END TOPS10 CONDITIONAL
SUBTTL NORAM - ROUTINE TO PROCESS RAM LOADING ERRORS
NORAM: MOVE S1,STREAM ;GET OUR STREAM NUMBER
$WTOR (,<^I/RAMI1/^J^M^T/RAMI2/>,@JOBOBA(S1),JOBWAC(S1))
SETOM JOBCHK(S1) ;WE WANT A CHECKPOINT TAKEN
$DSCHD (PSF%OR) ;WAIT FOR THE OPERATOR RESPONSE
TXNE S,ABORT+RQB ;CANCELED OR REQUEUED ???
JRST [SETZM J$FORM(J) ;YES,,ZAP THE LOADED FORMS TYPE
$RETT ] ;AND RETURN
HRROI S1,J$RESP(J) ;GET THE RESPONSE ADDRESS
PUSHJ P,S%SIXB ;CONVERT IT TO SIXBIT
MOVEM S2,J$FRAM(J) ;SAVE THE NEW RAM TYPE
JRST LODRAM ;AND TRY AGAIN
RAMI1: ITEXT (<RAM Error, Can't Load RAM '^W/J$FRAM(J)/'>)
RAMI2: ASCIZ /Respond With RAM Type to Continue/
SUBTTL I/O Subroutines for LPFORM.INI
;ROUTINE TO RETURN A SIXBIT WORD IN T1
;RETURNS WITH WORD IN T1. SKIPS NORMALLY, NON-SKIP ON EOF.
FH$SIX: CLEAR T1, ;CLEAR FOR RESULT
MOVE T2,[POINT 6,T1] ;POINTER FOR RESULT
FH$SX1: PUSHJ P,FH$CHR ;GET A CHARACTER
JUMPF .RETF ;FAIL IF EOF
CAIL C,"A" ;CHECK FOR ALPHA
CAILE C,"Z"
SKIPA ;ITS NOT!!
JRST FH$SX2 ;IT IS, DEPOSIT IT
CAIL C,"0" ;CHECK FOR NUMBER
CAILE C,"9"
$RETT ;NO REASONALBE
FH$SX2: SUBI C,40 ;CONVERT TO SIXBIT
TLNE T2,770000 ;GET SIX YET?
IDPB C,T2 ;NO, DEPOSIT ANOTHER
JRST FH$SX1 ;AND LOOP AROUND
;ROUTINE TO RETURN 1 CHARACTER IN ACCUMULATOR C
FH$CHR: SOSGE FMBYT ;MAKE SURE THERE IS DATA IN BUFFER.
JRST FH$C.1 ;IF NOT,,GET ANOTHER BUFFER.
ILDB C,FMPTR ;PICK UP A BYTE
CAIE C,.CHTAB ;CONVERT TABS
CAIN C,.CHCRT ;AND CARRIAGE RETURNS
MOVEI C,40 ;INTO SPACES
CAIE C,.CHFFD ;CONVERT FORM FEEDS
CAIN C,.CHVTB ;AND VERTICAL TABS
MOVEI C,.CHLFD ;INTO LINEFEED
CAIL C,141 ;CHECK LOWER CASE
CAILE C,172 ;141-172
$RETT ;ITS NOT
SUBI C,40 ;YUP, CONVERT TO UPPER
$RETT ;AND SKIP BACK
FH$C.1: MOVE S1,FMIFN ;PICK UP THE IFN.
PUSHJ P,F%IBUF ;READ A BUFFER.
JUMPF .RETF ;IF AN ERROR,,RETURN.
MOVEM S1,FMBYT ;SAVE THE INPUT BYTE COUNT.
MOVEM S2,FMPTR ;SAVE THE INPUT BYTE POINTER.
JRST FH$CHR ;CONTINUE PROCESSING.
;ROUTINE TO SEARCH FOR EOL IN LPFORM.INI
FH$EOL: PUSHJ P,FH$CHR ;GET A CHARACTER
JUMPF .RETF ;FAIL IF EOF
CAIE C,.CHLFD ;EOL?
JRST FH$EOL ;NO, LOOP
$RETT ;YES, RETURN!
;ROUTINE TO PICK UP A DECIMAL NUMBER
FH$DEC: CLEAR T1, ;PLACE TO ACCUMULATE RESULT
FH$DE1: PUSHJ P,FH$CHR ;GET A CHARACTER
JUMPF .RETF ;EOF, RETURN
CAIL C,"0" ;CHECK THE RANGE
CAILE C,"9" ;0-9
POPJ P, ;RETURN
IMULI T1,12 ;SHIFT A PLACE
ADDI T1,-"0"(C) ;ADD IN A DIGIT
JRST FH$DE1 ;AND LOOP AROUND
SUBTTL OUTGET -- OPEN the output device
;THIS ROUTINE OPENS THE SPECIFIED OUTPUT DEVICE, AND SETS UP A BUFFER RING
TOPS10 <
OUTGET: PUSHJ P,GENDEV ;CREATE THE PHYSICAL DEVICE NAME.
MOVEM S1,J$LDEV(J) ;AND SAVE IT
MOVE S1,STREAM ;GET OUR STREAM NUMBER
MOVEM S1,J$LCHN(J) ;SAVE IT AS THE CHANNEL NUMBER
MOVX S2,PSF%DO+PSF%OB ;GET OFFLINE+OUTPUT BLOCKED BITS
ANDCAM S2,JOBSTW(S1) ;AND CLEAR THE SCHEDULING BITS
LSH S1,^D23 ;SHIFT CHANNEL # TO RIGHT PLACE
IOR S1,[OPEN T1] ;MAKE IT AN INSTRUCTION
MOVX T1,.IOASC+IO.SFF+UU.PHS+UU.AIO
;ASCII+SUPRESS FF+PHONLY+NBIO
MOVE T2,J$LDEV(J) ;OUTPUT DEVICE NAME
MOVSI T3,J$LBRH(J) ;BUFFER HEADER
XCT S1 ;AND EXECUTE IT
JRST OUTDNA ;LOSE GIVE ERROR
MOVE T1,[2,,T2] ;ARG POINTER
MOVX T2,.DFHCW ;HARDWARE CHARACTERISTICS WORD
MOVE T3,J$LCHN(J) ;GET CHANNEL NUMBER
DEVOP. T1, ;READ THE CHARS
JRST OUTDDE ;SHOULDN'T HAPPEN
TXNE T1,DF.LCP ;IS IT A LOWER-CASE PRINTER?
SETOM J$LLCL(J) ;YES, SET THE FLAG
MOVE S1,[SIXBIT/LP64/] ;DEFAULT RAM TO 64 CHARACTER
SKIPE J$LLCL(J) ;UNLESS ITS LOWER CASE
MOVE S1,[SIXBIT/LP96/] ;THEN DEFAULT TO 96 CHARACTER SET
MOVEM S1,J$LRAM(J) ;SAVE THE DEFAULT RAM FILE NAME
MOVE S1,D$TAPE ;GET THE DEFAULT VFU TYPE.
SKIPN J$FTAP(J) ;HAS THE VFU ALREADY BEEN DEFAULTED ???
MOVEM S1,J$FTAP(J) ;NO,,SAVE AS THE VFU DEFAULT.
LDB S1,[POINTR(T1,DF.CLS)] ;GET THE COBTROLLER TYPE
MOVEM S1,J$LCLS(J) ;SAVE IT FOR LATER
LDB T1,[POINTR(T1,DF.VFT)] ;GET VFU TYPE
CAIN T1,.DFVTD ;IS IT A DAVFU?
SETOM J$LDVF(J) ;YES, SET THE FLAG
SKIPGE J$LREM(J) ;SKIP IF LOCAL PRINTER
JRST OUTG.2 ;SETUP REGULAR BFRS FOR REMOTE
MOVE T1,J$LBUF(J) ;GET ADDRESS OF BUFFER PAGE
SUBI T1,BUFSIZ ;BACK UP ONE BUFFER
SETZ T2, ;CLEAR A COUNTER
OUTG.1: ADDI T1,BUFSIZ ;POINT TO NEXT BUFFER
MOVEI S1,BUFSIZ+1(T1) ;GET LINK TO NEXT BUFFER
HRLI S1,BUFSIZ-2 ;AND NUMBER DATAWORDS+1
MOVEM S1,1(T1) ;AND STORE IT AWAY IN BUFFER
CAIGE T2,BUFNUM-1 ;GOT THEM ALL?
AOJA T2,OUTG.1 ;NO, LOOP AROUND
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
MOVNI T2,BUFSIZ*BUFNUM ;LOAD -<COMPLETE BUFFER SIZE>
ADDM T2,1(T1) ;MAKE LAST BUFFER POINT TO FIRST
MOVE T1,J$LBUF(J) ;GET ADDRESS OF BUFFER PAGE BACK
ADDI T1,1 ;POINT TO WORD 1
TXO T1,BF.VBR ;MAKE IT A VIRGIN RING
MOVEM T1,J$LBRH(J) ;AND PUT IT WHERE MONITOR WILL FIND IT
JRST OUTSOK ;AND CONTINUE ON
OUTG.2: MOVE S1,J$LBUF(J) ;GET ADR OF BUFFER PAGE
EXCH S1,.JBFF ;SWAP IT WITH JOBFF
MOVE S2,J$LCHN(J) ;GET THE CHANNEL NUMBER
LSH S2,^D23 ;POSITION IT
IOR S2,[OUTBUF 2] ;MAKE AN INSTRUCTION
XCT S2 ;AND EXECUTE IT
MOVEM S1,.JBFF ;RESTORE JOBFF
JRST OUTSOK ;AND CONTINUE ON
GENDEV: SKIPE S1,J$MTAP(J) ;IS THERE A SPECIFIC DEVICE TO WRITE ON
$RETT ;YES,,RETURN WITH DEVICE IN S1
MOVE T1,STREAM ;PICK UP STREAM NUMBER.
MOVE T1,JOBOBA(T1) ;PICK UP OBJECT BLOCK ADDRESS.
MOVE S1,OBJ.ND(T1) ;PICK UP THE NODE NUMBER.
CAME S1,CNTSTA ;IS IT THE CENTRAL SITE ???
SETOM J$LREM(J) ;NO,,THEN ITS A REMOTE LPT.
IDIVI S1,10 ;SPLIT NODE NUMBER IN HALF.
IMULI S1,100 ;SHIFT LEFT 2 DIGITS.
ADD S1,S2 ;ADD SECOND NODE DIGIT.
IMULI S1,100 ;SHIFT LEFT ANOTHER 2 DIGITS.
ADD S1,OBJ.UN(T1) ;ADD THE UNIT NUMBER.
ADD S1,[SIXBIT/LPT000/] ;CREATE THE PHYSICAL DEVICE NAME.
POPJ P, ;RETURN. . . . .
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTGET: SKIPE J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
PJRST TAPGET ;YES,,OPEN DIFFERENTLY
MOVSI S1,(POINT 8,0) ;GET 8 BIT BYTE POINTER
MOVEM S1,J$LBTZ(J) ;SAVE IT FOR LATER
MOVE S1,STREAM ;GET OUR STREAM NUMBER
MOVE S1,JOBOBA(S1) ;GET OUR OBJECT BLOCK ADDRESS
SKIPN J$LREM(J) ;IS THIS A LOCAL LPT ???
$TEXT (<-1,,J$LSTG(J)>,<PLPT^O/OBJ.UN(S1)/:^0>) ;YES,,GEN UNIT NAME
SKIPGE J$LREM(J) ;IS THIS A REMOTE LPT ???
$TEXT (<-1,,J$LSTG(J)>,<^W/OBJ.ND(S1)/::PLPT^O/OBJ.UN(S1)/:^0>)
MOVX S1,GJ%FOU!GJ%SHT ;LOAD GTJFN FLAGS
HRROI S2,J$LSTG(J) ;POINT TO THE STRING
PUSHJ P,$GTJFN ;GET THE LPT JFN
JUMPF OUTDDE ;CANT,,FATAL ERROR
MOVEM S1,J$LCHN(J) ;WIN, SAVE THE JFN
MOVX S2,OF%WR+OF%OFL+8B5 ;OPEN FOR WRITING 8 BIT BYTES
PUSHJ P,$OPENF ;OPEN THE DEVICE
JUMPF OUTDNA ;CANT,,DEVICE NOT AVAILABLE NOW.
PUSHJ P,OUTRES ;SETUP/RESET THE OUTPUT BUFR POINTERS
SKIPLE J$LREM(J) ;IS THIS A DN60 (IBM) LPT ???
JRST [MOVX S1,%RSUOK ;YES,,GET 'SETUP OK'
$RETT ] ; AND SKIP THE REST OF THIS !!!
MOVE S1,J$LCHN(J) ;GET LPT JFN
MOVX S2,.MORST ;GET FUNCTION TO READ STATUS
MOVEI T1,T2 ;LOAD ADDRESS OF ARG BLOCK
MOVEI T2,3 ;LOAD LENGTH OF ARG BLOCK
PUSHJ P,$MTOPR ;GO GET THE DEVICE STATUS
JUMPF OUTSOK ;CANT,,IGNORE THE ERROR
TXNE T3,MO%FNX ;DOES THE LPT EXIST ???
PJRST [PUSHJ P,OUTREL ;NO,,RELEASE JFN AND CLOSE THE LPT
PJRST OUTDDE ] ; AND RETURN THROUGH 'DOES NOT EXIST'
TXNE T3,MO%LCP ;IS IT A LOWER CASE PRINTER?
SETOM J$LLCL(J) ;YES, SET THE FLAG
MOVE S1,[SIXBIT/LP64/] ;DEFAULT TO 64 CHARACTER RAM
SKIPE J$LLCL(J) ;UNLESS IT IS A LOWER CASE LPT,
MOVE S1,[SIXBIT/LP96/] ;THEN ITS A 96 CHARACTER RAM
MOVEM S1,J$LRAM(J) ;SAVE THE DEFAULT RAM FILE NAME
MOVE S1,D$TAPE ;GET THE DEFAULT VFU TYPE.
SKIPN J$FTAP(J) ;HAS THE VFU ALREADY BEEN DEFAULTED ???
MOVEM S1,J$FTAP(J) ;NO,,SAVE AS THE VFU DEFAULT.
TXNN T3,MO%LVU ;IS IT NOT OPTICAL VFU
SETOM J$LDVF(J) ;YES, SET THAT
MOVX S1,PSF%DO ;DEVICE OFFLINE FLAG
ANDCAM S1,JOBSTW ;CLEAR THE VALUE
TXNE T3,MO%OL ;IS IT OFF-LINE?
IORM S1,JOBSTW ;YES, SET FLAG
JRST OUTSOK ;CONTINUE ON OK
> ;END TOPS20 CONDITIONAL
SUBTTL OUTGET Exit Subroutines
OUTSOK: PUSHJ P,INTCNL ;CONNECT UP THE LPT
JUMPF OUTDDE ;DID NOT SUCCEED,,DEVICE DOES NOT EXIST
TXO S,INTRPT ;INDICATE WE'RE CONNECTED
MOVX S1,%RSUOK ;LOAD THE CODE
$RETT ;AND RETURN
OUTDNA: MOVX S1,%RSUNA ;NOT AVAILABLE RIGHT NOW
$RETF ;AND RETURN
OUTDDE: MOVX S1,%RSUDE ;NEVER AVAILABLE
$RETF ;RETURN
SUBTTL TAPGET - ROUTINE TO SETUP A MAG TAPE DEVICE FOR OUTPUT
TOPS20 <
TAPGET: SKIPN J$LSTG(J) ;DO WE HAVE A DEVICE NAME YET ???
$TEXT (<-1,,J$LSTG(J)>,<^W/J$MTAP(J)/:^0>) ;NO,,GEN THE DEVICE NAME
SETZM J$LREM(J) ;FORCE US TO BE LOCAL
HRLI S1,(POINT 7,0) ;GET 7 BIT BYTE POINTER (OUTPUT)
MOVEM S1,J$LBTZ(J) ;SAVE IT FOR LATER
MOVX S1,GJ%SHT+GJ%FOU ;GET GTJFN FLAG BITS
HRROI S2,J$LSTG(J) ;POINT TO THE DEVICE NAME
GTJFN ;GET A JFN
JRST TAPG.2 ;CANT,,TOUGH BREAKEEE
MOVEM S1,J$LCHN(J) ;SAVE THE JFN
DVCHR ;GET THE DEVICE CHARACTERISTICS
ERJMP TAPG.1 ;SHOULD NOT HAPPEN
MOVX S1,DEVX2 ;GET ALREADY ASSIGNED ERROR CODE
HLRZS T1 ;MOVE LEFT TO RIGHT,,ZERO LEFT
CAIE T1,-1 ;THE TAPE SHOULD NOT BE ASSIGNED !!!
JRST TAPG.1 ;IT IS,,CAN THE REQUEST
MOVE S1,J$LCHN(J) ;GET THE JFN BACK
MOVX S2,OF%WR+7B5 ;WRITE+7 BIT BYTES
OPENF ;OPEN THE MAG TAPE
JRST TAPG.1 ;CANT,,TOUGH !!!
MOVE S1,J$LCHN(J) ;GET THE JFN
MOVX S2,.MONOP ;WAIT FOR I/O or SET TTY PAGE WIDTH
SETZM T1 ;NO ARGS or INFINITE PAGE WIDTH
MTOPR ;DO IT !!!
ERJMP .+1 ;IGNORE THE ERROR
PUSHJ P,OUTRES ;SETUP THE OUTPUT POINTERS
PJRST OUTSOK ;SO FAR HE WINS...
TAPG.1: MOVE T1,S1 ;SAVE THE ERROR CODE
MOVE S1,J$LCHN(J) ;GET THE JFN
RLJFN ;RELEASE IT
JFCL ;IGNORE THE ERROR
MOVE S1,T1 ;RESTORE THE ERROR CODE TO S1
TAPG.2: MOVE S2,STREAM ;GET OUR STREAM NUMBER
$WTO (<^T/J$LSTG(J)/ ^E/S1/>,,@JOBOBA(S2)) ;TELL THE OPERATOR
PJRST OUTDDE ;GIVE UP THE SHIP
>
SUBTTL OUTOUT -- Routine to output a buffer
TOPS10 <
;NOTE: The 'Output-Blocked' bit is set here in order to avoid
; a race condition which would allow LPTSPL to miss the
; 'Output-Done' Interrupt. In particular, this avoids
; the problem of getting the 'Output-Done' interrupt
; before LPTSPL has set the 'Output-Blocked' bit when
; de-scheduling the stream. This situation would cause
; the stream to block forever, waiting for an interrupt
; which it had already received.
OUTOUT: MOVE S1,STREAM ;GET THE STREAM NUMBER
MOVX S2,PSF%OB ;GET THE 'OUTPUT-BLOCKED' BIT
IORM S2,JOBSTW(S1) ;TURN ON THE 'OUTPUT-BLOCKED' BIT
MOVE S1,J$LCHN(J) ;GET THE CHANNEL NUMBER
LSH S1,^D23 ;POSITION IT
TLO S1,(OUT 0,0) ;MAKE IT AN OUTPUT UUO
XCT S1 ;OUTPUT THE BUFFER
JRST [MOVE S1,STREAM ;NO ERROR,,GET OUR STREAM NUMBER
ANDCAM S2,JOBSTW(S1) ; AND CLEAR THE OUTPUT BLOCKED BITS
$RETT ] ; NOW WE CAN RETURN
PJRST OUTERR ;ERROR,,GO PROCESS IT
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTOUT: PUSHJ P,.SAVET ;SAVE THE 'T' ACS
OUTO.1: PUSHJ P,OUTWON ;CHECK OFFLINE STATUS
$DSCHD(0) ;FORCE A SCHEDULING PASS
SKIPGE T1,J$LBCT(J) ;GET BYTES REMAINING IN BUFFER
SETZM T1 ;IF LESS,,MAKE IT ZERO
SUB T1,J$LIBC(J) ;CALC -BYTE COUNT IN BUFFER
JUMPGE T1,OUTRES ;NOTHING TO PUT OUT,,RESET BUFR PTRS
MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVE S2,J$LIBP(J) ;GET THE STARTING BYTE POINTER
PUSHJ P,$SOUT ;OUTPUT THE DATA
MOVEM S2,J$LIBP(J) ;SAVE THE BUFFER POINTER AND
MOVMM T1,J$LIBC(J) ; THE BYTE COUNT JUST IN CASE
SETZM J$LBCT(J) ;CLEAR BYTE COUNT FOR THE BUFFER
SKIPT ;SKIP IF SOUT WAS OK
PUSHJ P,OUTERR ;ELSE GO PROCESS THE ERROR
SKIPLE J$LIBC(J) ;ANY BYTES LEFT IN THE BUFFER ???
JRST OUTO.1 ;YES,,GO PUT THEM OUT
OUTRES: MOVEI S1,BUFCHR ;GET CHARACTERS PER BUFFER
MOVEM S1,J$LBCT(J) ;SAVE AS BUFFER BYTE COUNT
MOVEM S1,J$LIBC(J) ;HERE ALSO
MOVE S1,J$LBUF(J) ;GET THE BUFFER ADDRESS
ADD S1,J$LBTZ(J) ;ADD THE BYTE PTR (LEFT HALF)
MOVEM S1,J$LBPT(J) ;SAVE AS BUFFER BYTE POINTER
MOVEM S1,J$LIBP(J) ;HERE ALSO
$RETT ;AND RETURN
> ;END TOPS20 CONDITIONAL
SUBTTL OUTERR -- Handle Output Device Errors
OUTERR:
TOPS10 <
MOVE S1,J$LCHN(J) ;GET THE CHANNEL NUMBER
LSH S1,^D23 ;POSITION IT
IOR S1,[GETSTS J$LIOS(J)] ;MAKE IT AN INSTRUCTION
XCT S1 ;AND EXECUTE IT
MOVE S1,J$LIOS(J) ;GET THE IOERROR STATUS
TXNE S1,IO.ERR!IO.EOT ;WAS THERE AN ERROR? OR HIT END OF TAPE?
JRST OUTE.1 ;YES, GIVE THE ERROR
$DSCHD(0) ;BLOCK FOR OUTPUT DONE (See Above)
JRST OUTOUT ;AND TRY AGAIN
OUTE.1: PUSHJ P,.SAVET ;SAVE ALL THE 'T' ACS
MOVE T4,STREAM ;GET THE STREAM NUMBER
MOVE S1,J$LIOS(J) ;GET THE ERROR STATUS
TRC S1,IO.ERR ;TEST FOR ALL FOUR ERROR BITS
TRCE S1,IO.ERR ;BEING SET.
JRST OUTE.5 ;AND THEY ARE NOT
MOVE T1,[2,,T2] ;PREPARE FOR DEVOP. UUO
MOVEI T2,.DFRES ;READ EXTENDED ERROR STATUS
MOVE T3,J$LCHN(J) ;GET CHANNEL NUMBER
DEVOP. T1,
JRST OUTE.2 ;LOSE, JUST GIVE STATUS
CAXN T1,IOVFE% ;IS THE ERROR BAD VFU ?
JRST OUTE.4 ;YES,,DO SOME SPECIAL PROCESSING
CAXE T1,IOPAR% ;IS IT RAM TROUBLE ???
JRST OUTE.2 ;NO,,GENERAL I/O ERROR
;YES,,FALL THROUGH AND PROCESS IT
> ;END TOPS10 CONDITIONAL
TOPS20 <
MOVE T4,STREAM ;GET OUR STREAM NUMBER
PUSHJ P,$GDSTS ;GET THE DEVICE STATUS
MOVEM S1,J$LIOS(J) ;SAVE THE DEVICE STATUS
MOVE T1,S1 ;SAVE IT HERE ALSO
TXZ S1,MO%OL ;CLEAR THE OFFLINE BIT
PUSHJ P,$SDSTS ;RESET THE DEVICE STATUS
TXNE T1,MO%LVF ;VFU ERR ???
JRST OUTE.4 ;YES,,GO PROCESS IT
TXNN T1,MO%RPE ;WAS IT A RAM PARITY ERROR
JRST OUTE.2 ;NO,,PROCESS AS AN I/O ERROR
> ;END TOPS20 CONDITIONAL ;YES,,PROCESS IT
;RAM PARITY ERROR
OUT.2A: $WTO (RAM Parity Error,,@JOBOBA(T4)) ;YES,,TELL OPERATOR
PUSHJ P,OUTE.3 ;PERFORM SOME PRELIMINARY PROCESSING
SETZM J$FLRM(J) ;FORCE A RAM RELOAD
PUSHJ P,LODRAM ;GO DO IT !!!
$RETT ;AND RETURN
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
;UNKNOWN TYPE I/O ERROR OCCURED
OUTE.2: $WTO (I/O Error,<Status is: ^O/J$LIOS(J)/>,@JOBOBA(T4))
;GENERAL I/O ERROR RECOVERY ROUTINE
OUTE.3: PUSHJ P,OUTDIE ;SEE IF TOO MANY ERRORS
PUSHJ P,OUTFLS ;RESET THE OUTPUT CHANNEL
JUMPF [MOVX S1,%RSUNA ;CAN'T,,GET 'DEVICE NOT AVAILABLE' ERROR
PUSHJ P,RSETUP ;TELL QUASAR TO RESET THE OBJECT
PJRST SHUTIN ] ;SHUT DOWN THE DEVICE
TXNN S,VFULOD+BANHDR ;IF LOADING VFU OR PRINTING HDRS
TXNN S,DSKOPN ; OR IF WE ARE NOT IN A FILE?
$RETT ;THEN JUST RETURN
MOVE S1,J$RNCP(J) ;GET NUMBER OF COPIES PRINTED
AOS S1 ;MAKE INTO CURRENCT COPY NUMBER
$TEXT (LOGCHR,<^I/LPERR/LPT I/O Error occurred during ^F/@J$DFDA(J)/, Copy:^D/S1/, Page:^D/J$RNPP(J)/; Status is: ^O/J$LIOS(J)/>)
MOVEI S1,[EXP 5] ;PREPARE TO BACKSPACE 5 PAGES
PUSHJ P,BSPACE ;BACKSPACE 5 PAGES
$RETT ;RETURN
;VFU ERROR OCCURED
OUTE.4: $WTOR (VFU error,<Re-align forms and put on-line^M^J^T/ENDRSP/>,@JOBOBA(T4),JOBWAC(T4))
SETOM JOBCHK(T4) ;SAY WE WANT A CHECKPOINT TAKEN
$DSCHD(PSF%OR) ;WAIT FOR THE OPERATOR RESPONSE
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED OR REQUEUED ???
$RETT ;YES,,JUST RETURN
MOVEI S1,CONANS ;POINT TO THE CONTINUE ANSWER BLOCK
HRROI S2,J$RESP(J) ;POINT TO THE ANSWER
PUSHJ P,S%TBLK ;DO WE MATCH ???
TXNE S2,TL%NOM+TL%AMB ;DID WE FIND IT OK ???
JRST OUTE.4 ;NO,,STUPID OPERATOR SO TRY AGAIN
PUSHJ P,OUTE.3 ;GO PERFORM SOME PRELIMINARY PROCESSING
SETZM J$FLVT(J) ;FORCE A VFU RELOAD
PUSHJ P,LODVFU ;GO RELOAD THE VFU
$RETT ;AND RETURN
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
;NO STOCK ERROR BITS SET, TRY EOF (END OF TAPE)
TOPS10<
OUTE.5: SKIPE J$MTAP(J) ;ARE WE SPOOLING TO TAPE?
TRZN S1,IO.EOT ;YES, HIT EOT?
JRST OUTE.2 ;NO, UNKNOWN ERROR
MOVE T1,J$LCHN(J) ;GET CHANNEL NUMBER
LSH T1,^D23 ;MOVE INTO PLACE (AC FIELD)
TLO T1,(SETSTS (S1)) ;MAKE INTO A UUO
XCT T1 ;CLEAR THE ERROR (EOT)
MOVE T1,[XWD 2,T2] ;AIM AT ARGUMENT BLOCK FOR TAPOP.
MOVX T2,.TFWTM ;CODE TO WRITE A TAPE MARK
MOVE T3,J$LCHN(J) ;DEVICE ON THIS CHANNEL
TAPOP. T1, ;WRITE ONE MARK
JFCL ;OH WELL
TAPOP. T1, ;WRITE ANOTHER (MARK END OF TAPE)
JFCL ;ITS A BAD DAY (AND A BAD TAPE!)
MOVX T2,.TFUNL ;CODE TO GET RID OF THE TAPE
TAPOP. T1, ;UNLOAD THIS FULL REEL
JFCL ;HAVE TO LIVE WITH IT
OUT.5A: $WTOR (End of tape,<Mount next reel on ^W/J$MTAP(J)/^M^Jand RESPOND with CONTINUE>,@JOBOBA(T4),JOBWAC(T4))
SETOM JOBCHK(T4) ;ASK FOR A CHECKPOINT
$DSCHD (PSF%OR) ;DROP THE STREAM TILL RESPONSE COMES IN
TXNE S,ABORT+RQB ;HAVE WE BEEN GIVEN THE GONG?
$RETT ;YES, QUIT NOW
MOVEI S1,CONANS ;POINT TO THE VALID RESPONSES
HRROI S2,J$RESP(J) ;AIM AT WHAT THE OPR TYPED
$CALL S%TBLK ;BOUNCE RESPONSE OFF TABLE
TXNE S2,TL%NOM+TL%AMB ;MATCH?
JRST OUT.5A ;NO, ASK OPR AGAIN
JRST OUTOUT ;NEW REEL IS UP, TRY OUTPUT AGAIN
>;END OF TOPS10
CONANS: 1,,1 ;TBLK CONTROL BLOCK
[ASCIZ/CONTINUE/],,0 ;POSSIBLE RESPONSE
OUTDIE: SOSL J$LERR(J) ;COUNT DOWN ERRORS
POPJ P, ;STILL ALIVE
MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (TOO MANY DEVICE ERRORS,,@JOBOBA(S1))
MOVEI S1,%RSUDE ;GET DEVICE DOES NOT EXIST BIT.
PUSHJ P,RSETUP ;TELL QUASAR PRINTER IS OUT TO LUNCH.
PJRST SHUTIN ;AND SHUT IT DOWN
SUBTTL OUTWON -- Wait for on-line
;On the -10, this routine should only be gotten to by DEBRKing to it
; on a device off-line interrupt. On the -20, it can be called
; from anywhere.
; NOTE: The ONLINE/OFFLINE (PSF%DO) status bits are set and cleared
; at interrupt level. This pervents a race condition from
; occuring where the device comes online while we are still
; processing the device offline interrupt. In this case
; it was possible for LPTSPL to miss the on-line
; change-of-state, and sleep forever waiting for the
; online interrupt.
TOPS10 <
OUTWON: PUSH P,S1 ;SAVE S1
PUSH P,S2 ;SAVE S2
MOVE S1,STREAM ;GET STREAM NUMBER
$WTO (<^T/BELL/>,,@JOBOBA(S1)) ;TELL THE OPERATOR.
$DSCHD(0) ;BLOCK THE PROCESS
POP P,S2 ;RESTORE S2
POP P,S1 ;RESTORE S1
JRST @J$LIOA(J) ;AND CONTINUE ON
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTWON: MOVX S2,PSF%DO ;DEVICE OFFLINE FLAG
MOVE S1,STREAM ;AND THE STREAM NUMBER
TDNN S2,JOBSTW(S1) ;IS IT OFF-LINE?
POPJ P, ;NO, JUST RETURN
$WTO (<^T/BELL/>,,@JOBOBA(S1)) ;TELL THE OPERATOR.
$DSCHD(0) ;BLOCK FOR DEVICE ONLINE
POPJ P, ;NO, RETURN
> ;END TOPS20 CONDITIONAL
BELL: BYTE(7) 07,07,117,146,146
ASCIZ/line/
SUBTTL OUTREL -- Release device on SHUTDOWN
TOPS10 <
OUTREL: TXZE S,INTRPT ;ARE WE CONNECTED TO INTRPT SYSTEM ??
PUSHJ P,INTDCL ;YES,,RELEASE THE INTERRUPTS
MOVE S1,J$LCHN(J) ;GET THE CHANNEL
SKIPE J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
JRST OUTR.1 ;YES,,ISSUE A CLOSE/RELEASE INSTEAD
RESDV. S1, ;RESET THE CHANNEL
JFCL ;IGNORE ANY ERRORS
$RETT ;AND RETURN
OUTR.1: LSH S1,^D23 ;POSITION THE CHANNEL NUMBER
TLO S1,(CLOSE 0,0) ;MAKE IT A CLOSE UUO
XCT S1 ;CLOSE THE MAG TAPE
MOVE S1,J$LCHN(J) ;GET THE CHANNEL NUMBER AGAIN
LSH S1,^D23 ;POSITION IT
TLO S1,(RELEASE 0,0) ;MAKE IT A RELEASE UUO
XCT S1 ;RELEASE THE DEVICE
$RETT ;AND RETURN
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTREL: MOVE S1,J$LCHN(J) ;GET THE CHANNEL(JFN)
MOVX S2,.MOFLO ;GET FLUSH BUFFERS CODE
SETZ T1, ;SET AC 3 TO 0
PUSHJ P,$MTOPR ;FLUSH THE BUFFERS
JUMPF .+1 ;IGNORE ANY ERRORS
SKIPE J$MTAP(J) ;ARE WE SPOOLING TO TAPE ???
JRST OUTR.1 ;YES,,DO THINGS A LITTLE DIFFERENTLY
MOVE S1,J$LCHN(J) ;NO,,GET THE JFN AGAIN
TXO S1,CZ%ABT ;ABORT ALL OUTPUT OPERATIONS
PUSHJ P,$CLOSF ;CLOSE IT DOWN
$RETT ;NO,, RETURN
OUTR.1: MOVE S1,J$LCHN(J) ;GET THE JFN
MOVX S2,.MONOP ;WAIT FOR ALL OUTPUT TO STOP
SETZM T1 ;NO ARGS
MTOPR ;DO IT !!!
ERJMP .+1 ;IGNORE THE ERROR
MOVX S2,.MOEOF ;WANT TO WRITE SOME TAPE MARKS
MTOPR ;WRITE ONE
ERJMP .+1 ;IGNORE ANY ERROR
MTOPR ;WRITE ANOTHER !!!
ERJMP .+1 ;IGNORE THE ERROR
MTOPR ;ONE MORE FOR GOOD LUCK !!!!
ERJMP .+1 ;IGNORE THE ERROR
MOVX S2,.MORUL ;WANT TO REWIND AND UNLOAD THE TAPE
MTOPR ;DO IT !!!
ERJMP .+1 ;IGNORE THE ERROR
TXO S1,CZ%ABT ;LITE THE ABORT BIT
CLOSF ;CLOSE DOWN THE MAG TAPE
JFCL ;IGNORE THE ERROR
$RETT ;AND RETURN
>;END TOPS20 CONDITIONAL
SUBTTL OUTEOF - ROUTINE TO CLEAR THE LPT OUTPUT BUFFERS
TOPS10 <
OUTEOF: $SAVE <T1> ;SAVE T1 FOR A MINUTE
MOVX S1,.TFWTM ;GET WRITE TAPE MARK CODE
MOVE S2,J$LCHN(J) ;GET THE DEVICE CHANNEL #
MOVE T1,[XWD 2,S1] ;GET LENGTH,,PARM BLOCK ADDRESS
TAPOP. T1, ;DO IT
JFCL ;IGNORE ANY ERRORS
$RETT ;AND RETURN
>
TOPS20 <
OUTEOF: MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVX S2,.MOEOF ;GET THE FLUSH BUFFERS CODE
SETZM T1 ;NO ARGS
PUSHJ P,$MTOPR ;DO IT
$RETT ;AND RETURN
>
SUBTTL OUTDMP -- Dump out buffers and wait
TOPS10 <
OUTDMP:
REPEAT BUFNUM+1,<
PUSHJ P,OUTOUT ;DUMP THE BUFFER
> ;END REPEAT BUFNUM
POPJ P, ;AND RETURN
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTDMP: PUSHJ P,OUTOUT ;DUMP THE INTERNAL BUFFERS
MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVX S2,.MONOP ;AND NO-OP FUNCTION
SETZM T1 ;ZAP AC 3
PUSHJ P,$MTOPR ;DO IT
SKIPT ;OK,,CONTINUE
PUSHJ P,OUTERR ;ELSE GO PROCESS THE ERROR
$RETT ;AND RETURN
> ;END TOPS20 CONDITIONAL
SUBTTL OUTFLS -- Flush already buffered output
;OUTFLS IS CALLED TO FLUSH OUTPUT TO THE PRINTER WHICH HAS ALREADY BEEN
; BUFFERED (AND POSSIBLE SENT TO THE PRINTER).
TOPS10 <
OUTFLS: PUSHJ P,INTDCL ;DISCONNECT PRINTER INTERRUPTS
MOVE S1,J$LCHN(J) ;LOAD THE CHANNEL NUMBER
RESDV. S1, ;RESET THE CHANNEL
JFCL ;??
PUSHJ P,OUTGET ;GO RESET UP THE OUTPUT DEVICE
CAIN S1,%RSUOK ;ARE WE ALL RIGHT ???
$RETT ;YES,,JUST RETURN
PUSHJ P,RSETUP ;NO,,SEND RESPONSE TO SETUP MSG
$RETF ;AND RETURN
> ;END TOPS10 CONDITIONAL
TOPS20 <
OUTFLS: MOVE S1,J$LCHN(J) ;GET OUTPUT JFN
MOVX S2,.MOFLO ;LOAD FLUSH FUNCTION
MOVEI T1,0 ;AND ZERO ARGUMENTS
PUSHJ P,$MTOPR ;FLUSH THE BUFFERS
JUMPF OUTF.1 ;ON AN ERROR,,SHUT IT DOWN AND RESET IT
PUSHJ P,OUTRES ;RESET THE OUTPUT POINTERS
MOVX S1,%RSUOK ;RETURN 'FLUSH' OK
$RETT ;HEAD BACK
OUTF.1: MOVE S1,J$LCHN(J) ;GET THE LPT JFN
TXO S1,CZ%ABT ;LITE THE ABORT BIT
PUSHJ P,$CLOSF ;CLOSE IT DOWN
PJRST OUTGET ;AND SET THE DEVICE UP AGAIN
> ;END TOPS20 CONDITIONAL
SUBTTL LPT CONTROL ROUTINES
;CONTROL CHARACTER TABLE
NCLRFF==1B0 ;DON'T CLEAR FORMFEED FLAG
SUPRCH==1B1 ;SUPPRESSABLE CHARACTER
EOLCHR==1B2 ;CHARACTER IS AN EOL (IN REPORT FILES)
CHTAB: EXP <NCLRFF+.POPJ> ;(00) NULL
EXP CHKARO ;(01) CONTROL-A
EXP CHKARO ;(02) CONTROL-B
EXP CHKARO ;(03) CONTROL-C
EXP CHKARO ;(04) CONTROL-D
EXP CHKARO ;(05) CONTROL-E
EXP CHKARO ;(06) CONTROL-F
EXP CHKARO ;(07) CONTROL-G
EXP CHKARO ;(10) CONTROL-H
EXP NCLRFF+DEVOUT ;(11) THIS IS A TAB
EXP SUPRCH+EOLCHR+DOLF ;(12) THIS IS A LINE FEED
EXP SUPRCH+EOLCHR+3+DOFRAC ;(13) THIS SKIPS 1/3 PAGE (VERT TAB)
EXP SUPRCH+NCLRFF+EOLCHR+DOFORM ;(14) THIS IS A FORM-FEED
EXP NCLRFF+EOLCHR+DEVOUT ;(15) CARRIAGE RETURN
EXP CHKARO ;(16) CONTROL-N
EXP CHKARO ;(17) CONTROL-O
EXP SUPRCH+EOLCHR+2+DOFRAC ;(20) THIS SKIPS 1/2 PAGE
EXP SUPRCH+EOLCHR+30+DOFRAC ;(21) THIS SKIPS 2 LINES (DC1)
EXP SUPRCH+EOLCHR+20+DOFRAC ;(22) THIS SKIPS 3 LINES (DC2)
EXP SUPRCH+EOLCHR+DODC3 ;(23) DC3 SKIPS 1 LINE
EXP SUPRCH+EOLCHR+6+DOFRAC ;(24) THIS SKIPS 1/6 OF A PAGE (DC4)
EXP CHKARO ;(25) CONTROL-U
EXP CHKARO ;(26) CONTROL-OL-V
EXP CHKARO ;(27) CONTROL-W
EXP CHKARO ;(30) CONTROL-X
EXP CHKARO ;(31) CONTROL-Y
EXP CHKARO ;(32) CONTROL-Z
EXP CHKARO ;(33) ESCAPE
EXP CHKARO ;(34) CONTROL-\
EXP CHKARO ;(35) CONTROL-]
EXP CHKARO ;(36) CONTROL-^
EXP CHKARO ;(37) CONTROL-
;FORTRAN CONTROL CHARACTOR TRANSLATION TABLE
DEFINE FORCHR(CHR,TRANS,N),<
EXP <CHR>B17+<N>B26+TRANS
> ;END DEFINE FORCHR
FORTAB: FORCHR " ",.CHLFD,1
FORCHR "0",.CHLFD,2
FORCHR "1",.CHFFD,1
FORCHR "2",20,1
FORCHR "3",13,1
FORCHR "/",24,1
FORCHR "*",23,1
FORCHR "+",.CHCRT,1
FORCHR 54,21,1
FORCHR "-",.CHLFD,3
FORCHR ".",22,1
NFORCH==.-FORTAB
SUBTTL FILOUT - SUBROUTINE TO SET UP FOR LPTIN AND LPTOUT
; CALL WITH:
; PUSHJ P,FILOUT
; RETURN HERE
;
FILOUT: MOVE T1,J$FLIN(J) ;START AT TOP OF PAGE
MOVEM T1,J$XPOS(J) ;SAVE IT
PUSHJ P,SETPFT ;SETUP FILE TYPE
PUSHJ P,(T1) ;DISPATCH
TXNN S,RQB ;HAVE WE BEEN REQUEUED ???
SKIPE J$XTOP(J) ;OR ARE WE AT TOP-OF-FORM?
POPJ P, ;YES TO EITHER,,JUST RETURN
AOS J$APRT(J) ;NO, CHARGE HIM FOR THE REST
AOS J$RNPP(J) ;HERE ALSO
POPJ P, ;AND RETURN
SUBTTL SETLST - SUBROUTINE TO COMPILE CODE TO TEST EACH LINE FOR A MATCH AGAINST
; THE /REPORT VALUE.
; CALL WITH:
; PUSHJ P,SETLST
; RETURN HERE
;
SETLST: MOVEI T2,J$XCOD-1(J) ;SET UP PDP TO COMPILED CODE
SKIPN .FPFR1(E) ;WAS /REPORT SPECIFIED?
$RETT ;NO, JUST RETURN
STLST1: MOVE T3,[POINT 6,.FPFR1(E)] ;POINTER TO LIST
MOVEI T4,^D12 ;ABSOLUTE LIMIT
STLST2: ILDB T1,T3 ;GET A CHAR
JUMPE T1,STLSC ;JUMP IF DONE
ADDI T1,"A"-'A' ;CONVERT TO ASCII
CAIN T4,^D12 ;1ST TIME THRU, WE'VE GOT A CHARACTER
JRST STLST4 ;YES--CHAR ALRADY IN C
PUSH T2,SETLSA ;COMPILE A PUSHJ
PUSH T2,SETLSB ;WE HAVE AN ERROR RETURN THEN
STLST4: HLL T1,SETLSC ;PLACE CHAR IN CAIE
PUSH T2,T1 ;COMPILE THE CAIE
PUSH T2,SETLSD ;COMPILE THE JRST TO FLUSH7
SOJG T4,STLST2 ;LOOP FOR WHOLE STRING
STLSC: PUSH T2,[POPJ P,] ;AND PROCESS THE CHARACTER
POPJ P, ;RETURN
;THE INSTRUCTIONS WHICH ARE GENERATED:
SETLSA: PUSHJ P,INPBYT
SETLSB: JUMPF .RETT
SETLSC: CAIE C,0
SETLSD: JRST FLUSH7
SUBTTL SETPFT -- Setup file processing type
;CALLED TO DETERMINE WHICH TYPE OF PROCESSING SHOULD BE DONE ON THE
; INPUT FILE.
;
;RETURNS WITH T1 CONTAINING ADDRESS OF PROCESSING ROUTINE AS FOLLOWS:
;
; LPTOCT <--> /PRINT:OCTAL
; LPTCOB <--> /FILE:COBOL
; LPTFOR <--> /FILE:FORTRAN /PRINT:(ARROW,ASCII,SUPPRESS)
; LPTRPT <--> /FILE:ASCII /REPORT:XXX /PRINT:(ARROW,ASCII,SUP)
; LPTASC <--> /FILE:ASCII /PRINT:(ARROW,ASCII,SUPPRESS)
; LPTELV <--> /FILE:ELEVEN
;THE DETERMINATION IS DONE IN THE ABOVE ORDER
SETPFT: LOAD S1,.FPINF(E),FP.FFF ;GET /FILE
LOAD S2,.FPINF(E),FP.FPF ;GET /PRINT
TXZ S,ARROW ;CLEAR SOME INITIAL FLAGS
TXO S,NEWLIN!FCONV ;AND SET SOME OTHERS
MOVEI T1,LPTOCT ;ASSUME /PRINT:OCTAL
CAIN S2,%FPLOC ;IS IT?
POPJ P, ;YES, RETURN
MOVEI T1,LPTCOB ;NO, ASSUME /FILE:COBOL
CAIN S1,.FPFCO ;IS IT?
POPJ P, ;YES, RETURN
CAIN S2,%FPLAR ;/PRINT:ARROW?
TXO S,ARROW ;YES, LIGHT A FLAG
CAIN S2,%FPLSU ;/PRINT:SUPPRESS?
TXO S,SUPFIL ;YES, LIGHT A BIT
MOVEI T1,LPTFOR ;ASSUME /FILE:FORTRAN
CAIN S1,.FPFFO ;IS IT?
POPJ P, ;YES, RETURN
MOVEI T1,LPTELV ;ASSUME /FILE:ELEVEN
CAIN S1,.FPF11 ;IS IT?
POPJ P, ;YES, RETURN
MOVEI T1,LPTASC ;ASSUME STANDARD ASCII
SKIPE .FPFR1(E) ;UNLESS /REPORT WAS SPECIFIED
MOVEI T1,LPTRPT ;USE REPORT ROUTINE
POPJ P, ;AND RETURN
SUBTTL LPTASC -- Print Regular ASCII on LPT
LPTASC: SOSL J$DBCT(J) ;COUNT DOWN AND JUMP IF DATA IS THERE.
JRST LPTA.2 ;GO GET A DATA BYTE.
PUSHJ P,INPBUF ;ELSE, GET A BUFFER FULL
JUMPT LPTASC ;IF OK,,CONTINUE PROCESSING.
$RETT ;ELSE RETURN.
LPTA.2: ILDB C,J$DBPT(J) ;GET A CHARACTER
CAIGE C,40 ;PRINTABLE ASCII?
JRST LPTA.5 ;NO, GO HANDLE SPECIAL CHARS
TXNE S,FORWRD ;ARE WE FORWARD SPACING ???
JRST LPTASC ;YES,,SKIP THIS.
SETZM J$XTOP(J) ;CLEAR TOF FLAG
LPTA.3: SOSGE J$LBCT(J) ;ANY ROOM IN BUFFER?
JRST LPTA.4 ;NO, FILL IT
IDPB C,J$LBPT(J) ;YES, DEPOSIT IN BUFFER
JRST LPTASC ;AND GET ANOTHER
LPTA.4: PUSHJ P,OUTOUT ;GET A BUFFER
JRST LPTA.3 ;AND LOOP
LPTA.5: PUSHJ P,CHKSP ;GO HANDLE SPECIAL CHARS
JRST LPTASC ;AND LOOP AROUND
SUBTTL LPTELV -- Print MACY11 file as regular ASCII
LPTELV: PUSHJ P,.SAVE1 ;PRESERVE P1
LPTE.1: SOSL J$DBCT(J) ;COUNT DOWN AND JUMP IF DATA IS THERE.
JRST LPTE.2 ;GO GET A DATA BYTE.
PUSHJ P,INPBUF ;ELSE, GET A BUFFER FULL
JUMPT LPTE.1 ;IF OK,,GET NEXT FOUR BYTES
$RETT ;ELSE RETURN.
LPTE.2: ILDB P1,J$DBPT(J) ;GET 4 BYTES TO PRINT
LDB C,[POINT 8,P1,17] ;GET THE FIRST BYTE
PUSHJ P,LPTE.3 ;PRINT IT
LDB C,[POINT 8,P1,9] ;GET SECOND BYTE
PUSHJ P,LPTE.3 ;PRINT IT
LDB C,[POINT 8,P1,35] ;GET THIRD BYTE
PUSHJ P,LPTE.3 ;PRINT IT
LDB C,[POINT 8,P1,27] ;GET FOURTH BYTE
PUSHJ P,LPTE.3 ;PRINT IT
JRST LPTE.1 ;GET THE NEXT FOUR BYTES
LPTE.3: CAIGE C,40 ;PRINTABLE ASCII?
JRST LPTE.6 ;NO, GO HANDLE SPECIAL CHARS
TXNE S,FORWRD ;ARE WE FORWARD SPACING ???
POPJ P, ;YES,,SKIP THIS.
SETZM J$XTOP(J) ;CLEAR TOF FLAG
LPTE.4: SOSGE J$LBCT(J) ;ANY ROOM IN BUFFER?
JRST LPTE.5 ;NO, FILL IT
IDPB C,J$LBPT(J) ;YES, DEPOSIT IN BUFFER
POPJ P, ;AND GET ANOTHER
LPTE.5: PUSHJ P,OUTOUT ;GET A BUFFER
JRST LPTE.4 ;AND LOOP
LPTE.6: PUSHJ P,CHKSP ;GO HANDLE SPECIAL CHARS
POPJ P, ;AND LOOP AROUND
SUBTTL LPTFOR -- Process FORTRAN data files
LPTFOR: SOSLE J$DBCT(J) ;AND CHARACTERS LEFT
JRST LPTF.1 ;YUP, GET THEM
PUSHJ P,INPBUF ;NO, GET MORE DATA
JUMPF .RETT ;RETURN AT EOF
LPTF.1: ILDB C,J$DBPT(J) ;GET ONE
JUMPE C,LPTFOR ;IGNORE NULLS
TXZE S,FCONV ;CHECK FOR CTL CHAR
JRST FORCNV ;GO DO IT
CAIN C,.CHLFD ;LINEFEED?
TXOA S,FCONV ;FLAG NEXT CHAR AS CTL CHAR
PUSHJ P,LPTOUT ;OTHERWISE PRINT IT
JRST LPTFOR ;AND LOOP AROUND AGAIN.
FORCNV: MOVSI T1,-NFORCH ;MAKE AN AOBJN POINTER
FORC.1: HLRZ T2,FORTAB(T1) ;GET CHAR FROM TABLE
CAMN C,T2 ;MATCH?
JRST FORC.2 ;YES, GO TRANSLATE
AOBJN T1,FORC.1 ;NO, LOOP
MOVEI C,.CHLFD ;DIDN'T FIND A MATCH, SO LOAD
PUSHJ P,LPTOUT ; A LINEFEED, SEND IT, AND
JRST LPTFOR ; CONTINUE ON
FORC.2: HRRZ C,FORTAB(T1) ;GET TRANS CHAR AND REPEAT COUNT
LDB T1,[POINT 9,C,26] ;GET REPEAT COUNT IN T1
MOVEM T1,J$XFRC(J) ;SAVE THE REPEAT COUNT
ANDI C,177 ;AND DOWN TO CHARACTER
FORC.3: PUSHJ P,LPTOUT ;SEND THE CHARACTER
SOSLE J$XFRC(J) ;COUNT DOWN THE REPEAT COUNTER
JRST FORC.3 ;AND LOOP
JRST LPTFOR ;AND CONTINUE
SUBTTL LPTRPT -- Process REPORT files
LPTRPT: PUSHJ P,INPBYT ;GET A BYTE FROM THE FILE
JUMPF .RETT ;AND RETURN WHEN DONE
PUSHJ P,LPTOUT ;DO ALL THE CHECKING
JRST LPTRPT ;AND GET ANOTHER
SUBTTL LPTOCT -- Give an Octal Dump
LPTOCT: PUSHJ P,.SAVE3 ;SAVE P1 - P3
LOAD T1,.FPINF(E),FP.FSP ;GET THE SPACING CODE
CAIE T1,1 ;SINGLE SPACE?
SKIPA P2,[22,,1] ;NO--THEN TRIPLE SPACE, DOUBLE SPACE
;IS UGLY --DO NOT ALLOW IT
MOVE P2,[12,,3] ;SINGLE SPACE THE LISTING
OCT1: MOVEI T1,(P2) ;BLOCK PER PAGE
OCT2: MOVEI T2,^D16 ;LINES PER BLOCK
OCT3: MOVEI T3,^D8 ;WORDS PER LINE
MOVE P1,J$FWCL(J) ;GET THE WIDTH CLASS
CAIN P1,2 ;IS IT 2?
MOVEI T3,4 ;YES, USE 4 WORDS/LINE
CAIN P1,1 ;IS IT 1?
MOVEI T3,2 ;YES, USE 2 WORDS/LINE
OCT4: MOVEI T4,^D12 ;DIGITS PER WORD
MOVEI C," " ;EACH WORD BEGINS WITH 3 BLANKS
PUSHJ P,DEVOUT ;ONE
PUSHJ P,DEVOUT ;TWO
PUSHJ P,DEVOUT ;THREE
PUSHJ P,INPBYT ;GET A WORD
JUMPF .RETT ;DONE!!
MOVE P3,C ;COPY WORD
SETZM J$XTOP(J) ;FLAG MIDDLE OF FORM
MOVE P1,[POINT 3,P3] ;LOAD BYTE POINTER
OCT5: ILDB C,P1 ;GET NEXT DIGIT
MOVEI C,60(C) ;MAKE ASCII
PUSHJ P,DEVOUT ;PRINT CHAR
SOJG T4,OCT5 ;END OF WORD?
SOJG T3,OCT4 ;END OF LINE?
HLRZ C,P2 ;GET MOTION CHARACTER
PUSHJ P,DEVOUT ; ..
SOJG T2,OCT3 ;END OF BLOCK?
PUSHJ P,DEVOUT ;YES--2 EXTRA LINE FEEDS
PUSHJ P,DEVOUT ; ..
SOJG T1,OCT2 ;END OF PAGE?
MOVEI C,.CHFFD ;PRINT A FORM FEED
PUSHJ P,DOFORM ;AND ENFORCE QUOTA ETC.
JRST OCT1 ;PRINT NEXT PAGE
SUBTTL LPTCOB -- Process COBOL Sixbit Files
LPTCOB: PUSHJ P,.SAVE2 ;SAVE P1 AND P2
SETZM J$XTOP(J) ;CAUSE A FORM FEED AT END
PUSHJ P,INPBYT ;GET THE FIRST WORD OF THE FILE
JUMPF .RETT ;NULL FILE
HLRZ T1,C ;COPY THE FIRST 3 LETERS
CAIE T1,'HDR' ;IS IT A HDR
JRST COBOL2 ;NO--NORMAL INPUT
MOVEI T1,15 ;FLUSH TAPE HEADER
PUSHJ P,INPBYT ;GET A WORD
JUMPF COBOL5 ;EOF
SOJG T1,.-2 ;LOOP FOR MORE
COBOL1: PUSHJ P,INPBYT ;GET A WORD
JUMPF COBOL5 ;THE LAST WORD HAS COME
COBOL2: ANDI C,7777 ;MASK TO 12 BITS
JUMPLE C,COBOL1 ;IGNORE 0 COUNTS FOR OBVIOUS REASON
MOVEI P1,(C) ;COPY THE COUNT
MOVEI S1,-1(P1) ;GET COUNT-1 IN S1
SUB S1,J$FWID(J) ;ROUND DOWN TO A LINE
IDIV S1,J$FWID(J) ;CONVERT TO # LINES
MOVNS S1 ;NEGATE IT
ADDM S1,J$XPOS(J) ;AND DECREMENT POSITION
COBOL3: PUSHJ P,INPBYT ;GET A DATA WORD
JUMPF .RETT ;END OF FILE-- ACTUALY THIS SHOULD
; NEVER HAPPEN SINCE THE COUNT IS EXACT.
MOVEI T1,6 ;CHARS PER WORD.
CAIG P1,6 ;ARE WE DOWN TO LAST DREGS?
MOVEI T1,(P1) ;YES--USE EXACT COUNT TO AVOID FREE
; CRLF ON EXTRA BLANKS.
MOVE T2,C ;COPY WORD
MOVE P2,[POINT 6,T2] ;POINT TO WORD
COBOL4: ILDB C,P2 ;AND GET THE CHARACTER
MOVEI C,40(C) ;MAKE ASCII
PUSHJ P,DEVOUT ;PRINT
SOJG T1,COBOL4 ;LOOP FOR NEXT CHAR
SUBI P1,6 ;COUNT 6 MORE CHARS
JUMPG P1,COBOL3 ;GET MORE
MOVEI C,.CHCRT ;LOAD A CARRIAGE RETURN
PUSHJ P,DEVOUT ;PRINT IT
MOVEI C,.CHLFD ;LOAD A LINE FEED
PUSHJ P,DOLF ;AND SEND EOL
JRST COBOL1 ;LOOP FOR MORE.
COBOL5: MOVEI C,.CHFFD ;GET A FORM FEED.
PUSHJ P,DEVOUT ;PUT IT OUT.
$RETT ;AND RETURN.
SUBTTL Character Interrogation Routines
;SUBROUTINE TO PLACE A CHAR ON THE LINE PRINTER
;CALL WITH:
; PUSHJ P,LPTOUT
; RETURN HERE (EOF SET IF OVER LIMIT)
LPTOUT: CAIGE C,40 ;VISABLE ASCII
JRST CHKSP ;NO--SEE IF SPACE
LPTOU1: TXZE S,NEWLIN ;AND THIS IS A NEW LINE
SKIPN J$XCOD(J) ;LETS NOT DO A /REPORT IS THERE IS NO CODE.
SKIPA ;DONT GO DOWN THE TUBES.
JRST J$XCOD(J) ;SEE IF REPORT LINE MATCHES
SETZM J$XTOP(J) ;CLEAR FORM FEED FLAG
PJRST DEVOUT ;PRINT IT
CHKSP: MOVE S1,CHTAB(C) ;GET THE DISPATCH
TXNE S1,EOLCHR ;IS THIS AN END OF LINE CHARACTER ???
TXO S,NEWLIN ;YES,,LITE NEW LINE BIT
TXNN S1,NCLRFF ;CLEAR FORMFEED FLAG?
SETZM J$XTOP(J) ;YES
TXNE S,SUPFIL!SUPJOB ;IN SUPPRESS MODE?
TXNN S1,SUPRCH ;YES, IS THIS CHARACTER SUPPRESSABLE?
JRST (S1) ;DISPATCH THE CHARACTER NORMALLY
JRST DOSUP ;SUPPRESS THE CHARACTER
;HERE TO THROW AWAY A LINE
FLUSH7: PUSHJ P,INPBYT ;GET A BYTE
JUMPF .RETT ;RETURN ON EOF
PUSHJ P,ISEOL ;END OF LINE?
JUMPF FLUSH7 ;NO--LOOP FOR REST OF LINE
FLUSH8: PUSHJ P,INPBYT ;GET A BYTE
JUMPF .RETT ;RETURN ON EOF
PUSHJ P,ISEOL ;GOT EOL CHARACTER?
JUMPF LPTOUT ;NO, NEW LINE, DO THE MATCH
JRST FLUSH8 ;YES, LOOP AGAIN
ISEOL: CAIL C," " ;IS IT PRINTABLE?
$RETF ;YES, ITS NOT AN EOL
MOVE S1,CHTAB(C) ;NO, GET TABLE ENTRY
TXNN S1,EOLCHR ;IS IT AN EOL?
$RETF ;NO, JUST RETURN
TXO S,NEWLIN ;YES, SET NEW LINE
$RETT ;AND RETURN
;HERE ON A LINE FEED
DOLF: LOAD T1,.FPINF(E),FP.FSP ;GET SPACING PARAMETER
SETO S1, ;START WITH 1 LINE
DOLF1: SOJLE T1,CNTDWN ;ANY MORE?
MOVEI C,.CHLFD ;LOAD A LINE-FEED
PUSHJ P,DEVOUT ;YES--GIVE IT
SOJA S1,DOLF1 ;AND SUBTRACT FROM QUOTA
;HERE TO PROCESS A FORM FEED
DOFORM: SKIPE J$XTOP(J) ;SKIP IF NOT AT TOP OF FORM
POPJ P, ;DO NOT PRINT BLANK PAGES
MOVN S1,J$XPOS(J) ;THIS TAKES ALL WE HAVE ON PAGE
SKIPL S1 ;WAS VPOS NEGATIVE?
CLEAR S1, ;DONT CHARGE FOR ANYTHING THEN.
;THIS MIGHT GIVE THE USER A
;BONUS OF 1-3 FREE LINES.
JRST CNTDWN ;COUNT DOWN THE LIMIT
;HERE IF /PRINT:SUPPRESS
DOSUP: MOVEI C,.CHLFD ;MAKE IT A LINEFEED, REGARDLESS
SKIPE J$XTOP(J) ;SKIP IF NOT TOP
POPJ P, ;ONLY 1 LINE FEED IN A ROW
SETOM J$XTOP(J) ;AND SET TOP
SETO S1,
JRST CNTDWN ;CHARGE FOR THE LINE
;HERE TO DO ARROW MODE STUFF IF NEEDED
CHKARO: TXNN S,ARROW ;ARROW MODE?
JRST DEVOUT ;NO--JUST PRINT
DOARO: PUSH P,C ;SAVE C
MOVEI C,"^" ;LOAD A ^
PUSHJ P,DEVOUT ;PRINT THE ^
POP P,C ;RESTORE C
MOVEI C,100(C) ;MAKE INTO REAL LETTER
PJRST DEVOUT ;PRINT
;HERE ON A DC3
DODC3: SETOM S1 ;DC3 SKIPS 1 LINE
JRST CNTDWN ;AND COUNT DOWN
;HERE IF SPECIAL CHARACTER SKIPS A FRACTION OF A PAGE
DOFRAC: HLRZS S1 ;GET 0,,FRACTION
ANDI S1,777 ;AND OUT FLAGS
MOVE T1,J$FLIN(J) ;GET CURRENT PAGE SIZE
IDIVI T1,(S1) ;FIND THE RIGHT PART
MOVE T2,J$XPOS(J) ;GET CURRENT POSITION
SOJL T2,[MOVN S1,J$XPOS(J) ;COPY VPOS
SUBI S1,3 ;SUBTRACT 3
JRST CNTDWN] ;AND CHARGE HIM
IDIVI T2,(T1) ;GET RESIDUE MOD SKIPSIZE
MOVNI S1,1(T3) ;AND MAKE IT NEGATIVE
JRST CNTDWN ;GO CHECK QUOTA
SUBTTL CNTDWN - COUNT DOWN LINE FEEDS AND PAGE FEEDS
;CALL: S1/ Line Count Modifier
; C/ The Character Being Printed
;
;RET: TRUE ALWAYS
CNTDWN: CAIL C,12 ;MAKE SURE THIS IS A CARRIAGE CONTROL
CAILE C,24 ; CHARACTER.
PJRST DEVOUT ;IF NOT,,JUST DUMP IT OUT.
CAIN C,.CHFFD ;IS IT A FORM FEED ???
JRST CNTDW1 ;YES,,SKIP THIS.
ADDB S1,J$XPOS(J) ;REDUCE VERTICAL POSITION
JUMPG S1,DEVOUT ;JUMP IF STILL ON PAGE
CAIN C,23 ;WAS IT A DC3?
CAMG S1,[-3] ;YES, GIVE HIM 3 EXTRA LINES
JRST CNTDW1 ;OFF PAGE ANYWAY
PJRST DEVOUT ;HE WINS!!
CNTDW1: MOVE S1,J$FLIN(J) ;BACK TO TOP OF PAGE
MOVEM S1,J$XPOS(J) ;SAVE POSITION
SOSG J$FPIG(J) ;DECREMENT THE FORWARD SPACING COUNT.
TXZ S,FORWRD ;TURN OFF THE FORWARD SPACE BIT.
TXNE S,FORWRD ;FORWARD SPACING ???
JRST .+3 ;YES,,SKIP THIS
AOS J$APRT(J) ;NO,,ADD 1 TO TOTAL PAGES COUNTER
AOS J$RNPP(J) ;NO,,ADD 1 TO PAGES PER COPY COUNTER
;Here we keep track of where we are for backspaceing
MOVE S1,J$FCBC(J) ;GET NUMBER OF BYTES IN THIS BUFFER
SUB S1,J$DBCT(J) ;CALC BYT POS OF THIS PAGE IN THIS BUFR
ADD S1,J$FTBC(J) ;CALC BYT POS OF THIS PAGE IN THIS FILE
MOVEM S1,@J$FBPT(J) ;SAVE THE PAGE ADDRESS IN THE PAGE TABLE
AOS S1,J$FBPT(J) ;BUMP TO NEXT PAGE TABLE ENTRY
CAIG S1,J$FPAG+PAGSIZ(J) ;ARE WE AT THE END OF THE PAGE TABLE ???
JRST .+4 ;NO,,CONTINUE ON
TXO S,FBPTOV ;YES,,LITE PAGE TABLE OVERFLOW FLAG
MOVEI S1,J$FPAG(J) ;AND WRAP THE
MOVEM S1,J$FBPT(J) ; PAGE TABLE AROUND ITSELF
PUSH P,C ;SAVE THE CURRENT CHAR
PUSHJ P,CHKALN ;CHECK FOR ALIGNMENT
POP P,C ;RESTORE THE OLD CHARACTER
MOVEI S1,3 ;LOAD A 3
CAIN C,23 ;GET HERE VIA DC3?
ADDM S1,J$XPOS(J) ;YES, GIVE HIM 3 XTRA LINES
CAIE C,23 ;WAS IT A DC3
SETOM J$XTOP(J) ;NO, SET TOP OF FORM
MOVE S1,J$RLIM(J) ;GET LIMIT
SUB S1,J$APRT(J) ;GET AMOUNT PRINTED
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
TXNN S,ABORT+GOODBY ;ARE WE ON OUR WAY OUT OR
SKIPL S1 ; STILL UNDER QUOTA ???
PJRST DEVOUT ;YES,,PRINT THE POOR CHARACTER
GETLIM S1,.EQLIM(J),FLEA ;GET FORMS-LIMIT-EXCEED ACTION
CAIN S1,.STCAN ;SEE IF CANCEL
JRST CNTDW2 ;IT WAS, DO IT
CAIN S1,.STIGN ;SEE IF IGNORE
PJRST DEVOUT ;YES, PRINT THE CHARACTER AND RETURN
;DEFAULT TO ASK IF NOT IGNORE OR CANCEL
CNTDWX: MOVE S1,STREAM ;GET THE STREAM NUMBER
SETOM JOBCHK(S1) ;SAY WE WANT TO TAKE A CHECKPOINT
$WTOR (Page Limit Exceeded,<^R/.EQJBB(J)/^T/LIMSG/>,@JOBOBA(S1),JOBWAC(S1))
$DSCHD (PSF%OR) ;WAIT FOR OPERATOR RESPONSE
TXNE S,ABORT+RQB ;HAVE WE BEEN CANCELED OR REQUEUED ???
JRST CNTIGN ;YES,,IGNORE THE ERROR
MOVEI S1,LIMANS ;POINT TO THE LIMIT ANSWER BLOCK
HRROI S2,J$RESP(J) ;POINT TO THE ANSWER
PUSHJ P,S%TBLK ;DO WE MATCH ???
TXNE S2,TL%NOM+TL%AMB ;DID WE FIND IT OK ???
JRST CNTDWX ;NO,,STUPID OPERATOR SO TRY AGAIN
HRRZ S1,0(S1) ;GET THE ROUTINE ADDRESS
JRST 0(S1) ;AND PROCESS THE RESPONSE
;IF ANSWER WAS 'IGNORE' COME HERE
CNTIGN: MOVX S1,.STIGN ;YES,,GET THE IGNORE BITS
STOLIM S1,.EQLIM(J),FLEA ;SAVE IT AS NEW LIMIT EX ACTION
PJRST DEVOUT ;GO DUMP THE BUFFERS
;IF ANSWER WAS 'ABORT' COME HERE
CNTDWC: MOVE S1,STREAM ;GET THE STREAM NUMBER
$WTO (Aborting,<^R/.EQJBB(J)/>,@JOBOBA(S1)) ;TELL THE OPERATOR
CNTDW2: $TEXT(LOGCHR,<^I/LPERR/Page Limit Exceeded>)
SETZM J$XTOP(J) ;CLEAR TOP-OF-FORM FLAG
PUSHJ P,SENDFF ;SEND A FORM FEED
TXO S,ABORT ;LIGHT THE ABORT BIT
PJRST INPFEF ;YES,,FORCE AN EOF
LIMANS: 2,,2
[ASCIZ/ABORT/],,CNTDWC ;ABORT ENTRY
[ASCIZ/IGNORE/],,CNTIGN ;IGNORE ENTRY
;SUBROUTINE TO OUTPUT ONE CHAR ON SELECTED DEVICE
;CALL WITH:
; PUSHJ P,DEVOUT
; RETURN HERE (HALTS IF ERROR)
;
DEVOUT: TXNE S,FORWRD ;ARE WE FORWRD SPACING ???
POPJ P, ;YES,,RETURN.
DEVO.0: SOSGE J$LBCT(J) ;DECREMENT THE BYTE COUT
JRST DEVO.1 ;LOSE, GO DUMP THE BUFFER
IDPB C,J$LBPT(J) ;DEPOSIT A BYTE
POPJ P, ;AND RETURN
DEVO.1: PUSH P,S1 ;SAVE S1
PUSHJ P,OUTOUT ;DUMP THE BUFFER
POP P,S1 ;RESTORE S1
JRST DEVO.0 ;AND TRY AGAIN
;SENDFF - ROUTINE TO SEND A FF IF J$XTOP IS OFF
;
SENDFF: MOVEI C,.CHFFD ;LOAD A FF
SKIPN J$XTOP(J) ;SKIP IF ALREADY AT TOP
PUSHJ P,DEVOUT ;NO, SEND IT
SETOM J$XTOP(J) ;SET THE FLAG
POPJ P, ;RETURN
CHKALN: SKIPL J$APRG(J) ;IS AN ALIGNMENT SCHEDULED ???
POPJ P, ;NO,,RETURN.
PUSHJ P,ALIGN ;YES,,THEN DO IT.
$RETT ;RETURN TO HIS CALLER.
SUBTTL Subroutines to send messages to the output device
;Since output to the output-device is interruptable $TEXT calls which
; send characters directly to the device cannot be done.
;
;A per-context buffer (J$XTBF) is defined to store $TEXT'ed characters
; in and the following set of subroutines exist to initialize,
; deposit characters in, and dump this buffer to the output device.
;TBFINI initializes the byte-pointer to J$XTBF
TBFINI: MOVEI S1,J$XTBF(J) ;GET THE ADDRESS OF THE BUFFER
HRLI S1,(POINT 7,0) ;MAKE IT A BYTE POINTER
MOVEM S1,J$XTBP(J) ;STORE IT
MOVEI S2,0 ;LOAD A NULL
IDPB S2,S1 ;AND INITIALIZE THE BUFFER
$RETT ;AND RETURN
;TBFCHR is the $TEXT subroutine to deposit characters in the text buffer.
TBFCHR: IDPB S1,J$XTBP(J) ;DEPOSIT THE CHARACTER
$RETT ;RETURN
;TBFDMP dumps the text buffer to output device and re-initializes the buffer
TBFDMP: SETZ S1, ;CLEAR THE AC
IDPB S1,J$XTBP(J) ;DEPOSIT THE BYTE
MOVEI S1,J$XTBF(J) ;GET ADDRESS OF BUFFER
PUSHJ P,BFRDMP ;DUMP THE BUFFER
PJRST TBFINI ;RE-INIT THE BUFFER AND RETURN
;STGOUT is included to allow dumping of any arbitrary buffer of characters
; Call with S1 containing either a byte pointer or the address of the buffer
STGOUT: PUSH P,S1 ;SAVE S1
PUSHJ P,TBFDMP ;FORCE ANY BUFFERED STUFF OUT
POP P,S1 ;RESTORE S1
;AND FALL INTO BFRDMP
;BFRDMP to dump the buffer pointed to by S1
BFRDMP: PUSHJ P,.SAVE1 ;SAVE P1
MOVE P1,S1 ;PUT THE POINTER IN P1
TLNN P1,-1 ;IS LEFT HALF ZERO
HRLI P1,(POINT 7,0) ;YES, MAKE IT A BYTE POINTER
BFRD.1: ILDB C,P1 ;GET A CHARACTER
JUMPE C,.RETT ;RETURN WHEN DONE
SETZM J$XTOP(J) ;CLEAR THE TOP-OF-FORM FLAG
CAIN C,.CHFFD ;IS IT A FORMFEED?
SETOM J$XTOP(J) ;YES, SET IT
PUSHJ P,DEVOUT ;OUTPUT THE CHARACTER
JRST BFRD.1 ;AND LOOP
SUBTTL ROUTINES TO GENERATE HEADERS AND TRAILERS
;JOB HEADERS AND TRAILERS
JOBTRL: MOVEI T4,[ASCIZ /END/] ;ADDRESS OF END TEXT
TXNE S,RQB ;CLEAR REQUE AND SKIP IF NOT SET
MOVEI T4,[ASCIZ /REQUE/] ;SAY SO
PUSHJ P,GIVHDR ;GO SETUP THE LINE
JRST TRAILR ;AND NOW GO PRINT THE TRAILER
JOBHDR: MOVEI T4,LPTERR ;ALLOW FOR LPT ERRORS HERE
MOVEM T4,J$LERR(J) ;STORE COUNTER
MOVEI T4,[ASCIZ /START/] ;ADDRESS OF START TEXT
PUSHJ P,GIVHDR ;GO SET THE LINE
JRST BANNER ;AND GO PRINT THE BANNER PAGES
GIVHDR: $TEXT (<-1,,J$XHBF(J)>,<^T7C*/0(T4)/ ^R/.EQJBB(J)/ ^I/DATMON/^0>)
MOVE S1,J$FWID(J) ;GET THE PAGE WIDTH
IDIVI S1,5 ;GET WORDS/BYTES TO THE END OF THE LINE
ADDI S1,J$XHBF(J) ;POINT TO THE LOGICAL END OF THE LINE
LOAD S2,PTRS(S2) ;GET BYTE PTR FOR END OF LINE
SETZM T1 ;GET A NULL BYTE
IDPB T1,S2 ;CUT THE HEADER OFF HERE !!!
$RETT ;RETURN.
PTRS: POINT 7,0(S1)
POINT 7,0(S1),6
POINT 7,0(S1),13
POINT 7,0(S1),20
POINT 7,0(S1),27
POINT 7,0(S1),34
SUBTTL BANNER -- Routine to print a banner
BANNER: PUSHJ P,.SAVE3 ;SAVE P1 THRU P3
SKIPN P3,J$FBAN(J) ;GET NUMBER OF BANNER PAGES
POPJ P, ;RETURN WHEN DONE
TOPS10 <
$TEXT(<-1,,J$PUSR(J)>,<^W6/.EQOWN(J)/^W/.EQOWN+1(J)/^0>)
> ;END TOPS10 CONDITIONAL
TOPS20 <
$TEXT(<-1,,J$PUSR(J)>,<^T/.EQOWN(J)/^0>)
> ;END TOPS20 CONDITIONAL
BANN.1: PUSHJ P,SENDFF ;SEND A FORM FEED
SETZM J$XPOS(J) ;AND SET 0 POSITION
MOVEI T1,4 ;LOAD AN OFFSET
CAIN P3,1 ;IS THIS THE LAST BANNER?
ADDM T1,J$XPOS(J) ;YES, DON'T PRINT OVER CREASE
PUSHJ P,BANN.2 ;PRINT A BANNER PAGE
SOJG P3,BANN.1 ;AND LOOP
POPJ P, ;RETURN
BANN.2: PUSHJ P,PLPBUF ;PRINT A LINE
PUSHJ P,PLPBUF ;PRINT ANOTHER LINE
PUSHJ P,CRLF ;TYPE A CRLF
MOVEI S1,1 ;LOAD THE BLOCKSIZE
MOVEI S2,J$PUSR(J) ;AND THE STRING ADDRESS
PUSHJ P,PICTUR ;AND PRINT A PICTURE
MOVEI T1,^D12 ;COUNT'EM
ADDM T1,J$XPOS(J) ;...
PUSHJ P,PLPBUF ;PRINT A LINE
PUSHJ P,PLPBUF ;AND ANOTHER
PUSHJ P,PLPBUF ;AND A THIRD
MOVEI T1,[0,,0] ;LOAD A NULL.
MOVE S1,J$FWCL(J) ;GET THE WIDTH CLASS
CAIN S1,3 ;ROOM ENOUGH FOR THE TITLE?
MOVEI T1,[ASCIZ /Note:/] ;YES, LOAD IT
GETLIM T2,.EQLIM(J),NOT1 ;GET FIRST HALF OF NOTE
JUMPE T2,PLINES ;NO NOTE, FINISH THE PAGE
GETLIM T3,.EQLIM(J),NOT2 ;AND THE SECOND HALF
$TEXT(<-1,,J$PNOT(J)>,<^T/0(T1)/^W6/T2/^W/T3/^0>)
MOVEI S1,1 ;GET THE BLOCKSIZE
MOVEI S2,J$PNOT(J) ;GET THE ADDRESS
PUSHJ P,PICTUR ;AND SEND IT OUT
MOVEI S1,^D11 ;LOAD NUMBER OF LINES
ADDM S1,J$XPOS(J) ;AND MOVE DOWN THE PAGE
PJRST PLINES ;GO TO EOP AND RETURN
SUBTTL TRAILR -- Routine to Print a Trailer
TRAILR: PUSHJ P,.SAVE3 ;SAVE P1 - P3
MOVE P3,J$FTRA(J) ;AND THE NUMBER OF TRAILERS
JUMPE P3,OUTDMP ;RETURN IF ZERO
TRAI.1: PUSHJ P,SENDFF ;SEND A FORMFEED
SETZM J$XPOS(J) ;CLEAR THE VERTICAL POSITION
PUSHJ P,TRAI.3 ;PRINT THE INTERNAL LOG
PUSHJ P,PLINES ;PRINT TILL END OF PAGE
SOJG P3,TRAI.1 ;LOOP UNTIL DONE
PJRST OUTDMP ;AND DUMP BUFFERS AND RETURN
;HERE TO PRINT THE INTERNAL LOG
TRAI.3: SKIPN J$GNLN(J) ;ANYTHING IN THE INTERNAL LOG?
POPJ P, ;NO, RETURN
PUSHJ P,PLPBUF ;YES, PRINT A LINE
PUSHJ P,PLPBUF ;AND ANOTHER LINE
MOVEI C,.CHTAB ;LOAD A TAB
MOVE T1,J$FWCL(J) ;GET THE WIDTH CLASS
PUSHJ P,DEVOUT ;PRINT A TAB
SOJG T1,.-1 ;PRINT N OF THEM
MOVEI S1,[ASCIZ /* * * L P T S P L R u n L o g * * *
/]
PUSHJ P,STGOUT ;AND DUMP IT
MOVE T2,J ;COPY OVER J
MOVE T3,J$GINP(J) ;GET NUMBER OF PAGES
TRAI.4: MOVE S1,J$GBUF(T2) ;GET ADR OF BUFFER
PUSHJ P,STGOUT ;AND DUMP IT OUT
MOVE S1,J$GBUF(T2) ;GET THE PAGE ADDRESS
CAME T2,J ;SKIP IF THIS IS THE PRE-ALLOCATED PAGE
PUSHJ P,M%RPAG ;AND RELEASE IT
CAMN T2,J ;SKIP IF THIS IS NOT PRE-ALLOC PAGE
PUSHJ P,.ZPAGA ;ZERO IT THEN
SOSLE T3 ;DECREMENT COUNT
AOJA T2,TRAI.4 ;AND LOOP IF NOT DONE
PUSHJ P,CRLF ;PRINT 1 CRLF
PUSHJ P,CRLF ;AND ANOTHER
PUSHJ P,CRLF ;AND ANOTHER
MOVE T1,J$GNLN(J) ;GET NUMBER OF LOG LINES
ADDI T1,4 ;ADD IN THE OVERHEAD
ADD T1,J$XPOS(J) ;AND ACCUMULATE VERTICAL POSITION
IDIV T1,J$FLIN(J) ;DID WE OVERFLW A PAGE?
MOVEM T2,J$XPOS(J) ;SAVE CURRENT POSITION
SETZM J$GNLN(J) ;AND DON'T PRINT IT AGAIN
SUB P3,T1 ;REDUCE PAGES TO PRINT
POPJ P, ;AND RETURN
SUBTTL - UTILITY ROUTINES
PLPBUF: MOVEI S1,J$XHBF(J) ;GET ADDRESS OF THE LINE
PUSHJ P,STGOUT ;AND DUMP IT
PUSHJ P,CR23 ;END THE LINE WITH A CR23
PUSHJ P,CR23 ;PRINT A CR23
PUSHJ P,CR23 ;AND ANOTHER
PUSHJ P,CR23 ;AND ANOTHER
MOVEI S1,4 ;WE PRINT 4 LINES
ADDM S1,J$XPOS(J) ;ADD TO COUNT
POPJ P,
PLINES: MOVE T2,J$FLIN(J) ;GET LINES/PAGE
ADDI T2,1 ;ACCOUNT FOR MARGIN
SUB T2,J$XPOS(J) ;SUBTRACT AMOUNT PRINTED
JUMPLE T2,PEOP ;JUMP IF DONE
IDIVI T2,4 ;ELSE GET NUMBER OF LINES TO PRINT
PLINE1: SOJL T2,PEOP ;JUMP IF DONE
PUSHJ P,PLPBUF ;PRINT A LINE (4 LINES)
JRST PLINE1 ;AND LOOP
PEOP: MOVE T2,J$FLIN(J) ;GET NUMBER OF LINES/PAGE
SUB T2,J$XPOS(J) ;SUBTRACT THOSE PRINTED
ADDI T2,1 ;COUNT THE MARGIN
PEOP1: JUMPLE T2,PEOP2 ;GO FINISH OFF
PUSHJ P,CR23 ;PRINT A CR23
SOJA T2,PEOP1 ;AND LOOP
PEOP2: MOVEI S1,STARS ;LOAD ADDRESS OF STRING
PUSHJ P,STGOUT ;AND SEND TO THE PRINTER
POPJ P, ;AND RETURN
CR23: SKIPE J$MTAP(J) ;SPOOLING TO TAPE ???
JRST CRLF ;YES,,JUST INSERT CRLF
MOVEI S1,[BYTE (7) 15,23,0,0,0] ;PRINT OUT CR23
SKIPA ;SKIP CRLF ENTRY POINT
CRLF: MOVEI S1,[BYTE (7) 15,12,0,0,0] ;PRINT AT CRLF
PUSHJ P,STGOUT ;PUT IT OUT
$RET ;AND RETURN
SUBTTL HEAD -- Generate File-header pages
HEAD: PUSHJ P,.SAVE3 ;SAVE SOME ACS
PUSHJ P,SENDFF ;SEND A FORMFEED
LOAD P1,.FPINF(E),FP.NFH ;GET THE NO HEADER BIT
SKIPN P1 ;SKIP IF WE DON'T WANT HEADERS
SKIPN P3,J$FHEA(J) ;GET NUMBER OF PICTURE PAGES
PJRST OUTDMP ;DUMP BUFFERS AND RETURN
PUSHJ P,SETHDR ;SETUP THE FILENAME FOR BLOCK LETTERS
PUSHJ P,HEAD.1 ;PRINT THE HEADER
SOJG P3,.-1 ;LOOP FOR THE WHOLE WORKS
PJRST OUTDMP ;FORCE EVERYTHING OUT, AND RETURN
HEAD.1: MOVE S1,J$PFLS(J) ;GET BLOCKSIZE
MOVEI S2,J$PFL1(J) ;AND ADDRESS OF FIRST LINE
PUSHJ P,PICTUR ;PRINT THE LINE
MOVE S1,J$PFLS(J) ;GET BLOCKSIZE
MOVEI S2,J$PFL2(J) ;AND ADDRESS OF SECOND LINE
PUSHJ P,PICTUR ;AND PRINT THE SECOND LINE
MOVE P1,J$FWCL(J) ;LOAD THE WIDTH CLASS
MOVEI S1,J$XHBF(J) ;LOAD ADDRESS OF BANNER LINE
PUSHJ P,STGOUT ;AND SEND IT
MOVE S1,J$DIFN(J) ;GET THE IFN
MOVX S2,FI.CRE ;WANT CREATION TIME
PUSHJ P,F%INFO ;GET IT
MOVEI S2,[ASCIZ /, /] ;GET A STRING
CAIE P1,3 ;WIDTH CLASS 3?
MOVEI S2,[BYTE (7) .CHCRT,.CHLFD,.CHTAB,0]
$TEXT(TBFCHR,<^M^JFile ^F/@J$DFDA(J)/, created: ^H/S1/^T/(S2)/printed: ^H/[-1]/>)
PUSHJ P,TBFDMP ;AND DUMP THE BUFFER
GETLIM S1,.EQLIM(J),FORM ;GET FORMS NAME
$TEXT(TBFCHR,<Job parameters: Request created:^H/.EQAFT(J)/ Page limit:^D/J$RLIM(J)/ Forms:^W/S1/ Account:^T/.EQACT(J)/^A>)
GETLIM S1,.EQLIM(J),NOT1 ;GET FIRST HALF OF NOTE
GETLIM S2,.EQLIM(J),NOT2 ;GET SECOND HALF OF NOTE
SKIPE S1 ;IS THERE A NOTE?
$TEXT(TBFCHR,< Note:^W6/S1/^W/S2/^A>)
PUSHJ P,CRLF ;END THE LINE
PUSHJ P,TBFDMP ;AND DUMP IT
LOAD S1,.FPINF(E),FP.FSP ;GET /SPACING
LOAD S2,.FPINF(E),FP.FCY ;GET THE TOTAL COPY COUNT
LOAD T1,J$RNCP(J) ;GET THE COPIES DONE SO FAR
ADDI T1,1 ;MAKE THIS THE CURRENT COPY
$TEXT(TBFCHR,<File parameters: Copy: ^D/T1/ of ^D/S2/ Spacing:^W/SPCTAB-1(S1)/^A>)
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
PUSHJ P,TBFDMP ;SEND THE LINE
LOAD S1,.FPINF(E),FP.FPF ;GET /PRINT
LOAD S2,.FPINF(E),FP.FFF ;GET /FILE
CAXN S2,.FPF8B ;/FILE:8-BIT?
MOVEI S2,4 ;YES, RECORD THE VALUE
CAXN S2,.FPF11 ;/FILE:ELEVEN?
MOVEI S2,5 ;YES,,RECODE THE VALUE
$TEXT(TBFCHR,< File format:^W/FFMTAB-1(S2)/ Print mode:^W/FMTAB-1(S1)/^A>)
LOAD S1,.FPINF(E),FP.DEL ;GET /DELETE BIT
SKIPE S1 ;IS IT SET?
$TEXT(TBFCHR,< /DELETE^A>) ;YES,,SAY SO
PUSHJ P,CRLF ;END THE LINE
MOVE S1,J$FPIG(J) ;GET STARTING PAGE
CAILE S1,1 ;SKIP IF 0 OR 1
$TEXT(TBFCHR,<^M^JPrinting will start at page ^D/J$FPIG(J)/>)
PUSHJ P,TBFDMP ;DUMP THE BUFFER
PJRST SENDFF ;SEND A FORM FEED
FMTAB: SIXBIT /ARROW/
SIXBIT /ASCII/
SIXBIT /OCTAL/
SIXBIT /SUPRES/
FFMTAB: SIXBIT /ASCII/
SIXBIT /FORT/
SIXBIT /COBOL/
SIXBIT /8-BIT/
SIXBIT /ELEVEN/
SPCTAB: SIXBIT /SINGLE/
SIXBIT /DOUBLE/
SIXBIT /TRIPLE/
SUBTTL SETHDR -- Setup header name for file
;SETHDR is called to setup the strings to be used for the two lines of
; block letters on the file header pages.
;
;Call: E/ address of the file's FP
;
;T Ret: always
SETHDR: PUSHJ P,.SAVE2 ;SAVE P1 AND P2
SETZM J$PFL1+1(J) ;CLEAR THE 2ND WORD OF FIRST BUFFER
SETZM J$PFL2+1(J) ; AND 2ND BUFFER, (SEE SETH.W)
SKIPN .FPFR1(E) ;IS THERE A /REPORT KEY?
JRST SETH.1 ;NO, CONTINUE ON
$TEXT(<-1,,J$PFL1(J)>,<Report:^0>) ;FIRST LINE
$TEXT(<-1,,J$PFL2(J)>,< ^W6/.FPFR1(E)/^W/.FPFR2(E)/^0>)
JRST SETH.W ;SET BLOCKSIZE AND RETURN
SETH.1: LOAD S1,.FPINF(E) ;GET FLAGS FOR FILE
TXNN S1,FP.SPL ;IS IT A SPOOLED FILE?
JRST SETH.3 ;NO, CONTINUE ON
TXNN S1,FP.FLG ;YES, IS IT ALSO THE LOG FILE?
JRST SETH.2 ;NO, JUST A PLAIN SPOOLED FILE
$TEXT(<-1,,J$PFL1(J)>,<Batch^0>) ;SPOOLED LOGS HAVE NO REASONABLE NAME
$TEXT(<-1,,J$PFL2(J)>,< Log File^0>) ;SO USE SOMETHING DESCRIPTIVE
JRST SETH.W ;AND FINISH UP
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
TOPS20 <
SETH.2:
SETH.3: MOVE P1,[POINT 7,J$PFL1(J)] ;GET THE FILENAME BYTE PTR
MOVE P2,[POINT 7,J$PFL2(J)] ;GET THE EXTEN BYTE PTR
MOVX S1,GJ%SHT!GJ%OFG ;PARSE-ONLY + SHORT-GTJFN
MOVE S2,J$DFDA(J) ;GET THE FD ADDRESS
HRROI S2,.FDFIL(S2) ;AND POINT TO THE FILESPEC
GTJFN ;GET A JFN FOR THE FILE
ERJMP SETH.S ;ERROR,,GIVE NON-DESCRIPT NAME
EXCH S1,P1 ;SAVE JFN IN P1, GET POINTER IN S1
MOVE S2,P1 ;GET JFN IN S2
MOVX T1,1B8 ;FILENAME ONLY
JFNS ;GET IT
MOVE S1,P2 ;GET THE 2ND LINE POINTER
MOVE S2,P1 ;GET THE JFN
MOVX T1,1B11 ;EXTENSION ONLY
JFNS ;GET THE EXTENSION
MOVEI T2,"." ;FIRST, LOAD A BLANK
IDPB T2,S1 ;AND DEPOSIT IT
MOVX T1,1B14 ;GET THE GENERATION NUMBER
JFNS ;DO IT!!
MOVE S1,P1 ;GET THE JFN
RLJFN ;RELEASE IT
ERJMP .+1 ;IGNORE THE ERROR
LOAD S1,.FPINF(E),FP.SPL ;GET THE SPOOL BIT
JUMPE S1,SETH.W ;IF NOT SPOOLED, THERE WE'RE DONE
MOVE P1,[POINT 7,J$PFL1(J)] ;RESTORE THE FILENAME BYTE PTR.
MOVEI S1,3 ;HOW MANY DASHES TO LOOK FOR
MOVE S2,P1 ;AND AN INPUT POINTER
SETH.4: ILDB T1,S2 ;GET A CHARACTER
JUMPE T1,SETH.S ;NO, SPOOLED NAME IF NULL
CAIE T1,"-" ;A DASH?
JRST SETH.4 ;NO, LOOP
SOJG S1,SETH.4 ;YES, LOOP UNTIL 4TH FIELD
MOVE S1,P1 ;GET A NEW POINTER TO SET DOWN CHARS
SETH.5: ILDB T1,S2 ;GET A CHARACTER
IDPB T1,S1 ;DEPOSIT IT
JUMPN T1,SETH.5 ;AND LOOP UNTIL A NULL
MOVEI S2,6 ;LOAD A COUNTER
IDPB T1,S1 ;AND DEPOSIT MORE NULLS
SOJG S2,.-1 ;FOR WIDTH CALCULATION
MOVE T1,J$PFL1(J) ;GET THE FIRST WORD ON 1ST LINE
TLNN T1,774000 ;IS THERE AT LEAST ONE CHARACTER?
JRST SETH.S ;NO, NO NAME
JRST SETH.W ;YES, FILL IN WIDTH AND RETURN
> ;END TOPS20 CONDITIONAL
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
TOPS10 <
SETH.2: MOVE S1,J$DIFN(J) ;GET THE FILE'S IFN
MOVX S2,FI.SPL ;GET THE SPOOL NAME INFO CODE
PUSHJ P,F%INFO ;GET THE SPOOLED NAME (.RBSPL)
JUMPE S1,SETH.S ;NO SPOOLED NAME
$TEXT(<-1,,J$PFL1(J)>,<^W/S1/^0>) ;GENERATE THE SPOOLED NAME
SETZM J$PFL2(J) ;AND NO EXTENSION
JRST SETH.W ;AND FINISH UP
SETH.3: MOVE P1,J$DFDA(J) ;GET THE FD ADDRESS
$TEXT(<-1,,J$PFL1(J)>,<^W/.FDNAM(P1)/^0>)
$TEXT(<-1,,J$PFL2(J)>,<^W3/.FDEXT(P1)/^0>)
JRST SETH.W ;FINISH UP AND RETURN
> ;END TOPS10 CONDITIONAL
;COMMON SUBROUTINES
;SETH.S is used to setup a non-descript name if we can't do any better
SETH.S: $TEXT(<-1,,J$PFL1(J)>,<Spooled^0>)
$TEXT(<-1,,J$PFL2(J)>,< Printer File^0>)
;AND FALL INTO SETH.W
;SETH.W is called to figure out the blocksize to use, set it, and return.
; If both lines are 6 characters or less, the current width-class is
; used as the blocksize, else, blocksize of 1 is used.
SETH.W: MOVE S1,J$FWCL(J) ;GET THE WIDTH CLASS
MOVE S2,J$PFL1+1(J) ;GET 2ND WORD OF LINE 1
IOR S2,J$PFL2+1(J) ;OR IN SECOND WORD OF LINE 2
TLNE S2,003760 ;IS THE 7TH CHARACTER THERE IN EITHER?
MOVEI S1,1 ;YES, USE BLOCKSIZE 1
MOVEM S1,J$PFLS(J) ;SAVE IT
$RETT ;AND RETURN
SUBTTL PICTUR -- Routine to print block letters
;Call: S1/ blocksize of letters
; S2/ pointer to string (left half can be 0 or byte-pointer)
PICTUR: PUSHJ P,.SAVE3 ;SAVE P1 THRU P3
PUSHJ P,.SAVET ;AND SAVE T1 THRU T4
DMOVE P1,S1 ;SAVE THE INPUT ARGUMENTS
MOVNI P3,^D35 ;GET A BIT COUNTER
PICT.1: MOVE T4,P1 ;COPY OVER THE BLOCK SIZE
PUSHJ P,PICT.2 ;PRINT A LINE
SOJG T4,.-1 ;AND DO IT "BLOCKSIZE" TIMES
ADDI P3,5 ;BUMP TO NEXT SEGMENT OF CHARACTER
JUMPL P3,PICT.1 ;AND LOOP FOR NEXT SEGMENT
MOVEI S1,[BYTE (7) 15,12,12,12,12,0,0]
PJRST STGOUT ;SEND FOUR BLANK LINES AND RETURN
;HERE TO PRINT ONE LINE OF THE CURRENT SEGMENT
PICT.2: PUSHJ P,.SAVE2 ;SAVE P1 AND P2
PUSH P,T4 ;SAVE T4
TLNN P2,-1 ;MAKE SURE ITS A BYTE POINTER
HRLI P2,(POINT 7,0) ;MAKE IT ONE
MOVE T2,J$FWID(J) ;GET LINEWIDTH
IDIV T2,[EXP 7,^D14,^D21]-1(P1) ;AND DIVIDE BY CHARACTER SIZE
MOVE T4,T2 ;SAVE MAX NUMBER OF CHARS/LINE
PICT.3: ILDB T2,P2 ;GET A CHARACTER
JUMPE T2,PICT.6 ;LAST CHARACTER, DONE
CAIGE T2,40 ;MUST BE GREATER THEN ' '
JRST PICT.3 ;ELSE GET THE NEXT CHAR
MOVE T1,CHRTAB-40(T2) ;GET THE WORD FROM THE TABLE
ROT T1,^D35(P3) ;POSITION TO CORRECT SEGMENT
TLZ T1,017777 ;ZERO BITS FOR SPACE BETWEEN CHARS
MOVEI T3,7 ;PRINT 5 CHARS + 2 SPACES
PICT.4: MOVEI C," " ;LOAD A SPACE
TLNE T1,(1B0) ;SEE IF HIGH BIT IS ONE
LDB C,P2 ;IT IS, GET THE CHARACTER
CAIN C,":" ;IS IT A COLON ???
MOVEI C,"#" ;MAKE IT A # SIGN.
PUSHJ P,PICT.5 ;PRINT IT THE CORRECT NUMBER OF TIMES
ROT T1,1 ;ROTATE WORD 1 BIT
SOJG T3,PICT.4 ;AND LOOP THE CORRECT NUMBER OF TIMES
SOJG T4,PICT.3 ;AND GET THE NEXT CHARACTER
JRST PICT.6 ;NO MORE ROOM, DONE
PICT.5: MOVE T2,P1 ;GET THE BLOCKSIZE
PUSHJ P,DEVOUT ;PRINT IT
SOJG T2,.-1 ;LOOP
POPJ P, ;AND RETURN
PICT.6: POP P,T4 ;RESTORE T4
PJRST CRLF ;TYPE A CR AND RETURN
CHRTAB: BYTE (5) 00,00,00,00,00,00,00 ;SP
BYTE (5) 04,04,04,04,04,00,04 ;!
BYTE (5) 12,12,00,00,00,00,00 ;"
BYTE (5) 12,12,37,12,37,12,12 ;#
BYTE (5) 04,37,24,37,05,37,04 ;$
BYTE (5) 31,31,02,04,10,23,23 ;%
BYTE (5) 10,24,10,24,23,22,15 ;&
BYTE (5) 06,02,00,00,00,00,00 ;'
BYTE (5) 04,10,20,20,20,10,04 ;(
BYTE (5) 04,02,01,01,01,02,04 ;)
BYTE (5) 00,25,16,33,16,25,00 ;*
BYTE (5) 00,04,04,37,04,04,00 ;+
BYTE (5) 00,00,00,00,00,06,02 ;,
BYTE (5) 00,00,00,37,00,00,00 ;-
BYTE (5) 00,00,00,00,00,06,06 ;.
BYTE (5) 00,00,01,02,04,10,20 ;/
BYTE (5) 16,21,23,25,31,21,16 ;0
BYTE (5) 04,14,04,04,04,04,16 ;1
BYTE (5) 16,21,01,02,04,10,37 ;2
BYTE (5) 16,21,01,02,01,21,16 ;3
BYTE (5) 22,22,22,37,02,02,02 ;4
BYTE (5) 37,20,34,02,01,21,16 ;5
BYTE (5) 16,20,20,36,21,21,16 ;6
BYTE (5) 37,01,01,02,04,10,20 ;7
BYTE (5) 16,21,21,16,21,21,16 ;8
BYTE (5) 16,21,21,17,01,01,16 ;9
BYTE (5) 00,00,06,06,00,06,06 ;:
BYTE (5) 00,06,06,00,06,06,02 ;;
BYTE (5) 02,04,10,20,10,04,02 ;<
BYTE (5) 00,00,37,00,37,00,00 ;=
BYTE (5) 10,04,02,01,02,04,10 ;>
BYTE (5) 16,21,01,02,04,00,04 ;?
BYTE (5) 16,21,21,27,25,25,07 ;@
BYTE (5) 16,21,21,21,37,21,21 ;A
BYTE (5) 36,21,21,36,21,21,36 ;B
BYTE (5) 17,20,20,20,20,20,17 ;C
BYTE (5) 36,21,21,21,21,21,36 ;D
BYTE (5) 37,20,20,36,20,20,37 ;E
BYTE (5) 37,20,20,36,20,20,20 ;F
BYTE (5) 17,20,20,20,27,21,16 ;G
BYTE (5) 21,21,21,37,21,21,21 ;H
BYTE (5) 16,04,04,04,04,04,16 ;I
BYTE (5) 01,01,01,01,21,21,16 ;J
BYTE (5) 21,21,22,34,22,21,21 ;K
BYTE (5) 20,20,20,20,20,20,37 ;L
BYTE (5) 21,33,25,21,21,21,21 ;M
BYTE (5) 21,21,31,25,23,21,21 ;N
BYTE (5) 16,21,21,21,21,21,16 ;O
BYTE (5) 36,21,21,36,20,20,20 ;P
BYTE (5) 16,21,21,21,25,22,15 ;Q
BYTE (5) 36,21,21,36,24,22,21 ;R
BYTE (5) 17,20,20,16,01,01,36 ;S
BYTE (5) 37,04,04,04,04,04,04 ;T
BYTE (5) 21,21,21,21,21,21,37 ;U
BYTE (5) 21,21,21,21,21,12,04 ;V
BYTE (5) 21,21,21,21,25,33,21 ;W
BYTE (5) 21,21,12,04,12,21,21 ;X
BYTE (5) 21,21,12,04,04,04,04 ;Y
BYTE (5) 37,01,02,04,10,20,37 ;Z
BYTE (5) 14,10,10,10,10,10,14 ;[
BYTE (5) 00,00,20,10,04,02,01 ;\
BYTE (5) 06,02,02,02,02,02,06 ;]
BYTE (5) 04,12,21,00,00,00,00 ;^
BYTE (5) 00,00,00,00,00,00,37 ;_
BYTE (5) 14,10,00,00,00,00,00 ;ACCENT GRAVE
BYTE (5) 00,00,36,01,17,21,17 ;LC A
BYTE (5) 20,20,20,36,21,21,36 ;LC B
BYTE (5) 00,00,17,20,20,20,17 ;LC C
BYTE (5) 01,01,01,17,21,21,17 ;LC D
BYTE (5) 00,00,16,21,36,20,17 ;LC E
BYTE (5) 16,21,20,34,20,20,20 ;LC F
BYTE (5) 00,00,16,21,17,01,37 ;LC G
BYTE (5) 20,20,20,36,21,21,21 ;LC H
BYTE (5) 00,04,00,04,04,04,04 ;LC I
BYTE (5) 00,04,00,04,04,24,10 ;LC J
BYTE (5) 20,22,22,24,30,24,22 ;LC K
BYTE (5) 04,04,04,04,04,04,04 ;LC L
BYTE (5) 00,00,24,37,25,25,25 ;LC M
BYTE (5) 00,00,20,36,21,21,21 ;LC N
BYTE (5) 00,00,16,21,21,21,16 ;LC O
BYTE (5) 00,00,36,21,36,20,20 ;LC P
BYTE (5) 00,00,17,21,17,01,01 ;LC Q
BYTE (5) 00,00,26,31,20,20,20 ;LC R
BYTE (5) 00,00,17,20,16,01,36 ;LC S
BYTE (5) 00,10,34,10,10,10,06 ;LC T
BYTE (5) 00,00,21,21,21,21,16 ;LC U
BYTE (5) 00,00,21,21,12,12,04 ;LC V
BYTE (5) 00,00,21,21,25,25,12 ;LC W
BYTE (5) 00,00,21,12,04,12,21 ;LC X
BYTE (5) 00,00,21,12,04,04,30 ;LC Y
BYTE (5) 00,00,37,02,04,10,37 ;LC Z
BYTE (5) 04,10,10,20,10,10,04 ;OPEN BRACE
BYTE (5) 04,04,04,00,04,04,04 ;VERTICAL BAR
BYTE (5) 04,02,02,01,02,02,04 ;CLOSE BRACE
BYTE (5) 00,10,25,02,00,00,00 ;TILDE
BYTE (5) 00,00,00,00,00,00,00 ;RUBOUT
SUBTTL SYSTEM INITIALIZATION FUNCTIONS
TOPS10 <
OPDINI: MOVEI T3,4 ;NUMBER OF WORDS IN SYSNAM - 1
MOVS T1,[%CNFG0] ;ADR OF FIRST WORD
GETSYN: MOVS T2,T1 ;GET THE GETTAB ADR
GETTAB T2, ;GET THE WORD
JFCL ;IGNORE THIS
MOVEM T2,LPCNF(T1) ;SAVE NAME
CAILE T3,(T1) ;DONE?
AOJA T1,GETSYN ;NO, LOOP
PUSHJ P,I%HOST ;GET THE HOST NAME AND NUMBER
MOVEM S2,CNTSTA ;SAVE THE NUMBER
MOVX T3,%%.MOD ;GET PROGRAM NAME
SETNAM T3, ;NO, TURN OFF JACCT
> ;END TOPS10 CONDITIONAL
TOPS20 <
OPDINI: PUSHJ P,I%HOST ;GET THE HOST NAME
MOVEM S1,CNTSTA ;SAVE IT
MOVX S1,.MSIIC ;GET 'IGNORE STR ACCTING' FUNCTION
MSTR ;WE WANT TO IGNORE STRUCTURE ACCOUNTING
ERJMP .+1 ;IGNORE ANY ERROR
MOVX S1,'SYSVER' ;NAME OF GETTAB FOR SYSNAME
SYSGT ;GET IT
HRLZ T1,S2 ;GET TABLE#,,0
MOVEI T2,10 ;AND LOAD LOOP COUNTER
GETSYN: MOVS S1,T1 ;GET N,,TABLE#
GETAB ;GET THE ENTRY
MOVEI S1,0 ;USE ZERO IF LOSING
MOVEM S1,LPCNF(T1) ;STORE THE RESULT
CAILE T2,(T1) ;DONE ENUF?
AOJA T1,GETSYN ;NO, LOOP
MOVX S1,RC%EMO ;EXACT MATCH
HRROI S2,[ASCIZ /PS:<SPOOL>/] ;DIRECTORY NAME
RCDIR ;GET THE NUMBER
MOVEM T1,SPLDIR ;SAVE IT
> ;END TOPS20 CONDITIONAL
IFN FTDN60,<
PUSHJ P,D60INI## ;INIT D60 DATA BASE
>
SETZM FMOPN ;CLEAR FORMS.INI OPEN FLAG
$RETT ;AND RETURN
SUBTTL OPNFRM -- Routine to open LPFORM.INI
OPNFRM: SKIPN FMOPN ;OPEN ALREADY?
JRST OPNF.1 ;NO, CONTINUE ON
MOVE S1,FMIFN ;YES, GET THE IFN
PUSHJ P,F%REL ;AND RELEASE IT
SETZM FMOPN ;CLEAR "OPEN"
OPNF.1: MOVEI S1,FOB.SZ ;FOB SIZE
MOVEI S2,FOB ;FOB ADDRESS
PUSHJ P,.ZCHNK ;ZERO IT
MOVEI S1,FMFD ;GET FD ADDRESS
STORE S1,FOB+FOB.FD ;STORE IT
MOVEI S1,7 ;LOAD BYTE SIZE
STORE S1,FOB+FOB.CW,FB.BSZ ;STORE IT
MOVEI S1,FOB.SZ ;LOAD THE FOB SIZE
MOVEI S2,FOB ;AND THE FOB ADDRESS
PUSHJ P,F%IOPN ;AND OPEN THE FILE
JUMPF .RETF ;LOSE?
MOVEM S1,FMIFN ;SAVE THE IFN
SETOM FMOPN ;SET "OPEN"
$RETT ;AND RETURN
TOPS10 <
FMFD: XWD FMFDL,0 ;FD SIZE
SIXBIT /SYS/ ;DEVICE
SIXBIT /LPFORM/ ;FILE NAME
SIXBIT /INI/ ;EXTENSION
EXP 0 ;AND PPN WORD
FMFDL==.-FMFD ;FD SIZE
> ;END TOPS10 CONDITIONAL
TOPS20 <
FMFD: XWD FMFDL,0 ;FD SIZE
ASCIZ /SYS:LPFORM.INI/ ;AND THE STRING
FMFDL==.-FMFD ;THE FD SIZE
> ;END TOPS20 CONDITIONAL
SUBTTL Interrupt Module
; INTINI INITIALIZE INTERRUPT SYSTEM
; INTON ENABLE INTERRUPTS
; INTOFF DISABLE INTERRUPTS
; INTCNL CONNECT THE LINEPRINTER
; INTDCL DISCONNECT THE LINEPRINTER
; INTIPC INTERRUPT ROUTINE -- IPCF
; INTDEV INTERRUPT ROUTINE -- LPT OFF-LINE
SUBTTL - INTERRUPT SYSTEM DATABASE
TOPS10 <
VECTOR: BLOCK 0 ;BEGINNING OF INTERRUPT VECTOR
VECIPC: BLOCK 4 ;IPCF INTERRUPT BLOCK
VECDEV: BLOCK 4*NPRINT ;DEVICE INTERRUPT BLK
ENDVEC==.-1 ;END OF INTERRUPT VECTOR
> ;END TOPS10 CONDITIONAL
TOPS20 <
LEVTAB: EXP LEV1PC ;WHERE TO STORE LEVEL 1 INT PC
EXP LEV2PC ;WHERE TO STORE LEVEL 2 INT PC
EXP LEV3PC ;WHERE TO STORE LEVEL 3 INT PC
CHNTAB: XWD 1,INTIPC ;IPCF INT - LEVEL 1
XWD 1,INTDEV ;DEV OFF LINE INT - LEVEL 1
BLOCK ^D34 ;RESTORE OF THE TABLE
LEV1PC: BLOCK 1 ;LVL 1 INTERRUPT PC STORED HERE
LEV2PC: BLOCK 1 ;LVL 2 INTERRUPT PC STORED HERE
LEV3PC: BLOCK 1 ;LVL 3 INTERRUPT PC STORED HERE
> ;END TOPS20 CONDITIONAL
TOPS10 <
DEFINE LPINHD(Z),<
XLIST
$BGINT 1,
MOVEI S1,Z
MOVEI S2,VECDEV+<4*Z>
JRST LPINTR
LPHDSZ==4
LIST
> ;END DEFINE LPINHD
> ;END TOPS10 CONDITIONAL
TOPS10 <
INTINI: MOVEI S1,INTIPC ;GET ADDRESS OF IPCF INT RTN
MOVEM S1,VECIPC+.PSVNP ;SAVE IN VECTOR
Z==0
REPEAT NPRINT,<
MOVEI S1,INTDEV+<LPHDSZ*Z> ;GET ADDRESS OF LPT HEADER
MOVEM S1,VECDEV+<4*Z>+.PSVNP ;STORE IN THE VECTOR
Z==Z+1
> ;END REPEAT NPRINT
POPJ P, ;AND RETURN
> ;END TOPS10 CONDITIONAL
TOPS20 <
INTINI: MOVX S1,.FHSLF ;LOAD MY FORK HANDLE
MOVX S2,1B0!1B1 ;CHANNELS 0 AND 1
AIC ;ACTIVATE THE CHANNELS
POPJ P, ;AND RETURN
> ;END TOPS20 CONDITIONAL
TOPS10 <
INTDCL: SKIPA S1,[PS.FRC+T1] ;REMOVE CONDITION USINGS ARGS IN T1
INTCNL: MOVX S1,PS.FAC+T1 ;ADD CONDITION USING ARGS IN T1
MOVE T1,J$LCHN(J) ;USE CHANNEL AS CONDTION
MOVE T2,STREAM ;GET STREAM NUMBER
IMULI T2,4 ;GET BLOCK OFFSET
ADDI T2,VECDEV-VECTOR ;GET OFFSET FROM BEGINNING
HRLZS T2 ;GET OFFSET,,0
HRRI T2,PS.RDO+PS.ROD+PS.ROL ;AND CONDITIONS
SETZ T3, ;ZERO T3
PISYS. S1, ;TO THE INTERRUPT SYSTEM
$RETF ;WE FAILED !!!
$RETT ;RETURN OK.
> ;END TOPS10 CONDITIONAL
TOPS20 <
INTCNL: MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVX S2,.MOPSI ;GET MTOPR FUNCTION
MOVEI T1,T2 ;AND ADDRESS OF ARGS
MOVEI T2,3 ;1ST ARG IS # ARGS
MOVEI T3,1 ;2ND ARG IS INT CHANNEL NUMBER
MOVX T4,MO%MSG ;DON'T TYPE THE MESSAGE
PUSHJ P,$MTOPR ;CONNECT IT
JUMPF .RETF ;IF AN ERROR,,RETURN ERROR
$RETT ;ELSE RETURN OK
> ;END TOPS20 CONDITIONAL
;INTERRUPT ROUTINES
INTIPC: $BGINT 1, ;SETUP FOR THE INTERRUPT.
PUSHJ P,C%INTR ;FLAG THE INTERRUPT.
TOPS10 <
$DEBRK ;DISMISS THE INTERRUPT.
> ;END TOPS10 CONDITIONAL
TOPS20 <
SKIPN J,JOBPAG ;DOES A STREAM EXIST ??
$DEBRK ;NO,,JUST FINISH UP HERE.
JRST INTDON ;FINISH UP -20 INTERRUPT PROCESSING.
> ;END TOPS20 CONDITIONAL
;Here on device interrupts on the -10. This routine consists of multiple
; interrupt headers (one for each stream) which load S1 and S2 and
; call the main interrupt body, LPINTR. Note that on the -10, while
; it is assumed that 'output done' and 'on-line' interrupts can happen
; anytime and anywhere, it is also assumed that 'device off-line'
; interrupts ONLY HAPPEN IN THE STREAM CONTEXT.
TOPS10 <
INTDEV: Z==0
REPEAT NPRINT,<
LPINHD(Z)
Z==Z+1 >
LPINTR: MOVE J,JOBPAG(S1) ;GET THE JOB PARAMETER PAGE
HRRZ T1,.PSVFL(S2) ;GET I/O REASON FLAGS
ANDCAM T1,.PSVFL(S2) ;AND CLEAR THEM
SETZ T2, ;CLEAR AN AC
TXNE T1,PS.ROL+PS.RDO ;IS IT DEVICE ONLINE OR OFFLINE ???
SETOM JOBCHK(S1) ;YES,,SAY WE WANT A CHECKPOINT
TXNE T1,PS.ROL ;IS IT ON-LINE?
MOVX T2,PSF%DO+PSF%OB ;YES,,CLEAR ON-LINE & OUTPUT-BLOCKED
TXNE T1,PS.ROD ;IS IT OUTPUT DONE?
TXO T2,PSF%OB ;YES, GET SCHEDULER BIT
ANDCAM T2,JOBSTW(S1) ;CLEAR THE SCHEDULER FLAGS
TXNN T1,PS.RDO ;IS IT DEVICE OFF-LINE?
$DEBRK ;NO,,DISMISS THE INTERRUPT.
TXNE T1,PS.ROL ;IF BOTH OFFLINE AND ONLINE,
$DEBRK ;DISMISS THE INTERRUPT.
MOVX T2,PSF%DO ;GET OFF-LINE BIT.
IORM T2,JOBSTW(S1) ; AND SET IT.
MOVEI T1,OUTWON ;LOAD RESTART ADDRESS
EXCH T1,.PSVOP(S2) ;STORE FOR DEBRK AND GET OLD ADRESS
MOVEM T1,J$LIOA(J) ;STORE OLD-ADDRESS FOR DEVICE ON AGAIN
$DEBRK ;DISMISS THE INTERRUPT.
> ;END TOPS10 CONDITIONAL
;HERE ON DEVICE INTERRUPTS ON THE -20.
; SINCE ALL I/O IS DONE BY CALLING A SUBROUTINE,
; IF AN INTERRUPT OCCURS WHILE WE ARE I/O ACTIVE,
; WE DONT WANT TO JUST DEBRK BACK INTO THE SOUT
; (UNLESS WE ARE PROCESSING A REMOTE LPT).
; FOR LOCAL LPT'S, WE JUST WANT TO RETURN FROM THE
; SUBROUTINE, WITH THE UPDATED BYTE POINTER AND BYTE
; COUNT. THIS IS WHY WE ALTER THE RETURN PC FOR LOCAL
; LPT'S IF WE ARE I/O ACTIVE. IN THIS CASE WE JUST
; RETURN TO THE CALLING ROUTINE (OUTOUT)
TOPS20 <
INTDEV: $BGINT 1, ;SETUP FOR INTERRUPT
SKIPN J,JOBPAG ;DOES A STREAM EXIST ??
$DEBRK ;NO,,DEBREAK
SETOM JOBCHK ;SAY WE WANT A CHECKPOINT TAKEN
MOVE S1,J$LCHN(J) ;GET THE LPT JFN
MOVX S2,.MORST ;READ-STATUS FUNCTION
MOVEI T1,T2 ;AND ADDRESS OF ARGS
MOVEI T2,3 ;LENGTH OF ARG BLOCK
PUSHJ P,$MTOPR ;GET THE LPT STATUS
MOVX S1,PSF%DO ;DEVICE OFFLINE FLAG
ANDCAM S1,JOBSTW ;CLEAR THE VALUE
TXNE T3,MO%OL ;IS IT OFF-LINE?
IORM S1,JOBSTW ;YES, SET FLAG
INTDON: SKIPE J$LREM(J) ;IS THIS A REMOTE PRINTER ???
JRST INTD.1 ;YES,,SKIP THIS 'LOCAL' STUFF
MOVEI S1,.RETT ;YES,,POINT TO EXIT ADDRESS
SKIPE J$LIOA(J) ;WERE WE I/O ACTIVE ???
MOVEM S1,LEV1PC ;DEBRK ADDRESS, SO SAVE IT.
INTD.1: SETZM J$LIOA(J) ;CLEAR I/O ACTIVE.
$DEBRK ;DISMISS THE INTERRUPT.
> ;END TOPS20 CONDITIONAL
SUBTTL TOPS-20 I/O LOCAL/REMOTE SUBROUTINES ($SOUT)
TOPS20 <
$SOUT: SETOM J$LIOA(J) ;INDICATE I/O IS ACTIVE
SKIPE JOBSTW ;ANY STATUS BITS SET ???
JRST SOUT.T ;YES,,RETURN NOW
SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST SOUT.2 ;YES,,GO PROCESS IT
JRST SOUT.6 ] ;NO,,MUST BE DN60
SOUT ;LOCAL,,ISSUE THE SOUT NORMALLY
ERJMP SOUT.F ;ON ERROR,,TAKE FAIL RETURN
SOUT.T: SETZM J$LIOA(J) ;CLEAR I/O ACTIVE
$RETT ;AND RETURN
SOUT.F: SETZM J$LIOA(J) ;CLEAR I/O ACTIVE
$RETF ;AND RETURN
$GTJFN: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST GTJF.2 ;YES,,GO PROCESS IT
JRST GTJF.6 ] ;NO,,MUST BE DN60
GTJFN ;LOCAL,,ISSUE THE GTJFN NORMALLY
$RETF ;NO GOOD,,RETURN FALSE
$RETT ;ELSE RETURN OK
$OPENF: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST OPEN.2 ;YES,,GO PROCESS IT
JRST OPEN.6 ] ;NO,,MUST BE DN60
OPENF ;LOCAL,,OPEN THE LPT NORMALLY
$RETF ;NO GOOD,,RETURN FALSE
$RETT ;ELSE RETURN OK
$CLOSF: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST CLOS.2 ;YES,,GO PROCESS IT
JRST CLOS.6 ] ;NO,,MUST BE DN60
CLOSF ;LOCAL,,CLOSE IT DOWN NORMALLY
$RETF ;NO GOOD,,RETURN FALSE
$RETT ;ELSE RETURN OK
$MTOPR: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST MTOP.2 ;YES,,GO PROCESS IT
JRST MTOP.6 ] ;NO,,MUST BE DN60
MTOPR ;LOCAL,,DO THE MTOPR NORMALLY
ERJMP .RETF ;ON AN ERROR,,RETURN NO GOOD
$RETT ;ELSE RETURN OK
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
$GDSTS: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
JRST [SKIPG J$LREM(J) ;YES,,IS THIS A DN200 REQUEST ???
JRST GDST.2 ;YES,,GO PROCESS IT
JRST .RETT ] ;NO,,MUST BE DN60 (NO MTOPR)
MOVE S1,J$LCHN(J) ;LOCAL,,GET THE DEVICE JFN
GDSTS ;GET THE DEVICE STATUS
ERJMP .RETF ;ON AN ERROR,,RETURN NO GOOD
MOVE S1,S2 ;RETURN STATUS BITS IN S1
$RETT ;RETURN OK
$SDSTS: SKIPE J$LREM(J) ;IS THIS A REMOTE LPT ???
$RETT ;YES,,CANT SET DEVICE STATUS
MOVE S2,S1 ;GET THE STATUS BITS IN S2
MOVE S1,J$LCHN(J) ;GET THE DEVICE JFN IN S1
SDSTS ;SET THE LPT STATUS
ERJMP .RETF ;ON AN ERROR,,RETURN NO GOOD
$RETT ;ELSE RETURN OK
SUBTTL DN200 I/O SUPPORT ROUTINES
IFN FTRJE,<
SOUT.2: PUSHJ P,USOUT## ;OUTPUT THE DATA
ERJMP SOUT.F ;ON ERROR,,TAKE FAIL RETURN
JRST SOUT.T ;OK,,JUST RETURN
GTJF.2: PUSHJ P,UGTJFN## ;MAKE GTJFN CALL VIA NURD
ERJMP .RETF ;NO GOOD,,SAY SO
$RETT ;ELSE HE WINS
OPEN.2: PUSHJ P,UOPENF## ;MAKE CALL VIA NURD
ERJMP .RETF ;NO GOOD,,SAY SO
$RETT ;ELSE HE WINS
CLOS.2: PUSHJ P,UCLOSF## ;MAKE CALL VIA NURD
ERJMP .RETF ;NO GOOD,,SAY SO
$RETT ;ELSE HE WINS
MTOP.2: PUSHJ P,UMTOPR## ;MAKE CALL VIA NURD
ERJMP .RETF ;NO GOOD,,SAY SO
$RETT ;ELSE HE WINS
GDST.2: MOVE S1,J$LCHN(J) ;GET THE JFN
MOVX S2,.MORST ;GET READ DEVICE FUNCTION
MOVEI T1,T2 ;AND ADDRESS OF ARGS
MOVEI T2,3 ;ARG BLOCK LENGTH
PUSHJ P,UMTOPR## ;MAKE CALL VIA NURD
ERJMP .RETF ;NO GOOD,,SAY SO
MOVE S1,T3 ;RETURN STATUS BITS IN S1
$RETT ;HE WINS
>
IFE FTRJE,<
SOUT.2:
GTJF.2:
OPEN.2:
CLOS.2:
MTOP.2:
GDST.2:
MOVE S1,STREAM ;GET OUT STREAM NUMBER
$WTO (DN200 Remote not Supported,,@JOBOBA(S1))
$RETF ;RETURN
>
SUBTTL DN60 I SUPPORT ROUTINES
IFN FTDN60,<
SOUT.6: SETZM J$LIOA(J) ;ZAP I/O ACTIVE (NONE FOR DN60)
PUSHJ P,D60SOUT## ;OUTPUT THE DATA
JUMPT SOU.6B ;IF OK,,RETURN
CAIN S1,D6NBR ;IS IT A NON-BLOCKING RETURN ???
JRST SOU.6B ;YES,,JUST RETURN
MOVE T2,STREAM ;GET OUR STREAM NUMBER
CAIE S1,D6DOL ;IS THE ERROR OFFLINE ???
CAIN S1,D6CGO ;OR IS IT CANT GET OUTPUT PERMISSION ??
JRST SOU.6A ;YES TO EITHER,,SKIP THIS
$WTO(<DN60 I/O Error # ^O/S1/ on ^B/@JOBOBA(T2)/>,,,<$WTFLG(WT.SJI)>)
PUSHJ P,OUTDIE ;COUNT DOWN I/O ERRORS
SOU.6A: PUSHJ P,I%NOW ;GET THE CURRENT TIME
ADDI S1,^D12 ;GET TIME + 4 SECONDS
MOVEM S1,JOBWKT(T2) ;SAVE IT FOR THE SCHEDULER
SKIPE J$OFLN(J) ;WERE WE ALREADY OFFLINE ???
JRST .+3 ;YES,,SKIP THIS
SETOM JOBCHK(T2) ;FLAG THAT WE WANT A CHECKPOINT TAKEN
$WTO (<^T/BELL/>,,@JOBOBA(T2)) ;NO,,TELL OPR LPT IS OFFLINE
SETOM J$OFLN(J) ;SET THE LPT OFFLINE FLAG
$DSCHD(PSF%AL+PSF%DO) ;DESCHEDULE THE PROCESS
$RETT ;AND RETURN
SOU.6B: SKIPN J$OFLN(J) ;WERE WE OFFLINE BEFORE THIS ???
$RETT ;NO,,JUST RETURN
SETZM J$OFLN(J) ;CLEAR THE OFFLINE FLAG
PUSH P,S2 ;SAVE S2 (BYTE POINTER)
PUSH P,T1 ;SAVE T1 (BYTE COUNT)
PUSHJ P,UPDTST ;UPDATE THE DEVICE STATUS
POP P,T1 ;RESTORE T1 (BYTE COUNT)
POP P,S2 ;RESTORE S2 (BYTE POINTER)
$RETT ;AND RETURN
GTJF.6: SETOM S1 ;NO JFN HERE (MUST RETURN -1)
$RETT ;AND RETURN (NO JFN HERE)
OPEN.6: SETOM J$LINK(J) ;INDICATE NO OPR MSG LIST YET
MOVE S1,STREAM ;GET OUR STREAM NUMBER
MOVE S1,JOBOBA(S1) ;GET OUR OBJECT BLOCK ADDRESS
MOVE S1,OBJ.UN(S1) ;GET OUR UNIT NUMBER
STORE S1,MSGBLK,OP$UNT ;SAVE THE UNIT NUMBER IN OPEN BLOCK
MOVX S1,.OPLPT ;WANT 'LPT' DEVICE
STORE S1,MSGBLK,OP$TYP ;SAVE THE DEVICE TYPE IN THE OPEN BLOCK
LOAD S1,J$DCND(J),CN$PRT ;GET THE PORT NUMBER
STORE S1,MSGBLK,OP$PRT ;SAVE IT IN THE OPEN BLOCK
LOAD S1,J$DCND(J),CN$LIN ;GET THE LINE NUMBER
STORE S1,MSGBLK,OP$LIN ;SAVE IT IN THE OPEN BLOCK
LOAD S1,J$DCND(J),CN$SIG ;GET THE LINE SIGNATURE
STORE S1,MSGBLK,OP$SIG ;SAVE IT IN THE OPEN BLOCK
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
HRROI S1,-OP$SIZ ;GET THE NEGATIVE BLOCK LENGTH
MOVEI S2,MSGBLK ;GET THE PARM BLOCK ADDRESS
PUSHJ P,D60OPN## ;OPEN THE PRINTER
JUMPF .RETF ;CANT OPEN IT (OH WELL !!!)
MOVEM S1,J$LCHN(J) ;SAVE THE LPT HANDLE
HRLZI S1,.OPCOU ;WANT OUTPUT CONSOLE FOR REMOTE
MOVEM S1,MSGBLK ;SAVE THE DEV-TYP,,UNIT NUMBER IN WORD 0
HRROI S1,-OP$SIZ ;GET THE NEGATIVE PARM BLOCK LENGTH
MOVEI S2,MSGBLK ;GET THE PARM BLOCK ADDRESS
PUSHJ P,D60OPN## ;OPEN THE OUTPUT CONSOLE
JUMPF [MOVE S1,J$LCHN(J) ;NO GOOD,,GET THE LPT ID
PUSHJ P,D60RLS## ;RELEASE THE LINE PRINTER
$RETF ] ;RETURN FALSE
MOVEM S1,J$D6OP(J) ;SAVE THE OPERATORS CONSOLE ID
PUSHJ P,L%CLST ;CREATE A LIST FOR OPERATOR MESSAGES
MOVEM S1,J$LINK(J) ;SAVE THE LIST ID
$RETT ;AND RETURN
MTOP.6: CAXE S2,.MOEOF ;IS THIS END OF FILE ??
$RETT ;NO,,JUST RETURN
MOVE S1,J$LCHN(J) ;GET THE LPT ID
PUSHJ P,D60EOF## ;CLEAR BUFFERS,,TURN THE LINE AROUND
$RETT ;AND RETURN
CLOS.6: MOVE S1,J$LCHN(J) ;MAKE SURE WE HAVE JUST THE HANDLE
PUSHJ P,D60RLS## ;CLOSE DOWN THE DN60
MOVE S1,J$D6OP(J) ;GET THE CONSOLE ID
PUSHJ P,D60RLS## ;CLOSE DOWN THE OPERATORS CONSOLE
SKIPL S1,J$LINK(J) ;CHECK AND GET THE OPERATORS LIST ID
PUSHJ P,L%DLST ;DELETE THE LIST IF THERE IS ONE
$RETT ;AND RETURN (NO JFN HERE)
>
IFE FTDN60,<
SOUT.6:
GTJF.6:
OPEN.6:
MTOP.6:
CLOS.6:
GDST.6:
MOVE S1,STREAM ;GET OUR STREAM NUMBER
$WTO (DN60 Type Remote not Supported,,@JOBOBA(S1))
$RETF ;RETURN
>
> ;END TOPS20 CONDITIONAL
SUBTTL STARS - JOB DEFINITION/SEPARATION LINE DEFINITIONS.
STARS: ASCII /000000000000000000000000000000000000000000000000000000000000/
ASCII /000000000000000000000000000000000000000111111111111111111111/
ASCII /1111111111/
BYTE(7) 61,61,23,15,15
ASCII /000000000111111111122222222223333333333444444444455555555556/
ASCII /666666666777777777788888888889999999999000000000011111111112/
ASCII /2222222223/
BYTE(7) 63,63,23,15,15
ASCII /123456789012345678901234567890123456789012345678901234567890/
ASCII /123456789012345678901234567890123456789012345678901234567890/
ASCII /1234567890/
BYTE(7) 61,62,23,0,0
LPTEND::END LPTSPL