;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = XGAMAC.INC
;*
;* DESCRIPTIVE NAME = Macros needed by CGA
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Macros needed by CGA
;*
;* FUNCTIONS    NONE
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*
;*****************************************************************************/

;***    invoke - call a procedure
;
;       WARNING: Use is discouraged because it increases link time and
;                encourages people to not declare external procedures
;                explicitly.
;
;       Generate a call to procedure "name." If the procedure "name"
;       is not defined in the current file then an extrn name:near is
;       also generated. This also causes larger .obj file and slower
;       link time because the extrn causes a flush of the LEDATA
;       record (data structure used by the assembler) for the current
;       segment, generates an EXTRN record, then re-opens the LEDATA
;       record. The fast way is to lump all EXTRN's in one place.
;
;       ENTRY:  name = name of procedure to call
;
;       EXIT:   call and extrn (if necessary) generated.

invoke  MACRO   name

IFNDEF name
        extrn   name:far
ENDIF
        CALL    name
ENDM


;***    REP_MOVSW
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_MOVSW   MACRO

IFNDEF  VDHCGA
        rep movsw
ELSE
        call    CGA_REP_MOVSW
ENDIF

ENDM

;***    REP_STOSW
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (es:di) - end of destination
;               (cx) - zero
;

REP_STOSW   MACRO

IFNDEF  VDHCGA
            rep stosw
ELSE
        call    CGA_REP_STOSW
ENDIF

ENDM

;***    REP_MOVSB_INCSI_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_MOVSB_INCSI_LOOP    MACRO

IFNDEF  VDHCGA
            .repeat                     ; 
                movsb                   ; Transfer chars to destination
                inc     si              ; 
            .loop                       ; 

ELSE
        call    CGA_REP_MOVSB_INCSI_LOOP
ENDIF

ENDM

;***    REP_MOVSB_STOSW_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_MOVSW_STOSW_LOOP    MACRO

IFNDEF  VDHCGA
            .repeat
                movsw           ; Transfer cells to destination
                stosw
            .loop
ELSE
        call    CGA_REP_MOVSW_STOSW_LOOP
ENDIF

ENDM

;***    REP_INCDI_STOSB_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_INCDI_STOSB_LOOP    MACRO

IFNDEF  VDHCGA
            .repeat
                inc     di                  ; skip the character
                stosb                       ; save the attribute
            .loop
ELSE
        call    CGA_REP_INCDI_STOSB_LOOP
ENDIF

ENDM


;***    REP_INCDI_STOSB_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (es:di) - end of destination
;               (cx) - zero
;

REP_STOSB_INCDI_LOOP    MACRO


IFNDEF  VDHCGA
            .repeat
                stosb
                inc     di                  ; skip the attribute
            .loop
ELSE
        call    CGA_REP_STOSB_INCDI_LOOP
ENDIF

ENDM


;***    REP_LODSB_STOSW_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_LODSB_STOSW_LOOP    MACRO

IFNDEF  VDHCGA
            .repeat
                lodsb                       ; (al) = char , (ah) = attribute
                stosw                       ; write the cell
            .loop
ELSE
        call    CGA_REP_LODSB_STOSW_LOOP
ENDIF

ENDM


;***    REP_MOVSB_INCDI_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_MOVSB_INCDI_LOOP    MACRO


IFNDEF  VDHCGA
            .repeat                         
                movsb                       
                inc     di
            .loop
ELSE
        call    CGA_REP_MOVSB_INCDI_LOOP
ENDIF

ENDM


;***    REP_MOVSB_ADDSI2_LOOP
;
;       This macro is used so that CGA can use the same buffer update
;       routines that VGA and EGA use.  At compile time, the macro is
;       replaced by either the simple data movement instructions or a
;       call to a routine that handles the movement for the CGA.
;
;       ENTRY:  (ds:si) - source pointer
;               (es:di) - destination pointer
;               (cx) - number of iterations
;
;       EXIT:   (ds:si) - end of source
;               (es:di) - end of destination
;               (cx) - zero
;

REP_MOVSW_ADDSI2_LOOP   MACRO

IFNDEF  VDHCGA
            .repeat                 
                movsw               
                add     si,2        ; Transfer cells to destination
            .loop                   ; skip final word of attribute
ELSE
        call    CGA_REP_MOVSW_ADDSI2_LOOP
ENDIF

ENDM
