add directory study
This commit is contained in:
81
study/sabre/os/files/HCI/FCS2CH.TXT
Normal file
81
study/sabre/os/files/HCI/FCS2CH.TXT
Normal file
@@ -0,0 +1,81 @@
|
||||
Instructions for putting FCS handle on CH Flightstick base
|
||||
----------------------------------------------------------
|
||||
|
||||
Here's a quick file to explain the procedure for taking a Thrustmaster
|
||||
Flight Control Stick and mounting it on a CH Flightstick base, while
|
||||
keeping all FCS button and hat functions (and only losing the throttle
|
||||
wheel on the CH base.)
|
||||
|
||||
You'll need a small phillips head screwdriver, a pair of wire-cutters,
|
||||
a pair of wire-strippers, electrical tape, and a T-10 star screwdriver
|
||||
(or similarly sized allen wrench)
|
||||
|
||||
First, remove the bottoms of both bases. Look at the internals.
|
||||
You'll see that the potentiomenter layouts for both sticks are very
|
||||
similar. The key to doing this whole procedure is removing the cable
|
||||
from the FCS and installing it in the CH base. In the Ch, you have 3
|
||||
wires that connect the pots (1 black, 1 blue, 1 tan) There is also a
|
||||
yellow wire that goes to the throttle wheel pot (the blue wire also
|
||||
goes to this pot as well) Ignore the throttle wheel pot as it won't
|
||||
work after the procedure (it uses the same pin assignments in the plug
|
||||
as the 4-way switch).
|
||||
|
||||
Cut the Black, blue, and tan wires that go to the cable. Cut the
|
||||
wires leading up to the CH handle triggers. Cut the yellow wire leading
|
||||
to the throttle wheel pot. Now, remove the cable from the base. On the
|
||||
FCS, there are also three wires for the pots...a black wire, a white
|
||||
wire, and a tan wire. There is also a gray wire connecting the pots
|
||||
together in the FCS, but you can ignore this wire completely (the pots
|
||||
in the CH are connected already by part of the blue wire) Cut the white,
|
||||
tan, and black wires leading to the FCS cable. Cut the wires leading up
|
||||
into the handle of the FCS, making sure to leave plenty of extra wire on
|
||||
either end as you'll be connecting them right back together.
|
||||
|
||||
Now, remove the FCS cable from the base. Unscrew the CH stick handle
|
||||
screws and remove the handle from the shaft. Notice that there is a small
|
||||
pilot hole on the shaft. This is important as it allows the FCS stick
|
||||
to fasten to the CH shaft. Unscrew the FCS stick screws and remove the
|
||||
free half of the handle. The other half is screwed to the shaft via a
|
||||
similar pilot hole. (At this point, use great care with the FCS stick...
|
||||
the buttons and solder joints are extremely fragile and break easily.)
|
||||
Unscrew the other half of the handle from the FCS shaft. Use the screw
|
||||
to open the small pilot hole in the CH shaft...then connect the handle
|
||||
to the shaft using the screw. Thread the wires from the handle back
|
||||
down the CH shaft, then screw the other half of the FCS handle on to
|
||||
the assembly.
|
||||
|
||||
Well, you're almost done!! Now, take the FCS cable and connect the pot
|
||||
wires as follows...
|
||||
|
||||
FCS Cable Ch Base and pots
|
||||
Black wire to Black wire
|
||||
White wire to Tan Wire
|
||||
Tan Wire to Blue Wire
|
||||
|
||||
Now just reconnect the FCS handle wires to the cable wires, slip the
|
||||
cable stop into the space provided in the base, and button her up!!
|
||||
Then just check the stick out using any program that takes advantage
|
||||
of the FCS features (I use AOTP to benchtest my stick...it was a dog
|
||||
with the FCS, but very sprightly with the CH stick...now it has the
|
||||
best of each!)
|
||||
|
||||
If you have any questions or problems with this procedure, contact
|
||||
me through CI$ Mail at Account Number 70761,1103. Hope it works as
|
||||
well for you as it did for me. Good luck!!
|
||||
|
||||
********************************NOTE**************************************
|
||||
I downloaded this file from Compuserve because of the problems I experienced
|
||||
with the Thrustmaster Flight Control System. I have since converted my FCS to
|
||||
my old CH Flightstick base and have had NO problems since doing this. The only
|
||||
real problem I found was that the person that wrote this left his number only,
|
||||
and not his name. This makes it very hard to contact someone to find out how
|
||||
well it worked. Well you can contact me, Albert Lowe, here on the MPSBBS, or
|
||||
through Compuserve at 73233,2455. If you need help. I must stress that you
|
||||
shouldn't try this unless you have a good dexterity and have worked with
|
||||
electrical wiring before. If you want this done, but don't think you can do it,
|
||||
get someone that you think can.
|
||||
|
||||
Good Luck,
|
||||
|
||||
Albert Lowe
|
||||
|
||||
108
study/sabre/os/files/HCI/GAMEPAD.TXT
Normal file
108
study/sabre/os/files/HCI/GAMEPAD.TXT
Normal file
@@ -0,0 +1,108 @@
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Programming the Gravis GamePad and Analog Pro <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Disclaimer <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
I assume no responsibility whatsoever for any effect that this file, the
|
||||
information contained therein or the use thereof has on you, your sanity,
|
||||
computer, spouse, children, pets or anything else related to you or your
|
||||
existance. No warranty is provided nor implied with this information.
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Programming the Gravis GamePad <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The Gravis GamePad plugs into the standard joystick connector. It is
|
||||
a pad with a 9 direction controller (including center) and four buttons.
|
||||
Two of the buttons can be selected as "autofire" by a switch on the
|
||||
GamePad.
|
||||
|
||||
_____ ||
|
||||
| \____||________
|
||||
| __ GRAVIS \
|
||||
| / \ GamePad B |
|
||||
| \__/ A C|
|
||||
|______________ D |
|
||||
\_____|
|
||||
|
||||
The chief difference between the GamePad and a regular joystick is that
|
||||
the GamePad uses fixed resistances of about 0<>, 50k<30> and 100k<30>. The
|
||||
resistances for each controller position are as follows:
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> x = 0<> <20> x = 50<35> <20> x = 100<30> <20>
|
||||
<20> y = 0<> <20> y = 0<> <20> y = 0<> <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
||||
<20> x = 0<> <20> x = 50<35> <20> x = 100<30> <20>
|
||||
<20> y = 50k<30> <20> y = 50<35> <20> y = 50<35> <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
||||
<20> x = 0<> <20> x = 50<35> <20> x = 100<30> <20>
|
||||
<20> y = 100<30> <20> y = 100<30> <20> y = 100<30> <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The x axis is read via the regular Joystick A X Axis, the y axis is read
|
||||
via the Joystick A Y Axis.
|
||||
|
||||
The GamePad buttons are accessed the same way that the normal joystick
|
||||
buttons are accessed:
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<EFBFBD> GamePad Button A = Joystick A, Button 1 <20>
|
||||
<EFBFBD> GamePad Button B = Joystick A, Button 2 <20>
|
||||
<EFBFBD> GamePad Button C (autofire A) = Joystick B, Button 2 <20>
|
||||
<EFBFBD> GamePad Button D (autofire B) = Joystick B, Button 1 <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Programming the Gravis Analog Pro <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The Analog Pro is very similar to a regular joystick, except it has 5
|
||||
buttons and a dial on the joystick, originally intended for use as a
|
||||
throttle for flight simulators.
|
||||
|
||||
|
||||
|
||||
-- B & A
|
||||
___
|
||||
C -> \ |
|
||||
||
|
||||
D - || - E
|
||||
_<>_||_<>_
|
||||
|______|
|
||||
|
||||
Left Side
|
||||
|
||||
|
||||
|
||||
The Analog Pro joystick position is read the same as the regular Joystick A.
|
||||
The throttle value is read the same as for the regular Joystick B X Axis
|
||||
value.
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Analog Pro Button A = Joystick A, Button 1 <20>
|
||||
<20> Analog Pro Button B = Joystick A, Button 2 <20>
|
||||
<20> Analog Pro Button C = Joystick B, Button 1 <20>
|
||||
<20> Analog Pro Button D = Joystick B, Button 2 <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The SDK is a bit vague as to how button E is read. It mentions that the
|
||||
buttons D and E can be set as any of the joystick buttons, but I believe
|
||||
this is done via switches on the joystick itself (not sure, I don't actually
|
||||
own one).
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> References <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
All the information in this file was obtained from the PC GamePad and Analog
|
||||
Pro SDK V1.1 which can be obtained via anonymous ftp:
|
||||
|
||||
site: wasp.eng.ufl.edu
|
||||
directory: /pub/msdos/demos/programming/source
|
||||
filename: joysdk11.lzh
|
||||
252
study/sabre/os/files/HCI/JOYSTICK.TXT
Normal file
252
study/sabre/os/files/HCI/JOYSTICK.TXT
Normal file
@@ -0,0 +1,252 @@
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Programming the PC Joystick <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Programming Info <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
All joystick programming is done via port 201h.
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> 7 <20> 6 <20> 5 <20> 4 <20> 3 <20> 2 <20> 1 <20> 0 <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<20> <20> <20> <20> <20> <20> <20> <20>
|
||||
Joystick B, Button 2 <20><><EFBFBD><EFBFBD> <20> <20> <20> <20> <20> <20> <20><><EFBFBD><EFBFBD> Joystick A, X Axis
|
||||
Joystick B, Button 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20> <20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Joystick A, Y Axis
|
||||
Joystick A, Button 2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Joystick B, X Axis
|
||||
Joystick A, Button 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Joystick B, Y Axis
|
||||
|
||||
Reading the status of the joystick buttons is fairly simple. Just read the
|
||||
byte from the joystick port and check the status of the appropriate bit. A
|
||||
clear bit (0) means the button is pressed, a set bit (1) means it is not
|
||||
pressed. Note that the button's are not hardware debounced. Each time a
|
||||
button is pressed it's bit may "bounce" between 0 and 1 a couple of times.
|
||||
|
||||
Reading the position of the stick positions is a bit more complicated. You
|
||||
must first write a dummy byte (any value will do) to the joystick port. This
|
||||
will set each axis bit to 1. You must then time how long the bit takes to
|
||||
drop back to 0, this time is roughly proportional to the position of
|
||||
the joystick axis (see Steve McGowan's discussion below).
|
||||
|
||||
AT computers also have a BIOS call which supports the joystick. I have come
|
||||
across numerous machines which apparently did not support this call. My own
|
||||
machine supports reading the joystick buttons apparently can't read the
|
||||
stick position values, so I do not advise using this call for any serious
|
||||
games. In any case here is info on the call:
|
||||
|
||||
Joystick Support BIOS Call
|
||||
|
||||
Int 15h
|
||||
|
||||
To call:
|
||||
AH = 84h
|
||||
DX = 00h Read switch settings
|
||||
01h Read joystick position
|
||||
|
||||
Returns:
|
||||
PC, PCjr : Carry flag set, AH = 80h
|
||||
PC XT : Carry flag set, AH = 86h
|
||||
All others : DX = 00h on calling
|
||||
AL = Switch settings (bits 4 - 7)
|
||||
Carry flag set on error
|
||||
DX = 01h on calling
|
||||
AX = A(X) value
|
||||
BX = A(Y) value
|
||||
CX = B(X) value
|
||||
DX = B(Y) value
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Hardware Pinout <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The joystick connects to a 15 pin female plug :
|
||||
|
||||
__________________________
|
||||
\ 8 7 6 5 4 3 2 1 /
|
||||
\ 9 10 11 12 13 14 15 /
|
||||
----------------------
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Pin # Joystick <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
||||
<20> 1 +5v <20>
|
||||
<20> 2 Joystick A, Button 1 <20>
|
||||
<20> 3 Joystick A, X Axis <20>
|
||||
<20> 4 Gnd <20>
|
||||
<20> 5 Gnd <20>
|
||||
<20> 6 Joystick A, Y Axis <20>
|
||||
<20> 7 Joystick A, Button 2 <20>
|
||||
<20> 8 +5v <20>
|
||||
<20> 9 +5v <20>
|
||||
<20> 10 Joystick B, Button 1 <20>
|
||||
<20> 11 Joystick B, X Axis <20>
|
||||
<20> 12 Gnd <20>
|
||||
<20> 13 Joystick B, Y Axis <20>
|
||||
<20> 14 Joystick B, Button 2 <20>
|
||||
<20> 15 +5v <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Misc notes on Joystick handling by Steve McGowan <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
With a polling loop on a 486-66 I got x/y values between 8 and 980. When
|
||||
I centered the stick the value was usually a value around 330.
|
||||
|
||||
NOTE: a Gravis Game Pad it only put out 3 values, 8(min), 330(center),
|
||||
and 980(max). Every joystick I have tried has been non-linear.
|
||||
|
||||
The "speed compensation" that some games require is due to the fact that
|
||||
the game designer did not anticipate the range of values that could
|
||||
come back on faster machines. On a 486-25 you may see max values of 360,
|
||||
I saw 980, on a Pentium the max value could be well over 2000. If you
|
||||
had used a unsigned byte value you probably would have been in good
|
||||
shape on an AT, or 386 but you would be in big trouble with faster machines.
|
||||
|
||||
Because the joystick logic returns a non linear value, if you base your
|
||||
scaling only on the 4 corners then the center will be off (biased towards
|
||||
a corner). If you just use the center value and a single scaling factor
|
||||
(i.e. of the center is at 330 then full throw should be at 660), then the
|
||||
stick will saturate (660) half way to the full throw position (980).
|
||||
That is why most joystick setup programs make the distinction between
|
||||
hitting the 4 corners and centering the stick.
|
||||
|
||||
Joystick position vs. loop count
|
||||
|
||||
x,y--------------------
|
||||
8,8| 330,8 | 980,8
|
||||
| |
|
||||
| | delta 330
|
||||
| |
|
||||
8,330| 330,330 | 980,330 (y centered)
|
||||
| |
|
||||
| | delta 650
|
||||
| |
|
||||
8,980| 330,980 | 980,980
|
||||
--------------------
|
||||
(x centered)
|
||||
|
||||
For the best effect you basically need 2 scale factors, depending on whether
|
||||
you are above or below the center value. I think the curve is actually an
|
||||
exponential (charging capacitor) but a straight line approximation should
|
||||
do fine.
|
||||
|
||||
The 10% dead zone in the center is a good idea. The centering mechanism of
|
||||
joysticks vary in repeatablity, they don't always come back to the same place.
|
||||
I have a cheap one that (1 time in 8) does not return to the X center if I
|
||||
just let it snap to center. It hangs on the high side.
|
||||
|
||||
I would recommend disabling interrupts while polling. An interrupt
|
||||
in the middle of your polling loop will really throw off the results. And
|
||||
any DMA that takes place will also give you bad values.
|
||||
|
||||
Joysticks are noisy, so holding the stick in a fixed position will return
|
||||
values that vary +-5% easily. I added a smoothing function to my joystick
|
||||
code where I throw away single values that are not continuous. It helped
|
||||
a lot with the noise and the DMA.
|
||||
|
||||
I use protected mode and the interrupt disable() call doesn't actually work
|
||||
because it only disables interrupts for the process not the processor.
|
||||
The smoothing trick can help here too.
|
||||
|
||||
If I turn on my machine and start the polling loop immediately, it will
|
||||
put out a centered value of 330,330 but after warming up for 10 minutes
|
||||
the value changes to 285,285. This variance also needs to be absorbed in
|
||||
your center dead zone. If after warming up the 'center' value is outside your
|
||||
dead zone then the cursor will drift (to the left and/or up). Make
|
||||
sure your game has a "center joystick" command to get around joystick
|
||||
interfaces with lousy temperature compensation.
|
||||
|
||||
You must wait for all of the axis bits to settle before initiating
|
||||
another read, otherwise strange results may come out. So, instead of
|
||||
reading X, then Y, in two separate loops (which take twice as much time)
|
||||
Read both X and Y simultaneously, polling until both bits settle. This
|
||||
can be extended for two joysticks, assuming that they are both attached.
|
||||
The respective X/Y bits never come true if there is no joystick attached.
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> A Simple Demo Joystick Unit <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
{
|
||||
JOY.PAS - By Mark Feldman
|
||||
e-mail address : u914097@student.canberra.edu.au
|
||||
myndale@cairo.anu.edu.au
|
||||
|
||||
|
||||
A simple Pascal Joystick Unit.
|
||||
}
|
||||
|
||||
|
||||
unit Joy;
|
||||
|
||||
Interface
|
||||
|
||||
{ Define constants for use as JoystickButton and JoystickPosition parameters }
|
||||
const JoystickAButton1 = $10;
|
||||
JoystickAButton2 = $20;
|
||||
JoystickBButton1 = $40;
|
||||
JoystickBButton2 = $80;
|
||||
JoystickAAxisX = $01;
|
||||
JoystickAAxisY = $02;
|
||||
JoystickBAxisX = $04;
|
||||
JoystickBAxisY = $08;
|
||||
|
||||
function JoystickButton(buttonnum : byte) : boolean;
|
||||
function JoystickPosition(axisnum : byte) : word;
|
||||
|
||||
Implementation
|
||||
|
||||
const JOYSTICKPORT = $201;
|
||||
|
||||
{ Button returns true is button is pressed }
|
||||
function JoystickButton(buttonnum : byte) : boolean;
|
||||
begin
|
||||
JoystickButton := (Port[JOYSTICKPORT] and buttonnum) = 0;
|
||||
end;
|
||||
|
||||
{ Returns position value of joystick. The value returned is highly
|
||||
dependent on machine speed. Changing the setting of the computer's
|
||||
Turbo speed button will affect the value returned.
|
||||
Returns $FFFF if the joystick is not connected
|
||||
}
|
||||
function JoystickPosition(axisnum : byte) : word;
|
||||
var count : word;
|
||||
begin
|
||||
asm
|
||||
mov word ptr count, 0
|
||||
cli { Disable interrupts so they don't interfere with timing }
|
||||
mov dx, JOYSTICKPORT { Write dummy byte to joystick port }
|
||||
out dx, al
|
||||
@joystickloop:
|
||||
inc count { Add one to count }
|
||||
cmp count, $FFFF { Check for time out }
|
||||
je @done
|
||||
in al, dx { Get joystick port value }
|
||||
and al, axisnum { Test the appropriate bit }
|
||||
jne @joystickloop
|
||||
@done:
|
||||
sti { Enable interrupts again }
|
||||
end;
|
||||
JoystickPosition := count;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> References <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
Title : Flights of Fantasy
|
||||
Author : Christopher Lampton
|
||||
Publishers : The Waite Group
|
||||
ISBN : 1-878739-18-2
|
||||
|
||||
Title : DOS and BIOS Functions Quick Reference
|
||||
Publishers : Que Corporation
|
||||
ISBN : 0-88022-426-6
|
||||
296
study/sabre/os/files/HCI/KeyboardFAQ.txt
Normal file
296
study/sabre/os/files/HCI/KeyboardFAQ.txt
Normal file
@@ -0,0 +1,296 @@
|
||||
The Keyboard Interface Tutorial
|
||||
Preface:
|
||||
|
||||
The Keyboard on the IBM PC and compatible is connected to the PPI -
|
||||
Programmable Peripheral Interface, which generally takes care of Keyboard
|
||||
functions, equipment information and timer functions. The PPI is addressable
|
||||
via port reads and writes, to addresses 060h thru 063h.
|
||||
|
||||
There are several type of keyboards available. The main difference between the
|
||||
various types is the key count. Existing sizez are:
|
||||
|
||||
83 Key (Original PC)
|
||||
84 Key (XT and clones)
|
||||
101 Key (Usually on AT's and up, called Enhanced Keyboard)
|
||||
|
||||
In addition to those standard types, there are numerous non-standard types,
|
||||
which varry from manufacturer to manufacturer. There are 102 Key keyboards,
|
||||
keyboards with two F-Key sets (upper and left), keyboards with weird
|
||||
hardly-used keys like 'Macro' and 'Turbo' (which DO have a scan code, though)
|
||||
etcetera.
|
||||
|
||||
The IBM AT and up provides a better way of negotiating the keyboard, by
|
||||
allowing the user to directly access and command the keyboard, as it will be
|
||||
demonstrated later.
|
||||
|
||||
Using assembly language, there are two major ways to handle the keyboard and
|
||||
keystrokes:
|
||||
|
||||
1. Using DOS functions:
|
||||
|
||||
DOS provides a useful set of functions to use in context with the keyboard.
|
||||
This includes one-key-input and string input.
|
||||
|
||||
2. Using BIOS interrupts:
|
||||
|
||||
The IBM PC BIOS (Basic Input Output System) provides an interrupt to handle
|
||||
the keyboard - Interrupt 016h (022d). These functions, titles KEYBOARD I/O,
|
||||
are an efficient medium level way of using the keyboard
|
||||
|
||||
In addition to the Interrupt 016h interface, there is the Keyboard
|
||||
Interrupt, Interrupt 009h. As opposed to the other interrupt, Interrupt
|
||||
009h is an IRQ - Interrupt Request, which means that it is never called by
|
||||
software. Only hardware, when certain conditions are met, calls IRQ
|
||||
interrupts. Naturally, the user is able to invoke them himself, but that is
|
||||
not commonly done.
|
||||
|
||||
3. Direct port access:
|
||||
|
||||
It is possible to access the keyboard using direct port reads and writes.
|
||||
As mentioned before, this is usually done by addressing the PPI. On AT's
|
||||
and up, however, it is possible to directly access the keyboard itself.
|
||||
|
||||
|
||||
The BIOS also supplies a certain amount of information about the keyboard
|
||||
within it's BDA - BIOS Data Area, aka BDS - BIOS Data Segment - which is the
|
||||
segment that lies at paragraph 040h (0040h:XXXXh or 0000h:04XXh):
|
||||
|
||||
Address Size Contents
|
||||
------- ---- --------
|
||||
0:0412 1 Errors in PCjr InfraRed keyboard link
|
||||
|
||||
0:0417 2 Keyboard status bits. See Keyboard Flags
|
||||
0:0419 1 Current (accumulating) value of Alt+numpad pseudo-key input.
|
||||
Normally 0. When [Alt] is released, value is stored in kbd buf.
|
||||
0:041A 2 Address of keyboard buffer head (keystroke at that addr is next)
|
||||
0:041C 2 Address of keyboard buffer tail
|
||||
0:041E 32 Keyboard buffer. BIOS stores keystrokes here (head and tail
|
||||
point to addresses from 041Eh to 043Dh inclusive).
|
||||
|
||||
0:0480 2 AT PS/2 Keyboard buffer offset start address (usually 01Eh)
|
||||
0:0482 2 end address (usually 03Eh)
|
||||
|
||||
0:0496 1 AT Keyboard flag bit 4=1 (10h) if 101-key keyboard is attached
|
||||
0:0497 1 AT Keyboard flag for LED 'key lock' display
|
||||
bits 0-2 are ScrollLock, NumLock, CapsLock respectively
|
||||
|
||||
******************************************************************************
|
||||
|
||||
Using DOS functions:
|
||||
--------------------
|
||||
|
||||
DOS provides a set of 7 functions to handle the keyboard:
|
||||
|
||||
01h Keyboard Input
|
||||
06h Console I/O
|
||||
07h No Echo Unfiltered Input
|
||||
08h No Echo Filtered Input
|
||||
0Ah Buffered Input
|
||||
0Bh Input Status
|
||||
0Ch Clear Keyboard Buffer & Input
|
||||
|
||||
In addition to these functions, it is also possible to read a selected amount
|
||||
of characters from the keyboard, using DOS's File Handle functions, as the
|
||||
Keyboard, aka Standard Input, has a pre-set handle of 0000h:
|
||||
|
||||
DOS Fn 3Fh: Read from keyboard via Handle
|
||||
------------------------------------------------------------------------------
|
||||
/-----------------------------------------------------------------\
|
||||
| Expects | AH | 3Fh |
|
||||
\---------| BX | 0000h - Handle for Standard Input (Keyboard) |
|
||||
| DS:DX | Address of buffer to receive data |
|
||||
| CX | Number of bytes to read |
|
||||
/---------|-------|-----------------------------------------------|
|
||||
| Returns | AX | Error code if CF is set to CY |
|
||||
\---------| AX | Number of bytes actually read |
|
||||
\-------------------------------------------------------/
|
||||
|
||||
Description: CX bytes of data are read from the keyboard. The data is placed
|
||||
into the caller's buffer pointed to by DS:DX.
|
||||
|
||||
Notes: It is handy to use this function for reading default handles
|
||||
such as the Standard I/O handles, instead of the buffered input
|
||||
or character-by-character input functions.
|
||||
|
||||
When you read from a device, AX returns the length of the line
|
||||
up to and including the termination CR (ASCII 13h).
|
||||
|
||||
******************************************************************************
|
||||
|
||||
Using BIOS Interrupts:
|
||||
----------------------
|
||||
|
||||
As mentioned before, there are two ways to use interrupts to access the
|
||||
keyboard.
|
||||
|
||||
The first is Interrupt 016h - Keyboard I/O.
|
||||
|
||||
INT 16h: Keyboard Services
|
||||
------------------------------------------------------------------------------
|
||||
This is the application-level interface to the keyboard. Keystrokes are
|
||||
actually processed asynchronously in the background. As each keystroke is
|
||||
received from the keyboard, it is processed by INT 09h and placed into a
|
||||
circular queue.
|
||||
|
||||
|
||||
The second is Interrupt 009h - Keyboard Interrupt, IRQ 1
|
||||
|
||||
INT 09h: Keyboard Interrupt
|
||||
------------------------------------------------------------------------------
|
||||
This hardware-generated interrupt (IRQ 1) is executed upon each press and
|
||||
release of a key. The ROM-BIOS code interprets the keystroke, storing values
|
||||
into the keyboard buffer at 40:1Eh. It also handles the special cases of the
|
||||
PrtSc and SysReq keys, and tracks the status of the shift and case-lock keys.
|
||||
|
||||
See: INT 16h .......... BIOS service to access the keys stored in the buffer
|
||||
and obtain status of the certain shift keys.
|
||||
Scan Codes ....... a list of the values of each possible keystroke as
|
||||
it is received by INT 09h.
|
||||
Extended ASCII ... for a summary of the values that BIOS stores into the
|
||||
the keyboard buffer after it translates a scan code.
|
||||
Keyboard Flags ... for a summary of how to obtain, test for, and modify
|
||||
the bit-settings of shift and case-lock flags.
|
||||
|
||||
TSRs (RAM-resident programs) that have a hot-key to trigger a popup usually
|
||||
intercept INT 09h and test for a certain key with a sequence such as this:
|
||||
|
||||
push ax
|
||||
in al,60h ; Read the key
|
||||
cmp al,POP_KEY ; Is this the hot key?
|
||||
je do_pop ; Yes, trigger the popup
|
||||
; No, drop through to original driver
|
||||
pop ax
|
||||
jmp cs:[int9_vect] ; Just hop out to original int handler
|
||||
|
||||
do_pop: ;------ the following housekeeping is needed to satisfy the hdwr int
|
||||
|
||||
in al,61h ; Get value of keyboard control lines
|
||||
mov ah,al ; Save it
|
||||
or al,80h ; Set the "enable kbd" bit
|
||||
out 61h,al ; And write it out the control port
|
||||
xchg ah,al ; Fetch the original control port value
|
||||
out 61h,al ; And write it back
|
||||
|
||||
mov al,20h ; Send End-Of-Interrupt signal
|
||||
out 20h,al ; to the 8259 Interrupt Controller
|
||||
|
||||
;------ other code handles other tests and finally the popup code
|
||||
|
||||
******************************************************************************
|
||||
|
||||
Direct port access:
|
||||
-------------------
|
||||
|
||||
The keyboard is addressable in two manners.
|
||||
|
||||
The first, available on all IBM PCs of all types, is by addressing the PPI -
|
||||
Programmable Peripheral Interface.
|
||||
|
||||
Port Description
|
||||
---- -----------
|
||||
060h PC/XT PPI port A. Read keyboard scan code:
|
||||
|
||||
IN al,60h ; Fetche most recent scan code. See INT 09h and Scan Code
|
||||
|
||||
AT keyboard data register. See AT Keyboard
|
||||
|
||||
061h PC/XT PPI (Programmable Peripheral Interface) port B.
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
| | | | | | | |
|
||||
| | | | | | | \-> 0: Timer 2 gate (speaker) --/--> OR 03h=speaker ON
|
||||
| | | | | | \---> 1: Timer 2 data ---------/ AND 0FCh=speaker OFF
|
||||
| | | | | \-----> 2: Always 0
|
||||
| | | | \-------> 3: 1=Read high switches; 0=read low switches(see 62h)
|
||||
| | | \---------> 4: 0=Enable RAM parity checking; 1=disable
|
||||
| | \-----------> 5: 0=Enable I/O channel check
|
||||
| \-------------> 6: 0=Hold keyboard clock low
|
||||
\---------------> 7: 0=Enable keyboard; 1=disable keyboard
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The second, available only on IBM PC/ATs and up, is by directly commanding the
|
||||
keyboard itself. -= This is for the AT keyboard only. =-
|
||||
|
||||
Port Description
|
||||
---- -----------
|
||||
064h AT keyboard command register. This port communicates with the 8042
|
||||
which runs an on-chip control program for the keyboard. It accepts
|
||||
command codes and data bytes.
|
||||
|
||||
The keyboard of the AT (and its Intel 8042 microcomputer interface) is
|
||||
programmable and a lot more interesting than the old-style PC keyboards.
|
||||
Using the information below, you can set the key repeat speed and play
|
||||
games with the "lock" key LED display.
|
||||
|
||||
Note: This is not a comprehensive coverage of the details of keyboard and
|
||||
8042 operation, but it should provide some food for thought.
|
||||
|
||||
Port 60h is for writing data and is maintained for compatibility with
|
||||
earlier models. If the examples using port 64h don't work, try using 60h.
|
||||
|
||||
Port 64h is for writing commands and data and for reading keyboard status.
|
||||
Before sending a command to the keyboard, the BIOS tests its status
|
||||
(IN al,64h) and makes sure a key isn't being pressed or the internal buffer
|
||||
isn't full, etc. There's a small risk if you just go ahead and send the
|
||||
command:
|
||||
|
||||
mov al,cmd_code
|
||||
out 64h,al
|
||||
|
||||
For a two-part command such as setting the typeamatic rate, it's wise to
|
||||
delay a little while between OUTs:
|
||||
|
||||
mov al,cmd_code
|
||||
out 64h,al
|
||||
mov cx,2000h ;arbitrary <20> 10ms+
|
||||
delay: loop delay
|
||||
mov al,data_value
|
||||
out 64h,al
|
||||
|
||||
Cmd Description
|
||||
--- -----------
|
||||
0FFh Reset the keyboard and start internal diagnostics
|
||||
0FEh Resend the last transmission
|
||||
0FDh-0F7h (NOP)
|
||||
0F6h Set keyboard to defaults and continue scanning
|
||||
0F5h Set keyboard to defaults and disable keyboard scanning
|
||||
0F4h Enable the keyboard. Kybd sends 'ACK', clears buffer, and starts scanning
|
||||
|
||||
0F3h Set typeamatic rate and delay. First send 0F3h, then send data byte:
|
||||
|
||||
-7-6-5-4-3-2-1-0-
|
||||
|0|dly|rept rate|
|
||||
-----------------
|
||||
| | | \---------> bits 0-4 set the repeat rate (see below)
|
||||
| \-------------> bits 5-6 set initial delay before first repeat:
|
||||
| 00=250ms; 01=500ms; 10=750ms; 11=1000ms
|
||||
\---------------> bit 7 is always 0
|
||||
Value Rate Value Rate
|
||||
This chart is a partial guide for the repeat 0 = 30.0 0Ah = 10.0
|
||||
rate (bits 0-4). You can interpolate for 1 = 26.7 0Dh = 9.2
|
||||
values not shown, but let's face it, you're 2 = 24.0 10h = 7.5
|
||||
only interested in the fastest rates. 4 = 20.0 14h = 5.0
|
||||
8 = 15.0 1Fh = 2.0
|
||||
|
||||
The keyboard is initially set to begin repeating after 1/2-second and
|
||||
repeat at a rate of 10 repeats per second. This is much too slow. A
|
||||
data byte of 01h sets the delay to 1/4-second with 26 repeats per second.
|
||||
|
||||
0F2h-0EFh (NOP)
|
||||
0EEh Echo. Diagnostics aid. Simply sends 0EEh right back.
|
||||
|
||||
0EDh Turn LED 'lock key' lights on or off. First send 0EDh, then send byte:
|
||||
|
||||
-7-6-5-4-3-2-1-0-
|
||||
| not used|c|n|s|
|
||||
-----------|-|-|-
|
||||
| | \-> ScrollLock light 01h=turn on
|
||||
| \---> NumLock light 02h=turn on
|
||||
\-----> CapsLock light 04h=turn on
|
||||
|
||||
The bit positions 0-3 correspond to bits 4-6 of the keyboard flags
|
||||
variable in the BIOS Data area. You should make an effort to keep the
|
||||
flags in sync with the lights. For instance, if you do a big favor for
|
||||
the user and set his ten-key pad into NumLock mode (by setting bit 5 of
|
||||
0:0417h) then be sure to turn on the corresponding LED (eg, bit 1).
|
||||
286
study/sabre/os/files/HCI/MOUSE1.TXT
Normal file
286
study/sabre/os/files/HCI/MOUSE1.TXT
Normal file
@@ -0,0 +1,286 @@
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Programming the Microsoft Mouse <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Disclaimer <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
I assume no responsibility whatsoever for any effect that this file, the
|
||||
information contained therein or the use thereof has on you, your sanity,
|
||||
computer, spouse, children, pets or anything else related to you or your
|
||||
existance. No warranty is provided nor implied with this information.
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Introduction <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
A complete list of mouse function calls can be found in the file GMOUSE.TXT,
|
||||
the file contains calls for both Microsoft (2 button) and Genius (3 button)
|
||||
modes.
|
||||
|
||||
Calling these functions from within a Pascal program is a fairly simple
|
||||
matter. This procedure would get the mouse position and button states:
|
||||
|
||||
const MOUSEINTR = $33;
|
||||
|
||||
procedure GetMousePos(var x, y : word; var button1, button2 : boolean);
|
||||
var regs : registers;
|
||||
begin
|
||||
regs.ax := 3;
|
||||
Intr(MOUSEINTR, regs);
|
||||
x := regs.cx;
|
||||
y := regs.dx;
|
||||
button1 := (regs.bx and 1) <> 0;
|
||||
button2 := (regs.bx and 2) <> 0;
|
||||
end;
|
||||
|
||||
|
||||
The mouse position is returned in variables x and y, the button states are
|
||||
returned in variable button1 and button2 (true = button is pressed).
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Writing Custom Handlers <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
Most mouse drivers do not support SVGA modes, so you must write custom
|
||||
handlers if you want mouse support for these modes.
|
||||
|
||||
Rather than writing an entire mouse driver, you can write a simple handler
|
||||
routine to take care of the graphics and tell the mouse driver to call it
|
||||
whenever the mouse does anything. This function is descibed in the GMOUSE.DOC
|
||||
file, but this demo Pascal program shows the general idea. It sets mode 13h,
|
||||
resets the mouse and waits for a key to be pressed. Whenever you do anything
|
||||
to the mouse (moving it or pressing a button) the handler will get called
|
||||
and it will draw a pixel on the screen. The color of the pixel depends on
|
||||
which buttons are being pressed.
|
||||
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
{ called with bl = buttons, cx = x * 2, dx = y }
|
||||
procedure Handler; far; assembler;
|
||||
asm
|
||||
|
||||
{ This mouse "handler" just draws a pixel at the current mouse pos }
|
||||
pusha
|
||||
mov ax, $A000
|
||||
mov es, ax
|
||||
shr cx, 1
|
||||
xchg dh, dl
|
||||
mov di, dx
|
||||
shr dx, 2
|
||||
add di, dx
|
||||
add di, cx
|
||||
mov al, bl
|
||||
inc al
|
||||
stosb
|
||||
popa
|
||||
end;
|
||||
{$F-}
|
||||
|
||||
begin
|
||||
asm
|
||||
|
||||
{ Set graphics mode 13h }
|
||||
mov ax, $13
|
||||
int $10
|
||||
|
||||
{ Initialize mouse driver }
|
||||
xor ax, ax
|
||||
int $33
|
||||
|
||||
{ Install custom handler }
|
||||
mov ax, SEG Handler
|
||||
mov es, ax
|
||||
mov dx, OFS Handler
|
||||
mov ax, 12
|
||||
mov cx, $1F
|
||||
int $33
|
||||
|
||||
{ Wait for a key press }
|
||||
xor ah, ah
|
||||
int $16
|
||||
|
||||
{ Back to text mode }
|
||||
mov ax, 3
|
||||
int $10
|
||||
end;
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
Alternatively you may wish to write your own interrupt handler to process
|
||||
mouse events as they happen. When a mouse event occurs, 3 interrupts are
|
||||
generated and the bytes are availble via the COM port.
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Interrupt Port <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
||||
<20> COM1 $0C $3F8 <20>
|
||||
<20> COM2 $0B $3F8 <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The three bytes sent are formatted as follows:
|
||||
|
||||
|
||||
1st byte 2nd byte 3rd byte
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20>-<2D>1<EFBFBD>?<3F>?<3F>X<EFBFBD>X<EFBFBD>Y<EFBFBD>Y<EFBFBD><59>-<2D>0<EFBFBD>X<EFBFBD>X<EFBFBD>X<EFBFBD>X<EFBFBD>X<EFBFBD>X<EFBFBD><58>-<2D>0<EFBFBD>Y<EFBFBD>Y<EFBFBD>Y<EFBFBD>Y<EFBFBD>Y<EFBFBD>Y<EFBFBD>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<20> <20> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<20> <20> <20> <20> <20> <20>
|
||||
<20> <20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ <20>
|
||||
<20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ <20> <20> <20>
|
||||
<20> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20><> <20> <20> <20> <20> <20> <20> <20> <20>
|
||||
Left Button <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Right Button <20><><EFBFBD><EFBFBD><EFBFBD> X increment Y increment
|
||||
|
||||
|
||||
The X and Y increment values are in 2's compliment signed char format. (BTW
|
||||
thanks go to Adam Seychell for posting this info to comp.os.msdos.programmer).
|
||||
|
||||
|
||||
A simple Borland Pascal 7.0 mouse handler follows. First we declare a few
|
||||
things we'll need:
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
|
||||
const COM1INTR = $0C;
|
||||
COM1PORT = $3F8;
|
||||
|
||||
var bytenum : word;
|
||||
combytes : array[0..2] of byte;
|
||||
x, y : longint;
|
||||
button1, button2 : boolean;
|
||||
MouseHandler : procedure;
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The bytenum variable is used to keep track of which byte is expected next
|
||||
(ie 0, 1 or 2). The combytes variable is simply an array to keep track of
|
||||
bytes received so far. The mouse position will be stored in the x and y
|
||||
varaibles (note that this example will not perfrom any range checking).
|
||||
Button1 and button2 will be used to store the states of each of the buttons.
|
||||
MouseHandler will be used to store the normal mouse driver event handler.
|
||||
We'll need it to reset everything once we are finished.
|
||||
|
||||
Here's the actual handler:
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
procedure MyMouseHandler; Interrupt;
|
||||
var dx, dy : integer;
|
||||
var inbyte : byte;
|
||||
begin
|
||||
|
||||
{ Get the port byte }
|
||||
inbyte := Port[COM1PORT];
|
||||
|
||||
{ Make sure we are properly "synched" }
|
||||
if (inbyte and 64) = 64 then bytenum := 0;
|
||||
|
||||
{ Store the byte and adjust bytenum }
|
||||
combytes[bytenum] := inbyte;
|
||||
inc(bytenum);
|
||||
|
||||
{ Have we received all 3 bytes? }
|
||||
if bytenum = 3 then
|
||||
begin
|
||||
{ Yes, so process them }
|
||||
dx := (combytes[0] and 3) shl 6 + combytes[1];
|
||||
dy := (combytes[0] and 12) shl 4 + combytes[2];
|
||||
if dx >= 128 then dx := dx - 256;
|
||||
if dy >= 128 then dy := dy - 256;
|
||||
x := x + dx;
|
||||
y := y + dy;
|
||||
button1 := (combytes[0] And 32) <> 0;
|
||||
button2 := (combytes[0] And 16) <> 0;
|
||||
|
||||
{ And start on first byte again }
|
||||
bytenum := 0;
|
||||
end;
|
||||
|
||||
{ Acknowledge the interrupt }
|
||||
Port[$20] := $20;
|
||||
end;
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
Once again pretty simple stuff. We just read the byte from the com1 port and
|
||||
figure out if it's time to do anything yet. If bit 6 is set to 1 then we
|
||||
know that it's meant to be the first byte of the 3, so we reset our
|
||||
bytenum variable to zero (in a perfect world bytes would always come in 3's
|
||||
and we would never need to check, but it never hurts to be careful).
|
||||
|
||||
When 3 bytes have been received we simple decode them according to the
|
||||
diagram above and update the appropriate variables accordingly.
|
||||
|
||||
The 'Port[$20] := $20;' command just lets the interrupt controller know we
|
||||
have processed the interrupt so it can send us the next one when it wants to.
|
||||
|
||||
Note that the above "handler" does nothing more than keep track of the
|
||||
current mouse position and button states. If we were writing a proper mouse
|
||||
driver for an SVGA game we would also have to write custom cursor routines.
|
||||
I'll leave that bit to you!
|
||||
|
||||
To actually install our mouse driver we'll have to set up all the variables,
|
||||
save the address of the current mouse handler and install our own. We'll
|
||||
also need call the existing mouse driver to set up the COM1 port to make
|
||||
sure it sends us the mouse bytes as it receives them. We could do this
|
||||
ourselves, but why make life harder than it already is?
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
procedure InitMyDriver;
|
||||
begin
|
||||
|
||||
{ Initialize the normal mouse handler }
|
||||
asm
|
||||
mov ax, 0
|
||||
int $33
|
||||
end;
|
||||
|
||||
{ Initialize some of the variables we'll be using }
|
||||
bytenum := 0;
|
||||
x := 0;
|
||||
y := 0;
|
||||
button1 := false;
|
||||
button2 := false;
|
||||
|
||||
{ Save the current mouse handler and set up our own }
|
||||
GetIntVec(COM1INTR, @MouseHandler);
|
||||
SetIntVec(COM1INTR, Addr(MyMouseHandler));
|
||||
end;
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
And finally when our program is finished it'll need to clean up after
|
||||
itself and return control back to the normal mouse driver:
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
procedure CleanUpMyDriver;
|
||||
begin
|
||||
SetIntVec(COM1INTR, @MouseHandler);
|
||||
end;
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
This little bit of source will test the above code. It does nothing more
|
||||
than repeatedly write the mouse position and button states to the screen
|
||||
until a keyboard key is pressed:
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
begin
|
||||
ClrScr;
|
||||
InitMyDriver;
|
||||
while not keypressed do
|
||||
WriteLn(x : 5, y : 5, button1 : 7, button2 : 7);
|
||||
CleanUpMyDriver;
|
||||
end.
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BIN
study/sabre/os/files/HCI/atarijoy.zip
Normal file
BIN
study/sabre/os/files/HCI/atarijoy.zip
Normal file
Binary file not shown.
1502
study/sabre/os/files/HCI/gmouse.txt
Normal file
1502
study/sabre/os/files/HCI/gmouse.txt
Normal file
File diff suppressed because it is too large
Load Diff
7
study/sabre/os/files/HCI/index.html
Normal file
7
study/sabre/os/files/HCI/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0;url=/Linux.old/sabre/os/articles">
|
||||
</head>
|
||||
<body lang="zh-CN">
|
||||
</body>
|
||||
</html>
|
||||
86
study/sabre/os/files/HCI/joybuttn.txt
Normal file
86
study/sabre/os/files/HCI/joybuttn.txt
Normal file
@@ -0,0 +1,86 @@
|
||||
From: s152226@proffa.cc.tut.fi (Saastamoinen Vesa)
|
||||
Subject: Joystikin salat
|
||||
Newsgroups: sfnet.harrastus.elektroniikka
|
||||
Date: 20 May 1996 18:54:59 GMT
|
||||
Organization: Tampere University of Technology, Computing Centre
|
||||
|
||||
|
||||
Joystick port .-----------------------.
|
||||
\ 8 7 6 5 4 3 2 1 /
|
||||
\ 9 10 11 12 13 14 15 /
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Pin Function Pin Function
|
||||
1 +5v 9 +5v (SB midi)
|
||||
2 Joy A, Button 1 10 Joy B, Button 1 (multibutton 3)
|
||||
3 Joy A, Direction X 11 Joy B, Direction X
|
||||
4 Gnd 12 Gnd (SB midi)
|
||||
5 Gnd 13 Joy B, Direction Y
|
||||
6 Joy A, Direction Y 14 Joy B, Button 2 (multibutton 4)
|
||||
7 Joy A, Button 2 15 +5v
|
||||
8 +5v
|
||||
|
||||
|
||||
Each switch grounds the respective pin. X and Y are wired via 100kohm variable
|
||||
resistor to +5V.
|
||||
Throttle: Joy B, Direction Y
|
||||
Pedals: Joy B, Direction X
|
||||
|
||||
In order to achieve 2 pedals, connect 2 separate 50kohm variables in series.
|
||||
|
||||
50 kohm 50 kohm
|
||||
GND o------|\/\/\/\|---+---|\/\/\/\|------o +5 V
|
||||
/_______|_______/
|
||||
|
|
||||
|
||||
Right up equals 50 kohm,
|
||||
Right down equals 0 kohm,
|
||||
Left up equals 50 kohm,
|
||||
Left down equals 0 kohm,
|
||||
|
||||
|
||||
|
||||
CH Virtualpilot pro and F-16 comp.stick buttons:
|
||||
|
||||
A B C D Function
|
||||
X Button 1
|
||||
X Button 2
|
||||
X Button 3
|
||||
X Button 4
|
||||
X X Button 5
|
||||
X X Button 6
|
||||
X X X X Hat 1 Up
|
||||
X X X Hat 1 Down
|
||||
X X X Hat 1 Right
|
||||
X X Hat 1 Left
|
||||
X X X Hat 2 Up
|
||||
X X Hat 2 Down
|
||||
X X Hat 2 Right
|
||||
X X Hat 2 Left
|
||||
|
||||
Where:
|
||||
A = switch has connection to Pin 2 trough a diode.
|
||||
B = switch has connection to Pin 7 trough a diode.
|
||||
C = switch has connection to Pin 10 trough a diode.
|
||||
D = switch has connection to Pin 14 trough a diode.
|
||||
|
||||
|
||||
Example: ``Hat 1 Left'' is "A" + "B"
|
||||
|
||||
S1 ___ D1
|
||||
GND o------o o--+----|<|----o Pin 2 (Button 1)
|
||||
| D2
|
||||
+----|<|----o Pin 7 (Button 2)
|
||||
|
|
||||
V You can use the above for other "Hat 1" buttons
|
||||
~ as well, by placing a diode here.
|
||||
|
||||
|
||||
Diodes D1,D2: anything you have, e.g. 1N 4002 (for heavy-duty use ;)
|
||||
|
||||
|
||||
[ Ms-Dos 6.22 + OS/2 3.0 = ]
|
||||
[ Vesa Saastamoinen Varoitus: Koneeni on osittain ]
|
||||
[ email s152226@cc.tut.fi Mikrosoftin saastuttama ]
|
||||
|
||||
|
||||
234
study/sabre/os/files/HCI/keyboard.txt
Normal file
234
study/sabre/os/files/HCI/keyboard.txt
Normal file
@@ -0,0 +1,234 @@
|
||||
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
<20> Programming the Keyboard <20>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Disclaimer <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
I assume no responsibility whatsoever for any effect that this file, the
|
||||
information contained therein or the use thereof has on you, your sanity,
|
||||
computer, spouse, children, pets or anything else related to you or your
|
||||
existance. No warranty is provided nor implied with this information.
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Overview <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The operation of the keyboard is really quite simple. Every time a key
|
||||
is pressed or released an interrupt 9 is generated, and reading the value
|
||||
from port 60h tells you what happened.
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Decoding the Keyboard Byte <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
So let's say you've installed an interrupt handler to handle all keyboard
|
||||
events and when an interrupt is generated your handler reads the byte from
|
||||
port 60h. What now?
|
||||
|
||||
Well..each key on the keyboard has an associated scan code which is contained
|
||||
in the lower 7 bits of the byte. The most significant bit (ie bit 7) tells
|
||||
you what was actually done, 0 = key was just pressed, 1 = key was just
|
||||
released. If someone had just pressed the ESC key for instance, the port will
|
||||
show a value of 1 (1 is the ESC key's scan code). If they hold their finger
|
||||
on the button the keyboard will keep generating interrupt 9's and each
|
||||
time the port will still show a value of 1. When the person releases the key
|
||||
a final interrupt will be generated and the port will return 129 (1 + 128,
|
||||
since the high bit will be set indicating the person has released the key).
|
||||
|
||||
Well...it's almost this simple. Some keys are "extended" keys. When an
|
||||
extended key is pressed an interrupt is generated and the keyboard port
|
||||
will return a value of 224 (E0h). This means that an extended key was pressed
|
||||
and it's *extended* scan code will be available during the *next* interrupt.
|
||||
Note that the left control key has a scan code of 29, while the *right*
|
||||
control key has an *extended* scan code of 29. The same applies to the alt
|
||||
keys and the arrow keys (keypad arrows vs the other ones).
|
||||
|
||||
It would be nice if all keys were created equal and we could just throw away
|
||||
the 224 extended bytes and handle all the other bytes normally. Unfortunately
|
||||
there are two buttons which on my machine at least (and others I have tested)
|
||||
do some really weird stuff:
|
||||
|
||||
PrtScn
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Pressing this button will send *2* extended characters to the handler, 42
|
||||
and 55, so the actual byte sequence will be 224, 42, 224, 55. (Also note
|
||||
that the left shift key has a regular scan code of 42, so there goes our
|
||||
idea of just throwing 224's away). Only the extended 55's are sent during
|
||||
auto-repeat. When the key is released, the two are sent again with the high
|
||||
bits set (224, 170, 224, and 183). If any of the shift or control keys are
|
||||
being held down when the PrtScn button is pressed then only the (224, 55) is
|
||||
sent when the key is pressed and only the (224, 183) is sent when it's
|
||||
released. If the alt key is being held down (System Request) then the key
|
||||
behaves like an ordinary key with scan code 84. The practical upshot of all
|
||||
this is that the handlers you write to handle normal keys and extended keys
|
||||
will work fine with all the different PrtScn combinations (although a program
|
||||
would have to check normal key 84 *AND* extended key 55 in order to determine
|
||||
if the key is currently being pressed).
|
||||
|
||||
Pause/Break
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Welcome to hell. If you press this key while either of the the control keys
|
||||
are being held down, it will behave like extended key 70, at all other times
|
||||
it will send the following bytes: (225, 29, 69, 225, 157, 197). Holding the
|
||||
key down does not result in autorepeat. Taking your finger off the key does
|
||||
not send any extra bytes, they appear to be sent after the "key down" bytes
|
||||
when you first press the key. Notice that 225 isn't 224, so our normal
|
||||
extended character handler will not take care of this. My personal theory is
|
||||
that while a scan code of 224 (E0h) means there is 1 more character
|
||||
following, a scan code of 225 (E1h) means there are *2* more following. I've
|
||||
seen a number of keyboard handler libraries and they all seem to overlook
|
||||
this key. So why not be the first kid on your block to have a keyboard
|
||||
handler which properly supports the Pause/Break key? CHECK IT OUT!!
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Writing a Handler <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
Writing a keyboard handler is fairly straightforward. This section will
|
||||
show how to do it in Pascal (you C and asm programmers would probably already
|
||||
know this stuff anyway).
|
||||
|
||||
First we'll declare a few things we'll need:
|
||||
|
||||
const KEYBOARDINTR = 9;
|
||||
KEYBOARDPORT = $60;
|
||||
|
||||
var BIOSKeyboardHandler : procedure;
|
||||
CallBIOSHandler : boolean;
|
||||
|
||||
The CallBIOSHandler variable will be initialised by the calling program. If
|
||||
we also want the BIOS handler to process all keystrokes then this variable
|
||||
must be set to true.
|
||||
|
||||
Next we need to store the value of the current handler and set up own our
|
||||
own one. We'll use a procedure called KeyboardHandler to handle the actual
|
||||
interrupt.
|
||||
|
||||
CallBIOSHandler := false; { ...or set it to true if you want. }
|
||||
GetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);
|
||||
SetIntVec(KEYBOARDINTR, Addr(KeyboardHandler));
|
||||
|
||||
Ok, so everything is now set up and our handler will now be able to process
|
||||
all keyboard events. The actual interrupt handler could look like this:
|
||||
|
||||
{$F+}
|
||||
procedure KeyboardHandler(Flags, CS, IP, AX, BX, CX, DX,
|
||||
SI, DI, DS, ES, BP: Word);
|
||||
interrupt;
|
||||
var key : byte;
|
||||
begin
|
||||
|
||||
key := Port[KEYBOARDPORT];
|
||||
|
||||
{ PROCESS THE KEYSTROKE HERE }
|
||||
|
||||
if CallBIOSHandler then
|
||||
|
||||
{ Call the BIOS keyboard handler if the calling program wants us to }
|
||||
begin
|
||||
asm pushf end;
|
||||
BIOSKeyboardHandler;
|
||||
end
|
||||
|
||||
{ Otherwise just acknowledge the interrupt }
|
||||
else Port[$20] := $20;
|
||||
end;
|
||||
{$F-}
|
||||
|
||||
|
||||
When the program is finished we can set the old keyboard handler again:
|
||||
|
||||
SetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> A Word of Warning <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
When I was writing a simple handler to test the info in this file I did
|
||||
something REALLY stoopid which I would like to share with the world. I
|
||||
thought that my program was stuffing the keyboard up because when I exited
|
||||
the program my editor (Borland Pascal 7.0) would act as though the control
|
||||
button was being held down (I'm sure some of you have already started
|
||||
laughing by now). I had to press it after each time I ran the program
|
||||
just to sort it out. After spending a few hours looking all over the place
|
||||
for info on what could possibly be wrong I realised what I was doing. I was
|
||||
pressing CTRL-F9 to compile the program which would also immediately make it
|
||||
run and I was releasing the control key when my program was running, ie the
|
||||
regular BIOS handler was not getting the control key's "key up" command and
|
||||
still thought it was being held down when my program returned control to
|
||||
it. Moron.....
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD> Scan Codes <20>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The following is a list of all the regular key scan codes in numerical
|
||||
order:
|
||||
|
||||
Scan Scan
|
||||
Code Key Code Key
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1 ESC 44 Z
|
||||
2 1 45 X
|
||||
3 2 46 C
|
||||
4 3 47 V
|
||||
5 4 48 B
|
||||
6 5 49 N
|
||||
7 6 50 M
|
||||
8 7 51 , <
|
||||
9 8 52 . >
|
||||
10 9 53 / ?
|
||||
11 0 54 RIGHT SHIFT
|
||||
12 - _ 55 * (KEYPAD)
|
||||
13 = + 56 LEFT ALT
|
||||
14 BACKSPACE 57 SPACEBAR
|
||||
15 TAB 58 CAPSLOCK
|
||||
16 Q 59 F1
|
||||
17 W 60 F2
|
||||
18 E 61 F3
|
||||
19 R 62 F4
|
||||
20 T 63 F5
|
||||
21 Y 64 F6
|
||||
22 U 65 F7
|
||||
23 I 66 F8
|
||||
24 O 67 F9
|
||||
25 P 68 F10
|
||||
26 [ { 69 NUMLOCK (KEYPAD)
|
||||
27 ] } 70 SCROLL LOCK
|
||||
28 ENTER (RETURN) 71 7 HOME (KEYPAD)
|
||||
29 LEFT CONTROL 72 8 UP (KEYPAD)
|
||||
30 A 73 9 PGUP (KEYPAD)
|
||||
31 S 74 - (KEYPAD)
|
||||
32 D 75 4 LEFT (KEYPAD)
|
||||
33 F 76 5 (KEYPAD)
|
||||
34 G 77 6 RIGHT (KEYPAD)
|
||||
35 H 78 + (KEYPAD)
|
||||
36 J 79 1 END (KEYPAD)
|
||||
37 K 80 2 DOWN (KEYPAD)
|
||||
38 L 81 3 PGDN (KEYPAD)
|
||||
39 ; : 82 0 INSERT (KEYPAD)
|
||||
40 ' " 83 . DEL (KEYPAD)
|
||||
41 ` ~ 87 F11
|
||||
42 LEFT SHIFT 88 F12
|
||||
|
||||
|
||||
The following is a list of all the extended key scan codes in numerical
|
||||
order:
|
||||
|
||||
Scan Scan
|
||||
Code Key Code Key
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
28 ENTER (KEYPAD) 75 LEFT (NOT KEYPAD)
|
||||
29 RIGHT CONTROL 77 RIGHT (NOT KEYPAD)
|
||||
42 PRINT SCREEN (SEE TEXT) 79 END (NOT KEYPAD)
|
||||
53 / (KEYPAD) 80 DOWN (NOT KEYPAD)
|
||||
55 PRINT SCREEN (SEE TEXT) 81 PAGE DOWN (NOT KEYPAD)
|
||||
56 RIGHT ALT 82 INSERT (NOT KEYPAD)
|
||||
71 HOME (NOT KEYPAD) 83 DELETE (NOT KEYPAD)
|
||||
72 UP (NOT KEYPAD) 111 MACRO
|
||||
73 PAGE UP (NOT KEYPAD)
|
||||
|
||||
1308
study/sabre/os/files/HCI/keyboard2.txt
Normal file
1308
study/sabre/os/files/HCI/keyboard2.txt
Normal file
File diff suppressed because it is too large
Load Diff
587
study/sabre/os/files/HCI/mouse.txt
Normal file
587
study/sabre/os/files/HCI/mouse.txt
Normal file
@@ -0,0 +1,587 @@
|
||||
Programming the Microsoft Mouse
|
||||
-------------------------------
|
||||
|
||||
"A Mouse! What A Great Idea!!"
|
||||
|
||||
-W. Disney
|
||||
|
||||
|
||||
Written for the PC-GPE by bri (accbpf@vaxc.hofstra.edu)
|
||||
and Mark Feldman (pcgpe@geocities.com)
|
||||
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
We assume no responsibility whatsoever for any effect that this file, the
|
||||
information contained therein or the use thereof has on you, your sanity,
|
||||
computer, spouse, children, pets or anything else related to you or your
|
||||
existance. No warranty is provided nor implied with this information.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Programming the mouse is one of the easiest tasks you'll ever have to
|
||||
undertake. Mouse drivers hook themselves into interrupt 33h, so you
|
||||
can just call driver-functions the same way you would BIOS functions.
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
The first step is to initialize the mouse driver. You do this by setting
|
||||
the ax register to 0 and calling interrupt 33h. This will return a
|
||||
non-zero number in ax if the driver is installed(which usually means if
|
||||
the mouse is installed. From here on in, anything I say about the mouse
|
||||
actually refers to the driver).
|
||||
|
||||
To display the mouse cursor on the screen, set ax to 1 before calling int 33h.
|
||||
In text-mode you should get what appears to be a block-like text cursor, and
|
||||
in any graphics mode you should get the arrow by default(although we'll see
|
||||
how to change this later). The driver detects what mode you're in and draws
|
||||
the appropriate cursor.
|
||||
|
||||
To hide the mouse cursor, you set the ax register to 2 and call the interrupt.
|
||||
Showing and hiding the mouse cursor is something you'll probably have to do
|
||||
often when you draw images to the screen. Believe you me, having a mouse move
|
||||
across something you're drawing can really wreck you're display. To get around
|
||||
this, hide the mouse cursor, draw what's necessary, and re-display the mouse
|
||||
cursor.
|
||||
|
||||
Please note, mouse drivers often keep a 'display counter' that reads 0
|
||||
if the cursor is displayed and less then 0 if its hidden. Consecutive
|
||||
calls to hide the mouse cursor will decrement the counter and make it
|
||||
more and more negative-in which case it will take more calls to display
|
||||
the mouse cursor to get the counter to 0. Once the counter is 0, calls
|
||||
to display the mouse cursor have no effect on the counter. To read the
|
||||
state of the counter, you can call function 2Ah, and the counter is
|
||||
returned in the ax register. I'll touch on function 2Ah a bit more later.
|
||||
|
||||
Last but not least, we should be able to figure out if any buttons are
|
||||
pressed, if so which ones, and where the mouse is. This is easy, just
|
||||
set ax to 3 and call int 33h-the horizontal coordinate is returned
|
||||
in the cx register, the vertical coordinate in the dx register and
|
||||
bx has the button status. In bx, each bit reads 1 if a corresponding
|
||||
button is pressed-for example bit 0 is 1 if the left button is pressed,
|
||||
bit 1 is 1 if the right button is pressed, and bit 2 is 1 if the
|
||||
center button is pressed.
|
||||
|
||||
As for the coordinates-be careful, as a lot of mouse drivers use a "virtual
|
||||
screen" of 640x200 pixels-which mean if you're screen resolution isn't this-
|
||||
you'll have to do some converting.
|
||||
|
||||
|
||||
SETTING THE CURSOR SHAPE
|
||||
------------------------
|
||||
|
||||
When you use your mouse in a graphics mode, by default, you're stuck
|
||||
with the shape of the mouse cursor as an arrow. This is fine most of the
|
||||
time, but it can get boring after a while. Don't fret!!! You can alter the
|
||||
shape to accomodate your needs!
|
||||
|
||||
The graphics mode cursor image is a 16-by-16 pixel area on the screen
|
||||
that is defined by a 64 byte buffer passed to int 33h, function 9. The first
|
||||
32 bytes contain the cursor mask-the appearance of the cursor on the screen.
|
||||
The second 32 bytes is the screen mask-it defines the appearance of the
|
||||
screen image under the cursor. In this 64 byte buffer, each bit corresponds
|
||||
to 1 pixel, i.e. the first two bytes in both of the masks corresponds to the
|
||||
16 pixels that make up the top row of the cursor.
|
||||
|
||||
When you're designing the cursor mask, each bit is 1 if it is displayed,
|
||||
and 0 if it is not. On the screen mask, bits that are 1 are transparent.
|
||||
|
||||
The mouse driver takes the screen mask, and the cursor mask and shoves
|
||||
them together, coming up with the following:
|
||||
|
||||
|
||||
Screen Mask Bit is Cursor Mask Bit is Resulting Screen Bit is
|
||||
------------------ ------------------ -----------------------
|
||||
0 0 0
|
||||
0 1 1
|
||||
1 0 Bit is Not Changed
|
||||
1 1 Bit is Inverted
|
||||
|
||||
To set the shape you call Function 9h with ES holding the segment of your
|
||||
buffer containing the masks, and DX containing the offset of the buffer
|
||||
containing the cursor mask.
|
||||
|
||||
One other important thing to note: your cursor has a hot spot=the point
|
||||
on your mouse cursor that is where the cursor is actually pointing.
|
||||
Usually this is 1, 1(that is 1 pixel from the top of the cursor and
|
||||
1 from the right). But when you change the image of your mouse cursor
|
||||
you might need to change the hot spot. You can do this by setting CX
|
||||
and DX of Function 9 to the horizontal and vertical offset of the hot
|
||||
spot.
|
||||
|
||||
ODDS AND ENDS
|
||||
-------------
|
||||
|
||||
Well, there are a few odds and ends here that you might find useful.
|
||||
|
||||
You can set limits on where you want to allow the mouse cursor to roam.
|
||||
Function 7 & 8(AX= 7 & AX = 8) set the horizontal and vertical limits
|
||||
of the mouse cursor respectively. In both cases you input cx as the minimum
|
||||
coordinate in pixels, and dx as the maximum coordinate in pixels.
|
||||
|
||||
You can take the mouse and move it to a certain position on the screen
|
||||
from inside your program. That's function 4(ax=4). You specify the
|
||||
horizontal coordinate in CX, and the vertical coordinate in DX. If you
|
||||
specify a coordinate outside a range you've set using functions 7 & 8,
|
||||
the mouse driver will most likely put the cursor at the very edge of
|
||||
that boundary.
|
||||
|
||||
Lastly, you can set the amount of distance you're actual mouse moves
|
||||
to get the cursor on the screen to move. Mouse movement is measured
|
||||
in mickeys(I'm not joking here!) where each mickey is approximately
|
||||
1/200 of an inch. To adjust this use function 0Fh. CX should contain
|
||||
the number of horizontal mickeys, and dx the number of vertical ones.
|
||||
The numbers in CX and DX actually refer to the amount of mickeys needed
|
||||
to move the mouse cursor a total of 8 pixels. By default, CX is 8, while
|
||||
DX is 16. You can set a range of 1(hyper-active energetic mouse) to
|
||||
32,767(unbelievably sluggish and lazy).
|
||||
|
||||
|
||||
SLAM DUNKS AND LOW CEILINGS
|
||||
----------------------------
|
||||
(With special thanks to Feldman the Great for this section)
|
||||
|
||||
Yes, like the subject header, something else that has never mixed very well
|
||||
together was mouse and SVGA programming. The reason, of course is that your
|
||||
mouse driver is what takes care of the updating of the image of the mouse
|
||||
cursor in graphics mode.
|
||||
|
||||
You see, in the beginning, SVGA was created. This was widely regarded
|
||||
as a bad idea.
|
||||
|
||||
Sure it looked cool, and there were more pretty colors than you could shake
|
||||
a kaleidoscope at, but there was no standard. (This was before VESA, and sadly
|
||||
even today many mouse drivers don't use VESA) This left all SVGA chip
|
||||
makers to deviously make chips however they wanted, depending on what
|
||||
kind of mood they were in, and what they had had for lunch. As most
|
||||
SVGA chip designers rarely ate the same thing at lunchtime, you wound up
|
||||
with a googleplex full of SVGA cards that all were 110% incompatible
|
||||
with each other.
|
||||
|
||||
Remember what I said about your mouse driver handling your mouse cursor.
|
||||
Now mouse drivers had to know how to handle every single SVGA card, so
|
||||
they could draw the cursors correctly in SVGA mode. Mouse driver
|
||||
maufacturers got around this problem in a rather novel way: they ignored
|
||||
SVGA.
|
||||
|
||||
Because of this, most mouse drivers throw up their hands in disgust when
|
||||
confronted with the ugly head of SVGA and simply provide you with no mouse
|
||||
cursor at all. Likewise, if you're programming for Mode X, you're likely to
|
||||
run into the same trouble. You CAN get around this, however. How? you ask
|
||||
with baited breath. Simply install your own mouse handler(I'm using the word
|
||||
'simply' rather loosely here). What this will do, is cause the mouse driver
|
||||
to call one of your functions-and then you're responsible for updating the
|
||||
graphics cursor image on the screen.
|
||||
|
||||
Basically, you call Function 0Ch. CX contains the event mask: on what
|
||||
conditions the mouse driver will call your function. The mask is listed
|
||||
below:
|
||||
Bit If set
|
||||
0 Mouse Cursor Movement
|
||||
1 Left Button Pressed
|
||||
2 Left Button Released
|
||||
3 Right Button Pressed
|
||||
4 Right Button Released
|
||||
5 Center Button Pressed
|
||||
6 Center Button Released
|
||||
|
||||
The ES register holds the segment of your mouse code that the driver
|
||||
should call, and DX holds the offset. (As an aside, I'd recommend
|
||||
doing the mouse handler itself in assembly, as getting it to work
|
||||
in C or Pascal is an uphill struggle at best).
|
||||
|
||||
When the mouse driver calls your function, AX will contain the event
|
||||
flag that you set earlier. BX will contain the button status: 0 if
|
||||
the left button is pressed, 1 if the right button is pressed, and 2
|
||||
if the center button is pressed. CX and DX contain the horizontal and
|
||||
vertical position of the mouse cursor respectively.
|
||||
|
||||
To disable an installed handler, simply call function 0Ch with an
|
||||
event mask of 0, or call Function 0h.
|
||||
|
||||
Well that about wraps it up...if you have any questions at all,
|
||||
please feel free to contact me (bri) at accbpf@vaxc.hofstra.edu and I'll
|
||||
do my best to answer them.
|
||||
|
||||
Quick Reference Guide to Interrupt 33h
|
||||
--------------------------------------
|
||||
|
||||
FUNCTION: AX = 0h
|
||||
Description: Determines whether a mouse is available and if it is
|
||||
initializes the mouse driver.
|
||||
Returns : AX = Non-Zero (If Mouse is installed, 0 if not)
|
||||
BX = Number of Mouse Buttons
|
||||
FUNCTION: AX = 1h
|
||||
Description: Increments the mouse cursor display counter.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 2h
|
||||
Description: Decrements the mouse cursor display counter.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 3h
|
||||
Description: Returns the current mouse position and button status.
|
||||
Returns : BX = Buttons status:
|
||||
Bit 0: Left Button
|
||||
Bit 1: Right Button
|
||||
Bit 2: Center Button
|
||||
CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
|
||||
FUNCTION: AX = 4h
|
||||
Description: Moves the mouse cursor to a certain position on the screen.
|
||||
Call With : CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 5h
|
||||
Description: Reports on the status and numbers of presses for a
|
||||
button.
|
||||
Call with : BX = Button to Check
|
||||
0 = Left Button
|
||||
1 = Right Button
|
||||
2 = Center Button
|
||||
Returns : AX = Button Status
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
BX = Button Press Counter
|
||||
CX = Horizontal Coordinate of Last Button Press
|
||||
DX = Vertical Coordinate of Last Button Press
|
||||
|
||||
FUNCTION: AX = 6h
|
||||
Description: Gets the button release information.
|
||||
Call With : BX = Button to Query
|
||||
0 = Left Button
|
||||
1 = Right Button
|
||||
2 = Center Button
|
||||
Returns : AX = Button Status(1 if pressed)
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
BX = Button Release counter
|
||||
CX = Horizontal Coordinate of last button release
|
||||
DX = Vertical Coordinate of last button release
|
||||
|
||||
FUNCTION: AX = 7h
|
||||
Description: Sets the horizontal limits for the mouse cursor.
|
||||
Calls With : CX = Minimum horizontal mouse coordinate.
|
||||
DX = Maximum horizontal mouse coordinate.
|
||||
|
||||
FUNCTION: AX = 8h
|
||||
Description: Sets the vertical limits for the mouse cursor.
|
||||
Call With : CX = Minimum vertical mouse coordinate.
|
||||
DX = Maximum vertical mouse coordinate.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 9h
|
||||
Description: Defines the shape of the graphics mode cursor.
|
||||
Call With : BX = Hoorizontal hot spot offset
|
||||
CX = Vertical hot spot offset
|
||||
ES = Segment of buffer containing cursor mask
|
||||
DX = Offset of buffer containing cusror mask
|
||||
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 0Ah
|
||||
Description: Definesthe shape of the text mode cursor
|
||||
Call With : BX = Cursor Type
|
||||
0 = Software Cursor
|
||||
1 = Hardware cursor
|
||||
if BX = 0 then
|
||||
CX = Screen Mask value
|
||||
DX = Cursor Mask Value
|
||||
else
|
||||
CX = Starting Scan Line For Cursor
|
||||
DX = Ending Scan Line For Cursor
|
||||
|
||||
FUNCTION: AX = 0Bh
|
||||
Description: Returns the net mouse movement since the last call
|
||||
to this function(or since the mouse was initialized).
|
||||
Returns : CX = Horizontal mouse movement(in Mickeys)
|
||||
DX = Vertical mouse movement(in Mickeys)
|
||||
|
||||
FUNCTION: AX = 0Ch
|
||||
Description: Sets the user defined mouse handler.
|
||||
Call With : CX = Event Mask
|
||||
|
||||
Bit If set
|
||||
0 Mouse Cursor Movement
|
||||
1 Left Button Pressed
|
||||
2 Left Button Released
|
||||
3 Right Button Pressed
|
||||
4 Right Button Released
|
||||
5 Center Button Pressed
|
||||
6 Center Button Released
|
||||
|
||||
ES = Segment of your mouse handler code
|
||||
DX = Offset of your mouse handler code
|
||||
Returns : AX = Event Mask
|
||||
BX = Button Status(1 if pressed)
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
|
||||
FUNCTION: AX = 2Ah
|
||||
Description: Returns display counter state, and current hot spot
|
||||
Returns : BX = Horizontal offset of hot spot
|
||||
CX = Vertical offset of hot spot
|
||||
|
||||
|
||||
|
||||
A complete list of mouse function calls can be found in the file GMOUSE.TXT,
|
||||
the file contains calls for both Microsoft (2 button) and Genius (3 button)
|
||||
modes.
|
||||
|
||||
Writing Custom Handlers
|
||||
-----------------------
|
||||
|
||||
Most mouse drivers do not support SVGA modes, so you must write custom
|
||||
handlers if you want mouse support for these modes.
|
||||
|
||||
Rather than writing an entire mouse driver, you can write a simple handler
|
||||
routine to take care of the graphics and tell the mouse driver to call it
|
||||
whenever the mouse does anything. This function is descibed in the GMOUSE.DOC
|
||||
file, but this demo Pascal program shows the general idea. It sets mode 13h,
|
||||
resets the mouse and waits for a key to be pressed. Whenever you do anything
|
||||
to the mouse (moving it or pressing a button) the handler will get called
|
||||
and it will draw a pixel on the screen. The color of the pixel depends on
|
||||
which buttons are being pressed.
|
||||
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
{ called with bl = buttons, cx = x * 2, dx = y }
|
||||
procedure Handler; far; assembler;
|
||||
asm
|
||||
|
||||
{ This mouse "handler" just draws a pixel at the current mouse pos }
|
||||
pusha
|
||||
push es ; pusha doesn't save es
|
||||
mov ax, $A000
|
||||
mov es, ax
|
||||
shr cx, 1
|
||||
xchg dh, dl
|
||||
mov di, dx
|
||||
shr dx, 2
|
||||
add di, dx
|
||||
add di, cx
|
||||
mov al, bl
|
||||
inc al
|
||||
stosb
|
||||
pop es
|
||||
popa
|
||||
end;
|
||||
{$F-}
|
||||
|
||||
begin
|
||||
asm
|
||||
|
||||
{ Set graphics mode 13h }
|
||||
mov ax, $13
|
||||
int $10
|
||||
|
||||
{ Initialize mouse driver }
|
||||
xor ax, ax
|
||||
int $33
|
||||
|
||||
{ Install custom handler }
|
||||
mov ax, SEG Handler
|
||||
mov es, ax
|
||||
mov dx, OFS Handler
|
||||
mov ax, 12
|
||||
mov cx, $1F
|
||||
int $33
|
||||
|
||||
{ Wait for a key press }
|
||||
xor ah, ah
|
||||
int $16
|
||||
|
||||
{ Back to text mode }
|
||||
mov ax, 3
|
||||
int $10
|
||||
end;
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
Alternatively you may wish to write your own interrupt handler to process
|
||||
mouse events as they happen. When a mouse event occurs, 3 interrupts are
|
||||
generated and the bytes are available via the COM port.
|
||||
|
||||
----------------------------
|
||||
| Interrupt Port |
|
||||
----------------------------
|
||||
| COM1 $0C $3F8 |
|
||||
| COM2 $0B $3F8 |
|
||||
----------------------------
|
||||
|
||||
The three bytes sent are formatted as follows:
|
||||
|
||||
|
||||
1st byte 2nd byte 3rd byte
|
||||
----------------- --------------- ---------------
|
||||
|-|1|?|?|X|X|Y|Y| - |0|X|X|X|X|X|X| |0|Y|Y|Y|Y|Y|Y|
|
||||
----------------- --------------- ---------------
|
||||
| | \ / \ / | |
|
||||
| | | | | |
|
||||
| | | ------------- ---------- |
|
||||
| | ---------- | \ \ |
|
||||
| | \_\_ _ _ _ _ _ _ \_\_ _ _ _ _ _ _
|
||||
| | |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_|
|
||||
| | X increment Y increment
|
||||
Left Button -- |
|
||||
Right Button ----
|
||||
|
||||
|
||||
The X and Y increment values are in 2's compliment signed char format. (BTW
|
||||
thanks go to Adam Seychell for posting this info to comp.os.msdos.programmer).
|
||||
|
||||
|
||||
A simple Borland Pascal 7.0 mouse handler follows. First we declare a few
|
||||
things we'll need:
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
|
||||
const COM1INTR = $0C;
|
||||
COM1PORT = $3F8;
|
||||
|
||||
var bytenum : word;
|
||||
combytes : array[0..2] of byte;
|
||||
x, y : longint;
|
||||
button1, button2 : boolean;
|
||||
MouseHandler : procedure;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The bytenum variable is used to keep track of which byte is expected next
|
||||
(ie 0, 1 or 2). The combytes variable is simply an array to keep track of
|
||||
bytes received so far. The mouse position will be stored in the x and y
|
||||
variables (note that this example will not perfrom any range checking).
|
||||
button1 and button2 will be used to store the states of each of the buttons.
|
||||
MouseHandler will be used to store the normal mouse driver event handler.
|
||||
We'll also need it to reset everything once we are finished.
|
||||
|
||||
Here's the actual handler:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure MyMouseHandler; Interrupt;
|
||||
var dx, dy : integer;
|
||||
var inbyte : byte;
|
||||
begin
|
||||
|
||||
{ Get the port byte }
|
||||
inbyte := Port[COM1PORT];
|
||||
|
||||
{ Make sure we are properly "synched" }
|
||||
if (inbyte and 64) = 64 then bytenum := 0;
|
||||
|
||||
{ Store the byte and adjust bytenum }
|
||||
combytes[bytenum] := inbyte;
|
||||
inc(bytenum);
|
||||
|
||||
{ Have we received all 3 bytes? }
|
||||
if bytenum = 3 then
|
||||
begin
|
||||
|
||||
{ Yes, so process them }
|
||||
dx := (combytes[0] and 3) shl 6 + combytes[1];
|
||||
dy := (combytes[0] and 12) shl 4 + combytes[2];
|
||||
if dx >= 128 then dx := dx - 256;
|
||||
if dy >= 128 then dy := dy - 256;
|
||||
x := x + dx;
|
||||
y := y + dy;
|
||||
button1 := (combytes[0] And 32) <> 0;
|
||||
button2 := (combytes[0] And 16) <> 0;
|
||||
|
||||
{ And start on first byte again }
|
||||
bytenum := 0;
|
||||
end;
|
||||
|
||||
{ Acknowledge the interrupt }
|
||||
Port[$20] := $20;
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Once again pretty simple stuff. We just read the byte from the com1 port and
|
||||
figure out if it's time to do anything yet. If bit 6 is set to 1 then we
|
||||
know that it's meant to be the first byte of the 3, so we reset our
|
||||
bytenum variable to zero (in a perfect world bytes would always come in 3's
|
||||
and we would never need to check, but it never hurts to be careful).
|
||||
|
||||
When 3 bytes have been received we simple decode them according to the
|
||||
diagram above and update the appropriate variables accordingly.
|
||||
|
||||
The 'Port[$20] := $20;' command just lets the interrupt controller know we
|
||||
have processed the interrupt so it can send us the next one when it wants to.
|
||||
|
||||
Note that the above "handler" does nothing more than keep track of the
|
||||
current mouse position and button states. If we were writing a proper mouse
|
||||
driver for an SVGA game we would also have to write custom cursor routines.
|
||||
I'll leave that bit to you!
|
||||
|
||||
To actually install our mouse driver we'll have to set up all the variables,
|
||||
save the address of the current mouse handler and install our own. We'll
|
||||
also need call the existing mouse driver to set up the COM1 port to make
|
||||
sure it sends us the mouse bytes as it receives them. We could do this
|
||||
ourselves, but why make life harder than it already is?
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure InitMyDriver;
|
||||
begin
|
||||
|
||||
{ Initialize the normal mouse handler }
|
||||
asm
|
||||
mov ax, 0
|
||||
int $33
|
||||
end;
|
||||
|
||||
{ Initialize some of the variables we'll be using }
|
||||
bytenum := 0;
|
||||
x := 0;
|
||||
y := 0;
|
||||
button1 := false;
|
||||
button2 := false;
|
||||
|
||||
{ Save the current mouse handler and set up our own }
|
||||
GetIntVec(COM1INTR, @MouseHandler);
|
||||
SetIntVec(COM1INTR, Addr(MyMouseHandler));
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
And finally when our program is finished it'll need to clean up after
|
||||
itself and return control back to the normal mouse driver:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure CleanUpMyDriver;
|
||||
begin
|
||||
SetIntVec(COM1INTR, @MouseHandler);
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
This little bit of source will test the above code. It does nothing more
|
||||
than repeatedly write the mouse position and button states to the screen
|
||||
until a keyboard key is pressed:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
begin
|
||||
ClrScr;
|
||||
InitMyDriver;
|
||||
while not keypressed do
|
||||
WriteLn(x : 5, y : 5, button1 : 7, button2 : 7);
|
||||
CleanUpMyDriver;
|
||||
end.
|
||||
----------------------------------------------------------------------
|
||||
|
||||
81
study/sabre/os/files/HCI/mouse_hw.txt
Normal file
81
study/sabre/os/files/HCI/mouse_hw.txt
Normal file
@@ -0,0 +1,81 @@
|
||||
From: Tomi Engdahl <then@snakemail.hut.fi>
|
||||
Date: Fri, 29 Apr 1994 13:28:37 +0200 (EET DST)
|
||||
|
||||
Serial mouse
|
||||
|
||||
Voltage levels:
|
||||
Mouse takes standard RS-232C output signals (+-12V) as its input signals.
|
||||
Those outputs are in +12V when mouse is operated. Mouse takes some current
|
||||
>from each of the RS-232C port output lines it is connected (about 10mA).
|
||||
Mouse send data to computer in levels that RS-232C receiver chip in the
|
||||
computer can uderstand as RS-232C input levels. Mouse outputs are normally
|
||||
something like +-5V, 0..5V or sometimes +-12V. Mouse electronics
|
||||
normally use +5V voltage.
|
||||
|
||||
|
||||
Microsoft serial mouse
|
||||
|
||||
Pins used:
|
||||
TD, RTS and DTR are used only as power source for the mouse.
|
||||
RD is used to receive data from mouse.
|
||||
|
||||
Serial data parameters: 1200bps, 7 databits, 1 stop-bit
|
||||
|
||||
Data packet format:
|
||||
Data packet is 3 byte packet. It is send to the computer every time
|
||||
mouse state changes (mouse moves or keys are pressed/released).
|
||||
|
||||
D7 D6 D5 D4 D3 D2 D1 D0
|
||||
|
||||
1. X 1 LB RB Y7 Y6 X7 X6
|
||||
2. X 0 X5 X4 X3 X2 X1 X0
|
||||
3. X 0 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
|
||||
The byte marked with 1. is send first, then the others. The bit D6
|
||||
in the first byte is used for syncronizing the software to mouse
|
||||
packets if it goes out of sync.
|
||||
|
||||
LB is the state of the left button (0 means pressed down)
|
||||
RB is the state of the right button (0 means pressed down)
|
||||
X7-X0 movement in X direction since last packet (signed byte)
|
||||
Y7-Y0 movement in Y direction since last packet (signed byte)
|
||||
|
||||
|
||||
Mouse systems mouse
|
||||
|
||||
Serial data parameters: 1200bps, 8 databits, 1 stop-bit
|
||||
|
||||
The data is sent in 5 byte packets in following format:
|
||||
|
||||
D7 D6 D5 D4 D3 D2 D1 D0
|
||||
|
||||
1. 1 0 0 0 0 LB CB RB
|
||||
2. X7 X6 X5 X4 X3 X2 X1 X0
|
||||
3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0
|
||||
4.
|
||||
5.
|
||||
|
||||
LB is left button state (0=pressed, 1=released)
|
||||
CB is center button state (0=pressed, 1=released)
|
||||
RB is right button state (0=pressed, 1=released)
|
||||
X7-X0 movement in X direction since last packet in signed byte
|
||||
format (-128..+127), positive direction right
|
||||
Y7-Y0 movement in Y direction since last packet in signed byte
|
||||
format (-128..+127), positive direction up
|
||||
|
||||
The last two bytes in the packet (bytes 4 and 5) contains
|
||||
information about movement data send in last packet. I have not
|
||||
found exact information about those bytes. I have not also found
|
||||
any use for such a information (maybe it is for syncronization
|
||||
or something like that).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--
|
||||
Tomi.Engdahl@hut.fi Helsinki University of Technology
|
||||
G=Tomi S=Engdahl O=hut ADMD=fumail C=fi Department of Computer Science
|
||||
# This text is provided "as is" without any express or implied warranty #
|
||||
|
||||
|
||||
29
study/sabre/os/files/HCI/two_mice.txt
Normal file
29
study/sabre/os/files/HCI/two_mice.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
From: Lennart Steinke <steinke@zeus.adv-boeblingen.de>
|
||||
Subject: Two mice, one pc
|
||||
Newsgroups: rec.games.programmer
|
||||
Date: Thu, 18 Jul 1996 10:14:53 -0500
|
||||
|
||||
Hi!
|
||||
|
||||
Sometime ago, I tried to use two mice at the
|
||||
the same PC. It worked, and I used it for a
|
||||
tron game, and a simple Air Hockey simulation
|
||||
(two player only).
|
||||
|
||||
Here's what I've done to use those two mice:
|
||||
0) Install mouse handler (com1)
|
||||
1) Save the address of the current hander
|
||||
2) Point the irq to "no handler installed"
|
||||
3) Install a mouse handler for com2
|
||||
4) Save it's address
|
||||
|
||||
To get the mouseinformation, just swap the
|
||||
isr addresses, then use the standard mouse
|
||||
functions.
|
||||
|
||||
Lenny
|
||||
--
|
||||
Lennart Steinke (steinke@adv-boeblingen.de)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user