;программа опроса клавиатуры 4*3 

#define	pb_dr	a2	;регистр управления порта В
#define	pb_wr	b2	;рабочий регистр порта В
#define	temp1	c1	;временная переменная 1
#define	temp2	c2	;временная переменная 2
#define	temp3	c3	;временная переменная 3
#define	key_code	c0	;код нажатой клавиши
#define	row_code	c1	;код строки
#define	col_mask	c2	;маска столбца
#define	key1		c4	;стек нажатых кнопок
#define	key2		c5	;стек нажатых кнопок


;область векторов прерывания
	jmp	start	;вектор прерывания по RESET
	nop
	nop
	nop
	nop
	nop
	nop
	nop

;точка старта
start:	ldr	#a,18h	;сегмент регистров конфигурации портов
	ldr	#b,0h	;сегмент рабочих регистров портов
	ldr	#c,40h	;1ый сегмент рабочих переменных

;конфигурируем порт В
	movl	pb_dr,00011011b
	movl	pb_dr,0ffh	;все вход/выход
	movl	pb_dr,0ffh	;все с активным выходом
	movl	pb_dr,0		;нагрузочные резисторы отключены
	movl	pb_dr,0		;прерывания
	movl	pb_dr,0		;запрещены

main:

;код вашей программы

	jmp	main



;************************************************************************
;* подпрограмма опроса клавиатуры					*
;* 4строки*3столбца							*
;* линии строк работают как выходы					*
;* линии столбцов работают как входы с притягивающими к Vcc резисторами *
;************************************************************************

;размещение кнопок на клавиатуре
;слева-направо, сверху-вниз
sym_set:		.byte	1,2,3,4,5,6,7,8,9,10,0,11

keyboard:
	movl	pb_dr,00001011b	;запись в 3ий подрегистр
	movl	pb_dr,10001111b	;старшая тетрада-входы
	movl	pb_dr,00001101b	;запись в 5ый подрегистр
	movl	pb_dr,01110000b	;на столбцы клав-ры повешены резисторы

;предварительное сканирование клавиатуры
;младшая тетрада порта В выставлена в ноль
;старшая тетрада работает как вход

	bicl	pb_wr,1111b	;сбросил мл. тетраду
	nop			;пропустил два такта
	btgh	pb_wr,1111b	;проверил старшую тетраду на ноль
	jz	key_code12	;если мл. тетрада вся установлена

;далее идет сканирование клавиатуры
	movl	row_code,1110b	;код верхней строки клав-ры
	movl	key_code,255	;инициализировал смещение
next_row:
	movl	col_mask,00010000b	;маска левого столбца клав-ры
	mov	pb_wr,row_code		;записываем код строки в порт В
next_col:
	inc	key_code	;увеличил смещение на 1
	mov	temp3,pb_wr	;читаем значение порта В во временную переменную
	and	temp3,col_mask	;сравниваем значение порта В с кодом столбца
	jz	key_def		;переходим к блоку преобразования в истинный код
	shl	col_mask	;сдвигаем маску столбца влево
	btth	col_mask,0111b	;проехали последний столбец?
	jnz	next_col	;переходим к опросу следующей кнопки в строке
	stc			;установил флаг переноса
	rlc	row_code	;сдвигаем код строки влево
	btth	row_code,0001	;проехали последнюю строку?
	jnz	next_row	;переходим к опросу следующей строки
key_code12:
	movl	key_code,12	;кнопка не была нажата
	jmp	no_key		;обхожу таблицу

;по смещению key_code в таблице определяем нажатую кнопку
key_def:	mdal	temp1,sym_set	;младший байт адреса таблицы в temp1
	mdah	temp2,sym_set		;старший байт адреса таблицы в temp2
	add	temp1,key_code
	adc	temp2			;добавили к адресу таблицы смещение
	mtpr	#6,temp1
	mtpr	#7,temp2		;загрузили регистр косвенной адресации этим адресом
	mov	key_code,d7		;получили истинное название кнопки

;по последовательности key1 key2 key_code определяю факт нажатия кнопки
	cmpl	key1,12			;была ли отжата кнопка
	jnz	no_key
	cmpl	key2,12			;была ли нажата кнопка
	jz	no_key
	cmp	key2,key_code		;равны ли последние опросы
	jnz	no_key
	mov	key1,key2
	mov	key2,key_code
	jmp	key_exit

no_key:	mov	key1,key2
	mov	key2,key_code
	movl	key_code,12
key_exit:	rts			;выход из процедуры обработки клавы


	.end	;конец программы