Metropoli BBS
VIEWER: sprites3.asm MODE: TEXT (ASCII)
;
; *** Listing 3 ***
;
;Byte-move graphics driver for putting rectangular images into
; the Color/Graphics Adapter's medium-resolution memory map.
;
; Inputs (DS and CS must be the same, ES must contain 0B800h):
;
;   BX - Row at which to put the top of the image. Range is 0 to 198.
;	  BX must be even: images cannot start at an odd row.
;
;   CX - The column at which to start the image in bytes. Range is
;	  0 to 79.
;
;   SI - Points to data structure which contains the image description.
;	  The first byte is the height in lines (h). The second is the
;	  width of the image in bytes (w). h*w image bytes follow which
;	  contain the values to be placed into the screen memory map.
;	  The image bytes are ordered as h consecutive sets of w line
;	  image bytes.	h must be an even number; images must be an
;	  even number of scan lines high.
;
; Outputs:
;
;   None.
;
; Note: AX,BX,CX,DX,BP,SI,DI destroyed.
;
cseg	segment para public 'cseg'
	assume	cs:cseg,ds:cseg,es:nothing
	public	byte_move_form_driver
;
byte_move_form_driver proc near
	mov	di,[bx+even_line_screen_offset_table]  ;find the offset
						       ; of the top
						       ; line of image
	add	di,cx	 ;ES:DI now points to byte at which to put
			 ; the image's upper left corner
	lodsb		 ;get the height of the image
	xor	ah,ah	 ;make height a word value for calculations
	mov	bx,ax	 ;store height in BX
	lodsb		 ;get the width of the image in bytes
	mov	bp,2000h ;calculate the amount to add after even scan
	sub	bp,ax	 ; lines are drawn to get to the address of the
			 ; next scan line
	mov	dx,1fb0h ;calculate the amount to subtract after odd 
	add	dx,ax	 ; scan lines are drawn to get to the address
			 ; of the next scan line
	jmp	[bx+inline_height_vector_table-2] ;-2 because there is
						  ; no zero lines entry
						  ; point
;
;This table is used to find the offset of an even scan line in
; the memory map of the color graphics adapter in medium 
; resolution mode.
;
even_line_screen_offset_table label word
x=0
	rept	100	;there are 100 even lines
	dw	x*50h	; each is 50h (80 decimal) long
x=x+1
	endm
;
;This is inline code for moving the image into the screen memory map.
;
label	macro	x	;this macro is used to label the inline code
line&x&:		; entry points
	endm
;
x=42			;there will be an entry point for each even
			; number of lines between 2 and 40. They will
			; be labeled "line2", "line4", ... "line40"
	rept	20
x=x-2			;calculate number of lines for this entry point
	label	%x	;put in label for entry point
	mov	cx,ax	;put width of image in bytes in CX to prepare
	rep	movsb	; for repeated move string on even line
	add	di,bp	;calc address of next line DI + (2000h-width)
	mov	cx,ax	;put width of image in bytes in CX to prepare
	rep	movsb	; for repeated move string on odd line
	sub	di,dx	;calc address of next line DI - (1fb0h+width)
	endm
	ret
;
;This table is used as an indirect address for jumping into
; the inline code for image moving.
;
inline_height_vector_table label word ;there is no entry point for zero
				      ; lines. Starting at 2 eliminates
				      ; the need to store a dummy entry
					; point address
entry_address	macro	x		;this macro is used to generate
		dw	line&x& 	; the labels corresponding to
		endm			; the inline code entry points
;
x=2
	rept	20
	entry_address	%x
x=x+2
	endm
;
byte_move_form_driver endp
;
cseg	ends
	end

[ RETURN TO DIRECTORY ]