Click here if you are stuck in someone else's frames.
Joystick BIOS Routines

Joystick BIOS extensions are yet another way to read joystick coordinates and if your system has them, it may be a more accurate way (albeit more slow) to read the coordinates.  There are two routines that I am aware of to read the joystick coordinates and for checking the status of their buttons.  Let's look at the BIOS call for checking the status of their buttons first.

    mov    ah, 84h    ; Get joysticks' status function
    mov    dx, 00h    ; Get status of buttons sub-function
    int    15h        ; Call BIOS function
                      ; Register AL now has the button status

We can use BIOS to read the status bits of the joystick buttons into register AL.  In this function, the BIOS just simply reads port 201h into register AL and returns.  It is the same as if we had read that port ourselves so you may not find this very useful.  The second joystick BIOS routine reads the joystick coordinates just as our functions do.  However, unlike our functions that read joystick coordinates, the BIOS routines will always try to maintain all four of the joystick pot values within a range of 0 and 200.

    mov    ah, 84h    ; Get joysticks' status function
    mov    dx, 01h    ; Get joystick coordinates sub-function
    int    15h        ; Call BIOS function
                      ; Register AX = Joystick A's X-axis
                      ; Register BX = Joystick A's Y-axis
                      ; Register CX = Joystick B's X-axis
                      ; Register DX = Joystick B's Y-axis

We can write C functions that "wrap up" the details of calling the BIOS functions just as we did with the SetVideoMode and GetVideoMode functions. Here is a program that does just that:

    /* JOYBIOS.C -- Reads joystick pot values and buttons.
     *
     * Using BIOS routines for both.
     */

    #include <dos.h>    /* Needed for int86 functions */
    #include "vmode.h"  /* Our video mode functions */

    /* Constants for joystick control */
    #define JsA_Xaxis   0x01
    #define JsA_Yaxis   0x02
    #define JsB_Xaxis   0x04
    #define JsB_Yaxis   0x08

    #define JsA_Button1 0x10
    #define JsA_Button2 0x20
    #define JsB_Button1 0x40
    #define JsB_Button2 0x80

    /* Function prototypes */
    int JoystickButtonPressed(int buttonMask);
    void GetJoystickPots(int *XA, int *YA, int *XB, int *YB);

    /* Main function */
    int main(void)
    {
        int X, Y, C = 1;  /* Pixel coordinates and color */

        if (!SetVideoMode(VGA256)) return 1;  /* Exit if no VGA */

        while (!JoystickButtonPressed(JsA_Button2)) {
            GetJoystickPots(&X, &Y, 0, 0);

            X %= ScreenWidth;
            Y %= ScreenHeight;

            if (JoystickButtonPressed(JsA_Button1))
                C = ++C % ScreenColors;

            SetPixel(X, Y, C);
        }

        SetVideoMode(TEXT_MODE);
        return 0;
    }

    int JoystickButtonPressed(int buttonMask)
    {
        union REGS regs;

        regs.h.ah = 0x84;
        regs.x.dx = 0x00;

        int86(0x15, &regs, &regs);

        return ((~regs.h.al) & buttonMask);
    }

    void GetJoystickPots(int *XA, int *YA, int *XB, int *YB)
    {
        union REGS regs;

        regs.h.ah = 0x84;
        regs.x.dx = 0x01;

        int86(0x15, &regs, &regs);

        if (XA) *XA = regs.x.ax;
        if (YA) *YA = regs.x.bx;
        if (XB) *XB = regs.x.cx;
        if (YB) *YB = regs.x.dx;
    }

The BIOS extensions are somewhat convenient if you need a quick way to read the joystick coordinates and you are not concerned too much with the speed of program execution.  Not all computers have joystick BIOS extensions, though and I find that on PC's that don't have these extensions return random values for joystick coordinates whenever the GetJoystickPots function is called.

Previous Page | Main Page | Next page

Send your questions, comments, or ideas here.