blog · git · desktop · images · contact


dusage for the command line and PMdusage for OS/2

2024-04-21

dusage-all.png

Okay, unlike planned at the end of this blog post from January, I didn’t dive more into assembly on DOS after all. I did something else instead. Well, the heart wants what it wants. %)

While toying around on my OS/2 Warp 4 box, I noticed that the disk was getting full. It’s been a while since I’ve installed something on this system, so I lost track of what was on it and how big it is. In the UNIX world, we have du and ncdu to investigate situations like these, but a basic OS/2 installation doesn’t come with such a tool and neither does DOS or Windows. This was the perfect opportunity to learn more about OS/2: I set out to write my own little du and called it – imaginative as I am – dusage.

Since I was going to use Open Watcom v2 for this anyway, it was easy to build binaries for several targets: 16-bit DOS, 32-bit Windows, 32-bit OS/2, and the host system (64-bit Linux in my case). Unlike other toolchains, this is hassle-free and super easy to do with Open Watcom. All you have to do is specify another target platform, e.g. -bdos, -bnt, -bos2v2, and so on. Pretty amazing! This is actually useful for me, since I do have a bunch of DOS and (old) Windows installations by now.

In the screenshot above, you can see dusage running on:

Now, dusage is a non-interactive text mode program. It scans the disk and prints the results on stdout. Nothing complicated. It was already good enough to quickly spot the issue with my full disk: There was a game lurking, weighing in at 200 MB, that I forgot about.

PMdusage

So far, I didn’t learn a lot about OS/2, though. dusage uses a bunch of fairly standard libc calls and that’s it.

The screenshot above already shows it: As an additional exercise, I wrote a GUI frontend for dusage and that is what PMdusage is. It uses the same code for scanning the disk, but then shows the results in a graphical window instead of printing it as text. Drawing a little “bar graph” is a bonus feature. This version only runs on OS/2 2.0 or later, not on any of the other build targets.

pmdusage1.png

Here’s a short demo video of PMdusage running on OS/2 2.1 on my Pentium 133. It’s a bit hard to spot, but there’s an interesting detail around timestamp 0:18 ff.: The program starts a scan of C: and thus displays the string Scanning .... While this is still going on, I quickly maximize the window, it redraws, and then the string Scanning shows up again – yep, this is a multithreaded program and scanning the disk takes place in a background thread, so the UI won’t block.

The scan finishes very quickly, because this isn’t running on a spinning hard disk but a Compact Flash card. Here’s a video of an earlier version of PMdusage running in QEMU with disk I/O slowed down to showcase this more clearly.

Along the way, the Open Watcom maintainers fixed an OS/2-related bug in no time. Amazing, thanks!

Another interesting little detail is how scrolling works. The program uses two different methods: For vertical scrolling, the program asks the windowing system to shift the window content up or down by a certain amount of pixels. This is pretty fast and you only have to draw the new portions that now came into view. For horizontal scrolling, I wanted the yellow bars to stay fixed and only the text to scroll. That’s not doable with the aforementioned method, so the whole window has to be redrawn.

I have done a little bit of programming on Windows some 20 years ago which involved using WINAPI directly. Programming the OS/2 GUI felt very similar and this clearly shows that IBM and Microsoft have a shared past. Handling the menu, for example, is pretty much the same: You get a WM_COMMAND message (just like in Windows, exact same name) and then one of the parameters is the ID of the menu item. WM_CREATE is WM_CREATE. The whole thing is very similar.

One of the strange things is that stdout and stderr just vanish when you run a GUI program from the OS/2 command prompt. No matter what your program prints, it doesn’t show up in the console window. That’s quite unfortunate as all error messages now end up in digital nirvana. You can’t just throw in a perror(). This is the case on Windows, too, huh? If the subsystem field in the .EXE file is set to 2 instead of 3, no printf()s show up in the console. I guess this actually answers a long standing question of mine: Why don’t Windows programs print helpful error messages on stderr? They just can’t, can they? Very different from what I’m used to these days on Linux or BSD, where a program is just a program and a GUI program just happens to use certain libraries – but stdout and stderr are always there and can print helpful diagnostics.

I can understand that you would want to annotate .EXE files with information about the subsystem, so that you can launch a console window when the user runs a text program. But why throw away text output when it’s a GUI program? This must have been a conscious decision and I’d love to know the reason behind it.

OS/2 nostalgia

os2disks.jpg warp3.png warp4.png

I’m full of nostalgia when it comes to OS/2. I still have our original OS/2 2.1 floppy disks from the 1990’ies and I own Warp 3 and Warp 4. (Gotta hunt down Warp 3 Connect some day.) This isn’t just some interesting retro OS, but it’s what we actually had running back then on the family PC. My earliest memories of using computers are of an 8086 with DOS (I forgot which one exactly), then Windows 3.x and OS/2 2.x followed soon after. I think. I don’t really remember the exact timeline anymore.

On the one hand, I was simply too young to truly explore and appreciate OS/2 back then. On the other hand, I did already write programs during that time – but it was BASIC on DOS. Because DOS was absolutely dominant, at least in my little world. DOS was what mattered most and I simply never got around to dig deeper into OS/2. The fact that you had to buy super expensive development kits didn’t help.

Long story short, Windows completely took over and then Linux. OS/2 simply vanished into obscurity. It is still very interesting to me and I am now taking a second look at it, mostly from a perspective of “what could have been”.

Being able to write programs for OS/2 in C now, even GUI programs, brings it to a whole new level. What better way to explore an operating system than to write software for it? Scratching my own itch, like I did with dusage and PMdusage, is perfect. On top of that, we have the amazing QEMU/KVM stack these days, which makes toying around with OSes very easy. Just look at my first screenshot above.

At some point in the past weeks, I wrote a simple little C program for OS/2 that did nothing but allocate 64 MB of RAM – which worked the same as it does today, no tricks like EMS needed. It’s just a malloc(), boom. And when the system runs out of physical RAM, it starts to swap and the whole thing keeps runnnig, as can be seen in this demo. All this at a time (early 1990’ies) when DOS was the standard thing in my world and when we were regularly fighting to free up some more kilobytes of conventional memory. Or when Windows 3.x programs would regularly lock up the entire machine.

OS/2 could have been the winner and the system that we all use today, but … well, I’ll refer to this video:

Another Boring Topic – The Fall of OS/2

(Windows NT is something that I had no contact with whatsoever back then. In my world, it took until Windows 2000 to get anything NT-like on my machine.)

In the end, for me personally, neither OS/2 nor Windows won. Free Software won and I’m very glad that it did. Nowadays, we all have easy access to operating systems, applications, and software development tools. I couldn’t care less about contemporary proprietary systems anymore. This is all very different from the “dark ages” of “every simple little program costs you 30 bucks or is annoying shareware”, let alone all the other downsides of proprietary software. As much as I enjoy all this nostalgia around DOS and OS/2, I really wouldn’t want to go back to that time.

Comments?