summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Bogatov <KAction@debian.org>2019-01-13 16:49:55 +0000
committerDmitry Bogatov <KAction@debian.org>2019-01-13 16:49:55 +0000
commit4aab39abc9f42b92955b2fe36bf4537aaa58e79d (patch)
treed18f5b9c3c381342e0695a6ecb53e7ac5e5c1ebe
Import Upstream version e3-2.30
-rw-r--r--COPYING.GPL340
-rw-r--r--COPYRIGHT24
-rw-r--r--ChangeLog985
-rw-r--r--Makefile169
-rw-r--r--README312
-rw-r--r--bin/Atheos/BUGS8
-rwxr-xr-xbin/Atheos/e311
l---------bin/Atheos/e3em1
l---------bin/Atheos/e3ne1
l---------bin/Atheos/e3pi1
l---------bin/Atheos/e3vi1
l---------bin/Atheos/e3ws1
-rwxr-xr-xbin/BeOS/e311
l---------bin/BeOS/e3em1
l---------bin/BeOS/e3ne1
l---------bin/BeOS/e3pi1
l---------bin/BeOS/e3vi1
l---------bin/BeOS/e3ws1
-rwxr-xr-xbin/DOS/e3-16.combin0 -> 3750 bytes
-rwxr-xr-xbin/ELKS/e3-16bin0 -> 4184 bytes
-rwxr-xr-xbin/FreeBSD/e3bin0 -> 12748 bytes
l---------bin/FreeBSD/e3em1
l---------bin/FreeBSD/e3ne1
l---------bin/FreeBSD/e3pi1
l---------bin/FreeBSD/e3vi1
l---------bin/FreeBSD/e3ws1
-rwxr-xr-xbin/Linux/e3bin0 -> 12652 bytes
-rwxr-xr-xbin/Linux/e3_selfcompressedbin0 -> 9081 bytes
l---------bin/Linux/e3_uncompressed1
l---------bin/Linux/e3em1
l---------bin/Linux/e3ne1
l---------bin/Linux/e3pi1
l---------bin/Linux/e3vi1
l---------bin/Linux/e3ws1
-rw-r--r--bin/NetBSD/Makefile69
-rw-r--r--bin/NetBSD/README4
l---------bin/NetBSD/e3em1
l---------bin/NetBSD/e3ne1
l---------bin/NetBSD/e3pi1
l---------bin/NetBSD/e3vi1
l---------bin/NetBSD/e3ws1
-rw-r--r--bin/OpenBSD/Makefile58
-rw-r--r--bin/OpenBSD/README4
l---------bin/OpenBSD/e3em1
l---------bin/OpenBSD/e3ne1
l---------bin/OpenBSD/e3pi1
l---------bin/OpenBSD/e3vi1
l---------bin/OpenBSD/e3ws1
-rwxr-xr-xbin/QNX/e311
l---------bin/QNX/e3em1
l---------bin/QNX/e3ne1
l---------bin/QNX/e3pi1
l---------bin/QNX/e3vi1
l---------bin/QNX/e3ws1
-rwxr-xr-xbin/Win9x/e3.exebin0 -> 19444 bytes
-rw-r--r--bin/Win9x/e3em.bat3
-rw-r--r--bin/Win9x/e3ne.bat3
-rw-r--r--bin/Win9x/e3pi.bat3
-rw-r--r--bin/Win9x/e3vi.bat3
-rw-r--r--bin/Win9x/e3ws.bat3
-rw-r--r--contrib/README.tinlink62416
-rw-r--r--contrib/e3.spec37
-rwxr-xr-xcontrib/ewrapper.sh21
-rwxr-xr-xcontrib/pico60
l---------doswin9x/e3-16.asm1
l---------doswin9x/e3.asm1
l---------doswin9x/e3.h1
-rw-r--r--doswin9x/make.bat18
-rw-r--r--e3-16.asm2361
-rw-r--r--e3.asm5657
-rw-r--r--e3.h734
-rw-r--r--e3.html370
-rw-r--r--e3.man300
-rw-r--r--e3c/Makefile35
-rw-r--r--e3c/README16
-rw-r--r--e3c/e3.asm_base_for_e3c2401
-rw-r--r--e3c/e3.c1796
-rw-r--r--e3c/e3.res105
-rw-r--r--e3c/e3c.man173
-rw-r--r--e3c/e3ws.hlp23
-rw-r--r--elks/Makefile10
l---------elks/e3-16.asm1
-rw-r--r--tests/e3test04
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&copy&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
diff --git a/README b/README
new file mode 100644
index 0000000..698cf2b
--- /dev/null
+++ b/README
@@ -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
new file mode 100755
index 0000000..c1f0e91
--- /dev/null
+++ b/bin/DOS/e3-16.com
Binary files differ
diff --git a/bin/ELKS/e3-16 b/bin/ELKS/e3-16
new file mode 100755
index 0000000..be06236
--- /dev/null
+++ b/bin/ELKS/e3-16
Binary files differ
diff --git a/bin/FreeBSD/e3 b/bin/FreeBSD/e3
new file mode 100755
index 0000000..70dcb17
--- /dev/null
+++ b/bin/FreeBSD/e3
Binary files differ
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
new file mode 100755
index 0000000..e081e1e
--- /dev/null
+++ b/bin/Linux/e3
Binary files differ
diff --git a/bin/Linux/e3_selfcompressed b/bin/Linux/e3_selfcompressed
new file mode 100755
index 0000000..ac89eb4
--- /dev/null
+++ b/bin/Linux/e3_selfcompressed
Binary files differ
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
new file mode 100755
index 0000000..31340f8
--- /dev/null
+++ b/bin/Win9x/e3.exe
Binary files differ
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
diff --git a/e3.asm b/e3.asm
new file mode 100644
index 0000000..ef6f31e
--- /dev/null
+++ b/e3.asm
@@ -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
diff --git a/e3.h b/e3.h
new file mode 100644
index 0000000..6601e17
--- /dev/null
+++ b/e3.h
@@ -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
+;--------------------------------------------------------------------------
diff --git a/e3.html b/e3.html
new file mode 100644
index 0000000..5074d37
--- /dev/null
+++ b/e3.html
@@ -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 &amp; 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
+&amp; 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>&lt;ESC&gt;; </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>
diff --git a/e3.man b/e3.man
new file mode 100644
index 0000000..d172687
--- /dev/null
+++ b/e3.man
@@ -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)&block;
+ 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