IV. DSLIB -- Clock and File Stamp Support Introduction . . . . . . . . . . . . . . . . . . . . . . 162 System Identity . . . . . . . . . . . . . . . . . . 163 TIMINI, GETDOS, FINDCK, CKTDF, DOSTYP (global), DOSVER (global), TIMTYP (global) Clock Reading . . . . . . . . . . . . . . . . . . . 164 RCLOCK, RDCLK File Stamp Routines . . . . . . . . . . . . . . . . 165 GSTAMP, PSTAMP, GETTD, SETTD Directory Selection . . . . . . . . . . . . . . . . 167 DDIRQS, DDIRQ, DDIRNPAK, DDIRPAK, DDIRSEL Time Conversions . . . . . . . . . . . . . . . . . 169 U2PTIM, P2UTIM, U2MTIM, M2UTIM Utility Routines . . . . . . . . . . . . . . . . . 172 FSTNXT, BCD2BIN, BIN2BCD, DVERS DateStamper TIME&DAT . . . . . . . . . . . . . . . 173 OPENTD, CLOSTD, RWTD DSLIB -- Clock and File Stamp Support INTRODUCTION: This library contains a collection of routines to facilitate addition of file time and date stamping and real time clock features. A common date and time format is used to ex change date and time data with user programs. It uses BCD digits as: Byte Offset: 00 01 02 03 04 05 YY MM DD hh mm ss where YY = year (78-99 is 1978-1999, 00-77 is 2000-2077), MM = month (1..12), DD = day (1..28,30,31), hh = hour (0..23), mm = minute (00..59), and ss = second (00..59). Generalized routines are included which uniformly return clock time, as well as file stamp data from ZSDOS/ZDDOS, CP/M 2.2, or ZRDOS 1.x with Plu*Perfect Systems' DateStamper, and Digital Research's CP/M Plus (also known as CP/M 3). The common data structures are automatically converted to the appropriate inter nal formats for the running system. As with the clock structure, file stamp data is handled in a consistent DateStamper-ZSDOS format of packed BCD digits in a 15- byte field: |-- Create --| |- Last Acc -| |-- Modify --| Byte Offset: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 YY MM DD hh mm YY MM DD hh mm YY MM DD hh mm where YY = year (78-99 is 1978-1999, 00-77 is 2000-2077), MM = month (1..12), DD = day (1..28,30,31), hh = hour (0..23), mm = minute (00..59). In addition to the generalized interface routines, entry points exist for DateStamper specific routines. Many of these specific routines are automatically called from the generalized routines when DateStamper is detected. Conversion routines also exist to manage interfaces between date- time fields of DateStamper, the MS-DOS compatible DosDisk, and the CP/M Plus-compatible P2DOS format. SYSTEM IDENTITY: Routine: TIMINI Function: See if there is a clock we can read. Entry: None Exit: A = time method, zero flag clear (NZ) if clock found A = 0, zero flag set (Z) if no clock found Affected: AF Usage: Calls GETDOS setting DOSVER and DOSTYP, then looks for a clock to read, implying a file stamp method. Types are: "S" = ZSDOS/ZDDOS internal, "D" = Date Stamper, "3" = CP/M Plus (CP/M 3, P2DOS type). This TIMTYP byte may be accessed when desired and is used by GSTAMP and PSTAMP to get and set file stamps respectively. Routine: GETDOS Function: Determine DOS type and version, set global variables. Entry: None Exit: A = DOS type (character), zero clear (NZ) if identified A = 0, zero flag set (Z) if not identified Affected: AF Usage: Used to identify the running DOS type and version. It is called from TIMINI, but may be called sepa rately. After it is called, DOSTYP and DOSVER globals may be directly accessed. Global: DOSTYP -- Byte character variable for DOS type ("S"=ZSDOS, "D"=ZDDOS, "1"=CP/M 1.x, "2"=CP/M 2.x, "3"=CP/M Plus (3.x), "R"=ZRDOS, 0=Unknown) Global: DOSVER -- Byte variable for DOS version number (vendor specific) Global: TIMTYP -- Byte character variable for type of time and date stamping and clock in use ("3"=CP/M Plus, "S"=Internal ZSDOS or ZDDOS, "D"=DateStamper). Routine: FINDCK Function: Check for DateStamper clock and set read status Entry: None Exit: A <> 0, zero flag clear (NZ) if clock found HL = pointer to clock starting address if found A = 0, zero flag set (Z), HL = - if not found Affected: AF, BC, DE, HL Usage: Used with DateStamper-specific interfaces. Call this routine near the beginning of a program to determine clock status. This routine is not need ed if the recommended TIMINI/RCLOCK generalized routines are used. Routine: CKTDF Function: Check for DateStamper TIME&DAT file on drive Entry: None, but user must log desired drive before calling Exit: A <> 0, zero flag reset (NZ) if TIME&DAT file is located A = 0, zero flag set (Z) if no TIME&DAT file present Affected: AF, BC, DE, HL Usage: Used with DateStamper-specific file stamp routines only, or with routines where individual file stamp access is too slow. It should be called before any attempt is made to access file stamp informa tion. A common use is to set flags for mode changing between stamp and non-stamp operations. CLOCK READING: Routine: RCLOCK Function: Read clock identified by TIMINI to specified address Entry: HL = address of 6-byte area to receive time string Exit: A = 0, zero flag set (Z) if OK, time string filled A <> 0, zero flag clear (NZ) if error Affected: HL, DE, BC, AF Usage: Forms a generalized clock read for ZSDOS, Date Stamper, or CP/M Plus clocks identified by TIMINI. It reads clock data to the specified address in the standard format. Since CP/M Plus does not return a valid read flag, the status is always assumed to be true for a good read. You must insure that a valid clock is installed and working before calling this routine. Example: EXT TIMINI,RCLOCK ; always declare both routines ... ; ..preliminary code CALL TIMINI ; initialize and identify clock ... ; ..other program code LD HL,TIMSTR ; place the time here CALL RCLOCK ; ..and read the clock JR NZ,BADCLK ; jump if error reading clock ... ; ..else proceed to use it TIMSTR: DEFS 6 ; date/time: YY MM DD HH MM SS Routine: RDCLK Function: Read DateStamper clock to specified buffer Entry: HL = pointer to 6-byte buffer location FINDCK must have been previously called Exit: HL = pointer to last byte of date/time string if OK A <> 0, zero flag clear (NZ) if OK A = 0, zero set (Z), HL = 0 if bad clock read Affected: AF, BC, DE, HL Usage: Used to read a DateStamper-specific clock. Date and time information is returned in the same for mat as other routines in this library. Example: EXT RDCLK,FINDCK ; declare the routine ... ; ..initial program code CALL FINDCK ; call this early in program ... ; ..intervening program code LD HL,TIMSTR ; set addr for 6-byte buffer CALL RDCLK ; read the clock JR Z,NOGOOD ; ..jump if bad read FILE STAMP ROUTINES: Routine: GSTAMP Function: Return file date stamp data for specified file Entry: DE = pointer to FCB for file of interest HL = pointer to 15-byte buffer for stamp data TIMINI must have been called to set global varia bles. Drive and user area for the specified file must be set prior to calling this routine. Exit: A <> 0, zero flag clear (NZ) if operation successful A = 0, zero flag set (Z) on error Affected: AF, BC, HL Current DMA address is altered. Usage: Recommended for file stamp access in CP/M-compati ble systems. Uses DOSTYP and TIMTYP variables to determine stamp method in effect, and will read file stamps under ZSDOS and DateStamper with CP/M 2.2 or ZRDOS, and will read stamps from CP/M Plus (CP/M 3). Example: See PSTAMP below. Routine: PSTAMP Function: Set file date stamp data for specified file Entry: DE = pointer to FCB for file of interest HL = pointer to 15-byte buffer with stamp data TIMINI must have been called to set global varia bles. Drive and user area for the specified file must be set prior to calling this routine. Exit: A <> 0, zero flag clear (NZ) if operation successful A = 0, zero flag set (Z) on error Affected: AF, BC, HL Current DMA address is altered. Usage: Recommended for file stamp access in CP/M-compati ble systems. Uses the DOSTYP and TIMTYP variables to determine stamp method in effect, and will write file stamps under ZSDOS and DateStamper with CP/M 2.2 or ZRDOS, but not under CP/M Plus (CP/M 3). Example: EXT GSTAMP,PSTAMP,TIMINI ; declare routines ... ; ..preceding code CALL TIMINI ; set the time sybsystem early ... ; ..other program code CALL SETFCB ; set an FCB to a desired file LD DE,FCB ; ..point to it LD HL,TBUFF ; ..and to buffer for stamps CALL GSTAMP ; get stamp for this file JR Z,NOSTAMP ; ..go to error handler if bad ... ; use the data CALL SETDAT ; set stamp data in buffer LD DE,FCB ; ..point to FCB for file LD HL,TBUFF ; ..and to buffer with stamps CALL PSTAMP ; stamp file with TBUFF values JR Z,NOSTAMP ; ..jump error if bad return ... ; else carry on FCB: DEFS 36 ; FCB for file of interest TBUFF: DEFS 15 ; buffer for stamp data Routine: GETTD Function: Get DateStamper file stamp for specified file Entry: A = TIME&DAT sector index (0..7) (from FSTNXT) DE = random record number (from FSTNXT) HL = pointer to 15-byte buffer for date-time info User must log onto drive containing file and stamp Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero flag set (Z) if no file or read error Affected: AF, BC, DE, HL DMA is altered by this routine. Usage: DateStamper-specific routine returning file stamp data for a file using FSTNXT call parameters. Example: EXT GETTD ; declare the routine ... ; ..check DateStamper ... ; ..log drive, call FSTNXT LD HL,USRDAT ; put 15-byte stamp data here CALL GETTD ; fill in destination string JR Z,NODATA ; ..jump if bad/no stamp ... ; else process the stamp Routine: SETTD Function: Set DateStamper file stamp for specified file. Entry: A = TIME&DAT sector index (0..7) (from FSTNXT) DE = random record number (from FSTNXT) HL = pointer to stamp data in 15-byte buffer User must log onto drive containing file and stamp Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero set (Z) if no file or read error Affected: AF, BC, DE, HL DMA is altered by this routine. Usage: DateStamper-specific routine sets file stamp data for a specified file to user-supplied values. Example: EXT SETTD ; declare the routine ... ; ..validate DateStamper ... ; ..log drive, call FSTNXT LD HL,USRDAT ; point to 15-byte stamp field CALL SETTD ; set DateStamper file stamp JR Z,BADSET ; ..jump if if error ... ; else carry on! DIRECTORY SELECTION: Routine: DDIRQS Function: Return sorted directory with file stamps and sizing Entry: HL = address of TPA buffer start DE = points to FCB entry to match directory entries A = mode select character: b7 -- 1 = select system files b6 -- 1 = select non-system files b5 -- 1 = select all users C = secondary mode select: b7 -- 1 = sort type then name, 0 = name then type b0 -- 1 = search DateStamper first, then DosDisk, then P2DOS stamps; 0 = skip DateStamper Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero set (Z) if TPA overflow BC = number of files in sorted directory array HL = address of first file in buffer Affected: HL, BC, AF DMA Address is set to 80h Usage: A replacement for the SYSLIB routine DIRQS. File stamps are automatically appended to directory data from DateStamper, P2DOS (CP/M Plus), and DosDisk. The last access field is nulled in P2DOS, and the single DosDisk stamp is returned in the last modified field. Each entry is 31 charac ters long (16 for file entry, 15 for stamp). Example: See DDIRQ below. Routine: DDIRQ Function: Return sorted directory with file stamps Entry: HL = address of TPA buffer start DE = points to FCB entry to match directory entries A = mode select character: b7 -- 1 = select system files b6 -- 1 = select non-system files b5 -- 1 = select all users C = secondary mode select: b7 -- 1 = sort type then name, 0 = name then type b0 -- 1 = search DateStamper first, then DosDisk, then P2DOS stamps; 0 = skip DateStamper Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero set (Z) if TPA overflow BC = number of files in sorted directory array HL = address of first file in buffer Affected: HL, BC, AF DMA Address is set to 80h Usage: A replacement for the SYSLIB routines DIRQ. File stamps are automatically appended to directory data from DateStamper, P2DOS (CP/M Plus), and DosDisk. The last access field is nulled in P2DOS, and the single DosDisk stamp is returned in the last modified field. Each entry is 31 charac ters long (16 for file entry, 15 for stamp). Example: EXT DDIRQ ; ..or DDIRQS, don't use both ... CALL CODEND ; get lower TPA value in HL LD DE,MYFCB ; match this file spec LD C,01H ; sort name/type, DS first LD A,0E0H ; SYS & non-SYS, all user areas CALL DDIRQ ; do the call (or to DDIRQS) JP Z,ERROR ; ..error if not enough space LD A,B ; do we have any files? OR C ; ..BC has number of files JP Z,NOFILS ; jump if no files in array ... ; ..use the files in the array MYFCB: DEFB 0,'???????????',0,0,0,0 ; FCB to match DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Routine: DDIRNPAK Function: Negate selection markings in directory buffer Entry: HL = points to directory buffer from DDIRQ/DDIRQS BC = number of entries in the buffer Exit: BC = number of entries in buffer after select/packing Affected: BC Usage: Used to delete file entries from DDIRQS or DDIRQ directory routines. Upon completion, only entries previously unmarked remain, and the table is com pressed to only these entries. This is similar to the SYSLIB routine DIRNPAK, but tailored to time- date stamped directory lists. Example: EXT DDIRNPAK ; declare the routine ... ; build dir table (DDIRQ(S)) ... ; ..and select entries LD HL,(BUFF) ; buffer start (DDIRQ/DDIRQS) LD BC,(COUNT) ; ..# of entries (DDIRQ/DDIRQS) CALL DDIRNPAK ; Keep unselected & pack buffer ... ; ..continue w/ new file count Routine: DDIRPAK Function: Pack directory buffer from DDIRQ/DDIRQS Entry: HL = points to directory buffer from DDIRQ/DDIRQS BC = number of entries in the buffer Exit: BC = new number of buffer entries after select/pack Affected: BC Usage: Compress file ID array from directory sort routine retaining only marked file entries. This routine is similar to the SYSLIB routine DIRPAK, but func tions with time-date stamped directory lists. Example: EXT DDIRPAK ; declare the routine ... ; build dir table (DDIRQ/DDIRQS) ... ; ..and select entries LD HL,(BUFF) ; buffer start (DDIRQ/DDIRQS) LD BC,(COUNT) ; ..# of entries (DDIRQ/DDIRQS) CALL DDIRPAK ; keep selected entries & pack ... ; ..continue w/new file count Routine: DDIRSEL Function: Select entries from DDIRQ/DDIRQS directory buffer Entry: HL = points to directory buffer from DDIRQ/DDIRQS DE = FCB entry to select against BC = number of entries in the buffer A = mode select flag: b7 -- select non-system files b6 -- select system files b5 -- select all users b4..b0 -- user number Exit: Selected files are marked Affected: None Usage: Select file entries by setting the MSB of the first byte (user #) based on file name and type in FCB, and selection flags. This routine is similar to the SYSLIB routine DIRSEL, but accomodates time-date stamped directory lists. Example: EXT DDIRSEL ; declare the routine ... ; build dir (DDIRQ/DDIRQS) LD HL,(BUFF) ; buffer start (DDIRQ/DDIRQS) LD DE,MYFCB ; ..FCB criteria for selection LD BC,(COUNT) ; ..and # entries (from DDIRQ) LD A,01100000B ; SYS files in all user areas CALL DDIRSEL ; mark matching entries ... ; ..continue on TIME CONVERSIONS: Routine: U2PTIM Function: Convert ZSDOS-DateStamper time to P2DOS (CP/M Plus) Entry: DE = points to Universal time string (source) HL = points to P2DOS time string (destination) Exit: A = 0, zero set (Z) if OK, destination time set (less seconds) A <> 0, zero clear (NZ) if error, destination zeroed DE = pointer to seconds byte in source string (not moved) HL = pointer to seconds byte in destination string (not filled) Affected: HL, DE, BC, AF Usage: Conversion of time from ZSDOS-DateStamper to CP/M Plus type. Only the date, hour, and minute fields are converted, but registers are returned such that a single LDI move instruction after the rou tine will move any seconds information. Years 78- 99 are assumed to be 1978-1999, 0-77 as 2000-2077. This routine would commonly be used in programs such as library utilities which internally use a CP/M Plus type of stamp. Example: EXT U2PTIM ; declare the variable ... ; read a clock or stamp LD DE,UTIM ; set source time spec address LD HL,PTIM ; ..and dest time spec addr CALL U2PTIM ; do the conversion JR NZ,ERROR ; ..jump if conversion error ... ; else use the P2DOS string Routine: P2UTIM Function: Convert P2DOS (CP/M Plus) time spec to standard Entry: HL = points to P2DOS (CP/M Plus) time string (source) DE = points to universal time string (destination) Exit: A = 0, zero set (Z), destination string filled (less seconds) Errors only due to bad entry (check YY=MM=0). HL = points to seconds byte in source string (not moved) DE = points to seconds byte in destination string (not filled) Affected: HL, DE, BC, AF Usage: Commonly used to provide interface from CP/M Plus systems to CP/M 2.2, or in library utility rou tines to provide time interface. Source stamp is P2DOS (CP/M Plus compatible), destination is ZSDOS-DateStamper standard. A single LDI move instruction after conversion will move the seconds byte. Only dates from 1 Jan 1978 through 31 Dec 2077 will be properly converted. Other dates will set year and month bytes to zero. Check this state for error condition. Example: EXT P2UTIM ; declare the variable ... ; read a clock or stamp LD DE,UTIM ; point to the dest string LD HL,PTIM ; ..and the source string CALL P2UTIM ; do the conversion LDI ; move the seconds (if desired) LD HL,UTIM ; check for errors LD A,(HL) ; get years byte INC HL ; ..advance to months OR L ; ..and check for errors JR Z,ERROR ; jump if error ... ; ..continue on Routine: U2MTIM Function: Convert universal time specification to MS-DOS/DosDisk Entry: DE = points to universal time string (source) HL = points to MS-DOS format time string (destination) Exit: A = 0, zero set (Z) if OK, destination time set (less seconds) A <> 0, zero clear (NZ) if error, destination string zeroed DE = pointer to seconds byte in source string (not moved) HL = pointer to high-order time byte in MS-DOS field (low-order byte has seconds field nulled) Affected: HL, DE, BC, AF Usage: Commonly used to convert from internal time format to external form for writing to MS-DOS disk for mats. Conversion of seconds data to the format used in the MS-DOS time specification is a user program responsibility. Dates from 1 January 1980 to 31 December 2077 will be properly converted. Example: EXT U2MTIM ; declare the variable ... ; read a clock or stamp LD DE,UTIM ; source time spec string addr LD HL,MTIM ; ..dest time spec string addr CALL U2MTIM ; do the conversion JR NZ,ERROR ; ..jump if conversion error ... ; else use P2DOS string Routine: M2UTIM Function: Convert MS-DOS/DosDisk time to universal Entry: HL = points to MS-DOS time string (source) DE = points to universal time string (destination) Exit: A = 0, zero set (Z), destination string filled (less seconds) A <> 0, zero clear (NZ) if error, destination nulled HL = points to second (hi-order) byte in MS-DOS string DE = points to seconds byte in destination string (not filled) Affected: HL, DE, BC, AF Usage: Commonly used to convert MS-DOS time to internal format for internal program manipulation. Conver sion of seconds is your responsibility. Dates from 1 Jan 1980 through 31 Dec 2077 will be pro perly converted. Others produce a null date. Example: EXT M2UTIM ; declare the variable ... ; read a clock or stamp LD DE,UTIM ; point to the dest string LD HL,MTIM ; ..and the source string CALL M2UTIM ; do the conversion JR NZ,ERROR ; ..handle error if bad ... ; else convert secs & continue UTILITY ROUTINES: Routine: FSTNXT Function: File search returning DateStamper indices Entry: C = 17 (search first) or 18 (search next) DOS command DE = points to FCB containing the target filename User must log drive and user before calling Exit: A = directory index (0..3), carry flag clear (NC) if found A = indeterminate, carry flag set (C) if not found DE = random sector number in !!!TIME&.DAT B = index into TIME&DAT sector (0..7) Affected: AF, BC, DE, HL Usage: Used in DateStamper-specific systems to perform file searches and return indices into the TIME&DAT file. Use this call for function 17 and 18 search calls in lieu of a direct call to the BDOS vector at location 5. Example: EXT FSTNXT ; declare the routine ... ; log drive/user & set FCB LD C,17 ; set for search first command LD DE,FCB ; ..addr FCB for desired name CALL FSTNXT ; search for the desired file JR NC,FOUND ; ..jump if file found ... ; else do not found things Routine: BCD2BIN Function: Convert binary coded decimal (BCD) byte to binary Entry: A = BCD digit to convert (0-99 value) Exit: A = binary byte representation of digit(s) (00-63h) Affected: AF Usage: Primarily used in conversions of dates used by DSLIB routines, but is available for other uses. It converts a packed BCD byte in the range of 0 to 99 to a binary byte of 0..63h. Routine: BIN2BCD Function: Convert binary byte to packed BCD Entry: A = binary digit to convert (00-63h, 0-99 decimal) Exit: A = packed BCD byte (1 or 2 digits) Affected: AF Usage: Commonly used to convert bytes in the range of 0- 99 (00-63h) to a packed BCD byte. It is primarily used in date conversion routines in DSLIB, but is available for other uses. Routine: DVERS Function: Return the DSLIB version number Entry: None Exit: HL = the version number (H = major, L = minor) Affected: HL Usage: Most often used for control or debugging purposes to embed the linked library version. DATESTAMPER TIME&DAT: Routine: OPENTD Function: Open DateStamper TIME&DAT file for read or write Entry: A = 0 for read, A = 0FFh for write You must select the drive before calling Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero flag set (Z) if open error Affected: AF, BC, DE, HL Usage: DateStamper-specific routine is used to access large numbers of stamps, or where performance penalties in per-file stamp accesses are undesire able. This routine opens the TIME&DAT file in user 0 on the current drive. If opened for writ ing, the R/O attribute is cleared. The user num ber is restored on exit. Routine: CLOSTD Function: Close DateStamper TIME&DAT file Entry: None Exit: A <> 0, zero flag clear (NZ) if OK A = 0, zero flag set (Z) if error Affected: AF, BC, DE, HL Usage: DateStamper-specific routine closes the TIME&DAT file in user 0 of current drive, and sets the R/O bit. It is used in conjunction with OPENTD above. Routine: RWTD Function: Read or write to TIME&DAT file on current drive Entry: A = 0 to read, A = 0FFh to write DE = random record to read or write Exit: HL = addresses the start of TIME&DAT sector to be read or written A <> 0, zero flag clear (NZ) if OK A = 0, zero flag set (Z) if error Affected: AF, BC, DE, HL, and BDOS DMA address Usage: DateStamper-specific routine normally used only for directory list and catalog or archive programs where access to blocks of date stamps is desired. You must reset DMA address after call if needed. Example: EXT RWTD ; declare the routine ... ; log drive, set DMA addr LD DE,(RECNUM) ; get T&D rec # from FSTNXT or ; ..specified random rec number LD A,MODE ; A=0 for read, A=FF for write CALL RWTD ; perform the action JR NZ,RWOK ; ..jump if OK ... ; else perform error activity RWOK: ... ; sector has been read/written This page intentionally left blank.