;**************************************************************************** ;* ;* 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