;****************************************************************************************
; Copyright © [11/21/1999] Scenix Semiconductor, Inc. All rights reserved.
;
; Scenix Semiconductor, Inc. assumes no responsibility or liability for
; the use of this [product, application, software, any of these products].
; Scenix Semiconductor conveys no license, implicitly or otherwise, under
; any intellectual property rights.
; Information contained in this publication regarding (e.g.: application,
; implementation) and the like is intended through suggestion only and may
; be superseded by updates. Scenix Semiconductor makes no representation
; or warranties with respect to the accuracy or use of these information,
; or infringement of patents arising from such use or otherwise.
;*****************************************************************************************
; 
; Filename:	EightUART_1_01.src
;
; Authors:	Vikram .S. Bidkar	
;		Software Engineer
;		Adamya Computing Technologies Pvt. Ltd.,
;
; Revision:	1.01
;
; Part:		SX28 - AB9932AB, SX52 - AB0004AC
; Freq:		50MHz
;
; Compiled using: SX-Key, SASM
;
; Date Written	: Aug 22, 2000
;
; Last Revised	: Sept 14, 2000
;
; Program Description:
;
;		This code implements 8 separate UART's in software for baud rates of 
;		1200,2400,4800,9600,19200, or 57600 bps depending on the rate selected 
;		for each UART by the user.  Three separate demonstration programs are 
;		supplied to aid the user in the familiarization process.  For more 
;		information on byteTransfer, stringTransfer, or fileTransfer, see 
;		page 14 of Application Note #40 available from www.scenix.com.      
;
; Interface Pins:
;		
;               rs232Rxpin1             ra.2	;UART1 receive input
;		rs232Txpin1             ra.3	;UART1 transmit output
;		rs232Rxpin2             rb.2	;UART2 receive input
;		rs232Txpin2             rb.3	;UART2 transmit output
;		rs232Rxpin3             rb.4	;UART3 receive input
;		rs232Txpin3             rb.5	;UART3 transmit output
;		rs232Rxpin4             rb.6	;UART4 receive input
;		rs232Txpin4             rb.7	;UART4 transmit output
;		rs232Rxpin5             rc.0	;UART5 receive input
;		rs232Txpin5             rc.1	;UART5 transmit output
;		rs232Rxpin6             rc.2	;UART6 receive input
;		rs232Txpin6             rc.3	;UART6 transmit output 
;		rs232Rxpin7             rc.4	;UART7 receive input
;		rs232Txpin7             rc.5	;UART7 transmit output
;		rs232Rxpin8             rc.6	;UART8 receive input
;		rs232Txpin8             rc.7	;UART8 transmit output
;
;
; Revision History:
;		1.01	Program description re-written.  Minor cosmetic changes implemented.
;			Jamie Aitken (09/14/00).	
;
;
;*******************************************************************************************
; Target SX
; Uncomment one of the following lines to choose the SX18AC,SX20AC,SX28AC,SX48BD, SX52BD. 
;*******************************************************************************************

;SX18_20
SX28AC
;SX48_52
	
;*******************************************************************************************
; Assembler Used
; Uncomment the following line if using the Parallax SX-Key assembler. SASM assembler
; enabled by default.
;*******************************************************************************************
;SX_Key

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 1 at the required baud rate
;*******************************************************************************************
;uart1baud1200		;baud rate of 1.2   Kbps
;uart1baud2400          ;baud rate of 2.4   Kbps
;uart1baud4800		;baud rate of 4.8   Kbps
uart1baud9600		;baud rate of 9.6   Kbps
;uart1baud1920		;baud rate of 19.2  Kbps   
;uart1baud5760		;baud rate of 57.6  Kbps 

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 2 at the required baud rate
;*******************************************************************************************
;uart2baud1200		;baud rate of 1.2   Kbps
;uart2baud2400          ;baud rate of 2.4   Kbps
;uart2baud4800		;baud rate of 4.8   Kbps
uart2baud9600		;baud rate of 9.6   Kbps
;uart2baud1920		;baud rate of 19.2  Kbps
;uart2baud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 3 at the required baud rate
;*******************************************************************************************
;uart3baud1200		;baud rate of 1.2   Kbps
;uart3baud2400          ;baud rate of 2.4   Kbps
;uart3baud4800		;baud rate of 4.8   Kbps
uart3baud9600		;baud rate of 9.6   Kbps
;uart3baud1920		;baud rate of 19.2  Kbps
;uart3baud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 4 at the required baud rate
;*******************************************************************************************
;uart4baud1200		;baud rate of 1.2   Kbps
;uart4baud2400          ;baud rate of 2.4   Kbps
;uart4baud4800		;baud rate of 4.8   Kbps
uart4baud9600		;baud rate of 9.6   Kbps
;uart4baud1920		;baud rate of 19.2  Kbps
;uart4aud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 5 at the required baud rate
;*******************************************************************************************
;uart5baud1200		;baud rate of 1.2   Kbps
;uart5baud2400          ;baud rate of 2.4   Kbps
;uart5baud4800		;baud rate of 4.8   Kbps
uart5baud9600		;baud rate of 9.6   Kbps
;uart5baud1920		;baud rate of 19.2  Kbps
;uart5aud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 6 at the required baud rate
;*******************************************************************************************
;uart6baud1200		;baud rate of 1.2   Kbps
;uart6baud2400          ;baud rate of 2.4   Kbps
;uart6baud4800		;baud rate of 4.8   Kbps
uart6baud9600		;baud rate of 9.6   Kbps
;uart6baud1920		;baud rate of 19.2  Kbps
;uart6aud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 7 at the required baud rate
;*******************************************************************************************
;uart7baud1200		;baud rate of 1.2   Kbps
;uart7baud2400          ;baud rate of 2.4   Kbps
;uart7baud4800		;baud rate of 4.8   Kbps
uart7baud9600		;baud rate of 9.6   Kbps
;uart7baud1920		;baud rate of 19.2  Kbps
;uart7aud5760		;baud rate of 57.6  Kbps

;*******************************************************************************************
; Uncomment one of the following to run the uart vp for UART 8 at the required baud rate
;*******************************************************************************************
;uart8baud1200		;baud rate of 1.2   Kbps
;uart8baud2400          ;baud rate of 2.4   Kbps
;uart8baud4800		;baud rate of 4.8   Kbps
uart8baud9600		;baud rate of 9.6   Kbps
;uart8baud1920		;baud rate of 19.2  Kbps
;uart8aud5760		;baud rate of 57.6  Kbps 

;*******************************************************************************************
; If BYTE is to be send on the UART, then uncomment the following
;******************************************************************************************* 
;byteTransfer 

;*******************************************************************************************
;If STRING is to be send on the UART, then uncomment the following
;*******************************************************************************************
stringTransfer

;*******************************************************************************************
;If FILE is to be transfard from one UART to another UART then uncomment the following
;*******************************************************************************************
;fileTransfer
;*******************************************************************************************


;*******************************************************************************************
;				Assembler directives
;	
;	High speed external osc, turbo mode, 8-level stack, and extended option reg.
;	SX18/20/28 - 4 pages of program memory and 8 banks of RAM enabled by default.
;	SX48/52 - 8 pages of program memory and 16 banks of RAM enabled by default. 
;*******************************************************************************************

IFDEF SX_Key 					;SX-Key Directives

  IFDEF SX18_20					;SX18AC or SX20AC device directives for SX-Key
	device	SX18L,oschs2,turbo,stackx_optionx
  ENDIF

  IFDEF SX28AC					;SX28AC device directives for SX-Key		
	device	SX28L,oschs2,turbo,stackx_optionx
  ENDIF


  IFDEF SX48_52					;SX48/52/BD device directives for SX-Key
	device	oschs2
  ENDIF
	freq	50_000_000

ELSE	  					;SASM Directives
  
  IFDEF SX18_20					;SX18AC or SX20AC device directives for SASM
	device	SX18,oschs2,turbo,stackx,optionx
  ENDIF

  IFDEF SX28AC					;SX28AC device directives for SASM
	device	SX28,oschs2,turbo,stackx,optionx
  ENDIF
  
  IFDEF SX48_52					;SX48BD or SX52BD device directives for SASM
	device	SX52,oschs2  
  ENDIF

ENDIF
		id	'8UART VP'		;
		reset	resetEntry		; set reset vector

	;*******************************************************************************************
	;--------------------------------------Macro's--------------------------------------
	; Macro: _bank
	; Sets the bank appropriately for all revisions of SX.
	;
	; This is required since the bank instruction has only a 3-bit operand, it cannot be used to 
	; access all 16 banks of the SX48/52.  FSR.7 (SX48/52bd production release) needs to be set 
	; appropriately, depending on the bank address being accessed. This macro fixes this.
	;
	; So, instead of using the bank instruction to switch between banks, use _bank instead.
	;*******************************************************************************************

_bank	macro	1
  noexpand
	bank	\1
	IFDEF SX48_52
	   IF \1 & %10000000			;SX48BD and SX52BD (production release) bank instruction 
  expand
		setb	fsr.7			;modifies FSR bits 4,5 and 6. FSR.7 needs to be set by software.
  noexpand
    	   ELSE
  expand
		clrb	fsr.7
  noexpand
          ENDIF
	ENDIF
 endm

	;*********************************************************************************************
	; Macro: _mode
	; Sets the MODE register appropriately for all revisions of SX.
	;
	; This is required since the MODE (or MOV M,#) instruction has only a 4-bit operand. 
	; The SX18/20/28AC use only 4 bits of the MODE register, however the SX48/52BD have 
	; the added ability of reading or writing some of the MODE registers, and therefore use
	; 5-bits of the MODE register. The  MOV M,W instruction modifies all 8-bits of the 
	; MODE register, so this instruction must be used on the SX48/52BD to make sure the MODE
	; register is written with the correct value. This macro fixes this.
	;
	; So, instead of using the MODE or MOV M,# instructions to load the M register, use
	;  _mode instead.
	;********************************************************************************************* 

_mode	macro	1

  noexpand
	IFDEF SX48_52
  expand
		mov	w,#\1           	;loads the M register correctly for the SX48BD and SX52BD
		mov	m,w
  noexpand
	ELSE
  expand
		mov	m,#\1    		;loads the M register correctly for the SX18AC, SX20AC
						;and SX28AC
  noexpand
	ENDIF

endm


	;*********************************************************************************************
        ; INCP/DECP macros for incrementing/decrementing pointers to RAM
        ; used to compensate for incompatibilities between SX28AC and SX52BD
	;*********************************************************************************************

 INCP macro 1					; Increments a pointer to RAM
		inc    \1
	IFNDEF	SX48_52
		setb  \1.4			; If SX18 or SX28AC,keep bit 4 of the pointer = 1
	ENDIF					; to jump from $1f to $30,etc
endm

DECP macro 1					; Decrements a pointer to RAM
	IFDEF	SX48_52
		dec    \1
	ELSE
		clrb   \1.4			; If SX18 or SX28AC, forces rollover to next bank
		dec    \1			; if it rolls over. (skips banks with bit 4 = 0)
		setb   \1.4             	; Eg: $30 ---> $20 ---> $1f ---> $1f 
	ENDIF                           	; AND: $31 ---> $21 ---> $20 ---> $30
endm

	;*********************************************************************************************
        ; Error generating macros
        ; Used to generate an error message if the label is intentionally moved into the second page .
        ; Use for lookup tables.
	;*********************************************************************************************

tablestart	macro	0			; Generates an error message if code that MUST be in
						; the first half of a page is moved into the second half
	if $ & $100
		ERROR      'Must be located in the first half of a page.'
	endif
endm

tableEnd	macro	0			; Generates an error message if code that MUST be in
						; the first half of a page is moved into the second half
	if $ & $100
		ERROR      'Must be located in the first half of a page.'
	endif
endm

;*****************************************************************************************
;----------------------------------- Memory Organization ---------------------------------
;*****************************************************************************************


;*****************************************************************************************
;------------------------------ Data Memory address definitions --------------------------
; These definitions ensure the proper address is used for banks 0 - 7 for 2K SX devices
; (SX18/20/28) and 4K SX devices (SX48/52). 
;*****************************************************************************************

IFDEF SX48_52

global_org	=	$0A
bank0_org	=	$00
bank1_org	=	$10
bank2_org	=	$20
bank3_org	=	$30
bank4_org	=	$40
bank5_org	=	$50
bank6_org	=	$60
bank7_org	=	$70

ELSE

global_org	=	$08
bank0_org	=	$10
bank1_org	=	$30
bank2_org	=	$50
bank3_org	=	$70
bank4_org	=	$90
bank5_org	=	$B0
bank6_org	=	$D0
bank7_org	=	$F0

ENDIF

;*****************************************************************************************
;-------------------------------- Global Register definitions ----------------------------
; NOTE: Global data memory starts at $0A on SX48/52 and $08 on SX18/20/28.
;*****************************************************************************************

	org     global_org

flags0		equ	global_org + 0		; stores bit-wise operators like flags 
						; and function-enabling bits (semaphores)   
;-----------------------------VP: RS232 Receive-------------------------------------------     
	rs232Tx1Flag  	equ     flags0.0	;indicates the Uart1 tx
	rs232Tx2Flag  	equ     flags0.1	;indicates the Uart2 tx
	rs232Tx3Flag  	equ     flags0.2	;indicates the Uart3 tx
	rs232Tx4Flag  	equ     flags0.3	;indicates the Uart4 tx
	rs232Tx5Flag  	equ     flags0.4	;indicates the Uart5 tx
	rs232Tx6Flag  	equ     flags0.5	;indicates the Uart6 tx
	rs232Tx7Flag  	equ     flags0.6	;indicates the Uart7 tx 
	rs232Tx8Flag  	equ     flags0.7	;indicates the Uart8 tx


flags1		equ	global_org + 1		; stores bit-wise operators like flags	
                                                ; and function-enabling bits (semaphores)			
	rs232RxFlag1	equ	flags1.0        ;indicates the reception of a bit from the UART1
	rs232RxFlag2	equ	flags1.1        ;indicates the reception of a bit from the UART2
	rs232RxFlag3	equ	flags1.2        ;indicates the reception of a bit from the UART3
	rs232RxFlag4	equ	flags1.3        ;indicates the reception of a bit from the UART4
	rs232RxFlag5	equ	flags1.4        ;indicates the reception of a bit from the UART5
	rs232RxFlag6	equ	flags1.5        ;indicates the reception of a bit from the UART6
	rs232RxFlag7	equ	flags1.6        ;indicates the reception of a bit from the UART7
	rs232RxFlag8	equ	flags1.7        ;indicates the reception of a bit from the UART8



isrTemp0	equ	global_org + 2		; Interrupt Service Routine's temp register.  
						; Don't use this register in the mainline.
localTemp0	equ	global_org + 3		; temporary storage register
						; Used by first level of nesting
						; Never guaranteed to maintain data
localTemp1	equ	global_org + 4		; temporary storage register	
						; Used by second level of nesting
						; or when a routine needs more than one 
						; temporary global register.	
localTemp2	equ	global_org + 5		; temporary storage register
						; Used by third level of nesting or by
						; main loop routines that need a loop 
						; counter, etc.


	;*********************************************************************************
        ;-------------------------- RAM Bank Register definitions ------------------------
	;*********************************************************************************
	;*********************************************************************************

	;*********************************************************************************
        ; Bank 0
	;*********************************************************************************

		org     bank0_org

bank0			=	$


	;*********************************************************************************
	; Bank 1
	;*********************************************************************************

		org     bank1_org

bank1			=	$
rs232TxBank1234		=       $		;UART bank
rs232Txhigh1		ds      1		;hi byte to transmit for UART1
rs232Txlow1		ds      1		;low byte to transmit for UART1
rs232Txcount1		ds      1		;number of bits sent for UART1
rs232Txdivide1		ds      1		;xmit timing (/4) counter for UART1
rs232Txhigh2		ds      1		;hi byte to transmit for UART2
rs232Txlow2		ds      1		;low byte to transmit for UART2
rs232Txcount2		ds      1		;number of bits sent for UART2
rs232Txdivide2		ds      1		;xmit timing (/4) counter for UART2
rs232Txhigh3		ds      1		;hi byte to transmit for UART3
rs232Txlow3		ds      1		;low byte to transmit for UART3
rs232Txcount3		ds      1		;number of bits sent for UART3
rs232Txdivide3		ds      1		;xmit timing (/4) counter for UART3
rs232Txhigh4		ds      1		;hi byte to transmit for UART4
rs232Txlow4		ds      1		;low byte to transmit for UART4
rs232Txcount4		ds      1		;number of bits sent for UART4
rs232Txdivide4		ds      1		;xmit timing (/4) counter for UART4


        ;*********************************************************************************
	; Bank 2
	;*********************************************************************************

		org     bank2_org

bank2			=	$
rs232TxBank5678		=       $		;UART bank
rs232Txhigh5		ds      1		;hi byte to transmit for UART5
rs232Txlow5		ds      1		;low byte to transmit for UART5
rs232Txcount5		ds      1		;number of bits sent for UART5
rs232Txdivide5		ds      1		;xmit timing (/4) counter for UART5
rs232Txhigh6		ds      1		;hi byte to transmit for UART6
rs232Txlow6		ds      1		;low byte to transmit for UART6
rs232Txcount6		ds      1		;number of bits sent  for UART6
rs232Txdivide6		ds      1		;xmit timing (/4) counter for UART6
rs232Txhigh7		ds      1		;hi byte to transmit for UART7
rs232Txlow7		ds      1		;low byte to transmit for UART7
rs232Txcount7		ds      1		;number of bits sent for UART7
rs232Txdivide7		ds      1		;xmit timing (/4) counter for UART7
rs232Txhigh8		ds      1		;hi byte to transmit for UART8
rs232Txlow8		ds      1		;low byte to transmit for UART8
rs232Txcount8		ds      1		;number of bits sent for UART8
rs232Txdivide8		ds      1		;xmit timing (/4) counter for UART8
      

        ;*********************************************************************************
	; Bank 3
	;*********************************************************************************

		org     bank3_org

bank3			=	$
rs232RxBank1234		=	$
rs232Rxcount1		ds      1		;number of bits received for UART1
rs232Rxdivide1		ds      1		;receive timing counter for UART1
rs232Rxbyte1		ds      1		;buffer for incoming byte for UART1
rs232byte1		ds	1		;used by serial routines for UART1
rs232Rxcount2		ds      1		;number of bits received for UART2
rs232Rxdivide2		ds      1		;receive timing counter for UART2
rs232Rxbyte2		ds      1		;buffer for incoming byte for UART2
rs232byte2		ds	1		;used by serial routines for UART2
rs232Rxcount3		ds      1		;number of bits received for UART3
rs232Rxdivide3		ds      1		;receive timing counter for UART3
rs232Rxbyte3		ds      1		;buffer for incoming byte for UART3
rs232byte3		ds	1		;used by serial routines for UART3
rs232Rxcount4		ds      1		;number of bits received for UART4
rs232Rxdivide4		ds      1		;receive timing counter for UART4
rs232Rxbyte4		ds      1		;buffer for incoming byte for UART4
rs232byte4		ds	1		;used by serial routines for UART4


        ;*********************************************************************************
	; Bank 4
	;*********************************************************************************

		org     bank4_org

bank4			=	$
rs232RxBank5678		=	$
rs232Rxcount5		ds      1		;number of bits received for UART5
rs232Rxdivide5		ds      1		;receive timing counter for UART5
rs232Rxbyte5		ds      1		;buffer for incoming byte for UART5
rs232byte5		ds	1		;used by serial routines for UART5
rs232Rxcount6		ds      1		;number of bits received for UART6
rs232Rxdivide6		ds      1		;receive timing counter for UART6
rs232Rxbyte6		ds      1		;buffer for incoming byte for UART6
rs232byte6		ds	1		;used by serial routines for UART6
rs232Rxcount7		ds      1		;number of bits received for UART7
rs232Rxdivide7		ds      1		;receive timing counter for UART7
rs232Rxbyte7		ds      1		;buffer for incoming byte for UART7
rs232byte7		ds	1		;used by serial routines for UART7
rs232Rxcount8		ds      1		;number of bits received for UART8
rs232Rxdivide8		ds      1		;receive timing counter for UART8
rs232Rxbyte8		ds      1		;buffer for incoming byte for UART8
rs232byte8		ds	1		;used by serial routines for UART8


	;*********************************************************************************
	; Bank5
	;*********************************************************************************

		org     bank5_org

bank5		        =	$     
MultiplexBank		=	$
isrMultiplex 	  	ds      1


	;*********************************************************************************
        ; Bank 6
	;*********************************************************************************

		org     bank6_org

bank6	        	=	$ 


	;*********************************************************************************
	; Bank 7
	;*********************************************************************************

		org     bank7_org

bank7		        =	$  

        IFDEF SX48_52

	;*********************************************************************************
	; Bank 8
	;*********************************************************************************

		org     $80

bank8		        =	$   


	;*********************************************************************************
	; Bank 9
	;*********************************************************************************

		org	$90			;bank 9 address on SX52

bank9		=	$       
 

	;*********************************************************************************
	; Bank A
	;*********************************************************************************

		org	$A0			;bank A address on SX52

bankA		=	$

	;*********************************************************************************
	; Bank B
	;*********************************************************************************

		org	$B0			;bank B address on SX52

bankB		=	$

	;*********************************************************************************
	; Bank C
	;*********************************************************************************

		org	$C0			;bank C address on SX52

bankC		=	$

	;*********************************************************************************
	; Bank D
	;*********************************************************************************

		org	$D0			;bank D address on SX52

bankD		=	$


	;*********************************************************************************
	; Bank E
	;*********************************************************************************

		org	$E0			;bank E address on SX52

bankE		=	$

	;*********************************************************************************
	; Bank F
	;*********************************************************************************

		org	$F0			;bank F address on SX52

bankF		=	$


ENDIF

;*****************************************************************************************
;---------------------------------- Port Assignment--------------------------------------
;*****************************************************************************************

RA_latch	equ	%00001000		;SX18/20/28/48/52 port A latch init
RA_DDIR		equ	%00000100		;SX18/20/28/48/52 port A DDIR value
RA_LVL		equ	%00000000		;SX18/20/28/48/52 port A LVL value
RA_PLP		equ	%00001100		;SX18/20/28/48/52 port A PLP value

RB_latch	equ	%10101000		;SX18/20/28/48/52 port B latch init;intial value affter reset
RB_DDIR		equ	%01010100		;SX18/20/28/48/52 port B DDIR value;0=Output,1=Input
RB_ST		equ	%11111111		;SX18/20/28/48/52 port B ST value;0=Enable,1=Disable
RB_LVL		equ	%00000000		;SX18/20/28/48/52 port B LVL value;0=CMOS,1=TTL
RB_PLP		equ	%11111100		;SX18/20/28/48/52 port B PLP value;0=Enable,1=Disable


RC_latch	equ	%10101010		;SX18/20/28/48/52 port C latch init;intial value affter reset
RC_DDIR		equ	%01010101		;SX18/20/28/48/52 port C DDIR value;0=Output,1=Input
RC_ST		equ	%11111111		;SX18/20/28/48/52 port C ST value;0=Enable,1=Disable
RC_LVL		equ	%00000000		;SX18/20/28/48/52 port C LVL value;0=CMOS,1=TTL
RC_PLP		equ	%11111111		;SX18/20/28/48/52 port C PLP value;0=Enable,1=Disable

IFDEF SX48_52		

RD_latch	equ	%00000000		;SX48/52 port D latch init;intial value affter reset
RD_DDIR		equ	%11111111		;SX48/52 port D DDIR value;0=Output,1=Input
RD_ST		equ	%11111111		;SX48/52 port D ST value;0=Enable,1=Disable
RD_LVL		equ	%00000000		;SX48/52 port D LVL value;0=CMOS,1=TTL
RD_PLP		equ	%00000000		;SX48/52 port D PLP value;0=Enable,1=Disable

RE_latch	equ	%00000000		;SX48/52 port E latch init;intial value affter reset
RE_DDIR		equ	%11111111		;SX48/52 port E DDIR value;0=Output,1=Input
RE_ST		equ	%11111111		;SX48/52 port E ST value;0=Enable,1=Disable
RE_LVL		equ	%00000000		;SX48/52 port E LVL value;0=CMOS,1=TTL
RE_PLP		equ	%00000000		;SX48/52 port E PLP value;0=Enable,1=Disable

ENDIF

;*****************************************************************************************
;--------------------------------- Pin Definitions ---------------------------------------
;*****************************************************************************************

rs232Rxpin1   	equ     ra.2			;UART1 receive input
rs232Txpin1    	equ     ra.3			;UART1 transmit output

rs232Rxpin2     equ     rb.2			;UART2 receive input
rs232Txpin2     equ     rb.3			;UART2 transmit output

rs232Rxpin3     equ     rb.4			;UART3 receive input
rs232Txpin3     equ     rb.5			;UART3 transmit output

rs232Rxpin4     equ     rb.6			;UART4 receive input
rs232Txpin4     equ     rb.7			;UART4 transmit output

rs232Rxpin5     equ     rc.0			;UART5 receive input
rs232Txpin5     equ     rc.1			;UART5 transmit output

rs232Rxpin6     equ     rc.2			;UART6 receive input
rs232Txpin6     equ     rc.3			;UART6 transmit output 

rs232Rxpin7     equ     rc.4			;UART7 receive input
rs232Txpin7     equ     rc.5			;UART7 transmit output

rs232Rxpin8     equ     rc.6			;UART8 receive input
rs232Txpin8     equ     rc.7			;UART8 transmit output


;*****************************************************************************************
;---------------------------------- Program constants ------------------------------------
;*****************************************************************************************

_enter		equ	13			; ASCII value for carridge return
_line_feed	equ	10			; ASCII value for a line feed

;*****************************************************************************************
;	UART Constants values
;*****************************************************************************************
intPeriod		= 217                   ;# of cycles between 2 continuous samples

UARTfs			= 230400                ;UART's basic frequency
	
Num			= 4	                ;This means that each individual thread 
						;containing a UART VP will execute itself 
						;every fourth interupt. 
;*****************************************************************************************				
;--------------------------------------- UART1 -------------------------------------------
;*****************************************************************************************

IFDEF uart1baud1200
	UARTBaud1	= 1200 
ENDIF
	
IFDEF uart1baud2400
	UARTBaud1	= 2400    
ENDIF
	
IFDEF uart1baud4800
	UARTBaud1	= 4800  
ENDIF
	
IFDEF uart1baud9600
	UARTBaud1	= 9600  
ENDIF
	
IFDEF uart1baud1920
	UARTBaud1	= 19200 
ENDIF  

IFDEF uart1baud5760
	UARTBaud1	= 57600 
ENDIF                       

	UARTDivide1	= (UARTfs/(UARTBaud1*Num)) 
        UARTStDelay1 	= UARTDivide1 +(UARTDivide1/2)+1  


;*****************************************************************************************
;--------------------------------------- UART2 -------------------------------------------
;*****************************************************************************************

IFDEF uart2baud1200
	UARTBaud2	= 1200 
ENDIF
	
IFDEF uart2baud2400
	UARTBaud2	= 2400    
ENDIF
	
IFDEF uart2baud4800
	UARTBaud2	= 4800  
ENDIF
	
IFDEF uart2baud9600
	UARTBaud2	= 9600  
ENDIF
	
IFDEF uart2baud1920
	UARTBaud2	= 19200 
ENDIF 

IFDEF uart2baud5760
	UARTBaud2	= 57600 
ENDIF                       

	UARTDivide2	= (UARTfs/(UARTBaud2*Num)) 
        UARTStDelay2 	= UARTDivide2 +(UARTDivide2/2)+1  


;*****************************************************************************************
;--------------------------------------- UART3 -------------------------------------------
;*****************************************************************************************

IFDEF uart3baud1200
	UARTBaud3	= 1200 
ENDIF
	
IFDEF uart3baud2400
	UARTBaud3	= 2400    
ENDIF
	
IFDEF uart3baud4800
	UARTBaud3	= 4800  
ENDIF
	
IFDEF uart3baud9600
	UARTBaud3	= 9600  
ENDIF
	
IFDEF uart3baud1920
	UARTBaud3	= 19200 
ENDIF 

IFDEF uart3baud5760
	UARTBaud3	= 57600 
ENDIF                       

	UARTDivide3	= (UARTfs/(UARTBaud3*Num)) 
        UARTStDelay3 	= UARTDivide3 +(UARTDivide3/2)+1 
        
;*****************************************************************************************
;--------------------------------------- UART4 -------------------------------------------
;*****************************************************************************************

IFDEF uart4baud1200
	UARTBaud4	= 1200 
ENDIF
	
IFDEF uart4baud2400
	UARTBaud4	= 2400    
ENDIF
	
IFDEF uart4baud4800
	UARTBaud4	= 4800  
ENDIF
	
IFDEF uart4baud9600
	UARTBaud4	= 9600  
ENDIF
	
IFDEF uart4baud1920
	UARTBaud4	= 19200 
ENDIF 

IFDEF uart4baud5760
	UARTBaud4	= 57600 
ENDIF                       

	UARTDivide4	= (UARTfs/(UARTBaud4*Num)) 
        UARTStDelay4 	= UARTDivide4 +(UARTDivide4/2)+1
        
;*****************************************************************************************
;--------------------------------------- UART5 -------------------------------------------
;*****************************************************************************************

IFDEF uart5baud1200
	UARTBaud5	= 1200 
ENDIF
	
IFDEF uart5baud2400
	UARTBaud5       = 2400
ENDIF
		
IFDEF uart5baud4800
	UARTBaud5	= 4800  
ENDIF
	
IFDEF uart5baud9600
	UARTBaud5	= 9600  
ENDIF
	
IFDEF uart5baud1920
	UARTBaud5	= 19200 
ENDIF 

IFDEF uart5baud5760
	UARTBaud5	= 57600 
ENDIF                       

	UARTDivide5	= (UARTfs/(UARTBaud5*Num)) 
        UARTStDelay5 	= UARTDivide5 +(UARTDivide5/2)+1                  
        
;*****************************************************************************************
;--------------------------------------- UART6 -------------------------------------------
;*****************************************************************************************

IFDEF uart6baud1200
	UARTBaud6	= 1200 
ENDIF
	
IFDEF uart6baud2400
	UARTBaud6	= 2400    
ENDIF
	
IFDEF uart6baud4800
	UARTBaud6	= 4800  
ENDIF
	
IFDEF uart6baud9600
	UARTBaud6	= 9600  
ENDIF
	
IFDEF uart6baud1920
	UARTBaud6	= 19200 
ENDIF 

IFDEF uart6baud5760
	UARTBaud6	= 57600 
ENDIF                       

	UARTDivide6	= (UARTfs/(UARTBaud6*Num)) 
        UARTStDelay6 	= UARTDivide6 +(UARTDivide6/2)+1         
        
;*****************************************************************************************
;--------------------------------------- UART7 -------------------------------------------
;*****************************************************************************************

IFDEF uart7baud1200
	UARTBaud7	= 1200 
ENDIF
	
IFDEF uart7baud2400
	UARTBaud7	= 2400    
ENDIF
	
IFDEF uart7baud4800
	UARTBaud7	= 4800  
ENDIF
	
IFDEF uart7baud9600
	UARTBaud7	= 9600  
ENDIF
	
IFDEF uart7baud1920
	UARTBaud7	= 19200 
ENDIF 

IFDEF uart7baud5760
	UARTBaud7	= 57600 
ENDIF                       

	UARTDivide7	= (UARTfs/(UARTBaud7*Num)) 
        UARTStDelay7 	= UARTDivide7 +(UARTDivide7/2)+1         
  

;*****************************************************************************************
;--------------------------------------- UART8 -------------------------------------------
;*****************************************************************************************

IFDEF uart8baud1200
	UARTBaud8	= 1200 
ENDIF
	
IFDEF uart8baud2400
	UARTBaud8	= 2400    
ENDIF
	
IFDEF uart8baud4800
	UARTBaud8	= 4800  
ENDIF
	
IFDEF uart8baud9600
	UARTBaud8	= 9600  
ENDIF
	
IFDEF uart8baud1920
	UARTBaud8	= 19200 
ENDIF 

IFDEF uart8baud5760
	UARTBaud8	= 57600 
ENDIF                       

	UARTDivide8	= (UARTfs/(UARTBaud8*Num)) 
        UARTStDelay8 	= UARTDivide8+(UARTDivide8/2)+1

;*****************************************************************************************


IFDEF SX48_52
;*****************************************************************************************
; SX48BD/52BD Mode addresses
; *On SX48BD/52BD, most registers addressed via mode are read and write, with the
; exception of CMP and WKPND which do an exchange with W.
;*****************************************************************************************
;------------------------------- Timer (read) addresses ----------------------------------

TCPL_R		equ	$00			;Read Timer Capture register low byte
TCPH_R		equ	$01			;Read Timer Capture register high byte
TR2CML_R	equ	$02			;Read Timer R2 low byte
TR2CMH_R	equ	$03			;Read Timer R2 high byte
TR1CML_R	equ	$04			;Read Timer R1 low byte
TR1CMH_R	equ	$05 			;Read Timer R1 high byte
TCNTB_R		equ	$06			;Read Timer control register B
TCNTA_R		equ	$07			;Read Timer control register A

;---------------------------------- Exchange addresses -----------------------------------
CMP		equ	$08			;Exchange Comparator enable/status register with W
WKPND		equ	$09			;Exchange MIWU/RB Interrupts pending with W

;--------------------------------- port setup (read) addresses----------------------------
WKED_R		equ	$0A			;Read MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_R		equ	$0B			;Read MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_R		equ	$0C			;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_R		equ	$0D			;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_R		equ	$0E			;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_R		equ	$0F			;Read Port Direction

;--------------------------------- Timer (write) addresses -------------------------------
CLR_TMR		equ	$10			;Resets 16-bit Timer
TR2CML_W	equ	$12			;Write Timer R2 low byte
TR2CMH_W	equ	$13			;Write Timer R2 high byte
TR1CML_W	equ	$14			;Write Timer R1 low byte
TR1CMH_W	equ	$15 			;Write Timer R1 high byte
TCNTB_W		equ	$16			;Write Timer control register B
TCNTA_W		equ	$17			;Write Timer control register A

;------------------------------- Port setup (write) addresses ----------------------------
WKED_W		equ	$1A			;Write MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_W		equ	$1B			;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$1C			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$1D			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$1E			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$1F			;Write Port Direction

ELSE
;*****************************************************************************************
; SX18AC/20AC/28AC Mode addresses
; *On SX18/20/28, all registers addressed via mode are write only, with the exception of
; CMP and WKPND which do an exchange with W.
;*****************************************************************************************
;------------------------------------ Exchange addresses ---------------------------------
CMP		equ	$08		        ;Exchange Comparator enable/status register with W
WKPND		equ	$09			;Exchange MIWU/RB Interrupts pending with W

;--------------------------------- Port setup (read) addresses ---------------------------
WKED_W		equ	$0A			;Write MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_W		equ	$0B			;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$0C			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$0D			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$0E			;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$0F			;Write Port Direction

ENDIF


;*****************************************************************************************
;---------------------------------- Program memory ORG defines ---------------------------
;*****************************************************************************************

INTERRUPT_ORG		equ	$0		; Interrupt must always start at location zero
RESETENTRY_ORG		equ	$1FB		; The program will jump here on reset
SUBROUTINES_ORG		equ	$200		; The subroutines are in this location
STRINGS_ORG		equ	$300		; The strings are in the location $300
PAGE3_ORG		equ	$400		; Page 3 is empty
MAINPROGRAM_ORG		equ	$600		; The main program is in the lastpage of program memory


;*****************************************************************************************
		org	INTERRUPT_ORG        	; First location in program memory.
;*****************************************************************************************


;*****************************************************************************************
;--------------------------------- Interrupt Service Routine -----------------------------
; Note 1: The interrupt code must always originate at address $0.
;	  Interrupt Frequency = (Cycle Frequency / -(retiw value))  
;	  For example: With a retiw value of -217 and an oscillator frequency 
;	  of 50MHz, this code runs every 4.32us.
; Note 2: Mode Register 'M' is not saved in SX 28 but saved in SX 52 when an Interrupt
;	  occurs. If the code is to run on a SX 28 and 'M' register is used in the ISR, 
;	  then the 'M' register has to be saved at the Start of ISR and restored at the 
;	  End of ISR.
;*****************************************************************************************

		org     $0
interrupt					;3
	IFDEF SX_28AC
		mov	w,m			; Save the m register.
		mov	isrTemp0,w		;
	ENDIF

;*****************************************************************************************
;-------------------------------------- VP:VP Multitasker --------------------------------
; Virtual Peripheral Multitasker : up to 24 individual threads, each running at the 
; (interrupt rate/4). Change the below:
;Input variable(s): isrmultiplex: variable used to choose threads
;Output variable(s): None,executes the next thread
;Variable(s) affected: isrmultiplex
;Flag(s) affected: None
;Program Cycles: 9 cycles (turbo mode)
;*****************************************************************************************

                 _bank          Multiplexbank	;  
                
                 inc            isrMultiplex    ; toggle interrupt rate
                 mov            w,isrMultiplex  ; 
               
;*****************************************************************************************
; The code between the tableStart and tableEnd statements MUST be completely within the first
; half of a page. The routines it is jumping to must be in the same page as this table.
;*****************************************************************************************

         tableStart                             ; Start all tables with this macro
                                                ;    
                jmp            pc+w             ;
                jmp            isrThread1       ;
                jmp            isrThread2       ;
                jmp            isrThread3       ;  
                jmp            isrThread4       ; 
                  
         tableEnd                               ; End all tables with this macro.   

;*****************************************************************************************
;VP: VP Multitasker
; ISR TASKS
;*****************************************************************************************
isrThread1                                          ; Serviced at ISR rate/4     
                                                                               
;--------------------------------------- VP: RS232 Transmit ------------------------------
rs232Transmit1    
               _bank	rs232TxBank1234		; switch to serial register bank   
	        sb      rs232Tx1Flag            ; Is data there for UART1,
	        jmp     :rs232TxOut1		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide1		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut1		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide1		; If Divide val becomes 0 & enters the Tx routine, then again load the
		mov	rs232TxDivide1,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount1		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut1		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh1		; right shift Tx data
		rr      rs232TxLow1		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount1		; decrement bit counter
		snb	rs232TxLow1.6		; if the bit in viewing window is hi
		clrb	rs232TxPin1		; Then make transmit pin lo  
		sb	rs232TxLow1.6		; if the bit in viewing window is lo  
		setb	rs232TxPin1		; Then make transmit pin hi  
IFNDEF          stringTransfer                     	; If not stringTransfer
	        test    rs232TxCount1           ; test count
		snz                             ; if zero
		clrb    rs232Tx1Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut1    

;*****************************************************************************************
rs232Receive1     
      		sb	rs232RxPin1		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin1		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank1234  
		test    rs232RxCount1           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount1,w		; it is, so load bit count
		mov     w,#UARTStDelay1		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide1,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide1		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut1		; then don't go into Rx routine 
		mov	w,#UARTDivide1		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide1,w	;  
		dec     rs232RxCount1           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte1            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag1            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte 
:rs232RxOut1

;*****************************************************************************************
;------------------------------------------ UART2 ----------------------------------------
;*****************************************************************************************
rs232Transmit2   
             	_bank	rs232TxBank1234		; switch to serial register bank   
	        sb      rs232Tx2Flag            ; Is data there for UART2, 
	        jmp     :rs232TxOut2		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide2		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut2		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide2		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide2,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount2		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut2		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh2		; right shift Tx data
		rr      rs232TxLow2		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount2		; decrement bit counter
		snb	rs232TxLow2.6		; if the bit in viewing window is hi
		clrb	rs232TxPin2		; Then make transmit pin lo  
		sb	rs232TxLow2.6		; if the bit in viewing window is lo  
		setb	rs232TxPin2		; Then make transmit pin hi  
IFNDEF          stringTransfer                  ; If not stringTransfer
	        test    rs232TxCount2           ; test count
		snz                             ; if zero
		clrb    rs232Tx2Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut2

;*****************************************************************************************
rs232Receive2     
	        sb	rs232RxPin2		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin2		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank1234  
		test    rs232RxCount2           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount2,w		; it is, so load bit count
		mov     w,#UARTStDelay2		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide2,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide2		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut2		; then don't go into Rx routine 
		mov	w,#UARTDivide2		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide2,w	;  
		dec     rs232RxCount2           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte2            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag2            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte 
:rs232RxOut2
               jmp	isrOut			; End of isrThread1

;*****************************************************************************************
isrThread2                      ;UART3&4
;*****************************************************************************************

rs232Transmit3    
               _bank	rs232TxBank1234		; switch to serial register bank   
	        sb      rs232Tx3Flag            ; Is data there for UART3,
	        jmp     :rs232TxOut3		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide3		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut3		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide3		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide3,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount3		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut3		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh3		; right shift Tx data
		rr      rs232TxLow3		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount3		; decrement bit counter
		snb	rs232TxLow3.6		; if the bit in viewing window is hi
		clrb	rs232TxPin3		; Then make transmit pin lo  
		sb	rs232TxLow3.6		; if the bit in viewing window is lo  
		setb	rs232TxPin3		; Then make transmit pin hi  
IFNDEF          stringTransfer                     	; If not stringTransfer
	        test    rs232TxCount3           ; test count
		snz                             ; if zero
		clrb    rs232Tx3Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut3    

;*****************************************************************************************
rs232Receive3     
      		sb	rs232RxPin3		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin3		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank1234  
		test    rs232RxCount3           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount3,w		; it is, so load bit count
		mov     w,#UARTStDelay3		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide3,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide3		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut3		; then don't go into Rx routine 
		mov	w,#UARTDivide3		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide3,w	;  
		dec     rs232RxCount3           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte3            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag3            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte              
:rs232RxOut3

;*****************************************************************************************
;---------------------------------------- UART4 ------------------------------------------
;*****************************************************************************************
rs232Transmit4   
             	_bank	rs232TxBank1234		; switch to serial register bank   
	        sb      rs232Tx4Flag            ; Is data there for UART4,
	        jmp     :rs232TxOut4		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide4		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut4		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide4		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide4,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount4		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut4		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh4		; right shift Tx data
		rr      rs232TxLow4		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount4		; decrement bit counter
		snb	rs232TxLow4.6		; if the bit in viewing window is hi
		clrb	rs232TxPin4		; Then make transmit pin lo  
		sb	rs232TxLow4.6		; if the bit in viewing window is lo  
		setb	rs232TxPin4		; Then make transmit pin hi  
IFNDEF          stringTransfer                  ; If not stringTransfer
	        test    rs232TxCount4           ; test count
		snz                             ; if zero
		clrb    rs232Tx4Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut4  

;*****************************************************************************************
rs232Receive4     
	        sb	rs232RxPin4		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin4		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank1234  
		test    rs232RxCount4           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount4,w		; it is, so load bit count
		mov     w,#UARTStDelay4		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide4,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide4		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut4		; then don't go into Rx routine 
		mov	w,#UARTDivide4		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide4,w	;  
		dec     rs232RxCount4           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte4            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
        	setb    rs232RxFlag4            ; if zero set the Rx flag to indicate the 
	                        		; complete reception of the byte 
:rs232RxOut4		                        ;
		jmp	isrOut                  ; End of isrThread2

;*****************************************************************************************
isrThread3                      ;UART5&6
;*****************************************************************************************
rs232Transmit5    
               _bank	rs232TxBank5678		; switch to serial register bank   
	        sb      rs232Tx5Flag            ; Is data there for UART5,
	        jmp     :rs232TxOut5		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide5		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut5		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide5		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide5,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount5		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut5		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh5		; right shift Tx data
		rr      rs232TxLow5		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount5		; decrement bit counter
		snb	rs232TxLow5.6		; if the bit in viewing window is hi
		clrb	rs232TxPin5		; Then make transmit pin lo  
		sb	rs232TxLow5.6		; if the bit in viewing window is lo  
		setb	rs232TxPin5		; Then make transmit pin hi  
IFNDEF          stringTransfer                     	; If not stringTransfer
	        test    rs232TxCount5           ; test count
		snz                             ; if zero
		clrb    rs232Tx5Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut5    

;*****************************************************************************************
rs232Receive5     
      		sb	rs232RxPin5		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin5		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank5678  
		test    rs232RxCount5           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount5,w		; it is, so load bit count
		mov     w,#UARTStDelay5		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide5,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide5		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut5		; then don't go into Rx routine 
		mov	w,#UARTDivide5		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide5,w	;  
		dec     rs232RxCount5           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte5            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag5            ; if zero set the Rx flag to indicate the 
                                                ; complete reception of the byte              
:rs232RxOut5

;*****************************************************************************************
;---------------------------------------- UART6 ------------------------------------------
;*****************************************************************************************
rs232Transmit6   
             	_bank	rs232TxBank5678		; switch to serial register bank   
	        sb      rs232Tx6Flag            ; Is data there for UART6,
	        jmp     :rs232TxOut6		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide6		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut6		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide6		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide6,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount6		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut6		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh6		; right shift Tx data
		rr      rs232TxLow6		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount6		; decrement bit counter
		snb	rs232TxLow6.6		; if the bit in viewing window is hi
		clrb	rs232TxPin6		; Then make transmit pin lo  
		sb	rs232TxLow6.6		; if the bit in viewing window is lo  
		setb	rs232TxPin6		; Then make transmit pin hi  
IFNDEF          stringTransfer                      ; If not stringTransfer
	        test    rs232TxCount6           ; test count
		snz                             ; if zero
		clrb    rs232Tx6Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut6

;*****************************************************************************************
rs232Receive6     
	        sb	rs232RxPin6		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin6		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank5678  
		test    rs232RxCount6           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount6,w		; it is, so load bit count
		mov     w,#UARTStDelay6		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide6,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide6		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut6		; then don't go into Rx routine 
		mov	w,#UARTDivide6		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide6,w	;  
		dec     rs232RxCount6           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte6            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag6            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte              
:rs232RxOut6		                 	; 
		jmp		isrOut          ; End of isrThread3


;*****************************************************************************************
isrThread4                      ;UART7&8
;*****************************************************************************************
rs232Transmit7    
               _bank	rs232TxBank5678		; switch to serial register bank   
	        sb      rs232Tx7Flag            ; Is data there for UART7,
	        jmp     :rs232TxOut7		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide7		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut7		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide7		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide7,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount7		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut7		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh7		; right shift Tx data
		rr      rs232TxLow7		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount7		; decrement bit counter
		snb	rs232TxLow7.6		; if the bit in viewing window is hi
		clrb	rs232TxPin7		; Then make transmit pin lo  
		sb	rs232TxLow7.6		; if the bit in viewing window is lo  
		setb	rs232TxPin7		; Then make transmit pin hi  
IFNDEF          stringTransfer                     	; If not stringTransfer
	        test    rs232TxCount7           ; test count
		snz                             ; if zero
		clrb    rs232Tx7Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut7    

;*****************************************************************************************
rs232Receive7     
      	 	sb	rs232RxPin7		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin7		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank5678  
		test    rs232RxCount7           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount7,w		; it is, so load bit count
		mov     w,#UARTStDelay7		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide7,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide7		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut7		; then don't go into Rx routine 
		mov	w,#UARTDivide7		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide7,w	;  
		dec     rs232RxCount7           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte7            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag7            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte              
:rs232RxOut7

;*****************************************************************************************
;---------------------------------------- UART8 ------------------------------------------
;*****************************************************************************************
rs232Transmit8   
             	_bank	rs232TxBank5678		; switch to serial register bank   
	        sb      rs232Tx8Flag            ; Is data there for UART8,
	        jmp     :rs232TxOut8		; then execute the Tx routine otherwise don't.
	        decsz	rs232TxDivide8		; enter Tx routine until Divide val becomes zero
		jmp	:rs232TxOut8		; i.e don't enter the Tx rotine 
		mov	w,#UARTDivide8		; If Divide val becomes zero & enters the Tx routine then again load the
		mov	rs232TxDivide8,w	; Divide val for not to enter the Tx routine 'Divide' times for next bit 
		test    rs232TxCount8		; If count becomes Zero then also don't enter
		snz				;  
		jmp	:rs232TxOut8		; 
                                                ; after all barriers then only it will come here
:txbit		clc                             ; i.e Txflag = hi, Divide=0, count != 0 
		rr      rs232TxHigh8		; right shift Tx data
		rr      rs232TxLow8		; right shift rs232TxLow which contains start bit 
		dec     rs232TxCount8		; decrement bit counter
		snb	rs232TxLow8.6		; if the bit in viewing window is hi
		clrb	rs232TxPin8		; Then make transmit pin lo  
		sb	rs232TxLow8.6		; if the bit in viewing window is lo  
		setb	rs232TxPin8		; Then make transmit pin hi  
IFNDEF          stringTransfer                     	; If not stringTransfer
	        test    rs232TxCount8           ; test count
		snz                             ; if zero
		clrb    rs232Tx8Flag            ; then clear the Tx flag & come out
ENDIF  
:rs232TxOut8

;*****************************************************************************************
rs232Receive8     
	        sb	rs232RxPin8		; get current rx bit
      	        clc				; if bit is zero clear the carry  
	        snb	rs232RxPin8		; other wise   
	        stc				; set the carrry  
		_bank	rs232RxBank5678  
		test    rs232RxCount8           ; test the Rx count
		sz				; If zero then only load the Rxcount  
		jmp	:rxbit                  ; if so, jump ahead
		mov     w,#9                    ; in case start, ready 9 bits
		sc				; if not start bit don't load the count
		mov     rs232RxCount8,w		; it is, so load bit count
		mov     w,#UARTStDelay8		; ready 1.5 bit periods (50MHz)		
		mov     rs232RxDivide8,w	; load fresh Divide value  
:rxbit          decsz	rs232RxDivide8		; If Divide value is not zero after dec 
          	jmp	:rs232RxOut8		; then don't go into Rx routine 
		mov	w,#UARTDivide8		; If yes,load fresh Divide val for next bit 
		mov	rs232RxDivide8,w	;  
		dec     rs232RxCount8           ; dec the count
		sz                              ; check for Rxcount value
		rr      rs232RxByte8            ; if zero rotate the buf to save the received bits
		snz                             ; check for Rxcount value
		setb    rs232RxFlag8            ; if zero set the Rx flag to indicate the 
		                                ; complete reception of the byte              
:rs232RxOut8		                 	; cycles until mainline program resumes execution
	        _bank	Multiplexbank
		mov	isrMultiplex,#255	; reload isrMultiplex so isrThread1 will be run on the
                                                ; next interrupt.
                jmp	isrOut           	; cycles until mainline program resumes execution
						; This thread must reload the isrMultiplex register
                                                ; since it is the last one to run in a rotation.
						; End of isrThread4
;-----------------------------------------------------------------------------------------
isrOut
;*****************************************************************************************
; Set Interrupt Rate
;*****************************************************************************************

isr_end	
	IFDEF SX_28AC	
		mov	w,isrTemp0		; Restore the mode register value.
		mov	m,w			
	ENDIF
		mov	w,#-intperiod		; refresh RTCC on return
						; (RTCC = 217-no of instructions executed in the ISR)
		retiw				; return from the interrupt
						
;*****************************************************************************************
; End of the Interrupt Service Routine
;*****************************************************************************************

;*****************************************************************************************
; RESET VECTOR 
;*****************************************************************************************

;*****************************************************************************************
;---------------------------------------- Reset Entry ------------------------------------
;*****************************************************************************************

	org 	RESETENTRY_ORG

resetEntry					; Program starts here on power-up
		page 	_resetEntry
		jmp	_resetEntry
		

;*****************************************************************************************
;--------------------------------------- UART Subroutines --------------------------------
;*****************************************************************************************

	org	SUBROUTINES_ORG

;*****************************************************************************************
; 	Function	: getbyte
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte1, rs232byte2, rs232byte3, rs232byte4,
;				rs232byte5, rs232byte6, rs232byte7, rs232byte8
; 	Get byte via serial port and echo it back to the serial port for all the 8 UART's.
;	If there isn't any byte on any of the UART's, the routine will be blocked until
;	a byte is received. This is true for all the UART's.
;	Instead use "getbyte" routines of the specific UART.
;*****************************************************************************************
getbyte  
                call     getbyte1
                call     getbyte2
                call     getbyte3
                call     getbyte4
                call     getbyte5
                call     getbyte6
                call     getbyte7
                call     getbyte8
		retp
		
;*****************************************************************************************
; 	Function	: getbyte1
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte1
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte1	   
           	_bank    rs232RxBank1234
                sb       rs232RxFlag1
                jmp      getbyte1 
		mov      rs232Byte1,rs232RxByte1 ; store byte (copy using W)    
		clrb     rs232RxFlag1	
	        retp

;*****************************************************************************************
; 	Function	: getbyte2
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte2
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte2	
        	_bank    rs232RxBank1234
		sb       rs232RxFlag2            ;if UART2 is set
		jmp      getbyte2 
		mov      rs232Byte2,rs232RxByte2 
                clrb     rs232RxFlag2 
                retp

;*****************************************************************************************
; 	Function	: getbyte3
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte3
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte3		
               _bank     rs232RxBank1234
		sb       rs232RxFlag3            ;if UART3 is set
		jmp      getbyte3 
		mov      rs232Byte3,rs232RxByte3  
		clrb     rs232RxFlag3 
		retp 

;*****************************************************************************************
; 	Function	: getbyte4
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte4
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte4
        	_bank    rs232RxBank1234
		sb       rs232RxFlag4            ;if UART4 is set
		jmp      getbyte4 
		mov      rs232Byte4,rs232RxByte4 
		clrb     rs232RxFlag4 
		retp

;*****************************************************************************************
; 	Function	: getbyte5
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte5
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte5
                _bank    rs232RxBank5678
		sb       rs232RxFlag5             ;if UART5 is set
		jmp      getbyte5 
		mov      rs232Byte5,rs232RxByte5 
		clrb     rs232RxFlag5 
		retp

;*****************************************************************************************
; 	Function	: getbyte6
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte6
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte6
                _bank    rs232RxBank5678
		sb       rs232RxFlag6             ;if UART6 is set
		jmp      getbyte6 
		mov      rs232Byte6,rs232RxByte6 
		clrb     rs232RxFlag6 
		retp

;*****************************************************************************************
; 	Function	: getbyte7
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte7
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte7
         	_bank    rs232RxBank5678
		sb       rs232RxFlag7             ;if UART7 is set
		jmp      getbyte7 		
		mov      rs232Byte7,rs232RxByte7 
		clrb     rs232RxFlag7
		retp

;*****************************************************************************************
; 	Function	: getbyte8
; 	INPUTS		: -NONE
; 	OUTPUTS		: -received byte in rs232byte8
; 	Get byte via serial port and echo it back to the serial port
;*****************************************************************************************
getbyte8
               _bank     rs232RxBank5678          ;if UART8 is set
		sb       rs232RxFlag8 
		jmp      getbyte8
		mov      rs232Byte8,rs232RxByte8 
                clrb     rs232RxFlag8 
                retp
                
;*****************************************************************************************
; 	Function	:sendbyte
;	INPUTS		:w  The byte to be sent via RS-232
;			: rs232Tx1Flag || rs232Tx2Flag || rs232Tx3Flag || rs232Tx4Flag ||
;			  rs232Tx5Flag || rs232Tx6Flag || rs232Tx7Flag || rs232Tx8Flag
; 	OUTPUTS		:Outputs The byte via RS-232
; 	
;	Send byte via serial port. The byte that has to be sent has to be in 'w' register
;	and the UART Tx flag for any of the 8 UART's has to be set. If the same data has 
;	to be sent on all the UART's, then the flags of all the UART's has to be set.
;	   The sendbyte routine returns to main routine only after the byte has been sent.
;*****************************************************************************************

sendbyte
	    	mov	localTemp0,w
   	
                sb      rs232Tx1Flag		; If uart1flag = 0, then :wait2
	        jmp     :u2			; if not uart1, check for uart2
                _bank    rs232TxBank1234 
                mov     w,rs232TxHigh1
                not     w                        
	        mov     rs232TxHigh1,w  
		setb    rs232TxLow1.7		; set up start bit     
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount1,w    
           
:u2		sb      rs232Tx2Flag
                jmp     :u3			; if not uart2, check for uart3
                _bank    rs232TxBank1234  
                mov     w,rs232TxHigh2
                not     w                        
	        mov     rs232TxHigh2,w 
        	setb    rs232TxLow2.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount2,w    
                
:u3		sb      rs232Tx3Flag
                jmp     :u4			; if not uart3, check for uart4
  	        _bank    rs232TxBank1234
                mov     w,rs232TxHigh3
                not     w                        
	        mov     rs232TxHigh3,w 
        	setb    rs232TxLow3.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount3,w 
 
:u4		sb      rs232Tx4Flag
                jmp     :u5			; if not uart4, check for uart5
                _bank    rs232TxBank1234
                mov     w,rs232TxHigh4
                not     w                        
	        mov     rs232TxHigh4,w 
        	setb    rs232TxLow4.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount4,w      

:u5		sb      rs232Tx5Flag
                jmp     :u6			; if not uart5, check for uart6 		
                _bank    rs232TxBank5678
                mov     w,rs232TxHigh5
                not     w                        
	        mov     rs232TxHigh5,w 
           	setb    rs232TxLow5.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount5,w    
		
:u6		sb      rs232Tx6Flag
                jmp     :u7			; if not uart6, check for uart7
                _bank    rs232TxBank5678
                mov     w,rs232TxHigh6
                not     w                        
	        mov     rs232TxHigh6,w 
           	setb    rs232TxLow6.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount6,w
				
:u7		sb      rs232Tx7Flag
                jmp     :u8			; if not uart7, check for uart8
                _bank    rs232TxBank5678
                mov     w,rs232TxHigh7
                not     w                        
	        mov     rs232TxHigh7,w 
          	setb    rs232TxLow7.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount7,w	
				
:u8		sb      rs232Tx8Flag
                jmp 	:wait1			; if not uart8
                _bank    rs232TxBank5678
                mov     w,rs232TxHigh8
                not     w                        
	        mov     rs232TxHigh8,w 
          	setb    rs232TxLow8.7		; set up start bit 
		mov     w,#10			; 1 start + 8 data + 1 stop bit
		mov     rs232TxCount8,w		  
		
:wait1		_bank    rs232TxBank1234
                test    rs232TxCount1		; wait until data on UART1 is Tx'ed
		sz
		jmp     :wait1   
	
:wait2		_bank    rs232TxBank1234
                test    rs232TxCount2		; wait until data on UART2 is Tx'ed
		sz
		jmp     :wait2
		
:wait3		_bank    rs232TxBank1234
                test    rs232TxCount3		; wait until data on UART3 is Tx'ed
		sz
		jmp     :wait3 
		
:wait4		_bank    rs232TxBank1234
                test    rs232TxCount4		; wait until data on UART4 is Tx'ed
		sz
		jmp     :wait4
		
:wait5		_bank    rs232TxBank5678
                test    rs232TxCount5		; wait until data on UART5 is Tx'ed
		sz
		jmp     :wait5
		
:wait6		_bank    rs232TxBank5678
                test    rs232TxCount6		; wait until data on UART6 is Tx'ed
		sz
		jmp     :wait6	
		
:wait7		_bank    rs232TxBank5678
                test    rs232TxCount7		; wait until data on UART7 is Tx'ed
		sz
		jmp     :wait7
		
:wait8		_bank    rs232TxBank5678
                test    rs232TxCount8		; wait until data on UART8 is Tx'ed
		sz
		jmp     :wait8									             	                                 

                retp

;*****************************************************************************************
; 	Function	: sendString
; 	INPUTS		:w	The address of a null-terminated string in program memory
; 	OUTPUTS		:outputs the string via RS-232
; 	Send string pointed to by address in W register
;*****************************************************************************************

sendString	
 		mov     localTemp1,w            ; store string address
:loop
		mov	w,#STRINGS_ORG>>8	; with indirect addressing
		mov	m,w
		mov     w,localTemp1
		iread                           ; using the mode register
		test    w                       ; are we at the last char?
		snz                             ; if not=0, skip ahead
		jmp	:out      
	
	        _bank	rs232TxBank1234		; Check for which UART the string has to be sent
		snb     rs232Tx1Flag
		mov     rs232TxHigh1,w
	
		_bank	rs232TxBank1234
		snb     rs232Tx2Flag
		mov     rs232TxHigh2,w 
	
		_bank	rs232TxBank1234
                snb     rs232Tx3Flag
		mov     rs232TxHigh3,w
		
		_bank	rs232TxBank1234
                snb     rs232Tx4Flag
		mov     rs232TxHigh4,w  
		
		_bank	rs232TxBank5678
                snb     rs232Tx5Flag
		mov     rs232TxHigh5,w 
		
		_bank	rs232TxBank5678
                snb     rs232Tx6Flag
		mov     rs232TxHigh6,w 
		
		_bank	rs232TxBank5678
                snb     rs232Tx7Flag
		mov     rs232TxHigh7,w 
		
		_bank	rs232TxBank5678
                snb     rs232Tx8Flag
		mov     rs232TxHigh8,w

		call    sendByte               	; not 0, so send character
		inc     localTemp1              ; point to next character
		jmp     :loop                   ; loop until done

:out		mov	w,#$1F			; reset the mode register
		mov	m,w
		retp



;*****************************************************************************************
	org    STRINGS_ORG     ; This label defines where strings are kept in program space.
;*****************************************************************************************

;*****************************************************************************************
;------------------------------------------- String Data ---------------------------------
;*****************************************************************************************

;VP: RS232 Transmit

_hello          dw      13,10,'Yup, The UART works!!!',0 
_hitSpace	dw	13,10,'Hit Space...',0


;*****************************************************************************************
	org	PAGE3_ORG
;*****************************************************************************************
		jmp	$



;*****************************************************************************************
;-------------------------------------- Main Program -------------------------------------
;	 Program execution begins here on power-up or after a reset
;*****************************************************************************************

;*****************************************************************************************
	org	MAINPROGRAM_ORG
;*****************************************************************************************
     
_resetEntry

;*****************************************************************************************
;---------------------------- Initialise all port configuration --------------------------
;*****************************************************************************************

		_mode	ST_W			;point MODE to write ST register
		mov     w,#RB_ST            	;Setup RB Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_ST            	;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rc,w	
 IFDEF SX48_52
		mov     w,#RD_ST            	;Setup RD Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_ST            	;Setup RE Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!re,w		
 ENDIF
		_mode	LVL_W			;point MODE to write LVL register
		mov     w,#RA_LVL            	;Setup RA CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!ra,w		 
		mov     w,#RB_LVL            	;Setup RB CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!rb,w		
		mov     w,#RC_LVL            	;Setup RC CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!rc,w	
 IFDEF SX48_52
		mov     w,#RD_LVL            	;Setup RD CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!rd,w		
		mov     w,#RE_LVL            	;Setup RE CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!re,w		
 ENDIF
		_mode	PLP_W			;point MODE to write PLP register
		mov     w,#RA_PLP            	;Setup RA Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!ra,w		 
		mov     w,#RB_PLP            	;Setup RB Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_PLP            	;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_PLP            	;Setup RD Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_PLP            	;Setup RE Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!re,w		
ENDIF
		_mode	DDIR_W			;point MODE to write DDIR register
		mov	w,#RA_DDIR		;Setup RA Direction register, 0 = output, 1 = input		
		mov	!ra,w	
		mov	w,#RB_DDIR		;Setup RB Direction register, 0 = output, 1 = input
		mov	!rb,w			
		mov	w,#RC_DDIR		;Setup RC Direction register, 0 = output, 1 = input
		mov	!rc,w			
IFDEF SX48_52
		mov	w,#RD_DDIR		;Setup RD Direction register, 0 = output, 1 = input
		mov	!rd,w			
		mov	w,#RE_DDIR		;Setup RE Direction register, 0 = output, 1 = input
		mov	!re,w			
ENDIF
		mov     w,#RA_latch          	;Initialize RA data latch
		mov     ra,w		
		mov     w,#RB_latch         	;Initialize RB data latch
		mov     rb,w		
		mov     w,#RC_latch          	;Initialize RC data latch
		mov     rc,w		
IFDEF SX48_52
		mov     w,#RD_latch         	;Initialize RD data latch
		mov     rd,w			
		mov     w,#RE_latch         	;Initialize RE data latch
		mov     re,w			
ENDIF

;*****************************************************************************************
;----------------------------- Clear all Data RAM locations ------------------------------
;*****************************************************************************************

IFDEF SX48_52   				;SX48/52 RAM clear routine
		mov	w,#$0a			;reset all ram starting at $0A
		mov	fsr,w
:zeroRam	clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zeroRam

		_bank	bank0			;clear bank 0 registers
		clr	$10
		clr	$11
		clr	$12
		clr	$13
		clr	$14
		clr	$15
		clr	$16
		clr	$17
		clr	$18
		clr	$19
		clr	$1a
		clr	$1b
		clr	$1c
		clr	$1d
		clr	$1e
		clr	$1f

ELSE     					;SX18/20/28 RAM clear routine
		clr	fsr			;reset all ram banks
:zeroRam	sb	fsr.4			;are we on low half of bank?
		setb	fsr.3			;If so, don't touch regs 0-7
		clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zeroRam
ENDIF

;*****************************************************************************************
; Initialize program/VP registers
;*****************************************************************************************

		_bank 	rs232TxBank1234		;select rs232 bank    
		mov 	w,#UARTDivide1		;load Txdivide with UART1 baud rate
		mov 	rs232TXdivide1,w   
		
		mov 	w,#UARTDivide2		;load Txdivide with UART2 baud rate
		mov 	rs232TXdivide2,w
		
		mov 	w,#UARTDivide3		;load Txdivide with UART3 baud rate
		mov 	rs232TXdivide3,w
		
		mov 	w,#UARTDivide4		;load Txdivide with UART4 baud rate
		mov 	rs232TXdivide4,w

		_bank 	rs232TxBank5678
		mov 	w,#UARTDivide5		;load Txdivide with UART5 baud rate
		mov 	rs232TXdivide5,w

		mov 	w,#UARTDivide6		;load Txdivide with UART6 baud rate
		mov 	rs232TXdivide6,w

		mov 	w,#UARTDivide7		;load Txdivide with UART7 baud rate
		mov 	rs232TXdivide7,w
		
                mov 	w,#UARTDivide8		;load Txdivide with UART8 baud rate
		mov 	rs232TXdivide8,w


;*****************************************************************************************
; Setup and enable RTCC interrupt, WREG register, RTCC/WDT prescaler
;*****************************************************************************************

RTCC_ON		=	%10000000		;Enables RTCC at address $01 (RTW hi)
						;*WREG at address $01 (RTW lo) by default
RTCC_ID		=	%01000000		;Disables RTCC edge interrupt (RTE_IE hi)
						;*RTCC edge interrupt (RTE_IE lo) enabled by default
RTCC_INC_EXT	=	%00100000		;Sets RTCC increment on RTCC pin transition (RTS hi)
						;*RTCC increment on internal instruction (RTS lo) is default
RTCC_FE		=	%00010000		;Sets RTCC to increment on falling edge (RTE_ES hi)
						;*RTCC to increment on rising edge (RTE_ES lo) is default
RTCC_PS_ON	=	%00000000		;Assigns prescaler to RTCC (PSA lo)
RTCC_PS_OFF	=	%00001000		;Assigns prescaler to WDT (PSA hi)
PS_000		=	%00000000		;RTCC = 1:2, WDT = 1:1
PS_001		=	%00000001		;RTCC = 1:4, WDT = 1:2
PS_010		=	%00000010		;RTCC = 1:8, WDT = 1:4
PS_011		=	%00000011		;RTCC = 1:16, WDT = 1:8
PS_100		=	%00000100		;RTCC = 1:32, WDT = 1:16
PS_101		=	%00000101		;RTCC = 1:64, WDT = 1:32
PS_110		=	%00000110		;RTCC = 1:128, WDT = 1:64
PS_111		=	%00000111		;RTCC = 1:256, WDT = 1:128

OPTIONSETUP	equ	RTCC_PS_OFF|PS_111	; the default option setup for this program.
		mov	w,#OPTIONSETUP		; setup option register for RTCC interrupts enabled 
		mov	!option,w		; and prescaler assigned to WDT.
		jmp	@mainLoop

;*****************************************************************************************
;--------------------------------- MAIN PROGRAM CODE -------------------------------------
;*****************************************************************************************
mainLoop   

;*****************************************************************************************
; Example 1
;*****************************************************************************************
IFDEF stringTransfer 				; For an example with "send string"
 
; ........................................................................................
; Uncomment any one of the following depending on which UART you want to Transmit on.
; ........................................................................................

		setb    rs232Tx1Flag
	;	setb    rs232Tx2Flag 
	;	setb    rs232Tx3Flag
	;	setb    rs232Tx4Flag 
	;	setb    rs232Tx5Flag
	;	setb    rs232Tx6Flag 
	;	setb    rs232Tx7Flag
	;	setb    rs232Tx8Flag
                        	
	        mov	w,#_hitSpace		; Send prompt to terminal at UART rate
	        call	@sendString		; String is sent to the UART whose flag
						; is SET above.
:loop	        call	@getByte1
	        cjne	rs232RxByte1,#' ',:loop	; Compare if "SPACE BAR" is received
	        mov	w,#_hello		; When space bar hit, send out string.
        	call	@sendString
                jmp	mainLoop
		       	 
; End of Example 1
ENDIF
;*****************************************************************************************


;*****************************************************************************************
; Example 2
;*****************************************************************************************
IFDEF byteTransfer 				; If "send string" is not required
 
; ........................................................................................
; Uncomment any one of the following depending on which UART you want to receive on.
; If you want to receive from all the UART's, then uncomment "call   @getByte"
; ........................................................................................

		call 	@getByte1		; Receive a Byte from UART1
	;	call   	@getByte2		; Receive a Byte from UART2		  
	;	call	@getByte3		; Receive a Byte from UART3
	;	call	@getByte4		; Receive a Byte from UART4
	;	call 	@getByte5		; Receive a Byte from UART5
	;	call	@getByte6		; Receive a Byte from UART6
	;	call 	@getByte7		; Receive a Byte from UART7
	;	call	@getByte8		; Receive a Byte from UART8
        
	;	call	@getByte       		; If you want to Receive on all the UART's
                
		_bank	rs232RxBank1234   
                mov	w,rs232Byte1
                _bank	rs232TxBank1234
                mov	rs232TxHigh1,w		; Load from the UART1 Rx buffer to Tx Buffer
                
                _bank	rs232RxBank1234     
                mov	w,rs232Byte2 
                _bank	rs232TxBank1234
                mov	rs232TxHigh2,w		; Load from the UART2 Rx buffer to Tx Buffer   

		_bank	rs232RxBank1234
                mov	w,rs232Byte3 
                _bank	rs232TxBank1234
                mov	rs232TxHigh3,w		; Load from the UART3 Rx buffer to Tx Buffer
                
                _bank	rs232RxBank1234
                mov	w,rs232Byte4 
                _bank	rs232TxBank1234
                mov	rs232TxHigh4,w		; Load from the UART4 Rx buffer to Tx Buffer
                                       
		_bank	rs232RxBank5678
		mov	w,rs232Byte5 
		_bank	rs232TxBank5678
		mov	rs232TxHigh5,w		; Load from the UART5 Rx buffer to Tx Buffer
                
		_bank	rs232RxBank5678
		mov	w,rs232Byte6 
		_bank	rs232TxBank5678
		mov	rs232TxHigh6,w		; Load from the UART6 Rx buffer to Tx Buffer
               
		_bank	rs232RxBank5678
		mov	w,rs232Byte7 
		_bank	rs232TxBank5678
		mov	rs232TxHigh7,w		; Load from the UART7 Rx buffer to Tx Buffer
               
		_bank	rs232RxBank5678
		mov	w,rs232Byte8 
		_bank	rs232TxBank5678
		mov	rs232TxHigh8,w		; Load from the UART8 Rx buffer to Tx Buffer
                                              
; ........................................................................................
; Uncomment any of the following lines to enable the echoing of data on the 
; respective UART (e.g.: uncomment setb re232TX2Flag in order to echo data on UART 2).
; ........................................................................................
            
		setb    rs232Tx1Flag		; Enable Tx flag for UART1
	;	setb    rs232Tx2Flag 
	;	setb    rs232Tx3Flag
	;	setb    rs232Tx4Flag 
	;	setb    rs232Tx5Flag
	;	setb    rs232Tx6Flag 
	;	setb    rs232Tx7Flag
	;	setb    rs232Tx8Flag
           
		call    @sendbyte  		; Send the Received byte back
                jmp	mainLoop
                            
; End of Example 2
ENDIF 
;*****************************************************************************************


;****************************************************************************************
; Example 3: The below code is the same as Example 2
;****************************************************************************************
IFDEF fileTransfer 				; For "File Transfer" Example
 
; ........................................................................................
; Uncomment any one of the following depending on which UART you want to receive on.
; If you want to receive from all the UART's, then uncomment "call   @getByte"
; ........................................................................................

		call 	@getByte1		; Receive a Byte from UART1
	;	call   	@getByte2		; Receive a Byte from UART2		  
	;	call	@getByte3		; Receive a Byte from UART3
	;	call	@getByte4		; Receive a Byte from UART4
	;	call 	@getByte5		; Receive a Byte from UART5
	;	call	@getByte6		; Receive a Byte from UART6
	;	call 	@getByte7		; Receive a Byte from UART7
	;	call	@getByte8		; Receive a Byte from UART8
        
	;	call	@getByte       		; If you want to Receive on all the UART's
                
		_bank	rs232RxBank1234   
                mov	w,rs232Byte1  
                _bank	rs232TxBank1234
                mov	rs232TxHigh1,w		; Load from the UART1 Rx buffer to Tx Buffer
                
                _bank	rs232RxBank1234     
                mov	w,rs232Byte2 
                _bank	rs232TxBank1234
                mov	rs232TxHigh2,w		; Load from the UART2 Rx buffer to Tx Buffer

		_bank	rs232RxBank1234
                mov	w,rs232Byte3 
                _bank	rs232TxBank1234
                mov	rs232TxHigh3,w		; Load from the UART3 Rx buffer to Tx Buffer
                
                _bank	rs232RxBank1234
                mov	w,rs232Byte4 
                _bank	rs232TxBank1234
                mov	rs232TxHigh4,w		; Load from the UART4 Rx buffer to Tx Buffer
                                       
		_bank	rs232RxBank5678
		mov	w,rs232Byte5 
		_bank	rs232TxBank5678
		mov	rs232TxHigh5,w		; Load from the UART5 Rx buffer to Tx Buffer
                
		_bank	rs232RxBank5678
		mov	w,rs232Byte6 
		_bank	rs232TxBank5678
		mov	rs232TxHigh6,w		; Load from the UART6 Rx buffer to Tx Buffer
               
		_bank	rs232RxBank5678
		mov	w,rs232Byte7 
		_bank	rs232TxBank5678
		mov	rs232TxHigh7,w		; Load from the UART7 Rx buffer to Tx Buffer
               
		_bank	rs232RxBank5678
		mov	w,rs232Byte8 
		_bank	rs232TxBank5678
		mov	rs232TxHigh8,w		; Load from the UART8 Rx buffer to Tx Buffer
                                              
; ........................................................................................
; Uncomment any of the following lines to enable the echoing of a file on the 
; respective UART (e.g.: uncomment setb re232TX2Flag in order to echo a file on UART 2).
; ........................................................................................
            
		setb    rs232Tx1Flag		; Enable Tx flag for UART1
	;	setb    rs232Tx2Flag 
	;	setb    rs232Tx3Flag
	;	setb    rs232Tx4Flag 
	;	setb    rs232Tx5Flag
	;	setb    rs232Tx6Flag 
	;	setb    rs232Tx7Flag
	;	setb    rs232Tx8Flag
           
		call    @sendbyte  		; Send the Received byte from file back
                jmp	mainLoop

; End of Example 3 
ENDIF   
;*****************************************************************************************

;*****************************************************************************************
END		;End of program code
;*****************************************************************************************
