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, ®s, ®s); 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, ®s, ®s); 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.
Send your questions, comments, or ideas here.