SK*DOS (R) (formerly called STAR-DOS) LEVEL I USER'S MANUAL Peter A. Stark Copyright (C) 1984, 1985 by Peter A. Stark and licensed to Star-Kits Software Systems Corporation P. O. Box 209 Mt. Kisco, N. Y. 10549 All rights reserved All Star-Kits computer programs are licensed on an "as is" basis without warranty. Star-Kits Software Systems Corp. shall have no liability or responsibility to customer or any other person or entity with respect to any liability, loss or damage caused or alleged to be caused directly or indirectly by computer equipment or programs sold by Star-Kits, including but not limited to any interruption of service, loss of business or anticipatory profits or consequential damages resulting from the use or operation of such computer or computer programs. Good data processing procedure dictates that the user test the program, run and test sample sets of data, and run the system in parallel with the system previously in use for a period of time adequate to insure that results of operation of the computer or program are satisfactory. SOFTWARE LICENSE A. Star-Kits Software Systems Corp. grants to customer a non-exclusive, paid up license to use on customer's computer the Star-Kits computer software received. Title to the media on which the software is recorded (cassette and/or disk) or stored (ROM) is transferred to customer, but not title to the software. B. In consideration of this license, customer shall not reproduce copies of Star-Kits software except to reproduce the number of copies required for use on customer's computer and shall include the copyright notice on all copies of software reproduced in whole or in part. C. The provisions of this software license (paragraphs A, B, and C) shall also be applicable to third parties purchasing such software from customer. Wherever used in this manual, SK*DOS and HUMBUG are registered trademarks of Star-Kits. SK*DOS was formerly marketed under the name STAR-DOS. This is revision 1.17 of the manual, last revised on June 1, 1986. CONTENTS 1. INTRODUCTION 1-1 2. FOR THE IMPATIENT ... 2-1 3. FILE SPECIFICATIONS 3-1 4. SK*DOS OVERVIEW 4-1 5. THE COMMAND PROCESSOR SYSTEM (CPS) 5-1 6. MEMORY RESIDENT COMMANDS 6-1 7. DISK RESIDENT COMMANDS 7-1 8. THE FILE CONTROL SYSTEM (FCS) 8-1 9. THE FILE CONTROL BLOCK 9-1 10. FCB OPERATION CODES 10-1 11. SK*DOS ENTRY POINTS 11-1 12. USER-ACCESSIBLE VARIABLES 12-1 13. PROGRAMMING EXAMPLES 13-1 14. DISK FORMAT AND RANDOM FILES 14-1 APPENDICES A. SK*DOS ENTRY POINTS A-1 B. USER-ACCESSIBLE VARIABLES B-1 C. THE FILE CONTROL BLOCK (FCB) C-1 D. FCS OPERATION CODES D-1 E. SK*DOS ERROR CODES E-1 F. DEFAULT EXTENSION CODES F-1 G. SK*DOS BOOT PROGRAM G-1 H. DISK RESIDENT COMMAND SUMMARY H- I. ADDENDA AND OTHER INFORMATION I-1 USER REGISTRATION AND UPDATE POLICY INDEX BEFORE STARTING In general, it is important that you develop good habits when using any floppy disk system. It is important that you make frequent backup disks, since it is very easy to lose a file, or even the data on an entire disk, due to a slippery finger or careless mistake. Since a Disk Operating System (DOS) is an extremely powerful program which allows you to access the disk on a most elementary basis, exercising caution and making frequent backups is especially important. If possible, you should make a backup of the SK*DOS system disk before doing anything else. If your SK*DOS was supplied to you already configured for the disk controller and other hardware you now have, then making such a backup is easy; if your hardware is different from what SK*DOS needs then it is not. Assuming that your hardware is capable of running this version of SK*DOS as is, here is what to do to get a backup. (1) Make sure the original SK*DOS disk is write-protected. On a five-inch disk you should place the write-protect tab over the slot on one edge of the disk; on an eight-inch disk you should remove the write-protect tab from the disk. (2) Place the SK*DOS disk into drive 0, close the door, and type your monitor disk boot command. For example, the disk boot command in HUMBUG is FD. If your monitor does not have a boot command, then you will have to type in and execute the boot program given in Appendix G. (3) After SK*DOS is booted and you get the prompt, use the FORMAT command to initialize a blank disk in drive 1. See Appendix H for instructions on using FORMAT. (4) Once a new disk is formatted, use the BACKUP command to copy the SK*DOS system disk onto the blank disk. (See Appendix H for instructions on BACKUP.) (5) Make several such backup disks, and put the original SK*DOS disk away into a safe place. In any case, it might be a good idea to read this entire manual before proceeding. PLEASE NOTE Although copy-protecting a disk is a good way for a software manufacturer to protect his software from unauthorized duplication and use, we have not done so. We firmly believe that protecting a disk from being copied and backed up is a major inconvenience to those of our customers who have legitimately purchased their copy of a program, and we really do not want to make life difficult for them. Please don't betray our concern for your convenience, and our trust in you, by giving a copy of this program to anyone else. 1. INTRODUCTION The Disk Operating System, or DOS for short, is a program which acts as a file manager for a disk. The DOS acts as a buffer between the disk hardware, and the software which uses that disk. Its primary function is to maintain a disk directory on each disk, fetch program or data files from the disk as needed, and store programs or data back on the disk. SK*DOS consists of three major parts: (1) The Command Processor System or CPS, which is the major interface to the user. When SK*DOS is active, the CPS monitors the keyboard and waits for user commands. At that time, you can load and execute programs from the disk and do certain other functions. In addition, the CPS has a number of subroutines which can be used by other programs to simplify input and output for the terminal. (2) The File Control System or FCS is the interface for programs running under SK*DOS. The FCS does the actual work of managing the contents of the disk. It has various routines which can be called by user programs for managing the disk contents. (3) Memory- and disk-resident commands provide additional functions which work in conjunction with the CPS and FCS to provide an easy way of maintaining the disk. In addition to the various commands supplied with SK*DOS, there are many other programs available from other vendors which will also work with SK*DOS. Simply look for those programs which are identified as working with either SK*DOS or Flex (a trademark of Technical Systems Consultants.) The interface between SK*DOS and user programs has been standardized over a number of years on other 6809 systems, and is fully documented in this manual. Since a DOS must be customized to run on a particular system, Star-Kits Software Systems Corporation, in conjunction with manufacturers who license SK*DOS, provides several different versions. Depending on the hardware configuration you specified with your order, you have probably received a version which is already customized for your hardware. In general, there will be three copies of SK*DOS on your disk: SK-DOS.SYS is a bootable version (which is started with the floppy disk boot command of your monitor) and which is configured for your hardware. (If your hardware configuration is different from those supported by Star-Kits or one of our licensed manufacturers, then this version will be for a DC-2 - type controller using a Western Digital 1771 disk controller. This is a bare-bones implementation of SK*DOS, and may be bootable on your controller even if it is not entirely compatible.) SK-DOS.COR is a general purpose version which lacks all console terminal and disk driver interfacing. In order to run this version, you will have to provide your own interface routines. A SK*DOS Configuration Manual, available for $50 from Star-Kits, describes the process of configuring SK*DOS for other hardware systems, and shows sample interfacing routines which can be used as a guide. SK-DOS.CMD is an overlay file for those users who already have either an earlier version of SK*DOS or another compatible disk operating system. Once the system is booted with the other DOS, executing SK-DOS.CMD will overlay SK*DOS over the other DOS, keeping only the disk and console drivers of the other DOS. SK*DOS will then be fully operational as if it had been booted from scratch. 2. FOR THE IMPATIENT ... If you're anything like us, you want to try out a new program even before reading the manual, just to make sure 'it works'. This is difficult to do with something as powerful as a DOS, but just to show you a bit of what SK*DOS can do, this section shows you how to bring the system up and run it. (This is only possible at this time if you have received a version of SK*DOS which is already configured for your specific hardware.) After you finish trying it out, we suggest you put it away and go back to reading this manual. To start, make sure that your disk is write-protected and place it into drive 0. Check your monitor manual for the correct disk boot command (FD in HUMBUG) and boot the disk by typing that command. The computer will load the program and respond with WELCOME TO SK*DOS LEVEL I (C) 1984 BY PETER A. STARK STAR-KITS SOFTWARE SYSTEMS CORP. ENTER TODAY'S DATE (MM,DD,YY): Respond with the date, using one or two digits for the month and day, and two digits for the year, as in 9,26,82, and hit the ENTER key. You will now get the prompt SK*DOS: SK*DOS is now running, and awaiting your further command. (You are looking at just the tip of SK*DOS - the part which is visible to the user. There is much more to SK*DOS than this, but this is the only part which you can see and experiment with without doing a bit more reading.) You can now type in a variety of commands. Some commands will be immediately recognized by SK*DOS and acted upon; these are called 'memory resident' commands. Others are not recognized, and so SK*DOS will try to find them on the disk; these are called 'disk resident' commands. To try a memory resident command, type the word XEQ and hit ENTER. XEQ tells SK*DOS to execute the last program loaded in by SK*DOS. Of course, we haven't yet used SK*DOS to load anything, and so we get an error message which reads ERROR 28 - MISSING TRANSFER ADDRESS SK*DOS error codes are explained in Appendix E; in this case there is no transfer address so SK*DOS does not know what to execute. Let us next execute a disk-resident command: CAT 0 The CAT command prints a catalog of the disk. (CAT or CAT 0 means drive 0, CAT 1 means drive 1, and so on). In response to the CAT 0 command, SK*DOS loads the CAT.CMD program from the disk and executes it, displaying a catalog of the disk in drive 0. (To halt the listing, just press the ESC or escape key. Pressing ESC again will continue the catalog listing, or pressing CR or RETURN will return to the SK*DOS prompt.) Once the CAT command is finished, you may repeat the entire command by pressing control-A. The control-A displays the entire previous command line (CAT 0) as if you had typed it again. At this point you may simply perform that command by pressing CR, or may backspace and change all or part of the line. For example, you may backspace to the 0 and replace it with a 1 (assuming you have a drive 1), thereby changing the command to CAT 1. Pressing the CR now would result in a catalog display of the disk in drive 1. Another way of repeating a command is by using the XEQ command. XEQ tells SK*DOS to execute the last program loaded by SK*DOS. In this case, the last disk-resident command loaded is CAT, so XEQ repeats the CAT command. There are two interesting points to note: 1. Running CAT again by typing XEQ is faster than typing CAT again, because typing CAT loads the program from disk and then executes it, whereas XEQ merely restarts the CAT program without loading it again. 2. Pressing control-A repeats an entire previous command line, including any arguments typed as part of that line (for example, the 0 in CAT 0 is the argument and specifies the drive number.) XEQ restarts a program but does not supply any arguments; these must be entered after the XEQ (as in XEQ 0). It is now time to return to reading the rest of this manual, so type the memory resident command MON This command exits SK*DOS and returns to the monitor. 3. FILE SPECIFICATIONS The term File Specification or just file-spec refers to the three items required to completely specify a file on a disk: the drive number, file name, and extension. The file-spec usually looks something like this: 0.FILENAME.EXT where the file name is one to eight characters long, the extension is one to three characters long, and the drive number is a number between 0 and 9, inclusive. (Most disk controllers only provide for four drives, in which case the drive number will range from 0 to 3. Drive numbers higher than 3 require special controllers or multiple controllers.) The drive number, file name, and extension are usually separated by periods. (Although the drive number usually precedes the file name, it may also follow, as in FILENAME.EXT.0). Filenames and extensions must begin with a letter, and the remaining characters may be either letters, numbers, hyphens, or the underscore. The extension and drive number are not always required if they are obvious. For example, SK*DOS defaults to certain extensions for certain commands. The drive number likewise defaults to drive 0, unless a different default drive is specified for either the system or working drive. 4. SK*DOS OVERVIEW The SK*DOS package consists of essentially two parts: 1. The SK*DOS program itself. 2. A set of disk-resident commands such as CAT and LIST. The disk-resident commands are described later; this section deals with the SK*DOS program itself. SK*DOS is a machine language program which occupies just slightly under 8K of memory. It occupies the 8K memory segment from address $C000 through $DFFF, but certain portions of that space are unused or dedicated for other purposes. The SK*DOS program in turn consists two parts: 1. The File Control System (or FCS for short) which maintains the disk directory and in general is responsible for managing the disk contents. The FCS has various subroutines which may be called by other programs; some of these subroutines actually handle the disk and its files, while other subroutines may handle peripheral functions (such as printing out strings, or converting numbers to and from decimal). These subroutines are used by the FCS, but they are documented in this manual and may also be used by application programs you write. 2. The Command Processor System (or CPS for short) which acts as an interface between a user and the FCS. When SK*DOS is first loaded and executed, the CPS prints the SK*DOS: prompt and awaits further instructions. These instructions may or may not involve the FCS. The following table provides a memory map of SK*DOS: $C000-C07F - stack for SK*DOS and user programs $C080-C0FF - line input buffer $C100-C83F - Disk Command Area used by some disk commands $C840-CCFF - system variables and storage $CD00-DFBF - SK*DOS program All of the entry points into SK*DOS are located at the beginning of the program: $CD00 COLDS is the cold-start entry point $CD03 WARMS is the warm-start entry point other entry points continue at $CD06 and up. COLDS is the entry point which is executed when SK*DOS is first started. The COLDS entry point initializes SK*DOS's flags and pointers, to make sure that SK*DOS always begins at the correct place. COLDS should not be used thereafter, since initializing SK*DOS via the COLDS entry point makes SK*DOS forget all about any open files. Hence entering COLDS once some disk files are opened may cause the disk data to be damaged. (You will not normally need COLDS since SK*DOS is normally started by a boot-up process which calls COLDS automatically.) WARMS is the correct re-entry point to use once SK*DOS has been run. This is the entry point which should be used by programs executed under SK*DOS. Beginning at $CD06 are other entry points into SK*DOS which may be used by machine and assembly language programs which use parts of SK*DOS for their own purposes. These addresses are listed in Appendix A, and are discussed further later in this manual. The rest of SK*DOS, including both the Command Processor System and the File Control System, is located above this memory area. 5. THE COMMAND PROCESSOR SYSTEM When SK*DOS is first loaded and started, it responds with the SK*DOS: prompt and waits for a command to be processed. At this point you may enter either a Memory Resident Command, or a Disk Resident Command. Depending on the command, sometimes several commands may be entered on one line, separated by colons. Commands may consist of more than one part and may be up to 127 characters long, if necessary. The various parts of a command may be separated by either spaces or commas, and the command should be followed by an ENTER. Commands typed into the command processor (and other input which may be entered in user programs) are stored in a line buffer (called LINBUF). If you type a control-A character while inputting a command or other input into the line buffer, SK*DOS will add the remaining contents of the line buffer to the input you have just typed and display it on your terminal. This is useful for repeating a command in its entirety, or repeating just parts of it. For example, suppose you have just completed the command COPY 0.NAME1.TXT 1.NAME2.OLD and then, upon completion of that command, you type a control-A. SK*DOS will display the entire previous line again and position the cursor after the D in OLD. If you then press the RETURN key, you will perform the command again. Alternatively, you may backspace and change any part of the command. For example, if you backspaced to the beginning of NAME2 and typed in a new name such as NAME3, then the line would read COPY 0.NAME1.TXT 1.NAME3 At this point you could either press RETURN and execute the line as is, or again press control-A; the latter would complete the line by adding the .OLD at the end. SK*DOS has several Memory Resident Commands, which it executes as soon as they are entered. Anything else entered in response to the SK*DOS: prompt (if not one of the Memory Resident Commands) is assumed to be a Disk Resident Command. SK*DOS then tries to load the corresponding command program from the disk and execute it. If a command is given which is neither one of the Memory Resident Commands, nor is a Disk Resident Command on the disk currently in the drive, then SK*DOS will print an error message and return with another SK*DOS: prompt. 6. MEMORY RESIDENT COMMANDS SK*DOS recognizes several Memory Resident Commands. These are commands which are integral parts of SK*DOS, and are in memory at all times. They are therefore called by their names, and do not get either an extension or drive number. GET GET is used to load a binary program file from the disk into memory. The word GET is followed by the file-name of the file to be loaded. An extension of .BIN is assumed unless specified otherwise. (See a previous section on valid file specifications.) For example, the command GET CAT.BIN or just GET CAT would load a binary program called CAT from drive 0 and place it in memory. MON MON is used to exit SK*DOS and return back to the system monitor. XEQ XEQ is used to execute a program previously loaded by SK*DOS using the execution address loaded with the file from the disk. If the program requires arguments as part of the calling line, these arguments can be placed after the XEQ. For example, suppose the command CAT 0 is used to display a catalog of a disk in drive 1; the command XEQ 1 would then repeat CAT, but would give it the argument 1 to specify drive 1. Control-A Strictly speaking, Control-A is not a command. Pressing a control-A while typing any command will repeat the remaining portion of any previous command, display it on the screen, and ready it for execution. The control-A is a powerful feature, but it can also be misused if entered past the end of the last previous command. 7. DISK RESIDENT COMMANDS SK*DOS is supplied with a variety of disk-resident commands which are described in Appendix H. In addition, it is relatively easy to write your own command files and store them on the disk for later execution. Disk resident commands are supplied as binary, machine language files with .CMD extensions. They are executed simply by typing their names. For example, the CAT.CMD command may be executed just by typing CAT after the SK*DOS: prompt. This is equivalent to typing the sequence SK*DOS: GET CAT.CMD SK*DOS: XEQ since any unknown word (other than one recognized by SK*DOS as a memory resident command) is interpreted as calling a disk command and executing it. A .CMD extension is assumed, and the program is automatically executed as soon as it is loaded. Since SK*DOS automatically searches the disk for commands, it is possible for users to write their own Disk Resident Commands. Arguments to be used by the command can be entered on the same line as the command name, and then processed by the command with the aid of SK*DOS routines such as NEXTCH (get the next character from the Line Buffer). The listing of the LIST command, later in this manual, will show how additional commands can be written. The disk-resident commands supplied with SK*DOS are described in Appendix H. 8. THE FILE CONTROL SYSTEM (FCS) The FCS is the heart of SK*DOS, since it is responsible for reading, writing, and locating files on the disk. Although the FCS system is working, it is invisible when you run some of the disk resident commands such as BUILD or LIST. It is, however, heavily used by all machine language programs which run under SK*DOS. The following explanation will assume that you have the knowledge and need to examine the operation of SK*DOS on this detailed level. When reading a file, the FCS looks up the file location in the system portion of the disk (track number 0 on the disk) and then goes to read it. When writing a file to the disk, the FCS uses the system track to assign space to the file; when the file is written, the FCS updates the system track so that the file can later be found. Fortunately, though this process is rather complex in any disk system, the user need not be concerned with how it is done, or where on the disk a given file is located. The SK*DOS FCS does all this automatically; the user need only give the FCS a file name and a command as to what to do. This is done by setting up a File Control Block or FCB for each file that is to be opened; a given program may use as many FCBs as desired. The FCB contains the file-spec, assorted flags and variables which are used by the FCS to keep track of the file, and also the data read from, or about to be written to, a single sector on the disk. For example, to access the disk through the FCS to read text from a disk file, the sequence of operations would be something like this: 1. Set up a File Control Block with an RMB 320 instruction. 2. Point the X register to the FCB, and jump into the SK*DOS FCS to input a file name. 3. Jump into SK*DOS again to assign a default extension, if needed. 4. Put an operation code into the FCB, and jump into SK*DOS to open the file. 5. Jump into SK*DOS to read a byte from the file. 6. Repeat step 5 as long as needed, then 7. Jump into SK*DOS to close the file. All of these operations use the FCB as a buffer, both to hold the contents of an entire sector of data read from or written to the disk, as well as to keep track of the file name and location, and other pertinent data. The FCB is discussed in the next section. 9. THE FILE CONTROL BLOCK The File Control Block, or FCB for short, is used for all communications between the File Control System (FCS) and user programs. One FCB is required for each file that is opened by a program, although that FCB can be reused again if a file is closed (thereby releasing the FCB) and another file is opened with the same FCB location. The FCB is an area of memory 320 bytes long. SK*DOS maintains several such FCBs for its internal use. One of these is called the User FCB, or USRFCB. It begins at address $C840, and is available for use by other programs. Although it is used by SK*DOS, this is done in a way which does not prevent its use by those programs which also require a FCB. The FCB consists of 320 bytes. Of these, the first 64 bytes are used for storage of various file parameters, while the remaining 256 bytes hold the data for one sector of disk data. During a disk read operation, these bytes hold the contents of the last sector previously read; during a write operation, these bytes generally hold the contents of the next sector to be written. Not all of the first 64 bytes are used; the following descriptions cover those bytes that are used in SK*DOS. Byte No. 0. Operation code (see Appendix D) Before using the File Control System, the calling program must store into this byte a code which describes the operation to be performed. These codes are described in the next section, and summarized in Appendix D. The following instructions are normally used to do this: LDX #FCB Point to the File Control Block LDA #.. Load the op code number to be used STA 0,X Store it into byte 0 of FCB JSR FCS Jump to FCS to perform operation Byte No. 1. Error code (see Appendix E) After the FCS is finished doing the above operation, it returns to the user program. If no error is found, then the Z bit in the condition code register is a 1 and the contents of this byte is irrelevant. But if an error is found, then the Z bit is a 0 and this byte contains an error code. The status of the Z bit should be tested directly after the JSR instruction with a BNE (to error routine) or BEQ (to normal continuation) instruction. The contents of this error byte is also stored in ERRTYP, location $CC20. Byte No. 2. Read / Write / Update status This byte indicates whether the file is open for reading, writing, or random file updating. SK*DOS checks the byte prior to reading or writing to make sure that the file is open for the appropriate operation. The values of this byte for an open file are as follows: 1 = open for sequential reading 2 = open for sequential writing 3 = open for updating, but no changes have been made to current sector 83 = open for updating, and changes have been made to current sector (this is hexadecimal 83) Byte No. 3. Drive number (0 through 9) This byte contains the number of the drive being used for this file control block. The drive number will normally be a number from 0 through 9, but when opening a file for reading or writing it may also be specified as $FF, in which case SK*DOS will search your drives, beginning with drive 0, for a drive where the requested operation can be completed. Then it will place the correct drive number into this byte and open the file. Since many disk drivers do not provide a way of determining whether a 5" floppy disk is ready or not, SK*DOS may "hang up" if there is no disk in a drive being searched. Bytes No. 4-11. File name (8 bytes) These eight bytes contain the name of the file being used with this FCB. The first character of the name (always in byte 4) must be a letter, and the remaining ones may be either letters, digits, hyphens, or underlines. If the name is shorter than 8 characters, then the remaining bytes must be filled with zeroes. Bytes No. 12-14. Extension (3 bytes) These three bytes contain the extension that goes with the name in bytes 4 through 11. The extension obeys the same rules as the name described above. Byte No. 15. File protection status This byte defines the type of user access permitted to this file. The bits are used as follows: Bits 0-3 - reserved for future use (leave at 0) Bit 4 - will not be listed by CAT utility Bit 5 - Reading not permitted Bit 6 - Deletion not permitted Bit 7 - Writing not permitted Byte No. 16. Copy protection status This byte is normally initialized at 0 by SK*DOS, and is not used by SK*DOS. Some COPY commands, however, ignore any files which contain a non-zero byte at this location and refuse to copy them. This feature is mentioned here strictly for reference as it is relatively useless - such files can be copied by use of the BACKUP command. Byte No. 17. First track of file Byte No. 18. First sector of file These two bytes point to the first sector of the file. Byte No. 19. Last track of file Byte No. 20. Last sector of file These two bytes point to the last sector of the file. Bytes No. 21-22. Number of sectors in the file These two bytes indicate the size of the file in sectors. Byte No. 23. Random file indicator This byte indicates whether the current file is a sequential file or a random file. A zero in this byte indicates a sequential file, a nonzero indicates a random file. (See the RANDOM command and Chapter 14 for further information on random files.) Byte No. 24. User-defined byte This byte is available for user-defined purposes. It is normally initialized at 0 when a file is opened for write, but may be changed by the user. It is then written into the directory when the file is closed, and restored into the FCB when the file is opened for reading. See the INTIME entry point for additional information. Byte No. 25. Month of file creation (1 through 12) Byte No. 26. Day of file creation (1 through 31) Byte No. 27. Year of file creation (last two digits) These three bytes hold the date when the file was created. All three bytes are in binary, but only the last two decimal digits of the year are stored. That is, in 1984 byte 27 stores a decimal 84, or a hexadecimal 54. Bytes No. 28-29. Next FCB pointer These two bytes point to the next FCB, if any, which was opened after this one (or, more exactly, they point to the corresponding bytes of the next FCB, not to the beginning of that FCB). This information is used by SK*DOS to keep a list of all FCBs currently in use, so that they can be closed if an FCSCLS operation is requested. If this is the last FCB in the chain, then these bytes contain zeroes. Byte No. 30. Current track number Byte No. 31. Current sector number These two bytes contain the track and sector number of the sector currently in the FCB. If the file is being read, then they indicate where the data currently in the FCB came from; if the file is being written, then they indicate where this data will go. Bytes Nos. 32-33. Current or desired sector number This byte indicates the position of the current sector within the file. In sequential files, the first sector of a file is sector number 1, and so on. In random files the first two sectors, which contain the file map, are number 0, and sector 1 is the first data sector of the file. (See the RANDOM command and Chapter 14 for further information on random files.) Byte No. 34. Sequential data pointer to next byte (4 through 255) On all sequential read or write operations, this byte points to the next byte to be read or written into the last 256 bytes of the FCB. The pointer is a 4 for the first byte, or 255 for the last byte. SK*DOS changes this byte automatically; users will not normally touch it. Byte No. 35. Random data pointer to next byte (4 through 255) On all random read or write operations, this byte points to the next byte to be read or written into the last 256 bytes of the FCB. The pointer is a 4 for the first byte, or 255 for the last byte. Unlike the sequential data pointer (byte 34), this byte is not changed by SK*DOS, but is to be set by user programs instead. (See the RANDOM command and Chapter 14 for further information on random files.) Bytes No. 36-46. Temporary name buffer 1 These eleven bytes are used to temporarily hold a file name and extension while the file is being renamed or deleted. Byte No. 47. Directory track number Byte No. 48. Directory sector number Byte No. 49. Directory byte number These three bytes point to the location in the directory where the current file is listed. The directory begins on track 0 sector 5, but may extend to other tracks if track 0 is filled. Bytes No. 53-63. Temporary name buffer 2 These eleven bytes hold the new name and extension of a file being renamed. The new name should be stored into these bytes prior to calling the rename function of the FCS, using the same rules as apply to bytes 4 through 11 above. (These bytes overlap with some of the bytes below, but there is no conflict as they are used at different times.) Byte No. 59. Space compression indicator This byte indicates whether space compression is being done in reading or writing the current file. Values of 0 through 127 ($00 through $7F) indicate that space compression is being done, and the actual value represents the number of spaces currently being compressed. A value of 255 ($FF) indicates that no space compression is being done. SK*DOS initializes this byte to 00 upon opening a file; it is up to the user to change it to $FF (after opening the file but before reading or writing) if space compression is not desired. Byte No. 60. Number of sectors per track This byte contains the number of sectors per track during random file operations. (See the RANDOM command and Chapter 14 for further information on random files.) Bytes No. 61-63. Work area These bytes are used as a temporary work area by SK*DOS. Byte No. 64. Beginning of data area The 256 bytes starting at byte 64 contain the data for an entire disk sector. 10. FCB OPERATION CODES Before calling the File Control System to initiate an operation on the FCB, the calling program must generally place an FCB operation code into byte 0 (the first byte) of the FCB. This is usually done with a set of instructions something like this: LDX #FCB Point to the File Control Block LDA #.. Load the op code number to be used STA 0,X Store it into byte 0 of FCB JSR FCS Jump to FCS to perform operation BNE ERROR Go process error if detected Note that it is required that the X register point to the beginning of the FCB when FCS is called. The contents of all registers (except for the condition code register and possibly the A accumulator) are preserved upon return from the FCS, so that the X register will still be pointing to the FCB upon return. This section describes the operation codes that are implemented in SK*DOS. If the FCS is called with an unimplemented operation code, the FCS will return error code 1 (FCS operation code error) and also print out an error message and ask whether the user wishes to continue despite the error. In general, this error is a fatal error and execution should be stopped if it is encountered. The following descriptions include typical error codes that may be generated on specific operations. In addition, most of the operations may also result in disk read or write errors due to hardware problems. In all cases, if no error occurs, then the FCS returns with the Z bit of the condition code register set. If an error does occur, then the Z bit is cleared and byte 1 of the FCB (as well as location ERRTYP) contains the code for the error that occurred. Error codes are listed in Appendix E. Error detection will normally be implemented as a BNE instruction as follows: . . JSR FCS Jump to FCS to perform operation BNE ERROR Go process error if detected . Continue if no error was detected . The error routine often looks like this: ERROR JSR PERROR Print error code JMP WARMST And abort the program Often the error routine analyzes the error and takes alternative actions depending on the error code. Operation 0: Read or write next byte Most FCS read or write operations are sequential; this operation is used to read or write the next sequential byte or character in the file. During a read, the next byte from the file is read from the sector currently in the FCB (using the data pointer in byte 34) and returned in the A accumulator, while during a write the character in the A accumulator is written to the file. Note several items. First, code 0 is used for both read and write; the decision as to which is done depends on whether the file has been opened for read or write. Second, since the file is read or written on the disk an entire sector at a time, operation 0 actually buffers the data through the sector buffer in the last 256 bytes of the FCB. Hence no actual disk read or write will generally occur for most operation 0 calls. When an actual disk read or write is required, SK*DOS will handle that automatically without user intervention. Operation 1: Open a file for read This operation opens a file for reading. Before calling the FCS, the calling program must insert the drive number, name, and extension of the desired file into bytes 3 through 14 of the FCB. The FCS will take care of initializing all other parts of the FCB. If the requested file is not on the disk, the FCS will return error code 4 (file does not exist). When the FCS is finished opening the file, it stores code 0 (read or write) into byte 0 of the FCB under the assumption that a sequential read will be performed next. Operation 2: Open a file for write This operation opens a file for writing. Before calling the FCS, the calling program must insert the drive number, name, and extension of the desired file into bytes 3 through 14 of the FCB. The FCS will take care of initializing all other parts of the FCB. If the specified disk already has a file with the specified name, the FCS will return error code 3 (file already exists). When the FCS is finished opening the file, it stores code 0 (read or write) into byte 0 of the FCB under the assumption that a sequential write will be performed next. This operation opens a sequential file, but it may be changed to a random file by storing a non-zero number into byte 23 of the FCB after opening the file, but before writing any data into it. (See the RANDOM command and Chapter 14 for further information on random files.) Operation 3: Open a file for update This operation opens a random file for reading or updating. Once the file is open, you may do one of the following: a. Use operation 21 to position to a particular sector of the file. b. Use operation 22 to backup to the preceding sector. c. Use operation 17 to read a particular byte from the currently selected sector. d. Use operation 18 to write a particular byte to the currently selected sector. e. Use operation 0 to sequentially read the sector, starting with the first. You may read as many bytes as there are in the file. (If executed after opening the file for update, operation 0 will start reading at the beginning of the file.) f. Use operation 23 to extend the file. g. Use operation 4 to close the file. h. The only way to write past the end of a sector into the next sector is to use operations 21 or 23 to position to the next sector. (See the RANDOM command and Chapter 14 for further information on random files.) Operation 4: Close file This operation closes a file currently opened for rading, writing, or updating. No operation is performed on read files, or on write files which were never written to, other than removing them from the chain of file pointers. When a write file is closed, any data remaining in the last 256 bytes of the FCB is written out to the disk, and both the directory and the file sector map are updated to indicate the correct track and sector numbers of the last sector and the file size. The system information sector (SIS) on track 0 sector 3 is also updated. When a random file open for updating is closed, the current sector is written out to disk if data has actually been written to it. Operation 5: Rewind file This operation can only be performed on a file which is open for reading, and will result in Error 1 (FCS operation code error) if attempted on a file open for writing. The Rewind operation is used to start reading a file from the very beginning, and is equivalent to closing the file and then immediately opening it for reading again. Operation 6. Open directory file This operation prepares the current FCB to read directory entries with operation 7. Before using this operation, the calling program should place the drive number into byte 3 of the FCB; no other initialization is required. This operation does not actually do any reading, but merely prepares the FCB for a subsequent read with operation 7. It is primarily used by the FCS itself, and will not usually be used by user programs. Operation 7. Read directory or system information sector This operation must be preceded by either operation 6 (open directory) or operation 16 (open system information sector) and reads the first (or next) entry in the directory or SIS, respectively, into the first 64 bytes of the FCB. When used on the SIS, only one read should be performed since only one entry exists in the SIS; when used on the directory, up to ten reads can be performed on any one sector since there are ten directory entries per sector. Upon the eleventh read, operation 7 will automatically read the next sector of the directory. Error 8 (input past end of file) will be returned at the end of the directory. Note that all entries are read, even deleted entries (indicated by a $FF as the first character of the file name) or unused entries (indicated by a 00 as the first character.) Operation 8. Close directory or SIS file This operation would normally be used after operation 7 when data in the FCB has been changed and is to be written back to the disk. CAUTIONARY NOTE This operation doesn't work the way you'd expect. Read this carefully. Operation 8 is intended to work with operations 6 (open a directory), 16 (open the SIS), and then 7 (read directory or SIS). Since operation 7 reads both the SIS and/or directory data from the 256-byte sector buffer in the FCB into the first 64 bytes (the interface area) of the FCB (for example, it moves the disk or file name up to byte 4, etc.), you'd normally expect Operation 8 to do the reverse. That is, you'd expect it to move the disk or file specification from the interface area of the FCB back to its appropriate place within the 256- byte sector buffer area, and then write it to disk. BUT it doesn't work like that. This operation is identical with function 10, as it simply writes the entire current sector back to the disk. It doesn't move the data from the FCB interface area to the sector buffer area first. This is omitted intentionally because existing programs which use the same FCS call do not expect it to do so. Hence the user program must put directory or SIS information directly into the sector buffer area of the FCB prior to calling operation 8. Operation 9: Read a single sector This operation provides direct access to the disk read routine. The user program must provide the drive number in byte 3 of the FCB, and the track and sector numbers in bytes 30-31. Upon exit, the data from the desired sector is in the last 256 bytes of the FCB. If an error is encountered, the Z bit of the condition code register is cleared and byte 1 of the FCB contains one of the following error codes: error 9 (disk read error), error 14 (disk seek error), or error 16 (drive not ready). Operation 10 ($A): Write a single sector This operation provides direct access to the disk write routine. The user program must provide the drive number in byte 3 of the FCB, the track and sector numbers in bytes 30-31, and the data to be written in the last 256 bytes of the FCB. If an error is encountered, the Z bit of the condition code register is cleared and byte 1 of the FCB contains one of the following error codes: error 10 (disk write error), error 11 (write protected disk), error 14 (disk seek error), error 16 (drive not ready), or error 29 (disk verify error). Operation 12 ($C): Delete a file This operation deletes a file name from the directory and returns its used sectors to the chain of free sectors maintained in the System Information Sector (track 0 sector 3). Before using this operation, the calling program must place the drive number, file name, and file extension of the desired file into bytes 3 through 14 of the FCB. It returns error 4 if the file name is not found, along with the Z bit of the condition code register cleared. Operation 13 ($D): Rename a file This operation renames an existing file; before calling the FCS, the user's program must place the old file specification into bytes 3 through 14 of the FCB, and the new name and extension into bytes 53-62 of the FCB (temporary name buffer 2). If there is an error, the Z bit is cleared and the FCS returns one of the following codes in byte 1 of the FCB: error 4 (old file does not exist), or error 3 (new file name already exists). Operation 15: Skip current sector This operation skips the current sector and goes to the next sector of the current file. When a file is being read, the FCS simply skips the remaining data in the current sector and prepares to read the next sector. On writing, the FCS fills the remainder of the current sector with zeroes, writes it out to the disk, and prepares to write into the next sector; if, however, the FCS is already pointing to a new sector (but has not yet written into it) then this operation is ignored. Operation 16: Open System Information Sector This operation prepares the current FCB to read the System Information Sector with operation 7. Before using this operation, the calling program should place the drive number into byte 3 of the FCB; no other initialization is required. This operation does not actually do any reading, but merely prepares the FCB for a subsequent read with operation 7. It is primarily used by the FCS itself, and will not usually be used by user programs. Operation 17: Read a random byte This operation allows you to read a specified random byte from a random file currently opened for update. To select the byte, place its number, a value from 4 to 256, into byte 35 of the FCB. (Note that there are only 252 data bytes per sector, and they are numbered from 4 through 256.)The byte will then be read from the currently selected sector. (See the RANDOM command and Chapter 14 for further information on random files.) Operation 18: Write a random byte This operation allows you to write a specified random byte to a random file currently opened for updating. To select the byte, place its number, a value from 4 to 256, into byte 35 of the FCB. (Note that there are only 252 data bytes per sector, and they are numbered from 4 through 256.) The byte will then be written to the currently selected sector. (See the RANDOM command and Chapter 14 for further information on random files.) Operation 20: Find next drive number This operation is used to find the next available drive number. On entry, you must place either the number $FF or a valid drive number into byte 3 (the drive number byte) of the FCB. The FCS will then return with the next available drive number. The FCS will start with the next higher drive number; since $FF is equivalent to -1, entering with this value will start with drive 0. Searching will continue up until the current value of MAXDRV; if no ready drive is found, the FCS will return error 16 (drive not ready) in byte 1 of the FCB and also set the carry bit; otherwise the carry bit is cleared. Operation 21: Select a specified random sector This operation allows you to select a specified random sector of a random file. This operation can only be used after an existing random file is opened for update with operation 3. To use this operation code, place the two-byte sector number of the desired sector into bytes 32 and 33 of the FCB and and then call the FCS. If the desired sector number is 0, then the first sector of the file map will be read; if the desired sector number is too large, an error will be generated. (See the RANDOM command and Chapter 14 for further information on random files.) Operation 22: Backup to previous sector This operation allows you to backup to the previous random sector of a random file. Read the description of operation 21, as this operation is similar. You cannot backup from sector 1 (the first data sector of the file) back to sector 0 (the first file map sector), and any attempt to do so will generate error 24 (invalid sector number). (See the RANDOM command and Chapter 14 for further information on random files.) Operation 23: Extend a random file This operation allows you to extend the size of a random file. This operation can only be used after an existing random file is opened for update with operation 3. To use this operation code, place the two-byte sector number of the desired sector into bytes 32 and 33 of the FCB and and then call the FCS. If the desired sector already exists in the file, then it is selected exactly as in operation 21. If the desired sector number is larger than the size of the file, then the file will be extended so that the desired sector number is the last sector of the file. The new sectors added to the file are filled with zeroes. 11. SK*DOS ENTRY POINTS SK*DOS has a large number of subroutines and functions which can be called from user programs. Some of these are essential to the proper operation of the File Control System; others are simply routines which the FCS itself uses and which are documented because it is felt that they might be useful to the typical programmer. All of the following routines and addresses are addressed through a jump table and are expected to stay at the same addresses even in future SK*DOS revisions. All of the following entry points preserve all registers, except the condition code register, and except in those cases where a register is used specifically for input or output. COLDST $CD00 Cold start COLDST is the entry point that is used when SK*DOS is first loaded from disk and executed. Entering at COLDST erases all pointers and completely initializes SK*DOS to the beginning. User programs should not use this entry point, especially when files are open, as entering at COLDST causes SK*DOS to 'forget' all its open files. This can corrupt the contents of a disk or its directory. COLDST should be entered with a JMP instruction. WARMST $CD03 Warm start WARMST is the re-entry point to be used by user programs. Reentering at WARMST closes all open files and thus helps to insure the integrity of the directory. SK*DOS then prints its prompt and looks for a command to be processed by the Command Processor System. WARMST should be entered with a JMP instruction. RENTER $CD06 Re-enter SK*DOS This entry point re-enters the SK*DOS command processor system at the point where it processes a command line. This entry point is used when it is desired to continue processing the remainder of a command line (such as after the O or P commands.) INCH $CD09 Input a character (alterable) INCH0 $CD0C Input a character (fixed) These routines are used to input a character from the keyboard into the A accumulator. The main character input routine (listed below) which should be used by user programs is GETCH. When GETCH is called, however, it is vectored through INCH (if location INCHSW is zero) or INCH0 (if INCHSW is not zero) to the actual input routine. INCH0 always points to the actual keyboard input routine, but user programs may change the INCH pointer to point to other routines if desired. The RESIO routine (which is called at WARMST and may also be called by user programs) copies the INCH0 vector into INCH, so that INCH will always be properly initialized when user programs return back to SK*DOS. OUTCH $CD0F Output a character (alterable) OUTCH0 $CD12 Output a character (fixed) These routines output a character from the A accumulator to the terminal. The main character output routine (listed below) which should be used by user programs is PUTCH. When PUTCH is called, however, it is vectored through OUTCH (if location OUCHSW is zero) or OUTCH0 (if OUCHSW is not zero) to the actual input routine. OUTCH0 always points to the actual terminal output routine, but user programs may change the OUTCH pointer to point to other routines if desired. The RESIO routine (which is called at WARMST and may also be called by user programs) copies the OUTCH0 vector into OUTCH, so that OUTCH will always be properly initialized when user programs return back to SK*DOS. GETCH $CD15 Get input character GETCH is used to get an input character from the keyboard; it returns with the character in the A accumulator. All valid keyboard character codes can be input, but the parity bit (bit 7) is changed to a 0 for all input. (GETCH is actually vectored through INCH or INCH0 as explained above). PUTCH $CD18 Output character (wrap) PUTCH is used to output a character from the A accumulator to the terminal. (PUTCH is actually vectored through OUTCH or OUTCH0 as explained above.) INLINE $CD1B Input into line buffer SK*DOS maintains a 128-byte line buffer which it uses to parse commands to its own Command Processor System. The INLINE routine is used to enter an entire line of text from the keyboard into this line buffer, and may also be used by user programs. A line is normally ended with a CR character ($0D), which is placed at the end of the entered text. Hence the maximum text line which can be entered into the 128-byte buffer is 127 bytes long. This routine permits erasing errors with the backspace key. The Control-X key erases an entire line and starts over. The Control-A key re-displays the entire previous line in the line buffer, from the current cursor position to the previous end of line (carriage return) and can be used to repeat all or any part of a previous line. PSTRNG $CD1E Print CR/LF and string PSTRNG is used to output an entire string of text to the terminal. The string is preceded by a carriage return and line feed, meaning that the text begins on a new line on the screen. On entry, the X register should point to the first character to be printed, and the string should end with an 04 byte to denote end of data. On exit, the X register points to the 04 byte. (See also PDATA.) CLASFY $CD21 Classify alphanumeric characters This routine is used to classify characters in the A accumulator. If the character is a letter or digit, then the C (carry) bit of the condition code register is cleared; otherwise, it is set. PCRLF $CD24 Print CR/LF This routine prints a carriage return / line feed; that is, it forces the cursor to the next line so that subsequent input or output will occur at the beginning of a new line. GETNXT $CD27 Get next character from buffer This routine is used to get the next character from the 128-byte input buffer used by SK*DOS. This character is returned in the A accumulator and also placed in the CURRCH location in SK*DOS; the previous character which was in CURRCH is placed into PREVCH so that user programs have access to the last two characters taken from the line buffer. This routine automatically calls CLASFY, so that the carry bit can be used to indicate whether the current character is alphanumeric or not. If the line buffer contains a string of spaces, then GETNXT will return only one space. GETNXT will continue fetching characters until it gets to the end of the line, at which time it will continue to output the end of line ($0D (CR) or ENDLIN) if it is called again, and will also set the carry bit to indicate a non-alphanumeric character. This routine uses the LPOINT pointer (see next section) to keep track of the next character to be taken from the buffer. This pointer is normally set to the beginning of the buffer after a line is input from the keyboard with INLINE, and is incremented by one each time a character is fetched from the buffer, so that it always points to the next character to be fetched. At the end of a line, it always points to the CR character. RESIO $CD2A Reset I/O pointers RESIO resets the INCH and OUTCH entry points to be the same as INCH0 and OUTCH0, respectively, and also clears the INCHSW and OUCHSW flags so that INCH and OUTCH are used. In general, RESIO resets console I/O vectors to their normal conditions. RESIO is called during WARMST so that SK*DOS always returns to a known state upon return from a user program. GETNAM $CD2D Get file name into FCB This routine is used to take a file specification from the input buffer and place it into the appropriate bytes of an FCB. At entry, the X register should point to the FCB to be filled, and the LPOINT line buffer pointer should point to the beginning of the file specification in the line buffer. As the file specification is parsed, the drive number will be placed into the drive number location of the FCB (unless no drive number is specified, in which case the working drive will be used). The file name and the extension, if present, will also be placed into the FCB; if missing, they will be replaced by zeroes. If the file specification has no errors, then the carry will be cleared; else it will be set. The file specification in the line buffer may end with a space, comma, CR, or ENDLIN character; if a space or comma, then LPOINT will point to the next character after it, if a CR or ENDLIN, then LPOINT will point to the CR or ENDLIN character. Errors will place error code 21 (illegal file name) into the FCB and set the carry. LOADML $CD30 Load open machine language file This routine is used to load a machine language file into memory at its normal load address (unless location OFFSET is non-zero, in which case OFFSET is added to the load address specified in the file). LOADML is normally used by the memory resident GET command to fetch programs prior to execution. Prior to entering LOADML, the user program should use the USRFCB (user FCB) to open the file to be loaded. The file is then loaded, and its transfer address is stored in the EXECAD location (see next section). If there is no transfer then XFERFL is set to 0; it is incremented by one for each transfer address found so that it is non-zero (unless there are 256 transfer addresses in the file, or an exact multiple of 256, an unlikely occurrence.) Any transfer address found is stored in the EXECAD location. Errors such as error 4 (file not found) cause an immediate return to the calling program with a non-zero condition and the FCB indicating the error; read errors once a file is found immediately abort the program, close all files, and return to SK*DOS warm start. DEFEXT $CD33 Default extension This routine is used to enter a default extension into an FCB if the file specification already in the FCB does not contain one. Before entering, the user program should point the X register to the beginning of the FCB, and should place into the A accumulator a numeric code which indicates which default is desired. The codes are as follows: 0 = BIN 2 = CMD 4 = SYS 6 = SCR 8 = BAC 10 = PRT 1 = TXT 3 = BAS 5 = BAK 7 = DAT 9 = DIR 11 = OUT ADDBX $CD36 Add B to X This routine is included strictly for compatibility with a 6800 DOS, and executes an ABX instruction followed by an RTS. OUT5D $CD39 Output 5 decimal digits This routine outputs a decimal number of up to five digits. Before entering, the calling program should point the X register to the two-byte, unsigned binary number to be printed, and set the B accumulator to zero if the number is to be printed without leading spaces or zeroes, or to nonzero if the number is to be printed with leading spaces. OUT2H $CD3C Output 2 hex digits This routine prints the two-digit hexadecimal number that is pointed to by the X register on entry. PERROR $CD3F Print error code When an error is encountered by the FCS while using an FCB, user programs should do a JSR to this routine to print the error code. PERROR should be entered with the X register pointing to the beginning of the FCB, and the error code in byte 1 of the FCB. The error codes are listed in Appendix E. The error code is printed as a number; in addition, if the system disk contains the file ERRCODES.SYS, SK*DOS will read a one-line text description from this file and print it alongside the numeric code to explain the error's meaning. HEXIN $CD42 Input hexadecimal number This routine inputs a hexadecimal number from the line buffer and places it in the X register. Before entering, the calling program should make sure that LPOINT points to the first digit of the number to be input; at the end, LPOINT will be left pointing as described earlier for GETNAM. On output, the B register is non-zero if a number was actually found, and the carry bit is set if an invalid character was found in the number. (It is possible for both B and the carry to be zero if HEXIN encounters a delimiter such as a space, comma, CR, or ENDLIN immediately on entry.) If a number is not found the number returned is zero; if the number is greater than $FFFF, then only the last four hex digits are returned. OUT4H $CD45 Output 4 hex digits This routine outputs the four-digit hexadecimal number pointed to by the X register on entry; all registers are preserved except for the condition code register. DECIN $CD48 Input decimal number This routine is similar to HEXIN, but inputs a decimal number rather than a hexadecimal one. EXECSD $CD4B Execute a SK*DOS command This entry point allows a user-written program to call SK*DOS as a subroutine and have it execute a command line placed into the line buffer. On entry, the X register should point to the beginning of the command (usually at the beginning of the line buffer), and the command should end with a CR or ENDLIN character. If the command line in turn executes a disk-resident program, then that program should end with a JMP WARMST instruction to return to SK*DOS. SK*DOS, in turn, knowing that the program was called from another user program, will return control to the user program. The user should be careful not to call a program which will overlay part of the calling program in memory. STATUS $CD4E Check keyboard for character This routine allows a user program to check whether a character is being entered from the keyboard. If no character is being entered, the Z bit in the condition code register is set; if a character is being entered, then the Z bit is clear. All other registers are preserved. MOVNAM $CD51 Move file specification This routine provides a simple way of moving an 11-character file specification (name and extension) from one place in memory into another. On entry, the X register should point to the beginning address of the old string, and Y should point to the new address. (Caution: this entry point is unique to SK*DOS, and programs using it may not run with other disk operating systems.) PDATA $CD54 Print a string PDATA is similar to PSTRNG, but does not precede the string with a carriage return and line feed. (Caution: this entry point is unique to SK*DOS, and programs using it may not run with other disk operating systems.) INTIME $CD57 Input a user-defined byte INTIME is a trap point rather than an entry point. The three bytes at INTIME are initialized to $39, $12, $12, which is an RTS (return from subroutine) and two NOP instructions. Each time that SK*DOS opens a file for writing, it loads a 0 into the A accumulator, does a JSR to the INTIME trap, and upon return stores the contents of the A accumulator into byte 24 (the user-defined byte) of the current FCB. Since INTIME is initialized at an RTS, it normally does nothing. A user may, however, replace these three bytes with a jump into a user-written routine which may replace the byte in the A accumulator with other data. For example, if the system has a time of day clock, this byte could represent the time of day. One byte is not enough to indicate a precise time down to the minute, but it can be used to represent time in tenths of hours, resulting in 6-minute resolution. (Caution: this entry point is unique to SK*DOS, and programs using it may not run with other disk operating systems. User programs using the INTIME trap must preserve all registers except for the A accumulator.) INNOEC $CD5E Input character without echo INNOEC is used to get an input character from the keyboard, but without echoing it to the output; it returns with the character in the A accumulator. This is generally a direct input call to the hardware keyboard input routine, and (unlike GETCH) is not vectored through INCH or INCH2. This entry point is provided strictly for those application programs which require the user to specify such an entry point address. FCSINI $D400 Initialize File Control System This entry point should not normally be used by user programs as it can result in corruption of the disk. It totally initializes the system -disk drivers are initialized, all open files are forgotten and left open, etc. FCSCLS $D403 Close all open files This routine allows user-written programs to close all open files without actually knowing which they are. If FCSCLS detects an error, then it prints error 13 (error in closing file), clears the Z bit in the condition code register, and returns with the X register pointing to the FCB which was being closed when the error was detected. When FCSCLS detects an error, it does not close the remaining files; hence its routine use to close files is not encouraged. Instead, users should close each file separately. FCS $D406 Execute FCS operation This is the main entry point into the File Control System to execute one of the operations detailed in the previous section. In order to perform the operation, the calling program must point the X register to the FCB to be operated on, store the appropriate function code in byte 0 of the FCB, and do a JSR to this entry point. If the operation is finished without error, then FCS returns with the Z bit set. If an error is detected, then the Z bit is cleared and the error code is in byte 1 of the FCB. If no error is detected, this byte is not necessarily 0, and should not be tested unless the Z bit indicates an error. FCS preserves all registers (except CC) except in those cases where a register, such as the A accumulator, is used to carry input to or output from the FCS. 12. USER-ACCESSIBLE VARIABLES Some of the SK*DOS variables are of use to a programmer writing programs to run under SK*DOS. This section lists and describes these. (There are additional variables stored in higher memory, but these should not be meddled with by the programmer and are not guaranteed to stay in the same locations in future releases.) USRFCB $C840-C97F User FCB (320 bytes) This area is an FCB which is used by SK*DOS for its own internal operations. This is done in such a way, however, that other programs which require an FCB can also use the system FCB without interfering with SK*DOS. This can save the effort of having to declare memory for a separate FCB. LINBUF $C080-C0FF Line buffer (128 bytes) The line buffer is a 128-byte buffer which is used by SK*DOS for holding and processing commands. It is, however, also accessible to user programs through the INLINE routine (which enters text from the keyboard into the buffer) and the GETNXT, GETNAM, and other routines (which take data from the buffer). In particular, note that whenever a user program is called from the keyboard while in SK*DOS, any remaining text entered after the program name in the command line is still in the line buffer, and may be recovered by the user program. For example, when the LIST program is called from the keyboard with a SK*DOS: LIST TEXT command, when the LIST program begins, the line buffer pointer LPOINT points to the first letter of the word TEXT. The LIST program can access the name with several subroutines, such as GETNAM. This is a convenient way of getting and passing arguments to programs directly from the command line. BACKSP $CC00 Backspace character ($08) DELETE $CC01 Delete character ($18) ENDLIN $CC02 End of line character ($3A) ESCAPE $CC0A Escape char ($1B) REPEAT $CC0D Repeat character ($01) These locations contain the backspace character ($08 or control H), delete character ($18 or control X), end of line character ($3A or colon), escape ($1B), and repeat ($01), respectively. These locations are used by SK*DOS in console input routines, and can be changed by user programs or the TTY command. The DELETE character may be used to delete an entire line and return to the beginning, while the ENDLIN character, normally a colon, is accepted much the same as a carriage return ($0D) as an end-of-command delimiter. The ENDLIN character, however, can also be used to separate multiple commands on one line. The ESCAPE character is used to halt output to the terminal. Output may be restarted with another ESCAPE, or else may be aborted with a carriage return (not ENDLIN). The REPEAT character, normally $01 or Control-A, is used to repeat the last-used console command. PLINES $CC03 Number of printed lines per page SLINES $CC08 Number of skipped lines between pages These two locations are initialized by SK*DOS at 0, which disables them. If PLINES is non-zero, then output to the terminal will stop after PLINES continuous lines of output, skip SLINES blank lines, and then continue. A typical application is to make PLINES equal to a decimal 56, and make SLINES equal to a decimal 10, for paged output to a printer. Printed output would then have 56 continuous lines of print, and 10 skipped lines which step over the perforation between pages. These constants may be changed with the TTY command. PAUSE $CC09 Output pause control byte If PAUSE is non-zero, and PLINES is non-zero, then terminal output will pause after each PLINES lines, and resume when the escape key is pressed on the keyboard. PAUSE is normally initialized at $FF, thereby enabling the pause, but since PLINES defaults to 0, no pause actually takes place. WIDTH $CC04 Page column width This byte is used to control the page width of output to the terminal or printer. When output goes to the right of the WIDTH column on the terminal or printer, SK*DOS will issue a carriage return / line feed at the next space character. WIDTH may be set with the TTY command. SK*DOS normally initializes WIDTH to 0, which disables it. To use WIDTH, you should set it to a value approximately 10 less than the actual screen or paper width, so as to leave room for any long words at the end of the current line. (WIDTH works in conjunction with the COLUMN and SPECIO variables described below.) SPECIO $CC21 Special I/O Indicator When SPECIO is nonzero, the WIDTH value is ignored by SK*DOS. SPECIO is initialized to zero at warm-start and by RESIO. COLUMN $CC29 Current output column This byte indicates the current output column on the terminal or printer. It is used with the WIDTH variable, and reset to zero at the beginning of every line, or by the printing of any control character. NULLWT $CC05 Null wait constant Some terminals or printers make errors if a carriage return or line feed character is immediately followed by printable characters. In that case, NULLWT may be used to insert a short delay. It is normally initialized to 00 or no delay, but may be changed by the user (via the TTY command). The wait delay depends on the CPU clock speed, but is approximately equal to 0.01 second times the value of NULLWT. SYSTDR $CC0B System default drive WORKDR $CC0C Working default drive Both of these locations are initialized at 0. They are used as default drive numbers. SYSTDR is used as the default for loading any disk-resident command, while WORKDR is used as a general default by the GETNAM routine whenever a drive number is not specified as part of a file spec. MONTH $CC0E Current date - month DAY $CC0F Current date - day YEAR $CC10 Current date - year The above three locations hold the month, day, and year entered from the keyboard when SK*DOS is first cold started. This date is used by SK*DOS when writing files on the disk, and may also be accessed or changed by user programs. All three bytes are binary numbers, and YEAR contains only the last two digits of the year; for example, in 1982 the registers contain 82, or a hexadecimal $52. LASTRM $CC11 Last terminator This byte contains the last terminator encountered by the GETNXT routine from the line input buffer. COMTAB $CC12-CC13 Pointer to command table (2 bytes) SK*DOS contains several memory-resident commands (such as XEQ and GET); users may add additional memory-resident commands, and let SK*DOS know about them via COMTAB by putting into COMTAB a pointer to a table which lists the added commands. This table is searched by SK*DOS after its own command table, but before it looks for disk resident commands. Each entry in the user command table should consist of (a) the command name of up to eight letters (with no extension), (b) a zero byte to signal the end of the name, and (c) a two-byte address pointing to the command program. An extra zero byte at the very end signals the end of the table. The command should end with either an RTS or JMP WARMST instruction. LPOINT $CC14-CC15 Pointer to line buffer (2 bytes) LPOINT points to the next character to be obtained from the line buffer. When the buffer is first filled (with INLINE), LPOINT points to the first character in the buffer. Each time another character is obtained from the buffer, LPOINT is incremented so that it points to the next byte. When the pointer gets to the CR code at the end of the line, it then remains pointing to the CR. When an entire name or number is fetched from the buffer, such as by GETNAM, then at the end of the routine LPOINT points to the first character past the delimiter (such as a space or comma), or to the delimiter itself (if CR). BREAK $CC16-CC17 Break (Escape) address (2 bytes) As indicated earlier, terminal output can be interrupted by pressing the ESCAPE key, at which time SK*DOS waits for a second character. If the second character is again an ESCAPE, then output resumes; if the second character is a carriage return ($0D) character, then SK*DOS will abort the program. This return is handled through the return address in BREAK, which is initialized by SK*DOS to point to WARMST. User programs may also use BREAK to return to SK*DOS in that way. More commonly, user programs may store a different address in BREAK to force a return elsewhere when the return key is pressed. CURRCH $CC18 Last character read from buffer PREVCH $CC19 Previous character read As characters are fetched from the line buffer by SK*DOS routines (such as GETNXT), these two locations hold the latest character fetched (CURRCH) and the previous character fetched (PREVCH). OFFSET $CC1B-CC1C Offset load address (2 bytes) The contents of OFFSET (which is initialized to 0 at warm-start) is added to the load address for all machine language programs loaded from disk by SK*DOS. As long as OFFSET is 0, then programs are loaded into their normal location; if OFFSET is changed by a user program prior to loading, then the program will be loaded into a different location. If the load address, as stored on the disk, plus OFFSET add up to over 65535, then the program will wrap around to low memory. OFFSET does not affect the execution address. EXECFL $CC1D Execution address flag This location is non-zero when location EXECAD contains a valid execution address for a machine language program, and is zero when such a valid execution address does not exist. If a command such as XEQ is executed when there is no valid address, then SK*DOS will print error 28 (missing transfer address.) EXECAD $CC1E-CC1F ML execution address (2 bytes) These two locations hold the transfer address obtained when a machine language file is loaded from the disk. This location is also used by the XEQ command to execute the last-loaded program. ERRTYP $CC20 Error type This byte contains the number of the last error detected by the File Control System. OUCHSW $CC22 Output character switch INCHSW $CC23 Input character switch These two switch bytes are used to select which output or input vector is used for PUTCH and GETCH, respectively. When zero, these routines use OUTCH and INCH; when non-zero, they use OUTCH0 and INCH0 respectively. FOADDR $CC24-CC25 File output address vector FIADDR $CC26-CC27 File input address vector These two locations are used for redirection of standard output or input, respectively. If they are zero, no redirection is done. If redirection is desired, then one (or both) of the above vectors may contain the address of an FCB currently open for writing or reading, respectively, and also OUCHSW (or INCHSW) should be zero. CMFLAG $CC28 Command flag This location indicates whether the Command Processor System is processing a keyboard command (when 0) or a command passed to it from a user program (when non-zero). MEMEND $CC2B-CC2C Last usable memory address (2 bytes) When SK*DOS is initially booted, it does a memory test to determine how many 4K memory blocks are installed in the system, and then stores the top address of the last contiguous 4K memory block in these locations. For example, in a 56K system, MEMEND usually is equal to $BFFF, the top address just under SK*DOS. User programs can check these locations to determine how much user memory is available, or can change the contents to set aside memory for themselves. ERRVEC $CC2D Error file vector (2 bytes) When reporting errors, SK*DOS normally uses the ERRCODES.SYS file on the system disk. If, however, ERRVEC is non-zero, then SK*DOS will assume that ERRVEC points to the name and extension of a different error file. The name should consist of 11 bytes, with 00 bytes filling out unused name or extension characters. ERRVEC is initialized at 0000 when SK*DOS is initially booted. ECHOFL $CC2F Input echo flag This location tells the character input routine whether to echo output to the output port. A non-zero value (initialized to $FF at warm-start) enables echo. FNCASE $CC49 File Name case flag This location determines whether lower-case file names are allowed either as disk-resident command names, or as file names processed by the GETNAM function. The default value is $60, which allows only upper-case names (and lower-case names are automatically converted to upper case). Lower-case names wil be allowed if FNCASE is changed to $FF. MAXDRV $CC5F Maximum drive number This location is used to define the maximum drive number on the system. It is initialized to 03, and the maximum number it may have is 09. SK*DOS will return a drive number error whenever a drive number is specified in a file- spec which exceeds the value of MAXDRV. If your system has more than four drives, then MAXDRV should be increased correspondingly when the appropriate disk drivers are installed. 13. PROGRAMMING EXAMPLES This section shows several examples of how to use SK*DOS in writing programs which access the disk. THE LIST UTILITY The LIST program is one of the utilities supplied with SK*DOS. It is called with a command line which includes the name of the file to be listed after the word LIST, as in SK*DOS: LIST TEXT The program reads the file name from the line buffer, opens the file, and reads and prints one character at a time. The following listing shows how this is done. * LIST UTILITY FOR SK*DOS LEVEL I * COPYRIGHT (C) 1984 BY PETER A. STARK * EQUATES TO SK*DOS C840 USRFCB EQU $C840 SYSTEM FCB CD03 WARMST EQU $CD03 WARM START CD18 PUTCH EQU $CD18 OUTPUT CHARACTER CD24 PCRLF EQU $CD24 PRINT RETURN / LINE FEED CD2D GETNAM EQU $CD2D GET FILE SPECIFICATION CD33 DEFEXT EQU $CD33 DEFAULT EXTENSION CD3F PERROR EQU $CD3F REPORT ERROR NUMBER D403 FCSCLS EQU $D403 CLOSE ALL FILES D406 FCS EQU $D406 CALL FCS C100 ORG $C100 C100 20 01 LIST BRA START GO TO START C102 01 VER FCB 1 VERSION NUMBER * START OF ACTUAL PROGRAM C103 BD CD24 START JSR PCRLF START ON NEW LINE C106 8E C840 LDX #USRFCB POINT TO SYSTEM FCB C109 BD CD2D JSR GETNAM GET FILE SPEC INTO FCB C10C 24 0D BCC NAMEOK IF FILE NAME WAS OK C10E C6 15 LDB #21 ELSE IT'S ERROR 21 - FILE NAME C110 E7 01 STB 1,X STORE ERROR CODE IN FCB * ERROR ROUTINE C112 BD CD3F ERROR JSR PERROR PRINT ERROR CODE C115 BD D403 JSR FCSCLS CLOSE ALL FILES C118 7E CD03 JMP WARMST AND RETURN TO SK*DOS * FILE SPEC WAS OK; DEFAULT TO .TXT C11B 86 01 NAMEOK LDA #1 DEFAULT EXTENSION CODE C11D BD CD33 JSR DEFEXT DEFAULT TO .TXT * NOW ACTUALLY OPEN THE FILE C120 86 01 LDA #1 OP CODE FOR OPEN FOR READ C122 A7 84 STA 0,X SAVE OPERATION CODE C124 BD D406 JSR FCS AND GO OPEN THE FILE C127 26 E9 BNE ERROR IF NOT ZERO (Z = 0) * MAIN LOOP TO READ AND PRINT EACH CHARACTER C129 8E C840 MAIN LDX #USRFCB POINT TO SYSTEM FCB C12C BD D406 JSR FCS GO READ NEXT CHARACTER C12F 27 0C BEQ CHAROK GO ON IF NO ERROR * IF THERE WAS AN ERROR, SEE IF END OF FILE C131 A6 01 LDA 1,X GET ERROR CODE C133 81 08 CMPA #8 COMPARE WITH END OF FILE (IE) ERROR C135 26 DB BNE ERROR NOT END OF FILE, SO REAL ERROR C137 BD D403 JSR FCSCLS ON E-O-F, JUST CLOSE FILE C13A 7E CD03 JMP WARMST AND QUIT * CONTINUE IF CHARACTER IS OK C13D BD CD18 CHAROK JSR PUTCH OUTPUT CHARACTER C140 81 0D CMPA #$0D WAS IT RETURN? C142 26 E5 BNE MAIN NO, SO JUST CONTINUE C144 86 0A LDA #$0A C146 BD CD18 JSR PUTCH FOLLOW WITH LF C149 20 DE BRA MAIN AND ALSO CONTINUE END LIST The above example shows a variety of techniques. Note especially how it checks for the end of file. When the read routine detects an error, the error code is fetched from byte 1 of the FCB and examined. If it is an 8 (input past end of file), then the program simply finishes up. If it is any other error, then it goes to an error routine. THE BUILD UTILITY The following example shows how to open a file for writing and actually proceed to write into it. * BUILD UTILITY FOR SK*DOS LEVEL I * COPYRIGHT (C) 1984 BY PETER A. STARK * EQUATES TO SK*DOS CD03 WARMST EQU $CD03 WARM START CD15 GETCH EQU $CD15 GET KEYBOARD CHARACTER CD18 PUTCH EQU $CD18 OUTPUT CHARACTER CD1B INLINE EQU $CD1B INPUT INTO LINE BUFFER CD1E PSTRNG EQU $CD1E PRINT A STRING CD24 PCRLF EQU $CD24 PRINT RETURN / LINE FEED CD2D GETNAM EQU $CD2D GET FILE SPECIFICATION CD33 DEFEXT EQU $CD33 DEFAULT EXTENSION CD3F PERROR EQU $CD3F REPORT ERROR NUMBER D403 FCSCLS EQU $D403 CLOSE ALL FILES D406 FCS EQU $D406 CALL FCS C840 USRFCB EQU $C840 SYSTEM FCB CC14 LPOINT EQU $CC14 LINE BUFFER POINTER C100 ORG $C100 C100 20 01 BUILD BRA START C102 01 VER FCB 1 VERSION * ACTUAL START OF PROGRAM C103 8E C840 START LDX #USRFCB POINT TO SYSTEM FCB C106 BD CD2D JSR GETNAM GET FILE SPECIFICATION C109 25 3D BCS ERROR ON ERROR * IF NAME WAS OK, DO DEFAULT EXTENSION C10B 86 01 LDA #1 CODE FOR DEFAULT C10D BD CD33 JSR DEFEXT GO DEFAULT IT * NOW OPEN FILE FOR WRITE C110 86 02 OPEN LDA #2 OP CODE FOR OPEN FOR WRITE C112 A7 84 STA 0,X STORE IN FCB C114 BD D406 JSR FCS GO DO IT C117 26 38 BNE OPENNG ERROR ON OPENING FILE C119 8E C17F NXTLIN LDX #PROMPT PRINT PERIOD PROMPT C11C BD CD1E JSR PSTRNG PRINT IT C11F BD CD1B JSR INLINE INPUT AN ENTIRE LINE OF TEXT C122 BE CC14 LDX LPOINT POINT TO NEXT CHARACTER C125 A6 80 LDA 0,X+ GET CHAR AND BUMP POINTER C127 BF CC14 STX LPOINT SAVE POINTER C12A 81 23 CMPA #'# CHECK FOR # C12C 27 1D BEQ QUIT YES, SO GO QUIT C12E 34 02 NEXTL1 PSHS A SAVE CHARACTER C130 8E C840 LDX #USRFCB POINT TO FCB C133 BD D406 JSR FCS GO OUTPUT CHARACTER TO DISK C136 35 02 PULS A FIX RESTORE CHARACTER AND STACK C138 26 0E BNE ERROR ON ERROR C13A 81 0D CMPA #$0D WAS IT END OF LINE? C13C 27 DB BEQ NXTLIN YES, SO START NEXT LINE C13E BE CC14 LDX LPOINT POINT TO NEXT CHAR C141 A6 80 LDA 0,X+ GET CHAR AND BUMP POINTER C143 BF CC14 STX LPOINT SAVE POINTER C146 20 E6 BRA NEXTL1 AND REPEAT (IGNORE #) * PROCESS ERRORS C148 BD CD3F ERROR JSR PERROR C14B BD D403 QUIT JSR FCSCLS C14E 7E CD03 JMP WARMST * ERROR HANDLING ON OPENING FILE C151 A6 01 OPENNG LDA 1,X CHECK ERROR CODE C153 81 03 CMPA #3 WAS IT AE - EXISTS? C155 26 F1 BNE ERROR NO, MUST BE REAL ERROR * IF FILE EXISTS, DELETE IT? C157 8E C181 LDX #ASKDEL C15A BD CD1E JSR PSTRNG ASK WHETHER TO DELETE C15D BD CD15 JSR GETCH GET ANSWER C160 81 59 CMPA #'Y IS IT YES? C162 26 E7 BNE QUIT QUIT IF NOT C164 8E C199 LDX #ASKSUR C167 BD CD1E JSR PSTRNG ASK IF HE'S SURE C16A BD CD15 JSR GETCH GET ANSWER C16D 81 59 CMPA #'Y IS IT YES? C16F 26 DA BNE QUIT QUIT IF NOT * DELETE FILE IF OK WITH USER C171 8E C840 LDX #USRFCB POINT TO FCB AGAIN C174 86 0C LDA #12 CODE FOR DELETE C176 A7 84 STA 0,X STORE OPERATION CODE C178 BD D406 JSR FCS GO DO IT C17B 26 CB BNE ERROR ON ERROR C17D 20 91 BRA OPEN NOW OPEN FILE AGAIN * TEXT STRINGS C17F 2E PROMPT FCC "." C180 04 FCB 4 C181 46 49 4C 45 ASKDEL FCC "FILE EXISTS ... DELETE?" C198 04 FCB 4 C199 53 55 52 45 ASKSUR FCC "SURE? " C19F 04 FCB 4 END BUILD 14. DISK FORMAT AND RANDOM FILES A typical disk, whether hard or floppy, is divided into tracks; each track is then divided into sectors. The number of tracks and sectors on a disk depends on the type of disk and drive - a 5-1/4" floppy disk might have as few as 35 tracks with 10 sectors per track, or a Winchester hard disk might have as many as 256 tracks with 32 or more sectors per track. In addition, the disk drive might be able to use both sides of a disk, or a Winchester disk might have multiple disks spinning on the same axis. As far as SK*DOS is concerned, the exact number of sides, tracks and sectors is unimportant as long as there are at most 256 tracks (numbered 0 through 255) per drive and 254 sectors (numbered 1 through 255) per track. The exact positioning of those sectors and tracks is controlled by the disk drivers and FORMAT routine, not by SK*DOS itself. Each sector in turn contains 256 bytes of data. Of these 256 bytes, the first four are used for system information, and the remaining 252 bytes are usable for file data. SK*DOS uses a linked-chain disk format. That is, the sectors used in files, as well as sectors which are in the so-called 'free chain' are linked to each other much like the links in a chain. Each sector contains a two-byte pointer which points to the next sector in that chain (unless it is 0, which indicates the end of that chain.) This pointer occupies the first two bytes of every sector. In addition, the sector also has a number, which occupies the third and fourth byte, and which counts the sectors within a file. Thus the sector format looks like this: Bytes 1 and 2 - pointer to next sector Bytes 3 and 4 - sector counter Bytes 5 through 256 - 252 bytes of data Some sectors have a slightly different format, and may omit the pointer or sector counter. All the tracks on a disk can be used for storing data and program files except for track 0. The sectors on this track have special uses as follows: Sector 1 on track 0 holds the super-boot program. This is a program which is loaded by the boot program in the system ROM monitor, and which in turn loads the rest of SK*DOS into memory. (This sector has 256 bytes of data, as the first four bytes of the sector are used for regular data storage rather than being used as pointer and sector count bytes.) Sector 2 is normally empty. It has been set aside as an extension of sector 1 in case more than 256 bytes are needed, but most ROM monitors cannot load it into memory and so this sector is unused. Sector 3 is the System Information Sector or SIS. It contains the disk name and number, the date when the disk was formatted, the number of tracks and sectors on the disk, and three pieces of information about the free sector chain on the disk: the track and sector numbers of the first sector in the chain, the track and sector numbers of the last sector in the chain, and the total number of sectors in the chain. Sector 4 is unused. Sector 5 begins the directory, which extends to the last sector of track 0. Each directory entry requires 24 bytes, so there is room for 10 entries in each sector with 16 bytes empty. For example, on a 5-14" single density, single sided disk, there are 10 sectors in track 0. Hence there are six sectors in the directory, numbered from 5 to 10, for a total of 60 directory entries. The six sectors are linked (through the first two bytes in each sector, and the last sector has a pointer of 00-00. When the directory is filled up, however, SK*DOS will take a sector from the free chain and add it to the directory, so that the directory can be expanded to make room for more entries (although this may greatly slow down the operation of the system if the added directory sector is on one of the inner tracks of the disk since the disk head will have to step in and out each time it accesses the directory.) The directory for each file only gives the track and sector numbers of the first and last sector of the file; it does not contain any information as to which other sectors the file uses. Since the sectors of a file need not necessarily be consecutive on the disk - they could lie anywhere on the disk if the disk has been much used and its free space is not all in one place - the file itself contains information linking one sector to the next. This is done by the first two bytes in each sector, which contain the track and sector number of the next sector in the file. In a sequential file, we normally start reading or writing at the beginning of a file and then continue through the file, following these two-byte links until we get to the end. As pointed out earlier, the third and fourth bytes of a data sector contain a two-byte (four hex-digit) sequence number which numbers the sectors of a file. For example, the first data sector of a file has the number 0001, the second is numbered 0002, and the seventh would be numbered 0007. Don't confuse these sequence numbers with the physical location of the sector on the disk, which is sometimes called the sector's 'disk address', and which consists of a track number and a sector number. This sequence number could be used to make sure we read the sectors of a file in the right order, but in practice is almost never used with sequential files. Though we have used the term 'sequence number' above, in the rest of this discussion we will simply call it the 'sector number'. Some people also call it the 'record number', but this is a bit confusing since the word 'record' can also be applied to a part of a sector. Although sequential files are most common, we often need 'random' or 'direct access' files. These are files which allow us to read or write data in the middle of a file without necessarily reading or writing all the data before it. For example, at some point we might need to read data located in sector 0007, followed by sector 0104, followed by sector 0025, and so on. This is accomplished by the random file capabilities of SK*DOS. In order to allow us to rapidly locate a particular sector number in a file, without reading all the sectors before it, SK*DOS provides for a special random file format which contains an extra two sectors. These two sectors, which are always at the very beginning of a random file, contain a 'file map' of the file, which maps out the placement of the file on the disk and helps us to find a specific sector. These two sectors always have a sector number of 0000. Thus the very first data sector of any file is always sector number 0001, but in a sequential file this is the first actual sector of a file, whereas in a random file it is actually the third sector. (If you try to do a sequential read of a random file, SK*DOS skips the first two sectors and so you will never know they are there.) Few application programs actually need random files, but if they do, they will take care of generating and manipulating them automatically, through SK*DOS and its RANDOM command. Nevertheless, here is information on how this is done. There is only one way to generate a random file: 1. Open a file for writing with FCS operation 2. 2. After opening, but before writing anything to it, change byte 59 of the FCB to a non-zero number. 3. Now write sequentially to the file using operation 0. 4. When done, close the file with operation 4. SK*DOS will automatically put a two-sector file map at the beginning of the file, and will update it as data is written to the file. Note that the file map is customized for the particular placement of the file sectors on the disk. If you copy a file from one disk to another, the two file map sectors will be different since the copy will most likely be in a different place on the disk. But you need not concern yourself with this since SK*DOS does this automatically. Once the file is written, it can be read or updated (the data in it can be modified), or lengthened. But random files are usually made oversize to begin with, so there is room for adding more data at a later time without increasing the file size later. The file can be read sequentially just like any sequential file. If it is opened (with operation 1) and then read (with operation 0), it will look like any sequential file, since SK*DOS will automatically skip the file map sectors and read only the data sectors. Things are a bit more complex - and interesting - if the file is opened for updating. We now have a number of options, which are listed in the description of the Open for Update operation, code 3. The most important concept is that, by use of FCS operation 21, we can locate any sector number (that is, a sector with a desired sequence number) in the file in a short time. For example, we can tell SK*DOS to read sector number 0104 of a file. Given a sector number, SK*DOS will look it up in the file map, calculate the exact location of that sector, and then go directly to it. In using operation 21, we must be a bit careful ... we will get an error if we specify a sector number which does not exist. The alternative is to use operation 23, which acts just line 21, except that it will lengthen a file if a sector number is specified which is beyond the end of the existing file. In that sense, operation 23 is unique to SK*DOS; it does not exist in similar operating systems such as FLEX. Once we have located the specific sector, we can specify an exact byte of that sector, and either read it (with operation 17) or write it (with operation 18). Knowing that there are 252 data bytes in each sector, we could thus locate any particular byte in a file after some fairly simple calculations. For example, to locate byte N in a file, we could use the following two BASIC lines: Sector number = INT(N/252) + 1 Byte number = N - INT(N/252)*252 + 4 N in these equations is assumed to start with 0; the 4 in the second equation is due to the fact that the first data byte in a sector is actually numbered 4. For example, the 253rd byte in a file (which would actually be numbered 252) would be byte number 4 (the first byte) in sector 0002. And last, one final --> NOTE <-- You must execute the RANDOM command before doing any random file operations. Any attempt to use random files without calling RANDOM first will result in an error message. APPENDIX A. SK*DOS ENTRY POINTS This appendix lists the standard entry points into SK*DOS. NAME ADDRESS FUNCTION ---- ------------ -------- COLDST $CD00 Cold start WARMST $CD03 Warm start RENTER $CD06 Re-enter SK*DOS INCH $CD09 Input a character (alterable) INCH2 $CD0C Input a character (fixed) OUTCH $CD0F Output a character (alterable) OUTCH2 $CD12 Output a character (fixed) GETCH $CD15 Get input character PUTCH $CD18 Output character INLINE $CD1B Input into line buffer PSTRNG $CD1E Print CR/LF and string CLASFY $CD21 Classify alphanumeric characters PCRLF $CD24 Print CR/LF GETNXT $CD27 Get next character from buffer RESIO $CD2A Reset I/O pointers GETNAM $CD2D Get file name into FCB LOADML $CD30 Load open machine language file DEFEXT $CD33 Default extension ABX $CD36 Add B to X OUT5D $CD39 Output 5 decimal digits OUT2H $CD3C Output 2 hex digits PERROR $CD3F Print error code HEXIN $CD42 Input hexadecimal number OUT4H $CD45 Output 4 hex digits DECIN $CD48 Input decimal number EXECSD $CD4B Execute a SK*DOS command STATUS $CD4E Check keyboard for character MOVNAM $CD51 Move file specification PDATA $CD54 Print string (w/o leading CR/LF) INTIME $CD57 Input user-defined byte INNOEC $CD5E Input character without echo FCSINI $D400 Initialize FCS FCSCLS $D403 Close all open files FCS $D406 Execute FCS operation APPENDIX B. USER-ACCESSIBLE VARIABLES The following table lists those SK*DOS variables which are of interest to the machine language programmer, with the default values listed in parentheses. VARIABLE ADDRESSES FUNCTION NAME -------- ---------- -------- LINBUF $C080-C0FF Line buffer (128 bytes) BACKSP $CC00 Backspace character ($08) DELETE $CC01 Delete character ($18) ENDLIN $CC02 End of line character ($3A) PLINES $CC03 No. of printed lines per page (0) WIDTH $CC04 Page width in columns (0) NULLWT $CC05 Null wait constant (0) SLINES $CC08 No. of skipped lines bet. pages (0) PAUSE $CC09 Output pause control ($FF=yes) ESCAPE $CC0A Escape ($1B) SYSTDR $CC0B System default drive (0) WORKDR $CC0C Working default drive (0) REPEAT $CC0D Repeat character ($01) MONTH $CC0E Current date - month DAY $CC0F Current date - day YEAR $CC10 Current date - year LASTRM $CC11 Last terminator COMTAB $CC12-CC13 Pointer to command table (2 bytes) LPOINT $CC14-CC15 Point to line buffer (2 bytes) BREAK $CC16-CC17 Break address (2 bytes) CURRCH $CC18 Last character read from buffer PREVCH $CC19 Previous character read OFFSET $CC1B-CC1C ML loading offset (0) EXECFL $CC1D Execution address flag EXECAD $CC1E-CC1F ML execution address ERRTYP $CC20 Last error type SPECIO $CC21 Special I/O Indicator OUCHSW $CC22 Output character switch INCHSW $CC23 Input character switch FOADDR $CC24-CC25 File output address vector FIADDR $CC26-CC27 File input address vector CMFLAG $CC28 Command flag COLUMN $CC29 Current terminal/printer column MEMEND $CC2B-CC2C Last usable memory address ERRVEC $CC2D-CC2E Error file vector (0000) ECHOFL $CC2F Input echo flag FNCASE $CC49 File Name case flag ($60) MAXDRV $CC5F Maximum drive number USRFCB $C840-C97F User FCB (320 bytes) APPENDIX C. THE FILE CONTROL BLOCK (FCB) The first 64 bytes of an FCB (numbered 0 through 63 for this discussion) hold the following information: BYTE(S) CONTENTS ------- -------- 0 Function code (see Appendix D) 1 Error code (see Appendix E) 2 Read / write / update status 3 Drive number (0 through 9) 4-11 File name (8 bytes) 12-14 Extension (3 bytes) 15 File protection status 16 Copy protection status 17 First track of file 18 First sector of file 19 Last track of file 20 Last sector of file 21-22 Number of sectors in the file 23 Random file indicator 24 User-defined byte 25 Month of file creation (1 through 12) 26 Day of file creation (1 through 31) 27 Year of file creation (last two digits) 28-29 Next FCB pointer 30 Current track number (0 through 34) 31 Current sector number (1 through 18) 32-33 Current sector count(0 through 67) 34 Sequential Data pointer to next byte (4 through 255) 35 Random Data pointer to next byte (4 through 255) 36-46 Temporary name buffer 1 47 Directory track number 48 Directory sector number 49 Directory byte number 53-63 Temporary name buffer 2 59 Space compression indicator 60 Number of sectors per track (random only) 64 Beginning of data area APPENDIX D. FCS OPERATION CODES This Appendix describes the operation codes which can be used in byte 0 (the first byte) of a file control block: OPERATION FUNCTION CODE --------- -------- 0 Read or write next byte 1 Open a file for read 2 Open a file for write 3 Open a file for update 4 Close file 5 Rewind File 6 Open directory file 7 Read directory is SIS file 8 Write dir. or SIS data (same as 10) 9 Read a single sector 10 ($A) Write a single sector 12 ($C) Delete a file 13 ($D) Rename a file 15 ($F) Skip current sector 16 ($10) Open SIS sector 17 ($11) Read a random byte 18 ($12) Write a random byte 20 ($14) Find next available drive 21 ($15) Select a specified random sector 22 ($16) Backup to previous sector 23 ($17) Extend a random file APPENDIX E. SK*DOS ERROR CODES SK*DOS uses the following error codes; in addition, user programs (such as TSC Extended Basic) may use other error codes which are documented in their respective manuals. NUMERIC MEANING CODE ------- ------- 1 FCS operation code error 2 File already open or in use 3 File already exists 4 File does not exist 5 Directory Error 7 Disk is full 8 Input past end of file 9 Disk read error 10 Disk write error 11 Disk is write protected 12 Protected file 13 Error in closing file 14 Disk seek error 15 Invalid drive number 16 Drive not ready 18 This FCS operation not permitted on this file 19 Random file operation not allowed 20 Disk I/O error 21 Illegal or missing file name or extension 22 Can't Close error 23 Random file map overflow 24 Specified random sector number is invalid 25 Random sector number does not match file contents 26 SK*DOS command syntax error 28 Missing transfer address 29 Disk has been switched while file was open 30 File not open Internally, SK*DOS errors are represented by one-byte numbers which are generally placed into byte 1 (the second byte) of a file control block by the File Control System. User programs should test for these by their numbers. Error messages are generally printed out by using the PERROR routine, which prints out the error number, usually followed by a one-line explanation of the error. Error 1 (FCS operation code error) is treated a bit differently from the others. When it is encountered, SK*DOS immediately prints an error message and asks whether you wish to continue anyway. If you answer Y, then it will return error 1 to the calling program and continue; any other answer will immediately abort the program, close all files, and return to SK*DOS. APPENDIX F. DEFAULT EXTENSION CODES The following default extension codes are used by the DEFEXT routine: 0 = BIN 1 = TXT 2 = CMD 3 = BAS 4 = SYS 5 = BAK 6 = SCR 7 = DAT 8 = BAC 9 = DIR 10 = PRT 11 = OUT APPENDIX G. SK*DOS BOOT PROGRAM A boot program is needed to boot SK*DOS. This boot program is most often resident in the system monitor ROM, and so need not usually concern us. If, however, your monitor does not have an appropriate disk boot program, then this Appendix will be of interest to you. The function of the boot program is to load sector 1 of track 0 of the disk into memory and transfer control to it. The data loaded from this sector is called the 'super-boot', and takes care of loading SK*DOS itself. The super- boot program we normally furnish with SK*DOS is relocatable, and so it doesn't particularly matter where the boot program puts it. The following listing provides a typical boot program which works for DC-2 - type controllers. It is assembled to begin at location $0000, and it loads the super-boot program into memory at location $C100. * DISK BOOT FOR SK*DOS * DISK CONTROLLER EQUATES E014 DLATCH EQU $E014 DRIVE SELECT LATCH E018 CMDREG EQU $E018 FDC COMMAND REGISTER E018 STAREG EQU CMDREG FDC STATUS REGISTER E019 TRKREG EQU CMDREG+1 FDC TRACK REGISTER E01A SECREG EQU CMDREG+2 FDC SECTOR REGISTER E01B DATREG EQU CMDREG+3 FDC DATA REGISTER * ACTUAL BOOT PROGRAM FOLLOWS 0000 10CE DFBF FLBOOT LDS #$DFBF RESET STACK 0004 86 D0 LDA #$D0 FORCE INTERRUPT/RESET COMMAND 0006 B7 E018 STA CMDREG 0009 7F E014 CLR DLATCH DRIVE = 0 AND MOTOR ON 000C C6 03 LDB #3 000E 30 1F FLWAIT LEAX -1,X WAIT A BIT FOR MOTORS 0010 26 FC BNE FLWAIT 0012 30 1F FLWAI1 LEAX -1,X 0014 26 FC BNE FLWAI1 0016 30 1F FLWAI2 LEAX -1,X 0018 26 FC BNE FLWAI2 001A 86 0F LDA #$0F RESTORE, LOAD, VERIFY, SLOW 001C B7 E018 STA CMDREG 001F 8D 33 BSR SHORTD 0021 F6 E018 FL1 LDB STAREG LOOK AT FDC STATUS 0024 C4 01 ANDB #$01 BUSY BIT 0026 26 F9 BNE FL1 WAIT IF STILL BUSY 0028 C6 01 LDB #1 002A F7 E01A STB SECREG READY FOR TRACK 0 SECTOR 1 002D 8D 25 BSR SHORTD 002F 86 8C LDA #$8C READ SECTOR COMMAND 0031 B7 E018 STA CMDREG 0034 8D 1E BSR SHORTD 0036 8E C100 LDX #$C100 POINT TO MEMORY 0039 20 09 BRA CHEKST GO WAIT FOR DATA 003B C4 02 GTDATA ANDB #$02 CHECK DRQ BIT 003D 27 05 BEQ CHEKST NO DRQ, GET STATUS AGAIN 003F B6 E01B LDA DATREG DRQ, SO GET DATA 0042 A7 80 STA 0,X+ AND STORE INTO MEMORY 0044 F6 E018 CHEKST LDB STAREG CHECK STATUS 0047 C5 01 BITB #$01 BUSY BIT 0049 26 F0 BNE GTDATA IF STILL BUSY LOOK FOR DATA 004B C5 2C BITB #$2C WHEN NOT BUSY CHECK FOR CRC OR LD 004D 27 02 BEQ FLDONE DONE WHEN NO ERROR 004F 20 AF BRA FLBOOT REPEAT ON ERROR 0051 7E C100 FLDONE JMP $C100 GO TO EXECUTE SUPER-BOOT * SHORT DELAY FOR FDC TO SETTLE 0054 C6 14 SHORTD LDB #20 0056 5A SHORT1 DECB 0057 26 FD BNE SHORT1 0059 39 RTS END FLBOOT The 'super-boot' program which is on your SK*DOS disk must be customized to your particular disk controller hardware. In those cases where the super-boot and other disk adaptation is supplied by the hardware manufacturer, it is possible that the stack address in the very first instruction may conflict with the super-boot or disk drivers. If this boot program does not work with your configuration, the first thing to try would be to change the address DFBF in this instruction to something else, such as $1000 or some other address well out of the way. APPENDIX H. DISK RESIDENT COMMAND SUMMARY This appendix describes the disk-resident commands currently supplied with SK*DOS. It is quite possible, however, that additional commands are supplied on your disk if they are developed after the date this manual was last revised. In that case they are described in a file called READ-ME.TXT on the disk. To get an explanation of these commands, type LIST READ-ME. APPEND The APPEND command is used to combine several 'source' files together to make a single large 'destination' file. For example, it can combine a number of text files together into a large file, or can combine several machine language programs into one large program. APPEND writes a new destination file, with the original source files left unchanged. To use this command, type the word APPEND followed by the names of the source files to be combined, followed by the name of the resulting destination file. For example, the command SK*DOS: APPEND PROG1.BIN PROG2.BIN 2.PROG3.BIN 1.PROG.CMD would combine PROG1.BIN, PROG2.BIN, and 2.PROG3.BIN, in that order, into a new file called PROG.CMD on drive 1. (All of the source files must exist, and the destination file must not exist.) Although files of any type may be appended, usually all the files will be of the same type. The extension of the first source file defaults to .TXT if not specified otherwise, and the extensions of all succeeding files (source and destination) default to the same extension as the first file. When machine language program files having transfer addresses are appended, the transfer addresses are carried forward into the destination file, but the SK*DOS load routine uses only the last transfer address given. (There is one exception to this rule: when machine language code is appended to the end of a version of SK*DOS which has a transfer address, and the resulting DOS is booted, some boot programs may not load or use any code following the first transfer address.) BACKUP The BACKUP command is used to make an exact backup of a disk. This command requires two drives. If BACKUP encounters an error on either the source disk or the destination disk, it will print an error message but continue copying until it finishes the disk. To call BACKUP, enter the command BACKUP followed by the drive numbers of the source and destination drives, as in SK*DOS: BACKUP 0 1 This command would copy from drive 0 to drive 1. (The two drive numbers must be entered and must be different.) Note carefully - BACKUP copies from the first drive specified to the second drive. Before BACKUP can be used, you must format the destination disk with the FORMAT command. Furthermore, the destination disk must have at least as many tracks and sectors as the source disk. If it has fewer tracks or sectors, then BACKUP will display an error message and stop. After BACKUP is finished, the destination disk will have the same apparent number of tracks and sectors as the source disk. For example: suppose you BACKUP a 35-track single density 5-1/4" disk (ten sectors per track) onto an 77-track double density double sided 8" disk. The destination disk will have only 35 tracks and ten sectors per track. (In reality, the remaining tracks and sectors will still be there, but will be completely inaccessible to SK*DOS from then on.) BASIC BASIC is a simple public domain Basic interpreter supplied with SK*DOS for testing purposes. It is a 4K floating point Basic which provides accuracy to 9 digits. It does not support strings or scientific functions, but does support all of the following: FOR ... TO ... (STEP) GO TO RUN INT( ) ON ..... GOTO IF ..... GO TO LIST TAB( ) ON ..... GOSUB IF ..... THEN NEW ABS( ) PRINT LET STOP CHR$( ) INPUT REM DIM READ DATA GOSUB RESTORE NEXT RETURN (It does not currently support SAVE or LOAD.) This Basic is a modification of the (by now almost classical) 4K Basic written by Robert H. Uiterwyk for the first SWTP 6800 machines in the mid seventies. The Basic interpreter is in the public domain and the original Version 2.1 source code is available in the book "Best of Interface Age, Volume 1: Software in BASIC", published in 1979 by dilithium Press, P.O. Box 92, Forest Grove OR 97116. We greatly recommend this book for further information about this interpreter. Basic error messages are printed in the form ERROR # xx IN LINE xxxx The line number identifies the location of the error in the program. If the line number is 0000, then the error occurred in a command or direct execution statement. The error codes are as follows: 01 - Variable greater than the allowable 255. 02 - Error in input. 03 - Illegal character or variable 04 - Missing quote 05 - Error in DIM 06 - Illegal arithmetic 07 - Reference to nonexistent line number 08 - Divide by zero error 09 - Excessive subroutine nesting 10 - RETURN without a prior GOSUB 11 - Illegal variable 12 - Miscellaneous error 13 - Parenthesis error 14 - Memory full 15 - Subscript error 16 - Too many nested FOR loops 17 - NEXT without prior FOR 18 - Error in loop nesting 19 - Error in READ statement 20 - Error in ON statement 21 - Input line too long BEEP NOBEEP Assuming that your terminal supports the BELL character (ASCII $07), the BEEP command will sound the bell (or beep) at each SK*DOS: prompt from then on. This is a useful function if you like to walk away from your computer while it is doing a lengthy task. Once the BEEP command is given, the bell will sound until the computer is rebooted, or until the NOBEEP command is used to cancel BEEP. BUILD BUILD is used to generate a text file on the disk. BUILD is not intended to replace a more general purpose editor; instead, BUILD might be used for testing or generating simple files. The BUILD command line must include the name of the file to be generated. This is usually done by including a file specification after the word BUILD, as in this example: BUILD TEXT The file specification defaults to a .TXT extension unless specified otherwise, and also assumes the current working drive. While entering text with the BUILD command, you may correct any line by backspacing and retyping a character. Or, while still in the middle of a line, you may erase the entire line and start it over by hitting the control-X key. Once the line is entered by hitting the carriage return key, however, it is stored and cannot be changed. In other words, BUILD is not an editor. The BUILD program ignores control characters, and is limited to a maximum line length of 127 characters. To end entering text, type a # character at the beginning of a new line. CACHE (Although a disk cache can be added to any computer if it has enough memory, at this time we support the CACHE command only for 128K Color Computers using the DSL 128K RAM expansion module. Color Computer owners may consult the CACHE.TXT file for an example of how to prepare a CACHE program for other memory expansion modules; further details are also contained in the SK*DOS Configuration Manual.) CACHE allows you to use the extra 64K RAM of a 128K Color Computer as a disk cache. The word 'cache' means 'storage place' or 'hiding place'. A disk cache is simply an area of memory used to store disk data. Each time Color Computer SK*DOS reads or writes a sector of data on any drive, it also places the contents of that sector in the cache memory. Each time SK*DOS or a program running under it asks to read a disk sector, the cache program first checks to see whether that particular sector is already stored in the cache; if it is, then SK*DOS takes it out of the cache instead of reading it from the disk. Using memory in this way instead of using the disk greatly speeds up the operation of the computer. In order to keep the cache memory organized, the cache program maintains a 'cache map' which lists which sector is where and how long ago it was last used. The 64K of cache memory has room for only 256 sectors, so it is quite likely that it will soon get filled up. When that happens, the cache program will remove from the cache memory those sectors which have been unused the longest, and put in the new sectors instead. Hence sectors which are often used, such as directory sectors or often used commands such as CAT or DIR, will almost always be available for immediate use, while files seldom used will either never go into the cache at all, or will be erased from the cache when they are no longer needed. To use or initialize the cache, simply enter the command CACHE When used for the first time, this command sets up the instructions needed to use the cache memory, and then 'flushes' or erases that cache. From now on, all disk operations will use the cache automatically without your even being aware of it. PLEASE NOTE: VERY IMPORTANT! When using a disk cache, the computer may use either the cache memory or the disk for disk operations. If you pull out a disk and substitute another, the computer has no way of knowing that you did this. Hence it will probably continue using the directory from the old disk (which is still in the cache memory) with the new disk, almost certainly resulting in the new disk being clobbered. To avoid this scary possibility, you >>> MUST <<< flush the cache whenever you change disks. You may flush the entire cache with the CACHE command, but there is a better way: follow the word CACHE with the number of the drive where you have swapped disks. For example, if you swap disks in drive 1, you should give the command CACHE 1 This will flush only data for drive 1 from the cache, and all data from other drives will still remain. In addition to the 64K of the 128K memory expansion, CACHE also uses about 1.8K at the top of user memory. When it is first invoked, CACHE moves the MEMEND pointer down to make room for itself. For example, in most normal applications MEMEND will be $BFFF when SK*DOS is started, and will be changed to approximately $B980. CAT CAT is used to obtain a catalog or directory of a disk. This command and documentation is being supplied through the courtesy of Bruno D. Puglia and Leo E. Taylor. At its simplest level, the CAT command consists of just the word CAT, followed by an optional drive number. If no drive number is specified, then the current working drive will be used. For example, the command CAT 1 will display a directory of the disk in drive 1. There are several option letters supported in CAT which make it a very powerful utility and maybe a bit overwhelming at first. As you use CAT you will begin to learn what the options are and how to use them effectively. All options are entered on the command line. If you have trouble remembering what the letters do, the CAT help list can be displayed by entering a command of CAT +. Options are preceded by a + sign, and should follow after the word CAT, as in CAT +SDF1 1 If an unimplemented option letter is used, CAT will display the HELP list. CAT uses positive option logic. Entering an option letter on the command line will turn the option on. All others are turned OFF so you must enter ALL options you want if you enter any at all. CAT + will display CAT's HELP list which summarizes the available options in the following format: - Display - - Comments - No A Alpha Alpha A,B,C type listing No D Date Display file Date No F File # Display DIR File number No M Maxi-DIR DIR full listing No N Non-existent Display Deleted files with (-) No P Paging Paging with printer column width No R Repeat Repeat CAT as listed on command line Yes S Size Display file sector Size This display shows that the S option defaults to Yes, while each of the others defaults to No. The following options are available: A CAT IN ALPHABETICAL GROUPS The "A" option will group the listing by the first letter. This simple form of alphabetical CAT must scan the entire directory for each letter and this will take time. When the "A" option is used you cannot use any match strings. Additional information is given later. D DISPLAY FILE DATE The "D" option will display the file's creation date. Not all SK*DOS users use real dates when first booting up SK*DOS so if the month is zero or over 12, CAT will display the month as "BAD". Dates can be very useful with our programs so the user will find it advantageous to use current dates. F LIST THE DIRECTORY FILE NUMBER The file number option will list the actual directory number. M MAXIMUM LISTING The "M" option turns CAT into a DIR type program. The "M" option will provide information on track-sector data and the protect file code information. The "M" option turns on the D,F and S options plus routines needed for the header, track and sector, and protect codes. You can still add option letters to enhance the DIR type listing. N LIST NON-EXISTING (DELETED) FILES The N option was chosen as "NON EXISTING" because it will display deleted file entries that exist in the directory. The actual file may not exist on the disk - it may have been over-written when it was part of the list of free sectors. You cannot assume a deleted file is intact unless you know it was recently deleted and you have not written enough new files on the disk to reuse the deleted file's sectors. In the disk's directory a deleted file will have the first letter of the file name changed to a $FF. CAT will display the $FF as a dash (-) as the first character of the file name. It is not a good practice to use one or two character file names since the first letter is deleted from the name when a file is deleted. When the "N" option is combined with the "M" option the DIR type listing will get you the starting sector of the deleted files in the directory. P PROVIDE A PAGED LISTING and USE PRINTER WIDTH EQUATE The "P" option will enable a paging subroutine. It will place blank lines on the top and bottom of the page. This is handy when listing a disk with a large number of files. The printer width equate is picked up and used to calculate the number of columns allowed for each form of the printed listing. R REPEAT OF CAT USING THE EXISTING COMMAND LINE The "R" option allows CAT to re-start. A prompt will appear at the end of each CAT; enter "E" to exit to SK*DOS, or hit any other key to do another CAT as originally listed on the command line. This option will allow you to change disks and do a CAT without re-entering the data on the command line. The user can select CAT options to control the type of information listed in the disk file. S DISPLAY FILE SECTOR SIZE The "S" option will enable the sector size of files to be displayed. EXAMPLES CAT List all files on the work drive using the default option S. CAT 0,1 C .BAS List all files starting with the letter C and all .BAS files on drive 0. After drive zero is done list drive 1. Since no options were given defaulted options will be used. CAT + Display HELP list showing options and defaulted options with a "YES" next to option letter. CAT +2 1 Display listing of the file names only for drive 1 in two columns. You may override the automatic column count by entering an option of 1-9. CAT +MA Display a DIR-type listing including the file number, name.ext, size, starting and ending track and sectors, date and protect codes and in "A" alpha groups of A B C etc. P CAT +MNP Print a DIR-type directory including all deleted files and page the listing. P CAT +ASDFP Print Alpha grouped listing to printer with the file number, name.ext, size and date. MEMORY USAGE Before discussing the features in CAT please accept the fact that CAT is a large program and we were committed to writing a CAT program that would fit into the utility space provided for by SK*DOS. We have attempted to squeeze in as many features as possible in the limited memory space. Alternate memory locations could be used and we made CAT re-enterable so the program could be moved to other free RAM areas like $E800. CAT can be re-used without being reloaded from disk since all variables (including default options) are initialized at the start of the program. The following sample shows what each CAT entry means: SK*DOS: CAT +M C R DRIVE: 2 DISK: SOURCE 4 CREATED:31-May-82 FILE# NAME TYPE BEGIN END SIZE DATE PRT 2 COPY99 .TXT 29-03 11-0F 128 21-Jun-82 D 12 RANDOM /SYS 01-01 01-03 3 3-Nov-81 FILES=21 BIGGEST=206 TOTAL=280/1029 FREE=111 DRIVE: The drive number that was catalogued. DISK: The disk name and number. CREATED: The date the disk was initialized. FILE#: Sequential number of the file in the directory. This catalog only shows files starting with C or R. If all files were catalogued then the numbers would count up from one. NAME/TYPE File name and extension. When a slash "/" appears in CAT as a separator the file was created as a random file. This marking is for display purposes only; when accessing a SK*DOS file extensions are always separated by a period. SIZE: Length of file in sectors. BEGIN/END: Starting and ending disk sectors for file. DATE: The date file was created or edited. PRT: The three SK*DOS protect codes are indicated by letters. The catalog protect bit is not honored by this CAT. C - catalog protect D - delete protect W - write protect FILES= Total number of files in the disk directory. BIGGEST= Largest file on the disk. TOTAL= Total number of sectors displayed followed by the total number of sectors used on the disk. FREE= Sectors remaining for use. ADDITIONAL FEATURES A simple A B C type alpha type sort was included in CAT for those disks which are not already alphabetized. Since the scan process will go through the entire directory for each letter A thru Z, the "A" alpha option may take a great deal of time. We have elected to use the "+" sign for options since it is consistent with other SK*DOS programs. The addition of having HELP built into CAT is required when several option letters are used. Automatic selection of the number of columns for both the display terminal and the printer make this CAT unique. CONCLUSION The programmers who wrote CAT hope you will enjoy using this new utility. As far as we know CAT is bug free. It is possible that you may locate a bug or make improvements to our CAT. We hope you would inform us if you make any changes. CAT, COPY, DATE, and FIND were written by, and provided through the courtesy of, Bruno D. Puglia and Leo E. Taylor. COMPARE The COMPARE command requires two drives, and does an exact, byte by byte, comparison of two disks. It is thus useful for checking whether a disk has been backed up correctly (although BACKUP will do its own checking if the verification mode is on.) To use COMPARE, type the word COMPARE followed by the drive numbers of the two drives holding your disks, as in SK*DOS: COMPARE 0 1 which would compare the disks in drives 0 and 1. If you want to check whether a single disk is readable, you may also specify the same drive number for both disks, as in SK*DOS: COMPARE 0 0 This mode reads a single disk twice, and checks not only that it is readable, but also that the same data is read both times. COPY COPY is used to copy files from disk to disk. This command and documentation are being provided through the courtesy of Bruno D. Puglia and Leo E. Taylor. In its simplest form, the COPY command is used by entering the word COPY, the file-spec of the file to be copied, and the file-spec of the destination. For example, COPY 0.PROG.TXT 1.NEWPROG.ABC would copy PROG.TXT from drive 0 to a new file called NEWPROG.ABC on drive 1. It is also possible to copy a file as follows: COPY 0 1 PROG.TXT which would copy PROG.TXT (and all other files whose name begins with the letters PROG) from drive 0 to drive 1. Additional file names can be specified as in this example: COPY 0 1 A B .BIN which would copy all files whose names begin with A or B, or which have a .BIN extension. In addition, however, COPY has a number of other options which are explained below. Throughout this description these terms will be used often: COPY the new program OLD COPY the program provided with SK*DOS SOURCE the file being copied from (any type of file) DESTINATION the file being written to OPTION LETTERS command line letters used to enable options MATCH LIST list of starting characters (see below) OPTION LETTERS There are over a dozen option letters supported in COPY which makes it very powerful and a bit overwhelming. It is important to know that you do not need to understand all of the options to use COPY effectively; in fact there are some options you may not WANT to use. If you can't remember the letter for the option you need you can type "COPY" without any parameters and the program will display a HELP list of option letters with a short explanation of each. Option letters are included on the command line after the word COPY and before any drive number or file name: COPY LDN 0,1 A.TXT Any number of letters may be used in any order. If an unimplemented letter is used COPY will display the HELP list of options. Options are positive; that is using the letter will enable the option. If a letter is accidentally used twice the option is still enabled. Typing COPY with no arguments will display the options currently in effect, as in this example: A copy in Alphabetical order C allow Corrupt files to be copied D copy files with newer Date E delete Existing destination file F copy by File number (alpha not allowed) K Kill duplicate file on source L List files without copying M Make random file N copy files Not on destination O turn Off defaults P Prompt before copying file R Recover from track-sector S makes Second copy of file (.CPY ext) T Track zero protection override U Use current SK*DOS date W Wait for disk change Z Zap source file after copying EXPLANATIONS OF OPTION LETTERS A COPY IN ALPHABETICAL ORDER The "A" option enables a sort subroutine that will alphabetize the source directory before files are selected to be copied. C ALLOW CORRUPT FILES TO BE COPIED The "C" option will enable you to copy a file that is damaged by a CRC error or record sequence error. This is a slightly dangerous option which should only be used if you don't have an alternate copy of a file. D COPY FILES WITH A NEWER DATE The "D" option will find files that are on both disks and compare their creation dates. If the source file is newer it will be copied as a replacement for the older destination file. E DELETE EXISTING DESTINATION FILE The "E" option is used when you want to replace a file on the destination disk. This option will suppress the prompt for whether you wish to delete the existing file. It will often be used along with "D" to update a disk with newer versions of programs. F COPY BY FILE NUMBER The "F" option changes copy's parameters from a match string list to a list of file numbers. Follow the drive numbers with a list of file numbers for those files that you want to copy. File numbers can be found with a utility such as CAT.CMD. A group of files can be specified as a starting and ending number separated by a dash. The command "COPY F 0,1 5 13-18 9" will copy file five, files thirteen through eighteen, and file nine. K KILL DUPLICATE FILE ON SOURCE The "K" option is VERY dangerous. This command isn't really a copy, rather it uses the directory compare routines to delete files from the source disk that appear on the destination. This allows you to clear off extra copies of programs not needed on the source disk. It operates very fast and will clear off a number of files faster than you can hit reset. As with all dangerous options it is protected with an "ARE YOU SURE" prompt. "COPY K 1,0" is most effective in killing files on drive 1 when they exist on drive 0. "COPY KD 1,0" will kill the file on drive 1 when it is older than the file on drive 0. Use COPY KDL 1,0 to preview what files will be deleted. L LIST WITHOUT COPYING The "L" option disables the file copy subroutine. This is used to display a list of files that WOULD have been copied if you hadn't used option "L". This can be used with other options to check disks for duplicate files, newer dates, bad files, etc. M MAKE RANDOM FILE The "M" option can be used to convert a SK*DOS serial file into a random file. This option is also used with "R" to recover a random file by track and sector. NOTE: this option is not used for normal file copying, if the source file is random COPY will make the destination file random. N COPY FILES NOT ON DESTINATION The "N" option is used to copy the files on the source disk that are not already on the destination disk. This can be used to add all new files to a backup disk. O TURN OFF DEFAULT OPTIONS The "O" option is a dummy character used to turn off all default options if you do not want any options. If used with any other option letters it has no effect. P PROMPT BEFORE COPYING The "P" option enables this prompt: "Prompt off (P):SK*DOS (S):copy (Y/N)?". You should respond with "P" if you want to continue copying without the prompt or "S" to return to SK*DOS or "Y" to copy this file. "N" or any other character will skip to the next file. This is useful for scanning through a disk copying only certain files. Another use is skipping down to a certain file on a disk and copying all files after that. R RECOVER FROM TRACK-SECTOR The "R" option is used to read a file without using the directory. If the directory of a disk has been destroyed but the user knows the the file's starting address, the file can be recovered. The command "COPY R 1 2B 5 0.NEWFILE" will read from drive 1, track $2B, sector 5 until encountering an end of file or a record out of sequence. The write file extension will default to .SCR. A second use for this option is to recover a deleted file. The first sector of a deleted file can be found with the CAT.CMD. If the file has not been over-written, COPY can recover it. Record sequence checking eliminates the restriction that the file be the last file deleted. Provision was made to start copying in the middle of a file. This is a somewhat dangerous option since it allows the user to override the SK*DOS File Control System. The command must be typed as shown with three numbers and a file name. Only a few other options can be used with "R". See "M" if the original file was random. S MAKE SECOND COPY OF A FILE The "S" option is used when you want two copies of a file to be written. The second copy will have the same name as the first with the extension of ".CPY". This is useful when sending a program to a friend whose drive may have difficulty reading your disks. By sending two copies there is a much higher chance that the file will be readable. T TRACK ZERO PROTECTION OVERRIDE The "T" option is used only for those systems that store data files on track zero. COPY normally prevents a file from linking to track zero. Some virtual disk systems include track zero as part of their free sector chain. U USE CURRENT SK*DOS DATE The "U" option is used when you want the destination file to have the present SK*DOS date rather than the date of the source file being copied. This may be useful if you know the source file has an erroneous date. W WAIT FOR DISK CHANGE The "W" option eliminates the need to copy COPY.CMD onto the source disk so that you may remove your system disk to insert the destination disk. When "W" is used on the command line COPY will wait for a key to be pressed before accessing any directories. Z ZAP SOURCE FILE AFTER COPYING The "Z" option is somewhat dangerous. It is used to delete the file from the source disk after it is copied. Essentially the file is moved from one disk to the other. EXAMPLES Often options can be combined to perform tasks that previously were impossible or required a separate command utility. Some examples: COPY C 0.BAD.TXT 1 Copies one file that has a CRC error, including whatever data is readable from the bad sector. COPY DN 0,1 Updates the destination with all files from the source that are not on the destination or have an older date on the destination. COPY EZ 0.P.CMD 2 Moves file P.CMD from source to destination no matter what. COPY F 2,0 1-16 COPY F 2,1 17-52 Useful for copying from one large drive to two smaller ones. Copies sixteen files to drive zero and the remainder to drive one. This is VERY difficult to accomplish otherwise. COPY KD 1,0 Kill the file on drive 1 when it is older than the file on drive 0. COPY LNA 2,1 Alphabetically lists those files on the source that are not on the destination. COPY M 2.FOO.DAT 3 Make a serial file FOO.DAT into a random file. COPY P 0,1 Prompt before each file is copied to allow user to select which files are desired. COPY R 2 4 6 1.FOO Recover a file on drive 2 that does not appear in the directory. Reading will begin at track 4 sector 6 and the file will be written to drive 1 with the name FOO.SCR. COPY W 0,1 .CMD After COPY is loaded the user is prompted with "Change disk- press key". The system disk may be removed and another disk inserted. DANGEROUS OPTIONS A few option letters enable dangerous functions such as killing the original file on the source drive. These options should only be used by an "Experienced Copier" and are protected with this prompt: dangerous option selected are you sure (Y/N)? If you accidentally stumble on a dangerous option type "N" and you will be returned to SK*DOS. With proper use these options can be quite useful. ERROR DETECTION COPY has many error checks that are not found in other SK*DOS utilities. One error COPY traps is files with a size of zero sectors. These files usually result from pressing reset while doing file operations. Novice SK*DOS users do not realize that if they reboot SK*DOS after aborting with reset a defective file is left on the disk. When a program like the TSC EDIT.CMD opens a file, SK*DOS creates a directory entry with zero sectors. If the program is aborted with reset or the disk is removed the zero sector file remains in the directory. Later, when the disk is copied, the defective file will result in the entire free space of the disk being copied. This copy "runaway" results in the destination disk being clobbered. Another problem which is eliminated with COPY results from a bad link in the source file causing it to intersect with another file. A third error solved by COPY is a bad link on the destination disk causing the file to overwrite the directory. COPY also will not waste time trying to copy a file that wouldn't fit in the available space on the disk. COPY will catch this error and report "file will not fit". COPY has several of the common SK*DOS error messages built in. In addition, the drive associated with the error is reported along with the offending track and sector. This is useful for such errors as CRC which could occur on either the source or destination drive, and in the file or the directory. It is important to realize that if you get an error while writing a file to the destination disk the new file may be defective. The file may appear in the directory but usually it is incomplete. The most common error message reported by users of COPY is "DATE BAD". This occurs when the user does not enter a valid date when SK*DOS is booted or by failure of a hardware clock when used for setting the SK*DOS date. COPY will check the date on all files when it reads the disk directory and report any dates outside a reasonable range. This reduces the chance that a bad date will be passed on to the new file. There are two alternatives when the "BAD DATE" message appears. You can answer "Y" indicating that you approve of bad dates or answer "N" and not copy the file. After returning to SK*DOS you can re- enter COPY using option "U" which will assign the current SK*DOS date to the file or use the new DATE command to set the file date to the day the file was made. MEMORY USAGE COPY uses 4-5K bytes of memory starting in base page for variables, program, messages, and file control blocks. The directories are loaded into memory after the FCBs and require 16 bytes per file. This puts a limit on the maximum number of files at 2600 for a full size 6809 system. This should not be a limitation for most SK*DOS users. The remaining user memory (less $800 bytes reserved for EXEC) is used as a buffer for the file being copied. NON-STANDARD SK*DOS ROUTINES Considerable care was made to determine that COPY would work on all SK*DOS systems. All accesses to the disks were made through the File Control System to avoid compatibility problems with user written disk drivers. Still, it was necessary to use a few tricks in order to make the program more useful. The FCS does not provide a means for determining if a disk is protected or even if it exists without attempting to write on it. This is the FIRST thing a program should do so the user doesn't waste time answering prompts only to find the program aborts later. COPY reads the SIS (sector 3) of the destination disk then duplicates it on sector 4. This is an unused sector on all systems tested. If the disk is protected or not ready the program will exit immediately. COPY checks the next to the last byte ($FE) of the SIS for an extended directory flag. This byte is set non-zero by some users to indicate the catalog has been extended to include all of track 1. If this flag is set COPY will protect track one as well as track zero. Finally the file date is inserted into the destination file FCB before the file is closed. This is done to keep the original date on the new file. None of these "tricks" have produced any problems for the SK*DOS users who have tested COPY; they are only mentioned in case someone has a problem with COPY that appears to be compatibility. COMMENTS on DATES and FILE NAMES Many SK*DOS users are lax in entering the correct date when booting their system. With the COPY utility the date takes on new significance since the date reflects when the file was originally created. To use the alphabetizing feature of COPY to its full advantage one should assign similar file names to similar files. For example, an assembler library file should have a name as close as possible to the assembler file it goes with. A documentation file could have the same name as the program it is documenting with an extension of ".DOC". This will keep the files together when copied. CONCLUSION The programmers who wrote COPY hope you will enjoy using this SK*DOS utility. COPY is written to be compatible with SK*DOS systems that use any 6809 processor and any disk controller. DAMON DAMON is a trouble-shooting program which displays the drive, track, and sector number of each sector being written or read by SK*DOS, and the address of the current File Control Block. You might use it whenever you want to follow SK*DOS disk accesses to see what it is doing. DAMON cannot be used with CACHE or RAMDISK as it conflicts with them. It also makes disk accesses run slower. Moreover, once DAMON is activated, the only way to turn it off is to reboot the system. Hence it is a specialty program, to be used only when needed to debug a program. DATE DATE allows you to change the SK*DOS system date, disk date, file date, disk name, or disk number. This command and documentation is being supplied through the courtesy of Bruno D. Puglia and Leo E. Taylor. Since the DATE command has many options, the best way to explain it is by a few examples: SK*DOS: DATE Display current date. SK*DOS: DATE 12,27,81 Change SK*DOS system date. SK*DOS: DATE FILENAM.EXT Change file to current date. SK*DOS: DATE 1,2,82 FILENAM.EXT Change file date. SK*DOS: DATE + Help with syntax. SK*DOS: DATE + 12,25,81 Change disk creation date. SK*DOS: DATE +DISKNAME 12345 Change name and number. SK*DOS: DATE+12,25,81 DISKNAME 321 Change all three. Including '+' between the command and the first parameter allows you to change the disk creation date, volume name, and volume number. Any items may be changed at once but they MUST be in the above order. Notes: In accordance with tradition all dates are specified as MM,DD,YY. Commas and spaces are interchangeable. Default drive is the assigned work drive and may be overridden as in 1.FILENAME.EXT or 2.DISKNAME. Default extension is .TXT. DELETE DELETE is used to delete a disk file from a disk. To delete a file, enter the command DELETE followed by the file name, as in DELETE TEXT.TXT The extension is required. You may delete several files with one DELETE command by specifying more than one file name. The maximum length of the entire DELETE command, however, is limited to 128 characters. FIND FIND may be used to find specific occurrences of (a) a string in a text file, or (b) a hex number or string in a binary file. This command and documentation is being supplied through the courtesy of Bruno D. Puglia and Leo E. Taylor. The program has two modes of operation: Text mode is entered without an option letter on the command line and will list all occurrences of a string in a text file. The default extension is .TXT. Binary mode is entered with an option letter (A,H,S) on the command line. The program will search a binary file for each match of address, hex bytes, or string. The program will stop and list record number, track, sector, byte number, program address, and the file contents at the program address. The default extension is .CMD. Here are some examples: FIND (no parameters) displays examples of commands. FIND filename string lists all the lines containing "string" in text file. FIND filename A AC00 prints file and disk address when the program address matches address on command line. FIND filename H 7E AD03 prints file and disk address for each occurrence of hex data '7E AD03' in binary file. Up to 128 bytes can be entered with or without spaces. FIND filename S string prints file and disk address for each occurrence of string in binary file. Definitions of option letters A address to find C complete file without prompting H hex data to find N proceed to next occurrence S string to find CR return to SK*DOS FORMAT FORMAT is used to initialize a blank disk and prepare it for use with SK*DOS. It completely erases a disk, writes the System Information Sector on the disk, initializes an empty directory, and sets up the remainder of the disk as free space. This section describes the FORMAT command in general terms; the particular FORMAT command provided for your particular disk controller may be slightly different, but the general operation will be the same. (There may be additional information supplied with this manual describing FORMAT in greater detail.) To format a disk, enter the command FORMAT followed by the drive number. For example, SK*DOS: FORMAT 1 would format the disk in drive 1. FORMAT will then ask HOW MANY TRACKS? to which you may answer any number from 2 through 80. Be sure not to specify more tracks than your drives can handle. You will normally answer 35 or 40, but formatting fewer tracks is often convenient when you wish to save time and don't need as much space on the disk. If your disk controller supports double-sided or double density operation, the next questions will be SINGLE OR DOUBLE SIDED? SINGLE OR DOUBLE DENSITY? Answer with an S or D, as appropriate. You will next be prompted ENTER DISK NAME: ENTER DISK NUMBER: The disk name must conform to standard file-name rules (and may have an extension!) and the number may go from 0 through 65535. IMPORTANT NOTE Although a disk name and number are not required to use a disk, you should get in the habit of putting a distinctive name and number on every disk because SK*DOS periodically checks them to make sure you have not switched a disk while a file is open on it. Giving every disk the same (or no) name and number will defeat this file protection method. While formatting the disk, FORMAT will display a track indicator to let you know its progress, and may display messages if errors are encountered. Most of FORMAT's time is spent checking each sector written to make sure it is readable. Unreadable sectors are removed from the chain of sectors, and at the end of the formatting process, FORMAT displays the number of good free sectors available on the disk. Any number of defective sectors can be thus bypassed, but formatting will be aborted if an error is discovered in several crucial sectors of track 0 (sectors 1, 3, or 5). (See also the LINK command description). INPIPE & OUTPIPE Any program which uses the standard input and output - usually a keyboard for input and a video screen for output - can have this input and/or output redirected via a disk file by using the INPIPE and OUTPIPE commands. Pipes are a mechanism for letting the output of one program be the input for another. On systems which allow two or more programs to run at the same time, the pipe is simply a large buffer which is filled by one program and emptied, more or less at the same time, by another. On systems which allow only one program to run at a time, which applies to most microcomputers, the pipe is a disk file which is first written by one program, and then read by the second at a later time. The OUTPIPE command is almost identical to the O command, except that the default extension type is .PIP rather than .OUT. To redirect the output of any program to a disk file, place the command OUTPIPE= before the command to be executed. For example, the command SK*DOS: OUTPIPE=TEMP CAT 1 would do a CATalog of drive 1, but write the catalog listing into a file called TEMP.PIP instead of displaying it on the screen. The INPIPE command does the opposite - it causes the following command to take its input from a disk file rather than from the keyboard. For example, the command SK*DOS: INPIPE=TEMP BUILD TEXT would BUILD a text file called TEXT, but take its input from TEMP.PIP rather than from the keyboard. In other words, INPIPE and OUTPIPE provide a simple means for one program to send its output to another. There are a number of other applications for INPIPE as well. For example, when deleting a number of files, the DELETE command repeatedly asks you whether you are sure, and you must reply Y each time. It is possible to construct a file called Y.PIP which contains nothing but a long string of YYYYYYYYY... and then call DELETE with INPIPE=Y DELETE Each time DELETE needs an answer, it will take a Y out of the Y.PIP file. Another example involves formatting a number of disks. The FORMAT program normally asks a number of questions, such as HOW MANY TRACKS? SINGLE OR DOUBLE SIDED? SINGLE OR DOUBLE DENSITY? ENTER DISK NAME: ENTER DISK NUMBER: ABOUT TO FORMAT DRIVE NUMBER 0 ARE YOU SURE YOU REALLY WANT TO? We could construct a file called ANSWERS.PIP which contains the following: 40 SSDISKNAME 15 Y and then call FORMAT with SK*DOS: INPIPE=ANSWERS FORMAT 1 FORMAT would then still ask the questions, but would take its answers from the ANSWERS.PIP file instead of the keyboard. In this case, "how many tracks" would be answered with 40, "single or double sided" would be answered with an S, "single or double density" also with an S, and so on. (Note that the number of tracks, the disk name, and the disk number would normally be followed with a carriage return, and so they are followed by a new line in the ANSWERS.PIP file. The S in the side and density question is not normally followed by a return, and so they do not rate a new line in ANSWERS.PIP.) There is one problem with the above example, and that is that it violates our urging you to assign a different disk name and number to each disk, so that SK*DOS can tell if you accidentally switch disks. As shown above, every disk you format will have the identical disk name and number. But there is a solution to this as well. If an error occurs while INPIPE is reading the input file, it prints an error message, goes to a new line and prints a colon (:) as a prompt, and then resumes taking input from the keyboard. This is of particular interest if the input pipe runs out of data, because you may then finish supplying the data from the keyboard. We may take advantage of this in the above example by omitting the last two lines (the 15 and the Y) from ANSWERS.PIP. When FORMAT needs the disk number, it reaches the end of the ANSWERS.PIP file, and hence takes the number from the keyboard. This gives you the chance to customize each disk. Pipes also allow you to write programs called 'filters'. A Filter is simply a program which takes some input, processes it in some way, and sends out an output. When writing a Filter program, you may ignore disk file input and output altogether. Write it initially as if all input were to come from the keyboard, and all output were to go to the screen. You may then debug it by giving it test input from the keyboard, and observing its output directly on the screen. Once debugged, simply redirect its input and output with INPIPE and OUTPIPE, like this: INPIPE= OUTPIPE= (where the items in brackets would be replaced by the appropriate file names.) INPIPE and OUTPIPE use FCB's at C5C0-C6FF, and C700-C83F, respectively. Make sure not to use them with programs which use these same locations for other purposes. LINK LINK is one of the commands used to generate a 'bootable' SK*DOS system disk. It tells the super-boot program where to find the SK*DOS program on the disk. Here is a short explanation of why LINK is needed. To start SK*DOS, you usually use a monitor command (such as FD in HUMBUG). This boot command loads a 'super-boot' program from track 0 sector 1 of the disk into memory. The super-boot program then reads the rest of SK*DOS and executes it. Since SK*DOS could be anywhere on the disk, the super-boot needs a quick way of finding it. This is accomplished by using LINK to store the disk address of SK*DOS directly into the super-boot program itself. LINK is only necessary when you want to generate a 'bootable' system disk; data disks which do not contain a copy of SK*DOS and which will never be booted do not need LINK. There are two basic ways of generating a bootable system disk: 1. Use BACKUP to do a mirror-image copy of an existing bootable system disk onto another formatted disk. Since BACKUP does an exact copy of a disk, the resulting disk will be exactly like the original and will also be bootable. (But if the original disk has unneeded files or defects, so will the new disk.) 2. Use FORMAT to initialize a blank disk, then use COPY to copy SK*DOS to it, and then use LINK to give its address to the super-boot program. In this way it is possible to copy only needed files to the new disk. Use of COPY instead of BACKUP also compacts the disk and rearranges the files to make disk access faster. To link a disk, enter the command LINK followed by the SK*DOS file name. For example, SK*DOS: LINK 1.SK*DOS.DC2 would tell the super-boot in drive 1 where to find the file SK*DOS.DC2. You must enter the extension. The drive number is optional, and will default to the working drive if omitted. Incidentally, self-contained programs (those which use the monitor but not SK*DOS itself) can also be linked to the super-boot. In that case, they will be loaded and executed directly upon booting the system. LIST The LIST command will list the contents of a disk text file to the screen or printer. The LIST command, in turn, requires the name of a file to list. It assumes that the required file name has been entered on the same line, separated from the word LIST by either a comma or a space. For example, SK*DOS: LIST TEXT would list the contents of the file called TEXT. Since LIST is intended for listing text files, it assumes a .TXT extension unless told otherwise. Hence LIST TEXT means the same as LIST TEXT.TXT. LOCATE LOCATE is used to identify the memory locations into which a binary file will load, and to provide the transfer (or starting) address. To use it, type the command LOCATE, followed by the name of the file desired, as in SK*DOS: LOCATE LOCATE.CMD The file name defaults to a .BIN extension if not supplied. Note that LOCATE's printout does not necessarily specify all of the memory used by a particular program, since the program may use memory areas without actually loading anything into them from disk. When several binary programs are appended together, they may contain more than one transfer address. Although LOCATE will indicate them separately, keep in mind that only the last transfer address will actually be used by SK*DOS. MAKEMPTY MAKEMPTY is a command which generates an empty file. Perhaps a bit of an explanation is in order. SK*DOS does not normally like empty files. When a program asks SK*DOS to open a file for writing, but does not actually write anything into it, SK*DOS does not actually put the file on the disk. In other words, it will not generally create a real, but empty, file on the disk (unless you reset the computer or remove a disk while a file is open for writing, which is something you should never do!) Nevertheless, there are times when an empty file would be useful - for example, to initialize a data file which is to be read by a Basic program, updated with more data, and then rewritten. That is precisely what MAKEMPTY does. To use MAKEMPTY, follow the command with a file name, as in SK*DOS: MAKEMPTY DATAFILE This command would create an empty file called DATAFILE.DAT on your working drive, since a default extension of .DAT is assumed unless specified otherwise. The resulting empty file contains all zeroes, which is interpreted by Basic as well as text editors as truly empty; an attempt to read this file will result in an immediate end-of-file indication. O O allows output redirection to the disk, and is used in conjunction with other disk-resident commands or programs. In order to have output directed to the disk rather than to the terminal, put the letter O and the desired file name before the command to be executed. For example, the line SK*DOS: O DISKFILE CAT 1 would do the CAT command, but instead of displaying the catalog of drive 1 on the terminal, would instead write it to a disk file called DISKFILE.OUT. (The default extension for O is .OUT unless specified otherwise.) The resulting file may then be viewed with LIST, or processed by other programs (such as an editor or Basic.) P P allows output redirection to a serial printer using an ACIA addressed at $E000. To use the printer, simply precede another command with a P, as in P CAT 1 which would print the catalog of drive 1. The P command program is entirely self-contained. Nevertheless, there are some commercial programs which look for a different file (called PRINT.SYS) which is the printer driver. SK*DOS includes a PRINT.SYS file (although it is not used by the P command) strictly for those commercial programs which look for it and which may provide an error message if they do not find it. The P command program (P.CMD) is listed in the SK*DOS Configuration Manual, and is easily changed for serial printers on other ports, or for parallel printers. PEEK POKE The PEEK and POKE commands are similar to the same commands of Basic. These commands can be used to make minor modifications to SK*DOS or other programs. To use PEEK, give the command PEEK followed by a hexadecimal address. The contents of that address will be printed out. To use POKE, enter the command POKE followed by the hexadecimal address of the location to be poked and the hexadecimal number to be poked into that location. The POKE command will print out both the old and the new contents as a check. PROMPT PROMPT allows you to change the system prompt from the normal SK*DOS: to any other string. For example, users who feel more at home with a shorter prompt such as, perhaps, three plus signs, can change the prompt with the command SK*DOS: PROMPT +++ The new prompt may be up to 10 characters long, and may include any printable character. PROMPT only changes the prompt currently in memory - it does not change the prompt string on the boot disk. Hence the original SK*DOS: prompt will return the next time you boot the system. Moreover, PROMPT may only be used once; that is, once PROMPT changes the current prompt it cannot change it again unless you reboot the system. PROTECT Files may be assigned one or more kinds of protection codes as follows: CATALOG protected files will not appear in a catalog or directory listing (although the CAT command supplied with SK*DOS ignores this kind of protection.) DELETE protected files cannot be deleted. WRITE protected files cannot be written over. The PROTECT command is used to assign protection codes to a file. To use PROTECT, give the command PROTECT, followed by the file name, followed by one or more of the following codes: C Catalog protect D Delete protect W Write protect X Cancel protection. For example, the command PROTECT SK-DOS.SYS WD would prevent SK-DOS.SYS from being deleted or written over. PROTECT LIST.CMD XD would cancel whatever protection LIST.CMD currently has and instead substitute delete protection. If protection codes contradict each other, the rightmost codes take precedence. For example, the code CDWXC would assign catalog, delete and write protection, then cancel them all, and instead provide only catalog protection. RAMDISK RAMDISK is designed primarily for SS-50 systems which have extended addressing and more than 64K of RAM. It allows the excess RAM to be used as a RAM disk (also called a virtual disk.) The RAM disk is an area of extended RAM which is used exactly like a real (or physical) disk drive. It has a drive number, is accessed exactly the same as a real disk, has a directory like a real disk, and can store programs or data files like a real disk. The main disadvantage of a RAM disk as compared with a real disk is that the RAM disk becomes erased when power is turned off (or if there is a power outage.) Hence any important data on a RAM disk should be copied to a real disk before power is turned off, and perhaps at frequent intervals between. The RAM disk can be as small as 56K (in a 128K system with some kinds of CPU boards) which would provide 14 tracks of 16 sectors each for a total of 208 free sectors (not counting 16 sectors in the directory), or as large as 960K (in a 1 megabyte system) which would provide 240 tracks of 16 sectors each for a total of 3824 free sectors (not counting those in the directory.) The extended addressing circuitry will be in the form of a Dynamic Address Translator (DAT, located either on the CPU board or on the memory board) which extends the address bus to 20 bits for a total addressing range of 1 megabyte. RAMDISK is supplied as a text file which must be customized to your system and then assembled. Customization involves changing three equates at the beginning of the program (further information is provided in the comments in the text file and will not be given here) to specify 1. Whether a SWTP-type or Gimix-type DAT is used, 2. Whether the DAT is on the CPU board or on the memory board, and 3. The total amount of memory (in K) in the system. After modification, the file should be assembled into a command file with the command ASMB RAMDISK RAMDISK.CMD +GLSY Once assembled, the RAM disk is enabled with the command SK*DOS: RAMDISK where the may be any number from 0 through 9, which then becomes the drive number of the RAM disk. If the drive number coincides with that of a real disk drive, then the real drive becomes inactive and the RAM disk takes its place. (A drive number must be supplied.) If the RAMDISK drive number is larger than any other existing drive, the value of MAXDRV will automatically be changed to reflect the RAM disk drive number. Since most systems will not have the maximum number of ten drives allowed by SK*DOS, it will usually be possible to place the RAM disk above other real drive numbers. The first time this is done, the RAM disk will be initialized and erased. As this is done, the RAMDISK program will print out a row of periods, one for each 'track' being initialized, to show that it is active. Note that the RAMDISK program checks for the existence of extended memory, but does not check whether enough memory exists or whether that memory is working correctly. We suggest that you use the memory manufacturer's memory test routines to make sure that your memory is working properly. The message EXTENDED MEMORY NOT INSTALLED will be printed only if no extended memory exists at all. Once the RAM disk has been initialized, it may be reassigned to a different drive number by again typing the RAMDISK command, followed by the new drive number. Both the RAMDISK program, as well as the extended disk memory, contains flags which indicate the status of the RAM disk. If you reboot SK*DOS (without powering down the system), the newly booted SK*DOS will not know about the RAM disk, but the RAM disk contents in extended memory will be retained. If you subsequently enter the RAMDISK command, the RAMDISK program will reenable the RAM disk, but will print the message RAM DISK WAS FORMATTED EARLIER rather than erasing it and formatting it again. Hence your data will be retained in the RAM disk (still assuming, of course, that power has not been turned off in the meantime.) If you do wish to actually erase all data on the RAM disk, insert the word NEW into the command, as in SK*DOS: RAMDISK NEW 1 which will totally erase the RAM disk and then reformat it as drive 1. Finally, here are some additional notes not covered in the above. 1. Since the RAM disk can have a drive number from 0 through 9, the RAMDISK program automatically changes MAXDRV to match. All programs which access drive numbers and file names through the GETNAM function will work correctly with any drive number, up through 9. However, some existing software (especially that designed for FLEX, which is limited to four drives) either may not allow drive numbers over 3, or may change such drive numbers to numbers below 3. (For example, the FLEX COPY command will change a COPY 1 4 command into COPY 1 0, since the 4 is changed into a 0.) Before using a RAM disk drive number above 3 with new programs, try them out to see if they support a drive number above 3. If not, then you have two options - either use a lower drive number for the RAM disk, or else patch the offending program. In most cases, the drive number test will be done with one or the other of the following two instructions: 81 03 CMPA #3, or 84 03 ANDA #3 The 81 03 instruction may be changed to 81 09 for drive numbers up to 9; the easiest way of modifying the 84 03 instruction is to change it to 84 07, which will allow the RAM disk to have a drive number up through 7, but not 8 or 9. Both of these changes can usually be made without even disassembling the offending program. 2. The RAMDISK program is loaded into the disk command area at $C100, but then relocates part of itself into user memory just under the value in MEMEND, where it occupies about 250 bytes. Once there, it cannot be removed except by rebooting SK*DOS. RANDOM RANDOM is an overlay file which allows SK*DOS to do random file operations. Because SK*DOS was written to be compatible with existing software, it had to fit into a certain pre-defined area of memory. But because SK*DOS does so much more, and is so much more careful in its error-checking, the space available for it was simply not large enough to contain all the extra code. It was therefore decided to take the one feature of SK*DOS that was likely to be least used, and make it into a separate file. That resulted in the RANDOM command. You must perform the RANDOM command before performing any random file operations. Once you do this, there is no need to repeat RANDOM again unless you reboot the system, since the random file overlay will stay in place. (If you do only random processing, you could even call RANDOM in your STARTUP file and leave it in place all the time.) If you attempt to do random file operations without first calling RANDOM, SK*DOS will give you an error message. The random file overlay takes up approximately 2K of memory, and is positioned just below the current value of MEMEND at the time it is called. Since it reduces your workspace memory slightly, there is really no reason to call RANDOM unless you intend to do random operations. Once you execute the RANDOM command, the SK*DOS: prompt will change to SK=DOS: to remind you that random files are allowed (unless you have used the PROMPT command to change prompts.) Additional information on random files may be found under FCS operation codes 3, 17, 18, 21, 22, and 23 in Chapter 10, and in the second half of Chapter 14. RENAME RENAME is used to rename a disk file. To use this command, enter the word RENAME, followed by the old name and the new name, as in RENAME OLDNAME.TXT NEWNAME.ABC No quotes are needed, but the extension must be supplied for both names. SAVE This utility saves binary data from memory to disk. No quotes are necessary for the file name, and the addresses must be hexadecimal. For example, the command SAVE PROGRAM 1000 2000 1003 would save a file called PROGRAM from memory locations $1000 through $2000, and assign a transfer (starting) address of $1003. The file name extension defaults to .BIN if not given, and the transfer address defaults to 0000 if not given. Please note: the SAVE command itself is a disk resident command which must be loaded into RAM memory to be executed. Some care is therefore needed to prevent SAVE from overlaying the very program it is supposed to be saving. SAVE normally lies in high memory (at address $C100). This SAVE cannot be used to save programs which themselves lie in high memory. For that reason, we supply a second version of SAVE called SAVELOW which begins at location $0000 in low memory. SAVELOW should be used for programs which exist in high memory, while SAVE should be used for programs which lie in low memory. STEPRATE The STEPRATE command is used to set the speed at which SK*DOS commands disk drives to step from track to track. (Depending on your disk controller and disk drivers, this command may not exist, or may be called by some other name such as SETUP.) For 5-1/4" disk drives, the allowable step rates are 6, 12, 20, or 30 milliseconds (ms) per step. The step rate is specified after the word STEPRATE as in SK*DOS: STEPRATE 30 Each time STEPRATE is called it responds by displaying the new step rate setting; if no step rate is specified in the command or an invalid number is specified, then the step rate remains the same and the current value is displayed. (For those users more at ease with programming floppy disk controllers, the values 0 through 3 {which are the values actually given to the floppy disk controller} may also be specified as follows: 0 = 6 ms 1 = 12 ms 2 = 20 ms 3 = 30 ms.) Smaller step rates will produce faster operation, but you should be careful not to specify a value smaller than your disk drives can handle since that may lead to errors. If in doubt, it is better to err on the conservative side. SYSTEM WORK The SYSTEM and WORK commands are used to specify the system and working drives respectively. When SK*DOS is first booted, drive 0 becomes the default system and working drive; this drive selection can be changed with these commands. For example, the command SK*DOS: SYSTEM 1 would make drive 1 the default system drive, while SK*DOS: WORK 8 would make drive 8 the default working drive. Entering the SYSTEM or WORK command without a valid drive number following causes the current system or work drive number to be displayed. SCAT & SEQUENCE SCAT is similar to CAT, but differs in three ways: (1) SCAT prints both the date of each file as well as its sequence number (if one has been assigned to the file), (2) The catalog listing is sorted by date and sequence number so that the most recent files appear first, (3) SCAT does not allow all of the options used by the CAT command. SCAT is designed for systems which do not have a clock IC installed. (If you do have a clock, then you should read the description of the TCAT command which, along with time stamping, provides greater capabilities.) When a clock is not installed and interfaced with SK*DOS, as described under TCAT, then SK*DOS automatically assigns a 'sequence number' to each file as it is written or updated. This number starts with 1 when the system is booted, and increments by 1 each time a new file is written. When your disk contains a number of files all having the same date, the sequence number tells you what order the files were written in. The SCAT command then prints the catalog, but sorted by date and sequence number so that the most recent file appears on top. SK*DOS's COPY command carries the old date and sequence number along with the file. Hence copies of your files will have the same date and sequence number as the original. (Be careful if you use the COPY command from some other DOS - it probably does not copy the original sequence number, and may not even copy the original date, assigning the current date instead.) Obviously, if your system has a clock, then using time-stamping and TCAT provides the actual time rather than just a sequence number, but the sequence number is a good second best if no clock is available. It has two characteristics you should keep in mind: 1. Each time the system is powered up, the sequence number starts with 1. In other words, if you turn off the power and then restart, the sequence number will return back to 1. To avoid having multiple files with the same date and sequence number, you may want to get in the habit of manually updating the sequence number if you restart the system, so that it continues with the next higher number. The SEQUENCE command is used for this purpose. For example, to change the number to 7, use the command SK*DOS: SEQUENCE 7 Typing just SEQUENCE without a number will print out the current sequence number. 2. The sequence number is incremented by 1 for every file written or updated. This includes files being copied, even though copied files are not assigned a new number. In other words, each time you copy a file, the sequence will appear to skip a number; this is the number that would have been assigned to the copied file if it had not kept its old number. TCAT TCAT is similar to CAT, but differs in three ways: (1) TCAT prints both the date of each file as well as the time (if one has been assigned to the file), (2) The catalog listing is sorted by date and time so that the most recent files appear first, (3) TCAT does not allow all of the options used by the regular CAT command. Although TCAT is provided primarily for those users who use the INTIME entry point for adding a time-of-day to each file's directory entry, it is also useful to others because of its ability to sort directory entries to display the latest files first. Here are a few examples of how to use TCAT: TCAT prints a catalog of the working disk TCAT 5 prints a catalog of drive 5 TCAT 5 FS prints a catalog of all files on drive 5 which have names beginning with FS TCAT 5 FS.T .CMD prints a catalog of all files on drive 5 which have file names beginning with FS and also have extensions beginning with .T, and of all files on drive 5 which have the extension .CMD (Try TCAT on the SK*DOS disk to see what it does.) If you have a clock-calendar IC in your system and decide to implement the time option (see INTIME) to add the time to your files, see the file TIMEADD.TXT on your disk for an example of how to implement the time read function; this version is for the 58167 clock-calendar chip on the Gimix CPU board. After assembly, this routine would normally be appended to SK-DOS.COR in the process of generating a system disk, although it could also simply be loaded into memory after SK*DOS is booted. (Note that TIMEADD is origined at $DDB0. This area is empty in the current version of SK*DOS, but may not remain so in future versions. The ORG address of TIMEADD should always be checked if it is used with later versions of SK*DOS.) SK*DOS's COPY command carries the old date and time along with the file. Hence copies of your files will have the same date and time as the original. (Be careful if you use the COPY command from some other DOS -it probably does not copy the original time, and may not even copy the original date, assigning the current date instead.) The time code is based on a 24-hour clock, and is given in tenths of an hour, ranging from 00 to 239. For example, a code of 123 means 12.3 hours, or 3/10 of an hour (18 minutes) past noon. The TCAT program would display this as 12:18. If the time code is 00, which is the case for files without a time, then TCAT will omit the time printout. TTY The TTY command can be used to change terminal or console parameters. (The name TTY dates back to the use of Teletype machines as terminals in the early days, but is still used for compatibility.) To use this command, type TTY, followed by the two-letter abbreviation for the parameter to be changed (see below), followed by an equals sign, and then followed by the new value. Several paramters can be changed in one command line, as in SK*DOS: TTY WD=64 BS=$08 PS=N Typing just TTY by itself will print out a list of the current parameters in effect. Parameter Address Abbreviation Function Common value * --------- ------- ------------ ------------------ ---------------- BACKSP $CC00 BS Backspace character $08 DELETE $CC01 DL Delete current line $18 ENDLIN $CC02 EL End of line char. $3A (:) PLINES $CC03 PL or DP Print lines / page 0 (cancel) WIDTH $CC04 WD Line width 0 NULLWT $CC05 NL Null wait on CR/LF 0 TAB $CC06 TB Tab character ** $00 ** BSECHO $CC07 BE Backspace Echo $00 SLINES $CC08 SL or EJ Skip lines betw pages 0 (cancel) PAUSE $CC09 PS Pause indicator YES ESCAPE $CC0A ES Escape character $1B (ESC) NOTES: * PAUSE value is either YES, NO, ON, or OFF; all other values are in decimal except those identified with a $. ** This parameter is listed for completeness, but is not used See the section on 'User-Accessible Variables' for the explanation of these terminal parameters. VERSION VERSION is used to determine the version number of a binary file (if that file has a version number included). All SK*DOS utilities, and most other programs, begin with the sequence of instructions START BRA START1 FCB X START1 ... actual program begins here so that the third byte of the program is the version number (X in the above example.) VERSION can be used to check that version code. To use it, type the command VERSION followed by the name of the file, as in SK*DOS: VERSION COPY If not entered, the file name defaults to a .CMD extension. APPENDIX I. ADDENDA AND OTHER INFORMATION My favorite law (which I affectionately call Stark's First Law of Computerdom) says "A program without bugs must be so simple that it probably wasn't worth writing in the first place." It is quite likely that somewhere within SK*DOS lie one or more bugs which have yet to be discovered. If you find one, please let us know and we will exterminate it at once. In any case, be sure to follow the instructions on the User Registration page to be sure that we can contact you with updates if required. This Appendix provides additional information about SK*DOS which does not seem to fit any other section, as well as addenda or corrections to the manual which are discovered after the remainder of the manual is printed. 1. When SK*DOS is first booted, it looks on the boot disk for a text file called STARTUP.TXT. This file may have a one-line command in it which will be immediately executed as if it had come from the keyboard. For example, if this file contains the text LIST READ-ME then SK*DOS will list the contents of the file READ-ME.TXT after it asks for the date, just before it prints its first prompt. 2. Each time SK*DOS is entered via the WARMST entry point, it clears the DP register to 0. SK*DOS itself does not use the DP register, and will thus always enter any user program with a 0 in this register. The instructions which clear the DP register begin at addresses CD5A, and may be replaced by NOPs if the user so wishes. 3. In order to preserve register contents when using SK*DOS, almost every SK*DOS subroutine stores its register contents on the stack on entry, and restores them on exit. As a result, SK*DOS uses more stack space than other similar disk operating systems. In writing user programs that use SK*DOS, make sure to leave adequate stack space. A good rule of thumb would be to leave at least 64 extra bytes of stack space over and above what you expect your own program to need. 4. Some application programs require that you provide them with the address of a routine which inputs a keyboard character without echoing it to the screen. INNOEC (at $CD5E) is such an entry point. INNOEC is, however, not a standard entry point with other similar DOSes, some of which have been modified to use $D3E4 for the same purpose. If your copy of SK*DOS contains a $7E at $D3E4 (you may use PEEK to find out) then you may also use this entry point instead of INNOEC. ($D3E4 is in the area reserved for disk drivers; hence it may not be usable as an alternative to INNOEC if it is used by the disk drivers.) 5. To save memory space (as well as to allow some customization of messages), the one-line explanations printed with error messages are contained in a file called ERRCODES.SYS. Whenever PERROR prints out an error code, it looks on the current system drive for the ERRCODES.SYS file. If that file is present, then PERROR searches for the appropriate error number in that file and prints the text immediately following that number. You may LIST ERRCODES.SYS to see the file format, and may make changes with any editor to suit your taste. If you do make changes to this file, however, please note the following: a. Entries are not in strict numeric order. For example, error 45 follows error 52, since the explanation of error 45 contains the string "52". If error 45 were in its correct numeric sequence, then error 52 would print as " OR <0)", which is the text immediately following the string "52". b. The ERRCODES.SYS file contains error codes up through 109; although SK*DOS itself only uses error codes through 30, higher codes are used by TSC Extended Basic and possibly other programs as well. a. Each line of the file begins with a two-character error code number; in order to allow error codes through 240 to be represented with just two characters, the first digit of codes above 99 must be replaced by its corresponding ASCII character. For example, code 100 is represented by :0 since the colon comes after the 9 in the ASCII code, and thus the colon represents the digits 10. 6. The P.CMD and PRINT.SYS files are written for a serial printer at address $E000, using an ACIA in what is commonly called "port 0". Another set of routines, called PP.CMD and PPRINT.SYS, are supplied for those users who have a parallel printer using a PIA at $E01C. If you are using a parallel printer, simply rename the original routines to SP.CMD and SPRINT.SYS, and then delete the extra P from the parallel routine names. 7. We now supply SK*DOS with several .TXT files for those users who are knowledgeable in machine and assembly language programming, and who may want to customize SK*DOS to their systems. This includes the following programs: TIMEADD (two versions) for implementing file time-stamping on those systems equipped with a clock chip. DATEADD for patching SK*DOS to automatically get the date from a clock/calendar chip on signing on. CACHE for using extended memory as a disk cache. 8. If you have a hard (Winchester) disk, there is a possibility that your disk drivers use part of track 0 for storing data, so as to get the maximum possible amount of data storage on the disk. (Check with the disk manufacturer if in doubt.) If that is so, then you should read the following very carefully: a. Since finding any data on track 0 of a floppy disk normally indicates that the disk has been damaged, the COPY command checks for this situation. If it finds that there is data on track 0, it issues an error message and refuses to copy any data. This check can be disabled by using the "T" option of COPY. Alternatively, there is on your disk a different version of COPY, called COPY0, which has the track 0 test permanently disabled. If you wish to use it, simply rename the standard COPY.CMD to some other name, and rename COPY0.CMD to COPY. b. If your hard disk places data on track 0, then DO NOT USE either BACKUP or COMPARE on that disk (although you may use them on other disks). The reason has to do with the structure of a SK*DOS disk. The only way BACKUP or COMPARE can know how many sectors there are on track 0 is to follow the directory links. As soon as these links indicate either (a) that the directory is ending, or (b) that the directory is being continued on another track, BACKUP and COMPARE immediately stop reading track 0. Hence these programs will not back up or compare any data sectors on track 0. USER REGISTRATION AND UPDATE POLICY In order to register as an authorized user of this product, and to receive updates if any are required, please 1. Fill out and return the Registration Form below to Star-Kits Software Systems Corporation P. O. Box 209 Mt. Kisco, N. Y. 10549 2. Enclose a self-addressed stamped envelope with the name and version of this product written in the lower left corner; we will keep the envelope on file, and use it to notify you of any updates that may be necessary. 3. Note that registration of your purchase is extremely important. We at Star-Kits stand behind our products, and make great efforts to let our customers know of updates and extensions to their programs. But to make this work, we ask that they send in their registration forms and envelopes. We do not maintain a separate mailing list, and will not notify our customers unless we have this material on file. ------------------------------------------------------- USER REGISTRATION FORM Purchaser Name: Address: Product Being Registered: SK*DOS LEVEL I Serial No.: Purchase Date: Purchased from: Comments: