This is the first posting of the Z80 microemacs source. 1. HISTORY I started with microemacs 3.6, which said " * This program is in public domain; written by Dave G. Conroy." All the files being edited in the buffers are kept in memory; it was fairly easy to compile the version of microemacs I used, and produce a runnable program, but the first version had no space at all for files! (March 1989). Porting to cp/m was easy because I used AZTEC C ( version 1.05c, from 1982 ). I really would have preferred BDS/C because compilation is so fast, but: no static initializers, no typedefs, no "long"... I'm not sure if BDS has overlays. If BDS has overlays, it would be worth while porting my version to BDS. If it doesn't, an overlay system could be added. I started making overlays and optimizing, and soon ( June 1989 ) could edit about 24KB of one file ( 58KB TPA ). As soon as I could edit 3K, I started using the editor to maintain itself; editors are always well-tested if you use them to maintain themselves. This is why the original files were split up into very small pieces, and some comments removed. The comments removed include the microemacs authors' names, but microemacs is freely available with attribution. No attempt to hide the origin is intended. I think the version of microemacs I used was 3.6, but I can't be sure. Then I stopped and created a program for customization of the binaries, figuring to distribute the z80me program in that fashion. There is one customization program that patches terminal-control sequences into the binary, and another that patches keystroke-to-command bindings. I could find no CP/M BBS to post it to, and gave up. ( July 1989 ). Documentation was never written, especially for the customization, and now I have to work from memory. In fact, I find no program to patch terminal-control; the term-control module was written to make this possible, though. In August or September, 1991, I saw a message in comp.os.cpm asking about editors. I posted a notice about microemacs for cp/m and got many helpful and encouraging replies. ---------------------------- 2. PHILOSOPHY AND FEATURES This program also embodies some of my thoughts about the nature of editors. Programmers use the editor more than any tool, and think about it less than any other. Even with a simple editor like vi, most programmers don't bother to learn every command... The version of microemacs that I started with was an awful editor, and I hated it. Some things had to change if I was to use it, so I changed them. If an editor's bindings are perfect from the standpoint of having neat little mnemonics ( ^N for "next line" ), they may are unlikely to be perfect from the standpoint of making frequently-used commands easy to type. A prime example is the emacs binding of Meta-f for "word forwards"; this is a frequently-used command, and should be ONE KEYSTROKE! The default Z80EMACS word forward is ^F, word back is ^B, del word forward is ^W. If an editor's bindings are perfect from both of the above standpoints, they still will run into trouble with the keyboard: yes, the dreaded ARROW KEYS. If you're alert, and leaning forward over the keyboard, you may not want to use the arrow keys; such is the argument in favor of vi's "hjkl". If you're thinking instead of typing, browsing instead of hacking, you want the arrow keys to work. Z80EMACS has predefined arrow keys that fit most ASCII terminals, ^H^J^K^L, and ^V the same as ^J. If a command is hard to type, so what? If you use it twice in a row, simply use the "REPEAT LAST COMMAND" key! It appears that I never put this feature into Z80EMACS. vi has two different kinds of word commands, "W" and "w" ( it also provides forward, backward, and forward-to-end directions for them ). Z80EMACS has word-forward and word-backward commands, just two commands, but there is another command that changes the way these two work -- you can use vi-style or emacs-style words, and stop at end-of-word or at beginning-of-word. Z80EMACS doesn't implement the vi ^^ ( control-carat ) command, that you use to toggle between buffers, but it does have the vi :n command, that you use to sequentially walk the linked list of buffers. It is inexcusable for any editor to be without at least one of these two commands. Both commands SHOULD exist. Z80EMACS can display more than one buffer on the screen at the same time; this capability was part of the original microemacs. With more than one buffer on the screen, however, you must remember to type very slowly! Z80EMACS stores its keyboard macro in a file; it uses the same mechanism as the "execute-file" command, which microemacs didn't have. Keyboard macro execution is slow, but it's better than retyping commands. Storing the keyboard macro in a file means that you can use it again after you exit and restart the editor. It looks like Z80EMACS still doesn't have "execute file"; however, internally, "execfile" would use the same mechanisms that you use to execute the keyboard macro from a file, and so "exec file" can be added with relative ease. Z80EMACS makes ".BAK" files when it saves or writes. Z80EMACS has the "vikill" command; kills whole lines, no matter where the cursor is in the line. I despise the emacs ^K command, except when used as "kill-to-end" ( the emacs-style kill is still there ). Z80EMACS has funny vertical arrows. Up-arrow moves two lines. Both up-arrow and down-arrow can wrap from the last line of the buffer to the first line. These are both bugs that would have been easy to fix; both are interesting features. I put the funny up-arrow in my unix version of emacs, and used it for at least a year before deciding I didn't like it after all ( it was that close to being a wash! ). The idea is, if you don't specify a parameter, up-arrow moves by two lines; if you do specify, it moves the correct number. If you want to move up 1, 2, 3, 4, 5, or 6 lines, it takes 2, 1, 3, 2, 4, or 3 keystrokes instead of 1, 2, 3, 4, 5, or 6 keystrokes; an average savings of one keystroke per line. However, moving up 1 line is the most common case, and the extra mental effort involved in overshooting and moving down one is distracting. ( As I type this, I have funny-up-arrow in effect on UNIX; you really do get used to it. ) Z80EMACS has two different command introducers; one for positive values ( ^U, "universal parameter" ), one for negative ( ^\ ). Many commands have special meanings with negative parameters. According to my editor theories, it's easier to learn and remember some of the odd commands if they're shoehorned onto normal commands with special parameters. For example, take the "go-to-start-of-line" command, with the normal emacs binding of ^A; if you just enter ^A with no parameters, you go to column 0; with the "shoehorn" theory in effect, if you specify a positive parameter, you go to column N, and if you specify a negative parameter, you go to the first non-white-space character in the line. I feel this is better than having three separate commands ( vi "0", "|", and "_", respectively. Metadigits start arguments. They start arguments between those who like their emacs to accept escape-9 as a command, and those who like it to supply an argument of 9 to the next command. I am in the latter camp, so in Z80EMACS, Metadigits start arguments. Z80EMACS has the vi "find-character-in-line" command. Z80EMACS has the "goto line by line number" command. (but doesn't display line numbers, so it's not as useful a command as it should be). Z80EMACS allows you to change the buffer name as well as the file name. Z80EMACS has the vi "go to column number" command: "go to start of line" with a positive parameter goes to a specific column in the line. ( with a negative parameter, it goes to end-of-line. ) ----------------------------------------------- Alas, no regular expressions, no search-replace. ----------------------------------------------- 3. OPTIMIZATION TO SAVE SPACE In order to have more room for editing files, the program had to be made smaller. A large part of this was done by moving things to overlays, but some of it was pure byte-squeezing. Most of the optimization was done in the root segment, but several overlays were optimized to make the overlay area smaller. The key to good performance with overlays is to have all the most-often-used commands in one overlay: this is ovudfb31.c ( overlay up down forward back, overlay 31 ) Almost every file was touched. Simple things like "putting the most-often-used structure member first in the structure" can save a lot of bytes. Using exactly the right number of register variables helps. Making exactly the right variables into registers helps. You have to experiment with your compiler... #define temp_int (*(int *)0xc0) saves bytes, compared to a stack variable; if ZCPR uses this area, too bad. I used a simple CP/M 2.2, with CCPPLUS, and the original ( Digital Research ) BDOS. I used zsid on the program to find out where in main() the main processing loop starts, and used up those addresses as variable addresses; I also discovered that nobody was using 0xc0 to 0xcf, and used those locations as well. Using temporary variables instead of repeated curwp->w_bufp->b_dotp->something->something_else saves a lot of bytes. Rewriting the whole thing with a better algorithm also saves a lot sometimes! When microemacs lengthens a line, or when it creates a new line, it allocates 16 bytes. Z80EMACS allocates 4 bytes. The savings is tremendous, especially when there are blank lines in the file. This is in line.c; for a while, I had COHERENT 3.0, which came with microemacs 3.8 as its only editor. I made the same change there, because they only had small-model compiler, and it dumped core! The AZTEC C library was available in source form. I chopped it down by quite a few bytes. Goodbye, stderr! Replacing shared, duplicated code with a "goto" is an optimization that a real C compiler will perform. The one that comes free with UNIX doesn't do it, and neither does CP/M AZTEC C. ( "gcc" does, though. ) Making the messages more terse saves bytes! 4. STRUCTURE OF THE PROGRAM AND OF THE POSTINGS comp.os.cpm isn't a "source-files" newsgroup. The whole source adds up to just under 600KB, uncompressed. One is not supposed to post so much to comp.os.cpm... I don't have direct internet access, so I can't just pop it into an archive site. I've decided to handle the source by mailing it to a volunteer >> acknowledged in the Internet version ofthis file << who can simply stick it into an internet archive site. This will be part00, and it will run to about 8 parts. The Z80EMACS editing system now consists of 3 ".COM" files, a slew of overlay files, a text data file, a ".SYM" file, source of one module, and minimal documentation. It supports ASCII and ANSI terminals, but the user has to patch it by hand; this uses the source file and the ".SYM" file. Binding of keystrokes to editor commands is a two-step procedure, using two of the ".COM" files, the text file, and the ".SYM" file. mapkeys.com makes a mapping, writing it to an intermediate file; meconfig.com uses the intermediate file to patch ME.COM. Z80EMACS can find its overlays if they are on the current drive, on drive a:, or on drive b:, or on drive c:, but only ( I think ) in the current user area -- checking other user areas is a job for a more advanced BDOS than the one I used, not a job for an application program. There are only two known bugs: 1. Random crashes, about once every three or four hours. No clues, and it doesn't happen often enough to make it easy to track down. 2. The file you name on the command line doesn't get read in. The buffer gets named okay, but the file is never read. Note: both the bugs were fixed since the above was written. Several other things were also corrected.