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

📄 e3.asm

📁 e3 是一个全屏的用户友好的文本编辑器
💻 ASM
📖 第 1 页 / 共 5 页
字号:
; side effect: sets 'columne' for RestoreStatusLine function (displays column); variable kurspos: for placing the cursor at new position; register bh counts lines; register bl counts columns visible on screen (w/o left scrolled); register edx counts columns in text lines; register ecx screen line counter and helper for rep stos; register esi text index; register edi screen line buffer index;DispNewScreen:test byte [mode], EM | PI | NE	jz NoEmBlock	mov ecx,[showblock]		;transfering Emacs's mark/point into....	jecxz NoEmBlock			;....WS's block display system	mov ecx,[EmaMark]	jecxz NoEmBlock	mov eax,edi	cmp ecx,eax	jb EmBlock	xchg eax,ecxEmBlock:mov [blockbegin],ecx	mov [blockende ],eax;-------NoEmBlock:call GetEditScreenSize	;check changed tty size	xor eax,eax	mov byte[isbold],al	mov byte[inverse],al	mov [zloffst],eax	mov [columne],eax	mov [fileptr],edi		;for seeking current cursor pos	push edi			;&&**##	call CountColToLineBeginVis	;i.e. expanding TABs	mov ebx,[columns]	lea ebx,[ebx-4]			;03 Jun 2001	cmp eax,ebx	jb short DispShortLine	sub eax,ebx	inc eax	mov [zloffst],eaxDispShortLine:call LookPgBegin 		;go on 1st char upper left on screen	mov esi,edi			;esi for reading chars from text	mov ecx,[lines]	jecxz Kviex	cld	mov bh,-1			;first lineDispNewLine:inc bh			;new line	mov edi,screenline		;line display buffer	xor edx,edx			;reset char counter	mov bl,0 			;reset screen column to 0%ifdef LESSWRITEOPS	call SetColor2			;set initial character color per each line%endifDispCharLoop:	cmp esi,[fileptr]		;display char @ cursor postion ?	jnz DispCharL1	cmp byte[tabcnt],0	jnz DispCharL1	mov [kurspos],ebx	mov byte [columne],bl	mov eax,[zloffst]		;chars scrolled left hidden	add [columne],eax%ifdef CURSORMGNT	stc	call SetInverseStatus	jnc DispEndLine%endifDispCharL1:call SetColor		;set color if neccessary;-------DispEndLine:cmp esi,ebp	ja FillLine			;we have passed EOF, so now fill rest of screen	cmp byte[tabcnt],0	jz ELZ	dec byte[tabcnt]	jmp short ELZ2ELZ:	cmp esi,ebp	jnz ELZ6	inc esi				;set esi>ebp will later trigger  "ja FillLine"	jmp short ELZ2ELZ6:	lodsb	cmp al,TABCHAR	jnz ELZ3	call SpacesForTab		;ah = space_up_to_next_tab location	dec ah				;count out the tab char itself	mov byte[tabcnt],ahELZ2:	mov al,SPACECHARELZ3:	cmp al,NEWLINE	jz FillLine%ifdef W32LF	cmp al,RETURN	jz ELZ5				;keep 0dh "invisible"%endif	cmp al,SPACECHAR	jae ELZ9			;simply ignore chars like carriage_return etc.	mov al,'.'ELZ9:	%ifndef W32	cmp al,7fh	jb ELZ7	cmp al,9Fh	ja ELZ7	mov al,'.'ELZ7:	%endif	cmp bl,byte [columns]		;screen width	jae DispEndLine			;continue reading line until end	inc edx				;also count hidden chars (left margin)	cmp edx,[zloffst]	jbe ELZ5			;load new char (but no display)	stosB%ifdef CURSORMGNT	clc	call SetInverseStatus%endif	inc bl				;counts displayed chars onlyELZ5:	jmp DispCharLoop;-------FillLine:push ecx			;continue rest of line	mov ecx,[columns]		;width	sub cl,bl	mov al,SPACECHAR		;fill with blanks	jecxz FillLine2	cmp byte[inverse],1		;special cursor attribute?	jnz FillLine1	stosB				;only 1st char with special attribute%ifdef CURSORMGNT	clc	call SetInverseStatus%endif	dec ecx				;one char less	jz FillLine2FillLine1:	rep stosB			;store the rest blanksFillLine2:pop ecx	mov byte[edi],0	call ScreenLineShow	dec ecx	jnz near DispNewLine	pop edi				;&&**##	;OLD: mov edi,[fileptr]	;=restore text pointer	jmp RestKursPos;----------------------------------------------------------------------; three helper subroutines called by DispNewScreen; dealing ESC sequences for character attributes; %ifdef CURSORMGNTSetInverseStatus:	push ecx		;returns zero flag	push esi	jnc SIS1	cmp byte [insstat],1	stc	jnz SIS4	mov byte[inverse],1	mov esi,reversevideoX	add esi,[revvoff]		;switch between esc seq for linux or Xterm	jmp short SIS2SIS1:	cmp byte[inverse],1	jnz SIS3	mov byte[inverse],0;-------continued...%endif;------; next presented in 2 versions: one for Win32, one for Terminals;%ifdef W32 ;------------- this can't be done via ESC seq ----------------SIS6:	mov byte[isbold],0SIS5:	mov eax,DARKWHITESIS2:	mov ecx,edi	sub ecx,screenline	mov edx,ecx			;current pos in columne	shl ecx,1	mov edi,attribline	add edi,ecx	mov ecx,[columns]	sub ecx,edx			;only current pos up to line end	rep stoswSIS3:	clcSIS4:	popa	retSetColor:				;expects cy flag:bold /  nc:normal	pusha	call IsShowBlock	jnc SCEsc1	cmp byte [isbold],1		;never set bold if it is already bold	jz SIS4	mov byte [isbold],1SCEsc2:	mov eax,WHITE	jmp short SIS2SCEsc1:	cmp byte [isbold],0		;ditto	jz SIS4	jmp short SIS6;-------SetColor2:pusha	call IsShowBlock	jnc SIS5	jmp short SCEsc2%else ;---------------------- TERMINAL part -----------------------------SIS6:	mov byte[isbold],0SIS5:	mov esi,bold0SIS2:	push byte boldlen	pop ecx	rep movsbSIS3:	clcSIS4:	pop esi	pop ecx	ret;-------SetColor:push ecx			;expects cy flag:bold /  nc:normal	push esi	call IsShowBlock	jnc SCEsc1	cmp byte [isbold],1		;never set bold if it is already bold	jz SIS4	mov byte [isbold],1SCEsc2:	mov esi,bold1	jmp short SIS2SCEsc1:	cmp byte [isbold],0		;ditto	jz SIS4	jmp short SIS6;-------%ifdef LESSWRITEOPSSetColor2:	push ecx	push esi	call IsShowBlock	jnc SIS5	jmp short SCEsc2%endif%endif ;----------------- end of double part -----------------------------;;-------; a little helper for SetColor* functions;IsShowBlock:cmp byte [showblock],0	je SBlock	cmp dword [blockbegin],0	je SBlock	cmp [blockbegin],esi	ja SBlock	cmp esi,[blockende]	jb SB_retSBlock:	clcSB_ret:	ret;-------; this helper for DispNewScreen checks screen size before writing on screen; FIXME: adjusting edit screen resize works with xterm, but not with SVGATextMode;GetEditScreenSize:%ifdef W32	push dword csbi	push dword [hout]	call GetConsoleScreenBufferInfo	or eax,eax	mov eax,[csbi]	jnz noerr	mov eax,0x00190050		;i.e. (80<<16)+24  (assume 80x25)noerr:	mov byte [columns],al	shr eax,16	dec eax	mov byte [lines],al		;columns > 255 are ignored...	ret%else	mov ecx,TERMIOS_WSIZE	mov edx,winsize	call IOctlTerminal	mov eax,[edx]			;each 16 bit lines,columns	cmp eax,0x0000FFFF		;some give no columns info..?	jb iserr 	or eax,eax 	jnz noerriserr: 	mov eax,0x00500018		;i.e. (80<<16)+24  (assume 80x24)noerr:	dec eax				;without status line ('dec al' are 2 byte!)	mov byte [lines],al	shr eax,16	mov byte [columns],al		;columns > 255 are ignored...	ret%endif;----------------------------------------------------------------------;; LOWER LEVEL screen acces function (main +2 helpers); this function does write the line buffer to screen i.e. terminal;; at first 2 special entry points:WriteTwo:mov [screenline],ecxStatusLineShow:%ifdef W32	push edi	mov ecx,[columns]	shr ecx,1	mov eax,YELLOW_BLUE_TWICE	mov edi,attribline	rep stosd	pop edi	mov edx,[kurspos2]	call sys_writeKP		;set cursor pos before reading chars%endif	xor ecx,ecx			;0 for bottom line;-------ScreenLineShow:pusha			;expecting in ecx screen line counted from 0%ifdef LESSWRITEOPS%ifdef W32				;screen attrib caching	mov eax,[columns]	mul ecx				;setting edx to 0	mov ebx,edx			;flag	lea edi,[eax+attribbuffer]	cld	mov esi,attriblineXsl3:	lodsw	cmp edi,attribbuffer_end	;never read/write beyond buffer	jnb Xsl5	cmp ax,[edi]	jz Xsl4	mov [edi],axXsl5:	inc ebx				;set flag whether line need redrawingXsl4:	inc edi	inc edi	or al,al	jnz Xsl3%else	xor ebx,ebx			;flag%endif;-------	mov eax,[columns]	lea eax,[eax+32]		;estimated max ESC sequences extra bytes (i.e. boldlen*X) (BTW add eax,32 islonger)	mul ecx				;setting edx to 0	lea edi,[eax+screenbuffer]%else	xor edx,edx			;counter%endif	cld	mov esi,screenlinesl3:	lodsb	inc edx				;count message length to write%ifdef LESSWRITEOPS	cmp edi,screenbuffer_end	;never read/write beyond buffer	jnb sl5	cmp al,[edi]	jz sl4	mov [edi],alsl5:	inc ebx				;set flag whether line need redrawingsl4:	inc edi%endif	or al,al	jnz sl3	dec edx				;one too much%ifdef LESSWRITEOPS	or ebx,ebx			;redraw ?	jz NoWrite%endif	push edx	xor edx,edx	mov dh,byte [lines]	sub dh,cl%ifdef W32_EXTENDED_IO	pop ebx				;len	shl edx,8	and edx,00ff0000h		;only line# (column is always 0)	push edx			;cursor data;-------	push dword w32result	push edx			;cursor	push ebx			;length	push dword screenline	push dword [hout]	call WriteConsoleOutputCharacterA;-------	pop edx	push dword w32result	push edx			;cursor	push ebx			;length	push dword attribline	push dword [hout]	call WriteConsoleOutputAttribute%else	;this works on both Terminal and W32, ...	;...but is suboptimal and slow on W32	call sys_writeKP		;set cursor pos before writing the line	pop edx	push ecx	mov eax,screencolors1		;set bold yellow on blue	call sys_writeSLColors		;special for status line (ecx==0)	mov ecx,screenline		;second argument: pointer to message to write	call WriteFile0;-------	pop ecx	mov eax,screencolors0		;reset to b/w	call sys_writeSLColors		;special for status line (ecx==0)	mov edx,[kurspos2]	call sys_writeKP		;restore old cursor pos%endifNoWrite:popa	ret;-------; a helper for ScreenLineShow;sys_writeSLColors:%ifndef W32	jecxz syswSL			;do nothing if not in status line	retsyswSL:	pusha	xchg eax,ecx			;parameter points to ESC-xxx color string	push byte scolorslen	pop edx	call WriteFile0	popa%endif	ret;----------------------------------------------------------------------;; getting line INPUT from terminal / UNDER CONSTRUCTION;; expecting pointer to message text in esi;InputStringWithMessage0:mov esi,extextInputStringWithMessage:call WriteMess9MakeLine	mov ecx,optbuffer	push byte optslen	pop edx	jmp short InputString;-------InputString00:mov ecx,suchtextInputString0:call WriteMess9MakeLine	mov edx,maxfilenamelen; expecting input line buffer in ecx; expecting max count byte in edx; return length in eax, CY for empty string (or user abort);InputString:push ecx	push edi	push byte 2	pop eax	xchg eax, [VICmdMode]	push eax			;LONGER: push dword [VICmdMode], mov byte [VICmdMode],2	push dword [kurspos2]	mov ebx,[columns]	lea ebx,[ebx-stdtxtlen]	cmp edx,ebx			;TODO enable some scrolling:	jb IS8				;not yet ready, so truncate at end of line	mov edx,ebxIS8:	xor ebx,ebx	mov edi,ecxIS0:	push ebx	push edx	add bl,stdtxtlen		;offset+column	mov bh,byte[lines]		;line#	mov [kurspos2],ebx%ifdef LESSWRITEOPS	mov byte [screenbuffer],0	;switching off usage of buffer v0.7%endif	call StatusLineShow	call GetChar	pop edx	pop ebx	cld;-------	call IsViMode	jnz NO_VI01	cmp al,0	je ISANO_VI01:	call CheckUserAbort	jne IS9ISA:	xor ebx,ebx			;length 0 triggers CY flag	jmp short IS1IS9:	cmp al,RETURN	je IS1	cmp al,8			;^H (translated DEL)	jne IS2	or ebx,ebx			;@left border?	jz IS0	dec ebx	dec edi	mov al,SPACECHAR	mov byte [ebx+screenline+stdtxtlen],al	jmp short IS0;-------IS2:	cmp al,SPACECHAR	jb IS0	stosb	mov byte [ebx+screenline+stdtxtlen],al		;ditto	inc ebx	cmp ebx,edx	jb IS0;-------IS1:	xor eax,eax	stosb				;make asciz string	pop dword [kurspos2]	pop dword [VICmdMode]		;restore original vi mode	pop edi	pop ecx	xchg eax,ebx	cmp al,1			;set cy flag if empty string (len always <256)ISready:ret				;eax length (but is < 255);----------;; GetChar (main function for kbd input);ReadChar:mov eax,edi	xchg eax,[old] 			;for ^QP	mov [veryold],eaxGetChar:call ReadOneChar		;ah=0xFF for usual keys%ifdef W32	cmp ah,0FEh			;cursor key			jnz GC33	shl eax,8	retGC33:	cmp ah,0FDh			;ALT key	jnz GC34	and al,5fh			;toupper	jmp short NOVI7GC34:%endif	cmp al,7FH	jne short RC_No7F		;special case: remap DEL to Ctrl-H%ifndef FREEBSD	mov al,8%else	mov al,7%endifRC_No7F:;-------%define DoNo 10;-------;; vi needs special handling of the ESC key;	call IsViMode	jz short ISVI7	cmp al,27 			;ESC ?	jnz ISready	call ReadOneChar		;dont care whether '[' or 'O' (should be [ for vt220 family  O for vt100 family)	jmp short NOVI7;-------ISVI7:	cmp byte [VICmdMode],1	jne NoCMDmode	cmp al,27	je ESCpressed	cmp al,VIsize	ja near Other	mov ebx,VIcmdTable		;process command mode keys......	jmp RCready_0			;....and ready;-------ESCpressed:call ReadOneChar	cmp al,'['			;decide: it's a cursor key?	je near Other			;yes, contine	jmp short NoCursorKey		;no push back char into buffer and exitNoCMDmode:cmp al,27 			;ESC ?	jnz ISready	call KeyVImode1			;ESC pressed in EDIT Mode%ifdef BEOS	call RestoreStatusLine%else%ifdef SYS_select	pusha	call Select			;differ between ESC and ESC_cursor_keys	popa	jz isSingleEscape%endif%endif	call ReadOneChar	cmp al,'['			;starting sequence of cursor key found?	je IsCursorKey			;pressed ESC, but do _NOT_ switch init cmd modeNoCursorKey:mov byte [VIbufch],al	;push char back into read buffer due it's not a cursor key	mov al,DoNo			;do nothing	jmp short JmpRCreadyisSingleEscape:mov al,3			;3 is keyLeft (i.e. entry #3 jumptab1)	jmp short JmpRCready		;keyLeft is what a real vi user expects here ;);-------IsCursorKey:call KeyVImode0		;reset mode to 'no_command' and continue;-------NOVI7:	cmp byte [mode],NE		;ALT keys are currently used for nedit mode...	jnz NONE7	cmp al,'i'	jnz NOi	mov al,0x10	jmp short JmpRCreadyNOi:	cmp al,'I'	jnz NONE7	mov al,0x10	jmp short JmpRCreadyNONE7:	call IsEmMode	jnz NOEM7			;ALT keys are currently used for Emacs mode...	cmp al,'%'			;...except altH for online Help	jne NoAltPer	mov al,0x28JmpRCready:jmp short RCready_1NoAltPer:cmp al,'<'	jne NoAltLt	mov al,0x0e	jmp short RCready_1NoAltLt:cmp al,'>'	jne NoAltGt	mov al,0x0f	jmp short RCready_1NoAltGt:and al,0x5F			;to upper case	sub al,'B'			;1at in table	js Other	cmp al,ATsize	ja Other	mov ebx,EmaAltTable

⌨️ 快捷键说明

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