- "For Networks and Multi-user Systems -- TurboDOS"
  Ron Fowler
  "Microsystems", Vol.5, No.8, August 1984, p.58
(Retyped by Emmanuel ROCHE.)

Gone  are the days when simple operating systems satisfied the needs  of  most
small-system  users. Once written primarily to satisfy the  relatively  modest
requirements  of hobbyists and experimenters, microcomputer operating  systems
are  now designed for performance, with special concern for providing  maximum
versatility to the user.
One  such  operating  system is TurboDOS, a product  of  Software  2000,  Inc. 
Written  originally for the Zilog Z-80 (and recently converted for  the  Intel
8088/8086  family), this package offers a high degree of  CP/M  compatibility,
multi-tasking background processing, powerful networking capability,  built-in
communications facilities, print spooling, and much more.
This article will take an in-depth look at this powerful system: what you  can 
expect  to  gain by using TurboDOS, and what (if anything) you might  lose  by
giving  up CP/M in favor of TurboDOS. We will examine the  TurboDOS  operating
system  and its utilities in detail, and conclude with a section addressed  to
the   programmer   or  system  developer  interested   in   writing   TurboDOS
(ROCHE> Unfortunately, when I read this article, 30 years later, it is obvious 
that  Ron  Fowler  had no experience of MP/M,  the  multi-tasking,  multi-user
version  of  CP/M...  By  the way, each time that he  says  "CP/M",  you  must
understand:  "CP/M  2.2". TurboDOS is, in fact, a multi-processor  version  of
MP/M.  That's why it is more compatible with MP/M than with CP/M  (2.2)!  Poor
Ron  Fowler,  not  knowing  MP/M, is often ecstatic  by  the  capabilities  of
TurboDOS, which are exactly (except multiple processors) those of MP/M...)

Much   of  the  information  presented  here  is  based  on  my   own   custom 
implementation  of TurboDOS Release 1.3. The evaluation copy of  the  software
was provided courtesy of North Star Computers, Inc. North Star provides a full
implementation for their own hardware, and offers it bundled with  Turbo-Plus,
a TurboDOS enhancement package (which I hope to review in a future article).
While  the  1.3 Release of TurboDOS provides Intel  8088  compatibility,  this 
discussion  is limited to the Zilog Z-80 version. The evaluation system  is  a
networked  version,  interconnecting  a Z-80-based S-100  Bus  system  with  a
disk-less  single-board  Z-80 computer, through Intel 8255 PIO chips  in  each
computer.  Figure 4 is a schematic of the circuit used to interconnect  the  2
The  S-100  Bus  system consists of an Integrand  mainframe  housing  a  Delta 
Products 4-MHz Z-80 CPU, 128K of CompuPro memory, and various I/O boards.

TurboDOS  is  structured in a 2/3 arrangement: the main body of  the  TurboDOS 
operating system is analogous to CP/M's CCP and BDOS. This portion is machine-
independent,  and is supplied as a group of Microsoft-format REL  (relocatable
machine  code) files. The remainder of the system is similar to  CP/M's  BIOS,
and  consists  of a collection of *DEVICE DRIVERS* (for such  things  as  disk
drives,  printers,  and  network communications).  These  driver  modules  are
written  by  the system integrator; if you purchase a packaged  system,  these
drivers are already written for you.
The modular design of the TurboDOS operating system allows it to be configured 
in  an  almost infinite variety of forms. Table 1 lists a number of  the  more
commonly-used modules.
Table 1. Common TurboDOS modules
(NOTE: Modules denoted by an asterisk (*) after the module names are  resident 
Name    Function
----    --------
LCLUSR* Supports the Transient Program Area
LCLMSG  Contains the system error messages
CMDINT  Command line interpreter, similar to CP/M's CCP
NETSVC* Services  network requests. Necessary only in processors that  provide
        facilities to the network (servers)
NETREQ  Makes requests of the network
NETTBL  Defines network topology from viewpoint of the local node
DSPOOL* Printer de-spooler (background print)
FLUSHR* Periodically flushes disk buffers
OSNTRY  Decodes system calls (C-functions and T-functions)
FILMGR  Handles the local file system.
        Nodes without disk storage do not require this module.
FILLOK  Handles file interlocks
FFOMGR  Handles the special FIFO files
FASLOD  Fast program-load optimizer
BUFMGR  Manages the disk buffers
DSKTBL  Defines the available disk drives (local and remote)
CPMSUP  Special support for CP/M.
        Makes TurboDOS operating system more CP/M-compatible.
CONMGR  Handles all console I/O
CONTBL  Connects CONMGR to hardware console driver module(s)
DOMGR   Handles batch commands
LSTMGR  Handles printer output
SPOOLR  Handles background spooled-print functions, as well as routine printer
        output over the network
RTCMGR  Maintains system date and time (real-time clock)
BNKMGR  Banked memory support
DSPCHR  Multi-tasking  kernel;  controls  CPU  dispatching  between  competing
        processes, as well as synchronization and inter-process communications
DSPSGL  Special "null" dispatcher; allows a non-multi-task version of TurboDOS
        to be created
MEMMGR  Controls dynamic allocation of memory
OSLOAD  Special module used to create a loader program
COMSUB  Common subroutines needed in all versions of TurboDOS
Each major function is isolated in its own module, many of which can be  added 
to  and  deleted from the TurboDOS operating system by the user  (ROCHE>  ?  A
*USER*  fine tuning a Disk Operating System?), thus providing the  ability  to
add  or  subtract functionality. For example, the SPOOLR module  contains  the
necessary  code to implement the TurboDOS print spooling  function  (described
later). By deleting this module in systems that do not require print  spooling
(e.g.,  single-user  systems),  the  TurboDOS operating  system  can  be  made
smaller, allowing more room for disk buffers and transient programs.
Flexible as this assortment of modules may be, it would be demanding a lot  to 
ask  all  users to build their own TurboDOS operating system. To  avoid  this,
TurboDOS  is  packaged with a number of "standard" versions  (Table  2),  each
providing a commonly-required configuration.
Table 2. Standard TurboDOS configuration packages
Name      Function
----      --------
STDLOADR  Cold-start system loader
STDSINGL  Single-user version, no spooling
STDSPOOL  Single-user version with spooling
STDMASTR  Network master
STDSLAVE  Network slave without local disks
STDSLAVX  Network slave with local disks
(ROCHE>  So, The first 3 versions correspond to CP/M, and the last 3  versions 
to MP/M. Note the emphasis on spooling. In fact, Digital Research was  selling
one  DESPOOL  program for CP/M Versions 1 and 2, but it only ran  reliably  on
DRI's Intel MDS-800 microcomputers...)
The system may be configured (and reconfigured) conveniently by using GEN.COM, 
the  supplied  system  generation  utility.  This  program  is,  in  fact,   a
sophisticated  linkage  editor  that  takes  its  commands  from  disk  files,
providing  a  high degree of automation in the system generation  process.  An
additional file (called a PAR file) can be specified to GEN.COM. The PAR  file
references, *BY NAME*, parameters within the system. It is a powerful concept:
you  can  restructure  major  portions of the  system  (such  as  the  network
definition  tables,  disk assignment tables, command-search  paths,  and  many
others) merely by editing the PAR file and regenerating the system.
Most implementations of TurboDOS provide for a boot PROM, allowing the  system 
to start up automatically at power-on. The boot PROM contains just enough code
to  load a file named OSLOAD.COM into the program area. OSLOAD then brings  in
the  rest of the TurboDOS operating system. My own implementation  boots  from
CP/M,  running  OSLOAD as a CP/M transient program. This suits  my  particular
needs better than setting up a boot PROM -- and, incidentally, illustrates the
versatility of TurboDOS.
When  the  TurboDOS operating system start up, it prints  a  sign-on  message, 
followed  by the system prompt. This is where TurboDOS begins to  differ  from
standard CP/M: the prompt contains the user number, as well as the drive name.
(TurboDOS supports 32 user numbers -- twice as many as CP/M; and the  familiar
angle  bracket  prompt  character of CP/M is replaced with  a  curly  bracket:
Depending on how the system is set up, it may be necessary to *LOG IN*  before 
any useful work can begin. A utility, LOGON.COM, is provided for this purpose,
and  another,  LOGOFF.COM,  is used to terminate the  session.  TurboDOS  may,
optionally,  be  instructed  to maintain a file of  logons  and  logoffs,  and
require  that a password be specified at login. Passwords are maintained in  a
special user accounts file maintained with a text editor. Additional  security
allows  logon  to  be retricted to a single user  area  (this  restriction  is
specified  in  the  user accounts file). Another  login  option  provides  for
privileged  logins  (non-privileged  logins may not  change  user  areas,  and
several of the supplied utilities will function only for privileged logins).
The  rhythm of this system is a bit different from that of CP/M. For  example, 
there  is no warm boot, since the entire TurboDOS operating system remains  in
memory  at  all  times.  (CP/M 2.2, of  course,  allows  the  Console  Command
Processor  to be overwritten by a user program, thus requiring that a  portion
of  the  CP/M 2.2 operating system be read back in from disk  when  a  program
terminates) (ROCHE> CP/M Plus ("CP/M Version 3" in the USA), launched in  1983
(so,  one year before this article), is a single-user version of  MP/M...  So,
since it supports "banked memory", the CCP is reloaded instantly from  memory.
Each  time CP/M Version 2 was spending too much time reading the floppy  disk,
the  data was stored in memory. 2 examples: the CCP and the directory.  That's
why CP/M Plus, in a good implementation, is much faster than CP/M 2.2  running
on the same hardware.)
Additionally,  there  are  no built-in commands; all commands  are  loaded  as 
transient  programs from the disk. Hence, functions such as ERASE  and  RENAME
take  a bit longer to complete than their CP/M 2.2 counterparts, because  time
is  needed to load them. Most of the utilities, however, make up for  this  in
expanded  power and versatility, as we shall see. In any case, if a hard  disk
is used, the extra time is so small as to be unnoticeable.
From the command level, TurboDOS works similarly to CP/M in that commands  are 
typed  into  the  system, and the specified files are  executed  as  transient
programs.  If, however, your TurboDOS is part of a network, the  programs  and
files  that  you use are not necessarily located on your  local  computer  (in
fact,  your  local  computer may not even have any  storage  facilities  (disk
drives) at all!). This networking capability is one of the strongest  features
of TurboDOS, and we will examine that aspect of the system in detail later.

CP/M compatibility
TurboDOS  is  compatible with almost all CP/M programs. There are only  a  few 
CP/M  programs  that I have seen that do not work properly under  TurboDOS  --
mostly  public  domain  utilities that access some of the  more  obscure  BDOS
system  calls  (7, 8, 24, 28, 29, 31, and 100-107). However, TurboDOS  may  be
installed  with  an  optional CP/M-support module  that  will  simulate  these
missing functions.
Another  incompatibility  involves  CP/M's SUBMIT processing: I  am  aware  of 
several  commercial packages that make use of CP/M 2.2's special $$$.SUB  file
for batch-command processing, and that do not work under TurboDOS because  the
$$$.SUB  file  is  not processed. Another optional module  is  supplied,  that
modifies the TurboDOS batch function to emulate CP/M 2.2 more closely (but  at
the  expense  of slowing down DO file processing). The packages  mentioned  do
work properly under TurboDOS if this module is installed.

Multi-tasking the CPU
Beginning  a more detailed study of TurboDOS, one of the first things that  we 
should  note  is  that  it can execute more than one  task  at  a  time;  this
capability  is usually referred to as *MULTI-TASKING*. (ROCHE> And  MP/M,  the
multi-user,  multi-tasking version of CP/M, had done it for at least  5  years
when this article was written...)
Integral to the concept of multi-tasking is the *RESIDENT PROCESS*. A resident 
process is a program that executes within the system; under TurboDOS, resident
processes  are  physically  attached to the operating  system,  but  logically
maintained  outside  of  it.  (That is to say:  they  perform  their  task  by
executing  operating system calls, in the same way that user programs do.  The
difference  is  that  user programs are transient in  nature,  while  resident
processes are always present.)
At  any  given time, a process may be in any of 3 states:  ready,  running  or 
suspended. A running process is one that is currently executing on the CPU;  a
ready  process  is  one that is waiting to execute (but  otherwise  ready).  A
suspended  process (sometimes referred to as "blocked") is a process  that  is
waiting  for some event to happen, or waiting for a period of time to  expire.
(TurboDOS provides a system call that allows a process to delay execution  for
a fixed time interval.)
The  suspended  state  is  perhaps the most significant.  A  process  that  is 
suspended  is  "stacked"  on  one  of  a  number  of  special  lists   (called
"semaphores"), and thus does not slow down the system by consuming CPU cycles.
At any given time, most processes will be in this suspended state. Hence, user
programs  that  are CPU-intensive (i.e., spend most of their  time  processing
data rather than waiting on I/O devices) run nearly as fast as they would on a
single-task system.
A  number  of "background" processes, present in each  CPU  running  TurboDOS, 
perform  such actions as monitoring the network, flushing disk  drive  buffers
periodically,   etc.   Additionally,  user-written  resident   processes   are
supported;  any  such  process is physically part of  the  TurboDOS  operating
system, and must be added to TurboDOS when the operating system is generated.

Banking the system
TurboDOS makes good use of bank-selectable memory. When more than one bank  is 
available,  most  of  TurboDOS resides in Bank  0,  while  transient  programs
execute  from Bank 1. (ROCHE> Exactly like CP/M Plus, the single-user  version
of  MP/M,  launched  one year before this article...)  Since  a  full-featured
network-master version of TurboDOS exceeds 24K in size, this frees up a lot of
program  area.  (ROCHE> That's why MP/M used banked memory, since MP/M  was  a
multi-user version of CP/M. So, each user wanted to have its own TPA, and most
CP/M program wanted as much RAM as possible... So, the only technical solution
was to provide "banks" of memory to each user.)
Banked  systems are often measured by the amount of *COMMON MEMORY* that  they 
consume.  Common memory is a section of memory (usually located physically  at
the top of the address space) that is always present within the CPU's  address
space,  regardless of which memory bank is switched in. Since the  Zilog  Z-80
CPU  is limited to 64K of total address space, it is obvious that the  common-
memory  requirement increases at the expense of the banked segments, and  thus
at  the  expense  of  memory available to  transient  programs  (in  the  case
of TurboDOS, at the expense of the allowable size of the operating system).
The  only portion of TurboDOS that *MUST* remain in common memory is  a  small 
inter-bank communications module, plus some portions of the  interrupt-service
routines.  (ROCHE>  Exactly like MP/M and CP/M Plus...) Thus,  the  amount  of
transient program area (TPA) available is 63K, even if banked memory  hardware
allows  bank  switching only on 4K or 16K boundaries.  (ROCHE>  Nothing  news,
here.  There is even a version of CP/M 2.2 for the Epson QX-10 having a  63.5K
A  utility  program,  BANK.COM, allows the TurboDOS  operating  system  to  be 
switched between banked and non-banked mode. When non-banked mode is selected,
programs must share Bank 0 with the operating system.

Disk drives and files
TurboDOS  supports file sizes of up to 32MB (ROCHE> Like CP/M Plus...)  and  a 
disk  drive  capacity of up to 134MB (ROCHE> CP/M Plus:  512MB...  Of  course,
compared to the 8MB of CP/M 2.2, this appeared to be an improvement...  Except
that  CP/M  Plus had been launched by Digital Research one  year  earlier!...)
Obviously, such large drives will have a lot of files, and will need a lot  of
seek  time  during  such operations as file opens,  directory  searches,  etc.
(ROCHE>  That's  why  directories are cached in CP/M Plus.) In  an  effort  to
decrease  this  time, TurboDOS supports a special directory  format  called  a
*HASHED  DIRECTORY*. (ROCHE> MP/M and CP/M Plus did not go this way.)  A  disk
directory  may, at any time, be restructured as a hashed  directory  (although
the opposite is not true) by running a program named FIXDIR. (ROCHE> CP/M Plus
has  something roughly similar, INITDIR.COM, which restructures the  directory
to  add date and time stamping of files.) Although hashing the directory  made
little difference on my small-capacity floppy disks, a hardware dealer I  have
worked  with  (who  sells TurboDOS on IMS systems) reports  a  dramatic  speed
increase  on his 40MB hard disk systems. (ROCHE> I am not surprised. Me,  from
experience, I only use INITDIR on floppy disks, since it consumes 1/4th of the
directory.  On the hard disk, I simply type the date and time at the  head  of
the files.)
Another technique used by TurboDOS to increase performance is disk  buffering. 
(ROCHE>  Called "disk caching" in CP/M Plus.) The system contains  a  built-in
buffer  manager;  moreover,  a  utility program  supplied  with  the  TurboDOS
operating  system, BUFFERS.COM, lets you change the size of each  disk  buffer
and  the number of buffers *WHILE THE SYSTEM IS RUNNING*. (ROCHE>  Under  CP/M
Plus,  this  is  done at system generation time, with GENCPM,  by  the  system
implementer.)  These buffers are taken "off the top" of the transient  program
area (TPA) (in unbanked versions of TurboDOS). If you are going to run  small,
disk-bound  programs, you can set up a large number of buffers,  and  increase
disk  access  speed.  Conversely, memory-hungry programs  (such  as  WordStar)
should  be  run with a small number of buffers, to provide as much  memory  as
possible.  (ROCHE> Well, with "banks" of memory, each user has its own 64K  of
(I  should  point out that, while directory hashing  made  little  performance 
difference  in my system, increasing the number of disk buffers in the  system
increased  disk  throughput dramatically.) (ROCHE> That's  why,  after  tests,
Digital Research added disk caching to CP/M Plus.)
Systems  using banked memory may set up most of the unused part of Bank  0  as 
disk buffer space, and not affect program memory space at all.
A  fast file-load function supplies yet a 3rd performance increase:  generally 
used by the Command Interpreter (the portion of the TurboDOS operating  system
that processes user command lines), this module allows a section of memory  to
be  loaded  in  the fastest manner possible. It works  by  scanning  the  disk
allocation  map, detecting sequentially-allocated segments, and loading  these
segments  at the fastest transfer rate of the disk controller.  (ROCHE>  Under
CP/M  Plus,  the CCP is reloaded from a system Bank, so it is  just  a  memory
transfer,  and  using  the  "Multi-Sector Count", allowing up  to  16K  to  be
read/written in one shot...)

File attributes
TurboDOS  expands  on the file attributes employed by CP/M. (ROCHE>  ???)  The 
CP/M "SYSTEM" attribute is replaced by the "GLOBAL" attribute. Files  resident
in  User area 0 and tagged as GLOBAL are accessible from any user  area,  thus
circumventing the need to duplicate frequently-used files in each user area of
the  disk. (ROCHE> Under CP/M 2.2! But MP/M had been available for at least  5
years  when  this article was written, and CP/M Plus one  year!)  This  global
access  applies  equally to files that are accessed  by  application  programs
(such as WordStar's overlay files), or chained BASIC programs.
ARCHIVE  is another (ROCHE> CP/M...) file attribute that saves time and  space 
when  backing up files. New files are created with the ARCHIVE attribute  off.
When a file is backed up using the COPY program, the ARCHIVE bit is set;  when
a  file  is changed (extended, or written to with a  random  write),  TurboDOS
resets  the ARCHIVE attribute. COPY can be instructed not to copy  files  that
have  been archived and have not been modified since. This process  is  called
"incremental backup". (ROCHE> And is provided by CP/M Plus' PIP...)
The final "new" file attribute is FIFO (ROCHE> This is specific to TurboDOS.); 
it  defines  a  special type of file accessed using  a  "first-in,  first-out"
(FIFO)  technique. FIFO files are accessed from programs like any other  file,
except that sequentially-written records are appended at the end of the  file,
and  sequential reads are taken from the beginning. Moreover, a FIFO file  may
be  declared as an in-memory file (accessed much faster, since it really  does
not  exist  on  disk at all; this limits the size of  the  file,  however,  to
available  memory.) (ROCHE> Most CP/M Plus implementations have a RAMdisk,  so
the  limit  is 32MB, in this case.) This whole scheme provides  a  very  handy
technique for passing data between background processes, and between  programs
executing on different processors. Since a FIFO file can be made to  "suspend"
(deactivate)  a process reading the FIFO file when it is empty, it is easy  to
visualize a background process that only "comes alive" when a program posts  a
record to a file monitored by the background process.
Two special utilities are provided to work with FIFO files: SEND and  RECEIVE. 
SEND  is invoked with a FIFO filename and a text string to place in the  FIFO.
RECEIVE  takes  only a FIFO filename; it reads one record from the  FIFO  file
(thus deleting the record) and displays it. Together, these 2 utilities may be
used to form a rudimentary mail facility between users. (ROCHE> Better to  use
CP/NET, which has been available for years...)

File interlocks
TurboDOS  features  file  and record lockouts, since  it  supports  background 
processes  that may access files at the same time as foreground processes.  In
fact,  network support for shared files requires at least one such process  in
each  file system offering file resources to the network. Interlocks are  used
to coordinate file accessing by multiple simultaneous processes and necessary,
for example, when an update program must replace an inventory item's wholesale
and  retail price fields. With no coordination, a querying program might  read
the  record sometime after the update program has begun writing new data,  but
before  the write is complete. Hence, the querying program reads  inconsistent
data.  With record locking capability, however, the update program can  obtain
exclusive  access to the record, "locking out" any other process that  may  be
attempting to access the same record.
File lockouts under TurboDOS may be configured for strict MP/M  compatibility; 
thus,  existing programs written for MP/M's record-locking techniques  (ROCHE>
Like Digital Research's Access Manager...) will work correctly under  TurboDOS
(ROCHE>  Fortunately,  since TurboDOS is a multi-processor  version  of  MP/M.
Hence the need to be compatible with its parent. It is the classical  "chicken
and  egg" problem.) Alternatively, a set of compatibility flags  is  available
(during system generation) to change certain rules, providing a number of  new
modes  not  previously available under MP/M. (ROCHE> Modes  which  disappeared
with TurboDOS, while CP/M is still alive, 30 years later...)

TurboDOS  provides a plethora of features, facilities, and utilities, but,  to 
me,  the  single most outstanding one is its built-in  networking  capability.
(ROCHE>  Never  heard of MP/M, launched 5 years earlier by  Digital  Research?
Never  seen  the advertisements for CP/NET in computer magazines? Why  do  you
think that TurboDOS is compatible with MP/M? For pleasure?) Multiple computers
running  TurboDOS  may be interconnected and share such  relatively  expensive
peripherals as disk drives, printers, plotters, etc.
In  this  discussion,  I  will use  the  terms  "node","CPU"  and  "processor" 
interchangeably.  (ROCHE>  Not a good thing. It shows that the  concept  of  a
network  is  still  a novelty for you. You should have read  the  MP/M  guides
published  several years earlier...) Generally, a node can be thought of as  a
workstation containing a CPU, memory, a network interface, and (optionally)  a
terminal, disk drives, and printers. A node is attached to the network via one
or  more  connection  points. It usually has some peripherals,  but  does  not
*REQUIRE* any.
Two  other terms will be used to refer to processors on the network:  *MASTER* 
(or  *SERVER*)  and *SLAVE* (or *SATELLITE*). Generally,  a  server  processor
provides  resources  to the network (such as disk  storage  and/or  printers),
while  satellites  do not. If satellites have local disks, these can  also  be
available to the network if the satellite contains the network service  module
First,  it is important to note that TurboDOS does not support multiple  users 
on  a single CPU. (ROCHE> Yes, since TurboDOS is a multi-processor version  of
MP/M.)  The  philosophy,  here,  is that,  since  processors  and  memory  are
relatively  cheap, why attempt to split up a hundred dollars or so in CPU  and
memory  hardware  when each user can have his own CPU and memory,  and  suffer
none of the processing delays that are so severe in such operating systems  as
MP/M  and  OASIS?  (ROCHE>  Good  question.  By  the  way,  why  did  TurboDOS
disappear,  while  MP/M  and OASIS are still running, 30  years  later,  under
emulators on the Internet?)
This concept works, and works well. (ROCHE> You should tell Intel, which never 
managed  to  make  its 8086 works this way. I  cannot  resist  mentioning  the
following, taken from "Chapter 1: Introduction" of the "Intel 8088/8086 Family
User's Manual", October 1979 (Yes, 5 years *EARLIER*!), page 1-1:
        "The 8086 family architecture is characterized by 2 major principles:
     1. System functions are distributed among specialized components.
     2. Multi-processing capabilities are inherent in the hardware.
     3. A  hierarchical bus organization provides for the complex  data  flows 
        required by high-performance systems without burdening simpler systems
        with unneeded capabilities."
This was written in 1979, for a CPU running at 4-MHZ. Today, *45 YEARS LATER*, 
Intel  has  not  been  able to produce even  a  single  computer  using  those
"principles"...  So, why did Intel, the richest microcomputer company  in  the
world, never managed to do it, while Software 2000, Inc. (e.g., Mike Busch and
Ron Raikes), did it? Was the Zilog Z-80 CPU so much better than the Intel 8088
of the IBM Clown?)
Each  user has full use of his own CPU; delays are generally  noticeable  only 
when shared disk drives are simultaneously accessed by multiple network users.
(Even   these  delays  can  be  abated  by  using  faster  drives  with   more
sophisticated seek mechanisms -- a cost that can be justified more easily with
TurboDOS,  since these expensive peripherals are more easily shared among  all
the users.)
TurboDOS  supports just about any kind of local network, ranging  from  simple 
implementation involving 2 computers (liked through,say, an RS-232-C channel),
to sophisticated structures with many processors sharing resources over  high-
speed  data  channels. The actual network structure is defined by  the  system
designer,  and  implemented  in  the network  driver  modules.  These  modules
constitute  what is known in network vernacular as the "physical layer";  they
control the hardware that interconnects the computers.
TurboDOS  defines  the network as being composed of *CIRCUITS* (which  can  be 
better  visualized as a cluster of nodes). A circuit may be composed of up  to
255  nodes. Further, there may be up to 255 interconnected circuits in a  full
TurboDOS system, allowing for a total of up to 65,535 total workstations in  a
TurboDOS network.
The unit of information exchange among network nodes in the *NETWORK MESSAGE*. 
This  message  is  a packet of data, containing source  and  destination  node
addresses,  byte length and other overhead, as well as the actual data  itself
(which may be a disk record, a file control block (FCB), or perhaps a block of
characters to be sent to a printer).
A  "forwarding" table may be specified in each node, allowing messages  to  be 
sent between network nodes that are not, themselves, directly connected.
One of the most common techniques that I have seen for implementing a  network 
with  TurboDOS  involves  S-100 Bus  single-board  computers.  Generally,  one
"master"  CPU is provided (to control access to disk drives, printers,  etc.),
and  one  or more "slave" processors are placed on the same S-100 Bus  as  the
master  (often these slaves have no local storage of their own  but,  instead,
rely  on  the master to provide storage. The user will see the  master's  disk
drives  as  if  they were connected to his  own  CPU.)  Typically,  high-speed
parallel-port  channels  are provided to allow network transfers  at  near-bus
speeds.  One  such system will, generally, be a circuit  in  itself;  multiple
systems may, then, be interconnected, forming a multiple-circuit network.
        Figure 1. A typical network
An  example should help tie this all together. In Figure 1, we have 2  network 
circuits  that  are  relatively independent. Each circuit  has  a  master  and
several  slaves,  as  well  as disk  drives  and  a  printer.  Master-to-slave
communication   is  through  a  high-speed  parallel   bus.   Master-to-master
communication is through a Local Area Network (LAN) interface and cable.  Note
that  slave  nodes do not have any local disk storage but,  instead,  use  the
master's  disk  drive (this will likely be a large-capacity hard  disk  drive,
segmented  into  several smaller drives, and apportioned  among  the  slaves).
Circuit 1 consists of 4 nodes: the master and the 3 slaves. Similarly, Circuit
2  consists of 5 nodes: the master and 4 slaves, 3 of which are connected  via
modems to dial-in phone lines.
Each  of the 2 masters are actually "known" on 2 circuits (their own, and  the 
other  master's)  and,  thus, have 2 circuit  drivers  within  their  TurboDOS
operating systems (and 2 network addresses, as a matter of fact).
This  system  might be part of an overall data-gathering  system  where  field 
agents phone in information to the nodes connected to modems (Nodes 2-2,  2-3,
and  2-4);  the  high-speed dot-matrix printer might be  used  to  maintain  a
"running  log"  of  these transactions. This raw  information  is  sorted  and
formatted  by programs entered by an operator at the terminal located at  Node
2-1 (the only "on-site" terminal in Circuit 2) and made available periodically
to Circuit 1 through the RS-232-C link between circuits, where service  clerks
work  at  terminals,  filling these orders. The  finished  orders  are,  then,
printed  up in the form of invoices on the letter-quality printer  located  on
Circuit 1.
Thus, most information flow between the 2 circuits will take place between the 
2  masters  (perhaps under the control of a resident process in each).  It  is
possible,  however,  to  allow  communications  between  slaves  on  different
circuits, using forwarding tables contained in each slave's operating  system.
This  might  be necessary, for example, to allow field salesmen  calling  into
Circuit  2 to make an inquiry about an order to a clerk working in Circuit  1.
Proper setup of the forwarding tables will allow this (in fact, the Turbo-Plus
enhancement  package  provides  special system functions  and  utilities  that
simplify this kind of communication).

Reconfiguring the network
Although  the physical network is defined in network driver modules,  TurboDOS 
provides  a lot of latitude in reallocating resources, using  the  previously-
mentioned  GEN  program.  Although  these  resources  are  not   *DYNAMICALLY*
changeable  (that  is  to  say: you cannot make  changes  while  the  TurboDOS
operating  system is running), it is a relatively simple matter to  patch  the
tables, and regenerate the system.
        Figure 2. Drive allocation example
An  example  should  help to clarify this. Referring to Figure  2,  we  see  2 
processors, named P1 and P2, each with local drives A and B. From the diagram,
you  can  see  that  each  processor has a drive  C,  which  is  the  opposite
processor's B drive. (These assignments are made in a table contained in  each
node's  copy of TurboDOS; this table is called the Disk Assignment Table,  and
is usually set up in a PAR file.)
        Figure 3. Allocation after regeneration
Now,  let  us consider changing that. Let us say that we want to  delete  P2's 
ability  to  reference P1's B drive, and increase P1's  available  storage  to
include P2's drive as P1's D. We simply make a few changes in each node's  PAR
file,  regenerate  each TurboDOS operating system, and we have  the  structure
shown  in Figure 3. This concept applies to other resources, such as  printers
and print queues.

Printers and spooling
Flexibility is apparent throughout the design of TurboDOS, but nowhere is this 
more evident that in the facilities available to produce printed output.
Each  processor  may have up to 16 printers defined in its  tables,  and  each 
printer  may  be accessed either locally or over the network.  Since  TurboDOS
provides a CP/M-like environment, only one of these printers may be  "current"
at  any  one  time for any one user. A utility program,  PRINT.COM,  lets  you
change the routing of your logical printer output, using syntax such as:
        PRINT PRINTER=E   (or PRINT P=E)
which selects Printer E in your local printer table. In addition, this utility 
allows  you  to  select  a  much more  flexible  form  of  printing:  *SPOOLED
PRINTING*.  (ROCHE>  Ever  heard of the "DESPOOL  (background  print  utility)
Operator's Guide", Digital Research, 1979? No? It was frequently found in CP/M
Version 1.4 and Version 2.2 advertisements...)
Spooled  printing reroutes your printer output: instead of going  directly  to 
the  printer, the output is routed to one of 16 *PRINT QUEUES*. A print  queue
is  implemented  as a set of disk files, using filenames of the  form:  PRINT-
x.nnn,  where  x  is  the queue name (A-P, corresponding to  each  of  the  16
possible queues) and nnn is a 3-digit number used to separate different  print
jobs within a queue.
Another  utility, PRINTER.COM, controls despooling of these print queues.  Any 
physical  printer may be assigned to any of the queues with a command such  as
PRINTER  E  QUEUE=C  (to  assign Printer E to the C  Queue).  A  3rd  utility,
QUEUE.COM, allows files to be manually entered into any of the various queues.
Let us tie this all together with an example: suppose your TurboDOS  operating 
system has 2 printers: Printer 1 is a fast dot-matrix printer, while Printer 2
is a slower letter-quality model (remember, either printer may be attached  to
our local network node, or to a remote node -- it does not matter *WHERE*  the
printer to be used is actually located). Assume that we have to print  several
program listings, a couple of letters, and a long report.
First,  we  will tackle the letters, since they will likely  use  single-sheet 
paper, requiring a good deal of manual intervention. The command:
gives  up  direct access to the letter-quality printer (we  must  be  careful, 
here, to coordinate access with any other network users, since direct printing
by  more  than one user will result in interspersed characters in  the  actual
printout). Now, we fire up the word-processor program, and print each  letter.
Not  so  different  from  CP/M,  so far (except  for  the  ability  to  switch
Now,  let  us tackle the program listings. We can begin to make use  of  print 
queues, here, by entering the following commands:
Now,  we have established Queue A as the queue associated with the  dot-matrix 
printer,  and  Queue B with the letter-quality printer. Now, we are  ready  to
print some listings. The command:
routes our printer output to Queue A; now, we can run our language  translator 
and  begin producing the program listings. Since our output is now going to  a
relatively  high-speed disk file (as opposed to a slow printer), the  language
translator finishes long before the first printout is complete.
In  fact, the first output file does not begin printing until  its  associated 
queue  file  is  closed (either by the  language  translator  terminating  and
returning to the TurboDOS operating system, or by a special end-print  control
sequence  from  the  console).  While  the first  file  is  printing  (in  the
background), we can run our language translator once more, to generate the 2nd
and 3rd listings. We might also decide to queue some existing disk files:
        QUEUE *.UPC ;DYQ=A
(Note  that the Q=A options specify which queue to send the file to.  The  3rd 
example illustrates queuing multiple files by specifying a wildcard  filename.
Additionally,  the ;DY portion specifies options. In this case, D causes  each
file to be Deleted after printing, and Y causes the QUEUE program to displa(Y)
the name of each file to be queued, allowing the operator to select  specified
Now, we are ready to print the letter-quality documents. The command:
switches  our printer output to the queue we have previously  associated  with 
the  letter-quality printer. (It does not matter that the files that  we  have
already  queued are still printing; they are now destined for  the  dot-matrix
printer, and changing the destination of our printer output no longer has  any
effect  on the previously-queued files.) Now, we can use  our  word-processor,
and  send  the letters and the report to the B Queue, similar to the  way  our
language translator output went to the A Queue.
At  this point, we have 2 printers running a number of print jobs entirely  in 
the background, and our console is free for new work. In addition, any  number
of network users can simultaneously queue files on the same printers,  without
intermixing printer output.
To  conclude  the discussion, I must mention that there are  many  more  print 
options  and  features  than those mentioned here; to  review  each  of  them,
however, is beyond the scope of this article.

Batch files
TurboDOS  allows  the  execution of batch-command files in a  way  similar  to 
CP/M's  SUBMIT facility, but with enhanced capabilities. The TurboDOS  version
of SUBMIT is named DO.COM; specifying DO with a filename will cause the system
to begin reading its input from the file.
DO  files  may  be  nested (ROCHE> Like SUBMIT under  CP/M  Plus...),  to  any 
reasonable depth (ROCHE> 128 levels under CP/M Plus.), merely by placing a  DO
statement within a DO file. After the subservient DO file is executed, control
returns to the superior file at the point where processing left off.
Command-line parameters may be specified in a manner similar to CP/M's SUBMIT. 
However, the parameters are referred to, in the DO file, by enclosing them  in
curly  brackets,  rather  than the dollar sign notation  of  CP/M.  Also,  the
parameters  in the DO command line may be made to contain embedded  spaces  by
enclosing them in quotes.
A handy option within the DO file allows default parameters to be filled in by 
adding  a  comma and a default value within the curly brackets.  Consider  the
following line within a DO file:
        L80 {1} {2,SYSLIB}
If  this  DO file is invoked only with Argument 1, then the  value  SYSLIB  is 
automatically supplied as the 2nd Argument.
Another  important characteristic of DO files is that they can  provide  input 
for  more than just system commands. Programs that require  interactive  input
will  receive that input from the DO file (thus, DO combines the  features  of
both  the  CP/M 2.2 programs SUBMIT and XSUB). (ROCHE> CP/M Plus  has  a  much
better and more powerful SUBMIT utility.)
DO  is somewhat faster than CP/M 2.2's SUBMIT when no command-line  parameters 
are  specified. Since there is no need to rewrite the DO file with  parameters
filled in, DO simply informs TurboDOS to begin executing the file (SUBMIT must
always write a $$$.SUB file).

TurboDOS  is  supplied with a large number of utilities, some  of  which  have 
already been described. The major remaining utilities are as follows:
AUTOLOAD  allows a user to set up command lines that automatically execute  on 
either  cold  or warm boot. COLDSTRT.AUT, the cold boot  file,  executes  only
once, when the TurboDOS operating system is first started up. WARMSTRT.AUT  is
executed at the completion of each transient program.
BACKUP  performs  a  fast disk copy. It is usable only  when  the  source  and 
destination diskettes are of the same format.
BATCH  is useful in network environments, and uses a special FIFO file  (named 
BATCH.DO)  to send a command line to a remote processor for execution.  Remote
processors  that use this facility (i.e., those which are to be available  for
batch  jobs) must execute the command DO BATCH via an AUToload file at  system
BOOT allows the system tracks of a diskette to be copied to another  diskette. 
Note  that TurboDOS allows 100% of the floppy disk space to be used  for  file
storage; however, in some implementations, the hardware demands  cold-starting
from reserved system tracks.
CHANGE  is used to safely allow removable disks (i.e., floppies  or  removable 
cartridges)  to be changed in a network environment. CHANGE.COM takes  one  or
more  drive  letters  as arguments, and aborts with an error  message  if  any
process has open files on the requested drive. If the requested drive is free,
CHANGE locks the drive until the user indicates that the disk has been changed
(any  user trying to access the drive while it is locked will receive  a  disk
error message).
COPY,  which was previously mentioned, allows files to be copied between  disk 
drives.  A  large  number  of command-line  options  make  this  an  extremely
versatile file copy and archiving program.
DELETE performs the same functions as CP/M's ERA. A command-line option causes 
DELETE  to  present each filename to be erased, and requests the  operator  to
confirm  before  deleting. (ROCHE> "The CONFIRM option informs the  CP/M  Plus
operating  system  to prompt (the user) for verification before  erasing  each
file  that matches the filespec." CP/M Plus User's Guide, Section  5:  Command
Summary, "The ERASE command".)
DIR prints a sorted directory on the screen (or, optionally, on the  printer). 
The  display  contains  a lot of the information  available  under  CP/M  only
through the CP/M 2.2 STAT command (such as filesizes and disk free space).  It
also  includes  time of day and combined size of files displayed, as  well  as
user-number specification.
DRIVE  displays information about the disk format (similar to CP/M 2.2's  STAT 
FIFO is used to create and delete the previously-described FIFO files.
FIXDIR  is a handy utility that reorganizes a disk directory. This  is  useful 
when  frequent file creations and deletions occur (especially on hard  disks).
FIXDIR  compacts  the directory, eliminates "holes", and makes  file  searches
faster. Also used to convert a directory to the hashed format, or  vice-versa.
(ROCHE>  ???  Ron  wrote "the opposite is not true" in the  "Disk  drives  and
files" paragraph...)
FORMAT  allows  a  diskette to be formatted in single density or  in  CP/M  or 
TurboDOS double-density format. It automatically calls VERIFY after formatting
is complete. (ROCHE> VERIFY marks all the "bad spots" of a disk. That's why it
is used after formatting the disk.)
MONITOR  is  the  TurboDOS replacement for CP/M 2.2's  DDT  program.  Intended 
mainly  for program patching, etc., it contains a save function as well  as  a
load  function  (this  is necessary because TurboDOS  lacks  CP/M  2.2's  SAVE
command). A number of other commands not found in DDT are present in  MONITOR.
(ROCHE> ASM and DDT were provided with CP/M 2.2. MAC and SID were professional
versions that were available separately, at a cost.)
Noticeably  lacking,  however,  are DDT's opcode  assembler  and  disassembler 
(ROCHE>  The A and L commands.), and single-step trace functions  (ROCHE>  The
TRACE  utility  of  SID.).  For program  debugging,  DEBUG  (Phoenix  Software
Associates (ROCHE> Software 2000, Inc., used their PASM to assemble TurboDOS.)
or  ZSID (Digital Research, Inc.) both work well under TurboDOS. (ROCHE>  This
is no surprise...)
RENAME  is  used  to  change the names of files. This  utility  has  a  syntax 
backward from that of CP/M. (Most people who have worked with other  operating
systems  claim that it is CP/M that has it backward. I am inclined to  agree.)
(ROCHE>  You (and them) are wrong. Demonstration: How work the opcodes of  the
(real, physical) processor? You write MNEMONIC DESTINATION,SOURCE... There  is
no  exception  to  this  rule!  So,  is  the  CPU  behaving  crazily?  Another
demonstration:  When you send dozens of different files to the same place.  If
the  destination  is at the beginning of the command line, you just  edit  the
source  specification, conveniently located at the end of the command  line...
which can be reached with one single control char!) This utility has the handy
option  of renaming by using wildcards. For example, the command RENAME  *.BAK
*.ASM renames all BAK files to ASM (a command-line option allows you to verify
any  rename  that  would  cause  an existing file  of  the  same  name  to  be
overwritten). (ROCHE> "If the file given by NEWNAME is already present in  the
directory,  RENAME displays the following message on the screen: Not  renamed:
FILENAME.TYP  file  already  exists, delete (Y/N)?" CP/M  Plus  User's  Guide,
Section 5: Command Summary, "The RENAME command".)
SERVER  has been renamed by North Star. The standard TurboDOS  distributed  by 
most vendors refers to this utility as MASTER.COM. In any case, its purpose is
to allow a slave console to act as a terminal to the master, a function useful
for running programs in the master processor.
SET is used to set and clear file attributes; SHOW displays them. (ROCHE> Just 
like MP/M and CP/M Plus...)
TYPE displays ASCII files on the console or (optionally) on the printer.
USER allows privileged logins to change the currently-logged user number. This 
is one command that I wish had been built into the TurboDOS operating  system.
(ROCHE>  Ron  ported  TurboDOS  Release 1.3. As far as  I  know,  the  Command
Interpreter of TurboDOS Release 1.4 recognizes the small form of changing user
numbers (1:), without the need of running the transient program USER.COM.)
VERIFY scans a disk for bad blocks, and locks them out.

Program interface
As you would expect, TurboDOS provides a good many additional system calls for 
the  programmer.  (ROCHE> Well, TurboDOS being a  multi-processor  version  of
MP/M,  most of them have been existing under MP/M for about 5  years...)  Non-
programmers may want to skip this section.
First of all, CP/M-compatible system calls are vectored through location 5 (as 
you would expect); versions of TurboDOS prior to Release 1.3 included extended
system  calls  vectored  in the same way. (ROCHE>  Like  MP/M...)  Recent  re-
releases  of CP/M and MP/M, however, have caused some conflicts with  TurboDOS
extended functions. (ROCHE> ???)
To  correct  this problem, TurboDOS Release 1.3 moved  all  TurboDOS  extended 
system calls to location 80 (0050H). CP/M-compatible (ROCHE> Which version  of
CP/M?  2 or 3?) system calls are now referred to as C-functions, and  TurboDOS
extended system calls as T-functions.
Resident  processes must often make system calls; they cannot call location  5 
or  50H.  (ROCHE>  ??? Why?) Two special entry points are  provided  for  this
purpose,  and must be called symbolically. They are: OCNTRY (C-functions)  and
OTNTRY (T-functions). (ROCHE> So, O means Operating system, C means CP/M,  and
T  means TurboDOS.) The calling conventions are, otherwise, strictly the  same
as  they would be for a transient program. For example, to set the DMA  buffer
address, you would use the following code:
        MVI     C,SetDMA
        LXI     D,Buffer
        CALL    OCNTRY#
A  wide range of T-functions is provided (see Table 1) for such varied  things 
as  creating  and deleting resident processes,  allocating  and  de-allocating
memory,  inter-process communications, date/time functions, extended file  and
disk  drive  requests, and more. A few of the more interesting  functions  are
described here.
Communications  channel  support  (T-functions 34-40): A  full  complement  of 
functions  allows  complete  access  to  the  optional  communications  system
(generally  implemented  in  the  form  of  RS-232-C  drivers  by  the  system
implementer).  These functions allow such actions as  send/receive  character,
read  status, get/set baud rate, and get/set modem controls. They  also  allow
the  creation  of system-independent communications software for  TurboDOS  --
something  that  is impossible with CP/M. (ROCHE> ??? And CP/NET, what  is  it
doing? It is not tied to any protocol or hardware!)
Delay  process (T-function 2) circumvents the need for software timing  loops. 
This function allows a program (or resident process) to delay by increments as
fine as the system "tick" time (generally 1/60th of a second). (ROCHE> In  the
USA. 1/50th of a second in Europe.)
Return serial number (T-function 12) returns the complete serial number of the 
TurboDOS operating system. (This function can be used to discourage piracy  by
keying the purchaser's TurboDOS operating system to your software package.)
Load file (T-function 15) uses the previously-described Load Optimizer to load 
code segments into the program area. Handy for loading overlays.
Activate DO file (T-function 16) allows a program to begin a batch  processing 
job.  (Compared  to  writing  the old backward $$$.SUB  file  with  CP/M  2.2,
starting batch jobs under TurboDOS is simple with this system call.)
Send  Command  Line (T-function 18) allows creation of  applications  such  as 
menus from assembly language programs. It does not work quite the same way  as
MP/M's similarly-named function (ROCHE> This must be a coincidence?), however,
in that the passed Command Line is not executed immediately (as it is in MP/M)
but  is,  instead,  deferred until the calling  program  terminates.  You  may
"stack" command lines by calling this function more than one.
Printer  control  functions  T-functions 27-30)  allow  complete  programmatic 
access of the printer spooling and despooling mechanisms. Function 28  (signal
end-of-print)  is  especially  handy, since it allows a queued  print  job  to
actually begin printing.
User-defined  function  (T-function 41) belongs to the user, for  any  purpose 
that  he desires to write code for. It can take full advantage of the  network
for  communications between processors. To implement this function,  you  must
write  your  function  in  a module that defines  the  public  symbol  USRFCN;
register-passing  conventions are described in the "TurboDOS Release  1.4  Z80
Programmer's Guide". Once the function is in place, your applications  program
may communicate with it simply by calling T-function 41.

No  software  evaluation  can be considered complete without  a  look  at  the 
documentation  supplied with the package. In the case of TurboDOS, I  have  to
rate  the documentation effort outstanding! (ROCHE>  Interesting.  Apparently,
not everyone thinks like you. "Many features of TurboDOS go underutilized  (or
totally  ignored) due to the difficulty in deciphering the manuals." and  "the
manuals  are  indescridably bad." This opinion was published in  nothing  less
than  the  "ACM SIGSMALL Newsletter"! Reference: Vol.10,  No.3,  August  1984,
p.24, "The TurboDOS Operating System", Keith Bierman.)
Three  manuals are provided with the Z80 TurboDOS operating system:  a  User's 
Guide, a Z80 Programmer's Guide, and the Z80 System Implementer's Guide.  Each
includes  a  table  of contents; the System Implementer's Guide  is  the  only
manual lacking an index.
The  User's  Guide  begins  with basics, and  takes  the  reader  through  the 
gradually  more  complex subjects of files, disks, printing,  and  processing,
concluding  with  a  summary of the entire set of 35-odd  utilities  that  are
provided with the TurboDOS operating system. The language is "gentle" and very
The  Programmer's  and Implementer's Guides are understandably  more  complex, 
since they deal with subjects that are technical in nature. They are complete,
and  provide  sufficient information to enable the programmer to do  his  job.
(ROCHE> Again, Ron implemented TurboDOS Release 1.3. Release 1.4 adds the 8086
programmer's Guide and the 8086 Implementer's Guide. TurboDOS thrived when  it
was  written in Z-80 assembly language for S-100 Bus systems, and  disappeared
when it was rewritten in the C language for the IBM PC...)

As  you see, TurboDOS provides powerful facilities for both the user  and  the 
programmer.  After more than 3 years on the market (it was first  released  in
April  1981)  (ROCHE>  So, MP/M had already been existing  for  2  years  when
TurboDOS appeared... Guess which is the chicken? Which is the egg?),  TurboDOS
is  still being continually refined. (By the time you read this,  Release  1.4
should  be  available.  This new release will  feature  full  Intel  8088/8086
compatibility  at both the slave *AND* the master level, as well as a  PC  DOS
emulator.)  (ROCHE> Emulating MS-DOS Version 1 under TurboDOS on a  S-100  Bus
system? Vade Retro, Satanas!)
I  have recently obtained a Mega Z-80 system, featuring  512K  bank-selectable 
RAM  and  27 *MEGABYTE* Winchester hard disk drive, for which I plan to  do  a
full  master-to-master implementation of TurboDOS (complete with RAMdisk).  As
"Microsystems"  magazine  expands its TurboDOS coverage, I hope to  provide  a
follow-up article on this project, as well as a review of Turbo-Plus, and  (if
there  is  sufficient  interest) a tutorial  on  TurboDOS  implementation  and
programming  technique. (ROCHE> This article was the last one written  by  Ron