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

📄 window.asm

📁 a fat12 source code, it is verified for many platform
💻 ASM
📖 第 1 页 / 共 2 页
字号:
		AND		DL,DL			; Already at first col?
		JZ		?vedit			; Yes, don't backup
		DEC		DL				; Reduce 'X' position
		JMP		<?vedit			; And exit
* Handle NEWLINE
?tstnl	CMP		AX,#'J'-$40		; Is it newline?
		JNZ		?norchr			; Yes, advance line
		MOV		AL,1[SI]		; Get flags
		TEST	AL,#$04			; Special case?
		JNZ		?advy			; Yes, don't reset 'X'
		XOR		DL,DL			; Reset cursor
		JMP		<?advy			; And goto a new line
* Normal Character, output it
?norchr	CALL	?xyaddr			; Calculate address
		MOV		AH,[SI]			; Get video attributes
		MOV		ES:[BX],AX		; Write to video display
* Advance 'X' position
?advx	INC		DL				; Advance 'X'
		CMP		DL,4[SI]		; Are we over?
		JB		?vedit			; No, its ok
		DEC		DL				; Restore it
		MOV		AL,1[SI]		; Get flags
		TEST	AL,#$01			; Line wrap enabled?
		JZ		?vedit			; No, skip it
		XOR		DL,DL			; Reset 'X' position
* Advance 'Y' position
?advy	INC		DH				; Advance 'Y' position
		CMP		DH,5[SI]		; are we over?
		JB		?vedit			; No, Its OK
		DEC		DH				; Reset it
		MOV		AL,1[SI]		; Get flags
		TEST	AL,#$02			; Screen wrap enabled?
		JZ		?vedit			; No, skip it
		CALL	?scroll			; Scroll window
* Restore callers environment & exit
?vedit	MOV		6[SI],DX		; Resave 'X' and 'Y'
		POP		ES				; Restore callers ES
		POP		BP				; Restore callers stack frame
		RET
*
* CLEAR current window: wclwin()
*
wclwin	CALL	?xsetup			; Get current window
		JMP		<?clscr1		; And proceed
*
* CLEAR entire window: w_clwin(window)
*
w_clwin	CALL ?wsetup				; Setup video
?clscr1	XOR		DX,DX			; Reset to top of screen
		MOV		6[SI],DX		; Reset cursor
		CALL	?updt2			; Position cursor
		XOR		DX,DX			; Reset again
		JMP		<?clscr2		; And proceed
*
* CLEAR to end of current window: wcleow()
*
wcleow	CALL	?xsetup			; Get current window
		JMP		<?clscr2		; And proceed
*
* CLEAR to END OF WINDOW: w_cleow(window)
*
w_cleow	CALL	?wsetup			; Setup video
?clscr2	CALL	?cleos			; Clear to end
		POP		ES				; Restore ES
		POP		BP				; Restore caller
		RET
*
* CLEAR to end of line in current: wcleol()
*
wcleol	CALL	?xsetup			; Get current window
		JMP 	<?cleol1		; And proceed
*
* CLEAR to END OF LINE: w_cleol(window)
*
w_cleol	CALL	?wsetup			; Setup video
?cleol1	CALL	?xyaddr			; Get address
		MOV		DI,BX			; Set up address
		MOV		CL,4[SI]		; Get size of line
		SUB		CL,DL			; Calculate remaining
		XOR		CH,CH			; Zero high
		MOV		AH,[SI]			; Get attribute
		MOV		AL,#' '			; Clear to space
		REP
		STOSW					; Clear a line
		POP		ES				; REstore ES
?cleol2	POP		BP				; Restore caller
		RET
*
* Position the cursor in current window: wgotoxy(int x, int y)
*
wgotoxy	PUSH	BP				; Save callers stack frame
		MOV		BP,SP			; Address parameters
		MOV		AL,6[BP]		; Get 'X' value
		MOV		AH,4[BP]		; Get 'Y' value
		MOV		SI,W_OPEN	; Get open window
		JMP		<?goto1			; And proceed
*
* Position the cursor in window: w_gotoxy(int x, int y, window)
*
w_gotoxy PUSH	BP				; Save callers stack frame
		MOV		BP,SP			; Address parameters
		MOV		AL,8[BP]		; Get 'X' value
		MOV		AH,6[BP]		; Get 'Y' value
		MOV		SI,4[BP]		; Get window buffer
?goto1	CMP		AL,4[SI]		; In range?
		JAE		?cleol2			; No, error
		CMP		AH,5[SI]		; In range
		JAE		?cleol2			; No, error
		MOV		6[SI],AX		; Save values
		JMP		<?updt1			; And proceed
*
* Update the cursor in current window: wgotoxy()
*
wupdatexy MOV	SI,W_OPEN		; Get open window
		JMP		<?updt2			; And proceed
*
* Update the cursor position: w_updatexy(window)
*
w_updatexy PUSH BP				; Save callers stack frame
		MOV		BP,SP			; Address parameters
		MOV		SI,4[BP]		; Get caller
?updt1	POP		BP				; Resture caller
?updt2	MOV		DX,2[SI]		; Get starting address
		ADD		DX,6[SI]		; Offset into window
		MOV		BH,W_PAGE		; Get video page
		MOV		AH,#$02			; Set cursor function
		INT		$10				; Call DOS
		RET
*
* Check for a key from the keyboard: c = w_tstc(window)
*
w_tstc	MOV		AH,#$01			; Check for key
		INT		$16				; Do we have key?
		JNZ		w_getc			; Yes, read it
?wtst1	XOR		AX,AX			; No key today
		RET
*
* Check for key with cursor in current window: c = wtstc()
*
wtstc	MOV 	AH,#$01			; Check for key
		INT		$16				; Do we have key?
		JZ		?wtst1			; No, return zero
*
* Get in cursor in current window: c = wgetc()
*
wgetc	MOV		SI,W_OPEN		; Get active window
		JMP 	<?getc1			; And proceed
*
* Get a key from the keyboard with translations: c = w_getc(window)
*
w_getc	MOV		BX,SP			; Address parameters
		MOV		SI,2[BX]		; Get window
?getc1	CALL	?updt2			; Update the cursor position
* Call BIOS to read key
		XOR		AH,AH			; Function code 0 - read key
		INT		$16				; Call bios
* Lookup key for special entries
		MOV		CL,#$80			; Beginning function code
		MOV		BX,#?W_KEYS		; Address of keys array
?lokkey	MOV		DX,[BX]			; Get key entry
		CMP		AX,DX			; Does it match?
		JZ		?fndkey			; We found it
		ADD		BX,#2			; Skip ahead
		INC		CL				; Advance key code
		OR		DH,DL			; End of table?
		JNZ		?lokkey			; Keep looking
* Translate ENTER key to newline
		CMP		AX,#$1C0D		; ENTER key?
		JNZ		?norkey			; Yes, we have it
		MOV		CL,#'J'-$40		; Newline is LINE-FEED
* Translate special keys
?fndkey	MOV		AL,CL			; Set return value
?norkey	CBW						; Set high bits
		RET
*
* Set the CURSOR OFF: wcursor_off()
*
wcursor_off	EQU	*
		MOV		CX,#$2020		; Value for cursor off
		JMP		<?setc2			; And set it
*
* Set the CURSOR to a block: wcursor_block()
*
wcursor_block EQU *
		MOV		CX,#$0006		; Color block cursor
		MOV		DX,#$000B		; Monochrome block cursor
		JMP		<?setc1			; and proceed
*
* Set the CURSOR to a LINE: wcursor_line()
*
wcursor_line EQU *
		MOV		CX,#$0607		; Color line cursor
		MOV		DX,#$0B0C		; Monochrome line cursor
?setc1	MOV		AX,W_BASE		; Get video base
		CMP		AX,#?MBASE		; Monochrome?
		JNZ		?setc2			; No, do it
		MOV		CX,DX			; Copy for later
* Set cursor to value in CX
?setc2	MOV		AH,#1			; Set cursor type
		INT		$10				; Call BIOS
		RET
*
* Set up addressability to video display & stack registers
* Exit:	ES = video base address
*		SI = window buffer address
*		DX = cursor address (X/Y)
*
?wsetup	POP		AX				; Get return address
		PUSH	BP				; Save callers stack frame
		MOV		BP,SP			; Address parameters
		MOV		SI,4[BP]		; Get window buffer
?wset1	PUSH	ES				; Save callers Extra segment
		PUSH	AX				; Replace return address
		MOV		ES,W_BASE	; Point to video base
		MOV		DX,6[SI]		; Get 'X' and 'Y' position
		RET
*
* Set up addressability to currently open window
*
?xsetup	POP		AX				; Get return address
		PUSH	BP				; Save callers stack frame
		MOV		BP,SP			; Address parameters
		MOV		SI,W_OPEN	; Get open window
		JMP		<?wset1			; And proceed
*
* Scroll window forward one line
*
?scroll	PUSH	DS				; Save data segment
		PUSH	DX				; Save cursor
		PUSH	SI				; Save SI
* First, calculate base address of window
		MOV		AL,3[SI]		; Get 'Y' position
		MOV		BL,#160			; Size of line
		MUL		BL				; Calculate 'Y' offset
		MOV		BL,2[SI]		; Get 'X' position
		XOR		BH,BH			; Zero high
		SHL		BX,1			; * 2 for char & attribute bytes		
		ADD		BX,AX			; BX = character position
		MOV		DI,BX			; Get base window address
* Scroll one line at a time
		MOV		DX,4[SI]		; Get 'X' and 'Y' sizes
		DEC		DH				; Don't copy to last
		PUSH	ES				; Stack ES
		POP		DS				; To place in DS
?scrol1	PUSH	DI				; Save DI
		MOV		SI,DI			; Begin with same address
		ADD		SI,#160			; Offset to next line
		MOV		CL,DL			; Get 'X' size
		XOR		CH,CH			; Zero high size
		REP
		MOVSW					; Move one line
		POP		DI				; Restore it
		ADD		DI,#160			; Offset to next line
		DEC		DH				; Reduce count
		JNZ		?scrol1			; And proceed
* Clear bottom line of screen
		MOV		CL,DL			; Get 'X' size
		POP		SI				; Restore SI
		POP		DX				; Restore cursor
		POP		DS				; Restore data segment
		MOV		AH,[SI]			; Get attribute
		MOV		AL,#' '			; And space
		REP
		STOSW					; Clear it
		RET
*
* Clear from cursor(DX) to end of line
*
?cleos	PUSH	DX				; Save cursor
?cleos1	CALL	?xyaddr			; Get address
		MOV		DI,BX			; Set up address
		MOV		CL,4[SI]		; Get size of line
		SUB		CL,DL			; Calculate remaining
		XOR		CH,CH			; Zero high
		MOV		AH,[SI]			; Get attribute
		MOV		AL,#' '			; Clear to space
		REP
		STOSW					; Clear a line
		XOR		DL,DL			; Zero 'X'
		INC		DH				; Advance 'Y'
		CMP		DH,5[SI]		; Are we finished
		JB		?cleos1			; Keep going
		POP		DX				; Restore cursor
		RET
*
* Calculate screen address from X/Y position (in DX)
* On exit: BX = address
*
?xyaddr	PUSH	AX				; Save AX
		MOV		AL,DH			; Get 'Y' position
		ADD		AL,3[SI]		; Offset from start of screen
		MOV		BL,#160			; Size of physical screen
		MUL		BL				; Calculate 'Y' offset
		MOV		BL,DL			; Get 'X' position
		ADD		BL,2[SI]		; Offset from start of screen
		XOR		BH,BH			; Zero high byte
		SHL		BX,1			; * 2 for char & attribute bytes
		ADD		BX,AX			; BX = character position
		POP		AX				; Restore it
		RET
$EX:malloc
$EX:free

⌨️ 快捷键说明

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