home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
b
/
bbl-v-1.zip
/
TSTCMD.ASM
< prev
Wrap
Assembly Source File
|
1992-08-18
|
9KB
|
418 lines
title tstcmd
page 58,132
;
; Program to test command-line handling for BBL device-driver
;
; Invoke as
; tstcmd c:\bbl.sys /font=att /mode=0
; for example, or invoke with Turbo debugger with command line
; as above.
;
PSP_Cmd EQU 080h
LFChar EQU 0ah
CRChar EQU 0dh
HTChar EQU 09h
ModeMax EQU '2' ;max number of virtual display modes
stak SEGMENT para STACK 'STACK'
db 64 DUP ('STACK ')
stak ENDS
dseg SEGMENT para public 'DATA'
ATTMsg db 'ATT font ptr loaded',CRChar, LFChar,'$'
EGAMsg db 'EGA font ptr loaded',CRChar, LFChar,'$'
VGAMsg db 'VGA font ptr loaded',CRChar, LFChar,'$'
HexMsg db 'Hex font ptr loaded',CRChar, LFChar,'$'
ModMsg db 'Mode set to $'
FontStr db 'FONT'
ModeStr db 'MODE'
ATTStr db 'ATT'
EGAStr db 'EGA'
VGAStr db 'VGA'
CmdErrStr db 'Unrecognized switch: $'
ModErrStr db 'Invalid Mode value (must be 0..2): $'
HexErrStr db 'Invalid hexidecimal string: $'
CRLF db CRChar,LFChar,'$'
;MyString db 'c:\bbl.sys /Font=ATT /Mode=2',LFChar
BBLMsg db 'Loaded BBL device driver',CRChar,LFChar,'$'
CurrMode db 0
fp_off dw 0
fp_seg dw 0
HexStart dw 0
dseg ENDS
cseg SEGMENT para public 'CODE'
assume CS:cseg, DS:dseg, SS:stak
Main PROC FAR
push ds
xor ax,ax
push ax
mov ax,dseg
mov ds,ax
; mov es,ax
; mov si,offset MyString
mov ah,62h ;for testing purposes, get command
int 21h ; string ptr from PSP into
mov es,bx ; es:si
mov si,PSP_Cmd
CmdLup: call SkipSwitch ;skip everthing to & including '/'
jc CmdDone ; hit end of line ... we're done
call GetToken ;get the next token after the /
jc CmdDone ;wasn't one ... we're done
;es:si points to the start of the token
;es:di points to the first char after it
lea dx,FontStr ;compare with "FONT"
call ChkTok
jne NotFont ;skip if not "FONT"
mov si,di ;update over recognized keyword
call Font ;yes, got "FONT" ... do it
jmp CmdLup ;and return for more
NotFont: lea dx,ModeStr ;check "MODE"
call ChkTok
jne NotMode ;skip if not "MODE"
mov si,di ;update over recognized keyword
call Mode ;yes, got "MODE"
jmp CmdLup ;and return for more
NotMode:
;insert others here with the pattern
; lea dx,CMDStr ;check "CMD"
; call ChkTok
; jne NotCMD ;skip if not "CMD"
; call CMD ;process "CMD"
; jmp CmdLup ;and return for more
NotCmd:
mov ah,09h ;if none of the above, issue error
lea dx,CmdErrStr
int 21h
call PrtStr ;print the offending string & advance si
mov ah,09h ;now the suffix
lea dx,CRLF
int 21h
jmp CmdLup
CmdDone: lea dx,BBLmsg
mov ah,09h
int 21h
retf
Main ENDP
SkipSwitch PROC NEAR
SSLoop: cmp BYTE PTR es:[si],'/' ;got a switch?
je GotS ;yes
cmp BYTE PTR es:[si],0ah ;end of line?
je EndLine ;yes
inc si ;none of the above ... skip it
jmp SSLoop
Gots: inc si ;skip that /
clc ;clear the flag
ret ;done
EndLine: stc ;set the flag to alert of eol
ret
SkipSwitch ENDP
GetToken PROC NEAR
call SkipBlanks
mov di,si ;advance es:di over the token
GetLup: mov al,BYTE PTR es:[di] ;examine next char
call MakeUpper ;make sure it's upper case
mov BYTE PTR es:[di],al
NotLow: cmp al,' ' ;blank, tab, '=', '/' or eoln is a delimiter
je GetDone
cmp al,LFChar
je GetDone
cmp al,HTChar
je GetDone
cmp al,'/'
je GetDone
cmp al,'='
je GetDone
inc di ;it was none of them ... part of token
jmp GetLup
GetDone: ret
GetToken ENDP
SkipBlanks PROC NEAR
;skip whitespace in string es:si
;return advanced si pointer
;carry set ==> eoln (end of string) encountered
;carry clear ==> found non-space
SBLup: cmp BYTE PTR es:[si],' ' ;spaces or tabs and eoln are "blanks"
je SBInc
cmp BYTE PTR es:[si],HTChar
je SBInc
cmp BYTE PTR es:[si],LFChar
je SBeoln ;if eoln, say so
clc ;otherwise, clear carry (not at eoln)
ret ; and we've done our job
SBeoln: stc ;got an eoln ... flag it
ret ;and ... we're done
SBInc: inc si
jmp SBLup ;go look at next one
SkipBlanks ENDP
Font PROC NEAR
call SkipEqual ;skip the equal sign
call GetToken ;get the option value
lea dx,ATTStr
call ChkTok
jne NotATT
call SetATT
mov si,di ;skip that token
ret
NotATT: lea dx,EGAStr
call ChkTok
jne NotEGA
call SetEGA
mov si,di ;skip that token
ret
NotEGA: lea dx,VGAStr
call ChkTok
jne NotVGA
call SetEGA
mov si,di ;skip that token
ret
NotVGA: mov HexStart,si ;save ptr to start of hex string for error msg
call GetHex
jc HexErr
mov fp_seg,dx
cmp BYTE PTR es:[si],':' ;need ':' as a separator
jc HexErr ;oops
inc si ;ok, go on
call GetHex
jc HexErr
mov fp_off,dx
lea dx,HexMsg ;[hdt]kill
mov ah,09h
int 21h
ret
Font ENDP
SkipEqual PROC NEAR
;advances es:si to the first char past
; next '=' on line
;sets carry if eoln found during scan
;clears if valid char follows '='
SELup: cmp BYTE PTR es:[si],'=' ;found it yet?
je FndEqual ;yes
cmp BYTE PTR es:[si],LFChar ;no ... at end of line?
je SEeoln ;if eoln, say so
inc si ;otherwise, go look at next char
jmp SELup
SEeoln: stc ;got an eoln ... flag it
ret ;and we're done
FndEqual: ;found an =
inc si ;skip it
cmp BYTE PTR es:[si],LFChar ;is it eoln?
je SEeoln ;yes, flag and return
clc ;no, we're ok, just return
ret
SkipEqual ENDP
SetATT PROC NEAR
lea dx,ATTMsg
mov ah,09h
int 21h
ret
SetATT ENDP
SetEGA PROC NEAR
lea dx,EGAMsg
mov ah,09h
int 21h
ret
SetEGA ENDP
HexErr PROC NEAR
;prints out error message for invalid
;hex string started at es:si and ending
;the char before es:di
;advances es:si past that string
mov ah,09h
lea dx,HexErrStr ;print the error msg
int 21h
call PrtStr ;print the offending string
mov ah,09h
lea dx,CRLF ;and finish it off
int 21h
mov si,di ;make sure we advance past it
ret ;and we're done
HexErr ENDP
GetHex PROC NEAR
;converts a 4-digit hex string
;beginning at es:si into a binary hex
;value. Returns
; binary value in dx
; es:si advanced over hex string
; if no error, not advanced if
; the string was invalid
; carry set if error, clear if none
;saves other regs
push ax
push cx
push si
mov cx,4 ;we always do 4 digits!
xor dx,dx
GHLup: xor ax,ax
mov al,BYTE PTR es:[si] ;get the next char
inc si ;and record that
cmp al,'0' ;is it a digit?
jl GHErr ; no
cmp al,'9' ;maybe
jg GHAlpha ; well, not 0..9
sub al,'0' ;yes, valid digit
GHInsert: ;ok, insert it into the resulting word
shl dx,1
shl dx,1
shl dx,1
shl dx,1
or dx,ax
loop GHLup ;and do it again
clc ;all done - flag no error
pop cx ;throw away saved si -- leave string
;pointer advanced
pop cx ;restore real cx
pop ax
ret
GHAlpha: call MakeUpper ;raise if alpha
cmp al,'A' ;is it in hex range
jl GHErr ;no
cmp al,'F'
jg GHErr
sub al,'A' ;yes -- convert to binary value
add al,0ah
jmp GHInsert ;and insert it into the resulting word
GHerr: stc ;oops ... some character offended ... say so
pop si ;restore original si
pop cx
pop ax
ret
GetHex ENDP
MakeUpper PROC NEAR
;converts the char in al to upper case,
; if necessary
cmp al,'a'
jl MUDone
cmp al,'z'
jg MUDone
sub al,'a'-'A'
MUDone: ret
MakeUpper ENDP
PrtStr PROC NEAR
;prints the string between es:si and
;the char before es:di and advances si
;
;returns si with value of initial di
push ax
push dx
PSLup: cmp si,di ;any left to print?
jge PSDone ;no
mov dl,BYTE PTR es:[si]
mov ah,02h
int 21h
inc si
jmp PSLup
PSDone: pop dx
pop ax
ret
PrtStr ENDP
ChkTok PROC NEAR
;compare string between es:si & es:di
;with string pointed to by ds:dx
;use je to check for equality on return
push cx
mov cx,di ;compute char count for cmpsb
sub cx,si
push si ;save registers
push di
push si
pop di
mov si,dx
cmpsb ;do compare
pop di ;restore & return
pop si
pop cx
ret
ChkTok ENDP
Mode PROC NEAR
call SkipEqual ;skip equal sign
mov al,BYTE PTR es:[si] ;get that char
inc si ;move over it
cmp al,'0' ;got a digit?
jl ModErr ; nope ... error
cmp al,ModeMax ;within upper range limit?
jg ModErr ; no ... report error
push ax ;[hdt]kill
sub al,'0' ;convert that digit
mov CurrMode,al ;set it
lea dx,ModMsg
mov ah,09h ;[hdt]kill
int 21h
pop dx
mov ah,02h
int 21h
mov ah,09h
lea dx,CRLF
int 21h
ret
ModErr: push ax ;save the offending digit
mov ah,09h ;print error header
lea dx,ModErrStr
int 21h
pop dx
mov ah,02h ;print digit
int 21h
mov ah,09h
lea dx,CRLF ;end the message
int 21h
ret
Mode ENDP
cseg ends
END Main