.TITLE QIOW .IDENT /31JA89/ ; Version: ; File:[22,320]QIOW.MAC Last Edit: 19-JUL-1989 11:22:03 ; ; Author: Philip Hannay ; History: 31-Jan-89 -- Philip Hannay. Created from old QIOW.MAC. ; ; .REM | Procedure QIOW(fnc: word; lun: word; efn: event_flag; var iosb: IO_status_block; var parm: QIO_param_list); EXTERNAL; {*USER* Pascal-3 Procedure to execute QIOW "wait" function. This procedure provides access to all functionality provided by the QIOW (wait) directive. It is assumed that you will include the PAS$EXT:QIO.TYP include file that contains various IO defintions for both normal and EIO type QIOs. A number of predefined function values are defined as constants. However, you may need to supply your own. NOTE: ERROR CODES are returned in your IOSB as byte integers. That means Pascal sees the first two bytes of the IOSB as a positive integer as the error code is in the low order byte (and thus the sign bit) of the first IOSB word. Take this into account when you examine the IOSB. If the low order byte exceeds 127 (177 octal), then you are looking at a negative byte integer. To extract the error code into an integer, MOD the first IOSB word by 256 (to get low order byte), and if result exceeds 127, subtract result from 256 and multiply by -1. The final integer will then the be correct positive or negative number. To extract the high order byte, DIV the first IOSB word by 256. Since this is the terminating character (7 or 8 bit), it is unsigned, and may be taken as is. The second IOSB word is always a two byte integer (character count), and is unsigned. You can treat it as signed, since no QIO character count can exceed 8192. Note that the IO_status_block definition in GENERAL.TYP also lets you look at the status block as a 4 byte array. This lets you access the two bytes of the first word of the block directly. Accessing the bytes directly, you can get the IO status code using an ORD(BYT[1]). The resulting integer is unsigned from 0 thru 255. So if you want a signed integer, subtract 256 from the integer IF integer exceeds 127. You can look directly at the high order byte (terminating character if any) of the first status block word by doing an ORD(BYT[2]). To look at it as a character, use CHR(ORD(BYTE[2])). NOTE that the QIOW action differs from the QIO (no wait) action. QIOW action is synchronized with your program, that is, your program stops execution until the IO is completed. Thus you are not required to wait for the event flag or check the IO status block for completion. When execution continues after the QIOW call, you can assume the IO is complete, provided the directive was accepted ($DSW=1). Make sure to check directive status first to insure that the QIOW was accepted. The QIOW directive is the same IO directive used by high level language program READLN, WRITELN, READ, WRITE statements. Note that you may need to supply imbedded carriage return and line feed in your output buffer, or use the VFC parameter (parameter 4) supplying a FORTRAN style form control character like blank (LF buffer CR) or "1" (LF buffer CR CR), etc. Note that normal DEC convention is to output a leading LF (linefeed) before any output, and then output a trailing CR (carriage return) after outputting buffer. FNC is the IO function code - a word value. Use the predefined contants in QIO.TYP, or supply your own code. LUN is the logical unit number to be assigned to the appropriate device. EFN is the event flag to be set when the I/O is completed. You must supply an event flag (local or otherwise). You cannot use f0. IOSB is the two word IO status block. PARM is the 6 word QIO parameter list. Supply a zero for any parameters that are null or not applicable. Remember that a zero will have meaning in many cases depending on the function code used. If you supply a timeout value in the parameter list, remember that a zero indicates a "zero timeout" is to be done, and a positive value indicates "timeout of value*10 seconds" to be done. IMPORTANT NOTE: Variables passed in the PARM parameter list cannot be noted by the Pascal compiler, and it may make a mistake when it optimizes code, based on the assumption that the QIOW call does not use those variables. To avoid a problem, be sure to make global any variable that is passed in PARM (as an address) that is modified by the QIOW call. In particular, the input buffer variable where the results of a read operation will be placed. By making the variable a global variable, the compiler will do no further optimization. IOSB and IOSB2 represent the two words of the IO status block. IOSB contains the IO status word. For read functions, the high byte contains the terminating character. IOSB2 is the second word of the IO status block, for read functions, it contains the byte count read in. Directive status is available in $DSW on return. } | ; ; Assemble with PASMAC.MAC as prefix file. ; .MCALL QIOW$S PROC QIOW PARAM FNC, INTEGER PARAM LUN, INTEGER PARAM EFN, SCALAR PARAM ISB1, ADDRESS PARAM PARM, ADDRESS SAVE BEGIN MOV SP,R0 ;PRESERVE SP MOVB EFN(0),R1 ;EFN PARAM IS A BYTE, MUST CLEAN IT UP BIC #^C^O377,R1 ;MAKE IT AN UNSIGNED WORD BNE 1$ MOV #IE.IEF, $DSW ;MUST SUPPLY EVENT FLAG BR 2$ 1$: MOV PARM(0),R2 ;R2 IS ADDRESS OF PARAMETER LIST ADD #10.,R2 ;R2 NOW POINTS TO LAST PARAMETER - ; NOTE THAT WE DO THIS SINCE THE ; QIOW$S WILL MOVE THE PARAMETERS ; ONTO THE STACK STARTING WITH THE ; LAST ONE. QIOW$S FNC(0),LUN(0),R1,,ISB1(0),,<-(R2),-(R2),-(R2),-(R2),-(R2),(R2)> 2$: ENDPR .END