COMMENT ~
 PROGRAM: PAGESPIN.ASM
  AUTHOR: Denis Boyles
 RELEASE: Public Domain (Dec 11, 1996)

 COMPILE: Arrowsoft Assembler (MASM v3.0)
      OS: MS-DOS (v6.20)

 PURPOSE: demonstrate text screen page flipping
~

TIMER EQU 4                            ;delay between each frame

CODE SEGMENT
    ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
    ORG 0100h

MAIN:
    mov     AX,003h                    ;BIOS video, set 80x25x16 text mode
    int     010h                       ;for a clean start

    mov     AX,0B800h                  ;setup color text RAM segment
    mov     ES,AX

    mov     BX,offset AnimeChars       ;set our offset into anime chars
    mov     AH,007h                    ;set attribute byte (lgrey on black)
    mov     AL,[BX]                    ;get current anime character
    mov     DI,0                       ;set text RAM offset 0 page 0

    mov     CX,004h                    ;going to fill 4 pages of text

FillPages:
    push    CX                         ;save current counter

    mov     CX,007D0h                  ;80*2*25=4000 bytes / 2=2000 words
    rep     stosw                      ;fill text page with anime char

    inc     BX                         ;point to next anime char
    mov     AL,[BX]                    ;get next anime character
    add     DI,060h                    ;add 96 bytes to point to next page
                                       ;(4000+96=4096 even pages)
    pop     CX                         ;restore outer loop counter
    rep     loop FillPages             ;fill all 4 pages with anime chars


FlipPages:
    mov     AH,001h                    ;BIOS was a key pressed?
    int     016h
    jnz     ExPrg                      ;YES, then exit program

    cmp     ScreenPage,004h            ;have we displayed all 4 pages?
    jz      ResetPage                  ;YES then go reset back to zero

    mov     AH,005h                    ;BIOS set active screen page
    mov     AL,ScreenPage              ;page to activate
    int     010h                       ;call BIOS to set page

    mov     BX,TIMER                   ;wait TIMER amount ticks?
    call    delay

    inc     ScreenPage                 ;next screen page
    jmp     FlipPages                  ;keep flipping until keypress

ResetPage:
    mov     ScreenPage,0               ;loop page back to zero again
    jmp     FlipPages                  ;back we go flipping pages

ExPrg:
    mov     AH,0                       ;BIOS read keypressed (to buffer)
    int     016h

    mov     AX,003h                    ;BIOS video, set text mode again to
    int     010h                       ;clean up
    ret                                ;a quick exit back to DOS

AnimeChars  db  "-\|/"                 ;`spinner' animation characters
ScreenPage  db  0                      ;current/active text screen page

delay proc
    push    DS                         ;save DS to stack
    mov     AX,040h                    ;setup BIOS data segment
    mov     DS,AX
    mov     AX,DS:[06Ch]               ;get current low word of timer ticker
    add     AX,BX                      ;add our wait time to that

CountDown:
    mov     BX,DS:[06Ch]               ;get current low word of timer ticker
    cmp     AX,BX                      ;compare with wanted time
    ja      CountDown                  ;if wanted is > current keep looping
    pop     DS                         ;restore DS from stack
    ret                                ;back to caller
delay endp

CODE ENDS
END MAIN
