.include "m32def.inc"

.def	temp1	=r16	;general scratch space
.def	temp2	=r17
.def	temp3	=r18
.def	temp4	=r19
.def	temp	=r20
.def	DecCount=r21
.def	Scd		=r22
.def	Min		=r23
.def	Hour	=r24
.def	Status	=r25

;*****************************************************************
.dseg
Digit:	.byte	4
Line:	.byte	4
Key:	.byte	1

;********************************************************************
.macro	stsi			;save immediate <SRAM_CELL>, <value>
		ldi temp, @1
		sts @0, temp
.endmacro

.macro	outi			;out immediate <value>, <register>
		ldi temp, @1
		out @0, temp
.endmacro

.macro	rdm
		ldi ZH, High(@0*2)
		ldi ZL, Low(@0*2)
		add ZL, temp1
		ADC ZH, temp2
		lpm
		mov	temp3, r0
.endmacro

;********************************************************************
.cseg
.org 0

		rjmp reset
		rjmp EXT_INT0		; IRQ0 Handler
		rjmp EXT_INT1		; IRQ1 Handler
		rjmp EXT_INT2		; IRQ2 Handler
		rjmp TIM2_COMP		; Timer2 Compare Handler
		rjmp TIM2_OVF		; Timer2 Overflow Handler
		rjmp TIM1_CAPT		; Timer1 Capture Handler
		rjmp TIM1_COMPA		; Timer1 CompareA Handler
		rjmp TIM1_COMPB		; Timer1 CompareB Handler
		rjmp TIM1_OVF		; Timer1 Overflow Handler
		rjmp TIM0_COMP		; Timer0 Compare Handler
		rjmp TIM0_OVF		; Timer0 Overflow Handler
		rjmp SPI_STC		; SPI Transfer Complete Handler
		rjmp USART_RXC		; USART RX Complete Handler
		rjmp USART_UDRE		; UDR Empty Handler
		rjmp USART_TXC		; USART TX Complete Handler
		rjmp ADC_INT		; ADC Conversion Complete Handler
		rjmp EE_RDY			; EEPROM Ready Handler
		rjmp ANA_COMP		; Analog Comparator Handler
		rjmp TWI			; Two-wire Serial Interface Handler
		rjmp SPM_RDY		; Store Program Memory Ready Handler

;*** Reset handler **************************************************
reset:
		ldi r16,high(RAMEND); Main program start
		out SPH,r16 		; Set Stack Pointer to top of RAM
		ldi r16,low(RAMEND)
		out SPL,r16

		cli

		outi DDRB, 0b11111111		;initialise port B as OUTPUT

		outi DDRD, 0b00001111

		stsi Digit, 0
		stsi Digit+1, 0
		stsi Digit+2, 0
		stsi Digit+2, 0

;**********************************************************
main:
		rcall Display
		rcall KeyRead
		rcall Keyboard
		rjmp main

;**********************************************************
EXT_INT0:		; IRQ0 Handler
EXT_INT1:		; IRQ1 Handler
EXT_INT2:		; IRQ2 Handler
TIM2_COMP:		; Timer2 Compare Handler
TIM2_OVF:		; Timer2 Overflow Handler
TIM1_CAPT:		; Timer1 Capture Handler
TIM1_COMPA:		; Timer1 CompareA Handler
TIM1_COMPB:		; Timer1 CompareB Handler
TIM1_OVF:		; Timer1 Overflow Handler
TIM0_COMP:		; Timer0 Compare Handler
TIM0_OVF:		; Timer0 Overflow Handler
SPI_STC:		; SPI Transfer Complete Handler
USART_RXC:		; USART RX Complete Handler
USART_UDRE:		; UDR Empty Handler
USART_TXC:		; USART TX Complete Handler
ADC_INT:		; ADC Conversion Complete Handler
EE_RDY:			; EEPROM Ready Handler
ANA_COMP:		; Analog Comparator Handler
TWI:			; Two-wire Serial Interface Handler
SPM_RDY:		; Store Program Memory Ready Handler
		reti	
;**********************************************************
Display:
		lds temp1,Digit
		ldi temp,0b00001110
		out PORTD,temp

		rcall Decoder

		out PORTB,temp1
		in temp, PIND
		sts Line, temp
		rcall Delay1
		;--------------------
		lds temp1,Digit+1
		ldi temp,0b00001101
		out PORTD,temp

		rcall Decoder

		out PORTB,temp1
		in temp, PIND
		sts Line+1, temp
		rcall Delay1
		;--------------------
		lds temp1,Digit+2
		ldi temp,0b00001011
		out PORTD,Temp

		rcall Decoder

		out PORTB,temp1
		in temp, PIND
		sts Line+2, temp
		rcall Delay1
		;--------------------
		lds temp1,Digit+3
		ldi temp,0b00000111
		out PORTD,temp

		rcall Decoder

		out PORTB,temp1
		in temp, PIND
		sts Line+3, temp
		rcall Delay1
ret
;**********************************************************
Decoder:
		ldi ZL,Low(DcMatrix*2)
		ldi ZH,High(DcMatrix*2)

		ldi temp2,0
		add ZL,temp1
		adc ZH,temp2

		lpm
		mov temp1,r0
		ret
;**********************************************************
DcMatrix:
		;     hgfedcba   hgfedcba
		.db 0b00111111,0b00000110	;0,1
		.db 0b01011011,0b01001111	;2,3
		.db 0b01100110,0b01101101	;4,5
		.db 0b01111101,0b00000111	;6,7
		.db 0b01111111,0b01101111	;8,9
		.db 0b01110111,0b01111100	;A,B
		.db 0b00111001,0b01011110	;C,D
		.db 0b01111001,0b01110001	;E,F
		.db 0b01111111,0b01111111

;**********************************************************
Delay1:
		push temp1
		push temp2
		ldi temp1,0
		ldi temp2,50
d11:	
		dec temp1
		brne d11
		dec temp2
		brne d11
		pop temp2
		pop temp1
		ret

;**********************************************************
KeyRead:
		lds temp, Line
		rcall KeyTest

		ldi temp, 0
		cpi temp1, 255
		brne SetKey
		;--------------------
		lds temp, Line+1
		rcall KeyTest

		ldi temp, 4
		cpi temp1, 255
		brne SetKey
		;--------------------
		lds temp, Line+2
		rcall KeyTest

		ldi temp, 8
		cpi temp1, 255
		brne SetKey
		;--------------------
		lds temp, Line+3
		rcall KeyTest

		ldi temp, 12
		cpi temp1, 255
		brne SetKey

		ldi temp, 0

SetKey:
		add temp, temp1

		lds temp1, Key
		cpi temp, 0x0F			; добавлено для клавиатуры 4ч4
		brne KR1				; добавлено для клавиатуры 4ч4
		
		cpi temp1, 0xFF			; добавлено для клавиатуры 4ч4
		brne KR1				; добавлено для клавиатуры 4ч4
		rjmp EndKeyRead			; добавлено для клавиатуры 4ч4
KR1:							; добавлено для клавиатуры 4ч4
		andi temp1, 0b00001111
		cp temp, temp1
		brne EndKeyRead

		ori temp, 0b10000000

EndKeyRead:
		sts Key, temp
		ret

;**********************************************************
KeyTest:
		andi temp, 0b11110000
		ldi temp1, 0b11110000
		eor temp, temp1
		breq NoButtons

		ldi temp1, 0

		cpi temp, 0b00010000
		breq EndKeyTest
		inc temp1

		cpi temp, 0b00100000
		breq EndKeyTest
		inc temp1

		cpi temp, 0b01000000
		breq EndKeyTest
		inc temp1

		cpi temp, 0b10000000
		breq EndKeyTest

NoButtons:
		ldi temp1, 255

EndKeyTest:
		ret

;**********************************************************
Keyboard:
		lds temp, Key
		mov temp1, temp
		andi temp1, 0b10000000
		brne EndKeyboard

		ldi ZH, High(KeysLUT*2)
		ldi ZL, Low(KeysLUT*2)

		ldi temp1, 0
		add ZL, temp
		adc ZH, temp1

		lpm
		mov temp, r0

		lds temp1, Digit+2
		sts Digit+3, temp1
		lds temp1, Digit+1
		sts Digit+2, temp1
		lds temp1, Digit
		sts Digit+1, temp1

		sts Digit, temp

EndKeyboard:
		ret

;**********************************************************
KeysLUT:
		.db 7,8,9,12,4,5,6,13,1,2,3,14,10,0,11,15
