Home Memoirs of a Gamer Movies I watched Guidebook Links
There's no 2 ways about it, the original PC Joystick protocol is a nightmare. It's computationally expensive, obtuse to implement, and obnoxious to read. It was the culmination of the IBM PC's root hardware design philosophy of "what's the cheapest way to implement this in hardware?" So how do we get analog axes from a joystick in a cheap fashion? Basically instead of a proper Analog to DC converter, it was decided to charge a set of capacitors (1 for each axis) and then signal the system to stop feeding said cap and loop through polling until the cap drained. Buttons were then fed directly through as binary inputs.
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
xor ax, ax mov bx, 0x0F mov cx, 1 mov dx, 0x201 cli out dx, al .startloop: in al, dx test al, 1 jz .passed_axis1 mov joy1_x, cx xor bx, 1 .passed_axis1: test al, 2 jz .passed_axis2 mov joy1_y, cx xor bx, 2 .passed_axis2: test al, 4 jz .passed_axis3 mov joy2_x, cx xor bx, 4 .passed_axis3: test al, 8 jz .passed_axis4 mov joy2_y, cx xor bx, 8 .passed_axis4: test bx, 0x0F jz .done inc cx cmp cx, 9999 jl .startloop .done: sti in al, dx shr al, 4 mov joy1_b1, al and joy1_b1, 1 shr al, 1 mov joy1_b2, al and joy1_b2, 1 shr al, 1 mov joy2_b1, al and joy2_b1, 1 shr al, 1 mov joy2_b2, al and joy2_b2, 1 |
int i, j, mask=15; disable(); outportb(0x201,0); for (i=1; mask&&i<9999; i++) { j = inportb(0x201) ^ mask; if (j&1) { joy1.x = i; mask^=1; } if (j&2) { joy1.y = i; mask^=2; } if (j&4) { joy2.x = i; mask^=4; } if (j&8) { joy2.y = i; mask^=8; } } enable(); j = inportb(0x201) ^ 0xF0; joy1.button1 = (j >> 4) & 1; joy1.button2 = (j >> 5) & 1; joy2.button1 = (j >> 6) & 1; joy2.button2 = (j >> 7) & 1; |
int i, j, mask=15; _disable(); outp(0x201,0); for (i=1; mask&&i<9999; i++) { j = inp(0x201) ^ mask; if (j&1) { joy1.x = i; mask^=1; } if (j&2) { joy1.y = i; mask^=2; } if (j&4) { joy2.x = i; mask^=4; } if (j&8) { joy2.y = i; mask^=8; } } _enable(); j = inportb(0x201) ^ 0xF0; joy1.button1 = (j >> 4) & 1; joy1.button2 = (j >> 5) & 1; joy2.button1 = (j >> 6) & 1; joy2.button2 = (j >> 7) & 1; |
All of that to derive 4 unsigned shorts and 4 binary buttons. It's amazing anyone bothered at all.