Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A VI subset for CP/M

793 views
Skip to first unread message

Nils M Holm

unread,
Jan 25, 2020, 5:21:55 AM1/25/20
to
I have written a text editor for CP/M that implements a small, but
hopefully useful subset of VI. It seems to be quite stable now, but
if you try it, please do back up any file before editing it!

Here are CP/M binaries: http://t3x.org/cpnc/programs/VE.LZH
and here is the source code: http://t3x.org/files/ve10.zip

The editor requires a VT52-compatible terminal or the CP/NC console.
Modifiying it for other terminals requires the source code and a
T3X compiler (http://t3x.org/t3x/index.html#Z).

--
Nils M Holm < n m h @ t 3 x . o r g > www.t3x.org

mi...@farmtek.net

unread,
Jan 25, 2020, 6:07:15 PM1/25/20
to
I’ve had this on my to-do list for the last eight years. I’m excited to take a look at this.

Mike

Udo Munk

unread,
Jan 26, 2020, 12:59:12 AM1/26/20
to
The editor 's' is a vi like editor written in C, small enough for running under CP/M

https://github.com/udo-munk/s

mi...@farmtek.net

unread,
Jan 26, 2020, 1:08:55 PM1/26/20
to
Looks like 'S' requires a Z80 and it's huge. My goal was to match the amazing size and speed efficiency of WordMaster. Even with a serial console it's responsive. The full binary is only 12K. The lazy me hoped to find the source for WordMaster since a conversion to VI key and command bindings wouldn't be a major rewrite. Unfortunately, I've never found the source. I started a disassembly effort on it during a couple of airplane trips, but after working on that a while I figured it would be better to just start from scratch.

Mike

mi...@farmtek.net

unread,
Jan 26, 2020, 1:10:57 PM1/26/20
to
Nils,

Could you make my life easier and compress and post the binaries in standard zip format as opposed to LZH? My version of 7-zip doesn't handle the LZH compression, nor does the Linux machine I have access to.

Thanks!

Mike

Nils M Holm

unread,
Jan 26, 2020, 1:27:34 PM1/26/20
to
Just download the source code archive (http://t3x.org/files/ve10.zip),
it also contains the binary. You can extract LZH archives directly on
CP/M using LHRD: http://t3x.org/cpnc/programs/LHRD.COM , full package
here: http://t3x.org/cpnc/programs/LHRD11.LZH .

Nils M Holm

unread,
Jan 26, 2020, 1:33:49 PM1/26/20
to
mi...@farmtek.net wrote:
> Looks like 'S' requires a Z80 and it's huge.

VE also requires a Z80. Its binary size is 19KB.

> My goal was to match
> the amazing size and speed efficiency of WordMaster.

If you are after a snappy editor, VE is maybe not for you.
This may improve in future versions.

> Even with a serial console it's responsive.

VE does have quite a few optimizations for slow serial
connections, though, because this is what I use mostly.

Martin

unread,
Jan 26, 2020, 5:42:53 PM1/26/20
to
Interesting little editor, using the "buffer gap" technique.
Worth studying, even if one is not really out to find his next
favorite editor.

On TUHS just was a discussion about screen editors, some posts
really amazing.

About redisplay algorithms:
https://minnie.tuhs.org/pipermail/tuhs/2020-January/019766.html

Or about vi, curses, rogue...:
https://minnie.tuhs.org/pipermail/tuhs/2020-January/019811.html


Martin

mi...@farmtek.net

unread,
Jan 27, 2020, 12:06:11 AM1/27/20
to
Just quickly played with VE on my Northstar Horizon - great job! Didn’t do a whole lot of editing with it yet, but so far it seems to work well and seems pretty responsive. Based on my habits with VI, I quickly realized change word and undo aren’t implemented yet. I would vote for those updates first :) (single level undo is fine)

I’ve tried ‘S’ in the past and didn’t have much luck with it. I re-downloaded it tonite from the link provided and tried again, but I get similar results. I ran it on a North Star Horizon and on a Vector Graphic MZ. Both are 56K CP/M configurations.

If I edit a small file with S, it displays the first page of the file, I can move left, right, up, and down, but ctrl-f and ctrl-d do nothing. Insert and open commands do not work either. After trying a few of these commands the editor crashes and continuously spews out a bunch of “#” characters interspersed with a few bangs. Based on my symptoms, I’m wondering if maybe the minimum TPA requirement is > 50K?

Mike

Nils M Holm

unread,
Jan 27, 2020, 5:47:43 AM1/27/20
to
mi...@farmtek.net wrote:
> Just quickly played with VE on my Northstar Horizon - great job!
> Didn?t do a whole lot of editing with it yet, but so far it seems to
> work well and seems pretty responsive. Based on my habits with VI, I
> quickly realized change word and undo aren?t implemented yet. I would
> vote for those updates first :) (single level undo is fine)

Short story: I have added the c and C commands (and e and X and fixed a
redraw bug).

Long story: cw is an idiomatic command, because it does not really
change the text between the cursor and the end point of the w motion,
but rather between the cursor and the character after the end of the
current or next word. So it requires some extra logic, which I tried
to avoid so far.

The current implementation of cw does a really lazy job, because it
first visually deletes the word to replace and then enters insert mode.
A real VI would delete the word invisibly and just mark the end point,
which is much more efficient on slow serial connections.

But I really want to keep the binary size under 20K, so this is
probably not going to happen.

Regarding single-level undo: it could be done, but the risk of corrupting
the text is high, so I have to think about it first. Also, doing the
redraw efficiently after an undo is pretty much impossible (when using
the display model of VE).

dott.Piergiorgio

unread,
Jan 27, 2020, 7:21:29 AM1/27/20
to
On 26/01/20 19:10, mi...@farmtek.net wrote:
> Nils,
>
> Could you make my life easier and compress and post the binaries in standard zip format as opposed to LZH? My version of 7-zip doesn't handle the LZH compression, nor does the Linux machine I have access to.

Dunno on your distro, but on Debian there's at least a pair of
swiss-grade ;) tools, unp(1) and unar(1) whose ID the archive and select
the most appropriate unpacker (incl. LZH, if you have installed lhasa(1) )

HTH and

Best regards from Italy,
dott. Piergiorgio.

dott.Piergiorgio

unread,
Jan 27, 2020, 7:27:26 AM1/27/20
to
On 26/01/20 23:39, Martin wrote:

> On TUHS just was a discussion about screen editors, some posts
> really amazing.

a word of warning on reading debates related to *nix editors: there's
not only vi, but also emacs... and I have sayed more than enough.

Nils M Holm

unread,
Jan 27, 2020, 9:16:22 AM1/27/20
to
Nils M Holm <n...@ananda.local> wrote:
> The current implementation of cw does a really lazy job, because it
> first visually deletes the word to replace and then enters insert mode.
> A real VI would delete the word invisibly and just mark the end point,
> which is much more efficient on slow serial connections.
>
> But I really want to keep the binary size under 20K, so this is
> probably not going to happen.

Well, never say never! I have just uploaded a version that replicates
the behavior of the cw command of VI! :)

Nils M Holm

unread,
Jan 29, 2020, 6:25:04 AM1/29/20
to
Nils M Holm <n...@ananda.local> wrote:
> Well, never say never! I have just uploaded a version that replicates
> the behavior of the cw command of VI! :)

The latest version also has backward search (?text) and the move
(on)to char commands (tchar, fchar). This will probably be it for
now, because the binary approaches 20K. Single-level undo (u) or
maybe single-line undo (U) is still on the To Do list, though.

Binary: http://t3x.org/cpnc/programs/VE.LZH
Sources and binaries: http://t3x.org/files/ve12.zip

If you want to compile VE yourself, you will need the latest version
of T3X/Z (http://t3x.org/t3x/index.html#Z), because the code uses
indirect function calls now, which previous versions of T3X/Z do not
have.

David Given

unread,
Feb 3, 2020, 10:24:32 AM2/3/20
to
On Wednesday, 29 January 2020 11:25:04 UTC, Nils M Holm wrote:
> Nils M Holm <n...@ananda.local> wrote:
> > Well, never say never! I have just uploaded a version that replicates
> > the behavior of the cw command of VI! :)
>
> The latest version also has backward search (?text) and the move
> (on)to char commands (tchar, fchar). This will probably be it for
> now, because the binary approaches 20K. Single-level undo (u) or
> maybe single-line undo (U) is still on the To Do list, though.

Rather belatedly: I have one too; it's called qe. I wrote most of it during a single-day session which I recorded, so if you like nine-hour screencasts:

http://cowlark.com/2019-06-28-cpm-vi

It's written in ANSI C, compiled into 8080 code with the ACK, and is about 10kB. I appear to have implemented a different subset of features than you have, so there's no search but I think there's more movement commands.

Nils M Holm

unread,
Feb 3, 2020, 2:08:22 PM2/3/20
to
David Given <david...@gmail.com> wrote:
> It's written in ANSI C, compiled into 8080 code with the ACK, and is
> about 10kB. I appear to have implemented a different subset of features
> than you have, so there's no search but I think there's more movement
> commands.

Good to see someone else working on something like this!
Let us compare notes. :)

QE supports delete word, delete line, and delete rest of line,
while VE supports the more general delete+motion command (in
addition to delete line and delete to EOL). For instance:

d'm delete to marked line
d`m delete to marker
db delete word backward
d0 delete to beginning of line
d/foo delete to following occurrence of "foo"
dH delete to first line on screen
dG delete to end of file
etc

Same works for changing and yanking. You can combine c,d,y with
any motion command.

Yanking (which you say you omitted completely) is done in-memory by
VE, if the yanked portion is up to one page in size, otherwise the
portion is written to disk.

Then VE can do search and replace, both globally and in a limited
region.

Motion commands: in addition to those supported by QE, VE has "move
to end of word" (e) and "go to char" (t and f). Or have I missed
any motion commands that VE does not have?

QE does have open above (O) and the :e and :n commands.

VE has :r (read and insert file) and :W (write region).

VE optimizes redraw quite a bit. For instance, if you move to the
next line at the end of the screen, it scrolls up and writes only
the last line. Same when moving up at the top of the screen. Hence
it feels quite responsive on a 2400-baud connection. How does QE
handle this?

I would say that VE offers quite a bit more functionality than QE.
Of course it is also twice the size of QE, so you can only edit
files of up to 27000 characters given the 48KB of TPA on my NC100.

Finally, I have been working on VE for much more than 9 hours!
So the comparison is a bit unfair, I think! :)

norwe...@gmail.com

unread,
Feb 3, 2020, 2:40:10 PM2/3/20
to
Hi David --

I'd like to play with qe, but I can't find "cpm.h". Would you give me a pointer to it??

Thanks.

Roger


David Given

unread,
Feb 4, 2020, 6:13:42 AM2/4/20
to
On Monday, 3 February 2020 20:40:10 UTC+1, norwe...@gmail.com wrote:
[...]
> I'd like to play with qe, but I can't find "cpm.h". Would you give me a pointer to it??

It's part of the compiler support package; you'll need https://github.com/davidgiven/ack. (AFAIK this is the only 8080 ANSI C compiler in existence.) The actual file is at https://github.com/davidgiven/ack/blob/default/plat/cpm/include/cpm.h and the implementation of the library is in https://github.com/davidgiven/ack/tree/default/plat/cpm/libsys.

Jon Bradbury

unread,
Feb 5, 2020, 4:58:47 AM2/5/20
to
Hello Nils

Lovely looking editor so far. I'm going to port it to the Superbrain (which is supposed to emulate a VT52 but in practice doesn't). Definitely needs a few things - undo, redo (dot command) and the :q should only act after a carriage return if we want it to be as vi-like as possible. I'm sure there are other comments I could make but it's early days and the screen draw is not working (on the Superbrain). As I am not familiar with the language it is written in, some comments in the code would be helpful. But other than that... good job!

Nils M Holm

unread,
Feb 5, 2020, 7:57:37 AM2/5/20
to
Jon Bradbury <dr_...@ntlworld.com> wrote:
> Lovely looking editor so far.

Good to hear! :)

> I'm going to port it to the Superbrain (which is supposed to emulate a
> VT52 but in practice doesn't). Definitely needs a few things - undo,
> redo (dot command)

Undo (u) and Redo (.) will need some kind of protocol for recording and
playing back commands, so they will take up quite a bit of space. This
is why I decided against implementing them in the end. Undo Line (U)
might be an alternative, but it is rather limited.

> and the :q should only act after a carriage return

It definitely should! This is something that I will implement at some
point.

> As I am not familiar with the language it is written in, some comments
> in the code would be helpful. But other than that... good job!

Give it a try! I have designed the language to be simple and unsurprising,
and if you have any experience in C or Pascal, the manual in T3XZ.TXT
should get you very far! In case you have questions, feel free to ask!

That being said, I agree that some comments would probably be helpful!
I will put this on the to-do list.
Message has been deleted

Jon Bradbury

unread,
Feb 5, 2020, 8:54:16 AM2/5/20
to

> Undo (u) and Redo (.) will need some kind of protocol for recording and
> playing back commands, so they will take up quite a bit of space. This
> is why I decided against implementing them in the end. Undo Line (U)
> might be an alternative, but it is rather limited.
>
> > and the :q should only act after a carriage return
>
> It definitely should! This is something that I will implement at some
> point.
>

Great!

> Give it a try! I have designed the language to be simple and unsurprising,
> and if you have any experience in C or Pascal, the manual in T3XZ.TXT
> should get you very far! In case you have questions, feel free to ask!

I will. Thanks, Nils!

I discovered that the Superbrain doesn't implement reverse scrolling. Duh. A fantastic computer let down by a very fat but limited BIOS. Will have to do it the hard way by re-positioning the top of screen pointer (which I assume exists) then issuing a redraw. A bit slow.

So it seems a bit of T3X is on the cards for me!

Nils M Holm

unread,
Feb 5, 2020, 11:25:44 AM2/5/20
to
Jon Bradbury <dr_...@ntlworld.com> wrote:
> I discovered that the Superbrain doesn't implement reverse
> scrolling. Duh. A fantastic computer let down by a very fat but
> limited BIOS. Will have to do it the hard way by re-positioning the
> top of screen pointer (which I assume exists) then issuing a redraw. A
> bit slow.

If you cannot reverse scroll, you might prefer to do a page up or
half-page up when hitting the top of the page. Page up is the
"prevpage" function and the parameter of "prev" inside of "prevpage"
is the number of lines to move backward.

The "newtop" function moves a line to the top of the screen, if you
prefer to do it that way.

> So it seems a bit of T3X is on the cards for me!

Enjoy! :)

norwe...@gmail.com

unread,
Feb 5, 2020, 12:17:08 PM2/5/20
to

> It's (qe) written in ANSI C, compiled into 8080 code with the ACK, and is
> about 10kB. I appear to have implemented a different subset of features than
> you have, so there's no search but I think there's more movement commands.

Sadly, I tried to get a working copy of ACK. Downloaded it to an Armbian platform and built it. The build seemed to work OK. There were lots of warning messages, but no "fatal"s that I could see. The tests at the very end worked only partially. As I remember it, about half failed. I built a cpm version of hilo from the C code. The .com (under disassembly) looked as if it ought to work, but when I tried to execute it, it only produced a garbled prompt and then hung.

What a shame!!! I've been looking for a good cross compiler for 8080 for a long time, and it seemed that ACK was the answer.

Roger

Udo Munk

unread,
Feb 5, 2020, 12:45:35 PM2/5/20
to
On Wednesday, February 5, 2020 at 6:17:08 PM UTC+1, norwe...@gmail.com wrote:
> Sadly, I tried to get a working copy of ACK. Downloaded it to an Armbian platform and
> built it. The build seemed to work OK. There were lots of warning messages, but no
> "fatal"s that I could see. The tests at the very end worked only partially. As I remember
> it, about half failed. I built a cpm version of hilo from the C code. The .com (under
> disassembly) looked as if it ought to work, but when I tried to execute it, it only
> produced a garbled prompt and then hung.

Same, i build it under Debian. Almost all tests worked other than a few using qemu-i386
to test some of the x86 binaries. That might be due to the very old qemu release packaged
for Debian.

I compiled the StarTrek and Paranoia games, but they won't run correct. Looks like it
has issues with the I/O routines in the runtime library.

> What a shame!!! I've been looking for a good cross compiler for 8080 for a long time,
> and it seemed that ACK was the answer.

Try again in a couple of years, then it might be better working ...

David Given

unread,
Feb 5, 2020, 5:25:52 PM2/5/20
to
On Wednesday, 5 February 2020 18:17:08 UTC+1, norwe...@gmail.com wrote:
[...]
> Sadly, I tried to get a working copy of ACK. Downloaded it to an Armbian platform and built it. The build seemed to work OK. There were lots of warning messages, but no "fatal"s that I could see. The tests at the very end worked only partially. As I remember it, about half failed. I built a cpm version of hilo from the C code. The .com (under disassembly) looked as if it ought to work, but when I tried to execute it, it only produced a garbled prompt and then hung.

You're absolutely right, that was broken. Looks like printf was trying to allocate a completely ridiculous 1025 bytes of buffer on the stack, which was naturally causing the CP/M binaries to explode. I have, hopefully, fixed it. Have another look, please?

Re the tests: on x86 or amd64 you should have any _failed_ tests, but you may have _skipped_ tests (usually due to not having qemu installed). On ARM some of the tests may fail because the PowerPC emulator, which I didn't write, behaves differently there!

(This one slipped through because apparently hilo was the only program which actually exploded, bizarrely. Even the mandelbrot generator worked, and of course the non-C programs were unaffected. I use the ACK for building the tools for cpmish, and it's all fine there, but of course I don't use the standard library because it's ridiculously huge...)

> What a shame!!! I've been looking for a good cross compiler for 8080 for a long time, and it seemed that ACK was the answer.

Ehhh. The generated code is... middling poor. The 8080 just can't do stack-frame languages at all well, and the ACK's insistence that everything is a word means that it can't exploit the 8080's not-entirely-terrible byte operations. But it does have the big benefit of existing, which no other ANSI C compiler does for the 8080.

David Given

unread,
Feb 5, 2020, 5:36:13 PM2/5/20
to
On Monday, 3 February 2020 20:08:22 UTC+1, Nils M Holm wrote:
[...]
> Good to see someone else working on something like this!
> Let us compare notes. :)

I should point out that I wasn't intending to steal your thunder at all --- it was just a 'oh, huh, I _completely_ forgot to tell anyone here about this' moment...

> QE supports delete word, delete line, and delete rest of line,
> while VE supports the more general delete+motion command (in
> addition to delete line and delete to EOL).

That's a big win, yes. It sounds like you made a generic motion layer which can be combined with the other commands; I only use a few motions myself, so I was never incentivised to do so.

[...]
> Yanking (which you say you omitted completely) is done in-memory by
> VE, if the yanked portion is up to one page in size, otherwise the
> portion is written to disk.

*facepalm* I dismissed in-memory buffers due to space. I dismissed disk buffers due to speed. It never occurred to me to do *both*!

[...]
> VE optimizes redraw quite a bit. For instance, if you move to the
> next line at the end of the screen, it scrolls up and writes only
> the last line. Same when moving up at the top of the screen. Hence
> it feels quite responsive on a 2400-baud connection. How does QE
> handle this?

It's mixed. I don't have a very slow terminal, but I do have an NC200 with a fairly slow tty and it's adequate there. It doesn't do line-at-a-time scrolling at all, instead doing half-page scrolling, but will insert/delete lines in the middle of the screen as you work to avoid having to redraw. The really painful thing is inserting text into a multi-line paragraph; it has to redraw the entire thing each keystroke. I never got round to doing anything about that.

> Finally, I have been working on VE for much more than 9 hours!
> So the comparison is a bit unfair, I think! :)

Honestly, the version in the repo took longer --- that was just the initial prototype.

I've actually stopped working on qe; I want to rewrite it in a different language to produce faster, smaller binaries (see http://cowlark.com/cowgol, although the version I'm currently working on is drastically different from the version described there). We'll see.

norwe...@gmail.com

unread,
Feb 6, 2020, 9:39:43 AM2/6/20
to
On Wednesday, February 5, 2020 at 2:25:52 PM UTC-8, David Given wrote:
....<snip>....
> You're absolutely right, that was broken. Looks like printf was trying to
> allocate a completely ridiculous 1025 bytes of buffer on the stack, which
> was naturally causing the CP/M binaries to explode. I have, hopefully,
> fixed it. Have another look, please?

Ahhhh .... that explains it. I traced the execution to a routine that appears to rely on the address of the chars. to be printed being passed to it in a register (HL? (forgot)). Trouble is, the register contents point off into nothingness.

Roger

Nils M Holm

unread,
Feb 6, 2020, 12:56:37 PM2/6/20
to
David Given <david...@gmail.com> wrote:
> On Monday, 3 February 2020 20:08:22 UTC+1, Nils M Holm wrote:
> [...]
>> Good to see someone else working on something like this!
>> Let us compare notes. :)
>
> I should point out that I wasn't intending to steal your thunder
> at all --- it was just a 'oh, huh, I _completely_ forgot to tell
> anyone here about this' moment...

Don't worry! I know my response probably came over a bit defensive!
Sorry about that!

No, really, it's always cool to hear from people who still write
CP/M programs!

>> QE supports delete word, delete line, and delete rest of line,
>> while VE supports the more general delete+motion command (in
>> addition to delete line and delete to EOL).
>
> That's a big win, yes. It sounds like you made a generic motion
> layer which can be combined with the other commands; I only use a
> few motions myself, so I was never incentivised to do so.

It is the one feature what made me a dedicated VI user a long time
ago, so I guess I kind of missed it in your version! :)

> The really painful thing is inserting
> text into a multi-line paragraph; it has to redraw the entire thing
> each keystroke. I never got round to doing anything about that.

This is why VE implements what is called "slowopen" mode in VI
(although you cannot turn it off in VE). When you start entering
text, screen refresh is turned off, so the text you input just
overwrites the text on the screen. The entire screen is refreshed
only after you exit insert mode. Even if you open a new line by
pressing <CR>, the lines below will not move out of the way. It
feels a bit unusual if you are not used to it, but saves a lot of
time on slow connections!

Interestingly, neither VIM nor NVI seems to implement slowopen.
They both have the option, but it does not seem to do anything.
0 new messages