Documentation for The Speech Thing Device Driver STDRIVER.SYS Version 2.73 Copyright 1988-92 COVOX INC. April, 1992 INTRODUCTION The Speech Thing device driver supports synthesized speech generated by the Smooth Talker programs from 'First Byte' (SPEECHV2.EXE and SPEECHV3.EXE). The device driver DOES NOT support the Version 4 text-to-speech program as used in the main program. NOTE: The device driver program is generally not recommended except in the following cases: (1) Third party software that specifically requests that you install STDRIVER.SYS, or (2) You wish to utilize the progamming features of the driver for your own custom programs or for general interest. The device driver program, "STDRIVER.SYS", will allow the Speech Thing to be employed in a wide variety of languages and operating environments. A device driver can also be accessed directly from DOS in much the same way as disk files. For instance, ASCII files can be sent to the device driver using DOS's 'TYPE' or 'COPY' command and Smooth Talker will then promptly speak them back. The first section describes how to install the STDRIVER.SYS driver program followed by the operation and functions of the driver as it pertains to text-to-speech. INSTALLING STDRIVER.SYS The device driver STDRIVER.SYS will work with any PC or MS DOS version 3.0 or higher. It can be installed by including it in a 'CONFIG.SYS' file which must reside in the root directory of the drive that is used to boot the system. If a CONFIG.SYS file already exists, then just add the STDRIVER.SYS driver program to it by including the following line: DEVICE = \COVOX\STHING\STDRIVER.SYS /SV3 This will cause the STDRIVER.SYS device driver to be installed the next time the system is booted up. The /SV3 is an optional parameter which tells the driver that it is using SPEECHV3. The default is SPEECHV2.EXE. DEVICE = \COVOX\STHING\STDRIVER.SYS /SV3 /DAC=559 This will cause the driver to use SPEECHV3.EXE and output the speech to port number 559 (or 22F in hex) which happens to be the default port setting for Sound Master II and Voice Master (VM0). A list of port used by COVOX is given as follows: Speech Thing LPT1 DEFAULT no /DAC= needed LPT2 632 usually LPT2 888 if monochrome card present Voice Master Key and Sound Master II VM0 559 VM1 591 VM2 655 VM3 719 In general, the command line format for STDRIVER is as follows: DEVICE = \COVOX\STHING\STDRIVER.SYS /P/P/P/etc. ^ a mandatory space Where the 'P' parameter represents any legal STDRIVER.SYS device command. For example DEVICE = \COVOX\STHING\STDRIVER.SYS /PHO/TTD Data sent to the driver would be interpreted as phonetic strings (PHO) and the string would not be echoed to the screen when spoken (TTD). These settings will remain in effect until a command is sent to the driver which changes one or more of them. If no parameters are entered, the device driver will install itself in the default mode which would be equivalent to the following: DEVICE = \COVOX\STHING\STDRIVER.SYS /ENG/CRE/TTE/TON=0 Keep in mind that the parsing routine will not accept an illegal parameter and if one is found then parsing will stop where the error occurs and default parameters will be used for the remaining parameters. Of course, the driver will notify you of any illegal parameters when it installs itself at boot- up time, but it will not specify exactly where the error occurred. You must determine this yourself. NOTE: The Speech Thing device driver will work correctly only with DOS versions 3.0 or higher. Also, don't forget that STDRIVER.SYS requires either SPEECHV2.EXE (for slow PC's like XT's) or SPEECHV3.EXE (for AT's or faster) to be loaded in memory before any strings can be sent to the driver. Probably the best way to do this is to include one of the two programs in an 'AUTOEXEC.BAT' file and then it will automatically be loaded into memory upon boot-up. After you are finished, both SPEECHV3.EXE and SPEECHV2.EXE can be removed from memory by typing the name of the program followed by a /Q. For example, SPEECHV3.EXE /Q removes the text-to-speech program from memory. However, the driver program, STDRIVER.SYS, still remains in memory. The only way to remove STDRIVER.SYS is to not include it in your CONFIG.SYS file. --- Device Driver IOCTL Commands --- The driver supports three distinct functions, WRITE, READ and IOCTL. Input Output ConTroL or IOCTL is function 44H of DOS interrupt 21H and is used to send commands to the Speech Thing device driver. Some languages like GW-BASIC and QuickBasic specifically support the IOCTL function and commands can easily be passed to the driver in the form of a three character ASCII string. In cases where the IOCTL function is not specifically supported, such as with Assembly language, Turbo PASCAL, or QuickC, then commands must be sent to the driver using the DOS interrupt directly. Some of the IOCTL commands are used to pass a numerical value to the driver program. This is done by immediately following the three character command with an equal sign, '=', and then the decimal number for the value to pass. For example, sending the IOCTL string 'SPE=8' would tell the driver to set the playback speed to a value of eight. IMPORTANT: When sending a parameter with an IOCTL command, this exact format, within the quotes, must be adhered to: 'CMD=XXXX'. Where CMD is the IOCTL command, which can be either upper or lower case letters, followed immediately by the equal sign and finally the decimal value. Note that no space characters or commas are allowed. SMOOTH TALKER MODE This mode of operation causes the device driver to pass data from DOS or the application program to the Speech Thing after the data has been translated by Smooth Talker. Therefore it is mandatory that either SPEECHV2.EXE or SPEECHV3.EXE be resident in memory when using this mode. When in this mode, the driver reads and writes data one byte or character at a time which means that an intermediate buffer between the driver and DOS, or an application program, is not required. Data bytes are passed to and from the driver as a stream of ASCII characters representing either English or phonetic structures. Data is passed in several ways, from DOS by using its 'COPY' or 'TYPE' command or from an application program using a WRITE or READ function. The ability to Send a string of characters directly from DOS to the driver is one advantage that STDRIVER.SYS has over the STALK program. On the other hand, STDRIVER.SYS does not support any of Smooth Talker's dictionary functions. Smooth Talker can continuously playback an English or phonetic string of up to 255 characters before it must pause to reset and read in the next string. If this pause occurs in the middle of a sentence, then the speech will sound discontinuous. For this reason, the driver program breaks up the string of input characters into grammatical sentences with natural pauses and then passes each sentence on to Smooth Talker for interpretation. A natural pause is considered by the driver to be a period, colon, question or exclamation mark. After Smooth Talker interprets the sentence, it sends the result to the Speech Thing for playback and then resets itself to receive another 255 characters. If the driver is sent a string that cannot be divided into sentences, then it will send the maximum of 255 characters to Smooth Talker and then pause. There is one exception to the above which is the 'carriage return' character. The driver can optionally be set to either ignore or acknowledge carriage returns. If acknowledged, then a carriage return character has exactly the same effect as a period or other sentence terminator. Causing smooth talker to speak directly from the DOS prompt can be done using one of three DOS commands as follows: A>COPY SAMPLE ST or A>TYPE SAMPLE > ST or A>ECHO SAMPLE >ST These methods have the same effect and will cause Smooth Talker to playback the file. Also the 'SHELL' command could be used with equal effect: SHELL "COPY SAMPLE ST" or SHELL "TYPE SAMPLE > ST" The above file, "SAMPLE", could be any ASCII text file of any length and can be created with a word processor, EDLIN, or directly from the DOS prompt. Here is an example of creating a file from the DOS prompt: A>COPY CON: SAMPLE This is a sample text file. ^Z Enter the above text exactly as shown and press ENTER after each line. The CONTROL-Z character on the last line is the 'end of file' marker and instructs DOS to create the file. IOCTL Commands in Smooth Talker Mode ENG - This instructs the driver that ASCII characters passed to it for playback will be sent as English strings. After issuing this command, all subsequent WRITEs by DOS or the application program will cause smooth talker to interpret the string as English and speak it. Once an 'ENG' command is sent, the driver will continue to interpret strings as English until specifically told to do otherwise by issuing the 'PHO' command. If a phonetic string is sent to the driver while it is in English mode, then it will attempt to speak the string as English. Also, the default mode for the driver is English and the 'ENG' command need not be sent if the driver was not previously in phonetic mode. PHO - Same as for 'ENG' above, but instructs the driver that phonetic strings will be passed instead. XEP - This instructs the driver that the next string sent to it is to be converted from English to phonetics. Immediately after issuing this command the application program should send an English string via a WRITE command to the driver, then the phonetic result can be obtained by sending the driver a READ command. Once the 'XEP' command has been issued, first a WRITE, then a subsequent READ must be performed before the driver will return to its normal I/O state. Also, the driver expects that the string written to it will be an English string, even if the driver is currently in phonetics mode. There is no need to first issue an 'ENG' command before sending the English string for the 'XEP' function. After issuing a READ to get the phonetic result, the driver will automatically be reset to its previous English or phonetic mode. TTE - This enables the Teletype mode which causes string data passed to the driver to be echoed onto the screen. TTD - This disables the Teletype mode. CRE - Causes the driver to acknowledge carriage returns. This feature should be enabled in applications where it is desired to have Smooth Talker speak the displayed string when an ENTER or RETURN key is pressed. CRD - Causes the driver to ignore carriage returns. This is useful when Smooth Talker is being used to speak back ASCII text files where carriage returns occur after every screen line and cause unwanted pauses. FLU - Flushes out the 255 byte string buffer that the device driver uses for passing strings to the SPEECHV2 or SPEECHV3 program. Sometimes it is necessary to clear out an English or phonetic string that was previously sent to the driver but never spoken by Smooth Talker. This situation can occur when carriage returns have been disabled and a string without a sentence terminator (a period, colon, etc.) is sent to the driver. DAC - Enable an alternate port address for output. By default the driver uses the port number at LPT1 (0:408 & 0:409) for sending data to a DAC (Digital to Analog Converter). This command allows an alternate port address to be specified as the DAC port. Range: DAC=0 to DAC=65535. TON - Sets the tone that smooth talker speaks with. The tone control will only work the SPEECHV3 program and has no effect if changed for SPEECHV2. Range: TON=0 for low tone or TON=1 for high tone. SPE - Sets the speed of playback. Range: SPE=0 to SPE=9. PIT - Sets the pitch of playback. Range: PIT=0 to PIT=9. VOL - Sets the volume of playback. Range: VOL=0 to VOL=8. --- Programming in Smooth Talker Mode --- Besides the IOCTL function, two other main I/O functions are also supported by the device driver. They are READ and WRITE which correspond, respectively, to functions 3FH and 40H of DOS interrupt 21H. In 'Smooth Talker Mode', data is passed to and from the driver as a string of ASCII characters whenever a WRITE or READ is performed. The maximum length of a string that is written to the driver will depend on the limitations of the language being used. For example, GW-BASIC only allows strings with a maximum length of 255 characters whereas QuickBasic strings can be up to 32,767 characters in length. On the other hand, the READ function always returns a string of 255 characters or less. In this present implementation of the driver program, the READ function is only used in association with the 'eXchange English for Phonetics' or 'XEP' command. In order to convert an English string to a phonetic string, the 'XEP' command is sent using the IOCTL function followed by sending an English string with a WRITE command. Finally, the phonetic result is obtained by using the READ function. Because the 'XEP' command employs all three of the available driver I/O functions, it will be used below as the primary example for passing string data to and from the driver. Example A ------------------------ GW-BASIC ----------------------- 100 ON ERROR GOTO 430 'Handle any I/O errors. 110 CMD$="XEP" 'Assign the device command to a string. 130 ENGLISH$="This is a sample string." 'Assign the string to write. 150 GOSUB 180 'Go do the conversion. 160 END 170 ' 180 'ENGLISH TO PHONETICS 190 GOSUB 240 'Send the command. 200 GOSUB 300 'Send the English string. 210 GOSUB 360 'Get phonetic string. 220 RETURN 230 ' 240 'DEVICE IOCTL 250 OPEN "ST" FOR OUTPUT AS #1 'First open device for IOCTL write access. 260 IOCTL #1,CMD$ 'Send the command to the driver. 270 CLOSE #1 'Close device for IOCTL write access. 280 RETURN 290 ' 300 'DEVICE WRITE 310 OPEN "ST" FOR OUTPUT AS #1 'Open device for write access. 320 PRINT #1,ENGLISH$ 'Send the English string to the driver. 330 CLOSE #1 'Close device for write access 340 RETURN 350 ' 360 'DEVICE READ 370 OPEN "ST" FOR INPUT AS #1 'Open device for read access. 380 INPUT #1,PHONETIC$ 'Read the phonetic conversion from the 390 PRINT PHONETIC$ 'driver and display it to the screen. 400 CLOSE #1 410 RETURN 'Exit from routine and return to caller. 420 ' 430 PRINT "AN I/O ERROR HAS OCCURRED" 440 GOTO 160 --------------------------------------------------------- Example B ------------------------ QuickBASIC --------------------- ON ERROR GOTO PRINT.MESSAGE 'Handle any I/O errors. CMD$="XEP" 'Assign the device command to a string. ENGLISH$="This is a sample string." 'Assign the English string to translate. CALL ENGLISH.TO.PHONETICS 'Go do conversion. TERMINATE: END 'End this program. SUB ENGLISH.TO.PHONETICS STATIC CALL DEVICE.IOCTL 'Send the command. CALL DEVICE.WRITE 'Send the English string. CALL DEVICE.READ 'Get and print the phonetic equivalent. END SUB SUB DEVICE.IOCTL STATIC SHARED CMD$ '(allow access to an external variable) OPEN "ST" FOR OUTPUT AS #1 'First open device for I/O-WRITE access. IOCTL #1,CMD$ 'Send the command to the driver. CLOSE #1 'Close the device for I/O-write access. END SUB SUB DEVICE.WRITE STATIC SHARED ENGLISH$ '(allow access to an external variable) OPEN "ST" FOR OUTPUT AS #1 'Open the device for a WRITE access. PRINT #1,ENGLISH$ 'Send the English string to the driver. CLOSE #1 'Close the device for write access END SUB SUB DEVICE.READ STATIC OPEN "ST" FOR INPUT AS #1 'and re-open it for a READ access. INPUT #1,PHONETIC$ 'Read the phonetic conversion from the PRINT:PRINT PHONETIC$ 'driver and display it to the screen. CLOSE#1 'Close read access and release file handle. END SUB PRINT.MESSAGE: 'If an error, then print message and PRINT "AN I/O ERROR HAS OCCURRED" RESUME TERMINATE 'terminate program. ------------------------------------------------------- Example C ------------------- Assembly Language ------------------- CSEG SEGMENT 'CODE' ASSUME CS:CSEG,SS:CSEG,DS:CSEG,ES:CSEG ORG 100H ASM_XEP_SAMPLE: CALL ENGLISH_TO_PHON RET ;Return to DOS or calling routine. CMD$ DB 3,'XEP' ENGLISH$DB 25,'This is a sample string.',CR ;EQUATES AND VARIABLES READ EQU 0 WRITE EQU 1 CR EQU 0DH ;Carriage return character. DEVICE_NAME DB 'ST',0 ;ASCIIZ file specification for ;the driver. HANDLE DW 0 ;File handle will be saved here. WRITE_STRING DW 0 ;This holds the address of the :string to send. WRITE_COUNT DW 0 ;Total number of characters in the above string. READ_STRING DB 100H DUP(0) ;Buffer for the returned string. READ_COUNT DB 0 ;Length of the returned string. ERR_MSG DB 'An error has occurred!',07H,CR,'$' ;ENGLISH TO PHONETICS PROCEDURE ENGLISH_TO_PHON PROC NEAR ;Open the driver for a write access. MOV AL,WRITE CALL DEVICE_OPEN JC ERROR ;Send a command string to the driver. CALL DEVICE_IOCTL JC ERROR ;Send the English string to be translated. MOV AL,ENGLISH$ ;Get number of characters in string MOV AH,0 MOV WRITE_COUNT,AX ;and save it for write. MOV AX,OFFSET ENGLISH$+1 ;Get address of the English MOV WRITE_STRING,AX ;string and save it also. CALL DEVICE_WRITE ;Go translate English to phonetics. JC ERROR ;Terminate the write access to the driver. CALL DEVICE_CLOSE JC ERROR ;Open the driver for a read access. MOV AL,READ CALL DEVICE_OPEN JC ERROR ;Get the phonetic translation from the driver. CALL DEVICE_READ JC ERROR MOV DX,OFFSET READ_STRING ;Get address of phonetic string. MOV BL,READ_COUNT ;Get length of string (always < 255). MOV BH,0 MOV READ_STRING[BX],'$' ;Add a DOS string terminator and CALL PRINT ;and go display the string. ;Terminate the read access to the driver and release the handle. CALL DEVICE_CLOSE JC ERROR JMP SHORT E_TO_P_DONE ;If an error occurs then notify user. ERROR: MOV DX,OFFSET ERR_MSG CALL PRINT CALL DEVICE_CLOSE E_TO_P_DONE: RET ;Exit this procedure. ENGLISH_TO_PHON ENDP ;INPUT/OUTPUT PROCEDURES DEVICE_OPEN PROC NEAR ;Open access to the 'ST' device. MOV AH,3DH MOV DX,OFFSET DEVICE_NAME INT 21H MOV HANDLE,AX ;Get and save handle for further access. RET DEVICE_OPEN ENDP DEVICE_CLOSE PROC NEAR ;Close access to the 'ST' device. MOV AH,3EH MOV BX,HANDLE INT 21H RET DEVICE_CLOSE ENDP DEVICE_IOCTL PROC NEAR ;Write an IOCTL command to the 'ST' device. MOV AH,44H ;DOS's 'DEVICE DRIVER CONTROL' function. MOV AL,3 ;Indicate a 'write command' sub-function. MOV BX,HANDLE MOV CL,CMD$ ;Get length of command to driver. MOV CH,0 MOV DX,OFFSET CMD$+1 ;Get address of command INT 21H;string and send it to driver. RET DEVICE_IOCTL ENDP DEVICE_WRITE PROC NEAR ;Write a string to the 'ST' device. MOV AH,40H ;DOS's 'WRITE to DEVICE' function. MOV BX,HANDLE MOV CX,WRITE_COUNT ;Tell driver number of characters in MOV DX,WRITE_STRING ;string and address of string. INT 21H;Send the string to the driver. RET DEVICE_WRITE ENDP DEVICE_READ PROC NEAR ;Read a string from the 'ST' device. MOV AH,3FH ;DOS's 'READ from DEVICE' function. MOV BX,HANDLE MOV CX,0FFH ;Maximum number of characters to read. MOV DX,OFFSET READ_STRING ;Address of string buffer. INT 21H;Tell driver to return a string. MOV READ_COUNT,AL ;Save length of string returned. RET DEVICE_READ ENDP PRINT PROC NEAR ;Print a string to the screen. MOV AH,09H INT 21H RET PRINT ENDP CSEG ENDS END ASM_XEP_SAMPLE ----------------------------------------------------- Example D -------------------- Turbo PASCAL --------------------- program pascal_XEP_sample; type data_str = string[16]; long_str = string[255]; regs = record ax,bx,cx,dx,bp,si,di,ds,es,flags: integer; end; var device, cmd_str: data_str; english_str, phonetic_str: long_str; result: regs; handle, carry: integer; work_var, read_len: byte; phonetic_array: array[1..256] of char; const write = 1; read = 2; procedure device_open(access : byte); begin device := 'ST' + chr(0); with result do begin ax := $3D00 + access; dx := ofs(device)+1; ds := seg(device); end; msdos(result); {Open device to get handle} with result do begin carry := flags and 1; handle := ax; end; end; procedure device_close; begin with result do begin ax := $3E00; bx := handle; end; msdos(result); {Close device} with result do begin carry := flags and 1; end; end; procedure device_ioctl; begin with result do begin ax := $4403; bx := handle; cx := length(cmd_str); dx := ofs(cmd_str)+1; ds := seg(cmd_str); end; msdos(result); {Send I/O command} with result do begin carry := flags and 1; end; end; procedure device_write; begin with result do begin ax := $4000; bx := handle; cx := length(english_str); dx := ofs(english_str)+1; ds := seg(english_str); end; msdos(result); {Write string to device} with result do begin carry := flags and 1; end; end; procedure device_read; begin with result do begin ax := $3F00; bx := handle; cx := $00FF; dx := ofs(phonetic_array); ds := seg(phonetic_array); end; msdos(result); {Read string from device} with result do begin carry := flags and 1; read_len := ax; end; work_var := read_len; phonetic_str := ''; while read_len > 0 do{Read the result into an array} begin {PASCAL programmers: Is their another way?} read_len := read_len - 1; phonetic_str := phonetic_str + phonetic_array[work_var - read_len]; end; end; procedure print_error; begin writeln('An error has occurred!'); end; procedure english_to_phon; begin device_open(write); if carry=0 then begin device_ioctl; if carry=0 then begin device_write; if carry=0 then begin device_close; device_open(read); if carry=0 then begin device_read; if carry=0 then begin writeln(phonetic_str); device_close; end; end; end; end; end; if carry=1 then print_error; device_close; end; begin cmd_str := 'XEP'; {IOCTL command to send to driver} english_str := 'This is a sample string.' + chr(13); {String to convert} english_to_phon; {Go convert string to phonetics} end. --------------------------------------------------------- Example E -------------------------- QuickC ----------------------- /* Sample program for using voice master device driver with the C programming language. Using: MicroSoft Quick C ver 1.0 compiled with EXE option set. */ #include #include #define READ 0x00 #define WRITE 0x01 char far *english = "This is a sample string.\r"; char phonetic[256]; char far *cmd[] = {"SV2","XEP",""}; /* procedure area */ int device_open(int *handle,int mode) /* open ST device */ { union REGS regs; struct SREGS segregs; static char far *file_name = "ST"; regs.h.ah = 0x3D; regs.h.al = (unsigned char) mode; segregs.ds = FP_SEG(file_name); regs.x.dx = FP_OFF(file_name); intdosx(®s,®s,&segregs); if(regs.x.cflag) return(-1); *handle = regs.x.ax; return(0); } int device_close(int handle) /* Close access to the 'ST' device */ { union REGS regs; regs.x.bx = handle; regs.x.ax = 0x3E00; intdos(®s,®s); return(0); } int device_ioctl(char far *cmd_string) /* Write an IOCTL command to the ST device */ { union REGS regs; struct SREGS segregs; int handle; if(device_open(&handle,WRITE)) return(-1); regs.x.ax = 0x4403; regs.x.bx = handle; regs.x.cx = strlen(cmd_string); segregs.ds = FP_SEG(cmd_string); regs.x.dx = FP_OFF(cmd_string); intdosx(®s,®s,&segregs); device_close(handle); if(regs.x.cflag) return(-1); return(0); } int device_write(char far *string) /* Write string to the 'ST' device */ { union REGS regs; struct SREGS segregs; int handle; if(device_open(&handle,WRITE)) return(-1); regs.x.ax = 0x4000; regs.x.bx = handle; regs.x.cx = strlen(string); regs.x.dx = FP_OFF(string); segregs.ds = FP_SEG(string); intdosx(®s,®s,&segregs); if(regs.x.cflag) return(-1); device_close(handle); return(0); } int device_read(char far *string,int max_length) /* Read a string from the 'ST' device */ { union REGS regs; struct SREGS segregs; int handle; if(device_open(&handle,READ)) return(-1); regs.x.ax = 0x3F00; regs.x.bx = handle; regs.x.cx = max_length; regs.x.dx = FP_OFF(string); segregs.ds = FP_SEG(string); intdosx(®s,®s,&segregs); device_close(handle); if(regs.x.cflag) return(-1); return(0); } main () { int i; i = 0; /* keep sending command until a zero length string */ while(strlen(cmd[i])){ if(device_ioctl(cmd[i++])){ printf("An I/O command error has occurred"); exit(-1); } } if(device_write(english)){ printf("A device write error"); exit(-1); } if(device_read((char far *)phonetic,sizeof(phonetic))){ printf("A device read error"); exit(-1); } printf("\n%s\n",phonetic); return(0); } ------------------------------------------------------- The above programming examples contain all the procedures necessary for sending any command or string of data to the driver program. In order to send a different command to the driver, simply change the string assigned to the variable 'CMD$'. Likewise, 'ENGLISH$' can also be changed as desired. In the program example that follows, procedures and variables that have already been defined will be assumed. Here is a QuickBASIC example that sets the playback speed to '8' and causes Smooth Talker to speak the greeting, 'Hello, how are doing?'. Simply make the following changes to the above QuickBASIC program (EXAMPLE B): Example F --------------------------------------------------------- CMD$="SPE=8" 'The IOCTL command to set playback speed. ENGLISH$="Hello, how are you doing?" 'Assign the English string to speak. CALL SPEAK.ENGLISH 'Go speak the greeting. SUB SPEAK.ENGLISH CALL DEVICE.IOCTL 'Send the speed command. CALL DEVICE.WRITE 'Send the English string. END SUB -------------------------------------------------------- Because the programming examples given for the other languages also use the string variables 'CMD$' and 'ENGLISH$' and contain I/O procedures with the same labels, the above logic can be applied to them as well. If this is not yet apparent, then go back and study the examples very carefully. NOTE: All the program examples given in this documentation have been checked for accuracy and should be executable. We hope that they will provide the programmer with adequate information for interfacing with our device driver. However, some of the examples could probably be written more effectively. So, if you have written a program (or re-written one of the above examples) that you believe better demonstrates the use of the STDRIVER.SYS device driver, then send us a copy and if we like it we will include it in this documentation along with full credit to you for your efforts. We would also be interested in seeing examples from other languages and application programs, like ADA, LISP, DBASE or whatever.