home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / joysdk11 / rdaxis_s.asm < prev    next >
Assembly Source File  |  1992-02-17  |  7KB  |  213 lines

  1.         page    ,132
  2. ;------------------------------------------------------------------------------
  3. ; Module Name: READAXIS.ASM
  4. ;
  5. ; Assembly language routine for reading joystick axis position
  6. ;
  7. ; Created: Feb 17th, 1992
  8. ; Author: Peter Wan
  9. ;
  10. ; Copyright (c) 1992 Advanced Gravis Computer Technology Limited
  11. ;
  12. ; Public Functions:
  13. ;    get_loop_count
  14. ;    read_axis
  15. ; Public Data:
  16. ;    None
  17. ; General Description:
  18. ;    This module contains functions to initialize itself and return
  19. ;    joystick axis position.
  20. ;------------------------------------------------------------------------------
  21.  
  22.         dosseg
  23.         .model     small
  24.  
  25. ;------------------------------------------------------------------------------
  26. ; Port address
  27. ;------------------------------------------------------------------------------
  28. GAMEPORT    equ    201h        ;gameport address
  29. TIMER0        equ    40h        ;8253 counter timer channel 0 address
  30. TIMER_CONTROL    equ    43h        ;counter timer control register address
  31.  
  32.         .data
  33. max_loop_count    dw    ?        ;loop count for 3 milliseconds
  34.  
  35.         .code
  36.  
  37. ;------------------------------------------------------------------------------
  38. ; get_loop_count
  39. ;
  40. ; The purpose of this routine is to determine how many iteration of the
  41. ; following instruction loop can be accomplished in 3 milliseconds.  The number
  42. ; of iteration count will be different on computers running at different speed
  43. ; or computers with different processing unit.    In the read joystick axis
  44. ; routine, it uses a similar program loop to determine joystick axis position
  45. ; and the count results from this routine will be used to limit axis read time
  46. ; up to 3 millesecond maximum.    This routine must be called once at
  47. ; initialization time.
  48. ;
  49. ; Entry:
  50. ;    None
  51. ; Returns:
  52. ;    None
  53. ; Error Returns:
  54. ;    None
  55. ; Registers Preserved:
  56. ;    BX,SI,DI,BP,DS,ES
  57. ; Registers Destroyed:
  58. ;    AX,CX,DX
  59. ; Calls:
  60. ;    None
  61. ;------------------------------------------------------------------------------
  62.  
  63.         public    _get_loop_count
  64. _get_loop_count proc
  65. init_count    equ    <[bp-2]>
  66.         push    bp
  67.         mov    bp,sp
  68.         sub    sp,2        ;2 bytes of local variable
  69.         mov    max_loop_count,0;use loop count of 16 to start with
  70.         mov    dx,GAMEPORT    ;gameport address
  71. glc3:
  72.         mov    ax,0ff00h
  73.         add    max_loop_count,16
  74.         mov    cx,max_loop_count
  75.         cli            ;system interrupt must be disabled
  76.         out    TIMER_CONTROL,al;latch count in timer 0
  77.         jmp    short $+2
  78.         in    al,TIMER0    ;read low byte of latched count
  79.         mov    init_count,al    ;save
  80.         jmp    short $+2
  81.         in    al,TIMER0    ;read high byte
  82.         mov    init_count+1,al ;save
  83.         out    dx,al        ;trigger gameport
  84.         in    al,dx        ;delay to allow gameport to switch on
  85. glc4:                    ;the following loop exits only when CX
  86.                     ;reaches zero
  87.         in    al,dx
  88.         or    al,ah
  89.         loopnz    glc4
  90.         mov    ax,0
  91.         jnz    $+2
  92.         out    TIMER_CONTROL,al;latch count in timer 0
  93.         sti            ;enable system interrupt
  94.         jmp    short $+2
  95.         in    al,TIMER0    ;read low byte of latched count
  96.         mov    ah,al
  97.         jmp    short $+2
  98.         in    al,TIMER0    ;read high byte
  99.         xchg    al,ah
  100.         sub    ax,init_count    ;subtract count latched before
  101.                     ;entering loop by count just read
  102.         neg    ax
  103.         cmp    ax,7160     ;has it exceed 3 milliseconds?
  104.         jl    glc3        ;no, increment loop count by 16 and
  105.                     ;repeat process
  106.         mov    sp,bp
  107.         pop    bp
  108.         ret
  109. _get_loop_count endp
  110.  
  111. ;------------------------------------------------------------------------------
  112. ; _read_axis
  113. ;
  114. ; This routine will accept a number from 0 to 3 for returning joystick axis
  115. ; position for joystick A-X, A-Y, B-X, B-Y respectively.  After bit position
  116. ; of requested axis is determined, count reading in counter timer chip channel 0
  117. ; will be read and saved.  A write cycle to gameport address 201 hex will
  118. ; trigger and toggle all four axis lines from low to high state.  The duration
  119. ; of these individual line staying high is directly proportional to the
  120. ; position of joystick for the individual axis.  After the requested axis line
  121. ; has returned to the low state, count reading in counter timer chip will be
  122. ; read again. The real time count of the duration the requested axis has stayed
  123. ; high can be obtained from the difference of the two counts read.  Allowance
  124. ; for other axis to return to low state must also be provided before next read.
  125. ; Therefore, return to calling function can only be done at the end of the
  126. ; 3 milliseconds duration.  The real time count return to the callind function
  127. ; can have a value ranges from 1 to maximum of 7160 depending on the position
  128. ; of the joystick, value of capacitors used and threshold voltage set
  129. ; on the gamecard.  If the requested axis has not returned to the low state
  130. ; after 3 milliseconds, it is assumed that no joystick is connected to that
  131. ; axis and zero will be returned to the calling function.  During the
  132. ; 3 milliseconds duration, all interrupts except NMI will be disabled.
  133. ;
  134. ; Entry:
  135. ;    [bp+4] = Axis to be read
  136. ;         0 = Joystick A - X axis
  137. ;         1 = Joystick A - Y axis
  138. ;         2 = Joystick B - X axis
  139. ;         3 = Joystick B - Y axis
  140. ; Returns:
  141. ;    AX = Count ranges from 1 to maximun of 7160 corresponds to joystick
  142. ;         position
  143. ; Error Returns:
  144. ;    AX = 0 if no joystick connected
  145. ; Registers Preserved:
  146. ;    BX,SI,DI,BP,DS,ES
  147. ; Registers Destroyed:
  148. ;    AX,CX,DX
  149. ; Calls:
  150. ;    None
  151. ;------------------------------------------------------------------------------
  152.  
  153.         public    _read_axis
  154. _read_axis    proc
  155. axis        equ    <[bp+4]>
  156. init_count    equ    <[bp-2]>
  157.         push    bp
  158.         mov    bp,sp
  159.         sub    sp,2        ;2 bytes of local variable
  160.         sub    ax,ax        ;determine bit position of axis to be
  161.         mov    ah,1        ;read
  162.         mov    cx,axis
  163.         shl    ah,cl
  164.         mov    cx,max_loop_count;use 3 milliseconds loop count obtian
  165.                     ;at initailization
  166.         mov    dx,GAMEPORT    ;gameport address
  167.         cli            ;disable interrupt
  168.         out    TIMER_CONTROL,al;latch count in timer 0
  169.         jmp    short $+2
  170.         in    al,TIMER0    ;read low byte of latched count
  171.         mov    init_count,al    ;save
  172.         jmp    short $+2
  173.         in    al,TIMER0    ;read high byte
  174.         mov    init_count+1,al ;save
  175.         out    dx,al        ;trigger gameport
  176.         in    al,dx        ;delay to allow gameport to switch on
  177. ra1:
  178.         in    al,dx        ;read gameport
  179.         test    al,ah        ;requested axis return to low state or
  180.                     ;3 milliseconds passed?
  181.         loopnz    ra1        ;no
  182.         mov    ax,0        ;return 0 if 3 milliseconds passed and
  183.         jnz    ra3        ;requested axis not yet in low state
  184.         out    TIMER_CONTROL,al;requested axis return to low state
  185.                     ;latch count in timer 0
  186.         jmp    short $+2
  187.         in    al,TIMER0    ;read low byte of latched count
  188.         mov    ah,al
  189.         jmp    short $+2
  190.         in    al,TIMER0    ;read high byte
  191.         xchg    al,ah
  192.         sub    ax,init_count    ;obtain real time count of high state
  193.         neg    ax        ;duration
  194.         jcxz    ra3        ;requested axis return to low state in
  195.                     ;exactly 3 milliseconds, all other axis
  196.                     ;should also have returned to low state
  197.                     ;by now
  198.         push    ax        ;even though the requested axis has
  199.         mov    ah,0ffh     ;returned to the low state, other axis
  200. ra2:                    ;may still be in the high state, we
  201.         in    al,dx        ;should wait till the end of the
  202.         or    al,ah        ;3 milliseconds duration to allow the
  203.         loopnz    ra2        ;other axis to return to high state
  204.         pop    ax        ;before returning to the calling
  205.                     ;fucntion
  206. ra3:
  207.         sti            ;enable system interrupt
  208.         mov    sp,bp
  209.         pop    bp
  210.         ret
  211. _read_axis    endp
  212.         end
  213.