	LIST    P = 16F84A
;	115200 full duplex (send delayed up to 8us) 
;		115200 = 
;		20 MHz = .2 us/instruction
;
;  pic0.asm is the current robot PIC0 program
;
	INCLUDE         <P16F84A.INC>
	__CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF   ;  configuration switches
;
SP	equ	0	;Send Pin 
GP	equ	1	;Get Pin 
PICN1	equ	2	;Pin to send 8 bit address to PIC1
EIO0	equ	3	;Enable IO 4-16 #0
EIO1	equ	4	;Enable IO 4-16 #1
OMSK	equ	0x04	;or mask for PICN1
AMSK	equ	0xfb	;and mask for PICN1
;OMSK	equ	0x08	;or mask for PICN1
;AMSK	equ	0xf7	;and mask for PICN1
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
DELA	equ	0x14	;delay count
KR	equ	0x15	;clear port count
EIO	equ	0x16	;bit 0=4-16 (0/1),bit1=send input (0/1),bit7=check for addr=0 later
;
	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,EIO0	;set 4-16 enable high
	bsf	PORTA,EIO1	;set 4-16 enable high
	bsf	PORTA,SP	;set send pin
	bsf	PORTA,PICN1	;set send pin for pic1
;	bcf	PORTA,PICN1	;clear send pin for pic1 (reversed)
	clrf	PORTB
	
	
;

;	goto	TOP0	;skip init

	movlw	0xff	;8  1.2 us b4 pic1 starts
	movwf	DELA	;9
Dlay0	decfsz	DELA,1	;DELA*3+1 DELA>0  
	goto	Dlay0	;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32
			;9+(11=32)=41



;	go thru addressed 0x0c-0x0f, and 0xc0-0xf0 and
;	clear 8-bit ports
	movlw	0xc
	movwf	SR
	movlw	0xc
	movwf	TGR
;send address to PIC1
LUP	call	SndByt	;set address lines
	clrf	PORTB	;clear data lines
	bcf	PORTA,EIO0	;enable 8-bit port
	nop
	bsf	PORTA,EIO0	
	incf	TGR,1
	nop
	movf	TGR,0
	movwf	SR
	btfss	TGR,4
	goto	LUP

	movlw	0xc0
	movwf	SR
	movlw	0xc0
	movwf	TGR

;	goto	TOP0	;test	


LUP2	call	SndByt	;set address lines
	clrf	PORTB	;clear data lines
	bcf	PORTA,EIO1	;enable 8-bit port
	nop
	bsf	PORTA,EIO1	
	movlw	0x10
	addwf	TGR,1
;	incf	TGR,1
	nop
	movf	TGR,0
	movwf	SR
	movf	TGR,0
	btfss	STATUS,Z
	goto	LUP2
;end clear 8 output ports


;15+14+14=43*.2=8.6us  (8.68us)
;now start 115200 communciation with serial port
TOP0	clrf	GR
	clrf	GR2
	clrf	SR
	clrf	GF
	clrf	SF
	;movlw	0x30	;for testing
	;movwf	SR	;for testing
	;bsf	SF,0	;for testing
	movlw	0xa
	movwf	SK
TOP	btfss	GF,0	;1
	goto	I1GA1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GA1	;4 get bit
	clrf	GF	;5 stop bit
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	TOPA	;8
	andlw	0xf0	;9
	btfss	STATUS,Z	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reversed
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15	;later finish send stop bit
;I can only guess that the end bit can delay an extra inst (15 not 14)
;and goes early to check for a new start 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)

;could infact go without using an end/stop bit

TOPA	bsf	EIO,7	;10 later part set EIO,0 based on data byte
	nop	;11
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reversed
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15	;later finish send stop bit



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	;14	;15+14+14=3.0+2.8+2.8=8.6 us (8.6806 us)

LAST	btfss	GF,1	;1
	goto	I1GB1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GB1	;4 get bit
	clrf	GF	;5 stop bit
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	LASTA	;8
	andlw	0xf0	;9
	btfss	STATUS,Z	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reversed
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15 (14+14=28 early 5.6 us) ok to be late (14)

LASTA	bsf	EIO,7	;10 later part set EIO,0 based on data byte
	nop	;11
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1  reverse
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15	;later finish send stop bit ok to be late (14)
;could have 2 nop

;--------------
;get byte 2  15+14+14  (TOP2+LAST2+NEXT2 [never a send during byte 2])
;could be 15+15+13
;--------------
;INST is sent during time of end/stop bit


TOP2	btfss	GF,0	;1
	goto	I1GA2	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GA2	;4 get bit
	movf	GR2,0	;5 set b7-b0  (d7 d6 d5 d4 d3 d2 d1 d0)
	movwf	PORTB	;6 
	movlw	3	;7 *
	movwf	SF	;8  set send flag
	clrf	GF	;9
	nop		;10
	btfss	EIO,0	;11
	goto	INST0	;13 4-16A
	goto	INST1	;14 4-16B  make 14 for end/stop bit+15
;	goto	INST	;13  goto INST  (16+15=31 extra 6us) 
;would normally delay for 43 inst, but instead sent INST during time of end/stop bit

LAST2	btfss	GF,1	;1
	goto	I1GB2	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GB2	;4 get bit
	movf	GR2,0	;5 set b7-b0  (d7 d6 d5 d4 d3 d2 d1 d0)
	movwf	PORTB	;6
	movlw	3	;7*
	movwf	SF	;8 set send flag
	clrf	GF	;9 
	nop		;10
	btfss	EIO,0	;11 
	goto	INST0	;13 
;	goto	INST0	;13  test
	goto	INST1	;14
;	goto	INST	;13 (16+15= 31)

;decide in/out (EIO,1)
;this is a delay for 1/3
NEXT2	btfsc	EIO,0	;1
	goto	NEXT2A	;2
	movlw	0xf4	;3
	addwf	GR,0	;4
	btfss	STATUS,C	;5
	bsf	EIO,1	;6 no carry=is input (0-11)
;	movlw	0xc	;3 
;	subwf	GR,0	;4
;	btfsc	STATUS,DC	;5
;	bsf	EIO,1	;6 did borrow=is input (0-11)
	nop	;7
	nop	;8
	nop	;9
	nop	;10
	nop	;11
	nop	;12
;	nop	;13
	GOTO	TOP2	;14

NEXT2A	movlw	0x40	;4
	addwf	GR,0	;5
	btfss	STATUS,C	;6
	bsf	EIO,1	;7 no carry=is input (<12)
;	movlw	0xc0	;4 high addr
;	subwf	GR,0	;5
;	btfsc	STATUS,DC	;6
;	bsf	EIO,1	;7 did borrow =is input (0-11)
	nop	;8
	nop	;9
	nop	;10
	nop	;11
	nop	;12
;	nop	;13
	GOTO	TOP2	;14
	

;sending intruction has 43-7(to INST)-15(INS)-14(NEXT)=7 extra instructions 
;that are 1 end bit anyway
;no send while getting byte 2
;INST is sent during get of end/stop bit
;to process PIC instructions for external devices (inputs, motors, ...)
;already set address lines thru PIC1 and data lines (PORTB)
INST0	nop	;14 extra from goto 
	btfss	EIO,1	;1=get input
;	btfss	EIO,6	;test
	goto	I1I0	;2
	bsf	STATUS,RP0	;3 select reg bank 1
	movlw	0xff	;4
	movwf	TRISB		;5 set PORTB to iiiiiiii
	bcf	STATUS,RP0	;6 select reg bank 0
	;the 4-16 address and data lines are set
	;this will send the PIC the (input) instruction
	bcf	PORTA,EIO0	;7 enable 4-16 0
	movf	PORTB,0	;8 copy PORTB to Send Register
	bsf	PORTA,EIO0	;9 disable 4-16 0
	movwf	SR	;10
	bsf	STATUS,RP0	;11 select reg bank 1
	clrf	TRISB		;12 set PORTB back to oooooooo
	bcf	STATUS,RP0	;13 select reg bank 0
	goto	NEXT	;15 1st do any send is going back early? 


INST1	btfss	EIO,1	;1=get input
	goto	I1I1	;2
	bsf	STATUS,RP0	;3 select reg bank 1
	movlw	0xff	;4
	movwf	TRISB	;5 set PORTB to iiiiiiii
	bcf	STATUS,RP0	;6 select reg bank 0
	;the 4-16 address and data lines are set
	;this will send the PIC the (input) instruction
	bcf	PORTA,EIO1	;7 enable 4-16 1
	movf	PORTB,0	;8 copy PORTB to Send Register
	bsf	PORTA,EIO1	;9 disable 4-16 1
	movwf	SR	;10
	bsf	STATUS,RP0	;11 select reg bank 1
	clrf	TRISB		;12 set PORTB back to oooooooo
	bcf	STATUS,RP0	;13 select reg bank 0
	goto	NEXT	;15 1st do any send  


;---end main loop
				
I1GA1	btfsc	GF,1	;4  check for start bit (A)
	goto	I3GA1	;5
	nop	;6
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,1	;8 got sb, get sb in other part (not this part)
	movlw	0xa	;9 10 (1=sb,8=bits,1=eb)
	movwf	GK	;10
	clrf	EIO	;11
	btfsc	GF,0	;12 if got sb, send sb to PIC1
;	bsf	PORTA,PICN1	;** 13 reversed
	;bcf	PORTA,PICN1	;** 13 start bit will be sent like other bits
	nop	;13
	goto	NEXT	;15  

I2GA1	rrf	GR,1	;6 get bit
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9	start new code
	iorlw	OMSK	;10 set to 1
	btfss	TGR,GP	;11
	andlw	AMSK	;12 set to 0
	movwf	PORTA	;13 ** send bit to PIC1
; setting bit in GR is now done in other part
;	btfsc	TGR,GP	;9   
;	bsf	GR,7	;10
;	btfss	TGR,GP	;11
;	bcf	GR,7	;12
;	nop	;13
	goto	NEXT	;15  


;getting byte in other part
I3GA1	btfsc	TGR,GP	;7 fill Get Register
	bsf	GR,7	;8
	btfss	TGR,GP	;9
	bcf	GR,7	;10
	nop	;11
	nop	;12
	nop	;13
	goto	NEXT	;15 


I1S	nop	;4
	nop
	nop
	nop
	nop
	nop
	nop	;10
	nop
	nop
;	nop	
	goto	LAST	;14

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 *
	nop	;14
;	goto	LAST	;15
;duplicate LAST
	btfss	GF,1	;1
	goto	I1GB1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GB1	;4 get bit
	clrf	GF	;5 stop bit
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	LASTA	;8
	andlw	0xf0	;9
	btfss	STATUS,Z	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reversed
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15 (14+14=28 early 5.6 us) ok to be 15 (late)


I4S	movlw	0xa	;9
	movwf	SK
	clrf	SF		;9 inst  43 inst is most close
	nop
	bsf	PORTA,SP	;13 *
	nop	;14
;	goto	LAST	;15
;duplicate LAST
	btfss	GF,1	;1
	goto	I1GB1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GB1	;4 get bit
	clrf	GF	;5 stop bit
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	LASTA	;8
	andlw	0xf0	;9
	btfss	STATUS,Z	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reversed
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15 (14+14=28 early 5.6 us) ok to be 15 (late)


I1GB1	btfsc	GF,0	;4 check for start bit (B)
	goto	I3GB1	;5
	nop	;6
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,0	;8 got sb, get byte next part
	movlw	0xa	;9 
	movwf	GK	;10
	clrf	EIO	;11
	btfsc	GF,1	;12 if got sb, send sb to PIC1
;	bsf	PORTA,PICN1	;** 13 reverse
	;bcf	PORTA,PICN1	;** 13
	nop	;13
	;goto	TOP	;15 should be 14
	nop	;14
;need duplicated TOP
	btfss	GF,0	;1 TOP
	goto	I1GA1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GA1	;4 get bit
	clrf	GF	;5
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	TOPA	;8
	andlw	0xf0	;9
	btfss	STATUS,Z	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reverse
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15	;later finish send stop bit
;end duplicated TOP


I2GB1	rrf	GR,1	;6
	movf	PORTA,0	;7 *
	movwf	TGR	;8
	btfsc	TGR,GP	;9
	iorlw	OMSK	;10 set to 1
	btfss	TGR,GP	;11
	andlw	AMSK	;12 set to 0
	movwf	PORTA	;13 ** send bit to PIC1
	nop	;14
;need duplicated TOP (again)
	btfss	GF,0	;1 TOP
	goto	I1GA1	;2 check for start bit
	decfsz	GK,1	;3
	goto	I2GA1	;4 get bit
	clrf	GF	;5
	movf	GR,0	;6
	btfsc	STATUS,Z	;7 both zeros
	goto	TOPA	;8
	andlw	0xf0	;9
	btfss	STATUS,2	;10
	bsf	EIO,0	;11 bits in high addr
	nop	;12
;	bcf	PORTA,PICN1	;**13 stop for PIC1 reverse
	bsf	PORTA,PICN1	;**13 stop for PIC1
	goto	TOP2	;15	;later finish send stop bit
;end duplicated TOP (again)


;getting byte in other part
I3GB1	btfsc	TGR,GP	;7 fill Get Register
	bsf	GR,7	;8
	btfss	TGR,GP	;9
	bcf	GR,7	;10
	nop	;11
	nop	;12
	goto	TOP	;14

;--------------------------
;byte 1 above, byte 2 below
;--------------------------

I1GA2	btfsc	GF,1	;4  check for start bit
	goto	I3GA2	;5
	nop	;6
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,1	;8 got start bit in next part
	movlw	0xa	;9 
	movwf	GK	;10
	nop	;11
	nop	;12
	nop	;13
	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	;13
	goto	LAST2	;15 

;getting byte in other part
I3GA2	btfss	EIO,7	;7 address=0x00, last bit = 4-16
	goto	I4GA2	;8
	nop	;9
	btfsc	GR2,0	;10 GR2,0 is 0 until last rrf
	bsf	EIO,0	;11
	nop	;12
	nop	;13
	goto	LAST2	;15  

I4GA2	nop	;10
	nop	;11
	nop	;12
	nop	;13
	goto	LAST2	;15  

I1GB2	btfsc	GF,0	;4
	goto	I3GB2	;5
	nop	;6
	btfss	PORTA,GP ;7 *  start bit = 0
	bsf	GF,0	;8 get byte in next part
	movlw	0xa	;9 stop bit - no need to get
	movwf	GK	;10
	nop	;11
	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

;getting byte in other part
I3GB2	btfss	EIO,7	;7
	goto	I4GB2	;8
	btfsc	GR2,0	;9 GR2,0 is 0 until last rrf
	bsf	EIO,0	;10
	nop	;11
	nop	;12
	goto	NEXT2	;14

I4GB2	nop	;10 not addr=0x00
	nop	;11
	nop	;12
	goto	NEXT2	;14

I1I0	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
	bcf	PORTA,EIO0	;11 enable 4-16
	bsf	PORTA,EIO0	;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


I1I1	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
	bcf	PORTA,EIO1	;11 enable 4-16
	bsf	PORTA,EIO1	;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


;=====================================
;initial clearing output port code
;=====================================
SndByt	movlw	8	;1
	movwf	SK	;2
	nop	;3
	nop	;4
	nop	;5
;	bsf	PORTA,PICN1	;*1 start bit  reversed start/stop bit
	bcf	PORTA,PICN1	;*1 start bit
	nop	;2
	movlw	0xb	;3
	movwf	DELA	;4
Dlay1	decfsz	DELA,1	;4+32=36
	goto	Dlay1	;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32
			;9+(11=32)=41
	nop	;37
	nop	;38

SndByt1	movf	PORTA,0	;39
	btfsc	SR,0	;40
	iorlw	OMSK	;41  3 set to 1
	btfss	SR,0	;42
	andlw	AMSK	;43 set to 0
	movwf	PORTA	;*1
	rrf	SR,1	;2 
	movlw	0xa	;3
	movwf	DELA	;4
Dlay2	decfsz	DELA,1	;4+29=33  
	goto	Dlay2	;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32
			;9+(10=29)=38
	nop	;34
	nop	;35	
	decfsz	SK,1	;36
	goto	SndByt1	;38	

;delay 6 and send stop bit
	nop	;38 lost 1 inst from decfsz
	nop	;39
	nop	;40
	nop	;41
	nop	;42
	nop	;43
;	bcf	PORTA,PICN1	;*1 stop bit reversed start/stop bit
	bsf	PORTA,PICN1	;*1 stop bit
	nop	;2
	movlw	0xd	;3
	movwf	DELA	;4
Dlay3	decfsz	DELA,1	;4+38=42  
	goto	Dlay3	;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32,12=35,13=38
			;9+(11=32)=41
	return	;44

;43	;14+15+14=3.0+2.8+2.8=8.6 us (8.6806 us)


	END
