;******************************************************************************
;                         DIGITAL FREQUENCY COUNTER
;                           
;******************************************************************************
;
;
RS	equ	0x2
RW	equ	0x1
EN	equ	0x0
;
gate	equ	0x20
cnt1	equ	0x21
cnt2	equ	0x22
cnt3	equ	0x23
TMR02	equ	0x24
count1	equ	0x25
count2	equ	0x26
;
	org	0x00
	goto	start
			
;
int_del	movlw	0x05		;delay 5.000 ms (4 MHz clock)
	movwf	count1
d1	movlw	0xA5
	movwf	count2
d2	decfsz	count2, f
	goto	d2
	decfsz	count1, f
	goto	d1
	retlw	0x00
;
lcd_dat	movwf	PORTB		;load data into PORTB
	bsf	STATUS, RP0   	; select Register-Page 1**************************
	movlw	b'00000000'	;define PORTB as output
	movwf	TRISB
	bcf	STATUS, RP0	; select Register-Page 0 ************************
	bsf	PORTA, RS	;rs = data
	bcf	PORTA, RW	;r/w = write
	bsf	PORTA, EN	;toggle enable
	bcf	PORTA, EN
	bsf	STATUS, RP0   	; select Register-Page 1**************************
	movlw	b'11111111'	;define PORTB as input
	movwf	TRISB
	bcf	STATUS, RP0  	; select Register-Page 0 ************************
	bcf	PORTA, RS	;rs = instruction
	bsf	PORTA, RW	;r/w = read
out1	bsf	PORTA, EN	;enable high
	btfss	PORTB, 7	;test busy flag
	goto	out2
	bcf	PORTA, EN	;enable low
	goto	out1
out2	bcf	PORTA, EN	;enable low
	retlw	0x00
;
lcd_com	movwf	PORTB		;load instruction into PORTB
	bsf	STATUS, RP0   	; select Register-Page 1**************************
	movlw	b'00000000'	;define PORTB as output
	movwf	TRISB
	bcf	STATUS, RP0  	; select Register-Page 0 ************************
	bcf	PORTA, RS	;rs = instruction
	bcf	PORTA, RW	;r/w = write
	bsf	PORTA, EN	;toggle enable
	bcf	PORTA, EN
	bsf	STATUS, RP0   	; select Register-Page 1**************************
	movlw	b'11111111'	;define PORTB as input
	movwf	TRISB
	bcf	STATUS, RP0  	; select Register-Page 0 ************************
	bsf	PORTA, RW	;r/w = read
inst1	bsf	PORTA, EN	;enable high
	btfss	PORTB, 7	;test busy flag
	goto	inst2
	bcf	PORTA, EN	;enable low
	goto	inst1
inst2	bcf	PORTA, EN	;enable low
	retlw	0x00
;
count	bcf	PORTA, 3
	bcf	PORTA, 2
	clrf	cnt3
	clrf	TMR0
	clrf	TMR02
	bsf	PORTA, 2	;toggle TMR0 pin
	bcf	PORTA, 2
	movf	gate, w		;get gate time
	movwf	count1
	bsf	PORTA, 3	;start count
fr4	movlw	0xFA
	movwf	count2
	goto	fr6
fr5	nop
	nop
	nop
	nop
	nop
	nop
fr6	movf	TMR0, w		;test for TMR0 rollover (12)
	subwf	TMR02, f	; TMR02 = TMR02 - W(TMR0)
	btfss	STATUS, z	; TMR02 == 0?
	goto	fr7		; nem
	nop
	goto	fr8
fr7	btfsc	STATUS, c	; TMR02 > 0?
	incf	cnt3, f		; igen
fr8	movwf	TMR02		; TMR02 = TMR0
	nop
	nop
	nop
	decfsz	count2, f
	goto	fr5
	decfsz	count1, f
	goto	fr4
	bcf	PORTA, 3	;stop count
	movf	TMR0, w		;get TMR0 count
	movwf	cnt2
	subwf	TMR02, f	;test for TMR0 rollover
	btfss	STATUS, c
	goto	fr9
	btfss	STATUS, z
	incf	cnt3, f
fr9	clrf	cnt1		;set to get prescaler count
fr10	decf	cnt1, f
	bsf	PORTA, 2	;toggle TMR0 pin
	bcf	PORTA, 2
	movf	TMR0, w		;test if TMR0 has changed
	xorwf	cnt2, w
	btfsc	STATUS, z
	goto	fr10
	retlw	0x00
;
cnvt	movlw	0x00		; BCD nullazas
	movwf	0x2c
	movwf	0x2d
	movwf	0x2e
	movwf	0x2f
	movwf	0x30
	movwf	0x31
	movwf	0x32
	movwf	0x33
;
	movlw	24		; kulso ciklus 24
	movwf	count2
big5	movlw	0x2c		; nagyobb-e 5-nel ciklus
	movwf	FSR		; bcd kezdo cim
big51	movlw	5
	subwf	INDF, w		; bcd szam - 5	
	btfss	STATUS, c	; bcd >= 5
	goto	big5-v		; nem
	movlw	3		; nagyobb, tehat +3
	addwf	INDF, f
big5-v	incf	FSR, f 
	movlw	0x34		
	xorwf	FSR, w
	btfss	STATUS, z	; nagyobb-e 5-nel ciklus vege
	goto	big51
rot	movlw	0x2c		; balra leptet ciklus
	movwf	FSR
rot1	bcf	STATUS, c	; clear carry bit
	rlf	INDF, f
	bcf	INDF, 4		; nem kell az 5. bit
	incf	FSR, f
	btfss	INDF, 3
	goto	rot-v
	decf	FSR, f
	bsf	INDF, 0	
	incf	FSR, f 
rot-v	movlw	0x33		
	xorwf	FSR, w
	btfss	STATUS, z	; balra leptet ciklus vege
	goto	rot1
	bcf	STATUS, c	; clear carry bit
	rlf	INDF, f
	bcf	INDF, 4		; nem kell az 5. bit
	btfss	cnt3, 7
	goto	rot_1
	bsf	INDF, 0	
rot_1	bcf	STATUS, c	; clear carry bit
	rlf	cnt3, f
	btfss	cnt2, 7
	goto	rot_2
	bsf	cnt3, 0	
rot_2	bcf	STATUS, c	; clear carry bit
	rlf	cnt2, f
	btfss	cnt1, 7
	goto	rot_3
	bsf	cnt2, 0	
rot_3	bcf	STATUS, c	; clear carry bit
	rlf	cnt1, f
	decfsz	count2, f	; kulso ciklus vege
	goto	big5
;
ascii	movlw	0x30
	addwf	0x2c, f
	addwf	0x2d, f
	addwf	0x2e, f
	addwf	0x2f, f
	addwf	0x30, f
	addwf	0x31, f
	addwf	0x32, f
	addwf	0x33, f
;
	retlw	0x00
;
;******************************************************************************
;                                   START
;******************************************************************************
;
start	movlw	7
	movwf	CMCON
	bsf	STATUS, RP0   	; select Register-Page 1 ****************************
	movlw	b'00110111'	; TMR0 = ext, 1/256
	movwf	OPTION_REG
	movlw	b'00010000'	; RA4 input
	movwf	TRISA
	movlw	b'00000000'	; RB output
	movwf	TRISB
	bcf	STATUS, RP0	; select Register-Page 0 ****************************
	call	int_del		; 15ms delay for LCD
	call	int_del
	call	int_del
	bsf	PORTB,	4	; 3x 0x30 out + 5ms delay
	bsf	PORTB,	5	
	bsf	PORTA, EN	;toggle enable
	bcf	PORTA, EN
	call	int_del
	bsf	PORTA, EN	;toggle enable
	bcf	PORTA, EN
	call	int_del
	bsf	PORTA, EN	;toggle enable
	bcf	PORTA, EN
	call	int_del
	movlw	0x38		;8bit display, 2 row, 5x8 font
	call	lcd_com
	movlw	b'00001100'	;display on, cursor off, blink cursor off
	call	lcd_com
	movlw	b'00000001'	;clear display
	call	lcd_com
	movlw	b'00000110'	;cursor forward
	call	lcd_com
	
	call	copyright
		
mhz	movlw	0x14		;0.1 sec gate
	movwf	gate
	call	count
	call	cnvt		;convert binary to BCD
	movlw	0x30		;test if "0"
	xorwf	0x2D, w
	btfss	STATUS, z
	goto	mhz1		; nem
	movlw	0x30		;test if "0"
	xorwf	0x2E, w
	btfsc	STATUS, z
	goto	khz1		; igen
mhz1	movlw	0x82		;set display address
	call	lcd_com
	movlw	0x02		;output first 2 characters
	movwf	count1
	movlw	0x2D		;MSD of freq
	movwf	fsr
mhz2	movlw	0x30		;test if "0"
	xorwf	INDF, w
	btfss	STATUS, z
	goto	mhz3
	movlw	0x20		;change preceeding "0's" to "space"
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	mhz2
	goto	mhz4
mhz3	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	mhz3
mhz4	movlw	0x2E		;"."
	call	lcd_dat
	movlw	0x05		;output last 5 characters
	movwf	count1	
mhz5	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	mhz5
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x4D		;"M"
	call	lcd_dat
	movlw	0x48		;"H"
	call	lcd_dat
	movlw	0x7A		;"z"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	goto	mhz
;
khz	movlw	0x14		;0.1 sec gate
	movwf	gate
	call	count
	call	cnvt		;convert binary to BCD
	movlw	0x30		;test if 0
	xorwf	0x2D, w
	btfss	STATUS, z
	goto	mhz1
	movlw	0x32		;test if < 2
	subwf	0x2E, w
	btfsc	STATUS, c
	goto	mhz1
	movlw	0x30		;test if "0"
	xorwf	0x2E, w
	btfss	STATUS, z
	goto	khz1
	movlw	0x30		;test if "0"
	xorwf	0x2F, w
	btfsc	STATUS, z
	goto	xkhz
khz1	movlw	0x82		;set display address
	call	lcd_com
	movlw	0x05		;output first 5 characters
	movwf	count1
	movlw	0x2D		;MSD of freq
	movwf	fsr
khz2	movlw	0x30		;test if "0"
	xorwf	INDF, w
	btfss	STATUS, z
	goto	khz3
	movlw	0x20		;change preceeding "0's" to "space"
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	khz2
	goto	khz4
khz3	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	khz3
khz4	movlw	0x2E		;"."
	call	lcd_dat
	movf	INDF, w		;output last 2 characters
	call	lcd_dat
	incf	fsr, f
	movf	INDF,w
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x4B		;"K"
	call	lcd_dat
	movlw	0x48		;"H"
	call	lcd_dat
	movlw	0x7A		;"z"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	goto	khz
;
xkhz	movlw	0xC8		;1 sec gate
	movwf	gate
	call	count
	call	cnvt		;convert binary to BCD
	movlw	0x30		;test if 0
	xorwf	0x2D, w
	btfss	STATUS, z
	goto	khz
	movlw	0x32		;test if < 2
	subwf	0x2E, w
	btfsc	STATUS, c
	goto	khz
	movlw	0x30		;test if 0
	xorwf	0x2E, w
	btfss	STATUS, z
	goto	xkhz1
	movlw	0x30		;test if 0
	xorwf	0x2F, w
	btfsc	STATUS, z
	goto	hz0
xkhz1	movlw	0x82		;set display address
	call	lcd_com
	movlw	0x04		;output first 4 characters
	movwf	count1
	movlw	0x2D		;MSD of freq
	movwf	fsr
xkhz2	movlw	0x30		;test if "0"
	xorwf	INDF, w
	btfss	STATUS, z
	goto	xkhz3
	movlw	0x20		;change preceeding "0's" to "space"
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	xkhz2
	goto	xkhz4
xkhz3	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	xkhz3
xkhz4	movlw	0x2E		;"."
	call	lcd_dat
	movf	INDF, w		;output last 3 characters
	call	lcd_dat
	incf	fsr, f
	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	movf	INDF, w
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x4B		;"K"
	call	lcd_dat
	movlw	0x48		;"H"
	call	lcd_dat
	movlw	0x7A		;"z"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	goto	xkhz
;
hz	movlw	0xC8		;1 sec gate
	movwf	gate
	call	count
	call	cnvt		;convert binary to BCD
	movlw	0x30		;test if "0"
	xorwf	0x2D, w
	btfss	STATUS, z
	goto	xkhz1
	movlw	0x30		;test if "0"
	xorwf	0x2E, w
	btfss	STATUS, z
	goto	xkhz1
	movlw	0x32		;test if < 2
	subwf	0x2F, w
	btfsc	STATUS, c
	goto	xkhz1
hz0	movlw	0x82		;set display address
	call	lcd_com
	movlw	0x07		;output first 7 characters
	movwf	count1
	movlw	0x2D		;MSD of freq
	movwf	fsr
hz1	movlw	0x30		;test if "0"
	xorwf	INDF, w
	btfss	STATUS, z
	goto	hz2
	movlw	0x20		;change preceeding "0's" to "space"
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	hz1
	goto	hz3
hz2	movf	INDF, w
	call	lcd_dat
	incf	fsr, f
	decfsz	count1, f
	goto	hz2
hz3	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x48		;"H"
	call	lcd_dat
	movlw	0x7A		;"z"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	movlw	0x20		;"space"
	call	lcd_dat
	goto	hz
;
copyright	
	movlw	0x40		; uj karakter beir 40-47 -ig. ez ASCII 0
	call	lcd_com
	movlw	0x08		;
	call	lcd_dat
	movlw	0x14		;
	call	lcd_dat
	movlw	0x16		;
	call	lcd_dat
	movlw	0x1F		;
	call	lcd_dat
	movlw	0x16		;
	call	lcd_dat
	movlw	0x16		;
	call	lcd_dat
	movlw	0x15		;
	call	lcd_dat
	movlw	0x00		;
	call	lcd_dat
	movlw	0xCF		;display address
	call	lcd_com
	movlw	0x00		;"copyright"
	call	lcd_dat
	retlw	0x00
;
	end
