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

📄 llcscn.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;	modified by the LOCATE statement, is the one that is displayed
;	for all but editing.  When editing a line of input, either the
;	Overwrite or Insert cursor will be used depending on whether
;	we are overwriting or inserting characters.  The Overwrite
;	cursor is identical to the User Cursor, except that it can
;	not be turned off with the LOCATE statement.
;
;
;	Initially, the User Cursor and Overwrite cursors are a full
;	block, and the insert cursor is a 1/2 block.  Under DOS, the
;	cursor has to be handled separately if we are in a graphics
;	mode since the IBM BIOS does not support a cursor font in
;	graphics mode.	Note that none of this has anything to do with
;	the graphics cursor, which is a one pixel location on the
;	current graphics screen and is never displayed.
;
;	NOTE: If you are supporting delayed screen initialization,
;	      B$SCNINIT has to be called before any changes are
;	      made.
;
;Algorithm:
;
;    B$INSCSR - Turn insert cursor on and move to specified location
;
;    B$OFFCSR - Turn cursor off and move invisible cursor to specified
;		 location
;
;    B$USRCSR - Turn on user cursor if specified as being visible in
;		 the last call to B$CSRATR, otherwise do not display
;		 a cursor.  Move (possibly invisible) cursor to specified
;		 location if the cursor is on.  If the cursor is off,
;		 DO NOT move the cursor (for speed).
;
;    B$OVWCSR - Turn overwrite cursor on and move to specified location.
;		 The overwrite cursor has the same specifications as the
;		 user cursor, but does not obey the visibility parameter
;		 specified in B$CSRATR.
;
;Entry:
;	[DL] = new 1-relative line number
;	[DH] = new 1-relative column number
;	It is assumed that the values in DX are in range.
;
;Exit:
;	None.
;
;Uses:
;	Per Convention
;
;Preserves:
;	BX,CX,DX
;
;Exceptions:
;	None.
;****
;***
;B$CSRDSP - Change Cursor Type and Location
;
;Purpose:
;	This routines display the specified cursor at a particular
;	location as given by the input parameters.  It may also
;	request to not display a cursor.  The text mode graphics cursor
;	will be implemented as a full block for user cursor requests,
;	and as a 1/2 block for insert modes.  The graphics cursor will
;	be handled separately (for DOS3) since the IBM BIOS does not
;	support a cursor font in graphics mode.
;
;	Entry points B$OFFCSR, B$OVWCSR, B$INSCSR, and B$USRCSR	[16]
;	exist to set AX to the appropriate value before falling through	[16]
;	into B$CSRDSP, in order to save code space. (Documented above)
;
;Algorithm:
;
;    B$CSRDSP:
;	if not OS/2
;	  if graphics request then
;	    if previous cursor valid
;	      if previous cursor is not an off cursor
;	        erase previous cursor using xor function on previous cursor
;	        and the screen.
;
;	convert 1-relative row and col to 0-relative row and column
;	swap row and col registers for bios call
;	get active screen page number
;	move cursor to desired location
;	swap start and stop lines
;	if text mode or OS/2
;	  if cursor type request != current cursor type
;	    change cursor to new type
;	else (DOS3 graphics modes)
;	  if requested cursor is not for an off cursor
;	    display requested cursor using an xor function on requested cursor
;		and the screen.
;	store new cursor position and type
;
;Entry:
;	b$CSRTYP = current cursor position
;	[AX] = new cursor type
;	[DL] = new 1-relative line number
;	[DH] = new 1-relative column number
;	It is assumed that the values in DX are in range.
;
;Exit:
;	b$CSRTYP = current cursor type (start and stop lines)
;
;Modifies:
;	None
;
;Preserves:
;	BX,CX,DX
;
;Exceptions:
;	None.
;****
CSRGRPH:
				;here if screen mode graphics
	PUSH	AX		;save csr request for call
	MOV	AX,b$CSRTYP	; get previous cursor type
	CMP	AL,-1		; unknown previous cursor type?
	JZ	NO_CURSOR	; brif so -- no cursor to erase
	CALL	GRPCSR		;erase previous cursor
NO_CURSOR:
	POP	AX		;restore csr request
	JMP	SHORT TXTCSR

labelNP <PUBLIC,B$SCNLOC>	; update cursor position variable
	MOV	b$CURSOR,DX	; and fall into SLOWUSRCSR.

labelNP <PUBLIC,B$SlowUsrCsr>
	CMP	[B$UsrCsrOn],0	; should users cursor be displayed?
	JZ	B$OFFCSR	; brif not -- turn off cursor

USRCSR:
	CMP	b$ScreenMode,0	; is screen mode graphics?
	JNZ	B$OFFCSR	; brif so -- use off cursor

labelNP <PUBLIC,B$OVWCSR>	; display overwrite cursor
	MOV	AX,b$UsrCsrTyp	; get user defined cursor
	JMP	SHORT B$CSRDSP	; and display it

labelNP <PUBLIC,B$INSCSR>	; display insert mode cursor
	MOV	AX,b$InsCsrTyp	; get insert mode cursor
	JMP	SHORT B$CSRDSP	; and display it

labelNP <PUBLIC,B$USRCSR>	; conditionally display user cursor
	CMP	[B$UsrCsrOn],0	; should users cursor be displayed?
	JNZ	USRCSR		; brif so -- check for graphics mode
	CMP	b$CSRTYP,OffCsrTyp ; cursor already off?
	JNE	B$OFFCSR	; brif not -- turn it off now
	RET			; otherwise, don't position or check type.
				; check type.

; This REALLY speeds up print statements, but will usually NOT update the
; hardware cursor!  To FORCE the cursor to get reset, invalidate the cursor
; type by moving -1 into b$CSRTYP.

labelNP <PUBLIC,B$OFFCSR>	; turn cursor off
	MOV	AX,OffCsrTyp	;  get off cursor


cProc	B$CSRDSP,<NEAR,PUBLIC>,<BX,CX>
cBegin

	PUSH	AX		; save registers
	PUSH	DX
	CALL	B$SCINIT	; make sure screen is initialized.
	cmp	b$ScreenMode,0	;is screen mode graphics?
	JNZ	CSRGRPH 	;br. if so
TXTCSR:

	DEC	DX		; DL = 0-relative row
	XCHG	DH,DL		;swap for BIOS call
	DEC	DX		; DL,DH = 0-relative column,row
	MOV	BH,b$ActPage	;get active page
	PUSH	AX		;save cursor type
	SCNIOS vSetCursorPos	; issue BIOS call to move cursor
	POP	AX		;recover cursor type
	cmp	b$ScreenMode,0	;Text mode ?
	JNZ	NOT_TEXT_MODE	; Brif not -- generate graphics cursor
	CMP	AX,b$CSRTYP	; (speed) need to change the cursor type?
	JE	DSPRET		; (speed) brif not -- just return
	XCHG	AX,CX		; CX = cursor type
				; CH = start line, CL = stop line


	SCNIOS	vSetCursorType	; display requested cursor
; The bios does not set the cursor type right for IBM EGA cards
; when trying to get an underline cursor when not in 25-line mode.  So
; we have to set it ourselves.  We do the BIOS call beforehand to update
; the internal BIOS cursor type variable.
	TEST	CH,20H		; cursor off request?
	JNZ	NoChangeType	; brif so -- don't reset type
	TEST	b$Adapter,EGA	; EGA adapter?
	JZ	NoChangeType	; brif not -- don't reset type
	CMP	b$ScrHeight,25	; 25-line mode?
	JZ	NoChangeType	; brif not -- don't reset type
	MOV	DX,03D4h	; EGA port
	XCHG	AX,CX		; AH = start line
	MOV	AL,0Ah		; select start line register
	OutWord 		; write correct value - macro for AT&T 6300
NoChangeType:

DSPRET:
	POP	DX		; restore new position and type
	POP	AX
	MOV	b$CSRTYP,AX	; store current cursor type
cEnd


NOT_TEXT_MODE:
	CALL	GRPCSR		; generate graphics cursor
	JMP	DSPRET		; exit

;*** 
; GRPCSR -- Toggle a generated graphics mode text cursor (DOS 3 only)
;
;Purpose:
;
;Entry:
;	AX = cursor type
;
;Exit:
;	None
;Uses:
;	AX,BX,CX
;
;Preserves:
;	DX
;
;Exceptions:
;	None
;
;******************************************************************************

cProc	GRPCSR,<NEAR>
cBegin
	CMP	AX,OffCsrTyp	; cursor off request?
	JE	GRPRET		; brif so -- return without doing anything
	PUSH	ES		; save ES
	mov	bl,[b$BiosMode] ; check BIOS mode
	cmp	bl,13h		; VGA mode 13h?
	je	Cursor13	; go if so
	XOR	CX,CX		; CX = 0
	MOV	ES,CX		; ES = 0
	CMP	BL,40h		; Is it Olivetti 640x400 mode?
	JNE	NotCsr40h	; brif not

; The Olivetti VGA handles character fonts normally in mode 40h, but we
; special-case their CGA and EGA which use a MASTER TABLE POINTER at 40:84.

	TEST	[b$Adapter],CGA+EGA; Is it CGA or EGA Olivetti?
	JZ	NotCsr40h	; brif not (ie. Olivetti VGA)

;Note: B$OgaCsr requires ES = CX = 0 on entry

	CALL	[b$pOgaCsr]	; use Olivetti version of routine
	JMP	SHORT GrpRet2
NotCsr40h:
	PUSH	ES:CHREXT	;Save Old Char Extention Ptr
	PUSH	ES:CHREXT+2
	MOV	ES:WORD PTR CHREXT,OFFSET DGROUP:BLTLOT
	MOV	ES:CHREXT+2,DS	;Segment Addr of Box Char

	CMP	AX,b$InsCsrTyp	; is it an insert cursor?

	PUSHF			; save check for insert mode
	cmp	b$BiosMode,8	;Hercules graphics mode?
	je	UseEga		;use EGA code if so
	CMP	b$BiosMode,0Dh	;current screen mode EGA?
	JB	NotEga		;brif not Ega mode
UseEga:
	MOV	BL,b$ForeMapped ;use current color
	OR	BL,080H 	;set XOR bit
	MOV	AL,0DCh 	;half height block character for EGA
	POPF			;insert mode?
	JZ	GRPCS2		;brif insert cursor
	DEC	AL		;make overwrite cursor
	JMP	SHORT GRPCS2
NotEga:
	POPF			;insert mode?


	MOV	AL,128		;Char code for Box
	JZ	GRPCS1		;brif it is insert cursor
	INC	AL		;Map to 128 or 129..
GRPCS1: 			;Half Box (128) If INS_MODE
				;Whole Box (129) for normal (NOT INS_MODE)
	MOV	BL,87H		;Select Invert (xor) Mode
				;bit 7 of [BL] = 1 for XOR mode and
				;low nibble =7, bcos we need low intensity white

GRPCS2:
	MOV	BH,b$ActPage	; Active Page
	INC	CX		; CX = 1 -- One Character
	SCNIOS	vWriteChar
	POP	ES:CHREXT+2
	POP	ES:CHREXT	;Restore Char Extention ptr
GrpRet2:
	POP	ES		;restore register
GRPRET:
cEnd

;
;BIOS mode 13H (SCREEN 13) does not perform XOR drawing of characters.
;We must therefore draw the cursor the hard way, XORing the 8x8 character
;cell with the desired cursor color.
;
Cursor13:
	push	dx		;preserve DX
	push	ax		;save cursor type
	SCNIOS	vReadCursorPos	;DH=cursor row, DL=column
	xor	ax,ax
	xchg	al,dh		;AX=row, DX=col
	mov	cl,3		;*8
	shl	ax,cl		;AX=Y coordinate of character
	shl	dx,cl		;DX=X coordinate of character
	mov	cx,dx		;CX=X
	mov	dx,ax		;DX=Y
	call	[b$MapXYC]	;convert X,Y to buffer offset
	mov	al,b$ForeMapped ;get cursor color
	mov	ah,al		;replicate for 2 pixels
	les	bx,b$AddrC	;buffer address for character start
DbAssertRel    ES,E,0A000H,RT_TEXT,<Buffer segment invalid in B$CSRDSP> 
	mov	cx,8		;8 raster lines down per character
	pop	dx		;restore cursor type
	cmp	dx,b$InsCsrTyp	;is it an insert cursor?
	jne	NextRaster	;go if not for full-block cursor
	shr	cx,1		;half-block cursor
	add	bx,320*4	;start 4 rasters down, do half as many
NextRaster:
	push	cx
	mov	cx,4		;8 pixels (4 words) across per character
NextWord:
	xor	word ptr es:[bx],ax ;xor 2 pixels with color
	inc	bx		;to next word
	inc	bx
	loop	NextWord	;do all 8 pixels
	pop	cx
	add	bx,320-8	;down to next raster and back to left
	loop	NextRaster
	pop	dx		;restore DX
	jmp	short GrpRet2


;***
;B$SCROLL - Scroll the screen by one line
;OEM-interface routine
;
;Purpose
;	Scrolls up one line an area of the screen with a left,top corner of
;	(1,b$WDOTOP), and a right,bottom corner of (b$CRTWIDTH,b$WDOBOT)
;
;Entry:
;	b$WDOTOP, b$WDOBOT, b$CRTWIDTH set.
;
;Exit:
;	None
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, BX, CX, DX
;
;Exceptions:
;	None.
;****

cProc	B$SCROLL,<PUBLIC,NEAR>,<AX,BX,CX,DX>
cBegin

	XOR	CX,CX		; CL = left column (0-relative)
	MOV	CH,b$WDOTOP	; CH = top row
	DEC	CH		; make it 0-relative
	MOV	BL,b$CRTWIDTH	; BL = right column
	MOV	BH,b$WDOBOT	; BH = bottom row
	DEC	BX		; make column 0-relative
	DEC	BH		; make row 0-relative

OLD_SCROLL:			; former entry point
;	[BH] = Window bottom row (0-relative)
;	[BL] = Right column of scroll window (0-relative)
;	[CH] = Window top row (0-relative)
;	[CL] = Left column of scroll window (0-relative)

	cCALL	B$SELAPG	; Active Visual Page

;	Determine if scrolling is Horizontal or Vertical by comparing
;	source line and destination line
;	Source line will can be equal to destination line if VIEW PRINT n TO n
;	is used.

⌨️ 快捷键说明

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