So I was playing with Watcom C/386 8.5 today

This was the first version of Watcom that included the much beloved DOS4/GW dos extender.  Funny enough it doesn’t bind in a stub for running DOS4/GW by itself, you have to do it manually or I guess write the stub for yourself.  Another fun feature of Watcom C/386 8.5 is that it includes the win386 windows extender.

Basically it does to Windows 3.0 what DOS4/GW does to MS-DOS.  Now I’ve never messed around with win386 that much because by the time I did have a 386sx processor with more than 1MB of ram, Win32s & OS/2 2.1 were all the rage.  But in the world of VM’s I thought I’d give it a shot.

The default example is the game of life.  It compiles trivially, but the moment you got to run it you get this fine error:

Ooops!

Ooops!

It turns out that it is a timing loop error, and effects of all things Microsoft FoxPro!  The solution is provided by Microsoft, in the form of IPatchFP.exe. Naturally it is a console Win32 executable.  But with enough of the HX DOS Extender‘s runtime I can run the patch inside of MS-DOS.

With my executable all patched up, I can now run the game of life!

Conway's game of life

Conway’s game of life

Which is all very exciting.

Win386 was very cool for the time, taking the Win16 API and making their own Win32 set out of it. Another cool thing is that there wasn’t a separate runtime to repackage, as Win386 was just bound to the executable. I’m sure it didn’t fall on deaf ears at Redmond with the disillusion of Cruiser, that Win16 could have a brave new future in Win32.

And I should mention I’ve gone over a lot of the Win32s versions here.

Building Descent 1 from source

Descent I

Descent I

I never was good at this game.

As a matter of fact, I was terrible.

Apparently I get lost in 3d worlds like this, and I get dizzy and need to lie down.  Something about these kinds of 3d virtual worlds.  At least it doesn’t pertain to virtual machines.

While browsing around, I came across the source code.  From their notes they built the thing using:

  • Watcom C/C++, version 9.5
  • Microsoft Macro Assembler, version 6.1x
  • Opus Make, version 6.01

 

I was unable to find Opus Make, however with a little bit of tweaking, Microsoft nmake can happily read the makefiles.  The other small snag largely was due to MS-DOS not being able to process massive commandlines, and having to build response files to the librarian and linker in various parts.  But all in all it was thankfully a trivial amount of work to get a working executable.

I only tested it for a few minutes until I was feeling out of it again.  I guess it isn’t surprising, I had issues when it was full screen back in 1994, but in a tiny window in 2013 it is unbearable.

For the two or three people who care, here is my VMDK that I used.  It works fine with Qemu probably other emulators that can read VMDK’s.

 

Public Domain Operating System

So, I came across this project from some random google search on Watcom the other day.  Simply put it is a MS-DOS API that is supported in both a 16bit real mode operating system, and a 32bit operating system.  It is quite sparse but very interesting all the same.  Using the ancient EMX port of GCC you can build 32bit (simple) programs, and run them in the 32bit DOS like Operating System.  What makes this even more interesting is that there is a port to the IBM 370, and 390 based hardware, along with the fictional 380.

Screen Shot 2013-09-16 at 6.40.03 PM

PDOS-16 booting in Qemu 1.6

Screen Shot 2013-09-16 at 6.39.47 PM

PDOS-32 booting in Qemu 1.6

You can download my diskimages, (VMDK & floppy disk) that I’ve used with Qemu to build & boot PDOS both 16bit and 32bit.

The included libc & system libraries are lacking compared to real MS-DOS, but this is public domain code, and with a bit of TLC it could be made into something much more.

Kali

My friend, Mara’akate is working on locating all the versions of Kali, and it’s precursor iDoom/iFrag.  His collection is available here.

Briefly this software let you play Doom (and other Doom variants) with other people over the internet.

I’ll have to write something up about this later on, but before I head out this Friday evening I thought I should at least give him a quick shout out, and hope that anyone out there has anything further to contribute could do so.

I wonder how hard it’d be to organize a Doom match in 2013…. probably just as hard as it was in 1993 if not more difficult.  Although the main issue today would be time, not finding a capable machine like it was back then.

Blake Stone source code released!

Blake Stone!

Blake Stone!

 

Honestly I never played Blake Stone, because as the wikipedia entry says DOOM came out a week later.  Blake is a Wolf3d variant, so I would imagine that the same build environment that can build Wolf3d can build Blake (Borland C 3.1 & TASM 3.1).

For those of you interested in this 20+ year old artifact, you can download the source code here.  And as mentioned Blake can be purchased through steam as part of the Apogee Throwback Pack.

An update to the whole thing, Marakaate has fixed the source well enough to compile!  You can read about his adventure here, and download his updated source here.  He’s also asked me to plug his BBS, marabbs.no-ip.org .. You can just telnet to the IP address.  There is some palette issues as they are compiled into the game, not read from the data files (wtf?) and have been extracted from an exe, however the starting logo is all wrong.. But the game works.

So, enjoy!

European MS-DOS 4.00 aka multitasking DOS

DOS 4.00M

DOS 4.00M

 

So this gem popped into my mailbox as everyone over at os2museum was whipped into a frenzy over the apparence of the predecessor to OS/2 making a showing!

So what is this, where did it come from?

To quote the excellent book, Inside OS/2 here is what this version is all about:

Microsoft started work on a multitasking version of MS-DOS in January 1983. At the time, it was internally called MS-DOS version 3.0. When a new version of the single-tasking MS-DOS was shipped under the name MS-DOS version 3.0, the multitasking version was renamed, internally, to MS-DOS version 4.0. A version of this product–a multitasking, real-mode only MS- DOS–was shipped as MS-DOS version 4.0. Because MS-DOS version 4.0 runs only in real mode, it can run on 8088 and 8086 machines as well as on 80286 machines. The limitations of the real mode environment make MS-DOS version 4.0 a specialized product. Although MS-DOS version 4.0 supports full preemptive multitasking, system memory is limited to the 640 KB available in real mode, with no swapping.

It is not feasible to support general purpose swapping without memory management hardware that is unavailable in 8086 real mode. This means that all processes have to fit into the single 640 KB memory area. Only one MS-DOS version 3.x compatible real mode application can be run; the other processes must be special MS-DOS version 4.0 processes that understand their environment and cooperate with the operating system to coexist peacefully with the single MS-DOS version 3.x real mode application.

Because of these restrictions, MS-DOS version 4.0 was not intended for general release, but as a platform for specific OEMs to support extended PC architectures. For example, a powerful telephone management system could be built into a PC by using special MS-DOS version 4.0 background processes to control the telephone equipment. The resulting machine could then be marketed as a “compatible MS-DOS 3 PC with a built-in superphone.”

Although MS-DOS version 4.0 was released as a special OEM product, the project–now called MS-DOS version 5.0–continued. The goal was to take advantage of the protected mode of the 80286 to provide full general purpose multitasking without the limitations–as seen in MS-DOS version 4.0–of a real-mode only environment. Soon, Microsoft and IBM signed a Joint Development Agreement that provided for the design and development of MS-DOS version 5.0 (now called CP/DOS). The agreement is complex, but it basically provides for joint development and then subsequent joint ownership, with both companies holding full rights to the resulting product.

As the project neared completion, the marketing staffs looked at CP/DOS, nee DOS 5, nee DOS 4, nee DOS 3, and decided that it needed…you guessed it…a name change. As a result, the remainder of this book will discuss the design and function of an operating system called OS/2.

So there you have it, OS/2 started out as a multitasking version of MS-DOS, one can even tell from some of the information on LINK4, that its architecture was also contributed to Windows, and much of how the original Windows 1.x and 2.x ‘wanted to be run from 286 protected mode, well I’d venture a guess that as OS/2 was being ‘born’ there were a lot of plans for this common architecture.  Of course I have no proof but it would seem to fit.. From Saving Windows from the OS/2 Bulldozer:

Thanks to Steve Wood’s original memory-allocation design, many of the changes involved bypassing real-mode code that served only to emulate the protected mode of the 286.

It would make sense at the time both multitasking DOS, being used for parts of early Windows, as both would be fighting the same problems regarding trying to live in the 640kb dos memory area.  While going with a protected mode in OS/2 there would be no need to maintain this, and they could start with a new memory model, Windows 3.0 went with an in house DOS Extender, and fleshed out more of its memory handling to be more 286 native.

Its a shame they didn’t go straight to 32bit stuff on the 386, bypassing the 286 but IBM was the proverbial elephant demanding 286 support.

For anyone wanting to try out this ancient OS, I was able to find out that it does run on DOSBox! So that means if you have a java capable machine you can quickly boot it up! The left alt key brings up the task switcher, and you can use the arrow keys to navigate.

DOOM runs.  I’m really still amazed at this, but it does crash on exit.  I think it was more so geared to small text mode stuff, much like what Windows 1.x or 2.x is capable of on a 286.

 

Found an old ad for 86-DOS

Seattle 86 Ad

GO 16-BIT NOW – WE HAVE MADE IT EASY
8086
8 Mhz. 2-card CPU Set
WITH 86-DOS®
ASSEMBLED,TESTED,GUARANTEED
With our 2-card 8086 CPU set you can upgrade your Z80 8-
bit S-100 system to run three times as fast by swapping the
CPUs. lf you use our 16-bit memory, it will run five times as
fast. Up to 64K of your static 8-bit memory may be used in the
8086’s 1-megabyte addressing range. A switch allows either 4
or 8 Mhz. operation. Memory access requirements at 4 Mhz.
exceed 500 nsec.
The EPROM monitor allows you to display, alter, and
search memory, do inputs and outputs, and boot your disk.
Debugging aids include register display and change, single
stepping, and execute with breakpoints.
The set includes a serial port with programmable baud rate,
four independent programmable 16-bit timers (two may be
combined for a time-of-day clock), a parallel in and parallel out
port, and an interrupt controller with 15 inputs. External power
may be applied to the timers to maintain the clock during
system power-off time. Total power: 2 amps at + 8V, less than
100 mao at + 16V and at -16V.
86-DOS@>, our $195 8086 single user disk operating
system, is provided without additional charge. It allows
functions such as console 1/0 of characters and strings, and
random or sequencial reading and writing to named disk files .
While it has a different format from CPIM, it performs similar
calls plus some extensions (CP/M is a registered trademark of
Digital Research Corporation). Its construction allows relatively
easy configuration of 1/0 to different hardware. Directly
supported are the Tarbell and Cromemco disk controllers.
The 86-D08@> package includes an 8086 resident assembler,
a Z80 to 8086 source code translator, a utility to read
files written in CPIM and convert them to the 86-DOS format, a
line editor, and disk maintenance utilities. Of significance to
Z80 users is the ability of the translator to accept Z80 source
code written for CPIM, translate this to 8086 source code,
assemble the source code, and then run the program on the
8086 processor under 86-D08. This allows the conversion of
any Z80 program, for which source code is available, to run on
the much higher performance 8086.
BASIC-86 by Microsoft is available for the 8086 at $350.
Several firms are working on application programs. Call for
current software status.
All software licensed for use on a single computer only.
Non-disclosure agreements required. Shipping from stock to
one week. Bank cards, personal checks, CODs okay. There is
a 10-day return privilege. All boards are guaranteed one year
– both parts and labor. Shipped prepaid by air in US and
Canada. Foreign purchases must be prepaid in US funds.
Also add $10 per board for overseas air shipment.
8/16 16-BIT MEMORY
This board was designed for the 1980s. It is configured as
16K by 8 bits when accessed by an 8-bit processor and
configured 8K by 16 bits when used with a 16-bit processor.
The configuration switching is automatic and is done by the
card sampling the “sixteen request” signal sent out by all S-
100 IEEE 16-bit CPU boards. The card has all the high noise
immunity features of our well known PLUS RAM cards as well
as “extended addressing”. Extended addressing is a replacement
for bank select. It makes use of a total of 24 address lines
to give a directly addressable range of over 16 megabytes.
(For older systems, a switch will cause the card to ignore the
top 8 address lines.) This card ensures that your memory
board purchase will not soon be obsolete. It is guaranteed to
run without wait states with our 8086 CPU set using an 8 Mhz.
clock. Shipped from stock. Prices: 1-4, $280; 5-9, $260; 10-up,
$240.

~Seattle (amputer Products, Inc. ~ 1114 Industry Drive, Seattle, WA. 98188
(206) 575-1830

 

The ad is from December of 1980, and of course the PC was released in August of 1981… Its interesting to see even back then there was some clear partnering with Microsoft!

Working with the Microsoft Programmer’s Library

OS/2 Programmers Ref

Well recently I did manage to get some GREAT books on OS/2, going back to the Microsoft days.. And they contain a lot of information, which was actually quite substantial.

Although there is the impression after the fact that Microsoft really wasn’t that dedicated to OS/2 the wealth of information in these books seem to be otherwise..

Anyways there is four volumes in the set, 1-3 going over version 1.1, and volume 4 with the 1.2 release of OS/2.

As luck would have it, someone gave me a lead on an ISO that contained not only these, but all of the programming documentation of the time on a CD.  No doubt this was the predecessor to the excellent MSDN.

There of course, is just one catch.  It uses the .hlp files, but not from Windows 3.00 its something much earlier and the only way to view the files is with an MS-DOS program.

Glorious MS-DOS interface

I even tried it on OS/2 hoping it was a family api program (like so many of the era were) but no luck.  I was then hoping maybe I could just ‘print’ the files to a virtual printer, and spool the whole job.  BUT YOU CANT PRINT.

So I then wondered if I could put together a TSR that would scrape the screen, append it to a file, and just keep hitting page down.   A few hours of cobbling together some example programs, and remembering to compile with the LARGE memory model (FAR pointers! remember those?)  I could then finally unleash the TSR through the program and extract some of the texts.

For those wondering how to do this kind of thing from MS-DOS here is the source.  While I wanted to use Scott’s program, there was the one drawback that almost everything grabs printscreen now so doing a REAL printscreen that hits interrupt 5 seems like it’d actually require a physical PC in MS-DOS.  And my current ‘retro’ PC has no ethernet so I wasn’t going to go that route.

So there is a lot of hacks with this, you can’t even uninstall it, just reboot …. but this hooks the clock, gives you about a minute to go where you want to go, then it saves a portion of the screen to a file, waits a few seconds and hits pagedown, and repeats….

// Written by Scott Hall of the U. of Missouri - Columbia, USA.
// This program will redirect your print screen button so that
// it goes to a file.  The file name is at the beginning of the
// start() function.  It can easily be modified to print screens
// that are larger than 80x25.

#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <dos.h>

#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif

char far *scr=(char far*)0xb0008000L;
#define VIDMEM 0Xb0008000L
#define INTR 0x1c

int busy=0;                                     // mutual exclusion (MUTEX)
void interrupt (*oldhandler)(__CPPARGS);
char far *old_dta;
char fname[9];

void interrupt int_5();
void tsr(unsigned size);                        // standard tsr bios call
void write_char(int x, int y, char ch, int attrib);
void write_string(int x, int y, char *str, int attrib);

void start(void);
void interrupt handler(__CPPARGS);

int main(int argc, char*argv[])
{
   if(argc==2)
   sprintf(fname,argv[1]);
      else
   sprintf(fname,"log.txt");

   printf ("installing\n");
   disable();
   oldhandler=getvect(INTR);
   setvect(INTR,handler);
   setvect(32,oldhandler);
   enable();
   printf("done\n");
   tsr(1000);
return 0;
}

void tsr(unsigned size)                 // standard tsr bios call
{                                       // you can also use keep()
union REGS r;

r.h.ah = 49;                            // function 0x31
r.h.al = 0;
r.x.dx = size;
int86(0x21,&r, &r);                     // last line executed
}                                       // never get to this line

unsigned char j=0;
unsigned int tcount;
unsigned int dcount=0;

//void interrupt int_5()                  // print screen button starts here
void interrupt handler(__CPPARGS)
{

if(dcount>480)
   {
   if(!busy&&tcount>5)
      {
      char far *p;
      union REGS r;
      struct SREGS s;

      p=scr;
      *p+=6;
      *p++=j;
      *p++=0x4f;

      j++;

      busy = !busy;                   // mutex around tsr
      start();

      r.h.ah=0x5;
      r.h.ch=0x51;    //pagedown?
      r.h.cl=0x0;
      int86x(0x16,&r, &r, &s);

      busy = !busy;
      tcount=0;
      }
   tcount++;
   }
else
   dcount++;
}

void write_char(int x, int y, char ch, int attrib)
{                                       // displays 1 character at (x,y)
char far *v;

v = (char far *) VIDMEM;
v += y*160 + x*2;
*v++ = ch;
*v = attrib;
}

void write_string(int x, int y, char *str, int attrib)
{                                       // writes string str at (x,y)
for( ; *str; str++,x++)
   write_char(x, y, *str, attrib);
}

int firsttime=0;        //need to skip 3 lines after the first time we
//page down.

void start(void)
{
int fd,x,y;
char cr=0x0D, lf=0x0A;

old_dta=getdta();
setdta((char far *)MK_FP(_psp,0x80));

//if((fd =_open("c:\\temp\\log.txt",O_WRONLY))<0) // open the file
//        if((fd =_creat("c:\\temp\\log.txt",_A_NORMAL))<0) // try to make new
//                write_string(1,1,"OOPS--write error1",0x8F);

if((fd =_open(fname,O_WRONLY))<0) // open the file
   if((fd =_creat(fname,_A_NORMAL))<0) // try to make new
   write_string(1,1,"OOPS--write error1",0x8F);

lseek (fd,0,SEEK_END);                          // jump to end of file

//for(y=0;y<25;y++)                               // grab lines 0 to 24
for(y=2+firsttime;y<24;y++)
   {
   //for(x=0;x<80;x++)                       // grab rows 0 through 79
   for(x=1;x<79;x++)                       //cut the bars from msl

   if(_write(fd,(char far *)(VIDMEM+160*y+2*x),1)==-1)
      write_string(1,2,"OOPS--write error2",0x8F);

   if(_write (fd,&cr,1)==-1)               // put a cr and lf at end
      write_string(1,3,"OOPS--write error3",0x8F); // of line

   if(_write (fd,&lf,1)==-1)
      write_string(1,4,"OOPS--write error4",0x8F);
   }

_close(fd);                                     // close the file

setdta(old_dta);
if(firsttime==0)
firsttime=1;
}

Hopefully this will help someone in the distant future, maybe it’ll just serve as a warning on how not to build stuff … lol

Oh and I used Borland C++ 3.1, but compiled this as C for the LARGE memory model.

DJGPP 1.03 saved thanks to shovelware + cd.textfiles.com

I can’t stress enough just how awesome cd.textfiles.com is for finding ancient stuff!

I’m not sure why I started on this quest but I was looking for some old finicky DOS extender, and started hunting for Go32, the first DOS extender used by DJGPP.  And for the heck of it, I wanted to find the first version, which I pretty much had assumed was lost to the mists of time.

However the CD-ROM shareware collection called MegaROM-1 actually had a ‘full’ copy of one of the first versions of DJGPP, 1.03.

Installation is pretty straightforward, however you have to use pkunzip for all the various old ‘methods’ of storing data in zip files, I found infozip leaves things out..

Also DJGPP 1.03 uses a LOT of environment space.. which is more so a problem for people running real MS-DOS on real machines.. (there are some!)…

Hello World!

It runs in DOSBox, but there is no doubt some stack corruption as trying to run things like dos edit result in:

Packed file is corrupt

But at least we can run more than one copy, or use a native editor.

GO-32 from this era is *NOT* DPMI compliant, nor is it VCPI compliant.  And its based on GCC 1.39, which was a popular level with things like 386 BSD, although it seems early Linux used GCC 1.40 ..  The tool chain by default outputs the GNU a.out format, but relies on modifying the linker that was separately included in G++.  Later versions of GO32 included VCPI support, and near it’s end of life version 1.10 added support for DPMI which greatly simplified things like hooking IRQ’s and doing DMA.

For those who want to play, without the pkzip fun, I’ve slapped it into a single 7zip file.  It’s not even a megabyte.  But it was 1991, when 4MB of ram seemed like an incredible amount of memory!