.header "Half Duplex SCI Bit Banger" 	;depends on assembler
.pagewidth 132t				;ditto

*************************************************************************	
*	Program Name: SCI1.ASM						*
*	Revision:1.01							*
*	Date August 27, 1992						*
*									*
*	Written By: Craig Haller					*
*		P&E Microcomputer Systems.				*
*									*
*	Modified By: Dan Bernard					*
*		Motorola CSIC Applications				*
*									*
*	Assembled Under: P&E Microcomputer Systems IASM05  	   	*
*									*
*			*****************************		 	*
*			*	Revision History    *			*
*			*****************************			*
*									*
*	Revision 1.00	7/09/92	Original Source				*
*		 1.01	8/27/92	Mostly cosmetic added			*
*				additional comments			*
*									* 
*************************************************************************
*************************************************************************
*			 						*
*	Program Description:		  				*
*									*
*	Code for HC705K1 to send and receive asynchronous data with 	*
*	non-return to zero (NRZ) format. The original code was tested 	*
*	at 9600 baud. This code can be used on any HC05 by changing 	*
*	the origin of the code and data areas and also changing to 	*
*									*
*	Start up conditions =						*
*		See individual subroutines for entry and exit 		*
*		conditions     						*
*			     ____					*
*		RXD	-->13|B1 |					*
*		TXD	<--12|B0 |					*
*		BUSY	<--11|A0 |					*
*			     |___|					*
*									*
*		Pin out for HC705K1					*
*									*
*	Operation:							*
*									*
*	(get_char) Port B bit 1 is used as the receive data pin. It is	*
*	continuously polled in order to detect a start bit. This would 	*
*	be a high to low transition. The program enters a half bit 	*
*	delay routine and checks to see if the port pin is still low. 	*
*	If it is it assumes a valid start bit. If the port pin has 	*
*	returned high it is assumed this was a false start bit, and 	*
*	goes back polling the RXD pin waiting for a valid start bit. 	*
*	When a valid start bit occurs, the rest of incoming bit changes *
*									*
*	(put_char) Port B bit 0 is used as the transmit data pin.The 	*
*	variable count is loaded with the total number of bits to 	*
*	transmit. This includes the start bit also First the start bit 	*
*	is sent out.  Each bit of the character in "char" is rotated 	*
*	into the carry bit then the carry is shifted into port B 	*
*	bit 0. "Count" is decremented and the sequence is repeated.	*
*									*		
*************************************************************************


*********************************Port Equates****************************

porta		equ $00			;port "A"
portb		equ $01			;port "B"
ddra		equ $04			;port A data direction register
ddrb		equ $05			;port B data direction register

ser_busy	equ porta		;another name for porta
ser_port	equ portb		;another name for portb
ser_ddr		equ ddrb		;another name for ddrb

ser_in		equ $01			;bit 1 of port B
ser_out		equ $00			;bit 0 of port B


********************************Memory Equates***************************


*************************************************************************
*									*
*	The values of these equates may change depending on MCU type 	*
*	These values are for the K1					*
*									*
*************************************************************************

ram		equ $00e0		;beginning of ram
rom		equ $200		;beginning of rom
reset		equ $03fe		;reset vector location

*********************************Other Equates***************************

half_bit_time  equ	$11		;9600 baud at 2 Mhz bus
full_bit_time  equ	$1C		;9600 baud

*******************************Memory Allocation*************************

	 org ram			;reserve memory variables

count	ds	1			;bit counter used in put_char
					;and get_char
char	ds	1			;get_char puts received 
					;character here
					;and put_char get character
					;to send from here

********************************Start of Program*************************
	
	org rom				;start of program area

main:
	rsp
	jsr	init

main_loop:
	jsr	get_char		;we're going to go get any 
	jsr	put_char		;character andand then
	bra	main_loop		;spit it right back out

 					;and do it over and over and--


*************************************************************************
*									*
*	"get_char"							*
*	Get a serial character from port pin				*
*									*
*	INPUTS		data from portb bit 1				*
*			Carry bit 	= parity			*
*	MODIFIES 	A, X, char, count				*
*									*
*************************************************************************

get_char:
	lda	#8			;[2] get 8 bits 
	sta	count			;[4] decremented as character
	clra				;[3] is assembled
get_wait:
	brset	ser_in,ser_port,$ 	;We're using polled mode, 
					;wait for start bit
get_start:
	ldx	#half_bit_time		;[2] delay 1/2 bit time
	nop				;[2] part of timing
get_start1:
	decx				;[3] delay loop
	bne	get_start1		;[3] for 1/2 bit time
					;now in middle of start bit
	brset	ser_in,ser_port,get_wait ;[5] false start if we branch
					;main loop for getting char
get_loop:
	bsr	delay_bit		;[6] wait until in the next
					;bit cell
	brset	ser_in,ser_port,get_loop1 ;[5] check the incoming bit  
					;the"brset" affects the carry
					;bit
	nop				;[2] timing
	nop				;[2] timing
	ror	char			;[5] store the received bit 
					;it's a zero
	bra	get_loop2		;[3] setup for next bit
get_loop1:
	ror	char			;[5] store the received bit
					;it's a one
	inca				;[3] for parity check counting
					;ones
get_loop2:				
	dec	count			;[5] decrement the bit count
	bne	get_loop		;[3] still have more bits 
					;to go
	bsr	delay_bit		;wait out stop bit?
	brset	ser_in,ser_port,get_loop3 ;carry = parity bit
get_loop3:
	adc	#0
	rora				;parity lsb bit in C
	rts

*************************************************************************
*									*
*	"delay_bit"							*
*									*
*	Delays one full bit time as determined by the "full_bit_time	*
*	equate. This value would change	with a change in baud rate	*
*									*
*************************************************************************

delay_bit:
	ldx	#full_bit_time		;[2]
delay_bit1:
	decx				;[3]
	bne	delay_bit1		;[3]
	rts				;[6]

*************************************************************************
*	"put_char"							*
*	Send a serial character						*
*									*
*	INPUTS		character in "char"				*
*	OUTPUTS		pin data					*
*	MODIFIES  	A, X, char, count				*
*									*	
*************************************************************************


put_char:
	lda	#9t			;total number of bits to send
	sta	count			;includes start bit
	clra				;A will hold ones count
	clc				;start bit
	bclr	ser_out,ser_port	;[5] start bit (for timing,
					;do it here also)
	bclr	ser_out,ser_port	;[5] start bit (for timing, 
					;do it here also)
	bra	put_loop1		;[3]
put_loop:
	brset	0,char,$+3		;[5] set or clr carry
	adc	#0			;[2] for parity calculation
	ror	char			;[5] next bit
put_loop1:
	rol	portb			;[5] put bit out on PB0
	bsr	delay_bit		;[6] delay bit time
	dec	count			;[5] one less to go!
	bne	put_loop		;[3] back, jack, do it again

	brset	0,char,$+3		;[5] for timing - does nothing
	rora				;[5] parity bit in carry
	nop				;[2] for timing
	rol	portb			;[5] put it out
	bsr	delay_bit		;delay a bit time before
	bset	ser_out,portb		;sending stop bit
	bsr	delay_bit		;delay for stop bit
	rts


********************************Initialization***************************

init:
	bset	ser_out,ser_port	;bring line high, level when 
					;not transmitting
	bset	ser_out,ser_ddr		;make output
	bclr	ser_in,ser_ddr		;make input (should default
					;anyway)
					;receive input
	bclr	ser_busy,porta		;set up busy pin, make low 
					;level default
	bset	ser_busy,ddra		;ready This is the only 
					;place we do anything with
	rts				;busy. Additional code can be
					;written and called as 


******************************Setup reset vector*************************

	org	reset
	dw	main


