After seeing the spotlight on twitter from WinWorld, on NetManage Chameleon, an old TCP/IP stack that supported Windows 3.0! With more details over on the forum. I was inspired to set it up myself.
I did go a bit overboard showing how to install MS-DOS & Windows 3.0 on Qemu. Maybe it’ll help someone who wants to try to use Qemu, but is too scared? Maybe I moved too quickly.
One thing I did do differently in this run, is launching the monitor and a serial port as tcp servers so I could telnet into the VM, effectively having a way to share text like a clipboard back and forth. I’m kind of surprised I hadn’t really started using Qemu in this manner much earlier.
The following is a guest post by NCommander of SoylentNews fame!
For those who’ve been long-time readers of SoylentNews, it’s not exactly a secret that I have a personal interest in retro computing and documenting the history and evolution of the Personal Computer. About three years ago, I ran a series of articles about restoring Xenix 2.2.3c, and I’m far overdue on writing a new one. For those who do programming work of any sort, you’ll also be familiar with “Hello World”, the first program most, if not all, programmers write in their careers.
A sample hello world program might look like the following:
#include <stdio.h>
int main() {
 printf("Hello world\n");
 return 0;
}
Recently, I was inspired to investigate the original HELLO.C for Windows 1.0, a 125 line behemoth that was talked about in hush tones. To that end, I recorded a video on YouTube that provides a look into the world of programming for Windows 1.0, and then testing the backward compatibility of Windows through to Windows 10.
Before we even get into the topic of HELLO.C though, there’s a fair bit to be said about these ancient versions of Windows. Windows 1.0, like all pre-95 versions, required DOS to be pre-installed. One quirk however with this specific version of Windows is that it blows up when run on anything later than DOS 3.3. Part of this is due to an internal version check which can be worked around with SETVER. However, even if this version check is bypassed, there are supposedly known issues with running COMMAND.COM. To reduce the number of potential headaches, I decided to simply install PC-DOS 3.3, and give Windows what it wants.
You might notice I didn’t say Microsoft DOS 3.3. The reason is that DOS didn’t exist as a standalone product at the time. Instead, system builders would license the DOS OEM Adaptation Kit and create their own DOS such as Compaq DOS 3.3. Given that PC-DOS was built for IBM’s own line of PCs, it’s generally considered the most “generic” version of the pre-DOS 5.0 versions, and this version was chosen for our base. However, due to its age, it has some quirks that would disappear with the later and more common DOS versions.
PC DOS 3.3 loaded just fine in VirtualBox and — with the single 720 KiB floppy being bootable — immediately dropped me to a command prompt. Likewise, FDISK and FORMAT were available to partition the hard drive for installation. Each individual partition is limited, however, to 32 MiB. Even at the time, this was somewhat constrained and Compaq DOS was the first (to the best of my knowledge) to remove this limitation. Running FORMAT C: /S created a bootable drive, but something oft-forgotten was that IBM actually provided an installation utility known as SELECT.
SELECT’s obscurity primarily lies in its non-obvious name or usage, nor the fact that it’s actually needed to install DOS; it’s sufficient to simply copy the files to the hard disk. However, SELECT does create CONFIG.SYS and AUTOEXEC.BAT so it’s handy to use. Compared to the later DOS setup, SELECT requires a relatively arcane invocation with the target installation folder, keyboard layout, and country-code entered as arguments and simply errors out if these are incorrect. Once the correct runes are typed, SELECT formats the target drive, copies DOS, and finishes installation.
Without much fanfare, the first hurdle was crossed, and we’re off to installing Windows.
Windows 1.0 Installation/Mouse Woes
With DOS installed, it was on to Windows. Compared to the minimalist SELECT command, Windows 1.0 comes with a dedicated installer and a simple text-based interface. This bit of polish was likely due to the fact that most users would be expected to install Windows themselves instead of having it pre-installed.
Another interesting quirk was that Windows could be installed to a second floppy disk due to the rarity of hard drives of the era, something that we would see later with Microsoft C 4.0. Installation went (mostly) smoothly, although it took me two tries to get a working install due to a typo. Typing WIN brought me to the rather spartan interface of Windows 1.0.
Although functional, what was missing was mouse support. Due to its age, Windows predates the mouse as a standard piece of equipment and predates the PS/2 mouse protocol; only serial and bus mice were supported out of the box. There are two ways to solve this problem:
The first, which is what I used, involves copying MOUSE.DRV from Windows 2.0 to the Windows 1.0 installation media, and then reinstalling, selecting the “Microsoft Mouse” option from the menu. Re-installation is required because WIN.COM is statically linked as part of installation with only the necessary drivers included; there is no option to change settings afterward. The SDK documentation details the static linking process, and how to run Windows in “slow mode” for driver development, but the end result is the same. If you want to reconfigure, you need to re-install.
The second option, which I was unaware of until after producing my video is to use the PS/2 release of Windows 1.0. Like DOS of the era, Windows was licensed to OEMs who could adapt it to their individual hardware. IBM did in fact do so for their then-new PS/2 line of computers, adding in PS/2 mouse support at the time. Despite being for the PS/2 line, this version of Windows is known to run on AT-compatible machines.
Regardless, the second hurdle had been passed, and I had a working mouse. This made exploring Windows 1.0 much easier.
The Windows 1.0 Experience
If you’re interested in trying Windows 1.0, I’d recommend heading over to PCjs.org and using their browser-based emulator to play with it as it already has working mouse support and doesn’t require acquiring 35 year old software. Likewise, there are numerous write-ups about this version, but I’d be remiss if I didn’t spend at least a little time talking about it, at least from a technical level.
Compared to even the slightly later Windows 2.0, Windows 1.0 is much closer to DOSSHELL than any other version of Windows, and is essentially a graphical bolt-on to DOS although through deep magic, it is capable of cooperative multitasking. This was done entirely with software trickery as Windows pre-dates the 80286, and ran on the original 8086. COMMAND.COM could be run as a text-based application, however, most DOS applications would launch a full-screen session and take control of the UI.
This is likely why Windows 1.0 has issues on later versions of DOS as it’s likely taking control of internal structures within DOS to perform borderline magic on a processor that had no concept of memory protection.
Another oddity is that this version of Windows doesn’t actually have “windows” per say. Instead applications are tiled, with only dialogue boxes appearing as free-floating Windows. Overlapping Windows would appear in 2.0, but it’s clear from the API that they were at least planned for at some point. Most notable, the CreateWindow() function call has arguments for x and y coordinates.
My best guess is Microsoft wished to avoid the wrath of Apple who had gone on a legal warpath of any company that too-closely copied the UI of the then-new Apple Macintosh. Compared to later versions, there are also almost no included applications. The most notable applications that were included are: NOTEPAD, PAINT, WRITE, and CARDFILE.
While NOTEPAD is essentially unchanged from its modern version, Write could be best considered a stripped-down version of Word, and would remain a mainstay until Windows 95 where it was replaced with Wordpad. CARDFILE likewise was a digital Rolodex. CARDFILE remained part of the default install until Windows 3.1, and remained on the CD-ROM for 95, 98, and ME before disappearing entirely.
PAINT, on the other hand, is entirely different from the Paintbrush application that would become a mainstay. Specifically, it’s limited to monochrome graphics, and files are saved in MSP format. Part of this is due to limitations of the Windows API of the era: for drawing bitmaps to the screen, Windows provided Display Independent Bitmaps or DIBs. These had no concept of a palette and were limited to the 8 colors that Windows uses as part of the EGA palette. Color support appears to have been a late addition to Windows, and seemingly wasn’t fully realized until Windows 3.0.
Paintbrush (and the later and confusingly-named Paint) was actually a third party application created by ZSoft which had DOS and Windows 1.0 versions. ZSoft Paintbrush was very similar to what shipped in Windows 3.0 and used a bit of technical trickery to take advantage of the full EGA palette.
With that quick look completed, let’s go back to actually getting to HELLO.C, and that involved getting the SDK installed.
The Windows SDK and Microsoft C 4.0
Getting the Windows SDK setup is something of an experience. Most of Microsoft’s documentation for this era has been lost, but the OS/2 Museum has scanned copies of some of the reference binders, and the second disk in the SDK has both a README file and an installation batch file that managed to have most of the necessary information needed.
Unlike later SDK versions, it was the responsibility of the programmer to provide a compiler. Officially, Microsoft supported the following tools:
Microsoft Macro Assembler (MASM) 4
Microsoft C 4.0 (not to be confused with MSC++4, or Visual C++)
Microsoft Pascal 3.3
Unofficially (and unconfirmed), there were versions of Borland C that could also be used, although this was untested, and appeared to not have been documented beyond some notes on USENET. More interestingly, all the above tools were compilers for DOS, and didn’t have any specific support for Windows. Instead, a replacement linker was shipped in the SDK that could create Windows 1.0 “NE” New Executables, an executable format that would also be used on early OS/2 before being replaced by Portable (PE) and Linear Executables (LX) respectively.
For the purposes of compiling HELLO.C, Microsoft C 4.0 was installed. Like Windows, MSC could be run from floppy disk, albeit it with a lot of disk swapping. No installer is provided, instead, the surviving PDFs have several pages of COPY commands combined with edits to AUTOEXEC.BAT and CONFIG.SYS for hard drive installation. It was also at this point I installed SLED, a full screen editor as DOS 3.3 only shipped with EDLIN. EDIT wouldn’t appear until DOS 5.0
After much disk feeding and some troubleshooting, I managed to compile a quick and dirty Hello World program for DOS. One other interesting quirk of MSC 4.0 was it did not include a standalone assembler; MASM was a separate retail product at the time. With the compiler sorted, it was time for the SDK.
Fortunately, an installation script is provided. Like SELECT, it required listing out a bunch of folders, but otherwise was simple enough to use. For reasons that probably only made sense in 1985, both the script and the README file was on Disk 2, and not Disk 1. This was confirmed not to be a labeling error as the script immediately asks for Disk 1 to be inserted.
The install script copies files from four of the seven disks before returning to a command line. Disk 5 contains the debug build of Windows, which are roughly equivalent to checked builds of modern Windows. Disk 6 and 7 have sample code, including HELLO.C.
With the final hurdle passed, it wasn’t too hard to get to compiled HELLO.EXE.
Dissecting HELLO.C
I’m going to go through these at a high level, my annotated hello.c goes into much more detail on all these points.
General Notes
Now that we can build it, it’s time to take a look at what actually makes up the nuts and bolts of a 16-bit Windows application. The first major difference, simply due to age is that HELLO.C uses K&R C simply on the basis of pre-dating the ANSI C function. It’s also clear that certain conventions weren’t commonplace yet: for example, windows.h lacks inclusion guards.
NEAR and FAR pointers
long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
Oh boy, the bane of anyone coding in real mode, near and far pointers are a “feature” that many would simply like to forget. The difference is seemingly simple, a near pointer is nearly identical to a standard pointer in C, except it refers to memory within a known segment, and a far pointer is a pointer that includes the segment selector. Clear right?
Yeah, I didn’t think so. To actually understand what these are, we need to segue into the 8086’s 20-bit memory map. Internally, the 8086 was a 16-bit processor, and thus could directly address 2^16 bits of memory at a time, or 64 kilobytes in total. Various tricks were done to break the 16-bit memory barrier such as bank switching, or in the case of the 8086, segmentation.
Instead of making all 20-bits directly accessible, memory pointers are divided into a selector which forms the base of a given pointer, and an offset from that base, allowing the full address space to be mapped. In effect, the 8086 gave four independent windows into system memory through the use of the Code Segment (CS), Data Segment (DS), Stack Segment (SS), and the Extra Segment (ES).
Near pointers thus are used in cases where data or a function call is in the same segment and only contain the offset; they’re functionally identical to normal C pointers within a given segment. Far pointers include both segment and offset, and the 8086 had special opcodes for using these. Of note is the far call, which automatically pushed and popped the code segment for jumping between locations in memory. This will be relevant later.
HelloWndProc is a forward declaration for the Hello Window callback, a standard feature of Windows programming. Callback functions always had to be declared FAR as Windows would need to load the correct segment when jumping into application code from the task manager. Hence the far declaration. Windows 1.0 and 2.0, in addition, had other rules we’ll look at below.
WinMain Decleration:
int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
PASCAL Calling Convention
Windows API functions are all declared as PASCAL calling convention, also known as STDCALL on modern Windows. Under normal circumstances, the C programming language has a nominal calling convention (known as CDECL) which primarily relates to how the stack is cleaned up after a function call. In CDECL-declared functions, its the responsibility of the calling function to clean the stack. This is necessary for vardiac functions (aka, functions that take a variable number of arguments) to work as the callee won’t know how many were pushed onto the stack.
The downside to CDECL is that it requires additional prologue and epilogue instructions for each and every function call, thereby slowing down execution speed and increasing disk space requirements. Conversely, PASCAL calling convention left cleanup to be performed by the called function and usually only needed a single opcode to clean the stack at function end. It was likely due to execution and disk space concerns that Windows standardized on this convention (and in fact still uses it on 32-bit Windows.
hPrevInstance
if (!hPrevInstance) {
/* Call initialization procedure if this is the first instance */
if (!HelloInit( hInstance ))
return FALSE;
} else {
/* Copy data from previous instance */
GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
}
hPrevInstance has been a vestigial organ in modern Windows for decades. It’s set to NULL on program start, and has no purpose in Win32. Of course, that doesn’t mean it was always meaningless. Applications on 16-bit Windows existed in a general soup of shared address space. Furthermore, Windows didn’t immediately reclaim memory that was marked unused. Applications thus could have pieces of themselves remain resident beyond the lifespan of the application.
hPrevInstance was a pointer to these previous instances. If an application still happened to have its resources registered to the Windows Resource Manager, it could reclaim them instead of having to load them fresh from disk. hPrevInstance was set to NULL if no previous instance was loaded, thereby instructing the application to reload everything it needs. Resources are registered with a global key so trying to register the same resource twice would lead to an initialization failure.
I’ve also gotten the impression that resources could be shared across applications although I haven’t explicitly confirmed this.
Local/Global Memory Allocations
NOTE: Mostly cribbled off Raymond Chen’s blog, a great read for why Windows works the way it does.
Another concept that’s essentially gone is that memory allocations were classified as either local to an application or global. Due to the segmented architecture, applications have multiple heaps: a local heap that is initialized with the program and exists in the local data segment, and a global heap which requires a far pointer to make access to and from.
Every executable and DLL got their own local heaps, but global heaps could be shared across process boundaries, and as best I can tell, weren’t automatically deallocated when a process ended. HEAPWALK could be used to see who allocated what and find leaks in the address space. It could also be combined with SHAKER which rearranged blocks of memories in an attempt to shake loose bugs. This is similar to more modern-day tools like valgrind on Linux, or Microsoft’s Application Testing tools.
Oh boy, this is a real stinker and an entirely unnecessary one at that. MakeProcInstance didn’t even make it to Windows 3.1 and its entire existence is because Microsoft forgot details of their own operating environment. To explain, we’re going to need to dig a bit deeper into segmented mode programming.
MakeProcInstance’s purpose was to register a function suitable as a callback. Only functions that have been marked with MPI or declared as an EXPORT in the module file can be safely called across process boundaries. The reason for this is that Windows needs to register the Code Segment and Data Segment to a global store to make function calls safely. Remember, each application had its own local heap which lived in its own selector in DS.
In real mode, doing a CALL FAR to jump to a far pointer automatically push and popped the code segment as needed, but the data segment was left unchanged. As such, a mechanism was required to store the additional information needed to find the local heap. So far, this is sounding relatively reasonable.
The problem is that 16-bit Windows has this as an invariant: DS = SS …
If you’re a real mode programmer, that might make it clear where I’m going with this. The Stack Segment selector is used to denote where in memory the stack is living. SS also got pushed to the stack during a function call across process boundaries along with the previous SP. You might begin to see why MakeProcInstance becomes entirely unnecessary.
Instead of needing a global registration system for function calls, an application could just look at the stack base pointer (bp) and retrieve the previous SS from there. Since SS = DS, the previous data segment was in fact saved and no registration is required, just a change to how Windows handles function epilogs and prologs. This was actually found by a third party, and a tool FixDS was released by Michael Geary that rewrote function code to do what I just described. Microsoft eventually incorporated his fix directly into Windows, and MakeProcInstance disappeared as a necessity.
Other Oddities
From Raymond Chen’s blog and other sources, one interesting aspect of 16-bit Windows was it was actually designed with the possibility that applications would have their own address space, and there was talk that Windows would be ported to run on top of XENIX, Microsoft’s UNIX-based operating system. It’s unclear if OS/2’s Presentation Manager shared code with 16-bit Windows although several design aspects and API names were closely linked together.
From the design of 16-bit Windows and playing with it, what’s clear is this was actually future-proofing for Protected Mode on the 80286, sometimes known as segmented protection mode. On 286’s Protected Mode, while the processor was 32-bit, the memory address space was still segmented into 64-kilobyte windows. The primary difference was that the segment selectors became logical instead of physical addresses.
Had the 80286 actually succeeded, 32-bit Windows would have been essentially identical to 16-bit Windows due to how this processor worked. In truth, separate address spaces would have to wait for the 80386 and Windows NT to see the light of day, and this potential ability was never used. The 80386 both removed the 64-kilobyte limit and introduced a flat address space through paging which brought the x86 processor more inline with other architectures.
Backwards Compatibility on Windows 3.1
While Microsoft’s backward compatibility is a thing of legend, in truth, it didn’t actually start existing until Windows 3.1 and later. Since Windows 1.0 and 2.0 applications ran in real mode, they could directly manipulate the hardware and perform operations that would crash under Protected Mode.
Microsoft originally released Windows 286, and 386 to add support for the 80286 and 80386, functionality that would be merged together in Windows 3.0 as Standard Mode, and 386 Enhanced Mode along with legacy “Real Mode” support. Due to running parts of the operating system in Protected Mode, many of the tricks applications could perform would cause a General Protection Fault and simply fail. This wasn’t seen as a problem as early versions of Windows were not popular, and Microsoft actually dropped support for 1.x and 2.x applications in Windows 95.
Windows for Workgroups was installed in a fresh virtual machine, and HELLO.EXE, plus two more example applications, CARDFILE and FONTTEST were copied with it. Upon loading, Windows did not disappoint throwing up a compatibility warning right at the get-go.
Accepting the warning showing that all three applications ran fine, albeit it with a broken resolution due to 0,0 being passed into CreateWindow().
However, there’s a bit more to explore here. The Windows 3.1 SDK included a utility known as MARK. MARK was used, as the name suggests, to mark legacy applications as being OK to run under Protected Mode. It also could enable the use of TrueType fonts, a feature introduced back in Windows 3.0.
The effect is clear, HELLO.EXE now renders in TrueType fonts. The reason TrueType fonts are not immediately enabled can be see in FONTTEST, where the system typeface now overruns several dialog fields.
The question now was, can we go further?
35 Years Later …
As previously noted, Windows 95 dropped support for 1.x and 2.x binaries. The same however was not true for Windows NT, which modern versions of Windows are based upon. However, running 16-bit applications is complicated by the fact that NTVDM is not available on 64-bit installations. As such, a fresh copy of Windows 10 32-bit was installed.
Some pain was suffered convincing Windows that I didn’t want to use a Microsoft account to sign in. Inserting the same floppy disk as used in the previous test, I double-clicked HELLO and Feature Installer popped up asking to install NTVDM. After letting NTVDM install, a second attempt shows, yes, it is possible to run Windows 1.x applications on Windows 10.
FONTTEST also worked without issue, although the TrueType fonts from Windows 3.1 had disappeared. CARDFILE loaded but immediately died with an initialization error. I did try debugging the issue and found WinDbg at least has partial support for working with these ancient binaries, although the story of why CARDFILE dies will have to wait for another day.
In Closing …
I do hope you enjoyed this look at ancient Windows and HELLO.C. I’m happy to answer questions, and the next topic I’m likely going to cover is a more in-depth look at the differences between Windows 3.1 and Windows for Workgroups combined with demonstrating how networking worked in those versions.
Any feedback on either the article, or the video is welcome to help me improve my content in the future.
It’s incredible how much it’s improved since I last touched on WineVDM, the port of Wine to run on Windows using the MS-DOS Player (and Mame 80386 emulation) at it’s heart.
The latest source build WineVDM_2018_07_30b.7z is now capable of loading and running Sim City for Windows 1.0.
I found it best to install Windows 3.0 into DOSBox, and then your application. After the install I copy the application so the physical drive of the hosts matches where it was installed, and then unpack the 7z build archive into that directory. There is a ‘WINDOWS’ directory and I xcopy the installed Windows directory into there so it has all the INI files, fonts and all that jazz. To make sure it doesn’t conflict I delete the following from Windows 3.0:
del windows\system\*.drv
del windows\system\*.exe
del windows\system\*.mod
del windows\system\WIN87EM.DLL
Since these files are most certainly going to be emulated by WineVDM. After that it’s time to run stuff!
130 KLOC!
I should also add that I’ve been able to use QuickC for Windows, and build a ‘non trivial’ program, the Fortran f2c compiler weighing in at 104,245 lines , and use that to compile 16,182 lines of Fortran 77 into C, and then compile the resulting C + the Fortran runtime library a staggering 130,405 lines of code, and the resulting binary works, just like it did on Windows 3.0!
I’ve also been able to print a text file using Microsoft Word 2.0 much to my amazement, although anything involving fonts just locks or crashes. I can’t say I’m all that surprised.
So no need to wait for Win3mu, there is WineVDM which is being developed RIGHT NOW, and the source is already available. You can see my notes on building it here.
Continuing in my eventual goal to get all the Maxis games (Sim City, Sim Earth) for Windows 3.0 I just acquired Sim Life.
Although the box that I have is the ‘Classics’ version, it actually does support Windows 3.0 as specified on the box. The requirements were again massive for the era, but pitiful for today requiring an 80386 processor, and 4MB of RAM, and a VGA display!
Unlike Sim City, the UI in Sim Life prevents you from moving MID child windows under the title bar, making playing on modern machines much more tolerable. My copy arrived with 3 low density 3 1/2″ diskettes, and a 204 page manual, making for a very hefty learning curve, along with a more involved experience then something casual, say Spore.
There is no doubt about how there is a great deal of overlap between Sim Earth and Sim Life, although the timescale is certainly more geared to life, unlike Sim Earth’s geological timescale, and even with these 3 programs it certainly feels like the save files should have been able to be transfered at some point, that the genesis of Spore is here with moving from geological to biological then to human lifetime scales. Although with so many things to change and get involved in, I really have to wonder if dumbing down Spore was the ‘right thing’ to do, to make it more accessible, however there is no doubt that the space portion of Spore was terrible with only a single ship to command, which made growing an empire of any size once the Grox has been encountered impossible.
Having a modern display does make the sense of the planet feel laughably small, but it’s a game, not a real life simulation, and as such expected to execute on 16Mhz machines. That said running on Crossover (Wine) on my Xeon it is incredibly snappy. One nice touch is that Sim Life is able to detect sound properly and it’ll run silently on Windows 3.0, but with 3.1 with configured audio & MIDI drivers, it’ll play (annoying) sounds, and the occasional MIDI track.
The included catalogue for this game didn’t have any prices so I don’t know what the retail price was at the time. And I have to admit, short of collecting old games for Windows 3.0 there is probably little value here compared to the far more relatable Sim City for Windows.
VGA display
Also it just goes to say that although it scales nicer for the UI on a VGA display, comparing my Apple Cinema display to VGA really makes for a claustrophobic experience.
Unless you are a diehard fan, I’d say that you’d get more out of the much flawed spore. Although if you want to see how incredibly more detailed the older games were, you’ll certainly love this one!
I don’t know why I never tried it before, but it actually works! And it’ll even spawn out to a window two. Although without share/record locking it’ll end up being a world of pain, I suspect. Maybe vDOS/vDosPlus will work? I know it’ll work fine if you boot MS-DOS inside of DOSBox, but for some reason I never actually tried to stress the v86 mode of DOSBox from within Windows.
In this case, I’m looking at the ultra-popular Sim series, and their Windows releases. While I was a big fan of SimCity, especially having played it on an Amiga, when I found out that there was a Commodore 64 version, I had bought it immediately as I wanted to play it at home. And let me tell you, it was a severely underwhelming experience.
SimCIty C64
From the logo it’s all down hill. I know that SimCity is actually from 1985, and as the first version, the Commodore 64 version is basically the prototype.
SimCity C64
Which was just graphically underwhelming, but I still played the hell out of it. And then I saw the Spectrum 48k version. Yes, the blocks are ‘buildings’ as the units fill up, they will turn into black with only the letter remaining. Despite the ultra-minimal graphics, the game play is there. And once you get used to the bizarre combination keyboard+joystick controls it is addictive. I mean it is SimCity!
SimCity Spectrum 48k
But going to the PC, I kind of grew out of SimCity. DooM was the hot game, and the whole immersive 3d thing. And of course during that era being on the PC I only knew of the MS-DOS version. While there was a version for OS/2 Warp released much much later, and by then if I felt the urge there was SimCity 2000 for Windows.
But after getting the kick for SimEarth, and finding the Windows 3.0 version, I was much surprised to find out that there was a version of SimCity of Windows 3.0 as well!
And I can see why I never had seen this for retail, or knew anyone who had it.
Maxis Order Form
That’s right in the included form, the price was $59.95. And SimEarth was $69.95! To put that in perspective that would be now $107.17, and $125.04 respectively. And people think $60 for a game today is expensive!
To get the full experience I went ahead and loaded up PCem, with a 386 and EGA graphics to get that original feel.
Since this requires Windows 3.0, with either EGA or VGA graphics, and 2MB of RAM, I figured I would go with a ‘top of the line’ souped up 386DX. I tried to load it up with the Wyse700 driver, and the game fails to load resources. I don’t know if its even possible to make black and white or four colour resources, as I live in the future, and I have millions of colours!
That said, I tested and it has no issues with 8bit depths either.
Installation is pretty smooth, the game is shipped on either two 360k 5 1/4″ diskettes, or a single 720kb diskette. While modern games have so much more, there is many things this game is lacking. But Maxine isn’t one of them.
Maxine the cow
No really, she is listed as a feature.
The music is through the PC speaker. Just like the sound effects. Multimedia integration with Windows that we take for granted today just wasn’t a thing back then. The version I have is 1.0, Although a pirated version 1.1 that was sent in actually includes WAV sound effects, and a single midi track. However it doesn’t run on Windows 3.0. So lucky me!
Unrecoverable Application Error
Ah the UAE, the bane of Windows 3.0. They were so unpopular that Microsoft had to rename the dialog.
SimCity on EGA
Living in the constraints of EGA feel absolutely claustrophobic in today’s world. 640×350 just isn’t enough screen rel estate. Even 640×480 is far far too small. And that lead to one issue I found
SimCity SVGA
While using a SVGA driver so I can get that impossible to afford experience of 1280×1024 in 256 colours, but the application was never meant to run in something that wide. You can easily put child windows ‘behind’ the dead space, and you can never recover them. You have to save and re-launch. bummer.
If any application failed to run on Windows 95, I took it as a personal failure. I spent many sleepless nights fixing bugs in third-party programs just so they could keep running on Windows 95. (Games were the worst. Often the game vendor didn’t even care that their program didn’t run on Windows 95!)
Yes, they basically knew it had problems. In the box they even had this cute flyer:
I sure hope Raymond got something for his efforts!
And yes, rest assured it actually does work. It even works on Windows 3.00a under Citrix MULTIUSER 2.0 Pointless as there is no way to have remote graphical displays but nice to see it work.
So what went wrong? Where was all the follow up games for Windows? Obviously, the hardware needed was incredibly expensive. A 386 or even a 286 with a few megabytes of RAM was expensive. VGA or EGA monitors were also very expensive. Even mice were expensive! Putting together a low end PC basically barred you from this high end premier experience. I can’t imagine that Maxis sold many copies of this. As mentioned above I’m pretty sure there is a reason why I never saw this in the wild.
Awesome Windows 386/486 machine prices February 1992
Spending $3000 in early 1992, which is $5197.95 in today’s money. I can’t even begin to imagine spending over $5,000 to play a game. It’s no wonder when older machines show up on eBay people want far too much for them.
In a strange way I like to watch SimCity animate in the background. It’s like a fish tank or staring out into a busy street. With the advantage that I can summon a giant lizard to destroy it at my whim.
As it started as an experiment on Windows 2, it became a product on it’s own, and launched an entire industry, along with being copied by every major OS vendor. In the 90’s having a screen saver was key, just as having simple games like solitaire, especially a broken shuffle one where the user wins most of the time led to Windows being heavily favored in the work space.
Magic Screen Saver for Windows 2
So for the heck of it, I figured I’d check it out, and as always thanks to Jason Scott, there is a copy of 1.02 on cd.textfiles.com And as reported it’s basically the ‘mystify your mind’ screen saver.
Magic in action
The runaway hit Magic Screensaver became After Dark, which then had several licensed addons like the Simpsons, Star Wars etc. Back then themes for Windows were popular along with sound effects. A lot of the functionality is still in Windows, although most people prefer that their machines are silent, only making audible alerts if there really is something wrong. But back in the day a ‘multimedia desktop’ was a $5,000 noise maker, and not many offices were impressed. Which of course gave rise to the ‘office sound card’
All Business and no fun!
Naturally under Windows there were virtual device drivers to emulate a sound blaster, as people still wanted to game with this cheaper ‘business audio’ card, although with the rise of Windows 95/Direct X gaming under Windows finally became a thing making Sound Blaster compatibility a thing of the past.
But going back to After Dark, they made a fatal error of teaming up with Berkeley Systems, who eventually started to make their own releases pushing the original team out of their own product.
After Dark 1.0 and the infamous flying toasters.
The toasters became focal in a few lawsuits, namely the Jefferson Airplane album, although it was dismissed as the artwork for the album had not been trademarked! And they were able to force the Opus ‘n Bill screen saver where Opus shoots the toasters. Late they changed the toasters to have propellers to avoid being too similar.
Opus shooting a flying toaster
Oddly stuff like screen savers too have largely fallen out of fashion with the rise of power saving monitors that just turn themselves off either from a lack of new images, or a signal from the OS.
One of those weird legacy things that in today’s world really doesn’t have that much meaning, but a scant 20 years ago was a major industry.
So I’ve always heard about the incompatibility, and I thought I’d give it a try in PCem. Â I know I used to run DR-DOS 5.00 and Windows 3.0 (because of the CGA driver) and it worked fine.
So just to prove it works, here I am installing Windows 3.0 on DR-DOS 5
Installing Windows 3.0
And even better, running Word 2.0! Although I did install a whopping 4MB of ram on this virtual 286.
MS Word 2.0
And to make it all the better, I changed to a 386, and re-installed Windows 3.0 and yes it runs in enhanced mode. Â And I can run DR-DOS in a windows.
386 enhanced mode
Of course there was the AARD code, in the Windows 3.1 betas, but as far as I know that didn’t make it to release. Â I was able to upgrade to a virtual VGA adapter, and update to Windows 3.1 in standard mode on a 286, just fine
Windows 3.1 standard mode on a 286
And DR-DOS worked through the standard mode task swapper
DR-DOS in standard mode
But Windows 3.1 in enhanced mode always locked up during setup. Â Maybe a PCem bug? Â I’m not sure. Â But Windows 3.0 works great.
Well from popular request I finally got around to loading this up. I went ahead with my favourite retro emulator, PCem for this, as it can nicely emulate an EGA display, unlike most emulators which do VGA, however when it comes to older versions of Microsoft products they really can detect the difference between EGA and VGA.
So, to start off, I downloaded from the project page, this version of PCem, compiled it, and installed MS-DOS 4.01 , from April of 1989. The Windows 3.0 Debug Release 1.14 itself is dated from February 22nd, 1989. Which I figured is close enough to the time period. I’m using the 486SX2/50 because I’m too impatient for the 386 speeds, but it does work fine on 386 or higher emulators. It does NOT work with any 286 emulation. I’m also using the HIMEM.SYS from MS-DOS 4.01 vs the one with the Windows 3.0 (Alpha? Beta? Technical Preview?) since it is slightly newer.
There is no setup program per say, rather it just xcopies all the files to a directory, and from there you run ‘d.bat’ and away you go. This version is hard coded to an EGA display, which again is the reason I went with PCem. Once you start it up, you are greeted with:
Windows v3.0 Debug Release 1.14
And it identifies itself as Windows Version 2.1
Look at all the memory!
And first thing to notice is that on my setup with 8MB of ram, I have over 6MB of RAM free. Compare this to regular Windows 2.1 which gives me 399Kb of ram in my current setup.
Windows 2.1 running in real mode
And with Windows/386 Version 2.1 it provides 383Kb of real memory, along with 6.7MB of EMS memory, as the Windows/386 Hypervisor includes EMS emulation.
Windows/386 memory
Of course the major limitation of Windows 2 is that it runs in real mode, or in the case of Windows/386 an 8086VM. As I mentioned a while back in a post about Windows 3.0, This was game changing.
As now with Windows running in protected mode, all the memory in my PC is available to Windows, and I am using MS-DOS, with nothing special.
Besides the limitation of being EGA only, the Debug version of 3.0 is that there is no support for MS-DOS applications, as WINOLDAP.MOD is missing.
NO MS-DOS for you!
This is clearly an interim build of Windows 3.0 as mentioned in Murray Sargent’s MSDN blog Saving Windows from the OS/2 Bulldozer. As mentioned from the article they began their work in the summer of 1988, so considering this is early 1989 it shows just how much progress they had made in getting Windows 2 to run in protected mode. Along with Larry Osterman’s MSDN blog post Farewell to one of the great ones, which details how the Windows 3.0 skunkworks project was writing the new improved 386 hypervisor, and how Windows 3.0 got the green light, and changed the direction of not only Microsoft but the entire software industry.
I’ve been able to run most of the Windows 2.1 applets, however I’ve not been able to run Excel 2, or Word 1. I suspect at this point that only small memory model stuff from Windows 1 or 2 is capable of running. Although at the same time, when 3.0 did ship, you really needed updated versions of Word 2 and Excel 3 to operate correctly.
Windows 3.0 Debug Release 1.14 on a 12MB system
The applets from Windows 2.1 seem to work a LOT better than the one from Windows/386 2.1 if that helps any.
This is an interesting peek at an exceptionally early build of Microsoft Windows.
So with all the excitement with jsDOSBox it was about time I tried to get something from my old java dosbox stuff running again.
As a quick note, as of right now, you cannot boot into a disk image… Nor can you really run bat files, or any kind of drivers beforehand. Â It’s basically either use a script that adds files one by one, or use an image file which gets mounted, and you run your exe/com file from that.
So here we go, back again is the old Fortran Dungeon (zork) compiled with QuickC for Windows, running on the working model version of Windows 3.0.