Sample 'screen shot' from WordStar 3.00:
editing no file < < < N O - F I L E M E N U > > > ---Preliminary Commands--- | --File Commands-- | -System Commands- L Changed logged disk drive | | R Run a program F File directory off (ON) | P Print a file | X EXIT to system H Set help level | | ---Commands to open a file--- | E RENAME a file | -WordStar Options- D Open a document file | O COPY a file | M Run MailMerge N Open a non-document file | Y DELETE a file | S Run SpellStar DIRECTORY of disk A: FFT.BAS KEYCON.ASM KEYCON.PRN KEYCON.SYM MORTGAGE.BAS PILOT.TXT SPELSTAR.DCT SQRTSIM.BAS THRASH.BAS TUTORIAL.PIL ZORK1.DAT ZORK2.DAT ZORK3.DAT KEYCON.HEX CD.COM FORTH.COM INSTALL.COM LOAD.COM MAC.COM MBASIC.COM PILOT.COM SARGON.COM TESTPROG.COM WS.COM WS.COM ZORK1.COM ZORK2.COM ZORK3.COM MAILMRGE.OVR MERGPRIN.OVR SPELSTAR.OVR WIMSGS.OVR WSMSGS.OVR WSOVLY1.OVRAnd then running Zork (from within WordStar):
r editing no file Enter name of program you wish to Run, optionally followed by appropriate arguments. Example (shows disk space): STAT ^S=delete character ^Y=delete entry ^F=File directory ^D=restore character ^R=Restore entry ^U=cancel command COMMAND? zork1 ZORK I: The Great Underground Empire Copyright (c) 1981, 1982, 1983 Infocom, Inc. All rights reserved. ZORK is a registered trademark of Infocom, Inc. Revision 88 / Serial number 840726 West of House You are standing in an open field west of a white house, with a boarded front door. There is a small mailbox here. >
I also began a port to the MIPS because we use those at work too, and this is an excellent vehicle for learning a processor's native instruction set. The move away from using the host processor's native condition-code flags proved to be a good one, because the MIPS doesn't even have a condition code register! However, though the resultant port compiles I was unable to get it to link properly so that it would actually execute. I have left finishing this 'til later, since my main objective (learning the MIPS) was accomplished and I was getting tired of working on it. The PPC timing results imply that any improvement would hardly be worth the effort anyway.
Performance (in seconds for the test run):
MHz| 4 8 10 20 25 25 233 800 3000 2330 CPU| Z-80 68000 68010 68020 68030 68030 PPC G3 PPC G4 Pent-D iC2Duo OS | CP/M CP/M DNIX DNIX NeXT SVR4 OSX 2.8 OSX 3.5 XP/Cyg OSX 4.8 ===+ ==== ===== ===== ===== ===== ===== ======= ======= ====== ======= com 35* 19 20 18.5* 0.50 0.19 comt 52 52 1.2 0.35 com10 82* 52 23 25 com10t 149 55 60 ccom 130 48 58 0.71 0.24 0.14 0.08 ccomt 260 91 92 1.3 0.38 0.17 0.13 comtest 2060 840 681 7.6 2.40 ccomtest 7.1 2.13 1.00 0.63 Note: * Old numbers, not reproducible. (Platforms long gone.)Of particular interest is that while for the 680x0 platforms I could beat the C code by a substantial margin, for the PPC it wasn't worth the effort! Modern C compilers seem to mate to modern RISC processors very well, imagine that. What's more, except for the large lookup table, the C version of the CPU is several kilobytes smaller! (This can be blamed on the assembly version's inline next macro, which doesn't seem to make any speed difference when replaced with a branch to a central next routine, which does make the assembly version smaller.) Most instructive, though the results were not exactly what I had expected. (Which means this was a worthy exercise.)
Also note that the C-only version of the
runs faster than the one that includes assembly language,
yet the simple assembler version runs faster than the simple C
version, though not by a huge margin. This tells me that the
processor's cache isn't big enough, and that
is starting to thrash the cache a bit more than
did, as it is larger. Interesting. (The comtest programs are for
pitting the C and assembler versions of a synthetic CPU against
each other. Differences halt the simulation. Both CPU
models have gained by this procedure. The C-only test version is
for debugging the test harness itself, as it compares two
identical CPU models, which can be tweaked to induce errors to
ensure that they are caught by the harness.)
Two additional makefiles have been added,
make.mips, the desired file should be linked to
Makefile, as appropriate.
The simulation environment has been enhanced to support CP/M drives A: through P:, the full set, though not to the associated 16 user spaces per drive. These translate to directories (one each) under Unix, and which are specified on the command line. Also provided is a way to 'bury' selected files within the simulator itself. This lets something like WordStar, which requires overlay files to always be available, edit files anywhere in the system, just like any native editor.
A makefile for Mac OS X has been added, named (obviously enough)
make.osx, it should be linked to
if appropriate. It's the one to use for any non-680x0 machine as
it's the one that's C-only. Changing one
the front specifies whether the target system is DNIX, SVR4, or
BSD in flavor. It has been compiled and run unchanged (except for
the flavor selector) on OS X, Cygwin, FreeBSD, and Linux.
As should be obvious, porting (to anything Unix-ey) is now a
nearly trivial exercise. The most system-specific code is in the
directory listing logic, what's there now is a choice of using the
dirent package or a really nasty exec of find and sed. This could
be converted to something else, the changes should be localized.
The next-most-system-specific code is the terminal handling code.
(That's the main reason for the flavor selector
in the first place.)
The C simulation code was written from scratch, so it's unrestricted.
$ time ../com mac keyconA stopwatch was used for the host (native) CP/M platforms.
4 8 10 20 25 25 233 800 3000 2330 Z-80 68000 68010 68020 68030 68030 PPC G3 PPC G4 Pent-D iC2Duo CP/M CP/M DNIX DNIX NeXT SVR4 OSX 2.8 OSX 3.5 XP/Cyg OSX 4.8 ==== ===== ===== ===== ===== ===== ======= ======= ====== ======= com 35* 19 20 18.5* comt 52 52 com10 82* 52 23 25 com10t 149 55 60 ccom 130 48 58 0.67 0.24 0.14 0.08 ccomt 260 91 92 1.1 0.38 0.17 0.13 comtest 2060 840 681 6.0 2.13 1.00 0.63 Note: * Old numbers, not reproducible. (Platforms long gone.)This simulator is probably not the fastest one out there, nor is it particularly complete, nor is it feature-laden, and it is far from the only one out there! What it is is venerable, it has existed (in some form) since 1984, making it one of the first, if not the first, CP/M simulators designed for practical use. (I won't count any potential simulations that may have existed at chip manufacturers.) I got it published in Dr. Dobb's Journal in 1986, my one and only publication.
$ ../com mbasic BASIC-80 Rev. 5.21 [CP/M Version] Copyright 1977-1981 (C) by Microsoft Created: 28-Jul-81 39730 Bytes free Ok files ZORK3 .DAT ZORK3 .COM ZORK2 .DAT ZORK2 .COM ZORK1 .DAT ZORK1 .COM WSOVLY1 .OVR WSMSGS .OVR WS .COM WS .COM WIMSGS .OVR TUTORIAL.PIL THRASH .BAS TESTPROG.COM SQRTSIM .BAS SPELSTAR.OVR SPELSTAR.DCT SARGON .COM PILOT .TXT PILOT .COM PARANOIA.BAS MORTGAGE.BAS MERGPRIN.OVR MBASIC .COM MAILMRGE.OVR MAC .COM LOAD .COM KEYCON .ASM JUNK .COM INSTALL .COM FORTH .COM FFT .BAS CD .COM Ok system $
Please remember that CP/M text files use both carriage returns and linefeeds (one each) to delimit lines, and the end-of-file character is an embedded control-Z. The EOF character is needed because CP/M files are always multiples of 128 bytes—there is no byte-level file length indication. CP/M programs can get annoyed if files fed to them don't conform to these expectations.
I have left as an exercise for the reader the writing of the synthetic CPU module for non-680x0 systems. I considered writing one in C to serve as a model, but it would function so slowly on the systems I use (the ones I did get it working on) that I didn't want to waste my time—it's not like I need a CP/M simulator for anything. The energetic could write one fairly easily (how hard can an 8080 be after all?), but for real speed a new assembly-language module should be written. It would be particularly efficient on an x86 machine, since the slowest part of the simulation is getting the flags right. The x86 and the 8080 have the same flags, so it's probable that the 8080 flags could just be taken straight out of the x86 flags register (i.e. no work at all). However, as I think that most x86 machines are evil incarnate I refuse to take a stab at the project (except maybe with a wooden stake).
There are three makefiles provided, one for DNIX, one for NeXT, and one for vanilla (?) System 5. The appropriate file should be linked to the name Makefile, then you should just be able to type 'make'. If I were better at multi-system configuration programs this could probably have been made more elegant, but it works well enough for me.
Return to Site Home