; From HOWARD SWINEHART - Text page flipping
;
; This will flip between text pages 0 and 1
; Press ESC to exit or any other key to flip the pages.

;MU>Any way to clear it in color col? (I know there is... But how do you do it?
;
;     mov  ax,0b800h          ; Text mode segment
;     mov  es,ax
;
;     mov  di,0               ; Or whatever your screen offset is
;     mov  cx,2000            ; 2000 words = 4000 bytes
;     mov  al,0               ; Fill with character 0
;     mov  ah,1fh             ; Background/Foreground colors
;                             ; (in this case, white on blue)
;     cld                     ; Be sure to move forward
;     rep stosw               ; Write 2000 words
;
;MU>What I want to be able to do is write to a virtual text
;MU>screen and then flip to it once it's been fully drawn/written.
;
;[...]  source code that demonstrates two ways to
;flip between two screens.  The routine FlipPage OUTs directly to the
;hardware.  Bflip goes through the BIOS.  Just comment out the one you
;don't want to use.



cseg    segment para public 'code'
        assume  cs:cseg, ds:cseg, es:cseg
        org     100h
main:
    jmp     start

dispscreen  dw  0           ; Offset of screen 0
workscreen  dw  4096        ; Offset of screen 1

start:
    mov     ax,3h
    int     10h             ; Text mode

    mov     ax,0b800h       ; Text screen's segment
    mov     es,ax

    call    FillScreen      ; Draw on page 1
    call    Bflip;FlipPage        ; Flip the page
    call    FillScreen      ; Draw on page 0
st1:
    mov     ah,0
    int     16h             ; Wait for a key

    cmp     al,27           ; Exit if ESC pressed
    je      exit

    call    Bflip;FlipPage        ; Display hidden page
    jmp     st1
exit:
    mov     ax,3h           ; Reset the screen
    int     10h
    mov     ax,4c00h        ; Exit
    int     21h
;
; Fill the hidden screen with its page number
;
FillScreen:
    mov     di,[workscreen] ; Always draw on [workscreen]

    mov     ax,di           ; Calculate page number
    mov     cl,12           ; Page # = offset / 4096
    shr     ax,cl

    add     al,48           ; Make it an ASCII digit
    mov     ah,47h          ; Background and foreground colors
    mov     cx,2000
    cld
    rep stosw               ; Write it to screen buffer
    ret
;
; Flip the page using OUTs.
;
FlipPage:
    push    ax
    push    cx
    push    dx

    mov     cx,[dispscreen] ; Swap the visible and hidden pages
    xchg    cx,[workscreen]
    mov     [dispscreen],cx

    shr     cx,1            ; Controller expects offset / 2

    mov     dx,3d4h
    mov     al,0ch          ; Select Start Address High register
    out     dx,al
    inc     dx
    mov     al,ch           ; Set it to CH
    out     dx,al
    dec     dx
    mov     al,0dh          ; Select Start Address Low register
    out     dx,al
    inc     dx
    mov     al,cl           ; Set it to CL
    out     dx,al

    pop     dx
    pop     cx
    pop     ax
    ret
;
; Flip the page using BIOS
;
Bflip:
    push    ax
    push    cx

    mov     ax,[dispscreen] ; Swap the visible and hidden pages
    xchg    ax,[workscreen]
    mov     [dispscreen],ax

    mov     cl,12
    shr     ax,cl           ; Divide offset by 4096 to get page #
    mov     ah,5h           ; BIOS display page function
    int     10h

    pop     cx
    pop     ax
    ret
cseg    ends
end     main

