Google
 

Trailing-Edge - PDP-10 Archives - cuspmar86binsrc_2of2_bb-fp63a-sb - 10,7/rsxt10/rsxt10.mac
There are 6 other files named rsxt10.mac in the archive. Click here to see a list.

;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976,1984,1986.
;ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;REVISION HISTORY

; 2	10-NOV-76	BELANGER
;


SUBTTL	INITIALIZATION AND RESTART

RSXFMT:
	JFCL	0,0		; NO-OP
	SETZ	0,0		; CLEAR ACS
	MOVEI	17,1
	BLT	17,17		; ZAP!
	RESET	0,0		; CLEAR REST OF THE WORLD
	SETZM	0,CLRBEG	; NOW CLEAR LOCAL VARIABLES
	MOVE	T1,[XWD CLRBEG,CLRBEG+1]
	BLT	T1,CLREND	; SO
	OPEN	TTYCH,TTYOPN	; OPEN THE TTY CHANNEL
	JRST	[OUTSTR	[ASCIZ	%
?? CAN'T OPEN TTY%]
		 EXIT	0,0]
	INBUF	TTYCH,0		; SET UP THE BUFFERS
	OUTBUF	TTYCH,0		; SO
	GETPPN	T1,0		; READ OUR PPN
	JFCL	0,0		; GUARD AGAINST [1,2]
	MOVEM	T1,OURPPN	; STASH IT AWAY
	MOVX	T1,<XWD M$DEF,M$DEF>
	MOVEM	T1,MODE		; SET DEFAULT MODE
	MOVEI	T1,^D256	; SET DEFAULT
	MOVEM	T1,RCDSIZ	; RECORD SIZE
	MOVX	F,F.ADDR	; DEFAULT TO ADDRESSES
CMDRST:
	MOVE	P,[IOWD PDLEN,PDL]
	CLOSE	CMDCH,0		; CLOSE THE COMMAND CHANNEL
	RELEASE	CMDCH,0		; AND RELEASE IT
CMDINI:
	TXZE	F,F.EXIT	; EXIT?
	EXIT	0,0		; YUP -- BYE...
	MOVEI	T2,[ASCIZ %RSXFMT>%]
	TXNN	F,F.CMND	; DON'T PROMPT IF COMMAND MODE
	CALL	TYPSTR		; PROMPT THE USER
	CALL	GETCMD		; GET THE COMMAND STRING
	JUMPE	P1,CMDINI	; JUMP IF NULL STRING
CMDNXT:
	MOVEI	P1,CMDTAB	; MAIN COMMAND TABLE POINTER TO P1
CONCMD:
	CALL	TABSCN		; SCAN THE TABLE
	HRRZ	P1,0(P1)	; GET THE DISPATCH
	CALL	0(P1)		; DO IT TO IT
	SKIPA	0,0		; SEE IF WE MUST CONTINUE THIS COMMAND
	JRST	CONCMD		; CONTINUE THIS COMMAND
	LDB	C,CMDPTR	; LOOK AT THE LAST BYTE
	JUMPE	C,CMDINI	; DO ANOTHER COMMAND
	JRST	CMDNXT		; DO THE NEXT COMMAND
SUBTTL	ERROR PROCESSING ROUTINES

; HERE ON "IGNORE"-ABLE ERROR, PREFIX MESSAGE POINTED TO BY P1 WITH "%"

CMDERI:
	TXNN	F,F.IGNR	; IGNORE THIS ERROR?
	JRST	CMDERR		; NO -- FATAL
	CALL	TYPTST		; SEE IF WE NEED A <CRLF>
	MOVEI	T2,[ASCIZ /% /]
	CALL	TYPSTR		; WARNING PREFIX
	MOVE	T2,P1		; STRING POINTER
	CALLR	TYPSTC		; DO THE LINE AND EXIT

; HERE ON FATAL ERROR, PREFIX MESSAGE WITH "?" AND TYPE ERROR STRING

CMDERR:
	CLOSE	TTYCH,0		; CLOSE THE TTY CHANNEL
	OPEN	TTYCH,TTYOPN	; RE-OPEN IT (FLUSH TYPE AHEAD)
	JRST	[OUTSTR	[ASCIZ %? CAN'T REOPEN TTY%]
		 EXIT	0,0]
	CALL	TYPTST		; SEE IF WE NEED A <CRLF>
	MOVEI	T2,[ASCIZ %? %]
	CALL	TYPSTR		; PRINT IT
	MOVE	T2,P1		; ERROR STRING
	CALL	TYPSTR		; PRINT THAT
	TXZN	F,F.CMND	; ARE WE IN COMMAND MODE?
	JRST	CMDER2		; NO -- JUST GO ON
	MOVEI	T2,[ASCIZ %:
RSXFMT>%]
	CALL	TYPSTR		; TYPE A PROMPT
	MOVEI	T2,CMDBUF	; POINT TO THE COMMAND
	CALL	TYPSTR		; PRINT IT
CMDER2:
	CALL	TYPTST		; DO <CRLF> IF REQUIRED
	CALLR	CMDRST		; AND TRY AGAIN
SUBTTL	$CONVE -- THE "CONVERT COMMAND

; HERE TO CONVERT A FILE FROM ONE FORMAT TO ANOTHER
; COMMAND IS
;
;	CONVERT INPUT-FILE-SPEC OUTPUT-FILE-SPEC
;
; IF THE OUTPUT FILE-SPEC IS OMMITTED THE ORIGINAL FILE IS SUPERCEDED.

$CONVE:
	TXZ	F,F.TTEM	; CLEAR TEMP FLAG
	JUMPE	C,[ERR (<ILLEGAL FILE SPEC>)]
CONVEA:
	MOVE	P1,[XWD INOPN,INPLEB]
	CALL	GETFIL		; GET THE INPUT FILE SPEC
	JUMPN	C,CNVRTA	; JUMP IF WE HAVE A FULL FILE SPEC
	MOVEI	T2,[ASCIZ %OUTPUT FILE: %]
	CALL	TYPSTR		; PROMPT
	CALL	GETCMD		; READ THE FILE-SPEC
	JUMPN	P1,CNVRTA	; JUMP IF NOT DEFAULT
CONVEB:
	MOVE	T1,[XWD INPLEB,OUTLEB]
	BLT	T1,OUTOPN+1	; COPY INPUT FILE SPEC TO OUTPUT FILE SPEC
	JRST	NXTFIL		; JUMP OVER THE CALL
CNVRTA:
	MOVE	P1,[XWD OUTOPN,OUTLEB]
	CALL	GETFIL		; GET THE OUTPUT FILE SPEC

; HERE TO DETERMINE THE INPUT FILE MODE

NXTFIL:
	HLRZ	IM,MODE		; GET THE MODE
	CAIE	IM,M$DEF	; DEFAULT?
	JRST	CNVRTC		; NO -- WE HAVE THE MODE ALREADY
	CALL	OPNINA		; YES -- OPEN THE FILE
	LOOKUP	INCH,INPLEB	; LOOK THE FILE UP
	ERR	<CAN'T FIND INPUT FILE>
	CALL	FILIN		; READ THE FIRST BYTE FROM THE FILE
	ERR	<PREMATURE END OF FILE>
	CLOSE	INCH,0		; CLOSE THE INPUT FILE
	RELEASE	INCH,0		; RELEASE IT
	HLLZS	0,INPLEB+LE.EXT	; RESET THE LOOKUP BLOCK
	MOVE	T1,INPLEB+LE.PPS; FOR THE NEXT LOOKUP
	MOVEM	T1,INPLEB+LE.PPN
	MOVEI	T1,EXTTAB	; EXTENSION TABLE POINTER
	HLLZS	0,INPLEB+LE.EXT	; FLUSH JUNK FORM EXTENSION
	MOVN	T4,0(T1)	; NEGATE THE LIST COUNT
	HRLS	0,T4		; SET THE COUNT
	HRRI	T4,1(T1)	; MAKE AN "AOBJN" POINTER
; HERE TO DETERMINE THE FILE MODE FROM THE EXTENSION

CNVRTB:
	HLRZ	T1,0(T4)	; GET THE POINTER TO THE EXTENSION
	MOVE	T1,0(T1)	; GET THE EXTENSION
	CAME	T1,INPLEB+LE.EXT
	AOBJN	T4,CNVRTB	; NO MATCH -- GO ON LOOKING
	JUMPG	T4,ASCFIL	; NO MATCH AT ALL -- ASSUME ASCII
	HRRE	IM,0(T4)	; MATCH -- GET THE MODE
	JUMPL	IM,ASCFL0	; GO SET SPECIAL ASCII FLAGS
	CAIE	IM,M$RSB	; BINARY FILE?
	JRST	CNVRTC		; NO -- MODE IS SET UP
	TLNN	C,177776	; YES -- DOS FORMAT?
	MOVEI	IM,M$DSB	; YES -- MARK IT
	JRST	CNVRTC		; AND EXIT

; HERE TO SET UP ASCII FILE MODES

ASCFL0:
	HRLZS	0,IM		; ASCII FLAGS TO LH IM
	TXZ	IM,1B0		; FLUSH THE SIGN BIT
	TXNN	F,F.IBCR!F.IPCR!F.LFSS
	TDO	F,IM		; SET THE MODE FLAGS FOR THIS FILE
ASCFIL:
	MOVEI	IM,M$RSA	; ASSUME RSX-ASCII
	TXNE	C,177B6		; IS IT 7-BIT ASCII?
	MOVEI	IM,M$DSA	; YES -- MARK IT

; HERE TO SET UP THE OUTPUT FILE MODES

CNVRTC:
	HRRZ	OM,MODE		; SET THE OUTPUT MODE
	CAIN	OM,M$DEF	; DEFAULT?
	HRRZ	OM,MSGTAB(IM)	; NO -- SET THE MODE
	CALL	OPENIN		; OPEN THE INPUT FILE
	CALL	OPNOUT		; OPEN THE OUTPUT FILE
	LOOKUP	INCH,INPLEB	; FIND THE INPUT FILE
	ERR	<CAN'T FIND INPUT FILE>
	ENTER	OUTCH,OUTLEB	; FIND THE OUTPUT FILE
	ERR	<CAN'T ENTER OUTPUT FILE>
	MOVE	P1,[XWD INOPN,INPLEB]
	MOVE	P2,IM		; FILE TYPE OFFSET TO P2
	CALL	TYPFIL		; PRINT THE FILE DESCRIPTION
	MOVEI	T2,[ASCIZ % ==> %]
	CALL	TYPSTR
	MOVE	P1,[XWD OUTOPN,OUTLEB]
	MOVE	P2,OM		; FILE TYPE OFFSET TO P2
	CALL	TYPFIL		; PRINT THE FILE DESCRIPTION
	SETZB	IC,INADR	; RESET INPUT CHARACTER AND ADDRESS
	SETZB	OC,OUTADR	; RESET OUTPUT TOO
; HERE TO PROCESS THE FILE

CNVTLP:
	CALL	@GRCTAB(IM)	; GET AN INPUT RECORD BYTE COUNT
	JRST	DONE		; E-O-F RETURN
	MOVE	P1,C		; BYTE COUNT TO P1
	CALL	@PRCTAB(OM)	; WRITE IT
	JUMPE	P1,ENDRCD	; E-O-R -- CLEAN UP

; HERE TO COPY THE FILE, BYTE COUNT IN P1

COPYLP:
	CALL	@GBYTAB(IM)	; GET AN INPUT BYTE
	ERRI	<PREMATURE END-OF-FILE>,CRET
	CALL	@PBYTAB(OM)	; WRITE IT
	SOJG	P1,COPYLP	; DO ENTIRE RECORD

; HERE ON END OF RECORD

ENDRCD:
	CALL	@EORTAB(OM)	; FINISH OUTPUT RECORD
	CALL	@EIRTAB(IM)	; AND THE INPUT RECORD
	JRST	CNVTLP		; GET THE NEXT RECORD

; HERE TO FINISH THE FILE AND CLOSE IT

DONE:
	SKIPGE	C,OC		; SKIP IF CHARACTER ALREADY OUTPUT
	CALL	FILOUT		; PUT THE LAST BYTE INTO THE FILE
	CALL	OUTFIL		; FORCE THE FILE OUT
	CLOSE	INCH,0		; CLOSE THE INPUT FILE
	RELEASE	INCH,0		; RELEASE THE CHANNEL
	CLOSE	OUTCH,0		; CLOSE THE OUTPUT FILE
	RELEASE	OUTCH,0		; RELEASE THE CHANNEL
	CALLR	TYPCR		; TYPE A <CRNL> AND EXIT
SUBTTL	$CRLF -- THE "CRLF" COMMAND

$CRLF:
	SETZ	P1,0		; SET DEFAULT
	JUMPE	C,CRLFX		; EXIT NOW IF DEFAULT
CRLFA:
	MOVEI	P1,ASCTAB	; TABLE POINTER TO P1
	CALL	TABSCN		; SCAN THE TABLE
	HRRZ	P1,0(P1)	; GET THE FLAGS
CRLFX:
	TXZ	F,F.IBCR!F.IPCR!F.LFSS
	TLO	F,0(P1)		; SET NEW FLAGS
	RETURN			; TO CALLER

; $EXIT -- THE "EXIT" COMMAND

$EXIT:
	EXIT	1,0		; EXIT
	JRST	RSXFMT		; RESTART

 ;$HELP -- THE "HELP" COMMAND

$HELP:
	SETZM	0,INOPN		; ASCII MODE
	MOVSI	T1,'HLP'	; DEFAULT DEVICE
	MOVEM	T1,INOPN+1	; SET IT
	MOVE	T1,[SIXBIT /RSXFMT/]
	MOVEM	T1,INPLEB	; FILE NAME
	MOVSI	T1,'HLP'	; EXTENSION
	MOVEM	T1,INPLEB+LE.EXT
	OPEN	INCH,INOPN	; OPEN THE CHANNEL
	ERR	<CAN'T OPEN HELP FILE>
	LOOKUP	INCH,INPLEB	; FIND THE FILE
	ERR	<CAN'T FIND HELP FILE>
HELPA:
	SOSGE	0,INPBLK+2	; COUNT THIS BYTE
	JRST	HLPMOR		; EMPTY BUFFER -- GET MORE
	ILDB	C,INPBLK+1	; LOAD THE BYTE
	JUMPE	C,HELPEX	; DONE IF <NULL>
	CALL	TTYOUT		; OUTPUT IT
	JRST	HELPA		; AND GET ANOTHER
HLPMOR:
	IN	INCH,0		; GET ANOTHER BUFFER
	JRST	HELPA		; GOT IT -- GO ON
	STATO	INCH,IO.EOF	; END-OF-FILE?
	ERR	<INPUT ERROR ON HELP FILE>
	SKIPLE	0,INPBLK+2	; ANYTHING IN THE BUFFER?
	JRST	HELPA		; YES -- CONTINUE
HELPEX:
	CLOSE	INCH,0		; NO -- CLOSE THE FILE
	RELEASE	INCH,0		; RELEASE THE CHANNEL
	RETURN			; RETURN
SUBTTL	$INFOR -- THE "INFORMATION" COMMAND

$INFOR:
	MOVX	P4,-1		; TO PREVENT RECURSION IN "ALL"
	JUMPE	C,INFALL	; DEFAULT IS ALL
	MOVEI	P1,INFTAB	; TABLE POINTER TO P1
	RETSKP			; SKIP RETURN

; INFORMATION ABOUT "ALL"

INFALL:
	AOJN	P4,CRET		; QUIT IF RECURSING
	MOVSI	P3,-INFSIZ	; POINTER TO ALL
INFAL1:
	HRRZ	T4,INFTAB+1(P3)	; GET A DISPATCH
	CALL	0(T4)		; DO IT
	AOBJN	P3,INFAL1	; TILL DONE
	RETURN			; EXIT

; INFORMATION ABOUT "ADDRESS WORDS"

INFADR:
	MOVX	P1,F.ADDR	; FLAG TO P1
	MOVEI	P2,[ASCIZ % ADDRESS (WORDS EXIST IN IMAGE FILES)%]
	CALLR	INFNOC

; INFORMATION ABOUT "CRLF"

INFCR:
	MOVEI	T2,[ASCIZ % CRLF (IN ASCII FILES IS) %]
	CALL	TYPSTR
	MOVEI	T2,[ASCIZ %DEFAULT%]
	TXNE	F,F.IBCR
	MOVEI	T2,[ASCIZ %IMBEDDED%]
	TXNE	F,F.IPCR
	MOVEI	T2,[ASCIZ %IMPLIED%]
	TXNE	F,F.LFSS
	MOVEI	T2,[ASCIZ %CARRIAGE-RETURN-SINGLE-SPACE%]
	CALLR	TYPSTC
; INFORMATION ABOUT "IGNORE"

INFIGN:
	MOVX	P1,F.IGNR
	MOVEI	P2,[ASCIZ % IGNORE (FILE FORMAT ERRORS)%]
	CALLR	INFNOC

; INFORMATION ABOUT "MODE"

INFMOD:
	MOVEI	T2,[ASCIZ % MODE (OF INPUT) %]
	CALL	TYPSTR
	HLRZ	T2,MODE
	HLRZ	T2,MSGTAB(T2)
	CALL	TYPSTR
	MOVEI	T2,[ASCIZ % (AND OUTPUT) %]
	CALL	TYPSTR
	HRRZ	T2,MODE
	HLRZ	T2,MSGTAB(T2)
	CALLR	TYPSTC

; INFORMATION ABOUT "RECORD-SIZE"

INFRCD:
	MOVEI	T2,[ASCIZ % RECORD-SIZE (OF IMAGE FILES IS) %]
	CALL	TYPSTR
	MOVE	P1,RCDSIZ
	CALL	TYPDEC
	CALLR	TYPCR

; INFORMATION ABOUT "NO-THING"

INFNOC:
	MOVEI	T2,[ASCIZ % NO%]
	TDNN	F,P1
	CALL	TYPSTR
	MOVE	T2,P2
	CALLR	TYPSTC
SUBTTL	$MODE -- THE "MODE" COMMAND

$MODE:
	MOVEI	P4,MSGTAB	; SO WE CAN COMPUTE OFFSET
	PUSH	P,MODE		; CURRENT MODE TO STACK
	JUMPN	C,MODEA		; CONTINUE PROCESSING
	MOVEI	P1,M$DEF	; DEFAULT
	JRST	MODEB		; SET IT
MODEA:
	MOVEI	P1,FMTTAB	; MODE TABLE POINTER TO P1
	CALL	TABSCN		; SCAN THE TABLE
	SUB	P1,P4		; GET THE OFFSET
MODEB:
	HRLM	P1,0(P)		; SET THE INPUT MODE
	MOVEI	P1,M$DEF	; ASSUME DEFAULT
	JUMPN	C,MODEC		; DEFAULT?
	JRST	MODEX		; YES -- SET IT AND EXIT
MODEC:
	MOVEI	P1,FMTTAB	; MODE TABLE POINTER TO P1
	CALL	TABSCN		; SCAN IT
	SUB	P1,P4		; GET THE OFFSET
MODEX:
	HRRM	P1,0(P)		; SET THE OUTPUT MODE
	POP	P,MODE		; SET THE NEW MODE WORD
	RETURN			; AND EXIT
SUBTTL	$NO -- THE "NO" COMMAND

; THE "NO" COMMAND

$NO:
	TXC	F,F.NO		; FLOP THE FLAG
	MOVEI	P1,NOCTAB	; "NO" OBJECT TABLE
	RETSKP			; SKIP RETURN

; THE "IGNORE" COMMAND

$IGNOR:
	MOVX	P1,F.IGNR	; "IGNORE" FLAG TO P1
	CALLR	NOSETF		; SET / CLEAR AND EXIT

; THE "ADDRESS" COMMAND

$ADDRE:
	MOVX	P1,F.ADDR	; "ADDRESS" FLAG TO P1
	CALLRX	NOSETF		; SET / CLEAR AND EXIT

; HERE TO SET OR CLEAR THE FLAG BIT IN "F" FROM THAT IN "P1"

NOSETF:
	TXZE	F,F.NO		; DID HE SAY "NO"?
	TDZA	F,P1		; YES -- CLEAR THE FLAG
	TDO	F,P1		; NO -- SET THE FLAG
	RETURN			; EXIT

; $RECOR -- THE RECORD SIZE COMMAND

; HERE TO GET THE FILE RECORD SIZE

$RECOR:
	CALL	GETDEC		; GET THE RECORD SIZE IN WORDS
	MOVEM	P1,RCDSIZ	; SET UP THE RECORD SIZE
	RETURN			; AND EXIT

; $TAKE -- THE "TAKE" COMMAND

; HERE TO GET A FILE SPEC FOR A COMMAND FILE AND OPEN IT

$TAKE:
	MOVE	P1,[XWD CMDOPN,CMDLEB]
	CALL	GETFIL		; GET THE FILE SPEC
	OPEN	CMDCH,CMDOPN	; OPEN THE FILE
	ERR	<CAN'T OPEN COMMAND FILE>
	LOOKUP	CMDCH,CMDLEB	; LOOK THE FILE UP
	ERR	<CAN'T FIND COMMAND FILE>
	TXO	F,F.CMND	; OK -- MARK COMMAND MODE
	RETURN			; AND GO PROCESS
SUBTTL	TABSCN -- SYMBOL TABLE SCANNER SUBROUTINE

; THIS SUBROUTINE WILL SCAN THE TABLE POINTED TO BY "P1" IN THE CALL
; FOR A MATCH WITH THE SYMBOL CURRENTLY POINTED TO BY THE INPUT POINTER.
; THE DISPATCH FOR THE SYMBOL IS RETURNED IN "P1".

TABSCN:
	PUSH	P,P2		; SAVE P2 ON THE STACK
	PUSH	P,P3		; AND P3
	SETZ	P2,0		; CLEAR IT
	MOVN	T1,0(P1)	; NEGATE THE TABLE LENGTH WORD
	MOVEI	P1,1(P1)	; GET OVER THE LENGTH WORD
	HRL	P1,T1		; MAKE AN "AOBJN" POINTER FROM IT
TBSCNA:
	SETZ	T1,0		; CLEAR THE MATCH COUNTER
	HLRZ	T4,0(P1)	; GET THE SYMBOL POINTER
	HRLI	T4,(POINT 7,)	; MAKE A BYTE POINTER FROM IT
	MOVE	T3,CMDPTR	; GET THE CURRENT COMMAND POINTER
TBSCNB:
	ILDB	C,T3		; GET THE CHARACTER FROM INPUT
	SKIPN	0,C		; END-OF-LINE?
	MOVEI	C," "		; YES -- FAKE A <SPACE>
	ILDB	T2,T4		; AND THAT FROM SYMBOL
	JUMPE	T2,TBSCNC	; JUMP ON END OF SYMBOL
	CAMN	C,T2		; DO THE CHARACTERS MATCH?
	AOJA	T1,TBSCNB	; YES -- GO ON
TBSCNC:
	JUMPE	T1,TBSCND	; JUMP IF NO MATCH
	CAIE	C," "		; LAST INPUT CHARACTER A <SPACE>?
	JRST	TBSCND		; NO -- NO MATCH
	JUMPE	T2,TBSCNE	; YES -- JUMP IF EXACT MATCH
	MOVE	T4,T1		; CURRENT MATCH COUNT TO T4
	HLRZ	T2,P2		; LAST MATCH COUNT TO T2
	SUB	T4,T2		; DIFFERENCE TO T4
	JUMPL	T4,TBSCND	; NO MATCH IF .LT. 0
	JUMPE	T4,[ERR	(<AMBIGUOUS SYMBOL>)]
	HRLZ	P2,T1		; PARTIAL MATCH -- SAVE MATCH COUNT
	HRR	P2,P1		; SAVE THE DISPATCH POINTER
	MOVE	P3,T3		; SAVE THE BYTE POINTER
TBSCND:
	AOBJN	P1,TBSCNA	; LOOK AT THE NEXT SYMBOL
	JUMPE	P2,[ERR	(<UKNOWN SYMBOL>)]
	HRRZS	0,P2		; FLUSH THE MATCH COUNT
	MOVE	T3,P3		; BYTE POINTER TO T3
	SKIPA	P1,P2		; PUT THE DISPATCH IN P1
TBSCNE:
	HRRZS	P1,P1		; EXACT MATCH -- FLUSH WORD COUNT
	MOVEM	T3,CMDPTR	; SET UP THE NEW INPUT POINTER
	LDB	C,T3		; READ THE LAST BYTE INTO "C"
	POP	P,P3		; RESTORE P3
	POP	P,P2		; RESTORE P2
	RETURN
SUBTTL	GETCMD -- COMMAND STRING INPUT ROUTINE

; HERE TO INPUT A COMMAND STRING. RETURNS WITH A POINTER TO THE
; COMMAND STRING IN "CMDPTR" AND THE BYTE COUNT IN P1.

GETCMD:
	MOVE	T1,[POINT 7, CMDBUF]
	MOVEM	T1,CMDPTR	; INIT BYTE POINTERS
	MOVEI	T2,<CMDSIZ*5>	; INIT THE BYTE COUNT
GTCMD1:
	CALL	TTYINP		; READ A CHARACTER
	JRST	GTCMDX		; BREAK CHARACTER -- GO PROCESS
	CAIN	C,.CHTAB	; IS THIS A <TAB>?
	MOVEI	C," "		; YES -- CONVERT TO <SPACE>
	IDPB	C,T1		; PUT THE BYTE IN THE BUFFER
	SOJG	T2,GTCMD1	; LOOP TILL EXHAUSTED
	ERR	<COMMAND BUFFER OVERFLOW>
GTCMDX:
	CAIE	C,.CHLFD	; LAST CHARACTER A <NEW-LINE>?
	CALL	TYPCR		; YES -- GIVE A FREE <CR-NL>
	SETZ	C,0		; RENDER CHARACTER NULL
	IDPB	C,T1		; NULL TERMINATOR TO BUFFER
	MOVEI	P1,<CMDSIZ*5>	; RETURN THE TRUE BYTE COUNT
	SUB	P1,T2		; BYTE COUNT TO P1
	RETURN			; TO CALLER
SUBTTL	GETFIL -- FILE SPEC INPUT SUBROUTINE

; THIS SUBROUTINE WILL INPUT AND SET A COMPLETE FILE SPEC OF THE FORM:
;
;		DEV:[PROJ,PROG]FILE.EXT
;
; THE DEFAULT FOR "DEV:" IS "DSK:", AND THE DEFAULT FOR [PROJ,PROG]
; IS "SELF". THE MINIMUM SPECIFICATION IS THE FILENAME.
; ENTER WITH LH P1 POINTING TO THE OPEN BLOCK AND RH P1 POINTING TO
; THE LOOKUP (ENTER) BLOCK. RETURNS WITH BOTH BLOCKS SET UP AND P1 INTACT.

GETFIL:
	PUSH	P,P4		; SAVE P4
	PUSH	P,P3		; AND P3
	MOVS	P4,P1		; CALLER'S POINTER TO P4
	SETZB	C,1(P4)		; RESET THE DEVICE NAME
	MOVSS	0,P4		; SWAP THE POINTERS
	SETZM	0,LE.NAM(P4)	; RESET THE LOOKUP / ENTER BLOCK
	SETZM	0,LE.EXT(P4)
	SETZM	0,LE.DAT(P4)
	SETZM	0,LE.PPN(P4)
	SETZM	0,LE.PPS(P4)
GTFILA:
	MOVE	P3,CMDPTR	; BYTE POINTER TO P3
	ILDB	C,CMDPTR	; READ A BYTE
	JUMPE	C,GTFILX	; EXIT IF <NULL>
	CAIN	C,"["		; PPN?
	JRST	GTFILP		; YES -- GO PROCESS
	MOVEM	P3,CMDPTR	; NO -- RESTORE BYTE POINTER
	CALL	GETSIX		; LOOK FOR FILE OR DEVICE SPEC
	JUMPE	P1,[ERR	(<NULL DEVICE OR FILENAME ILLEGAL>)]
	CAIN	C,":"		; END CHARACTER A <COLON>?
	JRST	GTFILD		; YES -- GO SET DEVICE
	CAIN	C,"."		; <PERIOD>?
	JRST	GTFILN		; YES -- SET THE FILE NAME
	SKIPN	0,LE.EXT(P4)	; ALREADY HAVE AN EXTENSION?
	SKIPN	0,LE.NAM(P4)	; NO -- MUST HAVE A NAME
	ERR	<FILE-SPEC SYNTAX ERROR>
	TRNE	P1,-1		; 3 CHARACTERS?
	ERR	<ILLEGAL EXTENSION FORMAT>
	MOVEM	P1,LE.EXT(P4)	; YES -- SET THE EXTENSION
	JRST	GTFILB		; AND CONTINUE
GTFILD:
	SKIPN	0,LE.PPN(P4)	; ALREADY HAVE A PPN?
	SKIPE	0,LE.NAM(P4)	; OR A FILENAME?
	ERR	<FILE-SPEC SYNTAX ERROR>
	MOVSS	0,P4		; NO -- SWAP THE POINTERS
	SKIPE	0,1(P4)		; ALREADY HAVE A DEVICE?
	ERR	<DOUBLE DEVICE SPECIFICATION ILLEGAL>
	MOVEM	P1,1(P4)	; NO -- SET UP THE DEVICE
	MOVSS	0,P4		; STRAIGHTEN OUT THE POINTER
GTFILB:
	CAIE	C," "		; DONE IF SPACE
	JUMPN	C,GTFILA	; GO LOOK FOR MORE
	JRST	GTFILX		; EXIT
GTFILN:
	SKIPE	0,LE.NAM(P4)	; ALREADY HAVE A NAME?
	ERR	<DOUBLE FILENAME ILLEGAL>
	SKIPE	0,LE.EXT(P4)	; OR AN EXTENSION?
	ERR	<FILE-SPEC SYNTAX ERROR>
	MOVEM	P1,LE.NAM(P4)	; NO -- SET THE NAME
	JRST	GTFILB		; AND GO GET THE REST OF THE FILE SPEC
GTFILP:
	SKIPE	0,LE.NAM(P4)	; ALREADY HAVE A NAME?
	ERR	<FILE-SPEC SYNTAX ERROR>
	SKIPE	0,LE.PPN(P4)	; ALREADY HAVE A PPN?
	ERR	<DOUBLE PPN ILLEGAL>
	CALL	GTOPPN		; NO -- READ THE PROJECT NUMBER
	CAIN	C,","		; TERMINATOR OK?
	TLNE	P1,-1		; IS IT LEGAL?
	ERR	<ILLEGAL PPN FORMAT>
	MOVSS	0,P1		; YES -- SWAP HALVES
	PUSH	P,P1		; AND SAVE IT
	CALL	GTOPPN		; READ THE PROGRAMMER NUMBER
	CAIN	C,"]"		; TERMINATOR OK?
	TLNE	P1,-1		; IN RANGE?
	ERR	<ILLEGAL PPN FORMAT>
	IORM	P1,0(P)		; YES -- BUILD COMPLETE PPN
	POP	P,LE.PPN(P4)	; SET IT UP
	JRST	GTFILB		; AND GO GET THE REST OF FILE SPEC
GTFILX:
	CAIE	C," "		; PROPER TERMINATOR?
	SKIPN	0,C
	SKIPN	0,LE.NAM(P4)	; YES -- HAVE AT LEAST A FILENAME?
	ERR	<ILLEGAL FILE SPEC>
	MOVSS	0,P4		; YES -- POINT TO THE OPEN BLOCK
	MOVSI	T1,'DSK'	; DEFAULT DEVICE NAME
	SKIPN	0,1(P4)		; SPECIFY A DEVICE?
	MOVEM	T1,1(P4)	; NO -- SET THE DEFAULT DEVICE
	MOVS	P1,P4		; RESTORE CALLER'S P1
	SKIPE	T1,LE.PPN(P1)	; DEFAULT PPN?
	MOVEM	T1,LE.PPS(P1)	; NO -- SAVE IT
	POP	P,P3		; YES -- RESTORE P3
	POP	P,P4		; RESTORE P4
	RETURN			; TO CALLER
SUBTTL	GETXXX -- INPUT PROCESSING SUBROUTINES

; HERE TO INPUT EITHER HALF OF A PPN.

GTOPPN:
	TXO	F,F.PPN		; SET THE FLAG

; HERE TO INPUT AN OCTAL NUMBER

GETOCT:
	SKIPA	T4,[EXP ^D8]	; SET THE RADIX TO OCTAL

; HERE TO INPUT A DECIMAL NUMBER

GETDEC:
	MOVEI	T4,^D10		; SET THE RADIX TO DECIMAL

; HERE TO INPUT A NUMBER, RADIX IN "T4"

GETNUM:
	SETZB	T1,T2		; CLEAR T1 AND T2
GTNUM1:
	ILDB	C,CMDPTR	; GET THE BYTE INTO "C"
	JUMPE	C,GTNUMX	; EXIT ON NULL
	CAIN	C," "		; DELIMITER?
	JRST	GTNUMX		; YES -- EXIT
	CAIL	C,"0"		; CHECK RANGE
	CAILE	C,"0"(T4)	; AGAINST RADIX
	JRST	GTNUME		; SEE IF REAL ERROR
	ANDCMI	C,"0"		; DE-ASCIIZE IT
	MOVE	T2,T1		; ACCUMULATION TO T2
	MUL	T2,T4		; MAKE ROOM FOR THIS DIGIT
	MOVE	T1,T3		; PRODUCT TO T1
	ADD	T1,C		; INSERT THIS DIGIT
	JRST	GTNUM1		; AND GO ON
GTNUME:
	CAIE	C,","		; IS THE CHARACTER A <COMMA>?
	CAIN	C,"]"		; OR A <RIGHT BRACKET>?
	TXZN	F,F.PPN		; YES -- ARE WE LOOKING FOR A PPN?
	ERR	<INPUT IS NOT NUMERIC>
GTNUMX:
	TXNE	T2,<EXP -2>	; DID WE OVERFLOW
	ERR	<INPUT NUMBER TOO LARGE>
	TXNE	T2,1B35		; DID WE OVERFLOW ONCE?
	TXO	T1,1B0		; YES -- PUT IT BACK
	MOVE	P1,T1		; SET RETURN
	RETURN
SUBTTL	GETSIX -- SIXBIT CONVERSION SUBROUTINE

; HERE TO CONVERT UP TO SIX ASCII CHARACTERS TO SIXBIT.
; SIXBIT STRING IS RETURNED IN P1. OK RETURN IS SKIP RETURN
; DIRECT RETURN INDICATES NULL STRING. THIS ROUTINE WILL STOP
; CONVERSION UPON ENCOUNTERING A SPACE, PERIOD OR COLON.

GETSIX:
	MOVE	T1,[POINT 6,P1]	; BYTE POINTER TO T1
	MOVEI	T4,^D6		; SIX CHARACTERS MAX.
	SETZ	P1,0		; CLEAR FOR RETURN
GTSIXA:
	ILDB	C,CMDPTR	; READ THE ASCII BYTE
	JUMPE	C,GTSIXE	; DONE IF <NULL>
	CAIL	C,"0"		; SEE IF NUMERIC
	CAILE	C,"9"
	SKIPA	0,0		; NOT NUMERIC -- TRY ALPHABETIC
	JRST	GTSIXB		; NUMERIC -- CONVERT IT
	CAIL	C,"A"		; SEE IF ALPHABETIC
	CAILE	C,"Z"
	JRST	GTSIXE		; NOT ALPHABETIC -- EXIT
GTSIXB:
	SUBI	C,40		; CONVERT IT
	IDPB	C,T1		; LOAD THIS BYTE
	SOJG	T4,GTSIXA	; LOOP TILL DONE
	ILDB	C,CMDPTR	; GET THE TERMINATOR BYTE
GTSIXE:
	JUMPE	P1,CRET		; DIRECT RETURN FOR NULL STRING
	RETSKP			; OK SKIP RETURN
SUBTTL	FILIN -- INPUT FILE HANDLER ROUTINES

; HERE TO OUTPUT ONE BLOCK OF THE FILE. AFTER THE OUTPUT IS DONE,
; IF THE BYTE SIZE OF THE FILE IS 18 BITS, THE BYTE SIZE IN THE
; BYTE POINTER IS HALVED AND THE BYTE COUNT IS DOUBLED.

FILIN:
	SOSGE	0,INPBLK+2	; COUNT THE BYTE OUT OF THE BUFFER
	JRST	INFIL		; EXHAUSTED -- GET ANOTHER
	ILDB	C,INPBLK+1	; GET THE BYTE INTO "C"
	RETSKP			; SKIP RETURN
INFIL:
	IN	INCH,0		; GET A BUFFER FULL
	JRST	INFILX		; OK -- FIX POINTERS IF NEEDED
	STATO	INCH,IO.EOF	; END-OF-FILE?
	ERR	<INPUT FILE ERROR>
	SKIPG	0,INPBLK+2	; MORE IN BUFFER?
	RETURN			; NO -- EXIT
INFILX:
	PUSH	P,T1		; SAVE T1
	HLRZ	T1,BSZTAB(IM)	; BYTE SIZE TO T1
	TXNN	F,F.IBHM	; HEADER ALREADY MODIFIED?
	CAIE	T1,<^D18_^D12>	; NO -- IS IT .EQ. 18.?
	JRST	INFILY		; NO -- JUST EXIT
	MOVE	T1,INPBLK+1	; YES -- GET MONITOR BYTE POINTER
	TXZ	T1,<77B11>	; FLUSH THE OLD SIZE FIELD
	TXO	T1,<^D18B11>	; SET IT TO 18 BITS
	MOVEM	T1,INPBLK+1	; IN THE BUFFER HEADER
	MOVE	T1,INPBLK+2	; GET THE BYTE COUNT
	ADDM	T1,INPBLK+2	; DOUBLE IT
	TXO	F,F.IBHM	; FLAG THE MODIFICATION
INFILY:
	POP	P,T1		; RESTORE T1
	JRST	FILIN		; AND TRY AGAIN

; HERE TO OPEN THE INPUT FILE. IF THE FILE IS AN ASCII FILE, IT IS
; OPENED IN ASCII MODE, OTHERWISE IT IS OPENED IN IMAGE MODE.

OPENIN:
	TXZ	F,F.IBHM	; RESET THE HEADER MODIFICATION FLAG
	HLRZ	T1,BSZTAB(IM)	; INPUT BYTE SIZE TO T1
	CAIE	T1,<^D7_^D12>	; IS IT AN ASCII FILE?
OPNINA:
	SKIPA	T1,[EXP .IOIMG]	; NO -- OPEN IN IMAGE MODE
	SETZ	T1,0		; YES -- OPEN IT IN ASCII MODE
	MOVEM	T1,INOPN	; SET THE MODE IN THE OPEN BLOCK
	OPEN	INCH,INOPN	; OPEN THE CHANNEL
	ERR	<CAN'T OPEN INPUT FILE>
	RETURN			; EXIT
SUBTTL	FILOUT -- OUTPUT FILE HANDLER ROUTINES

; HERE TO INPUT ONE BLOCK OF THE FILE. AFTER THE INPUT IS DONE,
; IF THE BYTE SIZE OF THE FILE IS 18 BITS, THE BYTE SIZE IN THE
; BYTE POINTER IS HALVED AND THE BYTE COUNT IS DOUBLED.

FILOUT:
	SOSG	0,OUTBLK+2	; COUNT THIS BYTE
	CALL	OUTFIL		; EXHAUSTED -- GET ANOTHER
	IDPB	C,OUTBLK+1	; PUT THE BYTE IN THE BUFFER
	RETURN			; EXIT
OUTFIL:
	OUT	OUTCH,0		; OUTPUT THIS BUFFER
	SKIPA	0,0		; SKIP OVER THE ERROR
	ERR	<OUTPUT FILE ERROR>
	PUSH	P,T1		; SAVE T1
	HLRZ	T1,BSZTAB(OM)	; GET THE FILE BYTE SIZE
	TXNN	F,F.OBHM	; HEADER ALREADY MODIFIED?
	CAIE	T1,<^D18_^D12>	; NO -- BYTE SIZE .EQ. 18?
	JRST	OUTFLX		; YES -- JUST EXIT
	MOVE	T1,OUTBLK+1	; YES -- GET MONITOR BYTE POINTER
	TXZ	T1,<77B11>	; FLUSH THE OLD SIZE FIELD
	TXO	T1,<^D18B11>	; SET IT TO 18 BITS
	MOVEM	T1,OUTBLK+1	; IN THE BUFFER HEADER
	MOVE	T1,OUTBLK+2	; NOW THE BYTE COUNT
	ADDM	T1,OUTBLK+2	; DOUBLE IT
	TXO	F,F.OBHM	; FLAG THE MODIFICATION
OUTFLX:
	POP	P,T1		; RESTORE T1
	RETURN			; AND EXIT

; HERE TO OPEN THE OUTPUT FILE. IF THE FILE IS AN ASCII FILE, IT IS
; OPENED IN ASCII MODE, OTHERWISE IT IS OPENED IN IMAGE MODE.

OPNOUT:
	TXZ	F,F.OBHM	; RESET THE MODIFICATION FLAG
	HLRZ	T1,BSZTAB(OM)	; BYTE SIZE TO T1
	CAIE	T1,<^D7_^D12>	; IS IT AN ASCII FILE?
	SKIPA	T1,[EXP .IOIMG]	; NO -- OPEN IN IMAGE MODE
	SETZ	T1,0		; YES -- OPEN IT IN ASCII MODE
	MOVEM	T1,OUTOPN	; SET THE MODE IN THE OPEN BLOCK
	OPEN	OUTCH,OUTOPN	; OPEN THE CHANNEL
	ERR	<CAN'T OPEN OUTPUT FILE>
	RETURN			; EXIT
SUBTTL	TTYINP -- TELETYPE INPUT SUBROUTINE

; HERE TO READ THE CURRENT INPUT DEVICE

TTYINP:
	TXNE	F,F.CMND	; "TAKE" COMMAND?
	JRST	CMDINP		; YES -- LOOK AT COMMAND DEVICE
	SOSGE	0,TTIBLK+2	; COUNT THE BYTE FROM THE BUFFER
	JRST	TTYBFR		; EXHAUSTED, GET ANOTHER
	ILDB	C,TTIBLK+1	; GET THE BYTE OUT OF THE BUFFER
TTINPA:
	CAIE	C,0		; IS THIS A <NULL>?
	CAIN	C,.CHDEL	; OR A <RUBOUT>?
	JRST	TTYINP		; YES -- IGNORE EITHER
	CAIN	C,.CHCNZ	; E-O-F CHARACTER?
	JRST	[TXO F,F.EXIT
		 JRST CRET]
	CAIL	C,.CHALT	; NO -- SOME FLAVOR OF <ALT-MODE>?
	MOVEI	C,.CHESC	; YES -- CONVERT TO THIS FLAVOR
	CAIL	C,140		; NO -- LOWER CASE?
	ANDCMI	C,40		; YES -- MAKE IT UPPER CASE
	CAIN	C,.CHCRT	; NO -- <CARRIAGE-RETURN>?
	JRST	TTYINP		; YES -- IGNORE IT
	CAIG	C,.CHCRT	; SOME KIND OF VERTICAL FORMAT?
	CAIGE	C,.CHLFD	; BETWEEN <CR> AND <NEW-LINE>?
	CAIN	C,.CHESC	; OR <ALT-MODE>?
	RETURN			; YES -- DIRECT RETURN
	RETSKP			; NO -- SKIP RETURN

; HERE TO GET ANOTHER BUFFER

TTYBFR:
	IN	TTYCH,0		; GET ANOTHER BUFFER
	JRST	TTYINP		; GOT IT -- CONTINUE
	STATO	TTYCH,IO.EOF	; DIDN'T GET IT -- EOF?
	JRST	[OUTSTR	[ASCIZ	%
? ERROR ON TTY INPUT%]
		EXIT	0,0]
	TXO	F,F.EXIT	; SET THE EXIT FLAG
	SKIPLE	0,TTIBLK+2	; ANYTHING IN THE BUFFER?
	JRST	TTYINP		; YES -- GO GET IT
	RETURN			; NO -- EXIT
SUBTTL	CMDINP -- COMMAND FILE INPUT SUBROUTINE

; HERE TO READ THE CURRENT COMMAND FILE

CMDINP:
	SOSGE	0,CMDBLK+2	; COUNT THIS BYTE
	JRST	CMDBFR		; NO MORE -- GET ANOTHER BUFFER
	ILDB	C,CMDBLK+1	; READ THE BYTE INTO "C"
	JRST	TTINPA		; AND GO PROCESS IT

; HERE TO GET ANOTHER BUFFER

CMDBFR:
	IN	CMDCH,0		; READ THE NEW BUFFER
	JRST	CMDINP		; OK -- GO ON
	STATO	CMDCH,IO.EOF	; END-OF-FILE?
	ERR	<ERROR ON COMMAND FILE INPUT>
	SKIPLE	0,CMDBLK+2	; ANYTHING IN THE BUFFER?
	JRST	CMDINP		; YES -- GO GET IT
	TXZ	F,F.CMND	; NO -- CLEAR THE COMMAND FLAG
	CLOSE	CMDCH,0		; CLOSE THE FILE
	RELEASE	CMDCH,0		; RELEASE THE CHANNEL
	RETURN			; AND EXIT
SUBTTL	TYPFIL -- TYPE A FILE DESCRIPTION

; THIS SUBROUTINE WILL TYPE A FILE DESCRIPTION.
; P1 POINTS TO THE LOOKUP / ENTER BLOCK, AND P2 CONTAINS AN OFFSET INTO
; THE FILE FORMAT TABLE

TYPFIL:
	MOVSS	0,P1		; SWAP THE POINTER
	HRLZI	T1,'DSK'	; DEFAULT DEVICE NAME
	CAMN	T1,1(P1)	; IS IT DEFAULT?
	JRST	TYPFLA		; YES -- GO ON
	MOVE	T1,1(P1)	; NO -- GET THE STRUCTURE NAME
	CALL	SIXTYP		; AND TYPE IT
	MOVEI	T2,[ASCIZ %:%]
	CALL	TYPSTR
TYPFLA:
	MOVSS	0,P1		; SWAP THE POINTER AGAIN
	MOVE	T1,LE.PPS(P1)	; GET THE PPN
	JUMPE	T1,TYPFLB	; JUMP IF DEFAULT
	CAMN	T1,OURPPN	; ARE THEY THE SAME?
	JRST	TYPFLB		; YES -- GO ON
	PUSH	P,P1		; SAVE OUR POINTER
	HRRZS	0,T1		; GET THE LOW HALF OF THE PPN
	PUSH	P,T1		; SAVE THAT
	HLRZ	P1,LE.PPS(P1)	; GET THE HIGH HALF OF PPN
	MOVEI	T2,[ASCIZ %[%]
	CALL	TYPSTR		; PRINT BRACKET
	CALL	TYPOCT		; TYPE IT
	MOVEI	T2,[ASCIZ %,%]
	CALL	TYPSTR
	POP	P,P1		; GET THE LOW HALF
	CALL	TYPOCT		; PRINT IT
	MOVEI	T2,[ASCIZ %]%]
	CALL	TYPSTR		; PRINT BRACKET
	POP	P,P1		; RESTORE OUR POINTER
TYPFLB:
	MOVE	T1,LE.NAM(P1)	; GET THE SIXBIT NAME
	CALL	SIXTYP		; PRINT IT
	MOVEI	T2,[ASCIZ %.%]	; NAME DELIMITER
	CALL	TYPSTR		; TYPE THAT
	HLLZ	T1,LE.EXT(P1)	; GET THE EXTENSION
	CALL	SIXTYP		; TYPE THAT
	MOVEI	T2,[ASCIZ % [%]
	CALL	TYPSTR		; SET UP FOR FILE TYPE
	HLRZ	T2,MSGTAB(P2)	; GET THE FILE TYPE
	CALL	TYPSTR		; PRINT IT
	MOVEI	T2,[ASCIZ %]%]
	CALLR	TYPSTR		; FINISH DESCRIPTION AND EXIT
SUBTTL	TYPSTR -- OUTPUT A STRING

; HERE TO SEE IF WE MUST PREFIX THE LINE WITH A <CRLF>

TYPTST:
	SKIPE	0,TTOCCT	; ARE WE AT THE BEGINNING OF THE LINE?
	CALLR	TYPCR		; NO -- GET US THERE
	RETURN			; YES -- GO AWAY

; HERE TO OUTPUT AN ASCIZ STRING AND APPEND A <CRLF>

TYPSTC:
	CALL	TYPSTR		; TYPE THE STRING
	CALLRX	TYPCR		; AND THE <CRLF>

; HERE TO OUTPUT A <CRLF>

TYPCR:
	PUSH	P,T2		; SAVE T2
	MOVEI	T2,[ASCIZ %
%]
	CALL	TYPSTR		; END THE LINE
	POP	P,T2		; RESTORE T2
	RETURN			; TO CALLER

; HERE TO OUTPUT THE SIXBIT STRING IN T1

SIXTYP:
	MOVE	T2,[POINT 6,T1]	; BYTE POINTER TO T2
	MOVEI	T3,^D6		; SIX BYTES, MAX
SIXTYA:
	ILDB	C,T2		; GET THE BYTE
	JUMPE	C,SIXTYX	; EXIT IF NULL
	ADDI	C,40		; MAKE IT ASCII
	CALL	TTYOUT		; PUT IT IN THE BUFFER
	SOJN	T3,SIXTYA	; LOOP TILL DONE
SIXTYX:
	CALLR	TTOBFR		; OUTPUT AND RETURN
; HERE TO OUTPUT THE DECIMAL NUMBER IN P1

TYPDEC:
	SKIPA	T4,[EXP ^D10]

;HERE TO OUTPUT THE OCTAL NUMBER IN P1

TYPOCT:
	MOVEI	T4,^D8

; HERE TO OUTPUT THE NUMBER IN P1, RADIX IN T4

TYPNUM:
	MOVE	T1,P1		; NUMBER TO T1
TYPNMA:
	IDIV	T1,T4		; DIVIDE IT
	HRLM	T2,0(P)		; SAVE IT ON THE STACK
	SKIPE	0,T1		; DONE?
	CALL	TYPNMA		; NO -- GO ON
TYPNMB:
	HLRZ	C,0(P)		; GET THE NUMBER OFF THE STACK
	ADDI	C,"0"		; ASCIIIZE IT
	CALLR	TTYOUT		; OUTPUT IT AND RETURN

; HERE TO OUTPUT AN ASCIZ STRING WITH POINTER TO STRING IN RH OF T2.
; T2 IS CLOBBERED ON EXIT.

TYPSTR:
	HRLI	T2,(POINT 7,)	; MAKE A BYTE POINTER
TYPSTL:
	ILDB	C,T2		; PUT THE BYTE INTO "C"
	JUMPE	C,TTOBFR	; DUMP THE BUFFER ON DELIMITER
	AOS	0,TTOCCT	; COUNT THIS CHARACTER
	CALL	TTYOUT		; PUT THIS BYTE INTO THE BUFFER
	JRST	TYPSTL		; AND GO GET ANOTHER
; HERE TO PUT THE BYTE IN AC "C" INTO THE BUFFER AND OUTPUT IF THE
; BUFFER IS FULL OR THE BYTE IS A <NEW-LINE> CHARACTER.

TTYOUT:
	SOSG	0,TTOBLK+2	; DO WE HAVE ROOM FOR THE BYTE?
	CALL	TTOBFR		; NO -- DUMP THIS BUFFER
	IDPB	C,TTOBLK+1	; YES -- PUT IT INTO THE BUFFER
	CAIGE	C,.CHCRT	; IS THIS A <CARRIAGE-RETURN>?
	CAIGE	C,.CHLFD	; NO -- VERTICAL FORMAT?
	RETURN			; NO -- JUST GO AWAY

; HERE TO OUTPUT THE BUFFER

TTOBFR:
	OUT	TTYCH,0		; OUTPUT IT
	SKIPA	0,0		; SKIP OVER THE ERROR
	JRST	[OUTSTR	[ASCIZ	%
? ERROR ON TTY OUTPUT%]
		EXIT	0,0]
	CAIN	C,.CHLFD	; IS THIS A REAL E-O-L?
	SETZM	0,TTOCCT	; YES -- RESET THE CHARACTER COUNT
	RETURN			; NO -- GO ON