diff options
author | Dmitry Bogatov <KAction@debian.org> | 2019-01-13 16:49:55 +0000 |
---|---|---|
committer | Dmitry Bogatov <KAction@debian.org> | 2019-01-13 16:49:55 +0000 |
commit | 4aab39abc9f42b92955b2fe36bf4537aaa58e79d (patch) | |
tree | d18f5b9c3c381342e0695a6ecb53e7ac5e5c1ebe |
Import Upstream version e3-2.30
83 files changed, 16198 insertions, 0 deletions
diff --git a/COPYING.GPL b/COPYING.GPL new file mode 100644 index 0000000..dc63aac --- /dev/null +++ b/COPYING.GPL @@ -0,0 +1,340 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..a4cdfb0 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,24 @@ +e3 is not public domain software --- it is copyrighted. However, it may be used +for any purpose without royalty or fees in accordance with the terms of the +copyright. + +----------------------------------------------------------------------------- + Copyright (c) 2000,01,02 Albrecht Kleine + All rights reserved. + + You may distribute under the terms of the GNU General Public License. + See COPYING.GPL for more details. + + IN NO EVENT SHALL ALBRECHT KLEINE BE LIABLE TO ANY PARTY FOR DIRECT, + INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF + THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ALBRECHT KLEINE + HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ALBRECHT KLEINE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + BASIS, AND ALBRECHT KLEINE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +----------------------------------------------------------------------------- + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..181e66e --- /dev/null +++ b/ChangeLog @@ -0,0 +1,985 @@ +Sun Apr 7 19:30:36 2002 Albrecht Kleine <kleine@ak.sax.de> + + e3-16: added color support for e3-16/ELKS (*) , + bugfixes and clean up for release + (*) ELKS (==Embeddable Linux Kernel Subset, 16 bit) + The 16 bit version has currently the label v0.1. + Build it via "make elks". + #174 + ***** released as v2.3 ***** +------------------------------------------------------------- +Wed Apr 3 20:30:33 2002 Albrecht Kleine <kleine@ak.sax.de> + + -initial 16 bit version having both ELKS and DOS + in one source file (control by %ifdef ELKS), + supporting only WS keys, but not yet no ^KR + #173 +------------------------------------------------------------- +Sat Mar 30 14:00:00 2002 Albrecht Kleine <kleine@ak.sax.de> + + -TASM->NASM conversion of old e2dos 16 bit stuff, + review and improving: now we can "official" support + DOS, having e3-16.com and e3-16e.exe + -enhanced W32 file make.bat for using 16bit e3stub.exe + as PE EXE stub for e3.exe. + Now we have TWO different editor executables in ONE file, + doing something useful instead of complaining about + "it can run only under Win32". + #172 +------------------------------------------------------------- +Sun Mar 17 10:05:40 2002 Albrecht Kleine <kleine@ak.sax.de> + + -Makefile: fixed a nasty NASM version conflict + NASM 0.98.08 claims to use -O2 by default, but does not + NASM 0.98 does not yet know the -O2 switch + -added special extension (via %define USE_EXT_MOVE): + get cursor move operation a little bit smarter: + double pressing of ^QD, for example, should return + cursor to original place, similar ^QC, ^QR, ^QS . + This not yet activated by default. + Tnx to Oleg Bartunov for suggestion. + #171 + ***** released as v2.21 ***** +------------------------------------------------------------- +Sat Mar 16 12:54:50 2002 Albrecht Kleine <kleine@ak.sax.de> + + -added some code in e3.asm and Makefile for running + an initial self test by running: + # make test + Self test is controlled by reading redirected input + from files e3.h and tests/e3test0 + -removed Atheos binaries from distribution, + but of course e3 will stil run under AtheOS + #170 +-------------------------------------------------------------- +Thu Mar 14 19:16:02 2002 Albrecht Kleine <kleine@ak.sax.de> + + -prepared e3.asm code for dynamic linking in LINUX + -added 3 new make destinations for building + LINUX executables linked against libc: + # make statc + # make dync + # make dync2 + (that are: static, dynamic_via_gcc, dynamic_via_ldd) + -some other byte squeeeeeeeeezed out of new UNDO code + #169 +-------------------------------------------------------------- +Sat Mar 9 13:43:25 2002 Albrecht Kleine <kleine@ak.sax.de> + + -rewrote UNDO for avoiding situations where undo + could be impossible: + done by using an external undo storage file, + if neccessary (and dropped dialog from #167). + Now at least undoing ONE level is _always_ possible, + see new man page for details. + -added external sed-pipe (WS: ^KP) to the + UNDOable operations. + -adjusted man page and html help file + -removed QNX and BeOS binaries from distribution, + see special README in bin/BeOS and bin/QNX + #168 + ***** released as v2.2 ***** +------------------------------------------------------------- +Tue Mar 05 19:20:21 2002 Albrecht Kleine <kleine@ak.sax.de> + + -added info on available UNDO info + in 1st column of status line (later removed again) + -added 'rollback' function for UNDOing all changes + as long undo info on stack (for internal testing only) + -replaced word 'through' with 'thru' saving + at all 12 byte :-)) + -added warning dialog if UNDO is impossible in + certain situations + #167 +------------------------------------------------------------- +Sun Mar 03 18:00:01 2002 Albrecht Kleine <kleine@ak.sax.de> + + -improved UNDO-concept by using a ring buffer stack + #166 (pre-released as v2.2alpha) +------------------------------------------------------------- +Sat Mar 02 11:44:10 2002 Albrecht Kleine <kleine@ak.sax.de> + + -initial study for basic UNDO. + Many thanks for idea to Terry Loveall! + Note: don't forget to visit his very nice + editor info page at: + http://www.users.qwest.net/~loveall/Twee.htm + #165 +------------------------------------------------------------- +Sun Feb 24 09:19:40 2002 Albrecht Kleine <kleine@ak.sax.de> + + -added ^Z key (^KZ in WS) for the AtheOS + -bugfix: added missing RestCursPos call for ^Z + -bugfix: shown_as_dot chars in Linux now 80h...9Fh + (old was 80h...0AFh) + -bugfix: 0d0a Return/linefeed problem on W32 fixed + #164 + ***** released as v2.11 ***** +------------------------------------------------------------- +Tue Feb 19 18:08:23 2002 Albrecht Kleine <kleine@ak.sax.de> + + -added patch useful for some LEAF project users, + see contrib/ + -added bugfix: never let edi go below start_of_text + -added bugfix against too much inserts in indent mode + (pressing RET in a line w pending tab characters: i.e.: + <BOL><tab><cursor><tab><tab><tab>.....<NewLine><EOL> + old e3 could insert 3 chars too much) + #163 +------------------------------------------------------------- +Sat Feb 9 12:16:15 2002 David Douthitt <DDouthitt@cuna.com> + + -added option for COMPRESSing in Makefile + (Set this to gzexe or upx if you want compression) + -clean target in Makefile removes e3~ backups + +Sat Feb 9 12:16:15 2002 Albrecht Kleine <kleine@ak.sax.de> + + -control helptext depending on USE_MATH, + moved "^KM Set mode" message for WS mode + #162 +------------------------------------------------------------ +Sun Feb 3 10:55:23 2002 Albrecht Kleine <kleine@ak.sax.de> + + -changed edi,esi register usage in FreeBSD + -now using old lseek in FreeBSD for more common code + -removed unused error messages + -added more %ifdef for helptexts depending what is + available on each OS and what is %defined by user + -at all more than 800 byte removed in #154..#161 + #161 + ***** released as v2.1 ***** +----------------------------------------------------------- +Mon Jan 28 00:00:00 2002 Albrecht Kleine <kleine@ak.sax.de> + + -more optimisation by size (e.g. with "movzx") + -fixed SetEditMode + -removed usage of gid,uid variables + -intro of "call ShowBl0" + -opt of EmaCtrl.. usage + -moved error message texts to e3.h + -more reorg of %ifdef code + #158,#159,#160 +------------------------------------------------------------- +Thu Jan 17 00:00:00 2002 Albrecht Kleine <kleine@ak.sax.de> + -moved ELF header stuff into ORGheader macro in e3.h + -optimized startup var initialisation (InitSomeVars) + -replaced fstsw [x87] with fnstsw [x87], saving 1 byte ;-) + -more optimisation by size, more "short" jumps + -intro of IsEmMode,IsViMode (also saves space) + -reduced system dependen parts (%ifdef W32.....) + #157 +------------------------------------------------------------ +Sun Jan 13 00:00:00 2002 Albrecht Kleine <kleine@ak.sax.de> + -moved lots of constants to e3.h + -heavy optimisation of GetHelpText + -rearranged code for replacing many "near" jumps + by "short" ones + -intro of utimbuf struc + #156 +------------------------------------------------------------ +Thu Jan 10 00:00:00 2002 Albrecht Kleine <kleine@ak.sax.de> + -intro of fstatbuf structure + -intro of symbolic constants for each OS version + (e.g. SYS_exit vs. 1) + -removed some dummy calls when sys call is not supported + (%ifdef ATHEOS / xor eax,eax / ret / %else / .......) + -FreeBSD replaced call 7:0 by int 80h, is shorter ;) + #155 +------------------------------------------------------------ +Sun Jan 6 19:01:19 2002 Albrecht Kleine <kleine@ak.sax.de> + + -new file e3.h: started moving system dependend stuff + into header file + -bugfix in OpenBSD (system call #342 not available) + (tnx for report to rmm@cynexus.net) + -e3.asm: added option to suppress sed/ex pipe + introduced in #109 (to save 500 byte if neccessary) + #154 +-------------------------------------------------------------- +Sat Dec 22 20:35:12 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: changed support of Atheos OS to direct + kernel calls, no more libc usage + #153 + ***** released as v2.01 (ATHEOS ONLY) ***** +------------------------------------------------------------- +Fri Dec 21 20:01:57 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: initial support of Atheos OS (via libc) + #152 +------------------------------------------------------------- +Tue Dec 18 19:30:22 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added vi's M command (jmp to middle of screen pos) + -now set cursor to last line when suspending via ^Z + #151 + ***** released as v2.0 ***** +-------------------------------------------------------------- +Fri Dec 14 20:30:12 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm/W32 version: + * added clipboard functions for the Nedit version: + i.e. ^C,^X,^V are working as usual in Win9x + and can cut©&paste texts via Win9x-clipboard + * characters 0x80-0x9F are shown again (in W32) + #150 +-------------------------------------------------------------- +Wed Dec 12 20:30:53 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: added "cursor_left" motion for e3vi + when switching into COMMAND MODE. This makes + e3vi once more act a bit like original vi. + Does work for Linux, FreeBSD, Win9x, QNX + but not for BeOS (due missing select syscall) + -Bugfix in SaveBlock for the BeOS version + (could not existing file overwrite in ^KW) + -replaced finit with fninit, saving 1 byte ;-) + -e3.c: fixed some comparisations with prefix + "unsigned long" + #149 +-------------------------------------------------------------- +Thu Dec 6 20:04:35 2001 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix ^SPACE in the Win32 version + (this makes e3em,e3ne more useable in W32) + -bugfix wrong %ifdef...%else...%endif for BEOS + -some experiments using Win32-clipboard, + but not yet ready for release + #148 + ***** released as v1.9 ***** +-------------------------------------------------------------- +Sun Dec 2 16:59:43 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: added SIGNAL HANDLING (see #146) to the + FreeBSD version + -e3.asm: optimized handling of NE helptext + -added a note in contrib/README about the usage of + the "tinlink & 624 super duper" self compressor + tools + -adjusted e3.html, e3.man + #147 +-------------------------------------------------------------- +Thu Nov 29 22:12:26 2001 Albrecht Kleine <kleine@ak.sax.de> + =the day the great George Harrison died :-( + + -added code to prevent editing non-regular files + on FreeBSD (because different kernel "read" + behaviour in Linux vs FreeBSD) + -added SIGNAL HANDLING acting on ^Z for job control + (for vi,emacs,pico,nedit modes, but ^KZ for WStar). + This does work currently for LINUX only, + the main problem was screen redrawing at SIGCONT. + #146 +-------------------------------------------------------------- +Mon Nov 26 20:06:50 2001 Albrecht Kleine <kleine@ak.sax.de> + + -hide return character 0dh on W32 version (expecting + 0d0a line delimiter) / control via %define W32LF + So the W32 version of e3 can edit texts with 0d0a + and single 0ah correctly. The Linux/*BSD/BeOS/QNX- + versions will continue showing 0dh characters as + single dots. + #145 +-------------------------------------------------------------- +Wed Nov 21 19:15:58 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added Makefiles and ported binaries to distribution + archive for the OpenBSD and NetBSD operating systems + #144 + ***** released as v1.82 ***** +-------------------------------------------------------------- +Sat Nov 10 20:05:05 2001 Albrecht Kleine <kleine@ak.sax.de> + + -continued QNX stuff (cursor key handling etc.) + +Thu Nov 08 17:03:00 2001 Terry Loveall <loveall@qwest.net> + + -added 19 short prefixes to jumps for assembling with newer + NASM versions (w/o using special command line switches) + #143 + ***** released as v1.81 ***** +-------------------------------------------------------------- +Thu Nov 08 16:50:17 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added initial basic support for QNX 6.1 Realtime OS + done by dynamic linking with /usr/lib/libc.so.1, + this is controled by %ifdef QNX + #142 +-------------------------------------------------------------- +Fri Nov 02 16:47:00 2001 Albrecht Kleine <kleine@ak.sax.de> + + -cleanup for release + -Makefile: added desination "w32lst" for + cross assembling w32 versions on Linux + -man page: updated for W32 versions + -added e3.html as manual page substitute for W32 systems + #141 + ***** released as v1.8 ***** +-------------------------------------------------------------- +Sun Oct 28 21:12:44 2001 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix ^F WStar (did not stop at line begin) + -Win9x: enhanced screen redrawing with colors + (select via %define W32_EXTENDED_IO) + #140 +-------------------------------------------------------------- +Sun Oct 21 16:09:58 2001 Albrecht Kleine <kleine@ak.sax.de> + + rewrote key handling (for alt- and cursor keys) on Win9x + #139 +-------------------------------------------------------------- +Sat Oct 20 13:09:36 2001 Albrecht Kleine <kleine@ak.sax.de> + + initial port to Win9x + (no cursor keys, no Alt keys, no colors & very slow) + #138 +-------------------------------------------------------------- +Sun Oct 14 18:34:18 2001 Albrecht Kleine <kleine@ak.sax.de> + + -rewrote the vi mode marker commands: + ma , d'a and y'a . Added 'a (=jmp to marker). + Tnx to Matthias Kopfermann for bug report. + -added mulinux patch by Philipe Corbes. Tnx. + #137 + ***** released as v1.71 ***** +-------------------------------------------------------------- +Tue Aug 21 15:02:46 2001 Charles Steinkuehler <charles@steinkuehler.net> + + -added :x command to the vi emulation mode of e3 + #136a +-------------------------------------------------------------- +Sun Jul 8 18:44:08 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added variable 'r' and constant 'p' to calc module: + r is for using last result in next calculation, + p is PI (more precise than simply using 3.141593) + #136 + ****** released as v1.7 ****** +-------------------------------------------------------------- +Mon Jun 25 20:37:45 2001 Albrecht Kleine <kleine@ak.sax.de> + + -completed arithmetics by adding parenthesis () + to calc parser + -added build option BUILTINHELP on top of e3.asm + (undefine if you really don't need help, + but saves 30% space in uncompressed version) + and 18% in gzexe-compressed version) + -added arithmetics to man page + #135 +-------------------------------------------------------------- +Tue Jun 19 21:18:14 2001 Albrecht Kleine <kleine@ak.sax.de> + + -completed arithmetics by adding signs to parser + -premium bugfix in subtraction: a-b-c now a+(-b)+(-c) + #133,#134 + ****** released as v1.62 ****** +--------------------------------------------------------------- +Sun Jun 10 14:57:38 2001 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix tabulator in very long lines + -bugfix: helptext vi + -bugfix: characters 0x80-0x9F now shown as a dot + -horizontal scrolling in long lines now earlier + #132 + ****** released as v1.61 ****** + including different binaries for BeOS, FreeBSD) +-------------------------------------------------------------- +Mon May 28 20:23:00 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added another wrapper script (see contrib directory) + thanks to Tito <farmatito@tiscalinet.it> + -e3.asm: + initial try for simple arithmetics with +-*/ + using a recursive descent parser + #127-#131, several steps + ****** released as v1.6 ****** +-------------------------------------------------------------- +Sun May 6 21:36:46 2001 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: improved WStar mode: + -added ^Z, ^W for scrolling up/down + (cursor tries to stay at his original line) + -changed ^J to help page + -changed ^A,^F in WStar mode for skipping by word + (thanks for note to Dan Strychalski) + #126 (released as v1.51, + including 3 different compressed binaries) +-------------------------------------------------------------- +Sun Apr 22 13:04:06 2001 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: removed line wrapping in vi mode + (fixing vi mode command keys l,h,a) + +Tue Apr 17 13:35:05 2001 David Douthitt <n9ubh@callsign.net> + README file: review and update + Makefile: fixed upx compressor usage + #125 ****** released as v1.5 ********* +------------------------------------------------------------- +Tue Apr 17 20:25:10 2001 Albrecht Kleine <kleine@ak.sax.de> + + -added experimental beeping in case of unsupported + VI command letters (but not at EOF,BOF,EOL,BOL) + [ configured via %define BEEP_IN_VI ] + -added experimental beeping if child process 'sed' + complains about a wrong input command line + Also avoids writing sed's STDERR to our edit screen. + [ configured via %define CAPTURE_STDERR ] + #124 +------------------------------------------------------------- +Mon Apr 16 21:38:06 2001 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: vi emulaton mode: + -added 'yy' key binding + -added variable "VInolinebased" for controling + line based pasting + -improved d'a y'a (re-numbering, cursor position etc.) + #123 +--------------------------------------------------------------- +Sun Apr 15 20:58:16 2001 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: added 'D','C' key binding for vi command mode + #122 +-------------------------------------------------------------- +Sun Mar 25 12:16:15 2001 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: added 'r' key binding for vi command mode + #121 +-------------------------------------------------------------- +Sat Mar 24 22:11:22 2001 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: adding a carriage return to the end of the + file if there isn't any (vi mode only) + -e3.asm: bugfix in vi mode :w! command: + no more writing files named '!' + (thanks for report to David Douthitt) + +Fri Mar 16 01:53:38 2001 Adrian Bunk <bunk@fs.tum.de> + Makefile: replaced upx compresor with gzexe + (save more than 1024 bytes in executable) + +Thu Feb 15 19:01:09 2001 Hilton Chiang <hilton_chiang@ipmental.com.tw> + e3.c: changed 'columns' setting in e3.c to fix it to 80x24 + (due portability problems) + #120 +------------------------------------------------------------- +Mon Jan 1 12:00:00 2001 Albrecht Kleine <kleine@ak.sax.de> + + -tested for running in Linux ak 2.4.0-test7: ok + -adjusted 'ex' path to more common '/usr/bin/ex' + -extended backup copy procedure (preserve change time) + #119 ****** released as v1.4 ********* +-------------------------------------------------------------- +Wed Dec 27 19:08:08 2000 Albrecht Kleine <kleine@ak.sax.de> + + -fixed handling of Del key in FreeBSD + -added specials for FreeBSD for piping via sed or ex + -Pico mode: added ^JT for repeating ^T (search&replace) + +Fri Dec 22 10:54:02 2000 Zas <lmonin@metaconcept.com> + -Pico mode: added ^JP for buffer piping like in vi mode + #118 +-------------------------------------------------------------- +Sat Dec 23 13:56:22 2000 Albrecht Kleine <kleine@ak.sax.de> + + -divide (via readlink) between files and symlinks + for back-up method (rename or copy old file) + -added initial backup copy procedure + -added changes for making error free assembling + on FreeBSD and BeOS : thanks for note to + Joseph Scott <joseph@randomnetworks.com> + #117 +-------------------------------------------------------------- +Tue Dec 19 18:07:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added access to vi's EX cmdline to WStar and + Emacs modes using either ^KP or ^X^P + -bugfix in esi parameter to "wait4" kernel call + -bugfix line re-numbering after deleting in pipe + -bugfix checking cursor position after pipe errors + #116 ****** released as v1.3 ********* +-------------------------------------------------------------- +Sun Dec 17 18:22:12 2000 Albrecht Kleine <kleine@ak.sax.de> + + -vi mode only: added a way for child process running + /bin/ex instead of /bin/sed (have different interfaces) + (Use ex by setting EXMODE to EX in makefile!) + #115 +-------------------------------------------------------------- +Sat Dec 16 11:34:28 2000 Albrecht Kleine <kleine@ak.sax.de> + + -ask before saving in Emacs mode key ^X^F, + ditto Nedit mode keys ^N and ^O + -prevent buffer mark problems if start editing + another file + #114 +------------------------------------------------------------- +Fri Dec 15 21:45:03 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added buffer overflow protection in sed piping + -added internal EOF marker handling in sed piping + -checked bad values before try to paste + #113 +-------------------------------------------------------------- +Wed Dec 13 20:21:15 2000 Albrecht Kleine <kleine@ak.sax.de> + + -improvements nedit mode ^A,^W + -added error checking to sed piping process + #111,#112 ****** released as v1.2 ********* +-------------------------------------------------------------- +Sun Dec 10 16:48:45 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added nedit-similar new mode + due request by Denis <jido@respublica.fr> + -improvements in sed pipe + -e3.c: removed usage of multibyte chars because not + portable to mips systems + #110 +-------------------------------------------------------------- +Sat Dec 9 20:05:05 2000 Albrecht Kleine <kleine@ak.sax.de> + + -initial piping through /bin/sed using a helper file + (vi mode under Linux only) / (thanks Michele for idea) + -bugfix vi mode: exchanged ^U and ^D + (thanks for report to David Duffy <davidD@qimr.edu.au>) + -bugfix vi mode: search is now case sensitive + (thanks for report to David Douthitt) + -re-added e3c to the distribution, but separated + #109 +-------------------------------------------------------------- +Sat Dec 9 20:05:04 2000 Albrecht Kleine <kleine@ak.sax.de> + + -very fruitless experiments for bidirectional piping + through /bin/sed + -introduction of using UPX packer in Makefile + see http://wildsau.idv.uni-linz.ac.at/mfx/upx.html + #107,#108 +-------------------------------------------------------------- +Mon Dec 4 19:33:07 2000 Albrecht Kleine <kleine@ak.sax.de> + + -fixed a bug in optslen (only for vi :e,:w of interest) + (tnx bug report Aaron Lehmann <aaronl@vitelus.com>) + -changed Makefile for FreeBSD and BeOS (ELF header build) + #106 (v1.1a released) +-------------------------------------------------------------- +Sun Dec 3 10:51:19 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added :e <file> command for the vi-friends + -added "edit mode switching" to the list of + documented commands (^KM, ^QM, ; , altX) + #105 ****** released as v1.1 ********* +-------------------------------------------------------------- +Sat Dec 2 17:41:31 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added e, G, 1G and ma, d'a, y'a commands for + the vi-friends (as recommended by David Douthitt) + attention: <n>G is not yet available! + -bugfix in P and p (vi paste) + #104 +-------------------------------------------------------------- +Wed Nov 22 17:37:15 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added 'z.' and ':w <file>' commands for the vi-friends + (now using cripled ELF header by default, compare #62) + #103 +--------------------------------------------------------------- +Sun Nov 19 10:25:15 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added bugfix for buffer overflow protection (e3pi,e3em) + (tnx report to Zas <lmonin@metaconcept.com>) + -squeezed some byte using 'short' attributes etc. + -setting block variable and emacs killbuffer size to 0 + avoiding side effects for save online edit-mode switching + -added 'ZZ' command for the vi-friends + #102 (v1.02 released) +-------------------------------------------------------------- +Sun Nov 12 10:35:35 2000 Albrecht Kleine <kleine@ak.sax.de> + + -squeezed ca.16 byte from KeyHelp, LookPageUp + added :w for vi mode, completed vi mode help + -bugfix dd/^K for vi/pico modes (crash if last line) + (tnx report Sergei Viznyuk <sviznyuk@hotmail.com>) + +Sat Nov 11 10:00:29 2000 David Douthitt + <ddouthitt@mennonite.minister.net> + -added wrapper script for sequential editing of files + #101 (v1.01 released) +-------------------------------------------------------------- +Fri Nov 10 18:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + bugfixes & last minute changes & clean up + #100 ****** released as v1.0 ********* +--------------------------------------------------------------- +Wed Nov 8 19:51:57 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added S,X for vi cmd mode, bugfix :<line> vi mode + -another patch for serial connections (tnx LRP folks) + -updated manpage+README + -bugfix in Alt-X (and friends) + -bugfix in ^QF (and friends) + #99 +-------------------------------------------------------------- +Tue Nov 7 21:11:11 2000 Albrecht Kleine <kleine@ak.sax.de> + + -MERGED ALL editor emulations TOGETHER + -moved "equ" to top for shorter code + -added online help+initial help pages + -tons of bugfixes for #96,#97 + -removed e3c.c from distribution and Makefile + -removed e2dos from distribution and Makefile + #98 +-------------------------------------------------------------- +Wed Nov 1 21:57:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm finished limited vi mode by adding this + commands: ^D,^U,^,/,?,p,P and changed 'I' + -e3.asm extendend PICO mode for some + ^Q Quick move + ^J Junk - operations + -e3.asm chg. exit choices to save: select between Y,n,l + (Y)es is default, l means "save+load_new_file" + -e3.asm WS mode: bugfix for ^QH + -e3.asm added %define MAKE_BACKUP (default is ON) + -e3.asm differ between ^J and ^M via terminal control + removing "icrnl" terminal property + -added/rewrote help texts + #97 branded v0.98 +------------------------------------------------------------- +Tue Oct 24 21:14:32 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: added initial PICO emulation mode: + differs from PICO as follows + ^O save (not save_as) + ^S save_as + ^XL save & load a new file + ^T search & replace, not 'to spell' + #96 +------------------------------------------------------------- +Fri Oct 20 21:14:43 2000 Albrecht Kleine <kleine@ak.sax.de> + + -e3.asm: bugfix missing ^QZ, renamed ALL_IN_ONE + with HELPFILES_INCLUDED + -e3.asm: intro some basics of the VI emulation mode + -e3.asm: bugfix ^S Emacs mode + #95 ******* released as v0.9 ******** +------------------------------------------------------------- +Sun Oct 15 19:41:09 2000 Albrecht Kleine <kleine@ak.sax.de> + + -asm+c: bugfix ^QP in wordstar mode + -e3c.c: bugfix ^KC (if cursor is inside block) + -renamed help text files for handling both (emacs+ws) + -e3.asm: some finetuning emacs mode, added ^X^W + #94 +------------------------------------------------------------- +Wed Oct 11 21:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + -e3.asm: now wrapping cursor around at left and + right margin (like joe, emacs etc) + -e3.asm: EMACS mode: add/rewrote ^K, region stuff, + ^L, alt F, alt B + #93 +------------------------------------------------------------- +Sun Oct 8 19:07:34 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: added basic EMACS emulation mode using most + important 8 Alt-keys, 5 Ctrl-X-keys, 20 Ctrl-keys + Compile it via %define EMACS + Problems: ^K works different+confusion with WS blocks + #92 +------------------------------------------------------------ +Sun Oct 1 11:42:50 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: rewrote cursor key and control key handling + using another XLAT table (saves another 32 byte) + #91 +------------------------------------------------------------- +Sun Sep 24 11:35:53 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.asm: sqeezed once more 32 byte from executable, + mostly by replacing inc/dec 8 bit with 32 bit version + #90 ******* released as v0.8 ******** +------------------------------------------------------------- +Sun Sep 17 11:39:14 2000 Albrecht Kleine <kleine@ak.sax.de> + + -Added 'make special' to Makefile: this will produce + an e3 executable with helper file contents inside + *one* file via defining ALL_IN_ONE. + -Sqeezed e3.res for this purpose and adjusted e3.c . + -Added Make_helper_inc script (using Perl) for + converting e3.res and e3.hlp into NASM syntax. + -e3.c bugfix in MoveBlock + -e3.hlp, e3.man added forgotten help text for ^KV + #89 +------------------------------------------------------------- +Mon Sep 4 17:36:09 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.c: removed usage of CY and ZR flags + (resulting better performance and less size) + Makefile: added '-fomit-frame-pointer' to gcc options + #88 +------------------------------------------------------------- +Sun Sep 3 10:07:42 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.c: removed 8 bit sub-register usage (al,bl,..), + started removing flag register usage + #87 +------------------------------------------------------------- +Sat Sep 2 20:45:15 2000 Albrecht Kleine <kleine@ak.sax.de> + e3.asm,e3.c: removed old keybard scancode values + (heritage from old DOS version) + #86 +------------------------------------------------------------- +Sat Sep 2 13:07:04 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3c: removed any side effects resulting in al,ah + as part of eax,bl,bh part of ebx ... etc. etc. + now no more register unions, made variables local + #85 +------------------------------------------------------------- +Fri Sep 1 22:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.c: some steps to improve C version + #82,#83,#84 +------------------------------------------------------------- +Wed Aug 23 20:31:26 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.c: changed usage of flags (sf,cy) + #81 ******* released as v0.7 ******** +------------------------------------------------------------- +Sun Aug 19 20:31:26 2000 Albrecht Kleine <kleine@ak.sax.de> + + e3.c: bugfix in Delete, also removed some useless + sf() calls, bugfix for #ifdef, added missing h files + #80 +------------------------------------------------------------- +Sat Aug 19 21:03:08 2000 Albrecht Kleine <kleine@ak.sax.de> + + -some clean up for releasing + -adjusted makefile + -e3.asm: replaced one jl with jb + -e3.c: removed some useless sf() calls, + bugfix: unsigned char vs. char + bugfix in ^QB + #79 +------------------------------------------------------------- +Fri Aug 18 19:12:44 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added support of VT300 terminal keys (not available + on asm version to keep tiny) + -added changes for running on OSF/1 Unix (64 bit + Alpha CPU machines) related to data alignment errors. + #78 (C-version only) +------------------------------------------------------------- +Thu Aug 17 22:00:10 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added a C written version (!!!) of e3 for + generic platforms. This is a functional copy + of #76, with minor changes in system interfaces + (kernel calls and termios handling). + #77 (C-version only) +------------------------------------------------------------- +Wed Aug 16 18:55:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix: added check for ioctl/TIOCGWINSZ syscall + aginst size 0/0 (so using 80x24 in case of problems) + tnx bug report to Urs Rau <urs.rau@uk.om.org> + -bugfix: replaced one forgotten di with edi + -removed 3 unused labels + #76 +------------------------------------------------------------- +Sun Jun 18 21:20:03 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix: empty replace string is allowed (in ^QA) + #75 +------------------------------------------------------------- +Sat Jun 10 10:19:28 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix for Ctrl-L (was bug if already searched and + later empty search string) + -bugfix for bugfix in #71 (redisplay problem) + -sqeezed some byte for BeOS to keep < 5000 byte + #74 +------------------------------------------------------------- +Sat Jun 3 14:58:22 2000 Albrecht Kleine <kleine@ak.sax.de> + + -workaround for 'crontab -e' problem + (no more RenameFile in /tmp files) + #73 ******* released as v0.6 ******** +------------------------------------------------------------- +Sat Jun 3 12:32:24 2000 Albrecht Kleine <kleine@ak.sax.de> + + -enhanced BeOS support + (now supporting all e3 functions, the syscalls are + working completely, but in some cases sometimes + I don't know why ;) + -bugfix showing line numbers in BeOS + -bugfix setting block begin mark (bug intro in #69) + #72 +------------------------------------------------------------- +Fri Jun 2 13:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix for missing redisplay in function Inputstring + (set new cursor position) if ' ' [=chr(32)] entered. + (This bug was introduced in build #63.) + #71 +------------------------------------------------------------- +Fri Jun 2 12:27:24 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added initial support for BeOS (PE 5) + (all except ^KR supported) + #70 +------------------------------------------------------------ +Tue May 30 20:10:40 2000 Albrecht Kleine <kleine@ak.sax.de> + + reorganized Inserting/Deleting (squeezed 66 byte) + #69 +------------------------------------------------------------- +Sat May 27 19:31:37 2000 Albrecht Kleine <kleine@ak.sax.de> + + -replaced some mov eax,.. with xchg eax,... + single_byte opcode + #68 ******* released as v0.5 ******** +------------------------------------------------------------ +Thu May 25 19:42:29 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added missing chown/chgrp handling + -bugfix in NewFile + #67 +------------------------------------------------------------- +Wed May 24 19:27:29 2000 Albrecht Kleine <kleine@ak.sax.de> + + sqeezed another 15 byte around ESC sequence functions + SetInverseStatus, SetColor and SetColor2 + #66 +------------------------------------------------------------- +Wed May 24 19:01:31 2000 Albrecht Kleine <kleine@ak.sax.de> + + added protection against screenbuffer overflow + #65 +------------------------------------------------------------- +Tue May 23 21:06:43 2000 Albrecht Kleine <kleine@ak.sax.de> + + now reducing useless cursor movements also + #64 +------------------------------------------------------------- +Mon May 22 19:20:55 2000 Albrecht Kleine <kleine@ak.sax.de> + + -reduced counts of useless writes, but still some + useless cursor movements + -recuced sys_writeSL byte write count by 1 + #63 +------------------------------------------------------------- +Sun May 21 12:04:40 2000 Albrecht Kleine <kleine@ak.sax.de> + + -built an editor version using crippled ELF header + (saving 220 byte) inspired by an idea in "A Whirlwind + Tutorial on Creating Really Teensy ELF Executables + for Linux" by Tiny Software BR903. + You can create it by "make crip install" using Linux. + If you want debug, then better build a "standard"-e3! + #62 +------------------------------------------------------------- +Tue Apr 04 20:04:14 2000 Albrecht Kleine <kleine@ak.sax.de> + + -some experiments to reduce screen redrawing + (later discarded: heavy increases filesize) +------------------------------------------------------------- +Sun Apr 02 21:21:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added bugfix (FreeBSD errno) + #61 +------------------------------------------------------------- +Fri Mar 31 21.58.52 2000 Albrecht Kleine <kleine@ak.sax.de> + + -experimental usage of esc[K to clear to eol + -squeezing some more byte from excutable + -added spec file to ./contrib/ for later RPM support + #60 released as v0.4 +------------------------------------------------------------- +Sat Mar 25 16.32.12 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added old e2 for DOS to distribution + -bugfixes/enhancements in Makefile, + -initial e3.spec for providing RPM archives + thanks to Urs Rau <urs.rau@uk.om.org> + #59 +------------------------------------------------------------- +Fri Mar 24 23:00:02 2000 Albrecht Kleine <kleine@ak.sax.de> + + - removed bug in setting file permissions of existing + files using fstat system calls + #58 +-------------------------------------------------------------- +Sun Mar 19 17:38:41 2000 Albrecht Kleine <kleine@ak.sax.de> + + -release 0.3: + *sqeezed some more byte + *bugfixes + *initial support for FreeBSD + #57 released as v0.3 +------------------------------------------------------------- +Thu Mar 16 21:13:09 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added initial early support for FreeBSD + #56 +------------------------------------------------------------- +Wed Mar 15 21:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix in ^QE + -bugfix in KeyDel in empty files: + thanks to Mark Zealey <mark@itsolve.co.uk> + #55 +------------------------------------------------------------- +Sat Mar 11 21:08:21 2000 Albrecht Kleine <kleine@ak.sax.de> + + -sqeezed some more 44 byte + #54 +------------------------------------------------------------- +Sun Mar 5 21:12:26 2000 Albrecht Kleine <kleine@ak.sax.de> + + -added special inverse cursor handling on linux terminals + (to mark INS mode, but standard cursor for OVR mode) + -added BAK file (*~) producer code + #53, released as v0.2 +------------------------------------------------------------- +Sun Mar 5 12:00:01 2000 Albrecht Kleine <kleine@ak.sax.de> + + -rewrote InputString: no more simple read from stdin, + although current is not much better, but we avoid unwanted + scrolling and abort via ^U (like WStar) + #52 +------------------------------------------------------------- +Sat Mar 4 11:11:30 2000 Albrecht Kleine <kleine@ak.sax.de> + + -removed "fline,fcol" data assuming text window always + will start upper left at 0,0 (saves 72 byte) + -continued status line optimization (saves 20 byte) + -squeezed INT calls + -removed some mov ebx,std.. + #51 +------------------------------------------------------------- +Thu Mar 2 20:58:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + -removed unused instruction in ^KY + -touched ^QB,^QK + -squeezed around status line and sys_writeSLColors functions + (at all 34 byte) + #50 +------------------------------------------------------------- +Tue Feb 29 21:09:54 2000 Albrecht Kleine <kleine@ak.sax.de> + + -bugfix (handling ^C in file name & line number input) + -bugfix too less buffer space for small files + -rewrote IntegerToAscii (squeezing 20 byte) + -replaced some mov eax,.. with xchg eax,.. + #49 +------------------------------------------------------------- +Tue Feb 27 19:00:00 2000 Albrecht Kleine <kleine@ak.sax.de> + + public release 0.1, file #48 +------------------------------------------------------------- +Tue Jan 11 21:06:02 2000 Albrecht Kleine <kleine@ak.sax.de> + + started port of my old 1990 editor EDDI (was DOS v2.81) + to Linux + file #01 + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bb2f6e7 --- /dev/null +++ b/Makefile @@ -0,0 +1,169 @@ +# 1. edit you OS if you want.... + +OS=LINUX +#OS=BEOS +#OS=FREEBSD +#OS=QNX +#OS=ATHEOS +#OS=W32 ** please use a separate make.bat for W9x ** + +# Set this to gzexe or upx if you want compression +COMPRESS=gzexe + +# 2. edit dest dir prefix if you want.... + +PREFIX='/usr/local' +#PREFIX=/boot/home + + +# 3. for vi friends only (else leave as is): +# choice between '/bin/ex' or default '/bin/sed' +EXMODE=SED +#EXMODE=EX + + + +BINDIR='$(PREFIX)/bin' +MANSEC='1' +MANDIR='$(PREFIX)/man/man$(MANSEC)' + + +#______________________do not edit below line________________________ + + +ASOURCES=e3.asm e3.h +AFLAGS = -w+orphan-labels -f elf + +# this fixes a nasty NASM version conflict +# NASM 0.98.08 claims to use -O2 by default, but does not. +# NASM 0.98 does not know the -O2 switch +# +ASVER := $(shell nasm -r) +ifeq ($(ASVER),NASM version 0.98) + NASM=nasm +else + NASM=nasm -O2 +endif + + +all: e3 + +e3: $(ASOURCES) Makefile +ifeq ($(OS),LINUX) + echo $(ASVER) + $(NASM) -f bin -l e3.lst -o e3 e3.asm -DCRIPLED_ELF=1 -D$(OS) -D$(EXMODE) + chmod +x e3 +ifeq ($(COMPRESS),upx) + if which upx > /dev/null 2>&1 ; then \ + upx -q -q -q -k -9 e3 ; \ + fi ; +endif +ifeq ($(COMPRESS),gzexe) + if which gzexe > /dev/null 2>&1 ; then gzexe e3; fi; +endif +else + echo $(ASVER) + $(NASM) $(AFLAGS) -o e3.o e3.asm -l e3.lst -D$(OS) -D$(EXMODE) +ifeq ($(OS),QNX) + ld -s -o e3 e3.o -lc +else + ld -s -o e3 e3.o +endif + strip --remove-section .comment e3 +endif + ln -sf e3 e3ws + ln -sf e3 e3em + ln -sf e3 e3pi + ln -sf e3 e3vi + ln -sf e3 e3ne + +# next three are for testing purpose: linking w libc +statc: + $(NASM) $(AFLAGS) -o e3.o e3.asm -l e3.lst -DLINUX -DLIBC -D$(EXMODE) + ld -s -static -o e3statc e3.o -lc + +dync: + $(NASM) $(AFLAGS) -o e3.o e3.asm -l e3.lst -DLINUX -DLIBC -DDYN -D$(EXMODE) + gcc e3.o -o e3dync + # strip e3dync + +dync2: + $(NASM) $(AFLAGS) -o e3.o e3.asm -l e3.lst -DLINUX -DLIBC -DDYN -D$(EXMODE) + ld -s -m elf_i386 -o e3dync2 e3.o \ + -lc -dynamic-linker /lib/ld-linux.so.2 \ + /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o + + +# next for running in gnu debugger +debug: $(ASOURCES) Makefile + $(NASM) $(AFLAGS) -g -o e3.o e3.asm -l e3.lst -D$(OS) -D$(EXMODE) + ld -s -o e3 e3.o + strip --remove-section .comment e3 + ln -sf e3 e3ws + ln -sf e3 e3em + ln -sf e3 e3pi + ln -sf e3 e3vi + ln -sf e3 e3ne + +# selftest, linux only, assembled with a special option for using an input pipe +test: +ifeq ($(OS),LINUX) + $(NASM) -f bin -l e3.lst -o e3test e3.asm -DSELFTEST -DCRIPLED_ELF=1 -DLINUX -D$(EXMODE) +ifeq ($(COMPRESS),upx) + if which upx > /dev/null 2>&1 ; then \ + upx -q -q -q -k -9 e3test ; \ + fi ; +endif +ifeq ($(COMPRESS),gzexe) + if which gzexe > /dev/null 2>&1 ; then gzexe e3test; fi; +endif + if [ -f PIPE_IN ]; then rm PIPE_IN ; fi + if [ -f e3test~ ]; then rm e3test~ ; fi + chmod +x e3test + cat e3.h tests/e3test0 | ./e3test + clear + diff e3.h PIPE_IN && echo -e "\n\n\n**** THE TEST WAS SUCCESSFUL ****\n\n\n" + rm PIPE_IN e3test +endif + +# next for cross asm for the ELKS people +elks: + nasm -w+orphan-labels -f as86 -o e3-16.o e3-16.asm -l e3-16.lst -D AS86 -D ELKS + ld86 -0 -s -i -H 0xF800 -o e3-16 e3-16.o + + +# next two for cross asm testing +w32lst: + $(NASM) -f coff -o e3.oW32 e3.asm -l e3.lstW32 -DW32 + rm e3.oW32 + +qnxlst: + $(NASM) -f elf -o e3.oQNX e3.asm -l e3.lstQNX -DQNX + rm e3.oQNX + +# next for release maintainance +man2html: + rman -f HTML e3.man >e3.html + +install: e3 +ifeq ($(OS),QNX) + cp ./e3 $(BINDIR)/e3 + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ws + ln -sf $(BINDIR)/e3 $(BINDIR)/e3em + ln -sf $(BINDIR)/e3 $(BINDIR)/e3pi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3vi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ne +else + install -d $(PREFIX) $(BINDIR) $(MANDIR) + install -m 755 e3 $(BINDIR) + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ws + ln -sf $(BINDIR)/e3 $(BINDIR)/e3em + ln -sf $(BINDIR)/e3 $(BINDIR)/e3pi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3vi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ne + install -m 644 e3.man $(MANDIR)/e3.$(MANSEC) +endif + +clean: + rm -f e3*.o e3*.lst e3 e3em e3pi e3vi e3ws e3ne *~ \ + PIPE_IN e3test~ e3test e3dync e3dync2 e3statc @@ -0,0 +1,312 @@ +README for mini editor e3 release 2.3 + +(c) GPL 2000-02 Albrecht Kleine +mailto:kleine@ak.sax.de + + +1. OVERVIEW +=========== +e3 is a collection of micro text editors with an executable code +size between 3500 and 20000 bytes, depending on used assembler options, +platform and self compressor. +Except for 'syntax highlighting', the e3 binary supports all of the basic +functions one expects plus built in arithmetic calculations. If you have +installed the stream editor 'sed' you can use these tools as sub-processes, +getting the full power of regular expressions. + +e3 can use Wordstar-, EMACS-, Pico, Nedit or vi-like key bindings, +whichever the user chooses. + +Also the user can calculate arithmetics inside the text. + +e3's assembler version is available on Linux, FreeBSD, NetBSD, +OpenBSD, BeOS, QNX, Win9x, Atheos, and just new in a 16 bit version (e3-16) +for DOS and ELKS (==Embeddable Linux Kernel Subset). + +There is also a GNU-C-written version for non-i386-Unix +platforms (e3.c) using Wordstar keybindings only. This README +doesn't further mention e3.c. (Just make it!) + +e3 is designed to be INDEPENDENT OF LIBC OR ANY OTHER library, +except on the QNX and Win32 operating systems. +It's been tested using the terminal console, but Xterm, Eterm, +kvt, rxvt, vt220 and vt100 should work too. +It's been tested under several x86 OS: + * Linux kernels 2.0, 2.2, 2.4 + * FreeBSD 2.2, 3.1, 4.4 + * OpenBSD 2.9 + * NetBSD 1.51 + * BeOS 5PE + * Win98 + * QNX RTP 6.1 + * Atheos 0.3.7 + * FreeDOS kernel 1.1.24 + * ELKS pre 0.1 (vt52 emulation) + + +2a. BUILD on Linux/FreeBSD/BeOS/QNX/Atheos +========================================== +A. For assembling of e3 you need NASM assembler v0.98 or v0.98.08 + +B. Unless you build a debug version ("make debug") Makefile will call + a compressor for executables, but in Linux only and only if you + have defined either gzexe or upx in Makefile. + UPX comes from http://wildsau.idv.uni-linz.ac.at/mfx/upx.html . + +C. If you don't like the default OS or destination (LINUX , /usr/local/ ) + then edit Makefile (other possible OS are FreeBSD or BEOS or QNX + or ATHEOS). + +D. e3 is expecting "sed" at /bin/sed, or "ex" at /usr/bin/ex; otherwise change + SEDPATH in e3.asm. By default /bin/sed is used, but you can + use /usr/bin/ex instead, if you edit Makefile as appropriate. + (NOT available for BeOS,QNX,Atheos)) + +E. Build e3 via typing 'make' (or 'gmake' on FreeBSD) for building: + e3 : the default Wordstar-like version, + e3ws : ditto Wordstar, + e3em : the Emacs-like version, + e3pi : the Pico-like version, + e3vi : the vi-like version. + e3ne : the Nedit-like version. + (e3?? are symbolic links to e3. In fact only one executable is built.) + +F. Optional: type 'make install' or + move or copy e3 and its symlinks wherever you want. + +G. Optional: some more editable options are on top of e3.h: + for example, if you don't like WS mode, choice an other default mode + by setting DEFAULT_MODE to one of EM, NE, PI or VI . + Also you could activate error beeping in vi mode by uncommenting + the BEEP_IN_VI line. + + +2b. BUILD on Win9x / ME / DOS +============================= +A. For assembling of e3 you need NASM assembler v0.98, + and ALINK (Anthony's Linker) and Win32 Import Library (win32.lib) + Both are available for free on the net: + http://www.octium.net/nasm/ + http://alink.home.dhs.org/ + +B. Type 'make' , i.e. run make.bat, and move e3.exe, e3-16.com + and e3*.bat wherever you want. + +C. Optional: some more editable options are on top of e3.h: + for example, if you don't like WS mode, choice an other default mode + by setting DEFAULT_MODE to one of EM, NE, PI or VI . In this + case you would not need to call one of the batches to run + your favourite mode. + + +2c. BUILD on NetBSD,OpenBSD +=========================== +Here are 2 Makefile for BSD-make included. +In general you don't need to change that files. + + +2d. BUILD for ELKS +================== +This is done on usual 32 bit x86 Linux systems either +by typing "make elks" or changing to elks/ and typing "make". +You need to have installed the ld86 linker. (If you are interested +in ELKS systems I think you have it already on the harddisk.) + + + +3. RELEASE NOTES +================ +* Added a 16 bit version of e3 (aka e3-16) supporting DOS and + ELKS (==Embeddable Linux Kernel Subset) in one source code. + This initial release supports WS keys only. + With e3-16 now we have e3 editors on the 9th and 10th operating system. +* Changed the Win32 version by replacing the DOS stub with e3-16 to + do something useful instead of complaining about "it can run + only under Win32". + So you have TWO different editor executables in ONE file! + + + +4. BASIC USAGE +============== +* All versions of e3 accept a filename as argument; see the man page. + +* There is a status and input line, where you can enter filenames, + find-texts, line numbers etc. In the lower right corner you will find + a code like "WS" showing the selected editor mode and a help + pointer (EXCEPT vi). + +* e3 changes the appearance of the cursor (to reverse) depending on + insert/overwrite mode (on Linux text console only). + +* For details on key bindings read each e3xx's initial page or + type Alt-H during edit (for vi use ESC:h). + +* On some computers (BeOS, QNX etc.) Alt-key combinations won't work: + press <ESC> followed by the key, e.g. press ESC and H instead of Alt-H. + +* e3 shows a dot for characters below ASCII 20h and between 80h and 9Fh + (except win9x). + +* At the end of an edit cycle, e3 asks you something like "SAVE? Ynl". Press + "n" to NOT save, "l" for SAVE and LOAD new, any other for SAVE and EXIT. + + +5. ARITHMETICS +============== +You can do some simple arithmetic calculations inside your text. +For example: + 1234+56*78= +place cursor here^ and press one of: + + ^KN for WSTAR mode + ^QC for PICO mode + ^X^N for EMACS mode + # for VI command mode + ^K for NEDIT mode +This should insert the result of 5602 into text. + + +Use values -999999999999.999999 ... -0.000001, 0, 0.000001 up to +999999999999.999999 and operators +-*/ and ( ) . + +Some more examples: + 2+4*8=34 + 2/3*3=2 + -4*-3--5*-4=-8 + 4-3--4-3=2 + -5*-(13+-2*(3+4))+2=-3 + (7*(((((6+2+(((((1)))))))))))=63 + (13120-9972)/9972=0.315684 + 100000000+0.000001=100000000.000001 + 10000000000+1=10000000001 + 1+1*2*3*4*5*6*7*8*9*10=3628801 + 7.627891*2.643189=20.161958 + 10000000000/8=1250000000 + 100000000000+1.00001=99999997953.00001 <--loss of precision! + 8/0= <--not possible. You know. + 100000000*100000000= <--overflow + +Some specials: + 12*p=37.699112 <--p is PI 3.14..... + r+20=57.699112 <--r is result of last calculation + +This arithmetic calculator is the smallest and simplest I could write. +It takes only some hundred byte in the executable because it does NOT use +precise BCD arithmetics, but built in x87-coprocessor features. So please +do NOT expect very high precision. + + + +6. MIXED HINTS +============== +* The emacs-mode version has currently a kill buffer but no kill ring, + so be careful about that. I'm sure, inside 10000 byte you won't + expect a complete Emacs key set, but IMHO you get the most important part. + +* The Pico mode is both: extended and incomplete compared to some Pico options, + new are some ^J (delete) and ^Q (quick_move) keys. + +* The size of files you edit is currently limited to the maximum of either + 100k or twice the file's size if you start with a file on command line, i.e., + for example, starting e3 with a 2MB_sized_file gives you another 2 MB space + for inserts. + +* You can choose inside the edit session (w/o leaving e3) between the + different edit modes, for example: + -start e3em <filename> + ---> now using Emacs style keys. + -type altX + -type e3vi + ---> welcome in the land of vi! + -type <ESC>; + -type e3ws + ---> you are entering Wordstar emulation sector! + ....etc.... + This VERY hot keys are ^KM (for WS), ^QM (for Pico), altX (for Emacs), + ^E (for Nedit) and <ESC>; (for vi-mode). + + Note: on some computers press ESC X instead of altX. + +* Everytime if e3vi does not recognize a vi-mode ex command, e3vi will pipe + the whole editor text buffer through /bin/sed or /bin/ex. I.e. you can use + pure sed or ex commands like: + 1,6 s/foo/bar/ + 2,$ d + 8,$ w filecopy + /remove_me/d + ***TAKE CARE***: "sed" or "ex" won't know your current cursor position in e3! + What call to subprogram (either ex or sed) is compiled in + you can find in helptext: + "pipe buffer through /bin/sed" + vs. + "pipe buffer through /bin/ex" + You should know this because the syntax is not equal: + s/./\./ <--sed syntax + 1,$ s/./\./g <-- ex syntax + Also you should know what "sed" version you have installed, + because sed 2.x and sed 3.x are quite different. + You can use this new buffer pipe features also from WS-, Pico- and Emacs modes + by pressing ^KP (Wordstar), or ^JP (Pico), or ^X^P (Emacs). + +* There is no predefined UNDO level count. You can expect to UNDO at least + one last insert-, delete-, overwrite- or sed_pipe-operation, but in most + cases there are lots of UNDO stages available. e3 has a fixed size undo buffer + and will use an external helper file if some deleted data is bigger sized + than the undo buffer. This buffer is organized as a ring, overwriting + older UNDO information if neccessary. So one never can say exactly + how many UNDO operations are possible. + For using the UNDO press one of: + ^U for WSTAR mode + ^QU for PICO mode + ^_ for EMACS mode + u for VI command mode + ^U for NEDIT mode + + +7. FILES +======== +Makefile - (edit destination path and OS if desired) +e3.asm +e3-16.asm +e3.h - NASM source code +e3.man - man page (copied by default to /usr/local/man/man1) +e3.html - man page, HTML version +e3.spec - spec file for building RPM archives +README - you are reading this +ChangeLog - version history +COPYING.GPL +COPYRIGHT - please read before using e3! +test/* - partial test suite +e3c/* - C stuff for non x86 systems, e.g. Alpha +contrib/* - useful things +doswin9x/* - specials for Win9x and its derivates +elks/* - specials for ELKS +binaries/* - binaries separated for some operating systems + NOTE: binaries for QNX,AtheOS,BeOS are no more included. + Sorry, but there never was any feedback. + + +8. THANKS +========= +Konstantin Boldyshev <konst at voshod.com> +Mark Zealey <mark at itsolve.co.uk> +Urs Rau <urs.rau at uk.om.org> +Terry Loveall <loveall at qwest.net> +David Douthitt <n9ubh at callsign.net> +Björn De Meyer <bjorn.demeyer at pandora.be> +Matthias Kopfermann <kopfermann at trio-hittfeld.de> +Tim Wegner <twegner at swbell.net> +Michele Andreoli <m.andreoli at tin.it> +Aaron Lehmann <aaronl at vitelus.com> +Zas <lmonin at metaconcept.com> +Sergei Viznyuk <sviznyuk at hotmail.com> +Philippe Corbes <philippe.corbes at laposte.net> +Charles Steinkuehler <charles at steinkuehler.net> +Adrian Bunk <bunk at fs.tum.de> + + +9. TM note +========== +Some names are trademarks of their owners: +Linux BSD BeOS QNX Unix WordStar Unox DOS Win Alpha BSE Atheos ELKS..etc. diff --git a/bin/Atheos/BUGS b/bin/Atheos/BUGS new file mode 100644 index 0000000..20d14d2 --- /dev/null +++ b/bin/Atheos/BUGS @@ -0,0 +1,8 @@ +Keyboard problems: + +* Home, End are not sending ESC sequences, but ASCII chars ^A,^F, + (maybe good for Emacs mode, but bad for WStar) +* using a German kbd map ^Z is at Ctrl+Y and NOT at Ctrl+Z, + + +I consider that as atheos bugs, not e3's bugs.
\ No newline at end of file diff --git a/bin/Atheos/e3 b/bin/Atheos/e3 new file mode 100755 index 0000000..f2b03f9 --- /dev/null +++ b/bin/Atheos/e3 @@ -0,0 +1,11 @@ +#!/bin/sh +clear +cat <<MSG +Dear e3/Atheos user, + +due less of feedback e3/Atheos binaries are no more shipped. +Please build it yourself by running make. Sorry for inconvenience. + +Albrecht Kleine +Sat Mar 16 17:06:04 MET 2002 +MSG
\ No newline at end of file diff --git a/bin/Atheos/e3em b/bin/Atheos/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Atheos/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Atheos/e3ne b/bin/Atheos/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Atheos/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Atheos/e3pi b/bin/Atheos/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Atheos/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Atheos/e3vi b/bin/Atheos/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Atheos/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Atheos/e3ws b/bin/Atheos/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Atheos/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/BeOS/e3 b/bin/BeOS/e3 new file mode 100755 index 0000000..5192b28 --- /dev/null +++ b/bin/BeOS/e3 @@ -0,0 +1,11 @@ +#!/bin/sh +clear +cat <<MSG +Dear e3/BeOS user, + +due less of feedback e3/BeOS binaries are no more shipped. +Please build it yourself by running make. Sorry for inconvenience. + +Albrecht Kleine +Sat Mar 16 17:06:04 MET 2002 +MSG
\ No newline at end of file diff --git a/bin/BeOS/e3em b/bin/BeOS/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/BeOS/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/BeOS/e3ne b/bin/BeOS/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/BeOS/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/BeOS/e3pi b/bin/BeOS/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/BeOS/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/BeOS/e3vi b/bin/BeOS/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/BeOS/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/BeOS/e3ws b/bin/BeOS/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/BeOS/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/DOS/e3-16.com b/bin/DOS/e3-16.com Binary files differnew file mode 100755 index 0000000..c1f0e91 --- /dev/null +++ b/bin/DOS/e3-16.com diff --git a/bin/ELKS/e3-16 b/bin/ELKS/e3-16 Binary files differnew file mode 100755 index 0000000..be06236 --- /dev/null +++ b/bin/ELKS/e3-16 diff --git a/bin/FreeBSD/e3 b/bin/FreeBSD/e3 Binary files differnew file mode 100755 index 0000000..70dcb17 --- /dev/null +++ b/bin/FreeBSD/e3 diff --git a/bin/FreeBSD/e3em b/bin/FreeBSD/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/FreeBSD/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/FreeBSD/e3ne b/bin/FreeBSD/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/FreeBSD/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/FreeBSD/e3pi b/bin/FreeBSD/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/FreeBSD/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/FreeBSD/e3vi b/bin/FreeBSD/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/FreeBSD/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/FreeBSD/e3ws b/bin/FreeBSD/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/FreeBSD/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3 b/bin/Linux/e3 Binary files differnew file mode 100755 index 0000000..e081e1e --- /dev/null +++ b/bin/Linux/e3 diff --git a/bin/Linux/e3_selfcompressed b/bin/Linux/e3_selfcompressed Binary files differnew file mode 100755 index 0000000..ac89eb4 --- /dev/null +++ b/bin/Linux/e3_selfcompressed diff --git a/bin/Linux/e3_uncompressed b/bin/Linux/e3_uncompressed new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3_uncompressed @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3em b/bin/Linux/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3ne b/bin/Linux/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3pi b/bin/Linux/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3vi b/bin/Linux/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Linux/e3ws b/bin/Linux/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/Linux/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/NetBSD/Makefile b/bin/NetBSD/Makefile new file mode 100644 index 0000000..6cba5be --- /dev/null +++ b/bin/NetBSD/Makefile @@ -0,0 +1,69 @@ +# Makefile for NetBSD +# (does not use GNU make extensions) +# +# On NetBSD we use some kind of Linux emulation mode +# (so you can use Linux settings completely) +# See some output from ktrace: +# 382 ktrace EMUL "netbsd" +# 382 ktrace RET ktrace 0 +# 382 ktrace CALL execve(0xbfbfdd77,0xbfbfdd00,0xbfbfdd0c) +# 382 ktrace NAMI "./e3" +# 382 e3 EMUL "linux" +# ......... +# + + +# 1. edit you OS if you want.... + +OS=LINUX # okay for NetBSD +#OS=BEOS +#OS=FREEBSD +#OS=QNX +#OS=W32 ** please use a separate make.bat for W9x ** + +# 2. edit dest dir prefix if you want.... + +PREFIX='/usr/local' + + +# 3. for vi friends only (else leave as is): +# choice between '/bin/ex' or default '/bin/sed' +EXMODE=SED +#EXMODE=EX + + + +BINDIR='$(PREFIX)/bin' +MANSEC='1' +MANDIR='$(PREFIX)/man/man$(MANSEC)' + + +#______________________do not edit below line________________________ + + +ASOURCES=e3.asm +AFLAGS = -w+orphan-labels -f elf + + +all: $(ASOURCES) Makefile + nasm $(AFLAGS) -o e3.o $(ASOURCES) -l e3.lst -D$(OS) -D$(EXMODE) + ld -s -o e3 e3.o + strip --remove-section .comment e3 + ln -sf e3 e3ws + ln -sf e3 e3em + ln -sf e3 e3pi + ln -sf e3 e3vi + ln -sf e3 e3ne + +install: e3 + install -d $(PREFIX) $(BINDIR) $(MANDIR) + install -m 755 e3 $(BINDIR) + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ws + ln -sf $(BINDIR)/e3 $(BINDIR)/e3em + ln -sf $(BINDIR)/e3 $(BINDIR)/e3pi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3vi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ne + install -m 644 e3.man $(MANDIR)/e3.$(MANSEC) + +clean: + rm -f e3*.o e3*.lst e3 e3em e3pi e3vi e3ws e3ne diff --git a/bin/NetBSD/README b/bin/NetBSD/README new file mode 100644 index 0000000..4bd0820 --- /dev/null +++ b/bin/NetBSD/README @@ -0,0 +1,4 @@ +This release does NOT carry binaries for +NetBSD and OpenBSD. Please build your own +using the included Makefiles. You don't +need GNU-make, so BSD-make will do the job. diff --git a/bin/NetBSD/e3em b/bin/NetBSD/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/NetBSD/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/NetBSD/e3ne b/bin/NetBSD/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/NetBSD/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/NetBSD/e3pi b/bin/NetBSD/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/NetBSD/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/NetBSD/e3vi b/bin/NetBSD/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/NetBSD/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/NetBSD/e3ws b/bin/NetBSD/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/NetBSD/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/OpenBSD/Makefile b/bin/OpenBSD/Makefile new file mode 100644 index 0000000..e5d29ae --- /dev/null +++ b/bin/OpenBSD/Makefile @@ -0,0 +1,58 @@ +# Makefile for OpenBSD +# (does not use GNU make extensions) +# + +# 1. edit you OS if you want.... + +#OS=LINUX +#OS=BEOS +OS=FREEBSD # okay for OpenBSD +#OS=QNX +#OS=W32 ** please use a separate make.bat for W9x ** + +# 2. edit dest dir prefix if you want.... + +PREFIX='/usr/local' + + +# 3. for vi friends only (else leave as is): +# choice between '/bin/ex' or default '/bin/sed' +EXMODE=SED +#EXMODE=EX + + + +BINDIR='$(PREFIX)/bin' +MANSEC='1' +MANDIR='$(PREFIX)/man/man$(MANSEC)' + + +#______________________do not edit below line________________________ + + +ASOURCES=e3.asm +AFLAGS = -w+orphan-labels -f elf + + +all: $(ASOURCES) Makefile + nasm $(AFLAGS) -o e3.o $(ASOURCES) -l e3.lst -D$(OS) -D$(EXMODE) + ld -s -o e3 e3.o + strip --remove-section .comment e3 + ln -sf e3 e3ws + ln -sf e3 e3em + ln -sf e3 e3pi + ln -sf e3 e3vi + ln -sf e3 e3ne + +install: e3 + install -d $(PREFIX) $(BINDIR) $(MANDIR) + install -m 755 e3 $(BINDIR) + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ws + ln -sf $(BINDIR)/e3 $(BINDIR)/e3em + ln -sf $(BINDIR)/e3 $(BINDIR)/e3pi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3vi + ln -sf $(BINDIR)/e3 $(BINDIR)/e3ne + install -m 644 e3.man $(MANDIR)/e3.$(MANSEC) + +clean: + rm -f e3*.o e3*.lst e3 e3em e3pi e3vi e3ws e3ne diff --git a/bin/OpenBSD/README b/bin/OpenBSD/README new file mode 100644 index 0000000..4bd0820 --- /dev/null +++ b/bin/OpenBSD/README @@ -0,0 +1,4 @@ +This release does NOT carry binaries for +NetBSD and OpenBSD. Please build your own +using the included Makefiles. You don't +need GNU-make, so BSD-make will do the job. diff --git a/bin/OpenBSD/e3em b/bin/OpenBSD/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/OpenBSD/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/OpenBSD/e3ne b/bin/OpenBSD/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/OpenBSD/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/OpenBSD/e3pi b/bin/OpenBSD/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/OpenBSD/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/OpenBSD/e3vi b/bin/OpenBSD/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/OpenBSD/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/OpenBSD/e3ws b/bin/OpenBSD/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/OpenBSD/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/QNX/e3 b/bin/QNX/e3 new file mode 100755 index 0000000..fedc4f0 --- /dev/null +++ b/bin/QNX/e3 @@ -0,0 +1,11 @@ +#!/bin/sh +clear +cat <<MSG +Dear e3/QNX user, + +due less of feedback e3/QNX binaries are no more shipped. +Please build it yourself by running make. Sorry for inconvenience. + +Albrecht Kleine +Sat Mar 16 17:06:04 MET 2002 +MSG
\ No newline at end of file diff --git a/bin/QNX/e3em b/bin/QNX/e3em new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/QNX/e3em @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/QNX/e3ne b/bin/QNX/e3ne new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/QNX/e3ne @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/QNX/e3pi b/bin/QNX/e3pi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/QNX/e3pi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/QNX/e3vi b/bin/QNX/e3vi new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/QNX/e3vi @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/QNX/e3ws b/bin/QNX/e3ws new file mode 120000 index 0000000..3e01419 --- /dev/null +++ b/bin/QNX/e3ws @@ -0,0 +1 @@ +e3
\ No newline at end of file diff --git a/bin/Win9x/e3.exe b/bin/Win9x/e3.exe Binary files differnew file mode 100755 index 0000000..31340f8 --- /dev/null +++ b/bin/Win9x/e3.exe diff --git a/bin/Win9x/e3em.bat b/bin/Win9x/e3em.bat new file mode 100644 index 0000000..782611d --- /dev/null +++ b/bin/Win9x/e3em.bat @@ -0,0 +1,3 @@ +@ren e3.exe e3em.exe >NUL
+@e3em.exe
+@ren e3em.exe e3.exe
diff --git a/bin/Win9x/e3ne.bat b/bin/Win9x/e3ne.bat new file mode 100644 index 0000000..3ed8ec2 --- /dev/null +++ b/bin/Win9x/e3ne.bat @@ -0,0 +1,3 @@ +@ren e3.exe e3ne.exe >NUL
+@e3ne.exe
+@ren e3ne.exe e3.exe
diff --git a/bin/Win9x/e3pi.bat b/bin/Win9x/e3pi.bat new file mode 100644 index 0000000..11b0552 --- /dev/null +++ b/bin/Win9x/e3pi.bat @@ -0,0 +1,3 @@ +@ren e3.exe e3pi.exe >NUL
+@e3pi.exe
+@ren e3pi.exe e3.exe
diff --git a/bin/Win9x/e3vi.bat b/bin/Win9x/e3vi.bat new file mode 100644 index 0000000..58a8bb6 --- /dev/null +++ b/bin/Win9x/e3vi.bat @@ -0,0 +1,3 @@ +@ren e3.exe e3vi.exe >NUL
+@e3vi.exe
+@ren e3vi.exe e3.exe
diff --git a/bin/Win9x/e3ws.bat b/bin/Win9x/e3ws.bat new file mode 100644 index 0000000..314310b --- /dev/null +++ b/bin/Win9x/e3ws.bat @@ -0,0 +1,3 @@ +@ren e3.exe e3ws.exe >NUL
+@e3ws.exe
+@ren e3ws.exe e3.exe
diff --git a/contrib/README.tinlink624 b/contrib/README.tinlink624 new file mode 100644 index 0000000..8462d8b --- /dev/null +++ b/contrib/README.tinlink624 @@ -0,0 +1,16 @@ +If you have problems running one of the primary self compressors +"gzexe" or "upx" you should give a try to the combination of +tinlink linker and 624 selfcompressor utility tools. + +Both are easy to find on the net (via freshmeat.net), +but available only for Linux. + + +Here's how that e3 can be built: +------------------------------------------------ +#!/bin/sh +nasm -f bin -o e3 e3.asm -DLINUX -DSED -DTINLINK +./tinlink -c e3 -m 10000000 -o e3.tin +./624 -s e3.tin e3 +chmod +x e3 +------------------------------------------------ diff --git a/contrib/e3.spec b/contrib/e3.spec new file mode 100644 index 0000000..da8b25c --- /dev/null +++ b/contrib/e3.spec @@ -0,0 +1,37 @@ +%define Name e3 +%define Version 2.3 +%define Prefix /usr/local +Name: e3 +Version: 2.3 +Release: 1 +Group: System/Utilities +Summary: e3 is tiny wordstar/emacs/pico/vi/nedit alike editor, well suited for rescue disks. +Copyright: GPL +Packager : Urs Rau <urs.rau@uk.om.org> +#Conflicts: +#Buildroot: /tmp/%{Name}-%{Version} +Provides: editor e3 e3-2.3 +Source: %{Name}-%{Version}.tar.gz + +%Description +e3 is teeny tiny editor that doesn't depend on any libs. +e3 uses subset of wordstar|emacs|pico|vi|nedit commands. +Author: Albrecht Kleine <kleine@ak.sax.de> + +%Prep +%setup -q -n %{Name}-%{Version} + +%Build +make + +%Install +rm -rf $RPM_BUILD_ROOT +make PREFIX="$RPM_BUILD_ROOT/usr/local" install + +%Clean +rm -rf $RPM_BUILD_ROOT + +%Files +%defattr(-,root,root) +%{Prefix}/bin/e3 +%{Prefix}/man/man1/e3.1 diff --git a/contrib/ewrapper.sh b/contrib/ewrapper.sh new file mode 100755 index 0000000..223e6a3 --- /dev/null +++ b/contrib/ewrapper.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# (c) 2000 GPL David Douthitt <ddouthitt@mennonite.minister.net> +# a wrapper for editing a sequence of files..... +# ....define your favourite edit mode in E3EMU (or use default) +# Thanks to David! -- Sat Nov 11 2000 a.k. + +E3_DEFAULT=e3vi # hey, I LIKE vi, alright? :-) + +case $E3EMU in + ws|wordstar) E3=e3ws ;; + vi) E3=e3vi ;; + em|emacs) E3=e3em ;; + pi|pico) E3=e3pi ;; + "") E3=$E3_DEFAULT ;; + *) echo "e3: improper emulation! ($E3EMU)"; exit 1;; +esac + +for file in "$@"; do + $E3 $file +done + diff --git a/contrib/pico b/contrib/pico new file mode 100755 index 0000000..d99a138 --- /dev/null +++ b/contrib/pico @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Date: Wed, 16 May 2001 15:11:08 +0200 +# +# I made this script from the original ewrapper.sh for a linux-on-a-floppy +# project i'm playing with. +# The main difference to the original is that you don't have all this e3xx +# links laying around and that you can call things with their real names +# (that's user friendly). +# "pico" is a demo for any other filename below. Copy to "emacs" etc. if you want, +# or create some links to this script. +# (c) 2001 Tito <farmatito@tiscalinet.it> +# +# +E3_PATH=/usr/local/bin +case $0 in + *ws|*wordstar) + E3=e3ws + ;; + *vi) + E3=e3vi + ;; + *em|*emacs) + E3=e3em + ;; + *pi|*pico) + E3=e3pi + ;; + *ne|*nedit) + E3=e3ne + ;; + *) + echo "e3: improper emulation! ($0).Use emacs,wordstar,vi,pico,nedit" + ;; +esac +if [ $@ = ] 2>/dev/null +then + ln -s $E3_PATH/e3 $E3_PATH/$E3 + $E3_PATH/$E3 + rm -f $E3_PATH/$E3 +else + for file in $@ + do + ln -s $E3_PATH/e3 $E3_PATH/$E3 + $E3_PATH/$E3 $file + rm -f $E3_PATH/$E3 + done + +fi + + + + + + + + + + + diff --git a/doswin9x/e3-16.asm b/doswin9x/e3-16.asm new file mode 120000 index 0000000..d5eade2 --- /dev/null +++ b/doswin9x/e3-16.asm @@ -0,0 +1 @@ +../e3-16.asm
\ No newline at end of file diff --git a/doswin9x/e3.asm b/doswin9x/e3.asm new file mode 120000 index 0000000..79f5882 --- /dev/null +++ b/doswin9x/e3.asm @@ -0,0 +1 @@ +../e3.asm
\ No newline at end of file diff --git a/doswin9x/e3.h b/doswin9x/e3.h new file mode 120000 index 0000000..d3f17af --- /dev/null +++ b/doswin9x/e3.h @@ -0,0 +1 @@ +../e3.h
\ No newline at end of file diff --git a/doswin9x/make.bat b/doswin9x/make.bat new file mode 100644 index 0000000..1dd09da --- /dev/null +++ b/doswin9x/make.bat @@ -0,0 +1,18 @@ +@rem 16 bit DOS .COM version
+NASMW -DCOM e3-16.asm -l e3com16.lst -o e3-16.com -f bin
+@rem
+@rem 16 bit DOS .EXE version
+NASMW -DEXE e3-16.asm -l e3exe16.lst -o e3-16e.exe -f bin
+@rem
+@rem 16 bit DOS EXE-STUB version for e3.exe
+NASMW -DEXESTUB e3-16.asm -l e3stub.lst -o e3stub.obj -f obj
+ALINK e3stub.obj
+@rem
+@rem 32 bit e3.exe itself
+NASMW -DW32 e3.asm -l e3.lst -f win32
+@rem
+@rem link all togehther
+ALINK -oPE -subsys console e3 win32.lib -entry _start -stub e3stub.exe
+@rem
+@rem install into path
+copy e3.exe C:\windows\e3.exe
diff --git a/e3-16.asm b/e3-16.asm new file mode 100644 index 0000000..0e399e5 --- /dev/null +++ b/e3-16.asm @@ -0,0 +1,2361 @@ +;------------------------------------------------------------------------- +; +; Copyright (C) 2002 Albrecht Kleine <kleine@ak.sax.de> +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation; either +; version 2 of the License, or (at your option) any later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; Library General Public License for more details. +; +; You should have received a copy of the GNU Library General Public +; License along with this library; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; +;-------------------------------------------------------------------------- +; +; FIXME: are pusha/popa valid on the 8086 ? +; +TAB equ 8 +TABCHAR equ 09h ; ^I +SPACECHAR equ ' ' +CHANGED equ '*' +UNCHANGED equ SPACECHAR +NEWLINE equ 0ah +errlen equ 100 +MAXERRNO equ 30 +ERRNOMEM equ 12 +sBREITE equ 80 ;cols +sHOEHE equ 24 ;rows +MAXLEN equ 0x7FFF +maxfilenamelen equ 255 +%ifdef ELKS + stdin equ 0 + stdout equ 1 + O_WRONLY_CREAT_TRUNC equ 1101q + O_RDONLY equ 0 + permissions equ 644q +%else ;-------------- + normfarbe equ 07h + kursorfarbe equ 70h + slinefarbe equ 1eh ;yellow on blue + blockfarbe equ 15 + O_WRONLY_CREAT_TRUNC equ 0 + permissions equ 0 +%endif + +section .text +bits 16 + +global _start +global _main ; for ELKS and the ld86 linker +_start: +_main: +EXE_startcode: +%ifdef EXESTUB +..start: +%endif +;------- +%ifdef ELKS + call InitBSS + pop ax + pop bx + pop si ;si points to first arg +%else +%ifdef COM + org 100h +%else +%ifdef EXESTUB + mov ax,data + mov es,ax + push ax +%else +%ifdef EXE + EXE_realstacksize equ 0x800 + org 0e0h +header_start: +;EXE header adapted from a NASM contribution by Yann Guidon <whygee_corp@hol.fr> + db 'M','Z' ; EXE file signature + dw EXE_allocsize % 512 + dw (EXE_allocsize + 511) / 512 + dw 0 ; relocation information: none + dw (header_end-header_start)/16 ; header size in paragraphs + dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem + dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem + dw -10h ; Initial SS (before fixup) + dw EXE_endbss + EXE_realstacksize ; 2k + dw 0 ; (no) Checksum + dw 100h ; Initial IP - start just after the header + dw -10h ; Initial CS (before fixup) + dw 0 ; file offset to relocation table: none + dw 0,0,0 ; (no overlay) +header_end: ; here we go... (@ org 100h) +%endif +%endif +%endif + call InitBSS + call GetArg +%ifdef EXESTUB + pop ds +%endif +%endif +;----------------------------------------------------------------------- +; +; start with OUTER editor loop +; +ReStart:call NewFile + jc E3exit +MainCharLoop:call DispNewScreen + call RestoreStatusLine + call HandleChar + cmp byte [endedit],0 + je MainCharLoop + xor si,si ;just like if no arg is present + cmp byte [endedit],2 + je ReStart ;^KD repeat edit using another file +E3exit: call KursorStatusLine +;------- +%ifdef ELKS + mov bx,stdout ;file handle + mov cx,newline ;enter next line on terminal + xor dx,dx + inc dx ;mov dx,1 + push dx + call WriteFile + pop ax ;mov ax,1 + xor bx,bx ;return 0 + int 80h +%else + mov ah,4ch + int 21h +%endif +;---------------------------------------------------------------------- +; +; MAIN function for processing keys +; +HandleChar:call ReadChar + jz ExtAscii ;DOS version got ah=0 by int 16 for F-keys and cursor keys + cmp al,19h ;^Y is the last + ja NormChar + mov bl,al + add bl,jumps1 + jmp short CompJump2 +NormChar:call CheckMode + jnz OverWriteChar + push ax + xor ax,ax + inc ax + call InsertByte + pop ax + jc InsWriteEnd ;error: text buffer full +OverWriteChar:cld + stosb + mov byte [changed],CHANGED +InsWriteEnd:ret +;------- +; +; helper for HandleChar +; +CtrlKMenu:mov bx,Ktable + mov cx,4b5eh ;^K + jmp short Menu +CtrlQMenu:mov bx,Qtable + mov cx,515eh ;^Q +Menu: call MakeScanCode + jc EndeRet ;if no valid scancode +ExtAscii:mov bl,ah ;don't use al (carries char e.g. TAB) + sub bl,lowest ;= scan code first key in jumptab1 + jb EndeRet + cmp bl,jumps1 + jae EndeRet +CompJump2:and bx,0ffh + shl bx,1 ;2*bx is due 2 byte per entry +;------- + call [bx+jumptab1] +;------- + cmp byte [numeriere],1 ;after return from functions... + jnz BZNret ;...decide whether count current line number + mov word [linenr],0 + push di + mov si,sot + xchg si,di +BZNLoop:inc word [linenr] + call LookForward + inc di ;point to start of next line +%ifndef ELKS + inc di ;for DOS one extra +%endif + cmp di,si + jbe BZNLoop + pop di + mov byte [numeriere],0 +BZNret: ret +;------- +MakeScanCode:call WriteTwo ;bx expects xlat-table + push bx + call GetChar + pop bx + and al,01fh + cmp al,26 + jnb exit + xlatb + mov ah,al ;returns pseudo "scancode" + stc +exit: cmc ;ok=nc +EndeRet:ret +;---------------------------------------------------------------------- +; +; processing special keys: cursor, ins, del +; +KeyRet: call CheckMode + jnz OvrRet + call CountToLineBegin ;set si / returns ax + inc si + inc si + xor bx,bx + or ax,ax + jz KeyRetNoIndent + dec bx +KeyRetSrch:inc bx ;search non (SPACE or TABCHAR) + cmp byte [si+bx],SPACECHAR + je KeyRetSrch + cmp byte [si+bx],TABCHAR + je KeyRetSrch +KeyRetNoIndent: + push si + push bx ;ax is 0 or =indented chars + call GoDown + pop ax + + push ax + inc ax ;1 extra for 0ah +%ifndef ELKS + inc ax +%endif + call InsertByte + pop cx ;# blanks + pop si ;where to copy + jc SimpleRet + inc word [linenr] + cld +%ifdef ELKS + mov al,NEWLINE + stosb +%else + mov ax,0a0dh + stosw +%endif + jcxz SimpleRet + rep movsb ;copy upper line i.e. SPACES,TABS into next +SimpleRet:ret +OvrRet: mov word [ch2linebeg],0 + jmp short DownRet +;------- +KeyDown:call CountColToLineBeginVis +DownRet:call GoDown + call LookLineDown + jmp short SetColumn +;------- +KeyUp: call GoUp + call CountColToLineBeginVis + call LookLineUp + jmp short SetColumn +;------- +KeyPgUp:call CountColToLineBeginVis + call LookPageUp + jmp short SetColumn +;------- +KeyPgDn:call CountColToLineBeginVis + call LookPgDown ;1st char last line +;------- +SetColumn:mov cx,[ch2linebeg] ;maximal columns + xor dx,dx ;counts visible columns i.e. expand TABs + dec di +lod: inc di + cmp dx,cx ;from CountColToLineBeginVis + jae fert +%ifdef ELKS + cmp byte [di],NEWLINE ;don't go beyond line earlier line end +%else + cmp byte [di],0dh +%endif + jz fert + cmp byte [di],TABCHAR + jz isTab + inc dx ;count columns + jmp short lod +isTab: call SpacesForTab + add dl,ah + cmp dx,cx ;this tab to far away right? + jna lod ;no +fert: ret +;------- +KeyHome:call CountToLineBegin + sub di,ax + ret +;------- +KeyEnd: call CountToLineEnd + add di,ax ;points to a 0ah char + ret +;------- +KeyIns: not byte [insstat] + ret +;------- +KeyDell:call KeyLeft + jz KeyDell2 +KeyDel: cmp di,bp + jnb KeyLeftEnd + mov ax,1 ;delete one @ cursor +%ifndef ELKS + cmp byte [di],0dh + jnz KeyDell3 + inc ax +%endif +KeyDell3:jmp DeleteByte +KeyDell2:call CheckBOF ;cmp di,sot delete newline char + jbe KeyLeftEnd + dec word [linenr] + dec di +%ifndef ELKS + dec di +%endif + jmp BisNeueZeile +;------- +KeyLeft:cmp byte [di-1],NEWLINE ;FIXME another check of BOF + jz KeyLeftEnd ;jmp if at BOL + dec di +KeyLeftEnd:ret +;------- +KeyRight: +%ifdef ELKS + cmp byte [di],NEWLINE +%else + cmp byte [di],0dh +%endif + jz KeyRightEnd ;at right margin + inc di +KeyRightEnd:ret +;------- +KeyCLeft3:call CheckBOF ;cmp di,sot bzw sot-1 + jbe KeyCLEnd + dec di +%ifndef ELKS + dec di +%endif +KeyCtrlLeft:call KeyLeft + jz KeyCLeft3 + cmp byte [di],2fh + jbe KeyCtrlLeft + cmp byte [di-1],2fh + ja KeyCtrlLeft +KeyCLEnd:ret +;------- +KeyCRight3:call CheckEOF + jae KeyCREnd + inc di +KeyCtrlRight:call KeyRight + jz KeyCRight3 + cmp byte [di],2fh + jbe KeyCtrlRight + cmp byte [di-1],2fh + ja KeyCtrlRight +KeyCREnd:ret +; +; processing special keys from the Ctrl-Q menu +; +;------- +KeyCtrlQA:call AskForReplace + jc CtrlQFEnd + mov byte [bereitsges],2 +CQACtrlL:push di + call FindText + jc CtrlQFNotFound + mov ax,[suchlaenge] + call DeleteByte + mov ax,[repllaenge] + call InsertByte + mov si, replacetext + call MoveBlock + jmp short CQFFound +;------- +KeyCtrlQF:call AskForFind + jc CtrlQFEnd + mov byte [bereitsges],1 +CQFCtrlL:push di + call FindText + jc CtrlQFNotFound +CQFFound:pop si ;dummy +CQFNum: mov byte [numeriere],1 + ret +CtrlQFNotFound:pop di +CtrlQFEnd:ret +;------- +KeyCtrlQC:mov di,bp + jmp short CQFNum +;------- +KeyCtrlQR:mov di,sot + jmp short CQFNum +;------- +KeyCtrlQP:mov di,[veryold] + jmp short CQFNum +;------- +KeyCtrlL:mov al,[bereitsges] ;2^QA 1^QF 0else + dec al + jz CQFCtrlL + dec al + jz CQACtrlL +SimpleRet4:ret +;------- +KeyCtrlQB:mov ax,di + mov di,[blockbegin] +CtrlQB2:or di,di ;exit of no marker set + jnz CQFNum + mov di,ax + ret +;------- +KeyCtrlQK:mov ax,di + mov di,[blockende] + jmp short CtrlQB2 +;------- +KeyCtrlQY:call CountToLineEnd + jmp short CtrlTEnd1 +;------- +KeyCtrlY:call CountToLineBegin + sub di,ax ;di at begin + call CountToLineEnd + call DeleteByteCheckMarker + jmp short BisNeueZeile +;------- +KeyCtrlT:call CountToWordBegin +%ifdef ELKS + cmp byte [di],NEWLINE +%else + cmp byte [di],0dh +%endif + jnz CtrlTEnd1 +BisNeueZeile:call CheckEOF + jz SimpleRet4 +%ifdef ELKS + mov ax,1 ;0ah +%else + mov ax,2 ;0dh,0ah +%endif +CtrlTEnd1:jmp DeleteByteCheckMarker +;---------------------------------------------------------------------- +; +; processing special Keys from Ctrl-K menu +; +KeyCtrlKY:call CheckBlock + jc SimpleRet3 ;no block: no action + mov ax,[blockende] + mov di,[blockbegin] + sub ax,si ;block length + mov di,si ;begin + call DeleteByte ;out cx:=0 + mov [blockende],cx + mov [blockbegin],cx + jmp CQFNum +;------- +KeyCtrlKH:xor byte [showblock],1 ;flip flop +SimpleRet3:ret +;------- +KeyCtrlKK:mov [blockende],di + jmp short KCKB +;------- +KeyCtrlKW:call CheckBlock + jc SimpleRet2 ;no action + call SaveBlock + jmp short CtrlKREnd +;------- +KeyCtrlKC:call CopyBlock + jc SimpleRet2 +CtrlKC2:mov [blockbegin],di + add ax,di + mov [blockende],ax + ret +;------- +KeyCtrlKV:call CopyBlock + jc SimpleRet2 + push di + cmp di,[blockbegin] + pushf + mov di,[blockbegin] + call DeleteByte + popf + pop di + jb CtrlKC2 + mov [blockende],di + sub di,ax +KeyCtrlKB:mov [blockbegin],di +KCKB: mov byte [showblock],1 +SimpleRet2:ret +;------- +KeyCtrlKR:call ReadBlock + jc CtrlKREnd + call KeyCtrlKB + add cx,di + mov [blockende],cx +CtrlKREnd:jmp RestKursPos +;------- +KeyCtrlKS:call SaveFile + pushf ;(called by ^kd) + call RestKursPos + popf + jc CtrlKSEnd + mov byte [changed],UNCHANGED +CtrlKSEnd:ret +;------- +KeyCtrlKQ:cmp byte [changed],UNCHANGED + jz CtrlKQ2 + mov dx, asksave + call DE1 + call RestKursPos + and al,0dfh + cmp al,'N' ;confirm + jnz KeyCtrlKX +CtrlKQ2:mov byte [endedit],1 + ret +KeyCtrlKD:call KeyCtrlKS + jc CtrlKSEnd + mov byte [endedit],2 + ret +KeyCtrlKX:call KeyCtrlKS + jc CtrlKSEnd + inc byte [endedit] +KeyKXend:ret +;--------------------------------------------------------------------- +; +; the general PAGE DISPLAY function: called after any pressed key +; +; side effect: sets 'columne' for RestoreStatusLine function (displays columne) +; 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 dx counts columns in text lines +; register cx screen line counter and helper for rep stos +; register si text index +; register di screen line buffer index +; +DispNewScreen:call GetEditScreenSize ;check changed tty size + xor ax,ax +%ifdef ELKS + mov byte[isbold],al + mov byte[inverse],al +%endif + mov [zloffset],ax + mov [columne],ax + mov [fileptr],di ;for seeking current cursor pos + call CountColToLineBeginVis ;i.e. expanding TABs + cmp ax,[columns] + jb DispShortLine + sub ax,[columns] + inc ax + mov [zloffset],ax +DispShortLine:call LookPgBegin ;go on 1st char upper left on screen + mov si,di ;si for reading chars from text + mov cx,[lines] + jcxz KeyKXend ;window appears too small + cld +%ifndef ELKS + dec si +%endif + mov bh,0 + dec bh +DispNewLine: +%ifndef ELKS + inc si +%endif + inc bh ;new line + mov di,screenline ;line display buffer + xor dx,dx ;reset char counter + mov bl,0 ;reset screen column +DispCharLoop: + cmp si,[fileptr] ;display char @ cursor postion ? + jnz DispCharL1 + cmp byte[tabcnt],0 + jnz DispCharL1 + mov [kurspos],bx + mov byte [columne],bl + mov ax,[zloffset] ;chars scrolled left hidden + add [columne],ax +%ifdef ELKS + stc + call SetzeInversStatus + jnc DispEndLine +%else + mov ah,kursorfarbe + cmp byte [insstat],1 + jz DispEndLine +%endif +DispCharL1:call SetzeFarbe +;------- +DispEndLine:cmp si,bp + ja FillLine ;we have passed EOF, so now fill rest of screen + cmp byte[tabcnt],0 + jz ELZ + dec byte[tabcnt] + jmp short ELZ2 +ELZ: cmp si,bp + jnz ELZ6 + inc si ;set si>bp will later trigger "ja FillLine" + jmp short ELZ2 +ELZ6: lodsb + cmp al,TABCHAR + jnz ELZ3 + push ax ;preserve color attribute + call SpacesForTab ;ah = space_up_to_next_tab location + dec ah ;count out the tab char itself + mov byte[tabcnt],ah + pop ax +ELZ2: mov al,SPACECHAR +ELZ3: +%ifdef ELKS + cmp al,NEWLINE +%else + cmp al,0dh +%endif + jz FillLine + cmp al,SPACECHAR + jae ELZ9 ;simply ignore chars like carriage_return etc. + mov al,'.' +ELZ9: cmp al,7fh + jne ELZ8 + mov al,'.' +ELZ8: cmp bl,byte [columns] ;screen width + jae DispEndLine ;continue reading line until end + inc dx ;also count hidden chars (left margin) +KZA6: cmp dx,[zloffset] + jbe near DispCharLoop ;load new char (but no display) +%ifdef ELKS + stosB + clc + call SetzeInversStatus +%else + stosw +%endif + inc bl ;counts displayed chars only + jmp DispCharLoop +;------- +FillLine:push cx ;continue rest of line + mov cx,[columns] ;width + sub cl,bl + mov al,SPACECHAR ;fill with blanks + jcxz FillLine2 +%ifdef ELKS + cmp byte[inverse],1 ;special cursor attribute? +%else + cmp ah,kursorfarbe +%endif + jnz FillLine1 +%ifdef ELKS + mov al,SPACECHAR + stosB ;only 1st char with special attribute + clc + call SetzeInversStatus + dec cx ;one char less + jz FillLine2 +FillLine1:rep stosB ;store the rest blanks +%else + stosw + dec cx + jz FillLine2 + mov ah,normfarbe +FillLine1:rep stosw +%endif +FillLine2:pop cx +%ifdef ELKS + mov byte[di],0 +%endif + call ScreenLineShow + dec cx + jnz near DispNewLine + call RestKursPos + mov di,[fileptr] ;restore old value + ret +;---------------------------------------------------------------------- +InitVars:mov word [textX],0a0ah ;don't touch si! + mov byte [changed],UNCHANGED + xor ax,ax + mov byte[bereitsges],al + mov [blockbegin],ax + mov [blockende],ax + mov [endedit],al + mov word[old], sot + inc ax + mov word [linenr],ax + mov byte [showblock],al + mov byte [insstat],al + mov word [error],'ER' + mov word [error+2],'RO' + mov word [error+4],'R ' + mov word [error+6],' ' + cld + ret +;---------------------------------------------------------------------- +; +; STATUS LINE maintaining subroutines +; at first the writer of a complete line +; +RestoreStatusLine:pusha ;important e.g. for asksave +%ifdef ELKS + mov cx,[columns] ;width + push cx + mov al,SPACECHAR ;first prepare the line buffer.... + mov di, screenline + cld + rep stosb + mov al,0 ;prepare ASCIIZ string + stosb + pop cx + cmp cl,stdtxtlen+15+5+2 ;this window is too small + jb no_lineNr + mov bl, byte [changed] + mov byte[screenline+1],bl ;changed status + mov bx,'I ' ;Insert + cmp byte [insstat],1 + jz rrr1 + mov bx,'O ' ;Overwrite +rrr1: mov [screenline+4],bx ;mode status + mov di,screenline+stdtxtlen + mov cx,[columns] + sub cx,stdtxtlen+15+5 ;space for other than filename + mov si,filepath +rrr2: lodsb + or al,al + jz raus +okay: stosb + loop rrr2 + jmp short wett +raus: mov al,SPACECHAR + stosb + loop raus +wett: mov di,screenline-15 + add di,[columns] + js no_lineNr + mov ax,[columne] + inc ax ;start with 1 + call IntegerToAscii + mov byte [di],':' ;delimiter ROW:COL + dec di + mov ax,[linenr] + call IntegerToAscii +%else ;---------------------------------------------- + mov di,zeilenangabe ;make string + mov cx,12 + mov al,SPACECHAR + cld + rep stosb + mov di,zeilenangabe+8 + mov ax,[columne] + inc ax ;start with 1 + call IntegerToAscii + mov byte [di],':' ;delimiter ROW:COL + dec di + mov ax,[linenr] + call IntegerToAscii + cld +;------- + mov cx,[columns] + mov ah,slinefarbe + mov al,SPACECHAR + mov di,screenline + cld + rep stosw + mov bl, byte [changed] + mov byte[screenline+2],bl + mov di,screenline+20 + mov cx,55 + mov si,filepath +rrr2: lodsb + stosw + loop rrr2 + mov cx,10 + mov si,zeilenangabe +rrr3: lodsb + stosw + loop rrr3 +%endif +no_lineNr:call StatusLineShow ;now write all at once + popa + ret +;------------------------------------------------------------------------- +; this function does write the line buffer to screen i.e. terminal +; at begin a special entry point for writing the STATUS line below +; +StatusLineShow:xor cx,cx ;0 for last line +ScreenLineShow:pusha ;expecting in cx screen line counted from 0 +%ifdef ELKS + xor dx,dx + mov dh,byte [lines] + sub dh,cl + mov dl,0 + call sys_writeKP + call sys_writeSL + mov dx,[kurspos2] + call sys_writeKP ;restore cursor pos +%else + mov ax,1302h + mov bx,0 + mov dh,[lines] + sub dh,cl + mov dl,0 + mov cx,[columns] + mov bp,screenline + int 10h +%endif + popa + ret +;----------------------------------------------------------------------- +; write an answer prompt into status line +; (with and without re-initialisation) +; expecting dx points to ASCIIZ-string +; +WriteMess9MachRand: + call InitStatusLine +WriteMess9: +%ifdef ELKS + pusha + mov di,screenline + mov si,dx + cld +WriteMLoop:lodsb + or al,al + jz WriteMEnd + cmp al,0ah ;for error messages + jz WriteMEnd + stosb + jmp short WriteMLoop +WriteMEnd:call StatusLineShow + popa +%else ;--------------------- + push si + push di + mov si,dx + cld + mov di,screenline + mov ah,slinefarbe +WriteMLoop:lodsb + or al,al + jz WriteMEnd + cmp al,0dh + jz WriteMEnd + stosw + jmp short WriteMLoop +WriteMEnd:call StatusLineShow + pop di + pop si +%endif + call KursorStatusLine + ret +;------- +; another way: write 2 letters in ch/cl to status line +; called by MakeScanCode for showing ^K and ^Q status (lower left) +; +WriteTwo:push di +%ifdef ELKS + mov word[screenline],cx +%else + mov di,screenline + mov al,cl + mov ah,slinefarbe + cld + stosw + mov al,ch + stosw +%endif + call StatusLineShow ;write the line on last screen line + pop di + ret +;-------------------------------------------------------------------- +; a helper for other status line functions: +; simply init an empty line +; +InitStatusLine:push di + push ax + push cx + mov di,screenline + cld + mov al,SPACECHAR + mov cx,[columns] +%ifdef ELKS + cld + rep stosb +%else + mov ah,slinefarbe + rep stosw +%endif + pop cx + pop ax + pop di + ret +;----------------------------------------------------------------------- +; +; getting INPUT from terminal +; at first read a whole string until <enter> pressed, +; follwed by handling reading one char alone +; +%ifdef ELKS +; expecting buffer in cx +; expecting count byte in dx +InputString:call sys_writeSLColors1 + push cx + mov bx,stdin ;file desc + call ReadFile + pop cx + stc + js ISRet + dec ax ;0ah + push bx + mov bx,ax + add bx,cx + mov byte[bx],0 ;make asciz string + pop bx + cmp ax,1 ;set cy flag if empty string +ISRet: pushf + call sys_writeSLColors0 ;FIXME should flush stdin: read until empty buffer + popf + ret +%else ;---------------------------------- +InputString:mov dx,cx ;ELKS register style + xor cx,cx ;char counter + push di + mov di,dx + cld +GetNameLoop:call GetChar + cmp ah,4bh ;left + jz GetNameDelete + cmp ah,4dh + jz GetNameOldChar + or al,al + jz GetNameLoop + cmp al,7 + jz GetNameLoop ;no beep + cmp al,0dh + jz GetNameEnd + cmp al,1bh + stc + jz GetNameErr + cmp al,8 + jnz GetNameChar +GetNameDelete:mov al,8 + dec cx + jS GetNameNoToDel + call xDispChar + dec di + mov al,0 + call xDispChar + mov al,8 + call xDispChar + jmp short GetNameLoop +GetNameOldChar:mov al,[di] + or al,al + jz GetNameLoop +GetNameChar:stosb + call xDispChar +GetNameNoToDel:inc cx + cmp cl,maxfilenamelen + jnc GetNameEnd + jmp short GetNameLoop +GetNameEnd:mov byte [di],0 + mov ax,di + sub ax,dx ;ret ax=lge + cmp ax,1 ;clc +GetNameErr:pop di + ret +;------- +xDispChar:push bx ;char in al + mov ah,0eh + mov bx,0111b ;page bh,0 + int 10h + pop bx + ret +%endif +;----------------------------------------------------------------------- +%ifdef ELKS +; +; GetChar returns ZERO flag for non ASCII (checked in HandleChar) +; +ReadChar:mov ax,di + xchg ax,[old] ;fuer ^QP + mov [veryold],ax +GetChar:mov cx, 0x5401 ;TCGETS asm/ioctls.h + mov dx,termios + call IOctlTerminal + call SaveTermStruc + push bx + mov bx,dx + and byte [bx+12],(~2) ;icanon off + and byte [bx+12],(~1) ;isig (^C) off + and byte [bx+12],(~8) ;iecho off + and word [bx+ 0],(~400h) ;ixon off + pop bx + mov cx, 0x5402 ;TCSETS asm/ioctls.h + call IOctlTerminal ;dx is termios pointer +readloop:call ReadOneChar + cmp al,7FH + jne No7F ; special case: remap DEL to Ctrl-H + mov al,8 +No7F: cmp al,27 ; ESC ? + jnz near ready_2 + call ReadOneChar ;e.g. [ for ELKS vt100 + mov bl,48h ;48h up - the lowest + cmp al,'A' + jz ready + add bl,3 ;4Bh left + cmp al,'D' + jz ready + add bl,2 ;4Dh right + cmp al,'C' + jz ready + add bl,3 ;50h down + cmp al,'B' + jz ready + jmp short ready_2 +;------- +ready: xor ax,ax + mov ah,bl +ready_2:push ax + mov cx,0x5402 ;TCSETS asm/ioctls.h + mov dx,orig + call IOctlTerminal ; restore termios settings + pop ax + or al,al ; was similar DOS version (via BIOS int 16h) + ret +;------- +SaveTermStruc:push di + mov si,termios + mov di,orig + mov cx,termios_size + cld + rep movsb + pop di + ret +;------- +; called by ReadChar/GetChar +; +ReadOneChar:mov bx,stdin ;file desc + mov cx,read_b ;pointer to buf + xor dx,dx + inc dx ;mov dx,1 (length) + call ReadFile + mov ax,[read_b] + ret +%else ;------- +ReadChar:mov ax,di + xchg ax,[old] ;for ^QP + mov [veryold],ax + call GetChar + or al,al + ret +;------- +GetChar:mov ah,0 + int 16h + ret +%endif +;---------------------------------------------------------------------- +%ifdef ELKS +; +; helper subroutine called by DispNewScreen +; +SetzeInversStatus: + push si ; returns zero flag + push cx + mov cx,boldlen + jnc SIS1 + cmp byte [insstat],1 + stc + jnz SIS4 + mov byte[inverse],1 + mov si,reversevideoX + rep movsb + jmp short SIS3 +SIS1: cmp byte[inverse],1 + jnz SIS3 + mov byte[inverse],0 + mov byte[isbold],0 + mov si,bold0 + rep movsb +SIS3: clc +SIS4: pop cx + pop si + ret +%endif +;------- +; another helper subroutine called by DispNewScreen +; +SetzeFarbe: +%ifdef ELKS + cmp byte [showblock],0 + je SetzeFarbeEnde1 + cmp word [blockbegin],0 + je SetzeFarbeEnde1 + cmp [blockbegin],si + ja SetzeFarbeEnde1 + cmp si,[blockende] + jb SetzeFarbeESC ;cy is set +SetzeFarbeEnde1:clc +SetzeFarbeESC: + push si ;expects cy flag:bold / nc:normal + push cx + mov cx,boldlen + jnc SFEsc1 + cmp byte [isbold],1 ;never set bold if it is already bold + jz SFEsc2 + mov si,bold1 + rep movsb + mov byte [isbold],1 + jmp short SFEsc2 +SFEsc1: cmp byte [isbold],0 ;ditto + jz SFEsc2 + mov si,bold0 + rep movsb + mov byte [isbold],0 +SFEsc2: pop cx + pop si + ret +%else ;--------------------------------- + mov ah,normfarbe + cmp byte[showblock],0 + je SetzeFarbeEnde + cmp word [blockbegin],0 + je SetzeFarbeEnde + cmp [blockbegin],si + ja SetzeFarbeEnde + cmp si,[blockende] + jnb SetzeFarbeEnde + mov ah,blockfarbe +SetzeFarbeEnde:ret +%endif +;----------------------------------------------------------------------- +; +; LOWER LEVEL screen acces function (main +2 helpers) (ELKS only) +; +%ifdef ELKS +sys_writeSL:push cx + or cx,cx + jnz sl1 + call sys_writeSLColors1 ;special for status line (cx==0) +sl1: push si + cld + xor dx,dx + mov si,screenline +sl3: lodsb + inc dx ;count message length to write + or al,al + jnz sl3 + pop si + mov bx,stdout ;first argument: file desc (stdout) + mov cx,screenline ;second argument: pointer to message to write + call WriteFile + pop cx + or cx,cx + jnz sl2 + call sys_writeSLColors0 +sl2: ret +;------- +sys_writeSLColors1: + pusha + mov bx,stdout + mov cx,screencolors1 ;set bold yellow on blue + mov dx,scolorslen + call WriteFile + popa + ret +;------- +sys_writeSLColors0: + pusha + mov bx,stdout + mov cx,screencolors0 ;reset to b/w + mov dx,scolorslen + call WriteFile + popa + ret +%endif +;---------------------------------------------------------------------- +; +; L O O K functions +; search special text locations and set register di +; +%ifdef ELKS +LookBackward: ;set di to 1 before EOL (0Ah) i.e., 2 before start of next line + push cx + push bx + xor bx,bx + cmp byte[di-1],NEWLINE ;at BOL ? + jz LBa3 + cmp byte[di],NEWLINE ;at EOL ? + jnz LBa1 + dec di ;at EOL ? start search 1 char earlier + inc bx ;increase counter +LBa1: mov cx,9999 + mov al,NEWLINE + std + repne scasb + mov ax,9997 + sub ax,cx + add ax,bx + pop bx + pop cx + jmp short CheckBOF +;------- +LBa3: xor ax,ax + pop bx + pop cx + dec di + dec di + jmp short CheckBOF +%else +LookBackward:push cx + mov cx,9999 + mov al,0ah + std + repne scasb + mov ax,9997 + sub ax,cx + pop cx + jmp short CheckBOF +%endif +LookForward:push cx + mov cx,9999 +%ifdef ELKS + mov al,NEWLINE +%else + mov al,0dh +%endif + cld + repne scasb + mov ax,9998 + sub ax,cx + pop cx + dec di +CheckEOF:cmp di,bp ;ptr is eof-ptr? + jnz CheckEnd ;Z flag if eof + jmp short CheckENum +CheckBOF:cmp di,sot + ja CheckEnd +CheckENum:mov byte [numeriere],1 ;if bof +CheckEnd:ret +;------- +LookPgBegin:mov dx,[kurspos2] ;called by DispNewScreen to get sync with 1st char on screen + mov cl,dh ;called by KeyCtrlQE (go upper left) + mov ch,0 + inc cl + jmp short LookPU2 +;------- +LookLineUp:mov cx,2 ;2 lines: THIS line and line BEFORE + dec word [linenr] + jmp short LookPU2 +;------- +LookLineDown:mov cx,2 ;2 lines: THIS and NEXT line + inc word [linenr] + jmp short LookPD2 +;------- +LookPageUp:mov cx,[lines] + sub [linenr],cx + inc word [linenr] ;PgUp,PgDown one line less +LookPU2:call LookBackward + jb LookPUEnd ;if BOF +%ifdef ELKS + inc di +%endif + loop LookPU2 ;after loop di points to char left of 0ah +%ifdef ELKS + dec di +%endif +LookPUEnd:inc di + inc di ;now points to 1st char on screen or line + ret +;------- +LookPgDown:mov cx,[lines] + add [linenr],cx + dec word [linenr] +LookPD2:call LookForward + jz LookPDEnd ;(jmp if EOF) +%ifndef ELKS + inc di +%endif + inc di ;1st char next line + loop LookPD2 +%ifndef ELKS + dec di +%endif + dec di ;last char last line +LookPDEnd:sub di,ax ;1st char last line + ret +;---------------------------------------------------------------------- +; +; some more CHECK functions +; +CheckBlock:cmp byte [showblock],1 ;returns CY if error else ok: NC + jc CheckBlockEnd + mov si,[blockende] + cmp si, sot + jb CheckBlockEnd + mov si,[blockbegin] ;side effect si points to block begin + cmp si, sot + jb CheckBlockEnd + cmp [blockende],si ;^KK > ^KB ..OK if above! +CheckBlockEnd:ret +;------- +CheckImBlock:cmp [blockbegin],di ;^KB mark > di ? + ja CImBlockEnd ;OK + cmp di,[blockende] ;di > ^KK +CImBlockEnd:ret ;output:cy fehler / nc ok inside block +;------- +CheckMode: +%ifdef ELKS + cmp byte [di],NEWLINE ;checks for INSERT status +%else + cmp byte [di],0dh +%endif + jz ChModeEnd + cmp byte [insstat],1 +ChModeEnd:ret ;Z flag for ins-mode +;------- +; a special case called by DeleteByteCheckMarker +; +CheckMarker: ;dx is blockbegin (^KB) + ;bx is deleate area end --- di delete area start + cmp di,dx ;delete area start < ^KB marker ? + ja CMEnd ;no + cmp bx,dx ;yes, but delete area end > ^KB ? + jl CMEnd ;no + mov dx,di ;yes so block start (^KB) to delete area start +CMEnd: 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 di + call LookForward + pop di + ret ;ax=chars up to line end +;------- +CountColToLineBeginVis: ;counts columns represented by chars in ax + call CountToLineBegin ;i.e. EXPAND any TAB chars found + push si + xor dx,dx + mov si,di ;startpoint + sub si,ax ;to bol + dec si +CCV1: inc si + cmp si,di + jae CCVend + cmp byte [si],TABCHAR + jz CCVTab + inc dx ;count visible chars + jmp short CCV1 +CCVTab: call SpacesForTab ;return space_up_to_next_tab in ah + add dl,ah ;FIXME: now using 8 bits only + jmp short CCV1 +CCVend: mov [ch2linebeg],dx ;ch2linebeg: interface to Key... functions + mov ax,dx ;ax: interface to DispNewScreen + pop si + ret +;------- +CountToLineBegin:push di ;output ax=chars up there + call LookBackward + mov si,di ;side effect: set di to 1st char in line + pop di + ret +;------- +CountToWordBegin: ;output ax=chars up there + mov si,di +CountNLoop:inc si +%ifdef ELKS + cmp byte [si],NEWLINE +%else + cmp byte [si],0dh +%endif + jz fertig2 + cmp byte [si],SPACECHAR ;below SPACE includes tab chars + jbe CountNLoop + cmp byte [si-1],2fh + ja CountNLoop +fertig2:mov ax,si + sub ax,di ;maybe =0 + ret +;--------------------------------------------------------------------- +; +; some CURSOR control functions +; +GoUp: mov al,0 + mov ah,-1 + jmp short UpDown +GoDown: mov al,byte [lines] + dec al + mov ah,1 +UpDown: mov dx,[kurspos2] ;former was call getkurspos + cmp dh,al + jz Goret + add dh,ah ;ONLY here we change curent line of cursor + jmp short SetKursPos +Goret: ret +;------- +; set cursor to some desired places +; +KursorStatusLine:mov dh,[lines] + mov dl,stdtxtlen + jmp short SetKursPos +RestKursPos:mov dx,[kurspos] +SetKursPos:mov [kurspos2],dx ;saves reading cursor pos (0,0) +%ifndef ELKS + push ax + mov ah,2 + mov bh,0 + int 10h + pop ax + ret +%else ;--------------------------------------------------------------- +sys_writeKP:pusha + call make_KPstr + mov bx,stdout ;file handle (stdout) + mov cx,setkp ;second argument: pointer to message to write + mov dx,setkplen ;third argument: message length + call WriteFile + popa + ret +;------- +; make ESC sequence appropriate to most important terminals +; +make_KPstr: + inc dl ;expecting cursor pos in dh/dl (0,0) + inc dh ;both line (dh) col (dl) are counted now from 1 + cld + mov di,setkp ;build cursor control esc string db 27,'[000;000H' + mov ax,0x5B1B ;line starts at setkp+2, col starts at setkp+6 + stosw + mov ax,'00' + stosw + mov ax,'0;' ;init memory + stosw + mov ax,'00' + stosw + mov ax,'0H' ;init memory + stosw + mov di,setkp+1+3 ;line end + xor ax,ax + mov al,dh ;DH=line + push dx + call IntegerToAscii ;make number string + pop dx + cld + mov di,setkp+1+3+4 ;column end + xor ax,ax + mov al,dl ;DL=col + jmp IntegerToAscii +%endif +;----------------------------------------------------------------------- +; +; functions for INSERTING, COPYING and DELETING chars in text +; +InsertByte:or ax,ax ;input: ax = #bytes , di = ptr + jz Ins3 + mov byte [changed],CHANGED + mov cx,MAXLEN ;max_len+offset-eofptr=freespace(cx) + add cx,sot + sub cx,bp + cmp cx,ax ;cmp freespace - newbytes ;>= 0 ok/ NC <0 bad / CY + jnc SpaceAva + mov word[errno],ERRNOMEM + call DosError + call RestKursPos + stc + ret +SpaceAva:push di + mov si,bp ;end of text + mov cx,bp + add cx,ax + sub cx,di ;space count + mov di,bp + add di,ax + std + rep movsB + pop di +;------- + add bp,ax + cmp di,[blockende] + ja Ins1 + add [blockende],ax +Ins1: cmp di,[blockbegin] + ja Ins2 + add [blockbegin],ax +Ins2: clc +Ins3: ret ;output:nc=ok / cy=bad +;------- +CopyBlock:call CheckBlock ;copy block, called by ^KC, ^KV + jc MoveBlEnd + call CheckImBlock + jc MoveBlEnd + mov ax,[blockende] + sub ax,si ;block len + call InsertByte + jc MoveBlEnd + mov si,[blockbegin] +MoveBlock:push di ;input : si=^KB di=current + mov cx,ax + cld + rep movsb + pop di + clc ;nocarry->ok +MoveBlEnd:ret +;------- +DeleteByteCheckMarker: ;di points to begin + mov bx,di + add bx,ax + mov dx,[blockbegin] + call CheckMarker + mov [blockbegin],dx + mov dx,[blockende] + call CheckMarker + mov [blockende],dx +DeleteByte:or ax,ax ;input in ax + jz DeleteByteEnd + mov byte [changed],CHANGED + push di + push si + mov cx,bp ;end + sub cx,di + mov si,di + add si,ax + sub cx,ax + add cx,3 + shr cx,1 + cld + rep movsW + pop si + pop di + sub bp,ax + cmp di,[blockende] + jae Del1 + sub [blockende],ax +Del1: cmp di,[blockbegin] + jae DeleteByteEnd + sub [blockbegin],ax +DeleteByteEnd:ret +;--------------------------------------------------------------------- +; read a file name for block operations +; expecting message text ptr in dx +; +getBlockName:pusha + call WriteMess9MachRand + mov cx,blockpath + mov dx,maxfilenamelen + call InputString ;cy if empty string + pushf + call RestKursPos + popf + popa + ret +;---------------------------------------------------------------------- +; +; functions reading/writing text or blocks from/into files +; +NewFile:call InitVars + call DelEditScreen + or si,si + jz noarg + cld + mov di,filepath +ccc: lodsb + stosb + or al,al + jnz ccc + jmp short GetFile +;------- +noarg: mov dx, filename + call WriteMess9MachRand + mov cx,filepath + mov dx,maxfilenamelen + call InputString + jc NFEnd2 ;empty string not allowed here +;------- +GetFile:mov bx,filepath + xor cx,cx ;i.e O_RDONLY + call OpenFile + mov di,sot + mov bp,di + mov bx,ax ;file descriptor + js NewFileEnd +OldFile:mov dx,MAXLEN + mov cx,di ;sot + call ReadFile + mov dx,ax ;bytes read + js DosEjmp0 ;DosError + call CloseFile + js DosEjmp0 ;DosError +;------- + mov word [errno],ERRNOMEM + cmp dx,MAXLEN ;MAXLEN read amount is too much + jz near DosError +;------- + mov bp,sot ;eof_ptr=filesize+start_of_text + add bp,dx +NewFileEnd: +%ifdef ELKS + mov byte [ds:bp],NEWLINE ;eof-marker +%else + mov word [ds:bp],0a0dh +%endif + clc +NFEnd2: ret +;------- +; save file (called by ^KS,^KX) +; +SaveFile:cmp byte [changed],UNCHANGED + jz SaveFile3 ;no changes: nothing to save + mov dx,filesave + call WriteMess9 + mov cx,O_WRONLY_CREAT_TRUNC + mov bx,filepath + mov dx,permissions +%ifdef ELKS + call OpenFile +%else + call CreateFile +%endif +DosEjmp0:js DosEjmp ;DosError + mov cx,sot ;cx=bof + mov dx,bp ;eof +SaveFile2:sub dx,cx ;dx=filesize= eof-bof + mov bx,ax ;file descriptor + call WriteFile + js DosEjmp ;DosError + mov word[errno],5 ;just in case of.... + cmp ax,dx ;all written? + jnz near DosError + call CloseFile + js DosEjmp ;DosError +SaveFile3:ret +;------------------------------ +; save block (called by ^KW) +; +SaveBlock:mov dx,blocksave + call getBlockName + jc near DE2 + mov cx,O_WRONLY_CREAT_TRUNC + mov bx,blockpath + mov dx,permissions +%ifdef ELKS + call OpenFile +%else + call CreateFile +%endif + js DosEjmp ;DosError + mov cx,si ;= block begin + mov dx,[blockende] + jmp short SaveFile2 +;------- +; read a block into buffer (by ^KR) +; +ReadBlock: +%ifdef ELKS + ret ;not ready due lseek +%endif + mov dx,blockread + call getBlockName + jc near DE2 + xor cx,cx ;i.e O_RDONLY + mov bx,blockpath + call OpenFile +DosEjmp:js DosError + mov bx,ax ;file desc + mov dx,2 + call SeekFile ;end + js DosError + push dx + push ax + xor dx,dx + call SeekFile ;home + pop ax + pop dx + js DosError + or dx,dx + mov word [errno],ERRNOMEM + jnz DosError + push ax + call InsertByte + pop dx ;file size + mov word [errno],ERRNOMEM + jc DosError + mov cx,di ;^offset akt ptr + call ReadFile + js preDosError ;to delete inserted bytes (# in dx) + mov cx,ax ;bytes read + call CloseFile + js DosError + mov word[errno],5 ;just in case of.... + cmp dx,cx ;all read? + jnz DosError +ReadBlock2:jmp NewFileEnd +;------------------------------------------------------------ +; +; Error handler +; +preDosError:mov ax,dx ;count bytes + call DeleteByte ;delete space reserved for insertation +DosError:push di + mov di,error+8 ;where to store ASCII value of errno + mov ax,[errno] + push ax + call IntegerToAscii ;TODO: print a string instead of errno value + pop cx + cmp cx,MAXERRNO + ja DE0 + mov di,errmsgs + call LookPD2 ;look message x in line number x + mov si,di + mov di,error+9 + mov ax,' :' + stosw + mov cx,80 ;max strlen / compare errlen equ 100 + rep movsb +DE0: mov dx,error + pop di +DE1: call WriteMess9 + call GetChar +DE2: call RestoreStatusLine + stc ;error status + ret +;---------------------------------------------------------------------- +; +; some GENERAL helper functions +; +IntegerToAscii: + mov cx,10 + std + mov bx,ax ;bx=quotient +Connum1:mov ax,bx + sub dx,dx + div cx + mov bx,ax ;save quotient (new low word) + mov al,dl + call Hexnibble + or bx,bx + jne Connum1 + cld + ret +Hexnibble:and al,0fh + add al,'0' + cmp al,':' + jb noHex + add al,7 ;(should never be due cx==10) +noHex: stosb + ret +;------- +; +; expects curent column in dx +; returns # spaces up to next tabulated location in AH +; +SpacesForTab:push cx + mov ax,dx + mov cl,TAB + div cl + neg ah ;ah = modulo division + add ah,TAB ;TAB - pos % TAB + pop cx + ret +;------- +GetEditScreenSize: + mov al,sHOEHE-1 + mov byte [lines],al + mov al,sBREITE + mov byte [columns],al ;columns > 255 are ignored... + ret +;------- +DelEditScreen:push si + push bp + mov di,help + mov bp,di ;end + add bp,help_ws_size + call DispNewScreen + pop bp + pop si + ret +;------- +InitBSS:mov cx,EXE_absssize ;init bss + mov di,EXE_startbss + cld + xor ax,ax + rep stosb + mov word [es:textX],0a0ah ;es: due EXESTUB version + ret +;------- +%ifndef ELKS +GetArg: mov si,80h ;point to params + mov cl,[si] ;get number of chars + xor ch,ch ;make it a word + inc si ;point to first char + add si,cx ;point to just after last char + mov byte [si],0 ;make into an ASCIIZ string + sub si,cx ;get back ptr to first char + cld + jcxz no_filename ;if no file name, then get one + mov dx,cx +del_spaces:lodsb + cmp al,SPACECHAR + jne found_letter ;exit loop if al not space + loop del_spaces +found_letter:dec si ;backup to first ascii char + cmp byte [si],SPACECHAR + jz no_filename + ret +no_filename:xor si,si + ret +%endif +;---------------------------------------------------------------------- +; +; FIND/REPLACE related stuff +; +AskForReplace:mov dx, askreplace1 + call WriteMess9MachRand + mov cx,suchtext + mov dx,maxfilenamelen + call InputString + jc AskFor_Ex + mov [suchlaenge],ax + mov dx,askreplace2 + call WriteMess9MachRand + mov cx,replacetext + mov dx,maxfilenamelen + call InputString + mov [repllaenge],ax + jc AskFor_Ex + jmp short GetOptions +AskForFind:mov dx,askfind + call WriteMess9MachRand + mov cx,suchtext + mov dx,maxfilenamelen + call InputString + mov [repllaenge],ax + jc AskFor_Ex +GetOptions:mov dx,optiontext + call WriteMess9MachRand + mov cx,optbuffer + mov dx,optslen + call InputString ; empty string is allowd for std options... + call ParseOptions ; ...(set in ParseOptions) + clc +AskFor_Ex:pushf + call RestoreStatusLine + call RestKursPos + popf + ret +;------- +; check string for 2 possible options +; +ParseOptions:push si + cld + mov si,optbuffer + mov word[vorwarts],1 + mov byte[grossklein],0dfh +Scan1: lodsb + and al,5fh + cmp al,'C' + jnz notCopt + xor byte[grossklein],20h ;result 0dfh, 2*C is 20h again -->not U option +notCopt:cmp al,'B' + jnz notBopt + neg word[vorwarts] ;similar 2*B is backward twice i.e. forward +notBopt:or al,al + jnz Scan1 + pop si + ret +;------- +; the find subroutine itself +; +find2: mov bx,di +find3: lodsb + or al,al ;=end? + jz found + cmp al,41h + jb find7 + and al,ch +find7: inc di + mov cl,byte [di] + cmp cl,41h + jb find10 + and cl,ch +find10: cmp al,cl + jz find3 + mov di,bx +FindText:mov dx,[vorwarts] ;+1 or -1 + mov ch,[grossklein] ;ff or df + mov si,suchtext + cld + lodsb + cmp al,41h + jb find1 + and al,ch +find1: add di,dx ;+1/-1 + mov cl,byte [di] + cmp cl,41h + jb find6 + and cl,ch +find6: cmp al,cl + je find2 + cmp di,bp + ja notfound + cmp di,sot + jnb find1 +notfound:stc + ret +found: mov di,bx + clc ;di points after location + ret +;---------------------------------------------------------------------- +; +; INTERFACE to OS kernel +; +%ifdef ELKS +ReadFile:mov ax,3 ;(3==sys_read) ;return read byte ax + jmp short IntCall ;bx file / cx buffer / dx count byte +;------- +WriteFile:mov ax,4 ;(4==sys_write) + jmp short IntCall +;------- +OpenFile:mov ax,5 + jmp short IntCall ;cx mode / bx path / dx permissions (if create) +;------- +CloseFile:pusha + mov ax,6 ;bx is file desc + int 80h + popa + xor ax,ax ;always return "NO_ERROR" + ret +;------- +SeekFile:xor cx,cx ;offset + mov ax,19 ;system call number (lseek) +IntCall:int 0x80 ;bx file / dx method + neg ax + mov [errno],ax + neg ax ;set flags also + ret +;------- +IOctlTerminal:mov bx,stdin ;expects dx termios or winsize structure ptr + mov ax,54 ;54 == the ioctl syscall no. + int 80h ;cx TCSETS,TCGETS,TIOCGWINSZ + ret +%else ;--------------- +; +; ******beside int 21h we have also BIOS calls: +; **** mov ax,1302h int 10h +; **** mov ah,0eh int 10h +; **** mov ah,2 int 10h +; **** mov ah,0 int 16h +; ***************************** +; +OpenFile:xchg bx,dx ;elks register style + mov ax,3d02h ;r/w input bx=^path +Intcall:int 21h ;=ax file + jnc NoErr + mov [errno],ax + mov ax,-1 +NoErr: test ax,ax ;set sign flag + ret +CreateFile:xchg bx,dx ;elks style + xor cx,cx ;input bx=^path + mov ah,3ch + jmp short Intcall +ReadFile:mov ah,3fh + jmp short WFile +WriteFile:mov ah,40h +WFile: push dx + xchg dx,cx + int 21h + jnc NoErr2 + mov [errno],ax + mov ax,-1 +NoErr2: test ax,ax ;set sign flag + pop dx + ret +CloseFile:mov ah,3eh ;path in bx + jmp short Intcall +SeekFile:mov al,dl ;ELKS register style + mov ah,42h + xor dx,dx + xor cx,cx + jmp short Intcall +%endif +EXE_endcode: +; +;---------------------------------------------------------------------- +; +section .data +bits 16 +EXE_startdata: +; +; CONSTANT DATA AREA +; +Ktable db 45h ;^K@ xlatb table for making pseudo-scancode + db 45h ;^ka 45h points to an an offset in jumptab1 + db 41h ;^kb 41h for example points to KeyCtrlKB function offset + db 43h ;^kc + db 5dh ;^kd + db 45h ;^ke 45h means SimpleRet i.e. 'do nothing' + db 45h ;^kf + db 45h ;^kg + db 57h ;^kh + db 45h ;^ki + db 45h ;^kj + db 42h ;^kk + db 45h ;^kl + db 45h ;^km + db 45h ;^kn + db 45h ;^ko + db 45h ;^kp + db 46h ;^kq + db 3dh ;^kr ;not yet for ELKS + db 5ch ;^ks + db 45h ;^kt + db 45h ;^ku + db 56h ;^kv + db 3eh ;^kw + db 44h ;^kx + db 4eh ;^ky +Qtable db 45h ;^q@ ditto for ^Q menu + db 54h ;^qa + db 5ah ;^qb + db 58h ;^qc + db 4fh ;^qd + db 45h ;^qe + db 55h ;^qf + db 45h ;^qg + db 45h ;^qh + db 45h ;^qi + db 45h ;^qj + db 5bh ;^qk + db 45h ;^ql + db 45h ;^qm + db 45h ;^qn + db 45h ;^qo + db 4ch ;^qp + db 45h ;^qq + db 59h ;^qr + db 47h ;^qs + db 45h ;^qt + db 45h ;^qu + db 45h ;^qv + db 45h ;^qw + db 45h ;^qx + db 40h ;^qy +size equ 2 ;(byte per entry) +jumptab1: ; The associated key values originaly were BIOS scan codes... + ; ... now using terminal device this does have less sense, so I altered some + ; ... special cases, like ^PageUp (was 84h, but extends the table too much) + ; ... to some places shortly after 5dh (i.e. shift F10). + ; Using terminals the F-keys are not supported on ELKS (but DOS only). +lowest equ 3bh + dw KeyCtrlKV ;3bh ^KV F1 (DOS only) + dw KeyCtrlL ;3ch ^L F2 (ditto) + dw KeyCtrlKR ;3dh ^KR F3 (etc) + dw KeyCtrlKW ;3eh ^KW + dw KeyCtrlT ;3fh ^T + dw KeyCtrlQY ;40h ^QY + dw KeyCtrlKB ;41h ^KB + dw KeyCtrlKK ;42h ^KK + dw KeyCtrlKC ;43h ^KC + dw KeyCtrlKX ;44h ^KX F10 + dw SimpleRet ;45h F11 + dw KeyCtrlKQ ;46h F12 + dw KeyHome ;47h + dw KeyUp ;48h + dw KeyPgUp ;49h + dw SimpleRet ;4ah ^QDel + dw KeyLeft ;4bh + dw KeyCtrlQP ;(5 no num lock) + dw KeyRight ;4dh + dw KeyCtrlKY ;(+) ^KY + dw KeyEnd ;4fh + dw KeyDown ;50H + dw KeyPgDn ;51h + dw KeyIns ;52H + dw KeyDel ;53H + dw KeyCtrlQA ;54h ^QA sF1 + dw KeyCtrlQF ;55h ^QF sF2 + dw SimpleRet ;56h + dw KeyCtrlKH ;57h + dw KeyCtrlQC ;58h + dw KeyCtrlQR ;59h + dw KeyCtrlQB ;5Ah ^QB + dw KeyCtrlQK ;5Bh ^QK sF8 + dw KeyCtrlKS ;5ch ^KS sF9 + dw KeyCtrlKD ;5dh ^KD sF10 +jumps1 equ ($-jumptab1) / size +jumptab3 dw SimpleRet ;^@ + dw KeyCtrlLeft ;^a + dw SimpleRet ;^b + dw KeyPgDn ;^c + dw KeyRight ;^d + dw KeyUp ;^e + dw KeyCtrlRight ;^f + dw KeyDel ;^g 7 + dw KeyDell ;^h 8 DEL (7fh is translated to this) + dw NormChar ;^i 9 + dw KeyRet ;^j = 0ah + dw CtrlKMenu ;^k b + dw KeyCtrlL ;^l c + dw KeyRet ;^m 0dh + dw SimpleRet ;^n e + dw SimpleRet ;^o f + dw CtrlQMenu ;^p 10 ;^P like ^Q + dw CtrlQMenu ;^q 11 + dw KeyPgUp ;^r 12 + dw KeyLeft ;^s 13 + dw KeyCtrlT ;^t 14 + dw SimpleRet ;^u 15 + dw KeyIns ;^v 16 + dw SimpleRet ;^w 17 + dw KeyDown ;^x 18 + dw KeyCtrlY ;^y 19 +;------- +optiontext db 'OPT? C/B ',0 +filename db 'FILENAME:',0 +filesave db ' SAVE: ',0 +asksave db 'SAVE? Y/n',0 +blockread db '^KR NAME:',0 +blocksave db '^KW NAME:',0 +askfind db '^QF FIND:',0 +askreplace1 db '^QA REPL:',0 +askreplace2 db '^QA WITH:',0 +stdtxtlen equ filesave-filename + +%ifdef ELKS + screencolors0 db 27,'[40m',27,'[37m' + bold0 db 27,'[0m' ;reset to b/w + screencolors1 db 27,'[41m',27,'[36m' ;yellow on blue + reversevideoX: + bold1: db 27,'[1m' ;bold + scolorslen equ $-screencolors1 + boldlen equ $-bold1 ;take care length of bold0 == length of bold1 +%endif + +;------- +%macro LD 0 + %ifdef ELKS + db 10 + %else + db 13,10 + %endif +%endmacro +;------- +errmsgs: +%ifdef ELKS +db "Op not permitted" ;1 +LD +db "No such file|directory" ;2 +LD +LD ;3 +LD ;4 +db "Input/output" ;5 +LD +db "No such device" ;6 +LD +LD ;7 +LD ;8 +db "Bad file descriptor" ;9 +LD +LD ;10 +LD ;11 +db "Cannot allocate memory" ;12 +LD +db "Permission denied" ;13 +LD +LD ;14 +LD ;15 +db "Device or resource busy" ;16 +LD +LD ;17 +LD ;18 +db "No such device" ;19 +LD +LD ;20 +db "Is a directory" ;21 +LD +db "Invalid argument" ;22 +LD +db "Too many open files" ;23 +LD +db "Too many open files" ;24 +LD +db "Inappropriate ioctl" ;25 +LD +db "Text file busy" ;26 +LD +db "File too large" ;27 +LD +db "No space left on device" ;28 +LD +db "Illegal seek" ;29 +LD +db "R/O file system" ;30 +LD +%else +db "Op not permitted" ;1 +LD +db "No such file|directory" ;2 +LD +db "Path not found" ;3 +LD +db "Too much open files" ;4 +LD +db "Access denied" ;5 +LD +LD ;6 +LD ;7 +LD ;8 +LD ;9 +LD ;10 +LD ;11 +db "Cannot allocate memory" ;12 +LD +LD ;13 +LD ;14 +db "Invalid drive" +LD ;15 +LD ;16 +LD ;17 +LD ;18 +db "R/O file system" ;19 +LD +LD ;20 +db "Drive not ready" ;21 +LD +db "Invalid argument" ;22 +LD +LD ;23 +LD ;24 +db "Illegal seek" ;25 +LD +LD ;26 +LD ;27 +LD ;28 +db "Write" ;29 +LD +db "Read" ;30 +LD +%endif +;----------------------------------------------------------------------- +newline: +db 10 +help: +db "MicroEditor e3 /16bit v0.1 GPL (C) 2002 A.Kleine <kleine@ak.sax.de>" +LD +db "Enter filename or leave with RETURN" +LD +LD +db "Files: ^KR Insert ^KS Save ^KX Save&Exit ^KQ Abort&Exit" +LD +db " ^KD Save&Load" +; ^KR not yet ready on ELKS +LD +LD +db "Blocks: ^KB Start ^KK End ^KC Copy ^KY Del" +LD +db " ^KV Move ^KW Write" +LD +LD +db "Search: ^QF Find ^L Repeat ^QA Srch&Repl" +LD +LD +db "Move: ^E Up ^X Down ^S Left ^D Right" +LD +db " ^R Page Up ^C Page Dn ^F Next Word ^A Prev Word" +LD +LD +db "Quick- ^QS Home ^QD End ^QR BOF ^QC EOF" +LD +db "-Move: ^QB Blk Begin ^QK Blk End ^F Next Word ^A Prev Word" +LD +LD +db "Delete: ^T Word ^Y Line ^H Left ^G Chr" +LD +db " ^QY Line End" +LD +help_ws_size equ $-help +LD +%ifndef EXESTUB +EXE_enddata: +;----------------------------------------------------------------------- +; +section .bss +bits 16 +%endif +EXE_startbss: +; +%ifdef ELKS + screenline_len equ 256+4*scolorslen ;max possible columns + 4 color ESC seq per line +%else ;-------------- + screenline_len equ sBREITE * 2 ;2 byte per char +%endif + +%ifdef ELKS + termios_size equ 60 + termios resb termios_size + orig resb termios_size + setkplen equ 10 + setkp resb setkplen ;to store cursor ESC seq like db 27,'[000;000H' + read_b resw 1 ;buffer for GetChar + isbold resw 1 ;control of bold display of ws-blocks + inverse resw 1 +%else ;----- + zeilenangabe resb 12 ;buffer for showlinenum +%endif +errno resw 1 ;used similar libc, but not excactly equal +error resb errlen ;reserved space for string: 'ERROR xxx:tttteeeexxxxtttt',0 +columne resw 1 ;helper for display of current column +zloffset resw 1 ;helper: chars scrolled out at left border +fileptr resw 1 ;helper for temp storage of current pos in file +tabcnt resw 1 ;internal helper byte in DispNewScreen() only +kurspos resw 1 ;cursor position set by DispNewScreen() +kurspos2 resw 1 ;cursor position set by other functions +insstat resw 1 +endedit resw 1 ;byte controls program exit +changed resw 1 ;status byte: (UN)CHANGED +linenr resw 1 ;current line +showblock resw 1 ;helper for ^KH +blockbegin resw 1 +blockende resw 1 +bereitsges resw 1 ;byte used for ^L +suchlaenge resw 1 ;helper for ^QA,^QF +repllaenge resw 1 +vorwarts resw 1 +grossklein resw 1 ;helper byte for ^QF,^QA +old resw 1 ;helper for ^QP +veryold resw 1 ;ditto +ch2linebeg resw 1 ;helper keeping cursor pos max at EOL (up/dn keys) +numeriere resw 1 ;byte controls re-numeration +lines resw 1 ;equ 23 or similar i.e. screen lines-2 (status-,unused line) +columns resw 1 ;equ 80 or similar word (using only LSB) +filepath resb maxfilenamelen+1 +blockpath resb maxfilenamelen+1 +replacetext resb maxfilenamelen+1 +suchtext resb maxfilenamelen+1 +optbuffer resb maxfilenamelen+1 ;buffer for search/replace options and for ^QI +optslen equ $-optbuffer +screenline resb screenline_len ;buffer for displaying a text line +textX resb MAXLEN +sot equ (textX+1) ;start-of-text + +alignb 4 +EXE_endbss: + EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3) +%ifdef EXE + EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3) + EXE_datasize equ EXE_enddata-EXE_startdata + EXE_allocsize equ EXE_acodesize + EXE_datasize +100h +%endif + +%ifndef ELKS +%ifdef EXESTUB +bits 16 +section .stack stack + resb 0x800 +%endif +%endif @@ -0,0 +1,5657 @@ +;-------------------------------------------------------------------- +; +; e3.asm v2.21 Copyright (C) 2000-2002 Albrecht Kleine <kleine@ak.sax.de> +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +;---------------------------------------------------------------------- +; +%include "e3.h" +; +section .text +bits 32 + ORGheader +global _start +; +; start with OUTER editor loop +; +_start: call SetTermStruc +%ifdef SELFTEST + mov eax,mode + mov byte [eax],WS ;store current editor mode: WS only.. + mov esi,pipein ;...because the test file expects WS "syntax" +%else +%ifdef W32 + push byte 0 + push dword 8192 ;initial size (to be extended) + push byte 0 + call HeapCreate + mov [heap],eax +;------ + mov eax,mode + mov byte [eax],DEFAULT_MODE ;store default editor mode + call GetCommandLineA ;eax points to either D:\PATH\E3.EXE args1 args2 args3... + xchg eax,esi ; or "d:\path\e3.exe" + ;-- for debug only -- ; or e3.exe "args" + ;pusha + ;push dword 0 ;single OK button + ;push dword esi + ;push dword esi + ;push dword 0 + ;call MessageBoxA ;show cmd line + ;popa + ;-------------------- + cld + xor ebx,ebx + cmp byte [esi],'"' ;due above mentined 2 different cmd line ways + jnz prog + dec ebx ;ebx -1 due pending '"' +prog: lodsb + or al,al + jz prog9 + cmp al,SPACECHAR ;TODO chk TABs + ja prog + inc esi +prog9: dec esi +prog0: push esi + lea esi,[esi+ebx-4-5] ;-4 due suffix ".exe" + call SetEditMode + jz prog1 + mov byte [eax],DEFAULT_MODE ;store current editor mode +prog1: pop esi + xor edx,edx ;no args +prog2: lodsb + or al,al + jz prog3 + cmp al,SPACECHAR + jbe prog2 + dec esi + jmp short prog5 +prog3: mov esi,edx +prog5: +%else +%ifdef BEOS ;----------------------------------------------------------- + pop eax + pop ebx ;args counter (1....x) + pop esi + mov esi,[esi] ;points to our_name0[args]0env..... + cld +prog: lodsb + or al,al + jne prog + mov edx,esi ;store arg ptr + lea esi,[esi-5] + call SetEditMode + jz prog1 + mov byte [eax],DEFAULT_MODE ;store current editor mode +prog1: xor esi,esi ;init for 'no args' + dec ebx + jz noarg + mov esi,edx +noarg: +%else +%ifdef DYN ;------------------------------------------------------------ +; This is to be called from dynamic linked libc startup code +; just like you would expect: int main(int argc,char**argv) +; (for experimental purpose only) +; + xor esi,esi ;init to "no args" + mov ecx,[esp+4] ;"int argc" + cmp ecx,1 + je NoArg + mov esi,[esp+8] ;"char**argv" + mov esi,[esi] + cld +Argl: lodsb + or al,al + jne Argl +NoArg: mov eax,mode + mov byte [eax],DEFAULT_MODE ;store current editor mode (WS only) +%undef CURSORMGNT +%else ;-------------- i.e. Linux, FreeBSD, QNX, Ath ------------------ +%ifdef SYS_sigaction + call SetSigHandler +%endif +;------- +%ifdef ATHEOS + pop edx + pop edx + pop edx +%endif + pop edx ;Linux: arguments # + pop esi ;Linux: argv[0] + cld +prog: lodsb + or al,al + jne prog ;get program name + lea esi,[esi-5] + call SetEditMode + jz prog1 + mov byte [eax],DEFAULT_MODE ;store current editor mode +prog1: +;------- + pop esi ;Linux: esi points to first arg (filename) +%endif +%endif +%endif +%endif +;------- +%ifdef CURSORMGNT + or esi,esi + jz moreenv +morearg:pop ecx ;arguments until NULL + or ecx,ecx + jnz morearg +;------- +moreenv:pop ecx + jecxz ReStart + cmp dword[ecx],'TERM' ;a short test for "TERM=linux" + jnz moreenv + cmp dword[ecx+5],'linu' + jnz ReStart + add byte[revvoff],boldlen ;special inverse cursor on linux terminals +%endif +;------- +ReStart:call NewFile + jc E3exit +MainCharLoop:call ChkCursPos + call IsViMode + jnz MCL + mov ecx,[blockbegin] + jecxz MCL + push edi + mov edi,ecx ;for vi only: keep Begin/End-line marker together + call KeyEnd + ; <------prev line------------> + ; BegM......marker line........EndM + ; <-------next line-----------> + mov [blockende],edi ;set WS's "blockende" to one after EOL for VI marker + pop edi + call ShowBl1 ;i.e. "mov byte [showblock],1" +;------- +MCL: call DispNewScreen + call RestoreStatusLine + call HandleChar +%ifdef W32LF + cmp byte [edi],RETURN ;never stay at character 0dh + jnz MCL2 + inc edi ;(rather stay at following 0ah) +MCL2: +%endif + mov ebx,endeedit + cmp byte [ebx],0 + je MainCharLoop + xor esi,esi ;just like if no arg is present + cmp byte [ebx],2 + je ReStart ;^KD repeat edit using another file +E3exit: call KursorStatusLine +%ifdef W32 + push dword w32result ;reset all to standard colors + push byte 0 + mov eax,[lines] + inc eax + mov ebx,[columns] + mul bl + push eax + push byte DARKWHITE ;equ 7 + push dword [hout] + call FillConsoleOutputAttribute +%endif + mov ecx,text ;enter next line on terminal NEWLINE is @ byte [text] + call WriteFile00 +;------- + mov ebx,tempfile2 ;undo info (if exist) + call Unlink +%ifdef W32 + push dword [heap] + call HeapDestroy + push byte 0 ;return code + call ExitProcess ;Ready&Exit +%else + mov ecx,TERMIOS_SET + call IOctlTerminal0 ;restore termios settings + jmp Exit +%endif +;---------------------------------------------------------------------- +; +; MAIN function for processing keys +; +HandleChar:call ReadChar + cmp ah,0xFF ;normal chars get 0xFF in ah + jne near ExtAscii ;go handling Cursor-Keys + mov esi,mode + test byte [esi], EM | PI + jz NO_EM01 + cmp al,11 + je IsCtrlK + mov byte [EmaCtrlK],0 +IsCtrlK:cmp al,13h ;^S + je IsCtrlS + cmp al,12h ;^R + je IsCtrlS + mov byte [EmaCtrlS],0 +IsCtrlS: +NO_EM01:cmp byte [esi],VI + jz ISVI1 + cmp al,32 ;in WS,EM,PI,NE: handle control chars + jae NormChar + mov bl,al + add bl,jumps1 + cmp byte [esi],WS + je CJump + add bl,32 + cmp byte [esi],EM + je CJump + add bl,32 + cmp byte [esi],PI + je CJump + add bl,32 +CJump: jmp CompJump2 +ISVI1: ;in VI: most control is done in command mode... + cmp al,7 ;... so maintaining another table for <Return>... + je near KeyDel ;... <Del> and <DelLeft> is useless + cmp al,8 + je near KeyDell + cmp al,RETURN + je near KeyRet +;------- +NormChar:test byte [mode], EM | PI + jz NOEM0 + call ShowBl0 ;i.e. "mov byte [showblock],0" +NOEM0: call CheckMode +%ifdef USE_UNDO + jz NormCh2 + call DataForUndoOverwrite + jmp short OverWriteChar +%else + jnz OverWriteChar +%endif +NormCh2:push eax +%ifdef W32LF + call CheckEof + jz noEOL + cmp word [edi-1],RETURN|(NEWLINE<<8) + jnz noEOL + dec edi ;move back to 0Dh +noEOL: +%endif + call Insert1Byte + pop eax + jc InsWriteEnd ;error: text buffer full +OverWriteChar:cld + stosb +SetChg: mov byte [changed],CHANGED +InsWriteEnd:ret +;------- +KeyVICmdr:call ReadOneChar ;repl one char (except newline) + cmp byte [edi],NEWLINE + je InsWriteEnd + cmp al,RETURN + jnz KeyVICmdr1 + mov al,NEWLINE +KeyVICmdr1:mov byte [edi],al + jmp short SetChg +;------- +KeyEmaCtrlQ:mov esi,asknumber + call GetOctalToInteger + jbe InsWriteEnd + xchg eax,ecx ;using decimal input for ASCII value + cmp eax,256 + jb NormCh2 + ret +;------- +; +; helper for HandleChar +; +CtrlKMenu:mov ebx,Ktable + mov al,'K' + jmp short Menu +CtrlQMenu:mov ebx,Qtable + jmp short PicoQM +PicoJMenu:mov ebx,PicoJtable + mov al,'J' + jmp short Menu +PicoQMenu:mov ebx,PicoQtable +PicoQM: mov al,'Q' + jmp short Menu +CtrlXMenu:mov ebx,Xtable + mov al,'X' +Menu: mov ecx,2020205eh + mov ch,al +;------- +MakeScanCode:call WriteTwo ;ebx expects xlat-table + push ebx + call GetChar + pop ebx + and al,01fh + cmp al,Ktable_size + jnb InsWriteEnd ;if no valid scancode + xlatb + mov ah,al ;=pseudo "scancode" +;------- cont +ExtAscii:mov bl,ah ;don't use al (carries char e.g. TAB) + cmp bl,jumps1 + jae InsWriteEnd + xor eax,eax + mov [EmaCtrl],eax +CompJump2:mov bh,0 + lea ebx,[bx] ;1 byte shorter than 'and ebx,0ffh' + movzx ebx,word [2*ebx+jumptab1] ;2*ebx is due 2 byte per entry + add ebx,_start ;offset inside code +;------- + call ebx ;the general code jump dispatcher +;------- + cmp byte [numeriere],1 ;after return from functions... + jnz BZNret ;...decide whether count current line number + push edi + mov esi,sot + xchg esi,edi + xor edx,edx +BZNLoop:inc edx ;edx=linenr counter + call LookForward + inc edi ;point to start of next line + cmp edi,esi + jbe BZNLoop + mov [linenr],edx + pop edi + mov byte [numeriere],0 +BZNret: ret +;---------------------------------------------------------------------- +; +; processing special keys: cursor, ins, del +; +KeyRetNoInd:xor eax,eax + jmp short KeyRetNInd +KeyRet: +%ifdef SELFTEST +xor eax,eax +%else + call CheckMode + jnz OvrRet + call CountToLineBegin ;set esi / returns eax + inc esi + inc esi + or eax,eax + jz KeyRetNInd + mov ebx,eax + xor eax,eax + dec eax +KeyRetSrch:inc eax ;search non (SPACE or TABCHAR) + cmp eax,ebx + jae KeyRetNInd + cmp byte [esi+eax],SPACECHAR + je KeyRetSrch + cmp byte [esi+eax],TABCHAR + je KeyRetSrch +%endif +KeyRetNInd:push esi + push eax ;eax is 0 or =indented chars + call GoDown + pop eax + push eax +%ifdef W32LF + inc eax ;1 extra for RETURN + call CheckEof + jz noEOL2 + cmp word [edi-1],RETURN|(NEWLINE<<8) + jnz noEOL2 + dec edi ;move back to 0Dh +noEOL2: +%endif + call InsertByte0 ;1 extra for NEWLINE + pop ecx ;# blanks + pop esi ;where to copy + jc SimpleRet + inc dword [linenr] + cld +%ifdef W32LF + mov ax,RETURN|(NEWLINE<<8) ;insert 0d0ah combination + stosw +%else + mov al,NEWLINE + stosb +%endif + jecxz SimpleRet + rep movsb ;copy upper line i.e. SPACES,TABS into next +SimpleRet:ret +OvrRet: xor eax,eax + mov [ch2linebeg],eax + jmp short DownRet +;------- +KeyDown:call CountColToLineBeginVis +DownRet:call GoDown + call LookLineDown + jmp short JmpSC +;------- +KeyUp: call GoUp + call CountColToLineBeginVis + call LookLineUp + jmp short JmpSC +;------- +KeyHalfPgUp:call CountColToLineBeginVis + call LookHalfPgUp + jmp short SetColumn +;------- +KeyHalfPgDn:call CountColToLineBeginVis + call LookHalfPgDn + jmp short SetColumn +;------- +KeyScrollUp:call CountColToLineBeginVis + call LookScrUp + jmp short SetColumn +KeyScrollDn:call CountColToLineBeginVis + call LookScrDn + jmp short SetColumn +;------- +KeyPgUp:call CountColToLineBeginVis + call LookPageUp +JmpSC: jmp short SetColumn +;------- +KeyPgDn:call CountColToLineBeginVis + call LookPgDown ;1st char last line +SetColumn:mov ecx,[ch2linebeg] ;=maximal columns + xor edx,edx ;counts visible columns i.e. expand TABs + dec edi +SCloop: inc edi + cmp edx,ecx ;from CountColToLineBeginVis + jae SCret + cmp byte [edi],NEWLINE ;don't go beyond line earlier line end + jz SCret + cmp byte [edi],TABCHAR + jz SCtab + inc edx ;count columns + jmp short SCloop +SCtab: call SpacesForTab + add dl,ah + cmp edx,ecx ;this tab to far away right? + jna SCloop ;no +SCret: ret +;---------------------------------------------------------------------- +; +; a helper for d'a and y'a vi commands +; have to differ whether cursor is below or above the marked line +; (at all this line based concept does not fit very well into e3) +; expects: +; ecx valid begin of marked line +; edi cursor +VIsetMarker:cmp edi,ecx + ja Marker_above_cursor + ; X........cursor line....... + ; ........................... + ; .........marker line....... + ; Y + mov ecx,[blockende] + inc ecx + cmp ecx,ebp + jb Mbel + dec ecx +Mbel: mov dword [EmaMark],ecx ;i.e. store point Y +;------- cont +KeyHome:call CountToLineBegin ;i.e. goto point X + sub edi,eax + ret +;------- +Marker_above_cursor: + ; Y.......marker line ....... + ; ........................... + ; ........cursor line........ + ; X ; + mov dword [EmaMark],ecx ;i.e. store point Y + call KeyEnd + inc edi ;i.e. goto point X + cmp edi,ebp + jb Mret + dec edi +Mret: ret +;---------------------------------------------------------------------- +KeyIns: not byte [insstat] + xor eax,eax + call IsViMode + jnz KeyIns2 + inc eax + cmp byte [VICmdMode],al + jne KeyIns2 + mov byte [insstat],al + call KeyVImode0 +KeyIns2:call IsEmMode + jnz KeyIns3 + mov byte [showblock],al +KeyIns3:ret +;------- +KeyVICmdJ:call KeyEnd + jmp short KeyDel +;------- +KeyDell:call KeyLeft + jz KeyDell2 +KeyDel: cmp edi,ebp + jnb KeyIns3 + xor eax,eax ;delete one @ cursor + inc eax +%ifdef W32LF + cmp byte [edi-1],RETURN + jnz KD2 + dec edi ;delete one more + inc eax +KD2: +%endif + jmp DeleteByte +KeyDell2:cmp edi,sot ;delete newline char + jbe KeyIns3 + dec dword [linenr] + dec edi + jmp KeyCtrlT1 +;------- +KeyEmaCtrlT:cmp edi,sot ;xchg 2 chars + jbe KeyRightEnd + cmp byte [edi],NEWLINE + jnz KECT + dec edi +KECT: mov al,byte [edi] + xchg al,byte [edi-1] + call KeyVICmdr1 ;mov byte [edi],al / mov byte [changed],CHANGED +;------- +KeyRight:cmp byte [edi],NEWLINE + jnz KeyRNoMargin + call CheckEof + jae KeyRightEnd + call IsViMode + je KeyRightEnd ;no more line wrap around in vi mode + call GoDown +KeyRNoMargin:inc edi +KeyRightEnd:ret +;------- +KeyCLeft3:cmp edi,sot + jbe KeyCLEnd + dec edi +KeyCtrlQW:cmp byte [edi-1],NEWLINE + jz KeyCLeft3 + dec edi + cmp byte [edi],2fh + jbe KeyCtrlQW + cmp byte [edi-1],2fh + ja KeyCtrlQW +KeyCLEnd:ret +;------- +KeyCRight3:call CheckEof + jae KeyCREnd + jmp short KQZ1 +KeyCtrlQZ:mov al,2fh + cmp byte [edi],NEWLINE + jz KeyCRight3 +KQZ1: inc edi + call IsEmMode + jz ISEM2 + cmp byte [edi],al ;ws stops at word begin + jbe KeyCtrlQZ + cmp byte [edi-1],al + jmp short ISEM22 +ISEM2: cmp byte [edi-1],al ;em stops after end + jbe KeyCtrlQZ + cmp byte [edi],al +ISEM22: ja KeyCtrlQZ +KeyCREnd:ret +;------- +KeyVIcmde3:call CheckEof ;end of word (vi only) + jae KeyCREnd + inc edi +KeyVIcmde:cmp byte [edi],NEWLINE + jz KeyVIcmde3 + inc edi + cmp byte [edi],2fh + jbe KeyVIcmde + cmp byte [edi+1],2fh + ja KeyVIcmde + ret +;------- +KeyEmaCtrlO:call Insert1Byte + jc KeyRightEnd + mov al,NEWLINE + mov byte [edi],al + ret +;---------------------------------------------------------------------- +; +; processing special keys from the WS's Ctrl-Q menu +; +KeyCtrlQE:call LookPgBegin ;goto top left on screen + call KursorFirstLine + jmp short KCtKV1 +;------- +KeyCtrlQX:call LookPgEnd ;1st goto last line on screen + call KeyEnd ;2nd goto line end + call KursorLastLine + jmp short KCtKV1 +;------- +KeyCtrlQV:cmp byte [bereitsges],0 ;goto last ^QA,^QF pos + jz KeyCREnd + mov edi,[oldQFpos] +KCtKV1: jmp CQFNum +;------- +KeyVIbsearch:push byte -1 + jmp short KVIf +KeyVIfsearch:push byte 1 +KVIf: mov byte[grossklein],0ffh + jmp short KeyECtS1 +;------- +KeyEmaAltPer:push byte 1 ;s&repl + pop dword[vorwarts] + mov byte[grossklein],0dfh +;------- +KeyCtrlQA:mov byte [bereitsges],2 + call AskForReplace + jc SimpleRet9 +CQACtrlL:push edi + call FindText + jnc CQACL2 + pop edi +SimpleRet9:ret +CQACL2: mov eax,[suchlaenge] + call DeleteByte + mov eax,[repllaenge] + call InsertByte + mov esi,replacetext + call MoveBlock + jmp short CQFFound +;------- +KeyPiCtrlJT:cmp byte [bereitsges],2 + jz CQACtrlL + ret +;------- +KeyEmaCtrlR:push byte -1 + jmp short KECS +;------- +KeyEmaCtrlS:push byte 1 +KECS: mov byte[grossklein],0dfh +KeyECtS1:pop dword[vorwarts] + mov [EmaMark],edi + call ShowBl0 ;i.e. "mov byte [showblock],0" +;------- cont +KeyCtrlQF:call IsEmMode + jnz NO_EM04 + cmp byte [EmaCtrlS],1 + jz KeyCtrlL +NO_EM04:push dword [suchtext] ;store begin of old find_text + mov byte [bereitsges],1 + call AskForFind + pop ebx + pushf + test byte [mode], VI | PI + jz NO_VIPI01 + popf + or eax,eax ;jmp if user entered a new find_text + jnz QFpico + or bl,bl ;jmp if no old find text available + jz CtrlQFEnd + mov byte [suchtext],bl ;restore last find_text +QFpico: mov [PicoSearch],edi ;store begin of search (because wrap around EOF) + jmp short CQFCtrlL +;------- +NO_VIPI01:popf + jc CtrlQFEnd +CQFCtrlL:push edi + call FindText + mov byte [EmaCtrlS],1 + jc CtrlQFNotFound +CQFFound:mov [oldQFpos],edi + pop esi ;dummy +CQFNum: jmp CheckENum ;i.e. "mov byte [numeriere],1 ret" +CtrlQFNotFound:pop edi +CtrlQFEnd:ret +;------- +KeyCtrlL:mov eax,[bereitsges] ;2^QA 1^QF 0else + dec eax + jz CQFCtrlL + test byte[mode],WS | NE | PI + jz SimpleRet4 + dec eax + jz near CQACtrlL +SimpleRet4:ret +;------- +KeyVIcmd1:call ReadOneChar + cmp al,'G' + je KeyCtrlQR + ret +ViSpecial:jecxz KeyCtrlQR + jmp short KCQI +KeyNedCtrlA:mov [EmaMark],ebp + call ShowBl1 ;i.e. "mov byte [showblock],1" but shorter +KeyCtrlQR:mov edi,sot + jmp short CQFNum +;------- +KeyCtrlQP:mov ecx,[veryold] + cmp ecx,ebp + ja SimpleRet4 + mov edi,ecx +JmpCQFN3:jmp short CQFNum +;------- +KeyCtrlQB:xchg eax,edi + mov edi,[blockbegin] +CtrlQB2:or edi,edi ;exit if no marker set + jnz CQFNum + xchg edi,eax + ret +;------- +KeyCtrlQK:xchg eax,edi + mov edi,[blockende] + jmp short CtrlQB2 +;------- +KeyCtrlQI:mov esi,asklineno + call GetAsciiToInteger + jbe CtrlQFEnd ;CY or ZR set +KCQI: mov edi,sot + call LookPD2 +JmpCQFN:jmp short JmpCQFN3 +;------- +KeyCtrlQDel:call KeyLeft ;delete all left of cursor + call CountToLineBegin + sub edi,eax + jmp short KCY +;------- +KeyVICmdD:mov byte [VInolinebased],1 +KeyCtrlQY:call CountToLineEnd +%ifdef W32LF + or eax,eax + jz KCQY + cmp byte [edi+eax-1],0dh + jnz KCQY + dec eax ;keep RETURN 0dh char if exist +KCQY: +%endif + jmp short CtrlTEnd1 +;------- +KeyCtrlY:call CountToLineBegin + sub edi,eax ;edi at begin + call CountToLineEnd + cmp byte[mode],WS + jnz NO_WS01 +KCY: call DeleteByteCheckMarker + jmp short KeyCtrlT1 +NO_WS01:test byte [mode], VI | PI + jz KeyCtrlT + lea ecx,[edi+eax] + cmp ecx,ebp + jz CtrlTEnd1 ;do not delete pending LINEFEED (0Ah) + inc eax + jmp short CtrlTEnd1 +;------- +KeyCtrlT:call CountToWordBegin + call IsEmMode + jnz NO_EM05 +KeyEmaCtrlK:call CountToLineEnd +NO_EM05:cmp byte [edi],NEWLINE + jnz CtrlTEnd1 +KeyCtrlT1:xor eax,eax + inc eax ;1 for LINEFEED (0ah) +%ifdef W32LF + cmp byte[edi-1],RETURN + jnz KCT2 + dec edi ;0dh is expected "left" of 0ah + inc eax ;1 for RETURN (0dh) +KCT2: +%endif +CtrlTEnd1:call CheckEof + jz SimpleRet3 + cmp byte[mode],WS + jz near DeleteByteCheckMarker + mov esi,edi + call KeyEmaAltW2 + jmp short DelBjmp +;------- +KeyEmaCtrlW:mov ecx,[showblock] + cmp byte[mode],PI + jne NOPI1 +KECW: jecxz KeyCtrlY + mov ecx,[EmaMark] + jecxz KECW + jmp short NOPI2 +NOPI1: jecxz SimpleRet3 + mov ecx,[EmaMark] + jecxz SimpleRet3 +NOPI2: call KeyEmaAltW + mov edi,[EmaKiSrc] + mov eax,[EmaKiSize] +DelBjmp:jmp DeleteByte +;---------------------------------------------------------------------- +; +; processing special Keys from WS's Ctrl-K menu +; +KeyCtrlKY:call CheckBlock + jc SimpleRet3 ;no block: no action + mov eax,[blockende] + mov edi,esi ;esi is blockbegin (side effect in CheckBlock) + sub eax,esi ;block length + call DeleteByte ;out ecx:=0 + xchg eax,ecx + call InitSV2 ;block no longer valid +JmpCQFN2:jmp JmpCQFN +;------- +KeyCtrlKH:xor byte [showblock],1 ;flip flop +SimpleRet3:ret +KeyCtrlKK:mov [blockende],edi + jmp short ShowBl1 +;------- +KeyCtrlKC:call CopyBlock + jc SimpleRet2 +CtrlKC2:mov [blockbegin],edi + add eax,edi + jmp InitSV3 ;mov [blockende],eax - ret +;------- +KeyCtrlXX:mov ecx,[EmaMark] + jecxz SimpleRet3 + call KeyEmaMark + mov edi,ecx + call KeyEmaCtrlL +KeyCXX: jmp short JmpCQFN2 +;------- +KeyCtrlKV:call CopyBlock + jc SimpleRet2 + push edi + cmp edi,[blockbegin] + pushf + mov edi,[blockbegin] + call DeleteByte + neg eax ;(for optimizing eax is negated there) + popf + pop edi + jb CtrlKC2 + mov [blockende],edi + sub edi,eax +KeyCtrlKB:mov [blockbegin],edi +ShowBl1:mov byte [showblock],1 +SimpleRet2:ret +ShowBl0:mov byte [showblock],0 + ret +;------- +KeyVICmdm:call ReadOneChar + cmp al,'a' ;ma (marker a) + jne SimpleRet2 + push edi + call KeyHome ;setting WS's "blockbegin" to BOL + mov [blockbegin],edi + pop edi + ret +;------- +KeyVICmdJmpM:call ReadOneChar + cmp al,'a' + jne SimpleRet2 + mov ecx,[blockbegin] ;like WStar's Ctrl-QB [also Sun Oct 7 17:01:37 2001] + jecxz SimpleRet2 + mov edi,ecx + jmp short KeyCXX +;------- +KeyEmaMark:mov [EmaMark],edi + jmp short ShowBl1 +;------- +KeyCtrlKR:call ReadBlock + jc CtrlKREnd + call KeyCtrlKB + add ecx,edi + mov [blockende],ecx + test byte [mode],EM | NE + jz NO_EM03 + mov [EmaMark],ecx + call ShowBl0 ;i.e. "mov byte [showblock],0" +NO_EM03:cmp byte [mode],PI + jnz CtrlKREnd + mov edi,ecx ;in PI: cursor at end of read file +CtrlKREnd:jmp RestKursPos +;------- +KeyCtrlKW:call CheckBlock + jc CtrlKSEnd ;no action + call SaveBlock + jmp short CtrlKREnd +;------- +KeyEmaCtrlXF:cmp byte [changed],UNCHANGED + jz KECF + mov esi,asksave2 + call DE1 + call RestKursPos + call CheckUserAbort + jz CtrlKSEnd + and al,0dfh + cmp al,'N' ;N for request NOT SAVE changes +KECF: jz KCKD2 + jmp short KeyCtrlKD +;------- +KeyEmaCtrlXW:call GetBlockName + jc CtrlKSEnd + mov esi,blockpath +XW1: cld + pusha + mov edi,filepath +XW0: lodsb + stosb ;copy to blockpath to filepath + or al,al + jne XW0 + stosb + popa +KeyCtrlKS0:call SetChg ;i.e. "mov byte [changed],CHANGED" to save it really +;------- +KeyCtrlKS:call SaveFile + pushf ;(called by ^kd) + call RestKursPos + popf + jc CtrlKSEnd +Unchg: mov byte [changed],UNCHANGED +CtrlKSEnd:ret +;------- +KeyCtrlKD:call KeyCtrlKS + jc KeyKXend +KCKD2: mov byte [endeedit],2 + ret +;------- +KeyCtrlKQ:cmp byte [changed],UNCHANGED + jz KCKXend + mov esi,asksave + call DE1 + call RestKursPos + call CheckUserAbort + jz CtrlKSEnd + and al,0dfh + cmp al,'N' ;N for request NOT SAVE changes + jz KCKXend + cmp al,'L' ;L for SAVE and LOAD a new file + jnz KeyCtrlKX + call KCKXend +KeyCtrlKX:call KeyCtrlKS + jc CtrlKSEnd +KCKXend:inc byte [endeedit] +KeyKXend:ret +;---------------------------------------------------------------------- +; +; some minimal limited vi specials in command mode +; +KeyVICmdW:lea esi,[ecx+2] + cmp byte [esi],SPACECHAR + ja XW1 + ret +;------- +VINoLineCmd:mov eax,[ecx] + cmp ax,'w!' ;save + je KeyCtrlKS0 + cmp ax,'w' ;save + je KeyCtrlKS + cmp ax,'x' ;save and exit + je KeyCtrlKX + cmp ax,'$' ;No line number, but EOF + jne KVI_KX0 +;------- +KeyCtrlQC:mov edi,ebp + jmp CQFNum +;------- +KVI_KX0:cmp ax,'wq' +KVI_KX: je KeyCtrlKX + cmp ax,'w ' ;save as ... and continue + je KeyVICmdW + cmp ax,'q' + je KeyCtrlKQ + cmp ax,'q!' + je KCKXend + cmp ax,'e ' ;edit another .. + je near KeyVICmdE + cmp ax,'h' + je near KeyHelp +%ifndef USE_PIPE + ret +%else + jmp KeyVICmdtemp +%endif +;------- +KeyVICmdZ:call ReadOneChar + cmp al,'Z' + je KVI_KX + ret +;------- +KeyVI1Char:call KeyHome + cmp byte [edi],SPACECHAR + ja KFC2 +KFC1: cmp byte [edi],NEWLINE + jz KFC2 + inc edi + cmp byte [edi],SPACECHAR + jbe KFC1 + cmp byte [edi-1],SPACECHAR + ja KFC1 +KFC2: ret +;------- +KeyVICmdS:call KeyHome + call KeyEmaCtrlK ;not quite ok in 'P'/'p' commands + mov byte [VInolinebased],1 + jmp short KeyVICmdI +KeyVICmdd:call ReadOneChar + cmp al,'d' ;"delete" + mov byte [VInolinebased],0 + je near KeyCtrlY + cmp al,"'" ;only line based mode supported + jne KFC2 + call ReadOneChar + cmp al,'a' ;" d'a " (only marker "a" supported) + jne KFC2 + mov ecx,[blockbegin] ;don't go further if no mark set + jecxz KFC2 + call VIsetMarker ;an helper for adjusting begin/end marker line +callKECW:call KeyEmaCtrlW + xor eax,eax + mov [blockbegin],eax ;after delete mark is no more set + jmp short JmpCQFn +;------- +KeyVICmdI:call KeyVI1Char + jmp short KeyVImode0 +;------- +KeyVICmdp:mov ecx,[EmaKiSize] ;check this before call KeyEmaCtrlY +jmpKFC2:jecxz KFC2 + cmp byte [VInolinebased],1 + jz KeyVICmdpnLB + call OvrRet ;ugly +KeyVICmdP:mov ecx,[EmaKiSize] ;check this before call KeyEmaCtrlY + jecxz jmpKFC2 + cmp byte [VInolinebased],1 + jz KeyVICmdPnLB + call KeyHome +KeyVICP2:push edi + call KeyEmaCtrlY + pop edi +JmpCQFn:jmp CQFNum +;------- +KeyVICmdR:mov byte [insstat],254 ;i.e "not 1" + jmp short KeyVImode0 +KeyVICmdO:call KeyHome + call KeyRet + call KeyUp + jmp short KeyVImode0 +KeyVICmdo:call KeyEnd + call KeyRet + jmp short KeyVImode0 +KeyVICmdA:call KeyEnd + jmp short KeyVImode0 +KeyVIcmda:call KeyRight +KeyVIcmdi:mov byte [insstat],1 +KeyVImode0:push byte 0 + jmp short KVim1 +KeyVICmdC:call KeyEmaCtrlK + mov byte [VInolinebased],1 + jmp short KeyVImode0 +;------- +KeyVICmdpnLB:call KeyVICP2 +KeyEnd: call CountToLineEnd + add edi,eax ;points to a LINEFEED (0ah) char + ret +;------- +KeyVICmdPnLB:call KeyLeft ;not_Line_Based mode + call KeyVICmdpnLB +;------- cont +KeyLeft:cmp byte [edi-1],NEWLINE + jnz KeyLNoMargin + cmp edi,sot ;i.e. CheckBof + je KeyLeftEnd + call IsViMode + je KeyLeftEnd ;no more line wrap around in vi mode + call GoUp +KeyLNoMargin:dec edi +%ifdef W32LF + cmp byte [edi],RETURN ;do not stay at 0dh + jnz KeyLeftEnd + dec edi +%endif +KeyLeftEnd:ret +;------- +KeyVImode1:push byte 1 +KVim1: pop eax + mov byte [VICmdMode],al + ret +;------- +KeyVIex:call InputStringWithMessage0 + pushf + call RestKursPos + popf + jc Kviex + mov esi,optbuffer + xor edx,edx + mov ecx,eax ;do not use xchg here + jecxz Kviex +;------- + push esi ;save optbuffer + cld +CheckDig:lodsb ;check for line number entered + cmp al,'0' + jnb CD1 + inc edx +CD1: cmp al,':' + jb CD2 + inc edx +CD2: loop CheckDig + pop ecx ;rest optbuffer +;------- + or edx,edx + jnz near VINoLineCmd + call GetAsciiToInteger + jmp ViSpecial ;due short jumps there +;------- +IsViMode:cmp byte [mode],VI + ret +IsEmMode:cmp byte [mode],EM +Kviex: ret +;--------------------------------------------------------------------- +; +; the general PAGE DISPLAY function: called after any pressed key +; +; 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,ecx +EmBlock: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],eax +DispShortLine: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 line +DispNewLine: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 +%endif +DispCharLoop: + 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 +%endif +DispCharL1: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 ELZ2 +ELZ: cmp esi,ebp + jnz ELZ6 + inc esi ;set esi>ebp will later trigger "ja FillLine" + jmp short ELZ2 +ELZ6: 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],ah +ELZ2: mov al,SPACECHAR +ELZ3: 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 only +ELZ5: 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 FillLine2 +FillLine1: + rep stosB ;store the rest blanks +FillLine2: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 CURSORMGNT +SetInverseStatus: + 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 SIS2 +SIS1: 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],0 +SIS5: mov eax,DARKWHITE +SIS2: 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 stosw +SIS3: clc +SIS4: popa + ret +SetColor: ;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],1 +SCEsc2: mov eax,WHITE + jmp short SIS2 +SCEsc1: 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],0 +SIS5: mov esi,bold0 +SIS2: push byte boldlen + pop ecx + rep movsb +SIS3: clc +SIS4: 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],1 +SCEsc2: mov esi,bold1 + jmp short SIS2 +SCEsc1: cmp byte [isbold],0 ;ditto + jz SIS4 + jmp short SIS6 +;------- +%ifdef LESSWRITEOPS +SetColor2: + 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_ret +SBlock: clc +SB_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 noerr +iserr: 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],ecx +StatusLineShow: +%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,attribline +Xsl3: lodsw + cmp edi,attribbuffer_end ;never read/write beyond buffer + jnb Xsl5 + cmp ax,[edi] + jz Xsl4 + mov [edi],ax +Xsl5: inc ebx ;set flag whether line need redrawing +Xsl4: 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,screenline +sl3: 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],al +sl5: inc ebx ;set flag whether line need redrawing +sl4: 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 +%endif +NoWrite:popa + ret +;------- +; a helper for ScreenLineShow +; +sys_writeSLColors: +%ifndef W32 + jecxz syswSL ;do nothing if not in status line + ret +syswSL: 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,extext +InputStringWithMessage:call WriteMess9MakeLine + mov ecx,optbuffer + push byte optslen + pop edx + jmp short InputString +;------- +InputString00:mov ecx,suchtext +InputString0: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,ebx +IS8: xor ebx,ebx + mov edi,ecx +IS0: 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 ISA +NO_VI01: + call CheckUserAbort + jne IS9 +ISA: xor ebx,ebx ;length 0 triggers CY flag + jmp short IS1 +IS9: 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],eax +GetChar:call ReadOneChar ;ah=0xFF for usual keys +%ifdef W32 + cmp ah,0FEh ;cursor key + jnz GC33 + shl eax,8 + ret +GC33: cmp ah,0FDh ;ALT key + jnz GC34 + and al,5fh ;toupper + jmp short NOVI7 +GC34: +%endif + cmp al,7FH + jne short RC_No7F ;special case: remap DEL to Ctrl-H +%ifndef FREEBSD + mov al,8 +%else + mov al,7 +%endif +RC_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 exit +NoCMDmode: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 mode +NoCursorKey:mov byte [VIbufch],al ;push char back into read buffer due it's not a cursor key + mov al,DoNo ;do nothing + jmp short JmpRCready +isSingleEscape: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 JmpRCready +NOi: cmp al,'I' + jnz NONE7 + mov al,0x10 + jmp short JmpRCready +NONE7: call IsEmMode + jnz NOEM7 ;ALT keys are currently used for Emacs mode... + cmp al,'%' ;...except altH for online Help + jne NoAltPer + mov al,0x28 +JmpRCready:jmp short RCready_1 +NoAltPer:cmp al,'<' + jne NoAltLt + mov al,0x0e + jmp short RCready_1 +NoAltLt:cmp al,'>' + jne NoAltGt + mov al,0x0f + jmp short RCready_1 +NoAltGt:and al,0x5F ;to upper case + sub al,'B' ;1at in table + js Other + cmp al,ATsize + ja Other + mov ebx,EmaAltTable + jmp short RCready_0 +NOEM7: 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 GetCharJmp +NoNumber: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 GetCharJmp +IsNumber:mov ebx,ScanTable +%endif +RCready_0:xlatb +RCready_1:shl eax,8 ;shift into ah (ah always != 0xFF) + ret +GetCharJmp: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 RoneC +NOVI4: 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 KeyCtrlKX +Cont: +%endif + mov eax,[ecx] ;[read_b] +%ifdef W32_EXTENDED_IO + ret +%endif +RoneC: 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 counter +LBa1: mov ecx,99999 + mov al,NEWLINE + std + repne scasb + lea eax,[ebx+99997] ;mov eax,99997 / add eax,ebx + sub eax,ecx +LBa5: 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 edi +CheckEof:cmp edi,ebp ;ptr is eof-ptr? + jnz CheckEnd ;Z flag if eof + jmp short CheckENum +CheckBof:cmp edi, sot-1 + ja CheckEnd +CheckENum:mov byte [numeriere],1 ;if bof +CheckEnd: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 less +LookPU1:sub [linenr],ecx + inc ecx +LookPU2: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 LookPD1 +LookScrUp:xor ecx,ecx + inc ecx + jmp short LookPU1 +LookHalfPgUp:mov ecx,[lines] ;vi special + dec ecx + shr ecx,1 + jmp short LookPU1 +LookHalfPgDn:mov ecx,[lines] + dec ecx + shr ecx,1 + jmp short LookPD1 +;------- +LookPgDown:mov ecx,[lines] + dec ecx ;PgUp,PgDown one line less +LookPD1:add [linenr],ecx + inc ecx +LookPD2:call LookForward + jz LookPDEnd ;(jmp if EOF) + inc edi ;1st char next line + loop LookPD2 + dec edi ;last char last line +LookPDEnd: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 > ^KK +CImBlockEnd:ret ;output:cy error / nc ok inside block +;------- +CheckMode:cmp byte [edi],NEWLINE ;checks for INSERT status + jz ChModeEnd + cmp byte [insstat],1 +ChModeEnd: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 start +CMEnd: 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 esi +CCV1: inc esi + cmp esi,edi + jae CCVend + cmp byte [esi],TABCHAR + jz CCVTab + inc edx ;count visible chars + jmp short CCV1 +CCVTab: call SpacesForTab ;return space_up_to_next_tab in ah + add dl,ah ;FIXME: now using 8 bits only + jmp short CCV1 +CCVend: 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 char +CCV2: +%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 +;------- +CountToWordBegin: ;output eax=chars up there + mov esi,edi +CountNLoop: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 CountNLoop +CTWend: mov eax,esi + sub eax,edi ;maybe =0 +Goret: ret +;---------------------------------------------------------------------- +; +; 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 UpDown +GoDown: mov al,byte [lines] + dec eax ;'dec al' are 2 byte! + mov ah,-1 +UpDown: 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 +;------- cont +KeyEmaCtrlL:call CountToLineBegin + mov dh,byte [lines] ;move cursor to center line (and later redisplay) + shr dh,1 + mov dl,al + jmp short SetKursPos +KursorFirstLine:xor edx,edx + jmp short SetKursPos +KursorLastLine:mov dh,byte [lines] + dec dh + mov dl,0 + jmp short SetKursPos +KursorStatusLine:mov dh,byte [lines] + mov dl,stdtxtlen + jmp short SetKursPos +RestKursPos: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 + mov eax,'[000' + stosd + mov al,';' ;i.e. load eax with ';000' + stosd + 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 eax +IntegerToAscii: + or eax,eax + jns ItoA1 + ;int 3 ;Assertation + xor eax,eax ;this should never be + inc eax +ItoA1: 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 + cld +ITAret: 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],edx +DeleteByte: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,eax +InsertByte0: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 [errno] ;(mov dword[errno],.. has 2 byte extra) + call OSerror + call RestKursPos + stc + ret +SpaceAva: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,edx +ISWS8: std + rep movsB +Ins0: 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],eax +Ins1: cmp edi,[blockbegin] + jae Ins2 + add [blockbegin],eax +NOWS8: + test byte [mode], EM | PI + jz NO_EM02 + cmp edi,[EmaMark] + jae Ins2 + add [EmaMark],eax +NO_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->ok +MoveBlEnd:ret ;return eax=size +;---------------------------------------------------------------------- +KeyVICmdyy:push edi + call KeyHome + mov [EmaMark],edi + call KeyEnd + inc edi ;add a line delimiter + call KeyEmaAltW + pop edi +KviRet: 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] + jmp short ISVI9 +; +; 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 + call IsClipboardFormatAvailable + or eax,eax + jz KECY0 + push byte CF_OEMTEXT + call GetClipboardData + or eax,eax + jz KECY0 + mov edi,ebp + inc edi ;one after eof + mov ecx,[maxlen] + add ecx,sot ;the last possible byte + xor ebx,ebx + dec ebx ;init counter -1 + xchg esi,eax + cld +Kloop: lodsb + inc ebx + cmp edi,ecx + jnb KECY2 + stosb + or al,al + jnz Kloop +KECY2: mov [EmaKiSize],ebx +KECY0: call CloseClipboard +KECY3: popa +KECY: +%endif + mov ecx,[EmaKiSize] + jecxz KeawRet + xchg eax,ecx ;OLD mov eax,ecx 1 byte longer + push eax + call InsertByte + pop ecx + jc KeawRet ;no_space_error is handled in InsertByte + mov esi,ebp + inc esi + mov [EmaMark],edi + cld + rep movsb + call ShowBl0 ;i.e. "mov byte [showblock],0" + call KeyEmaCtrlL +ISVI9: jmp CQFNum +;------- +KeyEmaAltW2:pusha + mov edi,ebp + inc edi + call IsViMode + jz KEW +;------- + cmp byte [EmaCtrlK],1 + jnz KEW + add edi,[EmaKiSize] + add [EmaKiSize],eax + jmp short KE2 +KEW: mov [EmaKiSize],eax + mov [EmaKiSrc],esi +KE2: mov ecx,eax + cld + rep movsb + call ShowBl0 ;i.e. "mov byte [showblock],0" +Keaw2: mov byte [EmaCtrlK],1 + popa +KeawRet:ret +;------- +KeyEmaAltW:mov byte [VInolinebased],0 + pusha + mov ecx,[showblock] + jecxz Keaw2 + mov ecx,[EmaMark] + jecxz Keaw2 + mov eax,edi + cmp ecx,eax + jb KEAW + xchg eax,ecx +KEAW: sub eax,ecx ;eax end / ecx beg + mov esi,ecx + mov edi,ebp + inc edi + mov [EmaKiSize],eax + mov [EmaKiSrc],esi + xchg eax,ecx ;OLD mov ecx,eax 1 byte longer + cld + rep movsb + call IsViMode + jz KEAW3 + call ShowBl0 ;i.e. "mov byte [showblock],0" +KEAW3: +%ifdef W32 + cmp byte[mode],NE ;Nedit ^C + jnz KEAW4 + push dword [EmaKiSize] + push byte 0 + push dword [heap] + call HeapAlloc + or eax,eax + jz KEAW4 + mov esi,[EmaKiSrc] + mov edi,eax + mov ecx,[EmaKiSize] + cld + rep movsb + mov byte[edi],0 ;ASCIIZ +;------- + push dword [heap] + push byte 0 + push eax ;push for later usage in HeapFree + push eax ;push clip handle for SetClipboardData + push byte 0 + call OpenClipboard + or eax,eax + jz KEAW8 + call EmptyClipboard + push byte CF_OEMTEXT + call SetClipboardData + call CloseClipboard +KEAW8: call HeapFree +KEAW4: +%endif + popa +KeaWRet:ret +;---------------------------------------------------------------------- +; +; functions reading/writing text or blocks from/into files +; +NFnoarg:mov esi,helptext ;initial part of help + mov edi,sot + push byte helptextsize + pop ecx + push edi + rep movsb +;------- + call GetHelpText ;second part of help + lea ebp,[ecx+sot+helptextsize] ;set END_OF_HELP_TEXT pointer + rep movsb + pop edi + call DispNewScreen +;------- + mov esi, filename + mov ecx, filepath + call InputString0 + jnc GetFile ;empty string not allowed here + ret +;------- +KeyVICmdE:lea esi,[ecx+2] + cmp byte [esi],SPACECHAR + je KeaWRet + pusha ;save before load new + call SaveFile + popa +;-------continue +NewFile:cld + call InitVars + or esi,esi + jz NFnoarg + mov edi,filepath +NF1: +%ifdef W32 + lodsb + cmp al,'"' + jz NF1 + stosb + cmp al,SPACECHAR ;truncate after blanks + jnz NF3 +NF4: mov byte [edi-1],0 + jmp short GetFile +NF3: cmp al,TABCHAR + jz NF4 +%else + lodsb + stosb +%endif +NF2: or al,al + jnz NF1 +;------- cont +GetFile: +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,filepath +%else + mov ebx,filepath +%endif + call OpenFile0 + mov edi,sot + mov ebp,edi + js NewFileEnd +%ifdef SYS_brk + call Seek + pusha + lea ebx,[eax+eax+102400] ;twice filesize plus reserve = space for inserts + mov [maxlen],ebx + add ebx,text + call SysBrk + popa + js OSejmp1 ;OSerror +%else + mov ebx,eax ;for FreeBSD memory is hard coded by maxlen +%endif +;------- +%ifdef SYS_fstat ;not for W32,BEOS + call Fstat + js OSejmp1 ;OSerror + mov eax,[fstatbuf+stat_struc.st_mode] +%ifdef FREEBSD + mov ecx,eax + and ecx,0F000h ;see /usr/include/sys/stat.h + cmp ecx,8000h ;not for special files + jz regFile + push byte ERRNOREGFILE + pop dword [errno] + jmp OSerror +regFile: +%endif + and eax,777q + mov [perms],eax +%ifdef SYS_utime + mov eax,[fstatbuf+stat_struc.st_mtime] + mov [accesstime+utimbuf_struc.modtime],eax +%endif +%endif ;end of code not for W32,BEOS +;------- +OldFile1:mov edx,[maxlen] ;i.e. either 'max' or filesize twice + mov ecx,edi ;sot + call Read_File + xchg edx,eax ;mov edx,eax bytes read + js OSejmp0 ;OSerror + call CloseFile +OSejmp1:js OSejmp0 ;OSerror + lea ebp,[edx+sot] ;eof_ptr=filesize+start_of_text +NewFileEnd:mov byte [ebp],NEWLINE ;eof-marker + clc +NFEnd2: ret +;------- +; save file (called by ^KS,^KX) +; +SaveFile:cmp byte [changed],UNCHANGED + jz NFEnd2 ;no changes: nothing to save + mov esi, filesave + call WriteMess9 +;------- + mov esi,filepath + push edi + mov edi,bakpath + mov ebx,esi + mov ecx,edi + cld +SF0: lodsb + stosb ;copy to BAK file path + or al,al + jne SF0 + dec edi + push byte '~' ;add BAK file extension + pop eax + stosd ;not stosb because ascii-ZERO + pop edi +%ifdef BEOS + push edi + mov ebx,0xFFFFFFFF + mov edx,ebx + mov ecx,filepath + mov edi,bakpath +%endif +%ifdef MAKE_BACKUP + cmp dword [ecx],'/tmp' + je no_ren +%ifdef SYS_readlink + pusha + mov ecx,linkbuffer ;we are only interested whether symlink or not + push byte linkbuffersize ;=4 byte dummy buffer + pop edx + call ReadLink + popa + jns CopyBAK ;no error means it's a symlink... + call RenameFile ;...but plain files are easy to rename (ecx is filepath) + jmp short no_ren ;...simlilar behave 'xemacs' and 'jed' +CopyBAK:call CopyToBackup ;we can't simply rename the link +%else + call RenameFile ;ecx is filepath +%endif +no_ren: ;...continue here... +%endif +%ifdef BEOS + pop edi +%endif +;------- +%ifdef W32 + mov ecx,CREATE_ALWAYS + mov ebx,filepath + mov edx,GENERIC_WRITE +%else +%ifdef BEOS + mov ebx,0xFFFFFFFF + mov ecx,filepath + mov edx,0x777 +%else + mov ecx,O_WRONLY_CREAT_TRUNC + mov edx,[perms] +%endif +%endif + call OpenFile +OSejmp0:js OSejmp9 ;OSerror + xchg ebx,eax ;file descriptor (xchg is only 1 byte) +;------- +%ifdef SYS_fstat + mov ecx,[fstatbuf+stat_struc.st_uid] +%ifdef UIDGID_WORD ;Linux special + mov edx,ecx + shr edx,16 + movzx ecx,cx ;OLD and ecx,0xffff +%else + mov edx,[fstatbuf+stat_struc.st_gid] +%endif + call ChownFile +%endif +;------- + mov ecx,sot ;ecx=bof + mov edx,ebp ;eof +SaveFile2:sub edx,ecx ;edx=fileesize= eof-bof + call IsViMode + jnz NoAddNL + cmp byte [ebp-1],NEWLINE + jz NoAddNL + inc edx ;append NewLine char for VI mode +NoAddNL:call Write_File ;ebx=file descriptor +OSejmp9:js OSejmp ;OSerror + push byte ERRNOIO + pop dword[errno] ;just in case of.... + cmp eax,edx ;all written? +%ifdef BEOS + jnz near OSerror +%else + jnz OSerror +%endif + call CloseFile + js OSejmp ;OSerror +SaveFile3:ret +;------- +; save block (called by ^KW) +; +SaveBlock:call GetBlockName + jc jcDE2 +SaveBl2: +%ifdef W32 + mov ebx,blockpath +SaveBl3:mov ecx,CREATE_ALWAYS + mov edx,GENERIC_WRITE +%else +%ifdef BEOS + mov ebx,blockpath +SaveBl3:mov ecx,0xFFFFFFFF + xchg ebx,ecx + mov edx,0x241 ;was 0x777 upto Dec 01 +%else + mov ebx,blockpath +SaveBl3:mov ecx,O_WRONLY_CREAT_TRUNC + mov edx,PERMS +%endif +%endif + call OpenFile + js OSejmp ;OSerror + mov ecx,esi ;= block begin + mov edx,[blockende] + xchg ebx,eax ;file descriptor (xchg is only 1 byte) + jmp short SaveFile2 +;------- +; read a block into buffer (by ^KR) +; +ReadBlock:call GetBlockName +jcDE2: jc near DE2 +ReadBlock2: +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,blockpath +%else + mov ebx,blockpath +%endif + call OpenFile0 +OSejmp: js OSerror + call Seek + js OSerror + push eax ;eax=fileesize + call InsertByte + pop edx ;file size + jc SaveFile3 ;ret if cy InsertByte told an error message itself + mov ecx,edi ;^offset akt ptr + call Read_File + js preOSerror ;to delete inserted bytes (# in EDX) + mov ecx,eax ;bytes read + call CloseFile + js OSerror + push byte ERRNOIO + pop dword[errno] ;just in case of.... + cmp edx,ecx ;all read? + jnz OSerror + ret +;------- +preOSerror:mov eax,edx ;count bytes + call DeleteByte ;delete space reserved for insertation +OSerror:push edi + mov edi,error+8 ;where to store ASCII value of errno + mov eax,[errno] + push eax + call IntegerToAscii + pop ecx ;for getting error text via LookPD2 + cmp ecx,MAXERRNO + ja DE0 + mov edi,errmsgs + call LookPD2 ;look message # (ecx) in line number # + mov esi,edi + mov edi,error+9 + mov ax,' :' + stosw + push byte 80 ;max strlen / compare errlen equ 100 + pop ecx + rep movsb +DE0: mov esi,error + pop edi +DE1: call WriteMess9 + call ReadOneChar ;was GetChar +DE2: ;continued... +;---------------------------------------------------------------------- +; +; more STATUS LINE maintaining subroutines +; +RestoreStatusLine:pusha ;important e.g. for asksave + call InitStatusLine + mov esi,mode + mov ecx,[columns] ;width + cmp cl,stdtxtlen+15+5+2 ;this window is too small + jb near RSno_lineNr + mov al,byte[changed] + mov byte[screenline+1],al ;changed status +;------- +%ifndef LINUX + lea eax,[ecx-13+screenline] ;FreeBSD or Beos ... +%else + lea eax,[ecx-12+screenline] +%endif + mov word[eax+8],'vi' ;vi does show mode info only. + cmp byte [esi],VI ;vi doesn't get altH text because altH won't work... + jnz RSL0 ;...caused by different handling due single ESC keys + cmp byte [VICmdMode],1 + jnz NOVI0 + mov ebx,'CMD ' + jmp short RSL1 +RSL0: mov dword [eax],'altH' + mov dword [eax+4],'=hel' ;'p' is stored with editor mode name + mov ebx,editmode + mov edx,[ebx] + cmp byte [esi],PI + jnz No_PI1 + mov edx,[ebx+4] +No_PI1: cmp byte [esi],EM + jnz No_Em1 + mov edx,[ebx+8] +No_Em1: cmp byte [esi],NE + jnz No_Ne1 + mov edx,[ebx+12] +No_Ne1: mov [eax+8],edx +;------- +NOVI0: mov ebx,'INS ' ;Insert + cmp byte [insstat],1 + jz RSL1 + mov ebx,'OVR ' ;Overwrite +RSL1: mov [screenline+4],ebx ;mode status + mov edi,screenline+stdtxtlen + lea ecx,[ecx-(stdtxtlen+15+5)] ;space for other than filename + mov esi,filepath ;lea ... is shorter than sub ecx,stdtxtlen+15+5 +RSL2: lodsb + or al,al + jz RSL4 + stosb + loop RSL2 +RSL4: mov edi,screenline-15 + add edi,[columns] + mov eax,[columne] + inc eax ;start with 1 + call IntegerToAscii + mov byte [edi],':' ;delimiter ROW:COL + dec edi + mov eax,[linenr] + call IntegerToAscii +RSno_lineNr:call StatusLineShow ;now write all at once + popa + stc ;error status only important if called via OSError + ret +;------- +; +; write an answer prompt into status line +; (with and without re-initialisation) +; expecting esi points to ASCIIZ or 0A terminated string +; +WriteMess9MakeLine:call InitStatusLine +WriteMess9:pusha + mov edi,screenline + cld +WriteMLoop:lodsb + cmp al,LINEFEED ;for error messages + jbe WriteMEnd + stosb + jmp short WriteMLoop +WriteMEnd:call StatusLineShow + popa + jmp KursorStatusLine +;------- +; a helper for other status line functions: +; simply init an empty line +; +InitStatusLine:pusha ;simply init an empty line + mov edi,screenline + mov al,SPACECHAR + mov ecx,[columns] +%ifndef LINUX + dec ecx ;? FreeBSD + js ISL ;should never be = -1 +%endif + cld + rep stosb + mov al,0 ;prepare ASCIIZ string + stosb +ISL: popa + ret +;------- +; read a file name for block operations +; +GetBlockName:pusha + mov esi,block + mov ecx,blockpath + call InputString0 ;cy if empty string + pushf + call RestKursPos + popf + popa + ret +;------- +; helper for NewFile +; +InitVars:mov byte [text],NEWLINE ;don't touch esi! + call Unchg ;i.e. "mov byte [changed],UNCHANGED" + call InitSomeVars ;set eax=0 + mov dword[old],sot + inc eax ;set eax=1 + mov byte [VICmdMode],al + mov dword [linenr],eax + mov byte [insstat],al + mov dword [maxlen],max + mov dword [error],'ERRO' + mov dword [error+4],'R ' + mov dword [perms],PERMS +%ifdef SYS_fstat + dec eax + dec eax ;eax == -1 i.e. no changes in fchown +%ifdef UIDGID_WORD ;Linux special + mov [fstatbuf+stat_struc.st_uid],eax ;both: giduid +%else + mov [fstatbuf+stat_struc.st_gid],eax + mov [fstatbuf+stat_struc.st_uid],eax +%endif +%endif + jmp ShowBl1 ;i.e. mov byte [showblock],1 +;------- +InitSomeVars: + xor eax,eax +%ifdef USE_UNDO + mov [undobuffer],eax ;i.e. invalid pointer + mov dword[undoptr],undobuffer+4 ;init to first frame +%endif + mov [EmaMark],eax + mov dword [oldQFpos],eax + mov byte[bereitsges],al + mov [endeedit],al +InitSV1:mov [EmaKiSize],eax ;do not allow side effects +InitSV2:mov [blockbegin],eax ;i.e. NO block valid now +InitSV3:mov [blockende],eax + ret +;------- +Seek: xchg ebx,eax ;mov file_descriptor to ebx (xchg is 1 byte only) + push byte 2 ;FILE_END + pop edx + call SeekFile ;end + js SeekRet + xor edx,edx ;FILE_BEGIN + push eax + call SeekFile ;home + pop eax +SeekRet:ret +;---------------------------------------------------------------------- +; +; FIND/REPLACE related stuff +; +AskForReplace:mov esi,askreplace1 + call InputString00 + jc AskFor_Ex + mov [suchlaenge],eax + mov esi,askreplace2 + mov ecx,replacetext + call InputString0 + jmp short GetOptions ;cy flag is allowed here 18.6.00 +AskForFind:mov esi,askfind + call InputString00 + jc AskFor_Ex +GetOptions:mov [repllaenge],eax + test byte [mode],WS|NE + jz GetOpt2 + mov esi,optiontext + call InputStringWithMessage ;empty string is allowd for std options... + call ParseOptions ;...(set in ParseOptions) +GetOpt2:clc +AskFor_Ex:jnc AFE2 + mov byte [bereitsges],0 +AFE2: pushf + call RestKursPos + popf + ret +;------- +; check string for 2 possible options: C,c,B,b (case sensitive & backward) +; +ParseOptions:push esi + cld + mov esi,optbuffer + push byte 1 + pop dword[vorwarts] ;mov dword[vorwarts],1 is longer + mov byte[grossklein],0dfh +Scan1: lodsb + and al,5fh ;upper case + cmp al,'C' + jnz notCopt + xor byte[grossklein],20h ;result 0dfh, 2*C is like not C option +notCopt:cmp al,'B' + jnz notBopt + neg dword[vorwarts] ;similar 2*B is backward twice i.e. forward +notBopt:or al,al + jnz Scan1 + pop esi + ret +;------- +; the find subroutine itself +; +find2: mov ebx,edi +find3: lodsb + or al,al ;=end? + jz found + cmp al,41h + jb find7 + and al,ch +find7: inc edi + mov cl,byte [edi] + cmp cl,41h + jb find10 + and cl,ch +find10: cmp al,cl + jz find3 + mov edi,ebx +FindText:mov ch,[grossklein] ;ff or df + mov esi,suchtext + cld + lodsb + cmp al,41h + jb find1 + and al,ch +find1: add edi,[vorwarts] ;+1 or -1 + mov cl,byte [edi] + cmp cl,41h + jb find6 + and cl,ch +find6: cmp al,cl + je find2 + cmp byte[mode],PI + jnz find_WS + cmp edi,ebp + jb foundEOF + mov edi,sot + cmp edi,[PicoSearch] + je notfound +foundEOF:jmp short find9 +find_WS:cmp edi,ebp + ja notfound +find9: cmp edi,sot + jnb find1 +notfound:stc + ret +found: mov edi,ebx + clc ;edi points after location + ret +;---------------------------------------------------------------------- +; +; some GENERAL helper functions +; +; +; Get.....ToInteger reads integer value from keyboard (only > 0) +; +GetOctalToInteger:push byte 7 ;octal base-1 + jmp short GATI2 +GetAsciiToInteger:push byte 9 ;decimal base-1 +GATI2: call IsViMode + jz ISVI8 + call InputStringWithMessage ;eax = al = length + call AskFor_Ex ;repair status line & set cursor pos / preserve flags +ISVI8: push byte 0 + pop esi ;preserve flags + pop ebx ;bl == base-1 + xchg ecx,esi + jc AIexit2 + cld +AIload: lodsb ;eax bit 8..31 are 0 + sub al,'0' + js AIexit + cmp al,bl + ja AIexit + cmp bl,7 ;if base==8 + je GATI3 + lea ecx,[ecx+4*ecx] + lea ecx,[2*ecx+eax] ;mul 10 plus digit + jmp short AIload +GATI3: lea ecx,[8*ecx+eax] ;mul 8 plus digit + jmp short AIload +AIexit: or ecx,ecx ;ret ecx +AIexit2:ret ;CY or ZR if error +;------- +; +; SpacesForTab expects current column in edx +; returns # spaces up to next tabulated location in AH +; +SpacesForTab:push ecx + mov eax,edx + mov cl,TAB + xor ah,ah + div cl + neg ah ;ah = modulo division + add ah,TAB ;TAB - pos % TAB + pop ecx + ret +;------- +; +; GetHelpText returns ecx==size of help text / esi==help text for current edit mode +; +GetHelpText: + mov esi,help_ne ;start with last text block... + mov ecx,help_ws_size +%ifdef USE_BUILTINHELP + mov eax,mode + cmp byte [eax],NE + jnz NoNe1 + mov ecx,help_ne_size + ret +NoNe1: sub esi,ecx ;...and sub block by block until we've found it + cmp byte [eax],VI + jz GHT + sub esi,ecx + cmp byte [eax],EM + jz GHT + sub esi,ecx + cmp byte [eax],PI + jz GHT + sub esi,ecx +%endif +GHT: ret +;------- +; +; Check whether user discarded his input +; +CheckUserAbort:mov esi,mode + cmp byte[esi],WS + jz CUAWS + cmp byte[esi],EM + jz CUAEM + cmp al,3 ;^C abort + ret +CUAWS: cmp al,15h ;^U abort + ret +CUAEM: cmp al,7 ;^G abort + ret +;------- +KeyEditMode: + mov esi,modetxt + call InputStringWithMessage ;empty string is allowd for std options... + call RestKursPos + mov esi,optbuffer + call InitSomeVars +;------- +SetEditMode:mov eax,mode ;returns Z flag if the mode was changed / NZ else + mov ecx,dword [esi] +%ifdef W32 + or ecx,020202020h ;convert to lower case +%endif + cmp ecx,'e3ne' + jnz NoNe + mov byte [eax],NE + ret +NoNe: cmp ecx,'e3em' + jnz NoEm + mov byte [eax],EM + ret +NoEm: cmp ecx,'e3pi' + jnz NoPi + mov byte [eax],PI + ret +NoPi: cmp ecx,'e3vi' + jnz NoVi + mov byte [eax],VI + ret +NoVi: cmp ecx,'e3ws' + jnz modeOK + mov byte [eax],WS +modeOK: ret +;----------------------------------------------------------------------- +; +; Oleg's suggestion / Sat Mar 16 17:58:06 +; +%ifdef USE_EXT_MOVE +KeyHome2:cmp byte[edi-1],NEWLINE + jz KCQPjmp + jmp KeyHome +;------- +KeyEnd2:cmp byte[edi],NEWLINE + jz KCQPjmp + jmp KeyEnd +;------- +KeyCtrlQR2:cmp edi,sot + jz KCQPjmp + jmp KeyCtrlQR +;------- +KeyCtrlQC2:cmp edi,ebp +KCQPjmp:jz near KeyCtrlQP + jmp KeyCtrlQC +%endif +;----------------------------------------------------------------------- +%ifdef SYS_kill +SigHandler:call RestKursPos + mov edi,screenbuffer ;make buffer invalid with something + mov ecx,screenbuffer_dwords ;this will force a complete screen redraw + cld + rep stosd +%endif +;------- cont +SetTermStruc: +%ifdef W32 + push dword STD_INPUT_HANDLE + call GetStdHandle + mov [hin],eax + push dword STD_OUTPUT_HANDLE + call GetStdHandle + mov [hout],eax + push byte ENABLE_WINDOW_INPUT ;equ 8 + push dword [hin] + call SetConsoleMode ;Do not use "jmp SetConsoleMode" here + ret +%else + mov ecx,TERMIOS_GET + call IOctlTerminal0 + mov esi,edx + mov edi,termios + mov edx,edi + push byte termios_struc_size ;prepare a copy of original settings + pop ecx + cld + rep movsb +;------- +%ifdef LINUX + mov byte [edx+termios_struc.c_cc+VMIN],1 ;set min=1 ->needed for gnome-terminal +%endif + and TSize [edx+termios_struc.c_lflag+0],(~ICANON & ~ISIG & ~ECHO) ;icanon off, isig (^C) off, echo off + and byte [edx+termios_struc.c_iflag+1],(~(IXON>>8) & ~(ICRNL>>8)) ;ixon off, icrnl off + mov ecx,TERMIOS_SET + jmp short IOctlTerminal ;edx is termios pointer +%endif +;---------------------------------------------------------------------- +; +; INTERFACE to OS kernel +; we differ between Linux, and and ... +; +%ifndef W32 +IOctlTerminal0:mov edx,termios_orig +IOctlTerminal:mov ebx,stdin ;expects EDX termios or winsize structure ptr +%ifdef LIBC + push edx + push ecx + push ebx + call ioctl + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_ioctl + jmp short IntCall ;ECX TCSETS,TCGETS,TIOCGWINSZ +%endif +%endif +;------ +ReadFile0: +%ifdef W32 + ;all API: + ;- direction flag is cleared before and after call + ;- preserves ebx,esi,edi,ebp + pusha + push dword 0xFFFFFFFF + push dword [hin] + call WaitForSingleObject + popa +%ifdef W32_EXTENDED_IO + push ecx ;destr + push edx ;destr + push dword w32result + push byte 1 + push ecx + push dword [hin] + call ReadConsoleInputA + pop edx + pop ecx +;------- + mov ebx,dword [ecx] + cmp bl,1 ;is it a key_event? + jnz ReadFile0 ;no, read new + mov ebx,dword [ecx+4] + cmp ebx,1 ;is it a keydown event? + jnz ReadFile0 ;no, read new + ;pusha + ;push dword [hin] + ;call FlushConsoleInputBuffer + ;popa +;------- + mov ebx,dword [ecx+8] ;virtual key code + shr ebx,16 +;------- + cmp ebx,dword VK_SPACE + jnz Normal0 + test dword [ecx+16],CTRL_PRESSED + jz Normal0 + mov dword[ecx],0FF00h ;return ascii 00 for EMACS ^SPACE key + ret +Normal0:cmp ebx,dword VK_DELETE + ja Normal1 + cmp ebx,dword VK_PRIOR + jb Normal1 +;------- + sub bl,VK_PRIOR ;found a cursor key + mov al,bl + mov ebx,ScanTable + xlatb ;translate to terminal value... + cmp al,DoNo ;...in results 0..9 +ReadF0: jz ReadFile0 + mov ah,0xFE ;marker for a pre-processed cursor key + mov [ecx],eax + ret +;------- +Normal1:mov ebx,dword [ecx+12] ;get ascii char value + shr ebx,16 + or bl,bl + jz ReadF0 ;no useful ascii char pressed + mov bh,0xFF + and dword [ecx+16],LEFT_ALT_PRESSED ;controlkeystate: left ALT key pressed + jz Normal2 + mov bh,0xFD ;marker for a pre-processed ALT key +Normal2:mov dword[ecx],ebx + ret +%else ;this way simple input via ReadFile + mov ebx,[hin] +%endif +%else + xor ebx,ebx ;mov ebx,stdin ;file desc +%endif +Read_File: +%ifdef W32 + push ecx ;destr + push edx ;destr + push byte 0 + push dword w32result + push edx ;length + push ecx ;buffer + push ebx ;handle + call ReadFile + pop edx + pop ecx +;------- + or eax,eax + jnz ReadFileOkay + call GetLastError + mov [errno],eax + neg eax + ret +ReadFileOkay: + mov eax,[w32result] + or eax,eax ;clear sign flag + ret +%else +%ifdef BEOS + push byte SYS_read ;4+X? stack places + jmp short WFile +%else +%ifdef LIBC + push edx + push ecx + push ebx + call read + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_read ;system call number (sys_read) ;return read byte EAX + jmp short IntCall ;ebx file / ecx buffer / edx count byte +%endif +%endif +%endif +;------- +WriteFile00:xor edx,edx + inc edx ;mov edx,1 write 1 byte +WriteFile0: +%ifdef W32 + mov ebx,[hout] +%else + xor ebx,ebx ;mov ebx,stdout ;file desc + inc ebx ;ditto +%endif +Write_File: +%ifdef W32 + push edx ;destr + push byte 0 + push dword w32result + push edx + push ecx ;buffer + push ebx ;handle + call WriteFile + pop edx + or eax,eax + jnz WriteFileOkay + call GetLastError + mov [errno],eax + neg eax + ret +WriteFileOkay: + mov eax,[w32result] + or eax,eax ;clr sign flag + ret +%else +%ifdef BEOS + push byte SYS_write +WFile: pop eax + call IntRdWr + nop + nop + nop + nop + ret +%else +%ifdef LIBC + push edx + push ecx + push ebx + call write + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_write + jmp short IntCall +%endif +%endif +%endif +;------- +OpenFile0: +%ifndef BEOS +%ifdef W32 + mov ecx,OPEN_EXISTING + mov edx,GENERIC_READ +%else + xor ecx,ecx ;i.e O_RDONLY +%endif +%endif +OpenFile: +%ifdef W32 + push byte 0 + push dword FILE_ATTRIBUTE_NORMAL + push ecx ;"CREATE_ALWAYS" or "OPEN_EXISTING" + push byte 0 + push byte 0 + push edx ;"GENERIC_WRITE" or "GENERIC_READ" + push ebx ;filename + call CreateFileA + cmp eax,INVALID_HANDLE_VALUE + jnz OpenFileOkay + call GetLastError + mov [errno],eax + neg eax +OpenFileOkay:ret +%else +%ifdef BEOS + mov al,SYS_open ;5 stack places + push edi + mov edi,0x1A4 + call IntCall + pop edi + ret +%else +%ifdef LIBC + push edx + push ecx + push ebx + call open + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_open + jmp short IntCall ;ecx mode / ebx path / edx permissions (if create) +%endif +%endif +%endif +;------- +CloseFile: +%ifdef W32 + push edx ;destr + push ecx ;destr + push ebx ;handle + call CloseHandle + pop ecx + pop edx + ret +%else +%ifdef LIBC + push edx ;destr + push ecx ;destr + push ebx + call close + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_close + jmp short IntCall ;ebx is file desc +%endif +%endif +;------- +%ifdef SYS_readlink +ReadLink:mov al,SYS_readlink + jmp short IntCall +%endif +;------- +%ifdef SYS_fstat +Fstat: mov ecx,fstatbuf +%ifdef LIBC + push ecx + push ebx + call fstat + pop ebx + pop ecx + or eax,eax + ret +%else + mov al,SYS_fstat + jmp short IntCall +%endif +;------- +ChownFile: +%ifdef LIBC + push edx + push ecx + push ebx + call fchown + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_fchown + jmp short IntCall +%endif +%endif ;endifdef SYS_fstat +;------- +RenameFile: +%ifdef W32 + push ebx ;destr + push ecx ;destr + push ecx ;for MoveFile + push ecx + call DeleteFileA + push ebx + call MoveFileA + pop ecx + pop ebx + or eax,eax + jnz RenameFileOkay + call GetLastError + mov [errno],eax + neg eax + ret +RenameFileOkay: + xor eax,eax + ret +%else +%ifdef LIBC + push ecx + push ebx + call rename + pop ebx + pop ecx + or eax,eax + ret +%else + mov al,SYS_rename + jmp short IntCall +%endif +%endif +;------- +%ifdef SYS_brk +SysBrk: mov al,SYS_brk + jmp short IntCall ;ebx addr +%endif +;------- +%ifndef W32 +Exit: xor ebx,ebx +Exit2: +%ifdef LIBC + push ebx + call _exit +%else + mov al,SYS_exit + jmp short IntCall +%endif +%endif +;------- +SeekFile:xor ecx,ecx ;ecx offset / ebx file / edx method +%ifdef W32 + push edx + push byte 0 + push ecx + push ebx + call SetFilePointer + cmp eax,0xFFFFFFFF + jnz SeekFileOkay + call GetLastError + mov [errno],eax + neg eax +SeekFileOkay:ret +%else +%ifdef BEOS + mov al,SYS_lseek ;4 stack places (using 64 bit for ptr) + push edi + push edx + mov edi,edx + xor edx,edx + call IntCall + pop edx + pop edi + ret +%else +%ifdef LIBC + push edx + push ecx + push ebx + call lseek + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else + mov al,SYS_lseek ;oldseek =32bit +%endif +%endif +%endif +;------- +%ifndef LIBC +%ifndef W32 +IntCall:mov ah,0 +IntCall2:cwde +%ifdef BEOS + push edi + push byte 0 + push edi + push edx + push ecx + push ebx + push dword be_ret + int 25h +be_ret: pop ebx + pop ebx + pop ecx + pop edx + pop edi + pop edi + mov [errno],eax + and dword [errno],7Fh + or eax,eax ;set flags also + pop edi +%else +%ifdef ATHEOS + int 80h + cmp eax,0xFFFFF001 + jae Fru + or eax,eax + ret +Fru: neg eax + mov [errno],eax + and dword [errno],7Fh + neg eax ;set flags also + ret +%else +%ifdef LINUX + int 80h +%else + push edi + push esi + push edx + push ecx + push ebx + push eax + int 80h + pop ebx + pop ebx + pop ecx + pop edx + pop esi + pop edi + jc err +%endif + neg eax +err: mov [errno],eax + neg eax ;set flags also +%endif +%endif + ret +%endif +%endif +;------- +%ifdef BEOS +IntRdWr:push edx ;used for Read & Write + push ecx + push ebx + push dword be_ret2 + int 25h +be_ret2:pop ebx + pop ebx + pop ecx + pop edx + mov [errno],eax + pop eax + lea eax,[eax+4] ;add eax,4 + push eax + mov eax,[errno] + and dword [errno],7Fh + or eax,eax ;set flags + ret +%endif +;-------------------------------------------------------------------------- +%ifdef SYS_select +%ifdef LIBC +Select: push dword timevalsec + xor ebx,ebx + push ebx + push ebx + mov ecx,readfds + push ecx + inc ebx + mov byte [ecx],bl + push ebx + call select + add esp,20 + or eax,eax + ret +%else +Select: xor ebx,ebx + inc ebx + mov ecx,readfds + mov byte [ecx],bl + xor edx,edx + xor esi,esi + mov edi,timevalsec ;points to [0 sec / 0 usec] + mov al,SYS_select + jmp short IntCall +%endif +%endif +;----------------------------------------------------------------------- +%ifdef SYS_readlink +Utime: mov al,SYS_utime + jmp short IntCall +%endif +;------- +%ifdef USE_PIPE +Fork: mov al,SYS_fork + jmp short IntCall +;------- +Pipe: mov al,SYS_pipe + jmp short IntCall +;------- +Dup2: mov al,SYS_dup2 + jmp short IntCall +;------- +Execve: mov al,SYS_execve + jmp short IntCall +;------- +Wait4: mov al,SYS_wait4 ;set ecx to buffer! + xor ebx,ebx + dec ebx + xor edx,edx + xor esi,esi + jmp short IntCall +;------- +%endif +Unlink: +%ifdef W32 + push edx + push ecx + push ebx + call DeleteFileA + pop ebx + pop ecx + pop edx + ret +%else +%ifdef LIBC + push edx + push ecx + push ebx + call unlink + pop ebx + pop ecx + pop edx + or eax,eax + ret +%else +%ifdef BEOS + mov ecx,ebx +%endif + mov al,SYS_unlink + jmp short IntCall ;ebx is file desc +%endif +%endif +;---------------------------------------------------------------------- +%ifdef SYS_kill +KeySuspend:call KursorStatusLine ;simply looks better so + push byte SIGSTOP + pop ecx + xor ebx,ebx +Kill: mov al,SYS_kill +ICjmp: jmp short IntCall +;------- +SetSigHandler: + push byte SIGCONT + pop ebx + xor edx,edx + mov ecx,sigaction + mov [ecx],dword SigHandler +Sigaction:mov al,SYS_sigaction + jmp short ICjmp +%endif +;----------------------------------------------------------------------- +; +; pipe buffer through child process +; +%ifdef USE_PIPE +KeyCtrlKP:call InputStringWithMessage0 ;WS, Emacs's, Pico's access to sed|ex pipe + pushf + call RestKursPos + popf + jc ExExEx +KeyVICmdtemp:call CheckENum ;i.e. mov byte [numeriere],1 + pusha + mov ebx,tempfile + mov esi,sot + mov [blockende],ebp + call SaveBl3 + popa + jnc SaveOK +ExExEx: ret ;cannot save buffer to tmp file... +SaveOK: ;...this is handled inside SaveBlock, so just return +%ifdef USE_UNDO + xor eax,eax + dec eax + call DataForUndoDelete +%endif +%ifdef CAPTURE_STDERR + mov ebx,sedpipeC0 + call Pipe + js OSerrJmp0 +%endif + mov ebx,sedpipeB0 + call Pipe + js OSerrJmp0 +%ifdef FREEBSD + mov [sedpipeB0],eax ;this seems to work, although... + inc eax ;...I don't know why....? + inc eax ;Someone can explain? + mov [sedpipeB1],eax +%endif + call Fork + js OSerrJmp0 + or eax,eax + jz near ForkChild +;------- +%ifdef USE_EX_NO_SED +; +; This is the UNDEFAULT way using "ex -s" (silent ex). +; We save the buffer into a tempfile and +; WRITE the COMMAND (followed by 'wq' command) +; into a pipe to ex's STDIN. +; Then we truncate the current edit buffer +; and read the tempfile just like a WS block. +; +; "Anything you want, you got it" +; "Anything you need, you got it" +; "Anything at all, you got it, Baby ...." (Jeff Lynne/Roy Orbison/Tom Petty 1989) +; + mov ebx,[ebx] ;i.e. sedpipeB0 + call CloseFile ;unused pipe direction READ +OSerrJmp0:js OSerrJmp1 + mov ebx,[sedpipeB1] +;------- + xor edx,edx + mov ecx,optbuffer + mov esi,ecx + cld + dec edx +Bufloop:inc edx + lodsb + or al,al + jnz Bufloop ;count ex cmd length + call WriteFile ;write to ex program +;------- + mov ecx,wq_suffix + mov edx,wq_suffix_len + call WriteFile ;write "wq" string to ex program + call CloseFile +OSerrJmp1:js OSerrJmp + mov ecx,optbuffer ;for return status + push edi + call Wait4 + pop edi + js OSerrJmp + mov ecx,[ecx] ;getting return status + shr ecx,8 + and ecx,0xFF + mov [errno],ecx + jnz OSerrJmp +;------- + mov ebx,tempfile + push ebp + push edi + mov edi,sot ;truncate old file + mov ebp,sot + mov al,LINEFEED + xchg byte [ebp],al ;EOF marker + push eax + call ReadBlock2 + pop eax + pop edi + jc preEx_Ex + pop ebx ;dummy (not restore ebp) +;------- + mov ebx,tempfile + call Unlink + jns ChkCursPos ;if no Error +;------- +OSerrJmp:call ChkCursPos ;Error in Wait,Close,... + jmp near OSerror ;TODO: unlink helper file if exists +preEx_Ex:pop ebp ;Error in ReadBlock + mov byte[sot],al ;restore pre op values if Read Error + ;continue ChkCursPos +; +%else ;------------------ DEFAULT WAY ------------------- +; +; This is the DEFAULT way using stream editor "sed -e". +; The default way is quite opposite: we save the buffer +; into a tempfile, then call sed with the operational command +; given on sed's command line and at last we READ the DATA +; from sed's output via a STDIN READ pipe. +; + push ebx + mov ebx,[ebx+4] ;i.e. sedpipeB1 + call CloseFile ;unused pipe direction +%ifdef CAPTURE_STDERR + mov ebx,[sedpipeC1] + call CloseFile ;unused pipe direction +%endif +OSerrJmp0:js OSerrJmp1 + pop ebx + mov esi,[maxlen] + mov ebx,[ebx] ;pipe read channel + mov ecx,sot-SEDBLOCK + add esi,ecx + push ebp + mov ebp,sot + xor eax,eax + call InitSV1 ;forbid any side efects +ReadPipe:mov edx,SEDBLOCK + add ecx,edx + call Read_File + add ebp,eax ;compute eof + cmp ebp,esi + jae ReadOK ;sorry, truncating. FIXME: add a message + cmp eax,edx + jz ReadPipe + cmp ebp,sot ;if nothing comes back, keep buffer as is + jnz ReadOK + pop edx + mov ebp,edx + push esi ;keep stack balanced +ReadOK: mov byte [ebp],NEWLINE ;EOF marker + pop esi ;dummy + call CloseFile +OSerrJmp1:js OSerrJmp +%ifdef CAPTURE_STDERR + mov ebx,[sedpipeC0] +%ifdef BEEP_IN_VI + mov ecx,buffercopy + xor edx,edx + inc edx + call Read_File + or eax,eax + je NoStdErrMsg + call VIBeepForD +%endif +NoStdErrMsg:call CloseFile ;stderr pipe +%endif + call SetChg ;i.e. mov byte [changed],CHANGED (assumption only) + mov ecx,optbuffer ;for return status + push edi + call Wait4 + pop edi + js OSerrJmp + mov ebx,tempfile + call Unlink + js OSerrJmp + movzx ecx,byte[ecx+1] ;old shr ecx,8 / and ecx,0xFF + mov [errno],ecx + jecxz ChkCursPos +OSerrJmp:call ChkCursPos ;TODO: unlink helper file if exists + jmp near OSerror +%endif +;---------------------------------------------------------------------- +ForkChild:mov ebx,[ebx] ;i.e. sedpipeB0 + xor ecx,ecx +%ifdef USE_EX_NO_SED + call Dup2 ;capturing STDIN + js FCError + mov ebx,[sedpipeB1] + call CloseFile ;unused pipe direction STDOUT + js FCError + mov ebx,expath + mov ecx,exargs +%else + call CloseFile ;unused pipe direction STDIN + js FCError + mov ebx,[sedpipeB1] + inc ecx + call Dup2 ;capturing STDOUT + js FCError +%ifdef CAPTURE_STDERR + mov ebx,[sedpipeC0] + call CloseFile ;unused pipe direction + inc ecx + mov ebx,[sedpipeC1] + call Dup2 ;capturing STDERR + js FCError +%endif + mov ebx,sedpath + mov ecx,sedargs +%endif + xor edx,edx ;no env + call Execve + push byte ERRNOEXEC + pop ebx ;set error +FCex: jmp near Exit2 ;in case of error +FCError:mov ebx,[errno] + jmp short FCex +%endif ;USE_PIPE +;---------------------------------------------------------------------- +; +; care about cursor pos +; +ChkCursPos:cmp edi,ebp ;never let run cursor outside buffer + jbe CCP + mov edi,ebp +CCP: cmp edi,sot + jae CCP2 + mov edi,sot +CCP2: ret +;---------------------------------------------------------------------- +; +; copy file to a real backup file (for sym linked files only) +; +; expecting ebx==filepath +; ecx==bakpath +; +%ifdef SYS_readlink +CopyToBackup:pusha + push ecx ;backup file path later needed for Utime call + push ecx + call OpenFile0 + xchg esi,eax ;save handle to copy of original file + mov ecx,O_WRONLY_CREAT_TRUNC + mov edx,[perms] + pop ebx ;handle to backupfile + call OpenFile + xchg ebx,eax + mov ecx,[fstatbuf+stat_struc.st_uid] +%ifdef UIDGID_WORD ;Linux special + mov edx,ecx + shr edx,16 + movzx ecx,cx ;OLD and ecx,0xffff +%else + mov edx,[fstatbuf+stat_struc.st_gid] +%endif + call ChownFile +;------- + xor edi,edi ;init eof indicator +copylop:push ebx + mov ebx,esi ;saved orig file handle + mov ecx,screenbuffer ;used as copy buffer + mov edx,4096 + call Read_File + pop ebx ;backup file handle + ;js... + cmp eax,edx + jz notready + inc edi ;eof found +notready:mov ecx,screenbuffer + mov edx,eax ;write read count of byte + call Write_File + ;js... + or edi,edi ;eof ? + jz copylop +;------- + call CloseFile ;ready: close backup file + mov ebx,esi + call CloseFile ;close original file + pop ebx ;original file path + mov ecx,accesstime ;i.e. a data structure of 2* 32 bit + call Utime ;set change time + popa + ret +%endif +;---------------------------------------------------------------------- +; recursive descent parser for very SIMPLE math calc within the text: +; 1234+56*78= +; place cursor ^<--here and press ^KN ^QC ^XN # ^K +; (for one of WS PI EM VI NE modes) +; this should insert the result of 5602 into text. +; +; Use values +-0, 0.000001 ,... up to 999999999999.999999 +; and + - * / +; and ( ) +; and r (for using the last result in next calculation) +; and p =3.141593 +; +KeyCtrlKN: +%ifdef USE_MATH + cld ;preserve ebp,edi! + fninit + mov esi,edi + mov [stackptr],esp + xor eax,eax + mov [level],eax + mov [ptlevel],eax + call Recurs0 + fnstsw [x87] + and byte[x87],1Fh ;any exception flags? +GErr: jnz near isErr + dec dword[level] ;stack balanced? + jnz GErr + xor eax,eax + cmp eax,[ptlevel] ;all parenthesis closed? + jnz GErr +NoAllgFehl:dec esi + mov edi,esi ;up to here we have read + lodsb + cmp al,'=' + jz EquChar + mov al,'=' + call OutChar + dec edi +EquChar:inc edi + fst qword[lastresult87] ;carry last result for further calc + fld qword[factor] + fmulp st1 + fbstp [x87] + push byte 12 ;12 digits + pop ecx + xor dh,dh ;flag for suppressing leading 0 + lea esi,[x87+9] ;9 BCD data byte and sign + std + lodsb + or al,al + jns plus + cmp al,0x80 + jnz GErr + mov al,'-' + call OutChar +plus: call OutHlp + or dh,dh + jnz dec_dig + mov al,'0' + call OutChar +;------- +dec_dig:mov esi,x87 + xor ebx,ebx + push byte 3 + pop ecx + cld +dlop: lodsb + mov dl,al + and al,0fh + jnz nonull + inc ebx + mov al,dl + shr al,4 + jnz nonull + inc ebx +isnul2: loop dlop + ret ;no decimal digits: ready +;------- +nonull: push byte 6 ;6 decimal digits + pop ecx + sub ecx,ebx + mov dh,0xff ;now do not suppress 0 + mov al,'.' + call OutChar + lea esi,[x87+2] ;decimal digits pos +OutHlp: std + lodsb + mov dl,al + shr al,4 + call OutNumber + dec ecx + jecxz xret + mov al,dl + and al,0fh + call OutNumber + loop OutHlp +xret: ret +;------- +Recurs0:mov al,'+' +RecursPars:push eax ;op code + mov byte[signctl],0 ;last token was an opcode +RecConti:lodsb + cmp al,LINEFEED ;EOL? + jz short RRR ;jz RecReturn + cmp al,')' + jz short RRet2 + cmp al,'=' ;end of task? +RRR: jz short RecReturn + cmp al,'!' ;white space? + jb short RecConti + cmp byte[signctl],0 ;last was opcode? + jnz short CheckNP ;sign is allowed after opcode only + cmp al,'+' + jz short rPlus + cmp al,'-' + jnz short CheckNP + inc byte[signctl] ;2 for minus +rPlus: inc byte[signctl] ;1 for plus + jmp short RecConti ;continue + +CheckNP:push dword [signctl] ;we need that for numbers and parenthesis + cmp al,'(' + jnz short CheckNum + inc dword[ptlevel] ;increase nesting level + call Recurs0 ;compute term instead of parse number + jmp short fromP +CheckNum:cmp al,'0' + jb short noNumber + cmp al,'r' ;last Result + jz short isLastRes + cmp al,'p' ;pi 3.141593 + jz short isPi + cmp al,'9' + ja short isErr2 + call Number +fromP: pop eax ;signctl on stack + cmp al,2 + jnz short isPlus + FCHS ;parenthesis or number is negative +isPlus: mov byte[signctl],1 ;last token was a number (or parenthesis) + mov al,[esp] ;our opcode + cmp al,'+' + jz short RecConti + cmp al,'-' + jnz short RecReturn + mov byte[esp],'+' ;adding negative value + FCHS +RecCon2:jmp short RecConti +;------- +RRet2: dec dword[ptlevel] +RecReturn:pop eax + ret +;------- +isLastRes:fld qword[lastresult87] + jmp short isPi2 +isPi: fldpi +isPi2: inc dword[level] + jmp short fromP +isErr2: jmp short isErr +;------- +noNumber:pop ecx ;due above "push dword [signctl]" (we don't need it here) + lea esp,[esp-16] + fstp dword [esp] + call RecursPars + fld dword [esp] + lea esp,[esp+16] + dec dword[level] + cmp al,'*' + jnz noMul + FMULP st1 + jmp short RecCon2 +noMul: cmp al,'/' + jnz noDiv + FDIVRP st1 + jmp short RecCon2 +noDiv: cmp al,'+' + jnz isErr ;not one of * / + + FADDP st1 + jmp short RecReturn +;------- +Number: FLDZ + FBSTP [x87] ;init buffer + push byte 12 ;read 13 chars (up to 12 digits) + pop ecx +num_ctr:call DigitHlp + jc int_end + loop num_ctr ;error if >12 digits +isErr: mov esp,[stackptr] ;restore stack pos for math calc +%endif ;USE_MATH +%ifdef BEEP_IN_VI +VIBeepForD:pusha +%ifdef W32 + push byte 0 + call MessageBeep +%else + mov ecx,BeepChar + call WriteFile00 +%endif + popa +%endif + ret +;------- +%ifdef USE_MATH +int_end:push edi ;**** + neg ecx + lea ecx,[ecx+13] + push ecx ;stor # of integer digits + inc dword[level] + dec esi ;num_ctr loop has read 1 too much + mov edx,esi ;position we have read so far + cmp al,('.'-'0') + jnz integers + inc esi + lea edi,[x87+2] ;start of decimal places + mov cl,3 ;6/2 decimal places +dec_ctr:cld + call DigitHlp + jc decend + shl al,4 + mov bl,al + mov [edi],al ;important if abort at digit 1,3,5 + call DigitHlp + jc decend + add al,bl + std + stosb + loop dec_ctr ;if >6 decimal places it will run into error later + inc esi +decend: dec esi + xchg edx,esi ;edx where later to continue scanning +;------- +integers:pop ecx ;ecx # of integer digits + dec esi ;esi where integer places are + lea edi,[x87+3] ;start of integer part +intloop:std + lodsb + sub al,'0' + mov bl,al + dec ecx + jecxz h2 + lodsb + sub al,'0' + shl al,4 + add al,bl +h2: cld + stosb + jecxz h3 + loop intloop +h3: FBLD [x87] + FLD qword [factor] + fdivp st1 + mov esi,edx ;pointer for continued reading + pop edi ;**** + ret +;------- +DigitHlp:lodsb + sub al,'0' + jb dret + cmp al,10 + cmc +dret: ret ;return: al=value / cy if error +;------- +OutNumber:cmp al,dh ;flag set? + jz OCret + add al,'0' + mov dh,0xff ;set flag +OutChar:push esi + push edx + push ecx + call NormChar + pop ecx + pop edx + pop esi + inc ebx +%endif +OCret: ret +;---------------------------------------------------------------------- +%ifdef USE_UNDO +%define ROLLBACK +%undef ROLLBACK +; Undo is organized in frames on a ringbuffer stack +; +; FRAME_AAAAprevFRAME_BBBBprevCURRENT_EMPTY_FRAME +; ^ v ^ v v +; | | | | | +; \-------/ \--------/| | +; | v +; v [undoptr] == next free frame +; [undoptr]-4 == begin of previous frame +; +; there are 3 types of frames: DELETE,INSERT,OVERWRITE, see details below: +; +DataForUndoDelete: +; +; Data collector for "delete" by PUSHING undo data into a frame on the undo stack, +; growing to higher addresses, using a variable size (16+X byte) data structure: +; +; |12345679|--WHERE-|--SIZE--|<data>....X |PREV-PTR|--NEXT--| ...... +; | =sign | =edi | =eax | | | | +; | | | | | | | +; | edx+0 | edx+4 | edx+8 | edx+12 |edx+16+X|edx+20+X| <----- ADDRESSES +; ^^^^^^^^ +; NEXT_undo_frame_address stored in [undoptr] +; If the data size is > undobuffer size we have to +; save the data otherwise, i.e. in a file: +; |1234567B|--WHERE-|--SIZE--|<PREV-PTR|--NEXT--| ...... +; | =sign | =edi | =eax | | | +; | | | | | | +; | edx+0 | edx+4 | edx+8 | edx+12 |edx+16 | <----- ADDRESSES +; + cmp byte [enter_undo],1 ;do not collect undo data if within undo operation + jz OCret + cmp eax,undobuffer_size-24 + pusha + jb DFok +;------- + pusha + mov ebx,[last_undo_file] + or ebx,ebx + jz noundo_info + cmp dword [ebx],0x01234567B + jnz noundo_info + mov dword [ebx],0 ;only ONE external undo info allowed, thus destroy older +noundo_info:mov esi,sot ;i.e. huge undo data + mov [blockende],ebp + mov ebx,tempfile2 + call SaveBl3 + popa +;------- + call InitUndoFrame0 + mov dword [edx],0x01234567B ;2nd signature for "delete" + mov [last_undo_file],edx + mov eax,ebp + sub eax,sot ;ebp -sot == size of buffer + jmp short OVWdata +;------- +DFok: ;i.e. small undo data + mov ecx,eax ;extra data size / size of copy + call InitUndoFrame + mov dword [edx],0x012345679 ;signature for "delete", later undo will insert data again + mov [edx+4],edi ;where + mov [edx+8],eax ;how much + mov esi,edi ;source is inside editor text buffer + lea edi,[edx+12] ;destination of copy + cld + rep movsb + mov eax,[undoptr] ;this frame... + mov [edi],eax ;... is the prev frame for the next one + lea eax,[edi+4] ;eax: now the new frame address + jmp short DFex +;------- +DataForUndoOverwrite: +; +; Data collector for "overwrite" by PUSHING data on a stack, +; growing to higher addresses, using a data structure like in DataForUndoInsert +; + pusha + call InitUndoFrame0 + mov dword [edx],0x01234567A ;signature for "overwrite", later undo will restore + mov eax,[edi] ;fetch overwritten char + jmp short OVWdata +;------ +DataForUndoInsert: +; +; Data collector for "insert" by PUSHING data on a stack, +; growing to higher addresses, using a fixed size (16 byte) data structure: +; +; |12345678|--WHERE-|--SIZE--|PREV-PTR|--NEXT--| ......... +; | =sign | =edi | =eax | | | +; | | | | | | +; | edx+0 | edx+4 | edx+8 | edx+12 |edx+16 |edx+20 <----- ADDRESSES +; ^^^^^^^^ +; NEXT_undo_frame_address stored in [undoptr] +; +; An analogue data structure is used for DataForUndoOverwrite: +; |1234567A|--WHERE-|--CHAR--|PREV-PTR|--NEXT--| ......... +; +; + cmp byte [enter_undo],1 ;do not collect undo data if within undo operation + jz DFUI + pusha + call InitUndoFrame0 + mov dword [edx],0x012345678 ;signature for "insert", later undo will delete that data +OVWdata:mov [edx+4],edi ;where + mov [edx+8],eax ;how much chars (or the character itself) + mov [edx+12],edx ;this frame is the prev frame for the next one + lea eax,[edx+16] ;address of next frame +DFex: mov [undoptr],eax ;let undoptr point to next frame + popa +DFUI: ret +;---------------------------------------------------------------------- +; +; this subroutine is bound to one of the keys like ^KU and +; will POP any UNDO data from the undo stack using 3 types of undo frames +; +KeyUndo:mov byte [enter_undo],1 ;do not log dele/insert when in undo mode + mov ebx,edi ;for case of error + mov edx,[undoptr] + mov edx,[edx-4] ;get begin of previos frame + or edx,edx + jz NotAv ;no date available + xor ecx,ecx ;read signature into ecx and destroy sign + xchg ecx,[edx] ;(destroying is neccessary because it's a ring buffer) + mov eax,[edx+8] ;data size or character itself + mov edi,[edx+4] ;position + sub ecx,0x12345678 + jz UndoOfInsert + dec ecx + jz UndoOfDelete + dec ecx + jz UndoOfOverwrite + dec ecx + jz ReReadBuffer +NotAv: mov edi,ebx ;abort UNDO: no valid signature found +%ifdef ROLLBACK + xor edx,edx +%endif + jmp short KUret +;------- +UndoOfDelete:lea esi,[edx+12] ;source ptr for deleted <data> + push esi + call InsertByte ;get some space..... + pop esi ;source ptr (somewhere inside UNDO frame) + call MoveBlock ;....and move <data> back into text + jmp short KUexit +;------- +UndoOfOverwrite:mov byte [edi],al + jmp short KUexit +;------- +UndoOfInsert:call DeleteByte + jmp short KUexit +;------- +ReReadBuffer:lea ebp,[eax+sot] ;compute eof pointer + push eax ;size + mov ebx,tempfile2 + call OpenFile0 + pop edx ;size + js KUexit + xchg ebx,eax ;file handle + mov ecx,sot + call Read_File + js KUexit + call CloseFile + mov ebx,tempfile2 + call Unlink +;------- +KUexit: mov edx,[undoptr] ;switch to undo frame before (i.e. POP) + mov edx,[edx-4] ;the prev frame.... + mov [undoptr],edx ;...is now current frame +KUret: mov byte [enter_undo],0 ;leave UNDO status +KUjmp: jmp CheckENum ;renumbering because we have changed the cursor position +;------- +%ifdef ROLLBACK +RollBack:call KeyUndo + or edx,edx + jnz RollBack + jmp short KUjmp +%endif +;---------------------------------------------------------------------- +; +; This inits the frame data pointer into edx. +; If there is not enough space we will wrap around to buffer begin and adjust [undoptr]: +; +;BEFORE WRAP: +;|******any_frame**********any_frame********any_frame*******PREV-PTR---------------| buffer_end +; <---too less---> +; ^^^^^^^^^ +; [undoptr] +;NOW AFTER WRAP: +;|PREV-PTR<-space_for_new_frame->ame********any_frame*******PREV-PTR---------------| buffer_end +; ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^ +; [undoptr] invalid last ok frame +; frame part +; +InitUndoFrame0:xor ecx,ecx ;no extra data +InitUndoFrame:mov edx,[undoptr] ;get current frame + mov esi,undobuffer_end-24 + sub esi,ecx ;extra data if exist + cmp edx,esi ;low memory? + jb IUFret ;leave if far away from buffer end +;------- + mov ebx,[edx-4] ;fetch PREV-PTR frame address @[undoptr-4] + mov edx,undobuffer ;wrap around: now BACK AT BUFFER BEGIN... + mov [edx],ebx ;store prev data frame pointer just before new frame + lea edx,[edx+4] ;=new frame begins here at undobuffer+4 + mov [undoptr],edx +IUFret: ret +%endif +;---------------------------------------------------------------------- +; +; CONSTANT DATA AREA +; +factor dq 1000000.0 +tempfile2 db 'e3##',0 ;tempfile (FIXME: use PID for name) +%ifdef USE_PIPE +tempfile db 'e3$$',0 ;tempfile (FIXME: use PID for name) +%ifdef USE_EX_NO_SED +exargs dd expath + dd minus_s + dd tempfile + dd 0 +expath db EX_PATH,0 +minus_s db '-s',0 +wq_suffix db LINEFEED,'wq',LINEFEED +wq_suffix_len equ $-wq_suffix +%else +sedargs dd sedpath ;this way default + dd minus_e + dd optbuffer + dd tempfile + dd 0 +sedpath db SEDPATH,0 +%ifndef PERLPIPE +minus_e db '-e',0 +%else +minus_e db '-pe',0 +%endif +; +%endif +%endif +; +optiontext db 'OPT? C/B',0 +filename db 'FILENAME:',0 +block db ' NAME:',0 +saveas db 'SAVE AS:',0 +filesave db ' SAVE:',0 +asksave db 'SAVE? Ynl',0 +asksave2 db 'SAVE? Yn',0 +askreplace1 db 'REPLACE:',0 +askreplace2 db 'RE WITH:',0 +asklineno db 'GO LINE:',0 +askfind db ' SEARCH:',0 +asknumber db '^Q OCTAL:',0 +extext db 'mode EX:',0 +modetxt db 'SET MODE',0 +%define DoNo 10 + +ScanTable: ;another xlat table containing offsets in jumptab1 table +%ifdef W32 + db 2 ;VK_PRIOR = Scan 21h (pgup) + db 7 ;VK_NEXT = Scan 22h (pgdn) + db 5 ;(end) + db 0 ;(home) + db 3 ;(left) + db 1 ;(up) + db 4 ;(right) + db 6 ;(dn) + db DoNo ;29h ignored + db DoNo ;2ah ditto + db DoNo ;2bh ditto + db DoNo ;2ch ditto + db 8 ;VK_INSERT = Scan 2dh (insert) + db 9 ;VK_DELETE = Scan 2eh (del) +%else + db DoNo ; esc[0~ + db 0 ;keyHome esc[1~ + db 8 ;keyIns esc[2~ + db 9 ;keyDel esc[3~ + db 5 ;keyEnd esc[4~ + db 2 ;keyPgUp esc[5~ + db 7 ;KeyPDn esc[6~ + db 0 ;keyHome esc[7~ + db 5 ;keyEnd esc[8~ + ;--------------------- +%ifdef QNX + db 8 ;keyIns esc[@ +%endif + db 1 ;keyUp esc[A + db 6 ;keyDown esc[B + db 4 ;keyRight esc[C + db 3 ;keyLeft esc[D + db DoNo ; esc[E + db 5 ;keyEnd esc[F + db 7 ;keyPgDn esc[G + db 0 ;keyHome esc[H +%ifndef LINUX + db 2 ;keyPUp esc[I + db DoNo ; esc[J + db DoNo ; esc[K + db 8 ;keyIns esc[L +%endif +%ifdef QNX + db DoNo ; esc[M + db DoNo ; esc[M + db DoNo ; esc[O + db 9 ; esc[P + db DoNo ; esc[Q + db DoNo ; esc[R + db DoNo ; esc[S + db DoNo ; esc[T + db 7 ; esc[U + db 2 ; esc[V + db DoNo ; esc[W + db DoNo ; esc[X + db 5 ; esc[Y +%endif +STsize equ ($-ScanTable) +%endif +;---------------------------------------------------------------------- +EmaAltTable: ;another xlat table containing offsets in jumptab1 table + db 12h ;'B' + db DoNo ;'C' + db DoNo ;'D' + db DoNo ;'E' + db 13h ;'F' + db 11h ;'G' + db 3Dh ;'H' Help! + db DoNo ;'I' + db DoNo ;'J' + db DoNo ;'K' + db DoNo ;'L' + db DoNo ;'M' + db DoNo ;'N' + db DoNo ;'O' + db DoNo ;'P' + db DoNo ;'Q' + db DoNo ;'R' + db DoNo ;'S' + db DoNo ;'T' + db DoNo ;'U' + db 2 ;'V' + db 27h ;'W' + db 3Eh ;'X' +ATsize equ ($-EmaAltTable) +;---------------------------------------------------------------------- +%define Beep 0x4E +VIcmdTable:db Beep;0 + db Beep ;1 + db 2 ;^B PageUp + db Beep ;3 + db 36h ;^D half PageUp + db Beep ;5 + db 7 ;^F PageDn + db Beep ;7 + db 3 ;^H KeyLeft + db Beep ;9 + db 6 ;^J KeyDown + db Beep ;11 + db Beep ;12 + db 6 ;^M KeyDown + db Beep ;^N + db Beep ;^O + db Beep ;^P + db Beep ;^Q + db Beep ;^R + db Beep ;^S + db Beep ;^T + db 37h ;^U + db Beep ;22 + db Beep ;23 + db Beep ;24 + db Beep ;25 + db 51h ;^Z + db Beep ;27 + db Beep ;28 + db Beep ;29 + db Beep ;30 + db Beep ;31 + db 4 ;' ' KeyRight + db Beep ;33 + db Beep ;34 + db 4fH ;35 Numerics + db 5 ;'$' KeyEnd + db Beep ;37 + db Beep ;38 + db 50h ; ' + db Beep ;40 + db Beep ;41 + db Beep ;42 + db 6 ;'+' KeyDown + db Beep ;44 + db 1 ;'-' KeyUp + db Beep ;46 + db 39h ;'/' Search + db 0 ;'0' KeyHome + db 44h ;'1' 1G BOF + db Beep ;'2' + db Beep ;'3' + db Beep ;'4' + db Beep ;'5' + db Beep ;'6' + db Beep ;'7' + db Beep ;'8' + db Beep ;'9' + db 2Ch ;':' ex mode + db 3Eh ;';' e3 special command: QUICK leave vi mode :-) press e3ws, e3em, e3pi, e3ne + db Beep ;'<' + db Beep ;'=' + db Beep ;'>' + db 3Ah ;'?' search backw + db Beep ;'@' + db 2Eh ;'A' + db 12h ;'B' left word + db 4Bh ;'C' Change rest of line + db 4Ch ;'D' Delete rest of line (not unlike ^QY in WStar) + db Beep ;'E' + db Beep ;'F' + db 0Fh ;'G' EOF + db 30h ;'H' First LIne + db 33h ;'I' switch to insert mode + db 4Dh ;'J' Join lines + db Beep ;'K' + db 31h ;'L' Last Line + db 52h ;'M' + db Beep ;'N' + db 32h ;'O' Open Line + db 3Ch ;'P' Paste + db Beep ;'Q' + db 34h ;'R' overwrite + db 40h ;'S' kill +insmode + db Beep ;'T' + db Beep ;'U' + db Beep ;'V' + db 13h ;'W' next word + db 3fh ;'X' del left + db Beep ;'Y' + db 41h ;'Z' + db Beep ;'[' + db Beep ;'\' + db Beep ;']' + db 38h ;'^' KeyFirstChar + db Beep ;'_' + db Beep ;'`' + db 2Dh ;'a' append (KeyLeft plus insert mode) + db 12h ;'b' left word + db Beep ;'c' + db 35h ;'d' delete + db 43h ;'e' + db Beep ;'f' + db Beep ;'g' + db 3 ;'h' KeyLeft + db 2Bh ;'i' switch to insert mode + db 6 ;'j' KeyDown + db 1 ;'k' KeyUp + db 4 ;'l' KeyRight + db 45h ;'m' set the one and only marker 'a' + db Beep ;'n' + db 2Fh ;'o' Open Line + db 3Bh ;'p' Paste + db Beep ;'q' + db 4Ah ;'r' repl one char + db Beep ;'s' + db Beep ;'t' +%ifdef USE_UNDO + db 53h ;'u' UNDO, experimental +%else + db Beep ;'u' +%endif + db Beep ;'v' + db 13h ;'w' next word + db 9 ;'x' KeyDel + db 46h ;'y' + db 42h ;'z' center line z. +VIsize equ ($-VIcmdTable) +;---------------------------------------------------------------------- +Ktable db DoNo ;^K@ xlatb table for making pseudo-scancode + db DoNo ;^ka + db 24h ;^kb 24h for example points to KeyCtrlKB function offset + db 15h ;^kc + db 0dh ;^kd + db DoNo ;^ke DoNo means SimpleRet i.e. 'do nothing' + db DoNo ;^kf + db DoNo ;^kg + db 1dh ;^kh + db DoNo ;^ki + db DoNo ;^kj + db 14h ;^kk + db DoNo ;^kl + db 3eh ;^km Set Mode + db 4FH ;^kn + db DoNo ;^ko + db 48h ;^kp Pipe thru sed + db 0bh ;^kq + db 10h ;^kr + db 0ch ;^ks + db DoNo ;^kt + db DoNo ;^ku + db 23h ;^kv + db 25h ;^kw + db 16h ;^kx + db 19h ;^ky + db 51h ;^kz ^KZ suspend (like in joe editor) +Ktable_size equ $-Ktable +Qtable db DoNo ;^q@ ditto for ^Q menu + db 1ah ;^qa + db 20h ;^qb + db 0fh ;^qc + db 05h ;^qd + db 1eh ;^qe + db 1bh ;^qf + db DoNo ;^qg + db 17h ;^qh, ^qDEL + db 11h ;^qi + db DoNo ;^qj + db 21h ;^qk + db DoNo ;^ql + db DoNo ;^qm + db DoNo ;^qn + db DoNo ;^qo + db 18h ;^qp + db DoNo ;^qq + db 0eh ;^qr + db 00h ;^qs + db DoNo ;^qt + db DoNo ;^qu + db 1ch ;^qv + db 12h ;^qw + db 1fh ;^qx + db 22h ;^qy + db 13h ;^qz +;---------------------------------------------------------------------- +Xtable db DoNo ;^x^@ + db DoNo ;^x^a + db DoNo ;^x^b + db 0bh ;^x^c WS: ^KQ + db DoNo ;^x^d + db DoNo ;^x^e + db 47h ;^x^f + db DoNo ;^x^g + db 3Dh ;^x^h i.e. "HELP!" (The Beatles, 1965) ;-) + db 10h ;^x i WS: ^KR + db DoNo ;^x^j + db DoNo ;^x^k + db DoNo ;^x^l + db DoNo ;^x^m + db 4fh ;^x^n numerics + db DoNo ;^x^o + db 48h ;^x^p special sed pipe + db DoNo ;^x^q + db DoNo ;^x^r + db 0ch ;^x^s WS: ^KS + db DoNo ;^x^t + db DoNo ;^x^u + db DoNo ;^x^v + db 29h ;^x^w write to + db 26h ;^x^x xchg mark/point + db DoNo ;^x^y + db DoNo ;^x^z +;---------------------------------------------------------------------- +PicoJtable db DoNo ;^j@ Junk ops for PI mode + db DoNo ;^ja + db DoNo ;^jb + db DoNo ;^jc + db DoNo ;^jd + db DoNo ;^je + db DoNo ;^jf + db DoNo ;^jg + db 17h ;^jh Junk to line Home + db DoNo ;^ji + db DoNo ;^jj + db DoNo ;^jk + db 22h ;^jl Junk Line rest + db DoNo ;^jm + db DoNo ;^jn + db DoNo ;^jo + db 48h ;^jp special sed pipe + db DoNo ;^jq + db DoNo ;^jr + db DoNo ;^js + db 49h ;^jt repeat last search&replace + db DoNo ;^ju + db DoNo ;^jv + db 2Ah ;^jw Junk Word + db DoNo ;^jx + db DoNo ;^jy + db DoNo ;^jz +PicoQtable db DoNo ;^q@ Quick motions for PI mode: wordstar counterparts on different keys + db DoNo ;^qa + db 1Fh ;^qb Bottom of window + db 4FH ;^qc Calc numerics + db DoNo ;^qd + db 0fh ;^qe End of file + db 1Ch ;^qf last Find + db DoNo ;^qg + db DoNo ;^qh + db DoNo ;^qi + db DoNo ;^qj + db DoNo ;^qk + db 11h ;^ql Line number # + db 3eh ;^qm set mode + db 13h ;^qn Next word + db DoNo ;^qo + db 12h ;^qp Previous word + db DoNo ;^qq + db DoNo ;^qr + db 0Eh ;^qs Start of file + db 1Eh ;^qt Top of window +%ifdef USE_UNDO + db 53h ;^qu UNDO, experimental +%else + db DoNo ;^qu +%endif + db DoNo ;^qv + db DoNo ;^qw + db DoNo ;^qx + db DoNo ;^qy + db DoNo ;^qz +;---------------------------------------------------------------------- +esize equ 2 ;(byte per entry) +jumptab1: ;Storing 16 bit offsets is valid only for code less size 64 kbyte... + ; ... but in assembler that should never be a problem ;) +%ifndef USE_EXT_MOVE + dw KeyHome -_start ;0 +%else + dw KeyHome2 -_start ;0 +%endif + dw KeyUp -_start ;1 + dw KeyPgUp -_start ;2 + dw KeyLeft -_start ;3 + dw KeyRight -_start ;4 +%ifndef USE_EXT_MOVE + dw KeyEnd -_start ;5 +%else + dw KeyEnd2 -_start ;5 +%endif + dw KeyDown -_start ;6 + dw KeyPgDn -_start ;7 + dw KeyIns -_start ;8 + dw KeyDel -_start ;9 0..9 are Cursor pad keys +;------------------------ + dw SimpleRet -_start ;10 DO_NOTHING == DoNo + dw KeyCtrlKQ -_start ;0bh EMA ^X^C + dw KeyCtrlKS -_start ;0ch EMA ^X^S + dw KeyCtrlKD -_start ;0dh EMA ^X^F +%ifndef USE_EXT_MOVE + dw KeyCtrlQR -_start ;0eh EMA Alt< + dw KeyCtrlQC -_start ;0fh EMA Alt> +%else + dw KeyCtrlQR2 -_start ;0eh EMA Alt< + dw KeyCtrlQC2 -_start ;0fh EMA Alt> +%endif + dw KeyCtrlKR -_start ;10h EMA ^XI + dw KeyCtrlQI -_start ;11h EMA Alt-G + dw KeyCtrlQW -_start ;12h EMA Alt-B + dw KeyCtrlQZ -_start ;13h EMA Alt-F +;-------------------------- +;up to here this functions are considered common for all (exc vi) +;Of course some use different key names. +; +;now follows special stuff for each editor emulation: +;-------WS and Pico-------- + dw KeyCtrlKK -_start ;14h + dw KeyCtrlKC -_start ;15h + dw KeyCtrlKX -_start ;16h + dw KeyCtrlQDel -_start ;17h + dw KeyCtrlQP -_start ;18h + dw KeyCtrlKY -_start ;19h + dw KeyCtrlQA -_start ;1ah + dw KeyCtrlQF -_start ;1bh + dw KeyCtrlQV -_start ;1ch + dw KeyCtrlKH -_start ;1dh + dw KeyCtrlQE -_start ;1eh + dw KeyCtrlQX -_start ;1fh + dw KeyCtrlQB -_start ;20h + dw KeyCtrlQK -_start ;21h + dw KeyCtrlQY -_start ;22h + dw KeyCtrlKV -_start ;23h + dw KeyCtrlKB -_start ;24h + dw KeyCtrlKW -_start ;25h +;-------EM-------- + dw KeyCtrlXX -_start ;26h + dw KeyEmaAltW -_start ;27h + dw KeyEmaAltPer -_start ;28h Alt-% + dw KeyEmaCtrlXW -_start ;29h +;-------PI-------- + dw KeyCtrlT -_start ;2Ah +;-------VI-------- + dw KeyVIcmdi -_start ;2Bh + dw KeyVIex -_start ;2Ch + dw KeyVIcmda -_start ;2Dh + dw KeyVICmdA -_start ;2Eh + dw KeyVICmdo -_start ;2Fh + dw KeyCtrlQE -_start ;30h + dw KeyCtrlQX -_start ;31h + dw KeyVICmdO -_start ;32h + dw KeyVICmdI -_start ;33h + dw KeyVICmdR -_start ;34h + dw KeyVICmdd -_start ;35h + dw KeyHalfPgDn -_start ;36h + dw KeyHalfPgUp -_start ;37h + dw KeyVI1Char -_start ;38h + dw KeyVIfsearch -_start ;39h + dw KeyVIbsearch -_start ;3Ah + dw KeyVICmdp -_start ;3Bh + dw KeyVICmdP -_start ;3Ch +;------- later added (mostly vi stuff) ------ + dw KeyHelp -_start ;3Dh general + dw KeyEditMode -_start ;3Eh general + dw KeyDell -_start ;3Fh vi + dw KeyVICmdS -_start ;40h vi + dw KeyVICmdZ -_start ;41h vi + dw KeyVICmdz -_start ;42h vi + dw KeyVIcmde -_start ;43h vi + dw KeyVIcmd1 -_start ;44h vi + dw KeyVICmdm -_start ;45h vi + dw KeyVICmdy -_start ;46h vi + dw KeyEmaCtrlXF -_start ;47h emacs (extended ^KD from WS) +%ifdef USE_PIPE + dw KeyCtrlKP -_start ;48h use sed-pipe in WS,Emacs,Pico +%else + dw SimpleRet -_start ;48h +%endif + dw KeyPiCtrlJT -_start ;49h Pico + dw KeyVICmdr -_start ;4Ah vi + dw KeyVICmdC -_start ;4Bh vi + dw KeyVICmdD -_start ;4Ch vi + dw KeyVICmdJ -_start ;4Dh vi +%ifdef BEEP_IN_VI + dw VIBeepForD -_start ;4Eh vi +%else + dw SimpleRet -_start ;4Eh vi +%endif + dw KeyCtrlKN -_start ;4Fh general + dw KeyVICmdJmpM -_start ;50h vi +%ifdef SYS_kill + dw KeySuspend -_start ;51h general +%else + dw SimpleRet -_start ;51h +%endif + dw KeyVI_M -_start ;52h vi +%ifdef USE_UNDO + dw KeyUndo -_start ;53h general & experimental +%else + dw SimpleRet -_start ;53h +%endif +jumps1 equ ($-jumptab1) / esize +;--- 32 more for WS-------- + dw SimpleRet -_start ;^Space + dw KeyCtrlQW -_start ;^a + dw SimpleRet -_start ;^b ;; TEST dw KeyUndo-_start + dw KeyPgDn -_start ;^c + dw KeyRight -_start ;^d + dw KeyUp -_start ;^e + dw KeyCtrlQZ -_start ;^f + dw KeyDel -_start ;^g 7 + dw KeyDell -_start ;^h 8 DEL (7fh is translated) + dw NormChar -_start ;^i 9 (TAB) +%ifdef SELFTEST + dw KeyRet -_start ;^j 0ah +%else + dw KeyHelp -_start ;^j +%endif + dw CtrlKMenu -_start ;^k b + dw KeyCtrlL -_start ;^l c + dw KeyRet -_start ;^m 0dh + dw SimpleRet -_start ;^n e + dw SimpleRet -_start ;^o f + dw KeyHelp -_start ;^p 10 Help! + dw CtrlQMenu -_start ;^q 11 + dw KeyPgUp -_start ;^r 12 + dw KeyLeft -_start ;^s 13 + dw KeyCtrlT -_start ;^t 14 +%ifdef USE_UNDO + dw KeyUndo -_start ;^u 15 (abort in Input) +%else + dw SimpleRet -_start ;^u +%endif + dw KeyIns -_start ;^v 16 + dw KeyScrollUp -_start ;^w 17 + dw KeyDown -_start ;^x 18 + dw KeyCtrlY -_start ;^y 19 + dw KeyScrollDn -_start ;1a + dw SimpleRet -_start ;1b + dw SimpleRet -_start ;1c + dw SimpleRet -_start ;1d + dw SimpleRet -_start ;1e +%ifdef ROLLBACK + dw RollBack -_start ;1f for internal testing of UNDO ring buffer only +%else + dw SimpleRet -_start ;1f +%endif +;--- 32 more for EM-------- + dw KeyEmaMark -_start ;^Space + dw KeyHome -_start ;^a + dw KeyLeft -_start ;^b + dw SimpleRet -_start ;^c (not planned) + dw KeyDel -_start ;^d + dw KeyEnd -_start ;^e + dw KeyRight -_start ;^f + dw SimpleRet -_start ;^g (abort in Input) + dw KeyDell -_start ;^h + dw NormChar -_start ;^i (TAB) + dw KeyRet -_start ;^j + dw KeyEmaCtrlK -_start ;^k + dw KeyEmaCtrlL -_start ;^l + dw KeyRetNoInd -_start ;^m 0dh + dw KeyDown -_start ;^n + dw KeyEmaCtrlO -_start ;^o + dw KeyUp -_start ;^p + dw KeyEmaCtrlQ -_start ;^q + dw KeyEmaCtrlR -_start ;^r + dw KeyEmaCtrlS -_start ;^s + dw KeyEmaCtrlT -_start ;^t + dw SimpleRet -_start ;^u (not yet planned) + dw KeyPgDn -_start ;^v + dw KeyEmaCtrlW -_start ;^w + dw CtrlXMenu -_start ;^x + dw KeyEmaCtrlY -_start ;^y +%ifdef SYS_kill + dw KeySuspend -_start ;^z +%else + dw SimpleRet -_start ;51h +%endif + dw SimpleRet -_start ;1b + dw SimpleRet -_start ;1c + dw SimpleRet -_start ;1d + dw SimpleRet -_start ;1e +%ifdef USE_UNDO + dw KeyUndo -_start ;1f +%else + dw SimpleRet -_start ;1f +%endif +;--- 32 more for PI------ + dw KeyEmaMark -_start ;^Space a redundant marker because ^^ is ugly on some kbds + dw KeyHome -_start ;^a 1 + dw KeyLeft -_start ;^b 2 + dw SimpleRet -_start ;^c 3 + dw KeyDel -_start ;^d 4 + dw KeyEnd -_start ;^e 5 + dw KeyRight -_start ;^f 6 + dw KeyHelp -_start ;^g 7 + dw KeyDell -_start ;^h 8 DEL + dw NormChar -_start ;^i 9 (TAB) + dw PicoJMenu -_start ;^j a + dw KeyEmaCtrlW -_start ;^k b + dw KeyEmaMark -_start ;^l c a redundant marker because ^^ is ugly on some kbds + dw KeyRet -_start ;^m d + dw KeyDown -_start ;^n e + dw KeyCtrlKS -_start ;^o f SAVE + dw KeyUp -_start ;^p 10 + dw PicoQMenu -_start ;^q 11 + dw KeyCtrlKR -_start ;^r 12 + dw KeyEmaCtrlXW -_start ;^s 13 SAVE_AS + dw KeyEmaAltPer -_start ;^t 14 + dw KeyEmaCtrlY -_start ;^u 15 + dw KeyPgDn -_start ;^v 16 + dw KeyEmaCtrlS -_start ;^w 17 + dw KeyCtrlKQ -_start ;^x 18 + dw KeyPgUp -_start ;^y 19 +%ifdef SYS_kill + dw KeySuspend -_start ;^z 1A (not in pico) +%else + dw SimpleRet -_start ;51h +%endif + dw SimpleRet -_start ;^[ 1B + dw SimpleRet -_start ;^\ 1C + dw SimpleRet -_start ;^] 1D + dw KeyEmaMark -_start ;^^ 1E see ^L + dw SimpleRet -_start ;1F +;--- 32 more for NE------ + dw KeyEmaMark -_start ;^Space toggle selection mode (no shift cursor keys available!) + dw KeyNedCtrlA -_start ;^a 1 Mark all + dw KeyIns -_start ;^b 2 toggle Ins mode + dw KeyEmaAltW -_start ;^c 3 COPY + dw SimpleRet -_start ;^d 4 + dw KeyEditMode -_start ;^e 5 set EDit mode + dw KeyCtrlQF -_start ;^f 6 find + dw KeyCtrlL -_start ;^g 7 find again + dw KeyDell -_start ;^h 8 DEL + dw NormChar -_start ;^i 9 TAB + dw KeyRet -_start ;^j a RETURN + dw KeyCtrlKN -_start ;^k b numerics + dw KeyCtrlQI -_start ;^l c LINE # + dw KeyRet -_start ;^m d RETURN + dw KeyEmaCtrlXF -_start ;^n e OPEN another + dw KeyEmaCtrlXF -_start ;^o f OPEN another + dw SimpleRet -_start ;^p 10 + dw KeyCtrlKQ -_start ;^q 11 EXIT + dw KeyCtrlQA -_start ;^r 12 REPLACE + dw KeyCtrlKS -_start ;^s 13 SAVE + dw SimpleRet -_start ;^t 14 +%ifdef USE_UNDO + dw KeyUndo -_start ;^u 15 UNDO experimental +%else + dw SimpleRet -_start ;^u 15 +%endif + dw KeyEmaCtrlY -_start ;^v 16 PASTE + dw KeyEmaCtrlXW -_start ;^w 13 SAVE_AS/WRITE TO + dw KeyEmaCtrlW -_start ;^x 18 CUT + dw SimpleRet -_start ;^y 19 +%ifdef SYS_kill + dw KeySuspend -_start ;^z 1A +%else + dw SimpleRet -_start ;51h +%endif + dw SimpleRet -_start ;^[ 1B + dw SimpleRet -_start ;^\ 1C + dw SimpleRet -_start ;^] 1D + dw SimpleRet -_start ;^^ 1E + dw SimpleRet -_start ;1F +;---------------------------------------------------------------------- +; +%ifdef W32 + scolorslen equ 0 +%else + BeepChar db 7 + screencolors0 db 27,'[40m',27,'[37m' + bold0 db 27,'[0m' ;reset to b/w + screencolors1 db 27,'[44m',27,'[33m' ;yellow on blue + reversevideoX: + bold1: db 27,'[1m' ;bold + scolorslen equ $-screencolors1 + boldlen equ $-bold1 ;take care length of bold0 == length of bold1 +%ifdef LINUX + db 27,'[7m' ;good for "linux" terminal on /dev/tty (but not xterm,kvt) + ;again take care length = length of boldX + ;!! important: store directly after bold1 !! +%endif +%endif +%ifdef SELFTEST + pipein db 'PIPE_IN',0 +%endif +;------------------------------------------------------------------------- +editmode:db 'p WSp Pip Emp NE' +; +helptext: +db "MicroEditor e3 v2.21 GPL (C) 2000-02 A.Kleine <kleine@ak.sax.de>",10 +db "Enter filename or leave with RETURN",10,10 +helptextsize equ $-helptext +%if helptextsize>127 + %error helptextsize +%endif +helpfoot:db 10,10,10,TABCHAR,TABCHAR,TABCHAR,"-= PRESS ANY KEY =-" ;at least 6 wasted byte ;-) +helpfootsize equ $-helpfoot +%if helpfootsize>127 + %error helpfootsize +%endif +; +%ifdef USE_BUILTINHELP +help_ws: +db "Key bindings in WS mode:",10,10 +db "Files: ^KR Insert ^KS Save ^KX Save&Exit ^KQ Abort&Exit",10 +%ifndef USE_PIPE +db " ^KD Save&Load",10 +%else +%ifdef USE_EX_NO_SED +db " ^KD Save&Load ^KP Pipe buffer thru 'ex' ",10 +%else +db " ^KD Save&Load ^KP Pipe buffer thru 'sed'",10 +%endif +%endif +db 10 +db "Blocks: ^KB Start ^KK End ^KC Copy ^KY Del",10 +db " ^KV Move ^KW Write",10 +db 10 +db "Search: ^QF Find ^L Repeat ^QA Srch&Repl",10 +db "Move: ^E Up ^X Down ^S Left ^D Right",10 +db " ^R Page Up ^C Page Dn ^W Scroll Up ^Z Scroll Dn",10 +db "Quick- ^QE Wnd Top ^QX Wnd Bott ^QS Home ^QD End",10 +db "-Move: ^QR BOF ^QC EOF ^QB Blk Begin ^QK Blk End",10 +db " ^F Next Word ^A Prev Word ^QI Line# ^QV Last Find",10 +db 10 +db "Delete: ^T Word ^Y Line ^H Left ^G Chr",10 +db " ^QY Line End ^QDel,^QH Line Beg",10 +%ifdef USE_MATH +db "Other: ^KM Set mode ^KN Numerics" +%else +db "Other: ^KM Set mode" +%endif +%ifdef SYS_kill +db " ^KZ Suspend " +%endif +%ifdef USE_UNDO +db " ^U Undo" +%endif +help_ws_size equ $-help_ws +;------------------------- +help_pi: +db "Key bindings in PICO mode:",10,10 +db "Files: ^XN ExitNoSave ^XY Exit+Save ^XL Save+Load New File",10 +db " ^O Save ^S Save as ^R Read",10 +db 10 +db "Move: ^P Up ^N Down ^B Left ^F Right",10 +db " ^Y Page up ^V Page down ^QN Next word ^QP Previous word",10 +db " ^A Home ^E End ^QS Start ^QE EOF",10 +db " ^QT Top screen ^QB Bottom scr ^QL Line # ^QF last Find",10 +db 10 +db "Search: ^W Where is ^T Search&Repl ^JT Repeat Search & Replace",10 +db 10 +db "Delete: ^H Left char ^D This char ^K Kill line/region",10 +db " ^JW Word ^JL Line end ^JH Line begin",10 +db 10 +db "Other: ^U Unkill ^G Help ^^,^L,^<SPC> Mark region",10 +%ifndef USE_PIPE +db " ^QM Set Edit Mode ",10 +%else +%ifdef USE_EX_NO_SED +db " ^QM Set Edit Mode ^JP Pipe buffer thru 'ex' ",10 +%else +db " ^QM Set Edit Mode ^JP Pipe buffer thru 'sed'",10 +%endif +%endif +%ifdef USE_MATH +db " ^QC Calculate" +%else +db " " +%endif +%ifdef SYS_kill +db " ^Z Suspend" +%endif +%ifdef USE_UNDO +db " ^QU Undo" +%endif +help_pi_size equ $-help_pi +;------------------------- +help_em: +db "Key bindings in EMACS mode:",10,10 +db "Files: ^X^C Exit ^XI Insert ^X^S Save ^X^F Load New",10 +%ifndef USE_PIPE +db " ^X^W Write new ^X^H Help ",10 +%else +%ifdef USE_EX_NO_SED +db " ^X^W Write new ^X^H Help ^X^P Pipe buffer thru 'ex' ",10 +%else +db " ^X^W Write new ^X^H Help ^X^P Pipe buffer thru 'sed'",10 +%endif +%endif +db 10 +db "Move: ^P Up ^N Down ^B Left ^F Right",10 +db " altV Pg up ^V Pg down altB Left word altF Right word",10 +db " ^A Home ^E End alt< BOF alt> EOF",10 +db " altG Go line# ^L Center Pos",10 +db 10 +db "Search: ^S Find fwd ^R Find bwd alt% Search&Replace like WS",10 +db 10 +db "Buffer: altW Copy ^Y Yank ^<SPC> Mark ^X^X Xchg Mark/Pt",10 +db 10 +db "Delete: ^K Line ^W Region ^H Left Chr ^D This Chr",10 +db 10 +db "Other: ^O Open line ^T Xchg Chr ^I Ins Tab ^Q Quoted Ins",10 +db " ^M NL ^J NL+indent altX Set edit mode",10 +%ifdef USE_MATH +db " ^X^N Calculate" +%else +db " " +%endif +%ifdef SYS_kill +db " ^Z Suspend" +%endif +%ifdef USE_UNDO +db " ^_ Undo" +%endif +help_em_size equ $-help_em +;------------------------- +help_vi: +db "Key bindings in vi mode:",10 +db 10 +db "<ESC> enter cmd mode",10 +db "h,j,k,l,+,-,<Ret>,<SPC> move by chars&lines",10 +db "^B,^F,^D,^U move by [half]page",10 +db "$,0,^,w,b,e,H,L,M,z. move in line/screen",10 +db "/,?,G srch fwd/bwd, go EOF",10 +db "ma,'a set/go marker a",10 +db "x,X,<Del>,D delete chr, to EOL",10 +db "S,C,dd,d'a,yy,y'a subst,change,delete,yank",10 +db "p,P paste",10 +db "A,a,I,i,<Ins>,O,o enter ins.mode",10 +db "R,r enter ovw.mode,ovw.chr",10 +db "J join lines",10 +%ifdef USE_UNDO + %ifdef SYS_kill + db "ZZ,^Z, u save&quit,suspend, undo!",10 + %else + db "ZZ, u save&ex, undo!",10 + %endif +%else + %ifdef SYS_kill + db "ZZ,^Z save&quit,suspend",10 + %else + db "ZZ save&ex",10 + %endif +%endif +%ifdef USE_MATH +db ";,# E3 SPECIAL: set edit mode,calculate",10 +%else +db "; E3 SPECIAL:set edit mode",10 +%endif +db ":w,:wq,:x,:q,:q!,:e ex mode:save,quit,save_as,edit other",10 +db ":0,:$,:<line#> ex mode:go BOF,EOF,line",10 +db ":h ex mode:help",10 +%ifndef USE_PIPE +db " " +%else +%ifdef USE_EX_NO_SED +db ":<other cmd> pipe buffer thru 'ex' " +%else +db ":<other cmd> pipe buffer thru 'sed'" +%endif +%endif +help_vi_size equ $-help_vi +;------------------------- +help_ne: +db "Key bindings in NEDIT mode:",10 +db 10 +db "Files: ^QN Exit_NoSave ^QY Exit&Save ^QL Save&Load new",10 +db " ^S Save ^W WriteTo=SaveAs",10 +db "Move: ^L Line#",10 +db " ^F Find ^R Search&Replace (like WS)",10 +db " ^G Go repeat last ^F,^R",10 +db 10 +db "Select: ^<SPACE> begin&extend by cursor keys (like Emacs)",10 +db " ^A All buffer",10 +db " ^X Cut ^C Copy ^V Paste",10 +db 10 +db "Other: ^E Set edit mode",10 +%ifdef USE_MATH +db " ^K Calculate",10 +%endif +db " altH Help" +%ifdef SYS_kill +db " ^Z Suspend" +%endif +%ifdef USE_UNDO +db " ^U Undo" +%endif +help_ne_size equ $-help_ne + +%if help_ws_size != help_pi_size || help_ws_size!= help_em_size || help_ws_size!= help_pi_size || help_ws_size!= help_vi_size +%error Helptext +dw help_vi_size +dw help_ws_size +dw help_pi_size +dw help_em_size +%endif +%else ;no help texts built in +help_ws: +help_pi: +help_em: +help_vi: +help_ne: +db "This e3 is built w/o help texts." +help_ws_size equ $-help_ws +help_ne_size equ $-help_ws +%endif +; +errmsgs:errortext ;see e3.h + +;------- +; +%ifdef CRIPLED_ELF + filesize equ $ - $$ +%endif +;----------------------------------------------------------------------- +%ifdef ATHEOS +section .data ;unused in Linux/FreeBSD/BeOS: save byte in ELF header +bits 32 ;unused in W32: save byte in PE header +%endif +;----------------------------------------------------------------------- +section .bss +bits 32 +align 4 +%ifdef CRIPLED_ELF + bssstart: +%endif +screenbuffer_size equ 62*(160+32) ;estimated 62 lines 160 columns, 32 byte ESC seq (ca.12k) +screenbuffer_dwords equ screenbuffer_size/4 +screenbuffer resb screenbuffer_size +screenbuffer_end equ $ ;If you really have higher screen resolution, + ;...no problem, except some useless redrawing happens. +%ifdef W32 + attribbuffer resw 62*160 ;estimated 62 lines 160 columns + attribbuffer_end equ $ +%else + termios: resb termios_struc_size + termios_orig: resb termios_struc_size + winsize: resb winsize_struc_size + setkplen equ 10 + setkp resb setkplen ;to store cursor ESC seq like db 27,'[000;000H' + resb 2 ;fill up + revvoff resd 1 +%endif +%ifdef USE_UNDO + enter_undo resd 1 ;a status byte: 1 while in a undo process, else 0 + last_undo_file resd 1 ;a pointer to undo info stored external in a disk file + undoptr resd 1 ;points on top frame in undo ringbuffer stack + undobuffer_size equ 0x10000 ;64 k + undobuffer resb undobuffer_size + undobuffer_end equ $ +%endif +lines resd 1 ;equ 24 or similar i.e. screen lines-1 (1 for statusline) +columns resd 1 ;equ 80 or similar dword (using only LSB) +columne resd 1 ;helper for display of current column +zloffst resd 1 ;helper: chars scrolled out at left border +fileptr resd 1 ;helper for temp storage of current pos in file +kurspos resd 1 ;cursor position set by DispNewScreen() +kurspos2 resd 1 ;cursor position set by other functions + +tabcnt resd 1 ;internal helper byte in DispNewScreen() only +changed resd 1 ;status byte: (UN)CHANGED +oldQFpos resd 1 +bereitsges resd 1 ;byte used for ^L + +blockbegin resd 1 +blockende resd 1 +endeedit resd 1 ;byte controls program exit +old resd 1 ;helper for ^QP +veryold resd 1 ;ditto +linenr resd 1 ;current line +showblock resd 1 ;helper for ^KH +suchlaenge resd 1 ;helper for ^QA,^QF +repllaenge resd 1 +vorwarts resd 1 +grossklein resd 1 ;helper byte for ^QF,^QA + +ch2linebeg resd 1 ;helper keeping cursor pos max at EOL (up/dn keys) +numeriere resd 1 ;byte controls re-numeration +read_b resd 1 ;buffer for getchar +%ifdef W32 + resd 4 ;4 extra due size INPUT_RECORD in w32 +%endif +isbold resd 1 ;control of bold display of ws-blocks +inverse resd 1 +insstat resd 1 +errno resd 1 ;used similar libc, but not excactly equal + +errlen equ 100 +error resb errlen ;reserved space for string: 'ERROR xxx:tttteeeexxxxtttt',0 + +maxlen resd 1 +;------- +; +maxfilenamelen equ 255 +filepath resb maxfilenamelen+1 +bakpath resb maxfilenamelen+1 +blockpath resb maxfilenamelen+1 +replacetext resb maxfilenamelen+1 +suchtext resb maxfilenamelen+1 +suchtext2 resb maxfilenamelen+1 ;for PICO mode +optbuffer resb optslen ;buffer for search/replace options and for ^QI +linkbuffersize equ 4 +linkbuffer resb linkbuffersize +sigaction resd 40 +;------ +perms resd 1 +%ifdef SYS_fstat + fstatbuf: resb stat_struc_size +%endif +%ifdef SYS_utime + accesstime: resb utimbuf_struc_size +%endif +;------- +screenline resb 256+4*scolorslen ;max possible columns + 4 color ESC seq per line + ;(buffer for displaying a text line) +%ifdef W32 + attribline resb 256*2 ;attrib is a word +%endif +EmaKiSize resd 1 +EmaKiSrc resd 1 +EmaMark resd 1 +EmaCtrl: +EmaCtrlK resb 1 +EmaCtrlS resb 1 + resb 2 +EmaNumHelper resd 1 +VICmdMode resd 1 +VIbufch resd 1 +VInolinebased resd 1 +PicoSearch resd 1 ;where search started +%ifdef USE_PIPE + sedpipeB0 resd 1 + sedpipeB1 resd 1 + sedpipeC0 resd 1 + sedpipeC1 resd 1 +%endif + +mode resd 1 + +readfds resd 1 ;select data struc +timevalsec resd 1 ;lowest +timevalusec resd 1 ;most significant + + +buffercopysize equ 1024 +buffercopy resb buffercopysize +%ifdef USE_MATH + level resd 1 ;balance + ptlevel resd 1 ;parenthesis balance + stackptr resd 1 ;escape recursion + x87 resd 3 ;12 byte (need 10 byte for 80 bit BCD) + lastresult87 resq 4 ;8 byte + signctl resd 1 +%endif +%ifdef W32 + heap resd 1 + hin resd 1 + hout resd 1 + w32result resd 1 ;for the w32 API calls + csbi resd 6 ;screen_buffer_info +%endif + +%ifdef SYS_brk + max equ 102400 ;valid for NEW created files only +%else + max equ 10240000 +%endif +;------- +text resb max +sot equ (text+1) ;start-of-text + +%ifdef CRIPLED_ELF + bsssize equ $-bssstart +%endif @@ -0,0 +1,734 @@ +;-------------------------------------------------------------------------- +; e3.asm v2.21 Copyright (C) 2000-02 Albrecht Kleine <kleine@ak.sax.de> +; +; see GNU copyright details in e3.asm +;-------------------------------------------------------------------------- + +%define WS 1 +%define EM 2 +%define PI 4 +%define VI 8 +%define NE 16 +%define DEFAULT_MODE WS ;<---- select one of WS, EM, NE, PI, VI +%define MAKE_BACKUP +%define LESSWRITEOPS +;------- +%define BEEP_IN_VI ;undef if you hate beeping computers +%define USE_MATH ;undef if you don't use the numerics +%define USE_PIPE ;undef if you don't use piping through sed/ex +%define USE_BUILTINHELP ;undef if you really don't need help (saves some space) +%define USE_UNDO ;undef if there is low memory +;;;%define USE_EXT_MOVE ;smart move mode for Home,End,BOF,EOF keys +; +;------- +; +; D O N O T C H A N G E B E L O W L I N E +;---------------------------------------------------------------------- +%ifdef BEOS + ;posix/termios.h ;termios eq termio + %define TERMIOS_SET 8001h ;TCSETA + %define TERMIOS_GET 8000h ;TCGETA + %define TERMIOS_WSIZE 800Ch ;TIOCGWINSZ + %define NCCS 11 + %define VMIN 4 + %define speed_t1 resb + %undef USE_PIPE +%define SYS_exit 63 +%define SYS_read 2 +%define SYS_write 3 +%define SYS_open 0 +%define SYS_close 1 +%define SYS_unlink 39 +%define SYS_lseek 5 +%define SYS_rename 38 +%define SYS_ioctl 4 + +MAXERRNO equ 30 +ERRNOMEM equ 12 +ERRNOIO equ 5 + + %macro errortext 0 +db "Op not permitted",10 ;1 +db "No such file|directory",10 ;2 +db 10 ;3 +db 10 ;4 +db "Input/output",10 ;5 +db "No such device",10 ;6 +db 10 ;7 +db 10 ;8 +db "Bad file descriptor",10 ;9 +db "No child processes",10 ;10 +db 10 ;11 +db "Memory exhausted",10 ;12 +db "Permission denied",10 ;13 +db 10 ;14 +db 10 ;15 +db "Device|resource busy",10 ;16 +db "File exists",10 ;17 +db 10 ;18 +db "No such device",10 ;19 +db 10 ;20 +db "Is a directory",10 ;21 +db "Invalid argument",10 ;22 +db "Too many open files",10 ;23 +db "Too many open files",10 ;24 +db "Inappropriate ioctl",10 ;25 +db "Text file busy",10 ;26 +db "File too large",10 ;27 +db "No space on device",10 ;28 +db "Illegal seek",10 ;29 +db "R/O file system",10 ;30 + %endmacro + +%else +%ifdef QNX + ;termios.h + ;sys/ioctl.h + %define TERMIOS_SET 804c7414h ;TIOCSETA + %define TERMIOS_GET 404c7413h ;TIOCGETA + %define TERMIOS_WSIZE 40087468h ;TIOCGWINSZ + ; rw + ; size + ; 't' + ; nr. + %define NCCS 40 + %define VMIN 6 + %define speed_t2 resd +;------- +;the QNX version is linked against libc +%define LIBC +extern open,read,write,close,lseek,rename,_exit,ioctl,fstat,fchown,select,unlink +%undef USE_PIPE + %define SYS_fstat ;dummy + struc stat_struc +.st_ino: resd 2 +.st_size: resd 2 +.st_dev: resd 1 +.st_rdev: resd 1 +.st_uid: resd 1;24 +.st_gid: resd 1;28 +.st_ctime: resd 1; +.st_atime: resd 1; +.st_mtime: resd 1;40 +.st_mode: resd 1;44 +.st_dummy: resd 20 ;who cares? + endstruc +MAXERRNO equ 30 +ERRNOMEM equ 12 +ERRNOIO equ 5 + + %macro errortext 0 +db "Op not permitted",10 ;1 +db "No such file|directory",10 ;2 +db 10 ;3 +db 10 ;4 +db "Input/output",10 ;5 +db "No such device",10 ;6 +db 10 ;7 +db 10 ;8 +db "Bad file descriptor",10 ;9 +db "No child processes",10 ;10 +db 10 ;11 +db "Memory exhausted",10 ;12 +db "Permission denied",10 ;13 +db 10 ;14 +db 10 ;15 +db "Device|resource busy",10 ;16 +db "File exists",10 ;17 +db 10 ;18 +db "No such device",10 ;19 +db 10 ;20 +db "Is a directory",10 ;21 +db "Invalid argument",10 ;22 +db "Too many open files",10 ;23 +db "Too many open files",10 ;24 +db "Inappropriate ioctl",10 ;25 +db "Text file busy",10 ;26 +db "File too large",10 ;27 +db "No space on device",10 ;28 +db "Illegal seek",10 ;29 +db "R/O file system",10 ;30 + %endmacro + +%else +%ifdef ATHEOS ;--------------------- A T H E O S ----------------------- + ;posix/termbits.h + %define TERMIOS_SET 5406h + %define TERMIOS_GET 5405h + %define TERMIOS_WSIZE 5413h + %define NCCS 19 + %define VMIN 6 + ;posix/stat.h + struc stat_struc +.st_dev: resd 1 +.st_ino: resd 2 +.st_mode: resd 1 +.st_nlink: resd 1 +.st_uid: resd 1 +.st_gid: resd 1 +.st_rdev: resd 1 +.st_size: resd 2 +.st_blksize: resd 1 +.st_blocks: resd 2 +.st_atime: resd 1 +.__unused1: resd 1 +.st_mtime: resd 1 +.__unused2: resd 1 +.st_ctime: resd 1 +.__unused3: resd 1 +.__unused4: resd 1 +.__unused5: resd 1 + endstruc + %undef USE_PIPE + +%define SYS_exit 6 +%define SYS_read 3 +%define SYS_write 4 +%define SYS_open 1 +%define SYS_close 2 +%define SYS_unlink 20 +%define SYS_lseek 13 +%define SYS_kill 92 +%define SYS_rename 7 +%define SYS_ioctl 116 +%define SYS_sigaction 93 +%define SYS_fchown 86 +%define SYS_fstat 11 +%define SYS_select 42 + +SIGCONT equ 18 +SIGSTOP equ 19 + + +MAXERRNO equ 30 +ERRNOMEM equ 12 +ERRNOIO equ 5 + + %macro errortext 0 +db "Op not permitted",10 ;1 +db "No such file|directory",10 ;2 +db 10 ;3 +db 10 ;4 +db "Input/output",10 ;5 +db "No such device",10 ;6 +db 10 ;7 +db 10 ;8 +db "Bad file descriptor",10 ;9 +db "No child processes",10 ;10 +db 10 ;11 +db "Memory exhausted",10 ;12 +db "Permission denied",10 ;13 +db 10 ;14 +db 10 ;15 +db "Device|resource busy",10 ;16 +db "File exists",10 ;17 +db 10 ;18 +db "No such device",10 ;19 +db 10 ;20 +db "Is a directory",10 ;21 +db "Invalid argument",10 ;22 +db "Too many open files",10 ;23 +db "Too many open files",10 ;24 +db "Inappropriate ioctl",10 ;25 +db "Text file busy",10 ;26 +db "File too large",10 ;27 +db "No space on device",10 ;28 +db "Illegal seek",10 ;29 +db "R/O file system",10 ;30 + %endmacro +%else +%ifdef LINUX ;----------------------- L I N U X ----------------------- + ;asm/termbits.h + ;asm/ioctls.h + %define TERMIOS_SET 5402h ;TCSETS + %define TERMIOS_GET 5401h ;TCGETS + %define TERMIOS_WSIZE 5413h ;TIOCGWINSZ + %define NCCS 19 + %define VMIN 6 +;------- + ;asm/stat.h + %define UIDGID_WORD + struc stat_struc +.st_dev: resd 1 +.st_ino: resd 1 +.st_mode: resw 1 +.st_nlink: resw 1 +.st_uid: resw 1 +.st_gid: resw 1 +.st_rdev: resd 1 +.st_size: resd 1 +.st_blksize: resd 1 +.st_blocks: resd 1 +.st_atime: resd 1 +.__unused1: resd 1 +.st_mtime: resd 1 +.__unused2: resd 1 +.st_ctime: resd 1 +.__unused3: resd 1 +.__unused4: resd 1 +.__unused5: resd 1 + endstruc + +%define SYS_exit 1 +%define SYS_fork 2 +%define SYS_read 3 +%define SYS_write 4 +%define SYS_open 5 +%define SYS_close 6 +%define SYS_unlink 10 +%define SYS_execve 11 +%define SYS_lseek 19 +%define SYS_utime 30 +%define SYS_kill 37 +%define SYS_rename 38 +%define SYS_pipe 42 +%define SYS_brk 45 +%define SYS_ioctl 54 +%define SYS_dup2 63 +%define SYS_sigaction 67 +%define SYS_readlink 85 +%define SYS_fchown 95 +%define SYS_fstat 108 +%define SYS_wait4 114 +%define SYS_select 142 + +%define time_t resd + struc utimbuf_struc +.actime: time_t 1 +.modtime:time_t 1 + endstruc +%ifdef CRIPLED_ELF +%define USE_SPECIAL_HEADER ;special ELF header etc +%endif +%define CURSORMGNT ;switch cursor depending of 'INSERT'-mode +SIGCONT equ 18 +SIGSTOP equ 19 + +%define CAPTURE_STDERR +%ifdef EX + %define USE_EX_NO_SED + %define EX_PATH '/usr/bin/ex' ;(ex is usually a symlink to vi) [ old was /bin/ex ] +%else + %undef USE_EX_NO_SED + %ifndef PERLPIPE + %define SEDPATH '/bin/sed' ;DEFAULT + %else + %define SEDPATH '/usr/bin/perl' + %endif +%endif + +MAXERRNO equ 32 +ERRNOMEM equ 12 +ERRNOIO equ 5 +ERRNOEXEC equ 31 + + %macro errortext 0 +db "Op not permitted",10 ;1 +db "No such file|directory",10 ;2 +db 10 ;3 +db 10 ;4 +db "Input/output",10 ;5 +db "No such device",10 ;6 +db 10 ;7 +db 10 ;8 +db "Bad file descriptor",10 ;9 +db "No child processes",10 ;10 +db 10 ;11 +db "Memory exhausted",10 ;12 +db "Permission denied",10 ;13 +db 10 ;14 +db 10 ;15 +db "Device|resource busy",10 ;16 +db "File exists",10 ;17 +db 10 ;18 +db "No such device",10 ;19 +db 10 ;20 +db "Is a directory",10 ;21 +db "Invalid argument",10 ;22 +db "Too many open files",10 ;23 +db "Too many open files",10 ;24 +db "Inappropriate ioctl",10 ;25 +db "Text file busy",10 ;26 +db "File too large",10 ;27 +db "No space on device",10 ;28 +db "Illegal seek",10 ;29 +db "R/O file system",10 ;30 +db "Can't exec " ;31 +%ifdef USE_EX_NO_SED +db EX_PATH,10 +%else +db SEDPATH,10 +%endif +db "Broken pipe",10 ;32 + %endmacro +%ifdef LIBC + extern open,read,write,close,lseek,rename,_exit,ioctl,fstat,fchown,select,unlink + %undef SYS_readlink + %undef SYS_brk + %undef SYS_kill + %undef SYS_sigaction + %undef USE_PIPE +%endif +%else +%ifdef FREEBSD ;----------------------- FREE B S D ----------------------- + ;sys/termios.h + %define TERMIOS_SET 802c7414h ;TIOCSETA + %define TERMIOS_GET 402c7413h ;TIOCGETA + %define TERMIOS_WSIZE 40087468h + ; rw + ; size + ; 't' + ; nr. + %define NCCS 20 + %define VMIN 16 + %define speed_t3 resd + %define ICRNL 0x100 + %define IXON 0x200 + %define ICANON 0x100 + %define ISIG 0x80 + %define ECHO 0x8 + %define TSize word ;due oversized ICANON +;------ + struc stat_struc +.st_dev: resd 1 +.st_ino: resd 1 +.st_mode: resw 1 +.st_nlink: resw 1 +.st_uid: resd 1 +.st_gid: resd 1 +.st_rdev: resd 1 +.st_atime: resd 1 +.st_atimes: resd 1 +.st_mtime: resd 1 +.st_mtimes: resd 1 +.st_ctime: resd 1 +.st_ctimes: resd 1 +.st_size: resd 2 +.st_blocks: resd 2 +.st_blksize: resd 1 +.st_flags: resd 1 +.st_gen: resd 1 +.st_spare: resd 5 + endstruc +%define SYS_exit 1 +%define SYS_fork 2 +%define SYS_read 3 +%define SYS_write 4 +%define SYS_open 5 +%define SYS_close 6 +%define SYS_unlink 10 +%define SYS_execve 59 +%define SYS_lseek 19 ;also 199 +%define SYS_utime 138 +%define SYS_kill 37 +%define SYS_rename 128 +%define SYS_pipe 42 +%define SYS_ioctl 54 +%define SYS_dup2 90 +%define SYS_sigaction 46 ;also 342 +%define SYS_readlink 58 +%define SYS_fchown 123 +%define SYS_fstat 189 +%define SYS_wait4 7 +%define SYS_select 93 +%define time_t resd + + struc utimbuf_struc +.actime: time_t 2 +.modtime:time_t 2 + endstruc + +%undef CAPTURE_STDERR ;******is buggy in e3/BSD****** +%ifdef EX + %define USE_EX_NO_SED + %define EX_PATH '/usr/bin/ex' ;(ex is usually a symlink to vi) [ old was /bin/ex ] +%else + %undef USE_EX_NO_SED + %ifndef PERLPIPE + %define SEDPATH '/usr/bin/sed' ;DEFAULT + %else + %define SEDPATH '/usr/bin/perl' + %endif +%endif + +MAXERRNO equ 32 +ERRNOMEM equ 12 +ERRNOIO equ 5 +ERRNOEXEC equ 31 +ERRNOREGFILE equ 21 + %macro errortext 0 +db "Op not permitted",10 ;1 +db "No such file|directory",10 ;2 +db 10 ;3 +db 10 ;4 +db "Input/output",10 ;5 +db "No such device",10 ;6 +db 10 ;7 +db 10 ;8 +db "Bad file descriptor",10 ;9 +db "No child processes",10 ;10 +db 10 ;11 +db "Memory exhausted",10 ;12 +db "Permission denied",10 ;13 +db 10 ;14 +db 10 ;15 +db "Device busy",10 ;16 +db "File exists",10 ;17 +db 10 ;18 +db "No such device",10 ;19 +db 10 ;20 +db "Is a directory",10 ;21 +db "Invalid argument",10 ;22 +db "Too many open files",10 ;23 +db "Too many open files",10 ;24 +db "Inappropriate ioctl",10 ;25 +db "Text file busy",10 ;26 +db "File too large",10 ;27 +db "No space on device",10 ;28 +db "Illegal seek",10 ;29 +db "R/O file system",10 ;30 +db "Can't exec " ;31 +%ifdef USE_EX_NO_SED +db EX_PATH,10 +%else +db SEDPATH,10 +%endif +db "Broken pipe",10 ;32 + %endmacro + +%else +%ifdef W32 ;----------------------- W I N 32 ----------------------- +%define W32LF ;<-- controls linefeed style + +STD_INPUT_HANDLE equ -10 +STD_OUTPUT_HANDLE equ -11 +ENABLE_WINDOW_INPUT equ 8 +FILE_ATTRIBUTE_NORMAL equ 128 +OPEN_EXISTING equ 3 +CREATE_ALWAYS equ 2 +GENERIC_READ equ $80000000 +GENERIC_WRITE equ $40000000 +INVALID_HANDLE_VALUE equ -1 +FOREGROUND_BLUE equ 1 +FOREGROUND_GREEN equ 2 +FOREGROUND_RED equ 4 +FOREGROUND_INTENSITY equ 8 +DARKWHITE equ (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED) +WHITE equ (DARKWHITE|FOREGROUND_INTENSITY) +BACKGROUND_BLUE equ 16 +YELLOW_BLUE equ FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY|BACKGROUND_BLUE +YELLOW_BLUE_TWICE equ YELLOW_BLUE| (YELLOW_BLUE<<16) +LEFT_ALT_PRESSED equ 2 +CTRL_PRESSED equ 12 +VK_SPACE equ 0x0020 +VK_PRIOR equ 0x0021 +VK_DELETE equ 0x002E +CF_OEMTEXT equ 7 + +extern MessageBoxA,MessageBeep,ExitProcess +extern GetStdHandle,GetCommandLineA,GetLastError,SetConsoleTextAttribute +extern SetConsoleMode,GetConsoleScreenBufferInfo,SetConsoleCursorPosition +extern WriteFile,ReadFile,CreateFileA,CloseHandle,SetFilePointer,MoveFileA,DeleteFileA +extern FillConsoleOutputAttribute,WaitForSingleObject,ReadConsoleA,ReadConsoleInputA +extern FlushConsoleInputBuffer,WriteConsoleOutputCharacterA,WriteConsoleOutputAttribute +extern HeapCreate,HeapAlloc,HeapFree,HeapDestroy,OpenClipboard,EmptyClipboard +extern SetClipboardData,GetClipboardData,IsClipboardFormatAvailable,CloseClipboard + %define W32_EXTENDED_IO + %undef USE_PIPE + +MAXERRNO equ 32 +ERRNOMEM equ 8 +ERRNOIO equ 7 + + %macro errortext 0 +db "invalid function",10 ;1 +db "file not found",10 ;2 +db "path not found",10 ;3 +db "too many open files",10 ;4 +db "access denied",10 ;5 +db "invalid handle",10 ;6 +db "I/O error",10 ;7 +db "not enough memory",10 ;8 +db 10 ;9 +db 10 ;10 +db 10 ;11 +db 10 ;12 +db 10 ;13 +db 10 ;14 +db 10 ;15 +db 10 ;16 +db 10 ;17 +db 10 ;18 +db 10 ;19 +db 10 ;20 +db 10 ;21 +db 10 ;22 +db 10 ;23 +db 10 ;24 +db 10 ;25 +db 10 ;26 +db 10 ;27 +db 10 ;28 +db 10 ;29 +db 10 ;30 +db 10 ;31 +db "sharing violation",10 ;32 + %endmacro + +%else ;----------------------- END OS ----------------------- +%error no OS defined +%endif +%endif +%endif +%endif +%endif +%endif + + +%ifdef TERMIOS_SET +%define tcflag_t resd +%define cc_t resb + + struc termios_struc +.c_iflag: tcflag_t 1 +.c_oflag: tcflag_t 1 +.c_cflag: tcflag_t 1 +.c_lflag: tcflag_t 1 +.c_line: cc_t 1 +%ifdef speed_t1 +c_ixxxxx: speed_t1 1 +c_oxxxxx: speed_t1 1 +%endif +.c_cc: cc_t NCCS +%ifdef speed_t2 +res: resd 3 +c_ixxxxx: speed_t2 1 +c_oxxxxx: speed_t2 1 +%endif +%ifdef speed_t3 +c_ispeed speed_t3 1 +c_ospeed speed_t3 1 +%endif + endstruc + + struc winsize_struc +.ws_row:resw 1 +.ws_col:resw 1 +.ws_xpixel:resw 1 +.ws_ypixel:resw 1 + endstruc + +%ifndef IXON ;all except *BSD +%define ICRNL 0000400q +%define IXON 0002000q +%define ICANON 0000002q +%define ISIG 0000001q +%define ECHO 0000010q +%define TSize byte +%endif +%endif + +;------- +%ifndef LINUX + %undef CRIPLED_ELF +%endif +; +%ifdef LESSWRITEOPS ;constraints + %define LESSWRITEOPS_OR_CURSORMGNT +%endif +%ifdef CURSORMGNT + %define LESSWRITEOPS_OR_CURSORMGNT +%endif + +stdtxtlen equ 10 ;do not move this to EOF: code size would increase + +%ifdef FREEBSD +SIGCONT equ 19 +SIGSTOP equ 17 +O_WRONLY_CREAT_TRUNC equ 601h ;see fcntl.h +%else +%ifdef QNX +O_WRONLY_CREAT_TRUNC equ 1401q +%else +O_WRONLY_CREAT_TRUNC equ 1101q +%endif +%endif + +O_RDONLY equ 0 +PERMS equ 644q +stdin equ 0 +stdout equ 1 +optslen equ 124 +TAB equ 8 +TABCHAR equ 09h +SPACECHAR equ ' ' +CHANGED equ '*' +UNCHANGED equ SPACECHAR +LINEFEED equ 0ah +NEWLINE equ LINEFEED +RETURN equ 0dh +SEDBLOCK equ 4096 + + + + +;-------------------------------------------------------------------------- +%ifdef CRIPLED_ELF +; +; building e3 via "nasm -f bin ...." using an idea from +;"A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux" +; + %macro ELFheader 0 +ehdr: db 0x7F, "ELF", 1, 1, 1, 0 ;Elf32_Ehdr starts here + dd 0,0 + dw 2 ;e_type + dw 3 ;e_machine + dd 1 ;e_version + dd _start ;e_entry + dd phdr1- $$ ;e_phoff + dd 0 ;e_shoff + dd 0 ;e_flags + dw ehdrsize ;e_ehsize + dw phdrsize ;e_phentsize + dw 2 ;e_phnum +phdr1: ;Elf32_Phdr starts here + dd 1 ;both p_type and e_shentsize,e_shnum + dw 0 ;both p_offset and e_shstrndx +ehdrsize equ $ - ehdr + dw 0 + dd $$ ;p_vaddr + dd $$ ;p_paddr + dd filesize ;p_filesz + dd filesize ;p_memsz + dd 5 ;p_flags i.e. READ/EXECUTE + dd 0; 0x1000 ;p_align +phdrsize equ $ - phdr1 +phdr2: ;another Elf32_Phdr starts here + dd 1 ;p_type + dd filesize + dd $$+filesize + dd $$+filesize + dd 0 ;p_filesz + dd bsssize ;p_memsz + dd 6 ;p_flags i.e. READ/WRITE + dd 0; 0x1000 ;p_align + %endmacro +%endif +;------- + %macro ORGheader 0 +%ifdef USE_SPECIAL_HEADER +%ifdef TINLINK + org 0x800004A ;see file contrib/README.tinlink624 +%else + org 0x8048000 + ELFheader +%endif +%else + ;nothing +%endif + %endmacro +;------- +%ifdef DYN ;DYN == "libc dynamic linked" + %define _start main ;call it "main", libc startup code expects this name +%endif +;-------------------------------------------------------------------------- @@ -0,0 +1,370 @@ +<!-- manual page source format generated by PolyglotMan v3.0.9, --> +<!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> + +<HTML> +<HEAD> +<TITLE>E3(1) manual page</TITLE> +</HEAD> +<BODY bgcolor=white> +<A HREF="#toc">Table of Contents</A><P> +<P> + +<H2><A NAME="sect0" HREF="#toc0">Name</A></H2> +E3 - A mini text editor <P> + +<H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> +<B>e3[ws|em|pi|vi|ne]</B> [filename] <P> + +<H2><A NAME="sect2" HREF="#toc2">Description</A></H2> +<P> +<I>e3</I> +is a complete mini application written fully in assembler, with a code +size less than 10000 byte. There is a status & input line, where you can +enter filenames, blocknames, find-texts and line numbers. The editor commands +are similary the families of <I>Wordstar</I>-like or <I>Emacs</I> or <I>Pico</I> or <I>vi</I> or <I>Nedit</I> +editors. For online help press ESC:h in vi mode, else Alt-H. This man page +describes Wordstar key bindings only. <P> + +<H2><A NAME="sect3" HREF="#toc3">Keyboard Commands for Ws</A></H2> +<P> + +<DL> + +<DT><B>^A </B></DT> +<DD>Go word +left </DD> + +<DT><B>^C </B></DT> +<DD>Go page down </DD> + +<DT><B>^D </B></DT> +<DD>Go right </DD> + +<DT><B>^E </B></DT> +<DD>Go up </DD> + +<DT><B>^F </B></DT> +<DD>Go word right </DD> + +<DT><B>^G </B></DT> +<DD>Delete current +character </DD> + +<DT><B>^H </B></DT> +<DD>Delete left character </DD> + +<DT><B>^I </B></DT> +<DD>Tabulator </DD> + +<DT><B>^J </B></DT> +<DD>Get online help </DD> + +<DT><B>^KB </B></DT> +<DD>Set +block start marker </DD> + +<DT><B>^KC </B></DT> +<DD>Copy current block </DD> + +<DT><B>^KD </B></DT> +<DD>Save file and load a new one +</DD> + +<DT><B>^KK </B></DT> +<DD>Set block end marker </DD> + +<DT><B>^KQ </B></DT> +<DD>Abort editing and exit. Confirm with Y or y that +your changes are lost. </DD> + +<DT><B>^KR </B></DT> +<DD>Insert a file as a new block </DD> + +<DT><B>^KS </B></DT> +<DD>Save file and +continue editing </DD> + +<DT><B>^KV </B></DT> +<DD>Move current block inside file </DD> + +<DT><B>^KW </B></DT> +<DD>Save a block into +a file </DD> + +<DT><B>^KX </B></DT> +<DD>Save file and exit </DD> + +<DT><B>^KY </B></DT> +<DD>Delete text a block </DD> + +<DT><B>^KZ </B></DT> +<DD>Suspend (simple +^Z in other editor modes) </DD> + +<DT><B>^L </B></DT> +<DD>Repeat last ^QF or ^QA </DD> + +<DT><B>^M </B></DT> +<DD>Enter new line </DD> + +<DT><B>^QA </B></DT> +<DD>Search +& Replace (a prompt appears). For options compare ^QF. </DD> + +<DT><B>^QB </B></DT> +<DD>Go to block begin +</DD> + +<DT><B>^QC </B></DT> +<DD>Go to end of file </DD> + +<DT><B>^QD </B></DT> +<DD>Go to end of line </DD> + +<DT><B>^QE </B></DT> +<DD>Go to top of screen: 1st columne, +1st line </DD> + +<DT><B>^QF </B></DT> +<DD>Find a text string (a prompt appears). Valid options are <I>C</I>ase +sensitive and <I>B</I>ackward. You could abort via pressing ^U . This options are +equal to <I>e3em</I>, <I>e3pi</I>, <I>e3ne</I>, but their abort keys are ^G and ^C. </DD> + +<DT><B>^QG </B></DT> +<DD>Delete character +under cursor </DD> + +<DT><B>^QG </B></DT> +<DD>Delete character left of cursor </DD> + +<DT><B>^QH,^Q(Del) </B></DT> +<DD>Delete up to +line begin </DD> + +<DT><B>^QI </B></DT> +<DD>Go to line number (prompt appears) </DD> + +<DT><B>^QK </B></DT> +<DD>Go to block end </DD> + +<DT><B>^QR +</B></DT> +<DD>Go to file begin </DD> + +<DT><B>^QS </B></DT> +<DD>Go to line begin </DD> + +<DT><B>^QV </B></DT> +<DD>Go to last postion of find </DD> + +<DT><B>^QW </B></DT> +<DD>Go +to previous word </DD> + +<DT><B>^QX </B></DT> +<DD>Go to bottom of window (last line, end of line) </DD> + +<DT><B>^QY +</B></DT> +<DD>Delete to line end </DD> + +<DT><B>^QZ </B></DT> +<DD>Go to next word </DD> + +<DT><B>^R </B></DT> +<DD>Go page up </DD> + +<DT><B>^S </B></DT> +<DD>Go left </DD> + +<DT><B>^T </B></DT> +<DD>Delete to +next word </DD> + +<DT><B>^U </B></DT> +<DD>Undo the last operation. Also abort input in status line (this +is used for ^QI,^QF,^KR,^KW etc.) </DD> + +<DT><B>^V </B></DT> +<DD>Toggle insert mode </DD> + +<DT><B>^W </B></DT> +<DD>Scroll up </DD> + +<DT><B>^X </B></DT> +<DD>Go down +</DD> + +<DT><B>^Y </B></DT> +<DD>Delete current line </DD> + +<DT><B>^Z </B></DT> +<DD>Scroll down <P> + <P> + </DD> +</DL> + +<H2><A NAME="sect4" HREF="#toc4">Undo Operation Details</A></H2> +<P> +<I>e3</I> has an UNDO +mode starting in v2.2. There is no predefined UNDO level count. You can expect +to UNDO at least <I>one</I> last insert-, delete-, overwrite- or sed_pipe-operation, +but in most cases there are <I>lots</I> of UNDO stages available. e3 has a fixed +size undo buffer and will use an external helper file if some deleted +data is bigger sized than the undo buffer. This buffer is organized as +a ring, overwriting older UNDO information if neccessary. So one never +can say exactly how many UNDO operations are possible. For using the UNDO +press one of: +<DL> + +<DT><B>^U </B></DT> +<DD>in Wordstar mode </DD> + +<DT><B>^QU </B></DT> +<DD>in Pico mode </DD> + +<DT><B>^_ </B></DT> +<DD>in Emacs mode </DD> + +<DT><B>u </B></DT> +<DD>in vi +command mode </DD> + +<DT><B>^U </B></DT> +<DD>in Nedit mode <P> + </DD> +</DL> + +<H2><A NAME="sect5" HREF="#toc5">Built in Calculator</A></H2> +<P> +<I>e3</I> has an arithmetic calculator +built in for some simple arithmetic calculations inside your text. Place +cursor at begin of the task i.e. something like: -3.002*-(2--3)= and press +one of: +<DL> + +<DT><B>^KN </B></DT> +<DD>in Wordstar mode </DD> + +<DT><B>^QC </B></DT> +<DD>in Pico mode </DD> + +<DT><B>^X^N </B></DT> +<DD>in Emacs mode </DD> + +<DT><B># </B></DT> +<DD>in vi command +mode </DD> + +<DT><B>^K </B></DT> +<DD>in Nedit mode </DD> +</DL> +<P> +This will insert the result into text. Use the values +between -999999999999.999999 ... 999999999999.999999 with up to 6 decimal digits +and the operators +-*/ and parenthesis ( ). Also available are p for constant +<P> +PI and r for accessing the result of last calculation <P> + <P> + +<H2><A NAME="sect6" HREF="#toc6">Runtime Mode Switching</A></H2> +<P> +You +can switch to other editor mode by pressing one of: +<DL> + +<DT><B>^KM </B></DT> +<DD>in Wordstar mode +</DD> + +<DT><B>^QM </B></DT> +<DD>in Pico mode </DD> + +<DT><B>altX </B></DT> +<DD>in Emacs mode </DD> + +<DT><B><ESC>; </B></DT> +<DD>in vi command mode </DD> + +<DT><B>^E </B></DT> +<DD>in Nedit mode +</DD> +</DL> +<P> +e3 will set a prompt <I>SET MODE</I> . Now enter one of e3ws, e3em, e3pi, e3vi, +e3ne for setting <I>Wordstar</I>-like or <I>Emacs</I> or <I>Pico</I> or <I>vi</I> or <I>Nedit</I> style. <P> + <P> + +<P> + +<H2><A NAME="sect7" HREF="#toc7">Options</A></H2> +<P> +e3 accepts a filename for text editing. Switch the editor mode depending +of the binary name, one of <I>e3ws</I>, <I>e3em</I>, <I>e3pi</I>, <I>e3vi</I>, <I>e3ne</I> <P> + <P> + +<H2><A NAME="sect8" HREF="#toc8">Files</A></H2> +<P> + +<DL> + +<DT><B>e3 </B></DT> +<DD>is an +assembled executable for Linux, FreeBSD, NetBSD, OpenBSD, BeOS(tm), QNX(tm). +<I>e3ws</I>, <I>e3em</I>, <I>e3pi</I>, <I>e3vi</I>, <I>e3ne</I> are symbolic links to e3. </DD> + +<DT><B>e3.exe </B></DT> +<DD>is an assembled +executable for 32 bit Win versions like 95/98/ME/etc, but not suitable +for 16 bit versions of Win. </DD> + +<DT><B>e3c </B></DT> +<DD>is a 'C' compiled executable for some other +platforms, optional built. </DD> + +<DT><B>e3.hlp </B></DT> +<DD>help text file (for e3c only) </DD> + +<DT><B>e3.res </B></DT> +<DD>error +message text file (for e3c only) <P> + </DD> +</DL> + +<H2><A NAME="sect9" HREF="#toc9">Copyright</A></H2> +e3 is Copyright (c) 2000,01,02 +<P> +Albrecht Kleine <P> + This program is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. <P> + This program is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. <P> + You should have received a +copy of the GNU General Public License along with this program; if not, +write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +02139, USA. <P> + +<H2><A NAME="sect10" HREF="#toc10">Bugs</A></H2> +There probably are some, but I don't know what they are +yet. <P> + +<HR><P> +<A NAME="toc"><B>Table of Contents</B></A><P> +<UL> +<LI><A NAME="toc0" HREF="#sect0">Name</A></LI> +<LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> +<LI><A NAME="toc2" HREF="#sect2">Description</A></LI> +<LI><A NAME="toc3" HREF="#sect3">Keyboard Commands for Ws</A></LI> +<LI><A NAME="toc4" HREF="#sect4">Undo Operation Details</A></LI> +<LI><A NAME="toc5" HREF="#sect5">Built in Calculator</A></LI> +<LI><A NAME="toc6" HREF="#sect6">Runtime Mode Switching</A></LI> +<LI><A NAME="toc7" HREF="#sect7">Options</A></LI> +<LI><A NAME="toc8" HREF="#sect8">Files</A></LI> +<LI><A NAME="toc9" HREF="#sect9">Copyright</A></LI> +<LI><A NAME="toc10" HREF="#sect10">Bugs</A></LI> +</UL> +</BODY></HTML> @@ -0,0 +1,300 @@ +.TH E3 1 + +.SH NAME +E3 \- A mini text editor + +.SH SYNOPSIS +.B e3[ws|em|pi|vi|ne] +[\fifilename] + +.SH DESCRIPTION +.PP +\fIe3\fP is a complete mini application written fully in assembler, +with a code size less than 10000 byte. There is a status & input line, +where you can enter filenames, blocknames, find-texts and line numbers. +The editor commands are similary the families of \fIWordstar\fP-like +or \fIEmacs\fP or \fIPico\fP or \fIvi\fP or \fINedit\fP editors. +For online help press ESC:h in vi mode, else Alt-H. +This man page describes Wordstar key bindings only. + +.SH KEYBOARD COMMANDS FOR WS +.PP +.TP +\fB^A +Go word left +.TP +\fB^C +Go page down +.TP +\fB^D +Go right +.TP +\fB^E +Go up +.TP +\fB^F +Go word right +.TP +\fB^G +Delete current character +.TP +\fB^H +Delete left character +.TP +\fB^I +Tabulator +.TP +\fB^J +Get online help +.TP +\fB^KB +Set block start marker +.TP +\fB^KC +Copy current block +.TP +\fB^KD +Save file and load a new one +.TP +\fB^KK +Set block end marker +.TP +\fB^KQ +Abort editing and exit. Confirm with Y or y that your changes are lost. +.TP +\fB^KR +Insert a file as a new block +.TP +\fB^KS +Save file and continue editing +.TP +\fB^KV +Move current block inside file +.TP +\fB^KW +Save a block into a file +.TP +\fB^KX +Save file and exit +.TP +\fB^KY +Delete text a block +.TP +\fB^KZ +Suspend (simple ^Z in other editor modes) +.TP +\fB^L +Repeat last ^QF or ^QA +.TP +\fB^M +Enter new line +.TP +\fB^QA +Search & Replace (a prompt appears). For options compare ^QF. +.TP +\fB^QB +Go to block begin +.TP +\fB^QC +Go to end of file +.TP +\fB^QD +Go to end of line +.TP +\fB^QE +Go to top of screen: 1st columne, 1st line +.TP +\fB^QF +Find a text string (a prompt appears). Valid options are \fIC\fPase sensitive and \fIB\fPackward. +You could abort via pressing ^U . This options are equal to \fIe3em\fP, \fIe3pi\fP, \fIe3ne\fP, +but their abort keys are ^G and ^C. +.TP +\fB^QG +Delete character under cursor +.TP +\fB^QG +Delete character left of cursor +.TP +\fB^QH,^Q(Del) +Delete up to line begin +.TP +\fB^QI +Go to line number (prompt appears) +.TP +\fB^QK +Go to block end +.TP +\fB^QR +Go to file begin +.TP +\fB^QS +Go to line begin +.TP +\fB^QV +Go to last postion of find +.TP +\fB^QW +Go to previous word +.TP +\fB^QX +Go to bottom of window (last line, end of line) +.TP +\fB^QY +Delete to line end +.TP +\fB^QZ +Go to next word +.TP +\fB^R +Go page up +.TP +\fB^S +Go left +.TP +\fB^T +Delete to next word +.TP +\fB^U +Undo the last operation. Also abort input in status line (this is used for ^QI,^QF,^KR,^KW etc.) +.TP +\fB^V +Toggle insert mode +.TP +\fB^W +Scroll up +.TP +\fB^X +Go down +.TP +\fB^Y +Delete current line +.TP +\fB^Z +Scroll down + + +.SH UNDO OPERATION DETAILS +.PP +\fIe3\fP has an UNDO mode starting in v2.2. There is no predefined +UNDO level count. You can expect to UNDO at least \fIone\fP last insert-, +delete-, overwrite- or sed_pipe-operation, but in most cases there +are \fIlots\fP of UNDO stages available. e3 has a fixed size undo buffer +and will use an external helper file if some deleted data is bigger +sized than the undo buffer. This buffer is organized as a ring, +overwriting older UNDO information if neccessary. So one never can +say exactly how many UNDO operations are possible. +For using the UNDO press one of: +.TP +\fB^U +in Wordstar mode +.TP +\fB^QU +in Pico mode +.TP +\fB^_ +in Emacs mode +.TP +\fBu +in vi command mode +.TP +\fB^U +in Nedit mode + +.SH BUILT IN CALCULATOR +.PP +\fIe3\fP has an arithmetic calculator built in for some simple +arithmetic calculations inside your text. Place cursor at +begin of the task i.e. something like: -3.002*-(2--3)= +and press one of: +.TP +\fB^KN +in Wordstar mode +.TP +\fB^QC +in Pico mode +.TP +\fB^X^N +in Emacs mode +.TP +\fB# +in vi command mode +.TP +\fB^K +in Nedit mode +.PP +This will insert the result into text. +Use the values between -999999999999.999999 ... 999999999999.999999 +with up to 6 decimal digits and the operators +-*/ and parenthesis ( ). +Also available are p for constant PI and r for accessing the result +of last calculation + + +.SH RUNTIME MODE SWITCHING +.PP +You can switch to other editor mode by pressing one of: +.TP +\fB^KM +in Wordstar mode +.TP +\fB^QM +in Pico mode +.TP +\fBaltX +in Emacs mode +.TP +\fB<ESC>; +in vi command mode +.TP +\fB^E +in Nedit mode +.PP +e3 will set a prompt \fISET MODE\fP . Now enter one of e3ws, e3em, e3pi, e3vi, e3ne +for setting \fIWordstar\fP-like or \fIEmacs\fP or \fIPico\fP or \fIvi\fP or \fINedit\fP style. + + + +.SH OPTIONS +.PP +e3 accepts a filename for text editing. Switch the editor mode +depending of the binary name, one of \fIe3ws\fP, \fIe3em\fP, \fIe3pi\fP, \fIe3vi\fP, \fIe3ne\fP + + +.SH FILES +.PP +.TP +\fBe3 +is an assembled executable for Linux, FreeBSD, NetBSD, OpenBSD, BeOS(tm), QNX(tm). +\fIe3ws\fP, \fIe3em\fP, \fIe3pi\fP, \fIe3vi\fP, \fIe3ne\fP are symbolic links to e3. +.TP +\fBe3.exe +is an assembled executable for 32 bit Win versions like 95/98/ME/etc, +but not suitable for 16 bit versions of Win. +.TP +\fBe3c +is a 'C' compiled executable for some other platforms, optional built. +.TP +\fBe3.hlp +help text file (for e3c only) +.TP +\fBe3.res +error message text file (for e3c only) + +.SH COPYRIGHT +e3 is Copyright (c) 2000,01,02 Albrecht Kleine + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +.SH BUGS +There probably are some, but I don't know what they are yet. diff --git a/e3c/Makefile b/e3c/Makefile new file mode 100644 index 0000000..5b373e1 --- /dev/null +++ b/e3c/Makefile @@ -0,0 +1,35 @@ +# edit dest dir prefix if you want.... + + PREFIX='/usr/local' +# PREFIX=/boot/home +# (used /boot/home in BeOS) + +LIBDIR='$(PREFIX)/lib' +BINDIR='$(PREFIX)/bin' +MANSEC='1' +MANDIR='$(PREFIX)/man/man$(MANSEC)' + + +##_____________________________________________________________ + +CTARGET=e3c +CSOURCES=e3.c +CFLAGS = -Wall -g -O2 -fomit-frame-pointer + +all: $(CTARGET) + + +$(CTARGET): $(CSOURCES) Makefile + gcc $(CFLAGS) -DLIBDIR=\"$(PREFIX)/lib\" $(CSOURCES) -o $(CTARGET) + strip $(CTARGET) + +list: $(CSOURCES) Makefile + gcc $(CFLAGS) -Wa,-a -c -g -DLIBDIR=\"$(PREFIX)/lib\" $(CSOURCES) >e3c.list + +install: $(CTARGET) + install -d $(PREFIX) $(BINDIR) $(LIBDIR) $(MANDIR) + install -m 755 $(CTARGET) $(BINDIR) + install -m 644 e3ws.hlp $(LIBDIR) + install -m 644 e3.res $(LIBDIR) + install -m 644 $(CTARGET).man $(MANDIR)/$(CTARGET).$(MANSEC) + diff --git a/e3c/README b/e3c/README new file mode 100644 index 0000000..494aec8 --- /dev/null +++ b/e3c/README @@ -0,0 +1,16 @@ +See ../README for details on e3 + +This e3c does support WS key bindings only, +based on e3 version 0.6 . +(For comparation purposes this file is still included +as e3.asm_base_for_e3c , former labeled as build #76.) + +BTW: it might look like assembler code, +but in fact e3c is really C code (for gcc). +It was the result of some experiments in +generating C code from asm code by using +a combination of lex/yacc parser tools. + +Another hint: I have got some intersting success stories, +for example linking against dietlibc getting small binaries. +See http://www.fefe.de/dietlibc/
\ No newline at end of file diff --git a/e3c/e3.asm_base_for_e3c b/e3c/e3.asm_base_for_e3c new file mode 100644 index 0000000..89da111 --- /dev/null +++ b/e3c/e3.asm_base_for_e3c @@ -0,0 +1,2401 @@ +;---------------------------------------------------------------------- +; +; e3 v0.6 Copyright (C) 2000 Albrecht Kleine <kleine@ak.sax.de> +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +;---------------------------------------------------------------------- +;;;;;;%include 'e3.inc' ;define where the helper files are +;;;;;; ;file is created by "make" +%define LIBDIR "/usr/local/lib/" + +%ifdef LINUX + %define CURSORMGNT +%else + %undef CRIPLED_ELF +%endif +; +;---------------------------------------------------------------------- +%define LESSWRITEOPS ;NEW for e3 0.5 +; +section .text ;here it goes.... +bits 32 + +%ifdef CRIPLED_ELF +; +; building e3 via "nasm -f bin ...." using an idea from +;"A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux" +; + org 0x08048000 +ehdr: db 0x7F, "ELF", 1, 1, 1, 0 ;Elf32_Ehdr starts here + dd 0,0 + dw 2 ;e_type + dw 3 ;e_machine + dd 1 ;e_version + dd _start ;e_entry + dd phdr1- $$ ;e_phoff + dd 0 ;e_shoff + dd 0 ;e_flags + dw ehdrsize ;e_ehsize + dw phdrsize ;e_phentsize + dw 2 ;e_phnum +phdr1: ;Elf32_Phdr starts here + dd 1 ;both p_type and e_shentsize,e_shnum + dw 0 ;both p_offset and e_shstrndx +ehdrsize equ $ - ehdr + dw 0 + dd $$ ;p_vaddr + dd $$ ;p_paddr + dd filesize ;p_filesz + dd filesize ;p_memsz + dd 5 ;p_flags i.e. READ/EXECUTE + dd 0; 0x1000 ;p_align +phdrsize equ $ - phdr1 +phdr2: ;another Elf32_Phdr starts here + dd 1 ;p_type + dd filesize + dd $$+filesize + dd $$+filesize + dd 0 ;p_filesz + dd bsssize ;p_memsz + dd 6 ;p_flags i.e. READ/WRITE + dd 0; 0x1000 ;p_align +%endif +; +; +%ifdef LESSWRITEOPS ;constraints + %define LESSWRITEOPS_OR_CURSORMGNT +%endif +%ifdef CURSORMGNT + %define LESSWRITEOPS_OR_CURSORMGNT +%endif +; +global _start +; +; start with OUTER editor loop +; +_start: call SetTermStruc + call ReadResource +%ifdef BEOS + pop eax + pop ebx ;args counter (1....x) + xor esi,esi ;init for 'no args' + dec ebx + jz noarg + pop esi + mov esi,[esi] ;points to our_name0[args]0env..... + cld +prog: lodsb + or al,al + jne prog +noarg: ;continued... +%else + pop eax ;Linux: arguments # + pop ebx ;Linux: argv[0] + pop esi ;Linux: esi points to first arg (filename) +%endif +;------- +%ifdef CURSORMGNT + or esi,esi + jz moreenv +morearg:pop ecx ;arguments until NULL + or ecx,ecx + jnz morearg +;------- +moreenv:pop ecx + jecxz ReStart + cmp dword[ecx],'TERM' ;a short test for "TERM=linux" + jnz moreenv + cmp dword[ecx+5],'linu' + jnz ReStart + add byte[revvoff],boldlen ;special inverse cursor on linux terminals +%endif +;------- +ReStart:call NewFile + jc E3exit +MainCharLoop:call DispNewScreen + call RestoreStatusLine + call HandleChar + cmp byte [endeedit],0 + je MainCharLoop + xor esi,esi ;just like if no arg is present + cmp byte [endeedit],2 + je ReStart ;^KD repeat edit using another file +E3exit: call KursorStatusLine + mov ecx,text ;enter next line on terminal NEWLINE is @ byte [text] + xor edx,edx + inc edx ;mov edx,1 + call WriteFile0 +;------- +%ifdef BEOS + mov ecx,8001h ;TCSETA +%else +%ifdef LINUX + mov ecx,5402h ;TCSETS asm/ioctls.h +%else + mov ecx,802c7414h ;TIOCSETA +%endif +%endif + call IOctlTerminal0 ;restore termios settings + jmp Exit +;---------------------------------------------------------------------- +; +; MAIN function for processing keys +; +HandleChar:call ReadChar + jz ExtAscii ;DOS version got ah=0 by int 16 for F-keys and cursor keys + cmp al,1ch + jae NormChar + mov bl,al + add bl,jumps1 + jmp short CompJump2 +NormChar:call CheckMode + jnz OverWriteChar + push eax + xor eax,eax + inc eax + call InsertByte + pop eax + jc InsWriteEnd ;error: text buffer full +OverWriteChar:cld + stosb + mov byte [changed],CHANGED +InsWriteEnd:ret +;------- +; +; helper for HandleChar +; +CtrlKMenu:mov ebx,Ktable + mov ecx,20204b5eh ;^K + jmp short Menu +CtrlQMenu:mov ebx,Qtable + mov ecx,2020515eh ;^Q +Menu: call MakeScanCode + jnc EndeRet ;if no valid scancode +ExtAscii:mov bl,ah ;don't use al (carries char e.g. TAB) + sub bl,lowest ;= scan code first key in jumptab1 + jb EndeRet + cmp bl,jumps1 + jae EndeRet +CompJump2:mov bh,0 + lea ebx,[bx] ;1 byte shorter than 'and ebx,0ffh' + movzx ebx,word [2*ebx+jumptab1] ;2*ebx is due 2 byte per entry + add ebx,_start ;offset inside code +;------- + call ebx ;the general code jump dispatcher +;------- + cmp byte [numeriere],1 ;after return from functions... + jnz BZNret ;...decide whether count current line number + push edi + mov esi,sot + xchg esi,edi + xor edx,edx +BZNLoop:inc edx ;edx=linenr counter + call LookForward + inc edi ;point to start of next line + cmp edi,esi + jbe BZNLoop + mov [linenr],edx + pop edi + mov byte [numeriere],0 +BZNret: ret +;------- +MakeScanCode:call WriteTwo ;ebx expects xlat-table + push ebx + call GetChar + pop ebx + and al,01fh + cmp al,27 + jnb EndeRet + xlatb + mov ah,al ;returns pseudo "scancode" +EndeRet:ret ;exception: ok=cy here +;---------------------------------------------------------------------- +; +; processing special keys: cursor, ins, del +; +KeyRet: call CheckMode + jnz OvrRet + call CountToLineBegin ;set esi / returns eax + inc esi + inc esi + or eax,eax + jz KeyRetNoIndent + xor eax,eax + dec eax +KeyRetSrch:inc eax ;search non (SPACE or TABCHAR) + cmp byte [esi+eax],SPACECHAR + je KeyRetSrch + cmp byte [esi+eax],TABCHAR + je KeyRetSrch +KeyRetNoIndent: + push esi + push eax ;eax is 0 or =indented chars + call GoDown + pop eax + push eax + inc eax ;1 extra for 0ah + call InsertByte + pop ecx ;# blanks + pop esi ;where to copy + jc SimpleRet + inc dword [linenr] + mov al,NEWLINE + cld + stosb + jecxz SimpleRet + rep movsb ;copy upper line i.e. SPACES,TABS into next +SimpleRet:ret +OvrRet: xor eax,eax + mov [ch2linebeg],eax + jmp short DownRet +;------- +KeyDown:call CountColToLineBeginVis +DownRet:call GoDown + call LookLineDown + jmp short SetColumn +;------- +KeyUp: call GoUp + call CountColToLineBeginVis + call LookLineUp + jmp short SetColumn +;------- +KeyPgUp:call CountColToLineBeginVis + call LookPageUp + jmp short SetColumn +;------- +KeyPgDn:call CountColToLineBeginVis + call LookPgDown ;1st char last line +;------- +SetColumn:mov ecx,[ch2linebeg] ;maximal columns + xor edx,edx ;counts visible columns i.e. expand TABs + dec edi +SCloop: inc edi + cmp edx,ecx ;from CountColToLineBeginVis + jae SCret + cmp byte [edi],NEWLINE ;don't go beyond line earlier line end + jz SCret + cmp byte [edi],TABCHAR + jz SCtab + inc edx ;count columns + jmp short SCloop +SCtab: call SpacesForTab + add dl,ah + cmp edx,ecx ;this tab to far away right? + jna SCloop ;no +SCret: ret +;------- +KeyHome:call CountToLineBegin + sub edi,eax + ret +;------- +KeyEnd: call CountToLineEnd + add edi,eax ;points to a 0ah char + ret +;------- +KeyIns: not byte [insstat] + ret +;------- +KeyDell:call KeyLeft + jz KeyDell2 +KeyDel: cmp edi,ebp + jnb KeyLeftEnd + xor eax,eax ;delete one @ cursor + inc eax + jmp DeleteByte +KeyDell2:cmp edi, sot ;delete newline char + jbe KeyLeftEnd + dec dword [linenr] + dec edi + jmp KeyCtrlT1 +;------- +KeyLeft:cmp byte [edi-1],NEWLINE ;FIXME another check of BOF + jz KeyLeftEnd ;jmp if at BOL + dec edi +KeyLeftEnd:ret +;------- +KeyRight:cmp byte [edi],NEWLINE + jz KeyRightEnd ;at right margin + inc edi +KeyRightEnd:ret +;------- +KeyCLeft3:cmp edi, sot + jbe KeyCLEnd + dec edi +KeyCtrlLeft:call KeyLeft + jz KeyCLeft3 + cmp byte [edi],2fh + jbe KeyCtrlLeft + cmp byte [edi-1],2fh + ja KeyCtrlLeft +KeyCLEnd:ret +;------- +KeyCRight3:call CheckEof + jae KeyCREnd + inc edi +KeyCtrlRight:call KeyRight + jz KeyCRight3 + cmp byte [edi],2fh + jbe KeyCtrlRight + cmp byte [edi-1],2fh + ja KeyCtrlRight +KeyCREnd:ret +;---------------------------------------------------------------------- +; +; processing special keys from the Ctrl-Q menu +; +KeyCtrlQE:call LookPgBegin ;goto top left on screen + call KursorFirstLine + jmp short CQFNum +;------- +KeyCtrlQX:call LookPgEnd ;1st goto last line on screen + call KeyEnd ;2nd goto line end + call KursorLastLine + jmp short CQFNum +;------- +KeyCtrlQV:cmp byte [bereitsges],0 ;goto last ^QA,^QF pos + jz CtrlQFEnd + mov edi,[oldQFpos] + jmp short CQFNum +;------- +KeyCtrlQA:mov byte [bereitsges],2 + call AskForReplace + jc CtrlQFEnd +CQACtrlL:push edi + call FindText + jc CtrlQFNotFound + mov eax,[suchlaenge] + call DeleteByte + mov eax,[repllaenge] + call InsertByte + mov esi,replacetext + call MoveBlock + jmp short CQFFound +;------- +KeyCtrlQF:mov byte [bereitsges],1 + call AskForFind + jc CtrlQFEnd +CQFCtrlL:push edi + call FindText + jc CtrlQFNotFound +CQFFound:mov [oldQFpos],edi + pop esi ;dummy +CQFNum: mov byte [numeriere],1 + ret +CtrlQFNotFound:pop edi +CtrlQFEnd:ret +;------- +KeyCtrlQC:mov edi,ebp + jmp short CQFNum +;------- +KeyCtrlQR:mov edi,sot + jmp short CQFNum +;------- +KeyCtrlQP:mov edi,[veryold] + jmp short CQFNum +;------- +KeyCtrlL:mov al,[bereitsges] ;2^QA 1^QF 0else + dec al + jz CQFCtrlL + dec al + jz CQACtrlL +SimpleRet4:ret +;------- +KeyCtrlQB:xchg eax,edi + mov edi,[blockbegin] +CtrlQB2:or edi,edi ;exit of no marker set + jnz CQFNum + xchg edi,eax + ret +;------- +KeyCtrlQK:xchg eax,edi + mov edi,[blockende] + jmp short CtrlQB2 +;------- +KeyCtrlQI:call GetAsciiToInteger + jc SimpleRet4 + mov edi,sot + call LookPD2 +JmpCQFN:jmp short CQFNum +;------- +KeyCtrlQDel:call KeyLeft ;delete all left of cursor + call CountToLineBegin + sub edi,eax + call DeleteByteCheckMarker + jmp short KeyCtrlT1 +;------- +KeyCtrlQY:call CountToLineEnd + jmp short CtrlTEnd1 +;------- +KeyCtrlY:call CountToLineBegin + sub edi,eax ;edi at begin + call CountToLineEnd + call DeleteByteCheckMarker + jmp short KeyCtrlT1 +;------- +KeyCtrlT:call CountToWordBegin + cmp byte [edi],NEWLINE + jnz CtrlTEnd1 +KeyCtrlT1:call CheckEof + jz SimpleRet4 + xor eax,eax + inc eax ;1 for 0ah +CtrlTEnd1:jmp DeleteByteCheckMarker +;---------------------------------------------------------------------- +; +; processing special Keys from Ctrl-K menu +; +KeyCtrlKY:call CheckBlock + jc SimpleRet3 ;no block: no action + mov eax,[blockende] + mov edi,esi ;esi is blockbegin (side effect in CheckBlock) + sub eax,esi ;block length + call DeleteByte ;out ecx:=0 + mov [blockende],ecx ;i.e. NO block valid now + mov [blockbegin],ecx + jmp short JmpCQFN +;------- +KeyCtrlKH:xor byte [showblock],1 ;flip flop +SimpleRet3:ret +;------- +KeyCtrlKK:mov [blockende],edi + jmp short KCKB +;------- +KeyCtrlKW:call CheckBlock + jc SimpleRet2 ;no action + call SaveBlock + jmp short CtrlKREnd +;------- +KeyCtrlKC:call CopyBlock + jc SimpleRet2 +CtrlKC2:mov [blockbegin],edi + add eax,edi + mov [blockende],eax + ret +;------- +KeyCtrlKV:call CopyBlock + jc SimpleRet2 + push edi + cmp edi,[blockbegin] + pushf + mov edi,[blockbegin] + call DeleteByte + neg eax ;(for optimizing eax is negated there) + popf + pop edi + jb CtrlKC2 + mov [blockende],edi + sub edi,eax +KeyCtrlKB:mov [blockbegin],edi +KCKB: mov byte [showblock],1 +SimpleRet2:ret +;------- +KeyCtrlKR:call ReadBlock + jc CtrlKREnd + call KeyCtrlKB + add ecx,edi + mov [blockende],ecx +CtrlKREnd:jmp RestKursPos +;------- +KeyCtrlKS:call SaveFile + pushf ;(called by ^kd) + call RestKursPos + popf + jc CtrlKSEnd + mov byte [changed],UNCHANGED +CtrlKSEnd:ret +;------- +KeyCtrlKQ:cmp byte [changed],UNCHANGED + jz KCKXend + mov esi,asksave + call DE1 + call RestKursPos + and al,0dfh + cmp al,'Y' + jnz KCKXend ;Y for request SAVE changes +KeyCtrlKX:call KeyCtrlKS + jc CtrlKSEnd +KCKXend:inc byte [endeedit] +KeyKXend:ret +KeyCtrlKD:call KeyCtrlKS + jc CtrlKSEnd + mov byte [endeedit],2 + ret +;--------------------------------------------------------------------- +; +; the general PAGE DISPLAY function: called after any pressed key +; +; side effect: sets 'columne' for RestoreStatusLine function (displays columne) +; 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: + 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 + call CountColToLineBeginVis ;i.e. expanding TABs + mov ebx,[columns] + cmp eax,ebx + jb DispShortLine + sub eax,ebx + inc eax + mov [zloffst],eax +DispShortLine:call LookPgBegin ;go on 1st char upper left on screen + mov esi,edi ;esi for reading chars from text + mov ecx,[lines] + jecxz KeyKXend ;window appears too small + cld + mov bh,0 ;first line + dec bh +DispNewLine: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 +%endif +DispCharLoop: + 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 +%endif +DispCharL1: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 ELZ2 +ELZ: cmp esi,ebp + jnz ELZ6 + inc esi ;set esi>ebp will later trigger "ja FillLine" + jmp short ELZ2 +ELZ6: 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],ah +ELZ2: mov al,SPACECHAR +ELZ3: cmp al,NEWLINE + jz FillLine + cmp al,SPACECHAR + jae ELZ9 ;simply ignore chars like carriage_return etc. + mov al,'.' +ELZ9: cmp al,7fh + jne ELZ8 + mov al,'.' +ELZ8: 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 only +ELZ5: 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 FillLine2 +FillLine1:rep stosB ;store the rest blanks +FillLine2:pop ecx + mov byte[edi],0 + call ScreenLineShow + dec ecx + jnz near DispNewLine + mov edi,[fileptr] ;restore text pointer + jmp RestKursPos +;---------------------------------------------------------------------- +; three helper subroutines called by DispNewScreen +; dealing ESC sequences for character attributes +; +%ifdef LESSWRITEOPS_OR_CURSORMGNT +SetInverseStatus:push ecx ;returns zero flag + push esi + mov ecx,boldlen + 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 SIS2 +SIS1: cmp byte[inverse],1 + jnz SIS3 + mov byte[inverse],0 +SIS6: mov byte[isbold],0 +SIS5: mov esi,bold0 +SIS2: rep movsb +SIS3: clc +SIS4: pop esi + pop ecx + ret +%endif +;------- +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],1 +SCEsc2: mov esi,bold1 + jmp short SIS2 +SCEsc1: cmp byte [isbold],0 ;ditto + jz SIS4 + jmp short SIS6 +;------- +%ifdef LESSWRITEOPS +SetColor2:push ecx + push esi + call IsShowBlock + jnc SIS5 + jmp short SCEsc2 +%endif +; +;------- +; 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_ret +SBlock: clc +SB_ret: push byte boldlen + pop ecx + 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 BEOS + mov ecx,800Ch ;TCGETA+13 +%else +%ifdef LINUX + mov ecx,5413h ;asm/ioctls.h: #define TIOCGWINSZ 0x5413 +%else + mov ecx,40087468h +%endif +%endif + mov edx,winsize + call IOctlTerminal + mov eax,[edx] ;each 16 bit lines,columns + or eax,eax + jnz noerr + mov eax,0x00500018 ;i.e. (80<<16)+24 (assume 80x24) +noerr: dec al ;without status line + mov byte [lines],al + shr eax,16 + mov byte [columns],al ;columns > 255 are ignored... + ret +;---------------------------------------------------------------------- +; +; 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],ecx +StatusLineShow:xor ecx,ecx ;0 for last line +; +ScreenLineShow:pusha ;expecting in ecx screen line counted from 0 +%ifdef LESSWRITEOPS + mov eax,[columns] + add eax,32 ;estimated max ESC sequences extra bytes (i.e. boldlen*X) + mul ecx ;setting edx to 0 + mov ebx,edx ;flag + lea edi,[eax+screenbuffer] +%else + xor edx,edx +%endif + cld + mov esi,screenline +sl3: 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],al +sl5: inc ebx ;set flag whether line need redrawing +sl4: inc edi +%endif + or al,al + jnz sl3 + dec edx ;one too much +%ifdef LESSWRITEOPS + or ebx,ebx ;redraw ? + jz NoWrite ;..no: quick exit +%endif + push edx + xor edx,edx + mov dh,byte [lines] + sub dh,cl + 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 +NoWrite:popa + ret +;------- +; a helper for ScreenLineShow +; +sys_writeSLColors: + jecxz syswSL ;do nothing if not in status line + ret +syswSL: pusha + xchg eax,ecx ;parameter points to ESC-xxx color string + mov edx,scolorslen + call WriteFile0 + popa + ret +;---------------------------------------------------------------------- +; +; getting line INPUT from terminal / UNDER CONSTRUCTION +; +; expecting pointer to message text in esi +; +InputStringWithMessage: + call WriteMess9MakeLine + mov ecx,optbuffer + push byte optslen + pop edx + jmp short InputString +InputString0: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 abort via ^U) +; +InputString:push ecx + push edi + push dword [kurspos2] + mov ebx,[columns] + sub ebx,stdtxtlen + cmp edx,ebx ;TODO enable some scrolling: + jb IS8 ;not yet ready, so truncate at end of line + mov edx,ebx +IS8: xor ebx,ebx +;;;; mov [bufptr],ecx + mov edi,ecx +IS0: push ebx + push edx + mov byte [kurspos2],bl ;colum + add byte [kurspos2],stdtxtlen ;offset + mov bl,byte[lines] ;line# + mov byte [kurspos2+1],bl +%ifdef LESSWRITEOPS + mov byte [screenbuffer],0 ;switching off usage of buffer v0.7 +%endif + call StatusLineShow + call GetChar + pop edx + pop ebx + cld + cmp al,15h ;^U abort (WStar) + jne IS9 + xor ebx,ebx ;length 0 triggers CY flag + jmp short IS1 +IS9: cmp al,NEWLINE + 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: mov al,0 + stosb ;make asciz string + pop dword [kurspos2] + pop edi + pop ecx + xchg eax,ebx + cmp al,1 ;set cy flag if empty string (len always <256) + ret +;---------- +; +; GetChar returns ZERO flag for non ASCII (checked in HandleChar) +; +ReadChar:mov eax,edi + xchg eax,[old] ;for ^QP + mov [veryold],eax +GetChar:call ReadOneChar + cmp al,7FH + jne RC_No7F ;special case: remap DEL to Ctrl-H + mov al,8 +RC_No7F:cmp al,27 ;ESC ? + jnz near RCready_2 + call ReadOneChar ;dont care whether '[' or 'O' (should be) or any else + call ReadOneChar ;e.g. [ for vt220,rxvt family O for xterm,vt100 family + mov bl,47h ;47h home - the lowest + cmp al,'1' + jz RC_Tilde + cmp al,'7' ;(on rxvt only) + jz RC_Tilde + cmp al,'H' + jz RCready ;(on xterm only) + inc bl ;48h up + cmp al,'A' + jz RCready + inc bl ;49h PgUp + cmp al,'5' + jz RC_Tilde +%ifndef LINUX + cmp al,'I' + jz RCready +%endif + inc bl + inc bl ;4Bh left + cmp al,'D' + jz RCready + inc bl + inc bl ;4Dh right + cmp al,'C' + jz RCready + inc bl + inc bl ;4Fh end + cmp al,'4' + jz RC_Tilde + cmp al,'8' ;(on rxvt only) + jz RC_Tilde + cmp al,'F' ;(on xterm only) + jz RCready + inc bl ;50h down + cmp al,'B' + jz RCready + inc bl ;51h PgDn + cmp al,'6' + jz RC_Tilde +%ifndef LINUX + cmp al,'G' + jz RCready +%endif + inc bl ;52h insert + cmp al,'2' + jz RC_Tilde +%ifndef LINUX + cmp al,'L' + jz RCready +%endif + inc bl ;53h del + cmp al,'3' + jnz short RCready_2 ;slightly ignore this chars +RC_Tilde:push ebx + call ReadOneChar ;read another ~ (after integer 1..8) + pop ebx + cmp al,'~' + jnz near GetChar ;could be F7,sF2 etc on linuxterm: ignored +;------- +RCready:xor eax,eax + mov ah,bl +RCready_2:or al,al ;was similar in old DOS version (via BIOS int 16h) + ret +;------- +SetTermStruc: +%ifdef BEOS + mov ecx,8000h ;TCGETA +%else +%ifdef LINUX + mov ecx,5401h ;TCGETS asm/ioctls.h +%else + mov ecx,402c7413h ;TIOCGETA +%endif +%endif + mov edx,orig + call IOctlTerminal0 + mov esi,edx + mov edi,termios + mov edx,edi + push byte termios_size ;prepare a copy of original settings + pop ecx + cld + rep movsb +;------- +%ifdef BEOS + and byte [edx+12],(~2 & ~1 & ~8);icanon off, isig (^C) off, echo off + and byte [edx+ 1],(~4) ;ixon off was: and word [edx+ 0],(~400h) + mov ecx,8001h ;TCSETA +%else +%ifdef LINUX + and byte [edx+12],(~2 & ~1 & ~8);icanon off, isig (^C) off, echo off + and byte [edx+ 1],(~4) ;ixon off was: and word [edx+ 0],(~400h) + mov byte [edx+23],1 ;set min=1 ->needed for gnome-terminal + mov ecx,5402h ;TCSETS asm/ioctls.h +%else + and word [edx+12],(~100h & ~80h & ~8h) ;icanon off, isig (^C) off, echo off + and word [edx+ 0],(~200h) + mov ecx,802c7414h ;TIOCSETA +%endif +%endif + call IOctlTerminal ;edx is termios pointer + ret +;------- +; called by ReadChar/GetChar +; +ReadOneChar:mov ecx,read_b ;pointer to buf + xor edx,edx + inc edx ;mov edx,1 (length) + call ReadFile0 + mov eax,[ecx] ;[read_b] + ret +;---------------------------------------------------------------------- +; +; 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 + 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 counter +LBa1: mov ecx,99999 + mov al,NEWLINE + std + repne scasb + lea eax,[ebx+99997] ;mov eax,99997 / add eax,ebx + sub eax,ecx +LBa5: 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 edi +CheckEof:cmp edi,ebp ;ptr is eof-ptr? + jnz CheckEnd ;Z flag if eof + jmp short CheckENum +CheckBof:cmp edi, sot-1 + ja CheckEnd +CheckENum:mov byte [numeriere],1 ;if bof +CheckEnd:ret +;------- +LookPgBegin:mov edx,[kurspos2] ;called by DispNewScreen to get sync with 1st char on screen + xor ecx,ecx + mov cl,dh ;called by KeyCtrlQE (go upper left) + inc cl + 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 less + sub [linenr],ecx + inc ecx +LookPU2:call LookBackward + jb LookPUEnd ;if BOF + inc edi + loop LookPU2 ;after loop edi points to char left of 0ah + dec edi +LookPUEnd:inc edi + inc edi ;now points to 1st char on screen or line + ret +;------- +LookPgDown:mov ecx,[lines] + dec ecx ;PgUp,PgDown one line less + add [linenr],ecx + inc ecx +LookPD2:call LookForward + jz LookPDEnd ;(jmp if EOF) + inc edi ;1st char next line + loop LookPD2 + dec edi ;last char last line +LookPDEnd: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 > ^KK +CImBlockEnd:ret ;output:cy fehler / nc ok inside block +;------- +CheckMode:cmp byte [edi],NEWLINE ;checks for INSERT status + jz ChModeEnd + cmp byte [insstat],1 +ChModeEnd: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 ? + jl CMEnd ;no + mov edx,edi ;yes so block start (^KB) to delete area start +CMEnd: 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 esi +CCV1: inc esi + cmp esi,edi + jae CCVend + cmp byte [esi],TABCHAR + jz CCVTab + inc edx ;count visible chars + jmp short CCV1 +CCVTab: call SpacesForTab ;return space_up_to_next_tab in ah + add dl,ah ;FIXME: now using 8 bits only + jmp short CCV1 +CCVend: mov [ch2linebeg],edx ;ch2linebeg: interface to Key... functions + mov eax,edx ;eax: interface to DispNewScreen + pop esi + 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 +;------- +CountToWordBegin: ;output eax=chars up there + mov esi,edi +CountNLoop:inc esi + cmp byte [esi],NEWLINE + jz CTWend + cmp byte [esi],SPACECHAR ;below SPACE includes tab chars + jbe CountNLoop + cmp byte [esi-1],2fh + ja CountNLoop +CTWend: mov eax,esi + sub eax,edi ;maybe =0 + ret +;--------------------------------------------------------------------- +; +; some CURSOR control functions +; +GoUp: mov al,0 + mov ah,-1 + jmp short UpDown +GoDown: mov al,byte [lines] + dec al + mov ah,1 +UpDown: mov edx,[kurspos2] ;former was call getkurspos + cmp dh,al + jz Goret + add dh,ah ;ONLY here we change curent line of cursor + jmp short SetKursPos +Goret: ret +;------- +; set cursor to some desired places +; +KursorFirstLine:xor edx,edx + jmp short SetKursPos +KursorLastLine:mov dh,byte [lines] + dec dh + mov dl,0 + jmp short SetKursPos +KursorStatusLine:mov dh,byte [lines] + mov dl,stdtxtlen + jmp short SetKursPos +RestKursPos:mov edx,[kurspos] +SetKursPos:mov [kurspos2],edx ;saves reading cursor pos (0,0) +sys_writeKP:pusha ;(old was: mov ah,2/mov bh,0/int 10h) + call make_KPstr + mov ecx,setkp ;second argument: pointer to message to write + push byte setkplen ;third argument: message length + pop edx + call WriteFile0 + popa + ret +;------- +; make ESC sequence appropriate to most important terminals +; +make_KPstr:inc dl ;expecting cursor pos in dh/dl (0,0) + inc dh ;both line (dh) col (dl) are counted now from 1 + cld + mov edi,setkp ;build cursor control esc string db 27,'[000;000H' + mov al,1Bh + stosb ;init memory + mov eax,'[000' + stosd + mov al,';' ;i.e. load eax with ';000' + stosd + mov al,'H' + stosb + mov edi,setkp+1+3 ;line end + xor eax,eax + mov al,dh ;DH=line + push edx + call IntegerToAscii ;make number string + pop edx + mov edi,setkp+1+3+4 ;column end + xor eax,eax + mov al,dl ;DL=col +;-------continued... +; a general helper +; expects integer# in eax +IntegerToAscii: + 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 + cld + ret +;---------------------------------------------------------------------- +; +; functions for INSERTING, COPYING and DELETING chars in text +; +InsertByte:or eax,eax ;input: eax = # of bytes edi = ptr where + jz Ins3 + mov ecx,[maxlen] ;max_len+offset-eofptr=freespace(ecx) + add ecx,sot + sub ecx,ebp + cmp ecx,eax ;cmp freespace - newbytes ;>= 0 ok/ NC <0 bad / CY + jnc SpaceAva + push byte 105 + pop dword [errno] ;(mov dword[errno],105 has 2 byte extra) + call OSerror + call RestKursPos + stc + ret +SpaceAva:push edi + 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 + std + rep movsB +Ins0: pop edi ;here is the jmp destination from DeleteByte +;------- + mov byte [changed],CHANGED + add ebp,eax + cmp edi,[blockende] + jae Ins1 + add [blockende],eax +Ins1: cmp edi,[blockbegin] + jae Ins2 + add [blockbegin],eax +Ins2: clc +Ins3: ret ;output:nc=ok/cy=bad /ecx=0/ eax inserted / -eax deleted +;------- +DeleteByteCheckMarker: ;edi points to begin + lea ebx,[edi+eax] ;ebx points to end + mov edx,[blockbegin] + call CheckMarker + mov [blockbegin],edx + mov edx,[blockende] + call CheckMarker + mov [blockende],edx +DeleteByte:or eax,eax ;input in eax + jz MoveBlEnd + push edi + mov ecx,ebp ;end + sub ecx,edi + lea esi,[edi+eax] ;current + x chars + sub ecx,eax + lea ecx,[ecx+3] ;add ecx,3 needs 3 byte more! + shr ecx,1 + cld + rep movsW + neg eax ;"neg eax" is for continuing @InsertByte + jmp short Ins0 ;pending "pop edi" +;------- +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->ok +MoveBlEnd:ret ;return eax=size +;---------------------------------------------------------------------- +; +; functions reading/writing text or blocks from/into files +; +NewFile:call InitVars + or esi,esi + jz NFnoarg + cld + mov edi,filepath +NF1: lodsb + stosb + or al,al + jnz NF1 + jmp short GetFile +NFnoarg: +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,helpfile +%else + mov ebx,helpfile ;load file with some help text (one page) +%endif + call OpenFile0 + mov edi,sot + mov ebp,edi + js GF0 + xchg ebx,eax ;mov ebx,eax is 2 byte + call OldFile1 ;Fixed in #67 +GF0: call DispNewScreen ;if not available: clear screen only +;------- + mov esi, filename + mov ecx, filepath + call InputString0 + jc NFEnd2 ;empty string not allowed here +;------- +GetFile: +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,filepath +%else + mov ebx,filepath +%endif + call OpenFile0 + mov edi,sot + mov ebp,edi + js NewFileEnd +%ifdef LINUX + call Seek + pusha + lea ebx,[eax+eax+102400] ;twice filesize plus reserve = space for inserts + mov [maxlen],ebx + add ebx,text + call SysBrk + popa + js OSejmp1 ;OSerror +%else + mov ebx,eax ;for FreeBSD memory is hard coded by maxlen +%endif +;------- + call Fstat + js OSejmp1 ;OSerror + mov eax,[fstatbuf+8] ;FIXME: define structure + and eax,777q + mov [perms],eax +%ifdef LINUX + mov eax,[fstatbuf+12] ;FIXME: define structure + mov [giduid],eax +%else +%ifndef BEOS + mov eax,[fstatbuf+12] + mov [uid],eax + mov eax,[fstatbuf+16] + mov [gid],eax +%endif +%endif +OldFile1:mov edx,[maxlen] ;i.e. either 'max' or filesize twice + mov ecx,edi ;sot + call ReadFile + xchg edx,eax ;mov edx,eax bytes read + js OSejmp0 ;OSerror + call CloseFile +OSejmp1:js OSejmp0 ;OSerror + lea ebp,[edx+sot] ;eof_ptr=filesize+start_of_text +NewFileEnd:mov byte [ebp],NEWLINE ;eof-marker + clc +NFEnd2: ret +;------- +; save file (called by ^KS,^KX) +; +SaveFile:cmp byte [changed],UNCHANGED + jz NFEnd2 ;SaveFile3 ;no changes: nothing to save + mov esi, filesave + call WriteMess9 +;------- + mov esi,filepath + push edi + mov edi,bakpath + mov ebx,esi + mov ecx,edi + cld +SF0: lodsb + stosb ;copy to BAK file path + or al,al + jne SF0 + dec edi + push byte '~' ;add BAK file extension + pop eax + stosw ;stosw not stosb because ascii-ZERO + pop edi +%ifdef BEOS + push edi + mov ebx,0xFFFFFFFF + mov edx,ebx + mov ecx,filepath + mov edi,bakpath +%endif + cmp dword [ecx],'/tmp' + je no_ren + call RenameFile ;ecx is filepath +no_ren: +%ifdef BEOS + pop edi +%endif +;------- +%ifdef BEOS + mov ebx,0xFFFFFFFF + mov ecx,filepath + mov edx,0x777 +%else + mov ecx,O_WRONLY_CREAT_TRUNC + mov edx,[perms] +%endif + call OpenFile +OSejmp0:js OSejmp9 ;OSerror + xchg ebx,eax ;file descriptor (xchg is only 1 byte) +;------- +%ifdef LINUX + mov ecx,[giduid] + mov edx,ecx + shr edx,16 + and ecx,0xffff + call ChownFile +%else +%ifndef BEOS + mov edx,[gid] + mov ecx,[uid] + call ChownFile +%endif +%endif +;------- + mov ecx,sot ;ecx=bof + mov edx,ebp ;eof +SaveFile2:sub edx,ecx ;edx=fileesize= eof-bof + call WriteFile ;ebx=file descriptor +OSejmp9:js OSejmp ;OSerror + mov word[errno],5 ;just in case of.... + cmp eax,edx ;all written? + jnz near OSerror + call CloseFile + js OSejmp ;OSerror +SaveFile3:ret +;------- +; save block (called by ^KW) +; +SaveBlock:call GetBlockName + jc near DE2 +%ifdef BEOS + mov ebx,0xFFFFFFFF + mov ecx,blockpath + mov edx,0x777 +%else + mov ecx,O_WRONLY_CREAT_TRUNC + mov ebx,blockpath + mov edx,PERMS +%endif + call OpenFile + js OSejmp ;OSerror + mov ecx,esi ;= block begin + mov edx,[blockende] + xchg ebx,eax ;file descriptor (xchg is only 1 byte) + jmp short SaveFile2 +;------- +; read a block into buffer (by ^KR) +; +ReadBlock:call GetBlockName + jc near DE2 +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,blockpath +%else + mov ebx,blockpath +%endif + call OpenFile0 +OSejmp: js OSerror + call Seek + js OSerror + push eax ;eax=fileesize + call InsertByte + pop edx ;file size + jc SaveFile3 ;ret if cy InsertByte told an error message itself + mov ecx,edi ;^offset akt ptr + call ReadFile + js preOSerror ;to delete inserted bytes (# in EDX) + mov ecx,eax ;bytes read + call CloseFile + js OSerror + mov word[errno],5 ;just in case of.... + cmp edx,ecx ;all read? + jnz OSerror + ret +;------- +preOSerror:mov eax,edx ;count bytes + call DeleteByte ;delete space reserved for insertation +OSerror:push edi + mov edi,error+8 ;where to store ASCII value of errno + mov eax,[errno] + push eax + call IntegerToAscii + pop ecx ;for getting error text via LookPD2 + mov edi,errmsgs + cmp byte [edi],0 ;are text error messages loaded ? + jz DE0 ;so no text available... + call LookPD2 ;look message # (ecx) in line number # + mov esi,edi + mov edi,error+9 + push byte 80 ;max strlen / compare errlen equ 100 + pop ecx + cld + rep movsb +DE0: mov esi,error + pop edi +DE1: call WriteMess9 + call GetChar +DE2: ;continued... +;---------------------------------------------------------------------- +; +; more STATUS LINE maintaining subroutines +; +RestoreStatusLine:pusha ;important e.g. for asksave + call InitStatusLine + mov ecx,[columns] ;width + cmp cl,stdtxtlen+15+5+2 ;this window is too small + jb RSno_lineNr + mov bl, byte [changed] + mov byte[screenline+1],bl ;changed status + mov ebx,'INS ' ;Insert + cmp byte [insstat],1 + jz RSL1 + mov ebx,'OVR ' ;Overwrite +RSL1: mov [screenline+4],ebx ;mode status + mov edi,screenline+stdtxtlen + sub ecx,stdtxtlen+15+5 ;space for other than filename + mov esi,filepath +RSL2: lodsb + or al,al + jz RSL4 + stosb + loop RSL2 +RSL4: mov edi,screenline-15 + add edi,[columns] + mov eax,[columne] + inc eax ;start with 1 + call IntegerToAscii + mov byte [edi],':' ;delimiter ROW:COL + dec edi + mov eax,[linenr] + call IntegerToAscii +RSno_lineNr:call StatusLineShow ;now write all at once + popa + stc ;error status only important if called via OSError + ret +;------- +; +; write an answer prompt into status line +; (with and without re-initialisation) +; expecting esi points to ASCIIZ or 0A terminated string +; +WriteMess9MakeLine:call InitStatusLine +WriteMess9:pusha + mov edi,screenline + cld +WriteMLoop:lodsb + or al,al + jz WriteMEnd + cmp al,0ah ;for error messages + jz WriteMEnd + stosb + jmp short WriteMLoop +WriteMEnd:call StatusLineShow + popa + jmp KursorStatusLine +;------- +; a helper for other status line functions: +; simply init an empty line +; +InitStatusLine:pusha ;simply init an empty line + mov edi,screenline + mov al,SPACECHAR + mov ecx,[columns] +%ifndef LINUX + dec ecx ;? FreeBSD +%endif + cld + rep stosb + mov al,0 ;prepare ASCIIZ string + stosb + popa + ret +;------- +; read a file name for block operations +; expecting message text ptr in esi +; +GetBlockName:pusha + mov esi,block + mov ecx,blockpath + call InputString0 ;cy if empty string + pushf + call RestKursPos + popf + popa + ret +;------- +; helper for NewFile +; +InitVars:mov byte [text],NEWLINE ;don't touch esi! + mov byte [changed],UNCHANGED + xor eax,eax + mov dword [oldQFpos],eax + mov byte[bereitsges],al + mov [blockbegin],eax + mov [blockende],eax + mov [endeedit],al + mov dword[old],sot + inc eax + mov dword [linenr],eax + mov byte [showblock],al + mov byte [insstat],al + mov dword [maxlen],max + mov dword [error],'ERRO' + mov dword [error+4],'R ' + mov dword [perms],PERMS + dec eax + dec eax +%ifdef LINUX + mov dword [giduid],eax ; eax == -1 i.e. no changes in fchown +%else +%ifndef BEOS + mov dword [gid],eax + mov dword [uid],eax +%endif +%endif + ret +;------- +ReadResource: +%ifdef BEOS + xor ebx,ebx + mov edx,ebx + dec ebx ;edx==0,ebx==-1 + mov ecx,resfile ;load file with some error message text +%else + mov ebx,resfile ;load file with some error message text +%endif + call OpenFile0 ;don't care about errors + js RRret + xchg ebx,eax ;mov file_descriptor to ebx (xchg is 1 byte only) + mov edx,errbufsize + mov ecx,errmsgs + call ReadFile + jns near CloseFile +RRret: ret +;------- +%ifdef BEOS +Seek: xchg ebx,eax ;mov file_descriptor to ebx (xchg is 1 byte only) + push byte 2 + pop edx + call SeekFile ;end + js SeekRet + xor edx,edx + push eax + call SeekFile ;home + pop eax +SeekRet:ret +%else +%ifdef LINUX +Seek: xchg ebx,eax ;mov file_descriptor to ebx (xchg is 1 byte only) + push byte 2 + pop edx + call SeekFile ;end + js SeekRet + xor edx,edx + push eax + call SeekFile ;home + pop eax +SeekRet:ret +%else ;64 bit +Seek: push edi + push esi + mov ebx,eax ;file desc + xor edx,edx + xor edi,edi + push byte 2 + pop esi + call SeekFile ;end + js SeekRet + xor esi,esi + push eax + call SeekFile ;home + pop eax +SeekRet:pop esi + pop edi + ret +%endif +%endif +;---------------------------------------------------------------------- +; +; FIND/REPLACE related stuff +; +AskForReplace:mov esi,askreplace1 + mov ecx,suchtext + call InputString0 + jc AskFor_Ex + mov [suchlaenge],eax + mov esi,askreplace2 + mov ecx,replacetext + call InputString0 + jmp short GetOptions ;cy flag is allowed here 18.6.00 +AskForFind:mov esi,askfind + mov ecx,suchtext + call InputString0 + jc AskFor_Ex +GetOptions:mov [repllaenge],eax + mov esi,optiontext + call InputStringWithMessage ;empty string is allowd for std options... + call ParseOptions ;...(set in ParseOptions) + clc +AskFor_Ex:jnc AFE2 + mov byte [bereitsges],0 +AFE2: pushf + call RestoreStatusLine + call RestKursPos + popf + ret +;------- +; check string for 2 possible options: C,c,B,b (case sensitive & backward) +; +ParseOptions:push esi + cld + mov esi, optbuffer + push byte 1 + pop dword[vorwarts] ;mov dword[vorwarts],1 is longer + mov byte[grossklein],0dfh +Scan1: lodsb + and al,5fh ;upper case + cmp al,'C' + jnz notCopt + xor byte[grossklein],20h ;result 0dfh, 2*C is like not C option +notCopt:cmp al,'B' + jnz notBopt + neg dword[vorwarts] ;similar 2*B is backward twice i.e. forward +notBopt:or al,al + jnz Scan1 + pop esi + ret +;------- +; the find subroutine itself +; +find2: mov ebx,edi +find3: lodsb + or al,al ;=end? + jz found + cmp al,41h + jb find7 + and al,ch +find7: inc edi + mov cl,byte [edi] + cmp cl,41h + jb find10 + and cl,ch +find10: cmp al,cl + jz find3 + mov edi,ebx +FindText:mov edx,[vorwarts] ;+1 or -1 + mov ch,[grossklein] ;ff or df + mov esi,suchtext + cld + lodsb + cmp al,41h + jb find1 + and al,ch +find1: add edi,edx ;+1/-1 + mov cl,byte [edi] + cmp cl,41h + jb find6 + and cl,ch +find6: cmp al,cl + je find2 + cmp edi,ebp + ja notfound + cmp edi, sot + jnb find1 +notfound:stc + ret +found: mov edi,ebx + clc ;edi points after location + ret +;---------------------------------------------------------------------- +; +; some GENERAL helper functions +; +GetAsciiToInteger: + mov esi,asklineno + call InputStringWithMessage + pushf + call AskFor_Ex ;repair status line & set cursor pos + mov esi,ecx ;optbuffer + xor ecx,ecx + xor eax,eax + popf + jc AIexit + cld +AIload: lodsb + sub al,'0' + js AIexit + cmp al,9 + ja AIexit + lea ecx,[ecx+4*ecx] + lea ecx,[2*ecx+eax] + jmp short AIload +AIexit: cmp ecx,1 ;ret ecx , cy if err + ret +;------- +; +; expects current column in edx +; returns # spaces up to next tabulated location in AH +; +SpacesForTab:push ecx + mov eax,edx + mov cl,TAB + div cl + neg ah ;ah = modulo division + add ah,TAB ;TAB - pos % TAB + pop ecx + ret +;---------------------------------------------------------------------- +; +; INTERFACE to OS kernel +; we differ between BeOS, Linux and any else (in fact only FreeBSD) +; +ReadFile0:xor ebx,ebx ;mov ebx,stdin ;file desc +ReadFile: +%ifdef BEOS + push dword 2 ;4+X? stack places + jmp short WFile +%else + mov al,3 ;system call number (sys_read) ;return read byte EAX + jmp short IntCall ;ebx file / ecx buffer / edx count byte +%endif +;------- +WriteFile0:xor ebx,ebx ;mov ebx,stdout ;file desc + inc ebx ;ditto +WriteFile: +%ifdef BEOS + mov eax,3 ;4+X? stack places + push dword 3 +WFile: pop eax + call IntRdWr + nop + nop + nop + nop + ret +%else + mov al,4 ;system call number (sys_write) + jmp short IntCall +%endif +;------- +OpenFile0: +%ifndef BEOS + xor ecx,ecx ;i.e O_RDONLY +%endif +OpenFile: +%ifdef BEOS + mov al,0 ;5 stack places + push edi + mov edi,0x1A4 + call IntCall + pop edi + ret +%else + mov al,5 ;system call number + jmp short IntCall ;ecx mode / ebx path / edx permissions (if create) +%endif + +;------- +CloseFile: +%ifdef BEOS + mov al,1 ;1 stack place +%else + mov al,6 ;system call number (close) +%endif + jmp short IntCall ;ebx is file desc +;------- +Fstat: +%ifdef BEOS + xor eax,eax ;dummy + ret +%endif + mov ecx,fstatbuf +%ifdef LINUX + mov al,108 +%else + mov al,189 +%endif + jmp short IntCall +;------- +RenameFile: +%ifdef BEOS + mov al,26h ;4 stack places + jmp short IntCall +%else +%ifdef LINUX + mov al,38 +%else + mov al,128 +%endif + jmp short IntCall +%endif +;------- +ChownFile: +%ifdef BEOS + xor eax,eax ;dummy + ret +%endif +%ifdef LINUX + mov al,95 +%else + mov al,123 ;fchown +%endif + jmp short IntCall +;------- +SysBrk: +%ifdef BEOS + xor eax,eax ;dummy + ret +%endif +%ifdef LINUX + mov al,45 ;system call number +%else + mov al,69 +%endif + jmp short IntCall ;ebx addr +;------- +IOctlTerminal0:mov edx,orig +IOctlTerminal:mov ebx,stdin ;expects EDX termios or winsize structure ptr +%ifdef BEOS + mov al,4 ;4 stack places +%else + mov al,54 ;54 == the ioctl syscall no. +%endif + jmp short IntCall ;ECX TCSETS,TCGETS,TIOCGWINSZ +;------ +Exit: +%ifdef BEOS + mov al,3fh +%else + mov al,1 +%endif + xor ebx,ebx + jmp short IntCall +;------- +SeekFile:xor ecx,ecx ;ecx offset / ebx file / edx method +%ifdef BEOS + mov al,5 ;4 stack places (using 64 bit for ptr) + push edi + push edx + mov edi,edx + xor edx,edx + call IntCall + pop edx + pop edi + ret +%else +%ifdef LINUX + mov al,19 ;system call number (lseek) +%else + xor edx,edx + xor edi,edi + mov al,199 +%endif +%endif +;------- +IntCall:mov ah,0 + cwde ;(and eax,0ffh) +%ifdef BEOS + push edi + push byte 0 + push edi + push edx + push ecx + push ebx + push dword be_ret + int 25h +be_ret: pop ebx + pop ebx + pop ecx + pop edx + pop edi + pop edi + mov [errno],eax + and dword [errno],7Fh + or eax,eax ;set flags also + pop edi +%else +%ifdef LINUX + int 80h +%else + push esi + push edi + push edx + push ecx + push ebx + push eax + call 7:0 + pop ebx + pop ebx + pop ecx + pop edx + pop edi + pop esi + jc err +%endif + neg eax +err: mov [errno],eax + neg eax ;set flags also +%endif + ret +;------- +%ifdef BEOS +IntRdWr:push edx ;used for Read & Write + push ecx + push ebx + push dword be_ret2 + int 25h +be_ret2:pop ebx + pop ebx + pop ecx + pop edx + mov [errno],eax + pop eax + add eax,4 + push eax + mov eax,[errno] + and dword [errno],7Fh + or eax,eax ;set flags + ret +%endif +;---------------------------------------------------------------------- +; +; CONSTANT DATA AREA +; +Ktable db 45h ;^K@ xlatb table for making pseudo-scancode + db 45h ;^ka 45h points to an an offset in jumptab1 + db 41h ;^kb 41h for example points to KeyCtrlKB function offset + db 43h ;^kc + db 5dh ;^kd + db 45h ;^ke 45h means SimpleRet i.e. 'do nothing' + db 45h ;^kf + db 45h ;^kg + db 57h ;^kh + db 45h ;^ki + db 45h ;^kj + db 42h ;^kk + db 45h ;^kl + db 45h ;^km + db 45h ;^kn + db 45h ;^ko + db 45h ;^kp + db 46h ;^kq + db 3dh ;^kr + db 5ch ;^ks + db 45h ;^kt + db 45h ;^ku + db 3bh ;^kv + db 3eh ;^kw + db 44h ;^kx + db 4eh ;^ky + db 45h ;^kz +Qtable db 45h ;^q@ ditto for ^Q menu + db 54h ;^qa + db 5ah ;^qb + db 61h ;^qc former 76h ctrl-PageDown + db 4fh ;^qd + db 58h ;^qe + db 55h ;^qf + db 45h ;^qg + db 4Ah ;^qh, ^qDEL + db 62h ;^qi + db 45h ;^qj + db 5bh ;^qk + db 45h ;^ql + db 45h ;^qm + db 45h ;^qn + db 45h ;^qo + db 4ch ;^qp + db 45h ;^qq + db 63h ;^qr former ctrl-PageUp + db 47h ;^qs + db 45h ;^qt + db 45h ;^qu + db 56h ;^qv + db 5Eh ;^qw former 73h ctrl-left + db 59h ;^qx + db 40h ;^qy + db 5fh ;^qz former 74h ctrl-right + +esize equ 2 ;(byte per entry) +jumptab1: ;Storing 16 bit offsets is valid only for code less size 64 kbyte... + ; ... but in assembler that should never be a problem ;) + ; The associated key values originaly were BIOS scan codes... + ; ... now using terminal device this does have less sense, so I altered some + ; ... special cases, like ^PageUp (was 84h, but extends the table too much) + ; ... to some places shortly after 5dh (i.e. shift F10). + ; Using terminals the F-keys are not yet supported (was DOS only). +lowest equ 3bh + dw KeyCtrlKV -_start ;3bh ^KV F1 (DOS only) + dw KeyCtrlL -_start ;3ch ^L F2 (ditto) + dw KeyCtrlKR -_start ;3dh ^KR F3 (etc) + dw KeyCtrlKW -_start ;3eh ^KW + dw KeyCtrlT -_start ;3fh ^T + dw KeyCtrlQY -_start ;40h ^QY + dw KeyCtrlKB -_start ;41h ^KB + dw KeyCtrlKK -_start ;42h ^KK + dw KeyCtrlKC -_start ;43h ^KC + dw KeyCtrlKX -_start ;44h ^KX F10 + dw SimpleRet -_start ;45h F11 + dw KeyCtrlKQ -_start ;46h F12 + dw KeyHome -_start ;47h + dw KeyUp -_start ;48h + dw KeyPgUp -_start ;49h + dw KeyCtrlQDel -_start ;4ah ^QDel + dw KeyLeft -_start ;4bh + dw KeyCtrlQP -_start ;(5 no num lock) + dw KeyRight -_start ;4dh + dw KeyCtrlKY -_start ;(+) ^KY + dw KeyEnd -_start ;4fh + dw KeyDown -_start ;50H + dw KeyPgDn -_start ;51h + dw KeyIns -_start ;52H + dw KeyDel -_start ;53H + dw KeyCtrlQA -_start ;54h ^QA sF1 + dw KeyCtrlQF -_start ;55h ^QF sF2 + dw KeyCtrlQV -_start ;56h + dw KeyCtrlKH -_start ;57h + dw KeyCtrlQE -_start ;58h + dw KeyCtrlQX -_start ;59h + dw KeyCtrlQB -_start ;5Ah ^QB + dw KeyCtrlQK -_start ;5Bh ^QK sF8 + dw KeyCtrlKS -_start ;5ch ^KS sF9 + dw KeyCtrlKD -_start ;5dh ^KD sF10 + ; + dw KeyCtrlLeft -_start ;5eh ^Left was 73h (compare notes above) + dw KeyCtrlRight -_start ;5fh ^Right (was 74h) + dw SimpleRet -_start ;60h ^End (was 75h) + dw KeyCtrlQC -_start ;61h ^PageDown (was 76h) + dw KeyCtrlQI -_start ;62h ^Home (was 77h) + dw KeyCtrlQR -_start ;63h ^PageUp (was 84h) +jumps1 equ ($-jumptab1) / esize + +jumptab3 dw SimpleRet -_start ;^@ (only former DOS version has a "jumptab2") + dw KeyHome -_start ;^a (compare notes above) + dw SimpleRet -_start ;^b + dw KeyPgDn -_start ;^c + dw KeyRight -_start ;^d + dw KeyUp -_start ;^e + dw KeyEnd -_start ;^f + dw KeyDel -_start ;^g 7 + dw KeyDell -_start ;^h 8 DEL (7fh is translated to this) + dw NormChar -_start ;^i 9 + dw KeyRet -_start ;^j = 0ah + dw CtrlKMenu -_start ;^k b + dw KeyCtrlL -_start ;^l c + dw SimpleRet -_start ;^m 0dh + dw SimpleRet -_start ;^n e + dw SimpleRet -_start ;^o f + dw SimpleRet -_start ;^p 10 + dw CtrlQMenu -_start ;^q 11 + dw KeyPgUp -_start ;^r 12 + dw KeyLeft -_start ;^s 13 + dw KeyCtrlT -_start ;^t 14 + dw SimpleRet -_start ;^u 15 + dw KeyIns -_start ;^v 16 + dw SimpleRet -_start ;^w 17 + dw KeyDown -_start ;^x 18 + dw KeyCtrlY -_start ;^y 19 + dw SimpleRet -_start ;^z + dw SimpleRet -_start ;esc +;------- +filename db ' NAME:',0 +filesave db ' SAVE:',0 +asksave db 'SAVE? Y/N',0 +block db 'BLK NAME:',0 +askfind db '^QF FIND:',0 +askreplace1 db '^QA REPL:',0 +askreplace2 db '^QA WITH:',0 +asklineno db '^QI LINE:',0 +optiontext db 'OPT? C/B',0 +stdtxtlen equ 10 +; +screencolors0 db 27,'[40m',27,'[37m' +bold0 db 27,'[0m' ;reset to b/w +screencolors1 db 27,'[44m',27,'[33m' ;yellow on blue +reversevideoX: +bold1 db 27,'[1m' ;bold +scolorslen equ $-screencolors1 +boldlen equ $-bold1 ;take care length of bold0 == length of bold1 +%ifdef LINUX + db 27,'[7m' ;good for "linux" terminal on /dev/tty (but not xterm,kvt) + ;again take care length = length of boldX + ;!! important: store directly after bold1 !! +%endif +; +O_WRONLY_CREAT_TRUNC equ 1101q +O_RDONLY equ 0 +PERMS equ 644q + +resfile db LIBDIR,'e3.res',0 +helpfile db LIBDIR,'e3.hlp',0 +stdin equ 0 +stdout equ 1 +; +TAB equ 8 +TABCHAR equ 09h ; ^I +SPACECHAR equ ' ' +CHANGED equ '*' +UNCHANGED equ SPACECHAR +LINEFEED equ 0ah +NEWLINE equ LINEFEED +%ifdef CRIPLED_ELF + filesize equ $ - $$ +%endif +;----------------------------------------------------------------------- +;section .data ;unused: save byte in ELF header +;bits 32 +;----------------------------------------------------------------------- +section .bss +bits 32 + +%ifdef CRIPLED_ELF + align 4 + bssstart: +%endif + +screenbuffer resb 62*(160+32) ;estimated 62 lines 160 columns, 32 byte ESC seq (ca.12k) +screenbuffer_end equ $ ;If you really have higher screen resolution, + ;...no problem, except some useless redrawing happens. +termios_size equ 60 +termios resb termios_size +orig resb termios_size + +winsize_size equ 8 +winsize resb winsize_size + +setkplen equ 10 +setkp resb setkplen ;to store cursor ESC seq like db 27,'[000;000H' +resb 2 ;fill up + +%ifdef LESSWRITEOPS_OR_CURSORMGNT +revvoff resd 1 +%endif + +;;bufptr resd 1 +lines resd 1 ;equ 24 or similar i.e. screen lines-1 (1 for statusline) +columns resd 1 ;equ 80 or similar dword (using only LSB) + +columne resd 1 ;helper for display of current column +zloffst resd 1 ;helper: chars scrolled out at left border +fileptr resd 1 ;helper for temp storage of current pos in file +kurspos resd 1 ;cursor position set by DispNewScreen() +kurspos2 resd 1 ;cursor position set by other functions + +tabcnt resd 1 ;internal helper byte in DispNewScreen() only +changed resd 1 ;status byte: (UN)CHANGED +oldQFpos resd 1 +bereitsges resd 1 ;byte used for ^L +blockbegin resd 1 +blockende resd 1 +endeedit resd 1 ;byte controls program exit +old resd 1 ;helper for ^QP +veryold resd 1 ;ditto +linenr resd 1 ;current line +showblock resd 1 ;helper for ^KH +suchlaenge resd 1 ;helper for ^QA,^QF +repllaenge resd 1 +vorwarts resd 1 +grossklein resd 1 ;helper byte for ^QF,^QA + +ch2linebeg resd 1 ;helper keeping cursor pos max at EOL (up/dn keys) +numeriere resd 1 ;byte controls re-numeration +read_b resd 1 ;buffer for getchar +isbold resd 1 ;control of bold display of ws-blocks +inverse resd 1 +insstat resd 1 +errno resd 1 ;used similar libc, but not excactly equal + +errlen equ 100 +error resb errlen ;reserved space for string: 'ERROR xxx:tttteeeexxxxtttt',0 + +maxlen resd 1 +stat resd 1 +;------- +; +maxfilenamelen equ 255 +filepath resb maxfilenamelen+1 +bakpath resb maxfilenamelen+1 + +blockpath resb maxfilenamelen+1 +replacetext resb maxfilenamelen+1 +suchtext resb maxfilenamelen+1 +optbuffer resb 8 ;buffer for search/replace options and for ^QI +optslen equ $-optbuffer + +%ifdef LINUX + giduid resd 1 +%else + uid resd 1 + gid resd 1 +%endif +perms resd 1 +fstatbuf resb 64 +screenline resb 256+4*scolorslen ;max possible columns + 4 color ESC seq per line + ;(buffer for displaying a text line) +errbufsize equ 4000 +errmsgs resb errbufsize +;------- +%ifdef LINUX +max equ 102400 ;valid for NEW created files only +%else +max equ 10240000 ;FIXME: brk in FreeBSD ?? +%endif +;------- +text resb max +sot equ (text+1) ;start-of-text + +%ifdef CRIPLED_ELF + bsssize equ $-bssstart +%endif +;---------------------------------------------------------------------- +;
\ No newline at end of file diff --git a/e3c/e3.c b/e3c/e3.c new file mode 100644 index 0000000..b21b94c --- /dev/null +++ b/e3c/e3.c @@ -0,0 +1,1796 @@ +//---------------------------------------------------------------------- +// e3.c v0.92 Copyright (C) 2000 Albrecht Kleine <kleine@ak.sax.de> +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +//--------------------------------------------------------------------- + +#ifndef __GNUC__ +#error "Sorry, but I need GNU C." +#endif + +#define CURSORMGNT +#define LESSWRITEOPS +#ifdef LESSWRITEOPS +#define LESSWRITEOPS_OR_CURSORMGNT +#endif +#ifdef CURSORMGNT +#define LESSWRITEOPS_OR_CURSORMGNT +#endif + +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> + +struct termios termios,orig; +//--------------------------------------------------------------------- +// +// CONSTANT DATA AREA +// +#define lowest 0x3b +unsigned char Ktable[]={ + 0x45 - lowest, // ^K@ xlatb table for making pseudo-scancode + 0x45 - lowest, // ^ka 45h points to an an offset in jumptab1 + 0x41 - lowest, // ^kb 41h for example points to KeyCtrlKB function offset + 0x43 - lowest, // ^kc + 0x5d - lowest, // ^kd + 0x45 - lowest, // ^ke 45h means SimpleRet i.e. 'do nothing' + 0x45 - lowest, // ^kf + 0x45 - lowest, // ^kg + 0x57 - lowest, // ^kh + 0x45 - lowest, // ^ki + 0x45 - lowest, // ^kj + 0x42 - lowest, // ^kk + 0x45 - lowest, // ^kl + 0x45 - lowest, // ^km + 0x45 - lowest, // ^kn + 0x45 - lowest, // ^ko + 0x45 - lowest, // ^kp + 0x46 - lowest, // ^kq + 0x3d - lowest, // ^kr + 0x5c - lowest, // ^ks + 0x45 - lowest, // ^kt + 0x45 - lowest, // ^ku + 0x3b - lowest, // ^kv + 0x3e - lowest, // ^kw + 0x44 - lowest, // ^kx + 0x4e - lowest, // ^ky + 0x45 - lowest}; // ^kz + +unsigned char Qtable[]={ + 0x45 - lowest, // ^q@ ditto for ^Q menu + 0x54 - lowest, // ^qa + 0x5a - lowest, // ^qb + 0x61 - lowest, // ^qc former 76h ctrl-PageDown + 0x4f - lowest, // ^qd + 0x58 - lowest, // ^qe + 0x55 - lowest, // ^qf + 0x45 - lowest, // ^qg + 0x4a - lowest, // ^qh, ^qDEL + 0x62 - lowest, // ^qi + 0x45 - lowest, // ^qj + 0x5b - lowest, // ^qk + 0x45 - lowest, // ^ql + 0x45 - lowest, // ^qm + 0x45 - lowest, // ^qn + 0x45 - lowest, // ^qo + 0x4c - lowest, // ^qp + 0x45 - lowest, // ^qq + 0x63 - lowest, // ^qr former ctrl-PageUp + 0x47 - lowest, // ^qs + 0x45 - lowest, // ^qt + 0x45 - lowest, // ^qu + 0x56 - lowest, // ^qv + 0x5e - lowest, // ^qw former 73h ctrl-left + 0x59 - lowest, // ^qx + 0x40 - lowest, // ^qy + 0x5f - lowest}; // ^qz former 74h ctrl-right + +// Using terminals the F-keys are not yet supported (was DOS only). + + + +//------ +char filename[] =" NAME:"; +char filesave[] =" SAVE:"; +char asksave[] ="SAVE? Y/N"; +char block[] ="BLK NAME:"; +char askfind[] ="^QF FIND:"; +char askreplace1[] ="^QA REPL:"; +char askreplace2[] ="^QA WITH:"; +char asklineno[] ="^QI LINE:"; +char optiontext[] ="OPT? C/B"; +#define stdtxtlen 10 + +char screencolors0[]={27,'[','4','0','m',27,'[','3','7','m'}; +char bold0[]={27,'[','0','m'}; // reset to b/w +char screencolors1[]={27,'[','4',/*'4'*/'1','m',27,'[','3','3','m'}; // yellow on red /*blue*/ +char bold1[]={27,'[','1','m',27,'[','7','m'}; // bold + +#define reversevideoX bold1 // good for "linux" terminal on /dev/tty (but not xterm,kvt) +#define scolorslen 14 +#define boldlen 4 // take care length of bold0 == length of bold1 +#define O_WRONLY_CREAT_TRUNC 01101 +#define PERMS 0644 + +char resfile[]=LIBDIR"/e3.res"; +char helpfile[]=LIBDIR"/e3ws.hlp"; + +#define TAB 8 +#define TABCHAR 0x9 // ^I +#define SPACECHAR ' ' +#define CHANGED '*' +#define UNCHANGED SPACECHAR +#define LINEFEED 0xa +#define NEWLINE LINEFEED + +//--------------------------------------------------------------------- + +unsigned char screenbuffer [62*(160+32)]; // estimated 62 lines 160 columns, 32 byte ESC seq (ca.12k) +#define screenbuffer_end screenbuffer[62*(160+32)] + // If you really have higher screen resolution, + // ...no problem, except some useless redrawing happens. + +#define winsize_size 8 +unsigned char winsize [winsize_size]; + +#define setkplen 10 +unsigned char setkp [setkplen]; // to store cursor ESC seq like db 27,'[000;000H' + +long revvoff; + +long lines; // equ 24 or similar i.e. screen lines-1 (1 for statusline) +long columns; // equ 80 or similar dword (using only LSB) + +long columne; // helper for display of current column +long zloffst; // helper: chars scrolled out at left border +long fileptr; // helper for temp storage of current pos in file +long kurspos; // cursor position set by DispNewScreen() +long kurspos2; // cursor position set by other functions + +long tabcnt; // longernal helper byte in DispNewScreen() only +long changed; // status byte: (UN)CHANGED +long oldQFpos; +long bereitsges; // byte used for ^L +long blockbegin; +long blockende; +long endeedit; // byte controls program exit +long old; // helper for ^QP +long veryold; // ditto +long linenr; // current line +long showblock; // helper for ^KH +long suchlaenge; // helper for ^QA,^QF +long repllaenge; +long vorwarts; +long grossklein; // helper byte for ^QF,^QA + +long ch2linebeg; // helper keeping cursor pos max at EOL (up/dn keys) +long numeriere; // byte controls re-numeration +long read_b; // buffer for getchar +long isbold; // control of bold display of ws-blocks +long inverse; +long insstat; + +#define errlen 100 +unsigned char error [errlen]; // reserved space for string: 'ERROR xxx:tttteeeexxxxtttt',0 + +long maxlen; + +#define maxfilenamelen 255 +unsigned char filepath [maxfilenamelen+1]; +unsigned char bakpath [maxfilenamelen+1]; +unsigned char blockpath [maxfilenamelen+1]; +unsigned char replacetext [maxfilenamelen+1]; +unsigned char suchtext [maxfilenamelen+1]; +#define optslen 8 +unsigned char optbuffer [optslen]; // buffer for search/replace options and for ^QI + +long uid; +long gid; +long perms; +struct stat fstatbuf; + +unsigned char screenline [256+4*scolorslen]; // max possible columns + 4 color ESC seq per line + // (buffer for displaying a text line) +#define errbufsize 4000 + +unsigned char errmsgs [errbufsize]; +//------ +#define max 10240000 +unsigned char text [max]; +#define sot (text+1) // start-of-text + +//--------------------------- END OF DATA SECTION --------------------- + +long stack[100]; + +#define RETURN goto *(*esp--) +#define CALL(calladr,retadr) *++esp=(long)&&_loc##retadr; goto calladr; _loc##retadr: +#define PUSH(arg) *++esp=arg +#define POP(arg) (long*)arg=*esp-- + +int main(int argc,char**argv,char **envp) +{ + long eax=0,ecx=0,edx=0,ebx=0,edi=0,esi=0,extra=0,extra2=0,parm; + long *esp=stack; + unsigned char *ebp=0; + #define jumps1 0x29 + static void* jarray[]={ + &&KeyCtrlKV, // 3bh ^KV F1 (DOS only) + &&KeyCtrlL, // 3ch ^L F2 (ditto) + &&KeyCtrlKR, // 3dh ^KR F3 (etc) + &&KeyCtrlKW, // 3eh ^KW + &&KeyCtrlT, // 3fh ^T + &&KeyCtrlQY, // 40h ^QY + &&KeyCtrlKB, // 41h ^KB + &&KeyCtrlKK, // 42h ^KK + &&KeyCtrlKC, // 43h ^KC + &&KeyCtrlKX, // 44h ^KX F10 + &&SimpleRet, // 45h F11 + &&KeyCtrlKQ, // 46h F12 + &&KeyHome, // 47h + &&KeyUp, // 48h + &&KeyPgUp, // 49h + &&KeyCtrlQDel, // 4ah ^QDel + &&KeyLeft, // 4bh + &&KeyCtrlQP, // (5 no num lock) + &&KeyRight, // 4dh + &&KeyCtrlKY, // (+) ^KY + &&KeyEnd, // 4fh + &&KeyDown, // 50H + &&KeyPgDn, // 51h + &&KeyIns, // 52H + &&KeyDel, // 53H + &&KeyCtrlQA, // 54h ^QA sF1 + &&KeyCtrlQF, // 55h ^QF sf1 + &&KeyCtrlQV, // 56h + &&KeyCtrlKH, // 57h + &&KeyCtrlQE, // 58h + &&KeyCtrlQX, // 59h + &&KeyCtrlQB, // 5Ah ^QB + &&KeyCtrlQK, // 5Bh ^QK sF8 + &&KeyCtrlKS, // 5ch ^KS sF9 + &&KeyCtrlKD, // 5dh ^KD sF10 + &&KeyCtrlLeft, // 5eh ^Left was 73h (compare notes above) + &&KeyCtrlRight, // 5fh ^Right (was 74h) + &&SimpleRet, // 60h ^End (was 75h) + &&KeyCtrlQC, // 61h ^PageDown (was 76h) + &&KeyCtrlQI, // 62h ^Home (was 77h) + &&KeyCtrlQR, // 63h ^PageUp (was 84h) +// jumps1......= 29h + &&SimpleRet, // ^@ (only former DOS version has a "jumptab2") + &&KeyHome, // ^a (compare notes above) + &&SimpleRet, // ^b + &&KeyPgDn, // ^c + &&KeyRight, // ^d + &&KeyUp, // ^e + &&KeyEnd, // ^f + &&KeyDel, // ^g 7 + &&KeyDell, // ^h 8 DEL (7fh is translated to this) + &&NormChar, // ^i 9 + &&KeyRet, // ^j = 0ah + &&CtrlKMenu, // ^k b + &&KeyCtrlL, // ^l c + &&SimpleRet, // ^m 0dh + &&SimpleRet, // ^n e + &&SimpleRet, // ^o f + &&SimpleRet, // ^p 10 + &&CtrlQMenu, // ^q 11 + &&KeyPgUp, // ^r 12 + &&KeyLeft, // ^s 13 + &&KeyCtrlT, // ^t 14 + &&SimpleRet, // ^u 15 + &&KeyIns, // ^v 16 + &&SimpleRet, // ^w 17 + &&KeyDown, // ^x 18 + &&KeyCtrlY, // ^y 19 + &&SimpleRet, // ^z + &&SimpleRet // esc + }; + CALL(SetTermStruc,0); + CALL(ReadResource,1); + esi=(long)*++argv; +#ifdef CURSORMGNT + if (!strcmp(getenv("TERM"),"linux")) + revvoff+=boldlen; // special inverse cursor on linux terminals +#endif +//------ + do { + CALL(NewFile,2); + if (extra) break; + do { + CALL(DispNewScreen,3); + CALL(RestoreStatusLine,4); + CALL(HandleChar,5); + } while (!endeedit); + esi=0; // just like if no arg is present + } while (endeedit==2); // ^KD repeat edit using another file +//------ + CALL(KursorStatusLine,6); + ecx = (long)&text; // enter next line on terminal NEWLINE is @ byte [text] + edx=1; + CALL(WriteFile0,7); + eax = (long)&orig; + CALL(SetTermStruc2,8); // restore termios settings + goto Exit; +//--------------------------------------------------------------------- +// MAIN function for processing keys +// +HandleChar:CALL(ReadChar,9); + if (!eax) goto CompJump2; // eax=0 for cursor keys + if (eax>=0x1c) goto NormChar; + ebx = eax+jumps1; + goto CompJump2; +NormChar:CALL(CheckMode,10); + if (!extra) goto OverWriteChar; + PUSH(eax); + eax=1; + CALL(InsertByte,11); + POP(eax); + if (extra) goto InsWriteEnd; // error: text buffer full +OverWriteChar:*(unsigned char*)edi++=eax; + changed = CHANGED; +InsWriteEnd:RETURN; +//------ +// +// helper for HandleChar +// +CtrlKMenu:ebx = (long)&Ktable; + ecx = 0x20204b5e; // ^K + goto Menu; +CtrlQMenu:ebx = (long)&Qtable; + ecx = 0x2020515e; // ^Q +Menu: CALL(MakeScanCode,12); + if (eax>=27) goto EndeRet; // if no valid scancode +CompJump2:ebx=(long)jarray[(int)ebx]; +//------ + CALL(*ebx,13); // the general code jump dispatcher +//------ + if (numeriere) + { + PUSH(edi); + esi=edi; + edi = (long)(sot); + linenr=0; + do { + linenr++; + CALL(LookForward,14); + ++edi; // point to start of next line + } while ((unsigned long)edi<=(unsigned long)esi); + POP(edi); + } + numeriere = 0; + RETURN; +//------ +MakeScanCode:CALL(WriteTwo,15); // ebx expects xlat-table + PUSH(ebx); + CALL(GetChar,16); + POP(ebx); + eax&=0x1f; + if (eax>=27) goto EndeRet; + ebx=*((unsigned char*)(ebx+eax)); // returns pseudo "scancode" in ebx +EndeRet:RETURN; // exception: ok=cy here +//--------------------------------------------------------------------- +// +// processing special keys: cursor, ins, del +// +KeyRet: CALL(CheckMode,17); + if (!extra) goto OvrRet; + CALL(CountToLineBegin,18); // set esi / returns eax + ++esi; + ++esi; + if (!eax) goto KeyRetNoIndent; + eax=-1; +KeyRetSrch:++eax; // search non (SPACE or TABCHAR) + if (*(unsigned char*)(esi+eax)==SPACECHAR) goto KeyRetSrch; + if (*(unsigned char*)(esi+eax)==TABCHAR) goto KeyRetSrch; +KeyRetNoIndent: + PUSH(esi); + PUSH(eax); // eax is 0 or =indented chars + CALL(GoDown,19); + POP(eax); + PUSH(eax); + ++eax; // 1 extra for 0ah + CALL(InsertByte,20); + POP(ecx); // # blanks + POP(esi); // where to copy + if (extra) goto SimpleRet; + ++linenr; + *(unsigned char*)edi++=NEWLINE; + if (ecx) + do { + *(unsigned char*)edi++=*(unsigned char*)esi++; + } while (--ecx); // copy upper line i.e. SPACES,TABS into next +SimpleRet:RETURN; +OvrRet: eax=0; + ch2linebeg = eax; + goto DownRet; +//------ +KeyDown:CALL(CountColToLineBeginVis,21); +DownRet:CALL(GoDown,22); + CALL(LookLineDown,23); + goto SetColumn; +//------ +KeyUp: CALL(GoUp,24); + CALL(CountColToLineBeginVis,25); + CALL(LookLineUp,26); + goto SetColumn; +//------ +KeyPgUp:CALL(CountColToLineBeginVis,27); + CALL(LookPageUp,28); + goto SetColumn; +//------ +KeyPgDn:CALL(CountColToLineBeginVis,29); + CALL(LookPgDown,30); // 1st char last line +//------ +SetColumn:ecx = ch2linebeg; // maximal columns + edx=0; // counts visible columns i.e. expand TABs + --edi; +SCloop: ++edi; + if (edx>=ecx) goto SCret; + if (*(unsigned char*)edi==NEWLINE) goto SCret; // don't go beyond line earlier line end + if (*(unsigned char*)edi==TABCHAR) goto SCtab; + ++edx; // count columns + goto SCloop; +SCtab: edx+= (TAB - edx % TAB); // spaces for Tab: + if (edx<=ecx) goto SCloop; // this tab to far away right? no +SCret: RETURN; +//------ +KeyHome:CALL(CountToLineBegin,32); + edi-=eax; + RETURN; +//------ +KeyEnd: CALL(CountToLineEnd,33); + edi+=eax; // points to a 0ah char + RETURN; +//------ +KeyIns: insstat = !insstat; + RETURN; +//------ +KeyDell:CALL(KeyLeft,34); + if (extra) goto KeyDell2; +KeyDel: if ((unsigned long)edi>=(unsigned long)ebp) goto KeyLeftEnd; + eax=1; // delete one @ cursor + goto DeleteByte; +KeyDell2:if ((unsigned long)edi<=(unsigned long)sot) goto KeyLeftEnd; + --linenr; + --edi; + goto KeyCtrlT1; +//------ +KeyLeft:if ((((unsigned char*)edi)[-1]) != NEWLINE) + { + --edi; + extra=0; + } + else + extra=1; +KeyLeftEnd:RETURN; +//------ +KeyRight:if (*(unsigned char*)edi != NEWLINE) + { + ++edi; + extra=0; + } + else + extra=1; + RETURN; +//------ +KeyCLeft3:if ((unsigned long)edi<=(unsigned long)(sot)) goto KeyCLEnd; + --edi; +KeyCtrlLeft:CALL(KeyLeft,35); + if (extra) goto KeyCLeft3; + if (*(unsigned char*)edi <= 0x2f) goto KeyCtrlLeft; + if (((unsigned char*)edi)[-1] > 0x2f) goto KeyCtrlLeft; +KeyCLEnd:RETURN; +//------ +KeyCRight3:CALL(CheckEof,36); + if (extra) goto KeyCREnd; + ++edi; +KeyCtrlRight:CALL(KeyRight,37); + if (extra) goto KeyCRight3; + if (*(unsigned char*)edi <= 0x2f) goto KeyCtrlRight; + if (((unsigned char*)edi)[-1] > 0x2f) goto KeyCtrlRight; +KeyCREnd:RETURN; +//--------------------------------------------------------------------- +// +// processing special keys from the Ctrl-Q menu +// +KeyCtrlQE:CALL(LookPgBegin,38); // goto top left on screen + CALL(KursorFirstLine,39); + goto CQFNum; +//------ +KeyCtrlQX:CALL(LookPgEnd,40); // 1st goto last line on screen + CALL(KeyEnd,41); // 2nd goto line end + CALL(KursorLastLine,42); + goto CQFNum; +//------ +KeyCtrlQV:if (!bereitsges) goto CtrlQFEnd; // goto last ^QA,^QF pos + edi = oldQFpos; + goto CQFNum; +//------ +KeyCtrlQA:bereitsges = 2; + CALL(AskForReplace,43); + if (extra) goto CtrlQFEnd; +CQACtrlL:PUSH(edi); + CALL(FindText,44); + if (!extra) goto CtrlQFNotFound; + eax = suchlaenge; + CALL(DeleteByte,45); + eax = repllaenge; + CALL(InsertByte,46); + esi = (long)&replacetext; + CALL(MoveBlock,47); + goto CQFFound; +//------ +KeyCtrlQF:bereitsges = 1; + CALL(AskForFind,48); + if (extra) goto CtrlQFEnd; +CQFCtrlL:PUSH(edi); + CALL(FindText,49); + if (!extra) goto CtrlQFNotFound; +CQFFound:oldQFpos = edi; + POP(esi); // dummy +CQFNum: numeriere = 1; + RETURN; +CtrlQFNotFound:POP(edi); +CtrlQFEnd:RETURN; +//------ +KeyCtrlQC:edi = (long)ebp; + goto CQFNum; +//------ +KeyCtrlQR:edi = (long)sot; + goto CQFNum; +//------ +KeyCtrlQP:ecx = veryold; + if ((unsigned long)ecx>(unsigned long)ebp) goto SimpleRet4; + edi=ecx; +//------ +KeyCtrlL:if (bereitsges==2) goto CQACtrlL; + if (bereitsges==1) goto CQFCtrlL; +SimpleRet4:RETURN; +//------ +KeyCtrlQB:eax=edi; + edi = blockbegin; +CtrlQB2:if (edi) goto CQFNum; + edi=eax; // exit if no marker set + RETURN; +//------ +KeyCtrlQK:eax=edi; + edi = blockende; + goto CtrlQB2; +//------ +KeyCtrlQI:CALL(GetAsciiToInteger,50); + if (!ecx) goto SimpleRet4; + edi = (long)sot; + CALL(LookPD2,51); +JmpCQFN:goto CQFNum; +//------ +KeyCtrlQDel:CALL(KeyLeft,52); // delete all left of cursor + CALL(CountToLineBegin,53); + edi-=eax; + CALL(DeleteByteCheckMarker,54); + goto KeyCtrlT1; +//------ +KeyCtrlQY:CALL(CountToLineEnd,55); + goto CtrlTEnd1; +//------ +KeyCtrlY:CALL(CountToLineBegin,56); + edi-=eax; // edi at begin + CALL(CountToLineEnd,57); + CALL(DeleteByteCheckMarker,58); + goto KeyCtrlT1; +//------ +KeyCtrlT:CALL(CountToWordBegin,59); + if (*(unsigned char*)edi != NEWLINE) goto CtrlTEnd1; +KeyCtrlT1:CALL(CheckEof,60); + if (extra) goto SimpleRet4; + eax=1; // 1 for 0ah +CtrlTEnd1:goto DeleteByteCheckMarker; +//--------------------------------------------------------------------- +// +// processing special Keys from Ctrl-K menu +// +KeyCtrlKY:CALL(CheckBlock,61); + if (extra) goto SimpleRet3; // no block: no action + eax = blockende; + edi = esi; // esi is blockbegin (side effect in CheckBlock) + eax-=esi; // block length + CALL(DeleteByte,62); // out ecx:=0 + blockende = ecx; // i.e. NO block valid now + blockbegin = ecx; + goto JmpCQFN; +//------ +KeyCtrlKH:showblock^=1; // flip flop +SimpleRet3:RETURN; +//------ +KeyCtrlKK:blockende = edi; + goto KCKB; +//------ +KeyCtrlKW:CALL(CheckBlock,63); + if (extra) goto SimpleRet2; // no action + CALL(SaveBlock,64); + goto CtrlKREnd; +//------ +KeyCtrlKC:CALL(CopyBlock,65); + if (extra) goto SimpleRet2; +CtrlKC2:blockbegin = edi; + blockende = eax+edi; + RETURN; +//------ +KeyCtrlKV:CALL(CopyBlock,66); + if (extra) goto SimpleRet2; + PUSH(edi); + extra=0; + if ((unsigned long)edi<(unsigned long)blockbegin) extra++; + PUSH(extra); + edi = blockbegin; + CALL(DeleteByte,67); + eax = -eax; // (for optimizing eax is negated there) + POP(extra); + POP(edi); + if (extra) goto CtrlKC2; + blockende = edi; + edi-=eax; +KeyCtrlKB:blockbegin = edi; +KCKB: showblock = 1; +SimpleRet2:RETURN; +//------ +KeyCtrlKR:CALL(ReadBlock,68) + if (extra) goto CtrlKREnd; + CALL(KeyCtrlKB,69); + ecx+=edi; + blockende = ecx; +CtrlKREnd:goto RestKursPos; +//------ +KeyCtrlKS:CALL(SaveFile,70); // (called by ^kd) + PUSH(extra); + CALL(RestKursPos,71); + POP(extra); + if (extra) goto CtrlKSEnd; + changed = UNCHANGED; +CtrlKSEnd:RETURN; +//------ +KeyCtrlKQ:if (changed==UNCHANGED) goto KCKXend; + esi = (long)&asksave; + CALL(DE1,72); + CALL(RestKursPos,73); + eax&=0xdf; + if (eax !='Y') goto KCKXend; // Y for request SAVE changes +KeyCtrlKX:CALL(KeyCtrlKS,74); + if (extra) goto CtrlKSEnd; +KCKXend:++endeedit; +KeyKXend:RETURN; +KeyCtrlKD:CALL(KeyCtrlKS,75); + if (extra) goto CtrlKSEnd; + endeedit = 2; + RETURN; +//-------------------------------------------------------------------- +// +// the general PAGE DISPLAY function: called after any pressed key +// +// side effect: sets 'columne' for RestoreStatusLine function (displays columne) +// variable kurspos: for placing the cursor at new position +// register extra2 counts lines +// register ebx 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:CALL(GetEditScreenSize,76); // check changed tty size + isbold = 0; + inverse = 0; + zloffst = 0; + columne = 0; + fileptr = edi; // for seeking current cursor pos + CALL(CountColToLineBeginVis,77);// i.e. expanding TABs + ebx = columns; + if (eax<ebx) goto DispShortLine; + eax-=ebx; + zloffst = eax+1; +DispShortLine:CALL(LookPgBegin,78); // go on 1st char upper left on screen + esi = edi; // esi for reading chars from text + ecx = lines; + extra2 = -1; // first line + if (!ecx) goto KeyKXend; // window appears too small +DispNewLine:++extra2; // new line + edi = (long)&screenline; // line display buffer + edx=0; // reset char counter + ebx = 0; // reset screen column to 0 +#ifdef LESSWRITEOPS + CALL(SetColor2,79); // set initial character color per each line +#endif +DispCharLoop:if (esi != fileptr) goto DispCharL1;// display char @ cursor postion ? + if (tabcnt) goto DispCharL1; + kurspos = extra2<<8|ebx; + columne = ebx+ zloffst; // chars scrolled left hidden +#ifdef CURSORMGNT + parm=1; + CALL(SetInverseStatus,80); + if (!extra) goto DispEndLine; +#endif +DispCharL1:CALL(SetColor,81); // set color if neccessary +//------ +DispEndLine:if ((unsigned long)esi>(unsigned long)ebp) goto FillLine; // we have passed EOF, so now fill rest of screen + if (!tabcnt) goto ELZ; + --tabcnt; + goto ELZ2; +ELZ: if (esi != (long)ebp) goto ELZ6; + ++esi; // set esi>ebp will later trigger "ja FillLine" + goto ELZ2; + +ELZ6: eax=*(unsigned char*)esi++; + if (eax != TABCHAR) goto ELZ3; + tabcnt = TAB - edx % TAB - 1; // spaces for Tab and count out the tab char itself +ELZ2: eax = SPACECHAR; +ELZ3: if (eax==NEWLINE) goto FillLine; + if (eax<SPACECHAR || eax== 0x7f) + eax = '.'; // simply ignore chars like carriage_return etc. + if (ebx>=columns) goto DispEndLine; // screen width + ++edx; // also count hidden chars (left margin) + if (edx<=zloffst) goto ELZ5; // load new char (but no display) + *(unsigned char*)edi++=eax; + +#ifdef CURSORMGNT + parm=0; + CALL(SetInverseStatus,83); +#endif + ++ebx; // counts displayed chars only +ELZ5: goto DispCharLoop; +//------ +FillLine:PUSH(ecx); // continue rest of line + ecx = columns; // width + ecx-=ebx; + if (ecx) + { + if (inverse-1) goto FillLine1; // special cursor attribute? + *(unsigned char*)edi++=SPACECHAR; // only 1st char with special attribute +#ifdef CURSORMGNT + parm=0; + CALL(SetInverseStatus,84); +#endif + if (!--ecx) goto FillLine2; // one char less +FillLine1:do { + *(unsigned char*)edi++=SPACECHAR; // store the rest blanks + } while (--ecx); + } +FillLine2:POP(ecx); + *(unsigned char*)edi = 0; + CALL(ScreenLineShow,85); + if (--ecx) goto DispNewLine; + edi = fileptr; // restore text pointer + goto RestKursPos; +//--------------------------------------------------------------------- +// three helper subroutines called by DispNewScreen +// dealing ESC sequences for character attributes +// expecting parm 0|1 +// returning extra +// +SetInverseStatus:PUSH(ecx); // returns zero flag + PUSH(esi); + if (!parm) goto SIS1; + if (insstat-1) + { + extra=1; + goto SIS4; + } + inverse = 1; + esi = (long)&reversevideoX; + esi+=revvoff; // switch between esc seq for linux or Xterm + goto SIS2; +SIS1: if (inverse-1) goto SIS3; + inverse = 0; +SIS6: isbold = 0; +SIS5: esi = (long)&bold0; +SIS2: ecx = boldlen; + do { + *(unsigned char*)edi++=*(unsigned char*)esi++; + } while (--ecx); +SIS3: extra=0; +SIS4: POP(esi); + POP(ecx); + RETURN; +//------ +SetColor:PUSH(ecx); // expects extra-flag:bold else normal + PUSH(esi); + CALL(IsShowBlock,86); + if (!extra) goto SCEsc1; + if (isbold==1) goto SIS4; // never set bold if it is already bold + isbold = 1; +SCEsc2: esi = (long)&bold1; + goto SIS2; +SCEsc1: if (!isbold) goto SIS4; // ditto + goto SIS6; +//------ +#ifdef LESSWRITEOPS +SetColor2:PUSH(ecx); + PUSH(esi); + CALL(IsShowBlock,87); + if (!extra) goto SIS5; + goto SCEsc2; +#endif +//------ +// a little helper for SetColor* functions +IsShowBlock:if (!showblock || !blockbegin || (unsigned long)blockbegin>(unsigned long)esi) goto SBlock; + if ((unsigned long)esi<(unsigned long)blockende) goto SB_ret; +SBlock: extra=0; + RETURN; +SB_ret: extra=1; + RETURN; +//------ +// this helper for DispNewScreen checks screen size before writing on screen +// FIXME: adjusting edit screen resize works with xterm, but not with SVGATextMode +// +GetEditScreenSize: + ecx = TIOCGWINSZ; + edx = (long)&winsize; + CALL(IOctlTerminal,88); + eax = *(long*)edx; // each 16 bit lines,columns + if (!eax) eax = 0x00500018; // i.e. (80<<16)+24 (assume 80x24) + lines = (eax-1)&0xFF; // without status line +#if 0 + // this is not portable: maybe 32bit Linux plus some Un*x systems ? + columns = eax >> 16; // columns > 255 are ignored... +#else + columns = 80; +#endif + RETURN; +//--------------------------------------------------------------------- +// +// 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:*(long*)(&screenline) = ecx; +StatusLineShow:ecx=0; // 0 for last line +ScreenLineShow:PUSH(eax); + PUSH(ecx); + PUSH(edx); + PUSH(ebx); + PUSH((long)ebp); + PUSH(esi); // expecting in ecx screen line counted from 0 + PUSH(edi); +#ifdef LESSWRITEOPS + eax = (columns+32)*ecx; // estimated max ESC sequences extra bytes (i.e. boldlen*X) + ebx = 0; // flag + edi = eax+(long)screenbuffer; +#endif + edx=0; + esi = (long)&screenline; +sl3: eax=*(unsigned char*)esi++; + ++edx; // count message length to write +#ifdef LESSWRITEOPS + if ((unsigned long)edi>=(unsigned long)(&screenbuffer_end)) goto sl5; // never read/write beyond buffer + if (eax == *(unsigned char*)edi) goto sl4; + *(unsigned char*)edi = eax; +sl5: ++ebx; // set flag whether line need redrawing +sl4: ++edi; +#endif + if (eax) goto sl3; + --edx; // one too much +#ifdef LESSWRITEOPS + if (!ebx) goto NoWrite; // redraw ? ..no: quick exit +#endif + PUSH(edx); + edx=(lines-ecx)<<8; + CALL(sys_writeKP,89); // set cursor pos before writing the line + POP(edx); + PUSH(ecx); + eax = (long)&screencolors1; // set bold yellow on blue + CALL(sys_writeSLColors,90); // special for status line (ecx==0) + ecx = (long)&screenline; // second argument: integer to message to write + CALL(WriteFile0,91); + POP(ecx); + 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 pos +NoWrite: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 chars +RC_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 counter +LBa1: 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 bof +CheckEnd: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 less +LookPU2: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 less +LookPD2:CALL(LookForward,107); + if (extra) goto LookPDEnd; + ++edi; // 1st char next line + if (--ecx) goto LookPD2; + --edi; // last char last line +LookPDEnd: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 bol +CCV1: ++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 eax +IntegerToAscii: +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->ok +MoveBlEnd:RETURN; // return eax=size +//--------------------------------------------------------------------- +// +// 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_text +NewFileEnd:*(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; // eof +SaveFile2: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 insertation +OSerror: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 subroutines +RestoreStatusLine: + 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+15+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'); // Overwrite +RSL1: + *((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+15+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[-15]); + 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 0xdf +find1: 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 buf +ReadFile:eax=read(ebx,(void*)ecx,edx); // ebx file / ecx buffer / edx count byte + RETURN; +WriteFile0:ebx=1; // mov ebx,stdout +WriteFile:eax=write(ebx,(void*)ecx,edx); + RETURN; +OpenFile0:ecx=0; // i.e O_RDONLY +OpenFile: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; +} diff --git a/e3c/e3.res b/e3c/e3.res new file mode 100644 index 0000000..03551df --- /dev/null +++ b/e3c/e3.res @@ -0,0 +1,105 @@ +Operation not permitted +No such file or directory + +Interrupted system call +Input/output error +Device not configured + + +Bad file descriptor + +Resource temporarily unavailable +Cannot allocate memory +Permission denied + +Block device required +Device or resource busy +File exists + +No such device +Not a directory +Is a directory +Invalid argument +Too many open files in system +Too many open files +Inappropriate ioctl for device +Text file busy +File too large +No space left on device +Illegal seek +Read-only file system + + + + + +File name too long + +Function not implemented + + + + + + + + + + + + + + + + + + + + + + +No data available + + + + + + + + + + + + + + + +File descriptor in bad state + + + + + + + + + + + + + + + + + +Operation not supported + + + + + + + + + +No buffer space available diff --git a/e3c/e3c.man b/e3c/e3c.man new file mode 100644 index 0000000..d4c485c --- /dev/null +++ b/e3c/e3c.man @@ -0,0 +1,173 @@ +.TH E3 1 + +.SH NAME +E3C \- A mini text editor + +.SH SYNOPSIS +.B e3c +[\fifilename] + +.SH DESCRIPTION +.PP +\fIe3c\fP is a complete mini editor using Wordstar features. + +.SH KEYBOARD COMMANDS +.PP +.TP +\fB^C +Go page down +.TP +\fB^D +Go right +.TP +\fB^E +Go up +.TP +\fB^I +Tabulator +.TP +\fB^KB +Set block start marker +.TP +\fB^KC +Copy current block +.TP +\fB^KD +Save file and load a new one +.TP +\fB^KK +Set block end marker +.TP +\fB^KQ +Abort editing and exit. Confirm with Y or y that your changes are lost. +.TP +\fB^KR +Insert a file as a new block +.TP +\fB^KS +Save file and continue editing +.TP +\fB^KV +Move current block inside file +.TP +\fB^KW +Save a block into a file +.TP +\fB^KX +Save file and exit +.TP +\fB^KY +Delete text a block +.TP +\fB^QA +Search & Replace (a prompt appears). For options compare ^QF. +.TP +\fB^QB +Go to block begin +.TP +\fB^QC +Go to end of file +.TP +\fB^QD +Go to end of line +.TP +\fB^QE +Go to top of screen: 1st columne, 1st line +.TP +\fB^QF +Find a text string (a prompt appears). Valid options are \fIC\fPase sensitive and \fIB\fPackward. +You could abort via pressing ^U . +.TP +\fB^QG +Delete character under cursor +.TP +\fB^QG +Delete character left of cursor +.TP +\fB^QH,^Q(Del) +Delete up to line begin +.TP +\fB^QI +Go to line number (prompt appears) +.TP +\fB^QK +Go to block end +.TP +\fB^QR +Go to file begin +.TP +\fB^QS +Go to line begin +.TP +\fB^QV +Go to last postion of find +.TP +\fB^QW +Go to previous word +.TP +\fB^QX +Go to bottom of window (last line, end of line) +.TP +\fB^QY +Delete to line end +.TP +\fB^QZ +Go to next word +.TP +\fB^R +Go page up +.TP +\fB^S +Go left +.TP +\fB^T +Delete to next word +.TP +\fB^U +Abort input in status line (this is used for ^QI,^QF,^KR,^KW etc.) +.TP +\fB^V +Toggle insert mode +.TP +\fB^X +Go down +.TP +\fB^Y +Delete current line + +.SH OPTIONS +.PP +e3c accepts a filename for text editing. + +.SH FILES +.PP +.TP +\fBe3c +is a 'C' compiled executable for some other platforms where e3 is not available. +.TP +\fBe3ws.hlp +help text file +.TP +\fBe3.res +error message text file + +.SH COPYRIGHT +e3,e3c Copyright (c) 2000 Albrecht Kleine + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +.SH BUGS +There probably are some, but I don't know what they are yet. +Caution: there's no UNDO feature.
\ No newline at end of file diff --git a/e3c/e3ws.hlp b/e3c/e3ws.hlp new file mode 100644 index 0000000..b77f5e4 --- /dev/null +++ b/e3c/e3ws.hlp @@ -0,0 +1,23 @@ +This is mini editor e3 (WS mode) v0.9 / GPL / (C) 2000 Albrecht Kleine + +Currently there's no file loaded. So now let's have a look at some help text: +Additionaly to CURSOR MOVEMENT keys you can use control keys as follows: + +Files: ^KR: Insert ^KS: Save ^KX: Save & Exit ^KQ: Abort & Exit + ^KD: Save&Load New +Blocks: ^KB: Block Start ^KK: Block End ^KC: Block Copy ^KY: Block Delete + ^KV: Block Move ^KW: Save Block +Search: ^QF: Find Word ^L: Repeat ^QA: Search & Replace + +Move ^E: Up ^X: Down ^S: Left ^D: Right + ^R: Page Up ^C: Page Down + +Quick- ^QE: Window Top ^QX: Wnd Bottom ^QS: Start o.Line ^QD: End Of Line +-Move: ^QR: BOF ^QC: EOF ^QB: Block Begin ^QK: Block End + ^QZ: Next Word ^QW: Prev Word ^QI: Goto Line # ^QV: Go Last Find + +Delete: ^T: Next Word ^Y: Line ^H: Left Char ^G: This Char + ^QY: Line End ^QDel,^QH: Line Begin + + +Enter a filename to start editing.... diff --git a/elks/Makefile b/elks/Makefile new file mode 100644 index 0000000..d023d7a --- /dev/null +++ b/elks/Makefile @@ -0,0 +1,10 @@ +ASOURCES=e3-16.asm +AFLAGS = -w+orphan-labels -f as86 + +all: $(ASOURCES) Makefile + nasm $(AFLAGS) -o e3-16.o $(ASOURCES) -l e3-16.lst -D AS86 -D ELKS + ld86 -0 -s -i -H 0xF800 -o e3-16 e3-16.o + + +clean: + rm -f e3*.o e3*.lst e3-16 diff --git a/elks/e3-16.asm b/elks/e3-16.asm new file mode 120000 index 0000000..d5eade2 --- /dev/null +++ b/elks/e3-16.asm @@ -0,0 +1 @@ +../e3-16.asm
\ No newline at end of file diff --git a/tests/e3test0 b/tests/e3test0 new file mode 100644 index 0000000..b08ba77 --- /dev/null +++ b/tests/e3test0 @@ -0,0 +1,4 @@ +RThis is a testfile for e3/Linux! +A text is written, deleted and undone + +
\ No newline at end of file |