        TITLE   SHRPRINT - PRINTF at SHARE level
        NAME    SHRPRINT
;
;       Microsoft Confidential
;       Copyright (C) Microsoft Corporation 1991
;       All Rights Reserved.
;
;   Modification history:
;
;       Created: MZ 16 June 1984
;

        .xlist
        .xcref
        include version.inc
        include dosseg.inc
        INCLUDE DOSSYM.INC
        INCLUDE DEVSYM.INC
        .cref
        .list

        I_Need  Proc_ID,WORD
        I_Need  User_ID,WORD

BREAK   <debugging output>

Share   SEGMENT PARA PUBLIC 'SHARE'
        ASSUME  SS:DOSGROUP,CS:SHARE




;       PFMT - formatted output.  Calling sequence:
;         PUSH    BP
;         PUSH    fmtstr
;         MOV     BP,SP
;         PUSH    args
;         CALL    PFMT
;         ADD     SP,n
;         POP     BP
;
; The format string contains format directives and normal output characters
; much like the PRINTF for C.  We utilize NO format widths.  Special chars
; and strings are:
;
;       $x      output a hex number
;       $s      output an offset string
;       $c      output a character
;       $S      output a segmented string
;       $p      output userid/processid
;       \t      output a tab
;       \n      output a CRLF
;
; The format string must be addressable via CS
;

Procedure PFMT,NEAR
        ASSUME  SS:nothing
        SAVE    <AX,BX,DS,SI>
        MOV     AX,8007h
        INT     2Ah
        GETDSEG DS
        SUB     BP,2
        Call    FMTGetArg
        MOV     SI,AX
FmtLoop:
        LODSB
        OR      AL,AL
        JZ      FmtDone
        CMP     AL,'$'
        JZ      FmtOpt
        CMP     AL,'\'
        JZ      FmtChr
FmtOut:
        CALL    fOut
        JMP     SHORT FmtLoop

fOut:
        call    putch                   ; put character on serial port
        return

FmtDone:
        MOV     AX,8107h
        INT     2Ah
        RESTORE <SI,DS,BX,AX>
        RET
;
; \ leads in a special character. See what the next char is.
;
FmtChr: LODSB
        OR      AL,AL                   ; end of string
        JZ      fmtDone
        CMP     AL,'n'                  ; newline
        JZ      FmtCRLF
        CMP     AL,'t'                  ; tab
        JNZ     FmtOut
        MOV     AL,9
        JMP     SHORT FmtOut
FmtCRLF:MOV     AL,13
        CALL    fOut
        MOV     AL,10
        JMP     SHORT FmtOut
;
; $ leads in a format specifier.
;
FmtOpt: LODSB
        CMP     AL,'x'                  ; hex number
        JZ      FmtX
        CMP     AL,'c'                  ; single character
        JZ      FmtC
        CMP     AL,'s'                  ; offset string
        JZ      FmtSoff
        CMP     AL,'S'                  ; segmented string
        JZ      FmtSseg
        CMP     AL,'p'
        JZ      FmtUPID
        JMP     SHORT FmtOut
FmtX:
        Call    FMTGetArg
        MOV     BX,AX
        CALL    MNUM
        JMP     SHORT FmtLoop
FmtC:
        Call    FmtGetArg
        CALL    fOut
        JMP     SHORT FmtLoop
FmtSoff:
        SAVE    <SI>
        Call    FmtGetArg
        MOV     SI,AX
        CALL    fmtsout
        RESTORE <SI>
        JMP     SHORT FmtLoop
FmtSSeg:
        SAVE    <DS,SI>
        CALL    FMTGetArg
        MOV     DS,AX
        CALL    FMTGetArg
        MOV     SI,AX
        CALL    fmtsout
        RESTORE <SI,DS>
        JMP     SHORT FmtLoop
FmtUPID:
        INTTEST
        SAVE    <DS>
        MOV     BX,0
        MOV     DS,BX
        INTTEST                 ; what to hell is this 82h?
        MOV     DS,DS:[82h]
    ASSUME DS:DOSDATA
        MOV     BX,User_ID
        CALL    MNUM
        MOV     AL,':'
        CALL    fOUT
        MOV     BX,Proc_ID
        CALL    MNUM
        RESTORE <DS>
    Assume DS:NOTHING
        JMP     SHORT FmtLoop
EndProc PFMT

Procedure   FMTGetArg,NEAR
        MOV     AX,[BP]
        SUB     BP,2
        return
EndProc FMTGetArg

Procedure   FmtSOut,NEAR
        LODSB
        OR      AL,AL
        retz
        CALL    fOUT
        JMP     SHORT FmtSOut
EndProc FMTSout

;**     MOut - output a message via serial port
;
;       ENTRY   (cs:bx) = message
;       USES    bx

Procedure   MOut,Near
        ASSUME  ES:NOTHING
        PUSHF
        Save    <ds, si, AX>
        PUSH    CS
        POP     DS
        MOV     SI,BX
        Call    FMTSout
        Restore <AX,SI,DS>
        POPF
        return
EndProc MOut

;   MNum - output a number in BX
;   Inputs:     BX contains a number
;   Outputs:    number in hex appears on screen
;   Registers modified: BX

Procedure   MNum,NEAR
        ASSUME  SS:NOTHING
        PUSHF
        SAVE    <ES,DI,AX,BX,CX,SI,DS>
        PUSH    SS
        POP     ES
        SUB     SP,6
        MOV     DI,SP                   ;   p = MNumBuf;
        SAVE    <DI>
        MOV     CX,4                    ;   for (i=0; i < 4; i++)
DLoop:  SAVE    <CX>
        MOV     CX,4                    ;       rotate(n, 4);
        ROL     BX,CL
        RESTORE <CX>
        MOV     AL,BL
        AND     AL,0Fh
        ADD     AL,'0'
        CMP     AL,'9'
        JBE     Nok
        ADD     AL,'A'-'0'-10
Nok:    STOSB                           ;       *p++ = "0123456789ABCDEF"[n];
        LOOP    DLoop
        XOR     AL,AL
        STOSB                           ;   *p++ = 0;
        RESTORE <SI>
        PUSH    ES
        POP     DS
        CALL    FMTSOUT                 ;   mout (mNumBuf);
        ADD     SP,6
        RESTORE <DS,SI,CX,BX,AX,DI,ES>
        POPF
        return
EndProc MNum


comport EQU     03f8h   ; default to COM1

;**     putch - put character
;
;       (al) = character to output


        Public  putch
putch   PROC    near
        push    dx

        cmp     al,7
        je      putch1
        cmp     al,0ah          ; filter out some garbage characters
        je      putch1          ; that %s can produce when we don't
        cmp     al,0dh          ; have a null terminated string
        je      putch1
        cmp     al,20h
        jae     pch0
        mov     al,'.'
        jmp     SHORT putch1

pch0:   cmp     al,07fh
        jb      putch1
        mov     al,'.'

putch1:
        cmp     al,0ah
        jne     putch2
        call    putraw
        mov     al,0dh
putch2: call    putraw
        pop     dx
        ret

putch   ENDP


        DPUBLIC putraw
putraw  PROC    near

        mov     dx, comport + 03fdh-3f8h
        mov     ah,al
putr5:  in      al,dx
        and     al,020h
        jz      putr5
        mov     al,ah
        mov     dx, comport
        out     dx,al
        ret

putraw  ENDP



 DPUBLIC <FmtLoop, FmtOut, fOut, FmtDone, FmtChr, FmtCRLF, FmtOpt, FmtX>
 DPUBLIC <FmtC, FmtSoff, FmtSSeg, FmtUPID, DLoop, Nok, pch0, putch1, putch2, putr5>

SHARE   ENDS
END
