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

 

 

 

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 the site has since moved to here:

http://nenecchi.html.xdomain.jp/

https://simk98.github.io/np21w/download.html (it moved again)

So for now this link, is the latest build, which was last updated on

Extract that, and rn np21nt.exe

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:


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

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.

Windows 3.0 Debug Release 1.14

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:

Win

Windows v3.0 Debug Release 1.14

And it identifies itself as Windows Version 2.1

w

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

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

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!

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

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.

Cross compiling to i386 Linux ELF from OS X

This isn’t terribly useful for 99.9% of the people out there but I needed to do something creative on an F5.  Luckily they run a somewhat sane version of Linux.

Unfortunately I am stuck on Windows 10 right now, so installing a matching Linux distro is out of the question.  So on my OS X box, I thought I’d just build a cross compiler.  Going back to my DJGPP cross compiler, I thought I’d stick with binutils 2.9.1 and gcc 2.95.3, since they worked so well before.

Plus to flesh it out, you’ll want libc, libg++, and the appropriate Linux includes.  I took all of these from Slackware 3.3 since it’s from around that era.

So on the plus side this cross compiler + library set , will crank out static ELF executables, which makes running things on alien platforms all the better.

On the realistic side, I doubt anyone will need it, but here it is.

Clang didn’t want to build anything this old, but luckily that backported GCC-4.2 has no issues.

PCem is getting a dynamic recompiler!

It’s in the current source, right now, but I figured I’d build it and give it a shot.

The dynamic core consumes MUCH less CPU power.  The only current downside seems to be a 56kb/sec memory leak (I guess some dynamic code block isn’t being discarded).  But I have to say it’s REALLY cool to be running DOOM v1.1 on MS-DOS 5.0 and it’s running at 0% CPU utilization on my Xeon.

And as always the ‘normal’ non dynamic version is just fantastic.

I’ve only tested it with DOOM, and it’s worked great.  Give it a try?