## Input/Output Device Driver Reference

[prev][next][parent][TOC]

### Understanding How the Joystick Device Driver Works

The pre-emptive multi-tasking nature of OS/2 can cause DOS applications reading the game adapter port to deduce incorrect positions for the joysticks connected. The solution implemented in this device driver to fix this is to regularly sample the game adapter port inside the Physical Device Driver (PDD) and then return fabricated values to the DOS application that reflect that state. With the logic for regularly sampling the port already in the PDD, all that must be done in that regard is to activate that procedure.

Before any of this can be initiated, the first thing that must be done is to trap any access to the game port by the DOS application. Any time I/O ports are to be trapped or emulated, an OS/2 Virtual Device Driver (VDD) is required. The VDD works in conjunction with the PDD to provide the device emulation by capturing port reads and returning values that reflect the current state as determined by the PDD. The VDD is also responsible for determining whether or not a given virtual DOS machine (VDM) is to have direct access to the port and, if so, for obtaining ownership of it.

At device initialization, the VDD first opens the PDD and then retrieves a pointer to the data area that will be used to store the current state of the device. The next job for the VDD comes when a DOS session is started- at which time, it hooks the I/O port for the game adapter. Knowing that the device must be written to by the CPU to fire the one-shots before the read sequence can begin, the hook handler for the write operation is the function where device ownership or emulation is resolved.

If the GAME_DIRECT_ACCESS DOS property is ON for that session, this specifies that the device is to be directly accessed by the VDM. In this case, the VDD must first obtain ownership of the device before allowing this operation to proceed. Device ownership is one of the more complex issues handled by this device driver. It first involves getting permission from the PDD, which can only be granted if the device is presently unused either by an OS/2 application or by another VDM through the emulation system. If not available, the user is given the choice to to kill the session, wait for the device to become free, or ignore that error and use the device in emulation mode. If the user chooses to wait for the device to become free, the DOS session process will be blocked on an event semaphore to be posted when the device is available.

Once the VDD is granted ownership of the device by the PDD, it then must arbitrate final ownership amongst all VDMs competing for it. A mutual exclusion (MUTEX) semaphore is used as the final decision maker in this process and the VDM that is granted ownership of it is given the same status with game adapter port. When the DOS application that owns the device terminates, this MUTEX is released-allowing any other VDMs waiting for it to compete for ownership once again. If no VDMs are waiting, the ownership of the device is returned to none through a call to the PDD.

When the GAME_DIRECT_ACCESS property for a VDM is in its default state of OFF and the game adapter port is written to, the emulation system is activated. First the VDD informs the PDD that it wishes to become a client of the sampling procedure. If no other clients are already active, this request forces an initial sampling so that valid data is immediately available to the VDD. Next the VDD copies the game-port data from the PDD space to its own VDM instance data area using the pointer retrieved at initialization. This copy of the data will be used when the DOS application reads the game port.

Next, the emulation system uses the other DOS property registered at initialization: GAME_DIGITAL_RESPONSE If set to ON, the joysticks connected are emulated as fixed-resistance style joysticks. In this case, the values for each axis are selected from a field in the PDD data area that corresponds to the range the actual value is presently within. That is, if the current value for an axis is less than the upper limit for the lower range, a given fixed value for the lower range is chosen.

With the given value for each axis in hand, the VDD is ready to emulate the game-port adapter when read by the DOS application. First the count on the number of reads is zeroed as the last operation in the port write handler. When the port read handler is called, the value for each axis is compared against the number of reads by this VDM and if greater, a one for that bit is generated. The state of each position bit mirrors the value returned by the actual hardware when the PDD last sampled it on that iteration. The bits for each of the buttons is retrieved from the PDD data area and used in generating the byte returned. This information is transferred on each read to maintain a "freshness" in the button data.