ZSDOS, Anatomy of an operating system by Harold F. Bower, Major, US Army Signal Corps. BSEE, MSCIS, Ham (WA5JAY), avid homebuilder (starting with 8008 running SCELBAL). and Cameron W. Cotrill, Vice President, Advanced Multiware Systems; specialist in "impossible" real-time hardware and software systems. It has been many years since Digital Research released CP/M 2.2, and much has changed since that time in the speed, capability and flexibility of 8-bit general purpose microcomputers. CP/M is one of the few operating systems that runs on a wide variety of hardware, and is widely supported. Other than the current popularity of MS/PCDOS, Unix and its derivatives have been the closest competitors to the universality of CP/M, with only the Unix family being hosted on more hardware types. This hardware independence is perhaps the single strongest point of CP/M, and we venture to guess that more than a few PCDOS users have wished for this kind of flexibility. In recent years, however, better and faster 8-bit hardware has been more available, and has fostered vastly improved software such as BackGrounder ii, DateStamper and the ZCPR 3.x series of Console Command Processors. On such systems, CP/M 2.2 has been weighed in the scales and found wanting. The only widely accepted replacement for CP/M 2.2 is the ZRDOS family which added only slight improvements to the basic Digital Research structure. CP/M 3.0 (also known as CP/M Plus) added some new features, but was not easily retrofitted to existing systems, and did not achieve the popularity level of CP/M 2.2. ZSDOS is our answer to what we perceive as a stagnation forced on the 8-bit computer community by a restrictive suite of Operating Systems. ZSDOS is a new BDOS replacement written in the spirit of the popular ZCPR command processor. Its roots come from P2DOS Version 2.1 by HAJ Ten Brugge of the Netherlands. P2DOS made significant strides in overcoming some of the limitations of CP/M 2.2 with such features as larger disk and file sizes, built-in CP/M Plus compatible file date stamping, and a Read-Only Path within the DOS for opening files. Use of attribute bits was expanded to include a modified recognition of the Plu*Perfect PUBlic bit and support for the Archive bit. Despite the number of nice features adopted by P2DOS, several other desirable ones were not included. We and several others including Benjamin Ho (SUPRBDOS), C. B. Falconer (DOS+25), Carson Wilson (Z80DOS, ZDDOS), have sought to extend the functions of P2DOS by adding features and fixing bugs. When BackGrounder ii with its task-swapping and cut and paste features was released, we found that even the modified P2DOS derivatives were unusable due to the very tight linkage needed between Backgrounder ii and the operating system. In independent contacts with Bridger Mitchell concerning the possibility of recognizing P2DOS as an "authorized" DOS for BackGrounder, we finally came to the realization that P2DOS was not stable enough. Seemingly everyone had source code and was changing it. Additionally, the added features were not much more beneficial than those offered by the ZRDOS family of operating systems. Until Bridger suggested that we pool our resources, each of us were embarked on different paths. Cameron's primary thrust was directed at refining the fundamental P2DOS architecture and adding compatibility with Plu*Perfect's tools. Hal concentrated on correcting bugs, optimizing for speed and building tools to support the P2DOS (CP/M Plus compatible) file date stamping method. Carson Wilson joined the group because of his efforts to embed the entire DateStamper module into Z80DOS. ZSDOS was born of our decision to join forces and develop a complete DOS. The result was a pair of compatible DOSes; a full ZSDOS with complete capabilities, and ZDDOS which sacrifices some features for the integral DateStamper support. ZSDOS was designed from the beginning to be compatible with existing applications. This sounds wonderful in theory but is no easy trick. To follow accepted standards, they must first be found, then understood to a degree sufficient to foil Murphy. Where no standards existed, a great deal of thought was given to future growth directions for CP/M compatible systems and how these would affect added functions. The first problem encountered was that there are no less that three BDOS standards; CP/M 2.2, CP/M 3.0 and ZRDOS. With much of the community using ZRDOS 1.7, we decided that it would be the final arbitrator of compatibility from a DOS call perspective. Functions not present in ZRDOS that resembled CP/M 3.0 functions would be similar in calling parameters and use the same function numbers. Much of the effort in ZSDOS involved defining the "real" standards. In the end, we arrived at what we hope are intelligent additions that will allow further evolution of CP/M compatible systems rather than hindering future growth. In compatibility, ZSDOS rates very highly, though not perfect. First, ZSDOS requires that the system's BIOS preserve the IX register. This may present problems for some Osborne and Bondwell owners. Secondly, ZSDOS forces applications programs to "play by the rules" when dealing with file control blocks. Unlike CP/M 2.2 and ZRDOS, but like CP/M Plus, ZSDOS does not create or open new extents until they are really needed. Programs that attempt to second guess the DOS by looking at the record count field of the FCB and opening their own extents can get into trouble due to the 80H value present after the last record in the extent is read or written. In over a year of extensive testing with hundreds of CP/M and Z System applications, only two such programs were found; TDL's linker and MicroPro's ReportStar 1.1. In defense of ZSDOS, neither of these programs will run under CP/M Plus either. When anything is altered within a DOS, there is a good chance of introducing more bugs than features. In applications programs, bugs are normally an annoyance. In a DOS they are a disaster (witness version X.0 of any Microsoft DOS if you doubt this assertion). DOS calls, therefore, must work as advertised, and any side effects of the calls must be properly documented. The DOS features should also be logically consistent. One of the problems with P2DOS is that it attempted to alter long-standing conventions pioneered by Digital Research and Plu*Perfect Systems. While there were good arguments in favor of the conventions used in P2DOS, they are inconsistent with what we viewed as a cohesive set of DOS standards. Several key philosophical concepts forming the basis for ZSDOS have already been mentioned - compatibility with existing systems and enhancements that make sense. The overall goal of ZSDOS is that the DOS must not "get in the way" of a user unless absolutely necessary. By getting in the way we mean that the DOS does not respond in the desired manner, or prevents seemingly logical actions from being properly executed. Any time a command file (e.g. editor, assembler, etc.) is executed from one drive/ user area and not another, DOS prevents it by getting in the way. When DOS requires a user to tell it that a disk has been changed, DOS is getting in the way. When a user can't tell which file is the latest version, DOS is getting in the way. The second guiding concept in ZSDOS is that the operating system is a tool. To this end, ZSDOS has a multitude of options never before available to the user. These options can be configured on the fly from the command line, command scripts, or interactively. In all cases, ZSDOS responds instantly to these changes. The following sections provide details on changes that ZSDOS brings to the user of 8-bit computer systems. Unless explicitly stated, references to ZSDOS also include ZDDOS. The topics assume a passing familiarity with CP/M 2.2 and ZRDOS. AUTOMATIC RELOG OF CHANGED DISKS. One of the first areas tackled in the development was automatic accommodation of changed disks. Benjamin Ho was one of the first to attempt a fix to P2DOS in his SUPRBDOS which implemented a changed disk detection method consisting of a flag which was set when the directory checksum of a disk didn't match the previous value. Relogging was then performed at a later time. This approach has been used in several systems (Z80DOS, SUPRBDOS, and P2DOS+) and seems to work as intended. Cameron had a problem with this method - the DOS relinquishes control without the problem being corrected. This put the DOS in an invalid state, and breaks a guiding principle of real-time control systems - NEVER leave the system in an undefined or invalid state! ZSDOS uses a more difficult approach that relogs disks at once when a change is detected. After slogging through the existing code, it became apparent why no one else has succeeded in finding a better method - the control flow is very difficult to follow, and it is nearly impossible to retrace the code, relog, then pick up where the change was detected. Cameron, having accomplished "impossible" programming tasks before, once again displayed his stubborn streak and succeeded in correcting this flaw by using a tool normally reserved for high-level language programmers: recursion. This code was one of the first major modifications to P2DOS and has now been running successfully for nearly two years. While developing ZSDOS, our original goal was to give users a warning that a changed disk had been detected only if ZSDOS was ready to write to an already opened file. It turns out that many programs successfully open more files than they close. Thus, counting opens and closes was not a viable solution. ZSDOS would have to track every FCB used by user programs in order to stand a fighting chance of sorting out whether or not to warn. This sloppy coding style seems endemic to the entire Personal Computer programmer community, and causes severe problems, particularly in multiuser and multitasking systems. ZSDOS consequently warns the user every time it detects a disk change. In the spirit of not "getting in the way", however, the message can easily be suppressed with the disk being automatically relogged. A little extra head activity on the drive will be the only noticeable effect. TIME AND DATE STAMPING. Probably the most desired, yet least standardized, DOS feature is time and date stamping of files. Within the 8-bit CP/M community there are currently three known methods, all mutually incompatible. The closest to a universal standard at this point is probably Plu*Perfect's DateStamper(tm). This is an add-on time/date stamping system which offers no DOS level functions, but can be installed on practically any CP/M compatible machine, with or without a real-time clock. It is also the most complete stamper available featuring times and dates of file creation, modification, and last access. DateStamper is well supported with file copy programs, directory and file utilities, disk catalog programs, etc. Finally, it consumes only one directory entry while the other two stamp methods consume 1/4 of your available directory space. On the negative side, it is slower than the other methods due to the need to open, update, and close the datestamp file when storing the stamp information. The other two known methods, P2DOS style (compatible with CP/M 3.0) and DOS+25, are very similar. Both use the fourth entry in each directory sector to hold the time and date information for the three file entries in the sector. Right away, one-fourth of the directory is consumed. While this may not be a problem for diskettes or hard drives that have 128 or more possible entries, it is definitely a problem with the 64 entry limit of systems such as the Kaypro. These two stamp methods are quite fast and add very little to DOS overhead because the directory entry is already in position when stamps are applied. The two methods differ only in the format of the stamps. The CP/M 3.0 type supports times and dates for Create and Modify only, while DOS+25 supports times and dates for Last Access and Modify, and dates only for Create. A disadvantage is that both of these schemes require an additional BIOS vector to function. While ZSDOS can, theoretically, manage nearly any type of time and date stamp construct, we have only implemented DateStamper and P2DOS schemes. This versatility is accomplished by placing method specific and clock code in BIOS or other protected memory, and by vectoring all DOS time stamp functions through a table in the configuration area of ZSDOS. By inserting addresses of the method specific service routines in this table, ZSDOS maintains control of program flow, calling stamp routines as needed. Vectors are currently provided for Get/Set Time, Get Stamp, Put Stamp, Stamp Create, Stamp Access, and Stamp Modify. Only the routines needed to support the required stamp method need be implemented. For example, all six vectors must be set in a full DateStamper system with ZSDOS, while only the Get/Set Time is required in the ZDDOS version. All but the Stamp Last Access vector, which is disabled, are needed in a P2DOS stamping system. ZSDOS does most of the required housekeeping in all stamp related calls to simplify the implementation. When external time stamp functions are called, ZSDOS has already loaded the directory buffer with the record containing the required entry. If a directory write is required, the drive has already been tested for Read/Write status. ZSDOS passes all necessary information to the external routines which are responsible for getting the time (if required), converting the stamp between universal format and target format, and placing the stamp where it belongs. Only in the case of stamp last access or put stamp is the BIOS actually required to call the write directory record routine. The external routines all return a status code to notify applications/users of the operation success or failure. When portions of the stamping scheme have been disabled, or have not been loaded, an error status is returned from dummy routines addressed by the unimplemented vectors in ZSDOS. To support file stamping in a coherent manner, ZSDOS has adopted four new function calls. Functions 98 and 99 are Get Time and Set Time respectively. A six-byte packed BCD construct is used to pass two-digit year (arbitrarily decided as 1978 to 2077), month, and day as well as hours, minutes and seconds values. Functions 102 and 103 are the Get Stamp and Put Stamp calls respectively. Key to the way ZSDOS handles these functions is that we have defined a format that is independent of the stamping method and can handle all present, and probably any future stamping method. Stamps are defined as three fields of five bytes each. Each field is comprised of packed BCD digits for Year, Month, Day, Hour and Minute, in the same manner as the Time returned from the clock, less the Seconds byte. Any conversions needed between this "Universal" format and the native stamp format is performed in the external stamping module. Since this is the native DateStamper format, ZDDOS operates directly on the data. We hope that this format will provide a meeting ground for the diverse methods and provide a badly needed standard applications interface. The six byte BCD format was adopted (after considerable debate) because it simplifies the code for applications that deal with the stamps. The order of the stamp lends itself readily to sorting by date. The BCD format makes conversion to Ascii display values a snap. The fact that it is the same format as the de- facto CP/M 2.2 standard, DateStamper, was also a key factor in the decision. ENHANCED ERROR HANDLING. Error handling in most CP/M compatible operating systems left much to be desired. CP/M 2.2 has been infamous for cryptic error messages. While ZRDOS attempted to be somewhat less so, it required users to look up error numbers in the manual (or via an online utility) to decipher the meaning. CP/M 3.0 for the first time provided truly useful error messages, reporting errors in something approaching plain English. Feedback includes the type of error, the function number which triggered the error, the drive in question, and the name of the file (if one was used). P2DOS and its derivatives adopted these messages but in P2DOS even Bad Sector errors which could be ignored under CP/M 2.2, caused an immediate warm boot. ZSDOS adopts the CP/M 2.2 recovery methodology added in most of the enhanced versions of P2DOS and continues the concept of plain English error messages. CP/M 3.0 also has a another very desirable feature which was never incorporated in CP/M 2.2 compatible BDOSes. With a new function 45, all errors can be returned to the application program including Select errors and Read Only errors. In this mode, errors return a unique code revealing the exact cause. Applications can even tell CP/M 3.0 to suppress all DOS error messages. This seemed to be a highly desirable feature, so we added it to ZSDOS. ZSDOS also reverts to strict CP/M compatibility in another obscure area, not following the path taken by ZRDOS. ZSDOS maintains a vector table for errors in the same location used by CP/M 2.2. This allows the few programs that patch the table, such as bad sector lockout programs, to operate properly. FUNCTION 37 FIXED. Probably the most troublesome of all functions provided by CP/M 2.2 was function 37. Many wrongly assumed that function 37 would relog a selected disk after performing the stated function of resetting (unlogging) all disks. It didn't! This anomaly caused many blasted disks and infuriated users. In accordance with the ZSDOS spirit, it seemed reasonable that if the default drive was logged out, it should be automatically relogged after a function 37 call. This is now the case with ZSDOS. GLOBAL AVAILABILITY OF FILES. One of the most frustrating aspects of most microcomputer operating systems is context sensitivity. The classic model for computer operating system file management - that of the ordinary filing cabinet - neglects one very important point. The phone, the pencils and pens, and the myriad of other tools found on most desks are not kept in the filing cabinet! Yet, on a vast majority of our file management systems they are. Clearly, some distinction should be made between tools and data if the operation of the system is to approach the intuitive level. One should be able to log into an area where data resides and have all the system tools available - without the need to either remember where they are or inform each and every application where it lives. The ZCPR family of Console Command Processor replacements made tremendous strides in freeing user dependence on strict drive and user area specification by creating a Search Path that the Command Processor uses to find Command files. Users were thereby able to use files spread across the computer's complement of drives with the privacy of user areas by specifying a Path consisting of a list of drive and user numbers. Unfortunately, the Path became inactive once command programs began executing unless the application program is specifically written to locate and use the Path. Programs using overlays (including most of the programs for which we bought computers in the first place) printed nasty messages about missing overlays and dumped us unceremoniously back to the Command Processor when we relied on Path access. Thus, Path alone wasn't the answer to context sensitivity. In 1984, Bridger Mitchell and Derek McKay of Plu*Perfect systems published the PUBlic patch for CP/M in Dr Dobb's Journal. With this patch, any file having the F2 bit (most significant bit of the second character of the file name) set could be accessed from any user area on the disk from BDOS, provided that it was specified with an unambiguous name. This solved the overlay problem when logged on the same disk as the overlays. It was also fast with only one scan of the directory required to locate the file! However, PUBlic files disappeared from the directory - at least according to directory utilities that didn't know how to look for them. Thus PUBlic was a major step forward but again was not the total solution. P2DOS was the first real attempt at a coherent solution. Path was implemented, along with a modified form of PUBlic from within the BDOS. By setting F2, a file was made Public, just as with the CP/M patch. By setting the system bit, Path was allowed to find the file. Thus, the user had complete control over the method of accessing files. Both Public and Path accesses were read only, and Path only worked for file opens. Public files even appeared in directories! Both limitations were reasonable, but there were bugs. The DOS routine that checked for file read only status had several serious bugs that prevented erasure of files when it should have been allowed by the Plu*Perfect definition. Also, due to the way the erase routine was implemented, erased Public files continued to be found on directory scans! Third, strange file R/O errors would randomly occur if the last file in a directory was declared Public. Finally, if ZCPR's Path was used, the entire Path would be walked N^2 times if the file was not found! ZRDOS attempted a different solution by providing a mechanism for declaring complete directories Public. A map is maintained of disks containing Public directories and user numbers declared Public. This arrangement is best visualized as a grid, with user numbers on one axis and directories on the other. Wherever the Public declarations for drive and user intersect on the grid, all files in the associated directory are Public. As with Plu*Perfect PUBlic, all Public files disappear from directory listings. Since this means everything in the directory, entire directories appear empty! Since access is R/W, accidental erasure or overwriting of files can be a real problem. From a performance aspect, it appears that one disk directory scan is required for each user area declared Public. Thus, considerable time overhead may be required in finding Public files if more than one user area is declared Public. The fact that a PUBlic patch for ZRDOS has been developed bespeaks the fact that ZRDOS hasn't found the magic combination either. Our approach in ZSDOS was to build on P2DOS's framework and remove the idiosyncrasies and bugs. The P2DOS approach had several very strong points. The access mode of the files was totally under the control of the user on a per file basis (unlike the per directory basis of ZRDOS), with only one directory scan per drive required, and P2DOS used two de-facto standard structures: Path and PUBlic. After many gyrations, we finally settled on the "best" definitions for Public and Path. For a start, we allow run-time configuration of the ZSDOS access modes - of which there are five in ZSDOS and two in ZDDOS (Path being sacrificed for the integral DateStamper)! Though these five modes are somewhat contrived, they serve to provide a way of understanding the options offered by ZSDOS which may be set on installation and altered on line at any time. The first access mode is the default mode. This is the way a standard CP/M 2.2 system accesses files. If the file is not found in the logged drive/user area, an error is returned. No other attempts are made to find the file. ZSDOS always tries this access mode first regardless of the access options enabled. This prevents files or entire directories from "disappearing" on the unsuspecting user. Wildcard file specifications are only allowed for this mode, not for any other. The second mode is the Path Directory Access mode featured only in the full ZSDOS. A search Path (which may be a ZCPR3 Path), an internal three element Path or a user defined Path is scanned to find the file. In this mode, all files in any directory along the Path may be located by using an unambiguous file name. This mode is similar to the ZRDOS Public mode. The third access mode is the Path File Access mode, again only contained in the full ZSDOS. As in the Path Directory mode, the DOS Path is used to search for files. This mode, however, requires that the SYStem attribute bit be set for the file to be found. In the Path File Access mode, the user has more control over how particular files will be accessed. Entire directories need not be made globally available, just those files with the SYStem attribute bit set. The fourth method is the Public access mode featured in both the ZSDOS and ZDDOS versions. This mode follows the Plu*Perfect PUBlic definition and requires the F2 attribute to be set to find the file. Unlike the original Plu*Perfect patch to CP/M 2.2, Public files are "visible" if you are logged into the same drive and user area as the file. The Public Access mode is very efficient for finding unambiguously specified files, correctly locating them on the first disk directory scan. One precaution to be observed with Public, however, is that only one file of the same name is permitted for any given disk. ZSDOS comes with appropriate support tools to enforce this rule. The fifth method is called the Combined Access mode. As in the other modes requiring a Path, it exists only in the ZSDOS version. Rather than being a distinct mode, it is selected by simultaneously setting options so that either Public or Path can access files. ZSDOS first uses Path to select a drive, then locates Public files on that disk in the first directory scan, regardless of the user area indicated in the Path. File access time is thereby significantly reduced for systems where files are spread over several drives and user areas. One of the thorny questions we had to deal with was whether to restrict access of Public and Path files to read only. The original Plu*Perfect definition of PUBlic allowed writes, while P2DOS did not. After many discussions with Bridger Mitchell and others, we decided to allow read/write access to both Path and Public files, but we didn't stop there. Many users are understandably wary of the accidental file erasure or overwriting possible with both Path and Public. To accommodate these users (we number ourselves among them), ZSDOS allows user selection between Read/Write and Read Only file accesses. As with most ZSDOS features, this selection can be set or changed at any time. The restriction to Read Only does not affect access to files in the currently logged drive/user area. Path access is necessarily restricted to the Open File function in order to prevent global chaos. Once successfully opened, the file will always be found again if the application doesn't alter FCB+0 and FCB+13. Actually implementing a writeable Path turned out to be one of the biggest compatibility problems we faced in the design of ZSDOS, and it was one of the last major features to be added. Formally defining a use for the byte at FCB+13 marks a departure from the accepted definitions of "undefined" and "reserved" in previous DOSes, but provides an upward compatibility with new system components such as ZCPR Version 3.3 and later. Also, providing the user with access to the F7 attribute bit to determine whether files were found by Path and/or Public is another deliberate step in providing software developers with additional tools to write responsive programs. USER NUMBER STORAGE IN THE FCB. In making the Path writeable, we had to break new ground with ZSDOS. While most ZSDOS features are refinements of existing ideas from other DOSses, the concept of user number storage in the FCB is borrowed from ZCPR Version 3 and is new for a DOS. As explained above, Path is only active in ZSDOS on file Opens, and only resolves the drive containing the file. Unless the Public bit on the file is set or we are logged in the right user area, subsequent accesses to the file will fail. Our answer to this dilemma is to have ZSDOS keep track of the user area in which the file was found using a trick from ZCPR3. Version 3.0 of ZCPR began to use the previously "reserved" byte at FCB+13 to store the user number of files several years ago. This byte, known as S1 in CP/M 2.2 and ZRDOS, was listed as "reserved" but unused until ZCPR began using it when parsing file specifications. ZSDOS also uses this byte to store the user number for the file. Simple? Far from it! Problem #1 - how do you distinguish between a valid user 0 and an FCB from an application that knows nothing of users and sets this byte to zero because the Digital Research documentation said to? The answer is fairly simple; use a bit as a user valid flag since only 5 bits are required to hold user numbers. Just check this bit. If it's clear, DOS has only to place the current user at this location, set the bit and the problems go away..right? If only life were this easy! There is a little known corollary to Murphy's law which states that Murphy is an optimist! We can attest to its validity after solving this problem. Digital Research did not specify that the S1 byte should be initialized prior to file opens. Consequently, many programs reuse FCB's without bothering to clear the S1 byte. When these recycled FCB's are used to call ZSDOS, the (usually wrong) user number is already resolved in the FCB! After much head scratching and experimentation, only one method provided the necessary backward compatibility. The user number in S1 is ignored on file opens UNLESS an application explicitly says that it knows about user numbers, and wants to work with them. We call these ZSDOS application programs, and they signal their presence by setting the BDOS error mode before executing file access commands. Pseudo code for this modified operation is: SELECT DRIVE FROM FCB: IF there's a "?" in FCB+0 GOTO function 14 (FCB+13 not altered or examined) ELSE SELECT drive from FCB IF D7 of FCB+13 is clear Get default user OR with 80H Place in FCB+13 ENDIF GET FCB+13 AND with 7FH Store in FCB+0 for SEARCH ENDIF SEARCH: (does not use FCB+13 - user is in FCB+0 at this point) IF file not found AND it's NOT open a new write extent Clear bit 7 of FCB+13 ENDIF So long as an application doesn't fiddle with FCB+0 to FCB+13, after a file open, this method works very well. For applications that do, logging in where your data is and using explicit DU: specifications to grab data from other drive user areas (just like you've been doing all along) will make even these perform correctly. A shining example of a program that is ill-behaved in this manner is MLOAD. Note that the access modes in ZSDOS are primarily designed to load applications and overlays - not find data files. By now, the reasons for this design should be clear. While there is nothing in the design of Path and Public as implemented in ZSDOS to prevent fetching data, our primary concerns were in backwards compatibility with programs that insist on altering FCB's once files have been opened. FAST RELOG OF HARD DISKS. Another enhancement provided by ZSDOS is fast relog of fixed disks. This again is simple in concept, but if all potential problems with relog are considered, things get more complex. In a normal CP/M system, every time a disk is reset, DOS clears its bit map showing what blocks on the disk are allocated. When the disk is logged in, the allocation vector is rebuilt by scanning the entire directory. This takes time, particularly on large hard disks that have 1,024 or more directory entries. When a non-removeable media drive such as a hard disk is present, the allocations do not change. Therefore, clearing the allocation vectors and scanning the directory can be avoided after the initial selection. DOS has all the information it needs to determine whether a disk contains removable media or not. The disk parameter header returned to DOS after a BIOS select contains a pointer to a scratchpad area known as the Work Area for Changed Diskettes (WACD). Each disk with removable media must have a WACD. If this pointer contains 0, the drive by definition contains non- removable media. So far, so good. All DOS has to do is build a vector defining which drives in the system are fixed disks and avoid relogging those drives. Now for another Murphyism. First, it is not always true that allocations won't change without DOS's knowledge. Any time the BIOS is directly manipulated, it can change disk allocations without giving DOS a clue. Examples of programs that do this are PACK, PUTDS, and PUTBG. Clearly, a method of signaling DOS to rebuild the drive allocation is required. Fortunately, ZRDOS (starting with V1.5) defined such a method. When a drive is logged out using function 37, the hard disk login vector is also cleared for that drive, forcing the allocation vector to be rebuilt. Now for the worst problem with the fast relog. Some BIOSes such as the Advent TURBOROM BIOS for Kaypro and the AMPRO BIOS support remapping of logical drives. For example, assume that at boot time, disks A through D are floppies and F through I are hard disks. On one of the BIOSes mentioned above, you could tell the BIOS to swap drives so that A through D are the hard disk and F through I are floppies. Since this is a BIOS function, DOS has no idea what has happened behind its back. If BIOS swap programs would reset these drives with a function 37 call, all would be well. Unfortunately, they don't. Now the compatibility issue raises its head again. We can't expect all the swap utilities to be rewritten or patched, nor do we want to depend on the user invoking custom programs such as RELOG or DSKRST. If drives can be swapped, DOS needs some method of discovering this and coping with it once discovered. The method chosen, while not perfect, provides protection in all but one rather unusual case. Since DOS knows that a WACD pointer can tell which drives are fixed and which are not, this information is combined with the state of the hard disk login vector to tell if BIOS has played games behind our back. Pseudo code for this procedure is: IF WACD indicates hard disk IF it's already logged in as a hard disk EXIT ELSE Log in as hard disk and build allocation ENDIF ELSE it's removable so IF it was logged as a hard disk before Clear all hard disk allocations ENDIF Build allocation vector ENDIF Those who looked over this carefully have probably discovered the one problem ZSDOS can't detect; the case of two hard disks being swapped. In all of our head scratching, we couldn't think of a simple, reliable method of doing this (if you know of one, let us know!). However, this is a rare situation and ample warning is given in the ZSDOS documentation. To be compatible with ZRDOS function conventions, the hard disk login vector can be examined using function 39. RUN TIME CONFIGURATION. The FLAGS byte originated in P2DOS has been extended in ZSDOS to allow more complete user control over the DOS. Currently, bits in the FLAGS variable control whether Path and Public are enabled, what Public mode is selected, whether the Fast Fixed Disk Relog is used, and whether the disk write protect buffer is flushed by a warm boot. In addition to setting default conditions for these parameters during installation, they can be dynamically altered with a supplied utility, or by applications programs using the new functions 100 and 101. These two functions Get and Set the FLAGS respectively in a standard and published way. While FLAGS is currently a BYTE value, it is defined and passed as a 16-bit WORD value with the upper byte set to zero. Future expansion is thereby accommodated with minimum changes to defined parameters. There should be no more need to use undocumented patches so commonly found with CP/M 2.2 and ZRDOS. EXPANDED ATTRIBUTE SUPPORT. Attribute bits are the Most Significant Bits in the name and type of files used in file specifications. They are denoted by "F" for file name, and "T" for file type, and a number for the specific byte in the field. Where CP/M recognized only two attribute bits, ZSDOS supports six of the possible eight. The Read Only (T1) and SYStem (T2) bits are retained with their original definitions. The popular Archive bit (T3) is supported as well. The Archive bit is automatically cleared by DOS when files are created and written to, and set by many file utilities such as ARCHIVE and BU. Attribute F2 is used to identify Public files in accordance with the Plu*Perfect standard covered above. Additionally, attribute F3 is used with the DateStamper file stamp method to tell ZSDOS not to update the Last Accessed time field. Finally, attribute F8 is used to show that the file is restricted to users with Wheel access privileges. ENHANCED WRITE PROTECTION. Protection against inadvertent writes has been increased in both areas of disk and file. Function 28 may be used to declare an entire disk as Read Only. In both CP/M and ZRDOS, this status reverts to Read/Write on a Warm Boot. Under ZSDOS, an option exists to declare the Read Only vector as permanent. In this mode, Read-Only Sustain, only reloading the DOS (or turning off the R/O sustain bit in FLAGS, then warm booting) will restore the drive to Read/Write status. File write protection has also been strengthened by methods related to the added ZSDOS features as well as retaining the old Read Only attribute (T1) bit. Prohibiting writes to Path and Public files is another method previously described. The final method to protect files is by using another concept from ZCPR, the Wheel Byte. We added a vector to the configuration area of ZSDOS which may be set to any arbitrary address, including a ZCPR Wheel Byte to control file writes. ZSDOS follows the same conventions as ZCPR where a null (zero) value in the Wheel byte means that the user is not a "Wheel" and cannot perform certain privileged activities, including erasing or writing to files marked with the Wheel Attribute (F8) bit. Disabling the Wheel protect feature of ZSDOS has the effect of granting full access to the user by setting the vector to a non-zero value. REVISED CONSOLE I/O. CP/M originated at a time when the Teletype Model 33 was a mainstay console for computers. The vast majority of terminals are now video based, and do not need the teletype editing sequences. We therefore decided to follow the lead of ZRDOS and many P2DOS hackers, and change the interface. Thus, ZSDOS no longer supports Control-E. The Rubout (7FH) and Backspace (08H) characters are both treated as destructive backspaces in function 10, Read Console Buffer. This was done in a way that does not require patching of such programs as WordStar. For the benefit of bulletin board operators, Control-U is synonymous with Control-X since the latter is a special character in many protocols. Also for remote operators, Control-R (retype line) has been retained in the full ZSDOS. ZDDOS sacrifices this feature to provide space for the embedded DateStamper. Function 6, Direct Console I/O, was also enhanced with the addition of a Get Console Character function. This operates as function 1 except that no character checking (such as Control-C Warm Boot trapping) is performed. The code was also revised to use a one character type-ahead buffer in a manner that permits free mixing of function 1 and 6 calls in a totally reliable manner. OTHER FEATURES AND TRADEOFFS. In addition to the features already mentioned, ZSDOS supports the ZRDOS return DMA pointer function (function 47), and a ZSDOS return version call (function 48) which is a logical extension of the ZRDOS call. ZSDOS is also compatible with the re-entrancy requirements of ZRDOS 1.7 for rudimentary multi-tasking support such as that required in some Input-Output Packages for ZCPR 3. ZSDOS features larger disk and file sizes by logically and transparently extending the original CP/M constructs. Files may now be as large as 32 Megabytes with random access files consisting of as many as 262,144 logical records. Disks may contain 1,048,576 kilobytes, or one gigabyte! True to the original goals, ZSDOS is fully compatible with the current suite of advanced tools such as BackGrounder ii. While an overlay is provided for existing versions, newer revisions will automatically recognize ZSDOS and permit direct loading. We also concentrated on providing a complete repertoire of support tools and utilities to take control of the various features. Installation tools and procedures are provided for overlaying ZSDOS onto a MOVCPM image, installing ZSDOS with NZ-COM, XBIOS, and Plu*Perfect's JetLDR. Tools are provided for: Directory listing of files with date stamps added by DateStamper, P2DOS, and DosDisk; file copying and archiving with date stamp preservation; Path manipulation; and run-time tailoring of all ZSDOS options. Additionally, the full set of over 40 clocks recognized in the Plu*Perfect library (as well as new drivers for the Ampro Little Board, several SB180 clocks, and the Oneac ON!) are supported with easy-to-use interactive installation tools. Now, how did we get all this into a DOS that originally had only 7 bytes left? Needless to say, nearly every trick in the book was used (and some we have NEVER seen in any book!). This gave us some room, though much of the effort was still slogging line by line through the code in tedious manual optimization. Both of us are somewhat proficient in code crunching (Hal having done a thesis on optimizing compilers and Cameron having used Z80's for a number of years in real time control systems). It took the best efforts of both of us to chop things down to size. What we missed, Bridger Mitchell, Joe Wright, and Carson Wilson found in their review of the code - but it wasn't much. Some details of this effort will be covered in the next part of this article along with some performance results and code fragments to show how to use the advanced capabilities of ZSDOS.