1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
;****************************************************************************
;*
;* SciTech OS Portability Manager Library
;*
;* ========================================================================
;*
;* The contents of this file are subject to the SciTech MGL Public
;* License Version 1.0 (the "License"); you may not use this file
;* except in compliance with the License. You may obtain a copy of
;* the License at http://www.scitechsoft.com/mgl-license.txt
;*
;* Software distributed under the License is distributed on an
;* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
;* implied. See the License for the specific language governing
;* rights and limitations under the License.
;*
;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
;*
;* The Initial Developer of the Original Code is SciTech Software, Inc.
;* All Rights Reserved.
;*
;* ========================================================================
;*
;* Language: 80386 Assembler
;* Environment: Intel x86, any OS
;*
;* Description: Assembly language support routines for reading analogue
;* joysticks.
;*
;****************************************************************************
ideal
include "scitech.mac" ; Memory model macros
ifdef flatmodel
header _joy ; Set up memory model
begcodeseg _joy ; Start of code segment
;----------------------------------------------------------------------------
; initTimer
;----------------------------------------------------------------------------
; Sets up 8253 timer 2 (PC speaker) to start timing, but not produce output.
;----------------------------------------------------------------------------
cprocstatic initTimer
; Start timer 2 counting
in al,61h
and al,0FDh ; Disable speaker output (just in case)
or al,1
out 61h,al
; Set the timer 2 count to 0 again to start the timing interval.
mov al,10110100b ; set up to load initial (timer 2)
out 43h,al ; timer count
sub al,al
out 42h,al ; load count lsb
out 42h,al ; load count msb
ret
cprocend
;----------------------------------------------------------------------------
; readTimer2
;----------------------------------------------------------------------------
; Reads the number of ticks from the 8253 timer chip using channel 2 (PC
; speaker). This is non-destructive and does not screw up other libraries.
;----------------------------------------------------------------------------
cprocstatic readTimer
xor al,al ; Latch timer 0 command
out 43h,al ; Latch timer
in al,42h ; least significant byte
mov ah,al
in al,42h ; most significant byte
xchg ah,al
and eax,0FFFFh
ret
cprocend
;----------------------------------------------------------------------------
; exitTimer
;----------------------------------------------------------------------------
; Stops the 8253 timer 2 (PC speaker) counting
;----------------------------------------------------------------------------
cprocstatic exitTimer
; Stop timer 2 from counting
push eax
in al,61h
and al,0FEh
out 61h,al
; Some programs have a problem if we change the control port; better change it
; to something they expect (mode 3 - square wave generator)...
mov al,0B6h
out 43h,al
pop eax
ret
cprocend
;----------------------------------------------------------------------------
; int _EVT_readJoyAxis(int jmask,int *axis);
;----------------------------------------------------------------------------
; Function to poll the joystick to read the current axis positions.
;----------------------------------------------------------------------------
cprocstart _EVT_readJoyAxis
ARG jmask:UINT, axis:DPTR
LOCAL firstTick:UINT, lastTick:UINT, totalTicks:UINT = LocalSize
enter_c
mov ebx,[jmask]
mov edi,[axis]
mov ecx,(1193180/100)
and ebx,01111b ; Mask out supported axes
mov dx,201h ; DX := joystick I/O port
call initTimer ; Start timer 2 counting
call readTimer ; Returns counter in EAX
mov [lastTick],eax
@@WaitStable:
in al,dx
and al,bl ; Wait for the axes in question to be
jz @@Stable ; done reading...
call readTimer ; Returns counter in EAX
xchg eax,[lastTick]
cmp eax,[lastTick]
jb @@1
sub eax,[lastTick]
@@1: add [totalTicks],eax
cmp [totalTicks],ecx ; Check for timeout
jae @@Stable
jmp @@WaitStable
@@Stable:
mov al,0FFh
out dx,al ; Start joystick reading
call initTimer ; Start timer 2 counting
call readTimer ; Returns counter in EAX
mov [firstTick],eax ; Store initial count
mov [lastTick],eax
mov [DWORD totalTicks],0
cli
@@PollLoop:
in al,dx ; Read Joystick port
not al
and al,bl ; Mask off channels we don't want to read
jnz @@AxisFlipped ; See if any of the channels flipped
call readTimer ; Returns counter in EAX
xchg eax,[lastTick]
cmp eax,[lastTick]
jb @@2
sub eax,[lastTick]
@@2: add [totalTicks],eax
cmp [totalTicks],ecx ; Check for timeout
jae @@TimedOut
jmp @@PollLoop
@@AxisFlipped:
xor esi,esi
mov ah,1
test al,ah
jnz @@StoreCount ; Joystick 1, X axis flipped
add esi,4
mov ah,2
test al,ah
jnz @@StoreCount ; Joystick 1, Y axis flipped
add esi,4
mov ah,4
test al,ah
jnz @@StoreCount ; Joystick 2, X axis flipped
add esi,4 ; Joystick 2, Y axis flipped
mov ah,8
@@StoreCount:
or bh,ah ; Indicate this axis is active
xor bl,ah ; Unmark the channels that just tripped
call readTimer ; Returns counter in EAX
xchg eax,[lastTick]
cmp eax,[lastTick]
jb @@3
sub eax,[lastTick]
@@3: add [totalTicks],eax
mov eax,[totalTicks]
mov [edi+esi],eax ; Record the time this channel flipped
cmp bl,0 ; If there are more channels to read,
jne @@PollLoop ; keep looping
@@TimedOut:
sti
call exitTimer ; Stop timer 2 counting
movzx eax,bh ; Return the mask of working axes
leave_c
ret
cprocend
;----------------------------------------------------------------------------
; int _EVT_readJoyButtons(void);
;----------------------------------------------------------------------------
; Function to poll the current joystick buttons
;----------------------------------------------------------------------------
cprocstart _EVT_readJoyButtons
mov dx,0201h
in al,dx
shr al,4
not al
and eax,0Fh
ret
cprocend
endcodeseg _joy
endif
END ; End of module
|