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

📄 llcgasup.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;				(whether or not they changed color)
;	CL		   = 0 iff no pixels changed color
;	DX		   = remaining border pixel count
;	b$OffC, b$MaskC  = the last non-border pixel examined/painted
;	SI, AL		   = the first non-border pixel encountered
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$CgaScanR,<PUBLIC,NEAR>,<DI,BP,ES>
cBegin
	mov	bp,dx		;save skip count in [bp]
	call	ScanInit	;init regs for scanning
scnr0:
	mov	al,bl		;screen byte in [al]
	xor	al,dl		;xor it with border
scnr1:
	test	al,ch		;border pixel or not ?
	jnz	begin_paint
	dec	bp		;decrement border count
	jz	scnrxt01	;brif border count zero
	ror	ch,cl		;move right by one pixel
	jnb	scnr1
	inc	di		;move right by one byte
	mov	bl,es:[di]	;screen byte in [bl]
	cmp	di,B$REOFST	;cursor offset same as right edge offset
	jnz	scnr0		;brif so....one more byte to go
	cmp	ch,B$VRMASK	;compare bit addresses
	jae	scnr0		;brif within screen limits
	xor	bp,bp		;pretend to run out of skip count
scnrxt01:
	jmp	scnrxt0

;	We begin painting here. Again the paint loop is in three
;	parts: prolog, main body, and epilog.

begin_paint:
	mov	SaveCa,di	;saving SaveCa and
	mov	SaveCm,ch	;  SaveCm
	mov	b$OffC,di	;set the cursor offset
	mov	b$MaskC,ch	;set the cursor mask
	push	bp		;save border count
	xor	bp,bp		;clear paint count
	test	ch,80h		;cursor byte aligned ?
	JNZ	SRMIDDLE0	;go if so

; PROLOG

begpaint1:
	call	Helper		;calls helper1 increments
				;paint count and sets painted flag
	jz	scnxtn1 	;brif border found
	cmp	di,B$REOFST	; cursor offset = right edge offset?
	jne	begpaint2	; brif not
	cmp	ch,B$VRMASK	; compare bit addresses
	je	scnxtn1		; brif edge of viewport
	ja	begpaint2	; loop if not edge yet
	xor	bp,bp		; special case:  nothing to paint
	jmp	short scnxtn1	
begpaint2:			
	ror	ch,cl		;move right by one pixel
	JNC	BEGPAINT1	;go if not byte aligned

; MAIN BODY

	INC	DI		;to next byte
SRMIDDLE0:
	cmp	b$BitsPerPixel,2
	je	SRMIDDLE2

srmiddle:
	mov	bl,es:[di]	;[bl] = screen byte
	cmp	B$REOFST,di	;are we at the right edge ?
	JBE	SCNRXTCHK	;brif so or beyond
	MOV	AL,BL		;copy screen byte
	NOT	AL		;bitwise equivalence with border color
	XOR	AL,DL		;  a bit in a pixel will be 1 if pixel
				;  is border color
	JNZ	BEGPAINT1	;go if border color found in the byte
	XOR	BL,DH		;detect any differences from paint color
	OR	SI,BX		;combine with the already painted flag
				;only LOByte is significant
	ADD	BP,8		;increment paint count
	INC	DI		;move right by one byte
	JMP	SHORT srmiddle	;go do the rest

SRMIDDLE2:
	MOV	AH,55H
SRMIDDLE3:
	MOV	BL,ES:[DI]	;get screen byte
	CMP	B$REOFST,di	;at the right edge or beyond?
	JBE	SCNRXTCHK	;go if so
	MOV	AL,BL		;copy screen byte
	NOT	AL		;bitwise equivalence with border color
	XOR	AL,DL		;  both bits in a pixel will be 1 if pixel
	MOV	BH,AL		;  is border color
	SHR	BH,1		;shift left bit in copy on to right bit
	AND	BH,AH		;mask off the trash
	AND	BH,AL		;see if both bits set in any pixel
	JNZ	BEGPAINT1	;go if border color found in the byte
	XOR	BL,DH		;detect any differences from paint color
	OR	SI,BX		;combine with the already painted flag
				;only LOByte is significant
	ADD	BP,4		;increment paint count
	INC	DI		;to next byte
	JMP	SHORT SRMIDDLE3 ;loop until border color or edge found

; EPILOG

SCNRXTCHK:
	jz	scnrxt3
	mov	cl,b$BitsPerPixel  ;[cl] = screen bits/pixel
	rol	ch,cl		;back up
	inc	di		;move right a byte
scnxtn1:
	JMP	SHORT scnrxt2	;start painting

scnrxt3:
	mov	ch,b$MaskLeft	;set the leftmost bit/bits
scnrxt31:
	call	Helper		;calls helper1 increments
				;paint count and sets painted flag
	jz	scnrxt2 	;brif border
	ror	ch,cl		;move right by one pixel
	jb	scnrxt1 	;special case ??????
	CMP	DI,B$REOFST	;test if on right viewport byte
	JNE	SCNRXT31	;if not, then continue on
	cmp	ch,B$VRMASK	;compare bit addresses
	jb	scnrxt1 	;brif edge encountered
	JMP	SHORT scnrxt31

scnrxt1:
	rol	ch,cl		;back up

scnrxt2:
	push	cx
	mov	bx,bp		;paint count
	or	bx,bx		;paint count = 0 ?
	jz	no_nset 	;branch around NSetC
	call	B$CgaNSetC
no_nset:
	mov	bx,bp		;return paint count
	pop	cx
	mov	b$OffC,di	;return cursor offset
	mov	b$MaskC,ch	;return cursor mask
	pop	dx		;return skip count
	mov	cx,si		;return already-painted -flag
	JMP	SHORT scnrxt

scnrxt0:
	mov	bx,bp		;paint count = 0
	mov	dx,bp		;skip count  = 0
	mov	cl,bl		;already-painted-flag = 0
	mov	b$OffC,di	;return cursor offset
	mov	b$MaskC,ch	;return cursor mask
scnrxt:
	mov	si,SaveCa	;returning SaveCm and
	mov	al,SaveCm	;  SaveCm
cEnd

;***
; LineSetup
;
;Purpose:
;	This routine is called at the beginning of LineX, LineY, and LineV.
;	It handles the buffer half splitting of the CGA and quadrant row
;	splitting of the HGC.
;	(See discussion of the architecture in the LLCGA and LLHGC headers).
;Entry:
;	DX	 = negative for up, otherwise down
;Exit:
;	DX	 = up/down move assumption
;Uses:
;	none.
;Exceptions:
;******************************************************************************
cProc	LineSetup,<NEAR>
cBegin
	OR	DX,DX		;Y difference negative? (up)
	MOV	DX,b$UpSub	;assume so, use UP subtractor
	JS	LineSetupExit	;go if correct assumption
	MOV	DX,b$DnSub	;no, use DOWN subtractor
LineSetupExit:			
cEnd

;***
; B$CgaLineX
;
;Purpose:
;	Draw an X-major line for CGA modes.
;Entry:
;	AH    = color (b$AttrC)
;	AL    = bit accumulator
;	BX    = point count
;	CH    = bit mask
;	CL    = trash for twiddle and pixel shift count
;	DX    = BP change for Y movement (UpSub or DnSub)
;	SI    = delta decision value
;	DI    = line style
;	BP    = video offset
;	ES    = video segment
;	Incr1 = major axis delta update value
;	Incr2 = minor axis delta update value
;	UpDnAdd = corrector for DX subtraction
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$CgaLineX,<PUBLIC,NEAR>
cBegin
	CALL	LineSetup	

	XCHG	BX,CX		;point count to BX
	MOV	CL,b$BitsPerPixel

LineCXloop:

	ROL	DI,1		;next line style bit
	JNC	LineCX2 	;go if bit is 0 not to plot

	OR	AL,CH		;OR this bit into byte mask
LineCX2:
	OR	SI,SI		;time to move in Y (+ or 0 delta)?
	JNS	LineCX4 	;go if so
	ADD	SI,b$Incr1	;update delta for X movement
	ROR	CH,CL		;move to next X
	JC	LineCX3 	;go if not still in same byte
	DEC	BX
	JNZ	LineCXloop	;go for more
	JMP	SHORT LineCX7	;  or exit
LineCX3:
	MOV	CL,AH		;get color, dump accumulated pixels
	XOR	CL,ES:[BP]	;change masked bits of video byte
	AND	CL,AL		;  to color in attribute byte
	XOR	ES:[BP],CL	;(twiddle)
	XOR	AL,AL		;clear pixel accumulator
	MOV	CL,b$BitsPerPixel  ;reload bits per pixel
	INC	BP		;go to next byte
	DEC	BX
	JNZ	LineCXloop	;go for more
	JMP	SHORT LineCX7	;  or exit
LineCX4:
	ADD	SI,b$Incr2	;update delta for Y movement
	MOV	CL,AH		;get color, dump accumulated pixels
	XOR	CL,ES:[BP]	;change masked bits of video byte
	AND	CL,AL		;  to color in attribute byte
	XOR	ES:[BP],CL	;(twiddle)
	XOR	AL,AL		;clear pixel accumulator
	MOV	CL,b$BitsPerPixel  ;reload bits per pixel
	ROR	CH,CL		;move to next X
	ADC	BP,0		;(+1 if next X byte)
	sub	BP,DX		;make the assumed Y movement
	jnb	LineCX5 	;go if no problem
	add	BP,b$UpDnAdd	;undo SUB + perform correct movement
LineCX5:
	DEC	BX
	JNZ	LineCXloop	;go for more
LineCX7:			;flush accumulated pixels
	XOR	AH,ES:[BP]	;change masked bits of video byte
	AND	AH,AL		;  to color in attribute byte
	XOR	ES:[BP],AH	;(twiddle)
cEnd

;***
; B$CgaLineY
;
;Purpose:
;	Draw a Y-major line for CGA modes.
;Entry:
;	AH    = color (b$AttrC)
;	AL    = bit mask
;	BX    = point count
;	CH    = trash for twiddle
;	CL    = pixel shift count
;	DX    = BP change for Y movement (UpSub or DnSub)
;	SI    = delta decision value
;	DI    = line style
;	BP    = video offset
;	ES    = video segment
;	Incr1 = major axis delta update value
;	Incr2 = minor axis delta update value
;	UpDnAdd = corrector for DX subtraction
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$CgaLineY,<PUBLIC,NEAR>
cBegin
	call	LineSetup	

	XCHG	BX,CX		;point count to BX
	MOV	CL,b$BitsPerPixel

LineCYloop:

	ROL	DI,1		;next line style bit
	JNC	LineCY2 	;go if bit is 0 not to plot

	MOV	CH,AH		;get color, dump accumulated pixels
	XOR	CH,ES:[BP]	;change masked bits of video byte
	AND	CH,AL		;  to color in attribute byte
	XOR	ES:[BP],CH	;(twiddle)
LineCY2:
	OR	SI,SI		;time to move in X (+ or 0 delta)?
	JNS	LineCY3 	;go if so
	ADD	SI,b$Incr1	;update delta for Y movement
	sub	BP,DX		;make the assumed Y movement
	jnb	LineCY2A	;go if no problem
	add	BP,b$UpDnAdd	;undo SUB + perform correct movement
LineCY2A:
	DEC	BX
	JNZ	LineCYloop
	ret
LineCY3:
	ADD	SI,b$Incr2	;update delta for X movement
	ROR	AL,CL		;move to next X
	ADC	BP,0		;(+1 if next X byte)
	sub	BP,DX		;make the assumed Y movement
	jnb	LineCY5 	;go if no problem
	add	BP,b$UpDnAdd	;undo SUB + perform correct movement
LineCY5:
	DEC	BX
	JNZ	LineCYloop	;go for more
cEnd

;***
; B$CgaLineV
;
;Purpose:
;	Draw a vertical line for CGA modes.
;Entry:
;	AH = color (b$AttrC)
;	AL = bit mask
;	BH = trash for twiddle
;	BL = unused
;	CX = point count
;	DX = BP change for Y movement (UpSub or DnSub)
;	SI = UpDnAdd = corrector for DX subtraction
;	DI = line style
;	BP = video offset
;	ES = video segment
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$CgaLineV,<PUBLIC,NEAR>
cBegin
	call	LineSetup	

	MOV	SI,b$UpDnAdd	;to register here

LineCVloop:

	ROL	DI,1		;next line style bit
	JNC	LineCV2 	;go if bit is 0 not to plot

	MOV	BH,AH		;get color, dump accumulated pixels
	XOR	BH,ES:[BP]	;change masked bits of video byte
	AND	BH,AL		;  to color in attribute byte
	XOR	ES:[BP],BH	;(twiddle)
LineCV2:
	sub	BP,DX		;make the assumed Y movement
	jnb	LineCV5 	;go if no problem
	add	BP,SI		;undo SUB + perform correct movement
LineCV5:			
	LOOP	LineCVloop	;go for more
cEnd

sEnd	GR_TEXT

	END

⌨️ 快捷键说明

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