summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/common/_joy.asm
blob: 0ff1ecf55d30d7d6e0c08c5c8f3560024997a632 (plain)
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
OpenPOWER on IntegriCloud