Wednesday 7 July 2021

Fig-Forth At PC=Forty (Part 2)

In part 1, I talked about how to get FIG-Forth for the IBM PC running on PCjs. FIG-Forth was a popular public-domain version of the Forth systems programming language and environment during the early 1980s, which offered a high degree of control, incredible compactness and a performance much better than the ubiquitous language BASIC and although quite a bit slower than assembler, comparable with high level language compilers of the day.

I Need An Editor

I found it was possible to copy and paste text from an editor into PCjs (actually, I simply copied it from the blog post as I was writing it), but it's quite an awkward way to program in Forth. I really want to be able to write code and store it on the emulated PC's disk.

And that's a problem for two reasons. Firstly, the FIG-Forth implementation I have is fairly minimalistic, with no text editor and just the raw disk block operations.

FIG-Forth is weird in that sense, because it was designed with a view to be the OS, language and editor. It doesn't really have any concept of a file system, just raw, absolutely addressed 0.5kB (or however big the disk sector is) disk blocks that can be read (into an in-memory cache) and written. Yet the executable is an MS-DOS program which is dependent on a file system, that absolutely can't be messed up by FORTH itself.

I Once Had a PC FIG-Forth

Some slightly later FORTHs fixed this by allowing users to create files and then access blocks within those files. I picked up one of those during the public-domain disk mail-ordering era of the later 1980s. It came on a single 360kB MSDOS disk (maybe 2) and was actually very complete, with a substantiative editor; maths libraries; libraries for handling more than 64kB; a string library and possibly hooks into MSDOS. I think maybe it even had a full-screen editor.

In FIG-Forth a screen itself always refers to 1kB of editable text, made from consecutive blocks, which is roughly the size of typical microcomputer screens ( 64x16 or eg 40x25). This Forth's screen editor was an overtyping editor, which meant that typing didn't insert characters, but simply replaced whatever was at the cursor position. However, I think you could copy lines around the screen which helped. Because the screen editor worked on a fixed character grid, it would have been extremely wasteful to type code in with the kind of indentations we would use today, instead definitions would spread out as much as possible.

I ordered that PC-based FIG-Forth while at University on a whim, because I liked Forth; having learned it on a Jupiter Ace and played with a version or two on a ZX Spectrum (Abersoft Forth). However, at the time, I was at the University Of East Anglia where the computer science course wasn't PC based. Instead we did all our course material on a DEC Vax (or Micro Vax I) or on early Macintosh computers (512kB, Mac Plus and later Mac II); or on Sun Workstations. Literally, nobody was interested in PCs even though the rest of the world had largely switched to them. And why would we? We already had access to a variety of graphical environments and PCs just felt like a step into the past.

But FIG-Forth for the PC did pique my interest which is why I tried it out.

The Solution

So, my solution is fairly simple. To avoid this new FIG-Forth on PCjs from overwriting MS-DOS files I'll simply swap the disk to a different one once I've run FORTH.EXE. It doesn't matter what I use for the image, I can just clone the existing disk, because Forth just cares about the sectors and I can just overwrite what I want.

There are standard line-oriented editors for Forth, but I'm not really interested in them (they're a pain), but I think a screen-oriented editor would be OK. However, to bootstrap that I'll have to write a simple line editor on one screen; then write my full-screen editor on another screen, so that I can then load my full-screen editor without needing the line editor.

All my line editor will be able to do is copy the rest of the command line of text from the input terminal to a specified line of text in the currently edited block and update it. Super-simple! Because screens map to multiple blocks, we need to specify the screen we want to edit and that's held in the variable SCR, which gets updated when we type n LIST.

To modify line l of the current block I'll add a word called EDL which would be used as:

l EDL : BM1 ." S" 10000 0 DO LOOP ." E" ;

At the end, EDL updates the block to say it's been edited. I can choose other screens to edit using LIST as much as I want - forth will cache them in its block buffers and write them back to disk as needed. 

I'll also need to know how much I can write on the current line so text doesn't get truncated, so I'll add a command EDMAR which displays the margins. This means I need two commands as follows:

: EDMAR
  SPACE
  55 49 DO ." ....:...." I EMIT LOOP
  ." ...."
;

: EDL ( l --)
  15 AND 8 /MOD SCR @ B/SCR * + BLOCK
  SWAP C/L * + DUP C/L BL FILL ( clear line )
  IN @ TIB @ + DUP 64 + SWAP DO ( dst I= maxTib tib )
    I C@ -DUP IF
 OVER C! 1+
    ELSE
 I IN ! LEAVE
    THEN
  LOOP
  UPDATE DROP
;

So, a bit of an editing session might look like:




Of course, I'll want to put these two commands as my first two definitions on my first editable block, though in reality I chose block 50. Does this code work? Yes, because I corrected the bugs before publishing it ;-) . When I've finished editing though I should type FLUSH to copy any remaining buffers back to disk and save the disk on my local computer so nothing gets lost. When I boot up Forth again, I'll mount that disk; then I'll type LOAD to compile the code back from source.

In the future I might modify FIG-FORTH to be standalone (or add commands so that I can use it with MS-DOS). If it's standalone, I'll allow 1kB at the beginning of the disk as a bootstrap, then 16kB for the Forth executable; so the first editable block will be number 17. 

Conclusion

FIG-FORTH and most early Forth editors were crude line-oriented things which I hate, so I've no intention of just loading up those early Forth editors even though might be relatively easy. Instead I've written a minimalistic editor which I'll use to bootstrap the better editor. That's also one of the good things about Forth, if you don't like what you've got - roll something you do.

FIG-FORTH for the PC (and early FORTHs) were also very (in my opinion) clumsy systems for handling files with zero integration with the operating system, in this case MS-DOS 2.0. This version of FIG-FORTH is odd, because it runs under MS-DOS, but can't edit code on MS-DOS disks. So, I'll use an empty disk for this purpose.