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