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

📄 ted2.asm

📁 一个很小的用汇编写的编辑器
💻 ASM
📖 第 1 页 / 共 5 页
字号:
RIGHT_AGAIN:
		PUSH	CX
		;-----------------------
		; (JEG)
		INC	SI
		CMP	SI,LAST_CHAR	;at end of file?
		DEC	SI
		JAE	DO_MOVE
		CMP	WORD PTR [SI],CRLF ;at end of line?
		;-----------------------
		JE	DONT_MOVE	;if at end, stop moving
DO_MOVE:
		CALL	RIGHT		;move right one character
DONT_MOVE:
		POP	CX

		MOV	AL,SAVE_COLUMN
		XOR	AH,AH
		CMP	AX,CX		;is cursor still in margin?
		JL	IN_MARGIN	;if yes, keep moving

		MOV	DX,CURS_POSN	;get cursor column again
		XOR	DH,DH
		CMP	DX,BP		;at saved cursor position?
		JE	RIGHT_DONE	;if yes, we're done
		JA	RIGHT_TOO_FAR	;did we go too far?
IN_MARGIN:
		LOOP	RIGHT_AGAIN
RIGHT_DONE:
		MOV	CX,BP
		MOV	SAVE_COLUMN,CL	;get back saved cursor position
NO_CHANGE:
		RET
		;-----------------------
RIGHT_TOO_FAR:
		CALL	LEFT		;move back left one place
		MOV	CX,BP
		MOV	SAVE_COLUMN,CL	;get back saved cursor position
		RET
SHIFT_RIGHT	ENDP

;=======================================================================
; This routine finds the beginning of the previous line.
;-----------------------------------------------------------------------
FIND_PREVIOUS	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		PUSH	CURSOR		;save the cursor location
		CALL	FIND_CR		;find the start of this line
		MOV	CURSOR,SI	;save the new cursor
		CALL	FIND_START	;find the start of this line
		POP	CURSOR		;get back starting cursor
		RET
FIND_PREVIOUS	ENDP

;=======================================================================
; This routine searches for the previous carriage return.  
; Search starts at DS:SI.
;-----------------------------------------------------------------------
FIND_CR		PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		PUSH	CX
		MOV	AL,LF		;look for a line feed character
		MOV	DI,SI
		MOV	CX,SI
		JCXZ	AT_BEGINNING
		DEC	DI
		STD			;search backwards
LF_PREV:
		REPNE	SCASB		;scan for the character
		;-----------------------
		; from TEDPLUS
		JCXZ	LF_END
		CMP	BYTE PTR [DI],CR
		JNE	LF_PREV
		DEC	DI
LF_END:
		;-----------------------
		CLD			;restore the direction flag
		INC	DI
		MOV	SI,DI
AT_BEGINNING:
		POP	CX
		RET
FIND_CR		ENDP

;=======================================================================
; This routine skips past the CR and LF at SI.  SI returns new offset.
;-----------------------------------------------------------------------
SKIP_CR_LF	PROC	NEAR
	;	ASSUME	CS:FILE_SEG
		CMP	SI,LAST_CHAR	;at last char in file?
		JAE	NO_SKIP		;if yes, don't skip anything
		CMP	BYTE PTR [SI],CR ;is first character a CR?
		JNE	NO_SKIP
		INC	SI		;look at next character
		CMP	SI,LAST_CHAR	;is it at the end of file?
		JAE	NO_SKIP		;if yes, don't skip anymore
		CMP	BYTE PTR [SI],LF ;is next character a line feed?
		JNE	NO_SKIP		;skip any line feeds also
		INC	SI
NO_SKIP:
		RET
SKIP_CR_LF	ENDP

;=======================================================================
; This routine computes the location of the start of current line.  
; Returns SI pointing to the first character of the current line.  
;-----------------------------------------------------------------------
FIND_START	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		MOV	SI,CURSOR	;get the current cursor
		OR	SI,SI		;at start of file?
		JZ	AT_START	;if yse, we're done
		CALL	FIND_CR		;find the CR
		CALL	SKIP_CR_LF
AT_START:
		RET
FIND_START	ENDP

;=======================================================================
; This routine finds the offset of the start of the next line.  The search 
; is started at location of ES:SI.  On return, CF=1 if no CR was found.
;-----------------------------------------------------------------------
FIND_NEXT	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		PUSH	CX
		CALL	FIND_EOL	;find the end of this line
		JC	AT_NEXT		;if at end of file, return
		CALL	SKIP_CR_LF	;skip past CR and LF
		CLC			;indicate end of line found
AT_NEXT:
		POP	CX
		RET
FIND_NEXT	ENDP

;=======================================================================
; This routine searches for the next carriage return in the file.  
; The search starts at the offset in register SI.  
;-----------------------------------------------------------------------
FIND_EOL	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		MOV	AL,CR		;look for a carriage return
CR_SCAN:
		MOV	CX,LAST_CHAR	;last letter in the file
		SUB	CX,SI		;count for the search
		MOV	DI,SI
		JCXZ	AT_END		;if nothing to search, return
		REPNE	SCASB		;scan for the character
		MOV	SI,DI		;return the location of the CR
		JCXZ	AT_END		;if not found, return
		;-----------------------
		; from TEDPLUS
		CMP	BYTE PTR [SI],LF
		JNE	CR_SCAN
		;-----------------------
		DEC	SI		;back up one, to CR character
		CLC			;indicate the CR was found
		RET
AT_END:
		STC			;indicate CR was not found
		RET
FIND_EOL	ENDP

;=======================================================================
; This routine positions the screen with the cursor at the row 
; selected in register DH.  On entry, SI holds the cursor offset.
;-----------------------------------------------------------------------
LOCATE		PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		MOV	CL,DH
		XOR	CH,CH
		MOV	CURSOR,SI
		XOR	DX,DX		;start at top of screen
		OR	SI,SI		;at start of buffer?
		JZ	LOCATE_FIRST

		CALL	FIND_START	;get start of this row
		XOR	DX,DX		;start at top of screen
		OR	SI,SI		;is cursor at top of file?
		JZ	LOCATE_FIRST
		JCXZ	LOCATE_FIRST	;if location to top row were done
FIND_TOP:
		PUSH	SI
		PUSH	CX
		CALL	FIND_CR		;find previous row
		POP	CX
		POP	AX
		CMP	WORD PTR [SI],CRLF
		JNE	LOCATE_FIRST
		CMP	SI,AX		;did it change?
		JE	LOCATE_DONE	;if not, quit moving
		INC	DH		;cursor moves to next row
		LOOP	FIND_TOP

LOCATE_DONE:
		PUSH	CURSOR
		MOV	CURSOR,SI
		CALL	FIND_START	;find start at top of screen
		POP	CURSOR
LOCATE_FIRST:
		MOV	TOP_OF_SCREEN,SI
		MOV	CURS_POSN,DX
		CALL	CURSOR_COL
		MOV	SAVE_COLUMN,DL
		RET
LOCATE		ENDP

;=======================================================================
; This routine computes the correct column for the cursor.  No inputs.  
; On exit, CURS_POSN is set and DX has row/column.
;-----------------------------------------------------------------------
CURSOR_COL	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		MOV	SI,CURSOR	;get cursor offset
		CALL	FIND_START	;find start of this line
		MOV	CX,CURSOR	;cursor location in file
		SUB	CX,SI
		MOV	DX,CURS_POSN	;get current row
		XOR	DL,DL		;start at column zero
		MOV	MARGIN_COUNT,DL	;count past the left margin
		JCXZ	COL_DONE
CURSOR_LOOP:
		LODSB			;get the next character
		INC	SI
		CMP	SI,LAST_CHAR
		DEC	SI
		JAE	NOT_EOL		;is <CR> without <LF>, at end of file

		CMP	WORD PTR [SI-1],CRLF ;(JEG)
		JE	COL_DONE	;if at end, we're done
NOT_EOL:
		CMP	AL,TAB		;is it a tab?
		JNE	NOT_A_TAB

		MOV	BL,MARGIN_COUNT
		OR	BL,00000111B
		MOV	MARGIN_COUNT,BL
		CMP	BL,LEFT_MARGIN	;inside visible window yet?
		JB	NOT_A_TAB	;if not, don't advance cursor
		OR	DL,00000111B	;move to multiple of eight
NOT_A_TAB:
		MOV	BL,MARGIN_COUNT
		INC	BL
		MOV	MARGIN_COUNT,BL
		CMP	BL,LEFT_MARGIN
		JBE	OUT_OF_WINDOW
		INC	DL		;we're at next column now
OUT_OF_WINDOW:
		LOOP	CURSOR_LOOP
COL_DONE:
		CMP	DL,COLUMNSB	;past end of display?
		JB	COLUMN_OK	;if not, we're OK
		MOV	DL,COLUMNSB
		DEC	DL		;leave cursor at last column
COLUMN_OK:
		MOV	CURS_POSN,DX	;store at last column
		RET
CURSOR_COL	ENDP

;=======================================================================
; MARK, CUT, PASTE, PRINT services
;=======================================================================
; This routine toggles the mark state and resets the paste buffer pointers.
;-----------------------------------------------------------------------
MARK		PROC	NEAR
		XOR	AX,AX
		NOT	CS:MARK_MODE	;toggle the mode flag
		CMP	CS:MARK_MODE,AL	;turning mode ON?
		JNE	MARK_ON
		OR	CS:DIRTY_BITS,1	;need to redraw the screen
		MOV	CS:MARK_START,0FFFFH
		JMP	SHORT MARK_RET
		;-----------------------
MARK_ON:
		MOV	AX,CS:CURSOR	;get the cursor offset
		MOV	CS:MARK_START,AX	;start of marked range
MARK_RET:
		MOV	CS:MARK_END,AX	;end of marked range
		MOV	CS:MARK_HOME,AX	;center of marked range
		RET
MARK		ENDP

;=======================================================================
; This routine removes the marked text and places it in the paste buffer.
;-----------------------------------------------------------------------
CUT		PROC	NEAR
		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JA	NO_MARK		;jump if read-only file
		CMP	CS:MARK_MODE,0	;is the mark mode on?
		JE	NO_MARK		;if not, then do nothing
		MOV	CX,CS:MARK_END	;get end of mark region
		MOV	SI,CS:MARK_START ;get start of mark region
		SUB	CX,SI		;number of bytes selected
		MOV	PASTE_SIZE,CX
		XOR	DI,DI		;point to paste buffer

		PUSH	CX
		PUSH	ES
		MOV	ES,CS:PASTE_SEG	;set the paste buffer segment to ES
		REP	MOVSB		;deleted text to buffer, DS:SI to ES:DI
		POP	ES
		POP	AX

		MOV	CX,CS:LAST_CHAR
		SUB	CS:LAST_CHAR,AX	;shorten the file this much
		MOV	DI,CS:MARK_START
		MOV	SI,CS:MARK_END
		SUB	CX,SI
		JCXZ	NO_DELETE
		REP	MOVSB		;shorten the file, DS:SI to ES:DI
NO_DELETE:
		MOV	DX,CS:CURS_POSN
		MOV	SI,CS:MARK_START
		CALL	LOCATE		;adjust the screen position
		CALL	MARK		;this turns off select

		;-----------------------
		; see if we made a CR-LF pair by cutting the character(s) from
		; between a Ctrl-M and a Ctrl-J.  If so, open a new line.
		;-----------------------
		CALL	C_IF_NEW_CRLF

NO_MARK:
		RET
CUT		ENDP

;=======================================================================
; This routine copies the paste buffer into the file at the cursor location.
;-----------------------------------------------------------------------
PASTE		PROC	NEAR
		MOV	AX,PASTE_SIZE	;number of characters in buffer
		OR	AX,AX		;any there?
		JZ	NO_PASTE	;if not, nothing to paste

		MOV	SI,CURSOR	;get cursor location
		PUSH	AX
		PUSH	SI
		CALL	OPEN_SPACE	;make room for new characters
		POP	DI
		POP	CX
		JC	NO_PASTE	;if no room, just exit
		XOR	SI,SI		;point to start of paste buffer
		PUSH	DS
		MOV	DS,PASTE_SEG	;segment of paste buffer
		REP	MOVSB		;copy in the new characters
		POP	DS
		OR	DIRTY_BITS,1	;redraw the screen
		CALL	C_IF_NEW_CRLF

NO_PASTE:
		RET
PASTE		ENDP

;=======================================================================
; This routine prints an ASCII Form-Feed character.
;-----------------------------------------------------------------------
PRINT_FF	PROC	NEAR
		CALL	MARK		;toggle MARK "on"
		PUSH	DS
		PUSH	CS
		POP	DS		
		MOV	CX,1		;one character to print
		MOV	SI,OFFSET FF	;offset of last byte in paste buffer
		CALL	DO_FF_CHAR
		POP	DS
		RET

FF		DB	12		;the ASCII Form-Feed character
PRINT_FF	ENDP
;-----------------------------------------------------------------------
; This routine prints the marked text.  If printer fails, it is cancelled.
;-----------------------------------------------------------------------
PRINT		PROC	NEAR
		CMP	MARK_MODE,0	;is mark mode on?
		JE	PRINT_RET	;if not, nothing to print
		MOV	CX,MARK_END	;end of marked region
		MOV	SI,MARK_START	;start of marked region
		SUB	CX,SI		;number of bytes selected
		JCXZ	PRINT_DONE	;if nothing to print, return
DO_FF_CHAR:
		XOR	DX,DX		;select printer 0
		MOV	AH,2
		INT	17H	

⌨️ 快捷键说明

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