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

📄 llegasup.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	CALL	TILSET		;set up for copy of off-screen tile

;	NOTE: This call has the effect of immunizing all bits from
;	      processor writes therefore, we must clear the bit mask
;	      following the write if tiling is on.

;	QCG tiling always does slow loop, so 2-plane hack isn't needed?

	TEST	b$Planes,4	;check for four-plane graphics mode
	JNZ	WRITE4		;if 2 planes, need byte-by-byte write routine
; QCG: would need to fix bkg mask here if using this code
	OR	BH,BH		;see whether SCANR or SCANL
	JNZ	CALLFT		;non-zero flag indicates move left
	CALL	WRTRGT		;zero indicates move right
	JMP	SHORT CLRBT2
CALLFT:
	CALL	WRTLFT
	JMP	SHORT CLRBT2

WRITE4:
	REP	STOSB
CLRBT2:
	EGAINT10STI		; reenable interrupts at common exit
	MOV	CL,1		;single pixels counted in B$EgaCHKBTR calls
				;non-zero as pixels changed flag
cEnd

;***
; WRTTIL
;Purpose:
;	Used for writing first and last bytes, possibly partial bytes,
;	to the screen when tiling is on for EGA modes.
;	At entry, the bit mask has been set up for the byte to write, and the
;	contents have been latched.
;	This routine writes the relevant bits to each plane one at a time,
;	using the map mask register to enable the planes from 3 to 0 and
;	writing from AttrTile from offset 3 down to 0.
;
;Entry:
;	ES:DI	 = screen address
;	AttrTile = tile value to write
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;*******************************************************************************
WRTTIL:
	PUSH	DX
	PUSH	BX
	MOV	DX,SEQADD	;index port for sequencer
	MOV	AL,LOW MMREG	;index to Map Mask Register
	OUT	DX,AL
	INC	DX
	MOV	AL,8H		;start with plane 3
	MOV	BX,3
WRTPLN:
	OUT	DX,AL		;set up for one plane
	MOV	AH,AttrTile[BX] ;get tile pattern for that plane
	MOV	ES:[DI],AH	;write to one plane
	MOV	AH,ES:[DI]	;latch that write
	DEC	BX
	SHR	AL,1		;next plane down the list
	JNB	WRTPLN		;repeat 3,2,1,0
	DEC	DX		;back to SEQADD
	MOV	AL,MMREG	
	OUT	DX,AL		;index the register
	XCHG	AL,AH		
	MOV	AL,0FH		;reeanable all planes
	INC	DX		;to data port
	OUT	DX,AL		
	POP	BX
	POP	DX
	RET

;***
; TILSET
;Purpose:
;	Prepares for write of whole tile bytes to the screen in the following
;	fashion :
;
;	i.  uses the routine WRTTIL to write the tile pattern, plane by
;	    plane, at the first offscreen address (6D60H); and, if we are
;	    in odd/even mode, writes it at the second offscreen address also
;	ii. sends 0 to Bit Mask Register to indicate all bits immune
;	iii.reenables write to all planes
;
;	This sets up the card so that it will always write not from processor
;	data but from the latches. If more than 64K, mode 10H, we can perform
;	one latch read at the off-screen address and then write on-screen bytes
;	in the tile pattern simply by changing the address back on-screen and
;	asking for writes to the screen.
;	If we are in odd/even mode, we must perform a latch for each byte
;	written, at the even address for even bytes, at the odd address for odd
;	bytes.	These reads occur within the routines WRTRGT and WRTLFT, which
;	then write to the screen from the latches, byte by byte.
;Entry:
;	ES:DI = screen address
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************

TILSET: 			;this routine altered for Modes D,E support
	TEST	b$Planes,4	;see if 4-plane tile
	JNZ	TILST4		;if so, just write first whole byte,latch,exit
	PUSH	DI		;for odd/even mode, save on-screen byte address
	MOV	DI,OFFSCN	;and substitute offscreen address (fancy
	CALL	WRTTIL		;monitor only)
	INC	DI		;if 2-plane, move to odd offscreen address
	CALL	WRTTIL		;and write to the 2 odd planes
	POP	DI		;restore on-screen address
	JMP	SHORT TILSEX	;no need to latch for 2-plane tile
TILST4:
	CALL	WRTTIL
	MOV	AL,ES:[DI]	;latch
TILSEX:
	MOV	AL,BMKREG	;send 0 to Bit Mask Register
	OUT	DX,AL		;index the bit mask register
	XOR	AL,AL		;disable all bits
	INC	DX		;to data port
	OUT	DX,AL		
	DEC	DX		;back to index port
	RET

;***
; B$EgaPIXCNT
;Purpose:
;	Whether or not we actually change any pixels, we have to send
;	the number "painted".
;
;Entry:
;	BP = number of whole bytes painted
;	DX = number of single pixels painted
;Exit:
;	BX = total number of pixels painted
;Uses:
;	BP, DX
;Exceptions:
;***************************************************************************
cProc	B$EgaPIXCNT,<PUBLIC,NEAR>
cBegin
	SHL	BP,1		;no. whole bytes * 2
	SHL	BP,1		;		 * 4
	SHL	BP,1		;		 * 8
SCNEX1:
	ADD	DX,BP		;pixel count
	MOV	BX,DX
cEnd

;***
; B$EgaSETCMP
;Purpose:
;	Set color compare register to current paint attribute.
;
;	This routine os called to set up the color compare register for
;	PIXLF2/PIXLF3/PIXRT2/PIXRT3.  Since these routines can take more
;	time than is allowed between CLI/STI, this routine must use an
;	EGAINT10 call to set the reg.
;Entry:
;	b$AttrC = attribute
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;*****************************************************************************
cProc	B$EgaSETCMP,<PUBLIC,NEAR>,<DX>
cBegin
	MOV	DX,GRPADD
	MOV	AL,LOW CLCREG
	OUT	DX,AL		;index the color compare register
	MOV	AL,b$AttrC	
	INC	DX		;to data port
	OUT	DX,AL
cEnd

;***
; CLRMSK
;Purpose:
;	Clear bit mask so full bytes will be written.
;Entry:
;	None
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;****************************************************************************

CLRMSK:
	MOV	AX,0FFH SHL 8 + BMKREG ;AH=FF,AL=8
	OUT	DX,AL		;index the bit mask register
	XCHG	AL,AH		
	INC	DX		;to data port
	OUT	DX,AL		
	DEC	DX		;back to index port
	RET

;***
; B$EgaCHKBTR
;Purpose:
;	Check byte right.
;	Look through byte setting up bit mask.
;	BX is used for bit masks, left and right bytes
;
;Entry:
;	AL = border bits set
;	AH = viewport edge mask if in this byte
;	CH = bit mask
;	DX = count of pixels painted so far
;Exit:
;	BH = final bit mask
;	CH = updated b$MaskC
;	DX = updated to reflect pixels painted
;Uses:
;	per conv.
;Exceptions:
;****************************************************************************
cProc	B$EgaCHKBTR,<PUBLIC,NEAR>
cBegin
	MOV	BH,CH		;initial bit mask

;if viewport edge coincides with a border pixel, don't count as painted
;	TEST	BH,AH		;is this viewport edge pixel?
;	JNZ	BYTEX1		;yes, set pixels (BH) and exit with
				; current b$MaskC
BYTLP:
	TEST	CH,AL		;check for border pixel
	JNZ	BYTEXT
	OR	BH,CH		;add pixel to set
	TEST	BH,AH		;have we just OR'd in viewport edge?
	JNZ	BYTEX1		;if so, exit with CH current and
				; BH=bit mask
	INC	DX		;count pixels painted
	ROR	CH,1		;move over one
	JNB	BYTLP		;repeat if not end of byte
	ROL	CH,1		;if off edge, rotate bit in at right
BYTEXT:

;	Final bit mask returned in BH.

	NOT	AL		;0 if border pixel(s) in AL
	AND	BH,AL		;cross out border pixel in bit mask
	RET

;	This exit only if viewport edge was encountered.

BYTEX1:
	INC	DX		;indicate one (more) pixel set
cEnd

;***
; B$EgaCHKBTL
;Purpose:
;	Check byte left.
;	Look through byte setting up bit mask.
;	BX is used for bit masks, left and right bytes
;
;Entry:
;	AL = border bits set
;	AH = viewport edge mask if in this byte
;	CH = bit mask
;	DX = count of pixels painted so far
;Exit:
;	BH = final bit mask
;	CH = value for updating b$MaskC
;	DX = updated to reflect pixels painted
;Uses:
;	per conv.
;Exceptions:
;**************************************************************************
cProc	B$EgaCHKBTL,<PUBLIC,NEAR>
cBegin
;	First check whether least significant bit is border (thinking
;	right to left).  If so, we have moved one byte too far to the
;	left for b$OffC, and want to set nothing in this byte.

	TEST	AL,CH
	JZ	BYTLF0
	INC	DI		;increment for b$OffC
	JMP	SHORT BYTLFX
BYTLF0:
	MOV	BH,CH		;initial bit mask
	TEST	BH,AH		;is this viewport edge pixel?
	JNZ	BYTLF1		;yes, set pixels (BH) and exit with
				; preexisting b$MaskC
BYTLFT:
	TEST	CH,AL		;check for border pixel
	JNZ	BYTLFX
	OR	BH,CH		;add pixel to set
	TEST	BH,AH		;test for viewport edge bit encountered
	JNZ	BYTLF1		;if found, exit with CH at that bit
	INC	DX		;count pixels painted
	ROL	CH,1		;move over one
	JNB	BYTLFT		;repeat if not end of byte
BYTLFX:
	ROR	CH,1		;else set up as rightmost pixel
	NOT	AL
	AND	BH,AL		; final bit mask returned in BH
	RET
BYTLF1: 			;this exit only if viewport edge bit encountered
	INC	DX		;count one (more) pixel painted
cEnd

;***
; PIXRT2
;Purpose:
;	Check for non-paint pixels right for 4 plane EGA modes.
;	Look through entire range of non-border pixels left to right
;	to determine whether any will actually change color.
;	AL is used for Color Don't Care mask
;
;Entry:
;	SI = byte address of leftmost byte in range
;	BL = bit mask for leftmost byte
;	BH = bit mask for rightmost byte
;	DI = total number of whole bytes -1
;	ES = video segment
;Exit:
;	CL = 0 if no pixels found to change, non-zero if pixels to change
;Uses:
;	per conv.
;Exceptions:
;****
cProc	PIXRT2,<NEAR>
cBegin
	XOR	CL,CL		;maybe no bits change

;	read first byte

	MOV	AL,ES:[SI]	;bit pattern of first byte with 0's where
				;color not paint attribute
	AND	AL,BL		;AND now produces difference if non-paint
				;bit in significant position
	XOR	AL,BL		;for significant bits in our first byte (bit
				;set in BH), then non-paint will be one
	JNZ	BITFDR		;found a bit to change
	OR	DI,DI		;any more bytes?
	JZ	PIXLAST 	;Brif not, test the last byte

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

LKPNTR:
	INC	SI
	MOV	AL,ES:[SI]
	NOT	AL		;check if all bits set (all paint color)
	OR	AL,AL		;NOT does not affect flags
	JNZ	BITFDR
	DEC	DI
	JNZ	LKPNTR		;keep looking until search of complete
				;bytes is exhausted
;	On last byte now, mask in BH.

PIXLAST:			
	INC	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	NOBITR
BITFDR:
	MOV	CL,AL		;set change bits flag to non-zero
NOBITR:
cEnd

;***
; B$EgaTILRGT
;Purpose:
;	Check for non-paint pixels right 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 leftmost partial byte
;	BH    = bit mask for rightmost 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$EgaTILRGT,<PUBLIC,NEAR>,<DX,BP>
cBegin
	PUSH	b$OffC
	PUSH	b$PenC
	PUSH	BX		;copy for BH check
	MOV	ByteCount,DI	;whole byte counter
	MOV	AL,BL		;copy bit mask from BL
	OR	AL,AL		;make sure at least 1 bit is set
	JZ	TILRT5
	CALL	LOWCHK		;check first partial byte (uses mask in AL)
	JNZ	TILRT1		;if no carry, non-match was found
TILRT5:
	CMP	ByteCount,0	;see whether whole bytes to check
	JZ	TILRT4
TILRT2:
	INC	SI
	MOV	b$OffC,SI
	MOV	b$MaskC,80H
	XOR	BP,BP		;offset to color array
TILRT3:
	CALL	[b$ReadC]
	CMP	AL,ColorBits[BP] ;check for non-match
	JNZ	TILRT1
	INC	BP
	SHR	b$MaskC,1	;move to next bit
	JNB	TILRT3
	DEC	ByteCount
	JNZ	TILRT2		;keep looking until all whole bytes done
TILRT4:
	POP	BX		;get bit mask in BH
	OR	BH,BH
	PUSH	BX
	JZ	TILRT6		;BH=0 indicates no "last byte"
	MOV	AL,BH		;get last partial byte
	INC	SI
	CALL	HICHK
	JNZ	TILRT1		;exit if non-match found
TILRT6:
	MOV	CL,-1
TILRT1:
	INC	CL		;non-zero if pixels changed
	POP	BX
	POP	b$PenC
	POP	b$OffC
cEnd

;***
; PIXLF2
;Purpose:
;	Check for non-paint pixels left for 4 plane EGA modes.
;	Look through entire range of non-border pixels right to left
;	to determine whether any will actually change color.
;	BH/BL = bit masks for leftmost and rightmost bytes, respectively
;	DI = total whole bytes between first and last
;
;Entry:
;	SI = byte address of rightmost byte in range
;	BL = bit mask for rightmost byte
;	BH = bit mask for leftmost byte
;	DI = total number of whole bytes
;	ES = video segment
;Exit:
;	CL = 0 if no pixels found to change, non-zero if pixels to change
;Uses:
;	per conv.
;Exceptions:
;****
cProc	PIXLF2,<NEAR>
cBegin
	XOR	CL,CL		;maybe no bits change

;	read first byte

	MOV	AL,ES:[SI]	;bit pattern of first byte with 0's where
				;color not paint attribute
	AND	AL,BL		;AND now produces difference if non-paint
				;bit in significant position
	XOR	AL,BL		;for significant bits in our first byte (bit
				;set in BH), then non-paint will be one
	JNZ	BITFDL		;found a bit to change
	OR	BH,BH		;see if only one byte
	JZ	NOBITL		;nothing to paint
	OR	DI,DI		;see if only a "last byte"

⌨️ 快捷键说明

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