;=================================================================== ;"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