; Greg Vigneault
;
; Below is a routine which can display a 16-bit unsigned value, in
; number bases 2 thru 16, and optionally pad the output to a minimum
; field width (adapted from my assembler libraries).
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
code        segment byte            ; complete executable example
            assume  cs:code,ds:code ; MASM prologue
            org     100h            ; lowly .COM file
main        proc    near            ; tiny code
            jmp     start           ; over subroutines & data
;----------------------------------------------------------------------
WriteLn:    mov     al,13           ; carriage return
            call    WriteChar
            mov     al,10           ; line feed
;--------------------------------
WriteChar:  mov     dl,al           ; ASCII character
            mov     ah,2            ; fn: display char
            int     21h             ; via dos
            ret                     ; WriteChar
;----------------------------------------------------------------------
nbase       dw      10      ; base 2..16 (binary=2,oct=8,dec=10,hex=16)
flen        db      0       ; minimum field width (0|1 = no padding)
padchr      db      ' '     ; field pad character, usually ' ' or '0'
WriteWord:                  ; call with 16-bit unsigned value in AX
            mov     bx, nbase       ; number base divider
            sub     cx,cx           ; to count digits
    ww1:    sub     dx,dx           ; clear high word
            div     bx              ; get low digit
            push    dx              ; save it
            inc     cx              ; count it
            test    ax,ax           ; more digits?
            jnz     ww1             ; yes
            mov     al, flen        ; minimum field width
            cmp     ax,cx           ; greater than actual width?
            jbe     ww3             ; no
            push    cx              ; save char string length
            sub     ax,cx           ; get difference
            mov     cx,ax           ; as pad char count
    ww2:    mov     al, padchr      ; get pad char
            call    WriteChar       ; display it
            loop    ww2             ; all pad chars
            pop     cx              ; original string length
    ww3:    pop     ax              ; get digit, raw 0..15
            add     al,90h          ; make it a packed digit
            daa                     ; correction for 10..15
            adc     al,40h          ; per ASCII
            daa                     ; correction for 0..9
            call    WriteChar       ; display this digit
            loop    ww3             ; and all digits
            ret                     ; WriteWord
;----------------------------------------------------------------------
start:                                  ; default: decimal, no padding
            mov     cx,2                ; outer loop count
    eg1:    push    cx                  ; save
            mov     cx,10               ; inner loop count
            mov     ax,cx               ; for 10..19 | 0Ah..13h
    eg2:    push    ax                  ; preserve value
            push    cx                  ;   and loop count
            call    WriteWord           ; display the word value
            call    WriteLn             ; new line
            pop     cx                  ; restore loop count
            pop     ax                  ;   and word value
            inc     ax                  ; next word
            loop    eg2                 ; ten consecutive values
            call    WriteLn             ; disjoined data
            mov     word ptr nbase,16   ; now display hexadecimal
            mov     byte ptr flen,4     ; pad to minimum of 4 digits
            mov     byte ptr padchr,'0' ; use '0' for padding
            pop     cx                  ; 2nd loop
            loop    eg1                 ; to show 000A..0013
            int     20h                 ; end program
;----------------------------------------------------------------------
main        endp                        ; MASM epilogue
code        ends
            end     main
