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

 

 

 

Tracking down the InfoTaskForce from 1987.

So like all zork obsessed people (I really should get help or something), I was trying to build a z-machine interpreter for the x68000, using Lydux’s cross GCC compiler.  And it was honestly looking like a LOT of work in the IO department.  Thinking that the older versions were more simpler, I went looking for the oldest open Z-machine, called the “The InfoTaskForce Infocom interpreter”, released by the InfoTaskForce.  Unfortunately I can only find version 4.01 searching for the source code.  Which still looks too complicated.  But looking the history file, the project started back in 1987.  So with that to go on a new google search got me this:

Infocom Adventure Executor Source Files (1987)(InfoTaskForce)[C].zip

From an TRS-80 dump of all things.  I don’t know what version this is other than the brief copyright mention:

/* (C)opyright 1987 InfoTaskforce. */

All of the files are dated 4/12/2001 so they obviously aren’t original. And the version string is:

echo ( “Interpreter: C Version 1.0\n” ) ;

So assuming this is correct, from the 4.01 history file:

REV_E – June 25, 1987.
———————-

REV_E is the first major overhaul to the interpreter.

* The source is now significantly lint free.

* TERMCAP support has now been added [#define TERMCAP option].

* Screen paging and word wrap has been added, along with a new
command line option which disables screen paging (-p).

* Random number generator seeding using time () added [#define
TIMESEED option].

* Attributes in the object list are listed as bits.

* A debuging version can now be produced as an inbuilt options
[#define DEBUG option].

* The coded requirement that 25k is always free in the system can
now be removed [#define ALLOCALL option].

* A new command line option was added to print the object/room list
as a tree (-r).

* interp.c has been re-written to improve efficiency [large
switches have been replaced with arrays of pointers to funcions].

There are now 14 machines on the porting list:

Machine C Compiler Operational Porting details

128K Apple
Macintosh Aztec C Version 1.06F 18/05/87

128K Apple
Macintosh Lightspeed C 2.01 29/05/87 Use “rb” & “wb” in all fopen()s

IBM PC/AT Microsoft C 4 30/05/87 Link with binmode.obj

DEC VAX 11/780 UNIX V7 cc 01/06/87

HP-9000 HP-UX cc 02/06/87

gould cc 03/06/87

Amiga Aztec C 04/06/87

Pyramid 9810 cc 04/06/87

Pyramid 90x cc 04/06/87

Osiris cc 05/06/87

DEC PDP-11/? UNIX V? cc 07/06/87 EXTENSIVE
mods to fix problems with signed chars.

VAX VMS cc 16/06/87 Add #define
times ttmes to fix multiply defined symbol problem. [infocom.h]

Version 1.00 – August 17, 1987.
——————————-

The REV_C interpreter of June 2, 1987 was officially archived as
Version 1.00 on August 17, 1987.

So this means it’s very 16bit & 32bit friendly, especially on BIG endian machines like the 68000 processor.

Luckily this older version is pretty trivial to compile, and get running.  But I was over thinking the build process and decided to strip the executable as GCC would kick out a 500kb file, which objcopy would extract a 81kb executable.  Stripping it brought the size down to a 50kb executable but it wouldn’t run in either xm6 or run68.  I ended up going in circles for a while trying to find fault in what is broken where until I manually compiled the interpreter, and omitted the strip step and suddenly had a working interpreter.

Now there is one issue, saving doesn’t work.  Something in the libc is having issues using fopen with a file to write.  Reading works perfectly fine though.  So to fix it, I went ahead and redid the save feature to use the HumanOS native _open/_write/_close functions and I’m able to now save & restore a game.

D:\proj\run68\test>run68.exe infocom.X minizork.z3
MINI-ZORK I: The Great Underground Empire
Copyright (c) 1988 Infocom, Inc. All rights reserved.
ZORK is a registered trademark of Infocom, Inc.
Release 34 / Serial number 871124

West of House
You are standing in an open field west of a white house, with a boarded front
door. You could circle the house to the north or south.
There is a small mailbox here.

West of House Score: 0/0
>restore
Filename: mz1.sav
Ok.

Living Room Score: 10/19
>inventory
You have:
A nasty knife
A rope
A sword
A brass lantern (providing light)
A brown sack
A glass bottle
The glass bottle contains:
A quantity of water
A leaflet

Living Room Score: 10/20
>

In this process I’ve also managed to build run68, and verified that it’s operating correctly, as both run68 and XM6 both failed to write to a file with fopen, and both work using the native calls.

Planetfall on a x68000

Planetfall on a x68000

I’m sure most people won’t care but I think it’s great having the ability to run a GCC generated C program in a relatively small interpreter.

If anyone cares, here is my updated cross compiler + run68 source along with tweaked Info Task Force 1.0 source.  Or a disk image that XM6 can boot up, and run some demo programs from Infocom of ages ago.

Apout on Windows

I read somewhere that kids these days are interested in games where you can modify how the game operates with sub programs written in their own languages etc.

Hello from Unix v7

Hello

So while this does sound interesting, it does remind me of that good old fashioned syscall emulation, where you emulate the CPU, load an executable, but any system calls that are made, are handled by the simulator, little if any hardware is actually emulated. Yes Basilisk II is an example of this, but so is Wine, WOW, NTVDM, i386 code on x64 platforms, and various others. The major advantage is that they typically can access your native file system so you don’t have to mess with virtual disks. Of course it all depends on the implementation.

I did remember this old simulator, Apout, which could run UNIX v6, 7 along with BSD 2.9 stuff on modern Unix. The emulation layer here being LIBC, and how pretty much the basics of how UNIX operates hasn’t changed since those ancient days in the 1970’s.

So I thought I’d try to see how much of this works on Win32 using Microsoft Visual C++ 5. And surprisingly I didn’t have to glue in that much, the biggest thing I had to do was trying to detect if a file about to be opened was ASCII or BINARY as the UNIX platform doesn’t distinguish these two but Win32 with it’s MS-DOS legacy does. As you can see I did get the banner program running, some of the games work ok, although I had to comment out the sgtty functions as there is no immediate equivalent on Windows, and I didn’t think there would be that much of a demand for such a thing anyways. I can even run the login program. Which brings me to the issue which is that it’ll spawn new programs fine, but when an exit is called Apout just exits. Even on Linux it’ll just do this. I tried doing something with setjmp/longjmp but it crashes shortly afterwards… No doubt some stack unwinding fun. As such trying to compile things just bomb out. I went ahead and took the source code to cc and made a native Win32 version that then calls apout for the various parts and that almost worked except I then found out that the assembler on the PDP-11 is a 2 pass assembler, written in assembly. And yes, when as calls as2, and unwinds all hell breaks loose. Which is another problem that UNIX likes to share file descriptors among itself and children, but children like to close things when they die. I guess the solution is to give each child it’s own descriptor table as everyone likes to close stdin/stdout/stderr and even #4, which the simulator uses for logging. it’s very annoying so I just prevented it from closing handles under 4.

But running each of the phases manually does get me an executable but it doesn’t seem to do anything, the only syscalls are closing all the file handles and exiting.

So close!

I don’t think anyone will care, but here is my source/binary along with Unix v7. It’s hard coded to dump stuff into c:\temp for temporary files, the Unix v7 must be in c:\v7 … ugh.

Hunt the wumpus on NT

Hunt the wumpus on NT

But yeah, you can play that thrilling game from 1979, hunt the wumpus!

SAGE CP/M disk fun

Wow this was without a doubt one of the more confusing things I’ve ever done.

So here is the problem.  I want to delete some files from an IMD disk image, and then copy some new ones in.  Easy right? .. maybe.

Ok first up the easiest tool I’ve found to manipulate CP/M disk images is cpmtools.  Even better their pre-compiled binary is for Win32, so I’ll run it with Wine on OS X.  which works fine.  Although there is one slight problem, cpmtools doesn’t read the IMD disk format.  So you will have to download imd118.zip from a backup of the late author’s computer.

Now using IMD you need to convert the OS disk into a ‘raw’ or ‘binary’ file.  Naturally IMD is a MS-DOS program so firing up DOSBox, I ran:

Screen Shot 2013-12-05 at 8.35.58 PM

Uncompressing, so easy!

IMDU CPM68K12.IMD CPM.RAW /B

And a few seconds later I had my raw file.  Now the next thing was to manipulate the image in cpmtools.  cpmtools has a database of disk drive types, and naturally there is no definition for the SAGE2.  However thanks to a friend of mine (hi Lorenzo!) I took at look at 22disk, and found their demo version did in-fact have a definition for the SAGE:

BEGIN SAG2 Sage IV – DSDD 96 tpi 5.25″
DENSITY MFM,LOW
CYLINDERS 80
SIDES 2
SECTORS 8,512
SIDE1 0 1,2,3,4,5,6,7,8
SIDE2 1 1,2,3,4,5,6,7,8
ORDER SIDES
BSH 4 BLM 15 EXM 0 DSM 315 DRM 63 AL0 080H AL1 0 OFS 2
END

Which is great, however it took a bit of experimenting to work out how to format this information for cpmtools.  I compared a bunch of known formats, and then managed to work this out:

diskdef sage2
seclen 512
tracks 160
sectrk 8
blocksize 2048
maxdir 128
skew 1
boottrk 2
os 2.2
end

And now I can look at the image file!

$ wine cpmls -f sage2 CPM68K12.RAW
0:
ar68.68k
armath.sub
as.sub
as68.68k
as68symb.dat
asgo.sub
brwnies.txt
copy.68k
core.sub
cpm.sys
ddt.68k
ddt68000.68k
dump.68k
e.sub
find.68k
halt.68k
init.68k
linkcore.sub
lnk.sub
lo68.68k
m.sub
mcc.sub
mince.68k
mince.swp
mind.sub
orbit.sub
p.sub
pe.sub
pip.68k
print.68k
red.sub
redasm.sub
sage4utl.68k
sagebios.sys
screen.68k
setenv.68k
setprntr.68k
sig.txt
space.sub
spacem.sub
startup.sub
stat.68k
tlnk.sub

So I tidy up the image, and copy it back to the IMD program for compressing.  And this was, without a doubt the most difficult to figure out, until after a bunch of searching, and Lorenzo once more again pointed me in the direction of bin2imd

not intuitive!

not intuitive!

So yeah.

BIN2IMD X.RAW X.IMD DM=2 N=80 SS=512 SM=1-8 /2

And the best part is that it worked!  So now I was able to transfer over a binary version of com.68k, com2.68k, along with Zork, and fire it up!

8080 Zork on 68k CP/M

8080 Zork on 68k CP/M

Unfortunately the interpreter doesn’t work right.  It could be the disk transfers fault, maybe the SIMH SAGE emulator, or even the 8080 emulator.  But it worked this far.

So I thought I’d have some fun with jsmips

Hello World!

Hello World!

The Javascript MIPS emulator.. So after snagging the source, and all went well building the binutils, gcc, then gcc again, the libc. All seemed well except I couldn’t work out exactly what goes where…

So after a bunch of messing around I managed to get it run..  kind of.  I think the php file that proxies the filesystem is broken as I get something like this from the now broken main js page..

function genroot(p){var dir=new Directory(p);function genbin(p){var dir=new Directory(p);dir.children["=listusers"]=remoteFile("./bin/listusers","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Flistusers");dir.children["=apropos"]=remoteFile("./bin/apropos","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Fapropos");dir.children["=banner"]=remoteFile("./bin/banner","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Fbanner");

And yet I get this kind of output:

{error: false, type: ‘d’, cont: [“dtextc.dat+”,”hi+”,”var/”,”hi.c+”,”source/”,”bin/”,”dungn27s.zip+”,”dungeon+”,”./”, “../”]}

Which.. isn’t right enough.  I’m not sure what is up with dir.php ..

Oh well, I was able to build a simple hello world type program, but anything that hopes to pull data off the drive won’t work.  If anyone thinks they can do better my archive of all the bits is here (48MB), and the ‘runnable’ version is here .. hi is about as much fun as it’ll get.

iBCS2 & NetBSD

I know that there is some people out there that seem to be all into Xenix, and old binaries… So I thought I’d share this little gem I found before I head out for the day… I came across this post, talking about how ibcs2 has fallen apart in the latest version of NetBSD. But the gem in there is that version 4.0.1 works perfectly fine!

So I copied in the old gcc, filled in some bits and….

Qemu 0.14.0 NetBSD 4.0.1 running Xenix gcc

Qemu 0.14.0 NetBSD 4.0.1 running Xenix gcc

It works!

Robots is so perfect you’d never know!

Qemu 0.14.0 NetBSD 4.0.1 running robots

Qemu 0.14.0 NetBSD 4.0.1 running robots

And it runs Xenix Dungeon/Zork without missing a beat!

Qemu 0.14.0 NetBSD 4.0.1 running dungeon

Qemu 0.14.0 NetBSD 4.0.1 running dungeon

So this may be yet another avenue for some people… I’d suspect that you could even build the 32v userland under the Xenix tools…? Since all the default stuff is keyed to licensing, but you could roll your own Unix v7 32bit userland which basically is Xenix and go from there…. Maybe even some of the OpenSolaris SYSVR4 stuff as well but that sounds too ambitious!

MS-DOS Player

Since the last time I reviewed it, the MS-DOS Player, by Takeda Toshiya has come a long way!. He’s fleshed out more of the MS-DOS emulation, and updated the CPU core.

I’ve now been able to run the Microsoft C 5.1 compiler under Windows 7:

MS-DOS Player running Microsoft C 5.1

MS-DOS Player running Microsoft C 5.1

Check it out!

The MS-DOS Player is similar in nature to DOSBox, except that it’s not interactive, but rather built for CLI batch based operation. The MS-DOS Player seems to have some 80286 capabilities, but it’s BIOS/DOS emulation doesn’t seem to have the protected mode interface to allow dos extenders to work.

It’s certainly great for people that still have ANCIENT cli based programs that you’d want to call & capture their output. This is a life saver for some of us that still rely on dbaseIII & some ancient i8085 micro controller.

*EDIT updates from the future

Well Looking back at this post, it really is a snapshot of life back in 2011. Since those many years later DPMI support was added, along with the ability to ‘bind’ old programs allowing you to have a ‘Win32/Win64’ native exe that’ll run the old program inside. This is incredibly valuable for ancient toolchains where the source was either lost, or never provided, but now you can run them! This saves things like the Nintendo toolchain, although you can cross build the compiler, and assembler as they are GNU standard, the linker is a special one that will output cartridge images. And now you can run the MS-DOS DPMI version under Win64. Awesome!

Line is not an emulator

I don’t know how I didn’t find this earlier, and how it’s been overlooked for so long….

But this incredible program, LINE, will run statically linked Linux ELF binaries on Windows.

Yes, you read that right, this user mode program will load an ELF exe, and run it under a software debugger with no need for device drivers, and intercept all the sycalls (ie int 0x80’s) through the cygwin1.dll, giving you a POSX/Command line linux experience.

It does come bundled with various hello programs, and a few things on testing forks… But the real magic for me was being able to grab a static version of dungeon, and running it on both Windows 7 x64, and emulated NT 4.0.

And it works!

Line running Dungeon

I’ve put my copy of dungeon, along with a copy of cygwin1.dll that works with the LINE package here for anyone interested.

I’m just amazed at the size, and simplicity of the whole thing…..

In the documentation there is even mentions of NSO (Native shared objects?), and dynamic linking…

Clearly this project should have had more of a future to it!

The oldest CP/M ‘simulator’ out there.

I was surprised to come across this little simulator simply called ‘com‘ tonight. This program started out as a 8080 instruction simulator for a mc68000 machine running CP/M, back in 1984, and was written by one Jim Cathey.

‘Com’ was then later written up, and published in Dr. Dobb’s Journal.

From there it’s evolved it’s assembly core to some other 68000 cpu families and platforms, then the MIPS and PowerPC. Then in 2006 the CPU core was re-written in C.

For a while it’s primary platform was a 68000 based Unix, and it still has a lot of unix’isims buried in the source. I’m sure it’d build in MinGW though.

But in the meantime I figured it was yet another reason to fire up the old gcc 1.37.1 for Xenix to give this thing a go.

The biggest, and dumbest thing I fought was without realizing there was both a ‘Makefile’, and a ‘makefile’, and gmake kept running the lowercase one, while I was editing the Makefile in vain… But with that out of the way, and a few includes to fix, it was VERY straight forward to build. Not to mention running Xenix on Virtual PC 2007 on my new intel core i7 cpu, it compiles the C version just about as quickly as I can hit the enter key.

Because it’s on Virtual PC the last few lines of the console are garbled.. Oh well, at least the floppy controller works (as long as you hard code /dev/fd0 to 2,60).

So, here is a picture:

Xenix 2.3.4 with ccom zork1

Xenix 2.3.4 with ccom zork1

And a disk image. All I’ve really done is tweaked a few things, and built this with gcc so it includes a binary for Xenix systems. Also the ‘com.tar.gz’ package did include quite a few sample programs… mandog.com is fun, along with zork 1,2 &3!

On a final note, I thought the Xenix thing was a good road to head down because in the 1990’s there was this BIG push for ibcs2 compatibility across all these Unix platforms on the i386 cpu. Well it’s been largely abandoned work, and the best I got was OpenBSD complaining that its always out of memory, and NetBSD kernel panics!.. Open Solaris has *NO* ibcs2 compatibility even left.

I suspect it doesn’t matter, esp now that you can run some real ibcs2 OS’s in a VM, who needs 3rd party emulation?

I guess I’m just too late to the party.