Trailing-Edge
-
PDP-10 Archives
-
decuslib10-12
-
43,50547/pltlib/sprout/sprout.pag
There is 1 other file named sprout.pag in the archive. Click here to see a list.
TITLE SPROUT -- Spooling PRocessor for OUTput - Version 4
SUBTTL D.A. Lewine - L.S. Samberg/PJT/DPM/NT/CTK 1-Mar-83
CSM01$==^D400 ;Plotter has 3 pens, ON-LINE indicator, 400 SPI
CSM02$==-1 ;Compressed plot files
CSM03$==-1 ;Red and Black in banner
CSM04$==-1 ;Do CSM accounting (minutes and inches used)
CSM05$==-1 ;Add SLEEP time to $DSCHD macro for TTY response wait
CSM06$==^D1200 ;Support the TAB Products Card Terminal at 1200 baud
CSM07$==-1 ;Change some QUEUE defaults
CSM08$==^D2400 ;PTC-6 Plotter Terminal Controller at 2400 baud
IF2,<IFN CSM02$,<PRINTX [CSM02$ uses TOLP.REL]>>
IF2,<IFN CSM06$,<PRINTX [CSM06$ uses TABCDP.REL]>>
IF2,<IFN CSM08$,<PRINTX [CSM08$ uses PTC6.REL]>>
REPEAT 0,< ;To completely remove the CSM changes, make this a REPEAT 1
CSM01$==0 ;Normal XY-10 plotter
CSM02$==0 ;Plot files are 1 byte per increment (very big)
CSM03$==0 ;Do not exercise the black and red pens
CSM04$==0 ;Account disk reads instead of forms type
CSM05$==0 ;No TTY I/O, therefore no sleep requests
CSM06$==0 ;Card punch is on I/O bus or front-end 11
CSM07$==0 ;Use whatever QUEUE says
CSM08$==0 ;Plotter is not connected to a TTY line
DEFINE CSMEDT($EDIT,$PART),<> ;Dummy macro
CSMED$==0 ;No additional edits
> ;End of REPEAT 0
;
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979,1980,1981,1982 BY
; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MA.
;
; 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.
PAGE
SALL ;Also searches UUOSYM and ACTSYM.UNV
SEARCH GLXMAC ;SEARCH GLXLIB SYMBOLS
SEARCH QSRMAC ;GET QUASAR SYMBOLS
SEARCH ORNMAC ;GET OPERATOR SYMBOLS
PROLOGUE(SPROUT) ;DO STANDARD PROLOG
IFNDEF CSMEDT,< SEARCH CSMEDT > ;CSM edit macro
.XCREF S1,S2,T1,T2,T3,T4,C,J,P ;[CSM] Save some trees
;VERSION INFORMATION
SPOVER==4 ;MAJOR VERSION NUMBER
SPOMIN==0 ;MINOR VERSION NUMBER
SPOEDT==2533 ;EDIT LEVEL
SPOWHO==2 ;Who last patched (JMS @ CSM)
%SPO==<BYTE (3)SPOWHO(9)SPOVER(6)SPOMIN(18)SPOEDT>+CSMED$
;STORE VERSION NUMBER IN JOBVER
LOC 137
.JBVER:: EXP %SPO ;SPROUT VERSION
RELOC 0
COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1971,1984.
SUBTTL Table of Contents
; Table of Contents for SPROUT
;
;
; Section Page
;
; 1. Table of Contents . . . . . . . . . . . . . . . . . . 1
; 2. Revision History . . . . . . . . . . . . . . . . . . . 2
; 3. CSM Revision History . . . . . . . . . . . . . . . . . 2
; 4. Constants (Conditional and Unconditional) . . . . . . 4
; 5. MACROS . . . . . . . . . . . . . . . . . . . . . . . . 5
; 6. Special Forms Handling Parameters . . . . . . . . . . 6
; 7. Flag Definitions . . . . . . . . . . . . . . . . . . . 7
; 8. Job Parameter Area . . . . . . . . . . . . . . . . . . 8
; 9. Random Impure Storage . . . . . . . . . . . . . . . . 11
; 10. Resident JOB DaTABase . . . . . . . . . . . . . . . . 12
; 11. Non-zero daTABase . . . . . . . . . . . . . . . . . . 13
; 12. $TEXT Utilities . . . . . . . . . . . . . . . . . . . 14
; 13. Program Initialization . . . . . . . . . . . . . . . . 15
; 14. Idle Loop . . . . . . . . . . . . . . . . . . . . . . 16
; 15. Deschedule Process . . . . . . . . . . . . . . . . . . 17
; 16. CHKTIM - Routine to see if it's time to schedule a s . 17
; 17. Do the Job . . . . . . . . . . . . . . . . . . . . . . 18
; 18. Process a File . . . . . . . . . . . . . . . . . . . . 19
; 19. End of Job . . . . . . . . . . . . . . . . . . . . . . 20
; 20. FILDIS . . . . . . . . . . . . . . . . . . . . . . . . 21
; 21. CHKQUE . . . . . . . . . . . . . . . . . . . . . . . . 22
; 22. CHKOBJ . . . . . . . . . . . . . . . . . . . . . . . . 23
; 23. FNDOBJ . . . . . . . . . . . . . . . . . . . . . . . . 24
; 24. GETBLK . . . . . . . . . . . . . . . . . . . . . . . . 25
; 25. NEXTJOB Message from QUASAR . . . . . . . . . . . . . 26
; 26. User CANCEL Request . . . . . . . . . . . . . . . . . 27
; 27. UPDATE Routine to send status update . . . . . . . . . 28
; 28. CHKPNT Routine to send checkpoint message . . . . . . 29
; 29. SETUP/SHUTDOWN Message . . . . . . . . . . . . . . . . 30
; 30. Response to setup message . . . . . . . . . . . . . . 31
; 31. Operator CANCEL command . . . . . . . . . . . . . . . 32
; 32. Operator STOP command . . . . . . . . . . . . . . . . 33
; 33. Operator CONTINUE command . . . . . . . . . . . . . . 33
; 34. Operator RESPONSE command . . . . . . . . . . . . . . 33
; 35. Operator REQUEUE command . . . . . . . . . . . . . . . 34
; 36. CLRMSG and SNDQSR routines . . . . . . . . . . . . . . 35
; 37. FRMLEX - Forms limit exceeded routine . . . . . . . . 36
; 38. Accounting routines . . . . . . . . . . . . . . . . . 37
; 39. FORMS - Setup Forms for a job . . . . . . . . . . . . 40
; 40. Forms switch Subroutines . . . . . . . . . . . . . . . 44
; 41. Plotter only switches . . . . . . . . . . . . . . . . 45
; 42. I/O Subroutines for SPFORM.INI . . . . . . . . . . . . 46
; 43. INPOPN - Routine to open the input file . . . . . . . 48
; 44. INPBUF - Read a buffer from the input file . . . . . . 49
; 45. INPBYT - Read a byte from the input file . . . . . . . 49
; 46. INPERR - Handle an input failure . . . . . . . . . . . 49
; 47. INPFEF - Force end-of-file on next input . . . . . . . 49
; 48. INPREW - Rewind the input file . . . . . . . . . . . . 49
; 49. OUTGET - OPEN the output device . . . . . . . . . . . 49
; 50. OUTBYT - Deposit a byte in the output buffer . . . . . 53
; 51. OUTOUT - Routine to output a buffer . . . . . . . . . 53
; 52. DEVERR - Handle Output Device Errors . . . . . . . . . 55
; 53. OUTREL - Release output device . . . . . . . . . . . . 56
; 54. OUTWON - Wait for on-line . . . . . . . . . . . . . . 57
; 55. OUTFLS Routine to flush output buffers . . . . . . . . 58
; 56. TTY I/O
; 56.1 Input character from TTY, no wait . . . . . . 59
; 56.2 Input character, wait up to 30 seconds . . . . 60
; 57. Card punch service
; 57.1 Dispatch table . . . . . . . . . . . . . . . . 61
; 57.2 Checkpoint text generation . . . . . . . . . . 62
; 57.3 File processing . . . . . . . . . . . . . . . 63
; 57.4 File headers . . . . . . . . . . . . . . . . . 69
; 57.5 File trailers . . . . . . . . . . . . . . . . 70
; 57.6 Banners . . . . . . . . . . . . . . . . . . . 71
; 57.7 Word punching . . . . . . . . . . . . . . . . 72
; 57.8 Letters . . . . . . . . . . . . . . . . . . . 73
; 57.9 Byte output . . . . . . . . . . . . . . . . . 74
; 58. Plotter service
; 58.1 Dispatch table . . . . . . . . . . . . . . . . 75
; 58.2 Checkpoint text generation . . . . . . . . . . 76
; 58.3 File processing . . . . . . . . . . . . . . . 77
; 58.4 Expand CSM's compressed plot format . . . . . 79
; 58.5 READ36, OPRTXT, PAUSEP, TITLE for TOLP . . . . 81
; 58.6 NEWPEN for 3-pen plotter . . . . . . . . . . . 82
; 58.7 DEVOUT output errors . . . . . . . . . . . . . 83
; 58.8 Banners . . . . . . . . . . . . . . . . . . . 84
; 58.9 File headers . . . . . . . . . . . . . . . . . 85
; 58.10 File trailers . . . . . . . . . . . . . . . . 86
; 58.11 Job trailers . . . . . . . . . . . . . . . . . 87
; 58.12 Solid lines . . . . . . . . . . . . . . . . . 88
; 58.13 Dashed lines . . . . . . . . . . . . . . . . . 89
; 58.14 Job information plotting . . . . . . . . . . . 90
; 58.15 Alignment and testing . . . . . . . . . . . . 91
; 58.16 Pen calibration . . . . . . . . . . . . . . . 92
; 58.17 Compute character size . . . . . . . . . . . . 93
; 58.18 Letters . . . . . . . . . . . . . . . . . . . 94
; 58.19 Line segments . . . . . . . . . . . . . . . . 95
; 58.20 PTC-6 interface . . . . . . . . . . . . . . . 97
; 58.21 Rotation and XY20 translation . . . . . . . . 98
; 58.22 Pen movement generation . . . . . . . . . . . 99
; 58.23 Character set . . . . . . . . . . . . . . . . 101
; 59. Paper tape punch service
; 59.1 Dispatch table . . . . . . . . . . . . . . . . 106
; 59.2 Checkpoint text generation . . . . . . . . . . 107
; 59.3 File processing . . . . . . . . . . . . . . . 108
; 59.4 Banners . . . . . . . . . . . . . . . . . . . 113
; 59.5 File headers . . . . . . . . . . . . . . . . . 114
; 59.6 File trailers . . . . . . . . . . . . . . . . 115
; 59.7 Trailers . . . . . . . . . . . . . . . . . . . 116
; 59.8 Blank folds . . . . . . . . . . . . . . . . . 117
; 59.9 Letters . . . . . . . . . . . . . . . . . . . 118
; 59.10 Byte output . . . . . . . . . . . . . . . . . 119
; 60. Character Bit Array for 5 X 7 Character Matrix . . . . 120
; 61. Common Utilities . . . . . . . . . . . . . . . . . . . 122
; 62. Interrupt Module . . . . . . . . . . . . . . . . . . . 124
; 63. IPCF and DEVICE Interrupt service for TOPS10 . . . . . 128
; 64. IPCF and DEVICE interrupt service for TOPS20 . . . . . 129
SUBTTL Revision History
Comment\
2000 First GALAXY-10 Field-Test release, June, 1975.
2100 Make this version 2, August, 1976.
First field-test release of GALAXY release 2, Jan 1977
2400 MAKE THIS VERSION 4, APRIL 1977.
(NOTE: RELEASE 3 OF GALAXY WAS TOPS20 ONLY AND DID NOT INCLUDE SPROUT)
INSERT CHANGES FOR NEW FP/FD.
2401 START CONVERTING TO USE GLXLIB INSTEAD OF CSP??? AND SBS???.
2402 FIX UP AC CONVENTIONS TO BE COMPATIBLE WITH GLXLIB.
2403 MAKE SPROUT INTO A SINGLE SEGMENT AND DO A CODE CLEANUP.
2404 START MERGING IN GLXFIL USAGE FOR THE INPUT FILE.
2405 MORE OF 2404 AND START REPLACING LUUOS WITH $TEXTS.
2406 MAKE MORE USE OF $TEXT.
2407 MANY MINOR BUG FIXES AND CHANGES.
2410 SOME MAJOR CODE CLEANUP.
2411 START MAJOR RE-WORK OF SPROUT TO MAKE MORE USE OF GLXLIB AND TO
TALK WITH THE NEW OPERATOR INTERFACE.
2412 CHANGE IMAGE MODE ON THE CDP TO IGNORE EACH 81ST BYTE READ
FROM DISK SO THAT IT IS COMPATIBLE WITH SPRINT AND PIP.
2413 DONT ENFORCE LIMITS ON PTP AND PLT SINCE THE LIMITS ARE DIRECTLY
DERIVABLE FROM THE FILE-SIZE.
2414 DO SOME CODE CLEANUP.
2415 Code Cleanup and add plotter and card letter routines
2416 Added Forms processing for SPFORM.INI File
2417 Added MSGFLG and Changed interrupt and Scheduling code
to set/check msgflg for IPCF messages
2420 Added code to check length of message for DEP6BP and DEPBP
2421 Removed msgflg (twas a bad idea)
2422 Fixed OUTOUT and DEVERR for TOPS10
2423 Fixed ACTION operator message processing
2424 Fixed Offline device interrupt code
2425 Updated to new library and message formats
2426 Added preliminary accounting parameters
Added two pass scheduling algorithm to allow mulitple
devices to operate in parallel on TOPS20
2427 Fixed bug in INPOPN regarding access checks
Moved impure interrupt stuff to impure storage
Added call to I%HOST to get local node name
2430 Changed all message processing to use ac M
Changed scheduling loop to WAIT instead of SLEEP
when no jobs are scheduable
2431 Added correct mulitple stream runtime accounting code
2432 Put IB.PRG back into IB
2433 add Mount Bypass
2434 Add WTOR kill code (AWC)
2435 Fix a $TEXT bug - IQN Stopcode (AWC)
2436 Put in Null routines for TOPS10 accounting
2437 Fix Plotter Banner Header and Trailer code
2440 Add plotter limit check code
2441 MAKE 8 BIT PAPER TAPE OUTPUT BYTE SIZE
2442 Add usage accounting for TOPS-10 (DPM)
2443 Use new feature IB.DET to detach from FRCLIN (DPM)
2444 Delete IB.DET (GLXLIB defaults to detach)
2445 Change reference of symbol z to ZZ [QAR 10-04715]
2446 Add missing (S2) in DVINTR rouine [QAR 10-4903]
2447 Close SPFORM.INI before returning from FRMSWI [QAR 10-4855]
2450 Call OUTOUT after outputing trailers (SPR 20-14682)
Make # chars per fanfold 85 not 90 (SPR 20-14680)
Fix spelling error & FRMFD length error (SPR 20-14911)
2451 Get the correct owners name based on type of system.
2452 Fix OUTOUT so we don't loose output done interrupts
2453 Adjust J$XPOS and J$YPOS before clipping output per limits
2454 Always call file trailer routine during file processing
2455 Add support for /DISP:RENAME
2456 Account for X plotter usage
2457 Compute minimum character size (YMAX-YMIN)/90
2460 Have SPROUT generate own checkpoints
2461 Make cryptic error messages more explicit.
2462 Position pen at EOF before printing error message. General
cleanup of job/file headers and trailers.
2463 Add missing entries in PLT dispatch table for /TAPE:BINARY.
2464 Add accounting support for the plotter.
2465 Don't do things like JRST .+3
2466 Remove edit 2456. Plotter usage is accounted for in minites, not
amount of paper.
2467 Clear up /BANNER/HEADER/TRAILER problems with plotter. Edit 2457
made the switch arguments nearly useless. Don't allow arguments
for the plotter.
2470 SPFORM.INI switch arguments were sometimes stored in half-words,
and later full-word multiplies were done. That produces strange
results in banners, headers and trailers.
2471 Remove /GUIDE, /ORIGIN and /SIZE switches from SPFORM.INI since
they didn't work and it was unclear how they should work. Replace
the "+" guide marks with a line across the paper. Always ram the
pen into the stops prior to starting a new job instead of setting
the origin where ever the operator left the pen.
2472 Remove SPFORM.INI switch defaulting since it could never work
correctly for all switches all the time (some switches take
multiple arguments).
2473 Remove TOPS-20 fork code since it never worked & will never be made to.
2474 Fix limit clipping so plots don't overwrite banners and trailers.
2475 If we get an I/O error on the plotter, complain but continue the
job, since plotters aren't supposed to get output errors.
2476 Always clear PSF%DO (device off-line bit) when the operator issues
a continue command. This can't hurt anything and will be a win while
driving a PTP. The PTP gives only off-line interrupts, but no on-line
interrupts.
2477 Add PTP accounting and fix up checkpoint messages a bit.
2500 Insure plotter trailers won't clip.
2501 Fix PTP banners, header and trailers so characters don't get mangled.
2502 Process /BANNER, /HEADER and /TRAILER switches for all devices like
it is done for PLTs. Also, add NOTE:foo to CDP and PTP banners since
they tell me it's documented that way.
2503 Fix problem with J$XLIM growing with every plot done.
2504 Use symbol FTFACT from GALGEN dialogue and remove references to FTOACT.
2505 Fix up CDP headers and trailers.
2506 Do both a status update and a checkpoint prior to asking about
limit exceeded action.
2507 Don't call EOF routines twice. Remove extra call at FILE.2+ a few.
2510 Clean up /NOTE switch processing a bit.
2511 Fix bug in PTPBYT that caused S1 and S2 to get trashed.
2512 Default /SPU value to 1 if not set in SPFORM.INI
2513 Make sure T1 is set up before calling BLKFLD to punch blank folds
off paper tape.
2514 Correct the calculation of the number of minutes of plotting time.
2515 Fix compiler errors on TOPS20 by putting TOPS10 refs under conditional
2516 Store sixbit device name on TOPS-20 so accounting doesn't get
screwed up. Also accumulate the number of feet plotted. Clean up
other assorted accounting bugs.
2517 Clean up TOPS-20 card banners, headers and trailers.
2520 Zap output buffer after doing SOUT.
2521 Clarify $WTOR responses as 'ABORT' or 'PROCEED' only.
2522 Fix UP-DOWN RIGHT-LEFT confusion. QAR 10-06785
2523 Add file name info to Cannot Access File message QAR 10-06759
2524 Correct checking for a null /NOTE switch.
Terminate job banner text properly.
Terminate note text with a NUL when processing job banners.
Requeue reason text may never gets to the error buffer. Fix it.
2525 Fix logic bug in SPFORM.INI parsing.
2526 Fix some bad error messages.
GCO: 1298
2527 Remove two extraneous intructions at the end of routine P$CHKS.
GCO: 1319
2530 Fix a bug that would not allow plots to be output if
/HEADER was not specified.
GCO: 1320
2531 Several very trivial fixes which don't really deserve seperate
edit numbers.
1) Put OUTSOK under TOPS-20 conditional since it's only needed for
that system.
2) Remove some extraneous symbols: J$FMSP, FOB. Put
FILNAM under TOPS20 conditional.
3) Fix OUTOUT on the -10 to not save S1/S2 if it is called from
itself.
GCO: 1341
2532 Fix a bug that keeps the last buffer from being output
to the plotter. It may be an obscure monitor bug that has
to be worked around.
;BEGIN CODE MEINTENANCE
2533 Fix bug in FILDIS. The /DELETE switch was improperly processed,
when the job was ABORTED by OPR, the file was deleted.
SPR 20-17944/CTK 1-MAR-83
End of revision history
\
PAGE
SUBTTL CSM Revision History
;
; Edit Date Who Description
;====== ========= === ===========
;
;CSM01$ 14-Nov-80 JMS Plotter has 3 pens and an ON-LINE indicator. Add
; routines to change pens and proper positioning after
; the plot. Make sure the plotter is on-line at OUTOUT.
CSMEDT 01 ;Show value of CSM01$
INCS=<CSM01$> ;400 increments per inch = 620 octal
IFN CSM01$,<ND CKPTIM,^D60> ;Checkpoint every minute.
;
;CSM02$ 14-Nov-80 JMS Use the compressed plot file format as defined
; in PLOT.REL (from CSM's FORLIB). Instead of one
; byte per increment, most halfwords in the file
; contains 9-bits of delta-X and 9 of delta-Y.
; Use TOLP.REL to translate the disk file back
; into calls to subroutine PLOT.
CSMEDT 02 ;Show value of CSM02$
IFN CSM02$,<IFE CSM01$,<PRINTX ?Must have CSM01$ on for CSM02$>>
;
;CSM03$ 14-Nov-80 JMS Change the plot banner to exercise the red and
; black pens. Plot error message even if no
; /TRAILER and set blue pen at P$EOF.
CSMEDT 03 ;Show value of CSM03$
;
;CSM04$ 25-Mar-81 JMS Put the forms name in place of DISK-WRITES,
; amount of paper in PAGES-PRINTED, cards, feet,
; or plot time in DISK-READS.
CSMEDT 04 ;Show value of CSM04$
;
;CSM05$ 8-Jan-81 JMS Add a sleep request to $DSCHD. RH of flags is
; number of seconds to wait. This is needed for
; non-blocking TTY I/O routines.
CSMEDT 05 ;Show value of CSM05$
;
;CSM06$ 8-Jan-81 JMS Add support for the TAB Products Card Terminal.
; It is a Reader/Punch that acts like a TTY.
CSMEDT 06 ;Show baud rate (^D1200=^O2260)
IFN CSM06$,<IFE CSM05$,<PRINTX ?Must have CSM05$ on for CSM06$>>
;
;CSM07$ 8-Mar-83 JMS Remove DSPMOD so that cards are punched in ASCII,
; paper tape is punched in ASCII, and plots are
; done in 18-bit BINARY mode unless explicitly
; requested otherwise. This is so that output
; from SOS or SED is not punched in image-binary.
; Remove "BEGIN:", "JOB", "jobnam", "USER:" from
; card punch banner, ignore QUEUE's default of
; /NOHEADER and always punch file header on cards.
CSMEDT 07 ;Show value of CSM07$
;
;CSM08$ 28-Jun-83 JMS Add support for the Houston Instruments PTC-6
; Plotter Terminal Controller on a TTY line.
CSMEDT 08 ;Show value of CSM08$
IFN CSM08$,< EXTERN PTCINI,PTCMOV,PTCOUT,PTCFIN
IFE CSM05$,<PRINTX ?Must have CSM05$ on for CSM08$>>
;
CSMED$==10 ;Increment this to change .JBVER
;End of CSM Revision History
SUBTTL Constants (Conditional and Unconditional)
;ACCUMULATORS
M==12 ;MESSAGE ADDRESS
S==13 ;STATUS FLAGS
J==14 ;BASE ADDRESS OF CONTEXT DATA
C==15 ;I/O CHARACTER
E==16 ;POINTER TO CURRENT FP
;SYSTEM DEPENDENT PARAMETERS
DEFINE FACT,<IFN FTFACT>
SYSPRM PTPBSZ,^D36,^D8 ;OUTPUT BYTESIZE FOR PTP
;RANDOM CONSTANTS
ND PDSIZE,100 ;SIZE OF PUSHDOWN LIST
ND FACTSW,-1 ;-1 TO INCLUDE ACCOUNTING
ND NSTRMS,5 ;NUMBER OF STREAMS
ND ACCTSW,1 ;TURN ACCOUNTING ON/OFF
ND TXT$LN,^D50 ;LENGTH OF JOB TEXT BUFFER
ND ERR$LN,^D20 ;LENGTH OF JOB ERROR TEXT BUFFER
ND NBFRS,2 ;NUMBER OF BUFFERS TO CREATE
ND NJBPGS,3 ;NUMBER OF JOB PAGES TO CREATE
ND CKPTIM,^D120 ;# of seconds between chkpnts
XP MSBSIZ,50 ;SIZE OF A MESSAGE BLOCK
;CHECKPOINT BLOCK OFFSETS
XP CKFIL,0 ;NUMBER OF FILES COMPLETED
XP CKCOP,1 ;NUMBER OF COPIES COMPLETED
XP CKPAG,2 ;NUMBER OF UNITS OF LAST COPY
XP CKTPP,3 ;NUMBER OF TOTAL UNITS processed
XP CKFLG,4 ;CHECKPOINT FLAGS
XP CKFREQ,1B0 ;REQUED BY OPERATOR
XP CKFCHK,1B1 ;JOB WAS CHECKPOINTED
;DEVICE DISPATCH TABLE OFFSETS
XP DHEAD,0 ;ADDRESS OF FILE HEADER ROUTINE
XP DTAIL,1 ;ADDRESS OF FILE TRAILER (EOF) ROUTINE
XP DNAME,2 ;DEVICE GENERIC NAME IN 6BIT
XP DBYTE,3 ;OUTPUT BYTE SIZE
XP DPROC,4 ;ADDRESS OF FILE processing ROUTINE
XP DBANN,5 ;ADDRESS OF JOB BANNER ROUTINE
XP DEOJ,6 ;ADDRESS OF JOB TRAILER (EOJ) ROUTINE
XP DLETR,7 ;ADDRESS OF CHARACTER processing ROUTINE
XP DERR,10 ;ADDRESS OF ERROR HANDLER
XP DACCT,11 ;ADDRESS OF END ACCOUTING ROUTINE
XP DCHKP,12 ;ADDRESS OF CHECKPOINT TEXT ROUTINE
CONT. (Constants) ;FORCE NEW LISTING PAGE
; Card punch constants
;
XP CPC,^D80 ;CHARACTERS PER CARD
; Plotter constants
;
COMMENT ~
From the OPERATOR's point of view, the supply spool on the plotter is
above the pen holder, and the takeup spool is below the pen holder.
Therefore, to move the pen in the +Y direction, the pen holder moves to
the left. To move the pen in the +X direction, the pen stays still and
the paper is moved down (towards the takeup spool). The following
definitions are based on this point of view.
;End of COMMENT ~
XP PNUP,40 ;RAISE PEN
XP PNDN,20 ;LOWER PEN
XP PEN2,14 ;SELECT PEN 2
XP PEN3,03 ;SELECT PEN 3
XP CNGP,17 ;CHANGE PENS
XP XYU,10 ;-X move the paper up
XP XYD,4 ;+X move the paper down
XP XYL,2 ;+Y move pen holder left
XP XYR,1 ;-Y move pen holder right
PLUSX== XYD ;[CSM] ;Move in positive X direction 0
PLUSY== XYL ;[CSM] ;Move in positive Y direction 90
MINUSX==XYU ;[CSM] ;Move in negative X direction 180
MINUSY==XYR ;[CSM] ;Move in negative Y direction 270
XP XYUL,XYL!XYU ;-X+Y MOVE UP+LEFT
XP XYDL,XYL!XYD ;+X+Y MOVE DOWN+LEFT
XP XYUR,XYR!XYU ;-X-Y MOVE UP+RIGHT
XP XYDR,XYR!XYD ;+X-Y MOVE DOWN+RIGHT
CSMEDT 01,0 ;3-pen plotter, definitions
IFE CSM01$,<XP PLTPEN,^D9> ;# TICS FOR PLOT PEN UP/DOWN
IFN CSM01$,<XP PLTPEN,^D<1800*30/1000> ;30 millisec compared to 1800 per second
XP PLTMOV,1 ;# TICS FOR PEN MOVEMENT
XP CHRPLN,^D90 ;# CHARACTERS PER LINE MAXIMUM
; Paper tape punch constants
;
XP CHPFLD,^D85 ;CHARACTERS PER FOLD OF PTP
XP FRMPFT,^D120 ;FRAMES PER FOOT OF TAPE
SUBTTL MACROS
DEFINE LP(SYM,VAL,FLAG),<;;Flag="Z" marks a variable to be zeroed per job
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
IFL 2000-J...X,<PRINTX ?PARAMETER AREA LONGER THAN A PAGE>
LIST
SALL
> ;END IF1
IF2,<
.XCREF
J...X==SYM
.CREF
SYM==J...X>;;END IF2>;;END DEFINE LP
;[CSM] Removed 2 CRLFs so that MACRO will show value in listing
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
;Format of SYS:SPFORM.INI
; DEV FORM/SWITCH This line applies to all devices of this type
; DEV FORM:ALL/SWITCH This line applies to all devices of this type
; DEV FORM:LOC/SWITCH This line applies to devices at the central site
; DEV FORM:REM/SWITCH This line applies to devices on remote nodes
; "DEV" can be one of PLT, CDP, or PTP
; "FORM" is the name of the forms type, 6 characters or less
;Note: SPROUT will use the first entry which meets the location
; specification for its device. Therefore, if ALL is used with
; LOC or REM, ALL should be after the LOC or the REM.
;Switches legal for all devices
; /BANNER Output the job header
; /HEADER Output file headers
; /TRAILER Output the job trailer
; /NOTE:AA Type NOTE to the OPR when forms are mounted
;Switches legal for plotters only
; /SPU:NN Steps per unit (a factor of all XX and YY)
; /SPS:NN Steps per second (for calculating run time)
; /MAXIMUM:XX:YY Maximum pen position
; /MINIMUM:XX:YY Minimum pen position after file header
;In the above and below explanations:
; NN is a decimal number
; AA is a string of 1 to 50 characters, terminated by next "/"
; XX is a limit for the X axis
; YY is a limit for the Y axis
;Typical SPFORM.INI forms specification
; CDP NORMAL/BANNER/HEADER -
; /NOTE:Load NORMAL Cards in Card Punch
;
; PLT NORMAL/BANNER/HEADER/TRAILER/SPS:900
; /SPU:1/MINIMUM:0:0/MAXIMUM:0:5900-
; /NOTE:Set Plotter Controls to 200 Steps per inch
;
; PTP NORMAL/BANNER/HEADER/TRAILER
; PTP BLACK /BANNER/HEADER/TRAILER/NOTE:Black oiled paper tape
PAGE
COMMENT | CSM interpretation of plotter parameters
;
Example for a drum plotter:
;
PLT NORMAL /SPS:1800/SPU:4/MINIMUM:0:0/MAXIMUM:0:1100 -
/BANNER/HEADER/TRAILER
;
PLT = This line applies to the plotter (not CDP or PTP).
NORMAL = The forms name.
/SPS:1800 = Do accounting based on speed of 1800 steps per second.
/SPU:4 = This plotter uses 400 steps per inch, the following
numbers are in 1/100ths of an inch.
/MINIMUM:0:0 = Pen cannot go to left or below the starting point.
/MAXIMUM::1100 = There is no maximum limit in the +X direction, +Y movement
is limited to 11.00 inches. The height of characters used
in the /BANNER/HEADER/TRAILER is 11.00/90 = 0.12 inches.
- = Hypen indicates a continued line.
/BANNER = Plot "* Start job XXX" 0.12 inches high, plot user's name
and PPN 0.36 inches high, and a line across the paper.
/HEADER = Plot file name 0.12 inches high and a dashed line.
/TRAILER = Plot a dashed line and the summary 0.12 inches high.
/NOTE = No note is specified, so that "OPR>START PLOT 0" will
not require a "RESPOND 'PROCEED' WHEN READY".
;
End of COMMENT |
DEFINE SWITCHES,<
FF BANNER
FF TRAILER
FF HEADER
FF NOTE
FF SPS
FF SPU
FF MINIMUM
FF MAXIMUM
>
;GENERATE TABLE OF SWITCH NAMES
DEFINE FF(A),< <<SIXBIT /A/>&777777B17>+S$'A >;;All on 1 line to look nice
XALL ;[CSM] Show definition in the listing
FFNAMS: SWITCHES
F$NSW==.-FFNAMS ;NUMBER OF SWITCHES
SALL ;[CSM] Normal macro expansions
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$RNFP,1,Z ;NUMBER OF FILES processed
LP J$RNCP,1,Z ;NUMBER OF COPIES OF CURRENT FILE
LP J$RNPP,1,Z ;NUMBER OF PAGES IN CURRNET FILE
LP J$RACS,20 ;CONTEXT ACS
LP J$RPDL,PDSIZE ;CONTEXT PUSHDOWN LIST
;DEV PARAMETERS
LP J$LBUF,1 ;ADDRESS OF DEV BUFFER
LP J$LBRH,1 ;BUFFER RING HEADER
LP J$LBPT,1 ;BUFFER BYTE POINTER
LP J$LBCT,1 ;BUFFER BYTE COUNT
LP J$TBCT,1 ;TOTAL BYTE COUNT FOR DEVICE
LP J$LIOA,1 ;-1 IF WE ARE IN A SOUT OR OUT
LP J$LREM,1 ;-1 IF WE ARE A REMOTE DEVICE
LP J$LSER,1 ;ADDRESS OF DEVICE SERVICE DISPATCH
TOPS10 <
LP J$LJFN,1 ;DEV I/O CHANNEL (OR JFN)
LP J$LDEV,1 ;DEVICE NAME (SIXBIT)
LP J$LIOS,2 ;DEVICE STATUS
LP J$LIOE,1 ;-1 IF DEVICE ERROR
> ;END TOPS10 CONDITIONAL
TOPS20 <
LP J$LJFN,1 ;JFN FOR THE DEV
LP J$LDEV,2 ;DEVICE NAME STRING
LP J$LIOS,2 ;DEVICE STATUS
LP J$LIOE,1 ;-1 IF DEVICE ERROR
LP J$LIBP,1 ;INITIAL BYTE POINTER
LP J$LIBC,1 ;INITIAL BYTE COUNT FOR BUFFERS
> ;END TOPS20 CONDITIONAL
;CURRENT FORMS PARAMETERS
LP J$FIFN,1 ;TEMPORARY IFN FOR FORM FILE
LP J$FORM,1 ;CURRENT FORMS TYPE
LP J$FPFM,1 ;PREVIOUS FORMS TYPE
LP J$FPLT,1 ;-1 = Plotter-only switches are legal
;STORAGE FOR CURRENT FORMS SWITCHS
DEFINE FF(X) <LP J$F'X,1>
LP J$FCUR,0 ;ORIGIN OF CURRENT SWITCH VALUES
SWITCHES ;ONE ENTRY PER SWITCH
;MISCELLANY
LP J$XFOB,FOB.SZ ;A FILE OPEN BLOCK
LP J$XTBF,TXT$LN,Z ;$TEXT BUFFER FOR OUTPUT DEVICE
LP J$XERR,ERR$LN,Z ;$TEXT BUFFER FOR ERROR MESSAGES
;CARD PUNCH VARIABLES
LP J$XCD1,1 ;1 SCRATCH LOCATION FOR CDP OUTPUT
LP J$CMSK,1 ;SPECIAL MASK FOR BLOCK CARD LETTERS
LP J$XCHB,40 ;CHECKSUM BLOCK
CSMEDT 05,1 ;TTY I/O and SLEEP, part 1 just before PLOTTER VARIABLES
IFN CSM05$,< ;Flags and variables
LP J$TTY,1 ;'CDP' in LH, UDX in RH
LP J$WUDT,1 ;UDT when to wakeup
LP J$NACK,1 ;Count of Negative ACKs
> ;End of IFN CSM05$
;PLOTTER VARIABLES
;[CSM] LP J$PAUS,1 ;PAUSE FOR EVERY FORM
LP J$XPOS,1 ;CURRENT PLOTTER X COORDINATE
LP J$XORG,1 ;ORIGINAL X MINIMUM
LP J$XLIM,1,Z ;HIGHEST XSTEP SEEN THIS PLOT
LP J$XMIN,1 ;X MINIMUM POINT IN FORM
LP J$XMAX,1 ;X MAXIMUM POINT IN FORM
LP J$YPOS,1 ;CURRENT PLOTTER Y COORDINATE
LP J$YLIM,1 ;HIGHEST YSTEP SEEN THIS PLOT
LP J$YMIN,1 ;MINIMUM Y POINT IN FORM
LP J$YMAX,1 ;MAXIMUM ALLOWABLE Y COORDINATE
LP J$ROTA,1 ;GRID ROTATION (0-3)
LP J$PPOS,1 ;PEN POSITION (UP 0 DOWN -1)
LP J$CSIZ,1 ;CHARACTER SIZE
LP J$XBAS,1 ;CHARACTER X BASE
LP J$YBAS,1 ;CHARACTER Y BASE
LP J$FUDG,1 ;CHARACTER WIDTH FUDG
LP J$SPTR,1 ;POINTER TO CHARACTER SEGMENT BYTES
LP J$STEP,1 ;STEP FUNCTION DETERMINES MOVEMENT
CSMEDT 01,1 ;3-Pen plotter, part 1 in "PLOTTER VARIABLES"
IFN CSM01$,< ;Flags and variables for plotter
LP J$PENN,1 ;Pen number, from 1 to 3
LP J$XLOW,1 ;Lowest XSTEP seen while pen was down
> ;End of IFN CSM01$
; Paper tape punch variables
;
LP J$TFRM,1,Z ;FRAMES OF TAPE PUNCHED
;ACCOUNTING BLOCK
LP J$PTPM,1 ;PLOTTER TICS PER MINUTE
LP J$PTIC,1,Z ;ACCOUNTING FOR PLOTTER
LP J$APRT,1,Z ;NUMBER OF PAGES processed
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 processed (FILES*COPIES)
LP J$ADSP,1,Z ;DISPOSITION (SIXBIT)
LP J$AQUE,1,Z ;QUEUE NAME (SIXBIT)
;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 ;BUFFER BYTE COUNT
LP J$DBSZ,1 ;INPUT BYTE SIZE
LP J$DMOD,1 ;I/O MODE OF DISK FILE
LP J$DSPN,1 ;SPOOLED FILE NAME IF ANY
LP J$DSPX,1 ;SPOOLED FILE EXTENSION
LP J$$END,1 ;END OF PARAMETER AREA
J$$LEN==J$$END ;LENGTH OF PARAMETER AREA
INTERN J$$END ;[CSM] ;For .ASSIGNing data areas
;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
ZZ==0
REPEAT <^D512+^D35>/^D36,<
XLIST
ZTAB(\ZZ)
ZZ==ZZ+1
LIST
> ;END REPEAT
SUBTTL Resident JOB DaTABase
STREAM: BLOCK 1 ;(LH) -1 WHILE IN STREAM CONTEXT
; 0 WHILE IN SCHED CONTEXT
;(RH) CURRENT STREAM NUMBER
JOBPAG: BLOCK NSTRMS ;ADDRESS OF A THREE PAGE BLOCK
; ONE FOR REQUEST, ONE FOR JOB PARAMS, ONE FOR BUFFER
JOBOBA: BLOCK NSTRMS ;TABLE OF OBJECT BLOCK ADDRESSES
JOBSTW: BLOCK NSTRMS ;JOB STATUS WORD
JOBACT: BLOCK NSTRMS ;-1 IF STREAM IS ACTIVE, 0 OTHERWISE
JOBOBJ: BLOCK 3*NSTRMS ;LIST OF SETUP OBJECTS
JOBWAC: BLOCK NSTRMS ;WTOR ACK CODE (TIME SETUP WAS RECIEVED)
JOBCHK: BLOCK NSTRMS ;Stream checkpoint indicator
;Contains the time for the next chkpnt
; or 0 if one is requested
CSMEDT 05,2 ;TTY I/O and SLEEP, part 2 before "LOWEND=="
IFN CSM05$,<
SLEEPT: BLOCK 1 ;Time to sleep
> ;End of IFN CSM05$
LOWEND==.-1
TOPS10 <
VECTOR: BLOCK 0 ;BEGINNING OF INTERRUPT VECTOR
VECIPC: BLOCK 4 ;IPCF INTERRUPT BLOCK
VECDEV: BLOCK 4*NSTRMS ;DEVICE INTERRUPT BLK
ENDVEC==.-1 ;END OF INTERRUPT VECTOR
> ;END TOPS10 CONDITIONAL
TOPS20 <
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
;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%NP==1B5 ;GO TO NEXT PROCESS
DEFINE $DSCHD(FLAGS),<
$CALL DSCHD
XLIST
JUMP [EXP FLAGS]
LIST
SALL
> ;END DEFINE $DSCHD
SUBTTL Program Initialization
SPROUT: JFCL ;NO CCL ENTRY
RESET ;CLEAR ALL ACTIVE I/O
IFN CSM02$,< ;Check to see where LINK .ASSIGNed the buffers
SKIPLE [TOLP..##-1777] ;Make sure data area is only one page
OUTSTR [ASCIZ /?Data area for TOLP extends past 1777/]
> ;End of IFN CSM02$
IFN CSM06$,<
SKIPLE [TABC..##-1777] ;Make sure data area is only one page
OUTSTR [ASCIZ /?Data area for TABCDP extends past 1777/]
> ;End of IFN CSM06$
IFN CSM08$,<
SKIPLE [PTC6..##-1777] ;Make sure data area is only one page
OUTSTR [ASCIZ /?Data area for PTC6 extends past 1777/]
> ;End of IFN CSM08$
MOVE P,[IOWD PDSIZE,PDL]
MOVEI S1,IB.SZ ;GET SIZE OF IB
MOVEI S2,IB ;GET ADDR OF IB
$CALL I%INIT ;START UP THE WORLD
MOVEI S1,<LOWEND-LOWBEG>+1 ;LOAD LENGTH OF RESIDENT IMPURE DATA
MOVEI S2,LOWBEG ;AND ITS ADDRESS
$CALL .ZCHNK ;AND ZERO IT OUT
$CALL INTINI ;INITIALIZE THE INTERRUPT SYSTEM
IFN ACCTSW,<
SETOM ACTFLG ;UNLESS HE DOESN'T WANT IT
PUSHJ P,ACTINI ;SET UP ACCOUNTING DATA
> ;END IFE ACCTSW
TOPS20 <
HRRZI S1,.MSIIC ;BYPASS MOUNTS
MSTR
ERJMP .+1
> ;END TOPS20 CONDITIONAL
$CALL I%ION ;TURN ON INTERRUPTS
MOVEI T1,HELLO ;GET HELLO MESSAGE
$CALL SNDQSR ;SEND IT
TOPS10< MOVSI S1,.STSPL ;PULL A SETUUO TO
SETUUO S1, ; CLEAR ANY SPOOLING BITS
JFCL ;IGNORE THE ERROR
>
$CALL I%HOST ;GET LOCAL HOST STUFF
TOPS10 <MOVEM T2,CNTSTA> ;SAVE NUMBER AS CENTRAL STATION
TOPS20 <MOVEM T1,CNTSTA> ;SAVE NAME AS CENTRAL STATION
JRST MAIN ;AND GO!
SUBTTL Idle Loop
MAIN: MOVE P,[IOWD PDSIZE,PDL] ;SETUP A NEW PDL
HRROS STREAM ;SET SCHEDULER CONTEXT
$CALL CHKQUE ;PROCESS MESSAGES
MOVX P2,PSF%NP ;GET NEXT PASS FLAG
MAIN.1: MOVSI P1,-NSTRMS ;SET UP DISPATCH AC
MAIN.2: SKIPN JOBACT(P1) ;IS THIS STREAM ACTIVE?
JRST MAIN.3 ;NO,,GET THE NEXT STREAM.
HRROM P1,STREAM ;YES -- SAVE NUMBER (IN SCHED CONTEXT)
MOVE J,JOBPAG(P1) ;GET ADDRESS OF JOB PAGES
PUSHJ P,CHKPNT ;CHECKPOINT JOB IF NECESSARY
CSMEDT 05,2 ;TTY I/O and SLEEP, part 2 at MAIN.2:+5
IFN CSM05$,< ;Watch for sleep time
PUSHJ P,CHKTIM ;Time to run this stream?
JUMPF MAIN.3 ;Not yet
> ;End of IFN CSM05$
SKIPN JOBSTW(P1) ;IS THE STREAM BLOCKED?
JRST MAIN.4 ;NO -- SETUP STREAM CONTEXT
MAIN.3: ANDCAM P2,JOBSTW(P1) ;CLEAR NEXT PASS BIT
AOBJN P1,MAIN.2 ;TRY NEXT STREAM
TXZE P2,PSF%NP ;ON SECOND PASS?
JRST MAIN.1 ;NOT YET..TRY AGAIN
;HERE IF NO STREAM IS RUNNABLE
IFE CSM05$,< MOVEI S1,0 > ;SNOOZE FOR INTERRUPT
IFN CSM05$,< MOVE S1,SLEEPT > ;Get sleep time in seconds
$CALL I%SLP ;GO WAIT
$CALL CHKQUE ;PROCESS MESSAGES
IFN CSM05$,< SETZM SLEEPT > ;Clear timer request
JRST MAIN.1 ;AND TRY AGAIN
MAIN.4: CAME J,ACTPAG ;SAME STREAM?
$CALL ACTRNT ;NO..INIT RUNTIME VALUES
MOVEM J,ACTPAG ;SAVE THIS AS ACCOUNTING PAGE
HRLZI 0,J$RACS+1(J) ;SET UP STREAM CONTEXT BLT
HRRI 0,1 ;START WITH AC 1
BLT 0,17 ;RESTORE THE ACS
HRRZS STREAM ;SET STREAM CONTEXT
POPJ P, ;AND RESTORE STREAM PC
;NOTE: Stream is now active and will return via DSCHD (see next page)
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: HRROS STREAM ;SET SCHED CONTEXT
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 STREAM ACS
HRRZ S1,0(P) ;GET ADDRESS OF "JUMP [FLAGS]"
CSMEDT 05,2 ;TTY I/O and SLEEP, part 2 at DSCHD:+6
IFE CSM05$,< MOVE S1,@0(S1) > ;GET THE FLAGS
IFN CSM05$,<
HRRZ T1,@0(S1) ;Get the seconds to sleep
HLLZ S1,@0(S1) ;Get the flags
> ;End of IFN CSM05$
HRRZ S2,STREAM ;GET STREAM NUMBER
IORM S1,JOBSTW(S2) ;SET THE FLAGS
IFE CSM05$,< JRST MAIN > ;AND GO LOOP
IFN CSM05$,< ;This code taken from LPTSPL
JUMPE T1,MAIN ;Loop if no sleep time
CONT. (SCHEDULER)
SKIPE SLEEPT ;Is a sleep time set?
CAMG T1,SLEEPT ;And current amount smaller?
MOVEM T1,SLEEPT ;Yes, save shorter interval
$CALL I%NOW ;Get the current time
IMULI T1,3 ;Seconds to UDT ticks
ADD T1,S1 ;Build wake-up time
MOVEM T1,J$WUDT(J) ;Save for CHKTIM
JRST MAIN ;Loop
SUBTTL CHKTIM - Routine to see if it's time to schedule a stream
;CALL: J/ Pointer to job page
;
;REG: TRUE if stream can be scheduled now (timewise)
; FALSE if stream needs to wait
CHKTIM: $CALL I%NOW ;Get the current time
MOVE S2,S1 ;Get the UDT in S2
MOVE S1,J$WUDT(J) ;Get the stream wakeup time
SUB S1,S2 ;Get time left in UDT ticks
IDIVI S1,3 ;Convert to seconds
SKIPG S1 ;Any seconds left?
JRST [SETZM SLEEPT ;No, clear old sleep time
$RETT ] ;Return TRUE
SKIPE SLEEPT ;Is a sleep time set?
CAMG S1,SLEEPT ;And current amount smaller?
MOVEM S1,SLEEPT ;Yes, save the shorter interval
$RETF ;Return FALSE
;End of code taken from LPTSPL> ;End of IFN CSM05$
SUBTTL SETUP/SHUTDOWN Message
SETUP: LOAD S2,SUP.FL(M) ;GET THE FLAGS
TXNE S2,SUFSHT ;IS IT A SHUTDOWN?
JRST [MOVEI S1,SUP.TY(M) ;GET OBJECT ADDRESS
$CALL FNDOBJ ;FIND IT
JRST SHUTDN] ;AND SHUT IT DOWN
SETZ T2, ;CLEAR A LOOP REG
SETU.1: SKIPN JOBPAG(T2) ;A FREE STREAM?
JRST SETU.2 ;YES!
CAIGE T2,NSTRMS-1 ;NO, LOOP THRU THEM ALL?
AOJA T2,SETU.1 ;NO, KEEP GOING
$STOP(TMS,Too many setups)
;[CSM] There is a problem if two streams start with 1/3 of a second
SETU.2: HRRZM T2,STREAM ;SAVE THE STREAM NUMBER
$CALL I%NOW ;USE SETUP TIME AS ACK STAMP
LSH S1,3 ;[CSM] ;Free up 3 bits
IOR S1,T2 ;[CSM] ;Make it be unique
MOVEM S1,JOBWAC(T2) ;SAVE CODE FOR $WTOR
MOVEI S1,NJBPGS ;NUMBER OF PAGES NEEDED
$CALL M%AQNP ;GET THEM
PG2ADR S1 ;CONVERT TO AN ADDRESS
MOVEM S1,JOBPAG(T2) ;AND SAVE IT
MOVE J,S1 ;PUT IT IN J
MOVEM J,J$RACS+J(J) ;SAVE J AWAY
MOVEI S1,2000(J) ;DEV BUFFER ADDRESS
MOVEM S1,J$LBUF(J) ;STORE IT
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
$CALL OUTGET ;GET THE OUTPUT DEVICE
$CALL RSETUP ;SEND RESPONSE TO SETUP
HRRZ S2,STREAM ;GET OUR STREAM NUMBER
$WTO (^T/@SETMSG(S1)/,,@JOBOBA(S2)) ;TELL THE OPERATOR
CAIN S1,%RSUOK ;ALL IS OK?
$RETT ;YES, RETURN
JRST SHUTDN ;NO, SHUT IT DOWN
SETMSG: [ASCIZ /Started/]
[ASCIZ /Not available right now/]
[ASCIZ /Does not exist/]
ACTBEG: SKIPN ACTFLG ;ACCOUNTING?
$RETT ;NO..JUST RETURN
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
MOVE S1,J$LSER(J) ;GET DISPATCH ADDRESS
MOVE S1,DNAME(S1) ;GET DEVICE (QUEUE) NAME
MOVEM S1,J$AQUE(J) ;SAVE FOR ACT END
SETZM J$PTIC(J) ;CLEAR PLOTTER ACCOUNTING
$RETT ;RETURN
ACTEND: 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
MOVE S1,J$LSER(J) ;GET DISPATCH ADDRESS
PUSHJ P,DACCT(S1) ;DO FINAL ACCOUNTING
MOVX S2,'NORMAL' ;ASSUME NORMAL DISPOSITION
TXNE S,RQB ;REQUED?
MOVX S2,'REQUED' ;YES
TXNE S,ABORT ;ABORTED?
MOVX S2,'CANCEL'
MOVEM S2,J$ADSP(J) ;STORE DISPOSITION
$CALL ACTRNT ;DO FINAL RUNTIME ACCOUTING
SETZM ACTPAG ;CLEAR THE PAGE ADDRESS
TOPS10< MOVE S1,[.NDRNN,,S2] ;GET CONVERT TO NAME FCT CODE
MOVEI S2,2 ;A BLOCK LENGTH OF 2
MOVE T1,.EQROB+.ROBND(J) ;GET THE NODE NUMBER
CONT. (ACTEND)
FACT< HRLZM T1,FACTBL+3 > ;STORE NODE NUMBER NOW
NODE. S1, ;CONVERT IT
SKIPA ;SKIP ON AN ERROR
MOVEM S1,.EQROB+.ROBND(J) ;SAVE THE NODE NAME
MOVX S1,<ACTLEN,,ACTLST> ;SET UP AC
QUEUE. S1, ;MAKE A USAGE ENTRY
PUSHJ P,ACTE.1 ;FAILED,,TELL OPR
FACT< MOVE S1,L.LIN ;GET LINE NUMBER
LDB S2,[POINT 7,L.TTY,6] ;GET TERMINAL DESIGNATOR
CAIN S2,"C" ;ON THE CTY
MOVEI S1,7777 ;YES, CTY DESIGNATOR
CAIN S2,"D" ;DETACHED
MOVEI S1,7776 ;YES, FLAG THAT INSTEAD OF LINE NUMBER
LSH S1,6 ;PUT IN BITS 18-29
HRL S1,L.JOB ;INSERT JOB NUMBER
IOR S1,[251000,,13] ;ADD FACT TYPE AND NUMBER OF WORDS
MOVEM S1,FACTBL+0 ;STORE IN BLOCK
MOVE S1,.EQOID(J) ;GET PPN
MOVEM S1,FACTBL+1 ;STORE
SETZM FACTBL+2 ;DAEMON FILLS IN THE DATE/TIME
MOVE S1,[%CNSER] ;CPU SERIAL NUMBER
GETTAB S1, ;ASK FOR IT
SETZ S1, ;USE 0 IF CAN'T FIND IT
HLLZ S2,J$AQUE(J) ;GET QUEUE NAME
TLZ S2,77 ;CLEAR JUNK
IOR S1,S2 ;INSERT QUEUE NAME
IORM S1,FACTBL+3 ;NODE NUMBER ALREADY STORED FROM ABOVE
MOVE S1,J$ARTM(J) ;RUN TIME IN MILLISECONDS
MOVEM S1,FACTBL+4 ;STORE
SETZM FACTBL+5 ;*** CORE TIME INTERGRAL
MOVE S1,J$ADRD(J) ;DISK READS
MOVEM S1,FACTBL+6 ;STORE
CSMEDT 04,1 ;CSM accounting, part 1 after QUEUE. uuo
IFE CSM04$,< SETZM FACTBL+7 > ;No disk writes
IFN CSM04$,<
MOVE S1,J$FORM(J) ;Get the forms type
MOVEM S1,FACTBL+7 ;Instead of disk writes
> ;End of CSM04$
CONT. (ACTEND)
MOVE S1,J$LDEV(J) ;DEVICE NAME
MOVEM S1,FACTBL+10 ;STORE
MOVE S1,J$ASEQ(J) ;SEQUENCE NUMBER
MOVEM S1,FACTBL+11 ;STORE
MOVE S1,J$APRT(J) ;Number of cards, feet, minutes
MOVEM S1,FACTBL+12 ;Store as pages printed
MOVE S1,[14,,FACTBL-1] ;DAEMON ARGUMENT
DAEMON S1, ;MAKE THE FACT ENTRY
JRST ACTE.1 ;REPORT THE FAILURE
> ;END FACT ACCOUNTING
> ;END TOPS10 ACCOUNTING
TOPS20< 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
> ;END OF TOPS-20 CONDITIONAL
$RETT ;RETURN WHEN DONE
ACTE.1: MOVE S1,STREAM ;GET THIS STREAM NUMBER
$WTO (System Accounting Failure,<^R/.EQJBB(J)/>,@JOBOBA(S1))
$RETT ;RETURN
ACTRNT: SKIPN ACTFLG ;Accounting turned on?
$RETT ;No - return
SETO S1, ;-1 Means us
MOVX S2,JI.RTM ;Function code
$CALL I%JINF ;Get our runtime
ADDM S2,ACTRNN ;Store accumulated time
MOVNS S2 ;Negate actual runtime
EXCH S2,ACTRNN ;INIT FOR NEXT PASS
SKIPE S1,ACTPAG ;GET LAST PROCESSES PAGE ADDRESS
ADDM S2,J$ARTM(S1) ;ACCUMULATE TOTAL
$RETT ;RETURN
SUBTTL FORMS - Setup Forms for a job
FORMS: GETLIM S1,.EQLIM(J),FORM ;GET THE FORMS TYPE
CAMN S1,J$FORM(J) ;EXACTLY THE SAME?
$RETT ;YES, JUST RETURN
MOVE S2,[POINT 7,J$XTBF(J)] ;GET POINTER TO WTOR BUFFER.
MOVEM S2,TEXTBP ;AND SAVE IT FOR DEPBP.
MOVEI S2,TXT$LN*5 ;GET MAXIMUM BYTE COUNT
MOVEM S2,TEXTBC
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: HRLZI S1,J$FCUR(J) ;GET START OF SWITCH STORAGE
HRRI S1,J$FCUR+1(J) ;MAKE BLT POINTER
SETZM J$FCUR(J) ;CLEAR THE FIRST WORD
BLT S1,J$FCUR+F$NSW-1(J) ;CLEAR THE BLOCK
FORM.2: $CALL FRMINI ;READ THE SPFORM.INI FILE.
MOVE S1,TEXTBP ;GET THE WTOR BYTE POINTER.
CAMN S1,[POINT 7,J$XTBF(J)] ;IS THERE A MESSAGE FOR THE OPERATOR?
$RETT ;NO,,RETURN.
IFN CSM02$,< FORM.3: > ;PUSHJ to here to wait for 'PROCEED' in OPRTXT
$TEXT (DEPBP,<Type 'RESPOND ^7/[.CHLAB]/number^7/[.CHRAB]/ PROCEED' when ready^0>)
HRRZ S1,STREAM ;GET STREAM NUMBER
$WTOR (,<^T/J$XTBF(J)/>,@JOBOBA(S1),JOBWAC(S1)) ;SEND THE WTOR.
$DSCHD (PSF%OR) ;WAIT FOR OPERATOR RESPONSE.
$RETT ;RETURN...
SUBTTL Plotter only switches
S$SPS: SKIPN J$FPLT(J) ;IS DEVICE A PLOTTER?
$RETF ;NO
PUSHJ P,FH$DEC ;GET STEPS PER SECOND
MOVEM T1,J$FSPS(J) ;STORE IT
$RETT ;RETURN
S$SPU: SKIPN J$FPLT(J) ;IS DEVICE A PLOTTER?
$RETF ;NO -- ERROR RETURN
$CALL FH$DEC ;GET STEPS PER UNIT
MOVEM T1,J$FSPU(J) ;AND SAVE IT
$RETT
S$MINI: SKIPN J$FPLT(J) ;IS DEVICE A PLOTTER?
$RETF ;NO -- INVALID SWITCH
SETZM J$XORG(J) ;DEFAULT TO ZERO
SETZM J$YMIN(J) ;DITTO
$CALL FH$DEC ;GET DECIMAL INTEGER
MOVEM T1,J$XORG(J) ;STORE X MINIMUM
CAIE C,":" ;IS Y ARGUMENT SPECIFIED?
$RETT ;NO -- RETURN
$CALL FH$DEC ;GET DECIMAL INTEGER
MOVEM T1,J$YMIN(J) ;STORE Y MINIMUM
$RETT ;AND RETURN
S$MAXI: SKIPN J$FPLT(J) ;IS DEVICE A PLOTTER?
$RETF ;NO -- INVALID SWITCH
MOVX T1,.INFIN ;GET A LARGE NUMBER
MOVEM T1,J$XMAX(J) ;DEFAULT
MOVEM T1,J$YMAX(J) ;DITTO
$CALL FH$DEC ;GET DECIMAL INTEGER
SKIPE T1 ;[CSM] ;If not zero,
MOVEM T1,J$XMAX(J) ;STORE X MAXIMUM
CAIE C,":" ;IS Y ARGUMENT SPECIFIED?
$RETT ;NO -- RETURN
$CALL FH$DEC ;GET DECIMAL INTEGER
SKIPE T1 ;[CSM] ;If not zero,
MOVEM T1,J$YMAX(J) ;STORE Y MAXIMUM
$RETT ;AND RETURN
;ROUTINE TO SEARCH FOR EOL IN SPFORM.INI
FH$EOL: $CALL 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: SETZ T1, ;PLACE TO ACCUMULATE RESULT
FH$DE1: $CALL 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,^D10 ;[CSM] ;Shift one decimal 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: HRRZ S1,STREAM ;GET THE STREAM NUMBER
MOVE S1,JOBOBA(S1) ;GET OBJECT BLOCK ADDRESS
MOVE S1,OBJ.TY(S1) ;GET OBJECT TYPE
SETZ S2, ;AND CLEAR AN AC
CAXN S1,.OTPTP ;IS IT A PAPERTAPE PUNCH?
MOVEI S2,T$DISP ;YES!
CAXN S1,.OTCDP ;NO, HOW ABOUT A CARD PUNCH?
MOVEI S2,C$DISP ;WIN!
CAXN S1,.OTPLT ;TRY FOR A PLOTTER
MOVEI S2,P$DISP ;AND GET THE PLOTTER DISPATCH
JUMPE S2,OUTDDE ;DONT KNOW ABOUT IT
MOVEM S2,J$LSER(J) ;SAVE IT
MOVEI S1,J$LDEV(J) ;ADDRESS OF WHERE TO PUT DEVNAM
HRLI S1,(POINT 6,0) ;MAKE IT A BYTE POINTER
MOVEM S1,TEXTBP ;SAVE IT
MOVEI S1,6 ;MAXIMUM CHARACTER COUNT
MOVEM S1,TEXTBC
HRRZ S1,STREAM ;GET THE STREAM NUMBER
MOVE S1,JOBOBA(S1) ;GET OBJECT BLOCK ADDRESS
$TEXT(DEP6BP,<^W3/DNAME(S2)/^O2R0/OBJ.ND(S1)/^O1/OBJ.UN(S1)/^A>)
MOVE T1,J$LDEV(J) ;GET THE DEVICE NAME
DEVNAM T1, ;GET ITS PHYSICAL NAME
JRST OUTDDE ;LOSE?
MOVEM T1,J$LDEV(J) ;AND SAVE IT
MOVX T1,.IOIMG+UU.PHS+UU.AIO ;IMAGE+PHONLY+NBIO
CSMEDT 05,3 ;TTY I/O and SLEEP, part 3 after DEVNAM in OUTGET
IFN CSM05$,< ;Check for devices connected to TTY lines
HLRZ T2,J$LDEV(J) ;Get first part of physical name
CAIE T2,'TTY' ;Is it a terminal?
JRST CSM05Z ;No
MOVE S2,J$LSER(J) ;Get service routine
MOVE S1,DNAME(S2) ;Get 'PLT' or 'CDP'
MOVEM S1,J$TTY(J) ;Put in LH
MOVE T2,J$LDEV(J) ;Get device again
IONDX. T2, ;Get UDX
SETZB T2,J$TTY(J) ;Should never happen
HRRM T2,J$TTY(J) ;Store TTY UDX in RH
CONT. (OUTGET) ;FORCE NEW LISTING PAGE
;Disable free CRLFs every 80 characters and SET TTY NO GAG
MOVX T1,.TONFC+.TOSET ;Change setting to
MOVEI T3,1 ; no free CRLFs
MOVE S1,[3,,T1]
TRMOP. S1, ;SET TTY NO CRLF
JFCL
;*BUG*; MOVX T1,.IOPIM+UU.PHS ;Packed image mode (no echo)
MOVX T1,.IOIMG+UU.PHS+IO.SUP ;Image mode, no echo
HLRZ S1,J$TTY(J) ;Get device type
CAIN S1,'PLT' ;Output to plotter?
MOVX T1,.IOASC+UU.PHS+IO.SUP ;ASCII mode, no echo
CSM05Z: > ;End of IFN CSM05$
MOVE T2,J$LDEV(J) ;OUTPUT DEVICE NAME
MOVSI T3,J$LBRH(J) ;BUFFER HEADER
MOVE S1,STREAM ;GET OUR STREAM NUMBER
MOVEM S1,J$LJFN(J) ;SAVE AS THE STREAM NUMBER
LSH S1,^D23 ;PUT IN THE RIGHT PLACE
IOR S1,[OPEN T1] ;MAKE IT AN INSTRUCTION
XCT S1 ;AND EXECUTE IT
JRST OUTDNA ;LOSE GIVE ERROR
MOVE S1,J$LSER(J) ;GET DEVICE DISPATCH ADDRESS
MOVE S1,DBYTE(S1) ;GET OUTPUT BYTE SIZE
IFN CSM05$,< ;Cannot use 6 bits to PTC-6
HLRZ S2,J$TTY(J) ;Nonzero if TTY as output device
CAIN S2,'PLT' ;Going to the plotter?
MOVEI S1,7 ;Yes, use normal ASCII mode
;SET TTY NO GAG after it has been inited
MOVX T1,.TOSND+.TOSET ;Change setting to
HRRZ T2,J$TTY(J)
MOVEI T3,0 ; no SENDs allowed
MOVE S2,[3,,T1]
SKIPE T2 ;Don't TRMOP. if not a TTY
TRMOP. S2, ;SET TTY GAG
JFCL
> ;End of IFN CSM05$
STORE S1,J$LBRH+1(J),BP.SIZ ;STORE IT
MOVX S1,PSF%OB!PSF%DO ;GET OUTPUT-BLOCKED AND DEVICE OFFLINE
HRRZ S2,STREAM ;AND STREAM NUMBER
ANDCAM S1,JOBSTW(S2) ;AND CLEAR THE CONDITIONS
MOVE T1,J$LJFN(J) ;LOAD CHANNEL NUMBER
WHERE T1, ;GET OUR STATION NUMBER
SETZ T1,
TLZ T1,-1 ;CLEAR STATION FLAGS
CAME T1,CNTSTA ;IS THIS CENTRAL STATION?
SETOM J$LREM(J) ;NO -- SET REMOTE
MOVEI S1,T1 ;LOAD ADDRESS OF ARGBLOCK FOR DEVSIZ
MOVX T1,.IOIMG ;GET IMAGE MODE
MOVE T2,J$LJFN(J) ;GET THE CHANNEL
DEVSIZ S1, ;DO THE DEVSIZ
JRST OUTDNA ;LOSE
MOVEI T1,PAGSIZ ;LOAD PAGE SIZE
IDIVI T1,(S1) ;GET NUMBER OF BUFFER TO CREATE
MOVE S1,J$LBUF(J) ;GET ADDRESS OF BUFFER PAGE
EXCH S1,.JBFF ;SWAP WITH JOBFF
MOVE S2,J$LJFN(J) ;GET CHANEL NUMBER
LSH S2,^D23 ;POSITION IT
IOR S2,[OUTBUF 0(T1)] ;BUILD THE OUTBUF
XCT S2 ;AND DO IT
MOVEM S1,.JBFF ;RESTORE JOBFF
$CALL INTCNL ;CONNECT TO INTERRUPTS
MOVX S1,%RSUOK ;LOAD OK CODE
$RETT ;AND RETURN
> ;END TOPS10 CONDITIONAL
SUBTTL OUTOUT - Routine to output a buffer
TOPS10 <
OUTOUT: $SAVE <S1,S2> ;SAVE SOME ACS
CSMEDT 01,2 ;3-Pen plotter, part 2 at OUTOUT:+1 <TOPS10>
IFN CSM01$,< ;The plotter does not interrupt for off-line or on-line
SKIPE J$FPLT(J) ;Is this going to the plotter?
PUSHJ P,PLTCHK ;Yes, check if it is on-line
> ;End of CSM01$
OUTO.1: MOVE S1,STREAM ;Get our stream number
MOVX S2,PSF%OB ;Assume we are blocked
IORM S2,JOBSTW(S1) ; waiting for output done
MOVE S1,J$LJFN(J) ;GET THE CHANNEL NUMBER
LSH S1,^D23 ;POSITION IT
TLO S1,(OUT 0,0) ;MAKE IT AN OUTPUT UUO
XCT S1 ;AND DO IT
JRST [MOVE S1,STREAM ;We won! Clear blocked bit
ANDCAM S2,JOBSTW(S1) ; so we are runnable
$RETT]
OUTERR: PUSHJ P,OUTSTS ;READ DEVICE STATUS
JUMPT [$DSCHD (0) ;ASSUME OUTPUT BLOCKED
JRST OUTO.1] ;RETRY OUTPUT
$CALL DEVERR ;PROCESS DEVICE ERROR
JUMPT OUTO.1 ;RETRY OUTPUT IF CORRECTED
JRST MAIN ;STREAM IS SHUTDOWN
OUTWAT: $CALL OUTOUT ;OUTPUT THE BUFFER
OUTW.1: $CALL OUTSTS ;GET THE STATUS
TXNN S1,IO.ACT ;DONE?
$RETT ;YES, RETURN
$DSCHD (0) ;FORCE A SCHEDULING RUN
JRST OUTW.1 ;TRY AGAIN
CONT. (OUTOUT)
IFN CSM01$,< ;After OUTWAT: inside TOPS10<>
;Ask the monitor to do a CONI to check if PLT is on-line
OPDEF STSPL. [CALLI -4] ;CSM UUO to do <CONI PLT,T1>
PLT.ON==1B30 ;The plotter power is on
PLTCHK: CSMEDT 08,1 ;PTC-6 Plotter Controller, part 1 inside CSM01$
IFN CSM08$,<
SKIPE J$TTY(J) ;Output going to a TTY?
POPJ P, ;Yes, cannot determine on-line status
> ;End of IFN CSM08$
STSPL. S1, ;Get current status of plotter
TXNE S1,PLT.ON ;Is the POWER-ON bit set?
JRST PLTONL ;Yes, plotter is on-line now
AOS S1,J$NACK(J) ;Increment NACK count
IDIVI S1,^D30 ;Set S2 modulo 30
JUMPN S2,PLTCH1 ;Complain every 30 seconds
HRRZ S1,STREAM ;Get stream number
SETOM JOBCHK(S1) ;Request checkpoint
$WTO (Off-line,,@JOBOBA(S1))
PLTCH1: CSMEDT 05,4 ;TTY I/O and SLEEP, part 4 after PLTCHK:
IFN CSM05$,< $DSCHD (1) > ;De-schedule for 1 second
IFE CSM05$,< MOVEI S1,1 ;Wait 1 second
SLEEP S1, > ; before continuing
JRST PLTCHK ;Check if it is on-line now
PLTONL: SETOM J$NACK(J) ;Plotter is on-line now
$RETT ;OK to do the OUT UUO
> ;End of IFN CSM01$
> ;END TOPS10 CONDITIONAL
CONT. (OUTOUT)
TOPS20 <
OUTOUT: $SAVE <T1,T2,T3,T4> ;PRESERVE TEMPORARIES
MOVE S1,J$LJFN(J) ;GET DEV JFN
MOVE S2,J$LIBP(J) ;GET POINTER TO BUFFER
SKIPGE T1,J$LBCT(J) ;GET REMAINING BYTE COUNT
SETZ T1, ;MUST BE .GE. 0
SUB T1,J$LIBC(J) ;GET NEG. BYTE COUNT
JUMPE T1,OUTO.2 ;DONE -- RESET BUFFER HEADER
OUTO.1: HRRZ T2,STREAM ;GET STREAM
SETOM J$LIOA(J) ;SET I/O ACT
SKIPE JOBSTW(T2) ;BLOCKED?
JRST OUTINT ;YES -- POSTPONE SOUT
SOUTR ;DUMP THE BUFFER
ERJMP OUTERR ;PROCESS ERROR
OUTO.2: SETZM J$LIOA(J) ;CLEAR I/O ACT
MOVE S1,J$LIBC(J) ;GET INITIAL BYTE COUNT
MOVEM S1,J$LBCT(J) ;RESET BUFFER COUNT
MOVE S1,J$LIBP(J) ;GET INITIAL BYTE POINTER
MOVEM S1,J$LBPT(J) ;RESET BUFFER POINTER
HRRZ T1,J$LIBP(J) ;GET START ADDRESS OF BUFFER
HRLZ T2,T1 ;COPY IT
HRRI T2,1(T1) ;MAKE A BLT POINTER
SETZM (T1) ;CLEAR THE FIRST WORD
BLT T2,PAGSIZ-1(T1) ;CLEAR THE BUFFER
$DSCHD (PSF%NP) ;PICK UP AGAIN AFTER SCHEDULE
$RETT ;AND FINALLY RETURN
OUTERR: SETOM J$LIOE(J) ;SET ERROR FLAG
OUTINT: SETZM J$LIOA(J) ;CLEAR IO ACTIVE
MOVEM S2,J$LBPT(J) ;SAVE THE CURRENT POINTER
MOVEM T1,J$LBCT(J) ;SAVE NUMBER OF CHARACTERS LEFT
SKIPE JOBSTW(J) ;DEVICE OFF-LINE?
$CALL OUTWON ;POSSIBLY. GO CHECK
SKIPE J$LIOE(J) ;ERROR?
$CALL OUTSTS ;READ DEVICE STATUS
SKIPT ;ERROR?
$CALL DEVERR ;YES -- PROCESS IT
JUMPF MAIN ;STREAM HAS BEEN SHUTDOWN
MOVE S1,J$LJFN(J) ;RESTORE DEVICE JFN
MOVE S2,J$LBPT(J) ;RESTORE POINTER
MOVE T1,J$LBCT(J) ;RESTORE COUNT
JRST OUTO.1 ;RESTART SOUT
> ;END TOPS20 CONDITIONAL
SUBTTL TTY I/O -- Input character from TTY, no wait
CSMEDT 05,5 ;TTY I/O and SLEEP, part 5 between OUTFLS and C$DISP
IFN CSM05$,< INTERN TIWAIT,TTYIN,TRMERR ;Entry points for TABCDP.MAC
;Routine to input a single character from terminal into S1.
;Uses T1 and T2.
TTYIN:: MOVX T1,.TOSIP ;Skip if input in progress
HRRZ T2,J$TTY(J) ;Get UDX
MOVE S1,[2,,T1] ;Point to args
TRMOP. S1, ;Check if input
JRST TTYIN1 ;Nothing there
MOVX T1,.TOISC ;Input single character
MOVE S1,[2,,T1] ;Point to args
TRMOP. S1, ;Get the char
PUSHJ P,TRMERR ;Should never happen
$RETT ;Got char in S1
TTYIN1: MOVEI S1,0 ;Signify failure
$RETF
TRMERR::$STOP (TUF,TRMOP. UUO Failure)
SUBTTL TTY I/O -- Input character, wait up to 30 seconds
;Routine to wait up to 30 seconds for a character to come in.
;Returns TRUE if char in S1, FALSE and zero in S1 if timed out
TIWAIT::PUSHJ P,TTYIN ;Check for input
JUMPT TIWAI2 ;Clear NACK counter if got input
;There is a good possibility that the response will come in within 1 second
MOVX S1,HB.RTC+^D1000 ;Wait 1 second, wake on char ready
HIBER S1,
JFCL
PUSHJ P,TTYIN ;Anything now?
JUMPT TIWAI2 ;Return if so
AOS J$NACK(J) ;No, waited 1 second already
TIWAT1: $DSCHD (1) ;De-schedule this stream for 1 second
PUSHJ P,TTYIN ;Input now?
JUMPT TIWAI2 ;Yes, continue
AOSG S1,J$NACK(J) ;No, count failure
JRST TIWAT1 ;Keep waiting if negative or zero
IDIVI S1,^D30 ;Set S2 modulo 30
JUMPN S2,TIWAT1 ;If less than 30 seconds, wait again
HRRZ S1,STREAM ;Get stream number
$WTO (<No response from ^W/J$LDEV(J)/ after ^D/J$NACK(J)/ seconds>,,@JOBOBA(S1))
MOVEI S1,0 ;Signify no response
$RETF
TIWAI2: SETZM J$NACK(J) ;Terminal is responding
POPJ P, ;TF has been set to TRUE already
> ;End of IFN CSM05$
SUBTTL Card punch service -- Dispatch table
C$DISP: JRST C$HEAD ;(0) FILE HEADER
JRST C$EOF ;(1) FILE TRAILER
SIXBIT /CDP/ ;(2) GENERIC DEVICE NAME
EXP ^D12 ;(3) OUTPUT BYTE SIZE
JRST C$PROC ;(4) PROCESS A FILE
JRST C$BANN ;(5) JOB BANNER
JRST C$TRAI ;(6) JOB TRAILER
JRST C$LETR ;(7) LETTER DEVICE
JRST .RETF ;(10) ERROR PROCESSOR
CSMEDT 04,2 ;CSM accounting, part 2 at C$DISP:+11
IFE CSM04$,< JRST .RETT > ;(11) ACCOUNTING
IFN CSM04$,< JRST CSMACT > ;(11) Accounting
JRST C$CHKP ;(12) CHECKPOINT TEXT GENERATION
IFN CSM04$,<
CSMACT: MOVE S1,J$APRT(J) ;Get cards punched or feet punched
MOVEM S1,J$ADRD(J) ;Save instead of disk reads
$RETT
> ;End of IFN CSM04$
SUBTTL Card punch service -- File processing
C$PROC: LOAD S1,.FPINF(E),FP.FPF ;GET PAPER FORMAT
CAILE S1,CDROUL ;WITHIN RANGE?
JRST BADMOD ;NO, LOSE
JUMPN S1,@C$ROUT-1(S1) ;YES, DISPATCH IF NON-ZERO
CSMEDT 07,1 ;QUEUE defaults, part 1 at C$PROC:+4
IFE CSM07$,<
MOVEI S1,C$MTAB ;GET ADDRESS OF MODE TABLE
MOVEI S2,C$ROUT ;GET ADDRESS OF ROUTINE TABLE
PJRST DSPMOD ;AND DISPATCH BASED ON MODE
> ;End of CSM07$
IFN CSM07$,<JRST CDASC> ;Default to ASCII mode
;TABLE OF processing ROUTINES
C$ROUT: EXP CDASC ;ASCII
EXP CD026 ;026
EXP CDBIN ;CHECKSUMMED BINARY
EXP CDASC ;ASCII
EXP CDIMA ;IMAGE AND IMAGE BINARY
CDROUL==.-C$ROUT ;LENGTH OF ROUTINE TABLE
;MODE TABLE
C$MTAB: BYTE (3) 1,1,0,0,0,0,0,0,5,0,0,5,3,0,3,3
SUBTTL Card punch service -- File headers
C$HEAD: SKIPN J$FHEA(J) ;HEADER ALLOWED?
$RETT ;NO -- RETURN
CSMEDT 07,2 ;QUEUE defaults, part 2 at C$HEAD:+2
IFE CSM07$,< ;Ignore QUEUE's default of /NOHEADER, always punch it
LOAD S1,.FPINF(E),FP.NFH ;GET NO FILE HEADER BIT
JUMPN S1,.RETT ;RETURN IF NOT WANTED
> ;End of IFN CSM07$
MOVEI C,4001 ;SPECIAL MASK FOR FILE CARDS
MOVEM C,J$CMSK(J) ;SAVE FOR C$LETR
MOVE S1,J$DFDA(J) ;POINT TO FD
SKIPN S2,J$DSPN(J) ;SPOOL NAME?
TOPS10< MOVE S2,.FDNAM(S1) > ;NO -- USE FILE NAME
TOPS20<
MOVX S1,GJ%SHT!GJ%OFG ;PARSE ONLY, SHORT JFN
MOVE S2,J$DFDA(J) ;GET FD ADDRESS
HRROI S2,.FDSTG(S2) ;POINT TO START OF FILESPEC
GTJFN ;GET A JFN
ERJMP .POPJ ;ASSUME A SPOOLED FILE
MOVE S2,[POINT 7,FILNAM] ;POINT TO FILENAME STORAGE
EXCH S1,S2 ;S1:= POINTER, S2:= JFN
MOVE T1,[FILNAM,,FILNAM+1] ;SET UP BLT
SETZM FILNAM ;CLEAR THE FIRST WORD
BLT FILNAM+7 ;CLEAR THE ENTIRE BLOCK
MOVX T1,1B8 ;WANT FILENAME ONLY
JFNS ;GET IT
HRROI S1,FILNAM ;POINT TO THE FILENAME
$CALL S%SIXB ;CONVERT TO SIXBIT
>
MOVEI S1,[ITEXT<^W6/S2/>] ;POINT TO NAME
PJRST C$WORD ;PUNCH CARD AND RETURN
SUBTTL Card punch service -- File trailers
C$EOF: MOVEI S1,^D80 ;PUNCH EOF CARD
MOVEI C,7417 ;TOP FOUR AND BOTTOM FOUR ROWS
PUSHJ P,CDPREP ;PUNCH EOF CARDS
;[CSM] PJRST OUTOUT ;FORCE OUTPUT
PJRST OUTCD1 ;[CSM] ;FORCE OUTPUT
SUBTTL Card punch service -- Banners
C$BANN: CSMEDT 06,1 ;TTY CDP, part 1 at C$BANN:
IFN CSM06$,< ;Set terminal to PUNCH+PRINT mode if /FORMS:NORMAL
MOVEI S1,J$FORM(J) ;Get forms name
CAMN S1,['NORMAL'] ;Normal forms?
MOVEI S1,0 ;Yes, turn on print mode
SKIPE S2,J$TTY(J) ;Punch really a terminal?
PUSHJ P,TABINI## ;Yes, set it up
> ;End of IFN CSM06$
SKIPN J$FBAN(J) ;BANNER cards wanted?
$RETT ;RETURN IF ZERO
MOVEI C,4003 ;MASK FOR JOB CARDS
MOVEM C,J$CMSK(J) ;SAVE FOR C$LETR
CSMEDT 07,3 ;QUEUE defaults, part 3 at C$BANN:+4
IFE CSM07$,< ;"BEGIN: JOB jobnam USER:" wastes 4 cards.
MOVEI S1,[ITEXT<BEGIN:>]
PJRST CTRA.1 ;FALL INTO COMMON CODE
> ;End of IFE CSM07$
IFN CSM07$,< ;Punch just NAME, PPN, and NOTE (if any)
PJRST CTRA.2 ;Punch user name
> ;End of IFN CSM07$
IFE CSM06$,<
C$TRAI: SKIPN J$FTRA(J) ;Check TRAILER wanted flag
$RETT ;RETURN IF ZERO
> ;End of IFE CSM06$
IFN CSM06$,< ;Call TABFIN after all is done
C$TRAI: SKIPE J$FTRA(J) ;Trailer cards wanted?
$CALL CTRA.0 ;Yes
SKIPE J$TTY(J) ;Output to a TTY?
PUSHJ P,TABFIN## ;Yes, finish up
$RETT
CTRA.0: > ;End of IFN CSM06$
MOVEI C,4003 ;MASK FOR JOB CARDS
MOVEM C,J$CMSK(J) ;SAVE FOR C$LETR
MOVEI S1,[ITEXT<END: >]
CTRA.1: $CALL C$WORD
MOVEI S1,[ITEXT<^W6/.EQJOB(J)/>]
$CALL C$WORD
MOVEI S1,[ITEXT <REQ-ID >]
PUSHJ P,C$WORD
MOVEI S1,[ITEXT<#^D5R0/.EQJBB+JIB.ID(J)/>] ;REQUEST ID
$CALL C$WORD
MOVEI S1,[ITEXT<USER: >]
$CALL C$WORD
$CALL SETTBF ;POINT TO TEXT BUFFER
CONT. (C$BANN)
IFN CSM07$,< CTRA.2: > ;Here to skip over garbage
TOPS10 < ;TOPS-10 ONLY
MOVEI S1,[ITEXT <^W6/.EQJBB+JIB.NM(J)/>] ;USER NAME (WORD 1)
PUSHJ P,C$WORD ;PUNCH IT
MOVEI S1,[ITEXT <^W6/.EQJBB+JIB.NM+1(J)/>] ;USER NAME (WORD 2)
PUSHJ P,C$WORD ;PUNCH IT
MOVEI S1,[ITEXT <^O6R /.EQOID(J),LHMASK/>] ;PROJECT NUMBER
PUSHJ P,C$WORD ;PUNCH IT
MOVEI S1,[ITEXT <^O6L /.EQOID(J),RHMASK/>] ;PROGRAMMER NUMBER
PUSHJ P,C$WORD ;PUNCH IT
> ;END TOPS-10 CONDITIONAL
TOPS20 <
MOVE TF,[POINT 6,FILNAM] ;GET BYTE POINTER
MOVEM TF,TEXTBP ;STORE THE BYTE POINTER
MOVEI TF,TXT$LN*^D12 ;GET BYTE COUNT
MOVEM TF,TEXTBC ;AND SAVE IT
SETZM FILNAM+0 ;CLEAR A WORD
SETZM FILNAM+1 ;CLEAR ANOTHER WORD
$TEXT (DEP6BP,<^T/.EQOWN(J)/^A>) ;ALLOW UP TO 12 CHARACTER NAMES
MOVEI S1,[ITEXT <^W6/FILNAM+0/>] ;WORD 1
PUSHJ P,C$WORD ;OUTPUT IT
MOVEI S1,[ITEXT <^W6/FILNAM+1/>] ;WORD 2
SKIPE FILNAM+1 ;IS THERE A SECOND WORD?
PUSHJ P,C$WORD ;OUTPUT IT
PUSHJ P,SETTBF ;RESET BYTE POINTER AND COUNT
>
GETLIM T1,.EQLIM(J),NOT1 ;GET /NOTE VALUE (WORD 1)
GETLIM T2,.EQLIM(J),NOT2 ;GET /NOTE VALUE (WORD 2)
SKIPN T1 ;RETURN IF BOTH
JUMPE T2,.RETT ; WORDS ARE ZERO
MOVEI S1,[ITEXT<NOTE: >]
PUSHJ P,C$WORD ;PUNCH IT
GETLIM T1,.EQLIM(J),NOT1 ;GET /NOTE VALUE (WORD 1)
MOVEI S1,[ITEXT<^W6/T1/>]
PUSHJ P,C$WORD ;PUNCH IT
GETLIM T1,.EQLIM(J),NOT2 ;GET /NOTE VALUE (WORD 2)
JUMPE T1,.RETT ;RETURN IF NO SECOND WORD
MOVEI S1,[ITEXT<^W6/T1/>]
PJRST C$WORD ;PUNCH LAST CARD AND RETURN
SUBTTL Card punch service -- Word punching
;C$WORD
;Call S1/ Address of Itext to punch as 6 Character word on card
; Also J$CMSK Specifies Extra Rows to punch with Characters
C$WORD: $CALL SETTBF ;SET POINTERS TO TEXT BUFFER
$TEXT(DEPBP,<^I/(S1)/^0>) ;STORE STRING IN BUFFER
MOVEI S1,0 ;GET A NULL
DPB S1,[POINT 7,J$XTBF+1(J),13] ;TRUNCATE TO SIX CHARACTERS
MOVEI C,3776 ;FIRST COLUMN WITH ROUNDED CORNERS
PUSHJ P,CDPBYT
MOVEI C,7777 ;SECOND COLUMN FULLY LACED
PUSHJ P,CDPBYT
MOVEI S1,3 ;NEXT 3 COLUMNS WITH SPECIAL MASK
MOVE C,J$CMSK(J)
PUSHJ P,CDPREP
$CALL STRING ;COLUMNS 6-77 FOR CHARACTERS
MOVE C,J$CMSK(J) ;COLUMN 78 SPECIAL MASK
PUSHJ P,CDPBYT
MOVEI C,7777 ;COLUMN 79 FULLY LACED
PUSHJ P,CDPBYT
MOVEI C,3776 ;COLUMN 80 ROUNDED CORNERS
PUSHJ P,CDPBYT
;[CSM] PJRST OUTOUT ;PUNCH CARD AND RETURN
PJRST OUTCD1 ;[CSM] ;PUNCH CARD AND RETURN
SUBTTL Card punch service -- Byte output
; AC 'C' contains the byte to output
;
CDPBYT: CSMEDT 06,2 ;TTY CDP, part 2 at CDPBYT
IFE CSM06$,< PJRST OUTBYT >
IFN CSM06$,< ;Special output for TAB Products Cardpunch Terminal
SKIPN J$TTY(J) ;Output to a TTY?
PJRST OUTBYT ;No
$SAVE <S1,S2> ;Yes, preserve ACs used
MOVE S1,C ;Copy to expected AC
PJRST TABBYT## ;Store byte in other buffer
> ;End of IFN CSM06$
; Force card out
;
OUTCDP: AOS S1,J$APRT(J) ;COUNT ANOTHER ONE
CAMLE S1,J$RLIM(J) ;OVER LIMIT?
PUSHJ P,FRMLEX ;HANDLE LIMIT EXCEEDED
OUTCD1: ;Output without counting
IFN CSM06$,< ;Special output for TAB Products Cardpunch Terminal
SKIPE J$TTY(J) ;Output to a TTY?
PJRST TABPUN## ;Yes, output the card
> ;End of IFN CSM06$
PJRST OUTOUT ;FORCE CARD OUT
; Repeat the byte in AC 'C'
; Call: MOVE S1,repeat count
; MOVE C,byte to output
; PUSHJ P,CDPREP
;
CDPREP: PUSH P,P1 ;SAVE P1
MOVE P1,S1 ;GET COUNT
;[CSM] PUSHJ P,PTPBYT ;OUTPUT A BYTE
PUSHJ P,CDPBYT ;[CSM] ;Use the right output routine
SOJG P1,.-1 ;AND LOOP
POP P,P1 ;RESTORE P1
POPJ P, ;RETURN
SUBTTL Plotter service -- Dispatch table
P$DISP: JRST P$HEAD ;(0) FILE HEADER
JRST P$EOF ;(1) FILE TRAILER
SIXBIT /PLT/ ;(2) GENERIC DEVICE NAME
EXP ^D6 ;(3) OUTPUT BYTE SIZE
JRST P$PROC ;(4) PROCESS A FILE
JRST P$BANN ;(5) JOB BANNER
JRST P$TRAI ;(6) JOB TRAILER
JRST P$LETR ;(7) LETTER PROCESSER
JRST P$DERR ;(10) DEVICE ERROR PROCESSOR
CSMEDT 04,3 ;CSM accounting, part 3 at P$DISP:+11
IFE CSM04$,<JRST .RETT> ;(11) ACCOUNTING
IFN CSM04$,<JRST PLTACT> ;(11) Plotter accounting
JRST P$CHKP ;(12) CHECKPOINT TEXT GENERATION
IFN CSM04$,< ;Account for both elapsed time and paper used
PLTACT: MOVE S1,J$XLIM(J) ;Get total X increments
ADDI S1,INCS/2 ;Round up
IDIVI S1,INCS ;Convert to inches
EXCH S1,J$APRT(J) ;Store amount of paper used
MOVEM S1,J$ADRD(J) ;Store minutes in place of disk reads
$RETT
> ;End of IFN CSM04$
SUBTTL Plotter service -- Checkpoint text generation
P$CHKP: $SAVE <P1,P2,P3> ;SAVE SOME ACS
MOVE P1,J$PTIC(J) ;GET # TICS FOR JOB
IDIV P1,J$PTPM(J) ;P1:= MINUTES, P2:= FRACTION
IMULI P2,^D10 ;[CSM] One decimal place
IDIV P2,J$PTPM(J) ;P2:= DECIMAL FRACTION OF A MINUTE
MOVE P3,J$RLIM(J) ;GET LIMIT
CAMN P3,[.INFIN] ;+INFINITY?
JRST P$CHK1 ;YES
CAMG P1,J$RLIM(J) ;OPERATOR ALLOW LIMIT TO EXCEED?
$TEXT (DEPBP,<plotted ^D/P1/.^D/P2/ of ^D/J$RLIM(J)/ minutes^0>)
CAMLE P1,J$RLIM(J) ;OPERATOR ALLOW LIMIT TO EXCEED?
P$CHK1: $TEXT (DEPBP,<plotted ^D/P1/.^D/P2/ minutes (limit exceeded)^0>)
POPJ P, ;RETURN
SUBTTL Plotter service -- File processing
P$PROC: LOAD S1,.FPINF(E),FP.FPF ;GET PAPER FORMAT
CAILE S1,PLROUL ;WITHIN RANGE?
JRST BADMOD ;NO, LOSE
JUMPN S1,@P$ROUT-1(S1) ;YES, DISPATCH IF NON-ZERO
CSMEDT 07,4 ;QUEUE defaults, part 4 at P$PROC:+4
IFE CSM07$,< ;This code removed because all plots must be BINARY halfwords
MOVEI S1,P$MTAB ;GET ADDRESS OF MODE TABLE
MOVEI S2,P$ROUT ;GET ADDRESS OF ROUTINE TABLE
PJRST DSPMOD ;AND DISPATCH BASED ON MODE
> ;End of IFE CSM07$
IFN CSM07$,< JRST PLTHLF > ;Default always to halfword format
P$ROUT: EXP PLTSIX ;/PLOT:IMAGE (6 BIT)
EXP PLTSVN ;/PLOT:ASCII (7 BIT)
CSMEDT 02,1 ;Halfword format, part 1 at P$ROUT:+3
IFE CSM02$,<EXP PLTSIX> ;/PLOT:BINARY (6 BIT)
IFN CSM02$,<EXP PLTHLF> ;/PLOT:BINARY (18 bit)
PLROUL==.-P$ROUT ;LENGTH OF ROUTINE TABLE
;MODE TABLE
P$MTAB: BYTE (3) 2,2,0,0,0,0,0,0,1,0,0,1,1,1,1,1
SUBTTL Plotter service -- Expand CSM's compressed plot format
CSMEDT 02,2 ;Halfword format, part 2 after PLTLP0:
IFN CSM02$,< ;Read halfwords from disk
COMMENT ~ Do not use many semicolons, it confuses FILCOM's /C switch
!=======================================================!
! !
! PLOTTER MODE -- 18 BIT !
! !
! In 18 bit mode, each word read from disk is divided !
! into halfwords, which are interpreted by subroutine !
! TOLP. Most halfwords have 9 bits of delta-X and !
! 9 bits of delta-Y, special opcodes raise and lower !
! the pen. See TOLP.MAC for a full description. !
! !
!=======================================================!
! Delta Y ! Delta X ! Delta Y ! Delta X !
!=======================================================!
Call TOLP. with
S1/ Addr of input routine, which returns data in S1, -1 on EOF
S2/ 0 to suppress header/trailer, 1 for header, 2 for trailer, 3 for both
T1/ Current X position (should be same as J$XMIN)
T2/ Current Y position (should be same as J$YMIN)
On return, ACs 7-16 have been preserved
TF/ Garbage
S1/ Garbage
S2/ Addr of error message, or 0 if no error
T1-T4/ Garbage
~ ;End of COMMENT
EXTERN TOLP. ;Routine to reverse PLOT
INTERN PLOT ;Routine to move the pen
INTERN NEWPEN,OPRTXT,PAUSEP,TITLE ;Other routines called by TOLP
ND INCS,^D400 ;Steps per inch (620 octal)
SUBTTL Plotter service -- READ36, OPRTXT, PAUSEP, TITLE for TOLP
;Routine to read a word from the input file, returns -1 for EOF, -2 if ABORT
READ36: MOVE S1,J$PTIC(J) ;Get tics plotted
IDIV S1,J$PTPM(J) ;Convert to minutes
CAMLE S1,J$RLIM(J) ;Still in range?
PUSHJ P,FRMLEX ;No, complain
PUSHJ P,INPBYT ;Get a word
MOVE T1,C ;Copy to expected AC
JUMPT .POPJ ;Use it if OK
MOVNI T1,1 ;-1 for EOF
TXNE S,RQB+ABORT ;Unless OPR caused EOF
MOVNI T1,2 ;-2 for ABORT
POPJ P, ;Continue back in TOLP
;Routine to send a message to the OPR.
;Called with byte count in S1, addr of ASCIZ message in S2.
OPRTXT: PUSHJ P,PLTOUT ;Dump buffers
HRRZ S1,STREAM ;Get the stream number
$WTO (OPRTXT message,<^T/0(S2)/>,@JOBOBA(S1)) ;Tell OPR
POPJ P,
;Routine to pause the plotter.
;Zero in S1 means to wait for human intervention, nonzero causes graphic
;terminals to pause that many seconds before automatically resuming.
PAUSEP: PUSHJ P,PLTOUT ;Dump the buffers
JUMPN S1,.POPJ ;Nonzero valid for graphics terminals
PUSHJ P,SETTBF ;Set up WTO buffer
PJRST FORM.3 ;Wait for a "PROCEED" response
;Routine to plot text.
; T1/ Height in increments
; T2/ Addr of text
; T3/ Angle in degrees, 0 to 359
; T4/ Byte count for text
TITLE: POPJ P, ;Not implemented
PLTOUT:
IFE CSM08$,< PJRST OUTOUT >
IFN CSM08$,<
SKIPE J$TTY(J) ;Output to a TTY?
PJRST OUTOUT ;No
PUSHJ P,PTCOUT## ;Yes, get ready to output last buffer
SETZM J$PPOS(J) ;PTCOUT always raises the pen
PJRST OUTRSP ;Output string and wait for response
> ;End of IFN CSM08$
> ;End of IFN CSM02$
SUBTTL Plotter service -- NEWPEN for 3-pen plotter
CSMEDT 01,3 ;3-Pen plotter, part 3 before P$DERR
IFN CSM01$,<
PEN.1: MOVEI S1,1 ;Set to blue pen
JRST NEWPEN
PEN.2: MOVEI S1,2 ;Set to black pen
JRST NEWPEN
PEN.3: MOVEI S1,3 ;Set to red pen and fall into NEWPEN
JRST NEWPEN
ND PENSEP,INCS*4/4 ;Pen separation is 1 inch or 3/4 inch
CHGPEN: BYTE (6) CNGP,PNDN,0 ;Codes to change to pen #1
BYTE (6) CNGP,PEN2,PNDN,0 ; #2
BYTE (6) CNGP,PEN3,PNDN,0 ; #3
;Routine to change pens. Called with pen number in S1, trashes it and S2.
NEWPEN: $SAVE <P1,P2> ;Save preserved ACs
;Make sure pen number in S1 is between 1 and 3 inclusive
SUBI S1,1 ;Change to number from 0 to 2
IDIVI S1,3 ;Set S2 modulo 3
AOS P2,S2 ;Copy new pen number (from 1 to 3)
CSMEDT 08,2 ;PTC-6 Plotter Controller, part 2 in NEWPEN
IFN CSM08$,< ;Special codes for PTC-6
SKIPE J$TTY(J) ;Using a terminal line?
JRST [PUSHJ P,PTCPEN## ;Yes, tell it (pen number in S2)
JRST NEWPN2 ] ;Then move the pen holder
> ;End of IFN CSM08$
MOVEI P1,CHGPEN-1(S2) ;Get addr of data
HRLI P1,(POINT 6,) ;Make into byte pointer
PUSHJ P,PENUP ;Raise any and all pens
;Output the codes to select new pen (even if it was previously selected)
NEWPN1: ILDB C,P1 ;Get a byte
PUSHJ P,PLTBTX ;Send to plotter (even if no-op)
JUMPN C,NEWPN1 ;Loop till no-op is sent
;When pen #1 is positioned at Y=5.0, then pen #2 is at Y=4.0 and pen #3
;is at Y=3.0. Therefore, when changing from pen #1 to pen #2 (or 2 to 3),
;the pen holder must be moved 1.0 inches in the +Y direction, without
;affecting J$YPOS and in spite of J$YMAX and J$YMIN.
NEWPN2: MOVE P1,P2 ;Copy new pen number
SUB P1,J$PENN(J) ;Find change (+1 if from pen 1 to pen 2)
JUMPE P1,.POPJ ;All done if same as previous pen
EXCH P2,J$PENN(J) ;Set new, get old
JUMPE P2,.POPJ ;All done if called from P$CPEN
IMULI P1,PENSEP ;Distance between pens
SKIPL P1 ;If going plus,
ADDM P1,J$YMAX(J) ; allow blue pen to move off the paper
SKIPG P1 ;If going minus,
ADDM P1,J$YMIN(J) ; allow red pen to move off the paper
MOVE T1,J$XPOS(J) ;No change in X
MOVE T2,P1 ;Delta Y
ADD T2,J$YPOS(J) ;New Y position
MOVEI T3,PN.UP ;Raise the pen
PUSHJ P,PLOT ;Move the pen holder into position
MOVNS P1 ;Cancel the offset
SKIPG P1 ;If used to be positive,
ADDM P1,J$YMAX(J) ; reset max limit
SKIPL P1 ;If used to be negative,
ADDM P1,J$YMIN(J) ; reset min limit
ADDM P1,J$YPOS(J) ;New pen is where previous one was
POPJ P,
;Routine to output bytes to plotter, passing nulls and CNGP codes correctly.
;Note: When changing pens, the first PNDN code does NOT lower the pen.
PLTBTX: MOVEI S1,PLTMOV ;Load # tics for movement
CAIN C,PNDN ;Pen down code?
MOVEI S1,PLTPEN ;Load # tics for pen up/down
ADDM S1,J$PTIC(J) ;Add in for accounting
PJRST OUTBYT ;Bypass J$ROTA check
> ;End of IFN CSM01$
SUBTTL Plotter service -- Banners
CSMEDT 03,1 ;Banner changes, part 1 at P$BANN:
;*; IFN CSM03$,<ND NAMSIZ,1>
ND NAMSIZ,3 ;User's name will be 3 times larger than other text
P$BANN: CSMEDT 08,3 ;PTC-6 Plotter Controller, part 3 at P$BANN
IFN CSM08$,<
SKIPE J$TTY(J) ;PTC-6 controller?
PUSHJ P,[MOVEI T1,PLTPEN ;Yes, positive to use CR handshake
PUSHJ P,PTCINI## ;Initialize terminal
PJRST OUTRSP ] ;Output string to TTY
> ;End of IFN CSM08$
PUSHJ P,P$CPEN ;RE-CALIBRATE THE PEN
SKIPN J$FBANN(J) ;BANNER WANTED?
POPJ P, ;NO - JUST RETURN
PUSH P,J$PTIC(J) ;DON'T CHARGE FOR PLOTTER OVERHEAD
MOVEI S1,[ASCIZ |Start|] ;GET LINE IDENTIFIER
PUSHJ P,PLTJOB ;PLOT JOB INFORMATION
BANN.1: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IFN NAMSIZ-1,< ;Start a separate line
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
> ;End of IFN NAMSIZ-1
IFE NAMSIZ-1,< ;Put LIMIT on same line as user name
MOVE T2,T1 ;Copy character size
ADD T2,J$YPOS(J) ;Space over a bit in plus-Y direction
MOVE T1,J$XPOS(J) ;Current X position
> ;End of IFN NAMSIZ-1
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;MOVE THE PEN
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
$TEXT (DEPBP,< Limit: ^D/J$RLIM(J)/, Forms: ^W/J$FORM(J)/^A>)
BANN.2: GETLIM T1,.EQLIM(J),NOT1 ;GET /NOTE VALUE (WORD 1)
GETLIM T2,.EQLIM(J),NOT2 ;GET /NOTE VALUE (WORD 2)
SKIPN T1 ;CHECK WORD 1
SKIPE T2 ;CHECK WORD 2
$TEXT (DEPBP,<, Note: ^W6/T1/^W/T2/^A>) ;YES
MOVEI S1,.CHNUL ;GET A <NUL>
PUSHJ P,DEPBP ;STORE IT
PUSHJ P,STRING ;PLOT STRING
POP P,J$PTIC(J) ;RESTORE # PLOTTER TICS
POPJ P, ;RETURN
SUBTTL Plotter service -- File headers
P$HEAD: PUSH P,J$PTIC(J) ;DON'T CHARGE FOR PLOTTER OVERHEAD
PUSHJ P,P$DASH ;SEPARATE FROM BANNER OR LAST FILE
SKIPN J$FHEA(J) ;HEADER ALLOWED?
PJRST P$HEA1 ;NO..POSITION TO ORIGIN
LOAD S1,.FPINF(E),FP.NFH ;GET NO FILE HEADER BIT
JUMPN S1,P$HEA1 ;SKIP IF NOT WANTED
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
$CALL SETTBF ;SETUP TO PRINT STIRNG
MOVE S1,J$DIFN(J) ;GET FILE IFN
MOVEI S2,FI.CRE ;GET CREATION DATE TIME
$CALL F%INFO
MOVEI S2,[ITEXT (<>)] ;ASSUME NOT /DISPOSE:RENAME
SKIPE J$DSPN(J) ;WAS IT /DISPOSE:RENAME?
MOVEI S2,[ITEXT (< (^W/J$DSPN(J)/.^W/J$DSPX(J)/)>)] ;YES
CSMEDT 02,3 ;Halfword format, part 3 at P$HEA1:-2
IFE CSM02$,< $TEXT (DEPBP,<* File: ^F/@J$DFDA(J)/^I/(S2)/ created:^H/S1/ *^0>) >
IFN CSM02$,< $TEXT (DEPBP,<* File: ^F/@J$DFDA(J)/^I/(S2)/ *^0>) >
;CSM internal headers have creation date/time
PUSHJ P,STRING ;PLOT TEXT
P$HEA1: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
MOVE T1,J$XPOS(J) ;GET CURRENT X POSITION
MOVEM T1,J$XMIN(J) ;UPDATE NEW MINIMUM
IFN CSM01$,< ;Allow plots to butt up against each other
ADDI T1,INCS/2 ;Set lowest seen to 1/2 inch margins
MOVEM T1,J$XLOW(J) ;(not fully implemented yet)
> ;End of IFN CSM01$
POP P,J$PTIC(J) ;RESTORE # PLOTTER TICS
POPJ P, ;RETURN
SUBTTL Plotter service -- File trailers
P$EOF: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
ADD T1,J$XLIM(J) ;POSITION BEYOND THE HIGHEST X STEP
MOVE T2,J$YMIN(J) ;GO BACK TO THE MARGIN
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
CSMEDT 08,4 ;PTC-6 Plotter Controller, part 4 at end of P$EOF
IFN CSM08$,< ;Call PTCOUT instead of OUTOUT
SKIPE J$TTY(J) ;PTC-6 controller?
JRST [PUSHJ P,PTCOUT## ;Yes, raise pen
PJRST OUTRSP ] ;Wait for response
> ;End of IFN CSM08$
PJRST OUTOUT ;DUMP WHAT WE HAVE
SUBTTL Plotter service -- Job trailers
P$TRAI: CSMEDT 03,3 ;Banner changes, part 3 at P$TRAI:
IFE CSM03$,< ;This test prevents error messages from coming out
PUSHJ P,P$DASH ;SEPARATE FROM LAST FILE
PUSH P,J$PTIC(J) ;DON'T CHARGE FOR PLOTTER OVERHEAD
SKIPN J$FTRA(J) ;TRAILER ALLOWED?
JRST P$TRA3 ;NO
> ;End of IFE CSM03$
IFN CSM03$,< ;Output dashed line only if text will be plotted
PUSH P,J$PTIC(J) ;Don't charge for plotter overhead
SKIPN J$FTRA(J) ;Plot the trailer?
SKIPE J$XERR(J) ; or an error message?
PUSHJ P,P$DASH ;Yes, separate text from plot
> ;End of IFN CSM03$
SKIPN J$XERR(J) ;ANY ERROR TEXT?
JRST P$TRA0 ;NO - ONWARD
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;[CSM] ;Make room for characters
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
$TEXT (DEPBP,<^T/J$XERR(J)/^0>) ;INCLUDE ERROR TEXT
PUSHJ P,STRING ;PLOT ERROR TEXT
P$TRA0:
IFN CSM03$,< ;Check for /TRAILER after plotting error message
SKIPN J$FTRA(J) ;Trailer wanted?
JRST P$TRA3 ;No, skip job line and summary
> ;End of IFN CSM03$
MOVEI S1,[ASCIZ |End|] ;GET LINE IDENTIFIER
PUSHJ P,PLTJOB ;PLOT JOB LINE
CONT. (P$TRAI)
P$TRA1: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IFN NAMSIZ-1,< ;Start a separate line
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
> ;End of IFN NAMSIZ-1
IFE NAMSIZ-1,< ;Put SUMMARY on same line as user name
MOVE T2,T1 ;Copy character size
ADD T2,J$YPOS(J) ;Space over a bit in plus-Y direction
MOVE T1,J$XPOS(J) ;Current X position
> ;End of IFN NAMSIZ-1
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
LOAD T1,.EQSPC(J),EQ.NUM ;GET NUMBER OF FILES
MOVEI T2,[ITEXT (<file>)] ;ASSUME 1 FILE
CAIE T1,1 ;WAS IT
MOVEI T2,[ITEXT (<files>)] ;NO
$TEXT (DEPBP,< Summary: ^D/T1/ ^I/(T2)/^A>)
P$TRA2: MOVE T1,(P) ;GET # TICS FOR JOB
IDIV T1,J$PTPM(J) ;T1:= MINUTES, T2:= FRACTION
IMULI T2,^D10 ;[CSM] 1 decimal place (=6 seconds)
IDIV T2,J$PTPM(J) ;T2:= DECIMAL FRACTION OF A MINUTE
$TEXT (DEPBP,< plotted in ^D/T1/.^D/T2/ minutes^0>)
PUSHJ P,STRING ;PLOT TEXT
P$TRA3: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;LEAVE THIS MUCH SPACE
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
PUSHJ P,P$LINE ;PLOT SEPARATOR
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;POINT TO NEXT LINE
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
POP P,J$PTIC(J) ;RESTORE # PLOTTER TICS
MOVE T1,J$PTIC(J) ;GET # TICS
IDIV T1,J$PTPM(J) ;GET MINUTES OF PLOTTER TIME
MOVEM T1,J$APRT(J) ;STORE IT
CSMEDT 08,5 ;PTC-6 Plotter Controller, part 5 at end of P$TRAI
IFN CSM08$,<
SKIPE J$TTY(J) ;PTC-6 controller?
PUSHJ P,[PUSHJ P,PTCOUT## ;Yes, raise pen
PUSHJ P,OUTRSP ;Wait for response
PUSHJ P,PTCFIN## ;Finish up and deselect
PJRST OUTSTG ] ;Output string to TTY
> ;End of IFN CSM08$
POPJ P, ;RETURN
SUBTTL Plotter service -- Solid lines
; This routine does the following:
; 1. Position to the next line
; 2. Plot a solid line
; 3. Position to the next line
;
P$LINE: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
CSMEDT 03,4 ;Banner changes, part 4 at P$LINE:+2
IFE CSM03$,< ;Going from MIN to MAX when pen is near MAX wastes time
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
MOVE T1,J$XPOS(J) ;Use current X position
MOVE T2,J$YMAX(J) ;GET MAXIMUM Y VALUE
> ;End of IFE CSM03$
IFN CSM03$,< ;Go to MAX, then to MIN and end there
MOVE T2,J$YMAX(J) ;Go to closer end point
CAIL T2,INCS*6 ;More than 6 inches?
MOVEI T2,INCS*6 ;Yes, don't waste inc
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;Position pen
MOVE T1,J$XPOS(J) ;Use current X position
MOVE T2,J$YMIN(J) ;Go to "HOME" position
> ;End of IFE CSM03$
MOVEI T3,PN.DWN ;Pen down
PUSHJ P,PLOT ;PLOT A LINE
LINE.1: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;LEAVE SOME SPACE
ADD T1,J$XPOS(J) ;POSITION TO NEXT LINE
MOVE T2,J$YMIN(J) ;GET MINIMUM Y VALUE
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN AT START OF NEXT LINE
PUSHJ P,OUTOUT ;DUMP BUFFERS
POPJ P, ;RETURN
SUBTTL Plotter service -- Dashed lines
; This routine works like P$LINE, but line is drawn with dashes.
; The length of each dash is the same as the height of the characters
P$DASH: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
CSMEDT 03,5 ;Banner changes, part 5 at P$DASH:+3
IFE CSM03$,< MOVE T2,J$YMIN(J) > ;GET MINIMUM Y POSITION
IFN CSM03$,<
MOVE T2,J$YMAX(J) ;Get maximum Y position
CAIL T2,INCS*6 ;More than 6 inches?
MOVEI T2,INCS*6 ;Yes, don't waste time and ink
> ;End of IFN CSM03$
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
DASH.1: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IFE CSM03$,<
ADD T1,J$YPOS(J) ;ADD TO Y POSITION
CAML T1,J$YMAX(J) ;GONE TOO FAR?
> ;End of IFE CSM03$
IFN CSM03$,<
MOVNS T1 ;Make negative
ADD T1,J$YPOS(J) ;Decrement Y position
CAMG T1,J$YMIN(J) ;Gone too far?
> ;End of IFN CSM03$
JRST LINE.1 ;YES - FINISH UP
MOVE T2,T1 ;PUT IN PROPER PLACE
MOVE T1,J$XPOS(J) ;GET X POSITION
MOVEI T3,PN.DWN ;Pen down
PUSHJ P,PLOT ;PLOT A LINE
DASH.2: PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IFE CSM03$,<
ADD T1,J$YPOS(J) ;ADD TO Y POSITION
CAML T1,J$YMAX(J) ;GONE TOO FAR?
> ;End of IFE CSM03$
IFN CSM03$,<
MOVNS T1 ;Make negative
ADD T1,J$YPOS(J) ;Decrement Y position
CAMG T1,J$YMIN(J) ;Gone too far?
> ;End of IFN CSM03$
JRST LINE.1 ;YES - FINISH UP
MOVE T2,T1 ;PUT IN PROPER PLACE
MOVE T1,J$XPOS(J) ;GET X POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;PLOT A LINE
JRST DASH.1 ;GO BACK AND DO IT AGAIN
SUBTTL Plotter service -- Job information plotting
; Here to job information for banner and trailer lines
; Call: MOVEI S1,[ASCIZ |Start|] ;OR [ASCIZ |End|]
; PUSHJ P,PLTJOB
;
PLTJOB: PUSH P,S1 ;SAVE TEXT POINTER
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;MOVE OUT A BIT
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
CSMEDT 03,6 ;Banner changes, part 6 at PLTJOB:+8
IFN CSM03$,< PUSHJ P,PEN.3 > ;Do "*START*" in red
MOVE T1,.EQJBB+JIB.JN(J) ;GET JOB NAME
MOVE T2,.EQJBB+JIB.ID(J) ;GET REQUEST ID
POP P,T3 ;RESTORE TEXT POINTER
$TEXT (DEPBP,<* ^T/(T3)/ Job ^W/T1/ req #^D/T2/ ^H/[-1]/ ^T/(T3)/ *^0>)
PUSHJ P,STRING ;PLOT STRING
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,NAMSIZ+1 ;[CSM] ;Size of name plus blank space
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;MOVE THE PEN
PUSHJ P,SETTBF ;SET UP POINTERS TO THE BUFFER
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,NAMSIZ ;[CSM] ;The name is bigger than other text
MOVEM T1,J$CSIZ(J) ;STORE IT
IFN CSM03$,< PUSHJ P,PEN.2 > ;Do user's name in black
CONT. (PLTJOB)
;PLOT THE USERS NAME
TOPS10< DMOVE T3,.EQOWN(J) ;Name and PPN, 28 chars max
$TEXT (DEPBP,< ^W6/T3/^W/T4/ ^P/.EQOID(J)/^0>) >
TOPS20< $TEXT (DEPBP,< ^T/.EQOWN(J)/^0>) >
PUSHJ P,STRING ;PLOT THE STRING
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
ADD T1,J$XPOS(J) ;POINT TO NEXT LINE
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
IFN CSM03$,< PUSHJ P,PEN.1 > ;Next dividing line will be blue
POPJ P, ;RETURN
SUBTTL Plotter service -- Alignment and testing
REPEAT 0,<
; Routine to test character plots
;
P$TEST: $SAVE <P1> ;SAVE P1
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
PUSHJ P,P$CPEN ;CALIBRATE THE PEN
MOVEI C,.CHNUL ;START WITH <NUL>
TEST.1: PUSH P,C ;SAVE CHARACTER
MOVEI S1,.CHNUL ;[CSM] ;Terminate previous string
PUSHJ P,DEPBP ;[CSM] ; (in case of /NOTE: in SPFORM.INI)
PUSHJ P,STRING ;OUTPUT TEXT
PUSHJ P,P$CHKS ;COMPUTE CHARACTER SIZE
IMULI T1,2 ;WANT DOUBLE HEIGHT CHARACTERS
MOVEM T1,J$CSIZ(J) ;REMEMBER IT
ADD T1,J$XPOS(J) ;OFFSET BY CURRENT POSITION
MOVE T2,J$YMIN(J) ;GET MINIMUM Y POSITION
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
PUSHJ P,SETTBF ;SET UP TEXT BUFFER
POP P,C ;RESTORE CHARACTER
CAIN C,200 ;DONE ALL CHARACTERS?
PJRST OUTOUT ;PLOT TEXT AND RETURN
MOVEI P1,40 ;SET UP COUNTER
TEST.2: SKIPN S1,C ;GET CHARACTER
MOVEI S1," " ;STRING SUBROUTINE CAN'T HANDLE <NUL>
PUSHJ P,DEPBP ;PUT CARACTER
ADDI C,1 ;ADVANCE TO NEXT CHARACTER
SOJLE P1,TEST.1 ;DONE WITH THIS LINE?
JRST TEST.2 ;NO
>
SUBTTL Plotter service -- Pen calibration
;This is the only place that J$XPOS is reset. It is called from P$BANN.
P$CPEN: MOVE T1,J$YMAX(J) ;GET THE MAXIMUM Y VALUE WE KNOW ABOUT
CSMEDT 01,4 ;3-pen plotter, part 4 at end of P$CPEN
IFN CSM01$,< ;Assume pen is positioned close to the origin
CAIL T1,INCS*4 ;More than 4 inches?
MOVEI T1,INCS*4 ;Yes, don't waste time ramming the pen
> ;End of IFN CSM01$
MOVEM T1,J$YPOS(J) ;FAKE OUT THE LOW LEVEL OUTPUT ROUTINE
PUSH P,J$YMIN(J) ;SAVE MINIMUM Y POSITION
SETZM J$YMIN(J) ;CLEAR SO WE CAN GO BELOW IT
MOVE T1,J$XPOS(J) ;Use current X position
MOVEI T2,0 ;RAM THE PEN INTO THE AXIS
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;POSITION PEN
SETZM J$XMIN(J) ;ZERO X MINIMUM
SETZM J$YMIN(J) ;ZERO Y MINIMUM
SETZM J$XPOS(J) ;ZERO X POSITION
SETZM J$YPOS(J) ;ZERO Y POSITION
MOVE T1,J$XORG(J) ;GET ORIGINAL X MINIMUM
MOVE T2,(P) ;GET MINIMUM Y VALUE
MOVEI T3,PN.UP ;Pen up
PUSHJ P,PLOT ;PUT PEN THERE
MOVE T1,J$XORG(J) ;GET ORIGINAL X MINIMUM
MOVEM T1,J$XMIN(J) ;STORE IT
POP P,J$YMIN(J) ;RESTORE MINIMUM Y POSITION
IFN CSM01$,< ;RECAL has positioned pen #1 at YMIN
SETZM J$PENN(J) ;Flag that pen holder was reset
MOVEI S1,1 ;Select pen number 1
PUSHJ P,NEWPEN ;Tell the plotter which pen to use
> ;End of IFN CSM01$
POPJ P, ;RETURN
SUBTTL Plotter service -- Compute character size
P$CHKS: MOVE T1,J$YMAX(J) ;CALCULATE SIZE
SUB T1,J$YMIN(J) ; OF PLOTTING AREA
IDIVI T1,CHRPLN ;MAXIMUM NUMBER OF CHARACTERS PER LINE
CSMEDT 01,5 ;3-Pen plotter, part 5 at P$CHKS:+3
IFN CSM01$,< ;Don't plot giant letters on 36 inch wide paper
CAIL T1,INCS/6 ;Bigger than 1/6 inch?
MOVEI T1,INCS/6 ;Yes, reduce size
> ;End of IFN CSM01$
MOVEM T1,J$CSIZ(J) ;STORE CHARACTER SIZE
POPJ P, ;RETURN
SUBTTL Plotter service -- Line segments
;Call T1/ X Coordinate to move to
; T2/ Y Coordinate to move to
; T3/ Pen code as follows
PN.SAM==1 ;No Change in Pen
PN.DWN==2 ;Pen Down before Plotting
PN.UP== 3 ;Pen Up before moving
;
PLOT: $SAVE <T1,T2,T3,T4> ;PRESERVE TEMPORARIES
CSMEDT 08,6 ;PTC-6 Plotter Controller, part 6 at PLOT:+1
IFN CSM08$,< ;Delay testing of T3 if output to a terminal
SKIPN J$TTY(J) ;Is the plotter really a TTY?
> ;End of IFN CSM08$
CAIG T3,PN.SAM ;CHANGE REQUESTED?
JRST PLT.1 ;NO..PROCEED
SUBI T3,PN.UP ;Yes, get -1 or 0
CAMN T3,J$PPOS(J) ;PEN IN POSITION?
JRST PLT.1 ;YES -- PROCEED
MOVEI C,PNUP ;GET PEN UP CODE
SKIPGE T3 ;WANT IT LOWERED?
MOVEI C,PNDN ;YES..GET THE CODE
$CALL PLTBYT ;MOVE THE PEN
PLT.1: SUB T1,J$XPOS(J) ;COMPUTE DELTA X
SUB T2,J$YPOS(J) ;COMPUTE DELTA Y
IFN CSM08$,< ;Call external routine if PTC-6
SKIPE J$TTY(J) ;TTY? (T1, T2, and T3 set up)
JRST PTCMV ;Yes, calculate character string
> ;End of IFN CSM08$
MOVEI T3,XYD ;ASSUME DOWN MOVEMENT
SKIPG T1 ;IS THAT CORRECT?
MOVEI T3,XYU ;NO..ASSUME UP
MOVEI T4,XYL ;ASSUME LEFTWARD MOVEMENT
SKIPG T2 ;IS THAT CORRECT?
MOVEI T4,XYR ;NO..THEN ASSUME RIGHT
MOVMS T1 ;MAKE DELTA X POSITIVE
MOVMS T2 ;MAKE DELTA Y POSITIVE
CAML T1,T2 ;IS SMALLEST DELTA IN T2?
JRST PLT.2 ;YES -- PROCEED
EXCH T1,T2 ;NO -- MAKE IT SO
EXCH T3,T4 ;EXCHANGE MOVEMENT CODES
PLT.2: JUMPE T1,PLT.8 ;DONE IF NO MOVEMENT REQUESTED
JUMPE T2,PLT.6 ;PLOT ONLY ONE DIRECTION
SUBTTL Plotter service -- PTC-6 interface
IFN CSM08$,< ;T1 & T2 have delta movement, T3 has 2 or 3
PTCMV: ADDM T1,J$XPOS(J) ;Update position
ADDM T2,J$YPOS(J)
MOVE S1,J$XPOS(J) ;Get new X position
CAIL T3,3 ;Pen up?
JRST PTCMV1 ;No, skip next tests
CAMLE S1,J$XLIM(J) ;Highest seen so far?
MOVEM S1,J$XLIM(J) ;Yes
CAMGE S1,J$XLOW(J) ;Closest to the origin?
MOVEM S1,J$XLOW(J) ;Yes
;T1, T2, and T3 are set up with delta-X, delta-Y, and pen up/down code
PTCMV1: PUSHJ P,PTCMOV## ;Translate move, fall into OUTRSP
PAGE
;Routine to output the string pointed to by T1 and wait for response.
;S1 has accumulated increments for the last 4 buffers, to be used to
;predict how long it will take for the PTC-6 to respond.
OUTRSP: JUMPE T1,.POPJ ;Don't wait if no string
IMULI S1,PLTMOV ;Number of ticks to move
LSH S1,-2 ;S1 has count for 4 buffers
ADDM S1,J$PTIC(J) ;Predict elapsed time
IMULI S1,^D60*4 ;Cancel LSH, use seconds not minutes
IDIV S1,J$PTPM(J) ;Number of seconds required
ADDI S1,^D<512*10/CSM08$> ;512 chars take 2 seconds at 2400 baud
MOVNM S1,J$NACK(J) ;Negative to delay the complaints
OUTRS1: PUSHJ P,OUTSTG ;Send the string
OUTRS2: PUSHJ P,TIWAIT ;Get response, waiting up to 30 seconds
JUMPT OUTRS3 ;Got it
TXNE S,RQB+ABORT ;REQUEUE or ABORT?
$RETF ;Yes, give up
PUSHJ P,PTCOUT## ;Send string to raise pen
SETZM J$PPOS(J) ;(just to get controller to respond)
JRST OUTRS1 ;Loop until response or REQUEUE
OUTRS3: CAIE S1,.CHCRT ;CR at end?
JRST OUTRS2 ;No, skip over "0", "C"
PJRST TTYIN ;Yes, snarf up the LF (if it's there)
;Routine to output the string pointed to by T1.
;The Monitor will put the job in "TO" Terminal Output wait if there are more
;than 400 characters in the TTY chunks.
TOMAX=^D248 ;Avoid output wait for TTY
OUTSTG: JUMPE T1,.POPJ ;Return if nothing to do
HRLI T1,(POINT 7,) ;Make into ASCII byte pointer
OUTST1: MOVEI S1,0 ;Clear byte count
OUTST2: ILDB C,T1 ;Get a character
JUMPE C,OUTOUT ;Stop on null, output buffer, return
PUSHJ P,OUTBYT ;Send it
CAIG S1,TOMAX ;Almost enough to cause 'TO' wait?
AOJA S1,OUTST2 ;Loop till end of ASCIZ
PUSHJ P,OUTOUT ;Dump partial buffer
$DSCHD (TOMAX*^D10/CSM08$) ;Wait 1 second at 2400 baud
JRST OUTST1 ;(gives checkpoint routine a chance)
> ;End of IFN CSM08$
SUBTTL Plotter service -- Rotation and XY20 translation
;Plotter Translation Table Entry Description
; 0 17 20 23 24 27 28 31 32 35
; ================================================================
; ! XY20 CODE ! !ROT = 3!ROT = 2!ROT = 1!ROT = 0!
; ================================================================
;
ROTAB: EXP 0 ; 0 NO MOVEMENT
BYTE (18) 106 (2) 0 (4) XYU ,XYL ,XYD ,XYR ; 1 Minus X
BYTE (18) 102 (2) 0 (4) XYD ,XYR ,XYU ,XYL ; 2 Plus X
BYTE (18) 114 (2) 0 (4) PEN3,PEN3,PEN3,PEN3 ; 3 SELECT PEN3
BYTE (18) 104 (2) 0 (4) XYR ,XYU ,XYL ,XYD ; 4 Plus Y
BYTE (18) 105 (2) 0 (4) XYDL,XYUL,XYUR,XYDR ; 5 Plus Y & Minus X
;[CSM] BYTE (18) 103 (2) 0 (4) XYDR,XYDL,XYUL,XYUR ;MOVE UP+RIGHT
BYTE (18) 103 (2) 0 (4) XYDR,XYUR,XYUL,XYDL;[CSM] 6 Plus Y & Plus X
EXP -1 ; 7 ILLEGAL
BYTE (18) 100 (2) 0 (4) XYL ,XYD ,XYR ,XYU ;10 Minus Y
;[CSM] BYTE (18) 107 (2) 0 (4) XYUL,XYUR,XYDR,XYDL ;MOVE DOWN+LEFT
BYTE (18) 107 (2) 0 (4) XYUL,XYDL,XYDR,XYUR;[CSM]11 Minus Y & Minus X
BYTE (18) 101 (2) 0 (4) XYUR,XYDR,XYDL,XYUL ;12 Minus Y & Plus X
EXP -1 ;13 ILLEGAL
BYTE (18) 113 (2) 0 (4) PEN2,PEN2,PEN2,PEN2 ;14 SELECT PEN 2
EXP -1 ;15 ILLEGAL
EXP -1 ;16 ILLEGAL
BYTE (18) 112 (2) 0 (4) CNGP,CNGP,CNGP,CNGP ;17 CHANGE PENS
ROPTR: POINT 4,ROTAB(C),35 ;POINTER TO ZERO ROTATION
POINT 4,ROTAB(C),31 ; ROTATION = 1
POINT 4,ROTAB(C),27 ; ROTATION = 2
POINT 4,ROTAB(C),23 ; ROTATION = 3
SUBTTL Plotter service -- Pen movement generation
;Call C/ Character to plot
;
;Will adjust values in J$XPOS and J$YPOS based on pen movement
;Also checks range on J$XMIN-J$XMAX and J$YMIN-J$YMAX
;Saves highest pen movement in J$XLIM and J$YLIM
;
PLTBYT: $SAVE <S1,S2> ;[CSM] ;Preserve ACs
TRZE C,PNUP ;TEST AND CLEAR PEN UP CODE
$CALL PENUP ;RAISE PEN
TRZE C,PNDN ;TEST AND CLEAR PEN DOWN CODE
$CALL PENDN ;LOWER PEN
PLTXYD: TRNN C,XYD ;GOING DOWN?
JRST PLTXYU ;NO
TRNE C,XYU ;[CSM] ;Going +X and -X at the same time?
JRST PLTB.8 ;[CSM] ;Yes, this is a change-pen code
AOS S1,J$XPOS(J) ;+1
CAMG S1,J$XMAX(J) ;BEYOND X MAXIMUM?
CAMG S1,J$XMIN(J) ;WITHIN X BOUNDS?
TRZ C,XYD!XYU ;STOP MOVING
PLTXYU: TRNN C,XYU ;GOING UP?
JRST PLTXYL ;NO
SOS S1,J$XPOS(J) ;-1
CAMGE S1,J$XMAX(J) ;BEYOND X MAXIMUM?
CAMGE S1,J$XMIN(J) ;WITHIN X BOUNDS?
TRZ C,XYD!XYU ;STOP MOVING
PLTXYL: TRNN C,XYL ;GOING LEFT?
JRST PLTXYR ;NO
TRNE C,XYR ;[CSM] ;Going +Y and -Y at the same time?
JRST PLTB.8 ;[CSM] ;Yes, this is a change-pen code
AOS S2,J$YPOS(J) ;+1
CAMG S2,J$YMAX(J) ;BEYOND Y MAXIMUM?
CAMG S2,J$YMIN(J) ;WITHIN Y BOUNDS?
TRZ C,XYR!XYL ;STOP MOVING
PLTXYR: TRNN C,XYR ;GOING RIGHT?
JRST PLTB.6 ;NO
SOS S2,J$YPOS(J) ;-1
CAMGE S2,J$YMAX(J) ;BEYOND Y MAXIMUM?
CAMGE S2,J$YMIN(J) ;WITHIN Y BOUNDS?
TRZ C,XYR!XYL ;STOP MOVING
CONT. (PLTBYT)
PLTB.6: SKIPN J$PPOS(J) ;IS PEN DOWN?
PJRST PLTB.8 ;NO..DON'T RECORD MAX POSITIONS
MOVE S1,J$XPOS(J) ;[CSM] ;In case of no AOS or SOS was done
CAMLE S1,J$XMAX(J) ;CLIPPED?
JRST PLTB.7 ;YES -- DON'T ADJUST LIMIT
CAMLE S1,J$XLIM(J) ;HIGHEST POINT SO FAR?
MOVEM S1,J$XLIM(J) ;YES -- SAVE IT
CSMEDT 01,6 ;3-pen plotter, part 6 at PLTB.6:+5
IFN CSM01$,< ;Remember X minimum for positioning trailer after X maximum
CAMGE S1,J$XLOW(J) ;Smaller than the previous XLOW?
MOVEM S1,J$XLOW(J) ;Yes, user went near -X boundry
;therefore put dashed line close to plot
> ;End of IFN CSM01$
PLTB.7: CAMLE S2,J$YMAX(J) ;CLIPPED?
JRST PLTB.8 ;YES -- DON'T ADJUST LIMIT
CAMLE S2,J$YLIM(J) ;HIGHEST POINT SO FAR?
MOVEM S2,J$YLIM(J) ;YES -- SAVE IT
PLTB.8: JUMPE C,.RETT ;RETURN IF NOTHING TO PLOT
MOVEI S1,PLTMOV ;LOAD # TICS FOR MOVEMENT
ADDM S1,J$PTIC(J) ;ADD TO TOTAL SO FAR
; MOVE S1,[LDB C,ROPTR] ;GET ROTATE INSTRUCTION
; ADD S1,J$ROTA(J) ;OFFSET BY GRID ROTATION
; XCT S1 ;ROTATE
PJRST OUTBYT ;OUTPUT THE BYTE
CHRBAS==6
CHRWID==6
FIN==<CHRBAS>B31!<CHRWID>B35
PLTTAB: ;Characters used at Stanford (SUAI)
C%000: Z ;NULL IS ILLEGAL
C%001: XX <200,542,702,142,604,FIN> ;Down arrow
.XCREF ;[CSM] Don't CREF the rest
C%002: XX <144,563,603,622,621,600,560,541,542,563,603,624,FIN> ;Alpha
C%003: XX <561,701,702,663,642,241,643,624,603,601,FIN>;Beta
C%004: XX <602,544,FIN> ;Up angle bracket
C%005: XX <220,624,564,FIN> ;Negation
C%006: XX <243,641,620,560,541,543,200,602,FIN> ;Epsilon
C%007: XX <141,641,240,644,243,543,FIN> ;Pi
C%010: XX <602,240,544,FIN> ;Lambda
C%011: XX <240,661,604,564,543,562,602,644,FIN> ;Gamma
C%012: XX <242,641,620,560,541,543,564,624,643,642,702,704,FIN> ;Linefeed
C%013: XX <160,541,562,662,703,664,FIN> ;Integral
C%014: XX <240,644,302,562,160,564,FIN> ;Plus or Minus
C%015: XX <200,560,541,543,564,624,643,641,620,600,604,242,542,FIN> ;CR
C%016: XX <202,561,600,620,641,622,602,563,604,624,643,622,FIN> ;Infinity
C%017: XX <204,623,621,600,560,541,543,564,644,702,701,FIN> ;Delta
C%020: XX <244,641,620,560,541,544,FIN> ;Subset
C%021: XX <240,643,624,564,543,540,FIN> ;Element of
C%022: XX <160,640,661,663,644,564,FIN> ;Intersection
C%023: XX <260,600,561,563,604,664,FIN> ;Union
C%024: XX <300,600,542,604,704,240,644,FIN> ;All elements
C%025: XX <544,704,700,221,624,206> ;There exists
C%026: XX <100,640,600,561,562,603,643,603,564,FIN> ;Mu (micro)
C%027: XX <143,564,603,164,560,221,640,661,240,644,FIN>;Double arrow
C%030: XX <541,561,600,620,641,643,624,604,563,543,544,FIN> ;Omega
C%031: XX <220,624,262,624,562,FIN> ;Left arrow
C%032: XX <142,600,642,604,542,FIN> ;Formerly C%175 ;Diamond box [CSM]
C%033: XX <602,642,704,244,640,200,604,FIN> ;Not equal
C%034: XX <160,563,303,620,623,FIN> ;Less or equal
C%035: XX <300,623,620,160,563,FIN> ;Greater or equal
C%036: XX <160,564,224,620,260,664,FIN> ;Identically
C%037: XX <200,542,604,FIN> ;Down angle bracket
C%140: XX <341,703,FIN>
C%141: XX <163,542,541,560,620,641,643,563,544,FIN>
C%142: XX <300,540,543,564,624,643,640,FIN>
C%143: XX <224,643,641,620,560,541,543,564,FIN>
C%144: XX <304,544,541,560,620,641,644,FIN>
C%145: XX <143,541,560,620,641,643,624,604,600,FIN>
C%146: XX <141,661,702,703,664,220,622,FIN>
C%147: XX <144,541,560,620,641,643,624,524,503,501,FIN>
C%150: XX <700,220,641,643,624,544,FIN>
C%151: XX <141,543,542,642,641,262,702,662,FIN>
C%152: XX <121,502,503,524,644,643,FIN>
C%153: XX <700,243,601,600,602,544,FIN>
C%154: XX <141,543,542,702,701,FIN>
C%155: XX <640,620,641,622,542,622,643,624,544,FIN>
C%156: XX <640,200,642,643,624,544,FIN>
C%157: XX <160,620,641,643,624,564,543,541,560,FIN>
C%160: XX <100,640,643,624,564,543,540,FIN>
C%161: XX <144,541,560,620,641,644,504,FIN>
C%162: XX <640,200,642,643,624,FIN>
C%163: XX <543,564,603,601,620,641,644,FIN>
C%164: XX <301,561,542,543,564,240,642,FIN>
C%165: XX <240,560,541,542,604,644,544,FIN>
C%166: XX <240,600,542,604,644,FIN>
C%167: XX <240,560,541,562,642,562,543,564,644,FIN>
C%170: XX <644,240,544,FIN>
C%171: XX <240,560,541,544,244,524,503,501,FIN>
C%172: XX <240,644,540,544,201,603,FIN> ;z Lowercase Z
C%173: XX <144,543,562,602,621,620,621,642,662,703,704,FIN> ;{
C%174: XX <102,702,FIN> ;| Vertical bar
;[CSM] Put close brace and tilde where they belong in the ASCII code
C%175: XX <541,562,602,623,624,623,642,662,701,700,FIN> ;} 175, not C%176
C%176: XX <160,601,543,564,FIN> ;~ Tilde, formerly C%032
.CREF ;[CSM] ;OK to CREF now
C%177: XX <260,564,FIN> ;\ Backslash, duplicate of C%134
SUBTTL Paper tape punch service -- Dispatch table
T$DISP: JRST T$HEAD ;(0) FILE HEADER
JRST T$EOF ;(1) FILE TRAILER
SIXBIT /PTP/ ;(2) GENERIC DEVICE NAME
EXP PTPBSZ ;(3) OUTPUT BYTE SIZE
JRST T$PROC ;(4) PROCESS A FILE
JRST T$BANN ;(5) JOB BANNER
JRST T$TRAI ;(6) JOB TRAILER
JRST T$LETR ;(7) LETTER ProcessER
JRST .RETF ;(10) ERROR PROCCESSOR
CSMEDT 04,4 ;CSM accounting, part 4 at T$DISP:+11
IFE CSM04$,< JRST .RETT > ;(11) ACCOUNTING
IFN CSM04$,< JRST CSMACT > ;(11) ACCOUNTING
JRST T$CHKP ;(12) CHECKPOINT TEXT GENERATION
SUBTTL Paper tape punch service -- File processing
T$PROC: LOAD S1,.FPINF(E),FP.FFF ;GET FILE FORMAT
CAIN S1,.FPF11 ;/FILE:ELEVEN?
JRST PTELF ;YES, DO IT
LOAD S1,.FPINF(E),FP.FPF ;GET PAPER FORMAT
CAILE S1,PTROUL ;WITHIN RANGE?
JRST BADMOD ;NO, LOSE
JUMPN S1,@T$ROUT-1(S1) ;YES, DISPATCH IF NON-ZERO
CSMEDT 07,5 ;QUEUE defaults, part 5 at T$PROC:+6
IFE CSM07$,< ;This code will punch SOS files in BINARY mode
MOVEI S1,T$MTAB ;GET ADDRESS OF MODE TABLE
MOVEI S2,T$ROUT ;GET ADDRESS OF ROUTINE TABLE
PJRST DSPMOD ;AND DISPATCH BASED ON MODE
> ;End of IFE CSM07$
IFN CSM07$,< JRST PTASC > ;Default always to ASCII
T$ROUT: EXP PTASC ;ASCII
EXP PTIMA ;IMAGE
EXP PTIBI ;IBIN
EXP PTBIN ;BINARY
PTROUL==.-T$ROUT ;LENGTH OF ROUTINE TABLE
;MODE TABLE
T$MTAB: BYTE (3) 1,1,0,0,0,0,0,0,2,0,0,3,4,4,4,4
SUBTTL Paper tape punch service -- Byte output
; AC 'C' contains the byte to output
;
PTPBYT: $SAVE <S1,S2> ;[CSM] ;Preserve ACs
PUSHJ P,OUTBYT ;OUTPUT THE BYTE
AOS S1,J$TFRM(J) ;COUNT THE FRAME
IDIVI S1,FRMPFT ;COMPUTE FEET OF TAPE USED
MOVEM S1,J$APRT(J) ;STORE FOR ACCOUNTING PURPOSES
CAMLE S1,J$RLIM(J) ;EXCEEDED LIMIT?
PUSHJ P,FRMLEX ;YES - ASK THE OPERATOR'S ADVICE
POPJ P, ;[CSM] ;ACs automatically retored on return
; Repeat the byte in AC 'C'
; Call: MOVE S1,repeat count
; MOVE C,byte to output
; PUSHJ P,PTPREP
;
PTPREP: $SAVE <P1> ;[CSM] ;Save P1
MOVE P1,S1 ;GET COUNT
PUSHJ P,PTPBYT ;OUTPUT A BYTE
SOJG P1,.-1 ;AND LOOP
POPJ P, ;RETURN
SUBTTL Common Utilities
;PUTERR Routine to Move error Messages into J$XERR Buffer
; Call: MOVE S1,address if ITEXT block
; PUSHJ P,PUTERR
;
PUTERR: $CALL SETEBF ;POINT $TEXT TO ERROR BUFFER
$TEXT (DEPBP,<? ^I/0(S1)/^0>) ;YES -- MOVE TO BUFFER
$RETT
;HERE TO PRINT THE STRING IN J$XTBF(J) ON THE DEVICE
STRING: $SAVE <P1,P2> ;SAVE P1 AND P2
MOVE P1,[POINT 7,J$XTBF(J)] ;LOAD A BYTE POINTER
MOVE P2,J$LSER(J) ;AND ADDRESS OF DISPATCH TABLE
STRI.1: ILDB S1,P1 ;GET A BYTE
JUMPE S1,.RETT ;END OF STRING
PUSHJ P,DLETR(P2) ;PRINT THE LETTER
JRST STRI.1 ;AND LOOP
;HERE TO SETUP A BYTE POINTER TO THE J$XTBF(J) BUFFER
SETTBF: MOVEI TF,J$XTBF(J) ;GET THE ADDRESS OF TEXT BUFFER
HRLI TF,(POINT 7,0) ;MAKE A POINTER
MOVEM TF,TEXTBP ;STORE THE BYTE POINTER
MOVEI TF,TXT$LN*5 ;GET BYTE COUNT
MOVEM TF,TEXTBC ;AND SAVE IT
SETZM J$XTBF(J) ;ZAP FIRST WORD
$RETT ;AND RETURN
SETEBF: MOVEI TF,J$XERR(J) ;GET THE ADDRESS OF ERROR BUFFER
HRLI TF,(POINT 7,0) ;MAKE A POINTER
MOVEM TF,TEXTBP ;STORE THE BYTE POINTER
MOVEI TF,ERR$LN*5 ;GET BYTE COUNT
MOVEM TF,TEXTBC ;AND SAVE IT
SETZM J$XERR(J) ;ZAP FIRST WORD
$RETT ;AND RETURN
PAGE
CSMEDT 07,6 ;QUEUE defaults, part 6 before DSPMOD:
IFE CSM07$,<
;HERE TO DISPATCH TO A processing ROUTINE BASED ON FILE MODE.
; S1 CONTAINS THE MODE-TABLE ADDRESS AND S2 CONTAINS THE ROUTINE-
; TABLE ADDRESS.
DSPMOD: $SAVE <T1,T2,T3,T4> ;SAVE SOME ACS
MOVE T1,J$DMOD(J) ;GET THE MODE
IMULI T1,3 ;3 BITS/MODE
DMOVE T2,0(S1) ;GET THE MODE TABLE
LSHC T2,(T1) ;GET THE CORRECT BYTE ON TOP
LDB T2,[POINT 3,T2,2] ;AND PICK IT UP
JUMPE T2,BADMOD ;LOSE BIG
ADD S2,T2 ;ELSE ADD IT IN
JRST @-1(S2) ;AND DISPATCH
> ;End of IFE CSM07$
BADMOD: MOVEI S1,[ITEXT (<Illegal file mode ^O/T2/>)]
PJRST PUTERR ;AND FORCE IT OUT
LITS: XLIST ;[CSM] Literals
LIT ;[CSM]
LIST ;[CSM]
SPOEND::END SPROUT