📄 e3.c
字号:
//// functions reading/writing text or blocks from/into files//NewFile:CALL(InitVars,122); if (!esi) goto NFnoarg; edi = (long)&filepath;NF1: eax=*(unsigned char*)esi++; *(unsigned char*)edi++=eax; if (eax) goto NF1; goto GetFile;NFnoarg:ebx = (long)&helpfile; // load file with some help text (one page) CALL(OpenFile0,123); edi = (long)sot; ebp = (unsigned char*)edi; if (eax<0) goto GF0; ebx=eax; CALL(OldFile1,124);GF0: CALL(DispNewScreen,125); // if not available: clear screen only//------ esi = (long)&filename; ecx = (long)&filepath; CALL(InputString0,126); if (extra) goto NFEnd2; // empty string not allowed here//------GetFile:ebx = (long)&filepath; CALL(OpenFile0,127); edi = (long)sot; ebp = (unsigned char*)edi; if (eax<0) goto NewFileEnd;//// In Linux/asm version here we have code for// calculating and allocating memory: twice filesize ...// ....plus 102400 byte reserve space for inserts.// Currently we have hard coded 'maxlen' sized buffer.// For FreeBSD/asm version memory always is hard coded by maxlen// ebx = eax; //------ CALL(Fstat,130); if (eax<0) goto OSerror; perms = fstatbuf.st_mode & 0777; uid = fstatbuf.st_uid; gid = fstatbuf.st_gid;//------OldFile1:edx = maxlen; // i.e. either 'max' or filesize twice ecx = edi; // sot CALL(ReadFile,131); if (eax<0) goto OSerror; edx=eax; // mov edx,eax bytes read CALL(CloseFile,132); if (eax<0) goto OSerror; ebp = edx+sot; // eof_ptr=filesize+start_of_textNewFileEnd:*(unsigned char*)ebp = NEWLINE; // eof-marker extra=0;NFEnd2: RETURN;//------// save file (called by ^KS,^KX)//SaveFile:extra=0; if (changed == UNCHANGED) goto NFEnd2; esi = (long)&filesave; CALL(WriteMess9,133);//------ ecx = eax = (long)&bakpath; if (*(int*)eax!=1886221359) // old was ..... 'pmt/') { ebx = esi = (long)&filepath; while ( (*(unsigned char*)eax++= *(unsigned char*)esi++) ) ; eax--; *(unsigned char*)eax++='~'; // add BAK file extension *(unsigned char*)eax++=0; CALL(RenameFile,134); // ecx is filepath } ecx = (O_WRONLY_CREAT_TRUNC); edx = perms; CALL(OpenFile,135); if (eax<0) goto OSerror; ebx=eax; // file descriptor edx = gid; ecx = uid; CALL(ChownFile,137);//------ ecx = (long)sot; // ecx=bof edx = (long)ebp; // eofSaveFile2:edx-=ecx; // edx=fileesize= eof-bof CALL(WriteFile,138); // ebx=file descriptor if (eax<0) goto OSerror; errno = 5; // just in case of.... if (eax-edx) goto OSerror; // all written? CALL(CloseFile,139); if (eax<0) goto OSerror; RETURN;//------// save block (called by ^KW)//SaveBlock:CALL(GetBlockName,140); if (extra) goto DE2; ecx = (O_WRONLY_CREAT_TRUNC); ebx = (long)&blockpath; edx = (PERMS); CALL(OpenFile,141); if (eax<0) goto OSerror; ecx = esi; // = block begin edx = blockende; ebx=eax; // file descriptor (xchg is only 1 byte) goto SaveFile2;//------// read a block into buffer (by ^KR)//ReadBlock:CALL(GetBlockName,142); if (extra) goto DE2; ebx = (long)&blockpath; CALL(OpenFile0,143); if (eax<0) goto OSerror; CALL(Seek,144); if (eax<0) goto OSerror; PUSH(eax); // eax=fileesize CALL(InsertByte,145); POP(edx); // file size if (extra) goto RB_ex; // ret if cy InsertByte told an error message itself ecx = edi; // ^offset akt ptr CALL(ReadFile,146); if (eax<0) goto preOSerror; // to delete inserted bytes (# in EDX) ecx = eax; // bytes read CALL(CloseFile,147); if (eax<0) goto OSerror; errno = 5; // just in case of.... if (edx!=ecx) goto OSerror; // all read? extra=0;RB_ex: RETURN;//------preOSerror:eax = edx; // count bytes CALL(DeleteByte,148); // delete space reserved for insertationOSerror:PUSH(edi); edi = (long)&error[8]; // where to store ASCII value of errno eax = errno; PUSH(eax); CALL(IntegerToAscii,149); POP(ecx); // for getting error text via LookPD2 edi = (long)&errmsgs; if (!*(unsigned char*)edi) goto DE0;// are text error messages loaded ? CALL(LookPD2,150); // look message # ecx in line number # esi = edi; edi = (long)&error[9]; *(unsigned char*)edi++=' '; *(unsigned char*)edi++=':'; ecx = 80; // max strlen / compare errlen equ 100 do { *(unsigned char*)edi++=*(unsigned char*)esi++; } while (--ecx);DE0: esi = (long)&error; POP(edi);DE1: CALL(WriteMess9,151); CALL(GetChar,152);DE2: // continued... //--------------------------------------------------------------------- // more STATUS LINE maintaining subroutinesRestoreStatusLine: PUSH(eax); PUSH(ecx); PUSH(edx); PUSH(ebx); PUSH((long)ebp); PUSH(esi); PUSH(edi); // important e.g. for asksave CALL(InitStatusLine,153); ecx = columns; // width if (ecx < (stdtxtlen+1 +5+2)) goto RSno_lineNr; // this window is too small screenline[1] = changed; ebx = (int)542330441; //(' SNI'); // Insert if (insstat==1) goto RSL1; ebx = (int)542266959; //(' RVO'); // OverwriteRSL1: *((unsigned char*)&(screenline[4])) = (char)ebx; ebx >>=8; *((unsigned char*)&(screenline[5])) = (char)ebx; ebx >>=8; *((unsigned char*)&(screenline[6])) = (char)ebx; ebx >>=8; *((unsigned char*)&(screenline[7])) = (char)ebx; edi = (long)(screenline+stdtxtlen); ecx-=(stdtxtlen+1+5); // space for other than filename esi = (long)&filepath;RSL2: eax=*(unsigned char*)esi++; if (!eax) goto RSL4; *(unsigned char*)edi++=eax; if (--ecx) goto RSL2;RSL4: edi = (long)&(screenline[-2]); edi+=columns; eax = columne; ++eax; // start with 1 CALL(IntegerToAscii,154); *(unsigned char*)edi-- = (':'); // delimiter ROW:COL eax = linenr; CALL(IntegerToAscii,155);RSno_lineNr:CALL(StatusLineShow,156); // now write all at once POP(edi); POP(esi); POP(ebp); POP(ebx); POP(edx); POP(ecx); POP(eax); extra=1; // error status only important if called via OSError RETURN;//------//// write an answer prompt into status line// (with and without re-initialisation)// expecting esi points to ASCIIZ or 0A terminated string//WriteMess9MakeLine:CALL(InitStatusLine,157);WriteMess9:PUSH(eax); PUSH(ecx); PUSH(edx); PUSH(ebx); PUSH((long)ebp); PUSH(esi); PUSH(edi); edi = (long)&screenline; while( (eax=*(unsigned char*)esi++)) { if (eax == 0xa) break; // 0xa is for error messages *(unsigned char*)edi++=eax; } CALL(StatusLineShow,158); POP(edi); POP(esi); POP(ebp); POP(ebx); POP(edx); POP(ecx); POP(eax); goto KursorStatusLine;//------// a helper for other status line functions:// simply init an empty line //InitStatusLine: PUSH(ecx); PUSH(edi); edi = (long)&screenline; ecx = columns-1; // -1 for cygwin do { *(unsigned char*)edi++=SPACECHAR; } while (--ecx); *(unsigned char*)edi=0; // prepare ASCIIZ string POP(edi); POP(ecx); RETURN;//------// read a file name for block operations// expecting message text ptr in esi//GetBlockName:PUSH(eax); PUSH(ecx); PUSH(edx); PUSH(ebx); PUSH(esi); PUSH(edi); esi = (long)█ ecx = (long)&blockpath; CALL(InputString0,159); // cy if empty string PUSH(extra); CALL(RestKursPos,160); POP(extra); POP(edi); POP(esi); POP(ebx); POP(edx); POP(ecx); POP(eax); RETURN;//------// helper for NewFile//InitVars:*(unsigned char*)&text = NEWLINE; // don't touch esi! changed = UNCHANGED; oldQFpos = 0; bereitsges = 0; blockbegin = 0; blockende = 0; endeedit = 0; old = (long)sot; linenr = 1; showblock = 1; insstat = 1; maxlen = max; *(int*)(&error) = (int)1330795077; //('ORRE'); *(int*)((unsigned char*)(&error[4])) = (int)538976338;//(' R'); perms = (PERMS); gid = -1; // -1 i.e. no changes in fchown uid = -1; RETURN;//------ReadResource: ebx = (long)&resfile; // load file with some error message text CALL(OpenFile0,161); // don't care about errors if (eax>=0) { ebx=eax; // mov file_descriptor to ebx edx = errbufsize; ecx = (long)&errmsgs; CALL(ReadFile,162); if (eax>=0) goto CloseFile; } RETURN;//------Seek: ebx=eax; // mov file_descriptor to ebx edx=2; CALL(SeekFile,165); // end if (eax>=0) { edx=0; PUSH(eax); CALL(SeekFile,166); POP(eax); } RETURN;//---------------------------------------------------------------------//// FIND/REPLACE related stuff//AskForReplace:esi = (long)&askreplace1; ecx = (long)&suchtext; CALL(InputString0,169); if (extra) goto AskFor_Ex; suchlaenge = eax; esi = (long)&askreplace2; ecx = (long)&replacetext; CALL(InputString0,170); goto GetOptions;AskForFind:esi = (long)&askfind; ecx = (long)&suchtext; CALL(InputString0,171); if (extra) goto AskFor_Ex;GetOptions:repllaenge = eax; esi = (long)&optiontext; CALL(InputStringWithMessage,172);// empty string is allowd for std options... CALL(ParseOptions,173); // ...(set in ParseOptions) extra=0;AskFor_Ex:if (!extra) goto AFE2; bereitsges = 0;AFE2: PUSH(extra); CALL(RestoreStatusLine,174); CALL(RestKursPos,175); POP(extra); RETURN;//------// check string for 2 possible options: C,c,B,b (case sensitive & backward) // ParseOptions: ebx = (long)&optbuffer; vorwarts=1; grossklein = 0xdf; do { eax=*(unsigned char*)ebx++ & 0x5f; // upper case if (eax=='C') grossklein^=0x20; // result 0dfh, 2*C is like not C option if (eax=='B') vorwarts = -vorwarts; // similar 2*B is backward twice i.e. forward } while (eax); RETURN;//------// the find subroutine itself//find2: ebx = edi;find3: eax=*(unsigned char*)esi++; if (!eax) goto found; // =end? if (eax>=0x41) eax&=grossklein; // 0xff or 0xdf ++edi; ecx = *(unsigned char*)edi; if (ecx>=0x41) ecx&=grossklein; // 0xff or 0xdf if(eax==ecx) goto find3; edi = ebx;FindText:edx = vorwarts; // +1 or -1 esi = (long)&suchtext; eax=*(unsigned char*)esi++; if (eax>=0x41) eax&=grossklein; // 0xff or 0xdffind1: edi+=edx; // +1/-1 ecx = *(unsigned char*)edi; if (ecx>=0x41) ecx&=grossklein; // 0xff or 0xdf if (eax==ecx) goto find2; if ((unsigned long)edi > (unsigned long)ebp) goto notfound; if ((unsigned long)edi >=(unsigned long)sot) goto find1;notfound:extra=0; RETURN;found: edi = ebx; extra=1; // edi points after location RETURN;//---------------------------------------------------------------------//// some GENERAL helper functions//GetAsciiToInteger: esi = (long)&asklineno; CALL(InputStringWithMessage,176); PUSH(extra); CALL(AskFor_Ex,177); // repair status line & set cursor pos esi = ecx; // optbuffer ecx=0; POP(extra); if (extra) goto AIexit;AIload: eax=*(unsigned char*)esi++ - '0'; if (eax<0 || eax>9) goto AIexit; ecx *=10; ecx +=eax; goto AIload;AIexit: RETURN; // ret ecx , ecx==0 if error//---------------------------------------------------------------------// INTERFACE to OS kernel//ReadFile0:ebx=0; // mov ebx,stdin edx=1; ecx = (long)&read_b; // integer to bufReadFile:eax=read(ebx,(void*)ecx,edx); // ebx file / ecx buffer / edx count byte RETURN;WriteFile0:ebx=1; // mov ebx,stdoutWriteFile:eax=write(ebx,(void*)ecx,edx); RETURN;OpenFile0:ecx=0; // i.e O_RDONLYOpenFile:eax=open((char*)ebx,ecx,edx); RETURN;CloseFile:eax=close(ebx); RETURN;Fstat: eax=fstat(ebx,&fstatbuf); RETURN;RenameFile:eax=rename((unsigned char*)ebx,(unsigned char*)ecx); RETURN;ChownFile:eax=fchown(ebx,ecx,edx); RETURN;IOctlTerminal:eax=ioctl(0,ecx,edx); // ECX TIOCGWINSZ ,EDX winsize structure ptr RETURN;SeekFile:eax=lseek(ebx,0,edx); // ecx offset / ebx file / edx method RETURN;Exit: _exit(0); ////------new code for the C version:SetTermStruc:tcgetattr(0,&orig); termios = orig; termios.c_lflag &= (~ICANON & ~ECHO & ~ISIG); termios.c_iflag &= (~IXON); termios.c_cc[VMIN] = 1; termios.c_cc[VTIME] = 0; eax=(long)&termios;SetTermStruc2:tcsetattr(0, TCSANOW, (struct termios*)eax); RETURN;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -