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

📄 ted2.asm

📁 一个很小的用汇编写的编辑器
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		ASSUME	DS:CSEG
		MOV	STATUS_REG,AX
		CMP	AX,3BAH		;is this a MONO display?
		JNE	COLOR		;if not, must be a CGA
		MOV	WORD PTR HWAIT,NO_DESNOW ;get rid of desnow
		JMP	SHORT MOVE_STACK

COLOR:
		MOV	VIDEO_SEG,0B800H ;segment for color card
		XOR	BH,BH		;use page zero
		MOV	AH,8		;get current attribute
		INT	10H
		AND	AH,77H		;turn off blink and high intensity
		MOV	NORMAL,AH	;save the normal attribute
		XOR	AH,01110111B	;flip the color bits
		MOV	INVERSE,AH
		OR	AH,80H
		MOV	SRCH_CLR,AH	;search is inverse/blink
MOVE_STACK:
		MOV	BX,OFFSET END_BUFFER
;**rounding	ADD	BX,15		;add offset value for SEG rounding up
		MOV	CL,4		;convert program size to 
		SHR	BX,CL		; paragraphs
		MOV	AH,4AH		;deallocate unused memory
		INT	21H		;DOS call
		MOV	BX,1000H	;request 64K for file segment
		MOV	AH,48H
		INT	21H		;DOS call
		MOV	ES,AX
		ASSUME	ES:FILE_SEG
		MOV	AH,48H		;request 64K for paste buffer
		INT	21H		;DOS call
		JNC	GOT_ENOUGH	;if enough memory, continue
NOT_ENOUGH:
		MOV	DX,OFFSET MEMORY_ERROR

EXIT_2_DOS:	JMP	EXIT_TO_DOS	;jump island to allow SHORT jumps.
		;-----------------------
GOT_ENOUGH:
		MOV	PASTE_SEG,AX	;use this for the paste buffer
GET_FILENAME:
		MOV	SI,80H		;point to command tail in PSP
		MOV	CL,[SI]		;get number of characters in tail
		XOR	CH,CH		;make it a word
		INC	SI		;point to first character
		PUSH	SI
		ADD	SI,CX		;point to last character
		MOV	BYTE PTR [SI],0	;make it an ASCIIZ string (clear the CR)
		MOV	NAME_END,SI	;save pointer to last character
		POP	SI		;get back pointer to filename
		JCXZ	NO_FILENAME	;if no params, just exit
		CLD
DEL_SPACES:
		LODSB			;get character into AL
		CMP	AL," "		;is it a space?
		JNE	FOUND_LETTER
		LOOP	DEL_SPACES
FOUND_LETTER:
		DEC	SI		;backup pointer to first letter
		MOV	NAME_POINTER,SI	;save pointer to filename

		MOV	DX,NAME_POINTER
		MOV	AX,4300H	;get file attribute byte (in CL)
		INT	21H		;DOS call
		JC	ATTRIB_ERROR
		AND	CL,1		;keep bit-0, read-only status
		ADD	CL,CL		;shift RO bit up 
		OR	INSERT_MODE,CL	;save as index modifier value
ATTRIB_ERROR:
		MOV	DX,SI
		MOV	AX,3D00H	;setup to open file
		INT	21H		;DOS call
		; If no carry, Then the opened file handle is in AX
		; If no carry, Then the opened file handle is in AX
		JC	NO_FILENAME	;if we can't open, must be new file
FILE_OPENED:
		PUSH	ES
		POP	DS		;DS has file segment also
		ASSUME	DS:FILE_SEG
		MOV	BX,AX		;get the handle into BX
		XOR	DX,DX		;point to file buffer, DS:DX
		MOV	CX,0FFFEH	;read almost 64K bytes
		MOV	AH,3FH		;read from file or device
		; BX = file handle
		INT	21H		;DOS call
		; If no carry, Then AX contains number of bytes read
		MOV	DI,AX		;number of bytes read in
		JNC	FILE_READ_OK	;if no error, take jump
		MOV	DX,OFFSET READ_ERR_MESS
		;-----------------------
		; the file has been opened, it should now be closed. (JEG)
		;-----------------------
CLOSE_ERR_EXIT:
		MOV	AH,3EH		;close the opened file
		; BX = file handle
		INT	21H
		JMP	SHORT EXIT_2_DOS
		;-----------------------
FILE_READ_OK:
		MOV	LAST_CHAR,DI	;save the file size
		CMP	CX,AX		;did the buffer fill?
		MOV	DX,OFFSET FILE_TOO_BIG
		JE	CLOSE_ERR_EXIT	;if yes, it is too big
		MOV	AH,3EH		;close the file
		; BX = file handle
		INT	21H
;**dirty	MOV	BYTE PTR CS:DIRTY_FILE,0 ;file opened but not altered.
NO_FILENAME:
		PUSH	ES
		PUSH	ES		;save the file segment
		PUSH	CS
		POP	DS
		ASSUME	DS:CSEG
		;-----------------------
		;INT 24 is the critical error handler
		;-----------------------
		MOV	AX,3524H	;get INT 24 vector
		INT	21H		;DOS call
		MOV	WORD PTR OLDINT24,BX   ;store the offset
		MOV	WORD PTR OLDINT24+2,ES ;and the segment
		MOV	DX,OFFSET NEWINT24 ;point to new vector
		MOV	AX,2524H	;now change INT 24 vector
		INT	21H		;DOS call
		;-----------------------
		;INT 23 is the CTRL-Break or CTRL-C handler
		;-----------------------
		MOV	DX,OFFSET NEWINT23
		MOV	AX,2523H	;set the INT 23 vector
		INT	21H		;DOS call

		POP	ES		;get back file segment
		POP	DS
		ASSUME	DS:FILE_SEG
		CALL	REDO_PROMPT	;draw the prompt line

;-----------------------------------------------------------------------
; Here's the main loop.  It updates the screen, then reads a keystroke.
;-----------------------------------------------------------------------
READ_A_KEY:
		CMP	MARK_MODE,0	;is the mark state on?
		JZ	MARK_OFF	;if not, skip this
		OR	DIRTY_BITS,4	;refresh the current row
		MOV	DX,CURS_POSN
		CMP	SAVE_ROW,DH	;are we on the save row?
		JE	SAME_ROW	;if yes, then redo the row only
		OR	DIRTY_BITS,1	;refresh the whole screen
SAME_ROW:
		MOV	AX,CURSOR	;get cursor location
		MOV	BX,MARK_HOME	;get the anchor mark position
		CMP	AX,BX		;moving backward in file?
		JAE	SAME1
		MOV	MARK_START,AX	;switch start and end positions
		MOV	MARK_END,BX
		JMP	SHORT MARK_OFF
SAME1:
		MOV	MARK_END,AX	;store start and end marks
		MOV	MARK_START,BX
MARK_OFF:
		CALL	DISPLAY_SCREEN	;redraw the screen

                XOR     AH,AH           ;read the next key (wait if none ready)
		INT	16H		;BIOS call
		; AL = ASCII code or 0 (for function keys)
		; AH = scan code
                TEST    SRCH_FLG,0FFH
		JZ	CHECK_KEY	;jump if inverse not on
		MOV	SRCH_FLG,0	;turn off highlight
		OR	DIRTY_BITS,1	;redraw screen (next time)
CHECK_KEY:
		OR	AL,AL		;is this an extended code?
		JZ	IS_EXTENDED_CODE ;(jump if not an ASCII character)
 		CALL	INSERT_KEY	;put this ASCII character in the file
;**short	JMP	READ_A_KEY	;get another key
		JMP	SHORT RD_NEXT_KEY ;get another key
;---------------------------------------

IS_EXTENDED_CODE:
		;-----------------------
		; The following code is for "orphan" key codes and alias keys
		;-----------------------
		CMP	AH,132		;is it Ctrl-PgUp? (an orphan code)
		JNE	NOT_CT_PGUP
		CALL	CTRL_PGUP
;**short	JMP	READ_A_KEY
		JMP	SHORT RD_NEXT_KEY ;get another key
		;-----------------------
NOT_CT_PGUP:
		CMP	AH,32		;is it Alt-D (MultiEdit Del-EOL)?
		JNE	NOT_ALT_D
		MOV	AH,66		;substitute scan code for F8
NOT_ALT_D:
		CMP	AH,31		;is it Alt-S (BSE string search)?
		JNE	NOT_ALT_S
		MOV	AH,64		;substitute scan code for F6
NOT_ALT_S:
		CMP	AH,30		;is it Alt-A (BSE search again)?
		JNE	NOT_ALT_A
		MOV	AH,89		;substitute scan code for Shft-F6
NOT_ALT_A:
		;-----------------------
		; The following code sets up a PASCAL style CASE statement.
		;-----------------------
		CMP	AH,DISPATCH_END	;split the dispatch table
		JB	DO_DISPATCH
		;-----------------------
		; offset cursor group of keys to join the regular dispatch table.
		;-----------------------
		CMP	AH,DISP_CURS_BASE
		JB	RD_NEXT_KEY
		CMP	AH,DISP_CURS_END
		JAE	RD_NEXT_KEY
		SUB	AH,LOW (DISP_CURS_BASE - DISPATCH_END) ;close table gap
DO_DISPATCH:
		;-----------------------
		; This is a PASCAL style CASE statement.
		;-----------------------
		MOV	BX,AX		;put AH offset value in BX, AL=0
		XCHG	BL,BH		;make into a proper word
		SUB	BX,DISPATCH_BASE ;zero offset for dispatch table jump
		JC	RD_NEXT_KEY	;too low, not in table
		ADD	BX,BX		;make into word
		CALL	CS:DISPATCH_TABLE[BX] ;call the key procedure
RD_NEXT_KEY:	JMP	READ_A_KEY	;then read another key


;=======================================================================
; KEYBOARD and CURSOR services
;=======================================================================
; These two routines shift the display right or left to allow editing 
; files which contain lines longer than 80 columns.  Starting with TED2, 
; they are proper subroutines.  
;-----------------------------------------------------------------------
SH_LEFT		PROC	NEAR
		CMP	LEFT_MARGIN,0	;at start of line already?
		JE	NO_SHIFT	;if yes,then don't shift
		SUB	LEFT_MARGIN,8	;move the window over
		JMP	SHORT SH_RETURN
SH_LEFT		ENDP
;-----------------------------------------------------------------------
SH_RIGHT	PROC	NEAR
		CMP	LEFT_MARGIN,255 - 8 ;past max allowable margin?
		JAE	NO_SHIFT	;then can't move any more
		ADD	LEFT_MARGIN,8	;this moves the margin over
SH_RETURN:
		CALL	CURSOR_COL	;compute column for cursor
		MOV	SAVE_COLUMN,DL	;save the current column
		OR	DIRTY_BITS,1	;redraw the screen
NO_SHIFT:
;**dispatch	JMP	READ_A_KEY
;**bad_key	RET
SH_RIGHT	ENDP

;-----------------------------------------------------------------------
; DISPATCH_TABLE calls to BAD_KEY now go here so that the stack can be 
; kept equallized.  
;-----------------------------------------------------------------------
BAD_KEY		PROC	NEAR
		RET
BAD_KEY		ENDP

;=======================================================================
; This routine moves the cursor to the top of the file.
;-----------------------------------------------------------------------
TOP		PROC	NEAR
		XOR	AX,AX		;get a zero into AX
		MOV	CURSOR,AX	;cursor to start of file
		MOV	TOP_OF_SCREEN,AX
		MOV	LEFT_MARGIN,AL	;move to far left margin
		MOV	CURS_POSN,AX	;home the cursor
		MOV	SAVE_COLUMN,AL	;save the cursor column
		MOV	DIRTY_BITS,3	;redraw the screen and cursor
		RET
TOP		ENDP

;=======================================================================
; This routine moves the cursor to the bottom of the file.
;-----------------------------------------------------------------------
BOTTOM		PROC	NEAR
		MOV	DH,ROWS		;get screen size
		MOV	SI,LAST_CHAR	;point to last character
		;-----------------------
		; from TEDPLUS
		DEC	SI
		;-----------------------
		MOV	LEFT_MARGIN,0	;set window to start of line
		CALL	LOCATE		;adjust the cursor screen position
		CALL	HOME		;move cursor to start of line
		MOV	DIRTY_BITS,1	;this will redraw the screen
		RET
BOTTOM		ENDP

;=======================================================================
; This routine moves the cursor to the start of the current line.
; If <HOME> key and already at start of line, move to start of previous line.
;-----------------------------------------------------------------------
HOME_KEY	PROC	NEAR
		CALL	LEFT		;back up one space, in case at home
HOME_KEY	ENDP

HOME		PROC	NEAR
		CALL	FIND_START	;find start of line
		MOV	CURSOR,SI	;save the new cursor
		MOV	SAVE_COLUMN,0	;save the cursor column

		MOV	BYTE PTR CURS_POSN,0 ;store the column number
		RET
HOME		ENDP

;=======================================================================
; These routines move the cursor right and left
;-----------------------------------------------------------------------
RIGHT		PROC	NEAR
		MOV	SI,CURSOR
		CMP	SI,LAST_CHAR	;at end of file?
		JE	LR_NO_CHANGE	;if yes, then can't move
		;-----------------------
		; from TEDPLUS
		INC	SI
		CMP	SI,LAST_CHAR	;at end of file?
		DEC	SI
		JAE	INC_RIGHT	;if yes, then increment
		CMP	WORD PTR [SI],CRLF ;is it CRLF?
		JE	MOVE_DOWN	;if yes, then move down to next line
INC_RIGHT:
		;-----------------------
		INC	CURSOR		;advance the cursor
		JMP	SHORT LR_RETURN
MOVE_DOWN:
		CALL	HOME		;move to start of line
		JMP	SHORT DOWN	;and move down one row
		;(CALL/RETurn)
RIGHT		ENDP
;-----------------------------------------------------------------------
LEFT		PROC	NEAR
		CMP	CURSOR,0	;at start of file?
		JZ	LR_NO_CHANGE	;then can't move left
		MOV	DX,CURS_POSN
		OR	DL,DL		;at first column?
		JZ	MOVE_UP		;if yes, then move up one
		DEC	CURSOR		;shift the cursor offset
LR_RETURN:
		CALL	CURSOR_COL	;compute column for cursor
		MOV	SAVE_COLUMN,DL	;save the cursor column
LR_NO_CHANGE:
		MOV	UNDO_LENGTH,0
		RET
		;-----------------------
MOVE_UP:
		CALL	UP		;move up to next row
		JMP	SHORT ENDD	;and move to end of line
		;(CALL/RETurn)
LEFT		ENDP

;-----------------------------------------------------------------------
; This routine moves the cursor to the end of the current line.
; If END key and already at end of line, move to end of next line.
;-----------------------------------------------------------------------
END_KEY		PROC	NEAR
		CALL	RIGHT		;move one space right, if at EOL
END_KEY		ENDP

ENDD		PROC	NEAR
		MOV	SI,CURSOR
		CALL	FIND_EOL	;find end of this line
		MOV	CURSOR,SI	;store the new cursor
		CALL	CURSOR_COL	;compute the correct column
		MOV	SAVE_COLUMN,DL	;save the cursor column
		RET
ENDD		ENDP

;-----------------------------------------------------------------------
; This routine moves the cursor down one row.  When the last row is reached, 
; the screen is shifted up one row.
;-----------------------------------------------------------------------
DOWN		PROC	NEAR
		MOV	UNDO_LENGTH,0
		MOV	DX,CURS_POSN
		CMP	DH,ROWS		;at bottom row already?
		MOV	SI,CURSOR	;get position in file
		JE	SCREEN_UP	;if at bottom, then scroll up
		CALL	FIND_NEXT	;find the start of next line
		JC	DOWN_RET	;if no more lines, then return
		MOV	CURSOR,SI

⌨️ 快捷键说明

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