	LIST P = PIC16F628A, R = DEC
	include "p16f628a.inc"

 __CONFIG 3F30h
;interní oscilátor, wdt off, power-up timer on, brown-out off
;komunikační rychlost je 19 200 Bd
;program přijme znak z klávesnice a okamžitě jej odešle na sériový port

TempW	equ	70h
TempSTAT equ	71h
TempFSR	equ	72h
TempPCLATH equ	73h

Bit	equ	20h	;registr určující pořadí právě přijímaného bitu
TempRx	equ	21h	;dočasný registr pro uložení právě přijímaného bytu
RxPS2	equ	22h	;registr pro uložení přijatého bytu
ParTMP	equ	23h	;pomocný registr pro výpočet parity
StatInt	equ	24h	;registr obsahující příznaky

TMP	equ	25h

#define	Chyba	StatInt,0	;příznak chyby
#define	Prijato	StatInt,1	;příznak nového příchozího bytu

#define	Dat	PORTB,4		;datová linka
#define	Clk	PORTB,5		;hodinová linka

	org	0
	goto	START

	org	4
INT	movwf	TempW
	swapf	STATUS,W	
	movwf	TempSTAT
	banksel 0

	btfss	INTCON,RBIF
	goto	END_INT
				;nastalo přerušení od portu B
	movf	PORTB,w		;zrušíme událost - změnu portu - jeho přečtením
	bcf	INTCON,RBIF	;vynulujeme příznak přerušení od portu B

	btfsc	Chyba		;je-li chyba v nule, můžeme pokračovat
	goto	END_INT		;jinak jdeme na konec přerušení
	btfsc	Clk		;je-li hodinová linka v nule, má smysl pokračovat
	goto	END_INT		;jinak se jde zase na konec

;Detekce Start bitu
DetStart
	movlw	.0
	xorwf	Bit,w	;porovnáme, jestli je v proměnné bit 0
	btfss	STATUS,Z	;je-li výsledek operace nula, Z bude v jedničce a tudíž budeme pokračovat na detekci start bitu
	goto	DetPar		;jinak jdeme na detekci parity
	btfsc	Dat	;start bit musí být v nule
	goto	Chyb	;jinak je to chyba
	incf	Bit,f	;start bit je platný, zvýšíme počítadlo bitů o jedničku
	clrf	TempRx	;a vymažeme dočasný registr pro data
	goto	END_INT

;detekce paritního bitu, kontrola parity
DetPar	movlw	.9
	xorwf	Bit,w
	btfss	STATUS,Z
	goto	DetStop		;není to devátý bit, jdi na další kontrolu (stop bit)
	rrf	TempRx,w	;výpočet parity
	xorwf	TempRx,w
	movwf	ParTMP
	swapf	ParTMP,f
	xorwf	ParTMP,f
	movf	ParTMP,w
	rlf	ParTMP,f
	rlf	ParTMP,f
	xorwf	ParTMP,w
	xorlw	B'00000100'	
	movwf	ParTMP		;nyní je v 2. bitu uložena lichá parita

	btfsc	Dat
	goto	DetPar1		;parita klávesnice je 1
				;parita klávesnice je 0
	btfss	ParTMP,2	;kontroluje, jestli je stejná i vypočtená
	goto	DetPar2		;souhlasí - pokračuje  dál
	goto	Chyb		;nesouhlasí - dojde k chybě

DetPar1	btfsc	ParTMP,2	;parita klávesnice je 1,
	goto	DetPar2		;pokud je i vypočtená parita 1, skočí se sem (pokračuje se dál)
	goto	Chyb		;jinak dojde k chybě

DetPar2	incf	Bit,f		;pokračování, v případě, že se parita shoduje
				;inkrementuje se počítadlo bitů a jde se ven
	goto	END_INT

;detekce stop bitu, uložení bytu
DetStop	movlw	.10
	xorwf	Bit,w
	btfss	STATUS,Z
	goto	SunBit		;není to stop bit, jdi na poslední operaci - posun bitů dovnitř
	btfss	Dat		;linka data musí být v jedničce, jinak dojde k chybě
	goto	Chyb		;chyba
	movf	TempRx,w	;přesun dat
	movwf	RxPS2
	bsf	Prijato		;příznak přijetí nového bytu
	clrf	Bit		;vynuluje počítadlo bitů
	goto	END_INT		;a jde na konec

;rotace přijímaných dat dovnitř
SunBit	bcf	STATUS,C	;vynulujeme Carry
	btfsc	Dat
	bsf	STATUS,C	;pokud je datový bit jednička, nastavíme Carry na jedničku
	rrf	TempRx,f	;rotace doprava
	incf	Bit,f		;zvýšíme počítadlo o jedničku
	goto	END_INT

Chyb	bsf	Chyba
END_INT	swapf	TempSTAT,w
	movwf	STATUS
	swapf	TempW,f
	swapf	TempW,w
	retfie
;..............................................................
START	movlw	B'10001000'	;nastaví přerušení
	movwf	INTCON
	movlw	B'10010000'	;nastaví UART
	movwf	RCSTA
	banksel	TRISB
	movlw	B'11110010'	;nastaví porty A i B
	movwf	TRISB
	clrf	TRISA
	movlw	B'00100110'
	movwf	TXSTA
	movlw	.12
	movwf	SPBRG
	banksel	0
	movlw	B'00000111'
	movwf	CMCON
	movf	PORTB,w		;zajistí základní stav portu B pro přerušení

Smycka
	btfsc	Prijato
	goto	Prevod
	btfsc	Chyba
	goto	Err
	goto	Smycka

Prevod	bcf	Prijato
	movf	RxPS2,w
	movwf	TMP
	swapf	TMP,w
	addlw	0Fh
	call	TabHex	;převede první číslo na hex
	call	Send
	movf	TMP,w
	addlw	0Fh
	call	TabHex	;převede druhé číslo na hex
	call	Send
	movlw	'h'	;přidá koncovku h
	call	Send
	movlw	0Dh	;nový řádek
	call	Send
	movlw	0Ah
	call	Send
	goto	Smycka

Err	movlw	'E'	;chyba při přenosu z klávesnice - odešle Err, nový řádek, vynuluje chybu a vrátí se zpět do smyčky
	call	Send
	movlw	'r'
	call	Send
	movlw	'r'
	call	Send
	movlw	0Dh
	call	Send
	movlw	0Ah
	call	Send
	bcf	Chyba
	clrf	Bit
	bcf	Prijato
	goto	Smycka

Send	btfss	PIR1,TXIF
	goto	$-1
	movwf	TXREG
	return

TabHex	addwf	PCL,f	;převod hexa na ASCII
	retlw	'0'
	retlw	'1'
	retlw	'2'
	retlw	'3'
	retlw	'4'
	retlw	'5'
	retlw	'6'
	retlw	'7'
	retlw	'8'
	retlw	'9'
	retlw	'A'
	retlw	'B'
	retlw	'C'
	retlw	'D'
	retlw	'E'
	retlw	'F'

	END