bin2bcd.asm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. ;===================================================================
  2. ;"bin16BCD5"- преобразование 16-битного двоичного
  3. ;значения в упакованный BCD формат
  4. ;===================================================================
  5. ;Количество слов кода :25 + возврат
  6. ;Количество циклов :25/176 (Мин/Макс) + возврат
  7. ;Использованные младшие регистры :нет
  8. ;Использованные старшие регистры :4(fbinL,fbinH/tBCD0,tBCD1,tBCD2)
  9. ;Использованные указатели :нет
  10. ;Вход
  11. .def fbinL =r16 ;двоичное значение, младший байт
  12. .def fbinH =r17 ;двоичное значение, старший байт
  13. ;Выход
  14. .def tBCD0 =r17 ;BCD значение, цифры 1 и 0
  15. .def tBCD1 =r18 ;BCD значение, цифры 3 и 2
  16. .def tBCD2 =r19 ;BCD значение, цифра 4
  17. ;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
  18. ;регистре.
  19. bin16BCD5: ldi tBCD2,-1
  20. b16BCD5_l1: inc tBCD2
  21. subi fbinL,low(10000)
  22. sbci fbinH,high(10000)
  23. brsh b16BCD5_l1
  24. subi fbinL,low(-10000)
  25. sbci fbinH,high(-10000)
  26. ldi tBCD1,-0x11
  27. b16BCD5_l2: subi tBCD1,-0x10
  28. subi fbinL,low(1000)
  29. sbci fbinH,high(1000)
  30. brsh b16BCD5_l2
  31. subi fbinL,low(-1000)
  32. sbci fbinH,high(-1000)
  33. b16BCD5_l3: inc tBCD1
  34. subi fbinL,low(100)
  35. sbci fbinH,high(100)
  36. brsh b16BCD5_l3
  37. subi fbinL,-100
  38. ldi tBCD0,-0x10
  39. b16BCD5_l4: subi tBCD0,-0x10
  40. subi fbinL,10
  41. brsh b16BCD5_l4
  42. subi fbinL,-10
  43. add tBCD0,fbinL
  44. ret
  45. -=-=-=-=-=-=-
  46. Для нижних регистров:
  47. ;******************************
  48. ; "bin16BCD5"- преобразование 16-битного двоичного значения в упакованный BCD формат
  49. ; Вход -- job1:job0
  50. ; Выход -- job3:job2:job1 (дес тыс:тыс,сот:дес,ед)
  51. ; использует temp и tmp1 и cnt1
  52. BIN16BCD5:
  53. ser temp
  54. mov job3,temp ; -1 в десятки тысяч
  55. ldi temp,low(10000)
  56. ldi tmp1,high(10000)
  57. b16BCD5_l1:
  58. inc job3 ; увеличили счётчик десятков тысяч
  59. sub job0,temp
  60. sbc job1,tmp1 ; уменьшили исходное на 10000
  61. brsh b16BCD5_l1 ; больше 0? повторим
  62. add job0,temp ; меньше. восстановим из минусов
  63. adc job1,tmp1
  64. ldi temp,-0x11
  65. mov job2,temp ; по -1 в тысячи и в сотни
  66. ldi temp,low(1000)
  67. ldi tmp1,high(1000)
  68. ldi cnt1,0x10
  69. b16BCD5_l2:
  70. add job2,cnt1 ; увеличили счётчик тысяч
  71. sub job0,temp
  72. sbc job1,tmp1 ; уменьшили исходное на 1000
  73. brsh b16BCD5_l2 ; больше 0? повторим
  74. add job0,temp ; меньше. восстановим из минуса
  75. adc job1,tmp1
  76. ldi temp,100
  77. clr tmp1
  78. b16BCD5_l3:
  79. inc job2 ; увеличили счётчик сотен
  80. sub job0,temp
  81. sbc job1,tmp1 ; уменьшили на 1000
  82. brsh b16BCD5_l3 ; больше 0? потоврим
  83. add job0,temp ; меньше. восстановим
  84. ldi temp,-0x10
  85. mov job1,temp
  86. ldi tmp1,10
  87. b16BCD5_l4:
  88. sub job1,temp ; увеличили счётчик десятков
  89. sub job0,tmp1 ; уменьшили на 10
  90. brsh b16BCD5_l4 ; больше 0? повторим
  91. add job0,tmp1 ; меньше, восстановим
  92. add job1,job0 ; остаток - единицы, к десяткам
  93. ret
  94. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  95. ;******************************
  96. ; "BIN2BCD6"- преобразование 20-битного двоичного значения (0x0F423F) (0b11110100001000111111)
  97. ; в упакованный BCD формат (000000 - 999999)
  98. ; Вход -- job2:job1:job0
  99. ; Выход -- job3:job2:job1 (сот тыс,дес тыс:тыс,сот:дес,ед)
  100. ; использует temp,tmp1 и cnt1,cnt2
  101. BIN2BCD6:
  102. ; считаем сотни тысяч
  103. ldi temp,-0x11
  104. mov job3,temp ; по -1 в десятки тысяч и в сотни тысяч
  105. ldi temp,0xa0
  106. ldi tmp1,0x86
  107. ldi cnt1,0x01 ; загрузили 100000
  108. ldi cnt2,0x10
  109. b2bcd6_l1:
  110. add job3,cnt2 ; увеличили счётчик сотен тысяч
  111. sub job0,temp
  112. sbc job1,tmp1
  113. sbc job2,cnt1 ; уменьшили исходное на 100000
  114. brsh b2bcd6_l1 ; остаток >= 100000? повторим
  115. add job0,temp ; нет, восстановим
  116. adc job1,tmp1
  117. adc job2,cnt1
  118. ; считаем десятки тысяч
  119. ldi temp,low(10000)
  120. ldi tmp1,high(10000)
  121. clr cnt1 ; загрузили 10000
  122. b2bcd6_l2:
  123. inc job3 ; увеличили счётчик десятков тысяч
  124. sub job0,temp
  125. sbc job1,tmp1
  126. sbc job2,cnt1 ; уменьшили остаток на 10000
  127. brsh b2bcd6_l2 ; >= 10000? повторим
  128. add job0,temp ; меньше. восстановим из минусов
  129. adc job1,tmp1
  130. ; считаем тысячи
  131. ldi temp,-0x11
  132. mov job2,temp ; по -1 в тысячи и в сотни
  133. ldi temp,low(1000)
  134. ldi tmp1,high(1000)
  135. b2bcd6_l3:
  136. add job2,cnt2 ; увеличили счётчик тысяч
  137. sub job0,temp
  138. sbc job1,tmp1 ; уменьшили остаток на 1000
  139. brsh b2bcd6_l3 ; >= 1000? повторим
  140. add job0,temp ; меньше. восстановим из минуса
  141. adc job1,tmp1
  142. ; считаем сотни
  143. ldi temp,100
  144. b2bcd6_l4:
  145. inc job2 ; увеличили счётчик сотен
  146. sub job0,temp
  147. sbc job1,cnt1 ; уменьшили на 100
  148. brsh b2bcd6_l4 ; >= 100? повторим
  149. add job0,temp ; меньше. восстановим
  150. ; считаем десятки. в остатке - единицы
  151. ldi temp,-0x10
  152. mov job1,temp
  153. ldi tmp1,10
  154. b2bcd6_l5:
  155. sub job1,temp ; увеличили счётчик десятков
  156. sub job0,tmp1 ; уменьшили на 10
  157. brsh b2bcd6_l5 ; >= 10? повторим
  158. add job0,tmp1 ; меньше, восстановим
  159. add job1,job0 ; остаток - единицы, к десяткам
  160. ret
  161. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  162. ;******************************
  163. ; "BIN2BCD4"- преобразование 14-битного двоичного значения в упакованный BCD формат
  164. ; Вход -- job1:job0
  165. ; Выход -- job2:job1 (тыс,сот:дес,ед)
  166. ; использует temp и tmp1 и cnt1
  167. BIN2BCD4:
  168. ; тысячи
  169. ldi temp,-0x11
  170. mov job2,temp ; по -1 в тысячи и в сотни
  171. ldi temp,low(1000)
  172. ldi tmp1,high(1000)
  173. ldi cnt1,0x10
  174. b2BCD4_l1:
  175. add job2,cnt1 ; увеличили счётчик тысяч
  176. sub job0,temp
  177. sbc job1,tmp1 ; уменьшили исходное на 1000
  178. brsh b2BCD4_l1 ; >= 1000? повторим
  179. add job0,temp ; меньше. восстановим из минуса
  180. adc job1,tmp1
  181. ; сотни
  182. ldi temp,100
  183. clr tmp1
  184. b2BCD4_l2:
  185. inc job2 ; увеличили счётчик сотен
  186. sub job0,temp
  187. sbc job1,tmp1 ; уменьшили на 100
  188. brsh b16BCD4_l2 ; >= 100? потоврим
  189. add job0,temp ; меньше. восстановим
  190. ; десятки
  191. ldi temp,-0x10
  192. mov job1,temp
  193. ldi tmp1,10
  194. b2BCD4_l3:
  195. sub job1,temp ; увеличили счётчик десятков
  196. sub job0,tmp1 ; уменьшили на 10
  197. brsh b16BCD4_l3 ; >= 10? повторим
  198. add job0,tmp1 ; меньше, восстановим
  199. add job1,job0 ; остаток - единицы, к десяткам
  200. ret
  201. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  202. ;******************************
  203. ;"bin16BCD3"- преобразование 16-битного двоичного
  204. ;значения 0..999 в упакованный BCD формат
  205. ;
  206. ;Количество слов кода :12 + возврат
  207. ;Количество циклов :14/70 (Мин/Макс) + возврат
  208. ;Использованные младшие регистры :нет
  209. ;Использованные старшие регистры :3(fbinL,fbinH/tBCD0,tBCD1)
  210. ;Использованные указатели :нет
  211. ;
  212. ;Вход
  213. .def fbinL =r16 ;двоичное значение, младший байт
  214. .def fbinH =r17 ;двоичное значение, старший байт
  215. ;
  216. ;Выход
  217. .def tBCD0 =r17 ;BCD значение, цифры 1 и 0
  218. .def tBCD1 =r18 ;BCD значение, цифра 2
  219. ;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
  220. ;регистре.
  221. bin16BCD3: ldi tBCD1,-0x01
  222. b16BCD5_l1: inc tBCD1
  223. subi fbinL,low(100)
  224. sbci fbinH,high(100)
  225. brsh b16BCD5_l1
  226. subi fbinL,-100
  227. ldi tBCD0,-0x10
  228. b16BCD5_l2: subi tBCD0,-0x10
  229. subi fbinL,10
  230. brsh b16BCD5_l2
  231. subi fbinL,-10
  232. add tBCD0,fbinL
  233. ret
  234. ;;; вариант для нижних регистров
  235. ; Вход job1:job0, Выход job2:job1 (сот дес ед); портит temp,tmp1
  236. BIN16BCD3:
  237. ser temp
  238. mov job2,temp ; ldi -1 > job2, сотни
  239. ldi temp,100
  240. clr tmp1
  241. b16BCD3_l1:
  242. inc job2 ; увеличили счётчик сотен
  243. sub job0,temp ;
  244. sbc job1,tmp1 ; уменьшили исходное число на 100
  245. brsh b16BCD3_l1 ; если остаток > 0 -- ещё один круг
  246. add job0,temp ; восстанавливаем мл. байт из отрицательного значения
  247. ; job1:job0 теперь должны быть < 100
  248. ldi temp,-0x10
  249. mov job1,temp ; инициируем счётчик десятков
  250. ldi tmp1,10
  251. b16BCD3_l2:
  252. sub job1,temp ; увеличили сч. десятков (+ 0x10)
  253. sub job0,tmp1 ; вычли из нашего остатка 10 (0x0A)
  254. brsh b16BCD3_l2 ; если остаток > 0 -- ещё на круг
  255. add job0,tmp1 ; восстанавливаем мл. байт из отрицательного значения
  256. add job1,job0 ; добавили единицы к сч. десятков.
  257. ret