]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/joy2.asm
remove rcs tags
[btb/d2x.git] / arch / dos / joy2.asm
1 ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
2 ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
3 ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
4 ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
5 ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
6 ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
7 ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
8 ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
9 ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
10 ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
11 ;
12 ;
13 ; Contains routines for joystick interface.
14 ;
15
16 [BITS 32]
17
18 [SECTION .data]
19
20         LastTick        dd      0
21         TotalTicks      dd      0
22
23         global  _joy_bogus_reading
24         global  _joy_retries
25         extern _JOY_PORT
26         _joy_bogus_reading      dd      0
27         _joy_retries            dd      0
28         RetryCount              dd      0
29
30         
31 [SECTION .text]
32
33 ;        JOY_PORT        EQU     0209h
34         TDATA           EQU     40h
35         TCOMMAND        EQU     43h
36
37 joy_get_timer:
38         xor     al, al                  ; Latch timer 0 command
39         out     TCOMMAND, al            ; Latch timer
40         in      al, TDATA               ; Read lo byte
41         mov     ah, al
42         in      al, TDATA               ; Read hi byte
43         xchg    ah, al
44         and     eax, 0ffffh
45         ret     
46
47
48
49
50 global _joy_read_stick_friendly2
51 _joy_read_stick_friendly2:
52                 push    ebx
53                 push    edi
54
55                 mov     ebx,[esp+12]
56                 mov     edi,[esp+16]
57                 mov     ecx,[esp+20]
58
59                 ; ebx = read mask
60                 ; edi = pointer to event buffer
61                 ; ecx = timeout value
62                 ; returns in eax the number of events
63
64                 mov     dword [RetryCount], 0
65                 mov     dword [_joy_bogus_reading], 0
66
67 _joy_read_stick_friendly_retry:
68                 inc     dword [RetryCount]
69                 cmp     dword [RetryCount], 3
70                 jbe     @@f1
71                 mov     dword [_joy_bogus_reading], 1
72                 inc     dword [_joy_retries]
73                 mov     eax, 0
74                 pop     edi
75                 pop     ebx
76                 ret
77
78 @@f1:
79                 push    ecx
80                 push    ebx
81                 push    edi
82
83                 and     ebx, 01111b             ; Make sure we only check the right values                                                                              
84                                                 ; number of events we found will be in bh, so this also clears it to zero.
85
86                 mov     dx, [_JOY_PORT]
87
88                 cli                             ; disable interrupts while reading time...
89                 call    joy_get_timer           ; Returns counter in EAX
90                 sti                             ; enable interrupts after reading time...
91                 mov     dword [LastTick], eax
92
93 waitforstable_f:        in      al, dx
94                 and     al, bl
95                 jz      ready_f                         ; Wait for the port in question to be done reading...
96                 
97                 cli                             ; disable interrupts while reading time...
98                 call    joy_get_timer           ; Returns counter in EAX
99                 sti                             ; enable interrupts after reading time...
100                 xchg    eax, dword [LastTick]
101                 cmp     eax, dword [LastTick]
102                 jb      @@f2
103                 sub     eax, dword [LastTick]
104 @@f2:           ; Higher...
105                 add     dword [TotalTicks], eax
106                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
107                 jae     ready_f
108                 jmp     waitforstable_f
109                 
110 ready_f:
111                 cli                     
112                 mov     al, 0ffh
113                 out     dx, al                  ; Start joystick a readin'
114
115                 call    joy_get_timer           ; Returns counter in EAX
116                 mov     dword [LastTick], eax
117                 mov     dword [TotalTicks], 0
118                 
119                 mov     [edi], eax              ; Store initial count
120                 add     edi, 4          
121
122 again_f:        in      al, dx                  ; Read Joystick port
123                 not     al
124                 and     al, bl                  ; Mask off channels we don't want to read
125                 jnz     flip_f                  ; See if any of the channels flipped
126
127                 ; none flipped -- check any interrupts...
128                 mov     al, 0Ah
129                 out     20h, al
130                 in      al, 20h         ; Get interrupts pending
131                 cmp     al, 0
132                 je      NoInts
133
134                 ; Need to do an interrupt
135                 sti
136                 nop     ; let the interrupt go on...
137                 cli
138                 
139                 ; See if any axis turned
140                 in      al, dx
141                 not     al
142                 and     al, bl
143                 jz      NoInts
144
145                 ; At this point, an interrupt occured, making one or more
146                 ; of the axis values bogus.  So, we will restart this process...
147
148                 pop     edi
149                 pop     ebx
150                 pop     ecx
151
152                 jmp     _joy_read_stick_friendly_retry
153
154 NoInts:
155                 call    joy_get_timer           ; Returns counter in EAX
156                 
157                 xchg    eax, dword [LastTick]
158                 cmp     eax, dword [LastTick]
159                 jb      @@f3
160                 sub     eax, dword [LastTick]
161 @@f3:           ; Higher...
162                 add     dword [TotalTicks], eax
163                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
164                 jae     timed_out_f
165                 jmp     again_f
166
167         flip_f: and     eax, 01111b             ; Only care about axis values
168                 mov     [edi], eax              ; Record what channel(s) flipped
169                 add     edi, 4  
170                 xor     bl, al                  ; Unmark the channels that just tripped
171
172                 call    joy_get_timer           ; Returns counter in EAX
173                 mov     [edi], eax              ; Record the time this channel flipped
174                 add     edi, 4          
175                 inc     bh                      ; Increment number of events
176
177                 cmp     bl, 0   
178                 jne     again_f                 ; If there are more channels to read, keep looping
179
180         timed_out_f:
181                 sti
182
183                 movzx   eax, bh                 ; Return number of events
184
185                 pop     edi
186                 pop     ebx
187                 pop     ecx
188
189                 pop     edi
190                 pop     ebx
191                 ret
192
193
194
195 global _joy_read_stick_asm2
196
197 _joy_read_stick_asm2:
198                 push    ebx
199                 push    edi
200
201                 mov     ebx,[esp+12]
202                 mov     edi,[esp+16]
203                 mov     ecx,[esp+20]
204
205                 ; ebx = read mask
206                 ; edi = pointer to event buffer
207                 ; ecx = timeout value
208                 ; returns in eax the number of events
209                 mov     dword [_joy_bogus_reading], 0
210
211                 and     ebx, 01111b             ; Make sure we only check the right values                                                                              
212                                                 ; number of events we found will be in bh, so this also clears it to zero.
213
214                 mov     dx, [_JOY_PORT]
215
216                 cli                             ; disable interrupts while reading time...
217                 call    joy_get_timer           ; Returns counter in EAX
218                 sti                             ; enable interrupts after reading time...
219                 mov     dword [LastTick], eax
220
221 waitforstable:  in      al, dx
222                 and     al, bl
223                 jz      ready                   ; Wait for the port in question to be done reading...
224                 
225                 cli                             ; disable interrupts while reading time...
226                 call    joy_get_timer           ; Returns counter in EAX
227                 sti                             ; enable interrupts after reading time...
228                 xchg    eax, dword [LastTick]
229                 cmp     eax, dword [LastTick]
230                 jb      @@f4
231                 sub     eax, dword [LastTick]
232 @@f4:             ; Higher...
233                 add     dword [TotalTicks], eax
234                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
235                 jae     ready
236                 jmp     waitforstable
237                 
238 ready:
239                 cli
240                 mov     al, 0ffh
241                 out     dx, al                  ; Start joystick a readin'
242
243                 call    joy_get_timer           ; Returns counter in EAX
244                 mov     dword [LastTick], eax
245                 mov     dword [TotalTicks], 0
246                 
247                 mov     [edi], eax              ; Store initial count
248                 add     edi, 4          
249
250         again:  in      al, dx                  ; Read Joystick port
251                 not     al
252                 and     al, bl                  ; Mask off channels we don't want to read
253                 jnz     flip                    ; See if any of the channels flipped
254
255                 call    joy_get_timer           ; Returns counter in EAX
256                 
257                 xchg    eax, dword [LastTick]
258                 cmp     eax, dword [LastTick]
259                 jb      @@f5
260                 sub     eax, dword [LastTick]
261 @@f5:             ; Higher...
262                 add     dword [TotalTicks], eax
263                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
264                 jae     timedout
265                 jmp     again
266
267         flip:   and     eax, 01111b             ; Only care about axis values
268                 mov     [edi], eax              ; Record what channel(s) flipped
269                 add     edi, 4  
270                 xor     bl, al                  ; Unmark the channels that just tripped
271
272                 call    joy_get_timer           ; Returns counter in EAX
273                 mov     [edi], eax              ; Record the time this channel flipped
274                 add     edi, 4          
275                 inc     bh                      ; Increment number of events
276
277                 cmp     bl, 0   
278                 jne     again                   ; If there are more channels to read, keep looping
279
280         timedout:
281                 movzx   eax, bh                 ; Return number of events
282
283                 sti
284                 pop     edi
285                 pop     ebx
286                 ret
287
288
289 global _joy_read_stick_polled2
290
291 _joy_read_stick_polled2:
292                 push    ebx
293                 push    edi
294
295                 mov     ebx,[esp+12]
296                 mov     edi,[esp+16]
297                 mov     ecx,[esp+20]
298
299                 ; ebx = read mask
300                 ; edi = pointer to event buffer
301                 ; ecx = timeout value
302                 ; returns in eax the number of events
303                 mov     dword [_joy_bogus_reading], 0
304
305                 and     ebx, 01111b             ; Make sure we only check the right values                                                                              
306                                                 ; number of events we found will be in bh, so this also clears it to zero.
307
308                 mov     dx, [_JOY_PORT]
309
310                 mov     dword [TotalTicks], 0
311
312 waitforstable1: in      al, dx
313                 and     al, bl
314                 jz      ready1                  ; Wait for the port in question to be done reading...
315                 
316                 inc     dword [TotalTicks]
317                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
318                 jae     ready1
319                 jmp     waitforstable1
320 ready1:
321                 cli
322                 mov     al, 0ffh
323                 out     dx, al                  ; Start joystick a readin'
324
325                 mov     dword [TotalTicks], 0
326
327                 mov     dword [edi], 0              ; Store initial count
328                 add     edi, 4          
329
330         again1: in      al, dx                  ; Read Joystick port
331                 not     al
332                 and     al, bl                  ; Mask off channels we don't want to read
333                 jnz     flip1                   ; See if any of the channels flipped
334
335                 inc     dword [TotalTicks]
336                 cmp     dword [TotalTicks], ecx         ; Timeout at 1/200'th of a second
337                 jae     timedout1
338                 jmp     again1
339
340         flip1:  and     eax, 01111b             ; Only care about axis values
341                 mov     [edi], eax              ; Record what channel(s) flipped
342                 add     edi, 4  
343                 xor     bl, al                  ; Unmark the channels that just tripped
344
345                 mov     eax, dword [TotalTicks]
346                 mov     [edi], eax              ; Record the time this channel flipped
347                 add     edi, 4          
348                 inc     bh                      ; Increment number of events
349
350                 cmp     bl, 0   
351                 jne     again1                  ; If there are more channels to read, keep looping
352
353         timedout1:
354                 movzx   eax, bh                 ; Return number of events
355
356                 sti
357                 pop     edi
358                 pop     ebx
359                 ret
360
361 global _joy_read_stick_bios2
362
363 _joy_read_stick_bios2:
364                 push    ebx
365                 push    edi
366
367                 mov     ebx,[esp+12]
368                 mov     edi,[esp+16]
369                 mov     ecx,[esp+20]
370                 ; ebx = read mask
371                 ; edi = pointer to event buffer
372                 ; ecx = timeout value
373                 ; returns in eax the number of events
374
375                 mov     dword [_joy_bogus_reading], 0
376                 
377                 pusha
378
379                 mov     dword [edi], 0
380                         
381                 mov     eax, 08400h
382                 mov     edx, 1
383                 cli
384                 int     15h
385                 sti
386         
387                 mov     dword [edi+4], 1    ;       Axis 1
388                 and     eax, 0ffffh
389                 mov     [edi+8], eax            ;       Axis 1 value
390
391                 mov     dword [edi+12], 2   ;       Axis 2
392                 and     ebx, 0ffffh
393                 mov     [edi+16], ebx           ;       Axis 2 value
394
395                 mov     dword [edi+20], 4   ;       Axis 3
396                 and     ecx, 0ffffh
397                 mov     [edi+24], ecx           ;       Axis 3 value
398
399                 mov     dword [edi+28], 8   ;       Axis 3
400                 and     edx, 0ffffh
401                 mov     [edi+32], edx           ;       Axis 3 value
402
403                 popa
404                 mov     eax, 4                  ; 4 events
405
406                 pop     edi
407                 pop     ebx
408                 ret
409
410
411 global _joy_read_buttons_bios2
412
413 _joy_read_buttons_bios2:
414                 ; returns in eax the button settings
415                 
416                 push    ebx
417                 push    ecx
418                 push    edx
419                 mov     eax, 08400h
420                 mov     edx, 0  ; Read switches
421                 int     15h
422                 pop     edx
423                 pop     ecx
424                 pop     ebx
425                 
426                 shr     eax, 4
427                 not     eax
428                 and     eax, 01111b
429                 ret
430 global _joy_read_buttons_bios_end2
431 _joy_read_buttons_bios_end2: ; to calculate _joy_read_buttons_bios size
432