
TITLE MSHAPE -- Animate a Multi_character shape 
;Move a shape horizontally across the screen,
;  with a 1/4 second delay between moves
;
data_seg segment
car 	  db 7		      ;shape table
	  db 52h,70h,0,0
	  db 0b1h,70h,0,1
	  db 0dbh,7,0,1
	  db 0dbh,7,0,1
	  db 4fh,7,1,0
	  db 4fh,7,0,-3
	  db 2,7,-2,1
char_cnt  dw ?
pointer   dw ?
line_on   db ?
col_on    db ?
data_seg ends
;--------------------------------------------------
code_seg segment
	assume cs:code_seg,ds:data_seg
main proc far
	push	ds		;for return
	sub	ax,ax
	push	ax
	mov	ax,data_seg	;initialize DS
	mov	ds,ax
	call	clear_screen	;clear the screen
	lea	di,car		;DI points to car
				;  shape table
	mov	dh,10		;body is on line 10
	mov	dl,10		;starting in col 10
	call	move_shape	;move the car
	ret
main endp
;--------------------------------------------------
clear_screen proc near
	push	ax		;save register
	push	bx
	push	cx
	push	dx
	mov	ah,6		;scroll up func.
	mov	al,0		;code to blank screen
	mov	ch,0		;upper left row
	mov	cl,0		;upper left column
	mov	dh,24		;lower right row
	mov	dl,79		;lower right column
	mov 	bh,7		;blank line attribute
	int	10h		;video ROM call
	pop	dx		;restore register
	pop	cx
	pop	bx
	pop	ax
	ret		    ;return to main program
clear_screen endp
;--------------------------------------------------
move_shape proc near
	push	ax	      ;save registers
	push	bx
	push	cx
	push	dx
	push	di
	mov	ah,0fh	      ;set BH to active page
	int	10h
	sub	ch,ch	      ;clear high byte of count
	mov	cl,[di]	      ;Cl holds char count
	inc	di	      ;DI points to first char
	mov	char_cnt,cx   ;save character count
	mov	pointer,di    ;shape table pointer
	mov	line_on,dh    ;and coordinates
	mov	col_on,dl
;These instructions plot the shape on the screen
plot_next:
	add	dh,[di+2]     ;update row pointer
	add	dl,[di+3]     ;and column pointer
	cmp	dl,80	    ;Is this char off the screen?
	jb	mov_crsr
	call	erase	    ;If so,erase shape and exit
	pop	di
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
mov_crsr:
	mov	ah,2		;mov cursor
	int	10h 
	mov	al,[di]		;fetch char value
	mov	bl,[di+1]	;and attribute
	push	cx
	mov	cx,1
	mov	ah,09		;write char to screen
	int	10h
	pop	cx
	add	di,4		;DI points to next char.
	loop	plot_next	;
	call	dly_qrtr	;wait a quarter second
	call	erase		;then erase the shape
	jmp	short plot_next
move_shape endp
;--------------------------------------------------
;This procedure erases a shape by reploting it 
;  with attribute = 0
erase proc near
	mov	cx,char_cnt	;reload char count
	mov	di,pointer	;shape table pointer
	mov	dh,line_on	;line number
	mov	dl,col_on	;and column number
erase_next:
	add	dh,[di+2]
	add	dl,[di+3]
	mov	ah,2
	int	10h
	mov	al,[di]		;to erase a character
	mov	bl,0		;use an attr = 0
	push	cx
	mov	cx,1
	mov	ah,9
	int	10h
	pop	cx
	add	di,4
	loop	erase_next
	mov	cx,char_cnt	;reload char count
	mov	di,pointer	;shape table point
	mov	dh,line_on	;line number
	inc	col_on		;point to next column
	mov	dl,col_on
	ret			;return to caller
erase endp
;--------------------------------------------------
;This procedure generate a one_quarter second delay
dly_qrtr proc near
	push	cx
	push	dx
	mov	dx,25
dl1:	mov	cx,2801
dl2:	loop	dl2
	dec	dx
	jnz	dl1
	pop	dx
	pop	cx
	ret
dly_qrtr endp
;--------------------------------------------------
code_seg ends
	 end main

