home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / csstuff / joy.asm next >
Assembly Source File  |  1998-06-08  |  10KB  |  441 lines

  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. ; $Source: f:/miner/source/bios/rcs/joy.asm $
  13. ; $Revision: 1.16 $
  14. ; $Author: john $
  15. ; $Date: 1995/03/30 11:03:30 $
  16. ;
  17. ; Contains routines for joystick interface.
  18. ;
  19. ; $Log: joy.asm $
  20. ; Revision 1.16  1995/03/30  11:03:30  john
  21. ; Made -JoyBios read buttons using BIOS.
  22. ; Revision 1.15  1995/02/14  11:39:36  john
  23. ; Added polled/bios joystick readers..
  24. ; Revision 1.14  1995/01/29  18:36:00  john
  25. ; Made timer count in mode 2 instead of mode 3.
  26. ; Revision 1.13  1994/12/28  15:32:21  john
  27. ; Added code to read joystick axis not all at one time.
  28. ; Revision 1.12  1994/12/27  15:44:59  john
  29. ; Made the joystick timeout be at 1/100th of a second, 
  30. ; regardless of CPU speed.
  31. ; Revision 1.11  1994/11/15  12:04:40  john
  32. ; Cleaned up timer code a bit... took out unused functions
  33. ; like timer_get_milliseconds, etc.
  34. ; Revision 1.10  1994/07/01  10:55:54  john
  35. ; Fixed some bugs... added support for 4 axis.
  36. ; Revision 1.9  1994/06/30  20:36:54  john
  37. ; Revamped joystick code.
  38. ; Revision 1.8  1994/04/22  12:52:06  john
  39.  
  40. .386
  41.  
  42. _DATA   SEGMENT BYTE PUBLIC USE32 'DATA'
  43.  
  44. rcsid    db    "$Id: joy.asm 1.16 1995/03/30 11:03:30 john Exp $"
  45.  
  46.     LastTick     dd    0
  47.     TotalTicks    dd    0
  48.  
  49.     PUBLIC    _joy_bogus_reading
  50.     PUBLIC    _joy_retries
  51.     _joy_bogus_reading    dd    0
  52.     _joy_retries        dd    0
  53.     RetryCount        dd    0
  54.  
  55.     
  56. _DATA   ENDS
  57.  
  58. DGROUP  GROUP _DATA
  59.  
  60.  
  61. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  62.  
  63.     ASSUME  ds:_DATA
  64.     ASSUME  cs:_TEXT
  65.  
  66.     JOY_PORT        EQU     0201h
  67.     TDATA           EQU     40h
  68.     TCOMMAND        EQU     43h
  69.  
  70. joy_get_timer:
  71.     xor    al, al                ; Latch timer 0 command
  72.     out    TCOMMAND, al        ; Latch timer
  73.     in    al, TDATA        ; Read lo byte
  74.     mov    ah, al
  75.     in    al, TDATA        ; Read hi byte
  76.     xchg    ah, al
  77.     and    eax, 0ffffh
  78.     ret    
  79.  
  80.  
  81.  
  82. PUBLIC joy_read_stick_friendly_
  83.  
  84. joy_read_stick_friendly_:    
  85.         ; ebx = read mask
  86.         ; edi = pointer to event buffer
  87.         ; ecx = timeout value
  88.         ; returns in eax the number of events
  89.  
  90.         mov    RetryCount, 0
  91.         mov    _joy_bogus_reading, 0
  92.  
  93. joy_read_stick_friendly_retry:
  94.         inc    RetryCount
  95.         cmp    RetryCount, 3
  96.         jbe    @f
  97.         mov    _joy_bogus_reading, 1
  98.         inc    _joy_retries
  99.         mov    eax, 0
  100.         ret
  101.  
  102. @@:
  103.         push    ecx
  104.         push    ebx
  105.         push    edi
  106.  
  107.         and    ebx, 01111b        ; Make sure we only check the right values                                        
  108.                         ; number of events we found will be in bh, so this also clears it to zero.
  109.  
  110.         mov     dx, JOY_PORT
  111.  
  112.         cli                ; disable interrupts while reading time...
  113.         call    joy_get_timer        ; Returns counter in EAX
  114.         sti                ; enable interrupts after reading time...
  115.         mov    LastTick, eax
  116.  
  117. waitforstable_f:    in    al, dx
  118.         and    al, bl
  119.         jz    ready_f             ; Wait for the port in question to be done reading...
  120.         
  121.         cli                ; disable interrupts while reading time...
  122.         call    joy_get_timer        ; Returns counter in EAX
  123.         sti                ; enable interrupts after reading time...
  124.         xchg    eax, LastTick
  125.         cmp    eax, LastTick
  126.         jb    @f
  127.         sub    eax, LastTick
  128. @@:        ; Higher...
  129.         add    TotalTicks, eax
  130.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  131.         jae    ready_f
  132.         jmp    waitforstable_f
  133.         
  134. ready_f:
  135.         cli            
  136.         mov     al, 0ffh
  137.         out     dx, al            ; Start joystick a readin'
  138.  
  139.         call    joy_get_timer        ; Returns counter in EAX
  140.         mov    LastTick, eax
  141.         mov    TotalTicks, 0
  142.         
  143.         mov    [edi], eax        ; Store initial count
  144.         add    edi, 4        
  145.  
  146.     again_f:    in    al, dx            ; Read Joystick port
  147.         not    al
  148.         and    al, bl            ; Mask off channels we don't want to read
  149.         jnz    flip_f            ; See if any of the channels flipped
  150.  
  151.         ; none flipped -- check any interrupts...
  152.         mov    al, 0Ah
  153.         out     20h, al
  154.         in    al, 20h        ; Get interrupts pending
  155.         cmp    al, 0
  156.         je    NoInts
  157.  
  158.         ; Need to do an interrupt
  159.         sti
  160.         nop    ; let the interrupt go on...
  161.         cli
  162.         
  163.         ; See if any axis turned
  164.         in    al, dx
  165.         not    al
  166.         and    al, bl
  167.         jz    NoInts
  168.  
  169.         ; At this point, an interrupt occured, making one or more
  170.         ; of the axis values bogus.  So, we will restart this process...
  171.  
  172.         pop    edi
  173.         pop    ebx
  174.         pop    ecx
  175.  
  176.         jmp    joy_read_stick_friendly_retry
  177.  
  178. NoInts:
  179.         call    joy_get_timer        ; Returns counter in EAX
  180.         
  181.         xchg    eax, LastTick
  182.         cmp    eax, LastTick
  183.         jb    @f
  184.         sub    eax, LastTick
  185. @@:        ; Higher...
  186.         add    TotalTicks, eax
  187.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  188.         jae    timed_out_f
  189.         jmp    again_f
  190.  
  191.     flip_f:    and    eax, 01111b        ; Only care about axis values
  192.         mov    [edi], eax        ; Record what channel(s) flipped
  193.         add    edi, 4    
  194.         xor    bl, al            ; Unmark the channels that just tripped
  195.  
  196.         call    joy_get_timer        ; Returns counter in EAX
  197.         mov    [edi], eax        ; Record the time this channel flipped
  198.         add    edi, 4        
  199.         inc    bh            ; Increment number of events
  200.  
  201.         cmp    bl, 0    
  202.         jne    again_f            ; If there are more channels to read, keep looping
  203.  
  204.     timed_out_f:
  205.         sti
  206.  
  207.         movzx    eax, bh            ; Return number of events
  208.  
  209.         pop    edi
  210.         pop    ebx
  211.         pop    ecx
  212.  
  213.         ret
  214.  
  215.  
  216.  
  217. PUBLIC joy_read_stick_asm_
  218.  
  219. joy_read_stick_asm_:    
  220.         ; ebx = read mask
  221.         ; edi = pointer to event buffer
  222.         ; ecx = timeout value
  223.         ; returns in eax the number of events
  224.         mov    _joy_bogus_reading, 0
  225.  
  226.         and    ebx, 01111b        ; Make sure we only check the right values                                        
  227.                         ; number of events we found will be in bh, so this also clears it to zero.
  228.  
  229.         mov     dx, JOY_PORT
  230.  
  231.         cli                ; disable interrupts while reading time...
  232.         call    joy_get_timer        ; Returns counter in EAX
  233.         sti                ; enable interrupts after reading time...
  234.         mov    LastTick, eax
  235.  
  236. waitforstable:    in    al, dx
  237.         and    al, bl
  238.         jz    ready             ; Wait for the port in question to be done reading...
  239.         
  240.         cli                ; disable interrupts while reading time...
  241.         call    joy_get_timer        ; Returns counter in EAX
  242.         sti                ; enable interrupts after reading time...
  243.         xchg    eax, LastTick
  244.         cmp    eax, LastTick
  245.         jb    @f
  246.         sub    eax, LastTick
  247. @@:        ; Higher...
  248.         add    TotalTicks, eax
  249.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  250.         jae    ready
  251.         jmp    waitforstable
  252.         
  253. ready:
  254.         cli
  255.         mov     al, 0ffh
  256.         out     dx, al            ; Start joystick a readin'
  257.  
  258.         call    joy_get_timer        ; Returns counter in EAX
  259.         mov    LastTick, eax
  260.         mov    TotalTicks, 0
  261.         
  262.         mov    [edi], eax        ; Store initial count
  263.         add    edi, 4        
  264.  
  265.     again:    in    al, dx            ; Read Joystick port
  266.         not    al
  267.         and    al, bl            ; Mask off channels we don't want to read
  268.         jnz    flip            ; See if any of the channels flipped
  269.  
  270.         call    joy_get_timer        ; Returns counter in EAX
  271.         
  272.         xchg    eax, LastTick
  273.         cmp    eax, LastTick
  274.         jb    @f
  275.         sub    eax, LastTick
  276. @@:        ; Higher...
  277.         add    TotalTicks, eax
  278.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  279.         jae    timedout
  280.         jmp    again
  281.  
  282.     flip:    and    eax, 01111b        ; Only care about axis values
  283.         mov    [edi], eax        ; Record what channel(s) flipped
  284.         add    edi, 4    
  285.         xor    bl, al            ; Unmark the channels that just tripped
  286.  
  287.         call    joy_get_timer        ; Returns counter in EAX
  288.         mov    [edi], eax        ; Record the time this channel flipped
  289.         add    edi, 4        
  290.         inc    bh            ; Increment number of events
  291.  
  292.         cmp    bl, 0    
  293.         jne    again            ; If there are more channels to read, keep looping
  294.  
  295.     timedout:
  296.         movzx    eax, bh            ; Return number of events
  297.  
  298.         sti
  299.         ret
  300.  
  301.  
  302. PUBLIC joy_read_stick_polled_
  303.  
  304. joy_read_stick_polled_:    
  305.         ; ebx = read mask
  306.         ; edi = pointer to event buffer
  307.         ; ecx = timeout value
  308.         ; returns in eax the number of events
  309.         mov    _joy_bogus_reading, 0
  310.  
  311.         and    ebx, 01111b        ; Make sure we only check the right values                                        
  312.                         ; number of events we found will be in bh, so this also clears it to zero.
  313.  
  314.         mov     dx, JOY_PORT
  315.  
  316.         mov    TotalTicks, 0
  317.  
  318. waitforstable1:    in    al, dx
  319.         and    al, bl
  320.         jz    ready1             ; Wait for the port in question to be done reading...
  321.         
  322.         inc    TotalTicks
  323.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  324.         jae    ready1
  325.         jmp    waitforstable1
  326. ready1:
  327.         cli
  328.         mov     al, 0ffh
  329.         out     dx, al            ; Start joystick a readin'
  330.  
  331.         mov    TotalTicks, 0
  332.  
  333.         mov    dword ptr [edi], 0        ; Store initial count
  334.         add    edi, 4        
  335.  
  336.     again1:    in    al, dx            ; Read Joystick port
  337.         not    al
  338.         and    al, bl            ; Mask off channels we don't want to read
  339.         jnz    flip1            ; See if any of the channels flipped
  340.  
  341.         inc    TotalTicks
  342.         cmp    TotalTicks, ecx        ; Timeout at 1/200'th of a second
  343.         jae    timedout1
  344.         jmp    again1
  345.  
  346.     flip1:    and    eax, 01111b        ; Only care about axis values
  347.         mov    [edi], eax        ; Record what channel(s) flipped
  348.         add    edi, 4    
  349.         xor    bl, al            ; Unmark the channels that just tripped
  350.  
  351.         mov    eax, TotalTicks
  352.         mov    [edi], eax        ; Record the time this channel flipped
  353.         add    edi, 4        
  354.         inc    bh            ; Increment number of events
  355.  
  356.         cmp    bl, 0    
  357.         jne    again1            ; If there are more channels to read, keep looping
  358.  
  359.     timedout1:
  360.         movzx    eax, bh            ; Return number of events
  361.  
  362.         sti
  363.         ret
  364.  
  365. PUBLIC joy_read_stick_bios_
  366.  
  367. joy_read_stick_bios_:    
  368.         ; ebx = read mask
  369.         ; edi = pointer to event buffer
  370.         ; ecx = timeout value
  371.         ; returns in eax the number of events
  372.  
  373.         mov    _joy_bogus_reading, 0
  374.         
  375.         pusha
  376.  
  377.         mov    dword ptr [edi], 0
  378.             
  379.         mov    eax, 08400h
  380.         mov    edx, 1
  381.         cli
  382.         int    15h
  383.         sti
  384.     
  385.         mov    dword ptr [edi+4], 1    ;    Axis 1        
  386.         and    eax, 0ffffh
  387.         mov    [edi+8], eax        ;     Axis 1 value
  388.  
  389.         mov    dword ptr [edi+12], 2    ;    Axis 2
  390.         and    ebx, 0ffffh
  391.         mov    [edi+16], ebx        ;     Axis 2 value
  392.  
  393.         mov    dword ptr [edi+20], 4    ;    Axis 3
  394.         and    ecx, 0ffffh
  395.         mov    [edi+24], ecx        ;     Axis 3 value
  396.  
  397.         mov    dword ptr [edi+28], 8    ;    Axis 3
  398.         and    edx, 0ffffh
  399.         mov    [edi+32], edx        ;     Axis 3 value
  400.  
  401.         popa
  402.         mov    eax, 4            ; 4 events
  403.  
  404.         ret
  405.  
  406.  
  407. PUBLIC joy_read_buttons_bios_
  408.  
  409. joy_read_buttons_bios_:    
  410.         ; returns in eax the button settings
  411.         
  412.         push    ebx
  413.         push    ecx
  414.         push    edx
  415.         mov    eax, 08400h
  416.         mov    edx, 0    ; Read switches
  417.         int    15h
  418.         pop    edx
  419.         pop    ecx
  420.         pop    ebx
  421.         
  422.         shr    eax, 4
  423.         not    eax
  424.         and    eax, 01111b
  425.         ret
  426.  
  427.  
  428. _TEXT   ENDS
  429.  
  430.  
  431.         END
  432. 
  433.