
;************************************************************************
; Load a new character generator into plane 2                           *
; Entry:        Ptr_CG  - Pointer to new character generator            *
;               Start   - First ASCII code to use                       *
;               Count   - Number of characters to load                  *
;************************************************************************

Ptr_CG  EQU     [BP+4]
Start   EQU     [BP+6]
Count   EQU     [BP+8]

        PUBLIC  _Write_Char_Gen

_Write_Char_Gen PROC    NEAR
        PUSH    BP
        MOV     BP,SP
        PUSH    ES
        PUSH    DS
        PUSH    DI
        PUSH    SI

        ;--- Enable memory for write into plane 2

        MOV     DX,03C4h                ; sequencer enable map 2 for write
        MOV     AL,2
        OUT     DX,AL
        INC     DX
        MOV     AL,4
        OUT     DX,AL

        DEC     DX                      ; sequencer no chaining
        MOV     AL,4
        OUT     DX,AL
        INC     DX
        MOV     AL,6
        OUT     DX,AL

        MOV     DX,03CEh                ; graphics use data from processor
        MOV     AL,1
        OUT     DX,AL
        INC     DX
        MOV     AL,0
        OUT     DX,AL

        DEC     DX                      ; graphics read and write modes
        MOV     AL,5
        OUT     DX,AL
        INC     DX
        MOV     AL,0
        OUT     DX,AL

        DEC     DX                      ; graphics address mapped to A000
        MOV     AL,6
        OUT     DX,AL
        INC     DX
        MOV     AL,05h
        OUT     DX,AL

        DEC     DX                      ; graphics enable 8 bits per write
        MOV     AL,8
        OUT     DX,AL
        INC     DX
        MOV     AL,0FFh
        OUT     DX,AL

        ;--- load the character generator into plane 2

        MOV     AX,0A000h               ;Point to segment A000
        MOV     ES,AX
        MOV     AX,Start                ;Compute offset into char gen plane
        MOV     CL,5                    ;as index * bytes_per_char
        SHL     AX,CL                   ;which is index * 32
        MOV     DI,AX                   ;Copy offset in char gen plane into DI
        MOV     SI,Ptr_CG               ;Fetch pointer to new characters
        MOV     AX,Count                ;Fetch number of characters to copy
        SHL     AX,CL                   ;Compute how many bytes to copy
        SHR     AX,1                    ;Divide by two so we can use MOV WORD
        MOV     CX,AX                   ;Copy count into CX

        REP     MOVSW                   ;Copy the data

        ;--- Restore Sequencer and Graphics Controller

        MOV     DX,03C4h                ; Enable plane 0 & 1 for write
        MOV     AL,2
        OUT     DX,AL
        INC     DX
        MOV     AL,03H
        OUT     DX,AL

        DEC     DX                      ; sequencer even/odd & text
        MOV     AL,4
        OUT     DX,AL
        INC     DX
        MOV     AL,3
        OUT     DX,AL

        MOV     DX,3CEH                 ; graphics read and write modes
        MOV     AL,5
        OUT     DX,AL
        INC     DX
        MOV     AL,10H
        OUT     DX,AL
        DEC     DX

        XOR     AX,AX
        MOV     ES,AX
        TEST    BYTE PTR ES:[BIOS_Equipment],2
        JNZ     WCG_Set_B000

        MOV     DX,3CEH                 ;Map display buffer to B800
        MOV     AL,6
        OUT     DX,AL
        INC     DX
        MOV     AL,0EH
        OUT     DX,AL
        JMP     WCG_Done
WCG_Set_B000:
        MOV     DX,3CEH                 ;Map display buffer to B000
        MOV     AL,6
        OUT     DX,AL
        INC     DX
        MOV     AL,0AH
        OUT     DX,AL

        ;--- Clean up and exit
WCG_Done:
        POP     SI
        POP     DI
        POP     DS
        POP     ES
        MOV     SP,BP
        POP     BP
        RET
_Write_Char_Gen ENDP
