        name    vcrtc     ; VGA CRTC register routines
        ;
        ;  int  CRTCread_reg(int reg);
        ;  int  CRTCset_reg(int reg, int value);
        ;  int  CRTCset_regm(int reg, int value, int bitmask);
        ;
CRTC_CTRL_PORT      EQU     03D4h
CRTC_DATA_PORT      EQU     03D5h

REGNO    equ     [bp+06]
VALUE    equ     [bp+08]
BMASK    equ     [bp+0ah]

CRTC_TEXT       segment byte public 'CODE'
        public  _CRTCread_reg
        assume  cs:CRTC_TEXT
_CRTCread_reg   proc    far
        push    bp
        mov     bp,sp

        mov     al,REGNO
        mov     dx,CRTC_CTRL_PORT
        out     dx,al
        inc     dx
        in      al,dx

        xor     ah,ah
        pop     bp
        ret
_CRTCread_reg   endp
        ;
        public  _CRTCset_reg
_CRTCset_reg   proc    far
        push    bp
        mov     bp,sp

        mov     ah,VALUE
@update:
        mov     al,REGNO
        mov     dx,CRTC_CTRL_PORT
        out     dx,ax

        xor     ax,ax
        pop     bp
        ret
_CRTCset_reg   endp
        ;
        public  _CRTCset_regm
_CRTCset_regm     PROC  far
        push    bp
        mov     bp,sp

        mov     al,REGNO                ; read old value
        mov     dx,CRTC_CTRL_PORT
        out     dx,al
        inc     dx
        in      al,dx

        mov     bl,BMASK                ; create new value
        not     bl        ; !mask
        and     al,bl     ; al=(!mask&reg(reg_num));
        mov     cl,al     ; save for a microsecond
        mov     ah,VALUE
        mov     bl,BMASK
        and     ah,bl
        or      ah,cl           ; leave value in ah for _CRTCset_reg

        jmp     @update         ; jump into _CRTCset_reg

_CRTCset_regm     ENDP
CRTC_TEXT       ends
        end

