	LIST    P = 16F84A
;	115200 full duplex (send delayed up to 8us) 
;		115200 = 
;		20 MHz = .2 us/instruction
;
	INCLUDE         <P16F84A.INC>
	__CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF   ;  configuration switches
;
SP	equ	0	;Send Pin 
GP	equ	1	;Get Pin 
AD2	equ	2	;a2 pin
AD3	equ	3	;a3 pin   Reg B = a1 a0 d5 d4 d3 d2 d1 d0
AMSK	equ	0xf3	;mask for AD2 AD3 (0xf3 for pins 2 and 3)
EIO	equ	4	;Enable IO 4-16
GR	equ	0xc	;byte to get
SR	equ	0xd	;byte to send
GF	equ	0xe	;get flag
SF	equ	0xf	;send flag
GK	equ	0x10	;get count
SK	equ	0x11	;send count
TGR	equ	0x12	;temp Get Register
GR2	equ	0x13	;Get Register for byte 2
DEL	equ	0x14	;delay count
TST	equ	0x15
;
	ORG	0
;
	bsf	STATUS,RP0	;select reg bank 1
	movlw	0x2			
	movwf	TRISA		;set port A pin 0 as out, pin 1 as in
	movlw	0x0
	movwf	TRISB		;set PORTB to output
	bcf	STATUS,RP0	;select reg bank 0
	bsf	PORTA,SP	;set send pin
;
;
	clrf	GR
	clrf	GR2
	clrf	SR
	clrf	GF
	clrf	SF
	movlw	0x30
	movwf	SR
	;bsf	SF,0
	movlw	0xa
	movwf	SK
	movlw	0x9
	movwf	GK
TOP	btfss	GF,0	
	goto	I1GA1	;check for start bit
	decfsz	GK,1
	goto	I2GA1	;get bit
	movlw	9	;stop bit - no need to get
	movwf	GK
	movlw	AMSK	;12 2 bcf cause problems
	andwf	PORTA,1	;13 set a3 a2
	btfsc	GR,0	
	bsf	PORTA,AD2
	btfsc	GR,1
	bsf	PORTA,AD3
	clrf	GF	;13
	goto	TOP2	;15	;later finish send stop bit

;the main idea is that TOP2 will land early on the stop bit
;the stop bit is 1 and the program will have time to get the
;next start bit (0)


NEXT	btfss	SF,0	
	goto	I1S
	btfsc	SF,1	
	goto	I2S	;send start bit
	decfsz	SK,1
	goto	I3S	;send data bit
	goto	I4S	;send stop bit
I3S	movf	PORTA,0	;8
	btfsc	SR,0
	iorlw	0x1
	btfss	SR,0
	andlw	0xfe
	movwf	PORTA	;13 *
	nop
	rrf	SR,1	;15	;14+15+14=3.0+2.8+2.8=8.6 us (8.6806 us)
				
LAST	btfss	GF,1
	goto	I1GB1	;check for start bit
	decfsz	GK,1
	goto	I2GB1	;get bit
	movlw	9	;stop bit - no need to get
	movwf	GK
	movlw	AMSK	;12 2 bcf cause problems
	andwf	PORTA,1	;13 set a3 a2
	btfsc	GR,0	
	bsf	PORTA,AD2
	btfsc	GR,1
	bsf	PORTA,AD3
	clrf	GF
	goto	TOP2	;goto	TOP2	;15 (14+14=28 early 5.6 us)
	

TOP2	btfss	GF,0
	goto	I1GA2	;check for start bit
	decfsz	GK,1
	goto	I2GA2	;get bit
	movlw	9	;stop bit - no need to get
	movwf	GK
	movf	GR2,0		;set b7-b0  (a1 a0 d5 d4 d3 d2 d1 d0)
	movwf	PORTB
;	movlw	0x3e	;test 
;	movwf	GR2	;test
	movlw	3
	movwf	SF	;set send flag
	bcf	GF,0	;11
	;nop	;12 get in inst part
	goto	INST	;13  goto INST?  (16+15=31 extra 6us)

LAST2	btfss	GF,1
	goto	I1GB2	;check for start bit
	decfsz	GK,1
	goto	I2GB2	;get bit
	movlw	9	;stop bit - no need to get
	movwf	GK
	movf	GR2,0	;set b7-b0  (a1 a0 d5 d4 d3 d2 d1 d0)
	movwf	PORTB
;	movlw	0x55	;test this part (has error)
;	movwf	GR2	;test
	movlw	3
	movwf	SF	;set send flag
	clrf	GF	;11
	;	nop	;12 get in inst part
	goto	INST	;13 (16+15= 31)


NEXT2	nop	;1 delay for 1/3 cycle
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	goto	TOP2	;15


;no send while getting byte 2
;use time to process PIC instructions for external devices (inputs, motors, ...)
;already set a3 a2
; and a1 a0 b5-b0
INST	btfss	GR,2	;1=get input
	goto	I1I
	bsf	STATUS,RP0	;select reg bank 1
	movlw	0x3f
	movwf	TRISB		;set PORTB to ooiiiiii
	bcf	STATUS,RP0	;select reg bank 0
	;the 4-16 address and data lines are set
	;this will send the PIC the (input) instruction
	bsf	PORTA,EIO	;enable 4-16 
	;nop	;extra inst
	bcf	PORTA,EIO	;disable 4-16
	movf	PORTB,0	;copy PORTB to Send Register
	;movlw	0x1e	;test value in SR
	;btfsc	TST,7	;for test
	;movf	GR2,0	;GR
	;btfss	TST,7	;for test
	;movf	GR2,0	;test byte2
;	movf	GR,0	;test byte2
	movwf	SR
	bsf	STATUS,RP0	;select reg bank 1
	clrf	TRISB		;set PORTB back to oooooooo
	bcf	STATUS,RP0	;select reg bank 0
	goto	NEXT	;1st do any sendTOP	;15 go back to getting byte 1  

;---end main loop
				
I1GA1	btfsc	GF,1	;4  check for start bit
	goto	I3GA1	;
	nop	;	btfsc	GF,2
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,0	;got sb, get sb next cycle
	nop	;	goto	I4GA1
	nop	;Did not get start bit delay
	nop
	nop	;12
	nop	
	goto	NEXT	;15

I2GA1	rrf	GR,1	;6 get bit
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9
	bsf	GR,7	;10
	btfss	TGR,GP	;11
	bcf	GR,7	;12
	nop
	goto	NEXT	;15

I3GA1	nop	;7  getting byte in other part
	nop
	nop
	nop
	nop
	nop
	nop
	goto	NEXT	;15


I1S	nop	;4
	nop
	nop
	nop
	nop
	nop
	nop	;10
	nop
	nop
	nop	
	goto	LAST	;15

I2S	nop	;6	send start bit
	nop	
	nop
	decfsz	SK,1
	bcf	SF,1	;clear bit 1 = do not send start bit again
	nop
	nop	
	bcf	PORTA,SP	;13 *
	goto	LAST	;15

I4S	movlw	0xa	;9
	movwf	SK
	clrf	SF		;9 inst  43 inst is most close
	nop
	bsf	PORTA,SP	;13 *
	goto	LAST	;15

I1GB1	btfsc	GF,0	;4
	goto	I3GB1	;
	nop	;	btfsc	GF,2
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,1	;got sb, get sb next cycle
	nop	;	goto	I4GB1
	nop	;Did not get start bit delay
	nop
	nop	;12
	goto	TOP	;14

I2GB1	rrf	GR,1	;6
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9
	bsf	GR,7	;10
	btfss	TGR,GP	;11
	bcf	GR,7	;12
	goto	TOP	;14

I3GB1	nop	;7  getting byte in other part
	nop	;
	nop	;
	nop
	nop
	nop
	goto	TOP	;14
	

;byte 1 above, byte 2 below
I1GA2	btfsc	GF,1	;4  check for start bit
	goto	I3GA2	;
	nop	;	btfsc	GF,2
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,0	;got start bit
	nop	;	goto	I4GA2
	nop	;
	nop
	nop	;12
	nop
	goto	LAST2	;15

I2GA2	rrf	GR2,1	;6 get bit
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9
	bsf	GR2,7	;10
	btfss	TGR,GP	;11
	bcf	GR2,7	;12
	nop
	goto	LAST2	;15

I3GA2	nop	;7  getting byte in other part
	nop
	nop
	nop
	nop
	nop
	nop
	goto	LAST2	;15


I1GB2	btfsc	GF,0	;4
	goto	I3GB2	;
	nop	;	btfsc	GF,2
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,1	;got start bit
	nop	;	goto	I4GB2
	nop	;	bsf	GF,2	;got sb, get sb next cycle
	nop	;Did not get start bit delay
	nop
	nop	;12
	goto	NEXT2	;14

I2GB2	rrf	GR2,1	;6
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9
	bsf	GR2,7	;10
	btfss	TGR,GP	;11
	bcf	GR2,7	;12
	goto	NEXT2	;14

I3GB2	nop	;7  getting byte in other part
	nop
	nop
	nop
	nop
	nop
	goto	NEXT2	;14


I1I	nop	;4	output only
	nop
	nop
	nop	;7
	nop
	nop
	nop	;10
	;the 4-16 address and data lines are set
	;this will send the output instruction
	bsf	PORTA,EIO	;11 enable 4-16
	bcf	PORTA,EIO	;12 disable 4-16
	clrf	SF	;13 clear Send Flag set in past to save time
	goto	TOP	;15 go back to getting byte 1 no need to send first

Delay	decfsz	DEL,1	;DEL*3+5 DEL>0  
	goto	Delay	;1=8,2=11,3=14,4=17,5=20,6=23
	return	;7=26,8=29,9=32,10=35

	END
