[Back to JOYSTICK SWAG index] [Back to Main SWAG index] [Original]
unit joy; {unit for accessing joystick 0}
interface
var
installed:boolean; {true if joystick 0 present at unit startup}
X,Y:word; {stick position}
A,B:boolean; {buttons down?}
const
Cal_L:word=$FFFF; {rect containing calibration extent of 'center'}
Cal_T:word=$FFFF;
Cal_R:word=0;
Cal_B:word=0;
procedure sample; {take a sample of current joystick 0 state}
procedure swirlCalibrate;
procedure centerCalibrate;
implementation
procedure sample;assembler;asm
xor si,si {x count}
xor di,di {y count}
mov dx,$201 {Game port}
out dx,al {Fire the joystick one-shots}
@@L:
in al,dx {get joystick bits}
mov ah,al {save original value}
shr al,1 {joy 0 x expired? 0 if so, else 1}
adc si,0 {accumulate in x}
jc @@TOOLONG {if overflow, give up}
shr al,1 {joy 0 y expired? 0 if so, else 1}
adc di,0 {accumulate in y}
jc @@TOOLONG {if overflow, give up}
test ah,3
jnz @@L {keep going til they're both 0 or we overflow}
not ah {flip button bits so 1=pressed}
mov al,ah
and al,$10 {mask off buttons and store them}
mov A,al
and ah,$20
mov B,ah
mov X,si {store x & y coords}
mov Y,di
jmp @@X
@@TOOLONG:
mov X,-1 {overflowed, return -1 as error}
mov Y,-1
mov A,0
mov B,0
@@X:
end;
procedure swirlCalibrate;begin {display message before starting this one!}
repeat sample until not (A or B);{make sure button is up}
repeat {collect max extents}
sample;
if x<Cal_L then Cal_L:=x;
if x>Cal_R then Cal_R:=x;
if y<Cal_T then Cal_T:=y;
if y>Cal_B then Cal_B:=y;
until a; {until user presses a button}
Cal_L:=((Cal_L*3)+Cal_R)div 4; {now adjust for center by}
Cal_R:=((Cal_R*3)+Cal_L)div 4; { weighted averaging}
Cal_T:=((Cal_T*3)+Cal_B)div 4;
Cal_B:=((Cal_B*3)+Cal_T)div 4;
end;
procedure centerCalibrate;var x2,y2:word;begin {doesn't require user
interaction}
sample;
x2:=x shr 1;
y2:=y shr 1;
Cal_L:=x-x2;
Cal_R:=x+x2;
Cal_T:=y-y2;
Cal_B:=y+y2;
end;
begin
sample;
installed:=(x<>$FFFF);
end.
[Back to JOYSTICK SWAG index] [Back to Main SWAG index] [Original]