meithecatte / miniforth

A bootsector FORTH
MIT License
121 stars 9 forks source link

Feature request/suggestion: `load` floppy/8088 BIOS compatibility (CHS support/LBA translation) #6

Open sirocyl opened 2 years ago

sirocyl commented 2 years ago

okay, so I get that this is possibly a big one here. I'm mostly posting this here to track it for myself, because I might implement this independently (perhaps in a branch or fork).

Essentially, I'd like to use CHS-type addressing to load a block from the floppy disk in the bootloader, rather than the LBA model; using the int13h AH=02 function rather than AH=42, and disk ID DL=00 (FDD 0) instead of DL=80 (HDD 0).

I'd be entirely ignoring/sero-setting C/H until the initial few blocks of forth code are loaded in, to save ASM space. Most floppies have 8, 9 or 18 sectors per track, but I'm sure LBA calculation could even be done in the first 1 or 2 sectors, in forth, along with 'extended' disk access; and load can be rewritten for such a thing on-the-fly. It might also save a tiny bit of space, since a 'packet' for the extended disk protocol is no longer necessary in the bootloader.

One reason for this, is to enable this forth environment on vintage and hobbyist kit computers. I couldn't get it done in time for the VCF East event (https://vcfed.org), but I wanted to create a booter floppy which has a text adventure game in it, with a minimal kernel of code for strings/formatting, saving game progress, and reading/evaluating user commands to advance the plot. Forth, and especially a minimal one like this, is best suited for such a thing.

meithecatte commented 2 years ago

Sounds great! I'd like to remark that I do use the boot disk ID provided by the BIOS.

The hairest issue I can see is the fact that I like to keep a "safe-mode" copy offset by 0x100 blocks. Getting this to work when the initial load can only see the first few sectors would require some ugly interleaving...

sirocyl commented 2 years ago

I'd like to remark that I do use the boot disk ID provided by the BIOS.

Ah, so the #disk on the stack could be 81 if it was on, say, the "D:" drive, and 00 if on the "A:" then, and that's BIOS negotiating those numbers. That makes sense!

Also, as far as a "safe copy" - the same initial sectors could be copied to a different cylinder, or even to the other head (of a double-sided drive), and the preconfigured cyliinder/head default changed accordingly, right? In those initial few sectors, the LBA translation and extended-mode disk code would likely be present, so sectors past that point would be accessed with only a sector number.

meithecatte commented 2 years ago

Also, as far as a "safe copy" - the same initial sectors could be copied to a different cylinder, or even to the other head (of a double-sided drive), and the preconfigured cyliinder/head default changed accordingly, right?

What do you mean by preconfigured? You need to be able to switch between them at boot time for it to be useful.

sirocyl commented 1 year ago

I've begun some implementation work toward this; #13 includes CHS loader code in uefix.s for a floppy disk (it's hardcoded to load from A:) and LBA or CHS usage is switched with -D FLOPPY. detected on the fly, by which drive number is being booted.

Reading the drive number from the BIOS is to be implemented.

I'll be making some headway on boot.s and the Forth environment; my current plan of action is:

With those changes, the rest of it should remain compatible as-is.

sirocyl commented 1 year ago

So I'm looking at it, and adding CHS wholesale to this implementation of miniforth itself (such that it remains compatible with filesystem.fth et al), seems like it'd be a big job and potentially change and break things that you won't want changed or broken.

So, I'll be managing a vintage-friendly implementation of miniforth, with CHS and FDD support, as well as pre-i386 hardware support, in a separate fork, more than likely. The big thing I want to enable with that, is a free-software "system disk" for vintage computers, as a replacement for PS/2, Toshiba, Tandy and Compaq's various proprietary tools for doing BIOS parameter setup in CMOS/NVRAM.

If you happen to be able to implement the features from my fork, then I'll probably reduce its scope (to application software for your version, as opposed to a whole OS fork) so as to not fragment things.

However, I think it is possible to remain compatible, and at least change the int13h/Function 42h (with LBA packet operands) out for Function 02h (with CHS register operands) in the bootsector load, and then later in the bootstrap.fth include/replace it with a direct LBA implementation in forth if the disk number is >80h, or a LBA -> CHS translation, if the disk number is <80h. This way, the only thing which potentially breaks, is filesystem.fth on some 286-and-older machines.

The reason for this, is that vintage BIOSes will be able to load sector-after-sector on the first track (8-21 sectors), and the CHS-appropriate disk "driver" code can fit in there; and newer BIOSes (e.g., Phoenix, Award, AMI, Toshiba) with or without Function 42h LBA support, would still be compatible out-of-the-box by doing the geometry translation in the BIOS, with a fixed track/head number of 0 and "logical sectors" up to 16383.

Eight sectors is the minimum possible sector count on one track of a PC floppy disk, excluding weird or non-PC formats, so the translation and load-pivot would need to happen there.

At first, I'd only plan on supporting CHS on floppy disks, but I've got this Compaq LTE-286 with a nice 10MB Connor hard drive in it too, and that doesn't accept LBA or "logical sectors" beyond the physical geometry on-disk.

In the end, largely, the only changes I'll be making to the bootsector itself on my fork, are to replace LBA with CHS. (there's no room for both there!)