home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
batutl
/
echsys10.arc
/
ENVSYS.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-09-25
|
25KB
|
600 lines
; EnvSys : put current system data (drive, dir, time, date etc)
; into an environment variable named first on the command line
;
; Version 1.0
;
; Free Software by TapirSoft Gisbert W.Selke, Sept 1989
;
; The environment setting stuff is
; Copyright 1987, A. B. Krueger GPW MI 48236
; All rights reserved. Contact "ARNY KRUEGER"
; at the EXEC-PC BBS (414-964-5160) for permission
; to use commercially.
;
; Otherwise, this programme may be used and copied any way you wish, but don't
; sell it. Give credit where credit is due, please. - The copyright remains
; with me and Arny; I do not guarantee proper operation of this utility; the
; whole risk of use lies with the user.
;
; Usage: envsys <varname> <string>
; String is put into an environment variable named varname;
; two-char sequences introduced by '^' are replaced as indicated
; at 'Usage' below.
;
; TASM envsys or MASM envsys
; TLINK /t envsys LINK envsys
; EXEBIN envsys.exe envsys.com
BackSpace Equ 08h
LineFeed Equ 0Ah
Return Equ 0Dh
CtrlZ Equ 1Ah
StuffChar Macro Chr ; macro to put a character
Push ax
Mov al, Chr ; into the env string
Call StuffIt
Pop ax
Endm
Jmps Macro Label ; Jump short
Jmp short Label
Endm
cseg Segment para public
Extrn env_set:near,DirString:byte,TimeBuf:byte,DateBuf:byte
Extrn OutLine:byte,OurStack:byte,ProgEnd:byte
Org 0080h
Parameter Db ?
Org 100h
Assume cs:cseg, ds:cseg, es:cseg, ss:cseg
Start: Jmp Begin
db 'SPECIAL='
Special db '^'
db Return
Copyright db 'EnvSys 1.0 - Free software by TapirSoft'
db ' Gisbert W.Selke, Sept 89', Return, LineFeed
db 'Parts copyright 1987, A. B. Krueger GPW MI 48236. '
db Return, LineFeed
db 'Use at your own risk.$', BackSpace, ' '
db Return, LineFeed, CtrlZ
Usage1 db Return, LineFeed, LineFeed
db 'Usage: envsys <varname> <string>', Return, LineFeed
db 'The string is put into the named environment '
db 'variable', Return, LineFeed
db 'with "$'
Usage2 db '@" replaced as indicated by @:', Return, LineFeed
db ': drive; \ directory; F free disk space; '
db 'T total disk space; R free RAM;', Return, LineFeed
db 'r RAM size; l #drives; f #floppies; P #printers; '
db 'S #serial ports;', Return, Linefeed
db '7 coprocessor? L LPT1 status; V video mode; '
db 'w screen width; t type of PC;', Return, LineFeed
db 'v DOS version; b BIOS version; i "<" symbol; '
db 'o ">" symbol; p "|" symbol; ', Return, LineFeed
db 'O switch char; A author''s note; '
db 'x char given by next 2 hex digits;', Return, LineFeed
db 'K key typed by user; C country code; $'
Usage3 db ' currency string;', Return, LineFeed
db 'k 1000s separator; 1 decimal separator; '
db '/ date separator; - time separator;'
db Return, LineFeed
db 'D day; M month; Y year; W weekday; h hour; m minute; '
db 's second; c centisecond.'
db Return, LineFeed, Return, LineFeed, '$'
RetVal db 0
ModelString db '??80AP30??ATJRXTPC'
ModelStrLen Label Byte
CmdLetters db 'csmhWYMD-/1k$CpoiKxAObvtwVL7SPflRrTF\:';command letters
EndCmdLetters Label Word
; **NOTE**: order of CmdLetters and Dispatch is reversed w.r.t. each other!
Dispatch dw Drive, Directory, FreeSpace, TotalSpace, MemSize
dw FreeMem, LogicDrives, Floppies, Printers
dw CommPorts, Coproc, LptStat, VideoMode, VideoWidth
dw SysModel, DosVersion, BiosVersion, SwitchChar, Author
dw Hexnumber, KeyBoard
dw StdInSymbol, StdOutSymbol, PipeSymbol, CountryInfo
dw Currency, Thousands, Decimal, DateSep, TimeSep
dw Day, Month, Year, WeekDay
dw Hour, Minute, Second, CentiSecond
Begin: Mov sp, Offset OurStack ; point to our own stack
Mov ah, 2Ch ; get current time right now
Int 21h
Mov [TimeBuf], ch ; stow away
Mov [TimeBuf+1], cl
Mov [TimeBuf+2], dh
Mov [TimeBuf+3], dl
Mov ah, 2Ah ; get current date
Int 21h
Sub cx, 1900 ; remove centuries
Mov word ptr [DateBuf], cx ; stow away
Mov [DateBuf+2], dh
Mov [DateBuf+3], dl
Mov [DateBuf+4], al
Mov si, 1+offset Parameter ; command line string
Xor al, al
Mov [OutLine], al ; init environment line
FindName: Lodsb ; find first parameter,
Cmp al, Return ; i.e., name of env variable
Je ShowUsage
Cmp al, ' '
Je FindName
Cmp al, 09h
Je FindName
FindName2: Cmp al, Return ; stuff all its characters
Je EndName
Cmp al, ' '
Je EndName
Cmp al, 09h
Je EndName
Call StuffIt
Lodsb
Jmps FindName2
EndName: StuffChar '=' ; prepare to set it
Cmp al, Return
Je Done
; now parse command line proper
Cmp al, ' ' ; skip first char, if
Je NextChar ; blank or tab
Cmp al, 09h
Je NextChar
Cmp al, Return
Jne CheckSpecials
ShowUsage: Mov dx, offset Copyright ; show author's note
Mov ah, 09h
Int 21h
Mov dx, offset Usage1 ; show usage hints
Mov ah, 09h
Int 21h
Mov dl, [Special]
Mov ah, 02h
Int 21h
Mov dx, offset Usage2 ; more usage hints
Mov ah, 09h
Int 21h
Mov dl, '$'
Mov ah, 02h
Int 21h
Mov dx, offset Usage3 ; more usage hints
Mov ah, 09h
Int 21h
Mov ax, 4CFFh ; termination code
Int 21h
NextChar: Lodsb
Cmp al, Return ; are we done?
Jne CheckSpecials
Done: Mov si, offset OutLine ; point to env line
Call env_set ; set environment variable
Or [OutLine], 80h ; set high bit
Mov si, offset OutLine ; point to env line
Call env_set ; set environment variable
Mov ah, 4Ch ; terminate normally
Mov al, [RetVal] ; return code
Int 21h
CheckSpecials: Cmp al, Special ; is it special sequence?
Je DoSpecials
CheckSp2: Call StuffIt ; otherwise just stuff it
Jmps NextChar ; and loop
DoSpecials: Lodsb ; get next char of sequence
Mov di, offset CmdLetters ; look up in table
Mov cx, (offset EndCmdLetters) - (offset CmdLetters)
Repne Scasb
Jz DoSp2 ; jump if found
Cmp al, Return ; otherwise: are we done?
Je Done
Jmps CheckSp2 ; otherwise treat normal
DoSp2: Add cx, cx ; double for Word
Mov bx, cx
Call [dispatch+bx] ; call the subroutine
Jmps NextChar
Drive: Mov ah, 19h ; get current drive
Int 21h
Add al, 41h ; convert to ASCII
Mov [RetVal], al ; store for return
Call StuffIt ; and stuff it
StuffChar ':' ; and a colon
Ret
Directory: Mov cx, si ; save si
Mov si, offset DirString ; buffer for dir string
Xor dl, dl ; use current drive
Mov ah, 47h ; get directory string
Int 21h
StuffChar '\' ; initial backslash
ShowDirLoop: Lodsb ; get next byte
Or al, al ; is it terminating null?
Jz ShowDirEnd
Call StuffIt ; otherwise show char
Jmps ShowDirLoop ; and loop
ShowDirEnd: Mov si, cx ; restore si
Ret
FreeSpace: Mov ah, 36h ; get disk space
Xor dl, dl ; on default disk
Int 21h
Jmps ShowSpace
TotalSpace: Mov ah, 36h ; get disk space
Xor dl, dl ; on default disk
Int 21h
Mov bx, dx ; choose total clusters
ShowSpace: Mul cx ; dx:ax = bytes per cluster
Mov cx, 10 ; prepare conversion to kB
ShowSp2: Or dx, dx ; if dx > 0, shift it
Jz ShowSp3
Inc cl
Shr dx, 1
Rcr ax, 1
Jmps ShowSp2
ShowSp3: Mul bx ; multiply by clusters
ShowSp4: Shr dx, 1 ; divide by 1024
Rcr ax, 1
Loop ShowSp4
Mov cx, 1000 ; process high digits first
Div cx
Mov [RetVal], al ; save for return
Mov bx, dx ; save remainder
Xor dh, dh ; no minimum # of digits
Or ax, ax ; are there high digits?
Jz ShowSp5 ; if not, skip
Call DisplayNumber ; otherwise display
Mov dh, 3 ; then minimum 3 digits
ShowSp5: Mov ax, bx ; retrieve low digits
Jmp DisplayNumber
Ret
MemSize: Int 12h ; get memory size
Mov [RetVal], ah ; save for return
Xor dh, dh ; no minimum # of digits
Jmp Displaynumber
FreeMem: Int 12h ; get total RAM size
Mov bx, es ; get start address of PSP
Mov cl, 6 ; convert paras to KB
Shr bx, cl
Sub ax, bx ; subtract from total RAM
Mov [RetVal], ah ; save for return
Xor dh, dh
Jmp DisplayNumber ; presto: free RAM!
LogicDrives: Mov ah, 19h ; get number of logical drives
Int 21h ; first, get current disk
Mov dl, al
Mov ah, 0Eh ; now get that number
Int 21h
Jmp DisplayVeryShort
Floppies: Int 11h ; number of floppies
Test al, 00000001b ; is floppy installed?
Jne FloppiesFound ; skip if so
Xor al, al ; otherwise set to 0
Jmp DisplayVeryShort
FloppiesFound: Mov cl, 6 ; isolate number of floppies
ShR al, cl
And al, 0F3h
Inc al
Jmp DisplayVeryShort
Printers: Int 11h ; number of printers
Mov cl, 14 ; isolate number of printers
ShR ax, cl
Jmp DisplayVeryShort
CommPorts: Int 11h ; number of comm ports
Mov cl, 9 ; isolate number of ports
ShR ax, cl
And al, 7
Jmp DisplayVeryShort
Coproc: Int 11h ; is coprocessor installed?
ShR al, 1 ; output as 0 or 1
And al, 1
Jmp DisplayVeryShort
LptStat: Mov ah, 02h ; get printer status
Xor dx, dx ; printer port #0
Int 17h
Mov al, ah
Xor dl, dl
Jmp DisplayShort
VideoMode: Mov ah, 0Fh ; get video mode
Int 10h
Xor dh, dh
Jmp DisplayShort ; display number
VideoWidth: Mov ah, 0Fh ; get screen width
Int 10h
Mov al, ah ; width was in ah
Xor dh, dh
Jmp DisplayShort
SysModel: Push es ; get model indicator
Mov bx, 0F000h ; save ES; set up ES to
Mov es, bx ; point to ROM location
Mov bl, byte ptr es:0FFFEh ; this is model indicator
Pop es ; restore ES
Sub bl, 0F7h ; subtract offset
Mov [RetVal], bl ; save for return
Shl bl, 1
Xor bh, bh
Cmp bl, ModelStrLen - ModelString
Jbe SysModel2
Xor bl, bl
SysModel2: StuffChar [ModelString+bx] ; display ID
StuffChar [(ModelString+1)+bx]
Ret
DosVersion: Mov ah, 30h ; get DOS version
Int 21h
Push ax
Call DisplayVeryShort ; show major version number
StuffChar '.'
Pop ax
Xchg ah, al ; and minor version number, too
Jmp DisplayTwoDigs
BiosVersion: Push ds ; get BIOS version; save DS
Push si ; ... and SI
Mov ax, 0FFFFh ; set up DS
Mov ds, ax ; to point to ROM location
Mov si, 5h
Mov cx, 8 ; 8 bytes length
Mov ah, 02h
BiosVer2: Lodsb
Call StuffIt ; stuff char
Loop BiosVer2 ; loop for 8 chars
Pop si ; restore SI...
Pop ds ; and DS
Ret
SwitchChar: Mov ax, 3700h ; get switch character
Int 21h
Mov [RetVal], dl ; save for return
StuffChar dl
Int 21h
Ret
Author: Push si
Mov si, offset Copyright ; show author's note
Author2: Lodsb
Cmp al, '$'
Je Author3
Call StuffIt
Jmps Author2
Author3: Pop si
Ret
KeyBoard: Xor ah, ah ; get key from user
Int 16h
Or al, al ; was it extended key?
Je KeyBoard ; if so, try again
Mov [RetVal], al ; save for return
Jmp StuffIt ; otherwise echo
StdInSymbol: StuffChar '<' ; display stdin redir.symbol
Mov [RetVal], '<' ; save for return
Ret
StdOutSymbol: StuffChar '>' ; display stdout redir.symbol
Mov [RetVal], '>' ; save for return
Ret
PipeSymbol: StuffChar '|' ; display pipe symbol
Mov [RetVal], '|' ; save for return
Ret
HexNumber: Lodsb ; display byte given by
Cmp al, Return ; two hex digits
Je HexEnd
Sub al, '0' ; subtract ASCII offset
Cmp al, 9 ; was that enough?
Jbe Digit1OK ; if so, skip
Sub al, 7 ; subtract rest
Cmp al, 0Fh ; was that enough?
Jbe Digit1OK ; if so, skip
Sub al, 'a'-'A' ; otherwise assume lower-case
Digit1OK: Mov cl, 4 ; shift as appropriate
ShL al, cl
Mov dl, al
Lodsb ; get second digit
Cmp al, Return
Je HexEnd
Sub al, '0' ; subtract ASCII offset
Cmp al, 9 ; was that enough?
Jbe Digit2OK ; if so, skip
Sub al, 7 ; subtract rest
Cmp al, 0Fh ; was that enough?
Jbe Digit2OK ; if so, skip
Sub al, 'a'-'A' ; otherwise assume lower-case
Digit2OK: Or al, dl ; combine digits
Mov [RetVal], al ; save for return
Jmp StuffIt ; and put 'em out
HexEnd: Pop ax ; premature end; pop address
Jmp Done
CountryInfo: Mov ax, 3800h ; get country info
Mov dx, offset DirString
Int 21h
Mov al, bl
Jmps DisplayVeryShort ; show it
Currency: Mov ax, 3800h ; get country info
Mov dx, offset DirString
Int 21h
Mov ah, [DirString+2]
Mov [RetVal], ah ; save for return
Xor bx, bx
Curr2: Mov al, [(DirString+2)+bx]
Or al, al
Je Curr3
Call StuffIt
Inc bx
Jmps Curr2
Curr3: Ret
Thousands: Mov cx, 7 ; prepare to get 1000 sep.
Jmps GetCountry
Decimal: Mov cx, 9 ; prepare to get decimal sep.
Jmps GetCountry
DateSep: Mov cx, 11 ; prepare to get date separator
Jmps GetCountry
TimeSep: Mov cx, 13 ; prepare to get time separator
GetCountry: Mov ax, 3800h ; get country info
Mov dx, offset DirString ; pointer to buffer
Int 21h
Mov bx, cx
Mov al, [DirString+bx]
Mov [RetVal], al ; save for return
Call StuffIt
Ret
Day: Mov al, [DateBuf+3] ; get day
Jmps DisplayTwoDigs
Month: Mov al, [DateBuf+2] ; get month
Jmps DisplayTwoDigs
Year: Mov ax, word ptr [DateBuf] ; get year
Jmps DisplayTwoDigs
WeekDay: Mov al, [DateBuf+4] ; get weekday
Jmps DisplayVeryShort
Hour: Mov al, [TimeBuf] ; get hours
Jmps DisplayTwoDigs
Minute: Mov al, [TimeBuf+1] ; get minutes
Jmps DisplayTwoDigs
Second: Mov al, [TimeBuf+2] ; get seconds
Jmps DisplayTwoDigs
CentiSecond: Mov al, [TimeBuf+3] ; get centiseconds
DisplayVeryShort: Xor dh, dh ; short number, no min digits
Jmps DisplayShort
DisplayTwoDigs: Mov dh, 02 ; display >= 2 digits
DisplayShort: Xor ah, ah ; output number up to 255
Mov [RetVal], al ; save for return
DisplayNumber: Xor cx, cx ; output number up to 2559
; dh is min # of digits
Mov dl, 10 ; divisor
DispNum2: Div dl
Push ax ; one digit
Inc cl
Xor ah, ah
Or al, al
Jnz DispNum2 ; loop until we are done
Cmp cl, dh ; do we have enough digits?
Jae DispNum3 ; if so, skip
Push cx
Sub dh, cl
Mov cl, dh
DispNum2a: StuffChar '0' ; otherwise output leading 0s
Loop DispNum2a
Pop cx
DispNum3: Pop ax ; get back one digit
Xchg ah, al
Or al, '0' ; convert to ASCII
Call StuffIt ; and display
Loop DispNum3
Ret
StuffIt: Push ax ; puts char in AL into env
Push bx ; string, if room permits
Mov Bl, [OutLine]
Cmp Bl, 7Fh ; is there room left?
Jae StuffIt2 ; if not, skip this
Inc Bl
Mov [OutLine], Bl
Xor Bh, Bh
Mov [OutLine+bx], Al
StuffIt2: Pop bx
Pop ax
Ret
cseg ends
end start