⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llegasup.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	JZ	LSTBYT

;	Look at whole bytes within viewport range until non-paint color found.

LKPNTL:
	DEC	SI
	MOV	AL,ES:[SI]
	NOT	AL		;check if all bits set (all paint color)
	OR	AL,AL		;NOT does not affect flags
	JNZ	BITFDL
	DEC	DI
	JNZ	LKPNTL		;keep looking until search of complete
				;bytes is exhausted

;	On last byte now, mask in BH.

LSTBYT:
	DEC	SI
	MOV	AL,ES:[SI]	;do last compare
	AND	AL,BH		;significant bit = 0 if not paint color
	XOR	AL,BH		;if different, not paint
	JZ	NOBITL
BITFDL:
	MOV	CL,AL		;set change bits flag to non-zero
NOBITL:
cEnd

;***
; B$EgaTILLFT
;Purpose:
;	Check for non-paint pixels left if tiling is on.
;	Use READC to do bit-wise color compares with tile colors stored in
;	color array ColorBits (colors of bits 0 to 7 configured left to right
;	are represented in the array as elements offset 0 to 7 from base
;	address).
;
;Entry:
;	BL    = bit mask for rightmost partial byte
;	BH    = bit mask for leftmost partial byte
;	DI    = count of whole bytes
;	ES:SI = screen address
;Exit:
;	CL = 0 iff no pixels to change
;Uses:
;	per conv.
;Exceptions:
;****
cProc	B$EgaTILLFT,<PUBLIC,NEAR>,<DX,BP>
cBegin
	PUSH	b$OffC
	PUSH	b$PenC
	PUSH	BX
	MOV	AL,BL		;copy of bit mask for rightmost byte
	MOV	ByteCount,DI	;store whole byte counter
	OR	AL,AL		;make sure at least 1 bit set
	JZ	TILLF5
	CALL	HICHK		;check first [partial] byte using mask in [AL]
	JNZ	TILLF1		;exit if non-match found
TILLF5:
	CMP	ByteCount,0	;check for intermediate whole bytes
	JZ	TILLF4		;if not, proceed to check for last byte
TILLF2:
	DEC	SI		;move left on line
	MOV	b$OffC,SI	; store in b$OffC for READC
	MOV	b$MaskC,1	;start at rightmost bit
	MOV	BP,7		;rightmost element of color array
TILLF3:
	CALL	[b$ReadC]	;determine color of pixel (returned in AL)
	CMP	AL,ColorBits[BP] ;look for non-match
	JNZ	TILLF1		;when we find one, we can exit
	DEC	BP
	SHL	b$MaskC,1	;move to next bit left
	JNB	TILLF3		;continue 'til we shift out of byte left
	DEC	ByteCount	;prepare to check next byte left
	JNZ	TILLF2
TILLF4:
	POP	BX
	OR	BH,BH		;see whether a "last byte"
	PUSH	BX
	JZ	TILLF6		;if not, there was only 1 byte
	MOV	AL,BH		;get last byte's bit mask
	DEC	SI
	CALL	LOWCHK		;look through last [partial] byte for match
	JNZ	TILLF1
TILLF6:
	MOV	CL,-1
TILLF1:
	INC	CL		;non-zero if pixels changed
	POP	BX
	POP	b$PenC
	POP	b$OffC
cEnd

;***
; HICHK
;Purpose:
;	Check partial byte for tile pattern match, where byte may be
;	partial in that some low bits may be immunized from PAINT and
;	therefore must be skipped during the tile pattern check.
;
;Entry:
;	AL = screen byte to check
;	ColorBits array contains tile pattern to check against
;Exit:
;	PSW.C set iff no match found
;Uses:
;	per conv.
;Exceptions:
;****
cProc	HICHK,<NEAR>
cBegin
	MOV	CH,10000000B	;rotate will start mask at 0000/0001
	MOV	BP,8		;start counter at 8
HICHK1:
	ROL	CH,1
	DEC	BP		;offset to first bit to check for color
	ROR	AL,1		;shift immune bits out right
	JNB	HICHK1		;if we got a 1, we found a relevant bit
	MOV	b$MaskC,CH
HICHK2:
	PUSH	AX		;store state of shift mask
	MOV	b$OffC,SI
	CALL	b$ReadC	;get color for this pixel
	CMP	ColorBits[BP],AL ;see if match
	POP	AX		;restore shift mask
	JNZ	HICHK3		;our goal is just one non-matching pixel
	DEC	BP
	ROR	AL,1		;look for additional 0's to left of first 1
	JNB	HICHK4
	SHL	b$MaskC,1
	JNB	HICHK2
HICHK4:
	XOR	BP,BP		;return ZF set if no match found
HICHK3:
cEnd

;***
; LOWCHK
;Purpose:
;	Check partial byte for tile pattern match, where byte may be
;	partial in that some high bits may be immunized from PAINT and
;	therefore must be skipped during the tile pattern check.
;
;Entry:
;	AL = screen byte to check
;	ColorBits array contains tile pattern to check against
;Exit:
;	PSW.C set iff no match found
;Uses:
;	per conv.
;Exceptions:
;****
cProc	LOWCHK,<NEAR>
cBegin
	MOV	CH,00000001B	;rotate will start mask at 1000/0000
	XOR	BP,BP
	NOT	BP		;counter at -1
LWCHK1:
	ROR	CH,1
	INC	BP		;offset to first bit to check for color
	ROL	AL,1		;shift immune bits out left
	JNB	LWCHK1		;if we got a 1, we found a relevant bit
	MOV	b$OffC,SI
	MOV	b$MaskC,CH
LWCHK2:
	PUSH	AX		;store state of shift mask
	CALL	b$ReadC	;get color for this pixel
	CMP	ColorBits[BP],AL ;see if match
	POP	AX		;restore state of shift mask
	JNZ	LWCHK3		;our goal is just one non-matching pixel
	ROL	AL,1		;look for any trailing 0's indicating immune
	JNB	LWCHK4
	INC	BP
	SHR	b$MaskC,1
	JNB	LWCHK2
LWCHK4:
	XOR	BP,BP		;set ZF
LWCHK3: 			;non-zero indicates non-match
cEnd

;***
; WRTLFT
;Purpose:
;	Used for tiling if in odd/even mode, during SCANL.
;	Latches off-screen tile pattern at even address when DI even, and
;	at odd address when DI odd, then "writes" this pattern at DI.
;
;Entry:
;	ES:DI = screen address of start byte
;	CX    = count of bytes to write
;Exit:
;	ES:DI = screen address of stop byte
;Uses:
;	SI
;Exceptions:
;****
cProc	WRTLFT,<NEAR>
cBegin
	MOV	SI,OFFSCN	;get address of off-screen location
	TEST	DI,1		;see whether first byte odd
	JNZ	INCBYL
	INC	SI		;even byte, so set up for DEC loop
DECBYL:
	DEC	SI		;SI gets even offscreen byte address
	MOV	AL,ES:[SI]	;latch even byte pattern
	MOV	ES:[DI],AL	;dummy write puts latched byte out
	DEC	DI		;move left on write line
	DEC	CX		;decrement byte counter
	JCXZ	LFTEX
INCBYL:
	INC	SI		;point to odd offscreen byte
	MOV	AL,ES:[SI]	;latch odd byte pattern
	MOV	ES:[DI],AL	;dummy write of latched pattern
	DEC	DI		;move left
	LOOP	DECBYL
LFTEX:
cEnd

;***
; WRTRGT
;Purpose:
;	Used for tiling if in odd/even mode, during SCANR.
;	Latches off-screen tile pattern at even address when DI even, and
;	at odd address when DI odd, then "writes" this pattern at DI.
;
;Entry:
;	ES:DI = screen address of start byte
;	CX    = count of bytes to write
;Exit:
;	ES:DI = screen address of stop byte
;Uses:
;	SI
;Exceptions:
;****
cProc	WRTRGT,<NEAR>
cBegin
	MOV	SI,OFFSCN	;get address of off-screen location
	TEST	DI,1		;see whether first byte odd
	JNZ	INCBYR
	INC	SI		;even byte, so set up for DEC loop
DECBYR:
	DEC	SI		;SI gets even offscreen byte address
	MOV	AL,ES:[SI]	;latch even byte pattern
	MOV	ES:[DI],AL	;dummy write puts latched byte out
	INC	DI		;move right on write line
	DEC	CX		;decrement byte counter
	JCXZ	RGTEX
INCBYR:
	INC	SI		;point to odd offscreen byte
	MOV	AL,ES:[SI]	;latch odd byte pattern
	MOV	ES:[DI],AL	;dummy write of latched pattern
	INC	DI		;move right
	LOOP	DECBYR
RGTEX:
cEnd

;***
; ScanL
;Purpose:
;	To scan left beginning one pixel to the left of the current
;	graphics cursor setting pixels to the paint attribute until
;	either edge of viewport or border is found; to return
;	certain information to the calling routine.
;
;	Algorithm for SCANL2 is as follows: starting next left to b$OffC
;	  b$MaskC:
;
;	  i.  While (not border) AND (not viewport edge) AND (not left
;	      edge of byte) move left in byte.
;	  ii. If (left edge of byte) then
;		 decrement b$OffC, set up b$MaskC, go to i.
;	      Else
;		 test if on border pixel
;		    x.	if true, exit unchanged
;		    xx. else
;			   xx1. set up bit mask for first byte
;			   xx2. calculate # whole bytes if any
;			   xx3. set up bit mask for last byte if any
;			   xx4. see whether any pixels in range will
;				change color
;				xx41. if not, exit to pixel count routine
;				xx42. if so, paint all pixels
;			   xx5. calculate number of pixels "painted"
;			   xx6. exit with appropriate information
;Entry:
;	b$AttrC       = attribute to paint
;	b$PaintBorder = border attribute which ends paint
;	b$OffC, b$MaskC specify pixel one to right of first to examine
;Exit:
;	BX = number of nonborder pixels tested
;	CL = 0 ifF no pixels changed color
;	b$OffC, b$MaskC specify location of last pixel painted, or
;	       unchanged if only border pixels found
;Uses:
;	per conv.
;Exceptions:
;****************************************************************************
cProc	B$EgaScanL,<PUBLIC,NEAR>,<ES>
cBegin
	CALL	B$EgaScanInit
	ROL	CH,1		;see if cursor is left edge of byte
	JNB	VWPCK1
	SUB	SI,1		;if so, start next byte left
	JNC	VWPCK1		;(SUB used since DEC doesn't set carry)
	JMP	BRDEX1		;if negative, hit corner of screen
VWPCK1: 			;to check first for viewport edge byte
	CMP	SI,B$LEOFST	;see if on edge of viewport, or off to left
	JNB	VWPCK2		;if viewport byte or to right,
	JMP	BRDEX1		; continue, else off to left; do nothing, exit
VWPCK2: 			;to check for edge bit if in edge byte
	JNZ	NOTEDG		;if not viewport edge byte, skip
	CMP	CH,B$VLMASK	;bit check else compare first pixel left with
				;viewport edge bit -- if farther left, we are
;	JA	BRDEX1		;are left of viewport edge and must
	JNA	NOTEDG		;exit
	JMP	BRDEX1
NOTEDG: 			;exit
	MOV	DI,SI		;extra copy of first byte address
	MOV	CL,CH		;extra copy of initial bit mask
	MOV	BP,-1		;this will be count of whole bytes
	XOR	DX,DX		;this will be #pixels painted
	XOR	AH,AH		;initialize this byte's viewport mask to 0

;	read first byte off the screen

	MOV	AL,ES:[DI]
	TEST	AL,CH		;see whether initial pixel is border
	JZ	SRCHLF		;if not, start search left
	XOR	CL,CL		;else set pixels-changed flag back to 0
	JMP	SHORT BRDEX1	;and exit gracefully
SRCHLF:

;	look for border or viewport in first byte

	CMP	DI,B$LEOFST	;is this in fact viewport edge byte?
	JNZ	NOTVWL
	MOV	AH,B$VLMASK	;if so, set up viewport mask in AH
NOTVWL:

;	while not border

	TEST	AL,CH
	JNZ	HAVPIX

;	and not viewport edge

	TEST	AH,CH
	JNZ	HAVPIX

;	and not off the edge of the byte

	ROL	CH,1
	JNB	NOTVWL

;	keep moving left - edge of first byte

	DEC	DI		;next byte address left
	INC	BP		;count of intermediate bytes
	MOV	AL,ES:[DI]	;read next byte left
	JMP	SHORT SRCHLF	;check next byte

HAVPIX:

;	Here when border or viewport edge found.
;	Set up bit mask for first (possibly only) byte.
;	SI = rightmost byte
;	DI = leftmost byte (possibly same byte)
;	CL = mask for rightmost bit in rightmost byte

;	If viewport edge was found, AH will contain the viewport bit
;	mask, and DI is the viewport edge byte. If SI=DI=viewport edge
;	byte, we need to retain the viewport mask in AH.  Otherwise
;	clear AH and fetch the mask again later if needed for DI.

	CMP	SI,B$LEOFST	;see if rightmost byte is LEFT viewport
	JZ	SINOTV		;if so, don't clear viewport mask
				; register
	XOR	AH,AH		;else clear AH for B$EgaCHKBTL on
SINOTV: 			;  rightmost byte
	MOV	CH,CL		;initial bit position in CH
	MOV	AL,ES:[SI]	;get border bits if any
	CALL	B$EgaCHKBTL	;set up bit mask for first byte
	MOV	BL,BH		;store in BL
	XOR	BH,BH		;there may be only one byte

;	see if more than 1 byte to paint

	PUSH	SI		;save a copy of rightmost address
	INC	BP		;see if still -1
	JZ	ONEBYT
	DEC	BP		;if not, recover real value
	MOV	CH,1		;set up mask for final byte
	MOV	AL,ES:[DI]	;get border bits if any
	CMP	DI,B$LEOFST	;was this viewport byte?
	JNZ	DINOTV		;no -- don't need viewport mask
	MOV	AH,B$VLMASK	;yes -- get viewport mask for CHKTBL
DINOTV:
	CALL	B$EgaCHKBTL	;set up leftmost byte bit mask in BH
ONEBYT:
	MOV	b$OffC,DI
	MOV	b$MaskC,CH	;update cursor
	PUSH	DI		;save a copy of leftmost address
	MOV	DI,BP		;store whole byte count for PIXLF2
	CMP	b$Tiling,0
	JZ	COLCM5
	CALL	B$EgaTILLFT
	JMP	SHORT COLCM6
COLCM5:
	CALL	B$EgaSETCMP	;set color compare register to paint attribute
	CALL	PIXLF2		;see whether any pixels in range will change
COLCM6:
	POP	SI		;restore leftmost address to SI
	POP	DI		;restore rightmost address to DI
	OR	CL,CL		;returns CL non-zero if changes needed
	JZ	BRDEXT

;	We found at least 1 pixel to change, so set entire range
;	set pixels-changed flag, set up write mode 2

	XOR	CH,CH
	NOT	CH		;set to FF as decrement flag
	STD			;for SCANL, decrement from DI
	CALL	B$EgaPAINPX
	CLD
BRDEXT:
	CALL	B$EgaPIXCNT	;returns # pixels "painted" in BX
BRDEX1:
	CALL	B$ResetEGA
cEnd

;***
; ScanR
;Purpose:
;	To scan right beginning with the graphics cursor at entry
;	setting certain pixels to the current graphics attribute
;	(color or tile pattern); to return certain information to
;	the calling routine .
;
;	ScanR algorithm is as follows :
;	 i.  Search right until
;	     a.  DX pixels have been tested without encountering non-
;		 border,
;		 OR
;	     b.  viewport edge is encountered without encountering non-
;		 border,
;		 OR
;	     c. a non-border pixel is found.
;	 ii. If a. or b., then exit with
;		[BX] = number of pixels painted = 0
;		[CL] = pixels modified flag = 0
;		[DX] = border pixels skipped during successful search for
;		       non-border pixel = 0
;		graphics cursor preserved
;		CSAVE (cursor values returned by previous SCANs) preserved
;
;	 iii.If c., then continue searching right painting non-border
;	     pixels until
;	     a. a border pixel is found
;		OR
;	     b. the edge of the viewport is encountered
;	     then exit with
;		[BX] = count of pixels painted (even if no color change
;		[CL] = pixels modified flag (0 if no pixels changed color)
;		[DX] = entry [DX] - count of border pixels searched before
;		       encountering non-border
;		b$OffC, b$MaskC = last pixel examined (border or viewport
;		      edge, painted if viewport edge
;		b$SaveCa,b$SaveCm = cursor values for first non-border pixel
;
;	This routin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -