HP OpenVMS Systems Documentation

Content starts here

VMS DECwindows Device Driver Manual


Previous Contents Index


Chapter 3
Writing a Class Input Driver

Input driver software that defines the device input DECwindows interface divides into two categories: class input drivers and port input drivers. This chapter describes the function, routines, and program entry of a DECwindows class input driver.

More information concerning the data structures referenced in this chapter may be found in Appendix A. Macros are described in Appendix B. When you write a new driver according to the DECwindows requirements in this manual, consult the OpenVMS VAX Device Support Manual for basic driver design and for information on terminal class and port drivers for specific class/port design.

3.1 Overview of Class Input Driver

The class input driver is the device-independent part of a device driver. A DECwindows class driver decodes serial device data and formats it into event packets for the server. The class driver is sometimes referred to as the "decoder" driver, as the serial data is decoded into events. Decoded events reported to the server include pointer motion, mouse button transitions, and key transitions.

A DECwindows class driver contains routines that implement the various device input, byte-stream, decoding functions that are independent of the controller/CPU type. These class routines specifically support the DECwindows standard interface. The port driver contains device-dependent routines of a VMS terminal driver that are specific to a controller/CPU type.

The DECwindows device drivers use only a subset of the full VMS terminal class/port interface. They bind together by means of the device unit control block (UCB) to form a class/port interface for a DECwindows device-dependent driver. DECwindows software currently supports the class input drivers for the keyboard (IKDRIVER) and mouse (IMDRIVER) listed in Table 1-1.

The driver also contains controller initialization and unit initialization routines that are startup routines required by VMS. They invoke macros needed by the class/port interface.

3.2 Class Driver Program Entry

Routines of the class driver are entered by way of a vector table. The vector table is a data structure that allows other drivers to find the appropriate class routine. Each entry name is a specific offset that points to the class routine. Therefore, each name is used as a symbolic offset.

The class routine symbolic addresses in the table are as follows:

  • CLASS_PUTNXT
  • CLASS_GETNXT
  • CLASS_DDT

The class driver builds the vector table by invoking the $VECINI macro, the $VEC macro for each table entry, and the $VECEND macro that terminates the structure. The COMMON_CTRL_INIT macro within the controller initialization routine relocates the table. Macros are described in Appendix B and the routines are discussed in this chapter.

The class driver routines are entry points from the common, port, and output drivers. Driver calls to some of these routines for the queue interface refer to symbolic offsets in the class vector table. A vectored class routine is called by a JSB instruction. Class routine call examples follow:


#1  MOVL  UCB$L_TT_CLASS(R5),R0 ;get vector table address
    JSB   @CLASS_PUTNXT(R0)     ;call class routine

#2  JSB   @UCB$L_TT_PUTNXT(R5)  ;use offset directly in UCB
                                ;to find routine

Note that, because the get-next-character and put-next-character routines are the most heavily used class driver routines, their addresses are stored in the terminal extension UCB. Fields UCB$L_TT_PUTNXT and UCB$L_TT_GETNXT provide direct access to the class driver. It is therefore possible to use one instruction (method 2), assuming R5 contains the UCB base address. This eliminates the move instruction (vector to general register) required in method 1.

3.3 Class Input Driver Routines

This section describes, in alphabetical order, the routines in a class input driver. The routines in this section are common to both the keyboard and mouse drivers (IKDRIVER and IMDRIVER).


CLASS_DDT

This entry in the class driver vector table points to the driver dispatch table (DDT). It is simply an offset to the table and not to a routine. The CLASS_UNIT_INIT macro uses the CLASS_DDT entry point to load the address of the DDT into the UCB. The DDT is described in the OpenVMS VAX Device Support Reference Manual.

CLASS_GETNXT

The CLASS_GETNXT routine returns to the caller with the next byte to be output from the SILO buffer. The port driver calls CLASS_GETNXT whenever it has finished processing an output request to see if there are more output requests in the SILO buffer. The CLASS_GETNXT routine calls the GET_ONE_BYTE routine that gets the data byte in the SILO. For example, in a keyboard driver, this routine passes LED (light) information from the SILO buffer to the keyboard.
input
Location Contents
R5 Input UCB address
output
Location Contents
UCB$B_TT_OUTYPE 0 if there is no data to be output, 1 if one character is in R3, or a negative value if there is a data burst to output
UCB$L_TT_OUTADR Address of burst if UCB$B_TT_OUTYPE is negative
UCB$B_TT_OUTLEN Length of data burst
R5 UCB address
All other registers Destroyed

CLASS_PUTNXT

The CLASS_PUTNXT routine is called by a port driver to pass input data from the serial line to the input queue. CLASS_PUTNXT decodes the data and converts it to an X event in the form of an input packet. It uses the GET_FREE_KB_PACKET macro to get a free packet and it terminates processing by invoking the PUT_INPUT_ON_QUEUE macro to insert the event in the input queue.

Note that the input and free queues are self-relative queues that must be accessed using interlocked instructions. The GET_FREE_KB_PACKET macro removes a free packet from the free queue using the REMQHI instruction. The routine then decodes the byte stream, setting the event data in the packet, and the PUT_INPUT_ON_QUEUE macro inserts the packet in the input queue using the INSQTI instruction.

input
Location Contents
R0 CSR
R3 Input data byte
R5 Input UCB address
output
Location Contents
UCB$B_TT_OUTYPE 0 if there is no data to be output, 1 if one character is in R3, or a negative value if there is a data burst to output
UCB$L_TT_OUTADR Address of first character in burst (burst mode only)
UCB$W_TT_OUTLEN Length of data burst (burst mode only)
R0 Preserved
R5 UCB address
All other registers Destroyed

Controller Initialization Routine

The controller initialization routine prepares a controller or hardware interface for operation. The routine is entered at system startup and during recovery after power failure and is always called at IPL$_POWER. The routine resets the controller unit and invokes the COMMON_CTRL_INIT macro to relocate the driver vector table.

Note that before invoking the COMMON_CTRL_INIT macro, a DECwindows class driver should invoke the $DECW_COMMON_READY macro to ensure that the common driver is loaded. If the common driver is not loaded, the driver does not operate on calls to the common service routines and the system may crash.

input
Location Contents
R4 CSR address of the controller
R5 IDB address of the controller
R6 DDB address of the controller
R8 CRB address of the controller
output
Location Contents
R0, R1, R2 Destroyed

Unit Initialization Routine

The unit initialization routine in the class driver sets up each device unit. The routine loads specific UCB locations with hardware unit requirements or controller-specific data, binds the class and port drivers, readies the hardware for input and output, and takes any necessary action should a power failure occur. The initialization routine loads the class vector table address into UCB field UCB$L_TT_CLASS. The unit initialization routine calls the COMMON_UNIT_INIT macro, which sets the driver dispatch table address (CLASS_DDT) in the class vector table to that of the common DDT. This routine is run each time a unit is created and is always called at IPL$_POWER.
input
Location Contents
R4 CSR address of the unit
R5 Input UCB address of the unit
output
Location Contents
R4 Preserved
R5 Preserved


Chapter 4
Writing a Port Input Driver

Input driver software that defines the device input DECwindows interface divides into two categories: class input drivers and port input drivers. This chapter describes the function, routines, and program entry points of a DECwindows port input driver.

More information concerning the data structures referenced in this chapter may be found in Appendix A. Macros are described in Appendix B. When you write a new driver according to the DECwindows requirements in this manual, consult the OpenVMS VAX Device Support Manual for basic driver design and the chapter on terminal class and port drivers for specific class/port information.

4.1 Overview of Port Input Driver

The port input driver is the device-dependent part of a DECwindows device driver. The port driver is sometimes referred to as the "interrupt" driver. It processes hardware interrupts and passes an uninterpreted byte stream of data to a class driver, where it is decoded into an X11 event packet.

The port driver contains device-dependent routines of a VMS terminal driver that are specific to a controller/CPU type. They bind together by means of the unit control block (UCB) to form a class/port interface for a DECwindows device-dependent driver.

The port driver contains the driver prologue table (DPT) data structure; initialization macros; device, unit, and controller initialization routines; a start I/O routine; port routines; and any additional device-dependent code, such as an interrupt service routine. VMS currently supports the port input driver (YEDRIVER) for workstations listed in Table 1-1.

The driver also contains the controller initialization and unit initialization routines that are startup routines required by VMS. The routines invoke macros needed by the class/port interface.

4.2 Port Driver Program Entry

Class drivers and output drivers call port routines to perform port-specific hardware functions. Routines of the port input driver are entered by way of a vector table. The port vector table is a data structure that allows the class driver to find the appropriate port routine. Each entry name is a specific vector table offset that points to the port routine. The port routine symbolic addresses in the table are as follows:

  • PORT_STARTIO
  • PORT_SET_LINE

  • PORT_ABORT
  • PORT_RESUME

The port driver builds the vector table by invoking the $VECINI macro, the $VEC macro for each table entry, and the $VECEND macro that terminates the structure. The COMMON_CTRL_INIT macro within the controller initialization routine relocates the table. Macros are described in Appendix B and the routines are in this chapter. A vectored port routine call example follows:


MOVL   UCB$L_TT_PORT(R5),R1 ;get vector table address
JSB    @PORT_STARTIO(R1)    ;call port start I/O routine

4.3 Port Input Driver Routines

The port input driver contains three types of routines: startup, initiate, and service routines. This section describes, in alphabetical order, the vectored routines that are part of the port input driver module.


PORT_ABORT

The PORT_ABORT routine commands the port to abort any currently active output activity. This port service routine can be called from the class input driver at any time and invalidates the data stored in UCB$L_TT_OUTADR.
input
Location Contents
R5 Input UCB address

PORT_RESUME

The PORT_RESUME routine directs the port to resume any previously stopped output. The port must allow this routine to be called at any time (whether the output is active or was already stopped). This routine ensures that the hardware is enabled for output.
input
Location Contents
R5 Input UCB address

PORT_SET_LINE

The PORT_SET_LINE routine changes the serial line characteristics. This initiate routine is called whenever any serial line characteristic in UCB$L_DEVDEPEND or UCB$L_DEVDEPEND2 is changed, when speed, parity, or automatic flow control is changed, or when DMA is enabled/disabled. This is the only port routine that can write the fields UCB$L_DEVDEPEND and UCB$L_DEVDEPEND2.
input
Location Contents
R5 Input UCB address
UCB$B_TT_MAINT Maintenance parameters
UCB$B_TT_PARITY Parity, stop bits, and frame size
UCB$B_TT_SPEED Low byte that defines transmit speed, high byte that defines receive speed or is 0
UCB$B_TT_PRTCTL DMA- and AUTOXOFF-enable flags
UCB$L_DEVDEPEND First longword for device-dependent status
UCB$L_DEVDEPND2 Second longword for device-dependent status
output
Location Contents
R4 Destroyed

PORT_STARTIO

The PORT_STARTIO initiate routine starts output on a serial line that is currently inactive. It enables output interrupts on an idle controller unit. It is always called with a character key (data byte) or a burst of data.
input
Location Contents
R3 Character to output (single character only)
R5 Input UCB address
UCB$B_TT_OUTYPE 0 if no character to output, 1 if one character to output, or a negative value if data burst to output
UCB$L_TT_OUTADR Address of burst if UCB$B_TT_OUTYPE is negative
UCB$B_TT_OUTLEN Length of data burst
output
Location Contents
R0 through R4 Destroyed
R5 UCB address

Controller Initialization Routine

The controller initialization routine prepares a controller or hardware interface for operation. The routine is entered at system startup and during recovery after power failure and is always called at IPL$_POWER. The routine resets the controller unit and invokes the COMMON_CTRL_INIT macro to relocate the driver vector table. The DPT_STORE macro places the address of this routine in the CRB.

Note that before invoking the COMMON_CTRL_INIT macro, a DECwindows port driver should invoke the $DECW_COMMON_READY macro to ensure that the common driver is loaded. If the common driver is not loaded, the driver does not process calls to the common service routines and the system might crash.

input
Location Contents
R4 CSR address of the port
R5 IDB address of the controller unit
R6 DDB address of the controller unit
R8 CRB address of the controller unit
output
Location Contents
R0, R1, R2 Destroyed

Unit Initialization Routine

The unit initialization routine sets up each individual device. The routine loads specific UCB locations with hardware unit requirements or controller-specific data, binds the class and port drivers, readies the hardware for input and output, and takes any necessary action should a power failure occur. The initialization routine loads the port vector table address into UCB field UCB$L_TT_PORT.

This routine is invoked each time a unit is created and is always called at IPL$_POWER. The DPT_STORE macro places the address of this routine in the CRB and sets the unit's DDT to the address of the common DDT.

input
Location Contents
R4 CSR address of the unit
R5 Input UCB address of the unit
output
Location Contents
R4 Preserved
R5 Preserved


Previous Next Contents Index