
;************************************************************************
;                                                                       *
; Select mode on EGA adapter by loading all control                     *
; registers.  Register are read from a table pointed to by              *
;                                                                       *
; Entry: [BP+4]-Pointer to the parameter table                          *
;               Parameter table should have the following format        *
;               1 byte  - 3BA for mono modes, 3DA for color modes       *
;               4 bytes - Sequencer values for register 1 - 4           *
;               25 bytes- CRT controller values                         *
;               9 bytes - Graphics controller values                    *
;               20 bytes- Attribute register values                     *
;                                                                       *
;************************************************************************

        PUBLIC  _Write_Register_Set
_Write_Register_Set      PROC    NEAR
        PUSH    BP                      ;Standard entry from C call
        MOV     BP,SP
        PUSH    SI
        PUSH    DI

        ;--- Select both graphics controllers

        MOV     DX,3CCH                 ;Load address
        MOV     AL,0                    ;Select controller 0
        OUT     DX,AL
        MOV     DX,3CAH                 ;Load address of second controller
        MOV     AL,1                    ;Select controller 1
        OUT     DX,AL

        ;--- Get address of CRT controller from the parameter table
        ;    and turn the video off

        MOV     SI,[BP+4]               ;Fetch pointer to param table
        MOV     DI,SI                   ;Keep pointer to first parameter
        LODSB                           ;Fetch the crt controller address
        MOV     DL,AL
        MOV     DH,3
        ADD     DX,6                    ;Turn video off
        IN      AL,DX                   ;First reset data/index flip flop
        MOV     DX,3C0H                 ;Address of attribute controller
        XOR     AL,AL
        OUT     DX,AL                   ;Write 0 to turn video off

        ;--- Load the Miscellaneous regiser

        MOV     DX,3C2H                 ;Fetch Misc register address
        LODSB                           ;Fetch value from parameter table
        OUT     DX,AL                   ;Load the Misc register

        ;--- Load the Sequencer registers

        MOV     DX,3C4H                 ;Halt the sequencer
        XOR     AL,AL
        OUT     DX,AL
        INC     DX
        MOV     AL,1
        OUT     DX,AL
        DEC     DX

        MOV     CX,4                    ;Number of registers to load
        MOV     AH,1                    ;First register to load

LoopSeq:MOV     AL,AH                   ;Fetch index
        OUT     DX,AL                   ;Select index
        INC     DX                      ;Address of data register
        LODSB                           ;Fetch value from paramter table
        OUT     DX,AL                   ;Load data register
        INC     AH                      ;Update register index
        DEC     DX
        LOOP    LoopSeq                 ;Check if more to do

        MOV     AL,0                    ;Restart the sequencer
        OUT     DX,AL
        INC     DX
        MOV     AL,3
        OUT     DX,AL

        ;--- Load the CRT controller registers

        MOV     DL,[DI]                 ;Fetch address of CRT controller
        MOV     CX,25                   ;Number of registers to load
        XOR     AH,AH                   ;Index of first register to load

LoopCRT:MOV     AL,AH                   ;Fetch index
        OUT     DX,AL                   ;Select register
        INC     DX                      ;Address of data register
        LODSB                           ;Fetch data
        OUT     DX,AL                   ;Load data register
        DEC     DX                      ;Address of index
        INC     AH                      ;Update index
        LOOP    LoopCRT

        ;--- Load the Graphics controller registers

        MOV     DX,3CEH
        MOV     CX,9
        XOR     AH,AH

LoopGrf:MOV     AL,AH                   ;Fetch index
        OUT     DX,AL                   ;Select index
        INC     DX
        LODSB                           ;Fetch value from parameter table
        OUT     DX,AL                   ;Load value into data register
        INC     AH
        DEC     DX
        LOOP    LoopGrf

        ;--- Load the palette registers in the Attribute controller

        MOV     DL,[DI]                 ;Reset data/index flip-flop
        ADD     DL,6
        IN      AL,DX

        MOV     DX,3C0H                 ;Address of index register
        MOV     CX,16                   ;Number of registers to load
        XOR     AH,AH                   ;First index

LoopVLT:MOV     AL,AH                   ;Fetch index
        OUT     DX,AL                   ;Select next index
        LODSB                           ;Fetch value from parameter table
        OUT     DX,AL                   ;Load the next data register
        INC     AH                      ;Update index
        LOOP    LoopVLT

        ;--- Load Attribute registers beyond palette

        MOV     CX,4                    ;Number of register to load
        MOV     AH,30H                  ;Starting index is 10H and 20h is
                                        ;used to turn Attr. Ctrl on
LoopAtt:MOV     AL,AH                   ;Fetch next index
        OUT     DX,AL                   ;Select the index
        LODSB                           ;Fetch value from parameter table
        OUT     DX,AL                   ;Load register with the value
        INC     AH                      ;Update index
        LOOP    LoopAtt

        POP     DI                      ;Standard return to C
        POP     SI
        MOV     SP,BP
        POP     BP
        RET
_Write_Register_Set  ENDP
