home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / USCX / SETPGMS.ZIP / SETREAD.ASM < prev    next >
Assembly Source File  |  1986-12-26  |  14KB  |  371 lines

  1.                page     64,132
  2.  
  3.                ;Copyright 1986, Arnold B. Krueger
  4.                ;All rights reserved. Contact "ARNY KRUEGER"
  5.                ;at the EXEC-PC BBS (414-964-5160) for permission 
  6.                ;to use commercially.
  7.  
  8.                ;SETREAD reads the keyboard and places what it reads into the
  9.                ;environment variable READSTR. Usage is:
  10.                ;
  11.                ;              SETREAD  [flags] [name] [flags]
  12.                ;            
  13.                ;              "name" is the name of the environment variable set.
  14.                ;              if none is supplied then READSTR is used.
  15.                ;         
  16.                ;flags are: /U - make input upper case
  17.                ;           /L - make input lower case
  18.                ;           /F - read a single keystroke
  19.                ;                honors typewriter keys, f1-f9
  20.                ;
  21.                ;You can then refer to the named string in .BAT files
  22.                ;    using its name delimited by percent signs ('%').
  23.                ;   
  24.                ;For example: 
  25.                ;     Echo name of program to run:
  26.                ;     SETREAD  
  27.                ;     echo  running: %readstr%
  28.                ;     %readstr%
  29.  
  30.                ;errorlevels are:
  31.                ;               0  if all goes well
  32.                ;               0  if the environment is out of space
  33.                ;                  (an error message will be typed by DOS)
  34.                ;               1  not at DOS 2.0 or above
  35.                ;               2  for SETREAD detected errors:
  36.                ;                        (an error message will be typed)
  37.                ;               3  for reading a null string
  38.                ;                        (no error message or alteration
  39.                ;                         of the environment)
  40.                ;               4  for ctrl-break
  41.                ;                        (no error message or alteration
  42.                ;                         of the environment)
  43.  
  44. code_seg       segment para public 
  45.                assume  cs:code_seg,ds:code_seg,ss:code_seg,es:code_seg
  46.                extrn   env_set:near
  47.                org     80h
  48. psp_parml      db      ?                    ;length of parms
  49. psp_parm       db      ?                    ;actual parms
  50.  
  51.                org     100h                 ; .COM file format
  52. main:          jmp     main_start           ; Skip around data declarations
  53. copyright      db      'Copyright 1986, Arnold B. Krueger GPW, MI 48236'
  54.  
  55. beep           equ     07
  56. cr             equ     13
  57. escape         equ     27
  58. lf             equ     10
  59.  
  60. set_string     db      'READSTR'
  61. set_length     equ     $-set_string
  62.  
  63. release_error  db    1,'Need at least DOS 2.0 to run SETREAD',cr,lf,'$'
  64. set_error      db    2
  65. crlf           db    cr,lf,'$'
  66.  
  67. scan_for_word   proc near           ;proc to scan es:di for contents of AX
  68.                                     ;   CX is length
  69.                                     ;at exit if found:  es:di points to word
  70.                                     ;                   cf is set
  71.                                     ;                   cx as at entry
  72.                                     ;        not found  es:di points to string
  73.                                     ;                   cf  not set
  74.                 push cx             ;                   cx as at entry
  75.                 push di 
  76.                 cmp  cx,2
  77.                 jb   scan_for_miss
  78.  
  79. scan_for_loop:  scasw               ;compare word to AX
  80.                 jz    scan_for_hit
  81.                 dec   di            ;back up a byte
  82.                 loop  scan_for_loop
  83.  
  84.                 pop   di            ;missed it
  85.                 pop   cx
  86. scan_for_miss:
  87.                 clc                 ;set not found flag
  88.                 jmp   scan_for_exit
  89. scan_for_hit:                       ;back up over string
  90.                 dec   di
  91.                 dec   di
  92.                 pop   cx            ;actually di data
  93.                 pop   cx
  94.                 stc                 ;set found flag
  95.  
  96. scan_for_exit:  ret
  97. scan_for_word   endp
  98.  
  99. scan_switches_switch     db  0     ;flag byte checked, as follows:
  100.  
  101. scan_switches_switches:            ;list of switches searched for
  102.                     db  '/u'
  103. switch_upper        equ 40h        ;translate to upper case
  104.                     db  switch_upper   
  105.  
  106.                     db  '/l'
  107. switch_lower        equ 20h        ;translate to lower case
  108.                     db  switch_lower
  109.  
  110.                     db  '/f'
  111. switch_fkey         equ 10h        ;accept as input a single keystroke
  112.                     db  switch_fkey
  113.  
  114. switch_list_length  equ  $-scan_switches_switches
  115. switch_count        equ  switch_list_length / 3 
  116.  
  117. scan_switches   proc  near          ;scan parameters for switches
  118.                 push  ax            ; Switches are defined above as word of text
  119.                 push  cx            ;       and byte containing switch bit(s)
  120.                 push  di            ; Switch text is blanked out of parameter
  121.                 push  es            ; If switch byte has hi bit turned on,
  122.                 push  si            ;       switch bit(s) are turned off
  123.  
  124.                 mov   cx,switch_count     ;number of switches to test for
  125.                 push  cs                  ;get PSP address
  126.                 pop   es                  ;    in ES
  127.                 mov   si,offset scan_switches_switches
  128. scan_switches_loop:
  129.                 push  cx                  ;save loop counter
  130.                 lodsw                     ;get flag to scan for into AX
  131.                 cmp   ah,'Z'              ;are we scanning for lower case?
  132.                 ja    scan_lower          ;if so, great
  133.                                           ;protect me from sloppy programmers (!)
  134.                 or    ah,32               ;if not, make lower.
  135. scan_lower: 
  136.                 mov   di,offset psp_parm  ;get where to scan
  137.                 xor   cx,cx
  138.                 mov   cl,[psp_parml]      ;get length of parm string
  139.                 jcxz  scan_switches_none  ;if no parms, no flags set
  140.  
  141.                 call  scan_for_word       ;scan for indicated flag
  142.                 jc    scan_case           ;if we got it, modify switches
  143.  
  144.                 and   ah,255-32           ;make upper case
  145.                 call  scan_for_word       ;scan for indicated flag in upper case
  146.  
  147. scan_case:
  148.                 lodsb                     ;put flag byte value in AL
  149.                 jnc   scan_switches_loop_inc ;skip including it, if not found
  150.  
  151.                 test  al,80h              ;if hi bit of flag is off
  152.                 jz    scan_turn_on        ;we are turning switch bits on
  153.                                           ;otherwise, turn them off by:
  154.  
  155.                 xor   al,0ffh             ;invert bits in flag     
  156.                 and   scan_switches_switch,al  ;and use to turn off switch bits
  157.                 jmp   scan_blank
  158.  
  159. scan_turn_on:
  160.                 or    scan_switches_switch,al  ;add into switch bit into switch byte
  161. scan_blank:
  162.                 mov   es:[di],'  '        ;blank out parm
  163. scan_switches_loop_inc:
  164.                 pop   cx                  ;restore loop counter
  165.                 loop  scan_switches_loop
  166.  
  167.                 jmp   scan_switches_exit
  168.  
  169. scan_switches_none:
  170.                 pop   cx                  ;clean up stack
  171. scan_switches_exit:
  172.                 pop   si
  173.                 pop   es
  174.                 pop   di
  175.                 pop   cx
  176.                 pop   ax
  177.                 ret
  178. scan_switches   endp
  179.  
  180. read_byte       proc near                ;read single byte into area at ds:di
  181.                                          ;return length of symbol in cx
  182.                 push  ax                 ;save registers
  183.                 push  dx
  184. read_byte_in:
  185.                 mov  ah,08h              ;dos int to read a key, no echo
  186.                 int  21h
  187.                 cmp  al,0                ;scan code returned?
  188.                 jnz  read_byte_text
  189.                 int  21h                 ;get scan code
  190.                 sub  al,59-1             ;F1 = 1
  191.                 jb   read_byte_again
  192.  
  193.                 cmp  al,9                ;F9 = 9
  194.                 ja   read_byte_again     ;anything else:error
  195.  
  196.                 add  al,030h             ;make it a number
  197.                 mov  byte ptr ds:[di],'F'
  198.                 mov  ds:[di+1],al
  199.                 mov  cx,2
  200.                 jmp  read_byte_exit
  201. read_byte_again:
  202.                 mov  ah,02               ;unrecognized key
  203.                 mov  dl,beep             ;complain audibly!
  204.                 int  21h
  205.                 jmp  read_byte_in
  206.  
  207. read_byte_text:
  208.                 cmp  al,cr               ;read a cr?
  209.                 je   read_byte_again
  210.                 mov  ds:[di],al
  211.                 mov  cx,1
  212. read_byte_exit:
  213.                 pop  dx
  214.                 pop  ax
  215.                 ret
  216. read_byte       endp
  217.  
  218. read_string proc near                ;read string into area at ds:di
  219.                                      ;max permissable length in cx
  220.                                      ;return length actually read in cx
  221.  
  222.         sub      di,2                ; back up two bytes
  223.         mov      bx,ds:[di]          ; save word in buffer
  224.         mov      ds:[di],cl          ; store out length
  225.         mov      dx,di               ; get what to use
  226.         mov      ah,0ah              ; buffered keyboard input
  227.         int      21h                 ; do the deed
  228.  
  229.         mov      dx,offset crlf      ; type cr,lf to acknowlege read
  230.         mov      ah,9h               
  231.         int      21h
  232.  
  233.         mov      cl,ds:[di+1]        ; get length 
  234.         xor      ch,ch               ; zero ch
  235.  
  236.         mov      ds:[di],bx          ; restore buffer
  237.         add      di,2                ; restore di
  238.         ret
  239.  
  240. read_string endp
  241.  
  242.  
  243.  
  244. main_start:
  245.         mov      dx,offset ctrl_break; Set Ctrl-Break exit
  246.         mov      ax,2523h            ; DOS resets it for me when I end
  247.         int      21h
  248.  
  249.         mov      ah,30h              ; get dos release number
  250.         int      21h               
  251.         cmp      al,1                ; above release 1.x
  252.         ja       main_parm           ; if not, don't go on.
  253.  
  254.         mov      si,offset release_error
  255.         jmp      error_exit
  256.  
  257. main_parm:
  258.         call     scan_switches       ; test parms for switches
  259.  
  260.         cld
  261.         xor      cx,cx
  262.         mov      cl,psp_parml        ; get length of parm
  263.         mov      di,offset psp_parm  ; look at passed parms
  264.         jcxz     main_add_name       ; if no parms, set default name: READSTR
  265.  
  266.         mov      al,' '              ; scan for non-blank
  267.         repz     scasb               ; chop off leading blanks
  268.         je       main_add_name       ; if all blanks, use default name
  269.  
  270.         dec      di                  ; back up over non-blank
  271.         inc      cx
  272.         repnz    scasb               ; scan for blank
  273.         jne      main_add_equals     ; none found, just add equals
  274.  
  275.         dec      di                  ; back up over blank
  276.         jmp      main_add_equals     ; and add '='
  277.  
  278.  
  279. main_add_name:
  280.         mov      di,offset psp_parm  ; put at start of string
  281.         mov      cx,set_length       ; how much to move
  282.         mov      si,offset set_string; get  READSTR
  283.         rep      movsb               ; into my PSP
  284.  
  285. main_add_equals:
  286.         mov      al,'='              ; tack on equals sign
  287.         stosb
  288.  
  289.         mov      cx,offset main      ; get end of parms string+1
  290.         sub      cx,di               ; subtract to get avail. length
  291.  
  292.         test     scan_switches_switch,switch_fkey
  293.         jz       main_read_string
  294.  
  295.         call     read_byte
  296.         jmp      main_string_read_ok
  297.  
  298. main_read_string:
  299.         call     read_string         ; read data into ds:di, length in cx
  300.         jcxz     main_null           ; if null string read, quit
  301.  
  302. main_string_read_ok:
  303.                                      ; case alteration dept
  304.         mov      si,di               ; where to get
  305.  
  306. case_loop:
  307.         lodsb
  308.         test     scan_switches_switch,switch_upper+switch_lower
  309.         jz       case_join           ; if no alterations, exit
  310.  
  311.         cmp      al,'z'              ; alphabetic?
  312.         ja       case_join
  313.         cmp      al,'A'
  314.         jb       case_join
  315.  
  316.         test     scan_switches_switch,switch_lower
  317.         jz       case_upper
  318.  
  319.         or       al,32               ; make lower case
  320.         jmp      case_join
  321.  
  322. case_upper:
  323.         test     scan_switches_switch,switch_upper
  324.         jz       case_join
  325.  
  326.         and      al,255-32           ; make upper case
  327. case_join:
  328.         stosb
  329.         loop    case_loop
  330.  
  331.         mov     ax,di                ; where we put last byte
  332.         sub     ax,offset psp_parm   ; minus where we started gives length
  333.         mov     psp_parml,al         ; store out
  334.  
  335.         mov     si,offset psp_parml  ; where to set from
  336.  
  337.         call    env_set              ; modify set string
  338.  
  339.         mov     si,offset set_error  ; set errorlevel 
  340.         mov     set_error,2          ; errorlevel=2       
  341.         jc      error_exit
  342.         xor     al,al
  343.         jmp     exit
  344.  
  345. ctrl_break:                          ; ctrl-break detected
  346.         mov     si,offset set_error  
  347.         mov     set_error,4          ; errorlevel=4       
  348.         jmp     error_exit
  349.  
  350. main_null:                           ; null string read
  351.         mov     si,offset set_error  
  352.         mov     set_error,3          ; errorlevel=3
  353.  
  354. error_exit:
  355.         lodsb                        ; reset al with errorlevel
  356.         push   ax                    ; save it
  357.         mov    dx,si                 ; get start of message
  358.         mov    ah,9h                 ; type it out
  359.         int    21h
  360.         pop    ax                    ; reset al with errorlevel
  361.  
  362. exit:
  363.         mov    ah,4ch                ; terminate program, set errorlevel from al
  364.         int    21h
  365.  
  366.  
  367. endcode equ    $
  368.  
  369. code_seg   ends
  370.            end    main
  371.