home *** CD-ROM | disk | FTP | other *** search
- ;
- ; *** Listing 1 ***
- ;
- ; Program to demonstrate bit-plane animation. Performs
- ; flicker-free animation with image transparency and
- ; image precedence across four distinct planes, with
- ; 13 32x32 images kept in motion at once.
- ;
- ;
- ; Set to higher values to slow down on faster computers.
- ; 0 is fine for a PC. 500 is a reasonable setting for an AT.
- ; Slowing animation further allows a good look at
- ; transparency and the lack of flicker and color effects
- ; when images cross.
- ;
- SLOWDOWN equ 0
- ;
- ; Plane selects for the four colors we're using.
- ;
- RED equ 01h
- GREEN equ 02h
- BLUE equ 04h
- WHITE equ 08h
- ;
- VGA_SEGMENT equ 0a000h ;mode 10h display memory
- ; segment
- SC_INDEX equ 3c4h ;Sequence Controller Index
- ; register
- MAP_MASK equ 2 ;Map Mask register index in
- ; Sequence Controller
- SCREEN_WIDTH equ 80 ;# of bytes across screen
- SCREEN_HEIGHT equ 350 ;# of scan lines on screen
- WORD_OUTS_OK equ 1 ;set to 0 to assemble for
- ; computers that can't
- ; handle word outs to
- ; indexed VGA regs
- ;
- stack segment para stack 'STACK'
- db 512 dup (?)
- stack ends
- ;
- ; Complete info about one object that we're animating.
- ;
- ObjectStructure struc
- Delay dw ? ;used to delay for n passes
- ; throught the loop to
- ; control animation speed
- BaseDelay dw ? ;reset value for Delay
- Image dw ? ;pointer to drawing info
- ; for object
- XCoord dw ? ;object X location in pixels
- XInc dw ? ;# of pixels to increment
- ; location by in the X
- ; direction on each move
- XLeftLimit dw ? ;left limit of X motion
- XRightLimit dw ? ;right limit of X motion
- YCoord dw ? ;object Y location in pixels
- YInc dw ? ;# of pixels to increment
- ; location by in the Y
- ; direction on each move
- YTopLimit dw ? ;top limit of Y motion
- YBottomLimit dw ? ;bottom limit of Y motion
- PlaneSelect db ? ;mask to select plane to
- ; which object is drawn
- db ? ;to make an even # of words
- ; long, for better 286
- ; performance (keeps the
- ; following structure
- ; word-aligned)
- ObjectStructure ends
- ;
- Data segment word 'DATA'
- ;
- ; Palette settings to give plane 0 precedence, followed by
- ; planes 1, 2, and 3. Plane 3 has the lowest precedence (is
- ; obscured by any other plane), while plane 0 has the
- ; highest precedence (displays in front of any other plane).
- ;
- Colors db 000h ;background color=black
- db 03ch ;plane 0 only=red
- db 03ah ;plane 1 only=green
- db 03ch ;planes 0&1=red (plane 0 priority)
- db 039h ;plane 2 only=blue
- db 03ch ;planes 0&2=red (plane 0 priority)
- db 03ah ;planes 1&2=green (plane 1 priority)
- db 03ch ;planes 0&1&2=red (plane 0 priority)
- db 03fh ;plane 3 only=white
- db 03ch ;planes 0&3=red (plane 0 priority)
- db 03ah ;planes 1&3=green (plane 1 priority)
- db 03ch ;planes 0&1&3=red (plane 0 priority)
- db 039h ;planes 2&3=blue (plane 2 priority)
- db 03ch ;planes 0&2&3=red (plane 0 priority)
- db 03ah ;planes 1&2&3=green (plane 1 priority)
- db 03ch ;planes 0&1&2&3=red (plane 0 priority)
- db 000h ;border color=black
- ;
- ; Image of a hollow square.
- ; There's an 8-pixel-wide blank border around all edges
- ; so that the image erases the old version of itself as
- ; it's moved and redrawn.
- ;
- Square label byte
- dw 48,6 ;height in pixels, width in bytes
- rept 8
- db 0,0,0,0,0,0 ;top blank border
- endm
- .radix 2
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,00000000,00000000,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- db 0,11111111,11111111,11111111,11111111,0
- .radix 10
- rept 8
- db 0,0,0,0,0,0 ;bottom blank border
- endm
- ;
- ; Image of a hollow diamond with a smaller diamond in the
- ; middle.
- ; There's an 8-pixel-wide blank border around all edges
- ; so that the image erases the old version of itself as
- ; it's moved and redrawn.
- ;
- Diamond label byte
- dw 48,6 ;height in pixels, width in bytes
- rept 8
- db 0,0,0,0,0,0 ;top blank border
- endm
- .radix 2
- db 0,00000000,00000001,10000000,00000000,0
- db 0,00000000,00000011,11000000,00000000,0
- db 0,00000000,00000111,11100000,00000000,0
- db 0,00000000,00001111,11110000,00000000,0
- db 0,00000000,00011111,11111000,00000000,0
- db 0,00000000,00111110,01111100,00000000,0
- db 0,00000000,01111100,00111110,00000000,0
- db 0,00000000,11111000,00011111,00000000,0
- db 0,00000001,11110000,00001111,10000000,0
- db 0,00000011,11100000,00000111,11000000,0
- db 0,00000111,11000000,00000011,11100000,0
- db 0,00001111,10000001,10000001,11110000,0
- db 0,00011111,00000011,11000000,11111000,0
- db 0,00111110,00000111,11100000,01111100,0
- db 0,01111100,00001111,11110000,00111110,0
- db 0,11111000,00011111,11111000,00011111,0
- db 0,11111000,00011111,11111000,00011111,0
- db 0,01111100,00001111,11110000,00111110,0
- db 0,00111110,00000111,11100000,01111100,0
- db 0,00011111,00000011,11000000,11111000,0
- db 0,00001111,10000001,10000001,11110000,0
- db 0,00000111,11000000,00000011,11100000,0
- db 0,00000011,11100000,00000111,11000000,0
- db 0,00000001,11110000,00001111,10000000,0
- db 0,00000000,11111000,00011111,00000000,0
- db 0,00000000,01111100,00111110,00000000,0
- db 0,00000000,00111110,01111100,00000000,0
- db 0,00000000,00011111,11111000,00000000,0
- db 0,00000000,00001111,11110000,00000000,0
- db 0,00000000,00000111,11100000,00000000,0
- db 0,00000000,00000011,11000000,00000000,0
- db 0,00000000,00000001,10000000,00000000,0
- .radix 10
- rept 8
- db 0,0,0,0,0,0 ;bottom blank border
- endm
- ;
- ; List of objects to animate.
- ;
- even ;word-align for better 286 performance
- ;
- ObjectList label ObjectStructure
- ObjectStructure <1,21,Diamond,88,8,80,512,16,0,0,350,RED>
- ObjectStructure <1,15,Square,296,8,112,480,144,0,0,350,RED>
- ObjectStructure <1,23,Diamond,88,8,80,512,256,0,0,350,RED>
- ObjectStructure <1,13,Square,120,0,0,640,144,4,0,280,BLUE>
- ObjectStructure <1,11,Diamond,208,0,0,640,144,4,0,280,BLUE>
- ObjectStructure <1,8,Square,296,0,0,640,144,4,0,288,BLUE>
- ObjectStructure <1,9,Diamond,384,0,0,640,144,4,0,288,BLUE>
- ObjectStructure <1,14,Square,472,0,0,640,144,4,0,280,BLUE>
- ObjectStructure <1,8,Diamond,200,8,0,576,48,6,0,280,GREEN>
- ObjectStructure <1,8,Square,248,8,0,576,96,6,0,280,GREEN>
- ObjectStructure <1,8,Diamond,296,8,0,576,144,6,0,280,GREEN>
- ObjectStructure <1,8,Square,344,8,0,576,192,6,0,280,GREEN>
- ObjectStructure <1,8,Diamond,392,8,0,576,240,6,0,280,GREEN>
- ObjectListEnd label ObjectStructure
- ;
- Data ends
- ;
- ; Macro to output a word value to a port.
- ;
- OUT_WORD macro
- if WORD_OUTS_OK
- out dx,ax
- else
- out dx,al
- inc dx
- xchg ah,al
- out dx,al
- dec dx
- xchg ah,al
- endif
- endm
- ;
- ; Macro to output a constant value to an indexed VGA
- ; register.
- ;
- CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE
- mov dx,ADDRESS
- mov ax,(VALUE shl 8) + INDEX
- OUT_WORD
- endm
- ;
- Code segment
- assume cs:Code, ds:Data
- Start proc near
- cld
- mov ax,Data
- mov ds,ax
- ;
- ; Set 640x350 16-color mode.
- ;
- mov ax,0010h ;AH=0 means select mode
- ;AL=10h means select
- ; mode 10h
- int 10h ;BIOS video interrupt
- ;
- ; Set the palette up to provide bit-plane precedence. If
- ; planes 0 & 1 overlap, the plane 0 color will be shown;
- ; if planes 1 & 2 overlap, the plane 1 color will be
- ; shown; and so on.
- ;
- mov ax,(10h shl 8) + 2 ;AH = 10h means
- ; set palette
- ; registers fn
- ;AL = 2 means set
- ; all palette
- ; registers
- push ds ;ES:DX points to
- pop es ; the palette
- mov dx,offset Colors ; settings
- int 10h ;call the BIOS to
- ; set the palette
- ;
- ; Draw the static backdrop in plane 3. All the moving images
- ; will appear to be in front of this backdrop, since plane 3
- ; has the lowest precedence the way the palette is set up.
- ;
- CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 08h
- ;allow data to go to
- ; plane 3 only
- ;
- ; Point ES to display memory for the rest of the program.
- ;
- mov ax,VGA_SEGMENT
- mov es,ax
- ;
- sub di,di
- mov bp,SCREEN_HEIGHT/16 ;fill in the screen
- ; 16 lines at a time
- BackdropBlockLoop:
- call DrawGridCross ;draw a cross piece
- call DrawGridVert ;draw the rest of a
- ; 15-high block
- dec bp
- jnz BackdropBlockLoop
- call DrawGridCross ;bottom line of grid
- ;
- ; Start animating!
- ;
- AnimationLoop:
- mov bx,offset ObjectList ;point to the first
- ; object in the list
- ;
- ; For each object, see if it's time to move and draw that
- ; object.
- ;
- ObjectLoop:
- ;
- ; See if it's time to move this object.
- ;
- dec [bx+Delay] ;count down delay
- jnz DoNextObject ;still delaying-don't move
- mov ax,[bx+BaseDelay]
- mov [bx+Delay],ax ;reset delay for next time
- ;
- ; Select the plane that this object will be drawn in.
- ;
- mov dx,SC_INDEX
- mov ah,[bx+PlaneSelect]
- mov al,MAP_MASK
- OUT_WORD
- ;
- ; Advance the X coordinate, reversing direction if either
- ; of the X margins has been reached.
- ;
- mov cx,[bx+XCoord] ;current X location
- cmp cx,[bx+XLeftLimit] ;at left limit?
- ja CheckXRightLimit ;no
- neg [bx+XInc] ;yes-reverse
- CheckXRightLimit:
- cmp cx,[bx+XRightLimit] ;at right limit?
- jb SetNewX ;no
- neg [bx+XInc] ;yes-reverse
- SetNewX:
- add cx,[bx+XInc] ;move the X coord
- mov [bx+XCoord],cx ; & save it
- ;
- ; Advance the Y coordinate, reversing direction if either
- ; of the Y margins has been reached.
- ;
- mov dx,[bx+YCoord] ;current Y location
- cmp dx,[bx+YTopLimit] ;at top limit?
- ja CheckYBottomLimit ;no
- neg [bx+YInc] ;yes-reverse
- CheckYBottomLimit:
- cmp dx,[bx+YBottomLimit] ;at bottom limit?
- jb SetNewY ;no
- neg [bx+YInc] ;yes-reverse
- SetNewY:
- add dx,[bx+YInc] ;move the Y coord
- mov [bx+YCoord],dx ; & save it
- ;
- ; Draw at the new location. Because of the plane select
- ; above, only one plane will be affected.
- ;
- mov si,[bx+Image] ;point to the
- ; object's image
- ; info
- call DrawObject
- ;
- ; Point to the next object in the list until we run out of
- ; objects.
- ;
- DoNextObject:
- add bx,size ObjectStructure
- cmp bx,offset ObjectListEnd
- jb ObjectLoop
- ;
- ; Delay as specified to slow things down.
- ;
- if SLOWDOWN
- mov cx,SLOWDOWN
- DelayLoop:
- loop DelayLoop
- endif
- ;
- ; If a key's been pressed, we're done, otherwise animate
- ; again.
- ;
- CheckKey:
- mov ah,1
- int 16h ;is a key waiting?
- jz AnimationLoop ;no
- sub ah,ah
- int 16h ;yes-clear the key & done
- ;
- ; Back to text mode.
- ;
- mov ax,0003h ;AL=03h means select
- ; mode 03h
- int 10h
- ;
- ; Back to DOS.
- ;
- mov ah,4ch ;DOS terminate function
- int 21h ;done
- ;
- Start endp
- ;
- ; Draws a single grid cross-element at the display memory
- ; location pointed to by ES:DI. 1 horizontal line is drawn
- ; across the screen.
- ;
- ; Input: ES:DI points to the address at which to draw
- ;
- ; Output: ES:DI points to the address following the
- ; line drawn
- ;
- ; Registers altered: AX, CX, DI
- ;
- DrawGridCross proc near
- mov ax,0ffffh ;draw a solid line
- mov cx,SCREEN_WIDTH/2-1
- rep stosw ;draw all but the rightmost
- ; edge
- mov ax,0080h
- stosw ;draw the right edge of the
- ; grid
- ret
- DrawGridCross endp
- ;
- ; Draws the non-cross part of the grid at the display memory
- ; location pointed to by ES:DI. 15 scan lines are filled.
- ;
- ; Input: ES:DI points to the address at which to draw
- ;
- ; Output: ES:DI points to the address following the
- ; part of the grid drawn
- ;
- ; Registers altered: AX, CX, DX, DI
- ;
- DrawGridVert proc near
- mov ax,0080h ;pattern for a vertical line
- mov dx,15 ;draw 15 scan lines (all of
- ; a grid block except the
- ; solid cross line)
- BackdropRowLoop:
- mov cx,SCREEN_WIDTH/2
- rep stosw ;draw this scan line's bit
- ; of all the vertical lines
- ; on the screen
- dec dx
- jnz BackdropRowLoop
- ret
- DrawGridVert endp
- ;
- ; Draw the specified image at the specified location.
- ; Images are drawn on byte boundaries horizontally, pixel
- ; boundaries vertically.
- ; The Map Mask register must already have been set to enable
- ; access to the desired plane.
- ;
- ; Input:
- ; CX - X coordinate of upper left corner
- ; DX - Y coordinate of upper left corner
- ; DS:SI - pointer to draw info for image
- ; ES - display memory segment
- ;
- ; Output: none
- ;
- ; Registers altered: AX, CX, DX, SI, DI, BP
- ;
- DrawObject proc near
- mov ax,SCREEN_WIDTH
- mul dx ;calculate the start offset in
- ; display memory of the row the
- ; image will be drawn at
- shr cx,1
- shr cx,1
- shr cx,1 ;divide the X coordinate in pixels
- ; by 8 to get the X coordinate in
- ; bytes
- add ax,cx ;destination offset in display
- ; memory for the image
- mov di,ax ;point ES:DI to the address to
- ; which the image will be copied
- ; in display memory
- lodsw
- mov dx,ax ;# of lines in the image
- lodsw ;# of bytes across the image
- mov bp,SCREEN_WIDTH
- sub bp,ax ;# of bytes to add to the display
- ; memory offset after copying a line
- ; of the image to display memory in
- ; order to point to the address
- ; where the next line of the image
- ; will go in display memory
- DrawLoop:
- mov cx,ax ;width of the image
- rep movsb ;copy the next line of the image
- ; into display memory
- add di,bp ;point to the address at which the
- ; next line will go in display
- ; memory
- dec dx ;count down the lines of the image
- jnz DrawLoop
- ret
- DrawObject endp
- ;
- Code ends
- end Start
-