CSeg   Segment Para Public 'CODE'
       Assume CS:CSeg,DS:CSEG,SS:CSeg,ES:Nothing
       Org   100h
Begin: Mov   AX,001h         ; Set video mode 1
       Int   10h
       Mov   AX,0B800h       ; Set ES to start of
       Mov   ES,AX           ;   video page 0
;
; Put the pattern into video page 0 and 1
;
       Mov   AL,219          ; Character is a solid block
       Mov   DX,0            ; Initialize row counter
RLoop: Mov   DI,DX           ; DI = row
       Mov   AH,DL           ; Color = row
       Mov   CL,4            ; 2 ^ 4 = 16
       SAL   DI,CL           ; DI = 16 * row
       Mov   CX,DI           ; Save in CX
       SAL   DI,1            ; DI = 32 * row
       SAL   DI,1            ; DI = 64 * row
       Add   DI,CX           ; DI = (64+16=80) * row
       Mov   CX,DI           ; CX = 80 * row
       Mov   BX,0            ; Init the column counter
CLoop: Inc   AH              ; Increment color number
       And   AH,15           ; Valid colors are 0-15 only
       Mov   DI,CX           ; DI = 80 * row
       Add   DI,BX           ; DI = 80 * row + column
       StoSW                 ; Move word to page 0
       Add   DI,2046
       StoSw                 ; Move word to page 1
       Mov   DI,CX           ; DI = 80 * row
       Add   DI,78           ; DI = 80 * row + 78
       Sub   DI,BX           ; DI = 80 * row - column + 78
       StoSw                 ; Move word to page 0
       Add   DI,2046
       StoSw                 ; Move word to page 1
       Mov   DI,CX           ; DI = 80 * row
       Neg   DI              ; DI = -80 * row
       Add   DI,1920         ; DI = -80 * row + 1920
       Add   DI,BX           ; DI = -80 * row + column + 1920
       StoSw                 ; Move word to page 0
       Add   DI,2046
       StoSw                 ; Move word to page 1
       Mov   DI,CX           ; DI = 80 * row
       Neg   DI              ; DI = -80 * row
       Add   DI,1998         ; DI = -80 * row + 1998
       Sub   DI,BX           ; DI = -80 * row - column + 1998
       StoSw                 ; Move word to page 0
       Add   DI,2046
       StoSw                 ; Move word to page 1
       Add   BX,2            ; increment counter
       Cmp   BX,40           ; Columns done ?
       Je    ChkRow          ; Yes...check rows
       Jmp   CLoop           ; No....check column
ChkRow: Inc  DX              ; Increment row
       Cmp   DX,13           ; Rows done ?
       Je    MoveIt          ; Yes..move the patterns
       Jmp   RLoop           ; No...Next row
;
; Increment or decrement the valu of bits 0-3 for every attribute
; byte on alternating video pages 0 and 1 and swap active page.
;
MoveIt: Mov   BX,2049         ; BX = page offset
        Mov   SI,0            ; Set flag to no swap
MLoop:  Cmp   BX,2049         ; Page 1 displayed ?
        Je    Pg0             ; Yes, display page 0
        Mov   BX,2049         ; No..display page 1
        Mov   AL,1            ; Set page 1
        Jmp   SetPg
Pg0:    Mov   BX,1            ; Set page offset
        Mov   AL,0            ; Set page 0
SetPg:  Mov   DI,BX
        Mov   CX,1000         ; 1000 bytes to move
ILoop:  Mov   DH,ES:[DI]      ; Get attribute byte
IncDec: Inc   DH              ; Modify attribute byte (self modifying here)
        Jns   NotNeg          ; Sign is plus
        Mov   DH,15           ; Sign is negative
NotNeg: And   DH,15           ; Valid values are 0-15
        Mov   ES:[DI],DH      ; Place in the new attribute
        Inc   DI              ; Point past the character
        Inc   DI              ; And to the next attribute
        Loop  ILoop           ; Repeat this 1000 times
        Mov   AH,5            ; Set video page
        Int   10h
        Mov   CX,02701h       ; Time delay (lower this value for more speed)
Delay:  Loop  Delay           ; And wait
;
; Check for keypress - if a space, swap the code for inc and dec
; at label INCDEC - if ESC then exit.
;
         Cmp  SI,1            ; Is flag set ?
         Jz   Swap            ; Yes..swap INC/DEC code
         Mov  AH,6            ; ReadKeyboard function
         Mov  DL,0FFh         ; Set DL to read
         Int  21h             ; Call DOS
         Cmp  AL,' '          ; Space bar hit ?
         Jne  ChkEsc          ; No...check for ESC key
         Cmp  BX,2049         ; Are we displaying page 1 ?
         Je   Swap            ; Yes...swap INC/DEC code
         Mov  SI,1            ; No...set flag
         Jmp  MLoop           ; Continue
Swap:    Mov  SI,0            ; Reset flag
         Cmp  Byte Ptr IncDec+1,0C6h   ; Are we incrementing ?
         Je   DecIt           ; Yes..swap functions
         Mov  Byte Ptr IncDec+1,0C6h   ; Change to increment
         Jmp  Mloop           ; And redo the display
DecIt:   Mov  Byte Ptr IncDec+1,0CEh   ; Change to decrement
         Jmp  MLoop           ; And redo the display
ChkEsc:  Cmp  AL,27           ; ESC key pressed ?
         Jne  MLoop           ; No..redo the display
         Mov  AX,0003h        ; Yes..set to 80 column display
         Int  10h             ; Call BIOS
         Mov  AX,4C00h        ; Prepare to exit
         Int  21h             ; Terminate program
CSeg     Ends
         End  Begin
