
;**************************************************************************
;*                             hodiny                                     *
;**************************************************************************
;*          4 digit LED display connected to PIC                          *
;*          2 buttons used                                                *
;**************************************************************************
;*          v 2.02 - 22.06.2009                                           *
;**************************************************************************
;*          Hardw.: PIC16F628A used                                       *
;*          OSC.......: External osc. used                                *
;*          POWER.....:  3x1,2V accu                                      *
;**************************************************************************

W                            EQU     H'0000'
F                            EQU     H'0001'

;----- Register Files------------------------------------------------------

INDF                         EQU     H'0000'
TMR0                         EQU     H'0001'
PCL                          EQU     H'0002'
STATUS                       EQU     H'0003'
FSR                          EQU     H'0004'
PORTA                        EQU     H'0005'
PORTB                        EQU     H'0006'

INTCON                       EQU     H'000B'
OPTION_REG                   EQU     H'0081'
TRISA                        EQU     H'0085'
TRISB                        EQU     H'0086'
CMCON                        EQU     H'001F'

PCON                         EQU     H'008E'
PIR1                         EQU     H'000C'	;bank0
PIE1                         EQU     H'008C'	;bank1
T2CON                        EQU     H'0012'	;bank0

TMR2                         EQU     H'0011'	;bank0
PR2			     EQU     H'0092'	;bank1

;----- STATUS Bits --------------------------------------------------------
IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'

;==========================================================================
;
;       RAM Definition
;
;==========================================================================

    __MAXRAM H'01FF'
    __BADRAM H'07'-H'09', H'0D', H'13'-H'14', H'1B'-H'1E'
    __BADRAM H'87'-H'89', H'8D', H'8F'-H'91', H'93'-H'97', H'9E'
    __BADRAM H'105', H'107'-H'109', H'10C'-H'11F', H'150'-H'16F'
    __BADRAM H'185', H'187'-H'189', H'18C'-H'1EF'

;==========================================================================
;
;       Configuration Bits
;
;==========================================================================

_BODEN_ON                    EQU     H'3FFF'
_BODEN_OFF                   EQU     H'3FBF'
_CP_ALL                      EQU     H'03FF'
_CP_75                       EQU     H'17FF'
_CP_50                       EQU     H'2BFF'
_CP_OFF                      EQU     H'3FFF'
_DATA_CP_ON                  EQU     H'3EFF'
_DATA_CP_OFF                 EQU     H'3FFF'
_PWRTE_OFF                   EQU     H'3FFF'
_PWRTE_ON                    EQU     H'3FF7'
_WDT_ON                      EQU     H'3FFF'
_WDT_OFF                     EQU     H'3FFB'
_LVP_ON                      EQU     H'3FFF'
_LVP_OFF                     EQU     H'3F7F'
_MCLRE_ON                    EQU     H'3FFF'
_MCLRE_OFF                   EQU     H'3FDF'
_ER_OSC_CLKOUT               EQU     H'3FFF'
_ER_OSC_NOCLKOUT             EQU     H'3FFE'
_INTRC_OSC_CLKOUT            EQU     H'3FFD'
_INTRC_OSC_NOCLKOUT          EQU     H'3FFC'
_EXTCLK_OSC                  EQU     H'3FEF'
_LP_OSC                      EQU     H'3FEC'
_XT_OSC                      EQU     H'3FED'
_HS_OSC                      EQU     H'3FEE'


;	__CONFIG        _BODEN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
	__CONFIG        _BODEN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _XT_OSC


;==========================================================================
;       Variable Definition
;==========================================================================
;INPUTS
SW1		EQU     H'00'		;SW1 is triggering RA0
SW2		EQU     H'01'		;SW2 is triggering RA1
SW3		EQU     H'02'		;SW3 is triggering RA2
SW4		EQU     H'03'		;SW4 is triggering RA3
TIMER1		EQU	H'20'		;Used in delay routine
TIMER2		EQU	H'21'		; "	"	"	
dataA		EQU	H'22'
dataB		EQU	H'23'
TIMER3		EQU	H'24'		;Used in interrupt routine
TIMER4		EQU	H'25'		; "	"	"	
digit1		EQU	H'26'
digit2		EQU	H'27'
digit3		EQU	H'28'
digit4		EQU	H'29'
num1		EQU	H'2A'
num2		EQU	H'2B'
num3		EQU	H'2C'
num4		EQU	H'2D'

numx		EQU	H'2E'

c_desat		EQU	H'2F'
c_sest		EQU	H'30'

TIMER5		EQU	H'31'		;used for buttons

w_save		EQU	H'32'
s_save		EQU	H'33'
min_overflow	EQU	H'34'

cd_jenna	EQU	H'35'
;==========================================================================

		ORG	0		;Reset vector address
		GOTO	RESET		;goto RESET routine when boot.

		ORG	004
		goto	int_serv

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;	       **********************************
;              **  RESET :  main boot routine  **
;              **********************************

RESET		MOVLW	B'00000111'	;Disable Comparator module's
		MOVWF	CMCON
		;
		BSF	STATUS,RP0	;Switch to register bank 1
					;Disable pull-ups
					;INT on rising edge
					;TMR0 to CLKOUT
					;TMR0 Incr low2high trans.
					;Prescaler assign to Timer0
					;Prescaler rate is 1:256
		MOVLW	B'11010111'	;Set PIC options (See datasheet).
		MOVWF	OPTION_REG	;Write the OPTION register.

		clrf	INTCON		;disable interrupts

		MOVLW	B'01000000'	;RBx = 1 -> input; RBx = 0 -> output
		MOVWF	TRISB
		MOVLW	B'11110000'	;RAx = 1 -> input; RAx = 0 -> output
		MOVWF	TRISA

		bsf	PCON,D'003'	;set 4MHz oscillatory frequency


		movlw	D'199'		;instead of theoretical 200
		movwf	PR2


		BCF	STATUS,RP0	;Switch Back to reg. Bank 0
;----------------------------------------------------------------------------
;wait few seconds - if reprogramming will be required

		movlw	B'11111010'
		movwf	PORTA
		movlw	B'00000010'
		movwf	PORTB
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2

		movlw	B'11110101'
		movwf	PORTA
		movlw	B'00000010'
		movwf	PORTB
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2

		movlw	B'11111010'
		movwf	PORTA
		movlw	B'00000010'
		movwf	PORTB
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2

		movlw	B'11110101'
		movwf	PORTA
		movlw	B'00000010'
		movwf	PORTB
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2
		call	d2


		BSF	STATUS,RP0	;Switch to register bank 1
		MOVLW	B'00000000'	;RBx = 1 -> input; RBx = 0 -> output
		MOVWF	TRISB
		BCF	STATUS,RP0	;Switch Back to reg. Bank 0

; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; XXXXXXXXXX       init            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

;initialization
		clrf	num1
		clrf	num2
		clrf	num3
		clrf	num4

		movlw	D'010'
		movwf	c_desat
		movlw	D'006'
		movwf	c_sest
		movlw	B'01100000'
		movwf	cd_jenna

		movlw	D'050'
		movwf	TIMER3
		movlw	D'050'
		movwf	TIMER4

		movlw	D'050'
		movwf	TIMER5

;set-up interrupts -----------------------------------------------------------------
		clrf	INTCON		;disable all interrupts

		BSF	STATUS,RP0
		movlw	B'00000010'	;enable TIMER2 interrupt
		movwf	PIE1
		BCF	STATUS,RP0

		clrf	T2CON
		clrf	TMR2

		movlw	B'11000000'	;enable interrupts & peripheral interrupts
		movwf	INTCON		;set-up interrupts

;set-up TIMER2
;prescaler: 1:4
;postscaler: 1:15
;timer on
		movlw	B'01110101'
		movwf	T2CON

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;x                        main display routine                             x
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

main		call	main2
;digit #4 -------------------------------------------------------------
		clrf	PORTB

		movlw	B'11111110'
		movwf	PORTA

		movf	digit4,0
		call	ddrr2

		call	main2
;digit #3 -------------------------------------------------------------
		movlw	B'11111101'
		movwf	PORTA

		movf	digit3,0
		call	ddrr2

		call	main2
;digit #2 -------------------------------------------------------------
		movlw	B'11111011'
		movwf	PORTA

		bsf	digit2,D'000'
		movf	digit2,0

		call	ddrr2

		call	main2
;digit #1 -------------------------------------------------------------
		movlw	B'11110111'
		movwf	PORTA

		movf	digit1,0
		call	ddrr2

		goto	main

;----------------------------------------------------------------------
ddrr2		movwf	PORTB

		xorwf	cd_jenna,0
		btfsc	STATUS,D'002'
		goto	call_dr_ft
		call	delay_routine
		goto	fin1
call_dr_ft	call	del_rout_fast
fin1		clrf	PORTB
		return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;x             interrupt service routine                              x
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;
;TIMER2 input is int.osc./4

int_serv
;save STATUS & W
		bcf	INTCON,D'007'

		movwf	w_save
		swapf	STATUS, w
		movwf	s_save
;main interrupt routine

		DECFSZ  TIMER3,F
		goto	nyncen
		movlw	D'050'
		movwf	TIMER3
		DECFSZ  TIMER4,F
		goto	nyncen

		movlw	D'100'
irc11		movwf	TIMER4

		clrf	TMR2

		call	tik_tak

;restore STATUS & W
nyncen
		swapf	s_save,w
		movwf	STATUS
		swapf	w_save, f
		swapf	w_save, w

		bcf	PIR1,D'001'		;clear the TMR2IF flag

		bsf	INTCON,D'007'
		retfie

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;
;		*********************************************
;		*               delay routine               *
;		*********************************************
delay_routine	MOVLW   D'2'
		MOVWF   TIMER2
DEL_LOOP1       MOVLW   D'200'
		MOVWF   TIMER1
DEL_LOOP2       DECFSZ  TIMER1,F
                GOTO    DEL_LOOP2
                DECFSZ  TIMER2,F
                GOTO    DEL_LOOP1
		return

del_rout_fast	MOVLW   D'2'
		MOVWF   TIMER2
DEL_LOOPf1	MOVLW   D'090'
		MOVWF   TIMER1
DEL_LOOPf2	DECFSZ  TIMER1,F
                GOTO    DEL_LOOPf2
                DECFSZ  TIMER2,F
                GOTO    DEL_LOOPf1
		return
;----------------------------------------------------------------------------

d2		MOVLW   D'255'
		MOVWF   TIMER2
DEL_LOOP21	MOVLW   D'255'
		MOVWF   TIMER1
DEL_LOOP22	DECFSZ  TIMER1,F
                GOTO    DEL_LOOP22
                DECFSZ  TIMER2,F
                GOTO    DEL_LOOP21
		return
;----------------------------------------------------------------------------
main2		call	c_button
		call	c_step2
		return
;----------------------------------------------------------------------------
;called from interrupt routine - once a minute

tik_tak		call	inc_minutes
		btfsc	min_overflow,D'000'
		call	inc_hours

;in case of "running too fast" an additional dalay could be added here...
;
;

		return
;--------------------------------------------------
;increment minute timers (counts from 00 - 59)
;at overflow a bit 0 of min_overflow is set

inc_minutes	bcf	min_overflow,D'000'
		incf	num4,1
		movf	num4,0
		xorwf	c_desat,0
		btfss	STATUS,D'002'
		goto	tt_ret
;sme cez desat
		clrf	num4
		incf	num3,1
		movf	num3,0
		xorwf	c_sest,0
		btfss	STATUS,D'002'
		goto	tt_ret
;sme cez 59
		clrf	num3
		bsf	min_overflow,D'000'
		return
;-------------------------------------------------
;increment hour timers (counts from 00 - 23)
;
inc_hours	incf	num2,1

		btfsc	num1,D'001'
		goto	test_24
;test
		movf	num2,0
		xorwf	c_desat,0
		btfss	STATUS,D'002'
		goto	tt_ret

		clrf	num2
		incf	num1,1
		goto	c_step2

test_24		btfss	num2,D'002'
		goto	tt_ret
;sme cez 23:59
		clrf	num2
		clrf	num1

tt_ret		return
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
c_button	btfss	PORTA,D'004'	;S2 - inc minutes
		goto	clr_min
		btfss	PORTA,D'005'	;S1 - inc hours
		goto	clr_hrs
		return

clr_min		btfsc	PORTA,D'005'
		goto	inc_min
;both buttons are pressed - clear all counters
clr_count	clrf	num1
		clrf	num2
		clrf	num3
		clrf	num4
		return

clr_hrs		btfsc	PORTA,D'004'
		goto	inc_hrs
		goto	clr_count

;fast increment minutes, when button is pressed
inc_min		decfsz	TIMER5,F
		return
		movlw	D'200'
		movwf	TIMER5
		call	inc_minutes
		return

;fast increment hourss, when button is pressed
inc_hrs		decfsz	TIMER5,F
		return
		movlw	D'200'
		movwf	TIMER5
		call	inc_hours
		return
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;#2 translate numx to digitx

c_step2
		movf	num1,0
		call	translate_x
		movwf	digit1

;if 0 --> do not display anything
		movf	num1,0
		btfsc	STATUS,D'002'
		clrf	digit1

		movf	num2,0
		call	translate_x
		movwf	digit2

		movf	num3,0
		call	translate_x
		movwf	digit3

		movf	num4,0
		call	translate_x
		movwf	digit4

		return

;----------------------------------------------------------------------------
;RB0 - DP
;RB1 - G
;RB2 - F
;RB3 - E
;RB4 - D
;RB5 - C
;RB6 - B
;RB7 - A

translate_x	movwf	numx
		movf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe0			;0
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe1			;1
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe2			;2
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe3			;3
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe4			;4
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe5			;5
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe6			;6
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe7			;7
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe8			;8
		decf	numx,1
		btfsc	STATUS,D'002'
		goto	numxe9			;9

;error (overflow)
c_err		movlw	B'00000010'
		return

numxe0		movlw	B'11111100'
		return
numxe1		movlw	B'01100000'
		return
numxe2		movlw	B'11011010'
		return
numxe3		movlw	B'11110010'
		return
numxe4		movlw	B'01100110'
		return
numxe5		movlw	B'10110110'
		return
numxe6		movlw	B'10111110'
		return
numxe7		movlw	B'11100100'
		return
numxe8		movlw	B'11111110'
		return
numxe9		movlw	B'11110110'
		return
;----------------------------------------------------------------------------

		END