Section II SYSLIB REFERENCE ZCPR3: THE LIBRARIES A Reference Manual and User's Guide for SYSLIB, Z3LIB, and VLIB Written by Richard Conn Copyright 1986 Richard Conn This Page Left Blank ZCPR3: The Libraries SYSLIB Introduction 2. INTRODUCTION TO SYSLIB SYSLIB is an integrated tool set which is designed to assist the assembly language programmer in writing his application. It is intended to place him at a higher level of abstraction that allows him to concentrate on the problem at hand without having to concern himself with the low-level implementation details of the operating system interface, input/output, text parsing and evaluation, math, and sorting. To illustrate this point, consider an assembly language programmer who needs to access a disk directory. The application he is writing is one which displays a sorted disk directory to the user. Without SYSLIB or a library like it, the programmer would have to write a relatively sophisticated body to code to access the directory, load it into memory, sort it, and display it to the user. With SYSLIB, the programmer has a host of tools he can call on to perform some of the more tedious functions. One of these tools, DIRF, loads the elements of a disk directory which match a file spec into a memory buffer for him. But more than just providing a set of tools, SYSLIB was designed with structured programming and software engineering in mind. The basic goal in software design is that the programs meet the stated requirements. In applying software engineering, we want more than just this. Among other things, we want the program to be: o Modifiable o Efficient o Reliable o Understandable SYSLIB offers a significant set of facilities which can help to achieve these goals. 2-1 ZCPR3: The Libraries SYSLIB Introduction NOTES: 2-2 ZCPR3: The Libraries SYSLIB Character Input/Output 3. CHARACTER INPUT/OUTPUT CHAPTER OUTLINE Character Input CIN, RIN BIN CAPIN, CAPINE Conditional Input CONDIN Character Output COUT, LOUT, POUT, SOUT BOUT CCOUT, CLOUT, CPOUT, CSOUT New line Output CRLF, LCRLF, SCRLF Console Status CST BIST 3-1 ZCPR3: The Libraries SYSLIB Character Input/Output Character Input/Output This set of routines provides character-oriented I/O functions for the Console (CON:), List (LST:), Reader (RDR:), and Punch (PUN:) logical devices. There are no side effects on any registers. Direct BIOS calls are used on all routines except for BIN, BIST, and BOUT, so user controls such as "P (which are implemented by the BDOS) will not work. The functions provided by these routines include: Character Input from Console and Reader Character Output to Console, Printer, and Punch Character Output to Console, Printer, and Punch with Control-Character Processing Console Input Status Conditional Input New Line (CRLF) Output Capitalized Character Input Switched Output is provided in this set of routines as the S-series of routines (S-series routines use S as the first letter of their names). The S-series is different from the other series in that the S-series uses an external data byte to determine where the output is to be routed. This byte is referred to as SCTLFL (space = 20H) in value except , , , , and are output as an uparrow (") followed by the corresponding letter generated by adding 40H to the character value (i.e., 1 outputs as "~A", 2 as ""B", etc.). The characters less than in value NOT output in this manner are — Any character of value greater than is output normally. Inputs: A = Character to output Outputs: None (Character/Code is output) Registers Affected: PSW (only the Flags; Register A is NOT affected) SYSLIB Routines Called: COUT (for CCOUT); LOUT (for CLOUT); POUT (for CPOUT); SOUT (for CSOUT) Special Error Conditions: None 3.4. Newline Output Routine; CRLF, LCRLF, SCRLF Function: Print and on CON: (CRLF), LST: (LCRLF), or switched output (SCRLP). Inputs: None Outputs: None «CR> is printed) Registers Affected: None SYSLIB Routines Called: LOUT (for LCRLF); POUT (for CRLF); SOUT (for SCRLF) Special Error Conditions: None 3.5. Console Status Routine; CST Function: Input the status on CON: in Register A. If Read Data Available, A=0; otherwise, A=l. Inputs: None Outputs: A = Console Status 0 --> Read Data Available (RDA) 1 —> Read Data Not Available (Not RDA) Zero Flag is Affected character) and the Input Line Editor returns to the calling program with the user's text stored in a buffer. This text is terminated by a binary 0. Two of the Input Line Editors in SYSLIB use the BDOS to provide the line editor function. They preserve the registers during the function call and store the terminating zero at the end of the text. These routines occupy less space than the third Input Line Editor, INLINE. The third Input Line Editor, INLINE, is used when security is important. Unlike the other two, when typing a Ctrl-C to INLINE, the Input Line Editor and calling program are not aborted and control returned to the operating system. Instead, the Ctrl- C character is stored in the user's line. Also, unlike the other two, INLINE can be instructed to echo or not echo the input characters. This feature is useful for programs which input a password. INLINE can be instructed not to echo the password, but it will still provide the line editing functions for the user so that he can correct mistakes. Routine; BBLINE Function: BBLINE provides an interface to the BDOS for input line editor functions. It contains its own internal buffer for storage of the input line (200 bytes allocated), and it returns a pointer to the first byte of the line upon return. The line stored in this buffer is terminated by a binary zero (0). 4-5 ZCPR3: The Libraries SYSLIB String Input/Output BBLINE is called with a capitalization flag stored in the A Register. If A = 0, BBLINE does not capitalize the input line characters. If A <> 0, BBLINE capitalizes the input line characters before returning to the caller. No error codes are returned by BBLINE. On return, HL points to the first byte of the input line and A contains a count of the number of characters in that line (not counting the ending zero). Inputs: A=0 to Not Capitalize Line, AOO to Capitalize Outputs: HL pts to first char in the line A is number of characters in the line (not counting the ending zero) Registers Affected: PSW, HL SYSLIB Routines Called: CAPS Special Error Conditions; None Routine: BLINE Function: BLINE provides an interface to the BDOS for input line editor functions. It performs the same type of function as BBLINE, but it does not contain an internal buffer. The programmer is expected to provide such a buffer, which is structured as follows; SIZE: DB CCNT: DS 1 LINE: DS BLINE returns a pointer to the first byte of the line (LINE) upon return. The line stored in this buffer is terminated by a binary zero < 0). BLINE is called with a pointer to the buffer in HL and a capitalization flag stored in the A Register. If A = 0, BLINE does not capitalize the input line characters. If A 0 0, BLINE capitalizes the input line characters before returning to the caller. No error codes are returned by BLINE. On return, HL points to the first byte of the input line and A contains a count of the number of characters in that line (not counting the ending zero). Inputs: A=0 to Not Capitalize Line, AOO to Capitalize HL pts to first byte of user-supplied buffer Outputs: HL pts to first char in the line A is number of characters in the line (not counting the ending zero) Registers Affected: PSW, HL SYSLIB Routines Called: CAPS Special Error Conditions: None 4-6 ZCPR3: The Libraries SYSLIB String Input/Output Routine: INLINE Function: INLINE allows the user to input a line of text from CON: into the buffer pointed to by HL. The user is allowed to edit the text as he types it, and INLINE responds to the following editor commands: Key Command Function Delete previous character and back up cursor Delete previous character and echo it Input complete — return to calling program Skip down to next physical line and insert a into buffer Tabulate to next tab stop (every 8) Ctrl-11, Erase current line (clear buffer) and restart Ctrl-X input Ctrl-R Retype current line Ctrl-E Skip down to next physical line; insert nothing into buffer On exit, the buffer contains the text entered followed by a (binary 0); the typed to end the input is NOT placed in the buffer. Inputs: HL = pointer to input line buffer A = Echo Flag (Beep at CON; ) is output if attempt is made to delete character «BS> or No Error (Z is set) 1 —> File Not Found (NZ) 2 —> File is Full (no more room) (NZ) 3 —> File Found but Empty (NZ) TBUFF contains last record of file if A=0 Registers Affected: PSW SYSLIB Routines Called: INITFCB Special Error Conditions: As indicated Routine: P$APPL Function: Open the file for appending. The FCB is pointed to by DE. If the file is found and not empty, F$APPEND returns with A=0 and the Zero Flag Set (Z) to indicate no error. Various error conditions can occur, and are returned with A=error code and NZ. Error 3 is a note that the file is empty and is not fatal (processing can continue). 6-2 ZCPR3: The Libraries SYSLIB File Manipulation If the APPL is successful, TBUFF contains the last record in the file. The next sequential write (call F$WRITE) will write back over the last record in the file. See the documentation on the companion routine, F$APPEND, for more details; F$APPEND writes starting after the last record of the file. Inputs; DE = pointer to FCB Outputs: A = Error Code and PSW Flags Set (Zero Flag) —> No Error (Z is set) —> File Not Found (NZ) —> File is Full (no more room) (NZ) —-> File Found but Empty With F$APPL: LXI D,FCB CALL F$APPL LXI D,FCB CALL F$WRITE LXi D,FCB CALL F$CLOSE ;after last ;close file LXI D,FCB CALL F$WRITE LXI D,FCB CALL F$CLOSE ;on last 6.1.2. Close a File Routine; F$CLOSE Function: Close the file whose FCB is pointed to by DE. Inputs: DE = pointer to FCB Outputs: A = Error Code 0 —> No Error OFFH --> Error in closing file Registers Affected: PSW SYSLIB Routines Called: BDOS Special Error Conditions: None 6.1.3. Delete a File Routine; P$DELETE Function: Delete the file whose FCB is pointed to by DE. If file does not exist, nothing happens (no error message or code is given). Inputs: DE = pointer to FCB Outputs: None Registers Affected: PSW SYSLIB Routines Called: BDOS Special Error Conditions: None 6-3 ZCPR3: The Libraries SYSLIB File Manipulation 6.1.4. Test of Existence of a File Routine; FSEXIST Function: F$EXIST tests for the presence of the file whose FCB is pted to by DE in the current disk/user area. If this file does not exist in this area, F$EXIST returns with the Zero Flag Set (Z); if this file does exist, F$EXIST returns with NZ. Inputs: DE pts to FCB of file to test for Outputs: Zero Flag Set (Z) means file not found; NZ means file found Registers Affected: PSW SYSLIB Routines Called: BDOS Special Error Conditions: None 6.1.5. Create a File Routine; FSMAKE Function: Create the file whose PCB is pointed to by DE. Inputs; DE = pointer to FCB Outputs: A = Error Code OFFH —-> No directory space available Not OFFH —> No Error; Value is byte address in TBUFF (80H-OFFH) of directory entry allocated to the FCB Registers Affected: PSW SYSLIB Routines Called: BDOS, F$DELETE Special Error Conditions: None 6.1.6. Open a File Routine: FSOPEN Function: Open the file specified by the PCB pointed to by DE. If file not found, F$OPEN returns with an error code in A (OFFH) and Zero Flag Clear (NZ). Inputs: DE = pointer to FCB Outputs: A = Error Code and PSW Flags Set (Zero Flag) 0 —> No Error OFFH --> File not opened Registers Affected: PSW SYSLIB Routines Called: BDOS, CAPS, CIN, COOT, CRLF, PRINT Special Error Conditions: None Routine: PSMOPEN Function: Open the file specified by the FCB pointed to by DE. If file is not found, F$MOPEN tries to create one. It returns the error code of OFFH in A if there was not enough room in the disk directory to create the directory entry. Inputs: DE = pointer to FCB Outputs: A = Error Code and PSW Flags (Zero Flag) Set 0 —> No Error OFFH —> File not opened Registers Affected: PSW SYSLIB Routines Called: BDOS, CAPS, CIN, COUT, CRLF, PRINT Special Error Conditions: None 6-4 ZCPR3: The Libraries SYSLIB File Manipulation 6.1.7. Read and Write a Block Routine: F$READ Function: Read next block (128 bytes) from the opened file whose FCB is pointed to by DE into TBUFF (buffer at 80H - OFFH). Inputs: DE = pointer to FCB Outputs: A = Error Code 0 —> No Error 1 —> Read past end of file 2 —> Reading unwritten data in random access Registers Affected: PSW SYSLIB Routines Called: BDOS Special Error Conditions: None Routine: F$WRITE Function: Write next block (128 bytes) from TBUFF (buffer at 80H to OPFH) to the opened file whose FCB is pointed to by DE. Inputs; DE = pointer to FCB Outputs: A = Error Code 0 —> No Error 1 —> Error in extending file 2 —> End of disk data OFFH —> No more directory space Registers Affected: PSW SYSLIB Routines Called: BDOS Special Error Conditions: None 6.1.8. Rename a Pile Routine; FSRENAME Function: P$RENAME may be used to rename a file. On entry, DE pts to the first twelve bytes of the file's FCB and HL pts to the first twelve bytes of the FCB for the new file (that is, only the FN and FT fields are significant, so the rest of an FCB need not be present for this function to work). F$RENAME contains an internal FCB which is structured from the two entries to properly rename the file. Inputs: HL pts to 1st 12 bytes of new FCB DE pts to 1st 12 bytes of old FCB Outputs: Zero Flag Set (Z) means error (file not found) Registers Affected: PSW SYSLIB Routines Called: BDOS, FILLB, MOVEB Special Error Conditions: Z means File Not Found 6.1.9. Compute File Size Routine; F$SIZE Function: Compute the size of a file (in K) based on its record count. This routine gives the file size correct to the next 1K, but does not take into account the grouping factor. Inputs: DE points to the 1st 12 bytes of an FCB Outputs: HL contains file size Registers Affected: HL SYSLIB Routines Called: MOVEB, INITFCB, BDOS, SHFTRH Special Error Conditions: None 6-5 ZCPR3: The Libraries SYSLIB File Manipulation 6.1.10. Get Random Record Number Routine; GETRR, GETRR1 Function: Return the random record number of the last record sequentially read or written of the file whose FCB is pointed to by DE. The random record number is returned in HL, with A=0 and Zero Flag Set (Z) if no error. These routines are convenient in determining the current position in a file. GETRR does not affect the random record number field of the PCB and is larger in size. GETRR1 is smaller and affects the random record number field of the FCB. Inputs: DE = pointer to FCB Outputs: A = Error Code A = 0 --> No Error A 0 0 —> Random Record Overflow HL = Random Record Number Registers Affected: PSW, HL SYSLIB Routines Called: None Special Error Conditions: None 6.1.11. Get File Size in Records Routine; GETFS, GETFS1 Function: Return the file size (in terms of records) of the file whose FCB is pointed to by DE. The record count is returned in HL, with A^O and Zero Flag Set (Z) if no error. These routines are convenient in determining the number of records in a file. GETFS does not affect the random record number field of the FCB and is larger in size. GETFS1 is smaller and affects the random record number field of the FCB. Inputs: DE = pointer to FCB Outputs: A = Error Code A = 0 —> No Error A 0 0 —> Random Record Overflow HL = Number of Records in File (File Size) Registers Affected: PSW, HL SYSLIB Routines Called: None Special Error Conditions: None 6.1.12. Get File Attributes Routine: GEA Function: Return the attributes of the file whose FCB is pointed to by DE. On return, A contains a code indicating the R/0 and SYS attributes, where the 8th bit of A File is R/0 AO = 0 —> File is R/W A7 = 1 —> File is System A7 = 0 --> File is Non-System Registers Affected: PSW SYSLIB Routines Called: INITFCB Special Error Conditions: None 6.1.13. Random Read and Write a Block Routine; RSREAD Function: Read a block from the file whose FCB is pointed to by DE. The record number of the block is contained in HL, and the block is read into TBDFF (80H-OPFH). On exit, an Error Code is returned in A. It is assumed that the file has been opened by F$OPEN or equiv. Inputs: DE = pointer to FCB HL = record number Outputs: A = Error Code 0 —> No Error (Z Flag Set) 1 —> Attempt to Read Unwritten Record 3 —> CP/M could not Close Current Extent 4 —> Attempt to Read Unwritten Extent 6 —> Attempt to Read Beyond End of Disk Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None Routine: B$WRITE Function: Write the block contained in TBUPF (80H-OFFH) to the disk file whose FCB is pted to by DE and whose record number is contained in HL. This FCB should have previously been opened by a call to F$OPEN or the like. Inputs: DE = pointer to FCB HL = record number Outputs: A = Error Code 0 —> No Error (Z Flag Set) 1 —> Attempt to Read Unwritten Record 3 —> CP/M could not Close Current Extent 4 —> Attempt to Read Unwritten Extent 5 —> Directory Full 6 ~> Attempt to Read Beyond End of Disk Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None 6.1.14. Set and Clear File Attributes Routine; SCFA Function: Set and clear the attributes of the file whose FCB is pointed to by DE. On entry, A contains a code indicating the R/0 and SYS attributes, where the 8th bit of A (A7) is 1 if the file is to be a SYStem file and 0 if the file is to be a DIRectory (Non-SYStem) file and the 1st bit of A (AO) is 1 if the file is to be Read/Only and 0 if the file is to be Read/Write. All other file attributes are cleared to 0 (the MSBs of bytes 1-8 and 11 are set to 0). 6-7 ZCPR3: The Libraries SYSLIB File Manipulation Inputs: DE = pointer to FCB A = Attribute Code AO = 1 —> File is to be R/0 AO = 0 —> File is to be R/W A7 = 1 —> File is to be System A7 = 0 —> File is to be Non-System Outputs: None Registers Affected: None SYSLIB Routines Called: INITFCB Special Error Conditions: None Routine: SEA Function: Set the attributes of the file whose FCB is pointed to by DE. On entry, A contains a code indicating the R/0 and SYS attributes, where the 8th bit of A (A7) is 1 if the file is to be a SYStem file and 0 if the file is to be a DIRectory (Non-SYStem) file and the 1st bit of A File is to be R/0 AO = 0 —> File is to be R/W A7 = 1 —> File is to be System A7 = 0 —> File is to be Non-System Registers Affected: None SYSLIB Routines Called: INITFCB Special Error Conditions: None 6.2. Byte-Oriented File Input/Output The following covers the series of byte-oriented file input/output routines in SYSLIB. These routines allow the user to sequentially read from (GET) and write to (PUT) a file on a byte-for-byte basis. Hence, these routines provide a simple method for handling input from and output to a file. A typical program which employs these routines must open the required files before doing any processing, roust then perform the processing on the opened files, and must then close the files when the processing is complete (closing the files is optional for input files and mandatory for output files). SYSLIB provides four sets of routines for byte-oriented file input and output. These routines are — Input Open FIO$OPEN FI1$OPEN FI2$OPEN FI3$OPEN Output Open FOO$OPEN F01$OPEN F02$OPEN F03$OPEN GET FO$GET F1$GET F2$GET F3$GET PUT FO$PUT F1$PUT F2$PUT F3$PUT Input Close FIO$CLOSE PI1$CLOSE FI2$CLOSE FI3$CLOSE Output Close FOO$CLOSE F01$CLOSE F02$CLOSE F03$CLOSE 6-8 ZCPR3; The Libraries SYSLIB File Manipulation This system allows the user to have up to 8 files open simultaneously — four are open for input using GET and four are open for output using PUT. For example, the following is a sample code section using these routines for two files: EXT FIO$OPEN ; DECLARE LIBRARY REFERENCES EXT FOO$OPEN EXT FIO$CLOSE EXT FOO$CLOSE EXT FO$GET EXT FO$PUT LXI D,FCBI ; PT TO FCB OF INPUT FILE CALL FIO$OPEN LXI D,FCBO ; PT TO FCB OF OUTPUT FILE CALL FOO$OPEN [body containing CALL FO$GET and CALL FO$PUTl CALL PIO$CLOSE ; CLOSE FILE CALL POO$CLOSE Note that only the routines to be used are referenced in the EXT statements. If you do not need a particular routine, do not reference it. Not referencing an unneeded routine generally saves the overhead memory space of loading it from the library. Each set of INPUT OPEN, INPUT CLOSE, OUTPUT OPEN, OUTPUT CLOSE, GET, and PUT routines is contained in one library module, so referencing any of these routines causes the entire module to be loaded, and all the routines are accessable to the user (provided they are mentioned in the external definitions) without any additional memory overhead. Specifically, FIO$OPEN, FIO$CLOSE, FOO$OPEN, FOO$CLOSE, FO$GET, and FO$PUT are contained in one module, and reference to any of these routines loads the entire module; the same is true for the other sets of routines. The CLOSE routine for output (FOn$CLOSE) is ALWAYS required. It fills the rest of the current block with Ctrl-Z followed by bytes and properly closes file. The CLOSE routine for input (FIn$CLOSE) is required ONLY IF you are going to later open another file for input using the corresponding OPEN routine LXI D,IOCTL1 CALL FXI$OPEN JZ FNF LXI D,IOCTL2 CALL FXO$OPEN JZ NODIR LXI D,IOCTL1 CALL FX$GET JZ EOF ; Open 1 for Input ; File Not Found Error ; Open 2 for Output ; No Dir Space Error Get Next Input Byte in A Process EOF LXI D,IOCTL2 CALL FX$PUT JZ WERR Put Byte in A to Output File Process Write Error LXI D,IOCTL1 CALL FXI$CLOSE Close Input File 6-12 ZCPR3: The Libraries SYSLIB File Manipulation JZ FCERR ; File Close Error LXI D,IOCTL2 CALL FXO$CLOSE ; Close Output File JZ FCERR This example illustrates the flexibility of the FXIO routines. As many files as desired may be open for input or output, each file having its own I/O Control Block and Working Buffer. The advantages in efficient disk accessing with this set of routines over the previous ones are notable. The major disadvantage of using these routines is that the buffers are larger and the overhead of always ensuring that DE points to the proper I/O Control Block before each routine is called is present. 6.3.1. Open File Routine; PXI$OPEN, FXOSOPEN Function: Open the file whose I/O Control Block (IOCB) is pointed to by DE for Input (FXI$OPEN) or Output LXI D, IOCTL1 CALL FYI$OPEN JZ FNF LXI D,IOCTL2 CALL FYO$OPEN JZ NODIR LXI D,IOCTL1 CALL FY$GET JZ EOF Open 1 for Input File Not Found Error Open 2 for Output No Dir Space Error Get Next Input Byte in A Process EOF LXI D,IOCTL1 MVI A,CH CALL FY$UNGET Unget character CH 6-15 ZCPR3: The Libraries SYSLIB File Manipulation LXI D,IOCTL2 CALL FY$PUT ; Put Byte in A to Output File JZ WERR ; Process Write Error LXI D,IOCTL1 CALL FYI$CLOSE ; Close Input File JZ FCERR ; Pile Close Error LXI D,IOCTL2 CALL FYO$CLOSE ; Close Output File JZ FCERR This simple example illustrates the flexibility of the FYIO routines. As many files as desired may be open for input or output, each file having its own I/O Control Block and Working Buffer. The advantages in efficient disk accessing with this set of routines over the previous ones are notable. The major disadvantage of using these routines is that the buffers are larger and the overhead of always ensuring that DE points to the proper I/O Control Block before each routine is called is present. 6.4.1. Open File Routine: FYISOPEN, FYO$OPEN Function: Open the file whose I/O Control Block (IOCB) is pointed to by DE for Input (FYI$OPEN) or Output (FYO$OPEN). FYI$OPEN opens the file in the current directory after initializing the PCB and loads as much of the buffer space as possible with data from the file. If the file does not exist, FYI$OPEN returns an error code. FYO$OPEN deletes the file referenced by the FCB if it exists and opens the referenced file for output. If there is no directory space remaining in which to store the file's entry, FYO$OPEN returns an error code. The FYIO standard error return codes are used. A=0 and Zero Flag Set (Z) if error. Inputs: DE = ptr to I/O Control Block of file to open Outputs: A=0 and Zero Flag Set (Z) if error; A=OFFH and Zero Flag Reset (NZ) if OK Registers Affected: PSW SYSLIB Routines Called: INITPCB, F$OPEN, F$DELETE, F$MAKE, F$READ Special Error Conditions: None 6.4.2. Close File Routine: FYI$CLOSE, FYO$CLOSE Function: Close the file whose I/O Control Block (IOCB) is Pointed to by DE. FYI$CLOSE simply closes the file. FYO$CLOSE flushes the working buffer to disk, filling the last 128-byte block with "Z's if not completely filled already, and closes the file. The FYIO standard error return codes are used. A=0 and Zero Flag Set (Z) if error. Inputs: DE pts to I/O Control Block Outputs: A=0 and Zero Flag Set (Z) if Close Error; A=OFPH and Zero Flag Reset ; . < > 6-20 ZCPR3: The Libraries SYSLIB File Manipulation The following are valid examples: test.txt a:t 5:t cl0:x.y FN=TEXT FT=TXT, B reg = OFFH, C reg = OFFH FN=T FT=, B reg = 1, C reg = OFFH FN=T FT=, B reg = OFFH, C reg = 5 FN=X FT=Y, B reg = 3, C reg = 10 Inputs: HL points to the first byte of the target string (which ends in a delimiter) DE pts to the first byte of a 36-byte long FCB Outputs: B=Disk Number (1 for A to 16 for P, or OFFH if no disk specified) C=User Number (0 to 31 or '?' for all users, or OFFH if no user specified) HL points to the character which ended the scan A = 0 and Zero Flag Set (Z) if invalid Disk or User Specified; A = OFFH and NZ if no error Registers Affected: PSW, BC, HL SYSLIB Routines Called: CAPS Special Error Conditions: None 6.6.2. FCB Initialization Routine; INITFCB Function: INITFCB simply clears all of the fields of a 36- byte FCB to zero except for the FN and FT (File Name and File Type) fields, which it leaves untouched. Inputs: DE = pointer to FCB buffer Outputs: None Registers Affected: None SYSLIB Routines Called: FILLB Special Error Conditions: None 6.6.3. Set DMA Address Routine; SETDMA Function: SETDMA sets the DMA address to the 128-byte block whose address is contained in HL. Inputs; HL = Address of 128-byte block Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 6-21 ZCPR3: The Libraries SYSLIB File Manipulation NOTES: 6-22 ZCPR3: The Libraries SYSLIB Directory Manipulation 7. DIRECTORY MBNIPDIATION CHAPTER OUTLINE Memory Allocation Allocate a Block of Memory ALLOC Initialize Memory Allocation Buffer IALLOC Parsing Aids Character Skip SKNPUN, SKNSP, SKPUN, SKSP Character Test ISALNUM, ISALPHA, ISCTRL, ISDIGIT, File Size Computation FSIZE Free Space Computation DFREE General-Purpose DIRF, DIRFS DIRQ, DIRQS 7-1 ZCPR3: The Libraries SYSLIB Directory Manipulation This set of SYSUB routines concerns itself with the loading of and access of a disk directory for the general purposes of the user. Included in this set of routines are the functions of; 1. Pre-allocation of buffer space for the routines 2. Loading of all undeleted directory entries into a buffer, constantly checking for memory overflow as they go 3. Determining the amount of free space on the disk 4. Computing the size of a file in K-bytes 5. Sorting a loaded directory by file name and type or by file type and name 6. Selecting (by marking) a set of directory entries which match a given ambiguous file spec 7. Packing the loaded directory, leaving in it only those entries marked by the select routine The majority of these routines is intended to be used to provide a flexible directory access system which can be tailored by the user to his specific needs. For instance, with the DIRLOAD routine separated from the rest, several different loads of the directory (from, for instance, different ambiguous file specs) can be performed, and then one selection and one sort on all file specs loaded can be done. The DIRQ/DIRQS pair are intended for those applications which do not need this kind of flexibility. DIRQ (quick) and DIRQS (quick with sizing information) perform a load, select, and sort based on only one file specification. Using DIRQ/DIRQS instead of DIRF/DIRFS results in less code being generated and (generally) faster execution. Directory Buffer Structure DIRLOAD and DIRSLOAD are used to load a directory from disk into memory. The entries loaded are all non-deleted entries in either a particular user area or all user areas on the disk which is currently logged in. Each file entry in this buffer is 16 bytes long, and it is structured as follows: 7-2 ZCPR3: The Libraries SYSLIB Directory Manipulation DB DB DB DB DB DB user •FILENAME' •TYP' ext 0,0 rec user number of file name of file type of file extent of file* uninteresting - leave alone record count in this extent * ext is the file extent; for DIRLOAD, it is the first extent number of the file; for DIRSLOAD, it is the last extent number of the file Bow To Use These Routines The DIRF or DIRFS routines will probably be used to perform your directory access functions the vast majority of the time. Given a buffer, an ambiguous file spec, and a selection flag, DIRF and DIRFS load the desired files for you and then you can work with the 16-byte file entries from there. A typical calling sequence for DIRF or DIRFS is: CALL CODEND LXI D.FCB MVI A,1100$OOOOB CALL DIRF JZ TPAOVFL point to buffer space point to FCB of file spec select all files in user 0 load entries error condition HL pts to first entry, BC= number of entries If the user wishes to deviate from the "normal" use for DIRF and DIRFS, access to the routines used by DIRF and DIRFS is available. A case in which you may want to do this is when you are interested in files which match more than one file spec, such as *.ASM and *.TXT. A typical calling sequence for this type of access is: Setup CALL CODEND CALL DBUFFER CALL DIRLOAD JZ TPAOVFL Select first set of files LXI D.FCB1 MVI A,1100$OOOOB CALL DIRSEL point to buffer space get internal info and ptrs or DIRSLOAD to load entries error condition ; pt to first FCB to match ; select all files in user 0 ; select file entries from ; buffer Repeat the following 2 lines as necessary LXI D.FCB2 ; pt to 2nd FCB to match CALL DIRSEL ; select again 7-3 ZCPR3: The Libraries SYSLIB Directory Manipulation ; Finish up CALL DIRPACK ; pack the file entries, ; leaving only the valid ; entries in the buffer MVI A,0 ; alphabetize CALL DIRALPHA ; Done — HL pts to first file entry, BC=number of entries 7.1. Buffer Allocation Routine; DBCFFER Function: This routine allocates the buffer space necessary for use by the set of directory functions. In particular, it allocates the necessary space for the alphabetization function as well as the loaded directory itself. This routine must be used if the DIRALPHA routine is to be later used to sort the directory; this routine allocates all the space necessary by DIRALPHA to sort the routine (pointer space). If this routine is called, it is not necessary to call the DPARAMS routine. Inputs: HL points to the beginning address of a buffer area which extends to under the CCP (usually set by a call to CODEND) Outputs: HL points to the first byte at which the directory entries are to be loaded A=0 and Zero Flag is Set (Z) if the CCP is already overrun; else, AOO and NZ Registers Affected: HL, PSW SYSLIB Routines Called: DPARAMS Special Error Conditions: As indicated 7.2. Directory Alphabetization Routine: DIBALPHA Function: To alphabetize the files in the directory pointed to by HL by either file name and type (STEST.ASM goes before TEST.AAA) or by file type and name (TEST.AAA goes before STEST.ASM). Inputs: HL points to first directory entry (usually set by DBUFFER) BC contains the number of files to sort (usually set by DIRLOAD or DIRSLOAD) A is the sort flag; A=0 means sort by file name and then file type, AOO means by file type and name Outputs: None (directory list is sorted) Registers Affected: PSW SYSLIB Routines Called: PRINT Special Error Conditions: It is possible, altho highly unlikely from all tests given so far, that DIRALPHA may experience an internal error. If this happens, the message: DIRALPHA — Pointer Error will be printed and the routine will abort to the operating system. 7-4 ZCPR3: The Libraries SYSLIB Directory Manipulation • 7.3. Directory Entry Selection Routine; DIRSEL Function: DIRSEL selects all entries in the directory buffer which match the ambiguous file name specified in the FN and FT fields of the FCB pointed to by DE upon entry to DIRSEL. A selection flag is also passed to DIRSEL in the A register, and this flag tells DIRSEL whether or not to include Non-System files and System files in the selection and whether to select files in all user areas or in a particular user area. DIRSEL identifies the selected file entries by setting the Most Significant Bit of the first byte of each of these entries to 1 if the entry is selected. DIRSEL makes no other changes to the file entries in the directory buffer. Inputs: HL points to the directory buffer (usually set by DBUFFER) DE points to the FCB containing the ambiguous FN and FT fields; only the first 12 bytes are needed BC contains the number of files in the directory (usually set by DIRLOAD or DIRSLOAD) A contains a selection flag, organized as follows; Bit 7 - Select Non-System Files Bit 6 - Select System Piles Bit 5 - Select Files in All User Areas Bits 4-0 - If Bit 5 is 0, indicates number of User Area to select files from Outputs: None (MSBs of selected entries are set) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions; None 7.4. Directory Load Routine; DIRLQAD, DIRSLQAD Function; DIRLOAD and DIRSLOAD load entries for all undeleted files on the currently logged in disk into the memory buffer pointed to by HL. All entries are 16 bytes long. DIRLOAD is faster than DIRSLOAD. It loads just the first entry of each file on disk. DIRLOAD, however, should be used only if file sizing information is not required by the applications program. DIRSLOAD loads just the LAST entry of each file on disk. This entry contains the necessary file sizing information which may be used by FSIZE to compute the size of the loaded file. If the TPA is filled during DIRLOAD or DIRSLOAD and there are still more file entries to load, the load will be halted and an error return will be made to the caller. On return, if A=0 and the Zero Flag is Set (Z), then a load error occurred; otherwise, the load was OK. Inputs: HL points to the first byte of the directory buffer area; this area extends from after the last buffer used by the applications program to the page before the CCP. If alphabetization is to be done, the value returned in HL by DBUFFER is a correct input for DIRLOAD or DIRSLOAD. 7-5 ZCPR3: The Libraries SYSLIB Directory Manipulation Outputs: BC is the number of files loaded into the buffer A=0 and Zero Flag is Set (Z) if TPA Overflow; AOO and NZ if load OK Registers Affected: BC SYSLIB Routines Called: None Special Error Conditions: If TPA is filled and load is incomplete, A=0 and Zero Flag is Set (Z) as error indie 7.5. Directory Pack Routine; DIRPACK Function: DIRPACK restructures the directory buffer to contain only those entries marked by DIRSEL. In this way, those entries NOT marked by DIRSEL are discarded from the buffer (actually, just taken out of consideration, but the contents of the buffer after the last selected entry is not guaranteed to contain anything significant). The Most Significant Bit of the first byte of all entries remaining in the directory buffer is reset to 0 as a side effect of DIRPACK. Inputs: HL points to the directory buffer (usually set by DBUFFER) BC contains the number of files in the buffer (usually set by DIRLOAD or DIRSLOAD) Outputs: BC contains the number of files (those selected by DIRSEL) remaining in the directory buffer Registers Affected: BC SYSLIB Routines Called: None Special Error Conditions: None Routine: DIRNPACK Function: DIRNPACK restructures the directory buffer to contain only those entries NOT marked by DIRSEL. In this way, those entries marked by DIRSEL are discarded from the buffer (actually, just taken out of consideration, but the contents of the buffer after the last selected entry is not guaranteed to contain anything significant). The Most Significant Bit of the first byte of all entries remaining in the directory buffer is reset to 0 as a side effect of DIRNPACK. The routine DIRSEL MUST be called before DIRNPACK is used since DIRNPACK uses an internal flag set by DIRSEL < for SYSTEM and R/0 information). Inputs: HL points to the directory buffer (usually set by DBUFFER) BC contains the number of files in the buffer (usually set by DIRLOAD or DIRSLOAD) Outputs: BC contains the number of files (those NOT selected by DIRSEL) remaining in the directory buffer 7-6 ZCPR3: The Libraries SYSLIB Directory Manipulation Registers Affected: BC SYSLIB Routines Called: DIRPACK Special Error Conditions: None 7.6. Disk Parameter Information Extraction Routine: DPARAMS Function: This routine extracts necessary information from the Disk Parameter Block (DPB) and stores it away in some global buffers used by other Disk Directory Routines. The information extracted is not of general concern by the programmer. ALL THE PROGRAMMER NEEDS TO KNOW IS THAT THIS ROUTINE MUST BE CALLED AT LEAST ONCE BEFORE THE DIRLOAD OR DIRSLOAD ROUTINE IS CALLED. If the DBUFFER routine is called, then it is not necessary to call DPARAMS again. For the information of the reader, the following information is extracted: BLKSHF <— Block Shift Factor (1 Byte) BLKMSK <-- Block Mask (1 Byte) EXTENT <— Extent Mask (1 Byte) BLKMAX <— Max Number of Blocks on Disk (2 Bytes) DIRMAX <— Max Number of Dir Entries (2 Bytes) This routine automatically adjusts for versions 1.4 and 2.2 of CP/M and is compatable with both versions of CP/M. Inputs: None Outputs: None (Information Extracted into Buffers) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 7.7. File Size Computation Routine: FSIZE Function: This routine computes the size of a file whose entry (which MUST be loaded by DIRSLOAD) is pointed to by HL. This routine will work, but generally return incorrect results, if the entry pointed to was loaded by DIRLOAD instead. The routine DPARAMS (or DBUFFER, DIRF, or DIRFS, since they also call DPARAMS) must be called before this routine is used so that the correct disk parameter information is loaded for it. Inputs: HL points to first byte of file entry in vector loaded by DIRSLOAD or DIRFS (each file entry is 16 bytes long) Outputs: DE contains the file size in K Bytes Registers Affected: DE SYSLIB Routines Called: None Special Error Conditions: None 7.8. Free Space Computation Routine: DFREE Function: This routine computes the amount of free space (in K bytes) left on disk. 7-7 ZCPR3: The Libraries SYSLIB Directory Manipulation The routine DPARAMS (or DBUFFER, DIRF, or DIRFS, since they also call DPARAMS) must be called before this routine is used so that the correct disk parameter information is loaded for it. Inputs: None Outputs: DE = Amount of Free Disk Space in K Bytes Registers Affected: DE SYSLIB Routines Called: None Special Error Conditions: None 7.9. General-Purpose Routine: DIRF, DIRFS Function; This routine initializes the buffer area, loads a disk directory, selects a set of files from the loaded directory specified by the user's ambiguous file name and a passed flag (which indicates if System files are selected. Non-system files are selected, all user areas are to be covered, and what particular user area is to be covered if all user areas are not selected), packs the directory, and alphabetizes the directory by file name and file type. If DIRF is used, the processing proceeds faster since only the first entry of each file is loaded into the memory buffer. Pile sizing information is not included in this load, however. If DIRFS is used, the processing is somewhat slower, but the last entry for each file is loaded rather than the first. File sizing information is contained in this entry, and this information can be used by the FSIZE routine. Inputs: HL points to a buffer area which extends from after the user's code and buffer areas to the end of the TPA (usually set by a call to CODEND) DE points to the first byte of the FCB used to specify the ambiguous file name; only the chars in the FN and FT fields are significant, so this need not be a true FCB and may be as short as 12 bytes A is the selection flag, structured as follows: Bit 7 - If Set, Select Non-System Piles Bit 6 - If Set, Select System Files Bit 5 - If Set, Select All User Areas Bits 4-0 - If Bit 5 is Cleared, contains number of User Area to Select Outputs: HL points to the first file entry in the buffer; each file entry is 16 bytes long BC contains the number of files selected A contains an error flag; A=0 and Zero Flag Set CALL GETUD ; Return to marked location RETUD and LOGUD are to be used to find out where the program is (RETUD) and to enter a specific disk/user area (LOGUD). For example: CALL RETUD ; Find out where we are PUSH B ; Save Disk/User < move around on disks/users > POP B ; Get Disk/User CALL LOGUD ; Log into Disk/User GUA and SUA are to be used to find out what user area the program is in (GUA) and to enter a specific user area (SUA). For example: CALL GUA ; Find out current user PUSH PSW ; Save it < move around on other user areas> POP PSW ; Get current user CALL SUA ; Log into User GUA and SUA are useful in conjunction with the automatic disk logging feature of CP/M, where the first byte of the FCB indicates a disk to autolog into (1=A, 2=B, etc., 0=default). 8-2 ZCPR3: The Libraries SYSLIB User Areas and Disks 8.1. Save and Restore Disk/User Area Routine: GETUD Function: GETUD restores the current user and disk which was saved by PUTUD. The value of the current user and disk saved by PUTUD is stored internally to the GETUD/PUTUD module and is not available to the user. Inputs: None Outputs: None Registers Affected: None SYSLIB Routines Called: BDOS Special Error Conditions: None Routine: PUTUU Function: PUTUD saves the current user and disk numbers away for later retrieval by GETUD. PUTUD and GETUD are intended to be used to save and restore the current disk and user around some set of operations in another user/disk area. The values saved by PUTUD are stored in buffers internal to the GETUD/PUTUD module and are not available to the user. Inputs: None Outputs: None Registers Affected: None SYSLIB Routines Called: RETUD Special Error Conditions: None 8.2. Get and Set Current User Area Routine; GDA Function: GUA returns the current user area in the A register. There are no error codes associated with this function. Inputs: None Outputs: A = User Area (0-31) Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None Routine: SOA Function: SUA logs the program into the user area represented by the low-order 5 bits of the A register (value 0- 31). There are no error codes associated with this function. Inputs: A = User Area (0-31) Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 8.3. Log Into a Disk/User Routine; LOGUD Function: LOGUD logs in the disk specified by the B register (B=0 for Disk A) and the user specified by the C register. Inputs: B=Disk (B=0 for Disk A), C=User 8-3 ZCPR3: The Libraries SYSLIB User Areas and Disks Outputs: None Registers Affected: None SYSLIB Routines Called: BDOS Special Error Conditions: None 8.4. Return the Current Disk/User Routine; RETUD Function: RETUD returns the numbers of the current user in C and current disk in B CALL ACASE1 DB SIZE DW ERROR DB VAL1 DW ADDR1 DB VAL2 DW ADDR2 NUMBER OF ENTRIES IN TABLE GO HERE IF NO MATCH FIRST VALUE TO TEST FOR GO HERE IF A = VAL1 2ND VALUE TO TEST FOR GO HERE IF A = VAL2 DB VAL$SIZE ; 'SIZE' VALUE TO TEST FOR DW ADDR$SIZE ; GO HERE IF A = VAL$SIZE The following example illustrates the Computed GOTO; < register A = index < zero-relative) > CALL AGOT01 DW ADDRO ; GO HERE IF A = 0 DW ADDR1 ; GO HERE IF A = 1 DW ADDRN ; GO HERE IF A = N The following example illustrates the Computed GOTO with limits; < register A = index (zero-relative) > < register B = limit > CALL AGOT01 DW ADDRO ; GO HERE IF A = 0 DW ADDR1 ; GO HERE IF A = 1 DW ADDRN < error code > ; GO HERE IF A = N ; RESUME AFTER DW ADDRN IF A > B The following example illustrates the Arithmetic IF: < register A = key value > < register B = test value > CALL AIF1 DW ADDRLT ; GO HERE IF A < B DW ADDREQ ; GO HERE IF A = B DW ADDRGT ; GO HERE IF A > B See the SYSLIB test program STEST014.MAC for examples of use of all of the branching routines. 9-2 ZCPR3: The Libraries SYSLIB Branching The following routines are provided: Routine ACASE1 ACASE2 ACASE3 HCASE1 HCASE2 HCASE3 AGOT01 AGOT02 HGOT01 HGOT02 BGOT01 BGOT02 DGOT01 DGOT02 AIF1 AIF2 HIF1 HIF2 Comments Case statement with A = key value Like ACASE1, but DE = address of case table Like ACASE2, but return address is left on stack Like ACASE1, but HL Like ACASE2, but HL Like ACASE3, but HL key value key value key value Computed GOTO with A = key value Like AGOT01, but JMPs rather than DW follow Computed GOTO with HL = key value Like AGOT02, but HL = key value Like AGOT01, but B -- Like AGOT02, but B -- limit value limit value ; limit value : limit value Like HGOT01, but DE Like HGOT02, but DE Arithmetic IF with A, B = values Like AIF1, but JMPs rather than DW follow Arithmetic IF with HL, Like AIF2, but HL, DE •• DE = values : values 9.1. Case with Register A Routine: ACASE1 Function: ACASE1 is a case statement processor. On input, register A contains a value to test against. This value is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the matching value. This case acts as a multiway JMP instruction (return address from the call to ACASE1 is not retained). Example: MVI A,TEST CALL ACASE1 DB N DW DEFAULT DB VAL1 DW ADDR1 DB DW VALN ADDRN ; number of entries in the table ; go to this address if no match ; test for TEST = VAL1 ; go here if TEST = VAL1 ; test for TEST = VALN ; go here if TEST = VALN Inputs: A = value to test for Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9-3 ZCPR3: The Libraries SYSLIB Branching Routine: ACASE2 Function: ACASE2 is a case statement processor. On input, register A contains a value to test against and DE contains the address of the case table. The value in register A is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the matching value. This case acts as a multiway JMP instruction (return address from the call to ACASE2 is not retained). Example: MVI A,TEST LXI D,TABLE CALL ACASE2 value to test for address of table TABLE: DB N DW DEFAULT DB VAL1 DW ADDR1 DB DW VALN ADDRN number of entries in the table go to this address if no match test for TEST = VAL1 go here if TEST = VAL1 test for TEST = VALN go here if TEST = VALN Inputs: A = value to test for DE = address of case table Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; ACASE3 Function: ACASE3 is a case statement processor. On input, register A contains a value to test against and DE contains the address of the case table. The value in register A is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the matching value. This case acts as a multiway CALL instruction (return address from the call to ACASE3 is left on the stack). Example: MVI A,TEST LXI D,TABLE CALL ACASE3 < resume execution here if routines execute an RET instr > value to test for address of table TABLE: DB DW DB DW • • « DB DW N ; number of entries in the table DEFAULT ; go to this address if no match VAL1 ; test for TEST = VAL1 ADDR1 ; go here if TEST = VAL1 VALN ; test for TEST = VALN ADDRN ; go here if TEST = VALN 9-4 ZCPR3: The Libraries SYSLIB Branching Inputs: A = value to test for DE = address of case table Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9.2. Case with Register Pair HL Routine: HCASE1 Function; HCASE1 is a case statement processor. On input, register pair HL contains a value to test against. This value is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the matching value. This case acts as a multiway JMP instruction (return address from the call to HCASE1 is not retained). Example: LXI H,TEST CALL HCASE1 DW N ; number of entries in the table DW DEFAULT ; go to this address if no match DW VAL1 ; test for TEST = VAL1 DW ADDR1 ; go here if TEST = VAL1 DW VALN ; test for TEST = VALN DW ADDRN ; go here if TEST = VALN Inputs: HL = value to test for Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; HCASE2 Function: HCASE2 is a case statement processor. On input, register pair HL contains a value to test against and DE contains the address of the case table. The value in register pair HL is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the value. This case acts as a multiway JMP instruction the call to HCASE2 is not retained). matching (return address from Example: LXI H.TEST LXI D,TABLE CALL HCASE2 value to test for address of table TABLE: DW N DW DEFAULT DW VAL1 DW ADDR1 ; number of entries in the table ; go to this address if no match ; test for TEST = VAL1 ; go here if TEST = VAL1 DW VALN ; test for TEST = VALN DW ADDRN ; go here if TEST = VALN 9-5 2CPR3: The Libraries SYSLIB Branching Inputs: HL = value to test for DE = address of case table Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine: HCASE3 Function: HCASE3 is a case statement processor. On input, register pair HL contains a value to test against and DE contains the address of the case table. The value in register pair HL is compared to the values in a case table, and, if a match is found, control is transferred to the address associated with the matching value. This case acts as a multiway CALL instruction (return address from the call to HCASE3 is left on the stack). Example: LXI H,TEST } value to test for LXI D,TABLE ; address of table CALL HCASE3 < resume execution here if routines execute an RET instr > TABLE; DW N DW DEFAULT DW VAL1 DW ADDR1 DW DW VALN ADDRN number of entries in the table go to this address if no match test for TEST = VAL1 go here if TEST = VAL1 test for TEST = VALN go here if TEST = VALN Inputs: HL = value to test for DE = address of case table Outputs: None (branch is made) Registers Affected: None SYSLIB Routines Called: Itone Special Error Conditions: None 9.3. Computed Goto with Register A Routine: AQOT01 Function: AGOTOl is a computed GOTO. When called, register A = index (zero-relative) of the following address to branch to. No information is available on the number of allowed values, so it is the programmer's responsibility to see that the range of the Computed GOTO is not exceeded. Example: MVI A,INDEX CALL AGOTOl DW ADDRO DW ADDR1 DW ADDRN ; Index value ; GO HERE IF A = 0 ; GO HERE IP A = 1 ; GO HERE IP A = N 9-6 ZCPR3: The Libraries SYSLIB • Branching Inputs: A = index value (zero-relative) Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; AGOT02 Function: AGOT02 is a computed GOTO. When called, register A = index (zero-relative) of the following address to branch to. No information is available on the number of allowed values, so it is the programmer' s responsibility to see that the range of the Computed GOTO is not exceeded. Example: MVI A,INDEX ; Index value CALL AGOT02 JMP ADDRO ; RETURN TO THIS JMP IF A = 0 JMP ADDR1 ; RETURN TO THIS JMP IF A = 1 • • • JMP ADDRN ; RETURN TO THIS JMP IF A = N < next instr > ; RETURN TO THIS INSTR IF A = N+l Inputs: A = index value (zero-relative) Outputs: None Registers Affected; None SYSLIB Routines Called: None Special Error Conditions; None Routine: BGOT01 Function: BGOT01 is a computed GOTO. When called, register A = index (zero-relative) of the following address to branch to. Register B = maximum value allowed for the index (register A). If A > B, then control is transferred to after the last address in the table. Example: MVI A,INDEX ; Index Value MVI B,LIMIT ; Maximum Index Value CALL BGOT01 DW ADDRO ; GO HERE IF A = 0 DW ADDR1 ; GO HERE IF A = 1 • • • DW ADDR$LIMIT; GO HERE IF A = LIMIT < next instruction >; RETURN TO THIS INSTRUCTION IF A > LIMIT Inputs: A = index value (zero-relative) B = maximum index value allowed Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9-7 ZCPR3: The Libraries SYSLIB Branching Routine; BGOT02 Function: BGOT02 is a computed GOTO. When called, register A = index (zero-relative) of the following address to branch to. Register B = maximum value allowed for the index (register A). If A > B, then control is transferred to after the last address in the table. Example: MVI A,INDEX MVI B,LIMIT CALL BGOT02 JMP ADDRO JMP ADDR1 Index value Maximum Index Value RETURN TO THIS JMP IF A RETURN TO THIS JMP IP A JMP ADDR$LIMIT; RETURN TO THIS JMP IF A = LIMIT < next instr > ; RETURN TO THIS INSTR IF A > LIMIT Inputs: A = index value (zero-relative) B = maximum index value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9.4. Computed Goto with Register Pair HL Routine; HGOTOl Function: HGOTOl is a computed GOTO. When called, register pair HL = index (zero-relative) of the following address to branch to. No information is available on the number of allowed values, so it is the programmer's responsibility to see that the range of the Computed GOTO is not exceeded. Example: LXI H,INDEX CALL HGOTOl DW ADDRO DW ADDR1 Index value GO HERE IF HL = 0 GO HERE IF HL = 1 DW ADDRN GO HERE IF HL N Inputs: HL = index value (zero-relative) Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; HGOTO2 Function: HGOTO2 is a computed GOTO. When called, register pair HL = index (zero-relative) of the following address to branch to. No information is available on the number of allowed values, so it is the programmer's responsibility to see that the range of the Computed GOTO is not exceeded. Example: 9-8 ZCPB3: The Libraries SYSLIB Branching LXI H,INDEX CALL HGOT02 JMP ADDRO JMP ADDR1 • • • JMP ADDRN < next instr > Index value ; RETURN TO THIS JMP IF HL = 0 ; RETURN TO THIS JMP IF HL = 1 ; RETURN TO THIS JMP IF HL = N ; RETURN TO THIS INSTR IF HL = N+l Inputs: HL = index value (zero-relative) Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; DGOTO1 Function: DGOTO1 is a computed GOTO. When called, register pair HL = index (zero-relative) of the following address to branch to. Register pair DE = maximum value allowed for the index (register pair HL). If HL > DE, then control is transferred to after the last address in the table. Example: LXI H,INDEX LXI D,LIMIT CALL DGOTO1 DW ADDRO DW ADDR1 ; Index Value ; Maximum Index Value GO HERE IF HL GO HERE IF HL DW ADDR$LIMIT; GO HERE IF HL = LIMIT < next instruction >; RETURN TO THIS INSTRUCTION IF HL > LIMIT Inputs; HL = index value (zero-relative) DE = maximum index value allowed Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions; None Routine; DGOT02 Function; DGOT02 is a computed GOTO. When called, register pair HL = index (zero-relative) of the following address to branch to. Register pair DE = maximum value allowed for the index (register pair HL). If HL > DE, then control is transferred to after the last address in the table. Example: LXI H,INDEX LXI D,LIMIT CALL DGOT02 JMP ADDRO JMP ADDR1 ; Index value ; Maximum Index Value ; RETURN TO THIS JMP IF HL ; RETURN TO THIS JMP IF HL JMP ADDR$LIMIT; RETURN TO THIS JMP IF HL = LIMIT < next instr > ; RETURN TO THIS INSTR IF HL > LIMIT 9-9 ZCPR3: The Libraries SYSLIB Branching Inputs: HL = index value (zero-relative) DE = maximum index value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9.5. Arithmetic IF with Register A Routine; AIF1 Function: AIF1 is an arithmetic IF facility. A key value is passed in the B register and a test value is passed in the A register. Branching is done depending on the following tests: A < B, A = B, and A > B. Example: MVI A,TEST ; test value MVI B,KEY ? key value CALL AIF1 DW ALTB ; GO HERE IF A < B DW AEQB ; GO HERE IF A = B DW AGTB ; GO HERE IF A > B Inputs: A = test value B = key value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine: AIF2 Function: AIF2 is an arithmetic IF facility. A key value is passed in the B register and a test value is passed in the A register. Branching is done depending on the following tests: A < B, A = B, and A > B. Example: MVI A, TEST ; test value MVI B,KEY ; key value CALL AIF2 JMP ALTB ; RESUME AT THIS JMP IF A < B JMP AEQB ; RESUME AT THIS JMP IF A = B JMP AGTB ; RESUME AT THIS JMP IF A > B Inputs: A = test value B = key value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9.6. Arithmetic IF with Register Pair HL Routine; HIF1 Function: HIF1 is an arithmetic IF facility. A key value is passed in the DE register pair and a test value is passed in the HL register pair. Branching is done depending on the following tests: HL < DE, HL = DE, and HL > DE. Example: LXI H.TEST ; test value LXI D,KEY ; key value 9-10 ZCPR3: The Libraries SYSLIB Branching CALL HIF1 DW HLTD ; GO HERE IF HL < DE DW HEQD ; GO HERE IF HL = DE DW HGTD ; GO HERE IF HL > DE Inputs: HL = test value DE = key value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; HIF2 Function: HIF2 is an arithmetic IF facility. A key value is passed in the DE register pair and a test value is passed in the HL register pair. Branching is done depending on the following tests: HL < DE, HL = DE, and HL > DE. Example: LXI H.TEST ; test value LXI D,KEY ; key value CALL HIF2 JMP HLTD ; RESUME AT THIS JMP IF HL < DE JMP HEQD ; RESUME AT THIS JMP IF HL = DE JMP HGTD ; RESUME AT THIS JMP IF HL > DE Inputs: HL = test value DE = key value Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 9-11 ZCPR3; The Libraries SYSLIB Branching NOTES: 9-12 ZCPR3: The Libraries SYSLIB Mathematical Functions 10. MATHEMATICAL FUNCTIONS CHAPTER OUTLINE Arithmetic Operations ADDHD, SUBHD, MULHD, DIVHD Complement Operations NEGH, CMPH Logical Operations ANDHD, ORHD, XORHD Rotate and Shift Operations ROTLH, ROTRH, SHFTLH, SHFTRH Random Number Generator RNDINIT, RNDSEED, RND CRC Calculation CRCCLR, CRC1CLR, CRC2CLR CRCUPD, CRC1UPD, CRC2UPD CRCDONE, CRC1DONE, CRC2DONE 10-1 ZCPR3: The Libraries SYSLIB Mathematical Functions Mathematical Functions This set of routines are 16-bit unsigned mathematical functions. All routines use HL as the accumulator or the result, and HL and DE contain the operands required (if only one operand is needed, HL contains it). The available routines are: ADDHD — HL = HL + DE SUBHD — HL = HL - DE MULHD — HL = HL * DE DIVHD — HL = HL / DE NEGH — HL = 2's Complement of HL CMPH — HL = 1's Complement of HL ROTLH — HL is rotated left one bit position ROTRH — HL is rotated right one bit position SHFTLH — HL is shifted left one bit position SHPTRH — HL is shifted right one bit position ANDHD — HL = HL AND DE ORHD — HL = HL OR DE XORHD — HL = HL XOR DE RNDINIT — initialize random number generator RNDSEED — set seed for random number generator RND — generate random number CRCCLR, CRC1CLR, CRC2CLR — clear CRC accumulator CRCOPD, etc — update CRC value CRCDONE, etc — return accumulated CRC 10.1. Arithmetic Operations All of these routines operate on HL and DE, placing the result in HL. The Carry Flag is affected, frequently used to indicate overflow. The functions provided are add, subtract, multiply, and divide. Routine; ADOBD Function; HL = HL + DE Inputs: HL, DE are operands Outputs: HL is result. Carry Flag Set (C) means overflow Registers Affected: HL, PSW SYSLIB Routines Called: None Special Error Conditions: None 10-2 ZCPR3: The Libraries SYSLIB Mathematical Functions Routine: SDBHD Function: HL = HL - DE Inputs; HL, DE are operands Outputs: HL is result. Carry Flag Set (C) if HL ; ACQUIRE VALUES GET VALUE SAVE VALUE ROUTINE TO CHECK INCOMING CRC VALUE CLEAR CRC CRCUPD> ; ACQUIRE VALUES GET VALUE VALUE IN DE GET FIRST VALUE IN HL COMPARE HL TO DE CRC'S DON'T MATCH IF NOT EQUAL The following describe the CRC routines. The CRC-routines approximate the X"16+X~12+X~5+1 polynomial, the CRCl-routines use the X"16+X''15+X"2+1 polynomial, and the CRC2-routines use the public-domain hash code (CRC2 is the public-domain standard of Keith Petersen). 10-6 ZCPR3: The Libraries SYSLIB Mathematical Functions Routine: CRCCLR, CRC1CLR, CRC2CLR Function: Clear the internal CRC Accumulator in preparation to CRC computation. CRC2 is the public domain standard originated by Keith Peter sen. Inputs: None Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; CRCDPD, CRC1UPD, CRC2UPD Function: Update the CRC Accumulator value. Inputs: A=byte to be included in CRC Outputs: None Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None Routine; CRCDONE, CRC1DONE, CRC2DONE Function: Terminate CRC value accumulation and return the calculated 16-bit CRC value. Inputs: None Outputs: HL = calculated CRC value Registers Affected: HL SYSLIB Routines Called: None Special Error Conditions: None 10-7 ZCPR3: The Libraries SYSLIB Mathematical Functions NOTES: 10-8 ZCPR3: The Libraries SYSLIB Utilities 1 11. UTILITIES 1 CHAPTER OUTLINE Memory Allocation Allocate a Block of Memory ALLOC Initialize Memory Allocation Buffer IALLOC Parsing Aids Character Skip SKNPCN, SKNSP,.SKPUN, SKSP Character Test ISALNUM, ISALPHA, ISCTRL, ISDIGIT, ISGRAPH, ISHEX, ISPRINT, ISPUN, ISSP UNIX-Style ARGC/ARGV String Parser ARGV Sort SSB Initializer SSBINIT SSB Sort SORT String and Value Comparison Substring Search INSTR Value Comparison COMPHD Vector Comparison COMPB, COMPBC Vector Search SCANNER 11-1 ZCPR3; The Libraries SYSLIB Utilities 1 11.1. Memory Allocation The concept of memory allocation with these routines is relatively simple. Routines are provided to give the programmer memory allocation and deallocation capabilities, but the programmer is still in control. The basic idea is to reserve a buffer in memory from which to take bits and pieces from at a time. The bounding addresses of this buffer are specified (or set by default) by the IALLOC routine, and the ALLOC routine is used to obtain subbuffers from this larger buffer from time to time. ALLOC constantly checks to see if the buffer has enough space left to grant the request for a subbuffer, and, if it does, the subbuffer is provided. The largest buffer which may be reserved by the IALLOC routine is that buffer which extends from the end of the program to just below the CCP. This buffer is selected if IALLOC is called with A=0. The following illustrates the application using the largest buffer possible: XRA A ; Select Full Buffer CALL IALLOC LXI D,1024 ; Request 1K CALL ALLOC JZ MEMOVFL ; Abort if Memory Overflow SHLD BUF1 ; Set Pointer to First Subbuffer LXI D,36 ; Request 36 bytes CALL ALLOC J2 MEMOVFL ; Abort if Memory Overflow SHLD BCF2 ; Set Pointer to 2nd Subbuffer This memory allocation scheme also permits the division of memory into a group of buffers. One buffer may be allocated, its address preserved, another buffer may be allocated, its address preserved, and then subsequent calls to IALLOC may be used to select one buffer or the other. Each call to IALLOC frees the entire buffer area, so care should be taken in doing this. For example: 11-2 ZCPR3: The Libraries SYSLIB Utilities 1 CALL CODEND ; Use Codend as First Buffer SHLD BUF1 XCHG ; Address in DE LXI H,1024 ; 1K for this buffer DAD D ; HL pts to after this buffer XCHG ; HL is start, DE is end MVI A,3 ; Select Start and End CALL IALLOC CALL ALLOC ; Calls to ALLOC LHLD BUF1 ; Pt to 1st Buffer LXI D,1024 ; Set 2nd Buffer DAD D ; Pt to 2nd Buffer SHLD BUF2 XCHG DAD D ; Pt to end of 2nd Buffer (1K also) XCHG ; HL is start, DE is end MVI A,3 ; Select Start and End CALL IALLOC CALL ALLOC ; Calls to ALLOC 11.1.1. Allocate a Block of Memory Routine: ALLOC Function: ALLOC allocates a block of memory, which may be as small as one byte, for the user from the buffer pool bounded by the values set by a proceeding call to IALLOC. IALLOC must be called before ALLOC is used. The programmer indicates the number of bytes he wishes to use in the DE register pair. He then calls ALLOC, which, if enough space is available, returns the address of the first byte of that block of memory in HL. The PSW returns a flag saying if the allocation was done successfully. Inputs: DE = number of bytes requested Outputs: HL = Address of first byte allocated A=0 and Zero Flag Set (Z) if not enough space; A=OFFH and Zero Flag Reset (NZ) if request granted Registers Affected: HL, PSW SYSLIB Routines Called: None Special Error Conditions: As indicated by return code 11.1.2. Initialize Memory Allocation Buffer Routine: IALLOC Function: IALLOC initializes the buffer from which memory allocation via calls to the ALLOC routine is to be done. The programmer may specify the bounds of this buffer, or default bounds will be set by IALLOC if none are specified. Upon calling IALLOC, HL may contain the starting address of the buffer area. If it does not, then the end of the user' s program (returned by CODEND) is used. DE may contain the ending address of the buffer area. If it does not, then the byte below the CCP is used. The A register contains a coded flag saying which boundary values to use. If Bit 0 of A is 1, HL is used to indicate the starting address of the buffer. If Bit 0 is 0, the value returned by 11-3 ZCPR3: The Libraries SYSLIB Utilities 1 CODEND is used. If Bit 1 of A is 1, DE is to be used to indicate the ending address of the buffer. If Bit 1 is 0, the byte below the CCP is used. Inputs: HL = Possible Starting Address of Buffer DE = Possible Ending Address of Buffer A = Selection Code: Bit 0 - Use HL as Starting Address if 1 Use CODEND Value if 0 Bit 1 - Use DE as Ending Address if 1 Use CCP-1 if 0 Outputs: None Registers Affected: None SYSLIB Routines Called; CODEND Special Error Conditions: None 11.2. Parsing Aids 11.2.1. Character Skip These routines are used to skip over characters in the string pointed to by HL until either a character of the type they are not skipping is encountered or the end of the string (NULL character) is encountered. The character skip routines are: SKNPUN — Skip Over Non-Punctuation Chars SKNSP — Skip Over Non-Space Chars SKPUN — Skip Over Punctuation Chars SKSP — Skip Over Space Chars A Punctuation Character is a character between SP and DEL which is not 0-9, A-Z, or a-z. A Space Character is any of HT, LF, VT, FF, CR, or SP. All of these routines are characterized as follows: Routine; SKx Function: To skip over a certain class of characters in the string pointed to by HL until a character NOT in the skip group is encountered or the end of the string (NULL character) is encountered. Inputs: HL pts to first character in string Outputs: HL pts to character which terminated the skip Registers Affected: HL SYSLIB Routines Called: ISPUN or ISSP, as appropriate Special Error Conditions: None 11-4 ZCPR3: The Libraries SYSLIB Utilities 1 11.2.2. Character Test The Character Test routines check the character in the A register (after masking out its MSB) to see if it meets a condition. These conditions are: ISALNUM ISALPHA ISCTRL ISDIGIT ISGRAPH ISHEX ISPRINT I SPUN ISSP Is Alphanumeric Char? Is Alphabetic Char? Is Control Char? Is Digit Char? Is Graphic Char? Is Hexadecimal Char? Is Printable Char? Is Punctuation Char? Is Space Char? In all cases, the routines conform to this description: Routine; ISx Function: To test to see if the character in A meets a certain condition < the MSB is masked off of A before the test). Inputs: A = Char Outputs: Zero Flag is Set (Z) if Condition is TRUE; Zero Flag is Reset (NZ) if Cond is FALSE; A is not affected, only PSW Registers Affected: PSW (NOT including A) SYSLIB Routines Called: None Special Error Conditions; None Notes: The characters tested for by these routines are: ISALNUM ISALPHA ISCTRL ISDIGIT ISGRAPH ISHEX ISPRINT I SPUN ISSP Is Alphanumeric Char? Is Alphabetic Char? Is Control Char? Is Digit Char? Is Graphic Char? Is Hexadecimal Char? Is Printable Char? Is Punctuation Char? Is Space Char? A-Z, a-z, 0-9 A-Z, a-z Less than SP or DEL 0-9 Between SP and DEL 0-9, A-F, a-f Between SP and DEL, inci SP Between SP and DEL, DEL, NOT 0-9, A-Z, or a-z HT, LP, VT, FF, CR, and SP 11.2.3. UNIX-Style ARGC/ARGV String Parser Routine: ARGV Function: ARGV is a UNIX-style ARGC/ARGV string parser. It is passed a null-terminated string in HL and the address of a token pointer table which is structured as follows: 11-5 ZCPR3: The Libraries SYSLIB Utilities 1 number of token pointers number of tokens found by ARGV pointer to token 1 (in string) pointer to token 2 (in string) filled DB DS MAX$ENT 1 in DS 2 byARGV DS• * • 2 DS 2 pointer to token MAX$ENT (in string) Tokens are delimited by spaces and tabs. For example: " THIS IS FUN " contains three tokens, and ARGV will return pointers to the T in THIS, the I in IS, and the F in FUN. If A 0 0 on input, ARGV will store a binary 0 (null) into the string after each token for later ease in analysis. In the above example, a 0 would be stored over the first space following the S in THIS, the S in IS, and the N in FUN. If A=0, ARGV does not make any changes to the string. See the SYSLIB test program STEST016.MAC for examples of the use of ARGV. On output, ARGV has loaded its pointers into the token table and returns with A=0 and the Zero Flag Set if no error. If there were more tokens in the string than allowed for in the token table, ARGV returns with A=OFFH and the Zero Flag Reset (NZ). In this case, the last token pointer points to the last token allowed, and this extends to the end of the string. The null is not placed after the last token, so the rest of the string appears as a token (and may be parsed by ARGV again). Inputs: HL = address of string DE = address of token table A = 0 if null is not to be placed after each token OFFH if null is placed after each token 0 and Zero Flag Set (Z) if no error OFFH and Zero Flag Reset (NZ) if more tokens than allowed for (last token pointer points to the rest of the string) Registers Affected: PSW SYSLIB Routines Called: -None- Special Error Conditions: None A Outputs: A A 11.3. Sort Two routines are provided which give the SYSLIB programmer access to a very flexible sorting system. The main routine is called SORT, and it provides a utility which does an in-memory sort of a set of fixed-length records. The sorting technique used is a Shell Sort, adapted from the book "Software Tools" by Kernigan and Plaugher, published by Addison-Wesly, 1976, page 106. This sort is very fast, much more so than the simple bubble sort. The Shell Sort can be done in two ways: with or without using pointers. Sorting without using pointers is typically slower than sorting with pointers, and the only advantage to not using pointers is the savings of space which is taken up by the pointers <2*nurober of entries bytes). If pointers are used for the sort, then whenever an exchange is done, the pointers are 11-6 ZCPR3: The Libraries SYSLIB Utilities 1 simply exchanged, rather than the full records, and this greatly decreases the sort time in most casts. The SORT routine is controlled by passing to it a pointer to a Sort Specification Block (SSB) in DE. This Sort Specification Block is a series of 2-byte words -which contain the following information; Bytes O&l: Starting Address of 1st Record Bytes 2&3: Number of Records to Sort Bytes 4&5: Size of Each Record (in Bytes) Bytes 6&7: Address of Compare Routine Provided by User This routine compares two records, one pointed to by HL and the other pointed to by DE. If the record pointed to by DE is less in sorting order than that pointed to by HL, this Compare Routine is to return with Carry Set (C). If the records are equal in sorting order, this Compare Routine is to return with Zero Set (Z). Only the PSW is to be affected by the Compare Routine. Bytes 8&9; Address of Pointer Table Byte 10: Flag; OFFH means to use pointers, 0 means not Byte 11: Unused Two routines are available in the sort module. The first routine, SSBINIT, looks at the beginning of a scratch area and the initial contents of an SSB and allocates space for the pointer table. It also checks to see if the buffer required will overflow the TPA (Transient Program Area). The second routine, SORT, performs the sort, and controlled by the SSB pointer passed to it in DE. 11.3.1. SSB Initializer Routine: SSBINIT Function; This routine loads bytes O&l (address of first record) and 8&9 (address of pointer table) of an SSB, checking for TPA overflow. It is passed the start address of a scratch area, and sets the pointer table to start here, looks at the record size and record count entries of an SSB, and adds this product to the address of the pointer table. The resultant address is returned as the address of the first record. This routine may be used as described above before any records are loaded into memory for the sort, or it may be used after the records have already been loaded. In the latter case, the user should save the start address of the first record and call SSBINIT with the address of the first byte after the last record. Once SSBINIT has loaded the buffers in the SSB and checked for a TPA overflow (note that this is done for the pointers only), it will return to the caller, at which time the caller should restore the first two bytes of the SSB to their proper values, the actual start address of the first record. Inputs: HL pts to start of scratch area, DE pts to SSB Outputs: Z Flag is Set HL=DE, Carry Flag Set HL HL>DE. Inputs; HL, DE — Values to compare Outputs: Zero and Carry Flags Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions; None 11-8 ZCPR3: The Libraries SYSLIB Utilities 1 11.4.3. Vector Comparison Routine; COMPB, OOMPBC Function: Vector Compare Routines. Compare the vector pointed to by HL with that pointed to by DE (Vectors are of equal length) . Vectors are B bytes long for COMPB and BC bytes long for COMPBC. On return. Zero Flag Set (Z) => HL=DE, Carry Flag Set (C) => HL HL>DE. Inputs: HL, DE — Pointers to vectors to compare B (for COMPB), BC (for COMPBC) — number of bytes in vectors Outputs: Zero and Carry Flags Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None 11.4.4. Vector Search Routine; SCANNER Function: SCANNER scans the vector of bytes pointed to by HL for the vector of bytes pointed to by DE. The HL-byte vector is B bytes long and the DE-byte vector is C bytes long. On return, if found, HL points to the beginning location within the original HL vector of the located vector and the Zero Flag is Set; if not found. Zero Flag is not set and HL is not affected (points to the beginning of the original HL-byte vector). Inputs: HL = Pointer to vector to be scanned DE = Pointer to vector to scan for B = Number of bytes in HL-vector C = Number of bytes in DE-vector Outputs: If found. Zero Set and HL pts to located vector If not found. Zero Reset and HL unaffected Registers Affected: PSW, HL SYSLIB Routines Called: None Special Error Conditions: Automatic success if vector searched for is null. 11-9 ZCPR3: The Libraries SYSLIB Utilities 1 NOTES: 11-10 ZCPR3: The Libraries SYSLIB Utilities 2 12. UTILITIES 2 CHAPTER OUTLINE BDOS and BIOS Access BDOS BIOS Capitalization CAPS CAPSTR Command Line Tail Extraction CLINE Convert ASCII to Hexadecimal CATH End of Code CODEND $MEMRY Exchange Nybbles EN Memory Fill FILLB, FILLBC HFILB, HFILBC Memory Move MOVEB, MOVEBC HMOVB, HMOVBC Pause Execution PAUSE Version Number of SYSLIB VERSION 12-1 ZCPR3: The Libraries SYSLIB Utilities 2 This chapter describes the following routines -- BOOS For Direct BDOS Interface BIOS For Direct BIOS Interface CAPS For Character Capitalization CAPSTR For String Capitalization CATH Convert ASCII Character to Hexadecimal CLINE Command Line Extraction CODEND Provide End of Code/Data Area EN Exchange Nybbles in A FILLB Fill Memory (up to 255 bytes) FILLBC Fill Memory (up to 65,535 bytes) HFILB Fill Memory (up to 255 bytes) HFILBC Fill Memory (up to 65,535 bytes) MOVEB Move Memory (up to 255 bytes) MOVEBC Move Memory (up to 65,535 bytes) HMOvB Move Memory (up to 255 bytes) HMOVBC Move Memory (up to 65,535 bytes) PAUSE Delay N lOths of a Second VERSION Return Version Number of SYSLIB 12.1. BDOS and BIOS Access Routine; Function: and BC. Inputs: Outputs: BDOS Call Entry Point at location 5 and preserve DE C and DE provide input parameters A and HL provide output parameters Registers Affected; PSW, HL SYSLIB Routines Called: None Special Error Conditions; Determined by Routines Called Routine; BIOS Function: BIOS provides the user with a direct interface into the operating system BIOS. It is called with the Register A containing the index offset into the BIOS JMP table. No registers are preserved by this routine. The contents of HL, DE, and BC are passed to the BIOS unchanged. The following table summarizes the BIOS JMP Table Entries — Offset Function 0 Cold Start 1 Warm Start 2 Console Status; Returns A=OFFH if char ready, A=0 if not Console Input; Returns char in A Console Output; Char passed in C List Output; Char passed in C Punch Output; Char passed in C Reader Input; Returns char in A 12-2 ZCPR3: The Libraries SYSLIB Utilities 2 Offs'et Function 8 Home Disk Head (Return Version Number); Returns Version Number in HL 9 Select Disk; Disk Number (A=0, etc) passed in C 10 Set Track Number; Track Number passed in C 11 Set Sector Number; Sector Number passed in C 12 Set DMA Address; DMA Address passed in BC 13 Read Block from Disk; Returns A=0 if OK, A=l if Error 14 Write Block to Disk; Returns A=0 if OK, A=l if Error 15 List Status; Returns A=OFFH if ready to output, A=0 if not 16 Sector Translation; Logical-to-Physical Sector Translation; Logical Sector Number passed in BC and Translate Table Address passed in DE; Returns Physical Sector Number in HL Inputs: A = Offset (as per Table Above) BC = Input Parameters Outputs: A, HL = Output Parameters Registers Affected: All SYSLIB Routines Called: None Special Error Conditions: None 12.2. Capitalization Routine: CAPS Function: Capitalize ASCII character in Register A if it is lower-case alphabetic (a-z); otherwise, return A unaffected. Only the lower seven bits of the byte are considered, and the Most Significant Bit is masked out to zero. Inputs: A = character to capitalize Outputs: A = capitalized character Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None Routine; CAPSTR Function: CAPSTR capitalizes the -terminated (0- terminated) string pointed to by HL. No Registers are affected. Inputs: HL pts to first byte of string Outputs: None (String is Capitalized) Registers Affected: None SYSLIB Routines Called: CAPS Special Error Conditions: None 12.3. Command Line Tail Extraction Routine; CLINE Function: Save the command line whose character count is pointed to by HL away in an internal buffer as a string. The line may be up to 255 characters long and will be truncated if it is longer. The string will be terminated by a as per the SYSLIB concept of strings. 12-3 ZCPR3: The Libraries SYSLIB Utilities 2 Inputs; HL = Address of Command Line Buffer (Char Count) Outputs: HL = Address of Command Line String (1st Char) A = 0 and Zero Flag Set (20 Hex) in A Register as error code. Inputs: A = ASCII Hex Character (0-9, A-F) Outputs: A = Binary value represented by char Registers Affected: PSW SYSLIB Routines Called; None Special Error Conditions: If invalid hex char, (20 Hex) returned in A. 12.5. End of Code Routine; CODEND Function: Return the address of the next page following the last byte of code. This is useful in determining where the scratch area begins. Inputs; None Outputs: HL=Address of next page Registers Affected: HL SYSLIB Routines Called: None Special Error Conditions: None Buffer Name: SMOKY Function: $MEMRY contains the address of the next available byte of memory after the last module loaded and resolved by the LINK-80 linker of Microsoft, ZLINK linker of MITEK, and others. This reserved global variable should be accessed as follows; ext $MEMRY Ihid $MEMRY ; get value Contents: Address of next available byte 12-4 ZCPR3: The Libraries SYSLIB Utilities 2 12.6. Exchange Nybbles Routine; EN Function: Exchange Nybbles in Register A. The High-order four bits are exchanged with Low-order four bits of Register A. Inputs: A = Byte input Outputs: A = Byte output Registers Affected: PSW SYSLIB Routines Called: None Special Error Conditions: None 12.7. Memory Fill Routine; FILLB, FILLBC, HFILB, HFILBC Function: These routines fill an area of memory with a constant byte value. FILLB can fill up to a 256-byte buffer, and FILLBC can fill up to a 65,536-byte (within reason) buffer. FILLB and FILLBC have no effects on any registers. HFILB and HFILBC both affect the HL register pair, and they return with HL pointing to the byte after the last byte filled. HFILB and HFILBC are useful when further processing from the last point filled is desired. Inputs: HL points to the first byte of the buffer to be filled B (for FILLB) or BC (for FILLBC) = number of bytes in buffer A = byte value to fill buffer with Outputs: None for FILLB and FILLBC (Buffer is filled) HL points to next byte for HFILB and HFILBC Registers Affected: None for FILLB, FILLBC; HL for HFILB, HFILBC SYSLIB Routines Called: None Special Error Conditions: None 12.8. Memory Move Routine: MOVEB, MOVEBC, HMOVB, HMOVBC Function: Move the block of memory pointed to by HL to the memory location pointed to by DE. MOVEB can move up to a 256- byte buffer, and MOVEBC can move up to a 65,536-byte buffer. MOVEB and MOVEBC have no effects on any registers. HMOVB and HMOVBC both affect the HL register pair, and they return with HL and DE pointing to the byte after the last byte moved. HMOVB and HMOVBC are useful when further processing from the last point filled is desired. Inputs: HL points to the first byte of the buffer to move DE points to the first byte of the buffer to move to B (for MOVEB) or BC (for MOVEBC) = number of bytes in buffer Outputs: None for MOVEB and MOVEBC (Buffer is moved) HL and DE pt to byte after last byte moved for HMOVB and HMOVBC Registers Affected: None for MOVEB, MOVBC; HL, DE for HMOVB, HMOVBC SYSLIB Routines Called; None Special Error Conditions: None 12-5 ZCPR3: The Libraries SYSLIB Utilities 2 12.9. Pause Execution Routine; PAUSE Function: Delay N lOths of a Second. Inputs: HL = N (Number of lOths of a Second Delay desired) B = Processor Speed in MHz (1, 2, 3, 4, ...) Outputs: None (Routine returns N lOths of a Second later) Registers Affected: None SYSLIB Routines Called: None Special Error Conditions: None 12.10. Version Number of SYSLIB Routine: VERSION Function: Return Version Number of SYSLIB. Inputs: None Outputs: HL=Vers