;
		;**********************************************************************
		; oututil.asm	- Output String Utilities
		;**********************************************************************
		;
		; created  3/11/98 -jea
		; modified 4/17/98 -jea
		;
		; Several utilites are provided to help generate output strings:
		;
		; CpyTbl2Out is a macro which takes the program memory table address
		;  as a parameter and copies the table into the buffer pointed to by
		;  cmdOutPtr, using FSR0, until reaching a terminating 0.
		;
		; Hex2Buf and Dec2Buf are functions which convert the value in W
		;  from hex or decimal to ascii, storing the resulting string in the
		;  output buffer pointed to by cmdOutPtr. The digit string is then 0 
		;  terminated.
		;
		; ***** Variables for string utilities *****
		;
	cblock						; declare bank 0 variables
		cnvrtVal				; value to be converted to ascii
		cnvrtDigit				; digit currently being converted
	endc
		;
		; ***** Executable code for string utilities *****
		;
		;*********************************************************************
CpyTbl2Out	macro	TblAddr
		; macro to copy constant ascii strings from program memory to a gpr
		;  buffer. Uses table reads from program memory and indirect 
		;  addressing, via FSR0, into data memory. Calls Tbl2Buf function 
		;  after initalization of input parameter via macro text substitution
		;*********************************************************************
		movlw	high(TblAddr)		; load upper byte of output string addr
		movwf	TBLPTRH				; place it in the table pointer hi
		movlw	low(TblAddr)		; load lower byte of output string addr
		movwf	TBLPTRL				; place it in the table pointer lo
		movfp	cmdOutPtr, FSR0		; load FSR0 with output buffer addr
		call	Tbl2Buf				; copy string into output buffer
		movpf	FSR0, cmdOutPtr		; save current output buffer location
	endm
		;
		;*********************************************************************
CpyTbl2Buf	macro	TblAddr, BufAddr
		; macro to copy constant ascii strings from program memory to a gpr
		;  buffer. Uses table reads from program memory and indirect 
		;  addressing, via FSR0, into data memory. Calls Tbl2Buf function 
		;  after initalization of input parameter via macro text substitution
		;*********************************************************************
		movlw	high(TblAddr)		; load upper byte of output string addr
		movwf	TBLPTRH				; place it in the table pointer hi
		movlw	low(TblAddr)		; load lower byte of output string addr
		movwf	TBLPTRL				; place it in the table pointer lo
		movlw	BufAddr				; load literal buffer addr into W
		movfp	WREG, FSR0			; load FSR0 with buffer addr
		call	Tbl2Buf				; copy string into output buffer
		movpf	FSR0, WREG			; put terminating null location in W
	endm
		;
		;**********************************************************************
Tbl2Buf	; Function to copy a program memory table to a ram string buffer
		;**********************************************************************
		;
		; Copy 0 terminated string data from a program memory table to a 
		;  ram buffer. Input consists of the TBLPTRH and L preloaded with
		;  the table addr and the ram buffer addr in FSR0. On return
		;  FSR0 contains a pointer to the terminating null. The DataByte
		;  flag in the cmdFlags register, declared in the Cmd function, is
		;  used to track whether the last table read was the hi or lo byte.
		;
		tablrd	0, 1, WREG			; perform dummy read to init TABLAT
		bcf		cmdFlags, DataByte	; init cmdFlags causing hi read first
TblBfLp	; loop here to copy entire string
		btfss	cmdFlags, DataByte	; if last table byte read was hi then skip
		tlrd	1, INDF0			; otherwise fetch upper byte 
		btfsc	cmdFlags, DataByte	; if last table byte read was lo then skip
		tablrd	0, 1, INDF0			; otherwise fetch lower byte
		btg		cmdFlags, DataByte	; toggle bit indicating hi or lo byte read
		tstfsz	INDF0				; skip if new value is 0
		goto	$+2					; otherwise continue copy
		return						; end of string, return from copy
		incf	FSR0				; point to next buffer location
		goto	TblBfLp				; get next string char
		;
		;**********************************************************************
Dec2Buf	; Function to convert a decimal number into an ascii string buffer
		;**********************************************************************
		;
		; Interprets the input number as decimal and converts it into a
		;  0 terminated ascii string. Input is comprised of the number to be 
		;  converted in W and the addr of the string buffer in cmdOutPtr. On
		;  return cmdOutPtr points to the concatinated 0 termination.
		; [ed: see also:
		;   Binary to BCD half-packed 8 bit to 3 digit
		;   Binary to BCD packed and ASCII, 32 bit to 10 digits
		;   ]
		movwf	cnvrtVal			; store number in cnvrtVal
		movfp	cmdOutPtr, FSR0		; load FSR0 with output buffer addr
		clrf	cnvrtDigit			; init current conversion digit
		bcf		cmdFlags, Hundreds	; clear hundreds flag
DecHuns	; generate hundreds digit
		movlw	99					; load 99 decimal
		cpfsgt	cnvrtVal			; skip if cnvrtVal is 3 decimal digits
		goto	NoDcHns				; otherwise goto no hundreds conversion
		incf	cnvrtDigit			; increment current digit
		movlw	100					; load 100 decimal
		subwf	cnvrtVal			; subtract it from cnvrtVal
		goto	DecHuns				; continue to convert hundreds
NoDcHns	; no more hundreds digits
		tstfsz	cnvrtDigit			; skip if current digit is 0
		goto	$+2					; otherwise setup hundreds digit
		goto	DecTens				; no hundreds, convert tens
		bsf		cmdFlags, Hundreds	; set flag indicating hundreds not 0
		movlw	'0'					; load ascii 0 into W
		addwf	cnvrtDigit, W		; add cnvrtDigit to ascii 0
		movwf	INDF0				; store current digit char into buffer
		clrf	cnvrtDigit			; clear current digit
		incf	FSR0				; increment buffer pointer
DecTens	; generate tens digit
		movlw	9					; load 9 decimal
		cpfsgt	cnvrtVal			; skip if cnvrtVal is 2 decimal digits
		goto	NoDcTns				; otherwise goto no tens conversion
		incf	cnvrtDigit			; increment current digit
		movlw	10					; load 10 decimal
		subwf	cnvrtVal			; subtract it from cnvrtVal
		goto	DecTens				; continue to convert tens
NoDcTns	; no more tens digits
		tstfsz	cnvrtDigit			; skip if current digit is 0
		goto	$+3					; otherwise setup tens digit
		btfss	cmdFlags, Hundreds	; if hundreds nonzero setup anyway
		goto	DecOnes				; otherwise no tens, convert ones
		movlw	'0'					; load ascii 0 into W
		addwf	cnvrtDigit, W		; add cnvrtDigit to ascii 0
		movwf	INDF0				; store current digit into buffer
		clrf	cnvrtDigit			; clear current digit
		incf	FSR0				; increment buffer pointer
DecOnes	; generate ones digit unconditionally
		movlw	'0'					; load ascii 0 into W
		addwf	cnvrtVal, W			; add remaining cnvrtVal to ascii 0
		movwf	INDF0				; store current digit into buffer
		incf	FSR0				; increment buffer pointer
		clrf	INDF0				; terminate converted string with 0
		movpf	FSR0, cmdOutPtr		; save current output buffer location
		return						; return from convert
		;
		;**********************************************************************
Hex2Buf	; Function to convert a hex number into an ascii string buffer
		;**********************************************************************
		;
		; Interprets the input number as hexidecimal and converts it into a
		;  0 terminated ascii string. Input is comprised of the number to be 
		;  converted in W and the addr of the string buffer in cmdOutPtr. On
		;  return cmdOutPtr points to the concatinated 0 termination.
		;
		movwf	cnvrtVal			; store number in cnvrtVal
		movfp	cmdOutPtr, FSR0		; load FSR0 with output buffer addr
		; load upper nibble into cnvrtDigit for conversion
		movlw	0xF0				; load upper nibble mask
		andwf	cnvrtVal, W			; mask upper nibble into W
		movwf	cnvrtDigit			; store nibble in current digit
		swapf	cnvrtDigit			; swap value into lower nibble
		; convert current digit to ascii
		movlw	9					; load highest decimal digit
		cpfsgt	cnvrtDigit			; skip if current digit is greater
		goto	$+3					; otherwise convert as decimal
		movlw	'A' - 0x0A			; load ascii A - hex A conversion constant
		goto	$+2					; goto store char in buffer
		; decimal digit
		movlw	'9' - 0x09			; load ascii 9 - hex 9 conversion constant
		; store converted char in buffer and test for completion
		addwf	cnvrtDigit, W		; convert to ascci char in W
		movwf	INDF0				; store char in buffer
		incf	FSR0				; increment buffer pointer
		; load lower nibble into cnvrtDigit for conversion
		movlw	0x0F				; load lower nibble mask
		andwf	cnvrtVal, W			; mask lower nibble into W
		movwf	cnvrtDigit			; store nibble in current digit
		; convert current digit to ascii
		movlw	9					; load highest decimal digit
		cpfsgt	cnvrtDigit			; skip if current digit is greater
		goto	$+3					; otherwise convert as decimal
		movlw	'A' - 0x0A			; load ascii A - hex A conversion constant
		goto	$+2					; goto store char in buffer
		; decimal digit
		movlw	'9' - 0x09			; load ascii 9 - hex 9 conversion constant
		; store converted char in buffer and test for completion
		addwf	cnvrtDigit, W		; convert to ascci char in W
		movwf	INDF0				; store char in buffer
		incf	FSR0				; increment buffer pointer
		clrf	INDF0				; terminate converted string with 0
		movpf	FSR0, cmdOutPtr		; save current output buffer location
		return						; return from convert

; end of file oututil.asm *****************************************************