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

  1. ; Library:    ZSLIB
  2. ; Version:    3.6
  3. ; Module:    SLWDC
  4. ; Version:    1.0
  5. ; Author:    Gene Pizzetta
  6. ; Date:        March 6, 1992
  7. ; Comment:    Much modified from some ideas of David Cortesi.
  8. ;
  9. ; SLWDC -- output 4-byte binary integer as up to 10 ASCII digits, with or
  10. ; without leading spaces, to console, printer, or both (switchable).
  11. ;
  12. ; Entry: HL = address of 32-bit binary number (stored low-byte first)
  13. ;     A = minimum output field size (1-255)
  14. ; Exit:  None, number is printed.
  15. ; Uses:     None.
  16. ; Notes: The ASCII number will be padded with leading spaces to the field
  17. ;     size.  If the converted number is longer than the given field size,
  18. ;     the complete number will be output anyway.  Output destination is
  19. ;     set via SYSLIB SCTLFL.
  20. ;
  21.     PUBLIC    SLWDC
  22. ;
  23.     EXT    SOUT        ; SYSLIB
  24. ;
  25. SLWDC:    push    af        ; save all registers
  26.     push    bc
  27.     push    de
  28.     push    hl
  29.     ld    (FldSiz),a    ; save field size
  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.  If field
  86. ; size is less than or equal to the actual length, just output number.  If
  87. ; field size is greater, output spaces first.
  88.     ld    c,b
  89.     ld    b,0        ; BC = length of number
  90.     ld    a,(FldSiz)
  91.     sub    c        ; A = field size less number size
  92.     jr    c,NoSpc        ; (number bigger than field)
  93.     jr    z,NoSpc        ; (number equals field)
  94.     ld    b,a        ; B = count of leading spaces needed
  95.     ld    a,' '
  96. Loop3:    call    SOUT        ; output leading spaces
  97.     djnz    Loop3
  98. ; C = length of number, HL points to first byte of number, so output it.
  99. NoSpc:    ld    b,c        ; put count in B
  100. PrLoop:    ld    a,(hl)
  101.     call    SOUT
  102.     inc    hl
  103.     djnz    PrLoop    
  104.     pop    hl        ; restore all registers
  105.     pop    de
  106.     pop    bc
  107.     pop    af
  108.     ret
  109. ;
  110.     DSEG
  111. ;
  112. AscBuf:    ds    10        ; work area for ASCII 10-digit number
  113. LWBuf:    ds    4        ; work area for 4-byte long-word
  114. BCDBuf:    ds    5        ; work area for 5-byte packed BCD number
  115. FldSiz:    ds    1        ; storage for field size
  116. ;
  117.     end
  118.