
;************************************************************************
;*                                                                      *
;* File:        PALETTE.ASM - Load palette registers                    *
;* Routine:     _Load_Palette                                           *
;* Arguments:   Start, Count, ArrayPtr                                  *
;*                                                                      *
;************************************************************************

        PUBLIC  _Load_Palette

PAL_TEXT   SEGMENT BYTE PUBLIC 'CODE'

Arg_Start       EQU     WORD PTR  [BP+6]
Arg_Count       EQU     WORD PTR  [BP+8]
Arg_ArrayPtr    EQU     DWORD PTR [BP+0ah]
        ASSUME  CS:PAL_TEXT
_Load_Palette   PROC far
        PUSH    BP                      ;Preserve BP
        MOV     BP,SP                   ;Preserve stack pointer

        PUSH    ES                      ;Preserve segment and index registers
        PUSH    DS
        PUSH    DI
        PUSH    SI

        ; Get address of input status registers

        XOR     AX,AX                   ;Segment of BIOS data area
        MOV     ES,AX
        MOV     DX,ES:[463h]            ;Fetch address of CRTC
        ADD     DX,6                    ;Compute address of input status reg

        ; Load palette registers

        IN      AL,DX                   ;Reset data/address flip/flop
        MOV     DX,3C0h                 ;Fetch address of Attribute Controller
        LDS     SI,Arg_ArrayPtr         ;Fetch pointer to palette values
        MOV     AX,Arg_Start            ;Index of first palette register
        MOV     CX,Arg_Count            ;Number of registers to load

Palette_Loop:
        OUT     DX,AL                   ;Select next register
        XCHG    AH,AL                   ;Save register index
        LODSB                           ;Fetch next register value
        OUT     DX,AL                   ;Set next palette register
        XCHG    AH,AL                   ;Restore register index
        INC     AL                      ;Advance register index
        LOOP    Palette_Loop            ;Check if all done

        MOV     AL,20h                  ;Turn Attribute controller on
        OUT     DX,AL

        ; Cleanup and return

        POP     SI                      ;Restore segment and index registers
        POP     DI
        POP     DS
        POP     ES

        MOV     SP,BP                   ;Restore stack pointer
        POP     BP                      ;Restore BP
        RET
_Load_Palette   ENDP

PAL_TEXT   ENDS
        END

