📄 e3.asm
字号:
jmp short RCready_0NOEM7: and al,0x5F cmp al,'H' jnz Other mov al,0x3D jmp short RCready_1;-------Other: %ifdef W32 ret%else call ReadOneChar cmp al,'8' ja NoNumber push eax ;0,1,2....8 (i.e. 9 keys) call ReadOneChar xchg eax,ebx pop eax cmp bl,'~' ;if it's a number we expect following a '~' jne GetCharJmpNoNumber:sub al,'0' cmp al,9 jb IsNumber%ifdef QNX sub al,('@'-'0'-9) ;scantable starts with ESC[@%else sub al,('A'-'0'-9)%endif cmp al,9 jb GetCharJmp cmp al,STsize ja GetCharJmpIsNumber:mov ebx,ScanTable%endifRCready_0:xlatbRCready_1:shl eax,8 ;shift into ah (ah always != 0xFF) retGetCharJmp:jmp near GetChar;-------; called by ReadChar/GetChar;ReadOneChar:call IsViMode jnz NOVI4 xor eax,eax xchg eax,[VIbufch] ;preread char in buf? or eax,eax jne RoneCNOVI4: mov ecx,read_b ;pointer to buf xor edx,edx inc edx ;mov edx,1 (length) call ReadFile0%ifdef SELFTEST ;for NON_INTERACTIVE mode exit on EOF! jnz Cont jmp KeyCtrlKXCont:%endif mov eax,[ecx] ;[read_b]%ifdef W32_EXTENDED_IO ret%endifRoneC: mov ah,0xFF ret;----------------------------------------------------------------------;; L O O K functions; search special text locations and set register edi to;LookBackward: ;set EDI to 1 before LINEFEED (0Ah) i.e., 2 before start of next line push ecx push ebx xor ebx,ebx cmp byte[edi-1],NEWLINE ;at BOL ? jz LBa3 cmp byte[edi],NEWLINE ;at EOL ? jnz LBa1 dec edi ;at EOL ? start search 1 char earlier inc ebx ;increase counterLBa1: mov ecx,99999 mov al,NEWLINE std repne scasb lea eax,[ebx+99997] ;mov eax,99997 / add eax,ebx sub eax,ecxLBa5: pop ebx pop ecx jmp short CheckBof;-------LBa3: xor eax,eax dec edi dec edi jmp short LBa5;-------LookForward:push ecx ;don't touch edx (if called by BZNLoop only) mov ecx,99999 mov al,NEWLINE cld repne scasb mov eax,99998 sub eax,ecx pop ecx dec ediCheckEof:cmp edi,ebp ;ptr is eof-ptr? jnz CheckEnd ;Z flag if eof jmp short CheckENumCheckBof:cmp edi, sot-1 ja CheckEndCheckENum:mov byte [numeriere],1 ;if bofCheckEnd:ret;-------LookPgBegin:mov edx,[kurspos2] ;called by DispNewScreen to get sync with 1st char on screen movzx ecx,dh ;called by KeyCtrlQE (go upper left) OLD: xor ecx,ecx mov cl,dh inc ecx ;'inc cl' are 2 Bytes jmp short LookPU2;-------LookPgEnd:mov edx,[kurspos2] ;goes 1st char last line on screen mov ecx,[lines] sub cl,dh jmp short LookPD2;-------LookLineUp:push byte 2 ;2 lines: THIS line and line BEFORE pop ecx dec dword [linenr] jmp short LookPU2;-------LookLineDown:push byte 2 ;2 lines: THIS and NEXT line pop ecx inc dword [linenr] jmp short LookPD2;-------LookPageUp:mov ecx,[lines] dec ecx ;PgUp,PgDown one line lessLookPU1:sub [linenr],ecx inc ecxLookPU2:call LookBackward inc edi ;inc keeps CY flag! jb LookPUEnd ;if BOF loop LookPU2 ;after loop edi points to char left of LINEFEED (0ah)LookPUEnd:inc edi ;now points to 1st char on screen or line ret;-------LookScrDn:xor ecx,ecx inc ecx jmp short LookPD1LookScrUp:xor ecx,ecx inc ecx jmp short LookPU1LookHalfPgUp:mov ecx,[lines] ;vi special dec ecx shr ecx,1 jmp short LookPU1LookHalfPgDn:mov ecx,[lines] dec ecx shr ecx,1 jmp short LookPD1;-------LookPgDown:mov ecx,[lines] dec ecx ;PgUp,PgDown one line lessLookPD1:add [linenr],ecx inc ecxLookPD2:call LookForward jz LookPDEnd ;(jmp if EOF) inc edi ;1st char next line loop LookPD2 dec edi ;last char last lineLookPDEnd:sub edi,eax ;1st char last line ret;----------------------------------------------------------------------;; some more CHECK functions;CheckBlock:cmp byte [showblock],1 ;returns CY if error else ok: NC jc CheckBlockEnd mov esi,[blockende] cmp esi, sot jb CheckBlockEnd mov esi,[blockbegin] ;side effect esi points to block begin cmp esi, sot jb CheckBlockEnd cmp [blockende],esi ;^KK > ^KB ..OK if above!CheckBlockEnd:ret;-------CheckImBlock:cmp [blockbegin],edi ;^KB mark > edi ? ja CImBlockEnd ;OK cmp edi,[blockende] ;edi > ^KKCImBlockEnd:ret ;output:cy error / nc ok inside block;-------CheckMode:cmp byte [edi],NEWLINE ;checks for INSERT status jz ChModeEnd cmp byte [insstat],1ChModeEnd:ret ;Z flag for ins-mode;-------; a special case called by DeleteByteCheckMarker;CheckMarker: ;edx is blockbegin (^KB) ;ebx is deleate area end --- edi delete area start cmp edi,edx ;delete area start < ^KB marker ? ja CMEnd ;no cmp ebx,edx ;yes, but delete area end > ^KB ? jb CMEnd ;no mov edx,edi ;yes so block start (^KB) to delete area startCMEnd: ret;----------------------------------------------------------------------;; C O U N T functions; to return number of chars up to some place; (all of them are wrappers of Look....functions anyway);CountToLineEnd:push edi call LookForward pop edi ret ;eax=chars up to line end;-------CountColToLineBeginVis: ;counts columns represented by chars in EAX call CountToLineBegin ;i.e. EXPAND any TAB chars found push esi xor edx,edx mov esi,edi ;startpoint sub esi,eax ;to bol dec esiCCV1: inc esi cmp esi,edi jae CCVend cmp byte [esi],TABCHAR jz CCVTab inc edx ;count visible chars jmp short CCV1CCVTab: call SpacesForTab ;return space_up_to_next_tab in ah add dl,ah ;FIXME: now using 8 bits only jmp short CCV1CCVend: mov [ch2linebeg],edx ;ch2linebeg: interface to Key... functions mov eax,edx ;eax: interface to DispNewScreen pop esi%ifdef W32LF cmp byte[edi-1],RETURN jnz CCV2 dec byte [ch2linebeg] ;don't count in RETURN charCCV2: %endif ret;-------CountToLineBegin:push edi ;output eax=chars up there call LookBackward mov esi,edi ;side effect: set edi to 1st char in line pop edi ret;-------CountToWordBeginVIstyle: ;output eax=chars up there mov esi,edi cmp byte [esi],SPACECHAR ja CtWviStyleCountToWordBegin: ;output eax=chars up there mov esi,ediCountNLoop:inc esi%ifdef W32LF cmp byte [esi],RETURN%else cmp byte [esi],NEWLINE%endif jz CTWend cmp byte [esi],SPACECHAR ;below SPACE includes tab chars jbe CountNLoop cmp byte [esi-1],2fh ja CountNLoopCTWend: mov eax,esi sub eax,edi ;maybe =0Goret: ret;-------CtWviStyle:inc esi%ifdef W32LF cmp byte [esi],RETURN%else cmp byte [esi],NEWLINE%endif jz CTWend cmp byte [esi],2fh ja CtWviStyle jmp short CountNLoop;;;;;;;;;;;;CTWend;----------------------------------------------------------------------;; Online Help: show the message followed by common text;KeyHelp:%ifdef USE_BUILTINHELP push dword [kurspos] pusha xor eax,eax xchg eax,[showblock] ;hide an blockmarker push eax cld mov esi,sot ;save "buffercopysize" of text mov edi,buffercopy mov ecx,buffercopysize push edi push ecx push esi;------- rep movsb call GetHelpText pop edi push edi ;i.e. mov edi,sot;------- push edi rep movsb ;overwrite saved text with help message mov esi,helpfoot push byte helpfootsize pop ecx rep movsb mov ebp,edi ;set END_OF_HELP_TEXT pointer pop edi call DispNewScreen call ReadOneChar ;wait for a pressed char;------- pop edi pop ecx pop esi ;former edi cld rep movsb ;restore textbuffer with saved patr pop dword [showblock] popa pop edx ;cursor pos jmp short SetKursPos%else ret%endif;---------------------------------------------------------------------;; some CURSOR control functions;GoUp: xor eax,eax jmp short UpDownGoDown: mov al,byte [lines] dec eax ;'dec al' are 2 byte! mov ah,-1UpDown: mov edx,[kurspos2] ;former was call getkurspos cmp al,dh jz Goret sbb dh,ah ;ONLY here we change curent line of cursor jmp short SetKursPos;-------; set cursor to some desired places;KeyVICmdz:call ReadOneChar cmp al,'.' je KeyEmaCtrlL ret;-------KeyVI_M:call LookPgBegin call LookHalfPgDn test byte[lines],1 jnz KeyEmaCtrlL call LookLineDown;------- contKeyEmaCtrlL:call CountToLineBegin mov dh,byte [lines] ;move cursor to center line (and later redisplay) shr dh,1 mov dl,al jmp short SetKursPosKursorFirstLine:xor edx,edx jmp short SetKursPosKursorLastLine:mov dh,byte [lines] dec dh mov dl,0 jmp short SetKursPosKursorStatusLine:mov dh,byte [lines] mov dl,stdtxtlen jmp short SetKursPosRestKursPos:mov edx,[kurspos]SetKursPos:mov [kurspos2],edx ;saves reading cursor pos (0,0)sys_writeKP:pusha%ifdef W32 shl edx,8 ;linux cursorpos in dh/dl - w32 in edx 2*16bit mov dl,dh and edx,0x00FF00FF push dword edx ;xxxxyyyy x=line y=column push dword [hout] call SetConsoleCursorPosition%else call make_KPstr mov ecx,setkp ;second argument: pointer to message to write push byte setkplen ;third argument: message length pop edx call WriteFile0%endif popa ret;-------; make ESC sequence appropriate to most important terminals;%ifndef W32; ;expecting cursor pos in dh/dl (0,0)make_KPstr:cld mov edi,setkp ;build cursor control esc string db 27,'[000;000H' mov al,1Bh stosb ;init memory%ifndef ARMCPU mov eax,'[000' stosd mov al,';' ;i.e. load eax with ';000' stosd%else mov al,'[' stosb mov al,'0' stosb stosb stosb mov al,';' stosb mov al,'0' stosb stosb stosb%endif mov al,'H' stosb ;now we have written 10 chars lea edi,[edi-6] ;old was "mov edi,setkp+1+3" now using 1+3 == 10-6 movzx eax,dh ;DH=line inc eax ;now counted from 1 push edx call IntegerToAscii ;make number string pop edx mov edi,setkp+1+3+4 ;column end movzx eax,dl ;DL=col inc eax ;now counted from 1%endif;-------continued...; a general helper; expects integer# in eaxIntegerToAscii: or eax,eax jns ItoA1 ;int 3 ;Assertation xor eax,eax ;this should never be inc eaxItoA1: push byte 10 pop ecx std xchg eax,ebx ;ebx helper (xchg eax,.. is only 1 byte!)Connum1:xchg eax,ebx cdq div ecx xchg eax,ebx ;save quotient (new low word) mov al,dl and al,0fh add al,'0' stosb or ebx,ebx jne Connum1 cldITAret: ret;----------------------------------------------------------------------;; functions for INSERTING, COPYING and DELETING chars in text;DeleteByteCheckMarker: ;edi points to begin test byte [mode], WS | VI ;see above note at "jz NOWS8" jz DeleteByte lea ebx,[edi+eax] ;ebx points to end mov edx,[blockbegin] call CheckMarker mov [blockbegin],edx mov edx,[blockende] call CheckMarker mov [blockende],edxDeleteByte:or eax,eax ;input in eax jz ITAret%ifdef USE_UNDO call DataForUndoDelete%endif push edi mov ecx,ebp ;end sub ecx,edi lea esi,[edi+eax] ;current + x chars sub ecx,eax cmp byte [mode],WS jz No_WS8 add ecx,[EmaKiSize]No_WS8: inc ecx cld rep movsb neg eax ;"neg eax" is for continuing @InsertByte jmp short Ins0 ;pending "pop edi";-------Insert1Byte:xor eax,eaxInsertByte0:inc eax;; do NOT destroy eax;InsertByte:or eax,eax ;input: eax = # of bytes edi = ptr where jz ITAret mov ecx,[maxlen] ;max_len+offset-eofptr=freespace(ecx) add ecx,sot sub ecx,ebp mov edx,[EmaKiSize] sub ecx,edx ;sub size of kill buffer from free space cmp ecx,eax ;cmp freespace - newbytes ;>= 0 ok/ NC <0 bad / CY jnc SpaceAva push byte ERRNOMEM pop dword [ErrNr] ;(mov dword[ErrNr],.. has 2 byte extra) call OSerror call RestKursPos stc retSpaceAva:push edi%ifdef USE_UNDO call DataForUndoInsert%endif mov esi,ebp ;end of text movsb-source lea ecx,[ebp+1] sub ecx,edi ;space count: distance between eof and current position lea edi,[ebp+eax] ;movsb-destination cmp byte [mode],WS jz ISWS8 add ecx,edx ;add size of kill buffer to distance add edi,edx add esi,edxISWS8: std rep movsBIns0: pop edi ;here is the jmp destination from DeleteByte;------- call SetChg ;i.e. mov byte [changed],CHANGED add ebp,eax test byte [mode], WS | VI ;for vi mode it would be enough to handle blockbegin jz NOWS8 ;..because blockende is set at end of marker line.. cmp edi,[blockende] ;..at HandleVImarker procedure jae Ins1 add [blockende],eaxIns1: cmp edi,[blockbegin] jae Ins2 add [blockbegin],eaxNOWS8: test byte [mode], EM | PI jz NO_EM02 cmp edi,[EmaMark] jae Ins2 add [EmaMark],eaxNO_EM02:Ins2: clc ret ;output:nc=ok/cy=bad /ecx=0/ eax inserted / -eax deleted;-------CopyBlock:call CheckBlock ;copy block, called by ^KC, ^KV jc MoveBlEnd call CheckImBlock jc MoveBlEnd mov eax,[blockende] sub eax,esi ;block len call InsertByte jc MoveBlEnd mov esi,[blockbegin];-------MoveBlock:push edi ;input : esi=^KB edi=current mov ecx,eax ;don't use xchg here cld rep movsb pop edi clc ;nocarry->okMoveBlEnd:ret ;return eax=size;----------------------------------------------------------------------KeyVICmdyy:push edi call KeyHome mov [EmaMark],edi call KeyEnd inc edi ;add a line delimiter call KeyEmaAltW pop ediKviRet: ret;-------KeyVICmdy:call ReadOneChar cmp al,'y' je KeyVICmdyy cmp al,"'" jne MoveBlEnd call ReadOneChar cmp al,'a' ;" y'a " only marker "a" supported jne MoveBlEnd mov ecx,[blockbegin] ;don't go further if no mark set jecxz MoveBlEnd call VIsetMarker call KeyEmaAltW mov edi,[blockbegin]%ifdef W32 jmp ISVI9%else jmp short ISVI9%endif;; some of the EM specials;KeyEmaCtrlY:%ifdef W32 cmp byte[mode],NE ;Nedit ^V jnz KECY pusha push byte 0 call OpenClipboard or eax,eax jz KECY3 push byte CF_OEMTEXT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -