zeeDooM Xenix!

So a few months ago, gattilorenz had told me he managed to work out how to do direct video under Xenix, and was able to get DooM running! He made the source available, and I meant to do something back then, but I must have gotten distracted.

So I went ahead and added the zeeDooM thing I had been working on a while ago which is a combination of the John Romero released maps, and the FreeDoom assets. So it’s not 100% the released version, it just looks that way.

I’ve gone ahead and created a qemu disk image (if you convert it, it does run on VMware, so probably far more 386 capable emulators than I can imagine), along with an old Qemu exe for some stand alone fun on archive.org.

There is no sound, nor music. I should look closer one day, and see if I can drive some direct music to an Adlib since it’s just IO ports, and maybe grab all the direct sound code from viti95’s FastDoom?

Anyways, it’s zeeDooM!.. on Xenix!

Playing Mel Kaye’s LPG-30 Black Jack

Oh sure, the tale is as old as time itself, but how does one play the original Royal McBee LPG-30 game?

Something very Fallout’esque about this modern miracle of miniaturization!

Thankfully it’s all covered here: Using the SIMH LGP-30 emulator | Obsolescence Guaranteed

For the impatient the short story is this on a SIMH LGP prompt:

SET CPU LGP30
SET CPU TAPE
LOAD BKJCK.TX
SET CPU MANUAL
G -T 4500
g

Naturally you’ll need the game as well which is currently on FTP at ftp.informatik.uni-stuttgart.de . Obviously thanks to our google overlords FTP is no longer integrated in the browser because the browser is only http, not gopher, telnet, ftp .. who needs to be universal?

You’ll find it in the /pub/cm/lgp30/papertapes/Games directory.

Important things is that your yes/no should be inputted as y’ or n’ The game will stop SIMH so you need to ‘g’ to start again.

FUN!

Although this comes up time and time again, I found this hacker news post, that actually has a picture of Mel, showing that he was in fact a real person.

Chasing more 386 OMF

Microsoft’s first 32bit OS, Xenix

Well back before, I had been looking into old linkers for 386 OMF, I knew I’d found some fun with some old GNU tools going back to the heyday of Xenix 386. As kind of expected the tools used to build Xenix, along with it’s SDK were in fact Microsoft C/MASM. So yes way back in 1987 Microsoft not only has MASM386, but they also had a 32bit Microsoft C 5.00. Let that sink in for a moment as OS/2 had been forced into 16-bit land despite FOOTBALL, and Windows/386 being a 386 VM86 multitasker. So in a weird way all the parts were in existence.

Back in the old days of GCC 1.x there was a bit of excitement about the file masm386.c in the old GCC source directory, sadly despite it being updated, there was no real public push on modifying GCC to support non AT&T assemblers. Instead something unexpected (well to me!) happened is that GAS had been modified to output OMF.

I tested this on MinGW with some simple stuff, and sure enough it links just fine. Considering its what is on the GCC on Xenix port I’m sure it’s pretty solid.

Enter OS/2

Now this is more fun, and again kind of sad that GCC didn’t take on the ability to target other assemblers (just look at the x68000!), Maybe they didn’t see GAS for OMF, or just didn’t know. Instead a more aggressive choice was made, to alter the binary output. Linking on OS/2 with EMX involved 2 very different and incompatible paths, the first one is the ancient Unix i386 a.out format, which then a utility called emxbind will convert into a loader & stub that OS/2 can run. Think of it as an OS/2 extender to take simple Unix programs (which is what they are) to run on OS/2. Neat!

The second more ‘native’ approach is to convert the binary a.out files into what is known as OMF files, which non GNU linkers like Wlink from Watcom or Link386 from Microsoft can then link into direct native EXE’s or DLL’s.

There had been an experimental ELF build of the EMX toolchain on OS/2 but I think it may have died? So as crazy as it seems bigger and crazier programs need to be built on systems like Windows or Linux and linked outside of OS/2 to get around the old memory limits. It’s really hard to say as I’ve never used it, although being able to do the link outside of OS/2 would be an advantage.

I’ve found 2 programs to convert the a.out objects into OMF, the first and oldest being o2obj. The one drawback I’ve had is that this doesn’t play so well with the Watcom 386 OMF linker. Instead the much later RSXNT/LIBC0.6 project’s emxomf. I’ve done some painful hacking but it appears to do what it should do. A simple omfdump seems to be spilling stuff out.

Of course the alternative is to use a 64bit linker, and since a.out has been pulled from binutils the only real hope is the Watcom linker which is now running in a 64bit address space. And the Watcom chain won’t understand ancient i386 a.out, however Microsoft 386 OMF it certainly will, although it appears to be based around something later than the aforementioned o2obj, which is why I ahd to do the emxomf.

I know as this stands it’s not very satisfying but I kind of wanted to push this out the door as I’d been hacking from time to time on it, and didn’t want to leave it to rot completely. The EMX tools remind me of the NeXT stuff where everyone goes native platform wild never imagining a day when remaining portable would mean it’d be easier to target more software.

The one thing I wonder about sometimes if there was some kind of secret Microsoft extended DOS/Windows that relied on OMF & Link386 that predated the NT team and their switch to COFF? Obviously it’d be super obsolete and would have been something like the first PharLap 386 stuff. But I’ve only owned a disk dump of v4, and a legit copy of TNT v6. Old 386/DPMI/Extender tools are hard to find.

Linkers & loaders, along with binary formats are too hard for me, but I thought I’d share at least what I’d been able to conjure with MinGW. I’ll have to touch on EMX to native OMF linking later.

Fun with Nano Server

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

While everybody is busy buzzing about Windows 11, I wanted to commemorate the finest operating system ever made by Microsoft – Nano Server.

For most of people Nano Server was esoteric, distant and unapproachable. It had a rather high entry barrier, requiring you to build it on a Windows Server 2016 host using PowerShell magic spells. You couldn’t just simply download and run it. Even if you managed to get it running, there wasn’t anything you could actually do with it for fun. People didn’t bother to even check it out. My goal is to demystify this a bit, lower the entry bar and made it easy for people to hack it.

Background info (you can skip it)

Nano Server was an interesting attempt at creating a datacenter grade OS that’s not managed via local GUI, keyboard and mouse, but rather full automation, remote tooling and code. It went one step further than Server Core or Windows PE by completely removing GUI components and local shell. Hence it’s not actually called “Windows” or “Windows Nano” but rather simply “Nano Server”. Rumor has it, it started as MinWin. The OS has a rudimentary text mode console with functionality similar of VMware ESXi console. However Nano was much more than a bare metal hypervisor. It was a fully fledged operating system. Unlike ESXi you can develop and install services/apps for it and hypervisor wasn’t even it’s default role.

Ever since I first saw a demo on Microsoft Ignite (previously known as TechEd) I wanted to run aclock on the text console. Much like the WinNT BSOD edition. This article started around my efforts to run (or port if needed) aclock to this platform. At the time of writing, the technology has been dead for several years now. However all the artifacts and documentation are still available on Microsoft’s website. Probably not for long, so a good moment to do it now, before everything gets deleted in to oblivion.

How to quickly deploy Nano Server and run command line apps on the console

The hard way: you need to download Windows 2016 Server (eval) and run a PowerShell command to produce a bootable VHD file.

Microsoft provides (soon to be deleted) Nano Server Quick Start. However the steps are trivial so you can totally skip that and just do this:

  • Launch PowerShell terminal window on the WS2016 host.
  • Run: Import-Module D:\NanoServer\NanoServerImageGenerator -Verbose
    (D:\ drive being where Windows Server CDROM is mounted)
  • Run: New-NanoServerImage -DeploymentType Guest -Edition Standard -MediaPath d:\ -BasePath c:\nano -TargetPath c:\nano.vhdx -ComputerName nano -Development
    (c:\nano folder and c:\nano.vhdx image will be created for you)

Done! This will build a .vhdx image that can be run under Hyper-V as “Gen-2” VM. For Gen-1 or to run it on any other hypervisor change .vhdx to .vhd in -TargetPath while running the PowerShell command.

The easy way: you can just download a pre-built VM image from here. There are VHD for Hyper-v Gen-1 and VHDX for Hyper-v Gen-2 and OVA for everything else.

First Boot

Once you boot it up you will be greeted with a PowerShell prompt. Just like that! You can type cmd to launch the good old cmd.exe shell. MS-DOS 2016?

Keep in mind, this is a developer mode (see -Development flag). Normally you would be greeted with a login prompt and a boring menu that allows to change some networking settings and not much beyond that. In production mode you need to resort to hacks (or this) to get stuff running, fortunately nothing like that needed here.

So what can you run on it?

Firstly in order to get some external utilities going, you can mount a SMB share using net use in cmd or New-SMBMapping in PS world. Nano being a server and all, you can also share out a folder via net share or use C$ (you may need to create a user by using either net user /add in cmd or New-LocalUser in PS). Alternatively you can install Posh-SSH and use SCP to transfer files. If you don’t have working network you can just shut it down, mount the vhd image on the host and copy stuff in to the image then detach the VHD.

Aclock worked on the first run, no issues, using standard win64 exe:

aclock running on Nano Server Console

Wow! So looks like Nano console does have basic terminal controls. That opens quite a lot of possibilities. But can you run more complex apps? Text editors? Web browsers? GAMES?

Well, yes…, but likely not, but it really depends – on dependencies (read: DLLs).

From all the editors I tried XVI is probably the best:

XVI Editor Running on Nano Server Console

Everything else has a variety of issues:

  • The font is lacking line drawing characters. Some editors like YEdit allow to use ASCII drawing characters fortunately.
  • There is no reverse video. This manifests mostly in menus, etc. however it also applies to the cursor.
  • There is no cursor, or rather the cursor is an underscore and not transparent cell. Moving arrow left in the CLI doesn’t actually move the cursor it erases characters. There is no line editing.
  • Also related to reverse video, it appears Nano console has some weird issues with colors.
  • Missing DLLs. Nano Server not being a “Windows” OS is missing a lot of Windows DLLs and it has its own nano DLL hell. This has actually been acknowledged in MinWin. As such a lot of apps will not launch due to dependencies.

For example YEdit works remarkably well except for the menus, which use reverse video:

YEdit running on Nano Server Console

Update: Malcolm has fixed it in latest version of YEdit! Thank you!

Update: thanks to Ron Yorston you can also run BusyBox on Nano! All you need to do is get the 64bit version and before you run it set an environmental variable to disable ANSI emulation. In CMD set BB_SKIP_ANSI_EMULATION=0 in PS $env:BB_SKIP_ANSI_EMULATION=0. Done!

BusyBox on Nano Server

You even get ls colors and vi editor works flawlessly! Unix shell on Nano, thats awesome!

So what about games?

Initially nothing worked as expected. Either due to line drawing, colors or previously mentioned DLL hell. There was one game that actually worked – PowerShell adaptation of snake:

PowerShell Snake running on Nano Server Console

But I wanted something better. I had high hopes for ascii-patrol, which is pure text mode and they build it for win64. Unfortunately the game requires a bunch of multimedia / sound DLLs from Windows which are not present in Nano.

Thankfully Neozeed has stepped in, took the source code, amputated all the multimedia stuff, borrowed the Unix clock code and gettimeofday, and used an older Visual Studio to build it. But he managed to produce a fully working and playable version!!!! Truly amazing stuff!

ASCII Patrol Running on Nano Server Console

The binary is available here. To play the game scroll down one screen to start a mission. If you enter profile customization simply press ESC to get out. Thanks again Neozeed!

I’m hoping readers can find more text mode/ascii apps and games that will work on the console. Please comment and send links!

In another dimension, having a working text editor, Yori shell, smb/scp, maybe with help of mingw64, sdk tools or borrowed compilers from Visual Studio, one could have a self hosted developer workstation with this.

For now please just download the pre-build image, or make one yourself and run it in your favorite hypervisor and have some fun with it!

With this, goodbye Nano Server! You will be always remembered. I know folks at Redmond tried really hard to make it such beautiful gem.

Compiling Mach under Windows

This is a bit cheating, but I broke down and did some dump/exports of a building system to get the file layout. Since the MiG phase was totally done native, I didn’t bother with that, or trying to ‘fix’ the nested Makefiles, rather I just dumped the output and worked with that. I guess I could make my own Makefile but for now it’s a stupid script. I used the a.out build tools for Linux as the objects are all the same anyways.

So yeah, download and extract Ancient Linux on Windows, grab and extract mach25-X113-noblock.zip, and then run:

cd mach25-X113\obj\STD+WS-afs-nfs
build-gcc258.cmd

Since there is no Makefile it won’t run in parallel. About 20 seconds or so later you’ll get a linked ‘a.out’ but it won’t run. The script xport.cmd is rigged for me and Qemu 0.10.5 to create a tar file to extract inside of mach and perform the native link.

Obviously this means you can us modern UI’s tools and everything else as you are now on the outside! If you can force your build to use my ancient tools you can even do the build. Nice!

Doing a rebuild of the kernel in Qemu the 2.5.8 -O2 build shaved a whole second off the build, so yes it actually did something.

Things to do would be cross linking, fixing the drivers that don’t build, and probably improving stuff like bigger disks, filesystems and memory… or networking!.. .but that’s all too complicated for me!

WSLg aka the killer feature of Windows 11

One of the great things about Windows 11 was the inclusion of the Windows Subsystem for Linux or WSL. It wasn’t available at launch but it started with v1 a simple ELF loader and an implementation of the Linux kernel on the NTOS kernel. Being a re-implementation of Linux it was great for what did work, however many things did not. Compared to other Unix subsystems for NT over the years however WSLv1 was the best no question.

Not being enough however, Microsoft took a page out of the old WinOS/2 days and stubbed a Linux kernel to run under Hyper-V, allowing it to run far more applications, and for me giving the ability to use applications that alter memory space, and allowing i386/x32 applications to run. You could happily export your X-11 display to a Windows based X server, and get applications that way. But this isn’t 1993 so it was very limiting.

Enter WSLg

The big change is the ability to use RDP to hook both Wayland and Pulse Audio bringing Linux ‘desktop’ X11 applications to the Windows desktop. Also added in is virtual GPU capabilities allowing accelerated 3D, along with CUDA applications to run (although with a performance penalty.

The downshot for me, is that my existing Debian 10 install was not picking this up, and was somehow picking up a VMware

VMware llvmpipe

I have no idea how or why it was picking this up. While I did have the VMware Player installed, the newer versions backend through Hyper-V.

I did find this article, which gave me a path to get where I wanted, although the transition of an existing v2 instance didn’t work for me. Maybe Debian 10 is too weird. I don’t know.

Not sure where how to proceed I backed up my home directory and un-installed VMware Player and purged my existing Debian 10. I installed that Ubuntu Community Preview which promises to include all the new and exciting features.

$ glxinfo -B
name of display: :0
display: :0  screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
    Vendor: Microsoft Corporation (0xffffffff)
    Device: D3D12 (NVIDIA GeForce RTX 2070) (0xffffffff)
    Version: 21.0.3
    Accelerated: yes
    Video memory: 40710MB
    Unified memory: no
    Preferred profile: core (0x1)
    Max core profile version: 3.3
    Max compat profile version: 3.1
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.0
OpenGL vendor string: Microsoft Corporation
OpenGL renderer string: D3D12 (NVIDIA GeForce RTX 2070)
OpenGL core profile version string: 3.3 (Core Profile) Mesa 21.0.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 3.1 Mesa 21.0.3
OpenGL shading language version string: 1.40
OpenGL context flags: (none)

OpenGL ES profile version string: OpenGL ES 3.0 Mesa 21.0.3
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00

Now this is looking MUCH better.

224FPS! FurMark

Now compare this to a native version of FuMark:

500 FPS

So it’s a 50% haircut. Ouch.

Gaming however using steam (yes steam runs!) reveals some other deeper issues. The mouse tracking is WAY off. So for FPS stuff you’ll spend a lot of time staring at the ceiling or the floors. The next issue is there is no mouselock, so things that rely on being able to move the mouse far beyond a screen length is impossible to play. To be fair it’s a preview, and so far I have to admit Windows 11 feels more like a technical preview. Also I don’t know what the deal is or anything about profiling it but KOTOR2 is insanely slow. Although at least with 3d acceleration running it’s not 1 frame every 5 seconds.

Good news! Windows 11 leaked a day early!

This PC meets the minimum system requirements!

You too can download it from here:

https://www.microsoft.com/en-ca/software-download/windows11

I for one, blame Canada.

—-edit

So I installed steam, because why not? But this is steam for Linux. It’s picking up VMware 3D accel.. .I don’t think that’s right. KOTOR2 loads but it’s 100% cpu and 1 frame every 5 seconds.

On the otherhand I’d installed Micropolis ages ago, and it added itself to the 11 launcher:

Even better, IT JUST WORKS!

Space Cadet 3D Pinball reverse engineered!

With all the controversy over 64bit pinball, and where and how things appeared, then disappeared to the discovery that the x64 version was a thing, but it was left off the install manifest but shipped on CD, along with my simple script to just extract it, the problem was that ARM32/64 users were left in the cold.

Don’t get me wrong, the original 32bit exe runs fine under emulation, but who wants emulation when you can have NATIVE CODE?! You’d have to try to find the source code (lol good luck!) or reverse engineer the program. And that’s what happened, enter:

k4zmu2a/SpaceCadetPinball: Decompilation of 3D Pinball for Windows – Space Cadet (github.com)

64bit ARM Pinball!

I’m using Visual Studio 2019 to build this, and it was great it *just worked*. Hurray!

There is also a rebuild going on for SDL to bring Space Cadet Pin Ball to Linux and beyond. The only downside is that it uses a number of ‘new C++ features’ locking out older platforms. I’d done some work to dumb it down although there is a bit of this new fangled C++ I’m unsure of what is going on. So that means, unfortunately Itanium users are left in the dark, as Visual Studio 2010 is too old.

32016 stand alone planetfall!

InfoTaskForce’87 running on a simple NS32016 emulator

What is it?

It sure may not look like much but it was an adventure getting here.

First, what is it? Well it’s the very simple NS32016 from here, with a few minor changes. I expanded the RAM from 256kb to a whopping 8MB. Then I added simple character I/O allowing me to print messages to the screen. Next looking at the toolchain page, I used my old Linux to Windows GCC 4 cross compiler to build the appropriate Canadian cross compiler to the NS3216.

Building the tools

A while back, I had built a cross compiler from Linux to Windows using GCC 4.1 as the basis as it was the last version that didn’t have massive external dependencies. NS32016 support was dropped some time in the late 3.x or early 4.x GCC so it means we need to go old anyways. I arbitrary picked GCC 2.8.1 for this build, while using the recommended Binutils 2.27

I cheated and just downloaded my existing linux-minw32.7z cross compiler as I didn’t feel like rebuilding everything again, although it is all in the Building a MIPS Compiler for Windows on a Linux VM! article. I also used an old Linux to Linux i586 32bit compiler (back from the OSKit build!) although you can use your hosts as well.

configuring Binutils is pretty simple like this:

./configure --prefix=/cross --target=ns32k-pc532-netbsd --host=i686-mingw32 --build=i586-linux

You can try omitting the –build portion, Debian GNU Linux 10 seemed okay with Gcc 8 as the default system compiler.

configuring GCC 2.8.1 was pretty similar:

./configure --target=ns32k-pc532-netbsd --prefix=/cross --disable-libssp --build=i586-linux --host=i686-mingw32

GCC 2.8.1 doesn’t quite know what we are doing so there is some flags we need to run off in auto-config.h namely

  • #define HAVE_BCMP 1
  • #define HAVE_BCOPY 1
  • #define HAVE_BZERO 1
  • #define HAVE_INDEX 1
  • #define HAVE_KILL 1
  • #define HAVE_RINDEX 1
  • #define HAVE_SYS_RESOURCE_H 1
  • #define HAVE_SYS_TIMES_H 1

You can just comment them out, or remove those lines all together.

When it came to building GCC, I did run into issues with GCC 7/8 trying to build GCC 2.8.1. I found it much easier to either have that Linux 4.1 compiler, or if you have access to Wine or WSL you can just run the Win32 binaries for the gen phases.

./configure --prefix=/cross --target=ns32k-pc532-netbsd --host=i686-mingw32
make CC=i686-mingw32-gcc xgcc cccp cc1 cc1obj

If you can run your own Win32 exe’s on Linux it’ll run just fine using the Linux to Windows GCC 4 cross. Otherwise you will need to either patch GCC or make your own GCC 4 hosted Linux to Linux cross compiler like this:

make CC=i686-mingw32-gcc HOST_CC=i586-linux-gcc xgcc cccp cc1 cc1obj

Hopefully that worked enough, and now you have your cross compiler. Now it’s time to build libgcc1.a

cp cccp cpp.exe
cp cc1 cc1.exe
cp xgcc xgcc.exe
cp ../binutils-2.27/gas/.libs/as-new.exe as.exe
cp ../binutils-2.27/binutils/.libs/ar.exe ar
cp ../binutils-2.27/binutils/.libs/ranlib.exe ranlib
make libgcc1.a TARGET_TOOLPREFIX="./" OLDCC=./xgcc.exe

Again you really want to be able to run the resulting programs on Linux but I guess you could script it out. Naturally if you wanted to just use Linux, it’d be easier to make that cross compiler directly, although I’m not sure how much of GCC 2.8.1 I want to fight, or just get GCC 4 running on Linux and use that to port.

crt0, somewhere for C to start

As mentioned a crt0.s is missing but there was enough inspiration to come up with this:

#NO_APP
gcc_compiled.:
.text
        .align 1
.globl _start
_start:
        enter [],0
#APP
#       setting the stack 256k under 8MB
        lprd sp,0x7c0000
        jsr _main
#NO_APP
L1:
        exit []
#       setting the stack 256k under 8MB
        lprd sp,0x7c0000
        bpt
        .align 1

#does nothing
.globl ___main
___main:
        ret 0

.globl _exit
_exit:
        bpt
        ret 0

I used a bit of the C example, and added some hooks that GCC was expecting namely a __main call that is made from main before it does anything (a place to init memory perhaps?), a place to catch an explicit exit call, along with setting the stack of course.

Patching InfoTaskForce without malloc / disk access

It’s not going to win any awards, but it was really great to get it to run a simple program written in GCC. Looking for something more fun, I took the old InfoTaskForce interpreter from ’87, and dug up my modification to run on cisco routers, and cooked up this version, that adds enough of printf from Linux, a bogus malloc that just allocates from a fixed memory array (otherwise you have to actually know about your platform), and a fun trick with later binutils where you can import a binary file directly as an object!

Neat!

Since I don’t have any file I/O being able to have the game data in RAM is crucial. I tried to tweak it so you could build the same working thing on Windows (maybe others?).

So for anyone who wants to look at the standalone adventure Win32 hosted tools are here, although the emulator should be somewhat portable.

lsblk for Windows released

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

Pleased to announce that lsblk utility for Windows is finally released. This is not entirely new, the original code was on github for a few years now, but it was lacking major features of printing drive letters, mount points and filesystem types.

Why would anyone even want lsblk for Windows? There are many other “native” ways of displaying disks and volumes. For example in PowerShell: Get-Disk or Get-PhysicalDisk or in cmd: wmic diskdrive list brief. Not to mention diskpart or disk management UI. There are a few answers to this.

Firstly the output format of lsblk on Linux is rather intuitive and useful, which can’t be said about previously mentioned utilities. People with Linux background find it more like at home.

PowerShell and wmic lack ability to combine disk and volume information, unless you want to write a larger script. This is now part of lsblk.

Lastly lsblk uses low level function to list objects directly from the kernel (think WinObj), rather than going through various high level services, management interfaces and relying on VDS (Virtual Disk Service). As such it’s super fast and you can use it even with VDS stopped or inoperable. Finally it’s yet another of these native Linux tools now also available on Windows.

Finally, some of the column names may sound cryptic, so here is an explanation:

ST – Status 1=healthy 0=unhealthy
TR – Trim / Unmap / Discard Capability
RM – Removable Media
MD – Media changed (for removable media)
RO – Read only