home *** CD-ROM | disk | FTP | other *** search
/ Multimedia & CD-ROM 3 / mmcd03-jun1995-cd.iso / utils / various / utils-1 / batchkey.asm < prev    next >
Assembly Source File  |  1991-06-24  |  11KB  |  256 lines

  1. ;****************************************************************************
  2. ; BATCHKEY allows batch files to get keyboard input.  Its syntax is:
  3. ;
  4. ;       BATCHKEY [keylist]
  5. ;
  6. ; where keylist is an optional list of accepted values.  If no list is
  7. ; supplied, BATCHKEY returns the ASCII code of any key that is pressed in
  8. ; ERRORLEVEL (extended key codes return 0).  If a list is supplied,
  9. ; BATCHKEY returns an ERRORLEVEL value that reflects the key's position in
  10. ; the list.  An ERRORLEVEL value of 255 means the key code entered was not
  11. ; one of those in the list.
  12. ;
  13. ; Keylist values can be entered in three forms:
  14. ;
  15. ;       Literal          "Y"    Y key
  16. ;       ASCII code       13     Enter key
  17. ;       Extended code   (59)    Function key F1
  18. ;
  19. ; Literal values are not case-sensitive.  Thus, the command
  20. ;
  21. ;       BATCHKEY "YN" 27 13 (59)
  22. ;
  23. ; would return 1 if "Y" or "y" was pressed, 2 if "N" or "n" was pressed,
  24. ; 3 if Esc (ASCII 27) was pressed, 4 if Enter (ASCII 13) was pressed, 5 
  25. ; if function key F1 was pressed, or 255 if any other key was pressed.
  26. ;****************************************************************************
  27.  
  28. code            segment
  29.                 assume  cs:code,ds:code
  30.                 org     100h
  31. begin:          jmp     main
  32.  
  33. msg             db      13,10,"Invalid parameter",13,10,"$"
  34. buffer          db      64 dup (?)
  35. keyflags        db      64 dup (0)
  36. keycount        dw      ?
  37.  
  38. ;****************************************************************************
  39. ; Procedure MAIN
  40. ;****************************************************************************
  41.  
  42. main            proc    near
  43.                 cld                             ;Clear direction flag
  44.                 sub     cx,cx                   ;Initialize count in CX
  45.                 mov     di,offset buffer        ;Initialize SI and DI
  46.                 mov     si,81h
  47.                 call    findchar                ;Advance to first character
  48.                 jnc     main2
  49. ;
  50. ; No key list was entered.  Return the ASCII code of the first key pressed.
  51. ;
  52. main0:          mov     ah,08h                  ;Read the keyboard
  53.                 int     21h
  54.                 or      al,al                   ;Exit if AL is not 0
  55.                 jnz     main1
  56.                 mov     bl,al                   ;Save key code
  57.                 mov     ah,08h                  ;Read extended key code
  58.                 int     21h
  59.                 mov     al,bl                   ;Retrieve original code
  60. main1:          mov     ah,4Ch                  ;Exit with key code in AL
  61.                 int     21h
  62. ;
  63. ; Parse the command line and build the key list.
  64. ;
  65. main2:          lodsb                           ;Get a character
  66.                 cmp     al,28h                  ;Branch if "("
  67.                 je      extended
  68.                 cmp     al,22h                  ;Branch if quotation mark
  69.                 jne     ascii
  70. ;
  71. ; Process a string of literal key codes
  72. ;
  73. literal:        lodsb                           ;Get a character
  74.                 cmp     al,22h                  ;Exit when closing quotation
  75.                 je      nextchar                ;  mark is encountered
  76.                 cmp     al,0Dh                  ;Error if EOL
  77.                 je      error
  78.                 call    lc2cap                  ;Capitalize the character
  79.                 stosb                           ;Store it in the ley list
  80.                 inc     cx                      ;Increment count
  81.                 jmp     literal                 ;Loop back for more
  82. ;
  83. ; Process an extended key code entry
  84. ;
  85. extended:       call    asc2bin                 ;ASCII => binary
  86.                 jnc     error                   ;Exit on error
  87.                 cmp     bl,29h                  ;Error if ")" not found
  88.                 jne     error
  89.                 stosb                           ;Store the key code
  90.                 inc     si                      ;Advance SI beyond ")"
  91.                 inc     cx                      ;Increment count
  92.                 push    di                      ;Set flag indicating this
  93.                 dec     di                      ;  is an extended key
  94.                 sub     di,offset buffer        ;  code
  95.                 add     di,offset keyflags
  96.                 mov     byte ptr [di],1
  97.                 pop     di
  98.                 jmp     short nextchar          ;Continue
  99. ;
  100. ; Process an ASCII key code entry
  101. ;
  102. ascii:          dec     si                      ;Decrement SI
  103.                 call    asc2bin                 ;ASCII => binary
  104.                 jc      error                   ;Exit on error
  105.                 call    lc2cap                  ;Capitalize the character
  106.                 stosb                           ;Store it in the key list
  107.                 inc     cx                      ;Increment count
  108. ;
  109. ; Advance to the next character
  110. ;
  111. nextchar:       call    findchar                ;Advance to next character
  112.                 jnc     main2                   ;Loop back if found
  113. ;
  114. ; Read a key code and check for extended key codes.
  115. ;
  116.                 jcxz    main0                   ;Exit if no codes entered
  117.                 mov     keycount,cx             ;Save count
  118.                 mov     si,offset buffer        ;Initialize SI and DI
  119.                 mov     di,offset keyflags
  120.                 mov     ah,08h                  ;Read the keyboard
  121.                 int     21h
  122.                 or      al,al                   ;Branch if extended key
  123.                 jz      exonly                  ;  code
  124. ;
  125. ; Search the list for conventional key codes.
  126. ;
  127.                 call    lc2cap                  ;Capitalize the character
  128.                 mov     bl,al                   ;Save it in BL
  129. search1:        mov     al,[di]                 ;Get flag for next code
  130.                 inc     di
  131.                 or      al,al                   ;Branch if extended code
  132.                 jnz     next1
  133.                 mov     al,[si]                 ;Test key code against list
  134.                 cmp     al,bl
  135.                 je      match                   ;Exit on match
  136. next1:          inc     si                      ;Otherwise loop back for more
  137.                 loop    search1
  138.  
  139.                 jmp     short nomatch           ;No match if search exhausted
  140.  
  141. ;
  142. ; Search the list for extended key codes.
  143. ;
  144. exonly:         mov     ah,08h                  ;Read extended code
  145.                 int     21h
  146.                 mov     bl,al                   ;Save it in BL
  147. search2:        mov     al,[di]                 ;Get flag for next code
  148.                 inc     di
  149.                 or      al,al                   ;Branch if not extended code
  150.                 jz      next2
  151.                 mov     al,[si]                 ;Test key code against list
  152.                 cmp     al,bl
  153.                 je      match                   ;Exit on match
  154. next2:          inc     si                      ;Otherwise loop back for more
  155.                 loop    search2
  156. ;
  157. ; No match was found.
  158. ;
  159. nomatch:        mov     ax,4C00h                ;Exit with ERRORLEVEL=0
  160.                 int     21h
  161. ;
  162. ;An error was encountered while parsing the command line.
  163. ;
  164. error:          mov     ah,09h                  ;Display error message
  165.                 mov     dx,offset msg
  166.                 int     21h
  167.                 jmp     nomatch                 ;Exit with ERRORLEVEL=255
  168. ;
  169. ; A match was found.
  170. ;
  171. match:          mov     ax,keycount             ;Set ERRORLEVEL and exit
  172.                 sub     ax,cx
  173.                 inc     al
  174.                 mov     ah,4Ch
  175.                 int     21h
  176. main            endp
  177.  
  178. ;****************************************************************************
  179. ; FINDCHAR advances SI to the next non-space or non-comma character.
  180. ; On return, carry set indicates EOL was encountered.
  181. ;****************************************************************************
  182.  
  183. findchar        proc    near
  184.                 lodsb                           ;Get the next character
  185.                 cmp     al,20h                  ;Loop if space
  186.                 je      findchar
  187.                 cmp     al,2Ch                  ;Loop if comma
  188.                 je      findchar
  189.                 dec     si                      ;Point SI to the character
  190.                 cmp     al,0Dh                  ;Exit with carry set if end
  191.                 je      eol                     ;  of line is reached
  192.  
  193.                 clc                             ;Clear carry and exit
  194.                 ret
  195.  
  196. eol:            stc                             ;Set carry and exit
  197.                 ret
  198. findchar        endp
  199.  
  200. ;****************************************************************************
  201. ; ASC2BIN converts a decimal number entered in ASCII form into a binary
  202. ; value in AL.  Carry set on return indicates that an error occurred in
  203. ; the conversion.
  204. ;****************************************************************************
  205.  
  206. asc2bin         proc    near
  207.                 sub     ax,ax                   ;Initialize registers
  208.                 sub     bh,bh
  209.                 mov     dl,10
  210.  
  211. a2b_loop:       mov     bl,[si]                 ;Get a character
  212.                 inc     si
  213.                 cmp     bl,20h                  ;Exit if space
  214.                 je      a2b_exit
  215.                 cmp     bl,2Ch                  ;Exit if comma
  216.                 je      a2b_exit
  217.                 cmp     bl,0Dh                  ;Exit if carriage return
  218.                 je      a2b_exit
  219.  
  220.                 cmp     bl,"0"                  ;Error if character is not
  221.                 jb      a2b_error               ;  a number
  222.                 cmp     bl,"9"
  223.                 ja      a2b_error
  224.  
  225.                 mul     dl                      ;Multiply the value in AL by
  226.                 jc      a2b_error               ;  10 and exit on overflow
  227.                 sub     bl,30h                  ;ASCII => binary
  228.                 add     ax,bx                   ;Add latest value to AX
  229.                 cmp     ax,255                  ;Error if sum > 255
  230.                 jna     a2b_loop                ;Loop back for more
  231.  
  232. a2b_error:      dec     si                      ;Set carry and exit
  233.                 stc
  234.                 ret
  235.  
  236. a2b_exit:       dec     si                      ;Clear carry and exit
  237.                 clc
  238.                 ret
  239. asc2bin         endp
  240.  
  241. ;****************************************************************************
  242. ; LC2CAP capitalizes the ASCII code in AL
  243. ;****************************************************************************
  244.  
  245. lc2cap          proc    near
  246.                 cmp     al,"a"                  ;Exit if less than "a"
  247.                 jb      l2c_exit
  248.                 cmp     al,"z"                  ;Exit if greater than "z"
  249.                 ja      l2c_exit
  250.                 and     al,0DFh                 ;Capitalize
  251. l2c_exit:       ret
  252. lc2cap          endp
  253.  
  254. code            ends
  255.                 end     begin
  256.