
;************************************************************************
; Smooth horizontal scroll                                              *
; There is no error checking and it is assumed that new width was set   *
; Entry:        X_Offset- Current horizontal offset                     *
;************************************************************************

X_Offset        EQU     [BP+4]

        PUBLIC  _Horizontal_Scroll

_Horizontal_Scroll      PROC    NEAR
        PUSH    BP                      ;Standard entry from high level
        MOV     BP,SP
        PUSH    ES

        XOR     AX,AX                   ;Point ES to segment 0
        MOV     ES,AX

        ;--- Wait for an end of vertical retrace

        MOV     DX,ES:[BIOS_CRT_Addr]   ;Get address of CRT controller
        ADD     DX,6                    ;Wait for retrace to change registers
HS_Wait1:                               ;Wait for vertical to start
        IN      AL,DX
        JMP     $+2
        TEST    AL,8
        JZ      HS_Wait1
HS_Wait2:                               ;Wait for vertical to end
        IN      AL,DX
        JMP     $+2
        TEST    AL,8
        JNZ     HS_Wait2

        ;--- Set CRTC ADDRESS register to offset/8

        MOV     BX,X_Offset             ;Compute multiple of 8 offset to use
        SHR     BX,1                    ;in CRTC start address register 0D
        SHR     BX,1
        SHR     BX,1
        MOV     DX,ES:[BIOS_CRT_Addr]   ;Get address of CRT controller
        MOV     AL,0DH                  ;Index for START ADDRESS register LO
        OUT     DX,AL                   ;Select index
        INC     DX
        MOV     AL,BL                   ;Fetch the scroll value we computed
        OUT     DX,AL                   ;Set START register

        ;--- Set Attribute PANNING register to (offset mod 8)

        ADD     DX,5                    ;Point to status port
HS_Wait3:                               ;Wait for vertical to start
        IN      AL,DX
        JMP     $+2
        TEST    AL,8
        JZ      HS_Wait3

        MOV     DX,3C0H                 ;Fetch address of Attr write register
        MOV     AL,33H                  ;Fetch index
        OUT     DX,AL                   ;Select PANNING register
        MOV     AX,X_Offset             ;Fetch offset
        AND     AL,7                    ;Keep last 3 bits (offset mod 8)
        OUT     DX,AL                   ;Set PANNING register

        POP     ES
        MOV     SP,BP
        POP     BP
        RET
_Horizontal_Scroll      ENDP
