home *** CD-ROM | disk | FTP | other *** search
- page 64,132
-
- ;Copyright 1986, Arnold B. Krueger
- ;All rights reserved. Contact "ARNY KRUEGER"
- ;at the EXEC-PC BBS (414-964-5160) for permission
- ;to use commercially.
-
- ;SETREAD reads the keyboard and places what it reads into the
- ;environment variable READSTR. Usage is:
- ;
- ; SETREAD [flags] [name] [flags]
- ;
- ; "name" is the name of the environment variable set.
- ; if none is supplied then READSTR is used.
- ;
- ;flags are: /U - make input upper case
- ; /L - make input lower case
- ; /F - read a single keystroke
- ; honors typewriter keys, f1-f9
- ;
- ;You can then refer to the named string in .BAT files
- ; using its name delimited by percent signs ('%').
- ;
- ;For example:
- ; Echo name of program to run:
- ; SETREAD
- ; echo running: %readstr%
- ; %readstr%
-
- ;errorlevels are:
- ; 0 if all goes well
- ; 0 if the environment is out of space
- ; (an error message will be typed by DOS)
- ; 1 not at DOS 2.0 or above
- ; 2 for SETREAD detected errors:
- ; (an error message will be typed)
- ; 3 for reading a null string
- ; (no error message or alteration
- ; of the environment)
- ; 4 for ctrl-break
- ; (no error message or alteration
- ; of the environment)
-
- code_seg segment para public
- assume cs:code_seg,ds:code_seg,ss:code_seg,es:code_seg
- extrn env_set:near
- org 80h
- psp_parml db ? ;length of parms
- psp_parm db ? ;actual parms
-
- org 100h ; .COM file format
- main: jmp main_start ; Skip around data declarations
- copyright db 'Copyright 1986, Arnold B. Krueger GPW, MI 48236'
-
- beep equ 07
- cr equ 13
- escape equ 27
- lf equ 10
-
- set_string db 'READSTR'
- set_length equ $-set_string
-
- release_error db 1,'Need at least DOS 2.0 to run SETREAD',cr,lf,'$'
- set_error db 2
- crlf db cr,lf,'$'
-
- scan_for_word proc near ;proc to scan es:di for contents of AX
- ; CX is length
- ;at exit if found: es:di points to word
- ; cf is set
- ; cx as at entry
- ; not found es:di points to string
- ; cf not set
- push cx ; cx as at entry
- push di
- cmp cx,2
- jb scan_for_miss
-
- scan_for_loop: scasw ;compare word to AX
- jz scan_for_hit
- dec di ;back up a byte
- loop scan_for_loop
-
- pop di ;missed it
- pop cx
- scan_for_miss:
- clc ;set not found flag
- jmp scan_for_exit
- scan_for_hit: ;back up over string
- dec di
- dec di
- pop cx ;actually di data
- pop cx
- stc ;set found flag
-
- scan_for_exit: ret
- scan_for_word endp
-
- scan_switches_switch db 0 ;flag byte checked, as follows:
-
- scan_switches_switches: ;list of switches searched for
- db '/u'
- switch_upper equ 40h ;translate to upper case
- db switch_upper
-
- db '/l'
- switch_lower equ 20h ;translate to lower case
- db switch_lower
-
- db '/f'
- switch_fkey equ 10h ;accept as input a single keystroke
- db switch_fkey
-
- switch_list_length equ $-scan_switches_switches
- switch_count equ switch_list_length / 3
-
- scan_switches proc near ;scan parameters for switches
- push ax ; Switches are defined above as word of text
- push cx ; and byte containing switch bit(s)
- push di ; Switch text is blanked out of parameter
- push es ; If switch byte has hi bit turned on,
- push si ; switch bit(s) are turned off
-
- mov cx,switch_count ;number of switches to test for
- push cs ;get PSP address
- pop es ; in ES
- mov si,offset scan_switches_switches
- scan_switches_loop:
- push cx ;save loop counter
- lodsw ;get flag to scan for into AX
- cmp ah,'Z' ;are we scanning for lower case?
- ja scan_lower ;if so, great
- ;protect me from sloppy programmers (!)
- or ah,32 ;if not, make lower.
- scan_lower:
- mov di,offset psp_parm ;get where to scan
- xor cx,cx
- mov cl,[psp_parml] ;get length of parm string
- jcxz scan_switches_none ;if no parms, no flags set
-
- call scan_for_word ;scan for indicated flag
- jc scan_case ;if we got it, modify switches
-
- and ah,255-32 ;make upper case
- call scan_for_word ;scan for indicated flag in upper case
-
- scan_case:
- lodsb ;put flag byte value in AL
- jnc scan_switches_loop_inc ;skip including it, if not found
-
- test al,80h ;if hi bit of flag is off
- jz scan_turn_on ;we are turning switch bits on
- ;otherwise, turn them off by:
-
- xor al,0ffh ;invert bits in flag
- and scan_switches_switch,al ;and use to turn off switch bits
- jmp scan_blank
-
- scan_turn_on:
- or scan_switches_switch,al ;add into switch bit into switch byte
- scan_blank:
- mov es:[di],' ' ;blank out parm
- scan_switches_loop_inc:
- pop cx ;restore loop counter
- loop scan_switches_loop
-
- jmp scan_switches_exit
-
- scan_switches_none:
- pop cx ;clean up stack
- scan_switches_exit:
- pop si
- pop es
- pop di
- pop cx
- pop ax
- ret
- scan_switches endp
-
- read_byte proc near ;read single byte into area at ds:di
- ;return length of symbol in cx
- push ax ;save registers
- push dx
- read_byte_in:
- mov ah,08h ;dos int to read a key, no echo
- int 21h
- cmp al,0 ;scan code returned?
- jnz read_byte_text
- int 21h ;get scan code
- sub al,59-1 ;F1 = 1
- jb read_byte_again
-
- cmp al,9 ;F9 = 9
- ja read_byte_again ;anything else:error
-
- add al,030h ;make it a number
- mov byte ptr ds:[di],'F'
- mov ds:[di+1],al
- mov cx,2
- jmp read_byte_exit
- read_byte_again:
- mov ah,02 ;unrecognized key
- mov dl,beep ;complain audibly!
- int 21h
- jmp read_byte_in
-
- read_byte_text:
- cmp al,cr ;read a cr?
- je read_byte_again
- mov ds:[di],al
- mov cx,1
- read_byte_exit:
- pop dx
- pop ax
- ret
- read_byte endp
-
- read_string proc near ;read string into area at ds:di
- ;max permissable length in cx
- ;return length actually read in cx
-
- sub di,2 ; back up two bytes
- mov bx,ds:[di] ; save word in buffer
- mov ds:[di],cl ; store out length
- mov dx,di ; get what to use
- mov ah,0ah ; buffered keyboard input
- int 21h ; do the deed
-
- mov dx,offset crlf ; type cr,lf to acknowlege read
- mov ah,9h
- int 21h
-
- mov cl,ds:[di+1] ; get length
- xor ch,ch ; zero ch
-
- mov ds:[di],bx ; restore buffer
- add di,2 ; restore di
- ret
-
- read_string endp
-
-
-
- main_start:
- mov dx,offset ctrl_break; Set Ctrl-Break exit
- mov ax,2523h ; DOS resets it for me when I end
- int 21h
-
- mov ah,30h ; get dos release number
- int 21h
- cmp al,1 ; above release 1.x
- ja main_parm ; if not, don't go on.
-
- mov si,offset release_error
- jmp error_exit
-
- main_parm:
- call scan_switches ; test parms for switches
-
- cld
- xor cx,cx
- mov cl,psp_parml ; get length of parm
- mov di,offset psp_parm ; look at passed parms
- jcxz main_add_name ; if no parms, set default name: READSTR
-
- mov al,' ' ; scan for non-blank
- repz scasb ; chop off leading blanks
- je main_add_name ; if all blanks, use default name
-
- dec di ; back up over non-blank
- inc cx
- repnz scasb ; scan for blank
- jne main_add_equals ; none found, just add equals
-
- dec di ; back up over blank
- jmp main_add_equals ; and add '='
-
-
- main_add_name:
- mov di,offset psp_parm ; put at start of string
- mov cx,set_length ; how much to move
- mov si,offset set_string; get READSTR
- rep movsb ; into my PSP
-
- main_add_equals:
- mov al,'=' ; tack on equals sign
- stosb
-
- mov cx,offset main ; get end of parms string+1
- sub cx,di ; subtract to get avail. length
-
- test scan_switches_switch,switch_fkey
- jz main_read_string
-
- call read_byte
- jmp main_string_read_ok
-
- main_read_string:
- call read_string ; read data into ds:di, length in cx
- jcxz main_null ; if null string read, quit
-
- main_string_read_ok:
- ; case alteration dept
- mov si,di ; where to get
-
- case_loop:
- lodsb
- test scan_switches_switch,switch_upper+switch_lower
- jz case_join ; if no alterations, exit
-
- cmp al,'z' ; alphabetic?
- ja case_join
- cmp al,'A'
- jb case_join
-
- test scan_switches_switch,switch_lower
- jz case_upper
-
- or al,32 ; make lower case
- jmp case_join
-
- case_upper:
- test scan_switches_switch,switch_upper
- jz case_join
-
- and al,255-32 ; make upper case
- case_join:
- stosb
- loop case_loop
-
- mov ax,di ; where we put last byte
- sub ax,offset psp_parm ; minus where we started gives length
- mov psp_parml,al ; store out
-
- mov si,offset psp_parml ; where to set from
-
- call env_set ; modify set string
-
- mov si,offset set_error ; set errorlevel
- mov set_error,2 ; errorlevel=2
- jc error_exit
- xor al,al
- jmp exit
-
- ctrl_break: ; ctrl-break detected
- mov si,offset set_error
- mov set_error,4 ; errorlevel=4
- jmp error_exit
-
- main_null: ; null string read
- mov si,offset set_error
- mov set_error,3 ; errorlevel=3
-
- error_exit:
- lodsb ; reset al with errorlevel
- push ax ; save it
- mov dx,si ; get start of message
- mov ah,9h ; type it out
- int 21h
- pop ax ; reset al with errorlevel
-
- exit:
- mov ah,4ch ; terminate program, set errorlevel from al
- int 21h
-
-
- endcode equ $
-
- code_seg ends
- end main