1 * ***********************************************************
  2 * *                                                         *
  3 * * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  4 * *                                                         *
  5 * * Copyright (c) 1972 by Massachusetts Institute of        *
  6 * * Technology and Honeywell Information Systems, Inc.      *
  7 * *                                                         *
  8 * ***********************************************************
  9 
 10           ttl       multics/mcs printer trace package
 11           ttls      multics/mcs printer trace package
 12           lbl       ,printer_trace
 13           pcc       off
 14           pmc       off
 15           editp     on
 16           detail    on
 17           rem
 18 ***********************************************************
 19 *
 20 *         printer_trace
 21 *
 22 *              this routine does actual printer tracing
 23 *         if the trace routine decides that we should be
 24 *         called at all. if we are called we must
 25 *         assume that a printer is configured and the
 26 *         correct processor switches are set, and we
 27 *         will forge ahead and print the stuff.
 28 *
 29 *         there are two entries, ptrace and ptrabf.
 30 *         the first is for standard trace data msgs
 31 *         and the second to dump buffers to the printer.
 32 *
 33 *         this routine uses a queueing technique to handle
 34 *         the printer. standard trace messages must fit
 35 *         in one buffer (60 chars), and we will not allocate
 36 *         any buffers for printer trace if there are fewer
 37 *         than 64 left in the free pool.
 38 *
 39 ***********************************************************
 40           rem
 41           symdef    ptrace
 42           symdef    ptrabf
 43           symdef    pterm
 44           symdef    pspec
 45           rem
 46           symref    octasc
 47           symref    getbuf
 48           symref    frebuf
 49           symref    meterc
 50           rem
 51           pmc       save,on
 52           systm
 53           comreg
 54           buffer
 55           ttls      macros, constants and stuff
 56           rem
 57 ptrc      null
 58           start     ptrc,10
 59           pmc       restore
 60           rem
 61 mesg      macro
 62           pmc       save,off
 63           pcc       save,off
 64 temp      set       #1+1
 65 temp      set       temp/2
 66           dec       #1
 67           ascii     temp,#2
 68           pcc       restore
 69           pmc       restore
 70           endm
 71           rem
 72 mpy       macro
 73           mpf       #1
 74           lrl       1
 75           endm      mpy
 76           rem
 77           rem
 78 thresh    equ       64        we won't allocate a buffer if there aren't
 79           rem                 at least this many left
 80           rem
 81 bufsw     bool      000001
 82 blank     bool      040
 83 star      bool      052       * character
 84 tslew     bool      02        bit to tell printer to slew to top of form
 85 ntslew    equ       -3        complement of tslew
 86           ttls      ptrace - entry to do normal printer tracing
 87 ptrace    subr      ptr,(x1,x3)
 88           rem
 89 ***********************************************************
 90 *
 91 *         ptrace
 92 *
 93 *              this routine prepares and prints normal
 94 *         printer tracing messages.
 95 *
 96 *         at entry:
 97 *              x2 - points to trace data words
 98 *              a  - contains module number and switches
 99 *              q  - contains trace type indicator
100 *
101 ***********************************************************
102           rem
103           stx2      datap-*   save ptr for awhile
104           sta       modsw-*   save module number/switch word
105           stq       ttype-*   and trace type word, too
106           rem
107           ldx1      modsw-*   get module number of caller
108           ldx1      a.a006-*,*          (modtab,1) get address of module's message table
109           rem                 (-1 to index by module)
110           adcx1     ttype-*   index by type
111           ldx1      -1,1      x1 now points to message for specified module
112           rem                 and specified trace type
113           rem                 find out how many buffers are left
114           lda       a.a012-*,*          .crnbf
115           icmpa     thresh    are there enough?
116           tmi       tra160-*  if not, send "lost" message
117           ilq       bufsiz    else we will get a buffer to send to printer
118           tsy       a.a007-*,*          getbuf
119           tra       tra160-*  if we couldn't get one, send "lost" message
120           stx3      bufadr-*  save address of buffer
121           cx3a
122           ada       l.a005-*  bf.dta,b.0
123           cax2                data target address into x2 (with char addr)
124           rem
125           lda       0,1       get message length in chars
126           sta       bf.tly,3  it will be buffer tally
127           iera      -1        negate it
128           rem                 this is actually -(tally+1) in case we need blank
129           sta       msglen-*  save the complement
130           rem
131           cx1a                set x1 to point to beginning of message
132           ada       l.a006-*  1,b.0
133           cax1                with character addressing
134           rem
135           rem                 start copying characters into data buffer
136 tra100    null
137           lda       0,1,b.0   get message character
138           icmpa     star      is it a *?
139           tnz       tra150-*  no, just copy char into buffer
140           rem                 else must substitute program data
141           ldx3      a.a008-*  addr(conv),b.0
142           ldq       datap-*,* get data word to convert to ascii
143           tsy       a.a009-*,*          octasc
144           ilq       0         initialize count of digits
145           ldx3      a.a008-*  get starting address again
146 tra110    null
147           iaq       1         increment digit count
148           iacx1     0,b.1     point to next char
149           aos       msglen-*  if any
150           tze       tra120-*
151           lda       0,1,b.0   get character
152           icmpa     star      another star?
153           tze       tra110-*  yes, up digit count and check again
154           rem
155 tra120    null                store digits in buffer
156           cqa                 first figure out where to start
157           iaa       -6
158           tze       tra140-*  want all six
159 tra130    null
160           iacx3     0,b.1     skip leading zero
161           iaa       1         any more to skip?
162           tmi       tra130-*  yes, check again
163           rem
164 tra140    null
165           lda       0,3,b.0   get x3 -> digit
166           sta       0,2,b.0   put it in message buffer
167           iacx3     0,b.1     bump from and
168           iacx2     0,b.1     to pointers
169           iaq       -1        any more digits?
170           tnz       tra140-*  yes, get next one
171           szn       msglen-*  end of message
172           tze       tra170-*  yes, go queue it
173           lda       0,1,b.0   no, get character after stars
174           aos       datap-*   pick up next data word next time
175           rem
176 tra150    null                literal character from message
177           sta       0,2,b.0   into buffer
178           aos       msglen-*  any more?
179           tze       tra170-*  no, go send it
180           iacx1     0,b.1     yes, bump from and
181           iacx2     0,b.1     to pointers
182           tra       tra100-*  go around again
183           rem
184 tra160    null                if no buffer could be allocated,
185           rem                 queue the dummy buffer that says "lost"
186           ldx3      a.a010-*  addr(lost)
187           szn       0,3       is it already queued?
188           tnz       trabak-*  yes, forget it
189           tra       tra180-*
190           rem
191 tra170    null
192           ldx3      bufadr-*
193 tra180    null                x3 points to buffer to be queued for printing
194           tsy       a.a011-*,*          pquer
195           rem
196 trabak    return    ptrace
197           rem
198           rem
199 a.a006    ind       modtab-1,1          to address table of message table addresses
200 a.a007    ind       getbuf    buffer allocating suroutine
201 a.a008    zero      conv,b.0
202 a.a009    ind       octasc
203 a.a010    ind       lost
204 a.a011    ind       pquer
205 a.a012    ind       .crnbf    number of buffers available
206           rem
207 l.a005    zero      bf.dta,b.0
208 l.a006    zero      1,b.0
209           rem
210           even
211 lost      dec       0         dummy buffer for "lost" message
212           dec       4
213           aci       2,lost
214           rem
215 bufadr    bss       1         address of allocated buffer
216 datap     bss       1         address of current data word
217 msglen    bss       1         -(remaining no. of chars in message)
218 conv      bss       3         space for putting data word converted to ascii
219 modsw     bss       1         module number and switch word
220 ttype     bss       1         trace type
221           ttls      ptrabf -- subroutine to do actual printer tracing
222           rem
223 ************************************************************************
224 *
225 *   ptrabf is called by traceb if the printer is configured
226 *
227 *   the word containing the module number and buffer size is passed in the a
228 *
229 *   the low-order processor switch and the switch corresponding to the
230 *   module number must be on for tracing to occur
231 *
232 *   eight words per line will be sent to the printer
233 *
234 ************************************************************************
235           rem
236 ptrabf    subr      trb
237           rem
238           lrl       12        isolate modnum
239           iaa       -1        subtract one
240           ora       l.b002-*  get shift template
241           sta       trbshf-*  for shift instruction
242           ila       1         get high-order bit alone in a
243           als       17        for shifting
244 trbshf    arl       **        (modified above)
245           rem
246           cana      a.b001-*,*          .crtra
247           tze       trbbak-*  bit not on in enable mask
248           rem
249           sel       swch      get processor switches
250           stex      bprcsw-*
251           rem
252           iora      bufsw     bufsw + module switch
253           sta       temp2-*   must both be on
254           ana       bprcsw-*
255           cmpa      temp2-*
256           tnz       trbbak-*  else we'll skip it
257           ila       0
258           rem                 size is in q(0-11)
259           rem                 if we shift 9 high-order bits into a
260           lls       9         we will have size/8
261           iera      -1        negate it
262           iaa       1
263           sta       remain-*  this will be main loop counter
264           stx3      datptr-*  hang on to origin of buffer
265           rem                 put out heading message
266           ilq       bufsiz    get a buffer
267           tsy       a.b002-*,*          getbuf
268           tra       trb040-*  no buffer, just say "lost"
269           ila       16        set tally for introductory message
270           sta       bf.tly,3
271           stx3      outptr-*
272           ldq       datptr-*  get address of buffer being dumped
273           ldx3      a.b005-*  adrasc,b.0
274           tsy       a.b003-*,*          (octasc) convert it for output
275           ila       -4
276           sta       temp2-*
277           ldx1      outptr-*
278           iacx1     bf.dta    point x1 at word 2 of output buffer
279           ldx2      a.b006-*  addr(bufmsg)
280           rem
281 trb010    null
282           ldaq      0,2       put heading message into buffer
283           staq      0,1
284           iacx2     2
285           iacx1     2
286           aos       temp2-*
287           tmi       trb010-*
288           rem                 now send it to the printer
289           ldx3      outptr-*
290           tsy       a.b004-*,*          pquer
291           rem
292           rem                 for every 8 words, we will build
293           rem                 a buffer full of octal ascii digits
294           rem
295           ldx2      datptr-*
296 trb020    null
297           ilq       bufsiz    get a buffer
298           tsy       a.b002-*,*          getbuf
299           tra       trb040-*  "lost" if no buffer
300           stx3      outptr-*  save buffer pointer for queuing routine
301           ila       55        these buffers have 55 characters always
302           sta       bf.tly,3
303           cx3a
304           ada       l.b001-*  bf.dta,b.0
305           cax3                x3 points to data portion of output buffer
306           rem                 now put eight words wotrth of ascii
307           rem                 into that buffer
308           ila       -8
309           sta       temp2-*
310           rem
311 trb030    null
312           ldq       0,2       get data words
313           tsy       a.b003-*,*          (octasc) convert into output buffer
314           ila       blank     followed by a blank
315           sta       0,3,b.0
316           iacx3     0,b.1     put in a blank
317           iacx2     1         get next data word
318           aos       temp2-*   done eight words yet?
319           tmi       trb030-*  no, do the next one
320           rem                 yes, queue the line for printing
321           ldx3      outptr-*
322           tsy       a.b004-*,*          pquer
323           rem                 bump to next line
324           aos       remain-*  are there any more?
325           tmi       trb020-*  yes, go process next line
326           rem
327           rem
328 trbbak    null                all done
329           return    ptrabf
330           rem
331           rem
332           rem
333 trb040    null                if we couldn't get a buffer,
334           rem                 we'll queue the "lost" message
335           ldx3      a.b007-*  addr(lost)
336           szn       0,3       if it's not queued already
337           tnz       trbbak-*
338           tsy       a.b004-*,*          pquer
339           tra       trbbak-*  now return
340           rem
341           rem
342           rem
343           rem
344 a.b001    ind       .crtra    trace enable mask
345 a.b002    ind       getbuf
346 a.b003    ind       octasc    octal-ascii conversion routine
347 a.b004    ind       pquer
348 a.b005    zero      adrasc,b.0
349 a.b006    zero      bufmsg
350 a.b007    ind       lost
351           rem
352           rem
353 l.b001    zero      bf.dta,b.0
354 l.b002    arl       0
355           rem
356           rem
357 bprcsw    bss       1         for processor switches
358 temp2     bss       1         a temporary
359 remain    bss       1         number of lines remaining to print
360 datptr    bss       1         pointer to input buffer
361 outptr    bss       1         pointer to output buffer
362           rem
363           even
364 bufmsg    ascii     5,buffer at
365 adrasc    bss       3         address will be converted here
366           rem
367           ttls      pquer -- queue a line for printing
368           rem
369 ************************************************************************
370 *
371 *   pquer is called from ptrace or ptrabf to queue a line for the printer
372 *
373 *   the address of the buffer containing the line is passed in x3
374 *   if nothing is already queued, pwrite will be called to initiate the i/o;
375 *   otherwise, the buffer will be added to the chain of queued i/o
376 *
377 ************************************************************************
378           rem
379 pquer     subr      pqu,(inh,x1)
380           rem
381           ldx1      plast-*   prepare to add buffer to queue
382           tnz       pqu010-*
383           rem                 if no old chain,
384           stx3      pfirst-*  make this first and last
385           stx3      plast-*
386           tsy       pwrite-*  and start i/o
387           tra       pqubak-*  and return
388           rem
389 pqu010    null                a chain is there,
390           stx3      plast-*   make this the last buffer
391           stx3      0,1       and chain it to previous one
392           rem
393 pqubak    null
394           return    pquer
395           ttls      pwrite -- start i/o on the printer
396           rem
397 ************************************************************************
398 *
399 *   pfirst points to the buffer to be printed, whose second word contains
400 *   a character tally and whose data starts in the third word
401 *
402 *   we will keep a line count per page so as to slew to top of
403 *   form every 66 lines.
404 *
405 ************************************************************************
406           rem
407 pwrite    subr      pwr,(i,x3,a,q)
408           rem
409 *
410 *         load print buffer for prt300 here, once only
411 *
412           rem
413           ldx3      pfirst-*  get pointer to head of i/o chain
414           tze       pwrbak-*  oops, there isn't any
415           cx3a                get data address
416           ada       l.c001-*  bf.dta,c.0
417           sta       a.c001-*,*          lpicw (printer data icw mailbox)
418           rem                 we have to send the printer a tally of
419           rem                 6-bit bytes (god knows why)
420           lda       bf.tly,3  get tally
421           iaa       1         make sure shift doesn't truncate
422           ars       1         divide by 2
423           mpy       l.c005-*  =3
424           stq       a.c006-*,*          lpicw+1
425           rem
426           stz       pstat-*   zero out printer status
427           stz       pstat+1-*
428           ldaq      l.c002-*  printer status icw
429           staq      a.c002-*,*          lpst (printer status icw mailbox)
430           rem
431           lda       linect-*  get line count for this page
432           iaa       1         bump it
433           cmpa      maxlin-*  will this be last line on page?
434           tmi       pwr010-*  no, branch
435           rem                 yes, twiddle pcw to do slew to
436           rem                 top-of-form
437           ila       tslew
438           orsa      prtpcw+1-*
439           stz       linect-*  zero line count
440           tra       2
441 pwr010    null
442           sta       linect-*  update line count
443           rem
444           inh                 inhibit indicators for sel and cioc
445           sel       lpch      select the line printer channel
446           cioc      prtpcw-*  connect
447           rem
448 pwrbak    return    pwrite
449           rem
450           ttls      pterm -- printer terminate interrupt processor
451           rem
452 ************************************************************************
453 *
454 *   assuming good status, buffer at head of printer i/o queue (pfirst)
455 *   will be freed, unless it was dummy buffer containing "lost" message
456 *
457 *   if we find we just did slew to top of form (linect = 0),
458 *   we must fix pcw to resume slewing one line at a time
459 *
460 ************************************************************************
461           rem
462 pterm     subr      pte,(inh,a,q,x3)
463           rem
464           ldaq      pstat-*   get status
465           tze       ptebak-*  no status, don't bother
466           rem
467           cana      l.c003-*  =o200000, power off
468           tnz       ptebak-*  is useless
469           cana      l.c004-*  170000, major status mask
470           tze       pte100-*  it's cool we'll proceed
471           rem
472 ************************************************************************
473 *         code to deal with imperfect status goes here
474 *         just meter it for now
475 ************************************************************************
476           rem
477           ilq       6
478           tsy       a.c007-*,*          meterc
479           rem
480 pte100    null
481           ldx3      pfirst-*  get address of block just printed
482           lda       0,3       pointer to next block
483           sta       pfirst-*  is now first
484           tnz       2         if there is none,
485           stz       plast-*   no last pointer either
486           rem
487           cmpx3     a.c003-*  addr(lost)
488           tze       pte110-*  if line printed was "lost" message, don't free it
489           ilq       bufsiz    else free the buffer
490           tsy       a.c004-*,*          frebuf
491           tra       2
492 pte110    null                if "lost", just unchain the buffer
493           stz       0,3
494           rem
495           szn       linect-*  just started a new page?
496           tnz       pte120-*
497           ila       ntslew    yes, change pcw back to slew one line
498           ansa      prtpcw+1-*
499           rem
500 pte120    null
501           szn       pfirst-*  another line to print?
502           tze       ptebak-*  no, go away
503           tsy       pwrite-*  yes, start it off
504           rem
505 ptebak    return    pterm
506           ttls      pspec -- for printer special interrupts
507           rem
508           rem                 just start any outstanding printer i/o
509           rem
510 pspec     subr      psp,(inh)
511           rem
512           szn       pfirst-*  is there any i/o?
513           tze       2         no, forget it
514           tsy       pwrite-*  yes, start it up
515           rem
516           return    pspec
517           ttls      data for printer code
518           rem
519 a.c001    ind       lpicw     printer data icw mailbox
520 a.c002    ind       lpst      printer status icw mailbox
521 a.c003    ind       lost      dummy buffer for lost output
522 a.c004    ind       frebuf
523 a.c006    ind       lpicw+1   for storing tally
524 a.c007    ind       meterc
525           rem
526 l.c001    zero      bf.dta,c.0
527           even
528 l.c002    icw       pstat,w.2,1
529 l.c003    oct       200000
530 l.c004    oct       170000
531 l.c005    dec       3
532           rem
533           rem
534 linect    zero      0         number of lines on current page
535 maxlin    dec       60        maximum lines/page
536 called    oct       0         1 = pwrite has been called, 0 =
537           rem                 never been called
538           rem
539           even
540 prtpcw    oct       0,111     non-edited, slew one line (changed on occasion
541           rem                 to slew to top-of-form)
542 pstat     oct       0,0       printer status
543           rem
544 pfirst    zero      0         head of printer i/o queue
545 plast     zero      0         tail of printer i/o queue
546           ttls      printer tracing tables and messages
547 modtab    null
548           ind       skdtrc
549           ind       diatrc
550           ind       inttrc
551           ind       utltrc
552           ind       lsltrc
553           ind       hsltrc
554           rem
555           rem
556 skdtrc    null                scheduler tracing messages
557           ind       msg1.1
558           ind       msg1.2
559           ind       msg1.3
560           ind       msg1.4
561           ind       msg1.5
562           ind       msg1.6
563           ind       msg1.7
564           ind       msg1.8
565           rem
566 msg1.1    mesg      31,(interrupt at *****, 3wjt ******)
567 msg1.2    mesg      35,(idle, indicators ******, ier ******)
568 msg1.3    mesg      28,(run interrupt routine ******)
569 msg1.4    mesg      37,(restart interrupted routine at ******)
570 msg1.5    mesg      25,(run queued routine ******)
571 msg1.6    mesg      31,(set timer ****** for tib ******)
572 msg1.7    mesg      49,(interval timer runout, current time ****** ******)
573 msg1.8    mesg      48,(queue routine, pri ******, rtn ******, x1 ******)
574           rem
575 diatrc    null                dia tracing messages
576           ind       msg2.1
577           ind       msg2.2
578           ind       msg2.3
579           ind       msg2.4
580           ind       msg2.5
581           ind       msg2.6
582           ind       msg2.7
583           ind       msg2.8
584           ind       msg2.9
585           ind       ms2.10
586           ind       ms2.11
587           ind       ms2.12
588           ind       ms2.13    dial out
589           rem
590 msg2.1    mesg      26,(dia terminate, tcword = **)
591 msg2.2    mesg      28,(dia interrupt for mailbox **)
592 msg2.3    mesg      22,(dia reading mailbox **)
593 msg2.4    mesg      49,(new entry in dia i/o queue: opcode ***, line ****)
594 msg2.5    mesg      40,(wcd in mailbox **: opcode ***, line ****)
595 msg2.6    mesg      48,(using dia i/o queue entry: opcode ***, line ****)
596 msg2.7    mesg      47,(dia sending input count of ****** for line ****)
597 msg2.8    mesg      22,(dia writing mailbox **)
598 msg2.9    mesg      22,(dia freeing mailbox **)
599 ms2.10    mesg      44,(wtx in mailbox ** for line ****, *** buffers)
600 ms2.11    mesg      31,(rtx in mailbox ** for line ****)
601 ms2.12    mesg      24,(alter parameters: ******)
602 ms2.13    mesg      46,(dial: *** digits - ****** ****** ****** ******)
603           rem
604 inttrc    null                interpreter tracing messages
605           rem
606           ind       msg3.1
607           ind       msg3.2
608           ind       msg3.3
609           ind       msg3.4
610           ind       msg3.5
611           rem
612 msg3.1    mesg      36,(itest: tib at ******, t.cur = ******)
613 msg3.2    mesg      37,(iwrite: tib at ******, t.cur = ******)
614 msg3.3    mesg      51,(istat: tib at ******, t.cur = ******, status ******)
615 msg3.4    mesg      36,(itime: tib at ******, t.cur = ******)
616 msg3.5    mesg      30,(op block at ******, type = ***)
617           rem
618           rem
619 utltrc    null                utilities tracing messages
620           ind       msg4.1
621           ind       msg4.2
622           ind       msg4.3
623           ind       msg4.4
624           rem
625 msg4.1    mesg      38,(buffer allocated at ******, size = ***)
626 msg4.2    mesg      34,(buffer freed at ******, size = ***)
627 msg4.3    mesg      34,(request for ** buffers of size ***)
628 msg4.4    mesg      29,(freeing buffer list at ******)
629           rem
630 lsltrc    null                lsla tracing messages
631           rem
632           ind       msg5.1
633           ind       msg5.2
634           ind       msg5.3
635           ind       msg5.4
636           ind       msg5.5
637           ind       msg5.6
638           ind       msg5.7
639           rem
640 msg5.1    mesg      29,(lsla interrupt, 3wjt = ******)
641 msg5.2    mesg      43,(lsla output frame at ******, sfcm at ******)
642 msg5.3    mesg      28,(lsla output buffer at ******)
643 msg5.4    mesg      42,(lsla input frame at ******, sfcm at ******)
644 msg5.5    mesg      27,(lsla input buffer at ******)
645 msg5.6    mesg      41,(sending *** to lsla slot ** for line ****)
646 msg5.7    mesg      36,(escape in lsla slot ** for line ****)
647           rem
648           rem
649 hsltrc    null                hsla tracing messages
650           ind       msg6.1
651           ind       msg6.2
652           ind       msg6.3
653           ind       msg6.4
654           ind       msg6.5
655           rem
656 msg6.1    mesg      51,(hsla dcw processor, tib ******, list ******, len **)
657 msg6.2    mesg      39,(hsla pcw, tib ******, pcw ****** ******)
658 msg6.3    mesg      29,(hsla interrupt, 3wjt = ******)
659 msg6.4    mesg      45,(hsla status, tib ******, status ****** ******)
660 msg6.5    mesg      51,(hsla, tib ******, attempting icw indicator recovery)
661           rem
662           end