📄 e3.c
字号:
eax = (long)&screencolors0; // reset to b/w CALL(sys_writeSLColors,92); // special for status line (ecx==0) edx = kurspos2; CALL(sys_writeKP,93); // restore old cursor posNoWrite:POP(edi); POP(esi); POP(ebp); POP(ebx); POP(edx); POP(ecx); POP(eax); RETURN;//------// a helper for ScreenLineShow//sys_writeSLColors: if (!ecx) // do nothing if not in status line { PUSH(eax); PUSH(ecx); PUSH(edx); PUSH(ebx); ecx=eax; // parameter points to ESC-xxx color string edx = scolorslen; CALL(WriteFile0,94); POP(ebx); POP(edx); POP(ecx); POP(eax); } RETURN;//---------------------------------------------------------------------//// getting line INPUT from terminal / UNDER CONSTRUCTION//// expecting integer to message text in esi//InputStringWithMessage: CALL(WriteMess9MakeLine,95); ecx = (long)&optbuffer; edx = optslen; goto InputString;InputString0:CALL(WriteMess9MakeLine,96); edx = maxfilenamelen;//// expecting input line buffer in ecx// expecting max count byte in edx// return length in eax, CY for empty string (or abort via ^U)//InputString:PUSH(ecx); PUSH(edi); PUSH(kurspos2); ebx = columns-stdtxtlen; if (edx<ebx) goto IS8; // TODO enable some scrolling: now truncate at end of line edx = ebx;IS8: ebx=0; edi = ecx;IS0: PUSH(ebx); PUSH(edx); kurspos2 = ebx; // column kurspos2+=stdtxtlen; // offset ebx = lines; // line# ((unsigned char*)&kurspos2)[1] = ebx;#ifdef LESSWRITEOPS screenbuffer[0] = 0; // switching off usage of buffer v0.7#endif CALL(StatusLineShow,97); CALL(GetChar,98); POP(edx); POP(ebx); if (eax!=0x15) goto IS9; // ^U abort (WStar) ebx=0; // length 0 triggers CY flag goto IS1;IS9: if (eax==NEWLINE) goto IS1; if (eax-8) goto IS2; // ^H (translated DEL) if (!ebx) goto IS0; // @left border? --ebx; --edi; screenline[(ebx+stdtxtlen)] = SPACECHAR; goto IS0;//------IS2: if (eax<SPACECHAR) goto IS0; *(unsigned char*)edi++=eax; screenline[(ebx+stdtxtlen)] = eax; ++ebx; if (ebx<edx) goto IS0;//------IS1: *(unsigned char*)edi=0; // make asciz string POP(kurspos2); POP(edi); POP(ecx); eax=ebx; extra=!eax; // set extra-flag if empty string RETURN;//---------//// GetChar returns ZERO flag for non ASCII (checked in HandleChar)// (vt300 is _NOT_ supported in asm version)//ReadChar:veryold = old; // for ^QP old=edi;GetChar:CALL(ReadOneChar,99); if (eax==0x7f) // special case: remap DEL to Ctrl-H eax = 8; if (eax-27) goto RCready_2; // ESC ? CALL(ReadOneChar,100); // dont care whether '[' or 'O' (should be) or any else CALL(ReadOneChar,101); // e.g. [ for vt220,rxvt family O for xterm,vt100 family ebx = 0x47-lowest; // 47h home - the lowest if (eax=='1') goto RC_Tilde; if (eax=='7') goto RC_Tilde; // (on rxvt) if (eax=='H') goto RCready; // (on xterm) if (eax=='w') goto RCready; // (on vt300) ++ebx; // 48h up if (eax=='A') goto RCready; if (eax=='x') goto RCready; // (on vt300) ++ebx; // 49h PgUp if (eax=='5') goto RC_Tilde; if (eax=='I') goto RCready; if (eax=='y') goto RCready; // (on vt300) ++ebx; ++ebx; // 4Bh left if (eax=='D') goto RCready; if (eax=='t') goto RCready; // (on vt300) ++ebx; ++ebx; // 4Dh right if (eax=='C') goto RCready; if (eax=='v') goto RCready; // (on vt300) ++ebx; ++ebx; // 4Fh end if (eax=='4') goto RC_Tilde; if (eax=='8') goto RC_Tilde; // (on rxvt only) if (eax=='F') goto RCready; // (on xterm only) if (eax=='q') goto RCready; // (on vt300) ++ebx; // 50h down if (eax=='B') goto RCready; if (eax=='r') goto RCready; // (on vt300) ++ebx; // 51h PgDn if (eax=='6') goto RC_Tilde; if (eax=='G') goto RCready; if (eax=='s') goto RCready; // (on vt300) ++ebx; // 52h insert if (eax=='2') goto RC_Tilde; if (eax=='L') goto RCready; if (eax=='p') goto RCready; ++ebx; // 53h del if (eax=='l') goto RCready; if (eax-'3') goto RCready_2; // slightly ignore this charsRC_Tilde:PUSH(ebx); CALL(ReadOneChar,102); // read another ~ (after Integer 1..8) POP(ebx); if (eax-'~') goto GetChar; // could be F7,sf1 etc on linuxterm: ignored//------RCready:eax =0;RCready_2:RETURN;//-----------------------------------// called by ReadChar/GetChar//ReadOneChar:CALL(ReadFile0,105); eax = *(unsigned char*)ecx; RETURN;//---------------------------------------------------------------------//// L O O K functions// search special text locations and set register edi to//LookBackward: // set EDI to 1 before EOL (0Ah) i.e., 2 before start of next line PUSH(ecx); PUSH(ebx); ebx=0; if (((unsigned char*)edi)[-1] == NEWLINE) goto LBa3; // at BOL if (*(unsigned char*)edi != NEWLINE) goto LBa1; // at EOL ? --edi; // at EOL ? start search 1 char earlier ++ebx; // increase counterLBa1: ecx = 99999; while (--ecx && *(unsigned char*)edi-- != NEWLINE); eax = ebx+99997-ecx;LBa5: POP(ebx); POP(ecx); goto CheckBof;//------LBa3: eax=0; --edi; --edi; goto LBa5;//------LookForward:PUSH(ecx); // don't touch edx (if called by BZNLoop only) ecx = 99999; while (--ecx && *(unsigned char*)edi++ != NEWLINE); eax = 99998-ecx; POP(ecx); --edi;CheckEof:extra=0; if ((unsigned long)edi>=(unsigned long) ebp) extra++; goto CheckENum;CheckBof:extra=0; if ((unsigned long)edi>=(unsigned long)&text) goto CheckEnd; extra=1;CheckENum:numeriere = 1; // if bofCheckEnd:RETURN;//------LookPgBegin:edx = kurspos2; // called by DispNewScreen to get sync with 1st char on screen ecx= edx>>8; // called by KeyCtrlQE (go upper left) ++ecx; goto LookPU2;//------LookPgEnd:edx = kurspos2; // goes 1st char last line on screen ecx = lines; ecx-= (edx>>8); goto LookPD2;//------LookLineUp:ecx=2; // 2 lines: THIS line and line BEFORE --linenr; goto LookPU2;//------LookLineDown:ecx=2; // 2 lines: THIS and NEXT line ++linenr; goto LookPD2;//------LookPageUp:ecx = lines; linenr-=(ecx-1); // PgUp,PgDown one line lessLookPU2:CALL(LookBackward,106); if (extra) goto LookPUEnd; ++edi; if (--ecx) goto LookPU2; // after loop edi points to char left of 0ah --edi;LookPUEnd:++edi; ++edi; // now points to 1st char on screen or line RETURN;//------LookPgDown:ecx = lines; linenr+=(ecx-1); // PgUp,PgDown one line lessLookPD2:CALL(LookForward,107); if (extra) goto LookPDEnd; ++edi; // 1st char next line if (--ecx) goto LookPD2; --edi; // last char last lineLookPDEnd:edi-=eax; // 1st char last line RETURN;//---------------------------------------------------------------------//// some more CHECK functions//CheckBlock:esi = blockbegin; // side effect esi points to block begin extra=0; if (!showblock || ((unsigned long)blockende <(unsigned long) sot) || (unsigned long)esi <(unsigned long) sot || (unsigned long)blockende < (unsigned long)esi) extra++; RETURN;//------CheckMode:extra=0; // checks for INSERT status if (*(unsigned char*)edi == NEWLINE) extra++; if (insstat==1) extra++; RETURN;//---------------------------------------------------------------------//// 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,108); POP(edi); RETURN; // eax=chars up to line end//------CountColToLineBeginVis: // counts columns represented by chars in EAX CALL(CountToLineBegin,109); // i.e. EXPAND any TAB chars found PUSH(esi); edx=0; esi = edi - eax -1; // startpoint to bolCCV1: ++esi; if (esi>=edi) goto CCVend; if (*(unsigned char*)esi == TABCHAR) goto CCVTab; ++edx; // count visible chars goto CCV1;CCVTab: edx += (TAB -edx % TAB); goto CCV1;CCVend: ch2linebeg = edx; // ch2linebeg: interface to Key... functions eax = edx; // eax: interface to DispNewScreen POP(esi); RETURN;//------CountToLineBegin:PUSH(edi); // output eax=chars up there CALL(LookBackward,111); esi = edi; // side effect: set edi to 1st char in line POP(edi); RETURN;//------CountToWordBegin: // output eax=chars up there esi = edi;CountNLoop:++esi; if (*(unsigned char*)esi == NEWLINE) goto CTWend; if (*(unsigned char*)esi <= SPACECHAR) goto CountNLoop; // below SPACE includes tab chars if (((unsigned char*)esi)[-1] > 0x2f) goto CountNLoop;CTWend: eax = esi-edi; // maybe =0 RETURN;//--------------------------------------------------------------------//// some CURSOR control functions//GoUp: eax = 0; ebx = -1; goto UpDown;GoDown: eax = lines-1; ebx = 1;UpDown: edx = kurspos2; // former was call getkurspos if ((edx>>8)==eax) goto Goret; edx+=ebx==1?256:-256; // ONLY here we change curent line of cursor goto SetKursPos;Goret: RETURN;//------// set cursor to some desired places//KursorFirstLine:edx=0; goto SetKursPos;KursorLastLine: edx = (lines-1)<<8; goto SetKursPos;KursorStatusLine:edx = stdtxtlen+(lines<<8); goto SetKursPos;RestKursPos:edx = kurspos;SetKursPos:kurspos2 = edx; // saves reading cursor pos (0,0)sys_writeKP:PUSH(eax); PUSH(ecx); PUSH(edx); PUSH(ebx); PUSH(esi); PUSH(edi); CALL(make_KPstr,112); ecx = (long)&setkp; // second argument: integer to message to write edx = setkplen; // third argument: message length CALL(WriteFile0,113); POP(edi); POP(esi); POP(ebx); POP(edx); POP(ecx); POP(eax); RETURN;//------// make ESC sequence appropriate to most important terminals//make_KPstr:edx+=0x101;// ++dl; // expecting cursor pos in dh/dl (0,0)// ++dh; // both line (dh) col (dl) are counted now from 1 edi = (long)&setkp; // build cursor control esc string db 27,'[000;000H' *(unsigned char*)edi++=0x1b; // init memory *(unsigned char*)edi++= '['; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= ';'; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= '0'; *(unsigned char*)edi++= 'H'; edi = (long)&(setkp[1+3]); // line end eax= edx>>8; // DH=line PUSH(edx); CALL(IntegerToAscii,114); // make number string POP(edx); edi = (long)&(setkp[1+3+4]); // column end eax= edx&0xFF; // DL=col//------continued...// a general helper// expects int# in eaxIntegerToAscii:Connum1:edx= eax%10; eax/=10; edx&=0xf; edx+='0'; *(unsigned char*)edi--=edx; if (eax) goto Connum1; RETURN;//---------------------------------------------------------------------//// functions for INSERTING, COPYING and DELETING chars in text//InsertByte:if (!eax) goto Ins2; // input: eax = # of bytes edi = ptr where ecx = maxlen; // max_len+offset-eofptr=freespaceecx ecx+=(long)(&text[1]); ecx-=(long)ebp; if ((unsigned long)ecx>=(unsigned long)eax) goto SpaceAva; // cmp freespace - newbytes errno=105; CALL(OSerror,115); CALL(RestKursPos,116); extra=1; RETURN;SpaceAva:PUSH(edi); esi = (long)ebp; // end of text movsb-source ecx = (long)ebp+1-edi; // space count: distance between eof and current position edi = (long)ebp+eax; // movsb-destination do { *(unsigned char*)edi--=*(unsigned char*)esi--; } while (--ecx);Ins0: POP(edi); // here is the jmp destination from DeleteByte//------ changed = CHANGED; (long)ebp+=eax; if ((unsigned long)edi>=(unsigned long)blockende) goto Ins1; blockende+=eax;Ins1: if ((unsigned long)edi>=(unsigned long)blockbegin) goto Ins2; blockbegin+=eax;Ins2: extra=0; RETURN; // output:nc=ok/cy=bad /ecx=0/ eax inserted / -eax deleted//------DeleteByteCheckMarker: // edi points to begin ebx = edi+eax; // ebx points to end edx = blockbegin; if (!((unsigned long)edi>(unsigned long)edx || (unsigned long)ebx<(unsigned long)edx)) blockbegin = edi; edx = blockende; if (!((unsigned long)edi>(unsigned long)edx || (unsigned long)ebx<(unsigned long)edx)) blockende = edi;DeleteByte:if (!eax) goto MoveBlEnd; // input in eax PUSH(edi); esi = edi+eax; // current + x chars ecx = (long)ebp-esi; ecx++; do { *(unsigned char*)edi++=*(unsigned char*)esi++; } while (--ecx); eax = -eax; // "neg eax" is for continuing @InsertByte goto Ins0; // pending "pop edi"//------CopyBlock:CALL(CheckBlock,119); // copy block, called by ^KC, ^KV if (extra) goto MoveBlEnd; if ((unsigned long)edi>=(unsigned long)blockbegin && (unsigned long)edi<(unsigned long)blockende) { extra=1; goto MoveBlEnd; } eax = blockende-esi; // block len CALL(InsertByte,121); if (extra) goto MoveBlEnd; esi = blockbegin;MoveBlock:PUSH(edi); // input : esi=^KB edi=current if (eax) { ecx = eax; do { *(unsigned char*)edi++=*(unsigned char*)esi++; } while (--ecx); } POP(edi); extra=0; // nocarry->okMoveBlEnd:RETURN; // return eax=size//---------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -