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

📄 llegasup.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	TITLE	LLEGASUP - LowLevel EGA support (shared routines)
;***
; LLEGASUP - LowLevel EGA support
;
;	Copyright <C> 1987, Microsoft Corporation
;
;Purpose:
;	This module contains support routines extracted from LLEGA.ASM
;	which are shared by EGA and VGA functions.
;
;******************************************************************************

	INCLUDE switch.inc	;feature switches
	INCLUDE rmacros.inc

	USESEG	_BSS
	USESEG	GR_TEXT

	INCLUDE seg.inc
	INCLUDE ibmunv.inc
	INCLUDE baslibma.inc
	INCLUDE llgrp.inc

sBegin	_BSS
;
;
; ***************************************************************************
; External variables
; ***************************************************************************
;
externB b$EgaPalSup
externD b$InitPalette
externB b$MaxColor
externB b$Monitor
externW B$LEOFST
externW B$REOFST
externW B$VTOFST
externW B$VBOFST
externW B$VLOFST
externW B$VROFST
externB B$VLMASK
externB B$VRMASK
externD b$AddrC
externB b$AttrC
externW b$BytesPerRow
externB b$DivShift
externB b$EgaWrMd
externW b$Incr1
externW b$Incr2
externW b$IncrY
externB b$MaskC
externB b$MaxAttr
externW b$ModMask
externW b$OffC
externB b$PaintBorder
externW b$PenC
externB b$Planes
externW b$SegC
externB b$Tiling
externW b$SaveCa
externB b$SaveCm
externB b$PlaneMask
;
; ***************************************************************************
; External function vectors
; ***************************************************************************
;
externW b$PutVector
externW b$ReadC
externW b$PalTrans
externW b$PalPut
;
; ***************************************************************************
; Local variables
; ***************************************************************************
staticB AttrTile,,4		;tile attribute pattern table
staticB ColorBits,,8		;table of rotated tiling patterns
staticW ByteCount,,1
staticB EgaPalette,,17
;

sEnd	_BSS

assumes CS,GR_TEXT

sBegin	GR_TEXT

externNP B$BumpDS
externNP B$BumpES		
externNP B$DecDS		
externNP B$OutWord
externNP B$ResetEGA

;***
; B$EgaMapXYC_D
;
;Purpose:
;	Map given X and Y coordinates to the graphics cursor for Screen 7.
;Entry:
;	CX = X coordinate
;	DX = Y coordinate
;Exit:
;	b$OffC, b$MaskC updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaMapXYC_D,<PUBLIC,NEAR>
cBegin
	mov	bx,dx		;multiply y by 40 to compute row displacement
	shl	dx,1		;dx=2*Y
	shl	dx,1		;dx=4*Y
	add	dx,bx		;dx=5*Y
	jmp	short MapCommon
cEnd	<nogen>

;***
; B$EgaMapXYC
;
;Purpose:
;	Map given X and Y coordinates to the graphics cursor for EGA modes
;Entry:
;	CX = X coordinate
;	DX = Y coordinate
;Exit:
;	b$OffC, b$MaskC updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaMapXYC,<PUBLIC,NEAR>
cBegin
	mov	bx,dx		;multiply y by 80 to compute row displacement
	shl	dx,1		;dx=2*Y
	shl	dx,1		;dx=4*Y
	add	dx,bx		;dx=5*Y
	shl	dx,1		;dx=10*Y
MapCommon:
	shl	dx,1		;dx=20*Y
	shl	dx,1		;dx=40*Y
	shl	dx,1		;dx=80*Y   (40*Y for mode 0DH)
	mov	ax,cx		;save x
	shr	ax,1		;div by PixelsPerByte (8)
	shr	ax,1		;  to get byte index
	shr	ax,1
	add	dx,ax		;add x byte offset to y row address
	mov	b$OffC,dx	;save byte offset
	and	cl,7		;mask in x bit addr
	mov	ch,10000000B	;leftmost pixel on in shift mask
	shr	ch,cl		;move over to get mask
	mov	b$MaskC,ch	;store cursor mask
cEnd

;***
; B$EgaLeftC/B$EgaLeftC_13
;
;Purpose:
;	Move graphics cursor left 1 pixel for EGA modes or Screen 13,
;	depending on entry point.  No test is made for screen boundaries.
;Entry:
;	None
;Exit:
;	b$MaskC, b$OffC updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaLeftC,<PUBLIC,NEAR>
cBegin
	rol	b$MaskC,1
	jc	LeftCnext	;go if not in same byte
	ret
labelNP <PUBLIC,B$EgaLeftC_13>
LeftCnext:
	dec	b$OffC 	;move byte pointer
cEnd

;***
; B$EgaChkUpC
;
;Purpose:
;	Move graphics cursor up 1 pixel for EGA modes.	A test is made for
;	boundaries.  If it is a boundary then PSW.C is set upon return and
;	no move is made.
;
;Entry:
;	None
;Exit:
;	b$MaskC, b$OffC updated
;	PSW.C = set if original graphics cursor was on screen top edge.
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaChkUpC,<PUBLIC,NEAR>
cBegin
	MOV	AX,b$OffC	;[AX] = cursor offset
	CMP	AX,B$VTOFST	;already on top of viewport ?
	JAE	B$EgaUpC	;less than VTOFST means on top of
				;viewport
	STC			;STC to indicate that cursor already
cEnd				;on top of viewport

;***
; B$EgaUpC
;
;Purpose:
;	Move graphics cursor up 1 pixel for EGA modes.	No test is made for
;	screen boundaries.
;Entry:
;	None
;Exit:
;	b$MaskC, b$OffC updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaUpC,<PUBLIC,NEAR>
cBegin
	mov	ax,b$BytesPerRow 
	sub	b$OffC,ax	;up one row
	clc			;(no error for ChkUpC)
cEnd

;***
; B$EgaChkDownC
;
;Purpose:
;	Move graphics cursor down 1 pixel for EGA modes.  If beyond the
;	bottom edge, PSW.C is set upon return and no move is made.
;Entry:
;	None
;Exit:
;	PSW.C = set if original cursor was on screen edge.
;	b$MaskC, b$OffC Updated otherwise
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaChkDownC,<PUBLIC,NEAR>
cBegin
	MOV	AX,b$OffC	;[AX] = cursor offset
	CMP	AX,B$VBOFST	;already at the bottom of viewport?
	JB	B$EgaDownC	;Brif not
	STC			;STC to indicate that cursor is
cEnd				;on bottom of viewport

;***
; B$EgaDownC
;
;Purpose:
;	Move graphics cursor down 1 pixel for EGA modes.  No test is made for
;	screen boundaries.
;Entry:
;	None
;Exit:
;	b$MaskC, b$OffC Updated
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaDownC,<PUBLIC,NEAR>
cBegin
	mov	ax,b$BytesPerRow 
	add	b$OffC,ax	;down one row
	clc			;(no error for ChkDownC)
cEnd

;***
; B$EgaSetAttr
;
;Purpose:
;	Set b$AttrC to user-supplied attribute for EGA modes.	If
;	user-supplied attribute is outside legal range, use maximum legal
;	attribute.
;Entry:
;	AL = attribute
;Exit:
;	b$AttrC set to new attribute
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaSetAttr,<PUBLIC,NEAR>,<AX>
cBegin
	cmp	al,b$MaxAttr	;test against maximum attribute
	jbe	SetAttrOk	;Brif legal
	mov	al,b$MaxAttr	;limit to max
SetAttrOk:
	mov	b$AttrC,al
	clc			;exit no error
cEnd

;***
; B$EgaReadC
;
;Purpose:
;	For EGA modes, return the attribute of the current pixel as
;	specified by b$MaskC and b$OffC.
;
;Entry:
;	b$MaskC and b$OffC specify pixel to read
;Exit:
;	AL = attribute of pixel
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaReadC,<PUBLIC,NEAR>,<SI,ES>
cBegin
	les	si,b$AddrC
	mov	bx,0103H	;start at plane 3 and dec by 1 for 4 planes
ReadCX1:
	EGAINT10CLI		; disable interrupts if using EGAINT10
	MOV	DX,GRPADD	;address of graphics index register
	MOV	AX,RWMREG	;r/w mode index in AL, 0 in AH
	OutWord 		;set read mode to 0 so that we read byte
				;specified as 0/1 for one plane at a time
	MOV	AL,RMPREG	;AL=index to read map reg
	OUT	DX,AL		;indicate next data for read map register
	INC	DX		;data port address
	MOV	al,bl		;al = plane number
	xor	ah,ah		;ah = color accumulator
	MOV	cl,b$MaskC	;bit position
ReadC1:
	OUT	DX,AL		;indicate plane to read
	MOV	ch,ES:[si]	;get 8 bits for plane
	AND	ch,cl		;isolate bit to read
	neg	ch		;carry = (ch==0)?0:1
	rcl	ah,1		;shift bit into color accumulator
	sub	al,bh		;reference next color plane to read
	jae	ReadC1		;do next plane
	XCHG	AH,AL		;color attribute returned in AL
	CALL	B$ResetEGA	;set up EGA for next BIOS write
cEnd

;***
; B$EgaReadC_F
;
;Purpose:
;	For Screen 10, return the attribute of the current pixel as
;	specified by b$MaskC and b$OffC.
;
;Entry:
;	b$MaskC and b$OffC specify pixel to read
;Exit:
;	AL = attribute of pixel
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaReadC_F,<PUBLIC,NEAR>,<SI,ES>
cBegin
	les	si,b$AddrC
	mov	bx,0202H	;start at plane 2 and dec by 2 for 2 planes
				;  (0&2)
	jmp	short ReadCX1	;continue in common code
cEnd	<nogen>

;***
; B$EgaReadC_64K
;
;Purpose:
;	For Screen 9/64K, return the attribute of the current pixel as
;	specified by b$MaskC and b$OffC.
;
;Entry:
;	b$MaskC and b$OffC specify pixel to read
;Exit:
;	AL = attribute of pixel
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaReadC_64K,<PUBLIC,NEAR>,<SI,ES>
cBegin
	les	si,b$AddrC
	mov	bx,si		;copy video address
	mov	bh,2		;bh = dec by 2 between planes
	and	bl,1		;1 if odd, 0 if even
	add	bl,bh		;bl = plane (use maps 3 and 1 if odd address)
				;	    ( or maps 2 and 0 if even address)
	jmp	short ReadCX1	;continue in common code
cEnd	<nogen>

;***
; B$EgaSetC
;
;Purpose:
;	Set the pixel defined by the current graphics cursor to
;	the current attribute for EGA modes.
;Entry:
;	b$PenC  = cursor mask and attribute
;	b$AddrC = address of pixel byte
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaSetC,<PUBLIC,NEAR>,<ES>	
cBegin
	EGAINT10CLI		; disable interrupts if using EGAINT10
	MOV	DX,GRPADD	;address of graphics index port
	MOV	AL,RWMREG	;index to the graphics controller mode reg
	OUT	DX,AL
	MOV	AL,b$EgaWrMd	;write mode 2; odd/even or sequential addr.
	INC	DX		;address data port
	OUT	DX,AL
	MOV	AL,BMKREG	;index to the bit mask register
	DEC	DX
	OUT	DX,AL
	mov	ax,b$PenC	;[al] = cursor mask, [ah] = attribute
	INC	DX
	OUT	DX,AL		;set bit mask
	les	bx,b$AddrC	;[BX] = cursor offset, [DS] = segment
	XCHG	ah,es:[BX]	;latch screen contents and do a color write
	;reset EGA regs to those expected by the BIOS
	MOV	AL,0FFH 	;set all mask bits
	OUT	DX,AL
	MOV	AL,RWMREG	;index to the graphics controller mode reg
	DEC	DX
	OUT	DX,AL
	MOV	AL,b$EgaWrMd	;odd/even or sequential addr.
	and	al,10H		;set write mode 0 for bios
	INC	DX
	OUT	DX,AL
	EGAINT10STI		; reenable interrupts if using EGAINT10
cEnd

;***
; B$EgaSetPixC
;
;Purpose:
;	Set the pixel defined by the current graphics cursor to
;	the current attribute for EGA modes.  This is identical
;	to B$EgaSetC with the initialization and termination code
;	extracted to make it faster when multiple pixels are being
;	set in a graphics functin (ie: CIRCLE).  A call to
;	B$EgaSetPixFirstC should preceed the first call to
;	B$EgaSetPixC.	A call to B$ResetEGA should follow
;	the last.  B$EgaSetPixFirstC sets up ES which should be
;	preserved for all B$SetPixC calls.
;Entry:
;	ES	= video segment (set up by B$EgaSetPix)
;	b$PenC = cursor mask and attribute
;	b$OffC = address of pixel
;Exit:
;	None
;Uses:
;	per conv.
;Exceptions:
;******************************************************************************
cProc	B$EgaSetPixC,<PUBLIC,NEAR>
cBegin
	MOV	DX,GRPADD+1	;address graphics data port
	mov	ax,b$PenC	;[al] = cursor mask, [ah] = attribute
	OUT	DX,AL
	mov	bx,b$OffC	;[BX] = cursor offset
				;[ES] = setup by SetPixFirstC
	XCHG	ah,ES:[BX]	;latch screen contents and do a color write
cEnd

;***
; B$EgaSetPixFirstC
;
;Purpose:
;	Set up ES to the video segment and set up EGA write mode so
;	repeated calls can be made to B$EgaSetPixC without having
;	to reinitialize.

⌨️ 快捷键说明

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