;-*-MIDAS-*- title XGPSPL XGP unspooler subttl Definitions, etc... a=1 b=2 c=3 d=4 e=5 t=6 ;super temporaries, not prserved over subroutine calls tt=7 x=10 z=11 y=12 x0=13 y0=14 font=15 ;font index chnl=16 ;ten to 11 channel p=17 .xcref a b c d e t tt x z y x0 y0 font chnl p xx nq1bq2==5 ;number of things from q1 before q2 ;don't forget to change XGPDEV when you ;change this!!! nchnl==3 ;# of 10 to 11 channels we are willing to admit cochnl==0 ;command out cichnl==1 ;command in dochnl==2 ;data out ;time sharing i/o channels ch==,,-1 ;Bit typeout mask chttyi==0 ;TTY input chttyo==1 ;TTY output chfnti==2 ;Font file input chtxti==3 ;Text and SCN and PLX file input cherri==4 ;ERR: device input chcmdi==5 ;Queue file input chstao==6 ;Status file output chmail==7 ;Mail (notification) output chfoo==10 lambda==10.*60. ;10 second time out on xgp pagpsl==5 ;Number of pages we assume were lost when hardware complains. xgp11==1 ;identification # of xgp pdp-11 maxfnt==20 ;maximum # fonts we will send to pdp11 tty1==3 ;only these ttys can send to xgp tty2==24 mapmsk==574377776000 ;mask to type 10-11 map table entries define conc a,b,c a!b!c termin mk==117. ;max number of blocks allowable for plot files wdspl==51.+2 ybitl==51.*32. xbitl==11.*200. bytmax==52.*4 pjrst==jrst ;replace PUSHJ/POPJ pair define syscal call,args .call [setz ? sixbit/call/ ? args ((setz))] termin loc 42 jsr tsint loc 70 ; NOTE!! Do not, repeat, NOT mung these locations without changing ; XGPDEV too. XGPDEV depends upon locations 70-101 being these parameters ; and in this order(when it reads USR:XGP XGPSPL). cuname: 0 ;Uname of request currently being printed xslver: .fnam2 ;version of this XGPSPL nffq1: 0 ;number of frobs from q1 forms: 0 ;-1 if thesis forms, 0 if normal, 1 if waiting ;for forms change cqin: 0 ;queue index number of current request abortf: 0 ;-1 if XGP 11 program gronked or abort req. maintr: 0 ;-1 if actually in maint mode (not just ^X typed). idlep: -1 ;0 if not idle ;-1 if idle ;>0 (error code)if losing filsiz: -1 ;size of current file in words, or -1 if unknown filptr: 0 ;# words output so far from current file. lsterr: 0 ;address of error message describing XGP lossage. ;0 => XGP and pdp-11 not known to be losing, ;except can be nonzero temporarily ;while TYI is being called. subttl data areas pdl==60 pdb: block pdl nxgpfw: 0 ;0 or mapped address of system's nxgpfw variable lxgpfw: -1 ;last value of that variable seen (aoses when file written on .XGPR.) bypr: 0 ;bytes per row while loading fonts cmdfil: 0 ;spooled command file active flag dothis: 0 ;which queue to "Continue printing this file" from. See abort logic. dskcmd: 0 ;reading commands from text file (NOT queue file) flag ;-1 => reading, 1 => stop after this line, 0 => not reading. qtype: 0 ;patch this non-zero to type out queue files as read chsts: block 8 ;storage for currently plotted/scanned file txtbfl==200 txtcnt: 0 ;text buffer counter txtptr: 0 ;byte pointer into text buffer txtflg: 0 ;negative=>eof seen txtrhd: 0 ;-1 => a word of read-ahead is in txtrhw. txtrhw: 0 ;a word of read ahead saved from one bufferfull for the next one. ;This makes sure that eof is always anticipated by at least one word, ;for the sake of flushing ^C's from the end of the file. 0 ;dummy text buffer location used for end ;test at dbplr... must precede txtbuf txtbuf: block txtbfl txtpos: 0 ;char pos in file of where we are reading from the buffer. combfl==200 comcnt: 0 ;# chars left to read from the command. compnt: 0 ;pointer to read from the command. combuf: block combfl ;buffer for the current command line. qfn1: 0 ;fn1 of current queue file, zero if none qfn2: 0 quitf: 0 ;non-zero if aborted file should go last in queue. ;-1 means ask user for ABFLSF setting. 1 means ABFLSF already set. abflsf: 0 ;non-zero if aborted file shouldn't be requeued at all. oforms: 0 ;While switching forms (FORMS > 0), this has old value of forms. notflg: 0 ;non-zero ;NOTIFY seen notluz: 0 ;non-zero => notification contains error messages, so mail, not just send. notbfl==200 notcnt: 0 ;# chars used in notbuf notpnt: 0 ;pointer for storing into notbuf notbuf: block notbfl ;Text to send as notification. All error messages appended to it. notusl==10 notusr: block 10 ;Name of user to send notification to. nothst: 0 pfnbuf: block 10 ;buffer for printing filenames. centf: 0 ;-1 => plotting a subsheet of a multi-sheet plot. buf: block 200 ;buffer for plot files. bufl==.-buf t11pag: 0 ;next page to get from 11 buforg: 0 ;origin of buffers in 11 space txtdev: sixbit/DSK/ ;Filenames of file we are printing. txtfn1: 0 txtfn2: 0 txtsnm: 0 newtxt: 0 ;non-zero text file spec changed, re-open, otherwise can .access to 0. maintp: 0 ;-1 => want to be in maint mode for next file (parity of ^X's typed) ;as opposed to maintr, which says we are in maint mode right now. ;default page parameters iinitx0==1100. iinity0==-180. isqshfl==0 ilftmar==200. itopmar==200 ibotmar==174 islines==3504 ;vsp, slines, topmar, botmar set to make 60 lines of 25fg per page iplines==islines+itopmar+ibotmar ilsp==-1 dlsp==25.+6 ;25 high font + 6 lines of vsp ivsp==-1 ;default is to use lsp dvsp==6 iautcut==-1 iffcut==0 itxtcmd==-1 iudepth==-1 ;page parameters initx0: 0 inity0: 0 sqshfl: 0 ;non-zero => ;SQUISH, so squish useless chars out of fonts lftmar: 0 topmar: 0 ;allows 60 lines of text on one 11" page botmar: 0 nlines: 0 ;11 inches autcut: 0 ;-1 => cut paper evry so many inches. ffcut: 0 ;non-zero forces xgp to cut only at form feeds pskip: 0 ;# pages to skip at begining txtcmd: 0 ;0 implies dont look for commands in text file lsp: 0 ;base line spacing vsp: 0 ;-1 => use lsp, other wise lspheight+vsp udepth: 0 ;# prints in progress plines: 0 ;# scan lines on page slines: 0 ;# scan lines in text area page: 0 ;page # of first printed page tpages: 0 ;# of title pages in current ;title group. dfhdrf: 0 ;-1=>put default header on each page hdrcnt: 0 ;# characters in page header hdrtxl==<200+4>/5 ;size of text header area hdrtxt: block hdrtxl ;buffer for header text prsqsh: 0 ;-1 => file was pre-squished, and had ;KSUBSET commands. ;SQSHTB was set up by them, so we need not squish. sqshtb: block 200 ;one word for each ascii char ;bit 4.9 = font 0, 4.8 = font 1, etc. ;bit set => this char in this font is needed by the file. opcode: 0 ;Which operation should be performed on this file? op%txt==0 ;0 => print as text. op%plt==1 ;1 => plot it as PLX file. op%scn==2 ;2 => treat it as a SCN file. op%smp==3 ;3 => treat it as a font and make a sample of it. ;font variables fntspc: 0 ;-1 => fonts have been specified explicitly. ;A ;KSET in the file being printed doesn't count. fntbeg:: fnto: sixbit /DSK/ fntfn1: sixbit /25FG/ ;used as a flag, if 0 then font not specified fntfn2: sixbit /KST/ fntsnm: sixbit /FONTS/ height: 0 ;height of font base: 0 ;base line cpa: 0 ;column positon adjustment kstid: 0 ;font id fchflg: -1 ;-1=> transmit to 11 fntvln==.-fntbeg ;length of font variable area loc fntbeg+ delbeg:: ;Beginning of delete queue variables. delete:: deltxt: 0 ;-1 => delete this text file when done. delqln==10. delque: block delqln ;for each file on delete que, time (uptime in 30'ths) at which to delete. delqdv: block delqln ;device, fn1, fn2 and sname for each file on queue. delqf1: block delqln ;An entry which is not in use is all zeros. delqf2: block delqln delqsn: block delqln delend:: ;End of delete queue variables. cskip: 0 ;# of chars to skip at beginning (using .ACCESS) before printing. pagpos: block pagpsl ;Hold cskip values -- char positions in file -- of last pagpsl pages. ;The last word applies to the last page. tskip: 0 ;# of chars to skip at beginning before looking for commands in file. ttlpos: block pagpsl ;Like pagpos but holds tskip values rather than cskip values. baspag: 0 ;page number of page we started printing on. junk: block 10 ;Can be supplied as address of where to store some garbage data. ;10-11 channel data areas cmdpar: block nchnl ;parity cmdcnt: block nchnl ;bugger byte counter cmdsiz: block nchnl ;size of this buffer cmdbuf: block nchnl ;byte pointer to first 11 word of buffer cmdptr: repeat nchnl,conc cmdpt,\.rpcnt,(t) repeat nchnl,[ conc cmdpt,\.rpcnt,[: block 2] ] chhdrp: repeat nchnl,chhdr+*.rpcnt subttl Initialization and main loop go: .suset [.runame,,a] came a,[sixbit /XGP/] .value [asciz /:You must be logged in as XGP /] move p,[-pdl,,pdb-1] ;get a pdl .open chttyi,['TTY] ;open the tty .lose %lssys .open chttyo,[1,,'TTY] .lose %lssys pushj p,vertyp .core icore ;reduce to initial core .lose %lssys setzm cmdfil movei a,lnkvpg movem a,t11pag syscal T11MP,[t11pag ? [<3_34.>\1777\\]] .value nopdp11 skipn 10lnkv .hang ;wait for 11 to set things up move a,[%pirlt+%piioc+%picli] movei b,1_ .setm2 a, move a,[200000,,b] movei b,lambda ;xgp time out .realt a, jfcl push p,[442000,,10lnkv] ildb a,(p) ;points at channel headers ildb b,(p) ;# channels imuli b,bprchl ;# bytes in area pushj p,get11 ;get that page ildb a,(p) ;origin of buffer area ildb b,(p) ;size (bytes) movem a,buforg sub p,[1,,1] pushj p,get11 ;get buffer in map movei chnl,cochnl pushj p,open setzm nxgpfw move a,[squoze 0,nxgpfw] .eval a, jrst recycl ldb b,[121000,,a] syscal corblk,[ %climm,,%cbndr ? %climm,,%jself ? %climm,,syspag %climm,,%jsabs ? b] .lose %lsfil movei b,syspag dpb b,[121000,,a] movem a,nxgpfw .suset [.roptio,,a] tlne a,%opcmd ;if we have JCL, enter maint mode setom maintp ;before considering anything on the queue. ;main loop recycl: move p,[-pdl,,pdb-1] ;reset the stack movei chnl,cochnl setzb font,dskcmd setzm abortf ;XGP not believed to be losing until we find that it is. setzm lsterr pushj p,vreset ;reset variables and flush core. pushj p,freset ;reset fonts pushj p,nreset ;Reset some things special for top level loop. pushj p,cmnds ;get command from tty or other ;Important error: give up trying to print file, but do send a notify, ;which will contain the error message. lossag: move p,[-pdl,,pdb-1] ;reset the stack pushj p,notify ;Come here after doing one actual output (;SCAN or ;PLOT or ;PRINT or ;LIST, etc) done: skipe cmdfil ;No queue file is allowed to specify more than one, jrst cmdeof ;so mark this one "finished" and flush it. jrst recycl ;this is the file name reader RFN"$$RUC==1 RFN"$$RFN==1 RFN"$$PFN==1 rfn"ruc: pushj p,comget cail a,140 subi a,40 popj p, rfn"rsixtp: cain a,^J jrst popj1 jrst (t) if2 rfn"psixtp=cpopj ;CONC prevents @ from seeing this. .INSRT SYSENG;RFN > ;To read in a filename, call RFNM. ;B should contain the address of the block to store it in, ;which will hold the device, fn1, fn2 and sname in that order. ;T should contain a routine to skip if the character in A ;is a break character. Note that CR and LF are always break characters anyway. ;On return, A has the terminating character. ;E is zero if the filespec was null. rfnm==rfn"rfn ;Get a stream (such as a queue file) to read commands from. ;Read the commands, returning when we have read the name of a file to print. cmnds: skipe maintp ;If we are supposed to be in maint mode, jrst maintm ;enter it or remain in it. .suset [.ssname,,['.XGPR.]] ;read from spooling directory skipe forms ;are thesis forms mounted? jrst cmdtss ;yes, only do thesis requests skipn a,dothis jrst donorm setzm dothis cain a,'Q1 ;continue interrupted listing jrst cmdq1 cain a,'Q2 jrst cmdq2 cain a,'Q3 jrst cmdq3 donorm: .open chcmdi,['DSK ? sixbit/ Q10/] caia ; no ;PRIORITY request jrst cmdopn ; yes, this is VERY special move a,nffq1 cail a,nq1bq2 jrst cmdq2a cmdq1: .open chcmdi,['DSK ? sixbit/ Q1 unhang please move a,@nxgpfw movem a,lxgpfw jrst cmnds subttl command processing ;Having just found a queue file to process, set up to read it. cmdopn: syscal RFNAME,[movei %jself ? movei chcmdi ? movem b ? movem a ? movem b] .lose %lsfil ;can't get filename?? movem a,qfn1 ;save queue file name movem b,qfn2 andi a,'_ ;only want queue number rot a,-6 ;get queue number left justified lsh b,-6 ;get queue state number movem a,cqin ;save queue number iorm b,cqin ;and save the current QIN for later reference setzm idlep ;not idle any more move b,[010700,,combuf-1] ;load byte pointer setom cmdfil ;indicate command file active setzm maintr ;And not now in maintenance mode. jrst comman ;Enter maintenance mode, or reenter after printing a file. maintm: skipe maintr ;Were we already in it? jrst comman movei b,[ASCIZ/ XGP testing mode /] pushj p,outstr movsi b,'dsk ;When we first enter maint mode, reset default device. movem b,txtdev setom maintr ;Read the next command from the stream we are reading from. comman: skipn maintp skipe cmdfil caia jrst cmnds ;No stream to read from now => look for another. skipn cmdfil ;Read from tty, if not processing a queue file. jrst maint1 ;We already know that we must be in maint mode. pushj p,cmdlin ;Read stream from queue file, if reading one. jrst coman1 ;Remain in maintenance mode after a ;SKIP, etc. maint1: movei b,[ASCIZ /-->/] pushj p,outstr setom idlep ;claim to be idle pushj p,ttylin ;gobble message from XGP TTY setzm idlep ;claim to be doing work coman1: pushj p,spcsk1 ;Skip past initial spaces in the command. cain a,"; ;If line's first nonblank is a ";", it is jrst alter ;a special command. cain a,^j ;If it is a ^J, this is a blank line. Ignore it. jrst comman coman2: pushj p,combac ;Otherwise we just read 1st char of filename. Unread it. move a,opcode ;Then go print, plot, etc. the file. The operation routines jrst @optab(a) ;read the filename since some do it differently. optab: jrst prtfil ;Go print the file. jrst plotfil ;Go plot it jrst scanfil ;Go print as bit map SCN file jrst sampfil ;Go make sample of font. ;Here when a command is read that consists of a filename to print. prtfil: movei b,txtdev ;Else it starts with a filename to print. Parse it, movsi a,(SIXBIT/>/) movem a,txtfn2 move tt,txtdev movei t,[ cain a,"_ ;Stopping if we see an unquoted "_". aos (p) popj p,] pushj p,rfnm setom newtxt exch tt,txtdev ;If user specifies a device of DSK, don't change his default. came tt,['DSK,,] movem tt,txtdev getfnt: cain a,15 pushj p,comget ;ignore carriage returns pushj p,spcsk2 ;bugs in @ and xqueue manage to get ^M ^J cain a,12 jrst ptext ;end of line, no font specs. caie a,"_ skipa b,[[asciz /Ignoring font spec/]] pushj p,getf0 ;read font file names jrst comerr ptext: move p,[-pdl,,pdb-1] ;reset the stack. Come back here after printing title pages. pushj p,txtopn ;open text input file jrst txtluz ; file not found pushj p,open ;open up the data channel .call [ setz ? 'TTYVAR ? movei chttyo ? ['IDLTIM] ? setzi 0 ] jfcl ;We're doing something, zero idle time (for F) pushj p,prschk ;Barf at press files. skipe txtcmd ;Unless inhibited, read ";" commands from text file. pushj p,rtxtcm ;read settings from txtfile skipe sqshfl ;squish? skipe prsqsh ;and not done by XQUEUE already? jrst recyc2 skipe tpages ;and not in title pages (squishing not done on them)? jrst recyc2 pushj p,prescn ; must perform pre-scan pushj p,txtopn ;then re-open the text file. jrst txtluz recyc2: pushj p,fonts ;send those fonts movei font,0 pushj p,notify ;send notification if any pushj p,sndtxt ;skip pages and send remainder .close chtxti, pushj p,delchk ;delete any text files whose time has come. skipe deltxt pushj p,delreq ;request deletion of this file in 1 minute if all well. jrst done ;Assuming that the data of a file is already in TXTBUF, ;refuse to print it if it looks like a press file. prschk: move a,[-txtbfl,,txtbuf] setz b, ior b,(a) ;IOR all the file words together, aobjn a,.-1 trne b,17 ;If any word has one of the low four bits, that is good. popj p, movei a,txtdev ;Otherwise it is a press file (or so it seems) movei b,[asciz /Text /] ;so refuse to print it. push p,a pushj p,eprnt pop p,b move d,[440700,,pfnbuf] pushj p,rfn"pfn ;Convert filenames to a string. movei b,pfnbuf pushj p,eprnt ;Print it on tty and into notification. movei b,[asciz / IS NOT A TEXT FILE /] pushj p,eprnt jrst lossag ;routine to read font file names, assuming the "_" has already been read. ;No skip => ASCIZ string error message is in B. getf0: movei t,[ ;Comma terminates a font file name. cain a,", aos (p) popj p,] skipn dskcmd setom fntspc movei font,0 move c,[sixbit /dsk/] ;Initial sticky defaults for device and directory move d,[sixbit /fonts/] getf0a: movei b,fnto(font) ;Parse the next font's filename. skipe fntspc skipn dskcmd ;If this is a ;KSET inside a file being printed, jrst getf0b skipn fchflg(font) ;and this font was already specified, jrst getf0b movei b,junk ;don't override the user about it. pushj p,rfnm jrst getf2 getf0b: movem c,fnto(font) ;First store in last font's device and dir as defaults. movem d,fntsnm(font) pushj p,rfnm tlnn e,17 ;If it was empty, jrst getf2 ;this font isn't specified. movsi b,'KST tlne e,1_rfn"fn1 ;If FN1 was spec'd and not FN2, default FN2 to KST. tlne e,1_rfn"fn2 caia movem b,fntfn2(font) ;fnam2 setom fchflg(font) cain a,15 pushj p,comget ;ignore carriage returns getf2: caie a,15 ;End of line => no more fonts specified; return. cain a,12 jrst popj1 move c,fnto(font) ;more fonts left => get this font's dev and dir as move d,fntsnm(font) ;defaults for next one, and loop to read the next filename. addi font,fntvln caie a,", jrst [ movei b,[asciz /Ignoring junk at end of font specs./] popj p,] caige font,maxfnt*fntvln jrst getf0a ;go back for more movei b,[asciz /Ignoring excess fonts. 16. is the maximum./] popj p, ;routine to demand forms change formsc: skipe a,forms ;determine which message to do skipa b,[[asciz/Mount normal forms in the XGP/]] movei b,[asciz/Mount thesis forms in the XGP/] setzm forms ? aos forms ;indicate waiting for funny forms movem a,oforms ;remember what type of forms now loaded in case quit. pushj p,outstr ;and type message movei b,[asciz/ Type any character when ready (^G to refuse) ->/] pushj p,outstr ;and output prompt message .reset chttyi, ;flush input movei a,[asciz/waiting for forms change/] pushj p,tyi move a,oforms ;we got the char ok, and wasn't ^G, so forms were changd. setcam a,forms popj p, subttl Read and buffer a command line ;Read a line from the current queue file. cmdlin: setzm comcnt move b,[010700,,combuf-1] ;load command byte pntr movem b,compnt ;save it cmdln1: .iot chcmdi,a andi a,177 cain a,^L ;ignore form feeds. They are used by requeueing. jrst cmdln1 .see abort3 jumpe a,cmdln1 ;ignore nulls aosn abortf ;abort? jrst abort cain a,^C ;EOF? jrst cmdln2 ;yup skipe qtype ;if desired, .iot chttyo,a ;echo on XGP TTY cmdln3: pushj p,comput ;save the character caie a,^J ;hit the ? jrst cmdln1 ;nope, gobble down more popj p, cmdln2: movei a,^J ;If EOF is not after a null line, skipe comcnt ;Finish the unterminated line. Will come back here jrst cmdln3 ;after that command. ;delete old done queue entry, put current entry in the done queue, and close ;off the channel cmdeof: setzm cmdfil ;indicate no command file active now move a,['dsk,,] ;Make sure our defaults our unsurprising, movem a,txtdev ;in case we now enter maintenance mode. move a,['.xgpr.] ;(.XGPR. is as good as anything) movem a,txtsnm syscal DELETE,[['DSK,,] ? [sixbit/DONE/] ? [sixbit/QUEUE/] ? ['.XGPR.]] jfcl ;guess no queues done syscal RENMWO,[movei chcmdi ? [sixbit/DONE/] ? [sixbit/QUEUE/]] jfcl .close chcmdi, ;close off channel jrst recycl ;Look for next queue file, or enter maint mode. ;fill combuf with a command line from disk file ;This is used for the commands that go at the front of files being printed, ;not for queue files. dsklin: setzm comcnt move b,[010700,,combuf-1] movem b,compnt dskl1: pushj p,txti jumpe a,dskl1 ;ignore nulls jumpl a,dskstp ;eof? caie a,^C cain a,^L jrst dskstp ;on EOF or end of page, treat as newline and stop reading the file. cain a,^J ;Treat LF as a newline. jrst dsklf caie a,^M ;ignore carriage returns pushj p,comput jrst dskl1 dskstp: movei a,1 ;stop reading from disk file after this line movem a,dskcmd dsklf: movei a,^M pushj p,comput movei a,^J pushj p,comput movei a,0 jrst comput ;Read a command line from the TTY, in maintenance mode. ttylin: move b,[010700,,combuf-1] setzm comcnt ttyl1: setz a, pushj p,tyi jumpe a,ttyl1 cain a,177 jrst rubout ;rubout cain a,4 jrst [ movei b,[asciz / <--/] pushj p,outstr pushj p,sout ;control-d cancels whole line jrst ttylin] cain a,14 jrst ttyff ;form feed retypes buffer cain a,15 jrst ttycr cain a,12 jrst ttylf pushj p,comput jrst ttyl1 ;Read a character of input. If not in maintenance mode, ;then if we don't get any input for 5 minutes we tell everyone on the queue. ;A should contain a string to tell them, or 0 to use LSTERR. ;The caller should also bind LSTERR to a short string if the ;XGP status is not going to know about this state for any other reason. tyi: skipe maintp jrst tyimnt skipn a move a,lsterr skipn a .value push p,b push p,d movei b,5*60./2 ;# of 2-second intervals to sleep before crying loud for help. abcry1: movei d,60. .sleep d, .listen d, ;If there's input, we've been noticed, jumpn d,abcry2 ;so don't cry for help. sojg b,abcry1 ;If time interval elapses and no input, pushj p,cry ;yell at everyone on the queue. abcry2: .iot chttyi,a ;Now that we told them, we can just wait for input. pop p,d pop p,b popj p, tyimnt: .iot chttyi,a popj p, rubout: sosge comcnt jrst [ pushj p,crlf jrst ttylin] ldb a,b pushj p,tyo pushj p,decbp ;decrement byte pointer jrst ttyl1 decbp: add b,[070000,,0] jumpge b,cpopj sub b,[430000,,1] popj p, ttyff: push p,b ;form feed retypes buffer push p,c pushj p,crlf skipg c,comcnt jrst ttyffx move b,[010700,,combuf-1] ttyff1: ildb a,b pushj p,tyo sojg c,ttyff1 ttyffx: pop p,c pop p,b jrst ttyl1 ttylf: movei a,15 pushj p,tyo ttycr: pushj p,comput movei a,12 pushj p,comput move b,[010700,,combuf-1] movem b,compnt popj p, comput: camn b,[010700,,combuf+combfl-1] popj p, idpb a,b aos comcnt popj p, subttl ";"-command processing ;Process a line starting with a ";" from a queue file or the tty. alter: pushj p,spcskp ;skip over spaces, tabs, and crs cain a,12 jrst comman ;ignore blank alter commands altcom: pushj p,decode jrst [ pushj p,huh jrst comman] ;undefined command pushj p,spcskp move c,comtab(b) pushj p,(c) pushj p,comerr ;routine lost, print err msg (asciz string addr in B) pushj p,comxit ;gobble up rest of line jrst comman ;back to print mode ;here to skip over spaces in command line spcskp: cain a,12 ;don't skip over line feed popj p, spcsk1: pushj p,comget spcsk2: caie a,40 cain a,11 jrst spcsk1 cain a,15 jrst spcsk1 popj p, ;tty level command return comerr: push p,a comer1: pushj p,terprn pushj p,terpri popxit: pop p,a comxit: cain a,12 popj p, pushj p,comget jrst comxit huh: movei b,[asciz /Unknown command/] jrst comerr badarg: movei b,[asciz /Argument error/] popj p, pophuh: pop p,a althuh: movei b,[asciz /Syntax error/] popj p, ;read next character from buffer command line, into A. comget: sosge comcnt jrst gronkd ildb a,compnt popj p, gronkd: setzm idlep ? aos idlep .value [asciz\:Spooler gronked  .jpc/q/\] ;Back up one character (unread it) in command line. combac: move b,compnt pushj p,decbp ;decrement byte pointer movem b,compnt aos comcnt popj p, ;command dispatch table define xx name,routin [sixbit /name/],,routin termin ;should be in alphabetical order ;all these routines should skip return if no errors ; error return with pointer to asciz string in b ; norml return ;Routines that actually send to the XGP should return, if successful, to DONE. comtab: xx autcut,setcut xx botmar,setbot xx cskip,xcskip xx defaul,defaul xx delete,delcmd xx ffcut,setffc xx header,header xx height,shwhgt xx kill,kill xx kset,kset xx ksubset,ksubset xx lftmar,setlft xx list,list xx lsp,setlsp xx nlines,setlin xx notify,donote xx noxgp,cpopj1 xx plot,plot xx print,print xx priori,print xx reset,reset xx rotate,rotate xx sample,sample xx scan,scan xx show,show xx size,size xx skip,setpsk xx sndfnt,fontsa xx squish,squish xx status,status xx test,settst xx thesis,print xx title,xtitle xx topmar,settop xx tskip,xtskip xx txtcmd,setxtc xx verse,verse xx vsp,setvsp xx x0,setx0 xx y0,sety0 comtbl==.-comtab ;reads commands from text file rtxtcm: aosn abortf jrst abort push p,udepth ;to see if it changes push p,dskcmd setom dskcmd txtcm1: skipl dskcmd jrst txtcxt pushj p,dsklin ;get command from disk pushj p,comget ;get command character cain a,^M jrst txtcm1 ;ignore null line caie a,"; jrst txtcxt ;exit pushj p,spcskp cain a,12 jrst txtcm1 ;ignore null command line movei b,combuf push p,a skipn cmdfil pushj p,outstr ;let him know what's going on pop p,a pushj p,decode jrst txtcxt ;not in table, go away pushj p,spcskp move c,comtab(b) pushj p,(c) pushj p,comerr ;give error message for lossage pushj p,comxit jrst txtcm1 ;here to exit text file command reader txtcxt: pop p,dskcmd pushj p,txtopn ;reopen, it might even be a different file jrst txtluz ; can't => error message and give up. pop p,a came a,udepth jrst rtxtcm ;that was the command file, now read the print file popj p, ;here to decode command decode: move c,[440600,,d] tdza d,d decod1: pushj p,comget pushj p,cvsix ;convert to six bit jumpl b,[ cain a,15 pushj p,comget ;ignore carriage returns cain a,12 jrst decod2 popj p,] ;command not understood jumpe b,decod2 ;search command table tlne c,770000 idpb b,c ;only 6 characters jrst decod1 ;look up command in d decod2: jumpe d,[ cain a,": jrst decode ;don't screw for leading colon popj p,] ;error movei b,comtbl-1 decod3: movs c,comtab(b) camn d,(c) jrst popj1 ;found him sojge b,decod3 popj p, ;not found ;convert a to sixbit, leave result in b cvsix: cain a,11 movei a,40 movni b,1 ;assume not sixbit cail a,"a caile a,"z caia ;not lower case subi a,40 ;lower case: upper caseify cail a,40 ;now check for sixbit caile a,"_ popj p, ;not sixbit movei b,-40(a) ;convert from ascii to sixbit popj p, ;read in a decimal number and leave result in d ; non-skip return, number not read ;call with first character already in a. ;break character left in a. decin: movei c,1 ;sign cain a,"- pushj p,[ movni c,1 ;negative number jrst comget] pushj p,cvdig ;convert character code to digit jumpl b,cpopj ;not a digit, no number there tdza d,d decin1: pushj p,comget pushj p,cvdig ;leave digit in b jumpl b,[ jumpge c,popj1 movns c movns d jrst popj1] imuli d,10. imuli c,10. ;keep track of digits read add d,b jrst decin1 ;Read octal number into D. ;Call with first character already in A. ;Break character left in A. octin: setz d, octin1: pushj p,cvdig ;Try converting char in A to its value as a digit. jumpl b,cpopj ;Return when we come to a non-digit. imuli d,10 ;Accumulate digits into the result. add d,b pushj p,comget ;and move on in the command string. jrst octin1 ;covert digit in a to number cvdig: movni b,1 ;assume failure cail a,"0 caile a,"9 popj p, ;failure movei b,-"0(a) popj p, ;get positive argument ; non-skip return for failure posarg: pushj p,argin popj p, jumpl d,cpopj jrst popj1 argin: pushj p,decin popj p, ;error return pushj p,spcsk2 cain a,12 cpopj1: aos (p) popj p, subttl ;TITLE and title pages ; ;TITLE identifies the next pages (after this one) as title pages. ; It is allowed only in a file being printed. ; We continue to look for semicolon commands, and print the file as usual, ; except that after pages have been processed we mark all of the file so far ; as processed titles (by setting tskip) and pretend that the file begins ; at the point we have reached. That is, we start again looking for ; semicolon commands, etc. All fonts and so forth ; for the text after the title pages must be respecified there ; since they unpredictably may or may not be inherited from the titles. ; ;SQUISH and ;KSUBSET may not be used in title pages, though they may be ; used in the body of the file following the title pages. ; Page numbers start at 1 again after each group of title pages ends. ; ;SKIP in a group of titles is local to the titles and ;SKIP after ; the titles applies only to what follows the titles. xtitle: skipn dskcmd popj p, pushj p,posarg jrst badarg movem d,tpages jrst popj1 ; ;TSKIP command is used in requeueing files which have had titles printed. ; It says to skip to character position when looking at the file ; because everything up to there was made up of titles. xtskip: pushj p,posarg jrst badarg caml d,tskip movem d,tskip jrst popj1 subttl ;SCAN and ;PLOT ; The ;SCAN and ;PLOT commands themselves just set OPCODE, ; so that when the filename is encountered we dispatch through OPTAB ; to SCANFIL or PLOTFIL to read the filename and output the file. scanfil: pushj p,scnfn jrst [ movei b,[asciz /???/] popj p,] skipge delup ;Notify now if ;SCAN * SCN. pushj p,notify scan2: pushj p,nxtfil ;Open the scan file, or the next file if * was spec'd. movei a,sbuf scan1: hrrz b,a lsh b,-12 caile b,mk+1 ;read the whole scan file into core. jrst seof .core 1(b) .lose %lssys hrli a,-2000 .iot chtxti,a jumpl a,seof movei b,seof+mk*2000 cail b,(a) jrst scan1 seof: .close chtxti, pushj p,sndscn ;send over the scan file data now in core. pushj p,scndun ;Done with this file; if one-file command, exit. jrst scan2 ;Else loop back for next file. ;Here to send over a scan file in core. sndscn: push p,a movei a,2 pushj p,cmdo pushj p,cmdof movei a,30. ;wait for 11 to be ready for it. .sleep a, pop p,a subi a,sbuf hrrzs a lsh a,-12 aos a ;Say how many K of core the data occupies. push p,a move d,a pushj p,decpnt movei b,[asciz /K core locked /] pushj p,outstr pop p,a hrl a,a hrri a,sbuf_-12 syscal XGPIM,a ;Send it over, using I.T.S. interrupt level. jrst xpltl movei a,30.*30. ;Wait till it should all be over. .sleep a, .core sbufp ;Flush the core. .lose popj p, xpltl: movei b,[asciz /XGP lossage! /] pushj p,notstr pushj p,outstr .core sbufp .lose jrst lossag ;Read filename arg to ;SCAN or ;PLOT scnfn: setzm delup ;Delup gets set if this is a multi-file "*" request. movei b,txtdev movei t,cpopj pushj p,rfnm move a,[sixbit/*/] tlnn e,1_rfn"fn1 movem a,txtfn1 move a,[sixbit/SCN/] tlnn e,1_rfn"fn2 movem a,txtfn2 move a,txtfn1 camn a,[sixbit /*/] jsp b,[setom delup movsi e,(sixbit / write: hrrz x,x0 ;pick up x position of bit to write tdne b,mormsk(c) ;don't mark till all motion done JRST M1 ;NEXT BIT cail x,xbitl ;out of range? JRST QTEST ;TEST IF ALREADY DOING EXPANDED PLOT imuli x,wdspl ;words per scan line hrrz z,y0 ;pick up y position cail z,ybitl ;out of range? JRST QTEST ;TEST IF ALREADY DOING EXPANDED PLOT lshc z,-5 ;word # in line into z, bit position in high part of y add x,z ;add in the word number in the line lsh y,-<36.-5> ;move the bit position into spot to index with move z,bitab(y) ;pick up the bit we really want to use iorm z,bitbuf(x) ;zap it into the buffer jrst m1 ;back for another bit in the file qtest: skipge centf ;Here on point that is out of range. jrst m1 ;Already hacking multi-sheets, just don't plot it. popj p, ;Not hacking multi-sheets; this plot attempt has failed. ;make this call to PLOT3A fail so QMM is called. cnter==36. mormsk: repeat 5,[ cnter==cnter-7 0 0 0 7_cnter 3_cnter 1_cnter 0 ] 0 ;QMM and the other Q... routines are for computing how big the ;plot is without printing it, when we have seen that the plot is too big to print. ;When EOF is reached, PLOT3 is called several times set to print various ;subplots, which when put side-by-side will add up to the whole plot. QMM: .CORE SBUFP .lose %lssys syscal OPEN,[movsi .bii ? movei chtxti ? txtdev ? txtfn1 ? txtfn2 ? txtsnm] jrst txtluz SETZB X0,Y0 MOVE A,[4*XBITL] MOVEM A,XMIN' MOVNM A,XMAX' MOVE A,[4*YBITL] MOVEM A,YMIN' MOVNM A,YMAX' MOVEI TT,QM1 QLOOP: MOVE A,[-BUFL,,BUF] ;BUFFER LOCATION .IOT chtxti,A MOVNI A,-BUF(A) ;# WORDS TRANSFERED JUMPE A,QFILDN HRLZS A HRRI A,BUF MOVE B,(A) ;WORD QM1: JFFO B,QDOIT AOBJN A,.-2 JRST QLOOP QDOIT: ANDCM B,BITAB(C) XCT QDOBIT(C) JRST (TT) QDOBIT: BLOCK 36. QPLTD1: REPEAT 5,[ JRST QM1 MOVEI TT,QWRITE MOVEI TT,QM1 SOJA X0,(TT) AOJA X0,(TT) SOJA Y0,(TT) AOJA Y0,(TT) ] JRST QM1 QPLTD2: REPEAT 5,[ JRST QM1 MOVEI TT,QWRITE MOVEI TT,QM1 AOJA Y0,(TT) SOJA Y0,(TT) SOJA X0,(TT) AOJA X0,(TT) ] JRST QM1 QWRITE: CAML X0,XMAX MOVEM X0,XMAX CAMG X0,XMIN MOVEM X0,XMIN CAML Y0,YMAX MOVEM Y0,YMAX CAMG Y0,YMIN MOVEM Y0,YMIN JRST QM1 ;Reopen the plot file and plot whatever fits on the paper, ignoring what doesn't. plot3: syscal OPEN,[movsi .bii ? movei chtxti ? txtdev ? txtfn1 ? txtfn2 ? txtsnm] jrst txtluz setom centf pushj p,plot3a .value popj p, ;Here at end of QMM's pass. XMAX, XMIN, YMAX, YMIN now have the ranges ;or the two co-ordinates that the plot occupies. Determine how many subsheets ;are needed and call PLOT3 to plot them. QFILDN: MOVE X0,XMAX SUB X0,XMIN JUMPLE X0,SCNDUN MOVE Y0,YMAX SUB Y0,YMIN JUMPLE Y0,SCNDUN CAIL X0,XBITL JRST QF1 CAIL Y0,YBITL JRST QF1 ASH X0,-1 ;Fits on one sheet if we translate it. ASH Y0,-1 ADD X0,XMIN ADD Y0,YMIN MOVNM X0,INITX0 MOVNM Y0,INITY0 MOVEI X0,XBITL/2 ADDM X0,INITX0 MOVEI Y0,YBITL/2 ADDM Y0,INITY0 jrst plot3 QF1: CAIL X0,2*XBITL JRST QF2 CAIL Y0,2*YBITL JRST QF2 CAIGE X0,XBITL JRST QF1A CAIGE Y0,YBITL JRST QF1B ASH X0,-1 ASH Y0,-1 ADD X0,XMIN ADD Y0,YMIN MOVNM X0,INITX0 MOVNM Y0,INITY0 MOVEI X0,XBITL ADDM X0,INITX0 MOVEI Y0,YBITL ADDM Y0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVEI X0,XBITL ADDM X0,INITX0 MOVNI Y0,YBITL ADDM Y0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 popj p, QF1A: ASH X0,-1 ;X FITS ON ONE SHEET ASH Y0,-1 ADD Y0,YMIN ADD X0,XMIN MOVNM X0,INITX0 MOVNM Y0,INITY0 MOVEI X0,XBITL/2 ADDM X0,INITX0 MOVEI Y0,YBITL ADDM Y0,INITY0 pushj p,plot3 MOVNI Y0,YBITL ADDM Y0,INITY0 jrst plot3 QF1B: ASH X0,-1 ASH Y0,-1 ADD Y0,YMIN ADD X0,XMIN MOVNM X0,INITX0 MOVNM Y0,INITY0 MOVEI X0,XBITL ADDM X0,INITX0 MOVEI Y0,YBITL/2 ADDM Y0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 jrst plot3 QF2: ASH X0,-1 ASH Y0,-1 ADD Y0,YMIN ADD X0,XMIN MOVNM X0,INITX0 MOVNM Y0,INITY0 MOVEI X0,XBITL+ ADDM X0,INITX0 MOVEI Y0,YBITL+ ADDM Y0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVEI X0,2*XBITL ADDM X0,INITX0 MOVNI X0,YBITL ADDM X0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVEI X0,2*XBITL ADDM X0,INITX0 MOVNI X0,YBITL ADDM X0,INITY0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 pushj p,plot3 MOVNI X0,XBITL ADDM X0,INITX0 jrst plot3 ;this routine converts the bit map just produced into a possibly more compact ;representation, using the run length encoding option, and then outputs it. ;it can never result in a longer representation, since it can always use ;the image representation if that is more efficient. sllup: .close chtxti, move a,lftmar movem a,vpos' movei a,sbuf movem a,fptr' movei a,bitbuf sllup1: aos vpos push p,a pushj p,cnvrt pop p,a jumpe b,sllup2 move c,fptr move d,b addi d,1 ;for the extra position/length word lsh d,1 dpb d,[242000,,(c)] move d,vpos dpb d,[042000,,(c)] aos c move d,c add d,b movem d,fptr hrli c,bytbf ;source blt c,-1(d) sllup2: addi a,wdspl caige a,bitbuf+mk*2000 jrst sllup1 move a,fptr hrli a,442000 movei b,2 idpb b,a movei b,xbitl+100 add b,lftmar tro b,100000 idpb b,a setzm 1(a) aos fptr aos a,fptr jrst sndscn ;Output the run-length encoded data and return. cnvrt: setzm lstbb' setzm bytcnt' setzb e,d ;bit count, last different bit count movei c,0 jsp t,dep jfcl movei c,0 jsp t,dep jfcl hrli a,-wdspl+2 w1: move b,(a) w2: jffo b,dow ;found a black bit w3: addi d,32. ;all bits of this word white aobjn a,w1 move c,lstbb movem c,bytcnt ;backup byte buffer to last black bits repeat 3,[ movei c,0 ;escape code jsp t,dep jrst imsl ] movei c,1 jsp t,dep jrst imsl jrst esl b1: setcm b,(a) b2: jffo b,dob ;found a white bit b3: addi d,32. aobjn a,b1 movei c,0 jrst dob ;pretend we just got a white bit dow: andca b,mtb(c) cail c,40 jrst w3 add c,d ;bit position of this bit exch c,e ;last change update subm e,c ;difference in c dow2: caile c,377 jrst dow1 jsp t,dep jrst imsl jrst b2 dow1: movem c,temp' movei c,377 subm c,temp jsp t,dep jrst imsl jsp t,dep jrst imsl movn c,temp jrst dow2 dob: andca b,mtb(c) cail c,40 jrst b3 add c,d exch e,c subm e,c dob2: caile c,377 jrst dob1 jsp t,dep jrst imsl move c,bytcnt movem c,lstbb ;save last byte used for blackness jrst w2 dob1: movem c,temp movei c,377 subm c,temp jsp t,dep jrst imsl jsp t,dep jrst imsl movn c,temp jrst dob2 mtb: repeat 36.,[ <-1>_<-.rpcnt> ] dep: move x,bytcnt cail x,bytmax ;can we do better in image mode? jrst (t) ;yes move y,x andi y,3 lsh x,-2 dpb c,bytab(y) ;deposit in the kludgy format wanted by the xgp movei c,0 aos bytcnt jrst 1(t) bytab: 241000,,bytbf(x) 341000,,bytbf(x) 041000,,bytbf(x) 141000,,bytbf(x) bytbf: block wdspl ;get here when the run length encoded version is longer than an image scan line, ;and we want to convert the bit map into an image scan line. imsl: move a,-1(p) ;pointer to beg of bit map hrli a,-wdspl+2 setom lstbb ;we have blackness in this line setzm bytcnt ;start at beg of the bytcount movei c,0 ;esc jsp t,dep jfcl movei c,2 ;enter image mode jsp t,dep jfcl imsl1: move c,(a) ;pickup word from bit map circ c,44 ;reverse bit order move c,d ;pickup first 8 bits jsp t,dep jfcl lsh d,-8 ;next 8, etc. move c,d jsp t,dep jfcl lsh d,-8 move c,d jsp t,dep jfcl lsh d,-8 move c,d jsp t,dep jfcl aobjn a,imsl1 ;back for the next bit map word esl: move b,bytcnt addi b,3 ;round off to next higher word lsh b,-2 ;four bytes/word skipn lstbb movei b, ;return zero if this line is null popj p, subttl notification ;type out char from a into notification buffer notyo: setom notluz ;Any addition to notify string after the notify command ;is an error message. push p,a move a,notcnt cail a,notbfl*5 jrst popaj aos notcnt pop p,a idpb a,notpnt popj p, ;type out string pointed to be b into notification, no clobberage notstr: push p,a push p,b hrli b,440700 notst1: ildb a,b jumpe a,popbaj pushj p,notyo jrst notst1 ;same but then give crlf terprn: pushj p,notstr nocrlf: push p,a movei a,^M pushj p,notyo movei a,^J pushj p,notyo jrst popaj popbaj: pop p,b pop p,a popj p, ;Process NOTIFY command. donote: setom notflg ; notify seen move b,[440700,,nothst] ; get host # as ASCIZ donot1: tlne b,040000 idpb a,b pushj p,comget ; get another character caie a,<",> ; got a comma? jrst donot1 ; no, still getting a site number pushj p,comget ; get first character in UNAME move b,[440700,,notusr] movei c,5*notusl-1 move d,[440600,,cuname] setzm cuname donot2: sosl c ; skip if name buffer full idpb a,b ; output it caige a,140 subi a,40 tlne d,770000 idpb a,d pushj p,comget ; get another UNAME character caie a,<" > ; got a space? jrst donot2 ; no, still getting UNAME setz a, ; yes, terminate name idpb a,b donot3: pushj p,comget ; get message character pushj p,notyo ; output it caie a,^J ; hit terminating linefeed? jrst donot3 ; no, continue hacking message setzm notluz ; so far, there is no error message in the notification. jrst popj1 ; and return ;here to tell the world that XGP output is starting notify: skipn notflg ;send notification if desired popj p, syscal OPEN,[[.uao,,chmail] ? ['DSK,,] ? [sixbit/MAIL/] ? [sixbit/>/] ['.MAIL.]] ; write a mail file .lose %lsfil ; can't movei b,[ASCIZ /FROM-JOB:XGPSPL FROM:XI"The-XGP TO:(/] pushj p,notifz movei b,notusr ;output (user host (R-MODE-SEND mode)) pushj p,notifz .iot chmail,[40] movei b,nothst pushj p,notifz movei b,[asciz / (R-MODE-SEND /] pushj p,notifz movei b,[asciz /0/] ;If reporting error, mail if can't send. skipn notluz ;If no lossage to report, never mail. movei b,[asciz /-1/] pushj p,notifz movei b,[asciz /)) TEXT;-1 /] ; now comes the message!!! pushj p,notifz setz a, ;make it asciz, then send as asciz string. move b,notpnt idpb a,b movei b,notbuf pushj p,notifz .close chmail, popj p, ;Output asciz string B points at to chmail. Clobbers B, C. notifz: hrli b,440700 push p,a push p,b setz c, notfz1: ildb a,b skipe a aoja c,notfz1 pop p,b syscal siot,[%climm,,chmail ? b ? c] .lose %lsfil jrst popaj subttl deletion of text files ;delete all files on the delete queue whose time has come. delchk: push p,a push p,b .rdtime a, ;read uptime in 30'ths as of now. movsi b,-delqln delch1: skipe delque(b) ;Ignore queue entries that aren't in use. camge a,delque(b) jrst delch2 ;File deletion time is still in the future. syscal DELETE,[delqdv(b) ? delqf1(b) ? delqf2(b) ? delqsn(b)] jfcl setzm delque(b) ;clear out queue entries no longer in use. setzm delqdv(b) setzm delqf1(b) setzm delqf2(b) setzm delqsn(b) delch2: aobjn b,delch1 jrst popbaj ;request deletion of the current text file, two minutes from now. deldly==120.*30. ;Two minutes of 30'ths. delreq: push p,a push p,b .rdtime a, ;get uptime as of now, in 30'ths. addi a,deldly ;compute time to delete the file. movsi b,-delqln skipe delque(b) ;find a queue entry that is free. aobjn b,.-1 jumpge b,popbaj ;give up if queue is full. (10 files in 1 minute???) movem a,delque(b) ;store time at which this file should be deleted. move a,txtdev movem a,delqdv(b) ;store the names of the file. move a,txtfn1 movem a,delqf1(b) move a,txtfn2 movem a,delqf2(b) move a,txtsnm movem a,delqsn(b) jrst popbaj ; ;DELETE command - delete this file after processing it. delcmd: setom deltxt jrst popj1 subttl status line printout ; ;STATUS line types line on the tty and into the stats file. status: push p,a sretry: syscal OPEN,[movsi 100000\.uao ? movei chstao ? moves b ['DSK,,] ? [sixbit/QUEUE/] ? [sixbit/STATS/] ? ['.XGPR.]] jrst [ caie b,%ensfl ;FNF error? jrst [ movei b,[asciz/Waiting to access statistics file... /] pushj p,outstr ;and report what's goin' down movei b,60.*30. ;try waiting 60 seconds .sleep b, ;...zzz... jrst sretry] ;and try again movei b,[asciz/ Warning: Queue statistics file cannot be written over. A new file is being created! /] pushj p,outstr ;type warning syscal OPEN,[movsi .uao ? movei chstao ? ['DSK,,] ? [sixbit/QUEUE/] [sixbit/STATS/] ? ['.XGPR.]] .lose %lsfil ;lose here...must have file pop p,a ;restore clobbered character jrst gotoit] ;and go to it! syscal FILLEN,[movei chstao ? movem b] .lose %lsfil syscal ACCESS,[movei chstao ? b] .lose %lsfil pop p,a ;restore a gotoit: .iot chstao,a ;echo it .iot chttyo,a cain a,^J ;end of command? jrst [ .close chstao, ;close it off so it can be read jrst popj1] ;all done pushj p,comget ;gobble down another character jrst gotoit ;and try again defaul: cain a,^J ;EOL? jrst comman ;losey lose pushj p,combac ;regobble down last character movei t,cpopj movei b,txtdev ;Gobble filespec to set default device and sname. pushj p,rfnm jrst popj1 kill: pushj p,notify ;say who dun it syscal DELETE,[['DSK,,] ? [sixbit/DONE/] ? [sixbit/QUEUE/] ? ['.XGPR.]] jfcl ;don't really care syscal RENMWO,[movei chcmdi ? [sixbit/DONE/] ? [sixbit/QUEUE/]] jfcl ;don't really care at all! .close chstao, ;close the statistics channel .close chcmdi, ;close command channel .logout .break 16,160000 subttl parameter setting and examining commands ;Print out "Height". shwhgt: movei e,height romshw: caie a,12 jrst althuh shwarg: skipe cmdfil jrst popj1 move d,(e) push p,a pushj p,decpnt jrst popaj1 ;Print number of text lines per page. setlin: movei e,nlines jrst romshw ;positive only variables onearg: cain a,12 jrst shwarg ;no arg, show what we have pushj p,posarg jrst badarg movem d,(e) jrst popj1 setlft: movei e,lftmar jrst onearg settop: skipa e,[topmar] setbot: movei e,botmar setvs1: pushj p,onearg jrst badarg setvs2: pushj p,caline ;recalculate nlines jrst popj1 setlsp: caie a,12 pushj p,posarg jrst shwarg movem d,lsp setom vsp ;can't have it both ways jrst setvs2 settst: movei a,3 pushj p,cmdo pushj p,cmdof jrst comman setvsp: caie a,12 ;vsp is a funny one pushj p,posarg jrst badarg movem d,vsp setom lsp jrst setvs2 ;any value legal variables setx0: skipa e,[initx0] sety0: movei e,inity0 jrst anyval setffc: movei e,ffcut ;causes xgp to cut only on form feed jrst anyval setxtc: skipa e,[txtcmd] setcut: movei e,autcut anyval: cain a,12 jrst shwarg pushj p,argin jrst badarg movem d,(e) jrst popj1 ;miscellaneous routines rotate: movsi a,pltd2 hrri a,dobit blt a,dobit+43 MOVSI A,QPLTD2 HRRI A,QDOBIT BLT A,QDOBIT+43 jrst popj1 squish: setom sqshfl ;just set squish flag jrst popj1 .see sndfnt verse: caie a,12 jrst badarg pushj p,vertyp ;type out version # pushj p,crlf ;restores a to right thing! jrst popj1 header: setzm hdrcnt ;sets heading text cain a,12 ;null header jrst popj1 ; is easy movei b,hdrtxl*5 ;size of buffer move c,[440700,,hdrtxt] head1: pushj p,comget sosl b ;don't overflow buffer idpb a,c aos hdrcnt caie a,12 ;go until we find a line feed jrst head1 jumpge b,popj1 ;jumpe if all is okay movei b,[asciz /Header truncated/] popj p, ; ;PLOT, ;SCAN, ;SAMPLE specify different operations to be done on the file to be printed. ; They can be followed by a filename on the same line. plot: skipa b,[op%plt] scan: movei b,op%scn caia sample: movei b,op%smp movem b,opcode ;Note that the default value of OPCODE is op%txt (0), jrst print ;for ordinary output. ;list prints files with default header (time, date, and page #) list: setom dfhdrf ;flag for default header print: skipe dskcmd jrst print1 ;different things for dsk comnmands sub p,[1,,1] ;Don't return to ALTER. cain a,12 ;List, Plot, etc. just set flags if not followed by a filename. jrst comman ;In that case we expect tha filename to follow on another line. jrst coman2 ;Filename follows => read it and process the file. ;here to for print command while reading disk commands print1: aose udepth jrst popj1 ;only allow 1 level pushj p,combac ;unread the last character movei b,txtdev movsi a,(sixbit />/) movem a,txtfn2 movei t,cpopj pushj p,rfnm tlnn e,17 jrst print2 ;no file spec, ignore setom newtxt jrst popj1 print2: sos udepth ;not a different file after all jrst popj1 ;Print out all parameter settings and the selected font names. show: skipe cmdfil jrst popj1 push p,a movei b,[asciz /Skip /] movei e,pskip pushj p,show1 irp var,,[Cskip,Tskip,Lsp,Vsp,Lftmar,Topmar,Botmar,Nlines,Autcut,Ffcut,Txtcmd,Delete] movei b,[asciz /var! /] movei e,var pushj p,show1 termin movei b,[asciz /Ksets:/] pushj p,terpri jrst kset0a ;Print a list of the specified fonts. kset0: skipe cmdfil jrst popj1 push p,a kset0a: movei font,0 kset1: skipn fntfn2(font) jrst kset69 pushj p,kset4 movei a,fnto(font) pushj p,pntfnm ;print file name pushj p,crlf kset69: addi font,fntvln caige font,maxfnt*fntvln jrst kset1 pushj p,crlf aos -1(p) ;do the skip return jrst popxit show1: pushj p,outstr move d,(e) pushj p,decpnt jrst crlf ; ;KSET - Specify fonts, or, with no arg, list the specified fonts. kset: cain a,12 jrst kset0 pushj p,combac ;un read the last character pushj p,getf0 ;Get font file names. popj p, ;error return push p,a movei font,0 kset2: skipn fntfn2(font) jrst kset3 move a,fnto skipn fnto(font) movem a,fnto(font) move a,fntsnm skipn fntsnm(font) movem a,fntsnm(font) pushj p,fntopn jrst [ skipe cmdfil jrst kset3 pushj p,kset4 pushj p,fntfnf pushj p,crlf jrst kset3] .close chfnti, kset3: addi font,fntvln caige font,maxfnt*fntvln jrst kset2 jrst popaj1 kset4: move d,font idivi d,fntvln pushj p,decpnt movei a,40 pushj p,tyo jrst tyo ;Generate a sample of a font. Dispatch here when encounter a filename, ;when we see the opcode as set up by the ;SAMPLE command. sampfil: pushj p,vreset pushj p,getf0 popj p, ;error jumpn font,cpopj ;more chance for lossage push p,a move a,[fntbeg,,fntbeg+fntvln] blt a,fntbeg+-1 move a,[['DSK,, ? sixbit /25FG/ ? 'KST,, ? sixbit /FONTS/],,fntbeg] blt a,fntbeg+fntvln-1 movei font,0 samp1: setom fchflg(font) pushj p,fntopn jrst popaj ;lossage .close chfnti, setzm hdrcnt movei a,fnto+fntvln move c,[440700,,hdrtxt] pushj p,samp3 ;put font name in page header movei b,[asciz\ \] pushj p,samp6 pushj p,hdrdat ;put today's date in header pushj p,samp8 ;throw in some extra carriage returns pushj p,samp8 move a,[['DSK,, ? sixbit /CODES/ ? sixbit />/ ? sixbit /FONTS/],,txtdev] blt a,txtsnm pop p,a pushj p,comxit jrst ptext ;Now output the sample text as an ordinary text file. samp3: push p,a move b,(a) ;device camn b,[sixbit /DSK/] ;only AI has an XGP move b,[sixbit /AI/] pushj p,samp4 movei a,": pushj p,samp5 move a,(p) move b,3(a) ;sname pushj p,samp4 movei a,"; pushj p,samp5 move a,(p) move b,1(a) ;file name 1 pushj p,samp4 movei a,40 pushj p,samp5 pop p,a move b,2(a) ;file name 2 samp4: movei a,0 lshc a,6 addi a,40 pushj p,samp5 jumpn b,samp4 popj p, samp8: movei a,15 pushj p,samp5 movei a,12 samp5: aos hdrcnt idpb a,c popj p, samp6: hrli b,440700 samp7: ildb a,b jumpe a,cpopj pushj p,samp5 jrst samp7 ;:SKIP command - set to skip first pages of file setpsk: movei e,pskip cain a,12 jrst shwarg xcski1: pushj p,posarg jrst badarg movns d camge d,pskip ;pskip actually has minus number of pages to skip. movem d,pskip jrst popj1 ;:CSKIP

command - set to skip first characters of file. ;Also remember that after doing so we will be on page

. ;This command is put into queue files by the requeueing mechanism. xcskip: pushj p,posarg caia jrst badarg camle d,cskip movem d,cskip jrst xcski1 ; ;KSUBSET font bits bits bits bits ;Prespecify the result of a ;SQUISH, by saying which characters ;of font (a font number) are actually needed. ;Each "bits" is an octal number specifying 32 bits, ;so there are 128 bits, one for each character. Each bit says whether ;the corresponding character is needed. The chars are in ascii order. KSUBSE: pushj p,decin ;Read the font number. jrst badarg jumpl d,badarg setom sqshfl setom prsqsh ;indicate that ;SQUISH info is available. movns d movsi b,400000 lsh b,(d) ;get SQSHTB bit for that font. setz c, ;C points to character to set or clear bit for. ksubs1: push p,b pushj p,spcsk2 ;Skip over any spaces, and read 1st char of number. pushj p,octin ;read next 32-bit octal number, into D. pop p,b hrli c,-40 ;Set next 32 chars from this octal number. ksubs3: andcam b,sqshtb(c) ;Set this font's bit of next char, in sqshtb, tlne d,1_<31.-18.> ;according to next bit in the number. iorm b,sqshtb(c) lsh d,1 ;advance to next bit. aobjn c,ksubs3 ;advance to next character. Each number handles 32 characters. caie c,200 ;If not finished with all 200 chars, must be expecting jrst ksubs1 ;another arg, so read it. jrst popj1 subttl reset things between files ;Reset some things just for new file to be printed. nreset: move a,[440700,,notbuf] movem a,notpnt irps x,,notflg notcnt notusr nothst notluz cmdfil qfn1 setzm x termin move a,[.iot chttyo,a] movem a,tyo setzm txtfn1 setzm txtfn2 setom newtxt popj p, ; ;RESET command: Reset page sizes, etc. reset: pushj p,vreset aos (p) jrst comxit ;reset variables vreset: .core sbufp .lose %lssys movsi b,pltd1 hrri b,dobit blt b,dobit+43 MOVSI B,QPLTD1 HRRI B,QDOBIT BLT B,QDOBIT+43 setom sqshtb ;In case anyone looks, squish table says all chars move b,[sqshtb,,sqshtb+1] ;of all fonts are needed. blt b,sqshtb+177 setom filsiz ;We don't know file's size yet. setzm pagpos ;Zero out pagpos in case we abort before start of printing. move b,[pagpos,,pagpos+1] blt b,pagpos+pagpsl-1 irps var,,prsqsh deltxt opcode page filptr pskip cskip tskip hdrcnt dfhdrf setzm var termin irp var,,[vsp,lsp,lftmar,topmar,botmar,plines,autcut,txtcmd,udepth,initx0,inity0,sqshfl,ffcut] move b,[i!var] movem b,var termin ;calculates # text lines in text area caline: move d,plines sub d,topmar sub d,botmar movem d,slines skipge e,lsp ;use lsp if set jrst calin1 skipge e,vsp movei e,dvsp ;if vsp not set use default add e,height calin1: idiv d,e movem d,nlines popj p, ;reset fonts freset: move a,[[sixbit /DSK/ ? sixbit /25FG/ ? sixbit /KST/ ? sixbit /FONTS/ 25. ;height 20. ;base line 0 ;cpa 0 ;kst id -1],,fntbeg] ;fchflg blt a,fntbeg+fntvln-1 setzm fntbeg+fntvln move a,[fntbeg+fntvln,,fntbeg+fntvln+1] blt a,fntbeg+-1 setzm fntspc ;Say fonts have not been explicitly specified. popj p, ;calculates size of page with current settings size: movei font,0 ;do caluclations with this font caie a,12 jrst size2 ;set size of page by specification in inches skipe cmdfil jrst popj1 push p,a pushj p,fntopn jrst [ pushj p,fntfnf jrst pophuh] .close chfnti, jumple a,[ movei b,[asciz /Illegal height/] jrst comer1] move a,slines ;# scan lines in text area add a,topmar add a,botmar idivi a,192. ;scan line density (lines/inch) push p,b move d,a pushj p,decpnt movei a,". pushj p,tyo move d,(p) imuli d,1000. ;three decimal places suffices idivi d,192. ;scan line density movei a,"0 caige d,10. pushj p,tyo caige d,100. pushj p,tyo pushj p,decpnt movei a,"" pushj p,tyo skipn (p) jrst size1 movei b,[asciz / (/] pushj p,outstr move d,(p) pushj p,decpnt movei b,[asciz \/192)\] pushj p,outstr size1: pop p,(p) aos -1(p) ;skip return jrst popxit ;here read page size in inches and set slines size2: pushj p,argin ;read string of digits jrst [ caie a,". jrst badarg jrst .+1] jumple d,badarg imuli d,1000. ;thousandths of inches push p,d cain a,12 jrst size4 ;no decimal pushj p,comget ;get first digit for argin cain a,15 jrst .-2 cain a,12 jrst size4 pushj p,argin size3: jrst [ pop p,(d) jrst badarg] jumpl d,size3 imuli d,1000. ;thousandth's of inches idiv d,c ;scale to # digits read addm d,(p) size4: pop p,d imuli d,192. idivi d,1000. ;scan lines in text area move e,d sub d,topmar sub d,botmar jumple d,[ movei b,[asciz /Top and bottom margins exceed size specified/] popj p,] movem e,plines jrst setvs2 ;recalculate nlines and skip return ;here to transmit fonts in alter mode fontsa: caie a,12 jrst huh push p,a movei font,0 ;if he's gone to all this trouble. . . fonta1: skipe fntfn1(font) ;make sure a font is specified setom fchflg(font) ;transmit all fonts addi font,fntvln caige font,maxfnt*fntvln jrst fonta1 pushj p,fonts jrst popaj ;here to transmit fonts fonts: pushj p,clrkst ;clear all characters sets first movei font,0 ;transmit fonts that need it .core sbufp+fntpgs ;get extra pages to load fonts with. jrst lossag fonts0: aose fchflg(font) jrst fonts1 ;dont need to send that one pushj p,fntopn ;open font file (reads first 2 words) jrst fntluz ;file not found pushj p,sndfnt .close chfnti, fonts1: addi font,fntvln caige font,maxfnt*fntvln jrst fonts0 .core sbufp ;flush the extra core used for loading the fonts. .lose %lssys popj p, ;here to clear all ksets in pdp-11 clrkst: movei e,maxfnt-1 clrks1: movei a,0 pushj p,cmdo ;kset mode pushj p,cmdo ;clear . . . move a,e ;this character set pushj p,cmdo sojge e,clrks1 popj p, subttl tty output routines terpri: pushj p,outstr crlf: movei a,15 pushj p,tyo movei a,12 tyo: .iot chttyo,a popj p, sout: movei a,"* jrst tyo vertyp: move b,[.fnam1] ;print version number pushj p,sixo movei a,". pushj p,tyo move b,[.fnam2] pushj p,sixo pjrst crlf sixo: move c,[440600,,b] sixo1: ildb a,c jumpe a,cpopj addi a,40 pushj p,tyo tlne c,770000 jrst sixo1 popj p, outstr: hrli b,440700 outs1: ildb a,b jumpe a,cpopj pushj p,tyo jrst outs1 ;Decimal print number in D on terminal. decpnt: jumpge d,decpn1 movei a,"- pushj p,tyo movms d decpn1: idivi d,10. hrlm e,(p) jumpe d,decpn2 pushj p,decpn1 decpn2: hlrz a,(p) addi a,"0 jrst tyo ;decimal output of number in D to notification string. decnot: jumpge d,decno1 movei a,"- pushj p,notyo movms d decno1: idivi d,10. hrlm e,(p) jumpe d,decno2 pushj p,decno1 decno2: hlrz a,(p) addi a,"0 jrst notyo ;Octal printout of number in D. octpnt: idivi d,10 hrlm e,(p) jumpe d,decpn2 pushj p,octpnt jrst decpn2 subttl files not found txtluz: pushj p,txtfnf jrst lossag fntluz: pushj p,fntfnf jrst lossag txtfnf: movei a,txtdev movei b,[asciz /Text /] jrst fnf fntfnf: movei b,[asciz /Font /] movei a,fnto(font) fnf: push p,a pushj p,eprnt pop p,b move d,[440700,,pfnbuf] pushj p,rfn"pfn ;Convert filenames to a string. movei b,pfnbuf pushj p,eprnt ;Print it on tty and into notification. movei a,40 pushj p,tyo pushj p,notyo errtyp: .open cherri,['ERR ? 1] .lose 1400 ;don't take no for an answer errty1: .iot cherri,a caige a,40 jrst [ .close cherri, ;any control character stop this non-sense pushj p,crlf jrst nocrlf] pushj p,tyo pushj p,notyo jrst errty1 ;print file name <- A on terminal. pntfnm: push p,b push p,d move b,a move d,[440700,,pfnbuf] pushj p,rfn"pfn movei b,pfnbuf pushj p,outstr popdbj: pop p,d popbj: pop p,b popj p, ;print file name <- A to notification string. notfnm: push p,b push p,d move b,a move d,[440700,,pfnbuf] pushj p,rfn"pfn movei b,pfnbuf pushj p,notstr jrst popdbj ;print filename to both terminal and notification. errfnm: pushj p,pntfnm movei b,pfnbuf jrst notstr subttl pdp10 - pdp11 channels ;gets pages from pdp-11 ; call with 11 address in a and # bytes desired in b get11: lsh b,-2 ;protection in 10 words trz a,3 ;avoid possible embarassement lsh a,10 ;10 style address tlo a,600000 ;valid and write enable movei c,xgp11 lsh c,26. ;pdp-11 # ior a,c get11a: movei c,1777 ;possible protection camg b,c move c,b ;only wants part of page aos t11pag ior c,a ;map entry syscal T11MP,[t11pag ? c] .value nopdp11 add a,[2000_12] ;set for next page subi b,2000 jumpge b,get11a ;he wants more popj p, nopdp11: asciz /: Cannot get PDP-11 pages  / ;sends 8 bit byte to 11 cmdo: sosge t,cmdpar(chnl) ;get parity movns t,cmdpar(chnl) skipl @chhdrp(chnl) jrst abrted ;channel closed by 11 idpb a,@cmdptr(chnl) ibp @cmdptr(chnl) sosle cmdcnt(chnl) popj p, ;more room in buffer ;here to force buffer cmdof: move t,cmdsiz(chnl) ;size of this buffer sub t,cmdcnt(chnl) ;number of bytes room in buffer jumpe t,cpopj ;don't force skipl @chhdrp(chnl) jrst abrted ;channel closed by 11 idpb t,cmdbuf(chnl) ;mark with valid count ildb t,cmdbuf(chnl) ;next on ring jumpe t,[ skipn @cmdbuf(chnl) ;10-11 interface is on level 7 .hang ;and so is rug ldb t,cmdbuf(chnl) jrst .] pushj p,setcbf .call [ setz ? 'TTYVAR ? movei chttyo ? ['IDLTIM] ? setzi 0 ] jfcl ;We're doing something, zero idle time (for F) skipl @cmdbuf(chnl) .hang ;wait for that one to free up cmdof1: push p,a addi t,1 ;point at next ten word ildb a,t ;size of this buffer movem a,cmdcnt(chnl) movem a,cmdsiz(chnl) movei a,10 ;switch to 8 bit bytes dpb a,[300600,,t] movei a,0 exch a,t movem a,@cmdptr(chnl) addi t,1 ibp a movem a,@cmdptr(chnl) setzm cmdpar(chnl) popaj: pop p,a cpopj: popj p, ;here to open a 10-11 channel open: skipl @chhdrp(chnl) .hang movei t,@chhdrp(chnl) pushj p,adring ;will point to buffer 11 is hacking pushj p,adring ;advance to next buffer skipl (t) jrst gronkd ;that buffer better be free jrst cmdof1 ;found him set pointers adring: ldb t,[042000,,(t)] setcbf: sub t,buforg ;offset in bytes skipge t jrst gronkd ;pdp-11 buffers buggered lsh t,-2 ;in pdp-10 words add t,[442000,,buffer] movem t,cmdbuf(chnl) popj p, ;here to send word in a to 11 wrdo: push p,a pushj p,cmdo ;low order byte first move a,(p) lsh a,-10 ;now high order byte pushj p,cmdo jrst popaj ;time sharing i/o routines fntopn: setzm height(font) setzm kstid(font) move a,fntsnm(font) syscal OPEN,[movsi .bii ? movei chfnti ? fnto(font) ? fntfn1(font) ? fntfn2(font) ? a] popj p, pushj p,fntin movem a,kstid(font) pushj p,fntin hrrzm a,height(font) push p,a ldb a,[221100,,(p)] movem a,base(font) ldb a,[331100,,(p)] movem a,cpa(font) hrrzs (p) ;returns height of font in a pushj p,caline popaj1: pop p,a popj1: aos (p) popj p, ;Open text file and position TSKIP characters into the file. ;If the file is already open, just do the .access txtopn: skipl a,newtxt jrst txtopa txtop2: syscal OPEN,[movsi .bai ? movei chtxti ? txtdev ? txtfn1 ? txtfn2 ? txtsnm] popj p, seto a, setzm newtxt setzm filptr ;Right after opening, we are at position 0 in the file. setzm txtpos setz b, skipn tskip ;Just after opening, need not do .access jrst txtopb ;to get to position 0. txtopa: move c,a move a,tskip idivi a,5 ;Do the .access, with hair because of block mode. syscal ACCESS,[%climm,,chtxti ? a] jrst [ jumpe c,txtop2 ;Not random access device => reopen file (unless we just did) move b,tskip ;Skip all those chars from the beginning. jrst txtopb] movem a,filptr ;The ACCESS has changed our position in the file. imuli a,5 movem a,txtpos txtopb: push p,b ;B has number of characters to skip now. pushj p,txtop1 ;initialize buffering pop p,b jumpe b,popj1 pushj p,txti ;If must skip a few extra chars into the word, sojg b,.-1 ;read them out of the buffer. jrst popj1 txtop1: setzm txtflg ;We have not encountered EOF yet. setzm txtrhd ;We have no word of read-ahead in core. ;reload the text-file input buffer. txtbf: skipge a,txtflg popj p, ;found eof on previous refill => exit. setzm txtbuf move a,[txtbuf,,txtbuf+1] blt a,txtbuf+txtbfl-1 move a,[440700,,txtbuf] movem a,txtptr move a,[-txtbfl,,txtbuf] skipl txtrhd ;Is there a word of read-ahead? jrst txtbf1 move a,txtrhw ;Yes => store it at front of buffer, movem a,txtbuf setzm txtrhd move a,[1-txtbfl,,txtbuf+1] ;and any further file input follows it. txtbf1: .iot chtxti,a movem a,txtflg ;TXTFLG is set negative if we are at EOF. jumpge a,[ move a,txtbuf+txtbfl-1 movem a,txtrhw ;If no eof, take last word and save as read-ahead. setom txtrhd movei a,txtbfl*5-5 movem a,txtcnt ;Don't count it as part of this buffer. movei a,txtbfl-1 ;Update FILPTR, the count of words of file addm a,filptr ;ALREADY PROCESSED (includes prev. buffer, not this one). movei a,0 popj p,] movei a,0 hlro a,txtflg ;calculate # words read addi a,txtbfl push p,a imuli a,5 ;# characters read movem a,txtcnt pop p,a ;Now discard padding characters from end of buffer. addi a,txtbuf setom txtbuf-1 ;Don't lose if buffer is all padding! hrli a,010700 ;bp to last byte of last occupied word in buffer push p,b dbplr: ldb b,a ;go backward char by char. jumpe b,dbpl ;null, ignore caie b,3 cain b,14 jrst dbpl ;either eof char or form feed, flush txtbix: movei a, ;On reaching non-padding char, we are done. pop p,b popj p, dbpl: movei b,0 ;For a padding character, delete it from the buffer dpb b,a ;by turning it into a null character. add a,[070000,,] ;backup the byte pointer jumpge a,dbplr ;return to check this char sos a hrli a,10700 ;back up a word worth jrst dbplr ;here to get one character from text buffer txtbfi: pushj p,txtbf jumpl a,cpopj ;eof txti: sosge txtcnt jrst txtbfi ildb a,txtptr aos txtpos popj p, ;Peek ahead at the next character from the text buffer. txtpek: skipn txtcnt jrst [ pushj p,txtbf jumpl a,cpopj jrst txtpek] move a,txtptr ildb a,a popj p, ;here to get word from font file fntin: hrroi x,a .iot chfnti,x popj p, ;;; routine to pre-scan text file and decide what chars are needed. ;;; sets bits in sqshtb for the sndfnt routine to look at. ;;; skips on ***** failure **** to open the text file. .see recycl prescn: setzm sqshtb ;clear bit table move a,[sqshtb,,sqshtb+1] blt a,sqshtb+177 pushj p,txtopn ;open text file jrst popj1 ;failed skipa e,[400000,,0] ;initially in font 0 prsc0: iorm e,sqshtb(a) ;here if char is actually used (set bit) prsc1: pushj p,txti ;gobble char from file jumpl a,cpopj ;exit on eof jrst @.+1(a) prsc1 ;null repeat 7, prsc0 ;normal guys repeat 3, prsc1 ;bs, tab, lf prsc0 ;^K (normal) repeat 2, prsc1 ;ff, cr repeat 176-^M, prsc0 ;normal guys prsc2 ;rubout (xgp escape) prsc2: pushj p,txti ;xgp escape. Read escaped character. jumpl a,cpopj ;EOF?? jrst @.+1(a) prsc0 ;normal prsc3 ;xgp escape 1 (gobbles n bytes) prsc3c ;xgp escape 2 (gobbles 1 byte) prsc3b ;xgp escape 3 (gobbles 2 bytes) prsc11 ;xgp escape 4 (gobbles 11. bytes) repeat 3, prsc1 ;reserved repeat 3, prsc0 ;bs, tab, lf -- normal prsc1 ;reserved repeat 2, prsc0 ;ff, cr -- normal repeat 37-^M, prsc1 ;reserved repeat 137, prsc0 ;normal guys prsc0 ;rubout -- normal prsc3: pushj p,txti ;escape 1. Read command character. jumpl a,cpopj ;EOF?? jrst @prst(a) prst: repeat 40, prsc3a ; font select prsc3b ;40 column select (2 bytes) prsc3c ;41 ! underscore (1 byte) prsc3c ;42 " line space (1 byte) prsc3c ;43 # absolute base line adj (1 byte) prsc1 ;44 $ page number (no bytes) prsc3d ;45 % heading (count, then n bytes) prsc1 ;46 & start underline (no bytes) prsc3c ;47 ' stop underline (1 byte) prsc3c ;50 ( interchar spacing (1 byte) prsc3b ;51 ) variable width underline (2 bytes) prsc3c ;52 * relative base line adjust (1 byte) prstl==.-prst repeat 200-prstl, prsc1 ;reserved prsc3a: movsi e,400000 ;font select movns a lsh e,(a) jrst prsc1 prsc3b: pushj p,txti ;skip 2 bytes prsc3c: pushj p,txti ;skip 1 byte jrst prsc1 prsc3d: pushj p,txti ;skip n bytes skipa d,a prsc11: movei d,11. ;skip 11. bytes prsc3e: sojl d,prsc1 pushj p,txti jrst prsc3e comment $ MIT font format and CMU font format words 0-1 kstid byte (9) column_position_adjustment,base_line (18) height ;base line # rasters from top of character matrix remainder of file: one block of data for each character user_id ;not used 4/10/74 but low order bit must be 1 left_kern,,code ;left kern always 0 for cmu raster_width,,character_width ;raster width always 0 for cmu character_matrix ;the matrix is stored 4 8-bit bytes per word so that ;ildb with 8-bit byte size gets successive bytes. ;the bits are bit reversed in each byte (high order ;bit of character in low order bit of byte). ;the matrix is stored row by row. $ ;transmits font over command channel ;Assume that we have 20 extra pages at SBUF to read it in via. sndfnt: move a,[-fntpgs*2000,,sbuf] .iot chfnti,a ;read the whole font into core. jumpge a,[ movei b,[asciz /Font too large to process: /] jrst sndluz] move z,[444400,,sbuf] ;fetch the font file words with ildb off Z. move a,font ;convert font index to font # idivi a,fntvln movn b,a movsi x,400000 lsh x,(b) ;x has bit for sqshtb skipge sqshfl skipe tpages caia jsp e,sqchk ;don't send font if no characters used push p,a ;save font # movei a,0 ;escape to kset pushj p,cmdo movni a,1 ;load this font pushj p,cmdo pop p,a ;font # pushj p,cmdo move a,height(font) ;height pushj p,wrdo move a,base(font) ;base line pushj p,wrdo sndfn0: ildb a,z ;ignore user id trnn a,1 ;check terminating bit jrst [ movei b,[asciz /Bad font: /] jrst sndluz] sndf0a: ildb a,z ;character code move e,a hrrzs a ;clear kern info caile a,177 hrroi a,200 ;any illegal character stops us skipge sqshfl ;if squishing, and if not end of font, skipe tpages caia jumpge a,sndf7 ; then decide whether to send character sndf0h: movem a,lstchr pushj p,cmdo ;"send" it jumpl a,sndfxt ;force buffer and exit hlres e ;left kern add e,cpa(font) ;fudge cpa into kern movn a,e ;fudge for the pdp-11 program pushj p,cmdo ildb a,z ;raster width,,character width jumple a,[movei b,[asciz /Zero or negative char width: /] jrst cfntnm ;0 or negative width ] add a,e ;fudge in kern and column position adjustment jumple a,[ movei b,[asciz /Kern or CPA problem: /] jrst cfntnm ] ;half hearted check pushj p,wrdo ;spacing width tlne a,-1 hlrzs a pushj p,wrdo ;raster width addi a,7 lsh a,-3 ;# 8 bit bytes per row movem a,bypr ;byts per row move e,height(font) move c,bypr sndf1: ildb a,z move d,a ;bytes come packed 4 per word move b,[441000,,d] ;this is how we unpack them sndf2: ildb a,b pushj p,cmdo sojle c,sndf5 ;thats all for this row sndf21: tlnn b,700000 jrst sndf1 ;that's all for this word jrst sndf2 cfntnm: pushj p,eprnt move d,lstchr' pushj p,decpnt move d,lstchr' pushj p,decnot movei b,[asciz /. /] sndluz: pushj p,eprnt movei a,fnto(font) pushj p,errfnm pushj p,nocrlf pushj p,crlf jrst lossag sndf5: move c,bypr movei a,0 trne c,1 ;if odd # of bytes, send a 0 byte pushj p,cmdo sojle e,sndfn0 ;thats all for this char jrst sndf21 ;here to decide whether to send char in squish mode sndf7: tdne x,sqshtb(a) ;if bit not set in sqshtb, jrst sndf0h ; must skip over character ildb a,z ;skip raster width,,character width sndf7a: ildb a,z trnn a,1 ;bit 1.1 => user id for next char jrst sndf7a jrst sndf0a ;here exit sndfnt sndfxt: pushj p,cmdof ;force buffer skipge kstlod ;wait for pdp-11 to finish .hang ldb d,[242000,,kstlod] ;# characters missed jumpe d,cpopj push p,tyo ;If font didn't fit, print error message move a,[jrst notyo] ;to tty or notification skipe cmdfil movem a,tyo pushj p,decpnt ;saying how many characters didn't make it. movei b,[asciz / characters of font /] pushj p,outstr move d,font idivi d,fntvln pushj p,decpnt ;print font # movei a,", pushj p,tyo movei a,40 pushj p,tyo movei a,fnto(font) pushj p,pntfnm movei b,[asciz /, didn't fit. /] pushj p,outstr pop p,tyo popj p, ;scan through sqshtb for this font, if no characters in this font ;are used the take popj return other wise return to sndfnt sqchk: movei b,177 ;character code sqchk1: tdne x,sqshtb(b) jrst (e) ;found a character that is used in this font sojge b,sqchk1 popj p, ;no characters in this font used ;SNDTXT - prepare for sending text to the pdp-11. ;Take care of skipping pages or characters, and of the default header. ;Then go to XGPLPT to do the real work. sndtxt: syscal fillen,[%climm,,chtxti ? %clout,,filsiz] setom filsiz ;How big is this file? So XGP^F can tell people. setzm page aos page ;start printing on page 1 aosn dfhdrf ;want default header? pushj p,defhdr ; yes move a,cskip ;Skip to specific character position if desired. came a,tskip pushj p,skpchr sndtx1: skipl pskip ;skiping pages jrst sndtx2 ;no, print some goodies pushj p,txti ;get a character cain a,177 ;rubout is escape character pushj p,txtrub ;process rubout jumpl a,cpopj ;eof while skipping? caie a,^L ;page mark? jrst sndtx1 aos pskip aos a,page skipn tpages ;If we are doing title pages, see if they are finished. jrst sndtx1 camle a,tpages ;They can be finished because we have done jrst ptext ;the required number of pages, or pushj p,txtpek caie a,^L ;because we come to an empty page. jrst sndtx1 pushj p,txti ;And skip the empty page. jrst ptext ;Now that we have reached the place to start actually printing, ;set up the data base of the starting char positions of the last few pages. sndtx2: move a,txtpos movem a,pagpos ;init page position buffer to the starting point. move a,[pagpos,,pagpos+1] blt a,pagpos+pagpsl-1 move a,page movem a,baspag ;Remember which page number we are starting printing at. move a,tskip movem a,ttlpos ;Also remember tskip value at start of each page. move a,[ttlpos,,ttlpos+1] blt a,ttlpos+pagpsl-1 jrst xgplpt skpchr: idivi a,5 ;Skip to char pos in A, assuming current pos is TXTPOS. syscal ACCESS,[%climm,,chtxti ? a] jrst [ imuli a,5 ;Not random access device => add b,a sub b,txtpos ;read forward to desired position. jrst skpch1] movem a,filptr ;Update remembered position in file for what ACCESS did. imuli a,5 movem a,txtpos setzm txtrhd ;We have no word of read-ahead in core now. skpch1: setzm txtcnt movn a,pskip ;Initialize PAGE to the number of the page which addm a,page ;the character we are going to is located on. setzm pskip ;But don't skip those pages over again. jumpe b,cpopj pushj p,txti ;Then skip the excess characters. sojg b,.-1 popj p, ;here to process rubout while skipping pages in the text file txtrub: pushj p,txti ;get next character jumple a,cpopj ;eof? caile a,txtrdl ;legal control code jrst rubsxt ;no, just clobber a and return jrst @.(a) ;dispatch txtrdo: rubca ;1 complicated rubs1 ;2 column increment, soaks up 1 character rubs2 ;3 skip to scan line, soaks up 2 characters rubs13 ;4 vector, soaks up 13 characters txtrdl==.-txtrdo ;soaks up characters from input stream, looks for eof rubs3: skipa b,[3] rubs13: movei b,13 jrst rubs rubs1: skipa b,[1] rubs2: movei b,2 rubs: pushj p,txti ;get character jumpl a,cpopj ;eof? sojg b,rubs rubsxt: movei a,0 ;clobber character popj p, ;here to process rubout rubca: pushj p,txti ;get character jumpl a,cpopj ;eof? caige a,maxfnt ;font switch? move font,a subi a,37 ;look for other control codes jumple a,rubsxt ;under? caile a,txtadl ;over? jrst rubsxt jrst @.(a) ;dispatch txtado: rubs2 ;40 column select rubs3 ;41 ! underscore rubs1 ;42 " line space rubs1 ;43 # absolute baseline adjust rubsxt ;44 $ print page number takhdr ;45 % accept heading text rubsxt ;46 & start underline rubs1 ;47 ' stop underline rubs1 ;50 ( set intercharacter spacing rubs2 ;51 ) varible width underline rubs1 ;52 * relative baseline adjust rubs3 ;53 + relative baseline underscore txtadl==.-txtado ;send heading text to the PDP-11 takhdr: pushj p,txti ;get character count of header movem a,hdrcnt jumple a,cpopj ;eof? setzm hdrtxt ;clear header buffer move a,[hdrtxt,,hdrtxt+1] blt a,hdrtxt+hdrtxl-1 move b,hdrcnt ;prepare to read header text move c,[440700,,hdrtxt] movei d,hdrtxl*5 tkhdr1: pushj p,txti jumpl a,cpopj ;eof? sosl d idpb a,c sojg b,tkhdr1 jumpge d,rubsxt addm d,hdrcnt ;d has -# characters lost jrst rubsxt ;set up the default header defhdr: setzm hdrcnt move c,[440700,,hdrtxt] pushj p,hdrdat move a,[chtxti,,chsts] .rchst a, movei a,chsts hrlzs chsts pushj p,samp3 ;file name movei b,tensp pushj p,samp6 movei b,[asciz /Page $ /] pushj p,samp6 movei a,hdrtxl*5 movei b,[asciz /Header buffer overflow/] camge a,hdrcnt pjrst terpri popj p, tensp: asciz / / ;Store today's date into the header buffer. hdrdat: .rlpdt a, ldb a,[320300,,b] ;get day of week (0 => sunday) move b,[ [asciz /Sun/] [asciz /Mon/] [asciz /Tues/] [asciz /Wednes/] [asciz /Thurs/] [asciz /Fri/] [asciz /Satur/]](a) pushj p,samp6 movei b,[asciz /day, /] pushj p,samp6 .rdate b, lshc a,2*6 ;two six bit characters is year lsh a,44-<2*6> ;suitable for six bit printing push p,a movei a,0 lshc a,6 ;first digit of month movei d,-20(a) imuli d,10. movei a,0 lshc a,6 ;second digit of month addi d,-20(a) push p,b move b,[ [asciz /????/] [asciz /January /] [asciz /February /] [asciz /March /] [asciz /April /] [asciz /May /] [asciz /June /] [asciz /July /] [asciz /August /] [asciz /September /] [asciz /October /] [asciz /November /] [asciz /December /]](d) pushj p,samp6 pop p,b movei a,0 ;print day of month lshc a,6 ;get first digit caie a,'0 ;don't print leading zero lshc a,-6 pushj p,samp4 movei b,[asciz /, 19/] pushj p,samp6 pop p,b pushj p,samp4 ;year movei a,40 pushj p,samp5 pushj p,samp5 pushj p,samp5 .rtime b, ;date lshc a,2*6 lsh a,6 iori a,': lshc a,2*6 lsh a,6 iori a,': push p,b move b,a pushj p,samp4 pop p,b pushj p,samp4 movei b,tensp pushj p,samp6 ;ten spaces popj p, ;here to print the real goods xgplpt: movei a,1 ;escape to "mixed" pushj p,cmdo skipl lsp ;lsp specified jrst sndvar ; lsp is specified, use it skipge a,vsp movei a,dvsp ;vsp was not specified, use the default value add a,height movem a,lsp sndvar: movei a,zz pushj p,cmdo ;send count of number of parameter that follow zz==0 irp b,,[lsp,lftmar,topmar,botmar,plines,page,autcut,ffcut] zz==zz+1 move a,b pushj p,wrdo termin pushj p,cmdof ;force output movei chnl,dochnl ;all the rest goes on data out pushj p,open pushj p,sndrca ;send rubout move a,font ;do explicit font select pushj p,cmdo skipg b,hdrcnt ;send header text? jrst xgplop pushj p,sndrca movei a,45 ;accept header text pushj p,cmdo move a,hdrcnt pushj p,cmdo move c,[440700,,hdrtxt] ildb a,c pushj p,cmdo sojg b,.-2 move c,[440700,,hdrtxt] ;and now we send it xgplp1: ildb a,c ;so that it appears as header of first page pushj p,cmdo sosle hdrcnt jrst xgplp1 xgplop: pushj p,txti jumpl a,txteof ;eof? cain a,177 jrst xgplp7 ;rubout, process escape without form feed check cain a,14 jrst xgplp4 ;form feed, count pages printed xgplp0: pushj p,cmdo aose abortf jrst xgplop pushj p,txteof ;Abort! First, phony an EOF in the text stream. jrst abort ;Then abort, returning to RECYCL. ;When ^L is seen, update the data base of where the last few pages started in the file. xgplp4: aos b,page skipn tpages ;If we are doing title pages, see if they are finished. jrst xgplp5 camle b,tpages ;They are finished if we have done enough pages jrst [ pushj p,txteof jrst ptext] pushj p,txtpek caie a,^L ;or if we come to an empty page. jrst xgplp5 pushj p,txti ;Skip the empty page. pushj p,txteof jrst ptext xgplp5: movei a,^L move b,[pagpos+1,,pagpos] blt b,pagpos+pagpsl-2 ;Make sure that PAGPOS contains the char pos move b,txtpos ;of the start of the page pagpsl pages ago. movem b,pagpos+pagpsl-1 move b,[ttlpos+1,,ttlpos] blt b,ttlpos+pagpsl-2 ;Also remember the tskip values at the start of each page. move b,tskip movem b,ttlpos+pagpsl-1 jrst xgplp0 xgplp7: pushj p,cmdo pushj p,txti jumpl a,txteof ;eof caile a,4 jrst xgplp0 jrst @.+1(a) xgplp0 xgplr1 xgplr2 xgplr3 xgplr4 xgplr2: movei b,1 jrst xgplr5 xgplr3: movei b,2 jrst xgplr5 xgplr4: movei b,13 xgplr5: movem b,xgplcn' xgplr6: pushj p,cmdo pushj p,txti jumpl a,txteof sosle xgplcn jrst xgplr6 jrst xgplp0 xgplr1: pushj p,cmdo pushj p,txti jumpl a,txteof cail a,40 caile a,40+txtadl jrst xgplp0 skipe b,[2 ? 3 ? 1 ? 1 ? 0 ? 0 ? 0 ? 1 ? 1 ? 2 ? 1]-40(a) jrst xgplr5 jrst xgplp0 ;sends rubout sndrca: movei a,177 pushj p,cmdo movei a,1 jrst cmdo txteof: movei a,200 ;eof code pushj p,cmdo pushj p,cmdof ;force buffer movsi a,400000 andcam a,@chhdrp(chnl) ;close data out channel popj p, ;and return subttl interrupt routines and abort logic tsint: 0 0 push p,a skipge a,tsint jrst ttybrk ;tty channel interupt tlze a,%pjrlt pushj p,tsclk ;clock interupt trze a,%picli pushj p,cliint ;cli tells us to quit. trze a,%piioc jrst iocerr ;io channel error jrst tsx ttybrk: trzn a,1_ jrst tsx movei a,chttyi .ityic a, jrst tsx caie a,^X cain a,^G ;Avoid having our input buffer get full .reset chttyi, ;slowly due to many quits. cain a,^X ;XEROX XGP hardware person come in? setcmm maintp ;complement maintenence flag skiple forms caie a,^G ;If get ^G while asking for a forms change, jrst ttybr1 move a,oforms ;Indicate old forms still in the machine, movem a,forms ;and check queue again. .dismi [recycl] ttybr1: cain a,^G pushj p,quit tsx: hrrz a,tsint+1 ;unhang from idle wait cain a,fwait1 aos tsint+1 pop p,a .dismi tsint+1 cliint: .iopush chfoo, ;CLI interrupt. Discard the CLI file and quit. .open chfoo,[sixbit / CLA/] .lose .close chfoo, .iopop chfoo, setzm quitf aosa quitf ;1 so ABFLSF will be left 0. ;Here when ^G is typed. Set ABORTF to request abort at some later time. ;Set QUITF so that that abort will ask user whether to requeue. quit: setom quitf ;-1 so will ask user whether to requeue. setom abortf setzm abflsf push p,b movei b,[asciz /Quit! /] pushj p,eprnt jrst popbj ;Here from ABORT when it sees QUITF set to -1. ;Ask user whether to requeue and set ABFLSF if no. quit0: push p,b push p,lsterr movei b,[asciz /Asking question/] movem b,lsterr movei b,[asciz/ Requeue remainder of file?/] pushj p,outstr quit1: movei a,[asciz/waiting for Y or N after ^G/] pushj p,tyi push p,a pushj p,crlf pop p,a cail a,141 subi a,40 cain a,"N setom abflsf caie a,"N cain a,"Y jrst quit2 movei b,[asciz/ [Y or N]/] pushj p,outstr jrst quit1 quit2: pop p,lsterr pop p,b popj p, tsclk: move a,abortl ;Clock interrupts every 10 seconds. tlz a,777774 ;Has the pdp-11 signaled an abort? jumpe a,delchk ;not aborted => do pending deletions. .dismi [crash] ;here for io channel error iocerr: pushj p,txteof ;We will abort; prevent 11 from aborting a second time. movei b,[asciz /IO channel error: /] pushj p,eprnt .suset [.rbchn,,a] cain a,chfnti ;is it font lossage jrst [ pushj p,fntfnf jrst iocer1] cain a,chtxti ;perhaps it is the text file jrst [ pushj p,txtfnf jrst iocer1] pushj p,errtyp ;huh? what's this channel iocer1: .close chtxti, .close chfnti, pushj p,error ;Prepare for abort due to unexpected error. movei a,10.*30. ;Sleep a while to give network or whatever a chance to recover. .sleep a, .dismis [abort] ;Notify user, then try again to print. error: setzm delbeg move b,[delbeg,,delbeg+1] blt b,delend setzm quitf setzm abflsf popj p, eprnt1: movem b,lsterr movei b,[asciz / -- /] pushj p,eprnt move b,lsterr eprnt: skipe cmdfil pushj p,notstr jrst outstr subttl abort signalled by pdp11 ;Mysterious lossage in opening a channel to the pdp-11. abrted: movei b,[asciz/Listing aborted by pdp11/] pushj p,eprnt movem b,lsterr jrst crash1 ;Error condition reported asynchronously by pdp-11 program crash: movei b,[asciz/Listing aborted by pdp11/] pushj p,eprnt movem b,lsterr move c,abortl+1 ;Get the error flags. movei d,10 movem d,abortl lsh c,-24 movem c,idlep ;Indicate XGP losing for queue status. trne c,4 pushj p,e5 trne c,10 pushj p,e4 trne c,20 pushj p,e3 trne c,40 pushj p,e2 trne c,200 pushj p,e1 ;Print and remember the error message. crash1: move a,pagpos ;Make sure we requeue from pagpsl pages back. movem a,pagpos+pagpsl-1 move a,ttlpos movem a,ttlpos+pagpsl-1 movni a,pagpsl-1 add a,page camge a,baspag move a,baspag movem a,page pushj p,crlf pushj p,crlf pushj p,nocrlf pushj p,error pushj p,abort0 ;Notify user, requeue file. .reset chttyi, ;Now try to get the XGP fixed. movei b,[asciz / Waiting for corrective action. Type any character to continue ->/] pushj p,outstr setzm cmdfil ;clear reading from a command file flag .reset chttyi, move a,lsterr pushj p,tyi ;wait for the char. notify queue if wait too long. setom idlep ;claim to be idle again pushj p,crlf pushj p,crlf jrst recycl e1: movei b,[asciz /out of paper/] jrst eprnt1 e2: movei b,[asciz /paper jam (power off)/] jrst eprnt1 e3: movei b,[asciz /fuser cold/] jrst eprnt1 e4: movei b,[asciz /paper jam (filament cold)/] jrst eprnt1 e5: movei b,[asciz /out of web or out of paper/] jrst eprnt1 abort: setzm lsterr skipge quitf ;If quitting from terminal, ask user whether to requeue file. skipn cmdfil ;But not if there isn't any queue file. caia pushj p,quit0 pushj p,abort0 ;Abort the current queue file pushj p,crlf jrst recycl ;and look for another. ;QUITF indicates a ^G, ABFLSF indicates ^G and don't requeue, LSTERR indicates XGP losing. ;LSTERR zero means an IOC error or similar problem with the file. abort0: sosg d,page ;D and PAGE get # pages we trust were really printed. setzb d,page syscal open,[[.uai,,chtxti] ? [sixbit/dsk/] qfn1 ? qfn2 ? [sixbit/.xgpr./]] setom abflsf ;Queue file has been deleted => say it is being cancelled. .close chtxti, movei b,[asciz/Cancelled after /] skipn abflsf movei b,[asciz/Printing interrupted after /] pushj p,eprnt push p,d pushj p,decpnt pop p,d push p,tyo move b,[jrst notyo] movem b,tyo skipe cmdfil pushj p,decpnt pop p,tyo movei b,[asciz/ pages./] pushj p,eprnt pushj p,crlf skipn cmdfil jrst abort9 movei b,[asciz / Please come to the XGP to fix this condition. When it is fixed, printing will be resumed./] skipn lsterr movei b,[asciz / An attempt will be made to reopen the file./] skipn quitf pushj p,notstr pushj p,notify skipe abflsf ;Either flush the file, jrst abort7 jrst abort2 ;or requeue or continue it. ;Requeue a file (either at beginning or at end, according to QUITF). ;We requeue the file by adding new commands at the front of the queue file ;and putting it back in the queue in the right place. ;The new commands are ;CSKIP, ;TSKIP and ;KSUBSET and they say ;where in the file to resume printing. ;The new commands are followed by a ^L which precedes the original queue file. ;This is so that when a file is requeued a second time the commands added ;the first time can be flushed. abort2: syscal open,[[.uai,,chtxti] ? [sixbit/dsk/] qfn1 ? qfn2 ? [sixbit/.xgpr./]] .lose %lsfil syscal open,[[.uao,,chfoo] ? [sixbit/dsk/] [sixbit/_queue/] ? [sixbit/output/] ? [sixbit/.xgpr./]] .lose %lsfil push p,tyo move a,[.iot chfoo,a] movem a,tyo skipg d,pagpos+pagpsl-1 jrst abort8 movei b,[asciz /;CSKIP /] pushj p,outstr ;Put a ;CSKIP CRLF pushj p,decpnt ;at the front of the queue file. movei b,[asciz / /] pushj p,outstr ;Also output the number of that page move d,page ;so that the page numbers will be right after we requeue. pushj p,decpnt pushj p,crlf skipn d,ttlpos+pagpsl-1 jrst abort8 movei b,[asciz /;TSKIP /] pushj p,outstr ;Also arrange to skip over any titles already output. pushj p,decpnt pushj p,crlf ;If we have done a ;SQUISH, output ;KSUBSET commands to save the info ;so we need not repeat the squish when we start up again. abort8: skipn sqshfl jrst abfnt5 move d,[-maxfnt,,0] ;Write a ;KSUBSET command to save the info on the font w/ number in rh(D). abfnt1: hrrz c,d imuli c,fntvln ;Don't output a KSUBSET command for a non-existent font. skipn fntfn1(c) jrst abfnt4 movsi c,400000 movn b,d lsh c,(b) ;Get the SQSHTB bit for the font we will do next. movsi a,-200 tdne c,sqshtb(a) ;Are all chars of the font needed (default state)? aobjn a,.-1 jumpge a,abfnt4 ;Yes => there is no need for a KSUBSET cmd for this font. movei b,[asciz /;KSUBSET /] pushj p,outstr push p,d andi d,-1 pushj p,decpnt ;Output ;KSUBSET where is the font number. setz a, abfnt2: hrli a,-40 ;Output 4 32-bit octal numbers setz d, abfnt3: lsh d,1 tdne c,sqshtb(a) ;32 characters go into making up each number. iori d,1 aobjn a,abfnt3 push p,a .iot chfoo,[" ] ;After handling 32 characters, pushj p,octpnt ;output the number, pop p,a caie a,200 ;and go on to the next 32 characters. jrst abfnt2 pushj p,crlf pop p,d abfnt4: aobjn d,abfnt1 ;Do this for each font. abfnt5: .iot chfoo,[^L] ;^L separates stuff added on requeueing from original stuff. pop p,tyo abort3: .iot chtxti,a ;Now skip all of the old queue file up through the ^L, jumpl a,[ ;but if there's no ^L, don't skip anything; .access chtxti,[0] ;go back to the beginning. jrst abort6] caie a,^L jrst abort3 abort6: .iot chtxti,a ;Copy all but what we skipped jumpl a,abort4 ;from the old queue file into the new one. .iot chfoo,a jrst abort6 abort4: skipe quitf jrst abort5 syscal renmwo,[movei chfoo ? qfn1 ? qfn2] .lose %lsfil move a,qfn1 movem a,dothis ;endeavor to do same request again when restarted jrst abort7 abort5: syscal renmwo,[movei chfoo ? qfn1 ? [sixbit/>/]] ;to end of same queue .lose %lsfil abort7: syscal delete,[[sixbit/dsk/] ? qfn1 ? qfn2 ? [sixbit/.xgpr./]] jfcl abort9: .close chtxti, .close chfoo, .close chcmdi, popj p, ;done aborting subttl cry for help ;Call CRY to notify everyone on the XGP queue that the XGP is in trouble. ;A contains the address of the string which describes the problem. cry: syscal open,[[.bii,,chfoo] ? ['dsk,,] ? ['.file.] ? [sixbit/(dir)/] ? ['.xgpr.]] popj p, .core sbufp+1 ;Make a page to hold the directory. popj p, move b,[-2000,,sbuf] ;We will look at each file in the .XGPR. directory. .iot chfoo,b .close chfoo, cryyes: syscal OPEN,[[.uao,,chmail] ? ['DSK,,] ? [sixbit/_XGPSP/] ? [sixbit/OUTPUT/] ['.MAIL.]] ; write a mail file popj p, push p,a ;Save the error string. movei b,[ASCIZ /FROM-JOB:XGPSPL FROM:XI"The-XGP /] pushj p,notifz setz c, ;C counts number of users we notify, in case it's 0. move a,1+sbuf ;index in .XGPR. dir of first filename block. cryfil: cain a,2000 jrst cry1 move b,sbuf(a) trz b,77 came b,[sixbit/ Q/] ;is the next file a queue file? jrst cry9 ;Don't look at any other random files. syscal open,[[.bai,,chtxti] ? ['dsk,,] ? sbuf(a) ? sbuf+1(a) ? ['.xgpr.]] jrst cry9 ;don't get upset if it has been deleted. push p,a push p,c pushj p,txtop1 ;Initialize buffering the file for input. jfcl setom newtxt ;Be aware that previous text file isn't open. setzm dskcmd ;DSKCMD is set to 1 by DSKLIN on EOF. crylin: skipe dskcmd ;Give up on this file if just reached EOF. jrst cry8 pushj p,txti ;Skip over any ^L now so that DSKLIN doesn't think it's eof. cain a,^L jrst cryli1 aos txtcnt ;If we find something other than a ^L, unread it. move a,[070000,,] addm a,txtptr cryli1: pushj p,dsklin ;Read the next line from the file. move b,combuf ;Keep reading till we find a ;notify. ior b,[ascii / /_-7] ;Ignore case in comparing the letters. came b,[ascii /;noti/] jrst crylin crychr: pushj p,comget ;Skip the ";notify " itself, so the ;notify command routine caie a,40 ;can gobble the arguments. jrst crychr aos (p) ;Increment count of users to be notified. pushj p,donote ;Gobble them. jfcl setzm notflg movei b,[asciz / TO:(/] pushj p,notifz movei b,notusr ;output (user host (R-MODE-SEND -1)) pushj p,notifz .iot chmail,[40] movei b,nothst pushj p,notifz movei b,[asciz / (R-MODE-SEND -1)) /] pushj p,notifz cry8: .close chtxti, setzm dskcmd pop p,c pop p,a cry9: addi a,5 jrst cryfil ;Come here with all of message written except the text. ;The address of the error message is still on the stack. cry1: jumpe c,crylos ;Give up if no users were found on the queue. movei b,[asciz /TEXT;-1 The XGP needs human assistance: /] ; now comes the message!!! pushj p,notifz pop p,b ;Get it off the stack. skipe b pushj p,notifz ;output it into the mail file. syscal renmwo,[%climm,,chmail ? [sixbit /MAIL/] ? [sixbit />/]] .lose %lsfil .close chmail, popj p, crylos: pop p,b ;Discard syscal delewo,[%climm,,chmail] .lose %lsfil .close chmail, popj p, litter: constants vars:: variables pat: patch: block 100 patche: -1 icore==<.+1777>_<-12> ;memory map ;program pages 0-icore ;channel header pointer area lnkvpg==icore+1 ;page # 10lnkv=lnkvpg_12 ;origin lnkv==124 ;origin in 11 address space abortl=<402-lnkv>/4+10lnkv ;10 address of abort flag kstlod=abortl+6 ;pdp-10 address of kst loader flag ;channel header area chhdpg==lnkvpg+1 ;page # chhdr=chhdpg_12 ;origin bprchl==10 ;# bytes in 1 channel header ;10-11 buffer area bufpg==chhdpg+1 ;first page # buffer=bufpg_12 syspag==bufpg+1 ;mapped into system to access nxgpfw sbufp==syspag+1 sbuf=sbufp_12 bitbuf=sbuf+wdspl fntpgs==20. ;font loading uses 20 pages starting at sbufp as buffer. end go