PC-MOS/386 v5.01 released under GPL v3.0!

Sources over on github!

https://github.com/roelandjansen/pcmos386v501

I’ve only just received notification of this, and had to post it forward.  All I know is that you’ll need Borland C++ 3.1 along with Borland Brief to re-build the system.  I haven’t tried it just yet, but I most certainly will!

For those unaware, PC-MOS is a multi-user multi-tasking MS-DOS like Operating System.  I looked at this some years ago.. More so interested in seeing if and how various MS-DOS like OS’s could run under modern emulation.

It may be interesting to pit FreeDOS vs PC-MOS/386.

On a personal note, it’s great to see that PC-MOS won’t just end up a minor footnote in wikipedia until it gets pushed off, instead it can live on

Started to re-build my MS-DOS machine

DooM!

Good news, it actually works!  I was using the version 1.1 WAD, so honestly weird crashes really aren’t unexpected.  I haven’t looked much at what to do with audio, but I was really impressed compared to the Qauake II wars, it was really surprising to not only see DooM run on the first shot in real metal, but the keyboard works as well.  Well enough for me to pick a level, and get killed.

Naturally it doesn’t work under Windows, however it runs fine with MS-DOS mode.

Null DooM, GCC 1.39, GO32 and DPMI


phew.

DooM via DJGPP v1 GO32

Around the time of the x68000 port of DooM, I was cutting down the DooM source for a null/portable version.  I never could get it to actually run either using EMX or  DJGPP 1.03, as I couldn’t get it to link to save my life with a constant never ending battle of unresolved symbols. After a while I just used what I had towards the x68000 version and concentrated on getting it up and running, and just shelved the null/portable effort.

Later on I wanted to get it running again as part of messing with another cross compiler, as DooM isn’t a trivial application to port and verify correct operation. And in the process of trying to get the null version to build and run on Windows using TDM GCC, I wanted to make sure it at least kept compiling with GCC v1.x.

Once more again I was able to compile individual files but unable to link.  But this time, I just looked at the diffs for binutils, I thought it should be somewhat easy to get hosted on Windows.  Although versions may point to binutils 1.0, I had to use binutils-1.9.tar.gz even though the diffs are against Mar 24 1991, and the source for 1.9 is dated April 17 1991.

My first effort gave me a linker that would happily link, but go32 would either refuse to run the executable, or just crash.  I was going to give up again, but I found mention in another file that DJGPP actually uses the linker from G++, the C++ compiler which was a separate thing in the late ’80s and early’90’s.  This time it worked, and I could link a trivial hello world style application!

Now that I finally had a cross linker actually working, I didn’t want to compile under emulation, so looking at the other diffs, they didn’t look too extensive. I went ahead ,and took DJGPP v1.06 and patched up the compiler & assembler to get a full cross toolchain.  And in no time, I had a null version of DooM running on MS-DOS well at least tested on DOSBox.

This was fun, and all but I didn’t see any easy way to do fun things like hook interrupts so I could get the keyboard & clock like any good MS-DOS program.  DPMI greatly eased this kind of stuff, so looking at the DJGPP history, DJGPP v1 version 1.10 actually adds preliminary DPMI support!  And in the next version, DPMI was much more better supported, however the binary format had changed from a.out to COFF as part of the move to v1.11. I was able to take the memory, and DPMI portions from the final v1.12 libc, and manually build and run them against the v1.06 library / dev tools.

And much to my surprise, it actually worked!  At least having the wrong format didn’t have any effect on how GO32 worked for me.

So feeling lazy, I snagged some of the support code from Maraakate’s revamp of DooM, just to make sure of the timer code, and the keyboard code, and again verified that I can build with the keyboard & timer ISR and I’m able to play the v1.9 shareware & commercial levels fine.  I haven’t done a thing to clean up or update the DooM source itself against all the dozens of bugs and issues with Ultimate DooM, or other games like Chex Quest etc.

I’m sure 99% of people wouldn’t care but you can download it here:

Win32_DJGPPv1_DooM.7z
Download crossdjgppv1

Although I’m using DPMI to drive realtime events, if I looked further at the GO32 v1.06 environments I could either figure out how it operates it’s timer, or modify the extender directly to drive the PIC timer and keyboard as I need.  But overlooking that, the vintage 1991 software is more than capable of running DooM.

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://homepage3.nifty.com/takeda-toshiya/msdos/

MS-DOS 5.0 DPMI

MSDOS 5.00A BOOT

MS-DOS 5.00A booting on Neko Project 21

While I’m waiting for my real PC-9821 to arrive, I’ve been playing with various software.  One fun thing was the old DJGPP, as the version 1.x had a customized version of go32 to support the PC-98 hardware.  This is cool, but I’d love to perhaps start down the road of porting something to the PC-98.  There is no VGA adapter, and the I/O is mapped differently so naturally this is why they are only loosely compatible.  So while I was looking for any kind of source code using DJGPP, I found the FCE: Family Computer Emulator (NES).  It includes source code, which is great but it builds against DJGPP 2.x What makes it more interesting is that it has DPMI hooks in place, unlike the old DJGPP 1.x’s DOS extender which is DPMI incompatible.  So how do you magically get a DPMI environment for MS-DOS?  Well one way is to run it under Windows 3.0 or higher.  And certainly with MS-DOS 3.30 that is an option.  However lurking in the disk images of MS-DOS 5.00A was a fun program DPMI.EXE .  Well now that is interesting!

MSDOS 5.00A native memory

MSDOS 5.00A native memory

Using a generic config.sys I have 600kb of low RAM available, and 7MB of extended RAM.

Now the real interesting part is DPMI.INI

[386Enh]
ebios=
display=dddn.386
keyboard=*vkd
network=*vnetbios, *dosnet
device=*vpicd
device=*vtd
device=*vdmad
device=*vsd
device=*vsound
device=d86mgrn.386
device=*pageswap
device=*dosmgr
device=*vmpoll
device=*wshell
device=*vfd
device=*vscsid
device=dpdn.386
device=*parity
device=*biosxlat
device=dmcpd.386
device=*vhd
device=*vcd
device=*combuff
device=*resume
device=*la20hma
device=dpfd.386
Paging=Yes

As you can see this is pretty much the 386 enhanced portion of Windows 3.0!  So you get all of the DPMI services offered by Windows as part of the OS.

MSDOS 5.00A DPMI activated

MSDOS 5.00A DPMI activated

As you can see, with DPMI running I have access to EMS, and XMS memory now available.  Additionally with paging you can even over commit memory.

My only question, is why was DPMI not an added in feature of the English versions of MS-DOS?  Granted there was a LOT of OEM bundling with new machines so you were forced to purchase a copy of Windows along with MS-DOS on all new computers, regardless of what you were going to do with them, and this would have been a bit more interesting.

This kind of environment was extensively documented in the “Unauthorized Windows 95“, by Andrew Schulman that showed how DOSX.EXE could chain load Win386 + command.com achieving the same thing.  The DPMI environment from MS-DOS 5.00A is dated 11/11/1992, I wonder if he knew about this going into the Windows 95 book.  It’s been too long since I’ve read it to remember, but I don’t recall any details about Japanese PC-98 releases of MS-DOS.  There was also a ‘MSDPMI’ environment created for the beta versions of Microsoft C 7.0, but I’ve been unable to find one to verify.  MSC 7.0 was released in 1992, so it fits in the same timeframe, but the shipping products used QEMM’s DPMI server instead.

DooM 1.2j1.0 on NekoProject II

So the first thing you’ll need is Neko Project II.  It can be a little hard to track down downloads, but there is a whole slew of them here:

http://ux.getuploader.com/emu/index/1/date/desc

So for now this link, is the latest build, you’ll need to enter a password to download the file, it’s 9801.

The password is "9801"

The password is “9801”

Extract that, and you’ll want to configure the sound.

MIDI options

MIDI options

If you choose to use the MIDI you’ll have to map them to a MIDI-OUT port, and I used the default Microsoft GS Wavetable.  Of course you could use MUNT, or any other MIDI mapper or port.  Also you may want to setup the serial port MIDI as a backup plan.

Serial MIDI

Serial MIDI

The sound effect settings work best for the PC-9801-86 audio board.

xx

Select the correct board!

I’ll save installing MS-DOS, and installing DooM for another fun episode, but to configure DooM.

Run setup.exe to setup DooM!

Setup menu

Setup menu

The menu is simply:

  • 1 graphics
  • 2 Background Music
  • 3 sound effects
  • 4 not sure
  • 5 controller
Graphics

Graphics

The PC9821A driver works best from what I’ve done in my limited testing.  I guess if you had a different emulator, or a real PC-98 you’ll get more out of this.

Next is the BGM or music

 

BGM

BGM

You really have 2 options here, #3 for the PC9801 driver which uses the YM2608 chip.  Or the General MIDI either option 4 or 6. I didn’t notice any difference between the two of them, they both sound kinda slow, but workable.

Now for the audio board, select the PC-98

Doom sound drivers

Doom sound drivers

The PC-9801-86 is what you want here.  Now with either a 100% PC-9801-86 config, or a 50/50 of the MIDI/PC-9801-86 we are ready to run DooM!  Selection option 6 and away we go!

Save settings and run DooM

Save settings and run DooM

And all being well you’ll get the start of DooM!

DooM starting up

DooM starting up

Otherwise you’ll get this fun error:

DX386 error

DX386 error

In this case I had emm386.sys in my config.sys which conflicts with the dos extender DX386.

Personally I find it easier to boot off the #1 install diskette which will automatically start DooM!

If you are feeling brave, listen!

 

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:

[[code]]czoyNDA6XCIKICAgICAgICAgICAgKDApIChvbGQgR1MpCiAgICAgICAgICAgICgwKSAob2xkIEZTKQogICAgICAgICAgICAoMCkgKG97WyYqJl19bGQgRFMpCiAgICAgICAgICAgICgwKSAob2xkIEVTKQogICAgICAgICAgICAoMCkgKG9sZCBTUykKICAgICAgICAgICAgICAgKG9sZHtbJiomXX0gRVNQKQogICAgICAgICAgICAob2xkIEVGTEFHUykKICAgICAgICAgICAgKDApIChvbGQgQ1MpCiAgICAgICAgICAgICAgIChvbGQge1smKiZdfUVJUCkgJmx0Oy0gKFNTOlNQKQpcIjt7WyYqJl19[[/code]]

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:

[[code]]czoxNzU6XCJPcGVyYXRpbmcgU3lzdGVtLzIgIFZlcnNpb24gMS4zMAooQykgQ29weXJpZ2h0IE1pY3Jvc29mdCBDb3JwLiAxOTgxLCB7WyYqJl19MTk4NywgMTk4OC4KKEMpIENvcHlyaWdodCBJQk0gQ29ycC4gMTk4MSwgMTk4Ny4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCkludGVybntbJiomXX1hbCByZXZpc2lvbiA0LjQxLjAwLCAxMi8wMi84NwpcIjt7WyYqJl19[[/code]]

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

Wolfenstein 3D for DOS/4GW update

If you remember a while back, I had found the ‘missing link’ of Wolfenstein to Wolfenstein SDL, Wolf4GW.  Well Tobias has cleaned it up somewhat, and now it compiles on the latest builds of OpenWatcom 2.0c!

The first thing you’ll notice if you try to compile it, is that now it’s a single source file, that includes all the other modules.  And it compiles FAST, for me 1 second fast.

From the changes:

  • Compiles with OpenWatcom v2.
  • Keys (for Run, Shot…) are shown.
  • Hang with optimization is fixed.
  • Missing Spear of Destiny SignonScreen added.
  • Inter-procedural optimization (unity build).
  • External assembler routines re-implemented in C.
  • Better interrupt enablement /disablement.
  • Dead Code removed or #ifdefined.

So, if you want to Wolf3d, or SPOD, I’d check out Tobias’s Wolf4GW if you have a 32bit capable machine.  The maps load instantly, and it just feels all around much more smoother than the old 8086 code.