dtbcd.asm 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. ;
  2. ; This is a macro to generate packed BCD constants.
  3. ; It is obsoleted by "dt" with a packed BCD value with a "p"
  4. ; suffix, but it is included here as a rest of nested %rep.
  5. ;
  6. %macro dtbcd 1-*.nolist
  7. %push dtbcd
  8. %rep %0
  9. %defstr %$abc %1
  10. %substr %$sign %$abc 1
  11. %if %$sign == '-'
  12. %substr %$abc %$abc 2,-1
  13. %xdefine %$sign 0x80
  14. %elif %$sign == '+'
  15. %substr %$abc %$abc 2,-1
  16. %xdefine %$sign 0x00
  17. %else
  18. %xdefine %$sign 0x00
  19. %endif
  20. %strlen %$abclen %$abc
  21. %defstr %$abclen_str %$abclen
  22. %assign %$pos %$abclen
  23. %assign %$bc 0
  24. %assign %$ld -1
  25. %rep %$abclen
  26. %substr %$chr %$abc %$pos
  27. %assign %$pos %$pos-1
  28. %if %$chr >= '0' && %$chr <= '9'
  29. %if %$ld < 0
  30. %assign %$ld %$chr-'0'
  31. %assign %$bc %$bc+1
  32. %if %$bc > 9
  33. %warning "too many digits in BCD constant"
  34. %exitrep
  35. %endif
  36. %else
  37. db %$ld+((%$chr-'0') << 4)
  38. %assign %$ld -1
  39. %endif
  40. %elif %$chr == '_'
  41. ; Do nothing...
  42. %else
  43. %error "invalid character in BCD constant"
  44. %exitrep
  45. %endif
  46. %endrep
  47. %if %$ld >= 0
  48. db %$ld
  49. %endif
  50. %rep 9-%$bc
  51. db 0
  52. %endrep
  53. db %$sign
  54. %rotate 1
  55. %endrep
  56. %pop
  57. %endmacro
  58. dtbcd 123, -456, +789
  59. dt 123p, -456p, +789p
  60. dtbcd 765432109876543210
  61. dt 765432109876543210p
  62. dtbcd -765432109876543210
  63. dt -765432109876543210p
  64. dtbcd +765_432_109_876_543_210
  65. dt +765_432_109_876_543_210p
  66. dtbcd -765_432_109_876_543_210
  67. dt -765_432_109_876_543_210p
  68. ;; Both of these should warn...
  69. dtbcd 8_765_432_109_876_543_210
  70. dt 8_765_432_109_876_543_210p