.386p

;
; In general, you can use these three equates to do out_xxx's
; from any code, protect or real, in any module, retail or debug
;
;
;COM1      EQU     03f8h      ; COM1
;COM2      EQU     02f8h      ; COM2
;COM_PORT  EQU     COM1       ; Default COM Port
;
;
; For OS2LDR, we know the COM port to use.
;
; If HYBERLDR then it is expected that the com port ddress is already in dx.
ifndef HYBERLDR
COM_PORT   EQU    [ComPortAddr]
endif



;*********************************************
;
; Routines - out_str   |  Macros
;            out_char  |
;            out_byte  |
;            out_word  |
;            out_dword |
;            out_crlf  |
;            out_w_str |
;
; Define OUT32BIT if used in a 32 bit code
; object.
;
;*********************************************

;*********************************************
; Routine: out_str
;          Sends a string of characters and a
;          crlf out the specified com port
; Entry  : Str
; Exit   : None
; Uses   : None
;*********************************************

out_str   macro   str
          local   strptr, os1
          jmp     os1
strptr    db      str, 0
os1:      push    ax
          push    ds
ifdef OUT32BIT
          push    esi
else
          push    si
endif
          mov     ax,cs
          mov     ds,ax
ifdef OUT32BIT
          mov     esi,offset FLAT:strptr
else
          mov     si,offset strptr
endif
          out_w_str
          out_crlf
ifdef OUT32BIT
          pop     esi
else
          pop     si
endif
          pop     ds
          pop     ax
          endm

;*********************************************
; Routine: out_char
;          Low level routine that performs in's
;          and out's to send a character out
;          the specified com port
; Entry  : AL
; Exit   : None
; Uses   : None
;*********************************************

out_char  macro
          local   oc1
          pushf
ifndef HYBERLDR
          push    dx
          mov     dx,COM_PORT
endif
          push    dx
          add     dx,5
          push    ax
oc1:      in      al,dx
          test    al,020H
          jz      short oc1
          pop     ax
          pop     dx
          out     dx,al
ifndef HYBERLDR
          pop     dx
endif
          popf
          endm

;*********************************************
; Routine: out_byte
;          Formats a byte in ASCII and sends
;          it out the specified com port
; Entry  : AL
; Exit   : None
; Uses   : AX
;*********************************************

out_byte  macro
          local   l0,l1,l2,l3,l4,lx
          pushf
          push    bx
          mov     bx,1

l0:       push    ax
          shl     ax,4
          and     ah,0fh
          shr     al,4
          cmp     ah,9
          ja      short l1
          add     ah,30h
          jmp     short l2
l1:       add     ah,'a'-0ah
l2:       cmp     al,9
          ja      short l3
          add     al,30h
          jmp     short l4
l3:       add     al,'a'-0ah
l4:       xchg    al,ah
          out_char
          mov     al,ah
          out_char
          pop     ax
          dec     bx
          jz      short lx
          shr     ax,8
          jmp     short l0

lx:       pop     bx
          popf
          endm

;*********************************************
; Routine: out_word
;          Formats a word in ASCII and sends
;          it out the specified com port
; Entry  : AX
; Exit   : None
; Uses   : AX
;*********************************************

out_word  macro
          local   l0,l1,l2,l3,l4,lx
          pushf
          push    bx
          mov     bx,2
          rol     ax,8
l0:       push    ax
          shl     ax,4
          and     ah,0fh
          shr     al,4
          cmp     ah,9
          ja      short l1
          add     ah,30h
          jmp     short l2
l1:       add     ah,'a'-0ah
l2:       cmp     al,9
          ja      short l3
          add     al,30h
          jmp     short l4
l3:       add     al,'a'-0ah
l4:       xchg    al,ah
          out_char
          mov     al,ah
          out_char
          pop     ax
          dec     bx
          jz      short lx
          shr     ax,8
          jmp     short l0

lx:       pop     bx
          popf
          endm

;*********************************************
; Routine: out_dword
;          Formats a dword in ASCII and sends
;          it out the specified com port
; Entry  : EAX
; Exit   : None
; Uses   : EAX
;*********************************************

out_dword macro
          push    eax
          shr     eax,16
          out_word
          pop     eax
          out_word
          endm

;*********************************************
; Routine: out_crlf
;          Sends a carriage return and line
;          feed out the specified com port
; Entry  : None
; Exit   : None
; Uses   : None
;*********************************************

out_crlf  macro
          push    ax
          mov     al,13
          out_char
          mov     al,10
          out_char
          pop     ax
          endm

;*********************************************
; Routine: out_w_str
;          Sends a string of characters out
;          the specified com port
; Entry  : DS:SI - Address of string terminated by 0
; Exit   : None
; Uses   : SI
;*********************************************

out_w_str macro
          local   p0,px
          pushf
          push    ax
          cld
p0:       lodsb
          or      al,al
          jz      short px
          out_char
          jmp     short p0
px:       pop     ax
          popf
          endm

