Live coding a vi for CP/M from scratch
cowlark.com
cowlark.com
Eeeaggh. Yes, this took a while. I started after lunch and finished sometime after midnight (look at the clock in the bottom right hand corner of the screen). I'm still kicking myself at some of the dead ends I went through.
The result (even after I cleaned it up after the stream) is still a bit slow. The biggest issue is that it redraws the entire line every time you press a key in insert mode; fixing this is moderately straightforward, as I have all the information to know where the first modified character is, but it'll require some refactoring.
The biggest think I want next is a yank buffer, but the only realistic option is to store it on disk, which would be painfully slow. Being able to do repeated inserts would be nice, too.
I actually know Bram Moolenaar; maybe I should ask how he did it...
I’m no expert, but I think the Kaypro doesn't have a real serial port between the terminal and the computer the way a lot of CP/M machines did (Altair and IMSAI usually, H-8 and H-88 and H-89 always, while the Osborne used a memory-mapped screen like the Apple). I don't know how fast it can repaint the screen.
I don't think firing the loud solenoids on the floppy drive and waiting a second or two every time you delete something (or (p)ut it) is going to be a good user experience; the yank buffer probably needs to be in RAM to be usable. You could maybe prompt the user whether to discard the deletion if the text being deleted is over a threshold of size.
The Apple II had a couple "terminal" boards more or less like what I described that allowed it to display 80 and 132-column video. Their memory and registers would be manipulated through memory access as the 6502 didn't have dedicated IO functions. One very common was the Videx Videoterm, that used a 6845 just like the IBM CGA and MDA boards (but with a much nicer VT-100-like font). The Microsoft CP/M SoftCard emulates a SOROQ IQ-120 terminal in software.
Anyway the bit layout in the 2708 EPROM it used was identical to the Videx card's. I think the fonts we used were a late development, and that for most of its life the Videx font ROM was as bad as the original terminals'. We came to realize that the verticals really needed to be two pixels wide.
Probably if we had the good sense to use an emitter follower output stage, we could have got good sharp verticals.
I need to make clear that the only connections between the terminal and card were that both used a 6845 display driver and a 2708 character ROM.
"It turns out that Mandelbrot and Julia sets have the property that any area which is completely bounded by a colour contains only that colour. (Because it’s simply connected.) (No, I don’t understand a word of that paper.) So the program recursively traces out the bounds of boxes, and if all sides of the box are the same colour it fills it and doesn’t recurse in."
http://cowlark.com/2018-05-26-bogomandel/index.html
Also a bootloader for the GPU of the rasperry Pi: http://cowlark.com/piface/
This is all mine, though: http://cowlark.com/2013-10-19-insane-make
That said, I'm not sure if the additional complexity of a gap buffer is worth it --- a lot of editors in the early days of DOS used a single buffer, effectively memmove()'ing the tail part when you inserted characters, and there was no real noticeable lag even when entering characters at the beginning of a "large" (i.e. >100KB) file. On a CP/M system with 64K of total address space at most, it just doesn't take all that long to go through all of memory. As an advantage, cursor movement code is greatly simplified and doesn't involve modifying the buffers.
It also doesn't help cursor movement as much as you'd think; editors don't address characters very much, instead preferring to address lines. For that you still need to scan forwards or backwards looking for line breaks. It would let you use memchr and memrchr to find them, though.
My guess is that they took CS classes, and actually thought things taught there were good ideas and not desperate dodges for when the simple thing won't work.
Gap buffers, by contrast, should keep everything under a millisecond except search and moving the gap a long distance.
Many gap-buffer editors don't move the gap whenever the cursor moves; they wait until you modify something. But that does seem like it would be more complicated. I'm not sure how much simpler it can get than the gap-buffer case.
Suppose your document is 32 KBytes, and you're inserting chars at the start. It's going to take 0.2 seconds per keypress! You'd notice.
(0.2 seconds per keypress = 300 keypresses per second. Assume 6 keypresses per word (5 letters and a space), and that's 50 wpm. You probably type faster than that.)
I think you mean 300 keypresses per minute.
Who has such enormous documents, and who inserts chars at the start :-) ?
Given the 64kB limit for (program+data), you’ll soon need some way to keep things on disk (most likely by having a master document that lists the names of the files storing each ‘chapter’ in the complete document, and requiring the user to manually switch from file to file)
Therefore, I would implement that, search/replace and a yank buffer before I started worrying about such relatively edgy performance issues.
For comparison, the original MacWrite on a 128k Macintosh handled only 2 to 3 pages of text, and also soon got slower than that 0.2s per key press. It was smart enough to skip updates if typing was relatively fast, though. that is a feature you might want to add (e.g. by peeking into the keyboard buffer before refreshing the screen), as the best way to speed up code is by doing less.
All else being equal, though, I think a source-code editor that can comfortably handle a 48-kibibyte source file is considerably superior to one that can only handle, say, 10 or 20 kilobytes before it starts getting sluggish. Searching works better, refactoring is easier, you need less header files in C, and you can split and join source files a lot less often. Note that qe.c itself is (barely) over 20 kilobytes, and that's using TAB characters for compression.
Day in the life of a full-time software dev.
Plus going home and working on your FOSS side project for another three or four hours.
Why don't we have a list of nice hacker projects somewhere? With an estimate of skill and effort required, relative to other projects?
I started this at about 14:00 and finished at about 01:30, so about eleven to twelve hours wall clock time. And yes, if I hadn't been doing the recording I'd have given up and gone to bed. Also I, er, had to get up at 07:00 the next morning to go hiking.
even for 2~3h it's hard to keep my concentration.
I don't know how other people work but I just wanted to point out that at least for me often the reason for lack of focus seems to be not being 100% convinced that I want to do given thing. Because in reality there's usually plenty of reasons for doubt. So it takes some kind of "I don't care how rational that is, I just really want to do it".
It's hosted here: https://github.com/udo-munk/s
The main reasons for doing this cross-compiled were: that's what I had; life was too short; I wanted something for the cpmish cross-compilation environment _anyway_.
Making cpmish self-hosted would be awesome, though.
Hitech C used to be a free-as-in-beer download from htsoft's website, but it vanished about twelve years ago. I wonder if they'd be open to open sourcing it...
So — why not Wordgrinder?
(and no, msdos doesn't run on most 8bits. The Intel 8080 was 8bit. The Z80 expanded on that with additional instructions, and cp/m lives in this branch of the family tree. The 8086 gained 16bit instructions, and branches off in an entirely different direction birthing the x86 family tree, which is where you'll find msdos & most variants)
I find CP/M interesting because it's provably the minimum viable product for an operating system. It was the personal computer desktop operating system that really worked. It came with full documentation, a full development systems (an assembler and a debugger), and a full set of tooling to allow you to port CP/M to new systems. It was portable, too, and you could run the same program unmodified on nearly any hardware which supported CP/M. So it was this great open-ended system, cheap enough to get into the hands of ordinary people, simple enough that you could understand it all, and yet sophisticated enough that, with enough time, you could achieve _anything_ on it...
The CP/M kernel is 3.5kB of 8080 machine code. I think each frame of that video consumed more space than that.