home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / zslsrc36.lbr / MLWDC.ZZ0 / MLWDC.Z80
Encoding:
Text File  |  1992-03-06  |  4.0 KB  |  117 lines

  1. ; Library:    ZSLIB
  2. ; Version:    3.6
  3. ; Module:    MLWDC
  4. ; Version:    1.0
  5. ; Author:    Gene Pizzetta
  6. ; Date:        March 2, 1992
  7. ; Comment:    Much modified from some ideas of David Cortesi.
  8. ;
  9. ; MLWDC -- stores 4-byte binary integer as up to 10 ASCII digits, with
  10. ; or without leading spaces, in a memory buffer of variable size.
  11. ;
  12. ; Entry: HL = address of 32-bit binary number (stored low-byte first)
  13. ;     DE = address of memory buffer for output (10 byte minimum)
  14. ;     A = minimum output field size (1 to size of memory buffer)
  15. ; Exit:     DE = address of byte following output
  16. ; Uses:     DE
  17. ; Notes: Memory buffer for output must be at least the same size as the
  18. ;     field size given in A, with an 10 byte minimum.  The ASCII
  19. ;     number will be padded with leading spaces to the field size.
  20. ;     If the converted number is longer than the given field size,
  21. ;     the complete number will be output anyway.
  22. ;
  23.     PUBLIC    MLWDC
  24. ;
  25. MLWDC:    push    af        ; save registers
  26.     push    bc
  27.     push    hl
  28.     ld    (FldSiz),a    ; save field size
  29.     ld    (StrBuf),de    ; save address of string output buffer
  30.     ld    bc,4        ; move copy of long-word to local buffer
  31.     ld    de,LWBuf    ; ..to preserve original copy
  32.     ldir
  33.     xor    a
  34.     ex    de,hl        ; HL -> BCD buffer
  35.     ld    b,5        ; 5 bytes
  36. Fill:    ld    (hl),a        ; null it out
  37.     inc    hl
  38.     djnz    Fill
  39.     ld    b,32        ; 32 bits to convert
  40. ; Shift long-word one bit left, high bit moving to carry flag
  41. Loop0:    ld    hl,LWBuf
  42.     push    bc        ; save outer loop counter
  43.     ld    b,4        ; shift each of the four bytes
  44. LoopA:    rl    (hl)
  45.     inc    hl
  46.     djnz    LoopA
  47. ; Double 10-digit packed BCD number, adding bit in carry.  BCD number
  48. ; stored high byte first.
  49.     ld    hl,BCDBuf+4    ; start with low byte
  50.     ld    b,5        ; repeat for all 5 bytes
  51. LoopB:    ld    a,(hl)        ; get byte
  52.     adc    a,a        ; double it
  53.     daa            ; decimal adjust it
  54.     ld    (hl),a        ; store doubled byte
  55.     dec    hl        ; point to next byte
  56.     djnz    LoopB
  57.     pop    bc        ; restore outer loop counter
  58.     djnz    Loop0
  59.     ld    b,5        ; number of BCD bytes
  60. ; Unpack BCD digits to ASCII, backwards through BCD and ASCII buffers, from
  61. ; low byte to high byte.  RRD moves successive BCD digits to low nibble of A.
  62.     ld    de,AscBuf+9    ; low-order ASCII digit
  63.     ld    hl,BCDBuf+4    ; low-order BCD byte
  64.     ld    a,'0'        ; set high nibble of a digit
  65. Loop1:    rrd            ; low digit into A
  66.     ld    (de),a        ; ..stored
  67.     dec    de        ; point to next slot
  68.     rrd            ; high digit to A
  69.     ld    (de),a        ; ..stored
  70.     dec    de        ; point to next slot
  71.     dec    hl        ; back up to next BCD byte
  72.     djnz    Loop1
  73.     inc    de        ; DE -> last stored digit
  74.     ex    de,hl        ; move pointer to HL
  75. ; HL points to leftmost ASCII digit.  Scan right to first non-zero digit.
  76. ; Count of ASCII digits is in B (less 1, so the last digit will always be
  77. ; preserved, even if it's a zero).
  78.     ld    b,10-1        ; ASCII digit count in B
  79.     ld    a,'0'        ; compare to ASCII '0'
  80. Loop2:    cp    (hl)        ; zero?
  81.     jr    nz,Exit2    ; (no, we're through)
  82.     inc    hl        ; increment pointer
  83.     djnz    Loop2
  84. Exit2:    inc    b        ; correct count of digits
  85. ; HL points to first (leftmost) non-zero digit with counter in B.  Move them
  86. ; to the user's buffer.  If field size is less than or equal to the actual
  87. ; length, just move the number.  If field size is greater, add spaces first.
  88.     ld    de,(StrBuf)    ; point to output buffer
  89.     ld    c,b
  90.     ld    b,0        ; BC = length of number
  91.     ld    a,(FldSiz)
  92.     sub    c        ; A = field size less number size
  93.     jr    c,NoSpc        ; (number bigger than field)
  94.     jr    z,NoSpc        ; (number equals field)
  95.     ld    b,a        ; B = count of leading spaces needed
  96.     ld    a,' '
  97. SpLoop:    ld    (de),a        ; put a space into output buffer
  98.     inc    de        ; increment pointer
  99.     djnz    SpLoop
  100. ; BC = length of number, DE points to output buffer (after leading spaces),
  101. ; HL points to first byte of number.  Move it to output buffer.
  102. NoSpc:    ldir            ; leaves DE pointing to byte after last
  103.     pop    hl        ; restore registers
  104.     pop    bc
  105.     pop    af
  106.     ret
  107. ;
  108.     DSEG
  109. ;
  110. AscBuf:    ds    10        ; work area for ASCII 10-digit number
  111. LWBuf:    ds    4        ; work area for 4-byte long-word
  112. BCDBuf:    ds    5        ; work area for 5-byte packed BCD number
  113. FldSiz:    ds    1        ; storage for field size
  114. StrBuf:    ds    2        ; output buffer address
  115. ;
  116.     end
  117.