;===================================================================
;"bin16BCD5"- преобразование 16-битного двоичного
;значения в упакованный BCD формат
;===================================================================
;Количество слов кода            :25 + возврат
;Количество циклов               :25/176 (Мин/Макс) + возврат
;Использованные младшие регистры :нет
;Использованные старшие регистры :4(fbinL,fbinH/tBCD0,tBCD1,tBCD2)
;Использованные указатели        :нет


;Вход
.def    fbinL   =r16            ;двоичное значение, младший байт
.def    fbinH   =r17            ;двоичное значение, старший байт

;Выход
.def    tBCD0   =r17            ;BCD значение, цифры 1 и 0
.def    tBCD1   =r18            ;BCD значение, цифры 3 и 2
.def    tBCD2   =r19            ;BCD значение, цифра 4
;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
;регистре.


bin16BCD5:	ldi     tBCD2,-1
b16BCD5_l1: 	inc     tBCD2

        	subi    fbinL,low(10000)
        	sbci    fbinH,high(10000)

        	brsh    b16BCD5_l1

        	subi    fbinL,low(-10000)
        	sbci    fbinH,high(-10000)

        	ldi     tBCD1,-0x11

b16BCD5_l2:	subi    tBCD1,-0x10
        	subi    fbinL,low(1000)
	       	sbci    fbinH,high(1000)

	    	brsh 	b16BCD5_l2

	    	subi    fbinL,low(-1000)
        	sbci    fbinH,high(-1000)

b16BCD5_l3:	inc     tBCD1
        	subi    fbinL,low(100)
        	sbci    fbinH,high(100)

	    	brsh 	b16BCD5_l3

	    	subi    fbinL,-100
        	ldi     tBCD0,-0x10

b16BCD5_l4:	subi    tBCD0,-0x10
        	subi    fbinL,10

	    	brsh 	b16BCD5_l4
	    	subi    fbinL,-10
        	add     tBCD0,fbinL
        	ret

-=-=-=-=-=-=-
Для нижних регистров:

;******************************
; "bin16BCD5"- преобразование 16-битного двоичного значения в упакованный BCD формат
; Вход -- job1:job0
; Выход -- job3:job2:job1 (дес тыс:тыс,сот:дес,ед)
; использует temp и tmp1 и cnt1
BIN16BCD5:
	ser	temp
	mov	job3,temp	; -1 в десятки тысяч
	ldi	temp,low(10000)
	ldi	tmp1,high(10000)
b16BCD5_l1:
	inc	job3		; увеличили счётчик десятков тысяч
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили исходное на 10000
	brsh	b16BCD5_l1	; больше 0? повторим
	add	job0,temp	; меньше. восстановим из минусов
	adc	job1,tmp1

	ldi	temp,-0x11
	mov	job2,temp	; по -1 в тысячи и в сотни
	ldi	temp,low(1000)
	ldi	tmp1,high(1000)
	ldi	cnt1,0x10
b16BCD5_l2:
	add	job2,cnt1	; увеличили счётчик тысяч
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили исходное на 1000
	brsh	b16BCD5_l2	; больше 0? повторим
	add	job0,temp	; меньше. восстановим из минуса
	adc	job1,tmp1

	ldi	temp,100
	clr	tmp1
b16BCD5_l3:
	inc	job2		; увеличили счётчик сотен
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили на 1000
	brsh	b16BCD5_l3	; больше 0? потоврим
	add	job0,temp	; меньше. восстановим

	ldi	temp,-0x10
	mov	job1,temp
	ldi	tmp1,10
b16BCD5_l4:
	sub	job1,temp	; увеличили счётчик десятков
	sub	job0,tmp1	; уменьшили на 10
	brsh	b16BCD5_l4	; больше 0? повторим
	add	job0,tmp1	; меньше, восстановим
	add	job1,job0	; остаток - единицы, к десяткам

	ret

;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;******************************
; "BIN2BCD6"- преобразование 20-битного двоичного значения (0x0F423F) (0b11110100001000111111)
; в упакованный BCD формат (000000 - 999999)
; Вход -- job2:job1:job0
; Выход -- job3:job2:job1 (сот тыс,дес тыс:тыс,сот:дес,ед)
; использует temp,tmp1 и cnt1,cnt2
BIN2BCD6:
	; считаем сотни тысяч
	ldi	temp,-0x11
	mov	job3,temp	; по -1 в десятки тысяч и в сотни тысяч
	ldi	temp,0xa0
	ldi	tmp1,0x86
	ldi	cnt1,0x01	; загрузили 100000
	ldi	cnt2,0x10
b2bcd6_l1:
	add	job3,cnt2	; увеличили счётчик сотен тысяч
	sub	job0,temp
	sbc	job1,tmp1
	sbc	job2,cnt1	; уменьшили исходное на 100000
	brsh	b2bcd6_l1	; остаток >= 100000? повторим
	add	job0,temp	; нет, восстановим
	adc	job1,tmp1
	adc	job2,cnt1
	; считаем десятки тысяч
	ldi	temp,low(10000)
	ldi	tmp1,high(10000)
	clr	cnt1		; загрузили 10000
b2bcd6_l2:
	inc	job3		; увеличили счётчик десятков тысяч
	sub	job0,temp
	sbc	job1,tmp1
	sbc	job2,cnt1	; уменьшили остаток на 10000
	brsh	b2bcd6_l2	; >= 10000? повторим
	add	job0,temp	; меньше. восстановим из минусов
	adc	job1,tmp1
	; считаем тысячи
	ldi	temp,-0x11
	mov	job2,temp	; по -1 в тысячи и в сотни
	ldi	temp,low(1000)
	ldi	tmp1,high(1000)
b2bcd6_l3:
	add	job2,cnt2	; увеличили счётчик тысяч
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили остаток на 1000
	brsh	b2bcd6_l3	; >= 1000? повторим
	add	job0,temp	; меньше. восстановим из минуса
	adc	job1,tmp1
	; считаем сотни
	ldi	temp,100
b2bcd6_l4:
	inc	job2		; увеличили счётчик сотен
	sub	job0,temp
	sbc	job1,cnt1	; уменьшили на 100
	brsh	b2bcd6_l4	; >= 100? повторим
	add	job0,temp	; меньше. восстановим
	; считаем десятки. в остатке - единицы
	ldi	temp,-0x10
	mov	job1,temp
	ldi	tmp1,10
b2bcd6_l5:
	sub	job1,temp	; увеличили счётчик десятков
	sub	job0,tmp1	; уменьшили на 10
	brsh	b2bcd6_l5	; >= 10? повторим
	add	job0,tmp1	; меньше, восстановим
	add	job1,job0	; остаток - единицы, к десяткам

	ret

;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;******************************
; "BIN2BCD4"- преобразование 14-битного двоичного значения в упакованный BCD формат
; Вход -- job1:job0
; Выход -- job2:job1 (тыс,сот:дес,ед)
; использует temp и tmp1 и cnt1
BIN2BCD4:
	; тысячи
	ldi	temp,-0x11
	mov	job2,temp	; по -1 в тысячи и в сотни
	ldi	temp,low(1000)
	ldi	tmp1,high(1000)
	ldi	cnt1,0x10
b2BCD4_l1:
	add	job2,cnt1	; увеличили счётчик тысяч
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили исходное на 1000
	brsh	b2BCD4_l1	; >= 1000? повторим
	add	job0,temp	; меньше. восстановим из минуса
	adc	job1,tmp1
	; сотни
	ldi	temp,100
	clr	tmp1
b2BCD4_l2:
	inc	job2		; увеличили счётчик сотен
	sub	job0,temp
	sbc	job1,tmp1	; уменьшили на 100
	brsh	b16BCD4_l2	; >= 100? потоврим
	add	job0,temp	; меньше. восстановим
	; десятки
	ldi	temp,-0x10
	mov	job1,temp
	ldi	tmp1,10
b2BCD4_l3:
	sub	job1,temp	; увеличили счётчик десятков
	sub	job0,tmp1	; уменьшили на 10
	brsh	b16BCD4_l3	; >= 10? повторим
	add	job0,tmp1	; меньше, восстановим
	add	job1,job0	; остаток - единицы, к десяткам

	ret

;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

;******************************
;"bin16BCD3"- преобразование 16-битного двоичного
;значения 0..999 в упакованный BCD формат
;
;Количество слов кода            :12 + возврат
;Количество циклов               :14/70 (Мин/Макс) + возврат
;Использованные младшие регистры :нет
;Использованные старшие регистры :3(fbinL,fbinH/tBCD0,tBCD1)
;Использованные указатели        :нет
;
;Вход
.def    fbinL   =r16            ;двоичное значение, младший байт
.def    fbinH   =r17            ;двоичное значение, старший байт
;
;Выход
.def    tBCD0   =r17            ;BCD значение, цифры 1 и 0
.def    tBCD1   =r18            ;BCD значение, цифра 2
;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
;регистре.

bin16BCD3:	ldi     tBCD1,-0x01

b16BCD5_l1:	inc     tBCD1
        	subi    fbinL,low(100)
        	sbci    fbinH,high(100)
	    	brsh 	b16BCD5_l1

	    	subi    fbinL,-100
        	ldi     tBCD0,-0x10

b16BCD5_l2:	subi    tBCD0,-0x10
        	subi    fbinL,10
	    	brsh 	b16BCD5_l2

	    	subi    fbinL,-10
        	add     tBCD0,fbinL

        	ret

;;; вариант для нижних регистров
; Вход job1:job0, Выход job2:job1 (сот дес ед); портит temp,tmp1
BIN16BCD3:
	ser	temp
	mov	job2,temp	; ldi -1 > job2, сотни
	ldi	temp,100
	clr	tmp1
b16BCD3_l1:
	inc	job2		; увеличили счётчик сотен
	sub	job0,temp	;
	sbc	job1,tmp1	; уменьшили исходное число на 100
	brsh	b16BCD3_l1	; если остаток > 0 -- ещё один круг
	add	job0,temp	; восстанавливаем мл. байт из отрицательного значения
				; job1:job0 теперь должны быть < 100
	ldi	temp,-0x10
	mov	job1,temp	; инициируем счётчик десятков
	ldi	tmp1,10
b16BCD3_l2:
	sub	job1,temp	; увеличили сч. десятков (+ 0x10)
	sub	job0,tmp1	; вычли из нашего остатка 10 (0x0A)
	brsh	b16BCD3_l2	; если остаток > 0 -- ещё на круг
	add	job0,tmp1	; восстанавливаем мл. байт из отрицательного значения
	add	job1,job0	; добавили единицы к сч. десятков.

	ret
