
;************************************************************************
; Display text at specified row and column                              *
; Entry:        Row             - Starting row of the text              *
;               Column  - Starting column of the text                   *
;               String  - Pointer to a null terminated string of text   *
;************************************************************************

Row     EQU     [BP+4]
Column  EQU     [BP+6]
String  EQU     [BP+8]

        PUBLIC  _Write_String

_Write_String   PROC NEAR
        PUSH    BP
        MOV     BP,SP
        PUSH    DI                      ;Preserve registers
        PUSH    SI
        PUSH    ES

        ;--- Fetch number of rows and columns on the screen and
        ;    compute absolute address in display buffer

        XOR     AX,AX                   ;Point ES to segment zero
        MOV     ES,AX
        MOV     AX,Row                  ;Fetch row number
        MOV     BX,ES:[BIOS_Columns]    ;Fetch columns per screen
        MUL     BX                      ;Compute absolute address
        ADD     AX,Column               ;in the display buffer as
        SHL     AX,1                    ;((Row*Col_per_row)+Column)*2
        MOV     DI,AX                   ;Move address into register DI

        ;--- Determine and load segement of the display buffer

        MOV     AX,0B000H               ;Assume monochrome buffer address
        TEST    BYTE PTR ES:[BIOS_Equipment],2   ;Is mono attached?
        JNZ     Str_Address_Ok          ;...Yes, go load segment
        MOV     AX,0B800H               ;...No, change address to color
Str_Address_Ok:
        MOV     ES,AX                   ;Set segment of display buffer

        ;--- Fetch address of the text

        MOV     SI,String               ;Get pointer to the string
Next_String:
        LODSB                           ;Fetch next character
        OR      AL,AL                   ;Is character the terminating zero?
        JZ      String_Done             ;...Yes, we are done
        STOSB                           ;...No, put it into display buffer
        INC     DI                      ;Skip attribute byte
        JMP     Next_String             ;Go examine next character

String_Done:
        POP     ES                      ;Restore registers
        POP     SI
        POP     DI
        POP     BP
        RET
_Write_String   ENDP
