; Sprite
; MS-DOS demo for VGA adaptor.

; Animates a single sprite.

; This code got a head start from Michael Abrash's excellent book
; 'The Zen of Graphics Programming' and owes a lot to Michael's sample code.

; Assembled with MASM 6.15 and linked with LINK 5.60.339 (to get a DOS image)
; April 2001

		.MODEL small
		.STACK 256

VIDEO_SEGMENT   equ     0a000h          ;display memory segment for
                                        ; true VGA graphics modes
SCREEN_WIDTH	equ	80		; number of bytes in one scan line
SCREEN_HEIGHT	equ	350		; number of scan lines

PAGE0           equ     0       ;flag for page 0 when page flipping
PAGE1           equ     1       ;flag for page 1 when page flipping
PAGE0_OFFSET    equ     0       ;start offset of page 0 in VGA memory
PAGE1_OFFSET    equ     SCREEN_WIDTH * SCREEN_HEIGHT
                                ;start offset of page 1 (both pages
                                ; are 640*480 mode 10h screens)
SPRITE_WIDTH    equ     80/8    ;width of sprite in display memory bytes
SPRITE_HEIGHT   equ     80      ;height of sprite in scan lines
BLANK_OFFSET    equ     PAGE1_OFFSET * 2        ;start of blank image
                                                ; in VGA memory
SPRITE_OFFSET   equ     BLANK_OFFSET + (SPRITE_WIDTH * SPRITE_HEIGHT)
                                ;start offset of sprite image in VGA memory
;
; VGA register equates.
;
SC_INDEX        equ     3c4h    ;SC index register
MAP_MASK        equ     2       ;SC map mask register
GC_INDEX        equ     3ceh    ;GC index register
GC_MODE         equ     5       ;GC mode register
CRTC_INDEX      equ     03d4h   ;CRTC index register
START_ADDRESS_HIGH equ  0ch     ;CRTC start address high byte
START_ADDRESS_LOW equ   0dh     ;CRTC start address low byte
CRTC_OFFSET     equ     13h     ;CRTC offset register
INPUT_STATUS_1  equ     03dah   ;VGA status register
VSYNC_MASK      equ     08h     ;vertical sync bit in status register 1
DE_MASK         equ     01h     ;display enable bit in status register 1
AC_INDEX        equ     03c0h   ;AC index register
HPELPAN         equ     20h OR 13h      ;AC horizontal pel panning register
                                        ; (bit 7 is high to keep palette RAM
                                        ; addressing on)

		.DATA
CurrentPage             db      PAGE0           ;page to draw to
CurrentPageOffset       dw      PAGE1_OFFSET
;
; Four plane's worth of multicolored sprite image.
;
SpritePlane0Image label   byte            ;blue plane image
	db	087h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	0a7h, 0e1h, 0f8h, 00fh, 081h, 0f1h, 0cfh, 08fh, 080h, 0e0h
	db	0f7h, 0ech, 0f7h, 06fh, 0ddh, 0fbh, 0ffh, 0dfh, 0ceh, 0e0h
	db	0ffh, 0cfh, 0ffh, 07fh, 0dfh, 0f9h, 0dfh, 0dfh, 0cfh, 0e0h
	db	0f7h, 0e3h, 0ffh, 07fh, 09bh, 0fdh, 0ffh, 0dfh, 0cfh, 0e0h
	db	0c7h, 0f1h, 0ffh, 07fh, 09bh, 0fch, 0bfh, 0dfh, 0cfh, 0e0h
	db	087h, 0fch, 0feh, 07fh, 09fh, 0fch, 0bfh, 0dfh, 0dfh, 0e0h
	db	007h, 0deh, 0ffh, 07fh, 09fh, 0feh, 07fh, 0dfh, 0cfh, 0e0h
	db	007h, 0dfh, 0ffh, 07fh, 09dh, 0feh, 07fh, 0dfh, 0ceh, 0e0h
	db	007h, 0efh, 0feh, 03fh, 001h, 0ffh, 0ffh, 08fh, 080h, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0f1h, 0e0h
	db	00fh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0fdh, 000h
	db	01fh, 0e0h, 049h, 0f1h, 087h, 0c7h, 0c0h, 07ch, 00fh, 000h
	db	01fh, 0f6h, 05bh, 0fbh, 0cfh, 0efh, 0bbh, 0feh, 0efh, 000h
	db	03fh, 0f3h, 07bh, 0fbh, 0cfh, 0cfh, 0fbh, 0feh, 0ffh, 000h
	db	07eh, 07bh, 03fh, 0fbh, 0cfh, 0efh, 0fbh, 0feh, 0dfh, 000h
	db	0fch, 079h, 0b7h, 0fbh, 0cfh, 0cfh, 0fbh, 0feh, 0dfh, 000h
	db	0f0h, 07dh, 09fh, 0fbh, 0cfh, 0efh, 0fbh, 0feh, 0ffh, 000h
	db	0e0h, 07ch, 04fh, 0fbh, 0cfh, 0cfh, 0fbh, 0feh, 0ffh, 000h
	db	0c0h, 07eh, 0dfh, 0fbh, 0cfh, 0cfh, 0fbh, 0feh, 0efh, 000h
	db	0c0h, 07fh, 0ffh, 0e1h, 087h, 087h, 0f1h, 0ffh, 0ffh, 000h
	db	080h, 07fh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	001h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0dch, 000h, 000h, 000h, 000h, 01fh, 0feh, 000h
	db	0ffh, 0ffh, 0f8h, 000h, 000h, 000h, 000h, 01fh, 0feh, 000h
	db	0ffh, 0ffh, 0f0h, 000h, 000h, 000h, 000h, 00fh, 0feh, 000h
	db	0ffh, 0ffh, 0f0h, 000h, 000h, 000h, 000h, 00fh, 0feh, 000h
	db	0ffh, 0ffh, 0e0h, 000h, 000h, 000h, 000h, 00fh, 0ffh, 000h
	db	0ffh, 0ffh, 0e0h, 000h, 000h, 000h, 000h, 00fh, 0ffh, 000h
	db	0ffh, 0ffh, 0c0h, 000h, 000h, 000h, 000h, 007h, 0ffh, 000h
	db	0ffh, 0ffh, 080h, 000h, 000h, 000h, 000h, 007h, 0ffh, 080h
	db	0ffh, 0ffh, 080h, 000h, 000h, 000h, 000h, 007h, 0ffh, 080h
	db	0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 003h, 0ffh, 080h
	db	0ffh, 0feh, 000h, 000h, 000h, 000h, 000h, 003h, 0ffh, 080h
	db	0ffh, 0feh, 000h, 000h, 000h, 000h, 000h, 003h, 0ffh, 080h
	db	0ffh, 0fch, 000h, 000h, 000h, 000h, 000h, 003h, 0ffh, 0c0h
	db	0ffh, 0fch, 000h, 000h, 000h, 000h, 000h, 001h, 0ffh, 0c0h
	db	0ffh, 0f8h, 000h, 000h, 000h, 000h, 000h, 001h, 0ffh, 0c0h
	db	0ffh, 0f0h, 000h, 000h, 000h, 000h, 000h, 001h, 0ffh, 0c0h
	db	0ffh, 0e0h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 0c0h
	db	0ffh, 0e0h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 0c0h
	db	0ffh, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 0c0h
	db	0ffh, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 07fh, 0c0h
	db	0ffh, 080h, 000h, 000h, 000h, 000h, 000h, 000h, 07fh, 0e0h
	db	0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07fh, 0e0h
	db	0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 03fh, 0e0h
	db	0fch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 03fh, 0e0h
	db	0f0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 03fh, 0e0h
	db	0e0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 0e0h
	db	0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 0e0h
	db	080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 0e0h
	db	080h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00fh, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00fh, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00fh, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00fh, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 007h, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 007h, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 007h, 0e0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 007h, 0f0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f0h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f8h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f8h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f8h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f8h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0f8h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0fch
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0fch
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 0fch
SpritePlane1Image label   byte            ;green plane image
	db	016h, 01ch, 0e0h, 00fh, 0e0h, 000h, 000h, 080h, 001h, 0ffh
	db	036h, 01ch, 0e0h, 00fh, 0e0h, 000h, 000h, 000h, 007h, 083h
	db	034h, 018h, 0c0h, 00fh, 0e0h, 000h, 000h, 000h, 00fh, 000h
	db	038h, 018h, 080h, 00fh, 0e0h, 000h, 000h, 000h, 00eh, 000h
	db	028h, 031h, 080h, 007h, 0e0h, 000h, 000h, 000h, 01ch, 000h
	db	030h, 0f1h, 080h, 007h, 0e0h, 000h, 000h, 000h, 01ch, 000h
	db	037h, 0f1h, 080h, 007h, 0e0h, 000h, 000h, 000h, 038h, 000h
	db	07eh, 071h, 086h, 007h, 0f0h, 000h, 000h, 000h, 038h, 000h
	db	060h, 073h, 08fh, 007h, 0f0h, 000h, 000h, 000h, 070h, 000h
	db	063h, 0f3h, 013h, 003h, 0f0h, 000h, 000h, 000h, 070h, 000h
	db	067h, 0e3h, 033h, 083h, 0f0h, 000h, 000h, 000h, 070h, 000h
	db	0e6h, 063h, 033h, 003h, 0f0h, 000h, 000h, 000h, 0f0h, 000h
	db	0eeh, 063h, 03bh, 007h, 0f8h, 000h, 000h, 000h, 0f0h, 000h
	db	06ch, 063h, 03eh, 00fh, 0f8h, 000h, 000h, 000h, 0e0h, 000h
	db	06ch, 027h, 02eh, 00bh, 0f8h, 000h, 000h, 000h, 0e0h, 000h
	db	06eh, 03fh, 0e7h, 0f3h, 0f8h, 000h, 000h, 000h, 0e0h, 000h
	db	026h, 0f9h, 0c1h, 0c3h, 0f8h, 000h, 000h, 000h, 0f0h, 000h
	db	0f7h, 0b8h, 080h, 003h, 0fch, 000h, 000h, 000h, 070h, 000h
	db	0b0h, 000h, 000h, 003h, 0fch, 000h, 000h, 000h, 070h, 000h
	db	01ch, 000h, 000h, 003h, 0fch, 000h, 000h, 000h, 070h, 000h
	db	0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 078h, 000h
	db	00bh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 012h, 00bh, 000h
	db	000h, 000h, 000h, 050h, 000h, 000h, 000h, 001h, 000h, 001h
	db	000h, 000h, 000h, 03eh, 000h, 000h, 000h, 028h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 042h, 04dh, 000h, 004h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
SpritePlane2Image label   byte            ;red plane image

	db	087h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	0e7h, 0f1h, 0f8h, 00fh, 081h, 0f1h, 0cfh, 08fh, 080h, 0e0h
	db	0f7h, 0efh, 0f7h, 06fh, 0ddh, 0fbh, 0ffh, 0dfh, 0deh, 0e0h
	db	0ffh, 0cfh, 0ffh, 07fh, 0dfh, 0f9h, 0dfh, 0dfh, 0dfh, 0e0h
	db	0f7h, 0e3h, 0ffh, 07fh, 09bh, 0fdh, 0ffh, 0dfh, 0cfh, 0e0h
	db	0c7h, 0f1h, 0ffh, 07fh, 09bh, 0fch, 0bfh, 0dfh, 0cfh, 0e0h
	db	087h, 0fch, 0feh, 07fh, 09fh, 0fch, 0bfh, 0dfh, 0dfh, 0e0h
	db	007h, 0deh, 0ffh, 07fh, 09fh, 0feh, 07fh, 0dfh, 0dfh, 0e0h
	db	007h, 0dfh, 0ffh, 07fh, 09dh, 0feh, 07fh, 0dfh, 0ceh, 0e0h
	db	007h, 0efh, 0feh, 03fh, 001h, 0ffh, 0ffh, 08fh, 080h, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e0h
	db	007h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0f9h, 0e0h
	db	00fh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	03fh, 0e0h, 049h, 0f1h, 087h, 0c7h, 0c0h, 07ch, 00fh, 000h
	db	03fh, 0f7h, 05bh, 0fbh, 0cfh, 0efh, 0bbh, 0feh, 0efh, 000h
	db	03fh, 0f3h, 07bh, 0fbh, 0dfh, 0efh, 0fbh, 0feh, 0ffh, 000h
	db	07eh, 07bh, 03fh, 0fbh, 0dfh, 0efh, 0fbh, 0feh, 0dfh, 000h
	db	0fch, 079h, 0b7h, 0fbh, 0cfh, 0efh, 0fbh, 0feh, 0dfh, 000h
	db	0f0h, 07dh, 09fh, 0fbh, 0dfh, 0efh, 0fbh, 0feh, 0ffh, 000h
	db	0e0h, 07dh, 04fh, 0fbh, 0dfh, 0efh, 0fbh, 0feh, 0ffh, 000h
	db	0c0h, 07eh, 0dfh, 0fbh, 0dfh, 0cfh, 0fbh, 0feh, 0efh, 000h
	db	0c0h, 07fh, 0ffh, 0f1h, 08fh, 087h, 0f1h, 0ffh, 0ffh, 000h
	db	080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	081h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	003h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h
	db	0ffh, 0ffh, 0fdh, 0c0h, 018h, 000h, 000h, 01fh, 0feh, 000h
	db	0ffh, 0ffh, 0f9h, 080h, 030h, 000h, 000h, 01fh, 0feh, 000h
	db	0ffh, 0ffh, 0f1h, 080h, 070h, 000h, 000h, 00fh, 0feh, 000h
	db	0ffh, 0ffh, 0f1h, 080h, 0c0h, 000h, 00ch, 00fh, 0feh, 000h
	db	0ffh, 0ffh, 0f3h, 081h, 080h, 002h, 00eh, 00fh, 0ffh, 000h
	db	0ffh, 0ffh, 0e3h, 086h, 003h, 0e6h, 00eh, 00fh, 0ffh, 000h
	db	0ffh, 0ffh, 0c3h, 0ffh, 087h, 0e6h, 00eh, 007h, 0ffh, 000h
	db	0ffh, 0ffh, 083h, 0e3h, 0c7h, 0e4h, 00eh, 007h, 0ffh, 080h
	db	0ffh, 0ffh, 083h, 080h, 06ch, 0fch, 00eh, 007h, 0ffh, 080h
	db	0ffh, 0ffh, 003h, 000h, 03ch, 0feh, 01ch, 003h, 0ffh, 080h
	db	0ffh, 0feh, 007h, 000h, 03ch, 026h, 01ch, 003h, 0ffh, 080h
	db	0ffh, 0feh, 007h, 000h, 02ch, 026h, 03ch, 003h, 0ffh, 080h
	db	0ffh, 0fch, 006h, 000h, 06ch, 067h, 0ech, 003h, 0ffh, 0c0h
	db	0ffh, 0fch, 006h, 000h, 04eh, 0c3h, 0cch, 001h, 0ffh, 0c0h
	db	0ffh, 0f8h, 006h, 000h, 087h, 0c0h, 00ch, 001h, 0ffh, 0c0h
	db	0ffh, 0f0h, 00eh, 003h, 003h, 000h, 004h, 001h, 0ffh, 0c0h
	db	0ffh, 0e0h, 00eh, 006h, 000h, 000h, 004h, 000h, 0ffh, 0c0h
	db	0ffh, 0e0h, 00eh, 01ch, 000h, 000h, 004h, 000h, 0ffh, 0c0h
	db	0ffh, 0c0h, 01eh, 0f0h, 000h, 000h, 004h, 000h, 0ffh, 0c0h
	db	0ffh, 0c0h, 01fh, 0e0h, 000h, 000h, 006h, 000h, 07fh, 0c0h
	db	0ffh, 080h, 00eh, 000h, 000h, 000h, 006h, 000h, 07fh, 0e0h
	db	0ffh, 000h, 000h, 000h, 000h, 000h, 006h, 000h, 07fh, 0e0h
	db	0feh, 000h, 000h, 000h, 000h, 000h, 006h, 000h, 03fh, 0e0h
	db	0fch, 000h, 000h, 000h, 000h, 000h, 006h, 000h, 03fh, 0e0h
	db	0f0h, 000h, 000h, 000h, 000h, 000h, 004h, 000h, 03fh, 0e0h
	db	0e0h, 000h, 000h, 000h, 000h, 006h, 004h, 000h, 03fh, 0e0h
	db	0c0h, 000h, 000h, 000h, 000h, 00eh, 004h, 000h, 01fh, 0e0h
	db	080h, 000h, 07ch, 000h, 000h, 00ah, 006h, 020h, 01fh, 0e0h
	db	080h, 001h, 0ffh, 000h, 000h, 012h, 00eh, 070h, 01fh, 0e0h
	db	000h, 007h, 083h, 080h, 000h, 016h, 00ch, 0e0h, 00fh, 0e0h
	db	000h, 00fh, 000h, 0c0h, 000h, 016h, 018h, 0c0h, 00fh, 0e0h
	db	000h, 00eh, 000h, 040h, 000h, 034h, 018h, 0c0h, 00fh, 0e0h
	db	000h, 01ch, 000h, 000h, 000h, 038h, 018h, 080h, 00fh, 0e0h
	db	000h, 01ch, 000h, 000h, 000h, 028h, 031h, 080h, 007h, 0e0h
	db	000h, 038h, 000h, 000h, 000h, 030h, 071h, 080h, 007h, 0e0h
	db	000h, 038h, 000h, 000h, 000h, 023h, 0f1h, 080h, 007h, 0e0h
	db	000h, 070h, 000h, 000h, 000h, 03ch, 031h, 086h, 007h, 0f0h
	db	000h, 070h, 000h, 000h, 000h, 060h, 073h, 00fh, 007h, 0f0h
	db	000h, 070h, 000h, 000h, 000h, 063h, 0e3h, 013h, 003h, 0f0h
	db	000h, 070h, 000h, 000h, 000h, 067h, 0e3h, 033h, 003h, 0f0h
	db	000h, 0f0h, 000h, 000h, 003h, 0e6h, 063h, 033h, 003h, 0f0h
	db	000h, 0e0h, 000h, 000h, 007h, 0e6h, 063h, 03bh, 007h, 0f8h
	db	000h, 0e0h, 000h, 010h, 026h, 06ch, 023h, 01eh, 00fh, 0f8h
	db	000h, 0e0h, 000h, 010h, 0e4h, 06ch, 027h, 02eh, 00bh, 0f8h
	db	000h, 0f0h, 000h, 011h, 0e4h, 02eh, 03fh, 0e7h, 0f3h, 0f8h
	db	000h, 070h, 000h, 01bh, 0ech, 026h, 0f9h, 0c1h, 0c3h, 0f8h
	db	000h, 070h, 000h, 01fh, 066h, 067h, 098h, 080h, 003h, 0fch
	db	000h, 070h, 000h, 00eh, 037h, 0b0h, 000h, 000h, 003h, 0fch
	db	000h, 078h, 000h, 040h, 000h, 01ch, 000h, 000h, 003h, 0fch
SpritePlane3Image label   byte            ;intensity on for all planes,
                                        ; to produce high-intensity colors

	db	039h, 0ffh, 000h, 038h, 000h, 03fh, 000h, 000h, 001h, 00fh
	db	0bfh, 0ffh, 000h, 010h, 000h, 02fh, 000h, 000h, 000h, 087h
	db	07fh, 0f6h, 080h, 050h, 000h, 01fh, 000h, 000h, 000h, 00fh
	db	0dfh, 0fch, 000h, 090h, 000h, 03fh, 000h, 000h, 008h, 00fh
	db	09fh, 0feh, 000h, 018h, 000h, 00fh, 000h, 000h, 00ch, 01fh
	db	07fh, 0feh, 000h, 053h, 000h, 05fh, 000h, 000h, 01fh, 0ffh
	db	0ffh, 0feh, 080h, 066h, 000h, 03dh, 000h, 000h, 01fh, 0ffh
	db	0bfh, 0ffh, 080h, 038h, 000h, 02eh, 000h, 000h, 03fh, 0ffh
	db	0dfh, 0ffh, 080h, 018h, 000h, 00bh, 000h, 000h, 03fh, 0ffh
	db	03fh, 0ffh, 060h, 006h, 000h, 000h, 000h, 000h, 07fh, 0afh
	db	01fh, 0ffh, 0f0h, 01dh, 000h, 000h, 000h, 000h, 07fh, 04dh
	db	07fh, 0ffh, 0d0h, 060h, 000h, 014h, 000h, 000h, 07eh, 000h
	db	07fh, 0ffh, 0fch, 0e1h, 000h, 037h, 000h, 000h, 0feh, 003h
	db	07fh, 0ffh, 0f4h, 072h, 000h, 065h, 000h, 000h, 0ffh, 000h
	db	0ffh, 0ffh, 0ach, 02fh, 000h, 03eh, 000h, 000h, 0fch, 000h
	db	0ffh, 0ffh, 0fch, 01fh, 000h, 05fh, 000h, 000h, 0feh, 001h
	db	0ffh, 0ffh, 0fch, 037h, 000h, 03fh, 000h, 000h, 0fch, 001h
	db	0ffh, 037h, 0fbh, 02fh, 080h, 07fh, 000h, 000h, 0feh, 003h
	db	0ffh, 0e7h, 0f8h, 01fh, 0e0h, 0bfh, 000h, 000h, 0fch, 001h
	db	0feh, 00fh, 0f4h, 01fh, 0e1h, 07bh, 000h, 000h, 0feh, 003h
	db	0feh, 043h, 0ffh, 03fh, 0f1h, 05eh, 000h, 000h, 0feh, 007h
	db	0fdh, 081h, 05ch, 00fh, 0c8h, 02ch, 000h, 000h, 0ffh, 001h
	db	07ch, 005h, 0deh, 017h, 0f8h, 07fh, 000h, 000h, 0fdh, 050h
	db	07ch, 007h, 0d3h, 00fh, 0f4h, 07dh, 000h, 000h, 0ffh, 07ch
	db	0a8h, 053h, 0feh, 007h, 0fch, 017h, 000h, 000h, 0fah, 066h
	db	07ch, 007h, 0ffh, 082h, 0feh, 011h, 000h, 000h, 0fbh, 076h
	db	0f4h, 017h, 0ffh, 001h, 0feh, 02bh, 000h, 000h, 0e1h, 0feh
	db	0f8h, 0efh, 0ffh, 081h, 0f7h, 00bh, 000h, 000h, 0e8h, 03eh
	db	0f8h, 08fh, 0ffh, 000h, 0e8h, 00fh, 000h, 000h, 080h, 076h
	db	0f4h, 04fh, 0fbh, 020h, 0f4h, 00fh, 000h, 000h, 000h, 03ch
	db	0f0h, 03fh, 0ech, 008h, 0e0h, 01fh, 000h, 000h, 040h, 001h
	db	0f0h, 00fh, 0ech, 011h, 060h, 01fh, 000h, 000h, 000h, 038h
	db	0f0h, 01fh, 0e8h, 00eh, 080h, 01fh, 000h, 000h, 000h, 009h
	db	0e1h, 04fh, 0ffh, 086h, 0e0h, 03fh, 000h, 000h, 040h, 01fh
	db	0e7h, 0dfh, 0ffh, 0c5h, 0e0h, 03fh, 000h, 000h, 000h, 011h
	db	0c7h, 0ffh, 0ffh, 0e5h, 0c0h, 01fh, 000h, 000h, 002h, 039h
	db	08fh, 0ffh, 0ffh, 09bh, 0c0h, 01fh, 000h, 000h, 000h, 01ch
	db	09fh, 0ffh, 0ffh, 0fbh, 0c0h, 03fh, 000h, 000h, 000h, 01dh
	db	08fh, 0ffh, 0ffh, 0dbh, 0e0h, 03fh, 000h, 000h, 000h, 00fh
	db	00fh, 0ffh, 0ffh, 0efh, 0f0h, 0bfh, 000h, 000h, 000h, 003h
	db	087h, 0ffh, 0ffh, 0f9h, 0f4h, 0ffh, 000h, 000h, 010h, 003h
	db	087h, 0ffh, 0ffh, 0e7h, 0bfh, 0ffh, 000h, 000h, 020h, 001h
	db	0c3h, 0ffh, 0ffh, 06bh, 0efh, 0ffh, 000h, 000h, 020h, 001h
	db	0f7h, 0ffh, 0ffh, 0e0h, 087h, 0ffh, 000h, 000h, 06ch, 001h
	db	0ffh, 0ffh, 0feh, 0a0h, 00fh, 0ffh, 000h, 000h, 076h, 003h
	db	0ffh, 0ffh, 0ffh, 040h, 00fh, 0ffh, 000h, 000h, 07fh, 003h
	db	0ffh, 0ffh, 0ffh, 0e0h, 00fh, 0ffh, 000h, 000h, 07ch, 001h
	db	0ffh, 0ffh, 0ffh, 0a0h, 00eh, 0cfh, 000h, 000h, 0feh, 003h
	db	0ffh, 0ffh, 0ffh, 0f0h, 045h, 0c7h, 000h, 000h, 0d0h, 003h
	db	0ffh, 0ffh, 0ffh, 0f8h, 03dh, 0a7h, 000h, 000h, 0ech, 001h
	db	0e7h, 0ffh, 0ffh, 0f0h, 05bh, 0c1h, 000h, 000h, 0e4h, 001h
	db	090h, 0dfh, 07dh, 0feh, 01dh, 00dh, 000h, 000h, 018h, 000h
	db	000h, 07fh, 0d4h, 00eh, 03eh, 030h, 000h, 000h, 0a0h, 00ah
	db	001h, 021h, 013h, 0b5h, 07fh, 041h, 000h, 000h, 0eah, 000h
	db	000h, 029h, 0abh, 0f8h, 03eh, 004h, 000h, 000h, 0f0h, 007h
	db	000h, 053h, 01bh, 0c8h, 01fh, 091h, 000h, 000h, 0f1h, 0c2h
	db	0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 0fch, 041h
	db	0c4h, 00eh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 0c0h, 003h, 000h, 000h, 0c4h, 00eh
	db	050h, 000h, 000h, 000h, 050h, 000h, 000h, 000h, 001h, 000h
	db	000h, 000h, 000h, 000h, 03eh, 000h, 000h, 000h, 028h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 042h, 04dh, 0feh, 003h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
;
SpriteX           dw      40			;sprite x coord
SpriteY           dw      175			;sprite y coord
LastSpriteX       dw      40			;previous sprite x coords
LastSpriteY       dw      175			;previous sprite y coords
SpriteXInc		  dw      1				;x move factor for sprite
SpriteYInc        dw      1				;y move factor for sprite

;
; Macro to set indexed register P2 of chip with index register
; at P1 to AL.
;
SETREG  macro   P1, P2
        mov     dx,P1
        mov     ah,al
        mov     al,P2
        out     dx,ax
        endm
;

		.CODE
start   proc    near
	.STARTUP	; initialise segment registers
;
; Select graphics mode.
;
        mov     ax,010h		; VGA mode 10h
        int     10h
;
; ES always points to VGA memory.
;
        mov     ax,VIDEO_SEGMENT
        mov     es,ax
;
; Draw all four plane's worth of the sprite to undisplayed VGA memory.
;
        mov     al,01h          ;enable plane 0
        SETREG  SC_INDEX, MAP_MASK
        mov     si,offset SpritePlane0Image
        mov     di,SPRITE_OFFSET
        mov     cx,SPRITE_WIDTH * SPRITE_HEIGHT
        rep movsb
        mov     al,02h          ;enable plane 1
        SETREG  SC_INDEX, MAP_MASK
        mov     si,offset SpritePlane1Image
        mov     di,SPRITE_OFFSET
        mov     cx,SPRITE_WIDTH * SPRITE_HEIGHT
        rep movsb
        mov     al,04h          ;enable plane 2
        SETREG  SC_INDEX, MAP_MASK
        mov     si,offset SpritePlane2Image
        mov     di,SPRITE_OFFSET
        mov     cx,SPRITE_WIDTH * SPRITE_HEIGHT
        rep movsb
        mov     al,08h          ;enable plane 3
        SETREG  SC_INDEX, MAP_MASK
        mov     si,offset SpritePlane3Image
        mov     di,SPRITE_OFFSET
        mov     cx,SPRITE_WIDTH * SPRITE_HEIGHT
        rep movsb
;
; Draw a blank image the size of the sprite to undisplayed VGA memory.
;
        mov     al,0fh                  ;enable all memory planes, since the
        SETREG  SC_INDEX, MAP_MASK      ; blank has to erase all planes
        mov     di,BLANK_OFFSET
        mov     cx,SPRITE_WIDTH * SPRITE_HEIGHT
        sub     al,al
        rep stosb;
; Set VGA to write mode 1, for block copying sprite images.
;
        mov     dx,GC_INDEX
        mov     al,GC_MODE
        out     dx,al           ;point GC Index to GC Mode register
        inc     dx              ;point to GC Data register
        jmp     $+2             ;delay to let bus settle
        in      al,dx           ;get current state of GC Mode
        and     al,not 3        ;clear the write mode bits
        or      al,1            ;set the write mode field to 1
        jmp     $+2             ;delay to let bus settle
        out     dx,al
;
; Set VGA offset register in words to define logical screen width.
;
        mov     al,SCREEN_WIDTH / 2
        SETREG  CRTC_INDEX, CRTC_OFFSET
;
; Move the sprite by moving it and redrawing it, the blank border around the sprite
; will clear the old sprite since we're only moving one pixel at a time.
;
SpriteAnimationLoop:
;
; Erase old image of sprite in this page (at location from one more earlier).
;
        mov     si,BLANK_OFFSET ;point to blank image
        mov     cx,[LastSpriteX]
        mov     dx,[LastSpriteY]
        call    DrawSprite
;
; Set new last sprite location.
;
        mov     ax,[SpriteX]
        mov     [LastSpriteX],ax
        mov     ax,[SpriteY]
        mov     [LastSpriteY],ax;
; Move the sprite.
;
CheckYOutofBounds:
; First check if we need to reverse the y direction
		mov	ax,[SpriteY]
		cmp	ax,SCREEN_HEIGHT - SPRITE_HEIGHT
		jae	NegY
		cmp	ax,0
		jg	MoveSpriteY
NegY:
		neg	[SpriteYInc]
MoveSpriteY:
        mov     ax,[SpriteYInc]
        add     [SpriteY],ax           ;move in y direction
; only move x every so often
		mov		ax,[SpriteY]
		and		ax,006Fh
		jnz		FinishedMoving
CheckXOutofBounds:
; Now check if we need to reverse the x direction
		mov	ax,[SpriteX]
		cmp	ax,SCREEN_WIDTH - SPRITE_WIDTH
		jae	NegX
		cmp	ax,0
		jg	MoveSpriteX
NegX:
		neg	[SpriteXInc]
MoveSpriteX:
        mov     ax,[SpriteXInc]
        add     [SpriteX],ax           ;move in x direction
FinishedMoving:
;
; Draw sprite at new location.
;
        mov     si,SPRITE_OFFSET  ;point to sprite's image
        mov     cx,[SpriteX]
        mov     dx,[SpriteY]
        call    DrawSprite
;
; Wait for display enable (pixel data being displayed) so we know
; we're nowhere near vertical sync, where the start address gets
; latched and used.
;
        call    WaitDisplayEnable
;
; Flip to the new page by changing the start address.
;
        mov     ax,[CurrentPageOffset]
        push    ax
        SETREG  CRTC_INDEX, START_ADDRESS_LOW
        pop     ax
        mov     al,ah
        SETREG  CRTC_INDEX, START_ADDRESS_HIGH
;
; Wait for vertical sync so the new start address has a chance
; to take effect.
;
        call    WaitVSync
;
; Flip the page to draw to to the undisplayed page.
;
        xor     [CurrentPage],1
        jnz     IsPage1
        mov     [CurrentPageOffset],PAGE0_OFFSET
        jmp     short EndFlipPage
IsPage1:
        mov     [CurrentPageOffset],PAGE1_OFFSET
EndFlipPage:
;
; Exit if a key's been hit.
;
        mov     ah,1
        int     16h
        jnz     Done
        jmp     SpriteAnimationLoop
;
; Finished, clear key, reset screen mode and exit.
;
Done:
        mov     ah,0    ;clear key
        int     16h
;
        mov     ax,3    ;reset to text mode
        int     10h
;
	.EXIT		; exit to DOS
;
start   endp
;
; Routine to draw a sprite-sized image to all planes, copying from
; offset SI in VGA memory to offset CX,DX (x,y) in VGA memory in
; the current page.
;
DrawSprite        proc    near
        mov     ax,SCREEN_WIDTH
        mul     dx      ;offset of start of top image scan line
        add     ax,cx   ;offset of upper left of image
        add     ax,[CurrentPageOffset]  ;offset of start of page
        mov     di,ax
        mov     bp,SPRITE_HEIGHT
        push    ds
        push    es
        pop     ds      ;move from VGA memory to VGA memory
DrawSpriteLoop:
        push    di
        mov     cx,SPRITE_WIDTH
        rep movsb       ;draw a scan line of image
        pop     di
        add     di,SCREEN_WIDTH ;point to next destination scan line
        dec     bp
        jnz     DrawSpriteLoop
        pop     ds
        ret
DrawSprite        endp
;
; Wait for the leading edge of vertical sync pulse.
;
WaitVSync       proc    near
        mov     dx,INPUT_STATUS_1
WaitNotVSyncLoop:
        in      al,dx
        and     al,VSYNC_MASK
        jnz     WaitNotVSyncLoop
WaitVSyncLoop:
        in      al,dx
        and     al,VSYNC_MASK
        jz      WaitVSyncLoop
        ret
WaitVSync       endp

;
; Wait for display enable to happen (pixels to be scanned to
; the screen, indicating we're in the middle of displaying a frame).
;
WaitDisplayEnable       proc    near
        mov     dx,INPUT_STATUS_1
WaitDELoop:
        in      al,dx
        and     al,DE_MASK
        jnz     WaitDELoop
        ret
WaitDisplayEnable       endp

        end


