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

📄 ted2.asm

📁 一个很小的用汇编写的编辑器
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		INC	DH		;advance cursor to next row
		CALL	SHIFT_RIGHT	;move cursor to current column
DOWN_RET:
		RET
		;-----------------------
SCREEN_UP:
		CMP	SI,LAST_CHAR	;get cursor offset
		JE	DOWN_RET
		CALL	FIND_START	;find the start of this line
		MOV	CURSOR,SI	;this is the new cursor
		CALL	FIND_NEXT	;find the offset of next line
		JC	SHIFT_RET	;if no more lines, then return
		MOV	CURSOR,SI	;this is the new cursor
		MOV	SI,TOP_OF_SCREEN ;get the start of the top row
		CALL	FIND_NEXT	;and find the next line
		MOV	TOP_OF_SCREEN,SI ;store the new top of screen
		JMP	SHORT SHIFT_RET
		;(CALL/RETurn)
DOWN		ENDP

;-----------------------------------------------------------------------
; This routine moves the cursor up one row.  If the cursor is at the first row, 
; the screen is scrolled down.
;-----------------------------------------------------------------------
UP		PROC	NEAR
		MOV	UNDO_LENGTH,0
		MOV	DX,CURS_POSN
		MOV	SI,CURSOR
		OR	DH,DH		;at top row already?
		JZ	SCREEN_DN	;if yes, then scroll down
		DEC	DH		;move the cursor up one row
		CALL	FIND_CR		;find the beginning of this row
		MOV	CURSOR,SI
		CALL	FIND_START	;find start of this row
		MOV	CURSOR,SI
		CALL	SHIFT_RIGHT	;skip over to current column
AT_TOP:
		RET
		;-----------------------
SCREEN_DN:
		MOV	SI,TOP_OF_SCREEN
		OR	SI,SI		;at start of file?
		JZ	AT_TOP		;if at top, then do nothing
		CALL	FIND_PREVIOUS	;find the preceding line
		MOV	TOP_OF_SCREEN,SI ;save new top of screen
		MOV	SI,CURSOR
		CALL	FIND_PREVIOUS	;find the preceding line
		MOV	CURSOR,SI	;this is the new cursor
SHIFT_RET:
		OR	DIRTY_BITS,1	;need to redraw the screen
		MOV	SI,CURSOR
		MOV	DX,CURS_POSN
		JMP	SHIFT_RIGHT	;move cursor to current column
		;(CALL/RETurn)
UP		ENDP

;=======================================================================
; These four routines move the screen one page at a time by calling the 
; UP and DOWN procedures.
;-----------------------------------------------------------------------
CTRL_PGDN	PROC	NEAR	;do PgDn then PgUp
		CALL	PGDN
		JMP	SHORT PGUP
		;(CALL/RETurn)
CTRL_PGDN	ENDP
;-----------------------------------------------------------------------
PGUP		PROC	NEAR
		MOV	CS:PAGE_PROC,OFFSET UP
		JMP	SHORT PAGE_UP_DN
PGUP		ENDP
;-----------------------------------------------------------------------
CTRL_PGUP	PROC	NEAR	;do PgUp then PgDn
		CALL	PGUP
;**		JMP	SHORT PGDN
		;(CALL/RETurn)
CTRL_PGUP	ENDP
;-----------------------------------------------------------------------
PGDN		PROC	NEAR
		MOV	CS:PAGE_PROC,OFFSET DOWN
PAGE_UP_DN:
		MOV	CL,CS:ROWS	;get vertical length of screen
		SUB	CL,5		;don't page a full screen
		XOR	CH,CH		;make it a word
PAGE_LOOP:
		PUSH	CX
		CALL	PAGE_PROC	;move the cursor down
		POP	CX
		LOOP	PAGE_LOOP	;loop for one page length
		RET
PGDN		ENDP

;=======================================================================
; This routine toggles the Insert/Overstrike mode.
;-----------------------------------------------------------------------
INSERT		PROC	NEAR
	;	ASSUME	DS:NOTHING
;**RO mode	NOT	CS:INSERT_MODE	;toggle the switch
		XOR	CS:INSERT_MODE,1 ;toggle the "I/O" switch
		CALL	REDO_PROMPT ;redraw the insert/overstrike status
		RET
INSERT		ENDP

;=======================================================================
; FILE MANIPULATION services
;=======================================================================
; This routine forces the insertion of the NUL character, 00H, in the file.
;-----------------------------------------------------------------------
NUL_CHAR	PROC	NEAR
		XOR	AX,AX
NUL_CHAR	ENDP

;-----------------------------------------------------------------------
; This routine adds a character into the file.  In insert mode, remaining 
; characters are pushed forward.  If the scan code for <Enter> is detected, 
; a <CR><LF> pair is added as the EOL marker.  If the scan code for 
; <Backspace> is detected, the character to the left of the cursor is 
; deleted (unless the cursor is already at the start of the file).  
;-----------------------------------------------------------------------
INSERT_KEY	PROC	NEAR
		ASSUME	DS:FILE_SEG
		MOV	SI,CS:CURSOR

		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JA	FILE_FULL	;jump if read-only file

		CMP	AH,28		;was this the <Enter> key scan code?
		JE	NEW_LINE	;if yes, make new line: <CR><LF>.

		CMP	AH,14		;was it the <Backspace> key scan code?
		JE	BACK_SPACE	;if yes, delete character left.

		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JE	INSERT_CHAR	;jump if Insert
		;-----------------------
		; test for overstrike character at end of line or file.
		; if EOL or EOF, then insert rather than overstrike.
		;-----------------------
		CMP	SI,CS:LAST_CHAR	;at end of file?
		JAE	INSERT_CHAR
		INC	SI
		CMP	SI,CS:LAST_CHAR	;at end of file?
		DEC	SI
		JAE	INSERT_CHAR
		CMP	WORD PTR [SI],CRLF ;at end of line?
		JE	INSERT_CHAR

OVERSTRIKE_NOT_AT_CRLF:
		MOV	DI,SI
		PUSH	AX		;save new character
		XCHG	DS:[SI],AL	;switch new character for old one
		CALL	SAVE_CHAR	;store the old character
		POP	AX		;get back new character
		JMP	SHORT ADVANCE
;---------------------------------------
INSERT_CHAR:
		PUSH	SI
		PUSH	AX		;save the new character
		MOV	AX,1
		CALL	OPEN_SPACE	;make room for it at SI
		POP	AX		;get back the new character
		POP	DI
		JC	FILE_FULL
		STOSB			;insert character in file buffer, ES:DI
ADVANCE:
		OR	CS:DIRTY_BITS,4	;current line is dirty

		;-----------------------
		; see if we made a CR-LF pair by adding a Ctrl-M with a Ctrl-J
		;-----------------------
		CALL	C_IF_NEW_CRLF	;see if in middle of new CR-LF
		JC	FILE_FULL	;jump if new line was done
		;------------------------
		CMP	AL,CR		;was key <Ctrl-M> - CR?
		JNE	INS_NOT_CR
		MOV	CS:DIRTY_BITS,1	;redraw the screen (just in case EOL)
INS_NOT_CR:
		;-----------------------
		PUSH	UNDO_LENGTH
		CALL	RIGHT		;move cursor to next letter
		POP	UNDO_LENGTH
FILE_FULL:
		RET

CR_AT_EOF:
		INC	CS:CURSOR
		RET

;---------------------------------------
; process the <Enter> key, make new line
;---------------------------------------
NEW_LINE:
		PUSH	SI
		MOV	AX,2
		CALL	OPEN_SPACE	;make space for CR and LF
		POP	DI		;get back old cursor location
		JC	FILE_FULL
		MOV	AX,CRLF 	;LF*256+CR
		STOSW			;store the CR and LF
		JMP	SHORT ADVANCE_NEW_LINE ;repaint the screen
		;(CALL/RETurn)
INSERT_KEY	ENDP

;---------------------------------------
; process the <Backspace> key, delete character left of cursor.
;---------------------------------------
BACK_SPACE	PROC	NEAR
		OR	SI,SI		;is cursor at start of file?
		JZ	FILE_FULL	;if so, no delete right
		CALL	LEFT		;move left one space (flush UnDo buffer)
;**follows	JMP	DEL_CHAR	;and delete the character (into buffer)
		;(CALL/RETurn)
BACK_SPACE	ENDP

;=======================================================================
; This routine deletes the character at the cursor by shifting the remaining 
; characters forward.  <Del> key
;-----------------------------------------------------------------------
DEL_CHAR	PROC	NEAR
		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JA	NO_DEL		;jump if read-only file
		MOV	CX,LAST_CHAR
		MOV	SI,CURSOR
		MOV	DI,SI
		CMP	SI,CX		;are we at end of file?
		JAE	NO_DEL		;if yes, then don't delete
		LODSB			;loads char in AL, DS:SI
		CALL	SAVE_CHAR	;save it for UNDO function
		MOV	AH,[SI]		;look at the next character also
		PUSH	AX		;save character we're deleting
		DEC	LAST_CHAR	;shorten the file by one
		SUB	CX,SI
		REP	MOVSB		;move file down one, DS:SI to ES:DI

		POP	AX		;get back character we deleted
		CMP	AX,CRLF		;did we delete a CR?
		JE	COMBINE
		OR	DIRTY_BITS,4	;current line is dirty
		;-----------------------
		; see if we made a CRLF by deleting a character.
		; if we are in the middle of a CRLF, move the cursor back one.
		;-----------------------
		JMP	SHORT C_IF_NEW_CRLF
		;(CALL/RETurn) - saves a byte
;---------------------------------------
COMBINE:				;deleted an EOL marker, CR-LF
		CALL	DEL_CHAR	;now delete the line feed (recursive)
                MOV     DIRTY_BITS,3
                MOV     DX,CURS_POSN
		MOV	SAVE_COLUMN,DL	;save the cursor column
NO_DEL:
		RET
DEL_CHAR	ENDP

;=======================================================================
; see if we made a CR-LF pair with the cursor located on the LF character 
; by joining the character (Ctrl-M) with a (Ctrl-J).  If so, back up the 
; cursor and open a new line and return with carry set.  if not, return with 
; carry clear.
;-----------------------------------------------------------------------
C_IF_NEW_CRLF	PROC	NEAR
		MOV	SI,CS:CURSOR	;present cursor location
		OR	SI,SI		;is it at start of file
		JZ	DONE_CRLF
		CMP	WORD PTR [SI-1],CRLF ;did we make CR-LF?
		JNE	DONE_CRLF
		DEC	CS:CURSOR	;move cursor back to point at CR code
C_IF_NEW_CRLF	ENDP

;---------------------------------------
; This routine opens a new line.
;---------------------------------------
ADVANCE_NEW_LINE PROC	NEAR		;split line on screen for CR-LF
		CALL	HOME		;cursor to start of line
		CALL	DOWN		;move down to the new line
		MOV	DIRTY_BITS,3	;repaint the screen and cursor
		STC			;C=1 if new line was done
		RET
DONE_CRLF:
		CLC			;C=0 if not new line
		RET
ADVANCE_NEW_LINE ENDP

;=======================================================================
; This routine restores any characters which have recently been deleted.
;-----------------------------------------------------------------------
UNDO		PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		XOR	AX,AX
		XCHG	AX,CS:UNDO_LENGTH ;get buffer length
		MOV	SI,OFFSET UNDO_BUFFER
		JMP	INSERT_STRING
		;(CALL/RETurn)
UNDO		ENDP

;=======================================================================
; This routine inserts spaces into the file buffer.  On entry, AX
; contains the number of spaces to be inserted.  On return, CF=1 if 
; there was not enough space in the file buffer.
;-----------------------------------------------------------------------
OPEN_SPACE	PROC	NEAR
	;	ASSUME	DS:FILE_SEG
		MOV	CX,LAST_CHAR	;last character in the file
		MOV	SI,CX
		MOV	DI,CX
		ADD	DI,AX		;offset for new end of file
		JC	NO_ROOM		;if no more room, return error
		MOV	LAST_CHAR,DI	;save offset of end of file
		SUB	CX,CURSOR	;number of characters to shift
		DEC	DI
		DEC	SI
		STD			;string moves goes forward
		REP	MOVSB		;shift the file upward
		CLD
		MOV	BYTE PTR DIRTY_FILE,0FFH ;file has been altered
		CLC
NO_ROOM:				;carry is set if no room in file
		RET
OPEN_SPACE	ENDP

;=======================================================================
; This routine adds a character to the UNDO buffer.
;-----------------------------------------------------------------------
SAVE_CHAR	PROC	NEAR
		MOV	BX,UNDO_LENGTH
		OR	BH,BH		;is buffer filled?
		JNZ	NO_SAVE		;buffer overflowed, no insert
		INC	UNDO_LENGTH
		MOV	BYTE PTR CS:UNDO_BUFFER[BX],AL
		MOV	BYTE PTR CS:DIRTY_FILE,0FFH ;file altered
NO_SAVE:
		RET
SAVE_CHAR	ENDP

;=======================================================================
; This routine deletes from the cursor position to the end of the line.
;-----------------------------------------------------------------------
DEL_EOL		PROC	NEAR
		;-----------------------
		; from TEDPLUS,  modified by JEG, delete line if at column 1.
;**Shft-F8	MOV	CX,CURSOR_POSN
;**Shft-F8	JCXZ	DEL_L
		;-----------------------
		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JA	NO_DEL_L	;jump if read-only file
		MOV	LINE_FLAG,0
		PUSH	CURSOR		;save starting cursor location
		CALL	ENDD		;move to the end of the line
		POP	SI		;get back starting cursor
		MOV	CX,CURSOR	;offset of end of line
		MOV	CURSOR,SI	;restore starting cursor
		JMP	SHORT DEL_END	;delete characters to end of line
		;(CALL/RETurn)
DEL_EOL		ENDP

;-----------------------------------------------------------------------
; This routine deletes a line, placing it in the line buffer. <F9>, <Shft-F8>
;-----------------------------------------------------------------------
DEL_L		PROC	NEAR
		CMP	CS:INSERT_MODE,1 ;in insert mode? (0=ovr,1=ins,2 or 3=RO)
		JA	NO_DEL_L	;jump if read-only file
 		MOV	LINE_FLAG,1
		CALL	FIND_START	;find start of this line
		MOV	CURSOR,SI	;this will be the new cursor
		PUSH	SI		;save the cursor position
		CALL	FIND_NEXT	;find the next line
		MOV	CX,SI		;CX will hold line length
		POP	SI		;get back new cursor location
DEL_END:
		MOV	BYTE PTR DIRTY_FILE,0FFH ;file has been altered

		SUB	CX,SI		;number of bytes on line
		OR	CH,CH		;is line too long to fit?
		JZ	NOT_TOO_LONG
		MOV	CX,100H		;save only 256 characters
NOT_TOO_LONG:
		MOV	LINE_LENGTH,CX	;store length of deleted line
		JCXZ	NO_DEL_L
		MOV	DI,OFFSET LINE_BUFFER ;buffer for deleted line

		PUSH	CX
		PUSH	ES
		PUSH	CS
		POP	ES		;line buffer is in CSEG

⌨️ 快捷键说明

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