	.TITLE	ITRAP - IMP TRAP PACKAGE
;
; A.L. IBBETSON
; R.D. EAGER
; UNIVERSITY OF KENT AT CANTERBURY
; APRIL-MAY 1976
;
	.IDENT	/V01.02/
;
	;TRAP HANDLER FOR IMPLEMENTATION OF IMP UNDER DOS
	;SUPPORTS SINGLE CHARACTER I/O ON CONTROL TTY &
	;UP TO 6 DOS DEVICES (3 I/P, 3 O/P).
	;SYNTAX IS: #OUTPUT CHAN 1, 2, 3 < INPUT CHAN 1, 2, 3
;
	;ANY ERROR GIVES "STOPPED <N>" & THE USER IS THROWN OFF
;
	.NLIST	BEX
	.ENABL	PIC	;FOR IMP LINKER (NON-PIC GIVES R ERROR)
	JMP	.INIT	;INITIAL ENTRY MUST BE 1ST WORD
	.SBTTL	MACROS
;
	.REPT	0
  THIS MACRO COMPUTES AN ADDRESS IN A POSITION-INDEPENDENT MANNER.
  THE ADDRESS MAY BE PLACED IN ANY SENSIBLE PLACE. TROUBLESOME OR UNLIKELY
  ADDRESSING MODES (E.G. (PC)+ ) WILL RESULT IN A .ERROR CALL, INCLUDING
  THE VALUE OF THE ADDRESS MODE (E.G. (PC)+ IS REPRESENTED AS 000027),
  THE ARGUMENT ITSELF AND THE TEXT "ADDRESSING MODE ILLEGAL AS ARGUMENT
  TO ADDRESS MACRO".
	.ENDR
;
	.MACRO	ADDR  ADR,DST
	SP	= %^O6
	PC	= %^O7
	.NTYPE	.SYM,DST	; .SYM = ADDRESS MODE
.IF LE .SYM-^O6			; R0 TO R6
	 MOV	PC,DST
	 ADD	#ADR-.,DST
	.MEXIT
.ENDC
.IF EQ .SYM&^O70-^O10
.IF LE .SYM&^O7-^O6		; @R0 TO @R6
	 MOV	PC,DST
	 ADD	#ADR-.,DST
	.MEXIT
.ENDC
.ENDC
.IF EQ .SYM&^O70-^O20
.IF LE .SYM&^O7-^O6		; (R0)+ TO (R6)+
	 MOV	PC,(.SYM&^O7)
	 ADD	#ADR-.,DST
	.MEXIT
.ENDC
.ENDC
.IF EQ .SYM&^O70-^O30
.IF LE .SYM&^O7-^O6		; @(R0)+ TO @(R6)+
	 MOV	PC,-(SP)
	 ADD	#ADR-.,(SP)
	 MOV	(SP)+,DST
	.MEXIT
.ENDC
.ENDC
.IF EQ .SYM&^O70-^O40
.IF LE .SYM&^O7-^O6		; -(R0) TO -(R6)
	 MOV	PC,DST
	 ADD	#ADR-.,(.SYM&^O7)
	.MEXIT
.ENDC
.ENDC
.IF EQ .SYM&^O70-^O50
.IF LE .SYM&^O7-^O6		; @-(R0) TO @-(R6)
	 MOV	PC,DST
	 ADD	#ADR-.,@(.SYM&^O7)
	.MEXIT
.ENDC
.ENDC
.IF EQ .SYM&^O60-^O60		; [@]X(R0) TO [@]X(R7)
	 MOV	PC,-(SP)
	 ADD	#ADR-.,(SP)
	 MOV	(SP)+,DST
	.MEXIT
.ENDC
	 .ERROR	.SYM		; DST ADDRESSING MODE ILLEGAL AS
	 .PRINT			; ARGUMENT TO ADDRESS MACRO
	.ENDM	ADDR
	.SBTTL	DECLARATIONS
;
	;MANIFESTS
;
LF	=12
FF	=14
CR	=15
TRPVEC	=34
PR7	=340
PSW	=177776
R0	=%0
R1	=%1
R2	=%2
R3	=%3
R4	=%4
R5	=%5
SP	=%6
PC	=%7
;
	;TRAP CODES
;
MONITOR	=0	;MONITOR ENTRY
RDSYM	=1	;READSYMBOL INTO R0
NXTSYM	=2	;NEXT SYMBOL INTO R0 (NO ADVANCE)
PRSYM	=3	;PRINT SYMBOL IN R0
SELIN	=4	;SELECT I/P CHANNEL IN R0
SELOUT	=5	;SELECT O/P CHANNEL IN R0
ILLEGAL	=6	;CODES FROM HERE UP ARE ILLEGAL
;
;
	;RESERVED MONITOR "STOPPED" VALUES
;
ABORT	=-1	;(-VE). GIVES "ABORT" MESSAGE
NORMAL	=0	;NO MESSAGE
OFAIL	=3	;CHANNEL OPEN FAILURE
NOTRAP	=4	;REQUEST UNKNOWN TRAP
END	=8.	;ATTEMPTED READ BEYOND EOF
IO	=9.	;ILLEGAL I/O (STATUS GIVEN IF DEVICE ROUTINE ERROR)
SELINV	=10.	;INVALID SELECT CHANNEL PARAM (IE NOT 0 - 3)
; 1-2 & 5-7 ARE RESERVED FOR IMP COMPILER. >10. AVAILABLE TO USER
;
;
	;DATA AREA FOR 3 I/P AND 3 O/P DOS DEVICES
	;(EACH BLOCK MUST BE SAME SIZE - DONT MOVE)
;
I1:	.WORD	0	;LACK OF BUFFER SPACE FATAL
IP1LKB:	.WORD	0,0	;NO LOGICAL NAME
	.BYTE	1,0	;1 WORD TO FOLLOW, UNIT 0
	.RAD50	/SY/	;SYSTEM DEVICE BY DEFAULT
;
I1.ER:	.WORD	0	;OPEN FAIL ERROR RETURN
	.BYTE	4,0	;.OPENI
IP1FLB:	.WORD	0,0,0,0,0	;FILENAME, EXT, UIC, PROTECTION
;
IP1HDR:	.WORD	1	;MAX BYTE COUNT
	.BYTE	3	;UNFORMATTED BINARY
IP1STA:	.BYTE	0	;STATUS BYTE
IP1CNT:	.WORD	0	;ACTUAL BYTE COUNT
IP1BUF:	.WORD	0	;LOW BYTE IS BUFFER
IP1ERR:	.BYTE	0	;NON-ZERO IF DEVICE ERROR
IP1EOF:	.BYTE	0	;NON-ZERO IF EOF/EOM
IP1FIR:	.BYTE	0	;NON-ZERO AFTER 1ST TRANSFER
	.EVEN
;
I2:	.WORD	0,0,0	;ICHAN 2
	.BYTE	1,0
	.RAD50	/SY/
I2.ER:	.WORD	0
	.BYTE	4,0
	.WORD	0,0,0,0,0,1
	.BYTE	3,0
	.WORD	0,0,0,0
;
	.WORD	0,0,0	;ICHAN 3
	.BYTE	1,0
	.RAD50	/SY/
I3.ER:	.WORD	0
	.BYTE	4,0
	.WORD	0,0,0,0,0,1
	.BYTE	3,0
	.WORD	0,0,0,0
;
	.WORD	0,0,0	;OCHAN 1
	.BYTE	1,0
	.RAD50	/SY/
O1.ER:	.WORD	0
	.BYTE	2,0	;.OPENO
	.WORD	0,0,0,0,0,1
	.BYTE	3,0
	.WORD	0,0,0,0	;LAST 4 BYTES UNUSED FOR O/P CHANS
;
	.WORD	0,0,0	;OCHAN 2
	.BYTE	1,0
	.RAD50	/SY/
O2.ER:	.WORD	0
	.BYTE	2,0
	.WORD	0,0,0,0,0,1
	.BYTE	3,0
	.WORD	0,0,0,0
;
	.WORD	0,0,0	;OCHAN 3
	.BYTE	1,0
	.RAD50	/SY/
O3.ER:	.WORD	0
	.BYTE	2,0
	.WORD	0,0,0,0,0,1
	.BYTE	3,0
	.WORD	0,0,0,0
;
;
	;POINTERS SET BY SELIN & SELOUT
	;(THESE POINT INTO DATA AREA FOR CURRENT CHANNEL)
;
ILKBLK:	.WORD	0	;LINK BLOCK
IFLBLK:	.WORD	0	;FILE BLOCK
IBFHDR:	.WORD	0	;LINE BUFFER HEADER
ISTATU:	.WORD	0	;STATUS
ICNT:	.WORD	0	;ACTUAL BYTE COUNT
IBUFF:	.WORD	0	;BUFFER
IERR:	.WORD	0	;DEVICE ROUTINE ERROR FLAG
IEOF:	.WORD	0	;END OF FILE FLAG
IFIRST:	.WORD	0	;FIRST TRANSFER DONE FLAG
;
OLKBLK:	.WORD	0	;OUTPUT POINTERS SIMILAR
OFLBLK:	.WORD	0
OBFHDR:	.WORD	0
OSTATU:	.WORD	0
OCNT:	.WORD	0
OBUFF:	.WORD	0
;
;
	;TTY DATA AREA - CHANNEL 0
;
	.WORD	0
KBLNKB:	.WORD	0
	.RAD50	/CMI/		;LOGICAL NAME
	.BYTE	1,0
	.RAD50	/KB/
;
	.WORD	0
TPLNKB:	.WORD	0
	.RAD50	/CMO/		;LOGICAL NAME
	.BYTE	1,0
	.RAD50	/KB/
;
	.WORD	0
	.BYTE	4,0
KBFILB:	.WORD	0,0,0,0,0
;
	.WORD	0
	.BYTE	2,0
TPFILB:	.WORD	0,0,0,0,0
;
KBCMDH:	.BLKB	^D14		;TTY KB COMMAND BUFFER HEADER
KBHDR:	.WORD	^D84
	.BYTE	0	;FORMATTED ASCII
KBSTAT:	.BYTE	0
KBCNT:	.WORD	0
KBBUFF:	.BLKB	^D84
KBERR:	.BYTE	0
KBEOF:	.BYTE	0
KBFIRS:	.BYTE	0
	.EVEN
;
TPHDR:	.WORD	^D84	;MAX BYTE COUNT
	.BYTE	0	;FORMATTED ASCII
TPSTAT:	.BYTE	0
TPCNT:	.WORD	0
TPBUFF:	.BLKB	^D84
;
;
	;MISC. VARIABLES
;
DSIZE:	.WORD	0	;SIZE OF DATA SET ENTRY
CSIBLK:	.WORD	0,0,0	;FOR COMMAND STRING INTERPRETER
CODE:	.WORD	0	;TRAP CODE (FOR DEBUGGING)
POINT:	.WORD	0	;TEMP
DIGADD:	.WORD	0	;ADDRESS OF DIGBUF
DIGBUF:	.WORD	0,0,0,0	;FOR CHARS FROM .BIN2O & .BIN2D
COUNT:	.BYTE	0	;TEMP
CUROUT:	.BYTE	0	;CURRENT O/P CHAN
CURIN:	.BYTE	0	;)MUST BE 1 WORD
TTYIN:	.BYTE	0	;) FOR COMMUNICATION BETWEEN RDSYM & NXTSYM
MONINU:	.BYTE	0	;LOCKOUT FOR TRAP MONITOR
LASTOP:	.BYTE	0	;RESULT OF LAST OPERATION
	.EVEN
TENTRY:	.WORD	0	;ORIGINAL CONTENTS ABS 34 (DEBUGGING ONLY)
;
;
	;MESSAGES - TERMINATE WITH NULL FOR PRINT ROUTINES
;
PROMPT:	.BYTE	CR,LF,43,13,0,0	;HASH
;
SYNERR:	.ASCII	/SYNTAX ERROR/
	.BYTE	CR,LF
	.BYTE	0
	.EVEN
;
ABMES:	.ASCII	/ABORT/
	.BYTE	0
	.EVEN
;
STMES:	.ASCII	/STOPPED /
	.BYTE	0
	.EVEN
;
XLF:	.BYTE	CR,LF,0,0
;
OCH:	.ASCII	/ OCHAN /
	.BYTE	0
	.EVEN
;
ICH:	.ASCII	/ ICHAN /
	.BYTE	0
	.EVEN
;
STATMS:	.ASCII	/, STATUS /
	.BYTE	0
	.EVEN
	.SBTTL	INITIALISATION
;
	;MACRO ADDR CALCULATES ADDRESSES POSITION-INDEPENDENTLY
;
.INIT:	;IMP PROGS EXEC THIS & DROP THRO
	ADDR	ENTRY,R0	;ENTRY PT TRAP SERVICE RTN
	MOV	R0,@#TRPVEC
	MOV	#PR7,@#TRPVEC+2	;TAKE TRAP AT PRIORITY 7
;
; INITIALISE DOS ERROR RETURN WORDS
; IN FILE BLOCKS
;
	ADDR	IN.OF,R0
	MOV	R0,I1.ER
	MOV	R0,I2.ER
	MOV	R0,I3.ER
	ADDR	OUT.OF,R0
	MOV	R0,O1.ER
	MOV	R0,O2.ER
	MOV	R0,O3.ER
;
	;OPEN TTY FOR I/O
;
	ADDR	I2,DSIZE	;SET SIZE OF DATASET ENTRY
	ADDR	I1,R0
	SUB	R0,DSIZE
	CLR	R0	;SET I/O PTRS FOR TTY
	TRAP	SELIN
	CLR	R0
	TRAP	SELOUT
	MOV	ILKBLK,-(SP)
	EMT	6		;.INIT
	MOV	OLKBLK,-(SP)
	EMT	6
	MOV	IFLBLK,-(SP)
	MOV	ILKBLK,-(SP)
	EMT	16		;.OPEN
	MOV	OFLBLK,-(SP)
	MOV	OLKBLK,-(SP)
	EMT	16
;
	;O/P PROMPT AND SET UP I/O ON CHANS 1-3
;
GETSPE:	ADDR	PROMPT,R1	;CRLF #
	JSR	PC,PRINT
	MOV	IBFHDR,-(SP)
	MOV	ILKBLK,-(SP)
	EMT	4		;.READ COMMAND STRING
	MOV	ILKBLK,-(SP)
	EMT	1		;.WAIT
	ADDR	KBCMDH,-(SP)
	EMT	56	;CONDENSE COMMAND STRING
	MOV	(SP)+,R0
	BEQ	SYNOK
SYNTAX:	CLR	R0	;SELECT TTY
	TRAP	SELOUT
	ADDR	SYNERR,R1	;"SYNTAX ERROR"
	JSR	PC,PRINT
	CLR	R0
	TRAP	SELIN
	BR	GETSPECS	;TRY AGAIN
	;
	;SET UP LINK & FILE BLOCKS FOR 3 O/P FILES
	;
SYNOK:	CLR	R5	;HOLDS CHAN NR
	MOVB	#3,COUNT
;
1$:	DECB	COUNT
	BLT	2$
	INC	R5
	MOV	R5,R0
	TRAP	SELOUT	;SETS OLKBLK, OFLBLK
	ADDR	CSIBLK,R0
	MOV	R0,-(SP)
	ADDR	KBCMDH,(R0)+
	MOV	OLKBLK,(R0)+
	MOV	OFLBLK,@R0
	MOV	#2,KBCMDH	;GET NEXT O/P SPEC
	EMT	57	;FROM COMMAND STRING INTERPRETER
	MOV	(SP)+,R0
	BIT	#2,R0	;SWITCHES NOT ALLOWED
	BNE	SYNTAX
	BR	1$
2$:	BIT	#1,R0	;CHECK NO MORE O/P SPECS
	BEQ	SYNTAX
;
	;SET UP LINK & FILE BLOCKS FOR 3 I/P FILES
;
	CLR	R5	;EXACTLY SIMILAR TO ABOVE
	MOVB	#3,COUNT
;
3$:	DECB	COUNT
	BLT	4$
	INC	R5
	MOV	R5,R0
	TRAP	SELIN	;SETS ILKBLK, IFLBLK
	ADDR	CSIBLK,R0
	MOV	R0,-(SP)
	ADDR	KBCMDH,(R0)+
	MOV	ILKBLK,(R0)+
	MOV	IFLBLK,@R0
	CLR	KBCMDH	;GET NEXT I/P SPEC
	EMT	57	;SETS NULL DEV NAME IF NOT SPECIFIED
	MOV	(SP)+,R0
	BIT	#2,R0
	BNE	SYNTAX
	BR	3$
4$:	BIT	#1,R0	;CHECK NO MORE I/P SPECS
	BEQ	SYNTAX
;
	;OPEN & INITIALISE DATASETS
;
	CLR	R5
	MOVB	#3,COUNT
;
5$:	DECB	COUNT
	BLT	ENDOPEN
	INC	R5
	MOV	R5,R0
	TRAP	SELIN
	MOV	R5,R0
	TRAP	SELOUT
	MOV	OLKBLK,R0
	TST	6(R0)
	BEQ	6$	;DEV NAME 0 MEANS NOT SPECIFIED
	MOV	R0,-(SP)
	EMT	6	;.INIT
	MOV	OFLBLK,-(SP)
	MOV	OLKBLK,-(SP)
	EMT	16	;.OPEN (OUTPUT)
;
6$:	MOV	ILKBLK,R0
	TST	6(R0)
	BEQ	5$
	MOV	R0,-(SP)
	EMT	6
	MOV	IFLBLK,-(SP)
	MOV	ILKBLK,-(SP)
	EMT	16	;.OPEN (INPUT)
	BR	5$
;
ENDOPEN:	CLR	R0	;GIVE USER TTY INITIALLY
	TRAP	SELIN
	CLR	R0
	TRAP	SELOUT
	JMP	SETEXIT	;END OF INITIALISATION
;
;
PRINT:	MOVB	(R1)+,R0	;OUTPUT STRING. PTR IN R1
	TRAP	PRSYM
	TSTB	@R1	;TERMINATOR IS NULL
	BNE	PRINT
	RTS	PC
;
; CODE TO HANDLE FILE OPEN FAILURES
;
IN.OF:	CLRB	LASTOP		;INPUT OPEN FAILURE
	BR	ALL.OF
OUT.OF:	MOVB	#1,LASTOP	;OUTPUT OPEN FAILURE
ALL.OF:	MOV	#OFAIL,R0
	TRAP	MONITOR
	.SBTTL	ENTRY
;
	;TRAPS ENTER HERE
ENTRY:	MOV	2(SP),@#PSW		;RESET PRIORITY
	MOV	(SP),-(SP)		;COPY RETURN LINK
	SUB	#2,(SP)		;POINT BACK AT TRAP INSTR
	MOV	@(SP),(SP)		;PUT TRAP INSTR ON STACK
	TSTB	(SP)	;LOOK AT TRAP CODE
	BMI	ILLTRP
	CMPB	(SP),#ILLEGAL
	BGT	ILLTRP		;OUT OF RANGE
;
	BIC	#177600,(SP)	;LEAVE THE CODE LESS B:7
	MOV	(SP)+,CODE		;FOR DEBUGGING
	MOV	R1,-(SP)	;SAVE R1 TO R5 FOR EXIT
	MOV	R2,-(SP)
	MOV	R3,-(SP)
	MOV	R4,-(SP)
	MOV	R5,-(SP)
	MOV	CODE,-(SP)
	ASL	(SP)
	ASL	(SP)	;JMP IS 4 BYTE INSTR
	ADD	(SP)+,PC	;JUMP TO APPROPRIATE ROUTINE
;
	JMP	.MONITOR
	JMP	.RDSYM
	JMP	.NXTSYM
	JMP	.PRSYM
	JMP	.SELIN
	JMP	.SELOUT
ILLTRP:	JMP	.ILLEGAL
	.SBTTL	MONITOR

;
	;TRAP CODE 0. O/P OPTIONAL MESSAGE TO TTY,
	;CLOSE I/O, AND EXIT TO DOS
.MONIT:	;
	TSTB	MONINUSE
	BNE	CLOSE		;PREVENT RECURSIVE ENTRIES
	INCB	MONINUSE
	CLR	TPCNT		;ACTUAL BYTE COUNT
	TST	R0		;ENTRY PARAM
	BEQ	CLOSE		;NO MESSAGE
	BGT	STOP		;"STOPPED <N>" MESSAGE
;
	ADDR	ABMES,R1	;"ABORT" (-VE PARAM)
	JSR	PC,PACK
	BR	LF.MON
;
STOP:	MOV	R0,-(SP)	;+VE PARAM
	MOV	R0,-(SP)
	ADDR	STMES,R1	;"STOPPED"...
	JSR	PC,PACK
	MOV	(SP)+,R1
	JSR	PC,DECPACK	;...<R0 ON ENTRY>...
	MOV	(SP)+,R0	;ANY MORE INFO TO BE O/P?
	CMP	R0,#SELINV	;INVALID PARAM TO TRAP 4 OR 5
	BEQ	CHAN
	CMP	R0,#END	;END OF FILE
	BEQ	EOF
	CMP	R0,#OFAIL	;CHANNEL OPEN FAILURE
	BEQ	OF.MON
	CMP	R0,#IO	;ILLEGAL I/O
	BNE	LF.MON		;NO - O/P MESSAGE & EXIT
;
IOERR:	;LASTOP INDICATES WHETHER DEV RTN ERROR (B:1=1) OR
	;UNALLOCATED CHANNEL (B:1=0) & WHETHER O/P (B:0=1)
	;OR I/P (B:0=0)
;
	BITB	#2,LASTOP
	BEQ	CHAN		;JUMP IF UNALLOCATED CHANNEL
	BITB	#1,LASTOP	;DEVICE ROUTINE ERROR...
	BNE	1$
	JSR	PC,INCHAN	;ON INPUT
	JSR	PC,STAT
	MOVB	@ISTATUS,R1
	BR	2$
1$:	JSR	PC,OUTCHAN	;ON OUTPUT
	JSR	PC,STAT
	MOVB	@OSTATUS,R1
2$:	JSR	PC,OCTPACK	;STATUS BYTE INTO TTY BUFFER
	BR	LF.MON
;
OF.MON:
EOF:
CHAN:	BITB	#1,LASTOP	;0=I/P, 1=O/P
	BNE	1$
	JSR	PC,INCHAN	;"ICHAN <N>"
	BR	LF.MON
1$:	JSR	PC,OUTCHAN	;"OCHAN <N>"
;
LF.MON:	ADDR	XLF,R1
	JSR	PC,PACK		;CRLF
;
	;OUTPUT BUFFER TO TTY
	;(USED DIRECTLY TO AVOID CORRUPTING SELIN/SELOUT PTRS)
;
TTYOUT:	ADDR	TPHDR,-(SP)
	ADDR	TPLNKB,-(SP)
	EMT	2	;.WRITE
	ADDR	TPLNKB,-(SP)
	EMT	1	;.WAIT
;
	;CLOSE I/O CHANS 1-3 (UP TO 6 DEVICES)
;
CLOSE:	ADDR	IP1LKB,POINT
	MOVB	#6,COUNT
1$:	DECB	COUNT
	BLT	TTYCLOSE
	TST	@POINT
	BEQ	2$		;SKIP IF UNALLOCATED
	MOV	POINT,-(SP)
	EMT	17	;.CLSE
	MOV	POINT,-(SP)
	EMT	7	;.RLSE
2$:	ADD	DSIZE,POINT	;SIZE OF DATA AREA FOR 1 DEVICE
	BR	1$
;
	;CLOSE TTY (DSIZE NOT APPLICABLE)
;
TTYCLO:	CLR	R0		;SET PTRS FOR CHAN 0
	TRAP	SELIN
	CLR	R0
	TRAP	SELOUT
	MOV	ILKBLK,-(SP)
	MOV	@SP,-(SP)
	EMT	17
	EMT	7
	MOV	OLKBLK,-(SP)
	MOV	@SP,-(SP)
	EMT	17
	EMT	7
	EMT	60		;**** RETURN TO DOS ****
;
;
	;TRAP MONITOR SUBROUTINES
;
OUTCHA:	ADDR	OCH,R1		;"OCHAN"...
	JSR	PC,PACK
	MOVB	CUROUT,R1	;...<N>
	BR	DEC
;
INCHAN:	ADDR	ICH,R1		;"ICHAN"...
	JSR	PC,PACK
	MOVB	CURIN,R1	;...<N>
DEC:	JSR	PC,DECPACK
	RTS	PC
;
STAT:	ADDR	STATMS,R1		;", STATUS"...
	JSR	PC,PACK
	RTS	PC
;
OCTPAC:	MOV	R1,-(SP)	;PACK R1 AS OCTAL CHARS (LOW BYTE ONLY)
	ADDR	DIGBUF,R1	;HIGH BYTE MUST BE ZERO
	MOV	R1,-(SP)	;DESTINATION ADDRESS
	MOV	#5,-(SP)	;.BIN2O (6 CHARS)
	EMT	42
	ADD	#3,R1	;SKIP 1ST 3 CHARS (TOP BYTE)
	BR	PACK
;
DECPAC:	MOV	R1,-(SP)	;PACK R1 AS DECIMAL CHARS
	ADDR	DIGBUF,DIGADDR
	MOV	DIGADDR,-(SP)
	MOV	#3,-(SP)	;.BIN2D (5 CHARS)
	EMT	42
	MOV	DIGADDR,R1
1$:	TSTB	@R1	;SKIP LEADING ZEROS
	BNE	2$
	DEC	R1	;NULL MEANS DONE - O/P 1 ZERO
	BR	PACK
2$:	CMPB	@R1,#'0
	BNE	PACK
	INC	R1
	BR	1$	;LOOK AT NEXT CHARACTER
;
PACK:	ADDR	TPBUFF,R0	;PACK STRING INTO TTY BUFFER
	MOV	TPCNT,R2	;PTR IN R1 ON ENTRY
	ADD	R0,R2		;BUFFER PTR
1$:	CMP	TPCNT,#^D84
	BLT	2$	;) IF BUFFER FULL DISCARD
	TST	(SP)+	;) RETURN LINK AND O/P LINE
	BR	TTYOUT	;) - SHOULDNT HAPPEN
;
2$:	MOVB	(R1)+,(R2)+
	INC	TPCNT		;ACTUAL BYTE COUNT
	TSTB	@R1		;STRING TERMINATED BY NULL
	BNE	1$
	RTS	PC		;NORMAL EXIT
	.SBTTL	RDSYM
;
.RDSYM:	;TRAP CODE 1. READ SYMBOL INTO R0 AND ADVANCE
;
	CLRB	LASTOP	;I/P OPERATION
	CLRB	TTYIN	;FLAG FOR TRAP NXTSYM (SEE BELOW)
	TSTB	CURIN
	BNE	1$	;JUMP IF NOT TTY
	JSR	PC,READ	;ALWAYS READ THEN NXTSYM FOR TTY
	INCB	TTYIN	;USER ENTRY TO NXTSYM CHAN 0
	TRAP	NXTSYM	;GIVES "STOPPED 9"
	BR	3$
1$:	TSTB	@IFIRST		;SET BY READ ROUTINE
	BNE	2$
	JSR	PC,READ	;INITIAL READ 1ST TIME ONLY
2$:	TRAP	NXTSYM
	JSR	PC,READ
3$:	CLRB	TTYIN
	JMP	RTI
	.SBTTL	NXTSYM
;
.NXTSY:	;TRAP CODE 2. READ SYMBOL INTO R0 WITH NO ADVANCE
;
	CLRB	LASTOP	;I/P OPERATION
	TSTB	@IEOF		;SET BY READ ROUTINE
	BEQ	1$
	MOV	#END,R0	;ATTEMPT TO READ BEYOND EOF
	TRAP	MONITOR
1$:	TST	CURIN	;& TTYIN
	BEQ	2$	;USER ENTRIES FOR CHAN 0 ILLEGAL
	TSTB	@IERR	;SET BY READ ROUTINE ON DEVICE ERROR
	BEQ	3$
	MOVB	#2,LASTOP	;I/P DVR ERR
2$:	MOV	#IO,R0	;ILLEGAL I/O
	TRAP	MONITOR
3$:	TSTB	@IFIRST
	BNE	4$	;HAVE WE DONE INITIAL READ?
	JSR	PC,READ	;-NO
	TRAP	NXTSYM
	BR	5$	;NOT STRICTLY NECESSARY
4$:	MOVB	@IBUFF,R0	;PICK UP CHARACTER
5$:	BIC	#177400,R0	;TRIM
	JMP	RTI	;VALID EXIT
;
;
READ:	;SUBROUTINE FOR .RDSYM & .NXTSYM. INPUTS 1 BYTE FROM
	;CURRENT I/P CHAN (STOPPED 9 IF UNALLOCATED) TO CURRENT
	;I/P BUFFER. FLAGS ERRORS BUT TAKES NO ACTION SINCE
	;READS ARE NORMALLY 1 CHAR AHEAD OF USER DEMAND.
;
	TST	@ILKBLK
	BNE	1$	;CHANNEL ALLOCATED?
	MOV	#IO,R0	;-NO. FORCE STOPPED 9
	TRAP	MONITOR
1$:	MOV	IBFHDR,-(SP)
	MOV	ILKBLK,-(SP)
	EMT	4	;.READ
	MOV	ILKBLK,-(SP)
	EMT	1	;.WAIT
	TSTB	@ISTATUS
	BEQ	3$	;ANY ERRORS?
	BITB	#100,@ISTATUS	;-YES
	BEQ	2$	;WAS ERROR EOF?
	BITB	#1,@ISTATUS	;-YES, DID WE GET A CHAR?
	BNE	3$	;(IGNORE EOF FOR NOW IF YES)
	INCB	@IEOF	;-NO, FLAG IT FOR NXTSYM
	BR	3$
2$:	INCB	@IERR	;FLAG DVR ERR FOR NXTSYM
3$:	CLRB	@IFIRST
	INCB	@IFIRST	;FLAG INITIAL READ
	RTS	PC
	.SBTTL	PRSYM
;
.PRSYM:	;TRAP CODE 3. O/P SYMBOL IN R0
	;IF CHAN UNALLOCATED JUST EXIT
;
	CLRB	LASTOP
	INCB	LASTOP	;1=O/P (DEBUGGING ONLY)
	TST	@OLKBLK
	BEQ	3$	;CHANNEL ALLOCATED?
	TSTB	CUROUT
	BEQ	1$
	CLR	@OCNT	;NOT TTY
	INC	@OCNT	;RESET BUFFER COUNT
	MOVB	R0,@OBUFF	;CHAR INTO BUFFER
	BR	2$
1$:	MOV	OBUFF,R1	;TTY IS FORMATTED ASCII
	ADD	@OCNT,R1	;& IS TREATED SEPARATELY
	MOVB	R0,@R1	;CHARACTER INTO BUFFER
	INC	@OCNT
	CMPB	R0,#FF	;O/P TTY BUFFER ON OFLO
	BHI	3$	;OR TERMINATOR
	CMPB	R0,#LF
	BHIS	2$
	CMP	@OCNT,#^D84
	BLT	3$
;
2$:	MOV	OBFHDR,-(SP)
	MOV	OLKBLK,-(SP)
	EMT	2	;.WRITE
	MOV	OLKBLK,-(SP)
	EMT	1	;.WAIT
	CLR	@OCNT
	TSTB	@OSTATUS
	BEQ	3$
	MOVB	#3,LASTOP	;O/P DVR ERR
	MOV	#IO,R0	;ILLEGAL I/O
	TRAP	MONITOR
3$:	JMP	RTI	;VALID EXIT
	.SBTTL	SELECT
;
.SELIN:	;TRAP CODE 4. SELECT I/P CHAN IN R0
	;(SETS PTRS ILKBLK TO IFIRST)
;
	CLRB	LASTOP	;I/P FLAG FOR TRAP MONITOR
	MOVB	R0,CURIN
	TST	R0	;CHECK PARAM IN R0 LEGAL
	BLT	6$
	BEQ	4$	;TTY SELECT?
	CMP	R0,#3
	BGT	6$
;
	CLR	R1	;VALID PARAM
1$:	DEC	R0
	BLE	2$
	ADD	DSIZE,R1	;SET UP OFFSET IN DATA AREA
	BR	1$
;
2$:	ADDR	IP1LKB,ILKBLK	;INITIALISE PTRS
	ADDR	IP1FLB,IFLBLK
	ADDR	IP1HDR,IBFHDR	
	ADDR	IP1CNT,ICNT
	ADDR	IP1BUF,IBUFF
	ADDR	IP1ERR,R0
	MOV	R0,IERR	
	INC	R0
	MOV	R0,IEOF
	INC	R0
	MOV	R0,IFIRST
	ADDR	IP1STAT,ISTATUS
	ADDR	ILKBLK,R2
	MOV	#9.,R0	;NUMBER OF PTRS
3$:	DEC	R0
	BLT	5$
	ADD	R1,(R2)+	;ADD OFFSET TO PTRS
	BR	3$	;(CONTIGUOUS)
;
4$:	ADDR	KBLNKB,ILKBLK	;TTY IS SPECIAL CASE
	ADDR	KBFILB,IFLBLK	;(DSIZE DOES NOT APPLY)
	ADDR	KBHDR,IBFHDR
	ADDR	KBCNT,ICNT
	ADDR	KBBUFF,IBUFF
	ADDR	KBERR,R0
	MOV	R0,IERR
	INC	R0
	MOV	R0,IEOF
	INC	R0
	MOV	R0,IFIRST
	ADDR	KBSTAT,ISTATUS
5$:	JMP	RTI		;VALID EXIT
;
6$:	MOV	#SELINV,R0	;INVALID SELECT
	TRAP	MONITOR
;
;----------------------------------------------------------------------
;
.SELOUT:	;TRAP CODE 5. SELECT O/P CHAN IN R0
;
	CLRB	LASTOP
	INCB	LASTOP	;O/P FLAG FOR TRAP MONITOR
	MOVB	R0,CUROUT
	TST	R0	;CHECK LEGAL PARAM
	BLT	6$
	BEQ	4$	;TTY
	CMP	R0,#3
	BGT	6$
	ADD	#3,R0		;SKIP I/P DATA AREA
	CLR	R1
1$:	DEC	R0
	BLE	2$
	ADD	DSIZE,R1	;SET UP OFFSET IN DATA AREA
	BR	1$
2$:	ADDR	IP1LKB,OLKBLK	;INITIALISE PTRS
	ADDR	IP1FLB,OFLBLK
	ADDR	IP1HDR,OBFHDR
	ADDR	IP1CNT,OCNT
	ADDR	IP1BUF,OBUFF
	ADDR	IP1STAT,OSTATUS
	ADDR	OLKBLK,R2	;ADD OFFSET TO POINTERS
	MOV	#6,R0
3$:	DEC	R0
	BLT	5$
	ADD	R1,(R2)+
	BR	3$
;
4$:	ADDR	TPLNKB,OLKBLK	;TTY IS SPECIAL CASE
	ADDR	TPFILB,OFLBLK
	ADDR	TPHDR,OBFHDR
	ADDR	TPCNT,OCNT
	ADDR	TPBUFF,OBUFF
	ADDR	TPSTAT,OSTATUS
;
5$:	JMP	RTI		;VALID EXIT
;
6$:	MOV	#SELINV,R0		;INVALID SELECT
	TRAP	MONITOR
	.SBTTL	ILLEGAL
;
.ILLEG:	;TRAP CODE 6. ILLEGAL TRAP
;
	MOV	#NOTRAP,R0
	TRAP	MONITOR	;"STOPPED 4"
;
;-----------------------------------------------------------------
;
RTI:	MOV	(SP)+,R5	;RESTORE REGS & RETURN FROM INTERRUPT
	MOV	(SP)+,R4
	MOV	(SP)+,R3
	MOV	(SP)+,R2
	MOV	(SP)+,R1	;R0 USED ON READS
	RTI
;
	.EVEN		;IMP CONSOLIDATOR DEMANDS EVEN NR BYTES
SETEXIT:
	.END		;NO TXFER ADDR FOR IMP CONSOLIDATOR

