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

📄 llega.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	cmp	bl,2		;attributes 0 and 1 map directly
	jb	PalTrNxt	;go if so
	add	bl,2		;attribute 2 maps to 4, 3 to 5
PalTrNxt:
	push	di
	MOV	DI,GR_TEXTOFFSET TransF ;translate to color pair
	XOR	AH,AH
	SHL	AL,1		;word index
	ADD	DI,AX
	MOV	AX,CS:[DI]	;translate color AX to color pair AX
	pop	di
	clc			;no error
cEnd

;***
; PalTrans_10_64K
;
;Purpose:
;	Translate a user supplied attribute for Screen 9/64K to the
;	corresponding hardware value after verifying that the attribute
;	value and the color value are in the legal ranges.
;	    Attribute mapping:	0 --> 0
;				1 --> 1
;				2 --> 4
;				3 --> 5
;Entry:
;	DX:AX = user supplied color value
;	BL    = user supplied attribute value
;Exit:
;	PSW.C set if illegal value, reset if Ok
;	DX:AX = unchanged (user supplied color value)
;	BL    = actual attribute value
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
DbPub	PalTrans_10_64K
cProc	PalTrans_10_64K,<NEAR>
cBegin
	call	B$EgaPalTrans	;check attribute and translate color
	jc	PalTrErr	;error return
	cmp	bl,2		;attributes 0 and 1 map directly
	jb	PalTrExit	;go if so
	add	bl,2		;attribute 2 maps to 4, 3 to 5
PalTrExit:
	clc			;no error
	ret
PalTrErr:
	STC			;indicate error
cEnd

labelB	AttrX
	DB	0,3,0CH,0FH	;map to 0,3,C,F for odd/even

;***
; SetAttr_F_10_64K
;
;Purpose:
;	Map attribute value to the value needed by odd/even mode functions.
;		0 --> 00
;		1 --> 03
;		2 --> 0C
;		3 --> 0F
;	If supplied attribute is outside legal range, use maximum legal value.
;Entry:
;	AL = attribute
;Exit:
;	b$Attr updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
DbPub	SetAttr_F_10_64K
cProc	SetAttr_F_10_64K,<NEAR>,<AX,BX>
cBegin
	cmp	al,b$MaxAttr	;test against maximum attribute
	jbe	SetAttrXOk	;Brif legal
	mov	al,b$MaxAttr	;limit to max
SetAttrXOk:
	mov	bx,GR_TEXTOFFSET AttrX	;translate for odd/even mode
	xlat	cs:[bx]
	mov	b$AttrC,al
	clc			;exit no error
cEnd

;***
; SetColor
;
;Purpose:
;	Process the color statement for Bios modes 0Dh - 010h (BASIC Screen
;	modes 7-10).  Syntax for Screen 7-10 color statement is as follows:
;
;		COLOR	[foreground],[background]
;
;	where "foreground" is the attribute to be used for the foreground
;	  and "background" is the color to be used for the background
;
;	Any omitted parameter(s) indicate no change for that parameter.
;Entry:
;	parameter list
;		WORD 1 = flag 0 if param not present
;		WORD 2 = parameter if WORD 1 <> 0, else second param flag
;		etc.
;Exit:
;	PSW.C set if error, reset if Ok.
;	b$ForeColor is set to foreground attribute
;	b$ForeMapped is set to foreground attribute mapped to internal value
;
;Uses
;	per conv.
;Exceptions:
;*****************************************************************************
cProc	SetColor,<NEAR>
cBegin
	cCall	B$GetParm	;AL=foreground parameter
	mov	bh,b$ForeColor ;use old values as default
	mov	bl,b$ForeMapped
	jz	GotFore 	;go if none supplied
	cmp	b$MaxAttr,al	;check for valid range
	jc	SetColDun	;go if error
	push	ax		;save: unmapped attr [14]
	push	cx		;      param count
	push	b$PenC 	;  b$AttrC
	call	[b$SetAttr]	;translate the attribute
	mov	bl,b$AttrC	;translated attr in BL
	pop	b$PenC 	
	pop	cx
	pop	ax		;restore unmapped attr
	mov	bh,al		;unmapped attr to BH
GotFore:
	cCall	B$GetParm	;AL=background parameter
	jz	NoBack		;go if none supplied
	push	bx		;preserve foreground info
	xor	bx,bx		;attribute 0 is background
	cbw			;AX=color
	cwd			;DX:AX=color
	call	[b$PalPut]	;set background
	pop	bx
	jc	SetColDun	;go if error
NoBack:
	mov	b$ForeColor,bh ;save foreground values
	mov	b$ForeMapped,bl
	clc			;indicate no error
	jcxz	SetColDun	;if we got all params, thats true
	stc			;otherwise set error
SetColDun:
cEnd

;***
; PIXLF3
;Purpose:
;	Check for non-paint pixels left, odd/even EGA modes.
;	Look through entire range of non-border pixels right to left
;	to determine whether any will actually change color.
;	Use AL as Color Don't Care mask.
;
;	If using EGAINT10 interface, this routine must access the CDCReg
;	and perform the associated color compare read with ints disabled,
;	then reenable them to allow other processes to access the card
;	before the next byte is checked.  Since another process may have
;	modified the graphics chip index reg as well as the data reg, we
;	must send both index and data for each odd/even toggle.
;Entry:
;	SI = byte address of rightmost byte in range
;	BH = bit mask for leftmost byte
;	BL = bit mask for rightmost byte
;	DI = total number of whole bytes between first and last
;	ES = video segment
;Exit:
;	CL = 0 if no pixels found to change, non-zero if pixels to change
;Uses:
;	per conv.
;Exceptions:
;****
DbPub	PIXLF3
cProc	PIXLF3,<NEAR>,<DX>
cBegin
	MOV	DX,GRPADD	;index port for graphics register
	MOV	AL,LOW CDCREG	;specify Color Don't Care
	EGAINT10CLI		;disable ints if using EGAINT10
	OUT	DX,AL
	INC	DX
	MOV	AL,10101010B	;initially assume odd byte address
	TEST	SI,1
	JNZ	STMSKL		;if correct, set this mask
	ROR	AL,1		;else rotate for other pair of planes
STMSKL:
	OUT	DX,AL		;set up for initial color compare

;	read first byte

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

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

LKPTL3:
	DEC	SI
	ROR	AL,1
	OUT	DX,AL		;set up opposite Don't Care planes each time
	MOV	CL,ES:[SI]
	EGAINT10STI		;read is done, reenable ints if EGAINT10
	NOT	CL		;check if all bits set (all paint color)
	OR	CL,CL		;NOT does not affect flags
	JNZ	SETBTL
	DEC	DI
	EGAINT10CLI		;disable ints for next OUTs (loop
				;	or fall through)
	JNZ	LKPTL3		;keep looking until search of complete
				;bytes is exhausted

;	On last byte now, mask in BH.

LSBYT3:
	DEC	SI
	ROR	AL,1
	OUT	DX,AL		;last Don't Care
	MOV	CL,ES:[SI]	;do last compare
	AND	CL,BH		;significant bit = 0 if not paint color
	XOR	CL,BH		;if different, non-paint pixel(s) present
	JNZ	SETBTL
NOSETL:
	XOR	CL,CL		;no bits to set, so zero pixels-changed flag
SETBTL:
	EGAINT10STI		;reenable ints at common exit
cEnd

;***
; PIXRT3
;Purpose:
;	Check for non-paint pixels right with odd/even 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
;
;	If using EGAINT10 interface, this routine must access the CDCReg
;	and perform the associated color compare read with ints disabled,
;	then reenable them to allow other processes to access the card
;	before the next byte is checked.  Since another process may have
;	modified the graphics chip index reg as well as the data reg, we
;	must send both index and data for each odd/even toggle.
;Entry:
;	SI = byte address of leftmost byte in range
;	BH = bit mask for rightmost byte
;	BL = bit mask for leftmost 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:
;****
DbPub	PIXRT3
cProc	PIXRT3,<NEAR>,<DX>
cBegin
	MOV	DX,GRPADD	;index port for graphics
	MOV	AL,LOW CDCREG	;set up for Color Don't Care register
	EGAINT10CLI		;disable ints if using EGAINT10
	OUT	DX,AL
	INC	DX
	MOV	AL,10101010B	;initially assume odd byte mask
	TEST	SI,1		;check whether first byte odd or even
	JNZ	SETMSK		;if odd, branch to set mask
	ROR	AL,1		;else rotate mask 1 right
SETMSK:
	OUT	DX,AL

;	read first byte

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


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

LKPTR3:
	INC	SI
	ROR	AL,1		;shift Don't Care mask
	OUT	DX,AL
	MOV	CL,ES:[SI]
	EGAINT10STI		;read is done, reenable ints if EGAINT10
	NOT	CL		;check if all bits set (all paint color)
	OR	CL,CL		;NOT does not affect flags
	JNZ	PNTBIT
	DEC	DI
	EGAINT10CLI		;disable ints for next OUTs (loop
				;	or fall through)
	JNZ	LKPTR3		;keep looking until search of complete
				;bytes is exhausted

;	On last byte now, mask in BH.
PIXLAST:			
	INC	SI
	ROR	AL,1
	OUT	DX,AL
	MOV	CL,ES:[SI]	;do last compare
	AND	CL,BH		;significant bit = 0 if not paint color
	XOR	CL,BH		;if different, non-paint color pixels
	JNZ	PNTBIT		;leave CL non-zero as flag
NOBTR3:
	XOR	CL,CL		;else zero the flag
PNTBIT:
	EGAINT10STI		;reenable ints at common exit
cEnd

;***
; ScanLX
;Purpose:
;	Scan left beginning with the pixel to the left of cursor,
;	and paint pixels until:
;		(1) the viewport edge is encounteered (edge painted)
;		(2) a border pixel is encountered (border not painted)
;
;	This version supports PAINT for the odd/even EGA modes (bios mode
;	10H with 64K of memory, and monochrome bios mode F).  It differs
;	from SCANL2 in its use of the Color Don't Care register in
;	conjunction with screen reads.	This is necessary because if the
;	planes representing the even bytes and those representing the odd
;	bytes are not disabled during color compares for odd and even bytes,
;	respectively, the color compare is made as the sum of the bits set
;	for each even byte and its odd successor, all four planes at one
;	address.
;Entry:
;	b$AddrC, b$MaskC = pixel to right of starting pixel
;	b$PaintBorder	   = attribute of paint region border
;	b$AttrC	   = attribute to paint
;	B$LEOFST, B$VLMASK   = left viewport edge
;Exit:
;	BX		   = number of pixels scanned
;	CL		   = 0 iff no pixels changed color
;	b$OffC, b$MaskC  = the last non-border pixel examined/painted
;Uses:
;	per conv.
;Exceptions:
;*****************************************************************************
DbPub	ScanLX
cProc	ScanLX,<NEAR>,<ES>
cBegin
	CALL	B$EgaScanInit
	ROL	CH,1		;see if cursor is left edge of byte
	JNB	VWBYT1		;if not, proceed to viewport checks
	DEC	SI		;if so, start next byte left
	JS	SCNOUT		;if negative, hit corner of screen
VWBYT1:				;start on-screen viewport checks
	CMP	SI,B$LEOFST	;see if off edge of viewport to left
	JNB	VWBYT2
SCNOUT:
	JMP	BRDEX3		;else do nothing, exit
VWBYT2:
	JNZ	NOTBYT		;if not edge byte, skip bit checks
	CMP	CH,B$VLMASK	;else check for pixel left too far and
	JNA	NOTBYT
	JMP	BRDEX3		;thus off viewport edge -- exit if so
NOTBYT:
	MOV	DI,SI		;extra copy of first byte address
	MOV	BL,CH		;extra copy of initial bit mask
	MOV	BP,-1		;this will be count of whole bytes
	XOR	AH,AH		;initialize this byte's viewport mask to 0

;	First task is to set up initial Color Don't Care mask depending
;	on whether first byte is odd or even.

	MOV	CL,10101010B	;initially assume odd byte -- 10101010
	TEST	SI,1
	JNZ	STCDC3
	ROR	CL,1		;if even, set up 01010101
STCDC3:
	MOV	DX,GRPADD
	MOV	AL,LOW CDCREG	;index to Color Don't Care register

	OUT	DX,AL
	INC	DX
	MOV	AL,CL
	OUT	DX,AL

;	read first byte off the screen

	MOV	AL,ES:[DI]
	EGAINT10STI		;read is done, reenable ints if EGAINT10
	TEST	AL,CH		;see whether initial pixel is border
	JZ	SRCLF3		;if not, start search left
	XOR	CL,CL		;else set pixels-changed flag back to 0
	MOV	BL,CL		;zero out 8-bit register used
	JMP	BRDEX3		;and exit gracefully
SRCLF3:

;	look for border or viewport in first byte

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

;	while not border

	TEST	AL,CH
	JNZ	HAVPX3

;	and not viewport edge

	TEST	AH,CH
	JNZ	HAVPX3

;	and not off the edge of the byte

	ROL	CH,1
	JNB	NTVWL3

;	keep moving left - edge of first byte

	DEC	DI		;next byte address left
	INC	BP		;count of intermediate bytes
	ROR	CL,1		;rotate Color Don't Care mask
	MOV	AL,CL
	OUT	DX,AL
	MOV	AL,ES:[DI]	;read next byte left
	EGAINT10STI		;reenable ints between bytes if EGAINT10
	JMP	SHORT SRCLF3	;check next byte

;	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)
;	BL = 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.

HAVPX3:
	CMP	SI,B$LEOFST	;see if rightmost byte is LEFT viewport
	JZ	SINTV2		;if so, don't clear viewport mask
				; register
	XOR	AH,AH		;else clear AH for CHKBTL on
SINTV2:				; rightmost byte
	MOV	CH,BL		;initial bit position in CH
	MOV	CL,10101010B	;need to reset Color Don't Care mask
	TEST	SI,1		;see if odd byte
	JNZ	SISET
	ROR	CL,1
SISET:
	MOV	AL,CL
	OUT	DX,AL		;set up Color Don't Care
	MOV	AL,ES:[SI]	;get border bits if any
	XOR	DX,DX		;this will be #pixels painted
	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	ONEALN		;"one alone"
	DEC	BP		;if not, recover real value
	PUSH	DX		;store pixel count
	MOV	DX,GRPADD+1	;data port for Color Don't Care
	MOV	CL,10101010B	;assume mask 10101010
	TEST	DI,1		;check DI for odd or even address
	JNZ	DISET
	ROR	CL,1		;if even, set up 01010101
DISET:
	MOV	AL,CL
	OUT	DX,AL
	POP	DX		;restore pixel count
	MOV	AL,ES:[DI]	;get border bits if any
	MOV	CH,1		;set up mask for final byte
	CMP	DI,B$LEOFST	;was this viewport byte?
	JNZ	DINTV2		;no -- don't need viewport mask
	MOV	AH,B$VLMASK	;yes -- get viewport mask for CHKTBL
DINTV2:
	CALL	B$EgaCHKBTL	;set up leftmost byte bit mask in BH
ONEALN:
	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 PIXLFT
	CMP	b$Tiling,0	;see if tiling is on

⌨️ 快捷键说明

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