;Program: Monitor 1
;****************************************************************************
	LIST P = 16F84,	R = DEC
	#INCLUDE <P16F84.INC>
;----------------------------------------------------------------------------
 __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;****************************************************************************
RAM	EQU	H'0C'
;----------------------------------------------------------------------------
RBF	EQU	RAM
RBF1	EQU	RAM+1
NUM	EQU	RAM+2
POM	EQU	RAM+3
TMP	EQU	RAM+4
TM0	EQU	RAM+5
TM1	EQU	RAM+6
TM2	EQU	RAM+7
JEDN	EQU	RAM+8
DES	EQU	RAM+9
STA	EQU	RAM+10

#define	Q	PORTB,0
#define	RS	PORTB,1	
#define	RW	PORTB,2
#define	E	PORTB,3
#define	BF	RBF,3
#define	ZVUK	PORTB,4

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	ORG	0
	GOTO	START
;****************************************************************************
;PODPROGRAMY
;****************************************************************************
INILCD	CALL	t15mS		;doba 15 milisekund
	BCF	RS
	BCF	RW
	CALL	A_OUT		;port A výstup
	BSF	E
	MOVLW	B'00000011'
	MOVWF	PORTA
	BCF	E
	CALL	t4mS		;doba 4 milisekund
	BSF	E
	MOVLW	B'00000011'
	MOVWF	PORTA
	BCF	E
	CALL	t100uS		;doba 100 mikrosekund
	BSF	E
	MOVLW	B'00000011'
	MOVWF	PORTA
	BCF	E
	CALL	t100uS		;doba 100 mikrosekund
	MOVLW	B'00101000'
	CALL	WRPRI		;4.bitová komunikace a dva řádky
	MOVLW	B'00001000'
	CALL	WRPRI		;displej OFF
	MOVLW	B'00001100'
	CALL	WRPRI		;displej ON, kurzor OFF, blikání OFF
	MOVLW	B'00000110'
	CALL	WRPRI		;inkrementace, normální operace
	RETURN
;----------------------------------------------------------------------------
WRDATA	BSF	RS		;nastavení bitu RS pro zápis dat
	GOTO	$+2
WRPRI	BCF	RS		;nastavení bitů RS a RW pro zápis příkazu
	BCF	RW
	MOVWF	TMP		;číslo příkazu nebo data do registru TMP
	CALL	A_OUT		;portA jako výstup
	SWAPF	TMP,W		;horní 4 bity do registru W
	BSF	E
	MOVWF	PORTA		;zápis 4 horních bitů do displeje
	BCF	E
	MOVFW	TMP		;obsah registru TMP do registru W
	BSF	E
	MOVWF	PORTA		;zápis dolních 4 bitů do displeje
	BCF	E
	CALL	T_BF		;testování bitu BF
	RETURN
;----------------------------------------------------------------------------	

T_BF	BCF	RS		;podprogram testuje konec operace (bit BF)
	BSF	RW
	CALL	A_IN		;portA vstup (po ukončení zase výstup)
	BSF	E
	MOVFW	PORTA
	MOVWF	RBF
	BCF	E
	NOP
	BSF	E
	MOVFW	PORTA
	MOVWF	RBF1
	BCF	E
	BTFSC	BF		;je bit BF=0 ? (0 = konec operace)
	GOTO	$-10		;ne - testuj znova
;----------------------------------------------------------------------------
A_OUT	MOVLW	B'11110000'	;pin A0/A3 výstup, pin A4 vstup
	GOTO	$+2
A_IN	MOVLW	B'11111111'	;pin A0/A7 vstup
	BSF	STATUS,RP0	;banka 1
	MOVWF	TRISA		;nastavení portu A
	BCF	STATUS,RP0	;banka 0
	RETURN
;****************************************************************************
t15mS	MOVLW	49		;doba 15 milisekund
	GOTO	$+2
t4mS	MOVLW	14		;doba 4 milisekund
	MOVWF	TM1
	MOVLW	255
	MOVWF	TM2
	DECFSZ	TM2,F
	GOTO	$-1
	DECFSZ	TM1,F
	GOTO	$-5
	RETURN
;----------------------------------------------------------------------------
t100uS	MOVLW	83		;doba 100 mikrosekund
	MOVWF	TM1
	DECFSZ	TM1,F
	GOTO	$-1
	RETURN
;---------------------------------------------------------------
t100mS	MOVLW	160		;doba 100 milisekund
	MOVWF	TM1
	MOVLW	207
	MOVWF	TM2
	DECFSZ	TM2,F
	GOTO	$-1
	DECFSZ	TM1,F
	GOTO	$-5
	RETURN
;---------------------------------------------------------------
t500mS	CLRF	TM2		;doba 500 milisekund
	CLRF	TM1
	NOP
	DECFSZ	TM1,F
	GOTO	$-2
	NOP
	DECFSZ	TM1,F
	GOTO	$-2
	DECFSZ	TM2,F
	GOTO	$-7
	RETURN
;***************************************************************
PREVOD	MOVFW	NUM		;převede registr NUM na jednotky desítky a stovky
	MOVWF	POM		;obsah registru NUM do POM
	CLRF	DES		;vynulování desítek
	CLRF	STA		;vynulování stovek
	MOVLW	100
	SUBWF	NUM,W		;registr W=NUM-100
	BTFSS	STATUS,C	;došlo k podtečení?
	GOTO	$+4		;ano,proveď skok dopředu
	MOVWF	NUM		;ne,obsah W do NUM
	INCF	STA,F		;řád stovek + 1
	GOTO	$-6		;proveď skok zpět
	MOVLW	10
	SUBWF	NUM,W		;registr W=NUM-10
	BTFSS	STATUS,C	;došlo k podtečení?
	GOTO	$+4		;ano,proveď skok
	MOVWF	NUM		;ne,obsah W do NUM
	INCF	DES,F		;řád desítek + 1
	GOTO	$-6		;proveď skok zpět
	MOVFW	NUM
	MOVWF	JEDN		;zbytek po odečítání do registru JEDN
	MOVLW	48
	ADDWF	JEDN,F		;registr JEDN + 48
	ADDWF	DES,F		;registr DES + 48
	ADDWF	STA,F		;registr STA + 48
	MOVFW	POM
	MOVWF	NUM		;obnova registru NUM
	RETURN
;***************************************************************
PIP	MOVLW	30		;pípnutí při stisku klávesy
	MOVWF	TM2
	BSF	ZVUK
	CALL	PIP1
	BCF	ZVUK
	CALL	PIP1
	DECFSZ	TM2,F
	GOTO	$-5
	RETURN
;----------------------------------------------------------
PIP1	MOVLW	100
	MOVWF	TM0
	MOVLW	150
	MOVWF	TM1
	DECFSZ	TM1,F
	GOTO	$-1
	DECFSZ	TM0,F
	GOTO	$-1
	RETURN
;**************************************************************
ZOBR	MOVLW	1		;zobrazí stovky,desítky a jednotky na displeji
	CALL	WRPRI
	MOVFW	STA
	CALL	WRDATA
	MOVFW	DES
	CALL	WRDATA
	MOVFW	JEDN
	CALL	WRDATA
	RETURN
;**************************************************************
SAVE	MOVWF	EEADR		;obsah registru W do registru EEADR
	MOVFW	NUM
	MOVWF	EEDATA		;obsah registru NUM do registru EEDATA
	BSF	STATUS,RP0	;banka 1
	BSF	EECON1,WREN	;zápis do EEPROM povolen
	MOVLW	H'55'
	MOVWF	EECON2		;první zápis bezpečnostního kódu
	MOVLW	H'AA'
	MOVWF	EECON2		;druhý zápis bezpečnostního kódu
	BSF	EECON1,WR
	BTFSS	EECON1,EEIF	;je zápis ukončen?
	GOTO	$-1		;ne,čekej
	BCF	EECON1,EEIF	;bit EEIF vynulován
	BCF	EECON1,WREN	;zápis do EEPROM zakázán
	BCF	STATUS,RP0	;banka 0
	RETURN
;--------------------------------------------------------------
LOAD	MOVWF	EEADR		;obsah registru W do registru EEADR
	BSF	STATUS,RP0	;banka 1
	BSF	EECON1,RD	;přečti data
	BCF	STATUS,RP0	;banka 0
	MOVFW	EEDATA
	MOVWF	NUM		;zapiš data do registru NUM
	RETURN
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

START	BSF	STATUS,RP0	;banka 1
	MOVLW	B'11100001'
	MOVWF	TRISB		;nastavení portu B (B7=IN)
	BCF	STATUS,RP0	;banka 0
	CALL	INILCD		;inicializace displeje
	MOVLW	1
	CALL	WRPRI		;reset displeje

	CLRW			;registr W=0

	CALL	LOAD		;přečti data z adresy

	CALL	PREVOD		;převeď registr NUM na jednotky,desítky a stovky

	CALL	ZOBR		;výsledek zobrazit na displeji

	MOVLW	192
	CALL	WRPRI		;nastavení adresy DDRAM displeje
	MOVLW	48
	CALL	WRDATA		;tisk "0"
	MOVLW	63
	CALL	WRDATA		;tisk "?"
	MOVLW	32
	CALL	WRDATA		;tisk mezery
	MOVLW	45
	CALL	WRDATA		;tisk "-"

SEM	MOVLW	197
	CALL	WRPRI		;nastavení adresy DDRAM displeje
	MOVLW	'A'
	CALL	WRDATA		;tisk "A"
	MOVLW	'N'
	CALL	WRDATA		;tisk "N"
	MOVLW	'O'
	CALL	WRDATA		;tisk "O"

	CALL	PIP		;pípnutí

	CALL	t500mS		;doba 500 mS

	CLRF	PORTA
	BTFSC	Q		;je stisknuto TL1 (ENTER)?
	GOTO	VYMAZ		;ano,jdi na VYMAZ

	MOVLW	1
	MOVWF	PORTA
	BTFSS	Q		;je stisknuto TL2 (SET)?
	GOTO	$-6		;ne,tak testuj tlačítka znovu

	MOVLW	197
	CALL	WRPRI		;nastavení adresy DDRAM displeje
	MOVLW	'N'
	CALL	WRDATA		;tisk "N"
	MOVLW	'E'
	CALL	WRDATA		;tisk "E"
	MOVLW	32
	CALL	WRDATA		;tisk mezery

	CALL	PIP		;pípnutí

	CALL	t500mS		;doba 500 mS

	CLRF	PORTA
	BTFSC	Q		;je stisknuto tlačítko TL1 (ENTER)?
	GOTO	PROG		;ano,jdi na PROG

	MOVLW	1
	MOVWF	PORTA
	BTFSS	Q		;je stisknuto tlačítko TL2 (SET)?
	GOTO	$-6		;ne,tak testuj znovu
	GOTO	SEM		;ano,jdi na SEM

PROG	CALL	PIP		;pípnutí

PROG_1	CLRW			;vynulování registru W

	CALL	LOAD		;nahrání dat z adresy 0 EEPROM

	CALL	PREVOD		;převod registru NUM na jednotky,desítky a stovky

	CALL	ZOBR		;zobrazit na displeji

	BTFSS	PORTB,7		;je na pinu B stav 1?
	GOTO	$-1		;ne,tak testuj znovu

	CALL	t100mS		;doba 100 milisekund

	BTFSC	PORTB,7		;je na pinu B7 stav 0?
	GOTO	$-1		;ne,tak testuj znovu

	CALL	t100mS		;doba 100 milisekund

	INCF	NUM,F		;registr NUM + 1

	CLRW			;vynuluj registr W

	CALL	SAVE		;ulož data z registru NUM na adresu 0 EEPROM
	GOTO	PROG_1		;jdi na návěští PROG_1
;---------------------------------------------------------------

VYMAZ	CLRF	NUM		;vynulování registru NUM

	CLRW			;vynulování registru W

	CALL	SAVE		;ulož data z registru NUM na adresu 0 EEPROM
	GOTO	PROG		;jdi na návěští PROG
;***************************************************************
	END
