1 /////////////////////////////////////////////////////////////////////////
2 // $Id: gameport.cc,v 1.16 2008/07/26 08:02:27 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2003 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // Standard PC gameport
31 // Define BX_PLUGGABLE in files that can be compiled into plugins. For
32 // platforms that require a special tag on exported symbols, BX_PLUGGABLE
33 // is used to know when we are exporting symbols and when we are importing.
40 #include <linux/joystick.h>
41 #include <sys/types.h>
51 UINT STDCALL
joyGetPos(UINT
, LPJOYINFO
);
58 #define LOG_THIS theGameport->
60 bx_gameport_c
*theGameport
= NULL
;
62 int libgameport_LTX_plugin_init(plugin_t
*plugin
, plugintype_t type
, int argc
, char *argv
[])
64 theGameport
= new bx_gameport_c();
65 BX_REGISTER_DEVICE_DEVMODEL(plugin
, type
, theGameport
, BX_PLUGIN_GAMEPORT
);
69 void libgameport_LTX_plugin_fini(void)
74 bx_gameport_c::bx_gameport_c()
81 bx_gameport_c::~bx_gameport_c()
83 if (joyfd
>= 0) close(joyfd
);
87 void bx_gameport_c::init(void)
89 // Allocate the gameport IO address range 0x200..0x207
90 for (unsigned addr
=0x200; addr
<0x208; addr
++) {
91 DEV_register_ioread_handler(this, read_handler
, addr
, "Gameport", 1);
92 DEV_register_iowrite_handler(this, write_handler
, addr
, "Gameport", 1);
95 BX_GAMEPORT_THIS port
= 0xf0;
96 BX_GAMEPORT_THIS write_usec
= 0;
97 BX_GAMEPORT_THIS timer_x
= 0;
98 BX_GAMEPORT_THIS timer_y
= 0;
101 BX_GAMEPORT_THIS joyfd
= open("/dev/input/js0", O_RDONLY
);
102 if (BX_GAMEPORT_THIS joyfd
>= 0) {
103 for (unsigned i
=0; i
<4; i
++) poll_joydev();
107 if (joyGetPos(JOYSTICKID1
, &joypos
) == JOYERR_NOERROR
) {
108 BX_GAMEPORT_THIS joyfd
= 1;
110 BX_GAMEPORT_THIS joyfd
= -1;
113 BX_GAMEPORT_THIS joyfd
= -1;
117 void bx_gameport_c::reset(unsigned type
)
122 void bx_gameport_c::register_state(void)
124 bx_list_c
*list
= new bx_list_c(SIM
->get_bochs_root(), "gameport", "Gameport State", 6);
125 BXRS_HEX_PARAM_FIELD(list
, port
, BX_GAMEPORT_THIS port
);
126 BXRS_DEC_PARAM_FIELD(list
, delay_x
, BX_GAMEPORT_THIS delay_x
);
127 BXRS_DEC_PARAM_FIELD(list
, delay_y
, BX_GAMEPORT_THIS delay_y
);
128 BXRS_PARAM_BOOL(list
, timer_x
, BX_GAMEPORT_THIS timer_x
);
129 BXRS_PARAM_BOOL(list
, timer_y
, BX_GAMEPORT_THIS timer_y
);
130 BXRS_DEC_PARAM_FIELD(list
, write_usec
, BX_GAMEPORT_THIS write_usec
);
133 void bx_gameport_c::poll_joydev(void)
140 memset(&tv
, 0, sizeof(tv
));
142 FD_SET(BX_GAMEPORT_THIS joyfd
, &joyfds
);
144 if (select(BX_GAMEPORT_THIS joyfd
+1, &joyfds
, NULL
, NULL
, &tv
)) {
145 read(BX_GAMEPORT_THIS joyfd
, &e
, sizeof(struct js_event
));
146 if (e
.type
& JS_EVENT_BUTTON
) {
148 BX_GAMEPORT_THIS port
&= ~(0x10 << e
.number
);
150 BX_GAMEPORT_THIS port
|= (0x10 << e
.number
);
153 if (e
.type
& JS_EVENT_AXIS
) {
155 BX_GAMEPORT_THIS delay_x
= 25 + ((e
.value
+ 0x8000) / 60);
158 BX_GAMEPORT_THIS delay_y
= 25 + ((e
.value
+ 0x8000) / 62);
164 if (joyGetPos(JOYSTICKID1
, &joypos
) == JOYERR_NOERROR
) {
165 if (joypos
.wButtons
& JOY_BUTTON1
) {
166 BX_GAMEPORT_THIS port
&= ~0x10;
168 BX_GAMEPORT_THIS port
|= 0x10;
170 if (joypos
.wButtons
& JOY_BUTTON2
) {
171 BX_GAMEPORT_THIS port
&= ~0x20;
173 BX_GAMEPORT_THIS port
|= 0x20;
175 BX_GAMEPORT_THIS delay_x
= 25 + (joypos
.wXpos
/ 60);
176 BX_GAMEPORT_THIS delay_y
= 25 + (joypos
.wYpos
/ 60);
181 // static IO port read callback handler
182 // redirects to non-static class handler to avoid virtual functions
184 Bit32u
bx_gameport_c::read_handler(void *this_ptr
, Bit32u address
, unsigned io_len
)
186 #if !BX_USE_GAMEPORT_SMF
187 bx_gameport_c
*class_ptr
= (bx_gameport_c
*) this_ptr
;
188 return class_ptr
->read(address
, io_len
);
191 Bit32u
bx_gameport_c::read(Bit32u address
, unsigned io_len
)
195 #endif // !BX_USE_GAMEPORT_SMF
198 if (BX_GAMEPORT_THIS joyfd
>= 0) {
200 usec
= bx_pc_system
.time_usec();
201 if (BX_GAMEPORT_THIS timer_x
) {
202 if ((usec
- BX_GAMEPORT_THIS write_usec
) >= BX_GAMEPORT_THIS delay_x
) {
203 BX_GAMEPORT_THIS port
&= 0xfe;
204 BX_GAMEPORT_THIS timer_x
= 0;
207 if (BX_GAMEPORT_THIS timer_y
) {
208 if ((usec
- BX_GAMEPORT_THIS write_usec
) >= BX_GAMEPORT_THIS delay_y
) {
209 BX_GAMEPORT_THIS port
&= 0xfd;
210 BX_GAMEPORT_THIS timer_y
= 0;
214 BX_DEBUG(("read: joystick not present"));
216 return BX_GAMEPORT_THIS port
;
220 // static IO port write callback handler
221 // redirects to non-static class handler to avoid virtual functions
223 void bx_gameport_c::write_handler(void *this_ptr
, Bit32u address
, Bit32u value
, unsigned io_len
)
225 #if !BX_USE_GAMEPORT_SMF
226 bx_gameport_c
*class_ptr
= (bx_gameport_c
*) this_ptr
;
227 class_ptr
->write(address
, value
, io_len
);
230 void bx_gameport_c::write(Bit32u address
, Bit32u value
, unsigned io_len
)
234 #endif // !BX_USE_GAMEPORT_SMF
236 BX_GAMEPORT_THIS write_usec
= bx_pc_system
.time_usec();
237 BX_GAMEPORT_THIS timer_x
= 1;
238 BX_GAMEPORT_THIS timer_y
= 1;
239 BX_GAMEPORT_THIS port
|= 0x0f;