home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / KEYWAIT.ZIP / KEYWAIT.OS2 < prev   
Text File  |  1989-09-11  |  6KB  |  257 lines

  1. ;-------------------------------------------------------------------------------
  2. ;
  3. ;                keywait.asm
  4. ;                ===========
  5. ;
  6. ;    Waits a few seconds for a keystroke.  If ESC is pressed then sets
  7. ;    errorlevel to 27.  If a function key F1-F10 is pressed then sets
  8. ;    errorlevel to a value in the range 1-10 corresponding to the function
  9. ;    key.  If time expires or any other key is pressed then errorlevel
  10. ;    is set to zero.  Can be useful in .CMD files.
  11. ;
  12. ;    A public domain program by Jon Saxton.  Please distribute source
  13. ;    code and not just the object code.
  14. ;
  15. ;-------------------------------------------------------------------------------
  16.  
  17.     include os2.inc
  18.  
  19. COLON    equ    ':'
  20. CR    equ    0Dh
  21. LF    equ    0Ah
  22. ETX    equ    03h
  23. ESCk    equ    1Bh
  24. SPACE    equ    ' '
  25. TAB    equ    9
  26. F1    equ    59
  27. F10    equ    68
  28.  
  29. THREAD_STACK_SIZE   equ     512
  30. THREAD_STACK_OFFSET equ     THREAD_STACK_SIZE-2
  31.  
  32.     .model    small
  33.  
  34.     .data
  35.  
  36. keyData    KBDKEYINFO    <>
  37.  
  38. ticks    dw    10            ;Default number of seconds
  39. stkPtr    dd    ?
  40.     org    stkPtr
  41. stkOff    dw    ?
  42. stkSeg    dw    ?
  43. tid    dw    ?
  44. kid    dw    ?
  45.  
  46. keyboardInput    dd    ?        ; Keyboard input semaphore
  47. timeExpired    dd    ?        ; Timer semaphore
  48.  
  49. semaphoreList    dw    2        ; Number of elements
  50.         dw    0
  51.         dw    offset keyboardInput
  52.         dw    seg keyboardInput
  53.         dw    0
  54.         dw    offset timeExpired
  55.         dw    seg timeExpired
  56.  
  57. key        dw    0
  58. blankRet    db    CR
  59. blanks        db    '    '
  60. timerHandle    dd    ?
  61. timerSemHandle    dd    ?
  62. timerSemName    db    '\SEM\TICKER',0
  63. eventNumber    dw    -1
  64. kiMessage    db    'Key pressed: exit code '
  65. toMessage    db    'Timed out:   exit code '
  66. msgLen        equ    $-toMessage
  67. pointers    dw    kiMessage,toMessage
  68.  
  69.     .code
  70.     .286C
  71.  
  72. start:
  73.     mov    es,ax            ; Point at environment segment
  74.     mov    di,bx            ; Point at command name
  75.     xor    ax,ax
  76.     repne    scasb            ; Skip to end of command name
  77.     mov    cx,0
  78. skipLeadingBlanks:
  79.     mov    al,es:[di]        ; Get command-line character
  80.     inc    di            ; Point at the next one
  81.     or    al,al            ; Check if anything there
  82.     jz    setTicks
  83.     cmp    al,SPACE        ; Skip leading white space
  84.     je    skipLeadingBlanks
  85.     cmp    al,TAB
  86.     je    skipLeadingBlanks
  87. convertNumber:
  88.     xor    ah,ah
  89.     cmp    al,'0'
  90.     jb    setTicks
  91.     cmp    al,'9'
  92.     ja    setTicks
  93.     sub    al,'0'
  94.     add    cx,cx            ;*2
  95.     mov    dx,cx
  96.     add    cx,cx            ;*4
  97.     add    cx,cx            ;*8
  98.     add    cx,dx            ;*10
  99.     add    cx,ax
  100.     mov    al,es:[di]
  101.     inc    di
  102.     jmp    convertNumber
  103. setTicks:
  104.     mov    ax,cx
  105.     or    ax,ax
  106.     jz    default
  107.     cmp    ax,100
  108.     ja    default
  109.     mov    ticks,ax
  110. default:
  111.  
  112. ; At this point we have analysed the command line and interpreted a single
  113. ; number as the number of seconds to wait for a keystroke.  If the number
  114. ; of seconds was not specified or is unreasonably large then it has been
  115. ; forced to a value of 10.
  116. ;
  117. ; The next step is to initiate the timer and keyboard threads.    This is
  118. ; real OS/2 stuff.
  119.  
  120.     @DosSemSet    keyboardInput    ; Set the semaphores which are going
  121.     @DosSemSet    timeExpired    ; to be used by the two threads
  122.  
  123.     @DosAllocSeg    THREAD_STACK_SIZE,stkSeg,0    ; Get a stack
  124.     or        ax,ax            ; Check that it worked
  125.     jz        first
  126.     jmp        error100
  127. first:
  128.     mov        ax,THREAD_STACK_OFFSET    ; Create the timer thread
  129.     mov        stkOff,ax
  130.     @DosCreateThread ticker,tid,[stkPtr]
  131.  
  132.     @DosAllocSeg    THREAD_STACK_SIZE,stkSeg,0    ; Get a stack
  133.     or        ax,ax            ; Check that it worked
  134.     jz        second
  135.     jmp        error100
  136. second:
  137.     @DosCreateThread keyin,kid,[stkPtr]    ; Create the keyin thread
  138.  
  139. ; Now wait for one of the two threads to signal an event
  140.  
  141.     @DosMuxSemWait    eventNumber,semaphoreList,-1
  142.     mov        bx,eventNumber
  143.     add        bx,bx
  144.     mov        ax,pointers[bx]
  145.     push        ds
  146.     push        ax
  147.     push        msgLen
  148.     push        0
  149.     call far ptr VioWrtTTy
  150.     mov        si,offset blanks
  151.     mov        ax,'  '
  152.     mov        [si],ax
  153.     mov        ax,key
  154.     call        decimal
  155.     @VioWrtTTy    blanks,3,0
  156.     @DosExit    1,[key]
  157.  
  158. error100:
  159.     @DosExit    1,100
  160.  
  161. ;-----------------------------------------------------------------------------
  162. ;
  163. ;    Keyboard input handler.  Waits for a keystroke and returns a value
  164. ;    in the range 1-10 if a function key was pressed, 27 if the ESC key
  165. ;    was pressed, 0 if anything else was pressed.
  166. ;
  167. ;-----------------------------------------------------------------------------
  168.  
  169. keyin    proc
  170.  
  171.     @KbdCharIn    keyData,0,0        ; Get character
  172.     mov        al,keyData.kbci_chChar
  173.     or        al,al            ; Extended key code?
  174.     jnz        simple            ; No, check for ESC etc
  175.     mov        al,keyData.kbci_chScan    ; Fetch second byte
  176.     cmp        al,F1            ; Check for F1 - F10
  177.     jb        sig0
  178.     cmp        al,F10
  179.     ja        sig0
  180.     sub        al,F1-1
  181.     jmp        sig
  182. simple:
  183.     cmp        al,ESCk            ; ESC causes return value
  184.     jz        sig            ;  to be set to 27
  185. sig0:
  186.     xor        al,al
  187. sig:
  188.     mov        byte ptr key,al
  189.     @DosSemClear    keyboardInput
  190.     @DosExit    0,0
  191.  
  192. keyin    endp
  193.  
  194. ;------------------------------------------------------------------------------
  195. ;
  196. ;    Countdown timer.  Displays the number of ticks remaining.  Stops
  197. ;    at zero.
  198. ;
  199. ;------------------------------------------------------------------------------
  200.  
  201. ticker    proc
  202.  
  203.     @DosCreateSem    1,timerSemHandle,timerSemName
  204.     @DosSemSet    [timerSemHandle]
  205.     @DosTimerStart    1000,[timerSemHandle],timerHandle
  206. tick:
  207.     @DosSemWait    [timerSemHandle],-1
  208.     @DosSemSet    [timerSemHandle]
  209.     mov        si,offset blankRet+1
  210.     mov        ax,'  '
  211.     mov        word ptr [si],ax
  212.     mov        ax,ticks
  213.     dec        ax
  214.     mov        ticks,ax
  215.     pushf
  216.     call        decimal     ;  seconds remaining
  217.     @VioWrtTTY    blankRet,4,0
  218.     popf
  219.     jnz        tick
  220.     @DosSemClear    timeExpired
  221. ;    @DosTimerStop    [timerHandle]
  222.     @DosExit    0,0
  223.  
  224. ticker    endp
  225.  
  226. ;-----------------------------------------------------------------------------
  227. ;
  228. ;    DECIMAL
  229. ;
  230. ;    Converts an unsigned decimal number from AX into ASCII in the
  231. ;    buffer addressed by SI.
  232. ;
  233. ;    Destroys contents of AX, CX, DX
  234. ;
  235. ;-----------------------------------------------------------------------------
  236.  
  237. decimal    proc
  238.     xor    dx,dx        ; Clear high-order 16 bits of dividend
  239.     mov    cx,10        ; Load divisor
  240.     div    cx        ; Quotient to AX, remainder to DX
  241.     or    ax,ax        ; Test quotient
  242.     jz    remain        ; If zero then just display the remainder
  243.     push    dx        ; Otherwise save the remainder while we
  244.     call    decimal        ;  deal with the quotient
  245.     pop    dx        ; Recover the remainder
  246. remain:
  247.     add    dl,'0'        ; Convert remainder to a decimal digit
  248.     mov    [si],dl
  249.     inc    si
  250.     ret
  251.  
  252. decimal    endp
  253.  
  254.     .stack    160
  255.  
  256.     end    start
  257.