Looking back at MS-DOS 4.00M, or in the beginning before there was OS/2

With the pre-christmas release of the Microsoft OS/2 betas 1.00, 1.01, 1.02, 1.03 & 1.05 on archive.org, and helping Ncommander with an upcoming video, it seemed like a good place to start, not with OS/2 but rather with MS-DOS 4.0.

From the book INSIDE OS/2 ( ISBN 1-55615-117-9 )

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.2 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.

– Inside OS/2.

Although MS-DOS 4.00M disk images have been floating around for quite some time, either a 2 360k disk set, or a single 720k disk image, I don’t think anyone (including me) really tore into it that much. It does have the ability to freeze DOS 3 programs, giving the illusion of running more than one. The session manager is pretty sparse but hitting left alt twice will pop it up giving you the ability to toggle through programs with ease.

MS-DOS 4.00M

There is a FDISK, FORMAT & SYS command making it straight forward to setup a hard disk, and copy the files over, I didn’t see any installer.

there is a PS command to show running processes. Also there is a DOSSIZE to show the memory partitioning and how much is available. Although there is a SWAPPER program I’ve been unable to get it to actually fun.

multitasking!

Another interesting thing if you run the unix ‘strings’ command against all the EXE’s you’ll find the string:

C Library - (C)Copyright Microsoft Corp 1985

Implying that not only was DOS 4.00M a ‘new’ DOS, but it was also written in C. No doubt this contributed to a larger file size than DOS 3, however it would also give that holy grail of portability, at least to new CPU modes. Also many files have the name of the source files baked in such as:

@(#)append.c    1.1 85/10/09
@(#)assign.c    6.1 85/10/23
@(#)attrib.c    6.1 85/10/24
@(#)fdisk.c     1.1 85/10/09
@(#)fddata.c    1.1 85/10/09
@(#)fdlow.c     1.1 85/10/09
@(#)fdsub.c     1.1 85/10/09
@(#)joinsbst.c  6.3 85/11/08
@(#)sysvar.c    6.2 85/11/08
@(#)cds.c       6.2 85/11/08
@(#)dpb.c       6.1 85/11/08
@(#)label.c     6.1 85/10/24
@(#)newdef.y    6.2 85/10/14
@(#)ms4bnr.c    1.1 85/10/15
@(#)mode.c      6.2 85/10/24
@(#)getkey.c    6.1 85/10/25
@(#)pifmes.c    6.1 85/10/25
@(#)advpscrn.c  6.1 85/10/25
@(#)advescrn.c  6.1 85/10/25
@(#)usrscrn.c   6.1 85/10/25
@(#)rangers.c   6.1 85/10/25

Okay so far, so good. But we’ve all seen this before, and scratched this OS about this far, because what else can you do? It’s not like there is any dev tools to do anything fun!

Well the tool hidden in plain sight is LINK4, which in retrospect is specific for MS-DOS 4.00M.

Microsoft (R) 8086 Object Linker  Version 4.01
Copyright (C) Microsoft Corp 1984, 1985.  All rights reserved.

Object Modules [.OBJ]:

There is no SDK for MS-DOS 4.00M, but they were kind enough to leave the linker in place. A quick check of the Windows 1.01 SDK shows that it also includes LINK4:

Microsoft 8086 Object Linker
Version 4.00  (C) Copyright Microsoft Corp 1984, 1985

Object Modules [.OBJ]:

It appears that if the dates and versions are to be trusted they are of the same vintage, but the Windows linker is older, and that they both output to a NE or New Executable. So to start the experiment I created a simple hello world exe from a simple:

void main(){
  printf("Hello from MSC 3\n");
}

To compile this I used Microsoft C 3.0 (more on why later), and used LINK4 to create an EXE:

C:\dos\msc3>cl /c hello.c
Microsoft C Compiler  Version 3.00
(C)Copyright Microsoft Corp 1984 1985
hello.c

C:\dos\msc3>msdos dos4m\link4 hello.OBJ

Microsoft (R) 8086 Object Linker  Version 4.01
Copyright (C) Microsoft Corp 1984, 1985.  All rights reserved.

Run File [HELLO.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
Definitions File [NUL.DEF]

Okay, everything looks fine so far. Attempting to run this under MS-DOS just results in the error:

Program too big to fit into memory

Well now that’s odd. Checking the EXE with the Linux ‘file’ command reveals:

file HELLO.EXE
HELLO.EXE: MS-DOS executable, NE (unknown OS 0) (EXE)

So obviously it’s a NE, but it is an older/unknown version to the file map database. There is no stub so I suppose that is why MS-DOS is getting confused.

Now let’s try MS-DOS 4.00M

Hello!

Well now isn’t that interesting?!

Excited with the ability to create special MS-DOS 4.00M programs, I get my favorite vintage ’87 Infocom interpreter, InfoTaskForce 87, and get it building on MSC 3.0. However instead of using the MS-DOS 4.00M linker, I thought I should try to use the Windows 1.01 linker and libraries for the exe:

C:\dos\msc3\infocom>msdos ..\win101sdk\bin\LINK4.EXE @infocom.win.lnk

Microsoft 8086 Object Linker
Version 4.00  (C) Copyright Microsoft Corp 1984, 1985

Object Modules [.OBJ]: FILE.OBJ FUNCS.OBJ INFOCOM.OBJ INIT.OBJ INPUT.OBJ +
Object Modules [.OBJ]: INTERP.OBJ IO.OBJ JUMP.OBJ OBJECT.OBJ OPTIONS.OBJ PAGE.OBJ +
Object Modules [.OBJ]: PRINT.OBJ PROPERTY.OBJ SUPPORT.OBJ VARIABLE.OBJ TERM.OBJ
Run File [FILE.EXE]: INFOCOM.EXE/ALIGN:16
List File [NUL.MAP]: INFOCOM.MAP
Libraries [.LIB]: MWLIBFP MWLIBC/NOD
Definitions File [NUL.DEF] INFOW.DEF;

And for those interested this is my .DEF file:

NAME    Infocom

DESCRIPTION 'Infocom 87 interpreter for Planetfall(83)'

DATA    MULTIPLE


HEAPSIZE    1024        ; Must be non-zero to use Local memory manager
STACKSIZE   4096        ; Must be non-zero for SS == DS
                        ; suggest 4k as minimum stacksize

SEGMENTS
    _INIT   PRELOAD MOVEABLE DISCARDABLE

One thing to save you the horror is that between MS-DOS 2 & 3 the way command line arguments changed. I forget the details but no matter what I tried I was unable to parse the CLI or the environment in this setup. I suppose if I had documentation of the product there would be some hint as to what tools or setup to use. Instead, I took the easy way and hard coded to load Planetfall.

InfoTaskForce compiled with MSC 3.0, using Windows 1.01 libc / LINK4

Unfortunately, this success would prove to be the exception to the rule. I took trek, converted it to K&R C, as Microsoft C 3.00 from 1985 is well. old, and sadly it just won’t run. Likewise, I took Hack 1.03 and although it runs on MS-DOS it will not run on MS-DOS 4.00M. I am sure there is some fundamental reason why it’s not working, and probably tied to creating a proper DEF file. I’m sure it was all written down somewhere but I don’t know. And yes I tried specifying either floating point emulation via library or inline, and it made no difference.

Looking at OS/2 1.00

Loading up the infamous $3,000 OS/2 1.00 beta, and hitting ctrl+escape you are greeted with session manager!

Session Manager for OS/2

Notice the R for real-mode. With the obvious implication that everything else is protected mode. Going one step further on the excellent site pcjs.org there is OS/2 betas SIZZLE and although there is no OS/2 development bits on there, the directory DOS3TOOL reveals that the C compiler for this era for at least MS-DOS is MSC 3.0. Also included is our friend LINK4.

I create a simple def file that contains the single word ‘PROTMODE’ which should give me my OS/2 binary.

So let’s run that through hello world:

msdos sizzle\DOS3TOOL\link4  hello.OBJ,hello,,,hello.def;

Microsoft (R) Segmented-Executable Linker  Version 5.00.21
Copyright (C) Microsoft Corp 1984, 1985, 1986.  All rights reserved.


C:\dos\msc3>

However attempting to run this just crashes amazingly.

Real mode LIBC in Protected mode:

No doubt it’s because the real-mode libc is using interrupt 21 calls, which OS/2 sure wouldn’t like. I’m pretty sure it requires an OS/2 libc that uses DOSCALLS.DLL to function, which I just don’t have any pre-release versions, nor any libc source code to really make it possible. And attempting to port one to OS/2 pre-releases just doesn’t seem so worth the time.

So for the heck of it I point the LIB variable to the OS/2 1.00 SDK’s libs and re-run the link:

C:\dos\msc3>msdos sizzle\DOS3TOOL\link4  hello.OBJ,hello.exe,hello.map,C:\86box\100\x\MSC\LIB\slibc5.lib \86box\100\x\LIB\DOSCALLS.LIB,hello.def;

Microsoft (R) Segmented-Executable Linker  Version 5.00.21
Copyright (C) Microsoft Corp 1984, 1985, 1986.  All rights reserved.

By default it’s trying to link in EM.LIB, SLIBFP.LIB, SLIBC.LIB. Trying to add them all in the command line link just hangs LINK4 maybe a response file is better suited. Anyways:

Hello from MSC 3.0 in protected mode.

It does run on OS/2 1.00, which I guess isn’t surprising as the LINK4 & libraries are from/for this version.

As an interesting note, OS/2 links against doscalls library/DLL to interface to the OS. While MS-DOS 4.00M doesn’t have a seperate DLL, rather it’s baked into IBMDOS.COM

DOSCALLS
ALLOCSEG
REALLOCSEG
FREESEG
LOCKSEG
UNLOCKSEG
GETSEGSIZE
GETDSHANDLE
CRITENTER
CRITLEAVE
FCRITENTER
FCRITLEAVE
PBLOCK
PRUN
SUBSCREEN
GETPIDS
DOSDISCARDCODE
DOSGETHANDLE
DOSHANDLEJUMP

Noticeably absent is file I/O, No doubt allowing programs to use the standard int21 interface to the kernel for file I/O. No doubt this is in its primordial state, as the OS was going to evolve a bit more until it became OS/2. Unfortunately I have no idea how to link or call into this. Without any SDK it’s impossible to say. And even then is developing for a real mode OS worth the effort?

So what have we learned? LINK4, aka the MS-DOS 4.00M Linker, probably should have been called LINKNE for the NE format. Also there is references to it having it’s own virtual memory paging system, and being able to link larger EXE’s than the traditional link command. Sadly I was unable to get any non trivial programs running. I don’t think it was a memory model thing, although the C compiler has issues with InfoTaskForce and the large memory model for some reason, but small & medium work fine. I’d like to think that DOS 4.00M could support massive EXE’s much like Windows 1.01, however despite being from the same company and using the same tools, the memory manager for DOS 4.00M & Windows is fundamentally different.

With all these exiting OS/2 betas now available I’ll have to take some more time to explore them in more detail.

But until then I thought this genesis of DOS 4.00M was worth the look.

All in the Family

One of the more interesting things about OS/2 1.x is how it had this interesting idea of how to strattle the bridge between old and new, and it was a very common bridge tactic where you can have a shipping program that can simply run in both the older operating system, and the new one. Naturally there is trade offs, you can’t fully take advantage of all kinds of features on the new side, you will be largely held back on the old side, but all is not lost, there is space for things that fit in the ‘same but bigger’ world where you have an overlap between old and new.

For OS X, this was the Carbon era, for Windows this was the famous Win32s extensions, and for OS/2 it’s the Family API.

As a quick example, allocating memory under MS-DOS may be limited to 640kb, but under OS/2 you have access to so much more memory, the entire capacity of an IBM AT class machine. And this also got OS/2 tools into a lot of MS-DOS developer’s hands as the early compilers and tools were built around the Family API and were able to run on so called legacy environments. Although it was far better to run on OS/2, the advantage 30+ years later is that MS-DOS emulation is more common and prevalent than OS/2, especially on non x86 processors.

Ages ago I had done a very simple video memory dump of the Microsoft Programmer’s Library giving me electronic access to the old documents, and a few queries give these as the Family API building blocks:

DOS

  • DosAllocHuge
  • DosAllocSeg
  • DosBeep
  • DosBufReset
  • DosCaseMap
  • DosChDir
  • DosChgFilePtr
  • DosCLIAccess
  • DosClose
  • DosCreateCSAlias
  • DosDelete
  • DosDevConfig
  • DosDevIOCtl
  • DosDupHandle
  • DosEnumAttribute
  • DosErrClass
  • DosError
  • DosExecPgm
  • DosExit
  • DosFileLocks
  • DosFindClose
  • DosFindFirst
  • DosFindFirst2
  • DosFindNext
  • DosFreeSeg
  • DosGetCollate
  • DosGetCtryInfo
  • DosGetDateTime
  • DosGetDBCSEv
  • DosGetEnv
  • DosGetHugeShift
  • DosGetMachineMode
  • DosGetMessage
  • DosGetVersion
  • DosHoldSignal
  • DosInsMessage
  • DosMkDir
  • DosMove
  • DosNewSize
  • DosOpen
  • DosPutMessage
  • DosQCurDir
  • DosQCurDisk
  • DosQFHandState
  • DosQFileInfo
  • DosQFileMode
  • DosQFSInfo
  • DosQPathInfo
  • DosQVerify
  • DosRead
  • DosReallocHuge
  • DosReallocSeg
  • DosRmDir
  • DosSelectDisk
  • DosSetDateTime
  • DosSetFHandState
  • DosSetFileInfo
  • DosSetFileMode
  • DosSetFSInfo
  • DosSetPathInfo
  • DosSetSigHandler
  • DosSetVec
  • DosSetVerify
  • DosSizeSeg
  • DosSleep
  • DosSubAlloc
  • DosSubFree
  • DosSubSet
  • DosWrite

Keyboard

  • KbdCharIn
  • KbdFlushBuffer
  • KbdGetStatus
  • KbdPeek
  • KbdSetStatus
  • KbdStringIn

Video

  • VioGetBuf
  • VioGetConfig
  • VioGetCurPos
  • VioGetMode
  • VioGetPhysBuf
  • VioGetState
  • VioReadCellStr
  • VioReadCharStr
  • VioScrLock
  • VioScrollDn
  • VioScrollLf
  • VioScrollRt
  • VioScrollUp
  • VioScrUnLock
  • VioSetCurPos
  • VioSetCurType
  • VioSetMode
  • VioSetState
  • VioShowBuf
  • VioWrtCellStr
  • VioWrtCharStr
  • VioWrtCharStrAtt
  • VioWrtNAttr
  • VioWrtNCell
  • VioWrtNChar
  • VioWrtTTY

I’m sure this is not exhaustive by any stretch. I got the list from a simple query like this:

grep -i 'family api' os2dev.txt | awk '{print $2}' > fam.txt
grep -i 'family api' prgmr[34].txt| awk '{print $3}' >> fam.txt
sort fam.txt | uniq > family.txt

As an added bonus you really don’t have to mess with the API at all, as the LIBC will use it no doubt.

At any rate, using Microsoft C 6.00 (I can’t get the syntax right for 5.1 to save my life, I suspect I need to run it UNDER OS/2 to build for OS/2 properly), you can compile a typical stdio compliant program, and get an OS/2 executable.

The real fun is from the bind program which will convert that OS/2 program to a full Family mode app with the bind program.

And now on MS-DOS (Under OS/2) you can see very quickly that the OS/2 app won’t run, however the family mode one does!

So this is what let’s me run the older SDK tools as I’d simply forgotten about this great mode, letting you run programs in either environment.

Of course the added fun is the 3rd party product Phar Lap’s 286|Dos-Extender that provides some OS/2 services under MS-DOS in addition to greater memory but DLL’s! But that’s for another story.

**EDIT Oh and another edit, here is how to make the OS/2 program ‘window’ compatible with a link time definition file:

OS/2 2.00 via telnet

and then on the console:

Window mode

And there we go with some magical flags & def file it’s now marked as being compatible with window mode. So no full screen VIO tricks for you!

PCem v15 released!

The new dynamic recompiler appears to be much more faster, although if you want maximum performance, make sure to set your video card to the fastest possible performance.

I was doing my typical DooM thing, and the performance was abysmal. But I did have an 8bit VGA card selected, so what would I really expect? Interestingly enough in ‘low resolution’ mode it performed quite well, but setting it to the artificial ‘fastest PCI/VLB’ speed it was performing just great.

PCem v15 released. Changes from v14 :

  • New machines added – Zenith Data SupersPort, Bull Micral 45, Tulip AT Compact, Amstrad PPC512/640, Packard Bell PB410A, ASUS P/I-P55TVP4, ASUS P/I-P55T2P4, Epox P55-VA, FIC VA-503+
  • New graphics cards added – Image Manager 1024, Sigma Designs Color 400, Trigem Korean VGA
  • Added emulation of AMD K6 family and IDT Winchip 2
  • New CPU recompiler. This provides several optimisations, and the new design allows for greater portability and more scope for optimisation in the future
  • Experimental ARM and ARM64 host support
  • Read-only cassette emulation for IBM PC and PCjr
  • Numerous bug fixes

Thanks to dns2kv2, Greatpsycho, Greg V, John Elliott, Koutakun, leilei, Martin_Riarte, rene, Tale and Tux for contributions towards this release.

As always PCem can be downloaded here:

Microsoft XENIX 286 BASIC Compiler

(This is a guest post by Antoni Sawicki aka Tenox)

I have recently acquired this artifact:

It’s the Microsoft BASIC compiler for XENIX 286 Operating System. Compiler as opposed to just BASIC interpreter, it can produce executable a.out files, similar to C compiler for example.  

Carefully removed the shrink wrap. Inside were couple of 5.25″ floppies, registration card and a manual:

Interestingly the 32 year old disks read just fine on a first attempt. I need to start backing up important files to 5.25″ floppy disks as they seem to outlast everything else.

Thanks to efforts of Michal Necasek from OS/2 Museum now you can run Microsoft XENIX 286 in Virtual Box

The disks can be installed in to XENIX running on Vbox following a few simple steps:

tar xvf /dev/fd0
./msinstall /dev/fd0

Upon installation you invoke the compiler like this:

bascom demo.bas
./a.out

And it produced an a.out executable which worked perfectly fine.

It’s fun to write BASIC code in vi editor, which I just realized I never done before.

Curiously the compiler also worked on the brand spanking new Xenix 2018, or rather I should call it Open Server 6, which you can download here.

The BASIC compiler is available for download from my archive along with the manual in pdf.

2ine updated to have preliminary 16-bit .exe support!

From icculus’s patreon

This is nothing short of amazing.  In the last update, 2ine was running simple 32bit programs on Linux, and providing a portable API set to allow strict OS/2 API based programs to run on Linux.

And now Ryan has turned his focus onto 16bit support for 2ine, which you can read about here:

https://www.patreon.com/posts/2ine-16-bit-exe-19337541

As you can read right now It’s running a simple OpenWatcom 16bit hello world based program.  The 16bit OS/2 and 32bit OS/2 API’s ended up having different calling sizes, among other issues which had complicated the bridge program.  However Ryan’s newer use of scripts to generate the required glue for the API’s at least mean that adding the 16bit/32bit calling conventions & required bridges/glue is at least now automated.

This is super cool, as this will eventually open the door to Watcom C/Fortran, Zortec C, Microsoft Basic/C/Cobol/Fortran and of course many other languages that burst out into the initial OS/2 scene before the eventual weight of the SDK & associated costs doomed OS/2 to failure.

Seriously, for those among us who love OS/2 and have like $5 to spare, send some encouragement to Ryan… 🙂

Coherent 3.0

I don’t know why I was so dumb as a kid, but I remember thumbing through various magazines, and always seeing this ad:

Coherent Ad

And isn’t that sounding great?  Lex, Yacc, UUCP, and UNIX functionality on a AT compatible machine for $99!  And then you see reviews like this one from PC Mag:

Now even if you want to you can’t wind the clock back to the late 1970s, but Unix lovers can do the next best thing-pick up a copy of Mark William’s Coherent for $99.95.

Included in this time capsule are all of the utilities that you would have received in an AT&T Unix, Version 7, distribution circa 1978. The package includes a protected-mode multi-user multitasking operating system. over 150 utility programs, a C compiler, an assembler, software development tools, text formatting tools, system management tools, telecommunications utilities, and complete documentation in a very hefty, 1,000-page, perfect bound book. Most of the Unix classics-grep, ed, sed, awk, lex, sh, emacs-are there as well. The only favorites that are missing are vi (which is a text editor) and Dave Korn’s new shell.

Whether Coherent’s views on the Unix system match your own is a matter of taste. In the halcyon late 1970s, the Unix system was a relatively simple affair-lean and clean, and understandable to mere mortals. Since then, in an effort to make Unix the universal solution, countless features and versions have been grafted onto it by innumerable programmers, managers, committees, and boards of directors.

The result stands in stark contrast to the stated goals of Unix’s inventors. Coherent remains true to Unix’s roots and eschews local area networking, graphical user interfaces, menus, mice, and many of the other amenities that present-day DOS users and Unix users have come to expect of modem software.

Coherent’s installation is painless, but only after the agony of freeing up a 7MB or larger partition on an ordinary MFM or RLL disk, on a classic AT architecture machine. Since they are products of the modem era, ESDI and SCSI disks, as well as IBM’s Micro Channel architecture are not supported. Graphic display adapters are tolerated (used in text mode); mice are not supported. Coherent worked flawlessly, though, on my geriatric AT clone.

Coherent has a dual boot facility, so that you can choose to boot either DOS or Coherent during your startup procedures, but unfortunately you can’t run
DOS software from within the Coherent environment.

Mark Williams’president Robert Schwartz explained that the intended audience for Coherent are people who want to learn about or try the Unix system, without the hefty price tag and steep learning curve of the latest Unix versions. Part of Coherent’s advantage in both simplicity and price stems from its origins as a privately developed “clone” product-therefore no AT&T requirements need be met and no per-copy royalty is paid to AT&T. This gives Mark Williams the freedom to set prices as well as compatibility targets.

But learning Unix from Coherent would be a bumpy road. You could certainly master traditional system administration, learn the utilities. And experiment with Unix software development. But you couldn’t learn about networking or the increasingly important X Windows system. Nor could you realistically use Coherent to automate a small business.

Schwartz promises that future versions of Coherent will support 32-bit operation on the 386, and will likely support tighter integration with DOS, some form of window manager. And local area networking. When that occurs, Coherent will be much more like modem Unix systems and, like modem Unix systems, it will have strayed far from its roots.

List Price: Coherent Version 3.0, $99.95.
Requires: A free 7MB or larger hard disk partition, 640K RAM, highly disk drive, MFM or RLL controller.

Mark Williams Co., 601 N.
Skokie Hwy., Lake Bluff. IL
(Kaare Christian)

And then it seemed to my teenage eyes something pretty underwhelming.  So I dove into OS/2, and ignored the idea of having a UNIX like system.  I was still happy to finally move onto a 16-bit machine, and the thought of running stuff from the 1970’s wasn’t that appealing. Such missed opportunities.  But in the last few years, Coherent has been placed under a 3-clause BSD license.

Over at unix4fun, they did unearth some version 3.0 disks!  And yes, it’ll install on PCem/86Box using a 286/386/486 machine.  One issue I had was I first tried to install onto a massive 40Mb disk, and it never would reboot after the install correctly.  However it works great with a 32Mb or smaller disk.  As you can see from Kaare’s review it’ll fit into 7MB of disk space!  At least having to either re-partition or worry about dual booting is a thing of the past.  The disk images are 5.25 disk images, so re-configure your VM appropriately.

Coherent on PCem

As the advertisement says, the installation is a mere four diskettes!  And yes, it really does have a C compiler.  You will need a serial number for Coherent 3.0, which took a while to find, but Peter had one, and has been poking me for the last week+ to finally write this up.  Oh the number is 130500000.  305/Miami connection? Unlikely, but who knows.  Don’t forget to download the hefty manual, Coherent_Revision_8_1992, which is for a later version, but still suitable.

And yes, it feels just like Unix v7.  The kernel is tiny, 77kb!  It’s really cool for 16-bit era stuff, and really interesting to knock around.  I know there is a few more people out there that want fun things for their 286, and Coherent will certainly scratch that itch.

Additionally on the site are the 3.1 and 3.2 updates to give you thinks like Elvis so it doesn’t feel anywhere near as primitive.  Installing updates and 3rd party packages is covered on page 736 of the manual, or in short you need to know the magical ‘disk set name’ for everything you want to install.  I suppose back then it had stuff like this printed on them.

coh300-ddk.img Drv_110
coh300-rdb.img rdb
coh31update-1.img CohUpd310
coh320update-1.img
coh320update-2.img CohUpd320
coh320-ddk.img

While a ‘dump’ of the source code has been out there, I haven’t really gone through it, so I thought now would be as good as any to take a look at the kernel.  The layout is very similar to v6, so I based this on the file ‘sys1.c’ which appears quite a few times in the trees.  Using a MD5 checksum against the files there appears to be no less than 17 duplicated tress or 7 unique kernels, spread over three years.

cc3b2bef09be7d60d52a01ca908972f7 Jul,24,1991 gtz/relic/d/kernel/USRSRC/coh/sys1.c
cc3b2bef09be7d60d52a01ca908972f7 Jul,24,1991 romana/relic/d/kernel/USRSRC/coh/sys1.c

41797301f9d5771dd10161954df82a5d Jan,13,1992 gtz/relic/d/286_KERNEL/USRSRC/coh/sys1.c
41797301f9d5771dd10161954df82a5d Jan,13,1992 romana/relic/d/286_KERNEL/USRSRC/coh/sys1.c
6b888a45afb3476c5e482fa54fb4dd86 Jul,17,1992 gtz/relic/b/kernel/coh.286/sys1.c
6b888a45afb3476c5e482fa54fb4dd86 Jul,17,1992 romana/relic/b/kernel/coh.286/sys1.c
6b888a45afb3476c5e482fa54fb4dd86 Aug,11,1992 gtz/relic/d/PS2_KERNEL/coh.286/sys1.c
6b888a45afb3476c5e482fa54fb4dd86 Aug,11,1992 romana/relic/d/PS2_KERNEL/coh.286/sys1.c
b90f2659fdecfbfa576d39bc8e54ffa0 Aug,11,1992 romana/relic/d/PS2_KERNEL/coh.386/sys1.c
b90f2659fdecfbfa576d39bc8e54ffa0 Aug,11,1992 gtz/relic/d/PS2_KERNEL/coh.386/sys1.c

6503663ebb9a852007a46d66cd43ac1a Jun,14,1993 gtz/relic/b/kernel/coh.386/sys1.c
6503663ebb9a852007a46d66cd43ac1a Jun,14,1993 romana/relic/b/kernel/coh.386/sys1.c
35bc7569ab99ab340d2ca8bf66a47c46 Aug,9,1993 romana/relic/b/STREAMS/coh.386/sys1.c
35bc7569ab99ab340d2ca8bf66a47c46 Aug,9,1993 gtz/relic/b/STREAMS/coh.386/sys1.c
436f245293c88ceaecd99840c37dcbb4 Nov,15,1993 gtz/hal/r10/coh.386/sys1.c
436f245293c88ceaecd99840c37dcbb4 Nov,15,1993 gtz/src/sys.r12/coh.386/sys1.c
436f245293c88ceaecd99840c37dcbb4 Nov,15,1993 gtz/src/sys.r12/coh.386/r12/sys1.c

Phew!  Naturally the tree structure drifted, but I went ahead and just did a blind import into my CVS server to take a look. And there really does appear in the 1991 versions to be the remnants of either 2.3.37, 3.2.1.  It’s hard to say.

MS-DOS player can now embed executables

So what this means is that now you can make fully standalone Win32/Win64 executables out of CLI based MS-DOS applications.

D:\tcc>msdos\binary\i486_x64\msdos.exe tcc -Iinclude -Llib hi.c
Turbo C++ Version 3.00 Copyright (c) 1992 Borland International
hi.c:
Turbo Link Version 5.0 Copyright (c) 1992 Borland International

Available memory 4215648

D:\tcc>c:msdos\binary\i486_x64\msdos.exe hi
hi!

D:\tcc>c:msdos\binary\i486_x64\msdos.exe -c hi.exe
‘new_exec_file.exe’ is successfully created

D:\tcc>new_exec_file.exe
hi!

Isn’t that great?

I’ve had one issue with Turbo C++ 3.00 and that is the embedded executable will run out of memory while linking, but invoking it by calling msdos.exe let’s it run fine. If you compile and link separately it’ll run just fine.

As always you can find the project page here:

http://takeda-toshiya.my.coocan.jp/msdos/index.html

 

 

 

As requested, PCem v11 with networking

via SLiRP

via SLiRP

injecting networking was no more difficult than it was in version 10.  It’s only a few changes to pc.c, if you look at the USENETWORKING define you’ll see them.  The best notes are on the forum.

I haven’t changed or improved anything it still requires manual configuration.

Downloads are available on my site as pcem_v11_networking.7z.  You’ll have to defeat the password protection, as always.  I included the source, it ought to be trivial to rebuild.

*For anyone using an old version the ‘nvr’ directory is missing, so PC-em is unable to create new non volatile ram save files, meaning you always loose your BIOS settings.  Sorry I missed that one.

PCem v11 released

I haven’t had time to follow it, but great news!

PCem v11 released. Changes from v10.1 :

  • New machines added – Tandy 1000HX, Tandy 1000SL/2, Award 286 clone, IBM PS/1 model 2121
  • New graphics card – Hercules InColor
  • 3DFX recompiler – 2-4x speedup over previous emulation
  • Added Cyrix 6×86 emulation
  • Some optimisations to dynamic recompiler – typically around 10-15% improvement over v10, more when MMX used
  • Fixed broken 8088/8086 timing
  • Fixes to Mach64 and ViRGE 2D blitters
  • XT machines can now have less than 640kb RAM
  • Added IBM PS/1 audio card emulation
  • Added Adlib Gold surround module emulation
  • Fixes to PCjr/Tandy PSG emulation
  • GUS now in stereo
  • Numerous FDC changes – more drive types, FIFO emulation, better support of XDF images, better FDI support
  • CD-ROM changes – CD-ROM IDE channel now configurable, improved disc change handling, better volume control support
  • Now directly supports .ISO format for CD-ROM emulation
  • Fixed crash when using Direct3D output on Intel HD graphics
  • Various other fixes

Thanks to Battler, SA1988, leilei, Greatpsycho, John Elliott, RichardG867, ecksemmess and cooprocks123e for contributions towards this release.

Downloads are available for Windows & Linux.

FOOTBALL Design Document

Over at pcjs.org, this interesting prototype version of OS/2 has been unearthed.  What this means is that not only was there prototypes of a 386 aware version of OS/2 in 1986, but by 1987 the base of cruiser AKA OS/2 2.0 was already in place.  With this now somewhat made public, it really is clear that IBM’s meddling in OS/2 prevented it from being a success.

Check out the design document below:
The following text is from an email titled “3xBox Design Document” sent to the football alias on Saturday, February 28, 1987, at 5:02pm.

Overview

The goal for this research project was to demonstrate the feasability of supporting multiple virtual DOS 3.x machines on a 286DOS-based kernel running on an 386 personal computer. Each “3xBox” would have its own virtual screen, keyboard, interrupt vectors, and address space. Furthermore, well- behaved DOS 3.x applications that do text (as opposed to graphic) screen output would run in the background.

In order to acheive this goal in a reasonable amount of time, we started from the 286DOS “sizzle” kernel and made the minimum amount of changes necessary, both in code and fundamental design. The resulting DOS will be referred to as “386DOS” in this paper.

386DOS provides up to four 3xBoxes, depending upon the available RAM. More 3xBoxes could be supported if a slight change is made to the method of allocating page tables.

Well-behaved DOS 3.x applications (i.e., MS-Multiplan, MS-Word, Lotus 1-2-3) can run in the background, multi-tasking against one another and against the foreground screen group. Lotus 1-2-3 (version 2.01) passes its floppy-based copy protection when in the foreground.

It should be noted that 386DOS, while functional, is not an optimal design/implementation of multiple 3xBoxes. In particular, interrupt management, the device driver model, and the existence of V86-mode kernel code should be modified before 386DOS is made a commercial product.

Unless stated otherwise, most of the concepts extant in 286DOS apply to 386DOS.

V86 Mode and the 386

The 386 CPU has three distinct execution modes: REAL, PROT, and V86. REAL
and PROT modes are largely compatible with the corresponding modes of an 286.
V86 modes is exactly the same as RING 3 PROT mode, with the following
differences:

o Memory Address Hierarchy
A 386 has three levels of memory addresses:
– Virtual (Intel refers to this as Logical)
This is either the selector:offset or segment:offset address used by unprivledged machine language code.
– Linear
This is the 32-bit address arrived at either via a GDT/LDT
selector lookup, or via the 8086-compatible (seg << 4 + offset).
– Physical
This is the 32-bit address arrived at by pushing a linear address
through the paging mechanism. This is the address that the CPU
sends out on the bus to select physical memory.

When in V86 mode, the CPU performs the 8086-compatible computation.

o I/O instructions are NOT IOPL-sensitive
Trapping of I/O is done using the IO Permission Map.

o All instructions which modify or expose the Interrupt Flag ARE IOPL-
sensitive.
This allows the OS to simulate the Interrupt Flag, if desired.

V86 IRETD Frame

When any interrupt, trap, exception, or fault occurs in V86 mode, the CPU
switches to PROT mode and switches to the TSS Ring 0 Stack and builds the
following stack frame:


            (0) (old GS)
            (0) (old FS)
            (0) (old DS)
            (0) (old ES)
            (0) (old SS)
               (old ESP)
            (old EFLAGS)
            (0) (old CS)
               (old EIP) <- (SS:SP)

CPU Mode Determination

A new implementation of the WHATMODE macro was written in order to distinguish
between the three CPU modes: REAL, PROT, and V86. REAL mode is indicated by
a 0 PE bit in CR0 (a.k.a. MSW on a 286). If the PE bit is 1, then the mode
may be either PROT or V86. These two modes may be distinguished by attempting
to change the IOPL bits in the FLAGS word. At Ring 0 in PROT mode (the only
place WHATMODE is used), the IOPL may be changed. In V86 mode, IOPL cannot
be changed. So, we change IOPL and then check to see if it changed. If so,
PROT mode, else V86 mode.

CPU Mode Switching

The 286DOS kernel relies extensively on switching inbetween REAL and PROT.
This functionality is provided by the RealMode and ProtMode routines.
In 386DOS, RealMode is no longer needed. As soon as we switch to PROT mode
during SysInit, the CPU only uses PROT and V86 modes.

Two new routines, ProtToV86 and V86ToProt, that are analogous to RealMode and
ProtMode. ProtToV86 is quite straightforward. We build a V86 IRETD frame
on the stack with the VM bit set in the EFLAGS image. We set the SS:SP
image to be equivalent to the stack just above the V86 IRETD frame, and
set the CS:IP image to instruction following an IRETD. Then, we issue the
IRETD and the CPU continues processing following the IRETD and in V86 mode.

V86ToProt is a bit trickier. The only way to get out of V86 mode is to
trap or fault or issue a software interrupt. We chose to use a software
interrupt, 30h, which we call the V86 Services interrupt. The INT 30h entry
in the IDT is a ring 3 interrupt gate, so issuing an INT 30 from V86 mode
causes a V86 IRETD frame to be built on the TSS Ring 0 stack and control
transfers to the INT 30h vector. The handler verifies that the INT 30h
was issued by the V86ToProt routine (checks CS:IP on the stack). If not,
the interrupt is reflected back to the requesting 3xBox (See Interrupt
Reflection). If it was V86ToProt, we clean off the stack frame and return to
the caller. NOTE: V86 Services is also used for completing the 386 LOADALL
used by PhysToVirt to map “high” memory in “REAL” mode.

Stack Switching

In order to maintain the 286DOS mode switch and stack switch semantics
when V86 mode is used, we have a new stack (the V86 Stack) in the 3xBox PTDA.

286DOS Modes and Stacks

The RealMode and ProtMode procedures in 286DOS are the only ways to switch
the CPU execution mode. These routines both maintain SS:SP, allowing
RealMode and ProtMode to be reentrant. The TSS Ring 0 stack is always the
current TCB stack in the current PTDA. The only other stacks in the system
are the Interrupt Stack and user stack(s).

386DOS Modes and Stacks

In 386DOS, any interrupt or exception while in V86 mode causes a switch to
PROT mode and the TSS Ring 0 Stack. So we have a new way to mode switch with
an incompatible stack semantic. We had to fix this mode switch to make it
compatible with 286DOS.

Observation

In V86 mode, the current stack must not be the TSS Ring 0 Stack. The CPU
only leaves V86 mode via an interrupt/exception, which causes a stack switch
to the TSS Ring 0 Stack. If the current stack was the same as the TSS Ring 0
Stack, then the stack might get corrupted. In 286DOS, the Ring 0 Stack is
the PTDA. Since we run on this stack in V86 mode, we need a new Ring 0 stack
when a 3xBox is running.

Approach

1) When a PMBox is running, the TSS Ring 0 Stack is a PTDA TCB stack.
+ This is consistent with the 286DOS model.

2) When a 3xBox is running, the TSS Ring 0 Stack is the “V86 Stack”.
+ The V86 Stack is allocated in the 3xBox PTDA.
+ If the cause of the mode switch can be handled without enabling
interrupts (e.g., interrupt reflection, IN/OUT trapping), we stay
on the V86 stack.
+ Otherwise, copy the V86 IRETD frame to the previous stack and
switch back to the previous stack.

Details

1) Leaving V86 mode
a. V86ToProt (analog of ProtMode)
+ Issue special V86ToProt software interrupt. If the interrupt
gate is DPL=3 (and it must be a 386 Interrupt Gate), then the 386
switches to Ring 0 (and the TSS Ring 0 stack) and transfers
control to the handler.
+ To ensure that 3xBox apps don’t use this feature, the interrupt
handler checks that CS=DosGroup and IP is in the correct range.
If not, then the interrupt is reflected (see below).
+ To make V86ToProt compatible with ProtMode, the interrupt handler
switches to the old stack (we get SS:ESP from TSS Ring 0 stack,
which is where we are running).
+ Finally, V86ToProt restores saved registers and flags from the
stack and returns to caller.

b. Software interrupt
+ GP-Fault handler reflects to 3xBox IVT handler in V86 mode.
o Add IRET frame on old stack, taking IP, CS, FLAGS from
TSS Ring 0 Stack.
o Look up handler in 3xBox IVT.
o Edit TSS Ring 0 Stack EIP and CS to point to IVT handler.
o IRETD
+ IVT interrupt handler IRET uses IRET frame we built on old stack.

c. Hardware interrupt
+ To make this operation compatible with 286Dos, the interrupt
handler copies the V86 stack from the TSS Ring 0 stack to
the old stack, then switches stacks to the newly modified old
stack. This allows the Interupt Manager to do an IRETD to
get back to the correct mode.

d. Exception
+ Remain on V86 stack, process exception, and IRETD.

2) Entering V86 mode
a. ProtToV86
+ Build V86 IRETD frame on current stack and IRETD.
b. LinToVirtDM_HANDLE
+ Execute 386 LOADALL with VM bit set in EFLAGS image in loadall
buffer.

Interrupt Management

All software interrupts, hardware interrupts, and CPU traps and exceptions
are vectored through a common IDT, regardless of whether the CPU is in PROT
or V86 mode.

NOTE: Background 3xBoxes get no hardware interrupts. In the commercial 386DOS,
this restriction can be relaxed so that interrupts, other than for the
keyboard and mouse (since those are implicitly for the foreground box),
can be given to background 3xBoxes.

Passing Hardware Interrupts to the Foreground 3xBox

In the interrupt manager:

IF a 3xBox is foreground -AND-
the current mapped 3xBox is background
THEN
MapIn foreground 3xBox;
Dispatch interrupt;

And to make things more interesting, from the later version of FOOTBALL, oddly enough version 4:

OS/2 FOOTBALL Boot Disk (v4.41.00)

This disk contained an updated version of OS/2 FOOTBALL Boot Disk (v4.41.00). It was built in December 1987, using final OS/2 1.0 sources merged with assorted FOOTBALL changes, and although it was originally assigned version number 1.3, this version of OS/2 would ultimately become 2.0.

It crashes on an 80286, jumping to invalid code immediately after performing a processor check. On an 80386, the following version banner is displayed:

Operating System/2  Version 1.30
(C) Copyright Microsoft Corp. 1981, 1987, 1988.
(C) Copyright IBM Corp. 1981, 1987. All rights reserved.

Internal revision 4.41.00, 12/02/87

The numbering of revisions must have been, um, revised, because despite the lower revision (4.41.00 vs. 7.68.17), it is newer than the 7.68.17 prototype. This is confirmed by the boot message (12/02/87), the file dates (12-23-87) and the higher version number (1.3).