;*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
;*
;*****************************************************************************/

;/***************************************************************************
;*
;* MACRO NAME    = invoke - call a procedure 
;*
;* DESCRIPTION   = 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.                                      
;*
;*        WARNING: Use is discouraged because it increases link time and
;*                 encourages people to not declare external procedures
;*                 explicitly.
;*
;* INPUT         = name = name of procedure to call 
;*
;* OUTPUT        = call and extrn (if necessary) generated. 
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

invoke  MACRO   name

IFNDEF name
        extrn   name:far
ENDIF
        CALL    name
ENDM


;/***************************************************************************
;*
;* MACRO NAME    = REP_MOVSW
;*
;* DESCRIPTION   = 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.                                         
;*
;*        WARNING: Use is discouraged because it increases link time and
;*                 encourages people to not declare external procedures
;*                 explicitly.
;*
;* INPUT         = (ds:si) - source pointer         
;*                 (es:di) - destination pointer    
;*                 (cx) - number of iterations
;* OUTPUT        = (ds:si) - end of source         
;*                 (es:di) - end of destination
;*                 (cx) - zero                     
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_MOVSW   MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
        rep movsw
ELSE
        call    CGA_REP_MOVSW
ENDIF

ENDM

;/***************************************************************************
;*
;* MACRO NAME    = REP_STOSW
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;*                                                       
;* OUTPUT        = (es:di) - end of destination          
;*                 (cx) - zero                           
;*                 
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_STOSW   MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
        rep stosw
ELSE
        call    CGA_REP_STOSW
ENDIF

ENDM

;/***************************************************************************
;*
;* MACRO NAME    = REP_MOVSB_INCSI_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_MOVSB_INCSI_LOOP    MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat                     ; 
                movsb                   ; Transfer chars to destination
                inc     si              ; 
            .loop                       ; 

ELSE
        call    CGA_REP_MOVSB_INCSI_LOOP
ENDIF

ENDM

;/***************************************************************************
;*
;* MACRO NAME    = REP_MOVSB_STOSW_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_MOVSW_STOSW_LOOP    MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat
                movsw           ; Transfer cells to destination
                stosw
            .loop
ELSE
        call    CGA_REP_MOVSW_STOSW_LOOP
ENDIF

ENDM

;/***************************************************************************
;*
;* MACRO NAME    = REP_INCDI_STOSB_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_INCDI_STOSB_LOOP    MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat
                inc     di                  ; skip the character
                stosb                       ; save the attribute
            .loop
ELSE
        call    CGA_REP_INCDI_STOSB_LOOP
ENDIF

ENDM


;/***************************************************************************
;*
;* MACRO NAME    = REP_STOSB_INCDI_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_STOSB_INCDI_LOOP    MACRO


IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat
                stosb
                inc     di                  ; skip the attribute
            .loop
ELSE
        call    CGA_REP_STOSB_INCDI_LOOP
ENDIF

ENDM


;/***************************************************************************
;*
;* MACRO NAME    = REP_LODSB_STOSW_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_LODSB_STOSW_LOOP    MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat
                lodsb                       ; (al) = char , (ah) = attribute
                stosw                       ; write the cell
            .loop
ELSE
        call    CGA_REP_LODSB_STOSW_LOOP
ENDIF

ENDM


;/***************************************************************************
;*
;* MACRO NAME    = REP_MOVSB_INCDI_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_MOVSB_INCDI_LOOP    MACRO


IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat                         
                movsb                       
                inc     di
            .loop
ELSE
        call    CGA_REP_MOVSB_INCDI_LOOP
ENDIF

ENDM


;/***************************************************************************
;*
;* MACRO NAME    = REP_MOVSB_ADDSI2_LOOP
;*
;* DESCRIPTION   = 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.                                         
;*
;* INPUT         = (ds:si) - source pointer              
;*                 (es:di) - destination pointer         
;*                 (cx) - number of iterations           
;* OUTPUT        = (ds:si) - end of source               
;*                 (es:di) - end of destination          
;*                 (cx) - zero                  
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

REP_MOVSW_ADDSI2_LOOP   MACRO

IF NOT VDHCGA OR CGA_ALWAYS_FAST                                        ;MS??
            .repeat                 
                movsw               
                add     si,2        ; Transfer cells to destination
            .loop                   ; skip final word of attribute
ELSE
        call    CGA_REP_MOVSW_ADDSI2_LOOP
ENDIF

ENDM
