Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-12 - 43,50547/pltlib/v12/pltdsk.mac
There are 2 other files named pltdsk.mac in the archive. Click here to see a list.
SUBTTL	Spooler - writes compressed output to DSK:

;	!		PLOTTER MODE  --  18 BIT			!
;	!								!
;	! In 18 bit mode, each halfword from the disk has 9 bits of	!
;	! delta X and 9 bits of delta Y movement.  If the delta Y part	!
;	! is negative zero, then the X part is an op-code (such as to	!
;	! raise or lower the pen).  The only exception is in LONG mode,	!
;	! where the deltas come in halfword pairs.  The first of the	!
;	! pair is 16 bits of delta Y with 1 bit pen-down information	!
;	! (the OPCODE bit always zero), and the second byte is 18 bits	!
;	! of delta X.							!
;	!								!
;	!===============================================================!
;	! SGNY !  ABS(Delta Y)  ! SGNX ! ABS(Delta X) !	;SHORT mode
;	!=1B18=!=====377B26=====!=1B27=!====377B35====!
;	!  1   !      0         !   Operation code    !	;OPCODE
;	!=1B18=!=====377B26=====!=======777B35========!
;	!  0   ! PEN  ! SGNY !      ABS(Delta Y)      !	;1st LONG byte (Y)
;	!=1B18=!=1B19=!=1B20=!========77777B35========!
;	! SGNX !            ABS(Delta X)              !	;2nd LONG byte (X)
;	!=1B18=!=====================377777B35========!

;The output is a series of 18-bit bytes.  The high order 9 bits are 400
;for special opcodes.  (400 corresponds to Y = negative zero.)

OPCODE==400000	;Code for a special function
OP.SHT==     0	;Short mode
OP.DWN==     1	;400000=short+up, 400001=short+down
OP.LNG==     2	;400002=long+up,  400003=long+down
OP.EOP==     4	;End of plot (last byte in .PLT file)
OP.EOH==     5	;Marks end of header (start of data) and start of trailer
OP.OPR==     6	;Message for OPR follows
OP.PAS==     7	;Cause output to pause (usually used just after OP.OPR)
PEN1==      10	;Switch to pen #1
PEN2==      11	;Switch to pen #2
PEN3==      12	;Switch to pen #3
PEN4==      13	;(Future) Switch to pen #4
IFG FTHEAD,<
SYMB==      14	;Use symbols defined in spooler (GALAXY 4.1 only)>

;In short mode, each halfword has delta-X and delta-Y.

SNEGY==    400	;This implies a negative Y in short mode
SNEGX==    400	;This implies a negative X in short mode

;In long mode, 16 bits of delta Y are in the first byte, 18 of delta X in next

LNEGX== 400000	;This implies a negative X in long mode
LDOWN== 200000	;This implies the pen is to be down for the movement
LNEGY== 100000	;This implies a negative Y in long mode
SUBTTL	Revision History for PLTDSK.MAC

;Edit	  Date	   Who          Description
;----   ---------  ---  ----------------------------------------------------
; 500	16-Dec-81  JMS	Major changes.
;
;End of Revision History for PLTDSK

SUBTTL	PPDATA macro expansion

DSKBYT==INSVL.(^D18,IN.BYT)!INSVL.(.IOIBN,IN.MOD) ;Initial byte size and mode
DSKFLG==SP.OPR!SP.PEN!SP.TTL ;Special routines are OPRTXT, NEWPEN, and TITLE
DSKINC==400.0		;Increments per inch
DSKMAX==^D<327*400>,,^D<81*400>	;Max X and Y in increments
DSKTYP==0		;Does not go to a graphics terminal
DSKEXT==SIXBIT/PLT/	;Output extension

  DEFINE LCDATA,<
XBLOCK (CPLOT,1)	;;Count of calls to plot when OPRTXT was called
  >  ;End of DEFINE LCDATA





	PPDATA	(DSK)		;Expand data area
SUBTTL	INI - Initialize spooled plotter

;This data marks a real PLT file.  PLTSPL/SPROUT check it for legality

STRLST:	400000,,1		;ASCII, SIXBIT, and .REL files don't have this
	"PLOT"			;4 characters right justified
	VERSON			;Version number of plot (7th byte is flags)
STRSIZ==<.-STRLST>*2	;Byte count (2 per word)

;Plotter flags (the OPCODE bit must be off)
	PF.400==200000	;Using 400 increments per inch
	PF.PEN==100000	;Using more than one pen
	PF.OPR== 40000	;May use OPRTXT and CALL PLOT(X,Y,0) to pause plotter
	PF.HDR== 20000	;Header/trailer in ASCIZ for SPROUT to plot

;List of aliases for the spooler

DSKNAM:	DEC	1	;Data for PLOTS - IPLT=1 for subroutine WHERE
	ASCII /SPOOL/
	ASCII /DSK/	;Output to a disk file
	DEC	400	;400 increments per inch
	ASCII /DP7/	;Houston Instruments DP-7
	ASCII /DP-7/
	ASCII /DP8/	;Houston Instruments DP-8
	ASCII /DP-8/
DSKLEN==.-DSKNAM	;Length of name table

		PAGE
;Here from subroutine PLOTS to do device dependent initialization

DSKINI:	MOVE	T1,[POINT 18,STRLST]; Get addr for 'START' buffer
	MOVEI	T2,STRSIZ	;Byte count
	PUSHJ	P,OUTWRD	;Output words for PLTSPL/SPROUT
	MOVEI	T1,PF.400!PF.PEN!PF.OPR	;All but PF.HDR for now
	PUSHJ	P,OUTBYT	;Put plotter flags in file

IFN FTHEAD,<	;Plot the header and then send OP.EOH
	HRROI	T1,[DEC 0.10,90.0,1]+2  ;Literal data to be put in LOSEG
	POP	T1,ONE		;Set integer for NEWPEN(1)
	POP	T1,NINETY	;Angle in degrees for SYMBOL
	POP	T1,HDRHIT	;Size of header in inches (1/10 inch)

	MOVX	T1,INSVL.(1,PN.COL) ;Pen color number 1
	MOVEM	T1,CURR.P(P4)	;Set status to short mode, pen up
	MOVEI	T1,OPCODE!OP.SHT
	PUSHJ	P,OUTBYT	;Tell spooler short mode, pen up
	PUSHJ	P,HEADER	;Set up HEADBF
	PUSHJ	P,OUTHDR	;Plot header so tops of letters are at X=0
	MOVSI	X,(0.5)		;Move to 1/2 inch from when pen started
	PUSHJ	P,DSKORG	;Set absolute origin there
	MOVEI	T1,OPCODE!OP.EOH
	PUSHJ	P,OUTBYT	;Send OP.EOH for end of header
	TXZ	P4,P4.WIN	;The calls to PLOT from SYMBOL don't count
>  ;End of IFN FTHEAD

	MOVX	T1,INSVL.(1,PN.COL)!OP.LNG
	MOVEM	T1,CURR.P(P4)	;Set to long mode, pen up
	MOVEI	T1,OPCODE!OP.LNG
	PJRST	OUTBYT		;Tell spooler long mode, pen up
SUBTTL	FIN - Finish the plot

;Finish plot - Move to max X position and send OP.EOP

DSKFIN:	MOVEI	T1,1		;Reset to
	PUSHJ	P,DSKPN		; pen #1
	MOVE	X,MAXP.X(P4)	;Get highest X position in inches
	MOVEI	Y,0		;At bottom edge
	PUSHJ	P,MOVUP		;Move with pen up

IFN FTHEAD,<	;Move 0.5 inches past max and plot trailer
	MOVEI	T1,OPCODE!OP.EOH
	PUSHJ	P,OUTBYT	;Use EOH to mark start of trailer
	MOVEI	T1,OP.LNG!OP.DWN ;Get bits for long mode and pen down
	ANDCAM	T1,CURR.P(P4)	;Set status to short mode, pen up
	MOVEI	T1,OPCODE!OP.SHT
	PUSHJ	P,OUTBYT	;Tell spooler short mode, pen up
	MOVE	X,MAXP.X(P4)	;Current position
	FADRI	X,(0.5)		;1/2 inch past max
	FSBR	X,HDRHIT	;Leave room for trailer (X=MAX+0.4)
	PUSHJ	P,DSKORG	;Move to that position and set origin
	PUSHJ	P,TRAILR	;Set up HEADBF
	PUSHJ	P,OUTHDR	;Plot the trailer
	MOVE	X,HDRHIT	;Get height of header (0.1 inches)
	MOVEI	Y,0		;Position along lower edge
	PUSHJ	P,MOVUP		;Move to that position (0.5 from MAXP.X)
>  ;End of IFN FTHEAD

	MOVEI	T1,OPCODE!OP.EOP
	PJRST	OUTBYT		;Mark End Of Plot


;Routine to set the absolute origin.  Pen cannot move to left of this position
;Calling sequence:
;	MOVE	X,(position in inches)
;	PUSHJ	P,DSKORG
;	 *return*

DSKORG:	MOVEI	Y,0		;Y position at bottom edge of plot
	PUSHJ	P,MOVUP		;Move with pen up
	SETZB	X,Y		;Make this new origin
	DMOVEM	X,CURR.X(P4)	; so that trailer can
	DMOVEM	X,OLDP.X(P4)	; go past 11.0 inches
	DMOVEM	X,MAXP.X(P4)	; in X direction
	POPJ	P,
SUBTTL	Subroutine OPRTXT and DSKPAS


;DSKSPC is the special routine for the spooler.  Called with either
;SP.PEN or SP.OPR set in T1.

DSKSPC:	TXNE	T1,SP.PEN	;Is this a call to NEWPEN?
	 JRST	DSKPEN		;Yes
	TXNN	T1,SP.OPR	;Call to OPRTXT?
	 POPJ	P,		;No

DSKOPR:	MOVE	T1,C.PLOT	;Get count of calls to PLOT
	MOVEM	T1,CPLOT(P4)	;Save for subroutine DSKPAS
	MOVEI	T1,@(L)		;Get the start of IARRAY
	SKIPG	T2,@1(L)	;Get N
	CAILE	T2,^D300	;Skip if not to many char
	 MOVEI	T2,^D64		;Too many
	PUSHJ	P,SENDBC	;Send byte count and words
	POPJ	P,

;Routine to change pens

DSKPEN:	MOVE	T1,C.NPEN	;Get caller's argument
DSKPN:	LDB	T2,[POINTR CURR.P(P4),PN.COL] ;Get current pen number
	CAMN	T1,T2		;Are they the same?
	 JRST	DSKPE2		;Yes
	CAIL	T1,1		;Is it between 1 and 3?
	CAILE	T1,3
	 JRST	DSKPE1		;No, error
	DPB	T1,[POINTR CURR.P(P4),PN.COL] ;Set new pen number
	MOVEI	T1,OPCODE+PEN1-1(T1) ;Set to PEN1, PEN2, or PEN3
	PJRST	OUTBYT		;Tell spooler which pen to use

DSKPE1:	SETOM	SAVE0		;Set error flag
DSKPE2:	POPJ	P,


;Here to pause the plotter via CALL PLOT (X,Y,0)
;This is legal only if OPRTXT was called just before this routine

DSKPAS:	JUMPGE	T1,CPOPJ	;Ignore calls to PLOTOF and PLOTON
	SOS	T1,C.PLOT	;There must be no other calls to PLOT between
	CAME	T1,CPLOT(P4)	; the last call to OPRTXT and this call
	 JRST	DSKPA1		;No match, complain
	MOVEI	T1,OPCODE!OP.PAS
	PUSHJ	P,OUTBYT	;Spooler will pause when it hit this code
	POPJ	P,

DSKPA1:	ERRSTR	(<% Cannot CALL PLOT(X,Y,0) without calling OPRTXT first
% This call to PLOT ignored>)
	PJRST	TRACE.##	;Trace back from PUSHJ P,%PLOT
SUBTTL	Pen moving routines


;  Calling sequence:
;	DMOVE	X,(coordinates in increments)
;	SETO	T1,	;-1 for pen down, 0 for pen up
;	PUSHJ	P,DSKMOV
;	 *return*

;Format of CURR.P(P4)
IFN OP.DWN-PN.DWN,<PRINTX % OP.DWN / PN.DWN mismatch in DSKMOV routine>
IFN OP.LNG-PN.FL1,<PRINTX % OP.LNG / PN.FL1 mismatch in DSKMOV routine>

DSKMOV:	SUB	X,CURR.X(P4)	;Get delta movement
	SUB	Y,CURR.Y(P4)
	ADDM	X,CURR.X(P4)	;Set to position pen will be at
	ADDM	Y,CURR.Y(P4)
	SKIPN	X		;Any movement?
	 JUMPE	Y,CPOPJ		;No, ignore this call
	MOVE	T4,CURR.P(P4)	;Get pen number and long mode bit
	DPB	T1,[POINTR T4,OP.DWN] ;Set the pen down bit
	MOVE	T1,T4		;Put result in T1, T4 has current OP.LNG status
	MOVM	T2,X		;Get the ABS of X
	MOVM	T3,Y		;Get the ABS of Y
	CAIG	T2,377		;Skip if X is greater than short mode allows
	CAILE	T3,377		;Skip if Y is short enough for short mode
	 TXOA	T1,OP.LNG	;Set long mode bit
	TXZA	T1,OP.LNG	;Clear long mode and skip to DSKSHT
	 JRST	DSKLNG		;Go use long mode

;Here for short mode, DX and DY in single halfword

DSKSHT:	CAMN	T1,CURR.P(P4)	;Pen up/down/long status right?
	 JRST	DSKSH1		;Yes
	MOVEM	T1,CURR.P(P4)	;Save new pen status
	ANDI	T1,OP.DWN	;Keep only down bit
	IORI	T1,OPCODE!OP.SHT;Set up to say short mode
	PUSHJ	P,OUTBYT	;Output this info

DSKSH1:	MOVE	T1,T2		;Get DX into T1
	MOVEI	T2,OP.DWN	;The spooler keeps the pen up for only one
	IORM	T2,CURR.P(P4)	; move when in short mode
	SKIPGE	X		;Positive X movement?
	 ORI	T1,SNEGX	;Set the flag for a negative X
	SKIPGE	Y		;Positive Y movement?
	 ORI	T3,SNEGY	;Set the flag for a negative Y
	LSH	T3,9		;Shift Y into 9 left bits
	ORI	T1,(T3)		;Combine DY and DX
	PJRST	OUTBYT		;Go output the info
;Long mode uses first byte for dY, second byte for dX

DSKLNG:	TRNE	T4,OP.LNG	;OP.LNG set in CURR.P(P4)?
	 JRST	DSKLN1		;Yes, already in long mode
	MOVEM	T1,CURR.P(P4)	;Save new pen status
	ANDI	T1,OP.DWN	;Keep only the down bit
	IORI	T1,OPCODE!OP.LNG;Set up to say long mode
	PUSHJ	P,OUTBYT	;Output this info

DSKLN1:	TRNE	T1,OP.DWN	;Pen to be down this move?
	 ORI	T3,LDOWN	;Yes
	SKIPGE	X		;Positive X movement?
	 ORI	T2,LNEGX	;Set the flag for a negative X
	SKIPGE	Y		;Positive Y movement?
	 ORI	T3,LNEGY	;Set the flag for a negative Y
	HRL	T2,T3		;DY,,DX
				;Fall into DSKWRD

DSKWRD:	HLRZ	T1,T2		;Output left half
	PUSHJ	P,OUTBYT	; ...
	MOVEI	T1,(T2)		;Output right half
	PJRST	OUTBYT		; ...

;Send bytes pointed to by T1, using byte count in T2

SENDBC:	MOVE	T3,T1		;Save address
	MOVE	T1,T2		;Get the byte count
	PUSHJ	P,OUTBYT	;Output it
	MOVNI	T1,4(T2)	;Round up and make negative
	IDIVI	T1,5		;Make into -word count
	HRL	T3,T1		;Make AOBJN pointer
	JRST	SEND1		;Fall into SEND

SEND:	MOVE	T3,T1		;Put AOBJN pointer in less temporary AC
SEND1:	MOVE	T2,(T3)		;Get a word out of the buffer
	PUSHJ	P,DSKWRD	;Go output the word
	AOBJN	T3,SEND1	;Jump if anything more to send
	POPJ	P,		;Return
IFN FTHEAD,<	SUBTTL	Header/Trailer -- Create text

;This routine creates a header similar to the following:
;*START* NAME:SMITH JOE [11,10] DATE:3-JAN-82 9:45:50 JOB:TEST *START* PLOT%12(444)

HEADER:	MOVEI	T1,[ASCIZ /*START*/]
	PUSHJ	P,MAKHDR	;Make a header

;Put the version number of PLOT in the header buffer

	MOVEI	T1,[ASCIZ / PLOT%/]
	PUSHJ	P,STRING	;Put ' PLOT%' into the header
	MOVEI	T1,PLTVER	;Get the version number
	PUSHJ	P,OCTOUT	;Go put the version number in the header
IFG PLTMIN,<MOVEI  T4,"@"+PLTMIN  ;Get an 'A', 'B', 'C',... in the AC
	    PUSHJ  P,CHAR	  ;Put the minor version in the header >
	MOVEI	T4,"("		;Put '(' into the header
	PUSHJ	P,CHAR
	MOVEI	T1,PLTEDT	;Get the edit number
	PUSHJ	P,OCTOUT	;Put the edit number in the header
	MOVEI	T4,")"		;Put ')' into the header
	PUSHJ	P,CHAR
IFG PLTWHO,<MOVNI  T1,PLTWHO	  ;Get who last edit plot number
	    PUSHJ  P,OCTOUT	  ;Put this number into the header >
	POPJ	P,

;This routine creates a trailer similar to the following:
;**END** NAME:SMITH JOE [11,10] DATE:3-JAN-82 9:47:03 JOB:TEST **END**

TRAILR:	MOVEI	T1,[ASCIZ /**END**/]
MAKHDR:	PUSH	P,T1		;Save pointer to '*START*'
	MOVE	T2,[POINT 7,HEADBF] ;Set up the byte pointer to header block
	MOVEM	T2,HEADBP	; ...
	SETZM	HEADCT		;Clear character count
	PUSHJ	P,STRING	;Put '*START*' or '**END**' into header block
	MOVEI	T1,[ASCIZ / NAME:/]
	PUSHJ	P,STRING	;Put ' NAME:' into header block
TOPS20<	PRINTX	% Major changes needed in MAKHDR routine>
TOPS10<	HRROI	T1,.GTNM1	;Get the first half
	GETTAB	T1,		; of the user's name
	  MOVSI	T1,'???'	;Can never happen
	MOVEI	T3,0		;Set up a counter for SIXBIT output
	PUSHJ	P,SIXB		;Put name in header block (count trailing spaces)
	HRROI	T1,.GTNM2	;Get the second half
	GETTAB	T1,		; of the user's name
	  SETZ	T1,		;Can never happen
	PUSHJ	P,SIXB		;Put name in header block (including spaces)

		PAGE	;(still in TOPS10)
	MOVEI	T1,[ASCIZ / [/]
	PUSHJ	P,STRING	;Put ' [' into header block
	GETPPN	T1,		;Get user's PPN
	  JFCL			;*#$'&"&% JACCT!!
	MOVEM	T1,MYPPN	;Save my PPN for later
	HLRZS	T1
	PUSHJ	P,OCTOUT	;Output PROJ#
	MOVEI	T1,[ASCIZ /,/]
	PUSHJ	P,STRING	;Put a ',' between PROJ# and PROG#
	HRRZ	T1,MYPPN
	PUSHJ	P,OCTOUT	;Output PROG#
	MOVEI	T1,[ASCIZ /] DATE:/]
	PUSHJ	P,STRING	;Put '] DATE:' into header block
	DATE	T2,		;Get the date
	IDIVI	T2,^D31
	MOVEM	T2,TEMP
	MOVEI	T1,1(T3)
	PUSHJ	P,DECOUT	;Output the day
	MOVE	T1,TEMP
	IDIVI	T1,^D12
	MOVEM	T1,TEMP		;Save the year
	MOVE	T1,MONTAB(T2)	;Get the month
	PUSHJ	P,SIX		;Output the month
	MOVE	T1,TEMP		;Get the year
	ADDI	T1,^D64
	PUSHJ	P,DECOUT	;Output the year
	MOVEI	T4," "		;Separate with a space
	PUSHJ	P,CHAR
HDRTIM:	TIMER	T1,		;Get the time
	IDIVI	T1,^D216000	;Divide by ticks per hour
	MOVEM	T2,TEMP
	PUSHJ	P,DECOUT	;Output the hours
	MOVE	T1,TEMP
	IDIVI	T1,^D3600	;Divide by ticks per minute
	MOVEM	T2,TEMP
	PUSHJ	P,COLON2	;Output a colon and 2 digits
	MOVE	T1,TEMP
	IDIVI	T1,^D60		;Set up to output the seconds
	PUSHJ	P,COLON2	;Output a colon and 2 digits
	MOVEI	T1,[ASCIZ / JOB:/]
	PUSHJ	P,STRING	;Put ' JOB:' into the header block
	HRROI	T1,.GTPRG	;Job name is same as program name
	GETTAB	T1,		;Get it
	  MOVSI	T1,'PLT'
	PUSHJ	P,SIX		;Output job name
>  ;End TOPS10
	MOVEI	T4," "		;Add a space
	PUSHJ	P,CHAR
	POP	P,T1		;Get back original pointer
	PUSHJ	P,STRING	;Put '*START*' into the header block
IFN FTDBUG,<MOVEI T1,0		;Make for ASCIZ
	    MOVE  T2,HEADBP	; without affecting
	    IDPB  T1,T2	>	; byte pointer (for HEADBF$0T)
	POPJ	P,
SUBTTL	Header/Trailer -- Utility subroutines

;  Subroutine SIX - this routine puts a SIXBIT word into the output array
;		      defined by the byte pointer (B1), uses T1, T2, and CH

;  Calling sequence:
;	MOVE	B,(the SIXBIT word)
;	PUSHJ	P,SIX		;**This routine will destroy AC1 and AC2
;	 *return*

SIX:	SETZ	T3,		;Delete trailing spaces (SIXB prints spaces)
SIXB:	MOVE	T2,[POINT 6,T1]	;Set up a byte pointer to get chars for output
SIX0:	ILDB	T4,T2		;Get a char
	JUMPE	T4,SIX4		;Jump if the char is a space
	JUMPE	T3,SIX2		;Jump if no spaces to be output
	PUSH	P,T4		;Save T4
	MOVEI	T4," "		;Get a space

SIX1:	PUSHJ	P,CHAR		;Go output a space (i.e. between halves of user name)
	SOJG	T3,SIX1		;Jump if more spaces to output
	POP	P,T4		;Restore T4
SIX2:	ADDI	T4," "-' '	;Convert SIXBIT to 7-bit ASCII
	PUSHJ	P,CHAR		;Go output the char
SIX3:	TLNE	T2,770000	;Skip if no more char to output
	 JRST	SIX0		;Go output another char
	POPJ	P,		;Return
SIX4:	AOJA	T3,SIX3		;Add 1 to the space count and jump

;  Subroutine STRING - this routine puts an ASCIZ string into an array defined
;			 by the byte pointer (B1), uses CH

;  Calling sequence:
;	MOVEI	T1,(the address of the ASCIZ string)
;	PUHSJ	P,STRING	;Go output the array into B1
;	 *return*

STRING:	TLOA	T1,(POINT 7)	;Set up to output ASCIZ string
STRIN0:	PUSHJ	P,CHAR		;Output one char
STRIN1:	ILDB	T4,T1		;Get a char
	JUMPN	T4,STRIN0	;Jump if not a null char
	POPJ	P,		;Return

MONTAB:	SIXBIT	/-JAN-/	;Table of the months of the year in SIXBIT
	SIXBIT	/-FEB-/
	SIXBIT	/-MAR-/
	SIXBIT	/-APR-/
	SIXBIT	/-MAY-/
	SIXBIT	/-JUN-/
	SIXBIT	/-JUL-/
	SIXBIT	/-AUG-/
	SIXBIT	/-SEP-/
	SIXBIT	/-OCT-/
	SIXBIT	/-NOV-/
	SIXBIT	/-DEC-/
SUBTTL	Header/Trailer -- Numberic output routines

;TWOUT = 2 digits, DECOUT = decimal, OCTOUT = octal

;  Calling sequence:
;	MOVE	T1,(the number of output)
;	PUSHJ	P,routine
;	 *return*
;			Uses T1-T4, HEADBP and HEADCT

COLON2:	MOVEI	T4,":"		;Output a colon and 2 digits
	PUSHJ	P,CHAR
TWOUT:	MOVEI	T4,"0"
	CAIG	T1,^D9		;Skip if not less than ten
	 PUSHJ	P,CHAR		;Output a zero
	PFALL	DECOUT		;Now the other digit

DECOUT:	SKIPA	T3,[^D10]	;Move 10 into AC and skip
OCTOUT:	 MOVEI	T3,8		;Move 8 into AC
	JUMPGE	T1,RADOUT	;Jump if the number is positive
	MOVNS	T1		;Make the number positive
	MOVEI	T4,"-"
	PUSHJ	P,CHAR		;Put a '-' before the number
RADOUT:	IDIVI	T1,(T3)		;Divide by proper radix
	MOVEI	T4,"0"(T2)	;Convert to ASCII
	HRLM	T4,(P)		;Store char on PDL
	SKIPE	T1		;If not done,
	 PUSHJ	P,RADOUT	; go get an other number
	HLRZ	T4,(P)		;Get char off PDL
	PFALL	CHAR		;Output it

CHAR:	IDPB	T4,HEADBP	;Store a char
	AOS	HEADCT		;Add one to the count
	POPJ	P,
SUBTTL	Header/Trailer -- Output the prepared text

;Routine to plot the characters in HEADBF.
;Calling sequence:
;	PUSHJ	P,HEADER	or	PUSHJ	P,TRAILR
;	PUSHJ	P,OUTHDR
;	 *return*
;			Preserves only P3 and P4

OUTHDR:	PUSH	P,P3		;Save ACs
	PUSH	P,P4
	PUSH	P,X.ORIG	;Save current origin
	PUSH	P,Y.ORIG
	SETZM	X.ORIG		;Cancel origin offset
	SETZM	Y.ORIG
IFL FTHEAD,<MOVEI L,[-2,,0	  ;2 args for subroutine ISETAB
		INTEGER	ONE	  ;Table number 1
		INTEGER	TEMP	  ;Error code
		    ]+1		;Point to args
	PUSHJ	P,ISETAB##	;Change to default font in table 1
	MOVEI	L,[-6,,0	  ;6 args
		REAL	HDRHIT	  ;X
		REAL	L.ZERO	  ;Y
		REAL	HDRHIT	  ;HEIGHT
		INTEGER	HEADBF	  ;Array of characters
		REAL	NINETY	  ;ANGLE
		INTEGER	HEADCT	  ;Count of chars
		    ]+1		;Point to args
	PUSHJ	P,SYMBOL##>	;Use external subroutine (which calls PLOT)

IFG FTHEAD,<MOVEI T1,OPCODE!OP.SYM;Turn on hardware symbol generator
	PUSHJ	P,OUTBYT	; ...
	MOVE	T1,HDRHIT	;Height
	HLR	T1,NINETY	;Angle
	PUSHJ	P,DSKWRD	;Put in file
	MOVEI	T1,HEADBF	;Address
	MOVE	T2,HEADCT	;Byte count
	PUSHJ	P,SENDBC	;Send byte count and words
>  ;End of IFG FTHEAD

	POP	P,Y.ORIG	;Restore origin
	POP	P,X.ORIG
	POP	P,P4		;Restore ACs
	POP	P,P3
	POPJ	P,
>  ;End of IFN FTHEAD


LITDSK:	LIT

		PAGE		;End of PLTDSK.MAC