DRDRV.TXT DRDRV is a DR11-K software driver. It is in use at our location with a single DR11 jumpered for input direct from the control lines and interrupts on negative transitions on input bit 15. Our implementation uses it as a loadable driver. Although it seems to work on our system and configuration, it has not been tested with any other configuration. It probably would handle a DR11-C with minor modifications. This driver runs under RSX11M V3.1. Future releases, 11-D, IAS....??? DRDRV is a read-only driver at this time. It only supports the following functions (with sub-functions defined below): 1) IO.KIL -- cancel I/O 2) IO.ATT -- attach device 3) IO.DET -- detach device 4) IO.RLB -- read logical block (reads one word at a time) Normally, these four functions operate exactly as expected (IO.RLB requires the Exec module $PTWRD which is a sysgen option). The primary feature of DRDRV is that it was designed to handle high-speed interrupts without losing data during executive and task level queueing and dequeueing of I/O requests. In order to do this, the driver will, under QIO control, dynamically allocate a ring buffer from the system dynamic storage area (pool), and use this space for stacking unsolicited input. The buffer is allocated when the device is attached with the function code IO.ATT or'ed with the subfunction DR.ATB (this buffer has, consequently, been nicknamed the ATB buffer). The first parameter in the DPB parameter block of such a QIO request must contain the buffer size to allocate, in multiples of 4 bytes. In reality, an extra 4 bytes are tacked on to hold the queue/dequeue ptrs. The detach function (IO.DET), which is implicitly called on task exit (I/O rundown), deallocates the pool buffer and releases it to the Executive. Two mechanisms exist for preventing depletion of pool by accident: 1) there is an arbitrary maximum ATB size limit defined at assembly-time (see ATBLIM and SIZMSK in DRPRE.MAC) and 2) there is a dynamic ATB size limit which can be modified by the command SET /BUF=DR:###. This dynamic limit is stored in UCB offset U.CW4, which is the DEC standard "buffer size" storage word. The initial value is defined by DEFMAX in DRPRE.MAC. When a request to attach an ATB buffer is received, the driver performs the following checks: (atbsize refers to requested allocation) 0) Is device already attached? ... yes--error IE.DAA 1) Is atbsize =< 0 ? ... yes--error IE.SPC 2) Is atbsize a multiple of 4 ? ... no--error IE.SPC 3) Is atbsize > SET /BUF=DR: size (U.CW4) ? ... yes--error IE.SPC 4) Is atbsize > maximum size (ATBLIM) ? ... yes--error IE.SPC 5) Can Exec allocate atbsize+4 bytes? ... no--error IE.NDR Once the ATB buffer is attached, input interrupts are enabled and the data from each interrupt is queued onto the ring buffer. If there are no current I/O requests, or if a FORK is currently executing, or waiting to execute, a new FORK routine is NOT queued....this eliminates pool depletion from too many FORK blocks. If there is a current read request, each pass through the FORK routine empties the ring buffer completely. There are three flavors of read requests (IO.RLB): 1) IO.RLB -- with no ATB buffer attached. This functions like a normal read logical block request. Interrupts are enabled only for the duration of the input request and inter-request data is lost. 2) IO.RLB -- with ATB buffer attached. Since interrupts have been enabled ever since the ATB buffer was attached, the buffer is presumably full or overflowing. This function causes the buffer to be emptied first, then the request is satisfied. If the ATB buffer overflows again during the course of the request, the interrupt rate is too high and/or the ATB buffer is too small. 3) IO.RLB!DR.RIB -- Read Input Buffer This is the same as IO.RLB with an ATB buffer attached, except that the buffer is not cleared before the request is satisfied. If the ATB buffer overflowed before the request was dequeued, or during the course of satisfying the request, the error IE.DAO is returned, and the 2nd I/O status word contains the number of words transferred before the overflow. A typical sequence of events for an input sweep would then be: 1) IO.ATT!DR.ATB -- attach ATB buffer 2) IO.RLB -- flush the buffer and start the read request 3) IO.RLB!DR.RIB -- continue the read request without losing data 4) if IE.DAO (DAta Overrun), try increasing the ATB 5) go to 3 until done An even more elegant routine might keep two I/O requests queued and use ASTs to handle completion. This would shorten the time between active I/O requests and allow a smaller ATB buffer to do the same job. NOTES: 1) All error returns are in the low order byte of the first I/O status word. This is just like DEC drivers. Thus, the line: MOV IOSTAT,R0 BMI ERROR would not work, but: MOVB IOSTAT,R0 BMI ERROR would, and the sign bit will have propagated through R0. 2) I don't know about the DR11-C, but the DR11-K has some crummy design "features" which you might not know about: a) The input buffer bits (0-11) are set only on a negative transition and cleared only when a 1 is written to them. However, if your data line goes low and stays low thru many interrupts, the bit will not be set for more than the first interrupt!! b) Since the input bits are gated, interrupting on input lines seems to work ok. That is, an interrupt comes, the Interrupt Enable is cleared, you service it and enable interrupts, and then you wait for the next one. However, the External Data Ready interrupt control line is not gated. In fact, it is directly ANDed with Interrupt Enable and the result clocks the interrupt request logic. Therefore, the interrupt line goes low, Interrupt Enable is cleared, you service it, you set Interrupt Enable, and (bango!) if you're quick enough and External Data Ready is still low, you get another interrupt a few microseconds later! (cute, huh?) If you have any trouble, or if you implement WRITE functions, feel free to call me. I would actually appreciate hearing from anyone who uses this driver because, if anyone's interested, i will continue to submit updates and support suubroutines to the DECUS tapes. I am currently working on a set of FORTRAN callable routines which look similar to the K-Series Peripheral garbage that DEC gives out. (This driver was the result of that stuff, in a sense, because the K-Series routines require that the user be privileged, and a Common Region is mapped over the I/O Page, which is clearly unacceptable in a multi-user environment). Daniel Steinberg April 5, 1979 @SRI International loc K1023 333 Ravenswood Menlo Park, CA 94025 (415) 326-6200 ext.5539