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