How the FM TOWNS boots from CD-ROM


updated

The FM TOWNS was the first computer to come with a CD-ROM drive, and it well predates attempts to standardize bootable CD-ROM behavior on the IBM PC and other platforms. The FM TOWNS' boot process for CD-ROMs (as well as floppies, IC cards, and hard disks) is very similar in overall shape to the boot process for IBM-compatible PC disks, but with some fun wrinkles due to the way Fujitsu evolved the platform over time. I managed to make a bootable image that loads a small "kernel" that switches into protected mode and scribbles all over the screen, and get it working both in the Tsugaru emulator (which emulates an FM TOWNS MX) as well as my real-world UX20.

The boot ROM

Similar to a PC, the first thing that runs when you turn on an FM TOWNS is its boot ROM. This checks the hardware and RAM in the system, and if everything looks good, it cycles through the drives connected to the computer looking for a bootable medium. This includes the ROM drive, a DOS disk image burned into ROM which contains versions of MSDOS.SYS, COMMAND.COM, and MSCDEX.EXE, so that developers could ship games and software on bootable CDs without having to pay Microsoft to store those files on disk. On most FM TOWNS models, the ROM disk doesn't include Fujitsu's custom IO.SYS, so it isn't a bootable system on its own. The boot ROM therefore skips past the ROM drive and cycles through the floppy drives, CD-ROM drive, IC slot, and any drives on the SCSI bus until it finds a bootable medium.

The IPL boot sector

If you're familiar with PC development, you know a bootable floppy or hard disk has the magic bytes 55 AA at the end of the first sector, with the rest of the sector containing the boot code. The FM TOWNS boot ROM also looks for a magic signature, though in the case of the TOWNS, it looks for the magic string "IPL4" at the beginning of the sector to indicate a valid boot sector (IPL being a term dating back to IBM mainframes to refer to boot code, meaning "Initial Program Load"). If the magic is found, then the first four sectors of the disk are loaded into memory at linear address 0xB0000, and the boot ROM does a call far 0xB000:4 in real mode to transfer control to the boot code immediately following the magic string. Unlike a PC boot sector, an FM TOWNS boot sector can retf back into the boot ROM if something goes wrong during its attempt to boot from the disk, in which case the boot ROM will move on to the next potential bootable device.

At the point the IPL runs, the int 0x93 disk BIOS routines described in the FM TOWNS Technical Databook are not yet available, but the boot ROM provides most of the same API through the entry point call far 0xFFFB:0x14, so it is easy to read any kind of drive the boot ROM supports, including floppies, CD-ROMs, or SCSI drives, without any additional driver code.

Loading IO.SYS

As with Western variations of MS-DOS, the first part of DOS to load is IO.SYS, which prepares the hardware and provides a base layer of disk, console, and other basic device drivers for MSDOS.SYS to use. Fujitsu's IPL implementation reads IO.SYS from a fixed location on disk, and writes it to memory starting at linear address 0x400 (as low as it can go without clobbering the real mode interrupt vector table). It checks the beginning of the file for the magic string FBIOS. If it doesn't match, then the boot fails, and it returns back to the boot ROM, but if it succeeds, it loads a real-mode segment number from linear address 0x500, then does a jmp far <segment>:0 to transfer control into IO.SYS. IO.SYS then typically proceeds to initialize the hardware, set up device drivers, and then loads MSDOS.SYS and MSCDEX.EXE from the ROM disk, before passing control on to MSDOS.SYS. From that point, things behave mostly like a typical DOS system, just with suspiciously early-loaded support for ISO 9660 CD-ROM filesystems.

The FM TOWNS UX series and Marty

You might wonder why I went into so much detail about how IO.SYS is loaded, when this post is ostensibly about how to boot a non-DOS-based environment. There's a major wrinkle in dealing with the FM TOWNS UX models, as well as the Marty console. The original FM TOWNS machine used an 80386DX CPU, and its physical address space spans the full 32 bit address space supported by that CPU. Most models followed suit, using full 386DX, 486, or Pentium processors with the same hardware memory map. However, the UX and Marty were based on the 80386SX CPU. Although internally, the 386SX executes the same 32-bit x86 machine code we all know and love, outwardly it was chopped down to have only a 16-bit data bus and 24-bit physical address space. These models therefore had to use a totally different hardware physical memory map from the other models, and existing FM TOWNS software, with its OS software already burned onto discs, would not "just work" on these models.

Fujitsu's solution to this was to exploit their ROM disk. Unlike other FM TOWNS models, the ROM disk in a UX or Marty is itself a bootable device, and the image contains its own version of IO.SYS. This ROM-based IO.SYS completely takes over the boot process from the boot ROM. However, instead of charging ahead booting into DOS itself, it still checks all the bootable devices on the system itself for a device to boot on behalf of. It does this by loading the IPL sector from each disk in turn, but it doesn't execute the IPL's code; instead, it picks out the first sector and sector count of IO.SYS from the IPL, and loads the IO.SYS from that disk. It then inspects a string that appears at the beginning of TOWNS OS versions of IO.SYS, which generally looks something like this:

         IO.SYS ( BIOS )        Middle Resolution Display Type

         BIOS Version 3.58      1995-07-17

If the date code looks like one of the original versions of TOWNS OS that pre-date the UX series (1989-11-11, 1989-12-16, or 1990-10-01), then the ROM's version of IO.SYS will take over, booting itself instead of the IO.SYS that was on the disk. The ROM version of IO.SYS then also arranges to patch the corresponding older versions of Fujitsu's TBIOS library to support 24-bit hardware if it's loaded. However, if none of the date codes match, then the ROM assumes it's a newer version of TOWNS OS that presumably natively supports 24-bit hardware. In this case, it chain-loads the IO.SYS file from disk, loading it into memory at address 0x400 and then jumping into the segment stored at address 0x500 as if it had booted straight from the IPL.

Fooling the UX ROM to load your own kernel

This part has been edited based on corrections from captainys.

So if you want to boot your own software on an FM TOWNS, and want to support the UX and Marty models, your own boot sector still needs to look enough like a Fujitsu IPL that the UX ROM disk will accept it. This didn't turn out to be that hard. In the boot sector, the UX ROM determines where the disk's IO.SYS file is by reading the first sector as a 32-bit value from offset 0x20, and the number of sectors to load from offset 0x24. The range of sectors indicated has to be readable by the BIOS, otherwise the UX ROM will consider the device to not be bootable and move on to the next one. But as long as it can read something, and the file it reads doesn't look like an IO.SYS that needs patching (meaning there's no FBIOS magic string, or the date code doesn't match one of the versions it wants to patch), then the UX ROM will load the IPL into 0xB0000 and jump to it just like the original TOWNS ROM would. So the values in your boot sector at 0x20 and 0x24 can't be arbitrary code or data, but they can just refer back to the boot sector with a start sector of 0 and length of 1 or something like that.

View and comment on this post in the fediverse, or email me about it.