Tarbell to Cromemco

While playing around with old versions of 86-DOS, I came across a disk image of 86-DOS 1.14. I ran the older 86-DOS versions in the SIMH simulator which can emulate the Cromemco disk controller supported by 86-DOS.

Unfortunately the 86-DOS 1.14 disk was meant to be used with the different and incompatible Tarbell disk controllers. SIMH doesn’t emulate the Tarbell controller and the disk can’t be booted.

Then it occurred to me that 86-DOS came with all the required source code and it should be possible to adapt the Tarbell disk to use the Cromemco disk controller instead. The two 86-DOS variants (Cromemco and Tarbell) used the exact same 8″ floppy format (77 tracks, 26 sectors of 128 bytes each), just the disk controller was different, and therefore only the boot loader and the I/O system (both within the reserved tracks) were different; the actual files on the FAT file system were identical.

Everything necessary is on the 86-DOS 1.14 disk, all that’s missing is a way to edit and reassemble the source files and put the resulting object code into place on the disk. But that’s actually not too difficult either — the only additional requirement is an 86-DOS disk that boots in SIMH. And fortunately there is a suitable 86-DOS 1.10 disk. With that in hand, it is possible to attach both the (bootable) Cromemco 86-DOS 1.10 disk and the (non-bootable) Tarbell 86-DOS 1.14 disk to SIMH and boot.

Continue reading
Posted in Development, DOS, PC history | 16 Comments

Misconceptions on Top of Misconceptions

While researching the precise meaning of the Ctrl-Z (26 decimal, hex 1Ah, ASCII SUB) character in DOS, I was somewhat taken aback by this article which purports to correct a common misconception.

The article is, for the most part, entirely correct. The handle-based file API in DOS 2.0 and onward deals with pure binary files and no byte has any special meaning. Any special meaning that the Ctrl-Z character might have in such files is generally implemented in application programs and run-time libraries.

However, the statement that “MS-DOS didn’t have an End-Of-File character of any sort” is grossly misleading. The statement that “The treatment of character 26 and the handling of “text” files was a shared delusion, […] wholly layered above DOS itself” is simply untrue.

First of all, claiming that COMMAND.COM is “just an application” requires stretching the definition of what is “DOS” to the breaking point, and likely beyond. Sure, COMMAND.COM is not part of DOS… now try booting DOS without it.

And COMMAND.COM certainly ascribes special meaning to Ctrl-Z — for example when interpreting batch files, processing stops at a Ctrl-Z character. Again, claiming that batch files are merely an application construct, not part of DOS, is contrary to most people’s understanding of what DOS is.

But it’s not just COMMAND.COM. The DOS kernel itself (MSDOS.SYS in Microsoft’s releases) very much does ascribe special meaning to Ctrl-Z. One look at DOS 1.25 MSDOS.ASM is enough to ascertain that DOS does treat Ctrl-Z (look for ‘1AH’ in the source code) specially.

Continue reading
Posted in DOS | 21 Comments

86-DOS Revisited

At the end of December 2023, several disk images of very old versions of Seattle Computer Products 86-DOS unexpectedly turned up. This includes previously unseen releases of 86-DOS version 0.11 and 0.34 (going by the version number in the 86-DOS kernel).

Just how old these releases are is somewhat difficult to establish. Unlike 86-DOS 1.0 from April 1981, the older versions used a different format of FAT directory entries. The old format only used 16 bytes per entry (rather than 32) and had no room to store any timestamps, much like CP/M formats of the era.

The 0.34 disk (8″ of course) has a handwritten label which includes a date, 81/02/20. If the disk was written and the label was made on February 20, 1981, the 86-DOS files on the disk are presumably not newer than late February 1981.

86-DOS version 0.34 disk

The file INIT.ASM on the 86-DOS 0.34 disk contains the following comment:

; Translated from the Z80 on 12-19-80 and subsequently upgraded to handle
; all of the following controllers. Set switch to one to select.

Assuming the comment is correct, 86-DOS 0.34 must have been released sometime after December 19, 1980 but before late February 1981.

The file MSDOS.ASM released by the Computer History Museum includes revision history that starts with version 0.34, which is dated as December 29, 1980. It is likely that the date refers to the DOS kernel itself and not necessarily when 86-DOS 0.34 was shipped to customers.

The 86-DOS 0.11 disk contains no real clues about its age. The sign-on message says “Copyright 1980 Seattle Computer Products, Inc.” which is not too helpful. An interview with Tim Paterson from 1983 suggests that “QDOS 0.11” was finalized in August 1980. While this is possible, the interview is somewhat questionable because there is no sign of “QDOS” in 86-DOS 0.11; the system clearly identifies itself as “86-DOS version 0.11”.

In any case, August 1980 is at least plausible as a release date of 86-DOS 0.11. If so, it would pre-date the release of the IBM PC (and PC DOS) by a whole year.

Continue reading
Posted in DOS, PC history | 24 Comments

From the Annals of Preprocessor Hackery

Over the last few days I’ve been slowly attacking the source code for 386MAX, trying to build the entire product. One of the many problems I ran into turned out to be quite interesting.

There are several (16-bit) Windows components in 386MAX, and many have some sort of GUI. As is common, dialogs etc. are built from templates stored in resource (.rc) files. But… trying to process many of the resource files with the standard Windows 3.1 resource compiler fails:

The resource compiler does not like something

The problem is dialog text labels composed of multiple strings. Something like this:

LTEXT "Qualitas 386MAX\nVersion " "8" "." "03",-1, 12,7,112,17

For obvious reasons, the authors wanted to automatically update the strings with the current version numbers, and used macros to build those strings. Only that doesn’t quite work in the resource compiler.

Continue reading
Posted in 386MAX, C, Development, Microsoft | 25 Comments

VDS: Borne out of Necessity

In July 1990, Microsoft released a specification for Virtual DMA Services, or VDS. This happened soon after the release of Windows 3.0, one of the first (though not the first) providers of VDS. The VDS specification was designed for writers of real-mode driver code for devices which used DMA, especially bus-master DMA.

Why Bother?

Let’s start with some background information explaining why VDS was necessary and unavoidable.

In the days of PCs, XTs, and ATs, life was simple. In real mode, there was a given, immutable relationship between CPU addresses (16-bit segment plus 16-bit offset) and hardware visible (20-bit or 24-bit) physical addresses. Any address could be trivially converted between a segment:offset format and a physical address.

When the 386 came along, things got complicated. When paging was enabled, the CPU’s memory-management unit (MMU) inserted a layer of translation between “virtual” and physical addresses. Because paging could be (and often was) enabled in environments that ran existing real-mode code in the 386’s virtual-8086 (V86) mode, writers of V86-mode control software had to contend with a nasty problem related to DMA, caused by the fact that any existing real-mode driver software (which notably included the system’s BIOS) had no idea about paging.

Continue reading
Posted in 386, Documentation, Microsoft, PC history, Windows | 10 Comments

386MAX and EISA DMA

A few weeks back I was reminded that the source code to the 386MAX (later Qualitas MAX) memory manager was released in 2022 on github. Back in the 1990s I used primarily EMM386 and QEMM, but I have some experience with 386MAX as well. It’s quite comparable with QEMM in terms of features and performance.

The source code itself is quite interesting. The core memory manager is of course written 100% in assembler. However, it is very well commented assembly code, written in uniform style, and it generally gives the impression of a well maintained code base (unlike, say, MS-DOS).

The github release also includes enough binaries that one can experiment with 386MAX without building a monster code base.

Qualitas MAX 8.03 booting up

I was able to get enough of it installed to have a functional 386MAX setup. Then I thought that for easier experimentation, perhaps I should set up a boot floppy with 386MAX. And that’s where trouble struck.

Continue reading
Posted in 386MAX, DOS, EISA, Source code | 11 Comments

Learn Something Old Every Day, Part IX: AHA-154xB and ASPI4DOS.SYS

The other day I had a pressing “need” to examine the behavior of Adaptec 154x and compatible SCSI HBAs and their DOS drivers. I found the hard way that the AHA-154xB does not work with Adaptec’s last DOS drivers from circa 1999. That includes the drivers still available for download (ASPI4DOS.SYS version 3.36), as well as the driver shipped with OEM versions of Windows 98SE (ASPI4DOS.SYS version 3.36S).

The error message is far from enlightening; effectively the driver acts as if there were no HBA at all.

ASPI4DOS.SYS 3.36 and AHA-154xB don’t like each other

Quite unsurprisingly, this problem has been noticed before. It has been also observed that ASPI4DOS.SYS version 3.35 works fine, as do older versions. But why is the 3.36 driver really not working with AHA-154xB?

Continue reading
Posted in Adaptec, Bugs, BusLogic, SCSI | 6 Comments

Learn Something Old Every Day, Part VIII: RTFM

In my quest to understand the intricacies of x87 behavior and especially floating-point exceptions, I pulled out my trusty old Alaris Cougar board. The system board had a 100 MHz Intel OverDrive 486 DX4 plugged in and worked quite well. I could run applications, edit and compile programs, copy files to and from network, run Windows 3.1, that kind of stuff. No problems really.

Intel 486 DX4-100 OverDrive processor

But when I tried to test how floating-point exceptions behave, I had a bit of a shock: They didn’t happen at all. The machine just blazed through any and all code that was supposed to trigger FPU exceptions without a second glance. There was just nothing, no exceptions.

In an attempt to isolate the problem, I removed the DX4 OverDrive and used the onboard Blue Lightning CPU with the already installed 387 coprocessor (actually a rare Chips & Tech 387 but that doesn’t really matter). Lo and behold, math exceptions did work.

So I unplugged the 387 and put the DX4 OverDrive back. Sure enough, that did change things… but not exactly in a good way. Now any math exception hung the system instead!

Trying to obtain further data points, I plugged in a Pentium OverDrive instead of the DX4. To my great surprise, math exceptions suddenly worked properly. They did get delivered as expected and did not hang the system.

Trying to make sense out of this, I wondered if the board’s manual might perhaps have some useful information…

Continue reading
Posted in 486, Documentation, Intel, PC hardware, x87 | 9 Comments

This Code Smells of Desperation

A few weeks ago I had the questionable pleasure of diving into the math exception handler of WIN87EM.DLL, the Windows 3.1 math emulator and FPU support library. Actually WIN87EM.DLL appears to have been first shipped with Windows 3.0, and the version in Windows 3.1 is more or less identical. The version shipped with Windows 3.11 is byte for byte identical to the one in Windows 3.1.

The main function of WIN87EM.DLL is, as the name suggests, an x87 floating-point emulator. It appears to be an outgrowth of the math emulation packages shipped with many Microsoft languages. But even on a system with x87 hardware, WIN87EM.DLL has some work to do.

Namely WIN87EM.DLL intercepts math errors (exceptions). Depending on the system type, WIN87EM.DLL hooks either NMI vector 2 (PC and PC/XT) or IRQ 13 (PC/AT and compatibles).

The math interrupt handler in WIN87EM.DLL is very, very strange. It bears all the hallmarks of code that was written, rewritten, rewritten again, hacked, tweaked, modified, and eventually beaten into submission even if the author(s) had no real idea why it finally worked.

Continue reading
Posted in Bugs, Microsoft, PC architecture, x87 | 20 Comments

Retro-Porting to NT 3.1

In another useless project, I decided to find out why even trivial programs created with the Open Watcom compiler refuse to run on Windows NT 3.1. Attempting to start an executable failed with foo.exe is not a valid Windows NT application. But this time, the surgery was successful.

Failure and success running on NT 3.1

There turned out to be several problems, some related and some not. The biggest issue was the problem previously discussed in this post. To recap, the Open Watcom runtime calls the GetEnvironmentStringsA API, which does not exist on NT 3.1. This also causes trouble on Win32s; although newer Win32s versions do implement GetEnvironmentStringsA, it just always fails.

The solution is to use the original GetEnvironmentStrings API (which is equivalent to GetEnvironmentStringsA) . But that’s not enough.

Continue reading
Posted in Development, Microsoft, NT, Watcom | 12 Comments