	ALWAYS	2FEB84	HEXIO	<HEXIO - HEX ASCII CONVERSION ROUTINES>

	.MCALL	DIR$,CALLR

	.SBTTL	GETHX1 - GET 1 HEX ASCII DIGIT


; PURPOSE : TO GET ONE HEXADECIMAL DIGIT
;
; INPUT   : R0 POINTS TO A CHARACTER IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL - CARRY BIT CLEAR
;			    R0 POINTS JUST BEYOND CHARACTER
;			    R1(LOW BYTE) CONTAINS BINARY VALUE
;			    R1(HIGH BYTE) AND OTHER REGS ARE UNCHANGED
;
;	    FAILED(INVALID
;		HEX CHAR) - CARRY BIT SET
;			    R0 UNCHANGED
;			    R1(LOW BYTE) GARBAGE
;			    R1(HIGH BYTE) AND OTHER REGS ARE UNCHANGED
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
GETHX1::
	SWAB	R1		; PREPARE TO PRESERVE R1'S HIGH BYTE
	MOVB	R1,-(SP)	; PUSH HIGH BYTE OF R1 ON STACK
	MOVB	(R0)+,R1	; GET ASCII CHARACTER WITH SIGN EXTEND
	SUB	#'0,R1		; BEGIN CONVERSION
	BMI	ERROR		; ERROR IF NOT HEX DIGIT
	CMPB	#9.,R1		; NUMBER BETWEEN 0 & 9 ?
	BGE	DONE		; IF VALID, SET FLAGS & GET OUT
	SUB	#7.,R1		; DO CONVERSION FOR A - F
	CMPB	#10.,R1		; COMPARE WITH "A"
	BGT	ERROR		; ERROR IF NOT 0 - 9, A - F
	CMPB	#15.,R1		; COMPARE WITH "F"
	BGE	DONE		; VALID HEX
ERROR:
	MOVB	(SP)+,R1	; RETRIEVE OLD HIGH BYTE
	SWAB	R1		; PUT IN HIGH
	DEC	R0		; POINT TO INVALID ASCII CHAR
	PUSH	R0		; SAVE R0/R1
	PUSH	R1
	OUTPUT	HCE		; "HEX CONVERSION ERROR"
	POP	R1		; RESTORE R0/R1
	POP	R0
	SEC			; SET CARRY TO INDICATE ERROR
	BR	EX1		; GET OUT
DONE:	SWAB	R1		; STORE NEW LOW BYTE IN R1
	BISB	(SP)+,R1	; RETRIEVE OLD HIGH BYTE
	SWAB	R1		; NEW LOW IN LOW, OLD HIGH IN HIGH
	CLC			; CLEAR CARRY TO INDICATE SUCCESS
EX1:	RETURN			; EXIT

	.PAGE

	.SBTTL	GETHX2 - GET 2 HEX ASCII DIGITS

; PURPOSE : TO GET TWO HEXADECIMAL DIGITS
;
; INPUT   : R0 POINTS TO A CHARACTER STRING IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL - CARRY BIT CLEAR
;			    R0 POINTS JUST BEYOND STRING
;			    R1(LOW BYTE) CONTAINS BINARY VALUE
;			    R1(HIGH BYTE) AND OTHER REGS UNCHANGED
;
;	    IF FAILED	  - CARRY BIT SET
;			    R0 POINTS TO BAD CHARACTER
;			    R1(LOW BYTE) GARBAGE
;			    R1(HIGH BYTE) AND OTHER REGS UNCHANGED
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
; Modified by: Chris Doran, Sira Ltd.
; 4-Jan-84
;	Add GETHAS -- Get hex or ASCII byte:
;	  'char	gives parity-clear ASCII value,
;	  ^char gives parity-clear control code,
;	  -char gives parity-set ASCII value,
;	  ~char gives parity-set control code,
;	  ^#	gives 7F
;	  ~#	gives FF

GETHAS::
	TSTB	1(%0)		; Make sure we have two characters
	BNE	10$		; OK if so
	OUTPUT	HCE		; Else (Hex) conversion error
	SEC			; Flag error
	BR	60$		; on exit
10$:	CLRB	%1		; Parity-cleared ASCII if
	CMPB	(%0)+,#''	; leading prime?
	BEQ	40$		; Yes, put in character
	CMPB	-(%0),#'^	; ^ is control code
	BEQ	20$		; Go put it in
	BISB	#200,%1		; No, see if parity set char reqd
	CMPB	(%0)+,#'-	; -?
	BEQ	40$		; Yes, that's it
	CMPB	-(%0),#'~	; No, parity-set control?
	BNE	GETHX2		; No, go try for a hex byte
20$:	INC	%0		; Control character, point to char
	CMPB	(%0)+,#'#	; Is it hash?
	BNE	30$		; No, branch
	BISB	#177,%1		; Yes, that's the delete code
	BR	50$		; All done
30$:	BISB	-1(%0),%1	; Others just set
	BICB	#^C237,%1	; Bits 0-4 only
	BR	50$		; Return it
40$:	BISB	(%0)+,%1	; OR in char
50$:	CLC			; Say there is one
60$:	RETURN			; and return with it

GETHX2::PUSH	R2		; SAVE R2
	CALL	GETHX1		; GET HIGH NIBBLE - 1 ASCII DIGIT
	BCS	EX2		; IF ERROR, GET OUT
	MOV	R1,R2		; SAVE HIGH NIBBLE
	ASLB	R2		; PUT HIGH NIBBLE WHERE IT BELONGS
	ASLB	R2
	ASLB	R2
	ASLB	R2
	CALL	GETHX1		; GET LOW NIBBLE - 1 ASCII DIGIT
	BISB	R2,R1		; OR HIGH AND LOW NIBBLE TOGETHER
EX2:	POP	R2		; RESTORE R2
EX21:	RETURN			; EXIT

	.PAGE

	.SBTTL	GETHX4 - GET 4 HEX ASCII DIGITS

; PURPOSE : TO GET FOUR HEXADECIMAL DIGITS
;
; INPUT   : R0 POINTS TO A CHARACTER STRING IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL		: CARRY BIT CLEAR
;					  R0 POINTS JUST BEYOND STRING
;			 		  R1 CONTAINS BINARY VALUE
;			 		  OTHER REGS UNCHANGED
;
;	    IF FAILED (INVALID HEX CHAR): CARRY BIT SET
;					  R0 POINTS TO BAD CHARACTER
;					  R1 GARBAGE
;					  OTHER REGS UNCHANGED
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
GETHX4::CALL	GETHX2		; GET HIGH BYTE - 2 ASCII DIGITS
	BCS	EX4		; GET OUT IF ERROR
	SWAB	R1		; PUT HIGH BYTE WHERE IT BELONGS
	CALLR	GETHX2		; GET LOW BYTE - 2 ASCII DIGITS AND EXIT

EX4:	RETURN			; EXIT

	.PAGE

	.SBTTL	GETHX6 - GET 6 HEX ASCII DIGITS

; PURPOSE : TO GET SIX HEXADECIMAL DIGITS
;
; INPUT   : R0 POINTS TO A CHARACTER STRING IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL		: CARRY BIT CLEAR
;					  R0 POINTS JUST BEYOND STRING
;					  R1 CONTAINS LOW WORD
;					  R2 CONTAINS HIGH WORD
;					  OTHER REGS UNCHANGED
;
;	    IF FAILED (INVALID HEX CHAR): CARRY BIT SET
;					  R0 POINTS TO BAD CHAR
;					  R1,R2 GARBAGE
;					  OTHER REGS UNCHANGED
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
GETHX6::
	CALL	GETHX2		; GET LOW BYTE OF HIGH WORD
	BCS	EX6		; GET OUT IF ERROR
	CLR	R2		; PREPARE R2 TO HOLD HIGH WORD
	BISB	R1,R2		; MOVE LOW BYTE OF HIGH WORD TO R2
	CALLR	GETHX4		; GET LOW WORD AND EXIT

EX6:	RETURN			; EXIT

	.PAGE

	.SBTTL	GETHX8 - GET 8 HEX ASCII DIGITS

; PURPOSE : TO GET EIGHT HEXADECIMAL DIGITS
;
; INPUT   : R0 POINTS TO A CHARACTER STRING IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL		: CARRY BIT CLEAR
;					  R0 POINTS JUST BEYOND STRING
;					  R1 CONTAINS LOW WORD
;					  R2 CONTAINS HIGH WORD
;					  OTHER REGS UNCHANGED
;
;	    IF FAILED (INVALID HEX CHAR): CARRY BIT SET
;					  R0 POINTS TO BAD CHAR
;					  R1,R2 GARBAGE
;					  OTHER REGS UNCHANGED
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
GETHX8::
	CALL	GETHX4		; GET HIGH WORD - 4 ASCII DIGITS
	BCS	EX8		; ERROR? GET OUT
	MOV	R1,R2		; PUT HIGH WORD WHERE IT GOES
	CALLR	GETHX4		; GET LOW WORD - 4 ASCII DIGITS AND EXIT

EX8:	RETURN			; EXIT

	.PAGE

	.SBTTL	GETHXV - GET VARIABLE LENGTH HEX ASCII

; PURPOSE : TO GET A VARIABLE LENGTH HEX ASCII STRING
;
; INPUT   : R0 POINTS TO A CHARACTER STRING.
;	    THE FIRST CHARACTER OF THE VARIABLE LENGTH FIELD IS
;	    AN ASCII HEXADECIMAL DIGIT FROM 1 - 8 INDICATING THE
;	    NUMBER OF CHARACTERS FOLLOWING TO CONVERT TO A BINARY
;	    VALUE.
;
; OUTPUT  : IF SUCCESSFUL: CARRY BIT CLEAR
;			   R0 POINTS JUST BEYOND STRING
;			   R1 CONTAINS LOW WORD
;			   R2 CONTAINS HIGH WORD
;			   R3 CONTAINS THE BINARY VALUE OF THE TOTAL
;			      LENGTH OF THE FIELD
;			   OTHER REGS UNCHANGED
;
;	    IF FAILED (LENGTH=0 OR >8 OR INVALID HEX CHAR) :
;			   CARRY BIT SET
;			   R0 POINTS TO BAD CHAR
;			   R1,R2,R3 GARBAGE
;			   OTHER REGS UNCHANGED
;
;	    ALSO FAILS IF THE VARIABLE LENGTH FIELD WOULD
;	    OVERFLOW UNDER CURRENT MODE.
;
; AUTHOR  : MICHAEL R. HARRELL    DATE : 07-JUL-82
;
GETHXV::
	PUSH	R4		; PRESERVE R4
	CALL	GETHX1		; GET LENGTH TO BE CONVERTED
	BCS	250$		; ERROR? GET OUT
	MOVB	R1,R3		; PUT LENGTH WHERE IT GOES
	CLR	R1		; START FRESH WITH CLEAR R1/R2
	CLR	R2		;  GETHXV ALWAYS RETURNS A LONG WORD
				;  VALUE IN R1/R2

	INC	R3		; ADJUST LENGTH OF STRING
	CMPB	#2,R3		; CONVERT 1 ?
	BEQ	201$		; GO CONVERT 1 ASCII DIGIT
	CMPB	#3,R3		; CONVERT 2 ?
	BEQ	202$		; GO CONVERT 2 ASCII DIGITS
	CMPB	#4,R3		; CONVERT 3 ?
	BEQ	203$		; GO CONVERT 3 ASCII DIGITS
	CMPB	#5,R3		; CONVERT 4 ?
	BEQ	204$		; GO CONVERT 4 ASCII DIGITS
	CMPB	#6,R3		; CONVERT 5 ?
	BEQ	205$		; GO CONVERT 5 ASCII DIGITS
	CMPB	#7.,R3		; CONVERT 6 ?
	BEQ	206$		; GO CONVERT 6 ASCII DIGITS
	CMPB	#8.,R3		; CONVERT 7 ?
	BEQ	207$		; GO CONVERT 7 ASCII DIGITS
	CMPB	#9.,R3		; CONVERT 8 ?
	BNE	230$		;  NE: CONVERT > 8 OR < 1 -WRONG-

208$:	CALL	GETHX8		; CONVERT 8 ASCII DIGITS
	BCC	220$		;  CC: O.K. NOW CHECK TO SEE IF IN RANGE
	BR	250$		;  CS: HEX CONVERSION ERROR - TAKE ERROR EXIT
207$:	CALL	GETHX1		; CONVERT 1ST ASCII DIGIT
	BCS	250$		; ERROR ? GET OUT
	SWAB	R1		; PUT HIGH BYTE WHERE IT BELONGS
	CLRB	R1		; CLEAR LOW BYTE FOR EVENTUAL OR
	MOV	R1,R4		; SAVE LOW NIBBLE HIGH BYTE HIGH WORD  IN R4
	CALL	GETHX6		; CONVERT LOW 6 ASCII CHARS
	BCS	250$		; ERROR ? GET OUT
	BIS	R4,R2		; OR CONVERTED CHARS TOGETHER
	BR	220$		; O.K. NOW CHECK TO SEE IF IN RANGE
206$:	CALL	GETHX6		; CONVERT 6 ASCII CHARS
	BCC	220$		;  CC: O.K. NOW CHECK TO SEE IF IN RANGE
	BR	250$		;  CS: HEX CONVERSION ERROR - TAKE ERROR EXIT
205$:	CALL	GETHX1		; LOW NIBBLE LOW BYTE HIGH WORD
	BCS	250$		; ERROR ? GET OUT
	BISB	R1,R2		; PUT NIBBLE WHERE IT BELONGS
204$:	CALL	GETHX4		; GET 4 ASCII CHARS
	BCC	220$		;  CC: O.K. NOW CHECK TO SEE IF IN RANGE
	BR	250$		;  CS: HEX CONVERSION ERROR - TAKE ERROR EXIT
203$:
	CALL	GETHX1		; LOW NIBBLE HIGH BYTE LOW WORD
	BCS	250$		; ERROR ? GET OUT
	SWAB	R1		; PUT WHERE IT BELONGS
202$:
	CALL	GETHX2		; GET 2 ASCII CHARS
	BCC	220$		;  CC: O.K. NOW CHECK TO SEE IF IN RANGE
	BR	250$		;  CS: HEX CONVERSION ERROR - TAKE ERROR EXIT
201$:
	CALL	GETHX1		; GET 1 ASCII CHAR
	BCS	250$		;  CS: HEX CONVERSION ERROR - TAKE ERROR EXIT
220$:
	CMP	#32.,MODE	; ARE WE IN 32-BIT MODE?
	BEQ	253$		;  EQ: YES, ANYTHING IS LEGITIMATE
	CMPB	#377,R2		; 7 AND 8 DIGIT MUST BE ZERO
	BLO	230$		;  LO: NOT VALID UNDER CURRENT OFFSET
	CMP	#24.,MODE	; ARE WE IN 24-BIT MODE?
	BEQ	253$		; YES, DONE ALL THE CHECKING WE NEED TO DO
	TST	R2		; HIGH WORD MUST BE ZERO WHEN
	BEQ	253$		; UNDER 16-BIT MODE
230$:
	OUTPUT	VLI		; "VARIABLE LENGTH INVALID ..."
250$:
	SEC			; SET CARRY TO INDICATE FAILURE
	BR	255$
253$:
	CLC		; CLEAR CARRY TO INDICATE SUCCESS
255$:
	POP	R4		; RESTORE R4
	RETURN
	.PAGE
	.SBTTL	GETHXL - GETHX4/6/8 DEPENDING ON CURRENT MODE
;
; PURPOSE : TO GET 4/6/8 HEXADECIMAL DIGITS DEPENDING ON CURRENT MODE
;
; INPUT   : R0 POINTS TO A CHARACTER STRING IN A BUFFER
;
; OUTPUT  : IF SUCCESSFUL - CARRY BIT CLEAR
;			    R0 POINTS JUST BEYOND STRING
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;					OR 0 OF MODE IS 16-BIT
;			    OTHER REGISTERS ARE UNCHANGED
;
;	    IF FAILED	  - CARRY BIT SET
;			    R0 POINTS TO BAD CHARACTER
;			    R1 AND R2 GARBAGE
;			    OTHER REGISTERS ARE UNCHANGED
;
; AUTHOR  : KEVIN ANGLEY
GETHXL::
	CLR	R1		; ALWAYS RETURN 32-BIT VALUE IN R1/R2
	CLR	R2		;	EVEN IF MODE IS 16-BIT
	CMP	#32.,MODE	; IS MODE 32-BIT?
	BEQ	10$		;  EQ: YES
	CMP	#24.,MODE	; IS MODE 24-BIT?
	BEQ	20$		;  EQ: YES
	CALL	GETHX4		; NOTHING TO DO BUT ASSUME 16-BIT
	BR	255$		; EXIT
10$:
	CALL	GETHX8		; 32-BIT MODE: GET 8 HEX ASCII DIGITS
	BR	255$		; EXIT
20$:
	CALL	GETHX6		; 24-BIT MODE: GET 6 HEX ASCII DIGITS
255$:
	RETURN			; EXIT

	.PAGE

	.SBTTL	PUTHX1 - PUT 1 HEX ASCII DIGIT
;
; PURPOSE : TO PUT 1 HEXADECIMAL DIGIT
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGIT IS TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGIT
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

RAD16	=	20		; RADIX 16 PARAMETER FOR $CBTA
WIDTH1	=	4000		; WIDTH OF 1 BIT PARAMETER FOR $CBTA

PUTHX1::
	PUSH	R1		; SAVE NUMBER TO BE CONVERTED
	PUSH	R2		; PRESERVE R2
	BIC	#^C 17,R1	; IGNORE ALL BUT LOW NIBBLE
	MOV	#<RAD16!WIDTH1>,R2 ; SET UP PARMS FOR $CBTA
	CALL	$CBTA		; CONVERT
	POP	R2		; RESTORE R2
	POP	R1		; RESTORE NUMBER
	RETURN			; EXIT

	.PAGE

	.SBTTL	PUTHX2 - PUT 2 HEX ASCII DIGITS
;
; PURPOSE : TO PUT 2 HEXADECIMAL DIGITS
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGITS ARE TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGITS
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

PUTHX2::
	PUSH	R1		; SAVE NUMBER
	ASH	#-4,R1		; OUTPUT HIGH NIBBLE
	CALL	PUTHX1		; CONVERT TO ASCII
	POP	R1		; RESTORE ORIGINAL NUMBER
	CALLR	PUTHX1		; CONVERT TO ASCII
				;	& EXIT

	.PAGE

	.SBTTL	PUTHX4 - PUT 4 HEX ASCII DIGITS
;
; PURPOSE : TO PUT 4 HEXADECIMAL DIGITS
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGITS ARE TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGITS
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

PUTHX4::
	SWAB	R1		; OUTPUT HIGH BYTE FIRST
	CALL	PUTHX2		; CONVERT TO ASCII
	SWAB	R1		; OUTPUT ORIGINAL LOW BYTE
	CALLR	PUTHX2		; CONVERT TO ASCII
				;	& EXIT

	.PAGE

	.SBTTL	PUTHX6 - PUT 6 HEX ASCII DIGITS
;
; PURPOSE : TO PUT 6 HEXADECIMAL DIGITS
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGITS ARE TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGITS
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

PUTHX6::
	PUSH	R1		; SAVE LOW WORD
	MOV	R2,R1		; PREPARE TO OUTPUT HIGH WORD
	CALL	PUTHX2		; CONVERT TO ASCII
	POP	R1		; RESTORE LOW WORD
	CALLR	PUTHX4		; CONVERT TO ASCII
				;  & EXIT

	.PAGE

	.SBTTL	PUTHX8 - PUT 8 HEX ASCII DIGITS
;
; PURPOSE : TO PUT 8 HEXADECIMAL DIGITS
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGITS ARE TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGITS
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

PUTHX8::
	PUSH	R1		; SAVE LOW WORD
	MOV	R2,R1		; PREPARE TO OUTPUT HIGH WORD
	CALL	PUTHX4		; CONVERT TO ASCII
	POP	R1		; RESTORE LOW WORD
	CALLR	PUTHX4		; CONVERT TO ASCII
				;	& EXIT
	.PAGE
	.SBTTL	PUTHXL - PUTHX4/6/8 DEPENDING ON CURRENT MODE
;
; PURPOSE : TO PUT 4/6/8 HEXADECIMAL DIGITS DEPENDING ON CURRENT MODE
;
; INPUT   :
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;				(OR GARBAGE IF MODE IS 16 BITS)
;
; OUTPUT  :
;			    ALL REGISTERS ARE UNCHANGED
;
PUTHXL::
	CMP	#32.,MODE	; IS MODE 32-BIT?
	BEQ	10$		;  EQ: YES
	CMP	#24.,MODE	; IS MODE 24-BIT?
	BEQ	20$		;  EQ: YES
	CALL	PUTHX4		; NOTHING TO DO BUT ASSUME 16-BIT
	BR	255$		; EXIT
10$:
	CALL	PUTHX8		; 32-BIT MODE: PUT 8 HEX ASCII DIGITS
	BR	255$		; EXIT
20$:
	CALL	PUTHX6		; 24-BIT MODE: PUT 6 HEX ASCII DIGITS
255$:
	RETURN			; EXIT
	.PAGE
	.SBTTL	PUTHXJ - PUT OUT A 4/6/8 CHAR HEX DIGIT AND LEFT JUSTIFY
;
; PURPOSE : TO PUT 4/6/8 HEXADECIMAL DIGITS DEPENDING ON CURRENT MODE
;		AND, IF NECESSARY, PAD ON RIGHT WITH SPACES TO 8 CHARS
;
; INPUT   :
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;				(OR GARBAGE IF MODE IS 16 BITS)
;
; OUTPUT  :
;			    ALL REGISTERS ARE UNCHANGED
;
PUTHXJ::
	CMP	#32.,MODE	; IS MODE 32-BIT?
	BEQ	10$		;  EQ: YES
	CMP	#24.,MODE	; IS MODE 24-BIT?
	BEQ	20$		;  EQ: YES
	CALL	PUTHX4		; NOTHING TO DO BUT ASSUME 16-BIT
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
	BR	255$		; EXIT
10$:
	CALL	PUTHX8		; 32-BIT MODE: PUT 8 HEX ASCII DIGITS
	BR	255$		; EXIT
20$:
	CALL	PUTHX6		; 24-BIT MODE: PUT 6 HEX ASCII DIGITS
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
	MOVB	#' ,(R0)+	; PUT IN A SPACE TO LEFT JUSTIFY
255$:
	RETURN			; EXIT
	.PAGE
	.SBTTL	PUTHXV - PUT A VARIABLE LENGTH VALUE
;
; PURPOSE : TO PUT AN EXTENDED TEKHEX VARAIBLE LENGTH VALUE
;
; INPUT   :
;			    R0 POINTS TO BUFFER WHERE DIGITS ARE TO
;				BE PLACED
;
;			    R1 CONTAINS BINARY VALUE (LOW WORD)
;			    R2 CONTAINS BINARY VALUE (HIGH WORD)
;
; OUTPUT  :
;			    R0 POINTS JUST PAST DIGITS
;
;			    ALL OTHER REGISTERS ARE UNCHANGED
;

PUTHXV::
	PUSH	R1		; PRESERVE ORIGINAL R1-R5
	PUSH	R2
	PUSH	R3
	PUSH	R4
	PUSH	R5
	MOV	R2,R3		; START WITH HIGH WORD IN R3
	MOV	R1,R2		; SAVE LOW WORD IN R2 FOR LATER
	CLR	R4		; INITIALIZE COUNT OF DIGITS NEEDED
	PUSH	R0		; PRESERVE POINTER TO # OF DIGITS
	INC	R0		; SKIP LENGTH
	MOV	#7,R5		; OUTPUT, OPTIONALLY, LEADING 7 DIGITS
10$:
	CLR	R1		; START WITH FRESH R1 SO Z FLAG WILL BE RIGHT
	.REPT	4
	ROL	R3		; MOVE IN NEXT SIGNIFICANT NIBBLE
	ROL	R1		;	INTO R1 LOW NIBBLE
	.ENDR
	BNE	20$		;  NE: RESULT NIBBLE IS SIGNIFICANT
	TST	R4		; WE HAVE A ZERO - IS IT LEADING?
	BEQ	30$		;  EQ: MUST BE, NOTHING ELSE PUT OUT YET
20$:
	CALL	PUTHX1		; PUT OUT THE NIBBLE IN LOW NIBBLE OF R1
	INC	R4		; INCREMENT NUMBER OF DIGITS REQUIRED
30$:
	CMP	#4,R5		; ARE WE SWITCHING TO LOW WORD?
	BNE	40$		;  NE: NO
	MOV	R2,R3		; PUT LOW WORD INTO R3
40$:
	SOB	R5,10$		; FOR ALL 7 OPTIONAL DIGITS
	CLR	R1		; LEAST SIGNIFICANT DIGIT IS ALWAYS OUTPUT
	.REPT	4
	ROL	R3
	ROL	R1
	.ENDR
	CALL	PUTHX1		; PUT OUT LEAST SIGNIFICANT NIBBLE
	INC	R4		; INCREMENT NUMBER OF DIGITS NEEDED
	MOV	R4,R1		; PREPARE TO OUTPUT LENGTH
	POP	R0		; RESTORE POINTER TO LENGTH DIGIT
	CALL	PUTHX1		; OUTPUT LENGTH DIGIT
	ADD	R1,R0		; POINT PAST ALL DIGITS
	POP	R5		; RESTORE ORIGINAL R1-R5
	POP	R4
	POP	R3
	POP	R2
	POP	R1
	RETURN			; RETURN AFTER RESTORING R1-R5
	.PAGE
	.SBTTL	PUTASC
;
;	Entry parameters:
;
;	R0 points to a buffer in which the character display is to be placed.
;
;	R1 contains the value to be output (low byte)
;
;	Exit parameters:
;
;	R0 points just beyond the hex number
;	R1 & other registers are not affected
;
;	Author:  Chris Doran, Sira Ltd.
;
;	Date:  1-Dec-83
;
; Show byte in %1 as ASCII char, prefixed as follows:
;	space	this is the character, parity clear
;	^	control character, parity clear
;	-	this is the character, parity set
;	~	control character, parity set
; delete is shown as ^# (7F) or ## (FF)
;
; Entry PUTHAS stores the 2-digit hex value first, for EDIT and COMPARE
; entries that show both, as	hh=cc

PUTHAS::
	CALL	PUTHX2		; Display hex byte first
	INC	%0		; Skip '='
PUTASCII::
	MOV	(PC)+,-(SP)	; Load control flag
	.BYTE	100,'^		; and mask to make printable
	CMPB	%1,#40		; in case control char
	BLO	20$		; Yes, go output
	MOV	(PC)+,@SP	; No, space for normal printing char
	.BYTE	0,SPACE
	CMPB	%1,#177		; Try printing or delete
	BLO	20$		; 40-176 are printing, just put in char
	BNE	10$		; 177 is delete
	MOV	#"#^,@SP	; shown specially as
	BR	30$		; Store and return
10$:	MOV	(PC)+,@SP	; Try control char with parity set
	.BYTE	100,'~
	CMPB	%1,#240		; If it is
	BLO	20$
	MOV	(PC)+,@SP	; No, try printing char with parity set
	.BYTE	0,'-
	CMPB	%1,#377		; If not delete!200
	BNE	20$
15$:	MOV	#"##,@SP	; which is shown as ##
	BR	30$
20$:	BISB	%1,@SP		; OR in required char (with 100 for controls)
30$:	MOVB	1(SP),(%0)+	; Store prefix
	MOVB	(SP)+,(%0)+	; then suffix, purging stack
	RETURN

	.PSECT	PURE	RO,D

	DEFM	VLI	<Variable length value overflows under current offset>
	.EVEN

	.END
