	.include "m8def.inc"


;26.11.2016

GO:
	LDI	XH,HIGH(RAMEND)
	LDI	XL,LOW(RAMEND)
	OUT	SPH,XH
	OUT	SPL,XL

	LDI	R19,HIGH(9876)
	LDI	R20,LOW(9876)
	RCALL	BIN_BCD
	RJMP	GO

BIN_BCD:   
	CLR	R30		; 1000, 100
	CLR	R31		; 10, 1

	LDI	R24,16

BIN16BCD5:
	subi r31,-0x33	;add 0x33      вычитание константы из рагистра,ZCNVH
	sbrs r31, 3	;if carry to bit 3     skip if bit in register is set
	subi r31, 3	;subtract 3
	sbrs r31, 7	;if carry to bit 7
	subi r31, 0x30	;subtract 0x30

	subi r30,-0x33      ;  /*add 0x33*/
	sbrs r30, 3         ;  /*if carry to bit 3,*/
	subi r30, 3         ;  /*subtract 3*/
	sbrs r30, 7         ;  /*if carry to bit 7,*/
	subi r30, 0x30      ;  /*subtract 0x30*/

	lsl R20
	rol R19

	ROL r31
	rol r30

	dec R24		; регистр-1
	brne BIN16BCD5	;repeat for all bits*/

	MOV R29, R30; записываем R30 в R28
    MOV R28, R30; записываем R30 в R28
    SWAP R28; меняем местами полубайты
    ANDI R29, 0x0F; оставляем младший полубайт
    ANDI R28, 0x0F; оставляем младший полубайт

    MOV R30, R31; записываем R31 в R30
    SWAP R30; меняем местами полубайты
    ANDI R30, 0x0F; оставляем младший полубайт
	ANDI R31, 0x0F; оставляем младший полубайт
; для HD44780 преобразуем цифры
    subi R28,-0x30	;add 0x30
    subi R29,-0x30	;add 0x30
    subi R30,-0x30	;add 0x30 
    subi R31,-0x30	;add 0x30 

	RET
.EXIT


;26.11.2016
; Вариант преобразования от Starichok51

;--- преобразование двоичного числа, (не более 9999), в 4 десятичных цифры ---
;--- двоичное число в R11:R10,
; на выходе 4 десятичные цифры в R10:R11:R12:R13 в ASCII коде---
GO:
	LDI	XH,HIGH(RAMEND)
	LDI	XL,LOW(RAMEND)
	OUT	SPH,XH
	OUT	SPL,XL

	LDI	R21,HIGH(9876)
	LDI	R20,LOW(9876)
	MOV	R11,R21
	MOV	R10,R20
	RCALL	bin_to_4_decimal_digit	;BIN_BCD
	RJMP	GO

bin_to_4_decimal_digit:
	clr R13
clr R12            ; очистим старшие байты
ldi R17, high(10)
ldi R16,  low(10)
rcall div_32_16_16_16
mov R13, R12
rcall div_16_8_8_8
mov R12, R11
clr R11            ; очистим старший байт
rcall div_16_8_8_8
ldi R18, '0'            ; символ "0"
add R13, R18
add R12, R18
add R11, R18
add R10, R18
ret

;--- деление 16 бит в R11:R10 на 8 бит в R16 ---
;------ целая часть в R10, остаток в R11 -------
div_16_8_8_8:
ldi R18, 8            ; делаем 8 циклов сдвига делимого/результата
div_16_8_8_8a:
lsl R10
rol R11
brcs div_16_8_8_8b
cp R11, R16
brcs div_16_8_8_8c      ; если меньше, то пропускаем вычитание
div_16_8_8_8b:
sub R11,R16
inc R10
div_16_8_8_8c:
dec R18
brne div_16_8_8_8a
ret

;--- деление 32 бита в R13:R12:R11:R10 на 16 бит в R17:R16 ---
;--------- целая часть в R11:R10, остаток в R13:R12 ----------
div_32_16_16_16:
ldi R18, 16            ; делаем 16 циклов сдвига делимого/результата
div_32_16a:
lsl R10
rol R11
rol R12
rol R13
brcs div_32_16b
cp R12, R16
cpc R13, R17
brcs div_32_16c   
div_32_16b:         ; если меньше, то пропускаем вычитание
sub R12,R16
sbc R13,R17
inc R10
div_32_16c:
dec R18
brne div_32_16a
ret
.EXIT

;26.11.2016
; Вариант преобразования от dr.doc
.equ AtBCD0 = 4 ;address of r4 для подпрограммы BIN2_BCD
.equ AtBCD2 = 6 ;address of r6
GO:
	LDI	XH,HIGH(RAMEND)
	LDI	XL,LOW(RAMEND)
	OUT	SPH,XH
	OUT	SPL,XL

	LDI	R17,HIGH(9876)
	LDI	R16,LOW(9876)
	RCALL	BIN_BCD
	RJMP	GO
BIN_BCD:
; Input (r17:r16) output BCD number (r6:r5:r4:r3:r2).
; High registers used: 4(r16,r17,r18,r19)
; Pointers used: Z

ldi r18,16 ;Init loop counter
clr r6 ;clear result (3 bytes)
clr r5
clr r4
clr ZH ;clear ZH (not needed for AT90Sxx0x)
bBCDx_1:
lsl r16 ;shift input value
rol r17 ;through all bytes
rol r4 ;
rol r5
rol r6
dec r18 ;decrement loop counter
brne bBCDx_2 ;if counter not zero
; распределим числа по ячейкам
ldi r18,0x0F
mov r2,r4
and r2,r18
swap r4
mov r3,r4
and r3,r18
mov r4,r5
and r4,r18
swap r5
and r5,r18
ret ;return

bBCDx_2:
ldi r30,AtBCD2+1 ;Z points to result MSB + 1
bBCDx_3:
ld r19,-Z ;get (Z) with pre-decrement
subi r19,-$03 ;add 0x03
sbrc r19,3 ;if bit 3 not clear
st Z,r19 ;store back
ld r19,Z ;get (Z)
subi r19,-$30 ;add 0x30
sbrc r19,7 ;if bit 7 not clear
st Z,r19 ;store back
cpi ZL,AtBCD0 ;done all three?
brne bBCDx_3 ;loop again if not
rjmp bBCDx_1
.EXIT
