;
		;**********************************************************************
		; stdcmd.asm	- Standard set of commands for execution by Cmd
		;**********************************************************************
		;
		; created   3/11/98 -jea
		; modified 10/17/98 -jea
		;
		; Functions in this file:
		;  Null command (CR with no command line text)
		;  PortD set and read in decimal and hex
		;  Banked register read and write
		;  Display a string message on the local terminal
		;  Display the PICos version
		;
		; These functions should be used as examples for adding commands to
		;  the PICos environment. 
		;
		; Functions receive input parameters converted from the cmd line 
		;  according to the format string. All parameters are stored in the 
		;  cmdPrmBuff in the order in which they are entered. Decimal and 
		;  hexadecimal parameters occupy one byte while string parameters are 
		;  terminated with a 0. 
		;
		; Output must be provided in the form of a 0 terminated ascii string.
		;  This string is returned in the cmdOutBuff output buffer. If the
		;  first character in this buffer is not 0 it is resubmitted as 
		;  command input. The most common use of this is for the involkation
		;  of the u1: function to provide output to the user and redraw the
		;  command line prompt. All ouput strings must have a LF character
		;  as the last char before the 0 termination to cause the prompt to
		;  be redisplayed. This buffer is preinitalized by Cmd to contain
		;  header info to involke u1: with a LF only on return from all
		;  functions. This causes a new prompt after functions that don't
		;  generate any output.
		; 
		; The PortD commands are very simple and illustrate the use of both
		;  the input parameter buffer and the output string generation 
		;  utilities. The source code for the output string generation 
		;  utilities is located in the file "oututil.asm".
		;
		; Each command must be terminated with a return instruction which 
		;  results in returning from the command processor function Cmd. This 
		;  is due to the fact that Cmd was the last called function. Cmd loads
		;  the cmd function's address directly into the PC thus causing no 
		;  push onto the stack.
		;
		;*********************************************************************
NullCmd	; CR with no cmd line text
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	data	"\r", CmdPC, "Null command (CR_only)\r\n"		; CmdMenu table entry
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;
		return						; return null result string from Cmd
		;
		;*********************************************************************
		; I/O Port D interface functions
		;*********************************************************************
SetDDec	; load decimal parameter into port d
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"PORTDD=n\r", CmdPC, "Set portd to a decimal value\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;
		; fetch decimal parameter from buffer and copy to port d
		movlw	cmdPrmBuff			; load parameter buffer addr
		movwf	FSR1				; into FSR1
		movlb	1					; select sfr bank for port d
		movpf	INDF1, PORTD		; output parameter on port d
		; fall through to DspDDec
		;*********************************************************************
DspDDec	; create output string reporting value in portd as a decimal number
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"PORTDD\r", CmdPC, "Display portd in decimal\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		; copy first part of output string into output buffer using FSR0
		CpyTbl2Out	PortdD
		; copy port d value into output buffer as a decimal number
		movlb	1					; select sfr bank for port d
		movfp	PORTD, WREG			; load port d value into W
		call	Dec2Buf				; convert decimal value into output buffer
		; copy last part of output string into same output buffer using FSR0
		CpyTbl2Out	DcmlD
		return						; return from Cmd
		; This is the end of the functions executable code
		;
		; These data statements store constant ascii output strings in program 
		;  memory. They're accessed using the CpyTbl2Out macro.
PortdD	; constant string for port d display
	data	"\nPortD = ",0
DcmlD	; constant string for decimal display
	data	" decimal\n\r",0
		;
		;*********************************************************************
SetDHex	; load hexidecimal parameter into port d
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"PORTDX=x\r", CmdPC, "Set portd to a hex value\r\n"
	data	"PORTD=x\r", CmdPC, "Set portd to a hex value\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;
		; fetch hexidecimal parameter from buffer and copy to port d
		movlw	cmdPrmBuff			; load parameter buffer addr
		movwf	FSR1				; into FSR1
		movlb	1					; select sfr bank for port d
		movpf	INDF1, PORTD		; output parameter to port d
		; fall through to DspDHex
		;*********************************************************************
DspDHex	; create output string reporting value in port d as a hex number
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"PORTDX\r", CmdPC, "Display portd in hex\r\n"
	data	"PORTD\r", CmdPC, "Display portd in hex\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		; copy first part of output string into output buffer using FSR0
		CpyTbl2Out	PortdD
		; copy port d value into output buffer as a hex number
		movlb	1					; select sfr bank for port d
		movfp	PORTD, WREG			; load port d value into W
		call	Hex2Buf				; convert hex value into output buffer
		; copy last part of output string into same output buffer using FSR0
		CpyTbl2Out	HexD
		return						; return from Cmd
		; This is the end of the functions executable code
		;
		; These data statements store constant ascii output strings in program 
		;  memory. They're accessed using the CpyTbl2Out macro.
HexD	; constant string for hex display
	data	" hex\n\r",0

		;
		;*********************************************************************
RFRead	; read banked register file x:x
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"REGx:x\r", CmdPC, "Read banked register file x:x\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		; data memory allocation for banked register read
	cblock                          ; declare bank 0 variables
		saveBSR                     ; BSR context save variable
		readVal						; read register value storage
	endc
		; executable code for banked register read
		movlw	cmdPrmBuff			; load addr of parameter buffer
		movwf	FSR1				; into FSR1, pointing to bank parameter
		movlw	0x0F				; put mask in W
		andwf	INDF1, W			; mask bank parameter into W
		movlr	high(saveBSR)		; select gpr bank for BSR save
		movpf	BSR, saveBSR		; save current BSR in banked variable
		movwf	BSR					; load bank parameter into BSR
		incf	FSR1				; point to file address parameter
		movlw	0x18				; load address greater than sfr range
		cpfslt	INDF1				; if file addr is in sfr range then skip
		swapf	BSR					; otherwise move bank value to gpr bits
		movfp	INDF1, FSR0			; move address parameter into FSR0
		movfp	INDF0, WREG			; fetch data value into W
		movlr	high(readVal)		; select gpr bank for register storage
		movwf	readVal				; store read value in banked variable
		; create output string reporting value of data byte
		; copy first part of output string into output buffer using FSR0
		CpyTbl2Out	RFD
		; copy register bank into output buffer as a hexidecimal number
		decf	FSR1				; point back to bank paramter
		movlw	0x0F				; put mask in W
		andwf	INDF1, W			; mask bank parameter into W
		call	Hex2Buf				; convert hex value into output buffer
		; put a ':' after the bank value (Hex2Buf leaves FSR0 pointing at end)
		movlw	':'					; load : char
		movwf	INDF0				; put it into the output string
		movlr	high(cmdOutPtr)		; select cmdOutPtr bank
		incf	cmdOutPtr			; point to next output char location
		; copy register address into output buffer as a hexidecimal number
		incf	FSR1				; point to file address parameter
		movfp	INDF1, WREG			; read register file address into W
		call	Hex2Buf				; convert hex value into output buffer
		; copy " = " into same output buffer using FSR0
		CpyTbl2Out	EqD
		; copy register data into output buffer as a hexidecimal number
		movlr	high(readVal)		; select gpr bank for register storage
		movfp	readVal, WREG		; load read value into W
		call	Hex2Buf				; convert hex value into output buffer
		; put a LF and CR after the data
		movlw	'\n'				; load LF char
		movwf	INDF0				; put it into the output string
		incf	FSR0				; point to next output char location
		movlw	'\r'				; load ascii CR into last location in buff
		movwf	INDF0				;  CR terminates cmd line when resubmited
		movlr	high(saveBSR)		; select gpr bank for saved BSR
		movfp	saveBSR, BSR		; restore original BSR value
		return						; return from Cmd
		; This is the end of the functions executable code
		;
		; These data statements store constant ascii output strings in program 
		;  memory. They're accessed using the CpyTbl2Buf and CpyTblCont macros 
		;  with the addresses given by the labels.
RFD		; constant string for register file display
	data	"\nBanked Register ",0
		;
		;*********************************************************************
RFWrite	; write an x parameter into banked register file x:x
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"REGx:x=x\r", CmdPC, "Write x at banked register file x:x\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;
		movlw	cmdPrmBuff			; load addr of start of parameter buffer
		movwf	FSR1				; into FSR1
		movlw	0x0F				; put mask in W
		andwf	INDF1, W			; mask bank parameter into W
		movlr	high(saveBSR)		; select gpr bank for BSR save
		movpf	BSR, saveBSR		; save current BSR in banked variable
		movwf	BSR					; load bank parameter into BSR
		incf	FSR1				; point to file address parameter
		movlw	0x18				; load address greater than sfr range
		cpfslt	INDF1				; if file addr is in sfr range then skip
		swapf	BSR					; otherwise move bank value to gpr bits
		movfp	INDF1, FSR0			; move address parameter into FSR0
		incf	FSR1				; point to register value parameter
		movfp	INDF1, INDF0		; write data value into register
		movlr	high(saveBSR)		; select gpr bank for saved BSR
		movfp	saveBSR, BSR		; restore original BSR value
		return						; return null result string from Cmd

		;
		;*********************************************************************
		; USART1 output commands
		;*********************************************************************
MsgDisp	; Display the message string on USART1
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"MSG:s\r", CmdPC, "Display message s on USART1\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;
		movlw	cmdPrmBuff			; load parameter buffer addr
		movwf	FSR0				;  into FSR0
		bsf		ALUSTA, FS0			; setup FSR0 for auto increment
		bcf		ALUSTA, FS1			;
		movlw	cmdOutBuff			; load start of output buffer addr
		movwf	FSR1				;  into FSR1
		movlw	0x0D				; load CR char
		movwf	INDF1				;  into output buffer
		incf	FSR1				; point to next location
		movlw	0x0A				; load LF char
		movwf	INDF1				;  into output buffer
NxtOutM	incf	FSR1				; point to next location
		movfp	INDF0, INDF1		; move char from parameter to output
		tstfsz	INDF1				; skip if last parameter was 0
		goto	NxtOutM				; copy next char
		; 0 has terminated string parameter copy
		bsf		ALUSTA, FS1			; reset FSR0 to no change
		; send string to user terminal on USART1
		movlw	cmdOutBuff			; load output buffer addr
		movwf	txPtr				;  into txPtr
		call	StartTx				; start interrupt based Tx on UART1
		btfsc	u1Flags, TxRdy		; skip when Tx buffer empty
		goto	$-1					; until then wait
		; load LF and prompt into output buffer
		movlw	cmdOutBuff			; load start of output buffer addr
		movwf	FSR1				;  into FSR1
		movlw	'\n'				; load ascii LF char into W
		movwf	INDF1				; overwrite 0
		incf	FSR1				; point to next location
		movpf	FSR1, cmdOutPtr		; load current location into ptr
		CpyTbl2Out	PromptD			; concatinate prompt onto string
		; send string to user terminal on USART1
		movlw	cmdOutBuff			; load output buffer addr
		movwf	txPtr				;  into txPtr
		call	StartTx				; start interrupt based Tx on UART1
		btfsc	u1Flags, TxRdy		; skip when Tx buffer empty
		goto	$-1					; until then wait
		; init output buffer to cause u1: to display new prompt after cmd
		movlw	cmdOutBuff			; load start of output buffer
		movwf	FSR1				;  into FSR1
		movlw	'u'					; load ascii u
		movwf	INDF1				;  into buffer
		incf	FSR1				; point to next location
		movlw	'1'					; load ascii 1
		movwf	INDF1				;  into buffer
		incf	FSR1				; point to next location
		movlw	':'					; load ascii :
		movwf	INDF1				;  into buffer
		incf	FSR1				; point to next location
		movlw	'\n'				; load ascii LF
		movwf	INDF1				;  into buffer
		movpf	FSR1, cmdOutPtr		; save current location in output pointer
		incf	FSR1				; point to next location
		movlw	'\r'				; load ascii CR into last location in buff
		movwf	INDF1				;  CR terminates cmd line when resubmited
		return						; return from Cmd
		;
		;*********************************************************************
U1Disp	; command used by all commands to send user output to USART1
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"U1:s\r", CmdPC, "Transmit s on USART1\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		;

; support lcd command output display in here somewhere?
;		call	Out2LCD				; display function output on LCD

		movlw	cmdPrmBuff			; load parameter buffer addr
		movwf	FSR0				;  into FSR0
		bsf		ALUSTA, FS0			; setup FSR0 for auto increment
		bcf		ALUSTA, FS1			;
		movlw	cmdOutBuff-1		; load prestart of output buffer addr
		movwf	FSR1				;  into FSR1
NxtOutS	incf	FSR1				; point to next location
		movfp	INDF0, INDF1		; move char from parameter to output
		tstfsz	INDF1				; skip if last parameter was 0
		goto	NxtOutS				; copy next char
		; 0 has terminated string parameter copy
		bsf		ALUSTA, FS1			; reset FSR0 to no change
		decf	FSR1				; backup to char before 0 termination
		movlw	'\n'				; load ascii LF char into W
		cpfseq	INDF1				; skip if last char was a LF
		goto	TxS					; otherwise send existing string
		; last char was a LF, redisplay cmd prompt
		incf	FSR1				; inc to point at 0 termination
		movpf	FSR1, cmdOutPtr		; load current location into ptr
		CpyTbl2Out	PromptD			; concatinate prompt onto string
TxS		; send string to user terminal on USART1
		movlw	cmdOutBuff			; load output buffer addr
		movwf	txPtr				;  into txPtr
		call	StartTx				; start interrupt based Tx on UART1
		btfsc	u1Flags, TxRdy		; skip when Tx buffer empty
		goto	$-1					; until then wait
		clrf	cmdOutBuff			; clear first char in cmdOutBuff
		return						; return from Cmd
		; This is the end of the functions executable code
		;
		; These data statements store constant ascii output strings in program 
		;  memory. They're accessed using the CpyTbl2Buf and CpyTblCont macros 
		;  with the addresses given by the labels.
PromptD	; constant string for command line prompt
	data "\rPICos>",0
		;
		;*********************************************************************
DspVer	; display the PICos version
		;*********************************************************************
		; install this command in the CmdMenu lookup table
	CmdPC = $						; save current inline assembly PC value
	org CurCmdMenuAdr				; set assembly PC to addr for new entry
	; CmdMenu table entry
	data	"VER\r", CmdPC, "Display PICos version\r\n"
	CurCmdMenuAdr = $				; set current CmdMenu addr for next entry
	org CmdPC						; begin cmd code gen at inline address
		; copy first part of output string into output buffer using FSR0
		CpyTbl2Out	VerD
		; copy major version into output buffer
		movlw	high (Version)		; load major rev digit
		call	Dec2Buf				; convert decimal value into output buffer
		; put a . between the major and minor rev
		movlw	'.'					; load . char
		movwf	INDF0				; put it into the output string
		incf	cmdOutPtr			; point to next output char location
		; copy minor version into output buffer as a hex number
		movlw	low (Version)		; load minor rev digit
		call	Hex2Buf				; convert hex value into output buffer
		; put a LF and CR after the rev
		movlw	'\n'				; load LF char
		movwf	INDF0				; put it into the output string
		incf	FSR0				; point to next output char location
		movlw	'\r'				; load ascii CR into last location in buff
		movwf	INDF0				;  CR terminates cmd line when resubmited
		return						; return from Cmd
		; This is the end of the functions executable code
		;
		; These data statements store constant ascii output strings in program 
		;  memory. They're accessed using the CpyTbl2Out macro.
VerD	; constant string for version display
	data	"\nPICos Version ",0

; end of file stdcmd.asm ******************************************************