Google
 

Trailing-Edge - PDP-10 Archives - BB-H348C-RM_1982 - swskit-v21/debugging-tools/ddt11/ddtfil.mac
There are 16 other files named ddtfil.mac in the archive. Click here to see a list.
	TITLE DDTFIL DDT11 FILE ROUTINES AND OTHER SUPPORT FOR THEM

	SUBTTL	LISTING CONTROL, AND OTHER USEFUL STUFF

	SEARCH	DDTSYM,JOBDAT,MACTEN,UUOSYM,MONSYM,MACSYM

	SALL			;GET NICE LISTINGS FOR A CHANGE
	.HWFRMT			;AND SKIP THE FANCY BITS
	.DIRECTIVE LITLST,FLBLST

EXTERN ADDSYM,BYTCNT,CACHEL,CALER0,CMDLIM,CMDTKR,CNINWD,DATA,DELSYM,DOTFOO
EXTERN DOTINC,ESC.Q.,ETYPE,GETMEM,GETWRD,GOTO,INVLFN,LASTSW,LEVEL0,LEVEL2
EXTERN LEVL.0,LSTADR,MEMLIM,MEMORY,MEMUSE,MOVSMT,NDTFOO,NODE.N,O.MODE,ORADIX
EXTERN PDP8F,PORT,POSYMT,PUTFOO,RGFNDN,RSTART,S..END,SAVE2,SAVE24,SAVE34,SAVE4
EXTERN SBEGIN,SETFOO,SIMREG,SYMBEG,SYMBOL,SYMEND,SYMFND,TPOPJ,TPOPJ1,VALFND
EXTERN SWTTST,DDTSWT
EXTERN STB.MX,GSD.MX


ENTRY ADRTYP,B3.TYP,BLANKT,CMDCNT,CMDFIL,COLTYP,COMTYP,CRLTYP,CSECHO,DATYPE
ENTRY DECINP,DECTYP,ESC..D,ESC..P,ESC..Y,FILPOS,IDTYPE,MRGFLG,MYPPN,OCTYPE,OHD
ENTRY OPNFL0,PCNTYP,PDECTY,PERTYP,QESTYP,RADTYP,RDDUMP,RSTATE,SETFES,SETMRG
ENTRY SETREL,SETRST,SETSYM,SIXIN,SIXTYP,TABTYP,TIMTY1,TYPCHR,TYPSTR,GETCHR
ENTRY SIXOCT,FILDEV
;HERE FOR A /MERGE

SETMRG:	SWTCHK MERGE
	SETOM	MRGFLG#		;WANT TO MERGE OTHER FILES
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE BECAUSE USER TYPED /FESYM WITH /SYMBOL

SETFES:	SWTCHK FESYMB
	MOVE T1,[SIXBIT /MAPSYM/] ;DEFAULT EXTENSIONS
	MOVEM T1,DEFEXT
	MOVE T1,[400000,,RDSYMA] ;FLAG TO READ IN FE FORMAT
	MOVEM T1,LASTSW
	RETSKP
;HERE ON A /RELOCATION:VAL SWITCH

SETREL:	SWTCHK RELOCA
	CAIN T5,":"
	CALL SIXIN		;READ VALUE
	JRST [	TYPE <?
?Illegal argument for /RELOCATE switch
>
		RET]
	PUSH P,T1		;SAVE IF WE NEED IT LATER
	CALL SIXOCT		;CONVERT IT TO AN OCTAL NUMBER
	JRST [	POP P,T1	;GET TYPIN BACK
		CALL SYMFND	;FIND IF WE HAVE A SYMBOL TO MATCH IT
		JRST [	TYPE <?
?Unknown symbol as argument to /RELOCATE switch
>
			RET]
		HRRZ T1,1(SYM)	;GET THE VALUE FIELD
		MOVEM T1,RELOFF	;SAVE FOR THE READ CODE
		RETSKP]		;RETURN
	MOVEM T1,RELOFF		;SAVE THE NEW OFFSET
	JRST TPOPJ1		;CLEAN STACK, SKIP RETURN
;HERE FOR A /SYMBOL

SETSYM:	SWTCHK SYMBOL
	MOVE	T1,[400000,,RDSYMB]
	MOVEM	T1,LASTSW
	MOVE	T1,[SIXBIT \LSTCRF\] ;RESET DEFAULT EXTENSION
	MOVEM	T1,DEFEXT
	SETZM	USETIT		;ALWAYS START AT 0
	CAIE	T5,":"		;GIVEN A BLOCK TO START ON ?
	RETSKP SAFE		;NO, ITS OK
	CALL	DECINP		;GET BLOCK TO START READING AT
	JRST [	TYPE <?
?Illegal value for the /SYMBOL switch
>
		RET]
	HRRZM	T1,USETIT	;REMEMBER WHERE TO START READING
	RETSKP


;HERE FOR A /STB IN THE COMMAND LINE

SETRST:	SWTCHK STB
	MOVE T1,[SIXBIT /STBSYM/] ;DEFAULT EXTENSIONS
	MOVEM T1,DEFEXT
	MOVE T1,[400000,,RDSTB]	; DEFINE THE ROUTINE TO DO THE REAL WORK
	MOVEM T1,LASTSW
	RETSKP
;HERE TO READ A SYMBOL TABLE FROM A LISTING

RDSYMB:	SKIPN	FILDEV
	JRST	[TYPE <?
?Symbol file sepcification required with this switch
>
		RET]
	SKIPE	T1,USETIT	;WANT TO SKIP PART OF FILE ?
	USETI	1,(T1)		;POSITION FILE
	MOVE	T1,[FILDEV,,SYMDEV]
	BLT	T1,SYMDEV+$FBLEN-1	;COPY FILDEV, FILNAM, FILEXT, FILTIM
	SETZ	T5,		;COUNT OF SYMBOLS
GETSC1:	CALL	GETSCH
	CAIE	T1,12		;IS THIS A LINE FEED ?
	JRST	GETSC1		;LOOK FOR ONE
	SETZB	T3,SYMBOL	;BUILD SYMBOL HERE
	MOVE	T2,[POINT 6,SYMBOL]
	CALL	GETSCH		;GET FIRST CHAR FOR SYMBOL
	CAIL	T1,"0"		;CHECK TO SEE IF NUMERIC
	CAILE	T1,"9"
	CAIA			;NOT NUMERIC
	JRST	GETSC1		;NUMERIC SO FLUSH LINE
	CAIA
GETSC3:	CALL	GETSCH
	CAIG	T1,40
	JRST	GETSC4		;IF SO HAVE FINISHED SYMBOL
	CAIN	T1,"="		;DID SYMBOL END WITH "=" ?
	JRST	GETSC5
	SUBI	T1,40		;CONVERT TO SIXBIT
	CAME	T2,[POINT 6,SYMBOL,35]	;FILLED WORD YET ?
	IDPB	T1,T2		;NO SO KEEP FILLING
	JRST	GETSC3
GETSC4:	CAIE	T1,40		;SYMBOLS END WITH A SPACE
	JRST	GETSC1		;NOT SYMBOL - FLUSH LINE
GETSC5:	SKIPN	SYMBOL		;IS THERE A SYMBOL ?
	JRST	GETSC1		;NO SYMBOL FLUSH LINE
	TDZA	T4,T4		;CLEAR FLAGS
GETSC6:	CALL	GETSCH
	CAIN	T1,40
	JRST	GETSC6
	CAIN	T1,"="
	JRST	[	TRO	T4,SMF.SU	;SUPPRESSED SYMBOL
			JRST	GETSC6	]
	CAIN	T1,"%"
	JRST	[	TRO	T4,SMF.RG	;REGISTER NAME
			TRZ	T4,SMF.SU	;DON'T SUPPRESS REG NAMES
			JRST	GETSC6	]
	CAIL	T1,60
	CAILE	T1,67
	JRST	GETSC1		;FLUSH REST OF LINE
GETSC7:	IMULI	T3,^D8
	ADDI	T3,-60(T1)
	CALL	GETSCH
	CAIL	T1,60
	CAILE	T1,67
	CAIA
	JRST	GETSC7

	CAIE	T1,"8"
	CAIN	T1,"9"
	JRST	GETSC1		;FLUSH REST OD LINE
	CAIN	T1,"-"
	JRST	GETSC1		;FLUSH REST OF LINE
	MOVE	T1,SYMBOL	;COPY SYMBOL
	HRRZ	T2,T3		;VALUE
	HRLZ	T3,T4		;FLAGS
	MOVE	T4,SYMNAM	;FILE NAME
	PUSH	P,SYMEND
	CALL	ADDSYM
	POP	P,T1		;GET OLD SYMEND
	CAME	T1,SYMEND
	AOS	T5		;COUNT SYMBOL
	JRST	GETSC1		;FLUSH REST OF LINE
GETSCH:	CALL	FILCHR		;GET NEXT CHAR FROM FILE
	CAIA
	RET
	TYPE	< loaded >
	MOVE	T1,T5
	CALL	DECTYP
	TYPE	< symbols
>
	JRST TPOPJ1
	SUBTTL ROUTINES TO READ A RSX20F TYPE MAP FILE

;HERE TO READ A FE SYMBOL FILE

RDSYMA:	SKIPN	FILDEV		;WAS A FILE SPECIFIED?
	JRST	[TYPE <?
?Symbol file specification required with this switch
>
		RET]
	MOVE T1,[FILDEV,,SYMDEV] ; COPY OF FILE, DEVICE, EXT, TIME
	BLT T1,SYMDEV+$FBLEN-1	;MOVE IT
	SETZ T5,		;COUNT OF SYMBOLS WE HAVE READ
RDSYM1:	CALL GETSCH		;GET NEXT BYTE
	CAIE T1,12		;LINE FEED?
	JRST RDSYM1		;NO, KEEP LOOKING FOR IT.
RDSYM2:	SETZB T3,SYMBOL		;BUILD SYMBOL HERE
	MOVE T2,[POINT 6,SYMBOL];POINTER FOR SYMBOL NAME
RDSYM3:	CALL GETSCH		;GET NEXT SYMBOL NAME BYTE
	CAIE T1,40		;SPACE?
	CAIN T1,11		;TAB?
	JRST RDSYM3		;YES, IGNORE IT AT START OF LINE
	CAIA
RDSYM4:	CALL GETSCH		;GET NEXT BYTE, PLEASE
	CAIG T1,40		;IF SO, WE HAVE FINISHED SYMBOL
	JRST RDSYM5		;YES, WE ARE DONE WITH THAT PART
	CAIE T1,11		;IS IT A TAB?
	CAIN T1,75		;IS IT AN "="?
	JRST RDSYM5		;YES, TOO, SO GET NEXT PART
	SUBI T1,40		;CONVERT TO SIXBIT
	CAME T2,[POINT 6,SYMBOL,35];AT THE END YET?
	IDPB T1,T2		;NO, POU BYTE INTO SYMBOL
	JRST RDSYM4		;LOOP FOR MORE OF SYMBOL

RDSYM5:	CAIN T1,75		;END OF SYMBOL, WAS IT A "="?
	JRST [	SKIPN SYMBOL
		JRST RDSYM1	;NO SYMBOL, FLUSH THE LINE, TRY AGAIN
		SETZ T4,	;CLEAR THE FLAGS
		JRST RDSYM6]	;AND GET THE VALUE
	CAIE T1,11		;TAB
	CAIN T1,40		;SPACE?
	CAIA
	JRST RDSYM1		;NOT A SYMBOL AGAIN, FLUSH LINE
	SKIPN SYMBOL
	JRST RDSYM1		;NOT A SYMBOL, YET
	SETZ T4,
RDSYM7:	CALL GETSCH
	CAIN T1,40
	JRST RDSYM7		;EAT UP EXTRA SPACES
RDSYM6:	CAIN T1,75		;OK?
	JRST [	TRO T4,SMF.SU	;SUPPRESSED
		JRST RDSYM7]	;BACK FOR MORE
	CAIN T1,45		;"%"
	JRST [	TRO T4,SMF.RG	;REGISTER NAME
		TRZ T4,SMF.SU	;DONT KEEP THEM DOWN
		JRST RDSYM7]	;BACK AGAIN
	CAIL T1,60		;IS IT IN THE RANGE OF 0-7
	CAILE T1,67
	JRST RDSYM1		;NO, FLUSH LINE
RDSYM8:	IMULI T3,10		;MAKE ROOM FOR NEW VALUE
	ADDI T3,-60(T1)		;CONVERT AND ADD IT IN
RDSYM9:	CALL GETSCH		;NEXT BYTE
	CAIL T1,60
	CAILE T1,67
	CAIA
	JRST RDSYM8		;ADD IN NEXT VALUE
	CAIN T1,55		;WAS IT A "-"
	JRST RDSYM9		;YES, IGNORE IT
	CAIN T1,122		;IS IT A "R"
	ADD T3,RELOFF		;YES, ADD RELOCATION , AND KEEP GOING
	MOVE T1,SYMBOL		;GET SYMBOL NAME
	HRRZ T2,T3		;GET VALUE
	HRLZ T3,T4		;GET FLAGS
	MOVE T4,SYMNAM		;GET FILE MANE
	PUSH P,SYMEND		;SAVE END OF SYMBOL TABLE
	CALL ADDSYM		;ADD NEW SYMBOL
	POP P,T1		;GET OLD END
	CAME T1,SYMEND		;DID IT GROW?
	AOS T5			;YES, COUNT AS NEW SYMBOL (CROCK)
	JRST RDSYM2		;YES, GET NEXT SYMBOL FROM LINE
	SUBTTL ROUTINE TO READ A STB FILE

; STB FORMAT IS ODD.  THE FILE IS SAVED AS
;
;	0(2),BYTE2(8),BYTE1(8),0(2),BYTE4(8),BYTE3(8)
;
; JUST LIKE DTELDR DUMPS, AND SUCH, BUT IT IS A PAIN TO READ IN
; A SYMBOL TABLE THAT WAY, SO, WE HAVE TO FAKE THE WORK, AND MUNG
; THE POINTERS TO THE FILE BY HAND.

RDSTB:	SKIPN	FILDEV
	JRST	[TYPE <?
?Symbol file specification required with this switch
>
		RET]
	MOVE T1,[FILDEV,,SYMDEV] ; COPY THE FILE, DEVICE, EXT, AND PATH
	BLT T1,SYMDEV+$FBLEN-1	; MOVE THE DATA
	MOVE T1,FILDEV		; GET THE NAME OF THIS FILE, AND SAVE IT AS
	MOVEM T1,STBNAM		; THE NAME OF THIS SYMBOL TABLE
	SETZ T5,		; WE HAVE SEEN NO SYMBOLS YET...
	MOVEI T1,^D36		; 36 BIT BYTES, PLEASE
	CALL SETIHD		; SET UP THE HEADER
RDSTB1:	CALL RDSGYW		; GET THE COUNT WORD FROM THE INPUT FILE
	 JRST RDSTB2		; ERROR, END OF FILE NOT EXPECTED HERE
	MOVEM T1,STBSIZ		; SAVE THE SIZE OF THE RECORD, PLEASE
	JUMPE T1,RDSTB1		; NO MORE, GET NEXT RECORD
	CALL RDSGYW		; GET THE RECORD TYPE
	 JRST RDSTB2		; END OF FILE WE DID NOT WANT...
	SOS STBSIZ
	SOS STBSIZ
	CAILE T1,STB.MX		; THE MAX RECORD TYPE WE WILL ACCEPT
	 JRST RDSTB3		; ERROR, A BOGUS TYPE OF RECORD
	XCT STBREC(T1)		; EXECUTE THE DISPATCH FOR THIS RECORD
	JRST RDSTB1		; AND LOOP FOR MORE RECORDS...

STBREC:	JRST RDSTB3
	JRST GSDREC		; THE GSD RECORD
	CALL EGSDREC		; END OF THE GSD'S
	CALL TXTREC		; TEXT RECORD
	CALL RLDREC		; RELOCATABLE INFORMATION
	CALL ISDREC		; INTERNAL SYMBOL INFORMATION
	RETSKP SAFE		; END OF MODULE
; HERE TO PARSE A GSD RECORD FROM THE STB FILE

GSDREC:	SKIPN DDTSWT
	JRST GSDRE3
	TYPE <%Reading a GSD record
>
GSDRE3:	SKIPG STBSIZ		; WE HAVE ANY BYTES?
	 JRST RDSTB1		; NO, END OF THE RECORD
	CALL R50SIX		; CONVERT THE NEXT RADIX 50 SYMBOL TO
				; SIXBIT, IN T1
	 JRST GSDRE1		; REPORT END OF RECORD, BUT NOT ERROR HERE
	MOVEM T1,STBSYM		; SAVE THE SYMBOL FOR LATER
	SOSG STBSIZ		; DID WE RUN OUT OF BYTES?
	 JRST GSDRE1		; REPORT ERROR
	CALL RDSGYB		; GET THE FLAG BYTE
	 JRST RDSTB2		; EOF, NOT EOR
	MOVEM T1,STBFLG		; AND SAVE IT, TOO
	SOSG STBSIZ		; COUNT THIS DOWN
	 JRST GSDRE1		; ERROR HERE, TOO
	CALL RDSGYB		; GET THE ENTRY TYPE
	 JRST RDSTB2		; EOF, NOT EOR
	MOVEM T1,STBTYP		; SAVE THE ENTRY TYPE
	SOSLE STBSIZ
	SOSGE STBSIZ		; DID WE FINALLY RUN OUT OF BYTES?
	 JRST GSDRE1		; YES, REPORT THE PROBLEM
	CALL RDSGYW		; GET THE WORD OF VALUE WE EXPECT
	 JRST RDSTB2		; COUNT THIS AGAINST THE WORLD
	MOVEM T1,STBVAL		; SAVE THE VALUE, IT MIGHT BE USEFULL
	MOVE T1,STBTYP		; GET THE TYPE BACK
	CAILE T1,GSD.MX		; IS IT A GOOD ENTRY TYPE?
	JRST GSDRE2		; NO, ERROR TIME
	XCT GSDDSP(T1)		; GO FOR THE ENTRY TYPE...

GSDDSP:	JRST MODNAM		; MODULE NAME ENTRY
	JRST GSDCST		; CSECT ENTRY, IGNORED
	JRST GSDIGS		; INTERNAL GLOBAL SYMBOL
	JRST GSDRE3		; START ADDRESS, IGNORED
	JRST GSDNAM		; GLOBAL SYMBOL NAME
	JRST MODNAM		; PROGRAM SECTION NAME
	JRST GSDVER		; GSD VERSION INFORMATION
	JRST GSDRE3		; MAPPED ARRAY
	JRST GSDCRN		; COMPLETION ROUTINE ENTRY
; HERE WHEN WE FIND A MODULE NAME WITHIN A GSD RECORD

MODNAM:	SKIPN DDTSWT
	JRST MODNA1
	TYPE <%	Module name >
	MOVE T1,STBSYM
	CALL SIXTYP		; TYPE THE NAME
	TYPE < encountered
>
MODNA1:	MOVE T1,STBSYM		; GET THE SYMBOL
	MOVEM T1,STBNAM		; SAVE THE NAME FOR LATER

; AT SOME POINT IN THE FUTURE, THIS WILL BE USED TO DECIDED WHAT SYMBOL
; TABLE THE REST OF THE SYMBOLS WILL BE ADDED TO....

	JRST GSDRE3		; LOOP FOR MORE DATA

; HERE WHEN WE SEE A CSECT NAME ENTRY

GSDCST:	SKIPN DDTSWT
	JRST GSDCS1
	TYPE <%	Csect name >
	MOVE T1,STBSYM		; GET THE SYMBOL NAME
	CALL SIXTYP		; AND TYPE IT OUT
	TYPE < encountered
>
GSDCS1:	JRST GSDRE3		; IGNORE THE RECORD FOR ANY ACTION

GSDIGS:	SKIPN DDTSWT
	JRST GSDIG1
	TYPE <%	Internal symbol >
	MOVE T1,STBSYM		; GET THE SYMBOL NAME
	CALL SIXTYP		; AND TYPE IT OUT
	TYPE < encountered
>
GSDIG1:	JRST GSDRE3		; IGNORE THE RECORD FOR ANY ACTION

GSDNAM:GSDVER:GSDCRN:

	JRST GSDRE3


; HERE WHEN WE GET A RECORD INDICATING THERE ARE NO MORE GSD RECORDS

EGSDRE:	CALL EATREC		; EAT UP THE REST OF THE RECORD
	TYPE <%End of GSD record encountered
>
	RET


; HERE WITH A TEXT RECORD

TXTREC:	CALL EATREC		; EAT UP THE REST OF THE RECORD
	TYPE <%Text record encountered
>
	RET



; HERE WITH A LOCAL SYMBOLS RECORD

ISDREC:	CALL EATREC
	TYPE <%Internal symbol directory encountered, too bad...
>
	RET


; HERE WITH A RELOCATION RECORD

RLDREC:	CALL EATREC
	TYPE <%Relocation information record encountered
>
	RET
GSDRE2:	CALL EATREC		; FLUSH THE REST OF THE RECORD
	TYPE <?
?Illegal entry type in a GSD record while reading symbol table
>
	JRST RDSTB1		; READ MORE, NOT ALL IS LOST...

GSDRE1:	CALL RDSTB4		; TYPE THE ERROR MESSAGE
	JRST RDSTB1		; LOOK FOR ANOTHER RECORD

RDSTB2:	TYPE <?
?Unexpected End of File while reading the symbol table
>
	RET

RDSTB3:	TYPE <?
?Unexpected record type while reading the symbol table
>
	RET

RDSTB4:	TYPE <?
?Unexpected end of record while reading the symbol table
>
	RET

STBSIZ:	BLOCK 1			; THE SIZE OF THE CURRENT RECORD WE ARE DOING
STBNAM:	BLOCK 1			; THE NAME OF THE ROUTINE WE ARE DOING
STBSYM:	BLOCK 1			; THE SYMBOL WE ARE WORKING ON
STBVAL:	BLOCK 1			; THE VALUE OF THE SYMBOL WE ARE ON
STBTYP:	BLOCK 1			; THE TYPE OF STB RECORD ENTRY WE ARE ON
STBFLG:	BLOCK 1			; THE FLAGS FOR THE STB ENTRY WE ARE ON

; Here to eat up the rest of the record we are in the middle of (maybe)

EATREC:	SKIPN T2,STBSIZ		; ARE THERE ANY BYTES LEFT IN THE FILE?
	RET			; NO, WE ARE DONE.
	CALL RDSGYB		; GET THE NEXT BYTE
	 RET			; END OF FILE ENCOUNTERED....
	SOJG T2,.-2		; LOOP FOR MORE DATA
	SETZM STBSIZ		; CLEAR THE SIZE FIELD
	RET			; ALL DONE, YOU LOSE...
								COMMENT \
Here to read the next 8 bit byte from the STB file.  The format of the file is
0,byte2,byte1,,0,byte4,byte3, and we must keep tract of where we are, and spit
the bytes out in the right order.  This routine will return all bytes, (even
nulls), and with a skip return, and take the error return when the end of file
has been reached.
\

RDSGYB:	MOVE T1,RSTATE		; GET THE STATE POINTER
	ANDI T1,3		; SAVE ONLY THE TWO LOW ORDER BITS
	JRST @[			; AND CALL THE CORRECT ROUTINE
		RDSGY0		; GET NEXT WORD OF FILE, AND BYTE
		RDSGY1		; JUST GET NEXT BYTE...
		RDSGY1
		RDSGY1](T1)	; DETERMINED BY THE STATE FIELD

RDSGY0:	SOSGE IHD+2		; IS THERE ANOTHER WORD TO GET?
	JRST RDSGY2		; NO, GET ANOTHER BUFFER
	AOS IHD+1		; POINT TO THE NEXT WORD TO READ IN

RDSGY1:	MOVE T1,[	POINT 8,@IHD+1,17
			POINT 8,@IHD+1,9
			POINT 8,@IHD+1,35
			POINT 8,@IHD+1,27 ](T1)
	AOS RSTATE		; AND COUNT THIS TO THE NEXT STATE
	LDB T1,T1
	RETSKP FAST		; RETURN TO THE CALLING ROUTINE

; HERE TO GET THE NEXT BUFFER, AND SET UP THE POINTERS WE WILL NEED

RDSGY2:	IN 1,			; GET THE BUFFER WE NEED
	JRST RDSGYB		; IN NO ERROR, ADJUST THE COUNTS AND POINTERS
	GETSTS 1,T1		; GET THE FILE STATUS, DUE TO ERROR
	TXNE T1,IO.IMP!IO.DER!IO.DTE!IO.BKT ; ANY ERRORS WE WORRY ABOUT?
	CALL IFILER		; YES, REPORT THEM
	RELEASE 1,		; DUMP THE FILE
	SETZM FILDEV
	RET			; ERROR RETURN TO CALLER

; HERE TO READ WORD FROM THE FILE.

RDSGYW:	CALL RDSGYB		; GET THE NEXT DATA BYTE, AND
	 RET			; IF THERE IS AN ERROR, PASS IT UP, OR
	PUSH P,T1		; SAVE IT FOR LATER
	CALL RDSGYB		; GET YET ANOTHER BYTE
	 JRST TPOPJ		; AND PASS BACK THAT ERROR, TOO
	LSH T1,8		; MOVE THIS OVER 8 BITS
	ADD T1,(P)		; ADD IN THE TOP OF THE STACK
	POP P,(P)		; AND CLEAR THE STACK OFF
	RETSKP FAST		; RETURN THE WORD VALUE TO THE USER
; Here to convert the next two word in the input from RADIX 50 to SIXBIT
; Call:
;	CALL R50SIX
; Return:
;	+1	END OF RECORD OR FILE
;	+2	T1/ SIXBIT SYMBOL NAME...

R50SIX:	SOSLE STBSIZ		; COUNT THE FIRST BYTE
	SOSGE STBSIZ		; AND THE SECOND BYTE...
	 RET			; IF THERE IS NOT ENOUGH DATA, WE LOSE
	SOSLE STBSIZ		; COUNT THE FIRST BYTE
	SOSGE STBSIZ		; AND THE SECOND BYTE...
	 RET			; IF THERE IS NOT ENOUGH DATA, WE LOSE
	CALL R50SI1		; CONVERT THE FIRST HALFWORD
	 RET			; ERROR IN DOING IT
	LSH T1,^D18		; SAVE THE LEFT HALF AS THE LEFT HALF
	PUSH P,T1		; STACK IT
	CALL R50SI1
	 JRST TPOPJ		; ERROR, CLEAR THE STACK, AND RETURN IT
	ADD T1,(P)		; ADD IN THE STACK TOP
	POP P,(P)		; AND CLEAR IT
	RETSKP FAST		; RETURN THE GOOD NEWS...

R50SI1:	CALL RDSGYW		; READ THE FIRST TWO OF THE FOUR BYTES...
	 RET			; PROBLEM, END OF FILE
	IDIVI T1,50		; DEVIDE BY 50,
	PUSH P,T2		; AND SAVE THE LAST BYTE
	IDIVI T1,50		; GET THE OTHER TWO BYTES APART
	HRRZ T1,R50TAB(T1)	; CONVERT TO ASCII
	SUBI T1,40		; CONVERT TO SIXBIT
	HRRZ T2,R50TAB(T2)	; CONVERT TO ASCII
	SUBI T2,40		; CONVERT TO SIXBIT
	LSH T1,6		; MAKE SOME ROOM
	ADD T1,T2		; AND ADD IN THE BYTE
	POP P,T2		; GET THE LAST BYTE
	HRRZ T2,R50TAB(T2)	; CONVERT TO ASCII
	SUBI T2,40		; CONVERT TO SIXBIT
	LSH T1,6		; MAKE SOME ROOM
	ADD T1,T2		; AND ADD IN THE BYTE
	RETSKP FAST
	SUBTTL	GENERAL FILE ROUTINES

;HERE TO OPEN A FILE TO READ(F.WRIT=0) OR WRITE(F.WRIT=1)
; CALL	MOVE	T1,[SIXBIT \FILE\]	;DEFAULT FILE NAME
;	MOVE	T2,[SIXBIT \EXTEXT\]	;DEFAULT EXTENSIONS
;	MOVE	T3,[SWDSP,,SWLST]	;SWITCH POINTER
;	MOVE	T4,[400000,,ADR]	;DEFAULT LAST SWITCH
;	CALL	OPNFIL
;	LOSE RETURN
;	WIN RETURN
OPNFIL:	TROA	FLG,F.FLIP	;FLAG WE SHOULD PROMPT
OPNFL0:	TXZ	FLG,F.FLIP	;NO PROMPT PLEASE
	MOVEM	T2,DEFEXT	;SAVE DEFAULT EXTENSIONS
	SETZM	FILDEV		;INITIALIZE START OF FILE BLOCK
	MOVE	T2,[FILDEV,,FILDEV+1]  ;BLT POINTER TO
	BLT	T2,FILDEV+$FBLEN-1  ; INITIALIZE REST OF FILE BLOCK
	MOVEM	T1,FILNAM	;SAVE DEFAULT FILE NAME
	MOVEM	T3,FIL.SW	;SAVE POINTER TO SWITCHES
	MOVEM	T4,LASTSW	;LAST SWITCH WE GET
OPFIL1:	MOVEI	T1,[ASCIZ \
FILE:	\]
	TXOE	FLG,F.FLIP	;WANT PROMPT ?
	CALL	TYPSTR
	CALL	SIXIN		;GET FILE NAME
	JRST	OPFIL1
	JUMPE	T1,OPFIL4	;JUST SWITCHES
	MOVSI	T2,'DSK'	;DEFAULT DEVICE NAME
	MOVEM	T2,FILDEV
	CAIE	T5,":"		;WAS THIS A DEVICE SPECIFICATION ?
	JRST	OPFIL2
	MOVEM	T1,FILDEV	;YES SO WAS A DEVICE
	CALL	SIXIN		;GET FILE NAME
	JRST	OPFIL1
OPFIL2:	SKIPE	T1		;WAS THERE A FILE NAME ?
	MOVEM	T1,FILNAM	;SAVE FILE NAME
	CAIE	T5,"."		;GIVING AN EXTENSION ?
	JRST	OPFIL3		;NO
	CALL	SIXIN		;GET EXTENSION
	JRST	OPFIL1
	HLLZM	T1,FILEXT
OPFIL3:	CAIE	T5,"["		;GIVING A PPN ?
	JRST	OPFIL4

;HERE TO READ IN A PATH SPEC
	CALL	SIXIN
	JRST	OPFIL4
	CAIE	T5,","
	JRST	OPFIL4
	CALL	SIXOCT
	JRST	OPFIL4
	CAIN	T1,0		;USER TYPE IN EXPLICIT PROJECT?
	HLRZ	T1,MYPPN	;NO, USE HIS THEN
	HRLM	T1,FILPPN	; SET IN FILE PATH BLOCK
	CALL	SIXIN
	JRST	OPFIL1
	CALL	SIXOCT
	JRST	OPFIL1
	CAIN	T1,0		;USER TYPE IN EXPLICIT PROGRAMMER?
	HRRZ	T1,MYPPN	;NO, USE HIS THEN
	HRRM	T1,FILPPN	; SET IN FILE PATH BLOCK
	MOVEI	T4,FILSFD-1	; START OF SFD'S
OPFL30:	MOVE	T1,T5
	CAIE	T1,","		;WERE SFD'S SPECIFIED ?
	JRST	OPFL39
	CALL	SIXIN		;GET SFD NAME
	JRST	OPFL39
	CAIN	T4,FILSFD+4	; ALREADY FILLED ALL ?
	JRST	[TYPE	<?
?SFD depth greater than 5>
		RET	]
	PUSH	T4,T1
	JRST	OPFL30
OPFL39:	CAIN	T1,"]"
	CALL	RDCHAR
OPFL40:	MOVEM	T1,T5
OPFIL4:	CAIN	T5,40		;WAS BREAK CHAR A SPACE ?
	JRST	[CALL	RDCHAR	;GET NEXT CHAR
		JRST	OPFL40 ]
	CAIE	T5,"/"		;TIME FOR SWITCHES ?
	JRST	OPFIL7
	CALL	SIXIN		;GET SWITCH NAME
	JRST	OPFIL7
	MOVSI	T2,770000	;MAKE A MASK
OPFL41:	MOVE	T3,T1		;COPY ARGUMENT
	AND	T3,T2		;MASK IT
	CAMN	T1,T3		;WAS THAT RIGHT MASK ?
	JRST	OPFL42
	ASH	T2,-6		;MAKE MASK BIGGER
	JRST	OPFL41
OPFL42:	HRRZ	T4,FIL.SW
OPFL43:	SKIPN	T3,(T4)		;GET NEXT ENTRY IN LIST
	JRST	OPFIL5		;NO MATCH FOR SWITCH
	CAMN T1,T3		;EXACT ENTRY?
	JRST OPFIL6		;YES, IGNORE PARTIAL MATCHES
	AND	T3,T2		;MASK OFF ENTRY
	CAME	T1,T3		;DID WE FIND MATCH ?
	AOJA	T4,OPFL43	;TRY NEXT ENTRY
	MOVE	T3,1(T4)	;GET NEXT ENTRY FROM LIST
	AND	T3,T2		;MASK IT
	CAME	T1,T3
	JRST	OPFIL6
OPFIL5:	PUSH	P,T1		;SAVE SWITCH
	TYPE	<?
?Undefined or ambiguous switch />
	POP	P,T1
	CALL	SIXTYP
OPFL52:	TYPE	<
	Legal switches are:>
	HRRZ	T4,FIL.SW	;POINT TO LIST OF SWITCHES
OPFL55:	SKIPN	(T4)
	JRST	CRLTYP		;END WITH A FLURISH
	TYPE	< />
	MOVE	T1,(T4)		;GET SWITCH NAME
	CALL	SIXTYP
	AOJA	T4,OPFL55

OPFIL6:	SUB	T4,FIL.SW
	HLRZ	T1,FIL.SW
	ADDI	T1,(T4)
	SKIPGE	T1,(T1)
	JRST	[	MOVEM	T1,LASTSW
			JRST	OPFIL4 ]
	CALL	(T1)
	RET			;ERROR IN THE SWITCH, SO GIVE UP
	JRST	OPFIL4


OPFIL7:	CAIE	T5,15		;IS THE BREAK CHARACTER A CR?
	JRST	[TYPE <?
?Syntax error in file name or switches
>
		RET]
	SETZ	T1,
	SKIPN	T2,FILDEV	;DID USER TYPE A FILE NAME ?
	JRST OPNFL5
	MOVEI	T3,IHD
	TXNE	FLG,F.WRIT
	SKIPA	T3,[OHD,,0]
	SKIPA	T4,[OPEN 1,T1]	;READ ON CHNL 1
	MOVE	T4,[OPEN 0,T1]
	XCT	T4
	JRST	FILER0
	PUSH	P,.JBFF##
	MOVEI	T2,OBUFER
	MOVE	T1,[INBUF 1,NUMBUF]
	TXNE	FLG,F.WRIT
	SKIPA	T1,[OUTBUF 1]
	MOVEI	T2,IBUFER
	MOVEM	T2,.JBFF##
	XCT	T1
	NOP
	POP	P,.JBFF##
	SKIPE	FILEXT		; USER TYPE ANY EXTENSION?
	SETZM	DEFEXT		; YES, CLEAR DEFAULTS THEN
OPNFL2:	MOVE	T1,[LOOKUP 1,FILBLK]
	MOVEI	T2,LKELEN	; LENGTH OF EXTENDED LOOKUP/ENTER BLOCK
	MOVEM	T2,FILBLK	; SET IN LOOKUP/ENTER BLOCK
	SKIPN	FILPPN		; USER TYPE IN EXPLICIT PATH?
	TDZA	T2,T2		; NO, USE DEFAULT PATH
	MOVEI	T2,FILPTH	; YES, USE IT AS TYPED
	MOVEM	T2,FILDIR	; SET PATH BLOCK IN LOOKUP/ENTER BLOCK
	TXZE	FLG,F.APND	;IF APPENDING DO LOOKUP FIRST
	JRST	[TLZ	T1,000740	;CLEAR CHNL SPEC
		XCT	T1		;DO LOOKUP
		JRST	OPNFL2		;LOST BUT DON'T CARE
		TXO	FLG,F.APND	;NEED TO DO USETI
		LDB	T2,[POINTR 17,T1]  ;CHANNEL NUMBER
		MOVEM	T2,FILPTH	;SET IN PATH BLOCK
		MOVE	T2,[PTHLEN,,FILPTH]  ;ARG POINTER TO
		PATH.	T2,		;READ FILE TRUE PATH
		SETZ	T2,		;FAILED??
		JRST	.+1 ]
	TXNE	FLG,F.WRIT
	HRLI	T1,(ENTER)
	XCT	T1
	CAIA			;LOOKUP OR ENTER LOST
	JRST	OPNFL5		;WE HAVE A FILE READY FOR I/O
	TXNE	FLG,F.WRIT	;WRITING ?
	JRST	FILER0		;HE LOSES
	SKIPN	T2,DEFEXT	; ANY DEFAULTS LEFT?
	JRST	FILER0		;NO, ERROR
	HLLZM	T2,FILEXT	;YES, TRY NEXT DEFAULT
	LSH	T2,^D18		;TOSS IT OUT
	MOVEM	T2,DEFEXT	;AND SAVE ANYTHING LEFT FOR NEXT TIME
	JRST	OPNFL2
OPNFL5:	LDB	T2,[POINTR 17,T1]  ;CHANNEL NUMBER
	MOVEM	T2,FILPTH	;SET IN PATH. BLOCK
	MOVE	T2,[PTHLEN,,FILPTH]  ;ARG POINTER TO
	PATH.	T2,		;READ TRUE FILE PATH
	JFCL			;???
	SKIPN	FILDEV
	JRST	OPNFL6
	TXNE	FLG,F.APND
	USETI	-1		;IN CASE SUPERCEEDING
OPNFL6:	MOVE	T1,[FILDEV,,OFLDEV]	;BLT POINTER
	TXNN	FLG,F.WRIT	;ARE WE READING OR WRITING ?
	HRRI	T1,IFLDEV	;READING
	MOVEI	T2,$FBLEN-1(T1)	; LAST WORD TO TRANSFER
	BLT	T1,(T2)		;COPY FILE SPEC
	SKIPE	T1,LASTSW
	JRST	(T1)
	RETSKP	FAST
FILER0:	TXNE	FLG,F.WRIT
	SETZM	OHD
	TYPE	<?
?Can't LOOKUP/ENTER file >
FILERR:	TXNE	FLG,F.WRIT
	SETZM	OHD
	MOVEI	T1,FILDEV
	CALL	FILTYP
	CALL	CRLTYP
	TXNN	FLG,F.WRIT
	SETZM	IHD
	RET
FILTYP:	HRL	T2,T1		;BUILD BLT POINTER
	HRRI	T2,FILDEV
	BLT	T2,FILDEV+$FBLEN-1	; COPY FILE SPEC
	MOVE	T1,FILDEV	;GET DEVICE NAME
	CALL	SIXTYP
	CALL	COLTYP		;TYPE A COLON
	MOVE	T1,FILNAM	;GET FILE NAME
	CALL	SIXTYP
	CALL	PERTYP		;TYPE A "."
	HLLZ	T1,FILEXT	;GET EXTENSION
	CALL	SIXTYP
	SKIPN	FILPPN		; WAS THERE A PPN ?
	JRST	FILTY6
	MOVEI	T1,"["
	CALL	TYPCHR
	HLRZ	T1,FILPPN
	CALL	OCTYPE
	CALL	COMTYP		;TYPE A COMMA
	HRRZ	T1,FILPPN	; GET RH OF PPN
	ANDI	T1,-1
	CALL	OCTYPE
	MOVEI	T3,FILSFD	; START OF SFD'S
FILTY4:	CAIE	T3,FILSFD+5	; TYPED ALL SFD LEVELS ?
	SKIPN	T1,(T3)		;GET NEXT SFD NAME
	JRST	FILTY5
	CALL	COMTYP		;TYPE A COMMA
	CALL	SIXTYP
	AOJA	T3,FILTY4
FILTY5:	MOVEI	T1,"]"
	CALL	TYPCHR
FILTY6:	CALL	BLANKT
	LDB	T1,[POINT 11,FILTIM,23]
	JUMPE	T1,FILTY3
	CALL	TIMTY3
	CALL	BLANKT
FILTY3:	LDB	T1,[POINT 3,FILEXT,20]	;HIGH ORDER CREATION DATE
	LDB	T2,[POINT 12,FILTIM,35]	;LOWER ORDER CREATION DATE
	LSH	T2,^D24		;APPEND THE TWO TIMES INTO
	LSHC	T1,^D12		;ONE 15-BIT CREATION DATE
	CALL	DATET0		;TYPE DATE
	RET

;HERE TO CLOSE OUTPUT FILE
DONE.W:	SKIPN	OHD
	RET
	OUT
	CLOSE
	RELEASE
	SETZM	OHD
	TYPE	<File >
	MOVEI	T1,OFLDEV
	CALL	FILTYP
	TYPE	< written

>
	SETZM	FILDEV
	RET
;HERE TO GET NEXT CHAR FROM A FILE
; CALL	CALL	FILCHR
;	ERROR RETURN
;	NORMAL RETURN WITH CHAR IN T1
FILCHR:	CALL	FILBYT		;GET NEXT BYTE FROM FILE
	RET			;LOST
	JUMPE	T1,FILCHR	;FLUSH NULLS
	AOS	(P)
	RET

;HERE TO GET THE NEXT BYTE FROM INPUT FILE
FILBYT:	SOSGE	T1,IHD+2	;IS THERE MORE STUFF IN BUFFER ?
	JRST	FLCHR5		;NO
	ILDB	T1,IHD+1	;GET NEXT CHAR
	AOS	(P)		;SKIP RETURN
	RET

FLCHR5:	IN	1,		;GET NEXT BUFFER
	JRST	FILBYT		;TRY AGAIN
	GETSTS	1,T1		;GET FILE STATUS
	TXNE	T1,IO.IMP!IO.DER!IO.DTE!IO.BKT	;ANY ERRORS
	CALL IFILER		;REPORT ERROR
	RELEASE 1,		;GONE WITH CHANNEL
	SETZM FILDEV
	RET			;AND RETURN

IFILER:	TYPE	<?
?Error reading file >
	MOVEI	T1,IFLDEV	;ADR OF NAME OF FILE
	CALL	FILTYP
	TYPE	< status = >
	GETSTS 1,T1		;GET BACK STATUS
	CALL	OCTYPE
	JRST	CRLTYP

;HERE TO POSITION FILE FOR INPUT
; CALL	MOVE	T1,BYTE # IN FILE
;	CALL	FILPOS
;	RETURN
FILPOS:	IDIVI	T1,200*5	;FIND BLOCK TO READ
	USETI	1,1(T1)
	IN	1,		;GET NEXT BUFFER
	CAIA
	RET
FILPS4:	SOJL	T2,RSKP
	CALL	FILBYT
	RET
	JRST	FILPS4
;HERE TO INPUT AN OCTAL NUMBER
; CALL:	CALL	INPOCT
;	ERROR RETURN
;	RETURN WITH OCTAL NUMBER IN T1, BREAK CHAR IN T2
INPOCT:	CALL	SAVE34
	SETZB	T3,T4
INPRD2:	CALL	FILCHR		;GET NEXT INPUT CHAR
	JRST	INPRD9		;NO MORE IN FILE
	JUMPE	T1,INPRD2
	CAIE	T1," "		;LEADING SPACE ?
	CAIN	T1,"	"		;OR TAB ?
	JRST	INPRD2		;YES
INPRD5:	CAIL	T1,"0"
	CAILE	T1,"7"
	JRST	INPRD7
	IMULI	T3,^D8
	ADDI	T3,-60(T1)
	CALL	FILCHR
	CAIA			;EOF
	JRST	INPRD5
INPRD7:	MOVE	T2,T1
	MOVE	T1,T3
	AOS	(P)		;SKIP RETURN
INPRD9:	RET
;HERE TO GET A SIXBIT WORD FROM TTY
; CALL:	CALL	SIXIN
;	LOSE RETURN
;	WIN RETURN WITH SIXBIT WORD IN T1 & BREAK CHAR IN T5
SIXIN:	PUSH	P,T4		;SAVE REG
SIXIN0:	CALL	RDCHAR		;GET THE FIRST CHAR
	CAIE	T1," "		;IS IT A BLANK
	CAIN	T1,"	"		;OR A TAB ?
	JRST	SIXIN0		;YES SO SKIP IT
	MOVE	T4,[POINT 6,T5]
	SETZ	T5,		;CLEAR ACCUMULATED SYMBOL
	CAIN	T1,"%"
	JRST	SIXIN7
	JRST	SIXIN3
SIXIN2:	CALL	RDCHAR		;GET A CHAR FROM TTY
SIXIN3:	CAIN	T1,177
	JRST	[	TYPE	<xxx>
			POP	P,T4
			RET	]
	CAIL	T1,"0"
	CAILE	T1,"Z"+40
	JRST	SIXIN9		;RETURN
	CAILE	T1,"9"
	CAIL	T1,"A"+40
	JRST	SIXIN7
	CAIL	T1,"A"
	CAILE	T1,"Z"
	JRST	SIXIN9		;RETURN
SIXIN7:	CAIGE	T1,40+"A"	;CHECK FOR LOWER CASE
	SUBI	T1,40
	CAME	T4,[POINT 6,T5,35]	;HAVE WE ALREADY FILLED WORD ?
	IDPB	T1,T4		;NOT YET
	JRST	SIXIN2
SIXIN9:	EXCH	T1,T5
	POP	P,T4
	RETSKP FAST

;HERE TO CONVERT SIXBIT TO OCTAL
SIXOCT:	MOVE	T4,[POINT 6,T1]
	SETZ	T2,
SIXOC1:	ILDB	T3,T4
	JUMPE	T3,SIXOC9
	CAIL	T3,20
	CAILE	T3,27
	RET			;CAN'T CONVERT
	IMULI	T2,^D8
	ADDI	T2,-20(T3)
	CAME	T4,[POINT 6,T1,35]	;DONE ALL OF WORD ?
	JRST	SIXOC1
SIXOC9:	EXCH	T1,T2
	RETSKP FAST
;HERE TO GET A DECIMAL ARGUMENT FROM THE TTY
; CALL	CALL	DECINP
;	LOSE RETURN
;	WIN RETURN	WITH # IN T1, BREAK CHAR IN T5
DECINP:	MOVEI	T1,^D10		;RADIX
RADINP:	CALL	SAVE2		;SAVE SOME REGISTERS
	SETZ	T5,		;BUILD NUMBER HERE
	MOVE	T2,T1		;COPY RADIX
RADIN0:	CALL	RDCHAR		;GET NEXT CHAR FROM THE TTY
	CAIE	T1," "		;IS THIS A LEADING SPACE ?
	CAIN	T1,"	"		;OR TAB ?
	JRST	RADIN0		;YES SO FLUSH IT
	CAIL	T1,"0"		;IS FIRST CHARACTER NUMERIC ?
	CAIL	T1,"0"(T2)
	JRST	RADIN9		;ERROR RETURN
	AOS	(P)		;WIN
RADIN2:	CAIL	T1,"0"		;IS CHARACTER NUMERIC
	CAIL	T1,"0"(T2)	;IS IT IN RANGE ?
	JRST	RADIN9		;ALL DONE
	IMULI	T5,(T2)		;SHIFT CURRENT ACCUMULATION
	ADDI	T5,-60(T1)	;ADD NEXT DIGIT
	CALL	RDCHAR		;GET NEXT CHAR FROM THE TTY
	JRST	RADIN2
RADIN9:	EXCH	T1,T5
	RET
	SUBTTL	TTY ROUTINES

;HERE TO DISPLAY CONTENTS OF T1 AS AN ADDRESS
ADRTYP:	TLNN	T1,400000
	TLO	T1,777777
	TLNN	T1,200000
	JRST	DATIN9		;TYPE REGISTER NAME
	ANDI	T1,777777	;EIGHTEEN BITS ONLY PLEASE
	HRROM	T1,LSTADR	;SAVE LAST ADDRESS DISPLAYED
	CALL	VALFND		;SEE IF WE CAN FIND A SYMBOL
	JRST	RADTYP		;TYPE ADDR IN CURRENT RADIX
	SKIPN	1(SYM)		;DON'T USE IF SYMBOL=0
	JRST	RADTYP
	PUSH	P,T1		;SAVE VALUE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP		;TYPE SYMBOL
	POP	P,T1		;GET VALUE AGAIN
	SUB	T1,1(SYM)	;GET DISPLACEMENT
	ANDI	T1,177777	;STRIP EXTRA BITS
	JUMPE	T1,R		;IF EXACT WE ARE DONE
	PUSH	P,T1		;SAVE REMAINDER
	CALL	PLUTYP		;TYPE A "+"
	POP	P,T1
	JRST	RADTYP		;TYPE REST IN CURRENT RADIX
	SUBTTL	DISPLAY ROUTINES

;HERE TO TYPE CONTENTS OF CURRENT LOCATION
; CALL	WITH DOT SETUP TO POINT TO STARTING POINT OF DISPLAY
;	WITH BYTCNT AND O.MODE SETUP TO INDICATE TYPE OF DISPLAY
;	WITH BYTCNT AND O.MODE SETUP TO INDICATE TYPE OF DISPLAY
;	CALL	DATYPE

DATYPE:	HRRZ	T2,BYTCNT	;BYTE COUNT
	HRRZ	T3,O.MODE	;OUTPUT MODE
	MOVE	T1,DOT
	MOVEM	T1,DOTFOO
	SKIPE	PDP8F
	JRST	DATYP1
	TLNN	DOT,200000
	JRST	REGTYP		;WANT REGISTER DISPLAYED
	CAIG	T3,2		;IS THIS A WORD MODE
	ASH	T2,1		;YES SO BYTE=WORDS*2
DATYP1:	CALL	GETWRD
	JRST	[CALL	CALER0		;DESCRIBE PROBLEM
		RET	]		;THEN EXIT
	MOVEM	T1,ESC.Q.	;IN CASE OF <ESCAPE>Q LATER
	MOVEM	T1,DATA
	HRRZ	T5,BYTCNT	;REPETITION COUNT
	MOVE	T1,DATA		;GET DATA TO TYPE
	HRRZ	T2,O.MODE	;GET OUTPUT MODE
	JRST	@[
		EXP DATINS
		EXP DATADR
		EXP DATNUM
		EXP DATBYT
		EXP DATASC
		EXP DATEBC
		EXP DATR50
		](T2) 
;HERE TO TYPE THE CONTENTS OF A REGISTER

REGTYP:	ANDI	T1,177777	;STRIP EXTRA BITS
	CAILE	T1,7		;SMALL ENOUGH ?
	JRST	QESTYP
	MOVE	T1,SIMREG(T1)	;GET REGISTER TO DISPLAY
	MOVEM	T1,ESC.Q.	;IN CASE OF $Q LATER
	CALL	@[EXP ADRTYP,ADRTYP,RADTYP,RGTBYT,RGTASC,RGTEBC](T3)
	JRST	B3.TYP		;END WITH A FEW SPACES

;HERE TO TYPE CONTENTS OF REGISTER AS BYTES
RGTBYT:	MOVEI	T2,RADTYP	;ROUTINE TO DISPLAY BYTES (NUMERIC)
	JRST	RGTYPX

;HERE TO TYPE CONTENTS OF REGISTER AS ASCII
RGTASC:	MOVEI	T2,DATAS3	;ROUTINE TO DISPLAY ASCII BYTES
	JRST	RGTYPX

;HERE TO TYPE CONTENTS OF REGISTER AS EBCDIC
RGTEBC:	MOVEI	T2,DATEB3	;ROUTINE TO DISPLAY EBCDIC BYTES

RGTYPX:	PUSH	P,T1		;SAVE DATA
	ANDI	T1,377		;FIRST BYTE IS RH
	PUSH	P,T2		;SAVE ADR OF DISPLAY ROUTINE
	CALL	(T2)		;DISPLAY THE FIRST BYTE
	POP	P,T2		;GET ADR OF DISPLAY ROUTINE BACK
	CAIN	T2,RADTYP	;WAS THIS BYTES ?
	CALL	COMTYP		;YES SO WANT A COMMA IN BETWEEN
	POP	P,T1		;GET DATA BACK
	LDB	T1,[POINT 8,T1,27]	;WANT LH BYTE NOW
	JRST	(T2)		;DISPLAY LAST BYTE
;HERE TO TYPE CONTENTS OF CURRENT LOCATION AS A NUMERIC
DATNUM:	HRROM	T1,LSTADR	;IN CASE TYPES A TAB LATER
	CALL	RADTYP		;TYPE AS NUMERIC
	SOJLE	T5,B3.TYP
	CALL	BLANKT
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATNUM

NXTDWD:	CALL	NXTWRD		;GET NEXT WORD
	JRST	B3.TYP		;CAN'T READ NEXT WORD !
	MOVEM	T1,DATA
	RET

;HERE TO GET THE NEXT WORD FOR TYPEOUT
NXTWRD:	CALL	NDTFOO		;GET NEXT DOT FOO
	MOVE	T1,DOTFOO
	MOVEI	T2,2		;WANT 2 BYTES
	SKIPE	PDP8F
	MOVEI	T2,1
	CALL	GETWRD		;FIND WHAT NEXT WORD IS
	RET			;LOST
	MOVEM	T1,ESC.Q.	;IN CASE OF <ESCAPE>Q LATER
	RETSKP FAST
;HERE TO TYPE DATA AS AN ADDRESS
DATADR:	CALL	ADRTYP
	SOJLE	T5,B3.TYP	;HAVE WE DONE ENOUGH ?
	CALL	BLANKT		;TYPE A SPACE TO SEPERATE FIELDS
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATADR		;AND TYPE NEXT WORD


;HERE TO TYPE DATA AS INSTRUCTIONS
DATINS:
	SKIPE	PDP8F
	JRST	TYP8IN		;TYPE PDP8 INSTRUCTION
	CALL	INVLFN		;SEE IF WE CAN FIND AN INSTRUCTION TO MATCH
	JRST	DATNUM
	MOVE	T1,(SYM)	;GET INSTRUCTION NAME
	CALL	SIXTYP
	MOVE	T5,2(SYM)	;GET FLAGS AGAIN
	CALL	BLANKT		;TYPE A BLANK
	TLNE	T5,SMF.EI	;EIS TYPE INSTRUCTION ?
	JRST	[LDB	T4,[POINT 6,DATA,35]	;GET SOURCE CODE
		CALL	DATIN8		;DISPLAY IT
		CALL	COMTYP
		LDB	T1,[POINT 3,DATA,29]	;GET REGISTER
		CALL	DATIN9		;TYPE REG NAME
		JRST	B3.TYP]
	TLNE	T5,SMF.PL	;SPL TYPE INSTRUCTION ?
	JRST	[LDB	T1,[POINT 3,DATA,35]	;GET ARGUMENT
		CALL	OCTYPE
		JRST	B3.TYP]
	TLNE	T5,SMF.MK	;MARK TYPE ARGUMENTS ?
	JRST	[LDB	T1,[POINT 6,DATA,35]	;GET ARGUMENT
		CALL	RADTYP		;TYPE ARGUMENT AS NUMBER
		JRST	B3.TYP]
	TLNE	T5,SMF.EM	;EMT TYPE ARGUMENTS ?
	JRST	[LDB	T1,[POINT 8,DATA,35]	;GET ARGUMENT
		HRROM	T1,LSTADR	;IN CASE OF TAB
		CALL	RADTYP		;TYPE ARGUMENT AS NUMBER
		JRST	B3.TYP]
	TLNE	T5,SMF.RT	;RTS TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,35]	;GET REG ADR
		CALL	DATIN9		;TYPE REG NAME
		JRST	B3.TYP]
	TLNE	T5,SMF.JS	;JSR TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,29]
		CALL	DATIN9		;TYPE REG NAME
		CALL	COMTYP
		JRST	.+1]
	TLNE	T5,SMF.SB	;SOB TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,29]	;GET REGISTER
		CALL	DATIN9		;TYPE REG NAME
		CALL	COMTYP
		LDB	T1,[POINT 6,DATA,35]	;GET OFFSET
		IMULI	T1,-2
		ADDI	T1,2(DOT)
		ANDI	T1,177777
		CALL	ADRTYP
		JRST	B3.TYP]
	TLNN	T5,SMF.SS	;12BIT SSDD FORMAT ?
	JRST	DATIN2		;NO
	LDB	T4,[POINT 6,DATA,29]	;GET SS CODE
	CALL	DATIN8
	CALL	COMTYP
DATIN2:	TLNN	T5,SMF.SS!SMF.DD	;IS THERE A 6 BIT DESTINATION CODE ?
	JRST	DATIN4		;NO
	LDB	T4,[POINT 6,DATA,35]	;GET DD CODE
	CALL	DATIN8
DATIN4:	TLNN	T5,SMF.BR	;IS THIS BR TYPE ADDRESSING ?
	JRST	B3.TYP		;NO
	LDB	T1,[POINT 8,DATA,35]	;GET OFFSET
	TRNE	T1,200		;CHECK FOR NEGATIVE OFFSET
	IORI	T1,177400
	AOS	T1
	LSH	T1,1		;MAKE WORD ADDRESS
	ADD	T1,DOT
	ANDI	T1,177777	;16 BITS ONLY
	CALL	ADRTYP		;TYPE ADDRESS
	JRST	B3.TYP
DATIN8:	CAIN	T4,27		;CHECK FOR IMMEDIATE MODE
	JRST	[CALL	HSHTYP		;TYPE A #
		CALL	NXTWRD		;GET NEXT WORD
		RET
		JRST	ADRTYP]
	CAIN	T4,37		;CHECK FOR ABSOLUTE MODE
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		JRST	ADRTYP]
	TRNE	T4,10		;CHECK FOR DEFERRED MODE
	CALL	[MOVEI	T1,"@"
		PJRST	TYPCHR]
	CAIE	T4,77		;CHECK FOR RELATIVE DEFERRED MODE
	CAIN	T4,67		;CHECK FOR RELATIVE MODE
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		ADD	T1,DOTFOO	;MAKE RELATIVE
		ADDI	T1,2
		JRST	ADRTYP]
	LDB	T1,[POINT 3,T4,32]	;GET MODE
	CAIE	T1,4
	CAIN	T1,5
	CALL	MINTYP
	CAIL	T1,6		;CHECK FOR INDEX OR INDEX DEFERRED
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		CALL	ADRTYP
		JRST	DATIN1]
	TRNE	T1,6
DATIN1:	CALL	[MOVEI	T1,"("
		PJRST	TYPCHR]
	LDB	T1,[POINT 3,T4,35]	;GET REGISTER VALUE
	CALL	DATIN9		;TYPE REGISTER NAME
	TRNN	T4,60
	RET			;PLAIN REGISTER MODE
	MOVEI	T1,")"
	CALL	TYPCHR
	LDB	T1,[POINT 3,T4,32]
	CAIE	T1,2
	CAIN	T1,3
	CALL	PLUTYP
	RET
DATIN9:	ANDI	T1,7		;STRIP EXTRA BITS
	HRLI	T1,400000	;FLAG IS A REGISTER
	MOVEM	T1,LSTADR	;IN CASE DOES A TAB
	HRRZS	T1
	CALL	RGFNDN		;FIND REGISTERS NAME
	JRST	[CALL	PCNTYP		;TYPE A %
		CALL	OCTYPE
		RET]
	MOVE	T1,(SYM)	;GET REGISTERS NAME
	JRST	SIXTYP
;HERE TO TYPE A PDP8 INSTRUCTION
TYP8IN:	LDB	T1,[POINT 3,DATA,26]	;PICK UP OP CODE
	CAIN	T1,7		;IS THIS AN OPERATE INSTRUCTION ?
	JRST	OPRTYP		;YES SO SPECIAL HANDLING
	MOVE	T1,[SIXBIT \AND\
		SIXBIT	\TAD\
		SIXBIT	\ISZ\
		SIXBIT	\DCA\
		SIXBIT	\JMS\
		SIXBIT	\JMP\
		SIXBIT	\IOT\](T1)
	CALL	SIXTYP
	CALL	BLANKT
	LDB	T1,[POINT 3,DATA,26]	;GET OP CODE AGAIN
	CAIL	T1,6
	JRST	[LDB	T1,[POINT 9,DATA,35]
		CALL	RADTYP
		JRST	B3.TYP]
	MOVE	T2,DATA		;GET INSTRUCTION
	MOVEI	T1,[BYTE (7)"@",0]
	TRNE	T2,400		;IS INDIRECT BIT ON ?
	CALL	TYPSTR
	MOVE	T2,DOT
	ANDI	T2,7600
	LDB	T1,[POINT 8,DATA,35]
	TRZE	T1,200
	ADDI	T1,(T2)
	PUSH	P,T1		;SAVE ADR
	CALL	ADRTYP		;TYPE ADR
	POP	P,T1		;GET ADR BACK
	MOVE	T2,DATA		;GET DATA AGAIN
	TRNN	T2,400		;WAS THIS AN INDIRECT CASE ?
	JRST	B3.TYP		;NOT INDIRECT SO DONE
	LDB	T2,[POINT 3,T2,26]	;GET OP CODE
	CAIN	T2,6		;IOTS DON'T USE ADDRESSES
	JRST	B3.TYP
	PUSH	P,T1		;SAVE ADR AGAIN
	MOVEI	T1,"\"
	CALL	TYPCHR
	POP	P,T1		;GET ADR AGAIN
	MOVEI	T2,1		;ONLY NEED ONE WORD
	CALL	GETWRD		;GET THAT WORD
	JRST	[CALL	CALER0
		JRST	LEVEL0 ]
	CALL	ADRTYP
	JRST	B3.TYP
;HERE TO TYPE AN OPERATE INSTRUCTION
OPRTYP:	SETZ	T5,		;ACCUMULATE BITS MATCHED HERE
	SKIPN	SYM,SYMBEG	;GET STARTING ADDR FOR SYMBOL TABLE
	jrst	[TYPE <?
?Fatal error - symbol table is missing
>
		EXIT]
OPRTY1:	MOVE	T1,2(SYM)	;GET FLAGS FOR SYMBOL & MASK
	TLNE	T1,SMF.P8	;IS THIS A PDP8 SYMBOL ?
	TLNN	T1,SMF.IN	;AND IS THIS AN INSTRUCTION ?
	JRST	OPRTY5		;REJECT THIS SYMBOL
	AND	T1,DATA		;GET VALUE UNDER MASK
	CAME	T1,1(SYM)	;HIT RIGHT ONE ?
	JRST	OPRTY5		;NO
	SKIPE	T5		;FOUND ANY OTHERS YET ?
	CALL	BLANKT		;YES SO TYPE A SPACE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP		;TYPE SYMBOL
	IOR	T5,1(SYM)	;REMBER BITS WE EXPLAINED
OPRTY5:	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL BLOCK
	CAME	SYM,SYMEND	;HIT END OF TABLE ?
	JRST	OPRTY1		;LOOP BACK FOR REST
	ANDI	T5,7777		;STRIP EXTRA BITS
	CAME	T5,DATA		;DID WE MATCH ALL BITS ?
	CALL	QESTYP		;NO SO ADD QUESTION MARK
	JRST	B3.TYP		;CLEAN UP
;HERE TO TYPE DATA AS ASCII TEXT
DATASC:	SKIPE	PDP8F		;WAS THIS A PDP8 WORD ?
	JRST	DATAS2		;YES SO ONLY ONE CHAR/WORD
	ANDI	T1,377		;ONLY 8 BITS PLEASE
	CALL	DATAS3
	SOJLE	T5,B3.TYP
	LDB	T1,[POINT 8,DATA,27]
DATAS2:	CALL	DATAS3
	SOJLE	T5,B3.TYP
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATASC

;HERE TO TYPE CONTENTS OF T1 AS AN ASCII CHAR IF PRINTABLE, ELSE TYPE <#>
DATAS3:	MOVEM	T1,T3		;SAVE IN CASE NOT ASCII
	ANDI	T1,177		;STRIP PARITY BIT
	CAIL	T1,40
	CAILE	T1,176
	CAIA			;SPECIAL HANDLING
	JRST	TYPCHR		;JUST TYPE CHARACTER
	PUSH	P,T3		;SAVE WEIRD CHARACTER
	MOVEI	T1,"<"
	CALL	TYPCHR
	POP	P,T1		;GET CHAR
	CALL	RADTYP
	MOVEI	T1,">"
	PJRST	TYPCHR
;HERE TO TYPE DATA AS EBCDIC TEXT

DATEBC:	SKIPE	PDP8F		;IS THIS PDP8 STUFF ?
	JRST	DATEB2		;YES SO ONLY ONE CHAR/WORD
	CALL	DATEB3
	SOJLE	T5,B3.TYP
	LDB	T1,[POINT 8,DATA,27]
DATEB2:	CALL	DATEB3
	SOJLE	T5,B3.TYP
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATEBC
DATEB3:	ANDI	T1,377
	SETZ	T2,
	LSHC	T1,-2
	ROT	T2,2
	LDB T1,[POINT	8,EB.TRN(T1),7
		POINT	8,EB.TRN(T1),15
		POINT	8,EB.TRN(T1),23
		POINT	8,EB.TRN(T1),31 ](T2)
	PJRST	DATAS3
;HERE TO TYPE DATA AS BYTES

DATBYT:	ANDI	T1,377
	SKIPE	PDP8F
	ANDI	T1,77		;SIX BIT BYTES FOR PDP8
	CALL	RADTYP
	SOJLE	T5,B3.TYP
	CALL	COMTYP		;TYPE A COMMA
	LDB	T1,[POINT 8,DATA,27]
	SKIPE	PDP8F
	LDB	T1,[POINT 6,DATA,29]
	CALL	RADTYP		;TYPE IN CURRENT RADIX
	SOJLE	T5,B3.TYP
	CALL	COMTYP		;TYPE A COMMA
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATBYT
; HERE TO TYPE THE NEXT TWO WORDS AS RADIX 50

DATR50:	CALL DATR51		; TYPE FRIST THREE BYTES
	CALL NXTDWD		; GET THE NEXT DATA WORD, AND DO IT AGAIN
	CALL DATR51		; TYPE LAST THREE BYTES
	SOJLE T5,B3.TYP		; ARE WE DONE?
	CALL COMTYP		; COMMA, FOR A NICE LISTING
	CALL NXTDWD		; GET ANOTHER DATA WORD
	JRST DATR50		; TYPE THE WORD OUT, PLEASE

DATR51:	IDIVI T1,50		; GET THE LAST BYTE OUT
	HRRZ T2,R50TAB(T2)	; CONVERT TO ASCII
	PUSH P,T2		; SAVE THE THIRD BYTE
	IDIVI T1,50		; GET THE MIDDLE BYTE OUT
	HRRZ T2,R50TAB(T2)	; CONVERT THIS TO ASCII
	PUSH P,T2		; AND SAVE THAT, TOO
	HRRZ T1,R50TAB(T1)	; CONVERT THE FIRST BYTE TO ASCII
	CALL TYPCHR		; PRINT THIS BYTE
	POP P,T1		; GET CENTER BYTE
	CALL TYPCHR		; TYPE THAT, TOO
	POP P,T1		; GET LAST BYTE
	CALL TYPCHR		; HALF WAY THERE....
	RET
; TO TYPE A NUMBER IN THE CURRENT RADIX
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	RADTYP	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
RADTYP:	CALL	SAVE24
	HRRZ	T3,ORADIX
	CALL	RADTY2
	CAIN	T3,^D10
	CALL	PERTYP		;TYPE A "."
	RET

;HERE TO TYPE DECIMAL NUMBER
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	DECTYP	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
DECTYP:	CALL	SAVE24
	MOVEI	T3,^D10
	JRST	RADTY2

;HERE TO TYPE AN OCTAL NUMBER AS SIX DIGITS
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	OCTYPE	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
OCTYP6:	CALL	SAVE24
	MOVEI	T3,^D8
	MOVEI	T4,6
	JRST	RADTY3

;HERE TO TYPE AN OCTAL NUMBER
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	OCTYPE	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
OCTYPE:	CALL	SAVE24
	MOVEI	T3,^D8
	;JRST	RADTY2

RADTY2:	SETZ	T4,
RADTY3:	JUMPGE	T1,RADTY5
	MOVMS	T1
	CALL	MINTYP

RADTY5:	IDIVI	T1,(T3)
	HRLM	T2,(P)
	SOSG	T4
	SKIPE	T1
	CALL	RADTY5
RADTY7:	HLRE	T1,(P)
	ADDI	T1,"0"
	CAILE	T1,"9"
	ADDI	T1,7		;DOING HEX
	PJRST	TYPCHR
;HERE TO TYPE A DECIMAL NUMBER WITH COMMAS
PDECTY:	CALL	SAVE24
	MOVEI	T3,^D10
	JUMPGE	T1,PRADT5
	MOVMS	T1
	CALL	MINTYP
PRADT5:	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[EXP RADTY7]
	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[EXP RADTY7]
	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[54-60,,RADTY7]
	PUSH	P,[EXP RADTY7]
	JRST	PRADT5

SIXTYP:	MOVEM	T1,T2
SXTYP1:	SETZ	T1,
	LSHC	T1,6
	ADDI	T1,40
	CALL	TYPCHR
	JUMPN	T2,SXTYP1
	RET
COLTYP:	PUSH	P,T1
	MOVEI	T1,":"
	PJRST	TYPEIT

QESTYP:	PUSH	P,T1
	MOVEI	T1,"?"
	PJRST	TYPEIT

TABTYP:	PUSH	P,T1
	MOVEI	T1,"	"
TYPEIT:	CALL	TYPCHR
	JRST TPOPJ

CRLTYP:	PUSH	P,T1
	MOVEI	T1,15		;CARRIAGE RETURN
	CALL	TYPCHR
	MOVEI	T1,12		;LINEFEED
	PJRST	TYPEIT

B3.TYP:	CALL	BLANKT
	CALL	BLANKT
	;JRST	BLANKT
BLANKT:	PUSH	P,T1
	MOVEI	T1," "
	PJRST	TYPEIT

COMTYP:	PUSH	P,T1
	MOVEI	T1,","
	PJRST	TYPEIT

PERTYP:	PUSH	P,T1
	MOVEI	T1,"."
	PJRST	TYPEIT

PCNTYP:	PUSH	P,T1
	MOVEI	T1,"%"
	PJRST	TYPEIT

HSHTYP:	PUSH	P,T1
	MOVEI	T1,"#"
	PJRST	TYPEIT

MINTYP:	PUSH	P,T1
	MOVEI	T1,"-"
	PJRST	TYPEIT

PLUTYP:	PUSH	P,T1
	MOVEI	T1,"+"
	PJRST	TYPEIT
;HERE TO TYPE OR PRINT A STRING OF CHARACTERS
; CALL	MOVEI	T1,<ADR OF ASCIZ STRING>
;	CALL	TYPSTR
TYPSTR:	PUSH	P,T2
	MOVE	T2,[POINT 7,0]
	ADDI	T2,(T1)		;COPY STRING POINTER
TYPST3:	ILDB	T1,T2		;GET NEXT CHAR
	JUMPE	T1,TYPST5
	CALL	TYPCHR		;TYPE THE CHARACTER
	JRST	TYPST3
TYPST5:	POP	P,T2		;RESTORE REGISTER
	RET

;HERE TO TYPE OR PRINT A SINGLE CHARACTER
TYPCHR:	TXNE	FLG,F.NOUT	;SUPRESSING OUTPUT?
	RET			;YES
	SKIPE	OHD		;DOING A DUMP ?
	JRST	TYPCH3		;YES
	OUTCHR	T1
	RET

TYPCH3:	SOSGE	OHD+2		;ROOM IN BUFFER
	JRST	TYPCH4		;NO
	IDPB	T1,OHD+1
	RET
TYPCH4:	OUT
	JRST	TYPCH3
	HALT
;HERE TO TYPE PROGRAM NAME
IDTYPE:	TYPE	<DDT11 >
	LDB	T1,[POINT 9,.JBVER,11]
	CALL	OCTYPE
	LDB	T1,[POINT 6,.JBVER,17]
	MOVEI	T1,100(T1)
	CAIE	T1,100
	CALL	TYPCHR
	MOVEI	T1,"("
	CALL	TYPCHR
	HRRZ	T1,.JBVER
	CALL	OCTYPE
	MOVEI	T1,")"
	CALL	TYPCHR
	LDB	T1,[POINT 3,.JBVER,2]
	MOVNS	T1
	SKIPE	T1
	CALL	OCTYPE
	HRROI	T1,3		;CODE FOR PROGRAM NAME
	GETTAB	T1,
	JRST	IDTYP2
	CAMN	T1,[SIXBIT \DDT11\]
	JRST	IDTYP2
	PUSH	P,T1
	TYPE	< = >
	POP	P,T1
	CALL	SIXTYP
IDTYP2:	SKIPN	SYMDEV
	JRST	IDTYP3
	TYPE	< /SYMBOLS=>
	MOVEI	T1,SYMDEV
	CALL	FILTYP
IDTYP3:	CALL	BLANKT		;TYPE A BLANK
	RET
;HERE TO TYPE THE DATE
DATETY:	DATE	T1,
DATET0:	IDIVI	T1,^D31*^D12	;LEAVE YEAR-64 IN T1
	ADDI	T1,^D64
	PUSH	P,T1		;SAVE YEAR
	IDIVI	T2,^D31
	ADDI	T2,MONTAB	;GET NAME OF MONTH
	PUSH	P,T2		;SAVE ADR OF MONTH NAME
	AOS	T1,T3		;GET DAY
	CALL	DECTYP
	CALL	MINTYP		;TYPE A "-"
	POP	P,T1		;GET MONTH
	CALL	TYPSTR		;TYPE MONTH NAME
	CALL	MINTYP		;TYPE A "-"
	POP	P,T1		;GET YEAR
	CALL	DECTYP
	RET

MONTAB:	ASCIZ	\Jan\
	ASCIZ	\Feb\
	ASCIZ	\Mar\
	ASCIZ	\Aprl\
	ASCIZ	\May\
	ASCIZ	\June\
	ASCIZ	\July\
	ASCIZ	\Aug\
	ASCIZ	\Sept\
	ASCIZ	\Oct\
	ASCIZ	\Nov\
	ASCIZ	\Dec\
;HERE TO TYPE THE TIME OF DAY

TIMTYP:	CALL	SAVE4
	MSTIME	T1,		;GET TIME OF DAY IN MS
TIMTY1:	PUSH	P,T1		;SAVE TIME
	IDIVI	T1,^D1000	;GET RID OF MS
	IDIVI	T1,^D60		;LEAVES SECONDS IN T2
	PUSH	P,T2
	CALL	TIMTY3		;TYPE HH:MM
	CALL	COLTYP		;TYPE A COLON
	POP	P,T1
	CALL	DC2TYP		;TYPE 2 DIGIT DECIMAL NUMBER
	POP	P,T1		;TIME ORIGINAL TIME AGAIN
	CAIL	T1,^D60*^D1000	;LESS THAN A MINUTE ?
	RET			;NO SO DONE
	CALL	PERTYP		;TYPE A "."
	IDIVI	T1,^D1000	;GET MS FROM ORIGINAL TIME
	EXCH	T1,T2
	CAIL	T2,^D10
	JRST	[IDIVI	T1,^D100	;LEAVE TENTHS
		JRST	DECTYP ]	;TYPE TENTH'S
	IDIVI	T1,^D10
	JRST	DC2TYP		;TYPE HUNDRETHS
TIMTY3:	IDIVI	T1,^D60		;LEAVES MIN IN T2
	PUSH	P,T2
	CALL	DECTYP
	CALL	COLTYP		;TYPE A COLON
	POP	P,T1
	JRST	DC2TYP		;TYPE 2 DIGIT DECIMAL NUMBER

DC2TYP:	CAIL	T1,^D10
	JRST	DECTYP
	PUSH	P,T1
	MOVEI	T1,"0"
	CALL	TYPCHR
	POP	P,T1
	JRST	DECTYP
	SUBTTL	DUMP TO FILE

ESC..D:	TXO	FLG,F.FLIP	;ASSUME DOING COMMAND LOGGING
	TXZ	FLG,F..FOO	;ASSUME NOT DOING A DISASSEMBLY
	CALL	ESC.D0		;SET UP TO CALL OPNFIL
	SKIPE	CMDFIL		;PROCESSING A COMMAND FILE ?
	JRST	DUMP0		;DON'T OPEN A NEW DUMP
	CALL	OPNFIL
	JRST	DUMP9
	SKIPN	FILDEV
	JRST [TYPE <
?$D requires a dump file specification
>
		JRST LEVEL0]
	TXZ	FLG,F.FLIP	;NOT DOING COMMAND LOGGING
	CALL	ESC.D3		;PUT TITLE LINE ON DUMP
DUMP0:	SETZM	CACHEL		;SWEEP CACHE
	TXO	FLG,F.CACH	;PUT USE IT AFTER IT IS SET UP
	HRRO	DOT,SBEGIN	;WHERE TO BEGIN DUMP
	TXNN	FLG,F..FOO	;DOING A DIASSSEMBLY ?
	JRST	DUMP2		;GO DO USUAL DUMP
	PUSH	P,O.MODE	;SAVE OUTPUT MODE
	PUSH	P,BYTCNT	;AND REPETITION COUNT
DISA10:	CALL	CRLTYP		;TYPE A <CR><LF>
	CALL	TABTYP		;TYPE A <HT>
	CALL	DUMP6		;FIND IF LOCATION IS REAL
	JRST	DUMP8		;NOT REAL SO DONE
	HRRZ	T1,DOT		;GET CURRENT LOCATION
	CALL	OCTYP6		;TYPE SIX DIGIT OCTAL NUMBER
	CALL	TABTYP
	HRRZ	T1,DOT		;CURRENT LOCATION
	SETZM	O.MODE		;ASSUME DUMPING AS AN INSTRUCTION
	CALL	CNINWD		;FIND HOW MANY WORDS IN INSTRUCTION
	JRST	[	MOVEI	T1,1		;CODE FOR ADR TYPEOUT
			MOVEM	T1,O.MODE
			JRST	.+1 ]
	MOVEI	T5,(T1)		;NUMBER OF WORDS
	MOVEI	T1,(DOT)	;CURRENT ADR
	CALL	DISA40
	MOVEI	T1,2(DOT)
	CALL	DISA40
	MOVEI	T1,4(DOT)
	CALL	DISA40
	HRRZ	T1,DOT		;GET ADR TO TYPE TAG
	CALL	VALFND		;TRY TO FIND TAG FOR THIS LOCATION
	JRST	DISA20		;NO TAG HERE
	HRRZ	T1,DOT
	CAME	T1,1(SYM)	;EXACT MATCH ?
	JRST	DISA20		;NO IS SAME AS NOT CLOSE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP
	CALL	COLTYP		;PUT COLON AFTER SYMBOL
DISA20:	CALL	TABTYP
	CALL	DATYPE
	MOVE	T1,DOTFOO
	SETZM	DOTFOO
	CALL	DOTINC
	MOVEM	T1,DOT
	HRRZS	T1
	CAMG	T1,S..END
	JRST	DISA10
DISA90:	POP	P,BYTCNT	;RESTORE REPETITION COUNT
	POP	P,O.MODE	;AND OUTPUT MODE
	JRST	DUMP8

DISA40:	SOJL	T5,TABTYP
	MOVEI	T2,2
	CALL	GETWRD
	JRST	DISA90		;CAN'T GET = DONE
	CALL	OCTYP6
	JRST	TABTYP
DUMP1:	HRRZ	T1,DUMPA	;LAST ADDRESS WE TYPED
	ADDI	T1,20
	CAILE	T1,(DOT)	;TIME TO TYPE ADR AGAIN ?
	JRST	DUMP4
DUMP2:	CALL	CRLTYP
	CALL	CRLTYP
	HRRZ	T1,DOT
	CALL	ADRTYP
	JUMPE	SYM,DUMP3	;IF THERE WAS NO SYMBOL DON'T REPEAT
	CALL	BLANKT
	MOVEI	T1,"="
	CALL	TYPCHR
	CALL	BLANKT
	HRRZ	T1,DOT
	CALL	OCTYPE
DUMP3:	CALL	COLTYP		;TYPE A COLON
	HRRZ	T1,DOT
	ANDI	T1,177760	;IN CASE WAS HIGH
	MOVEM	T1,DUMPA	;REMEMBER LAST ADR WE TYPED
	CAIA			;SO WE DO AN EXTRA TAB
DUMP4:	TRNN	DOT,7
	CALL	TABTYP

	CALL	DUMP6		;GET NEXT WORD TO DUMP
	JRST	DUMP8		;ALL DONE
	CALL	DATYPE		;DUMP LOCATION
	MOVE	T1,DOTFOO
	SETZM	DOTFOO
	CALL	DOTINC
	MOVEM	T1,DOT
	HRRZS	T1
	CAMG	T1,S..END
	JRST	DUMP1

DUMP8:	CALL	CRLTYP
	CALL	CRLTYP
DUMP85:	TXNN	FLG,F.FLIP	;DON'T FLUSH IF LOGGING COMMANDS
	CALL	DONE.W
	CALL	CRLTYP
	CALL	CRLTYP
	JRST	LEVEL0

DUMP9:	SETZM	OHD
	TYPE	<error writing >
	CALL	FILERR
	JRST	LEVELB

;HERE TO USE DOT TO GET THE NEXT WORD FROM PDP11 (AND LOAD CACHE)
; CALL	CALL	DUMP6
;	LOSE RETURN
;	WIN RETURN DATA IN T1

DUMP6:	HRRZ	T1,DOT		;GET ADDRESS TO EXAMINE
	MOVE	T2,S..END
	SUB	T2,T1
	CAIL	T2,EXMAX
	SKIPA	T2,[EXP EXMAX]
	ADDI	T2,^D2
	CALL	GETWRD
	RET
	MOVEM	T1,DATA
	RETSKP FAST
;HERE BECAUSE USER TYPED $Y - INVOKES A COMMAND FILE

ESC..Y:	TYPE	<
	Log responses where: >
	CALL	ESC.D0		;SET UP TO CALL OPNFIL
	SETZ	T1,		;NO DEFAULT FILE NAME
	CALL	OPNFL0
	JRST	LEVELB
	SKIPN	FILDEV
	JRST	[TYPE <?
?$Y requires log file specification
>
		JRST LEVEL0]
	TXZ	FLG,F.WRIT!F.APND	;REMEMBER WE ARE READING
	MOVE	T1,[SIXBIT \DDT11\]
	MOVE	T2,[SIXBIT \DDTCMD\]	;DEFAULT EXTENSIONS
	MOVE	T3,[CMDDSP,,CMDSWL]
	MOVEI	T4,RSKP
	PUSH	P,OHD		;IN CASE LOGGING
	SETZM	OHD
	CALL	OPNFIL
	JRST	[POP P,OHD
		CALL DONE.W
		JRST LEVELB]
	POP	P,OHD
	SKIPN	FILDEV
	JRST	[CALL DONE.W
		TYPE <?
?$Y requires a command file specification
>
		JRST LEVEL0]
	CALL	ESC.D3		;PUT TITLE LINE ON DUMP
	TXZ	FLG,F.CERR	;NO COMMAND ERRORS YET
	SETZM	CSECHO		;NOT SUPPRESSING ECHO YET
	SETOM	CMDFIL
	SETZM	CMDCNT		;AT FIRST CHAR
	SETZM	CMDFAK
	JRST	LEVEL0


;HERE TO EAT UP THE REST OF A BAD FILE NAME
LEVELB:	CAIN	T5,15		;LINE ENDED WITH CR?
	JRST	LEVEL0		;YES
	CALL	GETCHR		;GET A CHARACTER
	MOVE	T5,T1		;
	JRST	LEVELB

;HERE TO GET A CHAR FROM A COMMAND FILE

CMDCH1:	SETZM	CMDFAK
CMDCHR:	SKIPE	T1,CMDFAK	;PREVIOUS "^ATEXT^A" TO HANDLE ?
	JRST	[CAMN	T1,[POINT 6,CMDFAK+1,35]
		JRST	CMDCH1
		ILDB	T1,CMDFAK	;GET NEXT CHAR
		JUMPE	T1,CMDCH1	;IF BLANK HIT END
		MOVEI	T1,40(T1)	;CONVERT TO ASCII
		JRST	CMDCH8 ]
	CALL	FILCHR
	JRST	CMDONE		;DONE WITH COMMAND FILE
	AOS	CMDCNT		;COUNT CHARACTERS INTO FILE
	CAIN	T1,177		;IS THIS A RUBOUT ?
	JRST	CMDCHR		;IGNORE IT
	CAIN	T1,1		;IS THIS A "^A"
	JRST	CMDSUB		;SPECIAL SUBSTITUTION
	SKIPGE	CSECHO		;SEARCHING FOR A TAG ?
	JRST	CMDCH8		;YES SO XON, XOF STUFF
	CAIN	T1,37&"S"	;IS THIS AN XOF ?
	JRST	[HLLOS	CSECHO		;YES SHUT OFF ECHOING
		JRST	CMDCHR ]	;ON TO NEXT CHAR
	CAIN	T1,37&"Q"	;IS THIS AN XON ?
	JRST	[HLLZS	CSECHO		;YES SO TURN ECHOING BACK ON
		JRST	CMDCHR ]	;ON TO NEXT CHARACTER
CMDCH8:	SKIPE	CSECHO		;DOING AN ECHO ?
	JRST	RSKP
	PUSH	P,T1		;SAVE CHARACTER
	CAIN	T1,33		;IS THIS AN ALTMODE ?
	MOVEI	T1,"$"		;YES SO ECHO RIGHT
	CALL	TYPCHR
	JRST TPOPJ1		;GET CHAR BACK, AND SKIP RETURN

CMDSUB:	CALL	SAVE24
	MOVE	T4,[POINT 6,CMDFAK+1]
	SETZM	CMDFAK+1
CMDCH2:	CALL	FILCHR		;GET NEXT CHAR
	JRST	CMDCH7
	AOS	CMDCNT		;COUNT THIS CHAR
	CAIN	T1,1		;IS THIS THE TRAILING "^A" ?
	JRST	CMDCH4		;GO EVALUATE WHAT WE HAVE
	CAIL	T1,"A"+40	;CHECK FOR LC
	CAILE	T1,"Z"+40
	TRC	T1,40		;CONVERT TO SIXBIT
	CAME	T4,[POINT 6,CMDFAK+1,35]
	IDPB	T1,T4
	JRST	CMDCH2
CMDCH4:	MOVE	T1,CMDFAK+1	;GET SYMBOL WE BUILT
	CALL	SYMFND		;SEE IF THERE IS A SYMBOL FOR THIS
CMDCH7:	JRST	[MOVEI	T1,1		;THIS IS HIS "^A"
		JRST	CMDCH8 ]
	PUSH	P,[EXP CMDCHR]
	MOVE	T1,1(SYM)	;GET VALUE
	MOVE	T3,[POINT 6,CMDFAK+1]
	MOVEM	T3,CMDFAK
	SETZM	CMDFAK+1
	MOVE	T4,ORADIX
CMDCH6:	IDIVI	T1,(T4)
	HRLM	T2,(P)
	SKIPE	T1
	CALL CMDCH6
	HLRZ	T1,(P)
	IORI	T1,20		;CONVERT TO SIXBIT
	IDPB	T1,T3
	RET


;HERE WHEN DONE WITH A COMMAND FILE

CMDONE:	SKIPE	SYM,SYMBEG	;POINTER TO BEGINING OF SYMBOL TABLE
CMDDN1:	CAMN	SYM,SYMEND	;HIT END YET ?
	JRST	CMDDN7		;DONE
	LDB	T1,[POINT 6,(SYM),5]
	CAIN	T1,'  %'
	JRST	[MOVE	T1,(SYM)	;GET SYMBOL
		CALL	DELSYM		;FLUSH SYMBOL
		JRST	CMDONE ]	;GO GET REST
	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL
	JRST	CMDDN1		;CHECK IT
CMDDN7:	SETZM	CMDFIL		;DONE WITH FILE NOW
	CALL	DONE.W		;IN CASE LOGGING COMMANDS
	TYPE	<
	Finished command file

>
	RET
;HERE TO SETUP FOR CALL TO OPNFIL
ESC.D0:	TXO	FLG,F.WRIT!F.APND	;REMEMBER WE ARE WRITING
	HRROI	T1,3
	GETTAB	T1,		;GET NAME OF JOB
	MOVE	T1,[SIXBIT \DDT11\]
	MOVSI	T2,'LSD'
	MOVE	T3,[DMPDSP,,DMPSWL]
	MOVEI	T4,RSKP
	RET

;HERE TO PUT A TITLE LINE ON A DUMP
ESC.D3:	MOVEI	T1,[BYTE (7)15,12,14,0]
	CALL	TYPSTR
	TYPE	<dump made >
	CALL	TIMTYP		;TYPE TIME
	CALL	BLANKT
	CALL	DATETY		;TYPE DATE
	TYPE	< of />
	MOVE	T1,[SIXBIT \PORT:\]
	SKIPE	MEMORY
	MOVE	T1,[SIXBIT \FILE:\]
	SKIPE	NODE.N
	MOVE	T1,[SIXBIT \NODE:\]
	CALL	SIXTYP
	SKIPE	MEMORY
	JRST	[	MOVEI	T1,DMPDEV
			CALL	FILTYP		;TYPE FILE ID
			JRST	ESC.D4 ]
	SKIPN	T1,NODE.N
	HRRZ	T1,PORT
	MOVEI	T2,OCTYPE
	TLNE	T1,-1
	MOVEI	T2,SIXTYP
	CALL	(T2)
ESC.D4:	TYPE	<
	by >
	CALL	IDTYPE
	CALL	CRLTYP
	CALL	CRLTYP
	RET
	SUBTTL	DUMP TO A BINARY FILE

ESC..P:	TXO	FLG,F.WRIT!F.PACK	;REMEMBER WE ARE WRITING
	TXZ	FLG,F.APND
	MOVE	T1,[SIXBIT /KRUFT/]	;DEFAULT FILE NAME
	MOVSI	T2,'BIN'	;DEFAULT EXTENSION
	MOVE	T3,[PUNDSP,,PUNSWL]

	SETZ	T4,
	SETZM	PROM.F#
	CALL	OPNFIL		;OPEN FILE
	JRST	LEVELB
	SKIPN	FILDEV
	JRST	[TYPE <?
?$P requires a dump file specification
>
		JRST LEVEL0]
	SKIPE	T1,PROM.F#
	JRST	PROM
	MOVEI	T1,^D18		;ASSUME HALFWORD WRITES
	TXNN	FLG,F.PACK	;UNLESS DOING PAPER TAPE
	MOVEI	T1,^D36		;IN WHICH CASE DO FULL WORDS
	DPB	T1,[POINT 6,OHD+1,11]
	MOVE	DOT,SBEGIN
	SETZM	CACHEL		;SWEEP THE CACHE
	TXO	FLG,F.CACH	;CAN USE THE CACHE FROM NOW ON
ESCP00:	SETZ	T4,		;NUMBER OF BYTES FOR CURRENT SEGMENT
	HRRZ	T3,DOT		;NEXT ADR TO GET
ESCP02:	MOVE	T1,T3		;NEXT ADR TO EXAMINE
	IDIVI	T1,^D36
	PUSH	P,T1		;SAVE RELATIVE PDP10 WORD ADR
	MOVN	T1,T2
	MOVSI	T2,400000	;MAKE BIT FOR WORD
	LSH	T2,(T1)		; MAKE IT RIGHT BIT
	POP	P,T1		;GET RELATIVE WORD ADR AGAIN
	TDNN	T2,@MEMUSE
	JRST	ESCP10		;WORD NOT IN USE
	MOVE	T1,T3		;NEXT ADR TO EXAMINE
	MOVEI	T2,1		;ONLY WANT ONE BYTE
	CALL	GETWRD		;TRY TO GET THE WORD
	JRST	ESCP10
	AOS	T4		;ANOTHER WORD TO DUMP
	CAML	T3,S..END
	JRST	ESCP10		;DONE
	CAIGE	T4,^D256
	AOJA	T3,ESCP02
ESCP10:	JUMPN	T4,ESCP11	;ANY BYTES
	AOJA	DOT,ESCP20	;NO SO ADVANCE WHERE TO DUMP FROM
ESCP11:	SETZ	T5,		;INITIALIZE THE CHECKSUM
	MOVEI	T1,1
	CALL	WRTWRD		;WRITE BINARY WORD
	MOVE	T1,T4		;COUNT FOR SEGMENT
	ADDI	T1,6
	CALL	WRTWRD
	HRRZ	T1,DOT
	CALL	WRTWRD
ESCP12:	HRRZ	T1,DOT
	AOS	DOT
	MOVEI	T2,1
	CALL	GETWRD
	EXIT
	SOJLE	T4,ESCP16
	PUSH	P,T1		;SAVE DATA
	HRRZ	T1,DOT
	AOS	DOT
	MOVEI	T2,1
	CALL	GETWRD
	EXIT
	DPB	T1,[POINT 8,(P),27]
	POP	P,T1
	CALL	WRTWRD
	SOJG	T4,ESCP12
	MOVE	T1,T5		;GET CHECKSUM
	ANDI	T1,377		;STRIP EXTRA BITS
	CALL	WRTWRD
	JRST	ESCP19
ESCP16:	SUB	T5,T1		;INCLUDE LAST CHAR IN CHECKSUM
	DPB	T5,[POINT 8,T1,27]
	CALL	WRTWRD

ESCP19:	SETZ	T1,		;ADD PAD BETWEEN SEQMENTS
	CALL	WRTWRD
	CALL	WRTWRD
	CALL	WRTWRD
ESCP20:	HRRZ	T1,DOT
	CAMGE	T1,S..END
	JRST	ESCP00
	SETZ	T5,		;INITIALIZE THE CHECKSUM
	MOVEI	T1,1
	CALL	WRTWRD
	MOVEI	T1,6
	CALL	WRTWRD
	SKIPN	T1,GOTO		;STARTING ADDRESS
	MOVEI	T1,1
	CALL	WRTWRD
	MOVE	T1,T5
	ANDI	T1,377
	CALL	WRTWRD
	CALL	DONE.W		;CLOSE OUTPUT FILE
	JRST	LEVEL2

WRTWRD:	SUB	T5,T1
	ROT	T1,-^D8
	SUB	T5,T1
	ROT	T1,^D8
	TXNN	FLG,F.PACK	;PUNCHING TAPE ?
	JRST	WRTBN4
	SOSGE	OHD+2		;IS THERE ROOM IN BUFFER ?
	CALL	WRTBN9		;NO ROOM
	ANDI	T1,177777	;STRIP EXTRA BITS
	IDPB	T1,OHD+1	;PUT WORD INTO BUFFER
	RET
WRTBN4:	SOSGE	OHD+2		;ROOM FOR LOW ORDER BITS ?
	CALL	WRTBN9
	PUSH	P,T1
	ANDI	T1,377		;ONLY 8 BITS
	IDPB	T1,OHD+1
	POP	P,T1
	LDB	T1,[POINT 8,T1,27]
	SOSGE	OHD+2
	CALL	WRTBN9
	IDPB	T1,OHD+1
	RET
WRTBN9:	SOS	(P)
	SOS	(P)
	OUT
	RET
	JRST	FILERR		;COMPLAIN

PUNIMG:	TXZA	FLG,F.PACK
PUNPAK:	TXO	FLG,F.PACK
	RET

PUNBM8:	SETO	T1,
	CAIA
PUNM93:	MOVEI	T1,1
	MOVEM	T1,PROM.F#
	RET
PROM:	CALL	PROM.2
	NOP
	CALL	PROM.2
	LSH	T1,-^D4
	SKIPG	PROM.F		;SKIP IF M9301
	JRST	DUMP85
	CALL	PROM.2
	LSH	T1,-^D8
	CALL	PROM.2
	LSH	T1,-^D12
	JRST	DUMP85
PROM.2:	MOVEI	T1,377
	CALL	TYPCHR
	MOVE	DOT,SBEGIN
	MOVEI	T4,^D128	;FOR BM873
	SKIPL	PROM.F
	MOVEI	T4,^D256	;FOR M9301
PROM.4:	HRRZ	T1,DOT
	MOVEI	T2,2		;REQUEST 2 BYTES
	CALL	GETWRD
	SETZ	T1,
	TRC	T1,777001
	XCT	@(P)
	SKIPGE	PROM.F#
	PUSH	P,T1
	ANDI	T1,17
	CALL	TYPCHR
	SKIPL	PROM.F
	JRST	PROM.6
	POP	P,T1
	LSH	T1,-^D8
	ANDI	T1,17
	CALL	TYPCHR
PROM.6:	ADDI	DOT,2
	SOJG	T4,PROM.4
	SKIPGE	PROM.F
	JRST	PROM.9		;DON'T NEED FOR BM873

	HRRO	DOT,S..END
	MOVEI	T4,^D256
PROM.8:	HRRZ	T1,DOT
	MOVEI	T2,2
	CALL	GETWRD
	SETZ	T1,
	TRC	T1,777001
	XCT	@(P)
	ANDI	T1,17
	CALL	TYPCHR
	ADDI	DOT,2
	SOJG	T4,PROM.8

PROM.9:	MOVEI	T4,^D256
	SETZ	T1,
	CALL	TYPCHR
	SOJGE	T4,.-1
	AOS	(P)
	RET
;HERE TO GET A CHARACTER IN LINE MODE
RDCHAR:	SKIPE	CMDFIL		;ARE WE DOING COMMAND FILE STUFF ?
	CALL	CMDCHR		;GET A COMMAND FILE CHAR
	INCHWL	T1		;GET THE NEXT CHAR
	CAIN	T1,32		;IS THIS A CONTROL Z ?
	EXIT
	CALL	GETCH8
	JRST	RDCHAR
	RET

;HERE TO GET A CHARACTER FROM THE TTY
GETCHR:	TXZ	FLG,F.NOUT	;STOP SUPRESSING OUTPUT
	SKIPE	T1,CMDTKR	;ARE WE RETYPING COMMAND LINE ?
	JRST	GETCH3		;YES SO DO IT THAT WAY
	SKIPE	CMDFIL		;ARE WE DOING COMMAND FILE STUFF ?
	CALL	CMDCHR		;GET A COMMAND FILE CHAR
	INCHRW	T1		;GET THE NEXT CHAR
GETCH1:	CALL	GETCH8
	JRST	GETCHR
	RET

GETCH3:	CAME	T1,CMDLIM	;RETYPED ENOUGH YET ?
	JRST	GETCH4		;NOT YET
	SETZM	CMDTKR		;DONE WITH TAKER
	JRST	GETCHR
GETCH4:	ILDB	T1,CMDTKR
	JRST	GETCH1

GETCH8:	JUMPE	T1,R		;FLUSH NULLS
	TXNN	FLG,F.TEXT	;DOING TEXT MODE STUFF ?
	CAIE	T1,15		;IS THIS A CARRIAGE RETURN ?
	JRST	GETCH9
	CALL	GETCHR		;GET LF
	CAIN	T1,15		;WAS THIS A 2ND CR ?
	JRST	GETCH8		;YES SO FLUSH IT ALSO
	MOVEI	T1,15		;CONVERT LF TO CR
GETCH9:	RETSKP FAST
	SUBTTL	/FILE: HANDLING

;HERE BECAUSE FOUND /FILE IN RESPONSE INITIAL DIAGLOGUE
; READ EITHER A BOOT11 OR NETLDR DUMP OR A BINARY FILE

RDDUMP:	SKIPN	FILDEV		;FILE SPECIFIED?
	JRST [TYPE	<?
?Dump file specification is required with this switch
>
	RET]
	SETZB	T1,T2		;IN CASE CORE NOT SETUP YET
	SKIPG	MEMLIM		;ANYTHING PUT IN MEMORY YET ?
	CALL	PUTFOO		;NO SO MAKE SOME CORE
	SETZ	AC1,		;HIGHEST LOCATION SO FAR
	MOVE	T1,[FILDEV,,DMPDEV]
	BLT	T1,DMPDEV+$FBLEN-1	;COPY FILDEV, FILNAM, FILEXT, FILPPN, FILTIM
	MOVE T1,[SIXBIT /DTED00/];IF FILE STARTS WITH DTED, ASSUME BIN
	XOR T1,FILNAM
	TDNN T1,[XWD -1,770000]	;MASK DOR "DTED"
	JRST [	TXNN FLG,F.FLOP	;IF NOT "/BINARY"
		TXO FLG,F..FOO	;SAY /DTE FOR HIM
		JRST .+1]
	TXNE FLG,F..FOO		;IS IT /DTE?
	JRST RDTDMP		;YES, READ THE DUMP
	HLRZ	T1,FILEXT	;GET FILE EXTENSION
	CAIE	T1,'BIC'	;OTHER WAY TO SPELL BIN
	CAIN	T1,'BIN'	;DID WE READ A BINARY FILE ?
	TXO	FLG,F.FLOP	;YES SO READING BINARY FILE
	SETZB	T5,T4		;ACCUMULATE CHECKSUM HERE
	TXNE	FLG,F..FOO	;DID WE GET A /DTELDR
	JRST	RDTDMP		;YES SO GO READ IT
	TXZN	FLG,F.FLOP	;READING A BINARY FILE ?
	JRST	RDUMP0		;NO READING A DUMP

	MOVEI	T1,^D36		;WANT 36BIT HEADERS
	CALL	SETIHD		;SO SET EM

;HERE TO LOOK FOR INITIAL 1
RDBN10:	CALL	RDBN70		;GET NEXT CHAR
	JRST	RDUMP9		;ALL DONE
	JUMPE	T1,RDBN10	;LOOP ON HEADER
	CAIE	T1,1		;IS THIS LEADING 1 ?
	JRST	RDBNER		;ERROR IN FORMAT
	CALL	RDBN70		;GET NEXT WORD = 0
	JRST	RDBNER		;ERROR IN FORMAT
	JUMPN	T1,RDBNER
	CALL	RDBN60		;GET 16BIT WORD = COUNT
	MOVEI	T3,-6(T1)	;MAKE BYTE COUNT
	CALL	RDBN60		;GET 16BIT WORD = ADR
	MOVE	T2,T1		;COPY ADDRESS
	TXZ	FLG,F.FLIP	;NO DATA MAYBE
	JUMPE	T3,RDBN30
RDBN20:	TXO	FLG,F.FLIP	;THIS SEGMENT HAD DATA
	CALL	RDBN70		;GET NEXT BYTE TO STUFF
	JRST	RDBNER
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO		;PUT BYTE INTO MEMORY
	AOS	T2		;ADVANCE LOCATION COUNTER
	SOJG	T3,RDBN20
RDBN30:	CALL	RDBN60		;INCLUDE CHECKSUM IN CALC
	TRNE	T5,377		;TEST CHECKSUM
	JRST	[	TYPE <?
?Checksum error
>
			EXIT	]
	TXNE	FLG,F.FLIP
	JRST	RDBN10		;PROBABLY MORE DATA
	ANDI	T2,177776	;ONLY 16 BITS & EVEN
	MOVEM	T2,GOTO		;SAVE STARTING ADDRESS
	MOVEM T2,SIMREG+PC	;SET INITIAL PC
	RELEASE 1,
	SETZM FILDEV
	JRST	RDUMP9
;HERE TO READ A DTELDR OR MDM DUMP
;THE LENGTH OF THE FILE IS CONTAINED IN THE "FILLEN" WORD.
;DTELDR AND MCBDUMP DUMPS ARE (BY BLIND LUCK) IN THE SAME FORMAT AS DDT11'S
; INTERNAL MEMORY REPRESENTATION.

RDTDMP:	MOVE T1,FILLEN
	SUBI T1,^D256
	TXNE FLG,F.MSYS
	MOVEM T1,FILLEN
	CALL	POSYMT		;MAKE SURE THE SYMTAB IS WHER EIT OUGHT
	PUSH	P,SYMBEG	;SAVE WHAT WILL BE THE START OF MEMUSE
	SKIPN	FILLEN
	JRST	[TYPE <?
?Attempted to read zero length file
>
		jrst rfile]
	MOVEI	T2,1		;CALCULATE THE			
RDTDM1:	CAML	T2,FILLEN	;  POWER OF TWO			
	JRST	RDTDM2		;  GREATER THAN			
	ASH	T2,1		;  OR EQUAL TO			
	JRST	RDTDM1		;  THE FILE LENGTH		
RDTDM2:	MOVE	T1,T2		;SAVE AS THE MEMORY SIZE	
	ASH	T2,2		;CALCULATE NUMBER OF BYTES	
	MOVEM	T2,MEMLIM	;  AND SAVE THE NUMBER		
	ADDI	T2,43		;CONVERT TO BITS  		
	IDIVI	T2,44		;  (ROUNDED UP)			
	ADD	T1,T2		;ADD MEMUSE, MEMORY SIZES TOGETHER
	PUSH	P,T2		;				
	CALL	MOVSMT		;GET THE ROOM.
	POP	P,T2		;GET BACK MEMUSE LENGTH		
	POP	P,T1		;FIRST FREE LOC BACK
	HRLI	T1,T1		;GET THE INCESTUOUS POINTER
	MOVEM	T1,MEMUSE	; AND SAVE POINTER TO MEMUSE TABLE
	ADD	T1,T2		;RELOCATE BY THE SIZE OF MEMUSE	
	HRRZM	T1,MEMORY	; AND SAVE POINTER TO START OF MEMORY
	HRRZ	T1,MEMUSE	;GET BACK ADDRESS OF USE TABLE
	HRL	T2,T1		;MAKE A BLT POINTER TO
	HRRI	T2,1(T1)	; TO THE USE TABLE
	SETOM	(T1)		;BLT ALL	  		
	MOVE	T3,FILLEN	;  BUT THE LAST			
	IDIVI	T3,44		;  WORD USED IN	 		
	ADD	T3,T1		;  THE MEMUSE TABLE		
	BLT	T2,0(T3)	;  TO "IN USE"			
	MOVE	T5,T3		;				
	MOVE	T1,FILLEN	;				
	ASH	T1,2		;				
	MOVE	T3,T1		;				
	IDIVI	T3,44		;CALCULATE THE			
	IMULI	T3,44		;  THE NUMBER       		
	ADDI	T3,44		;  OF BITS IN MEMUSE OVER	
	SUB	T3,T1		;  A MULTIPLE			
	SETO	T2,		;  OF 36			
	ASH	T2,0(T3)	;				
	MOVEM	T2,1(T5)	;  AND STORE MASK FOR LAST WORD	
	MOVN	T2,FILLEN	;CALCULATE IN "IOWD" FORM	
	HRLZ	T1,T2		;  THE NUMBER OF WORDS TO GET	
	HRR	T1,MEMORY	; MEMORY
	SOS	T1		; FOR A QUICK "IN"
	SETZ	T2,		;TERMINATE THE COMMAND LIST
	SETSTS	1,.IODMP	;SET DUMP MODE IO
	TXNE FLG,F.MSYS
	USETI 1,3
	TXNN FLG,F.MSYS
	USETI	1,1		;GO TO THE FIRST BLOCK
	IN	1,T1		;READ THE FILE
	 CAIA			; OK
	  CALL IFILER		;REPORT THE ERROR
rfile:	RELEAS	1,		;DONE WITH THE FILE
	SETZM FILDEV
	MOVE	AC1,MEMLIM	;PICK UP UP TOP OF MEMORY	
	MOVEM	AC1,DOT		;REMEMBER WHERE WE ARE AS WELL	
	MOVE	AC1,FILLEN	;SET HIGHEST			
	ASH	AC1,2		;  ADDRESS			
	SUBI	AC1,1		;  LOADED			
	JRST	RDUMP9		;DONE
;HERE TO SET BYTE SIZE FOR INPUT HEADER
; CALL	MOVEI	T1,<BYTE SIZE>
;	CALL	SETIHD
SETIHD:	LDB	T3,[POINT 6,IHD+1,11]	;GET S FIELD FROM INPUT POINTER
	DPB	T1,[POINT 6,IHD+1,11]	;SET NEW S FIELD
	MOVEI	T2,^D36
	IDIVI	T2,(T3)		;FIND NUMBER OF BITS/BYTE CURRENT
	MOVEM	T1,T3		;SAVE NEW SIZE
	MOVE	T1,IHD+2	;NUMBER OF BYTES IN CURRENT BUFFER
	IDIVI	T1,(T2)		;MAKE NUMBER OF WORDS IN CURRENT BUFFER
	MOVEI	T2,^D36
	IDIVI	T2,(T3)		;GET NUMBER OF BYTES/WORD IN NEW SIZE
	IMULI	T1,(T2)		;NUMBER OF BYTES OF NEW SIZE
	MOVEM	T1,IHD+2	;SAVE IT
	RET
;HERE TO GET SIXTEEN BITS
RDBN60:	CALL	RDBN70		;GET LOW ORDER BITS
	JRST	RDBNER
	PUSH	P,T2
	LSHC	T1,-^D8		;SHOVE EM INTO T2
	CALL	RDBN70		;GET HIGH ORDER BITS
	JRST	RDBNER
	ROTC	T1,^D8		;ADD LOW ORDER BITS
	POP	P,T2
	RET			;RETURN TO CALLER

;HERE TO GET NEXT BYTE FROM BINARY FILE
RDBN70:	JUMPE	T4,RDBN74	;HALF OF PREVIOUS WORD LEFT ?
	LDB	T1,[POINT 8,T4,27]	;LOW ORDER BITS FROM PREV HLF WRD
	SETZ	T4,		;DONE WITH HALF WORD
	JRST	RDBN79
RDBN74:	SOSGE	IHD+2		;MORE DATA IN BUFFER ?
	JRST	RDBN80		;NO SO READ MORE
	ILDB	T1,IHD+1
	TXNN	FLG,F.FLOP	;IS THIS PACKED FILE ?
	JRST	RDBN79		;NO
	HRRO	T4,T1		;COPY HALF WORD
	LDB	T1,[POINT 8,T4,35]	;GET HIGH ORDER BITS
RDBN79:	ANDI	T1,377		;STRIP EXTRA BITS
	ADDI	T5,(T1)		;INCLUDE IN CHECKSUM
	RETSKP FAST

RDBN80:	IN	1,		;GET NEXT BUFFER
	JRST	RDBN85		;GOT NEXT BUFFER
	GETSTS	1,T1
	TXNE	T1,IO.IMP!IO.DER!IO.DTE!IO.BKT
	CALL	IFILER
	RELEASE 1,
	SETZM	FILDEV
	RET
RDBN85:	HRRZ	T1,IHD		;GET ADDRES OF CURRENT BUFFER
	HLRE	T1,2(T1)	;GET FIRST WORD IN BUFFER
	JUMPE	T1,RDBN70	;PROCEED
	TXO	FLG,F.FLOP	;IS PACKED FILE
	LDB	T1,[POINT 6,IHD+1,11]	;GET S FIELD FROM INPUT POINTER
	CAIN	T1,^D18		;HALF WORD POINTER
	JRST	RDBN70		;YES
	MOVEI	T1,^D18
	DPB	T1,[POINT 6,IHD+1,11]	;CHANGE POINTER
	MOVE	T1,IHD+2	;GET WORD COUNT
	LSH	T1,1		;MULTIPLY BY 2
	MOVEM	T1,IHD+2
	JRST	RDBN70

RDBNER:	TYPE	<?
?Improper format in input tape
>
	EXIT
;ROUTINES TO READ BOOT11 OR NETLDR DUMPS

;HERE TO FLUSH REST OF INPUT LINE
RDUMP0:	CALL	FILCHR		;GET NEXT CHAR FROM DUMP
	JRST	RDUMP9		;END OF DUMP
	MOVE	T2,T1		;COPY CHAR
RDUMP1:	CAIE	T2,12		;WE ARE LOOKING FOR A LINE FEED
	CAIN	T2,15		;OR A CARRIAGE RETURN
	JRST	RDUMP2
	CAIE	T2,14		;BUT A FORM FEED WILL DO
	JRST	RDUMP0		;AND DIDN'T FIND ONE
RDUMP2:	CALL	INPOCT		;GET ADR
	JRST	RDUMP9
	CAIE	T2,":"		;FINISHED READING ADDRESS ?
	JRST	RDUMP1		;FLUSH LINE
	HRROM	T1,DOT		;SAVE ADDRESS
RDUMP5:	CALL	INPOCT		;GET DATA FOR LINE
	JRST	RDUMP9		;END OF DUMP
	CAIN	T2,40		;CHECK FOR SPACE
	JRST	RDUMP6		;THAT WAS DATA
	CAIE	T2,15		;CHECK FOR CR
	CAIN	T2,11		;CHECK FOR HT
	JRST	RDUMP6		;THAT WAS DATA
	JRST	RDUMP1		;FLUSH LINE
RDUMP6:	HRRZ	T2,DOT		;GET ADDRESS
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO
	SKIPE	PDP8F
	AOJA	DOT,RDUMP5	;YES SO BACK FOR MORE DATA
	LSH	T1,-^D8
	AOS	T2,DOT
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO
	AOJA	DOT,RDUMP5	;BACK FOR MORE DATA

RDUMP9:	MOVE	T1,MEMLIM	;HIGHEST ADDRESS READ
	MOVEM	T1,S..END	;END OF SEARCH
	TYPE	< highest location is >
	MOVE	T1,AC1		;HIGHEST LOCATION LOADED
	CALL	ADRTYP		;DISPLAY ADDRESS
	CALL	CRLTYP		;TYPE A CR/LF
	MOVEI	T1,RSTART
	MOVEM	T1,.JBREN##
	TXO	FLG,F.WENB	;SET WRITE ENABLE CAUSE SHOULDN'T HURT
	SKIPN	MRGFLG		;WANTED TO MERGE ?
	JRST	LEVL.0		;NO SO START
	RETSKP FAST
RSTATE:	BLOCK 1			; THE STATE OF THE INPUT ROUTINE FOR STBS
SYMDEV:	BLOCK	1		; DEVICE NAME FOR SYMBOL FILE
SYMBLK:	BLOCK	1		; START OF LOOKUP/ENTER BLOCK
SYMDIR:	BLOCK	1		; ADDRESS OF PATH BLOCK
SYMNAM:	BLOCK	1		; FILE NAME
SYMEXT:	BLOCK	1		; FILE EXTENSION
SYMTIM:	BLOCK	1		; TIME/DATE AND PROTECTION
SYMPTH:	BLOCK	2		; FILE PATH
SYMPPN:	BLOCK	1		; FILE PPN
SYMSFD:	BLOCK	6		;  AND SUBSEQUENT SFD'S
	BLOCK	1		; SWITCHES

DEFEXT:	BLOCK	1		; DEFAULT EXTENSIONS

FILDEV:	SIXBIT	\DSK\
FILBLK:	BLOCK	1		; START OF LOOKUP/ENTER BLOCK
FILDIR:	BLOCK	1		; POINTER TO FILE DIRECTORY
FILNAM:	BLOCK	1
FILEXT:	BLOCK	1
FILTIM:	BLOCK	1		; FILE PROTECTION AND DATES
FILLEN:	BLOCK	1		;LENGTH OF FILE IN -10 WORDS
	LKELEN==.-FILBLK-1	; SIZE OF LOOKUP/ENTER BLOCK
FILPTH:	BLOCK	2		; PATH BLOCK HEADER
FILPPN:	BLOCK	1		; FILE PPN
FILSFD:	BLOCK	5		;  AND SUBSEQUENT SFD'S
	BLOCK	1		; TERMINATING 0 WORD
	PTHLEN==.-FILPTH	; LENGTH OF PATH BLOCK
FIL.SW:	BLOCK	1
	$FBLEN==.-FILDEV	; LENGTH OF "FILE BLOCK"

IHD:	BLOCK	3		;HEADER FOR INPUT FILE
IBUFER:	BLOCK	<203*NUMBUF>
IFLDEV:	BLOCK	$FBLEN		; INPUT FILE SPEC

OHD:	BLOCK	3		;HEADER FOR OUTPUT FILE
OBUFER:	BLOCK	203
OFLDEV:	BLOCK	$FBLEN		; OUTPUT FILE SPEC


DMPDEV:	EXP	0		;DEVICE FOR DUMP FILE
	EXP	0		; LENGTH OF LOOKUP/ENTER BLOCK
DMPDIR:	EXP	0		; ADDRESS OF PATH BLOCK
	EXP	0		; FILE NAME
	EXP	0		; FILE EXTENSION
DMPTIM:	BLOCK	1		; TIME/DATE AND PROTECTION
DMPPTH:	BLOCK	2+5+1		; FILE DIRECTORY
	BLOCK	1		; SWITCHES WORD
	BLOCK	$FBLEN-<.-DMPDEV>

DUMPA:	BLOCK	1		;LAST ADDRESS TYPED OUT

USETIT:	Z		;BLOCK NUMBER TO START READING FOR SYMBOLS

RELOFF:	Z		;RELOCATION OFFSET IF READING AN FE- DUMP

MYPPN:	BLOCK	1		; PPN OF USER

CSECHO:	Z			;IF NONZERO SUPPRESS ECHOING COMMAND CHARACTERS
			; LH SET -1 IF SEARCHING FOR A TAG
			; RH SET -1 IF ENCOUNTER XOF, CLEARED WITH XON
CMDFIL:	Z
CMDCNT:	Z			;COUNT OF CURRENT COMMAND CHARACTER
CMDDSP:
CMDSWL:	Z
	Z
CMDFAK:	Z			;POINTER TO FOLLOWING WORD
	Z
	DEFINE	NAMES <

	X	BM873,PUNBM8
	X	IMAGE,PUNIMG
	X	M9301,PUNM93
	X	PACKED,PUNPAK

>
	DEFINE	X (Q,QQ) < EXP QQ >

PUNDSP:	NAMES

	DEFINE	X (Q,QQ) < SIXBIT \Q\ >

PUNSWL:	NAMES
	EXP	0
	DEFINE	NAMES <

	X	DISASS,SETFOO	;/DISASSEMBLY

>

	DEFINE	X (A,B) <	0,,B	>

DMPDSP:	NAMES

	DEFINE	X (A,B) <	SIXBIT	\A\ >

DMPSWL:	NAMES
	EXP	0
	SUBTTL	EBCDIC TO ASCII TRANSLATION TABLE

;TRANSLATION TABLE FROM EBCDIC TO ASCII

EB.TRN:

BYTE (8)  0,  1,  2,  3,  0, 11,  0,177,  0,  0,  0, 13, 14, 15,  0,  0 ;017
BYTE (8)  0, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 ;037
BYTE (8)  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 ;057
BYTE (8)  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 ;077
BYTE (8) 40,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 56, 74, 50, 53,136 ;117
BYTE (8) 46,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 44, 52, 51, 73,155 ;137
BYTE (8) 55, 57,  0,  0,  0,  0,  0,  0,  0,  0,174, 54, 45,137, 76, 77 ;157
BYTE (8)  0,  0,  0,  0,  0,  0,  0,  0,  0,140, 72, 43,100, 47, 75, 42 ;177
BYTE (8) 75,141,142,143,144,145,146,147,150,151,  0,  0,  0,  0,  0,  0 ;217
BYTE (8)  0,152,153,154,155,156,157,160,161,162,  0,  0,  0,  0,  0,  0 ;237
BYTE (8)100,176,163,164,165,166,167,170,171,172,134,116,153,133,113,141 ;257
BYTE (8) 60, 61, 62, 63, 64, 65, 66, 67, 70, 71,172,136,114,135,156,157 ;277
BYTE (8)173,101,102,103,104,105,106,107,110,111,  0,  0,  0,  0,  0,  0 ;317
BYTE (8)175,112,113,114,115,116,117,120,121,122,  0,  0,  0,  0,  0,  0 ;337
BYTE (8)134,  0,123,124,125,126,127,130,131,132,  0,  0,  0,  0,  0,  0 ;357
BYTE (8) 60, 61, 62, 63, 64, 65, 66, 67, 70, 71,174,  0,  0,  0,  0,  0 ;377

R50TAB:	
; THIS TABLE IS IN THE FORM OF -10 RADIX50,,-11 RADIX 50, NOTE THAT THEY
; ARE DIFFERENT BY QUITE A BIT

	 " ",," "		; RADIX 50 = 0
	 "0",,"A"
	 "1",,"B"
	 "2",,"C"
	 "3",,"D"
	 "4",,"E"
	 "5",,"F"
	 "6",,"G"
	 "7",,"H"
	 "8",,"I"
	 "9",,"J"
	 "A",,"K"
	 "B",,"L"
	 "C",,"M"
	 "D",,"N"
	 "E",,"O"
	 "F",,"P"
	 "G",,"Q"
	 "H",,"R"
	 "I",,"S"
	 "J",,"T"
	 "K",,"U"
	 "L",,"V"
	 "M",,"W"
	 "N",,"X"
	 "O",,"Y"
	 "P",,"Z"
	 "Q",,"$"
	 "R",,"."
	 "S",,"_"
	 "T",,"0"
	 "U",,"1"
	 "V",,"2"
	 "W",,"3"
	 "X",,"4"
	 "Y",,"5"
	 "Z",,"6"
	 ".",,"7"
	 "$",,"8"
	 "%",,"9"



	END