⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 what.asm

📁 查看本地文件信息
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	  TITLE	  WHAT

; Program WHAT.ASM
; Purpose Batch	file enhancer
; Input	  Command line consisting of:
;	     Command letter (with optional E for extended)
;	     Optional prompt enclosed in double	quotes
;	     Optional argument
; Output  Number in DOS	ERRORLEVEL and string in WHAT environment variable

	  DOSSEG
	  .MODEL  small
	  PAGE	  60,120
	  INCLUDE DOS.INC

	  .STACK  100h

	  .DATA
help1	  LABEL	  BYTE
DB 13,10,"			WHAT - Batch file enhancer",13,10,13,10
DB "Command			Purpose	    Argument   Environ	   Exit	       Extended",13,10
DB "---------		-------	    --------   -------	   ----	       ------",13,10
DB "C[E] [""prompt""]	[chars]	Get	    Allowable  Character   Character   Echo",13,10
DB "			character   characters",13,10,13,10
DB "S[E] [""prompt""]		Get string  None       String	   Length      Echo",13,10,13,10
DB "D[E]			Check DOS   None       Major	   (Major*10)  Minor",13,10
DB "					       version	   +Minor      version",13,10,13,10
DB "E[E]			Get environ None       Bytes	   Bytes/10    10 bytes",13,10
DB "			bytes left			   bytes       in exit",13,10,13,10
DB "F[E] filespec		Get file    Filespec   Kilobytes   Ks/10Ks     10Ks in",13,10
DB "			size			 (255=directory)       exit",13,10,13,10
DB "K[E] [driveletter]	Get disk    Drive      Kilobytes   Ks/10Ks     10Ks in",13,10
DB "			space					       exit",13,10,13,10
DB "Press a key to continue . . .$"
help2	  LABEL	  BYTE
DB 13,"M[E]			Check	    None       Kilobytes   Ks/10Ks     10Ks in",13,10
DB "			memory					       exit",13,10,13,10
DB "P			Check for   None       1=yes,0=no  1=yes,0=no  None",13,10
DB "			printer",13,10,13,10
DB "V [number]		Get/Set	    New mode   Current or  Current or  None",13,10
DB "			video mode	       last mode   last mode",13,10,13,10
DB "7			Check for   None       1=yes,0=no  1=yes,0=no  None",13,10
DB "			coprocessor",13,10,13,10
DB "A			Check for   None       1=yes,0=no  1=yes,0=no  None",13,10
DB "			ANSI driver",13,10,13,10
DB "Y[E]			Get current None       Directory   Level/Drive Drive",13,10
DB "			directory",13,10,"$"

guess	  DB	  80		 ; Prompt for string
actual	  DB	  ?
string	  DB	  80 DUP (0)

extend	  DB	  0		 ; Flag	for extended command
vid	  DB	  3		 ; Video mode
ans	  DB	  27,"[6n$"	 ; ANSI	string to get current position
overwrt	  DB	  8,8,8,8,"    $"; Overwrite ANSI characters
delete	  DB	  8,8,8,"$"	 ; Delete ANSI characters

what	  DB	  "WHAT="	 ; Variable name
lwhat	  EQU	  $-what

prompt	  DW	  0		 ; Pointer to prompt
lprompt	  DW	  0		 ; Length of prompt
arg	  DW	  0		 ; Pointer to argument
larg	  DW	  0		 ; Length of argument

; Command table

cmds	  DB	  "CSVDMEKFP7AY" ; Command character list
lcmds	  EQU	  $-cmds	 ;   and length	of list
	  EVEN
table	  DW	  GetChar	 ; Command procedure table
	  DW	  GetStr
	  DW	  DoVid
	  DW	  GetDOS
	  DW	  GetMem
	  DW	  GetEnvSz
	  DW	  GetDskSz
	  DW	  GetFilSz
	  DW	  VeriPrint
	  DW	  VeriCop
	  DW	  VerAnsi
	  DW	  GetDir
	  DW	  NoCmd

err1	  DB	  "Invalid command",7,13,10,"$"
err2	  DB	  "Out of environment space",7,13,10,"$"
err3	  DB	  "Must have DOS Version 2.0 or higher",7,13,10,"$"

	  .CODE
start:	  mov	  ax,@DATA		; Starting execution address
	  mov	  ds,ax			; Initialize data segment

	  @GetVer			; Get DOS version
	  or	  al,al			; Is it	0?
	  jne	  DOSOK			; No? Continue
	  @DispStr err3			; Yes? Quit for	1.x
	  int	  20h

DOSOK:	  mov	  si,83h		; Starting point in PSP
	  mov	  ax,WORD PTR es:[5Dh]	; Load command characters
	  cmp	  al,' '		; Is it	space?
	  jne	  isarg			; If no	argument, show help
	  call	  Help

isarg:	  cmp	  ah,'E'		; Extend flag?
	  jne	  noextend		; No? Continue
	  inc	  extend		; Yes? Turn on flag and	adjust pointer
	  inc	  si

noextend: call	  GetArg		; Get argument from command line

	  push	  es			; Save and load	DS into	ES
	  mov	  bx,ds
	  mov	  es,bx
	  mov	  di,OFFSET cmds	; Load pointer to command table
	  mov	  cx,lcmds+1		; Load length
	  repne	  scasb			; Find position	of command character
	  pop	  es
	  sub	  di,(OFFSET cmds)+1	; Point	to procedure
	  shl	  di,1			; Adjust for word addresses
	  call	  table[di]		; Call the selected procedure

	  push	  ax			; Save
	  push	  es
	  call	  DoEnviron		; Put result in	environment string
	  or	  ax,ax			; Test for 0 before
	  pop	  es			;   restore
	  pop	  ax
	  jz	  done

	  cmp	  BYTE PTR es:[5Dh],'E'	; Is it	Environment command
	  je	  done			; Yes? Skip message

error2:	  @DispStr err2			; Error	message

done:	  @Exit				; Quit with AL as return code

; End of program - Start of procedures

; Procedure GetChar
; Purpose   Get	a character from user
; Input	    Allowable characters pointed to by "arg" (optional)
;	    Prompt pointed to by "prompt" (optional)
; Output    Character in AX and	in "string"

GetChar	  PROC

	  call	  ShowPrmpt		; Display prompt if there is one

readkey:  @GetKey 0,1			; Get a	key
	  cmp	  al,13			; Is it	carriage return?
	  jne	  notcr			; Yes? Continue
	  mov	  al,"~"		; Call it tilde
					;   (use tilde in character list
					;    if	you want to accept CR)
notcr:	  or	  al,al			; Is it	0 for extended key?
	  je	  exkey			; Special case

	  mov	  bl,al			; Save a copy and swap
	  xchg	  ah,al

	  call	  UpCase		; Uppercase it

	  xchg	  ah,al			; Swap back
	  mov	  si,arg		; Load pointer and length of argument
	  mov	  cx,larg
	  jcxz	  gotchar		; If no	argument, quit early

; Compare character to argument	to see if it's valid

argcheck: mov	  ah,BYTE PTR es:[si]	; Get character
	  inc	  si			; Increment index

	  call	  UpCase		; Convert to uppercase

	  cmp	  ah,al			; Is it	in argument?
	  je	  gotchar		; Yes? We're done
	  loop	  argcheck		;   else check another
	  @DispCh 7			; Checked all, so ring bell
	  jmp	  SHORT	readkey		;   and	get another character

gotchar:  push	  ax
	  cmp	  extend,0		; Is extend flag set?
	  jne	  noecho		; Yes? Don't echo
	  cmp	  bl,"~"		; Don't echo ~ (alias for CR)
	  je	  noecho
	  @DispCh bl			; Display valid	character
noecho:	  pop	  ax
	  mov	  string,al		; Put the character in string
	  inc	  actual		; Length is one
	  ret

exkey:	  @GetKey 0,1			; Get second key in AL
	  mov	  si,arg		; Load pointer to argument
	  cmp	  BYTE PTR es:[si],"`"	; Is argument grave accent?
					;   (use grave in character list if
					;    you want to accept	extended keys)
	  je	  gotext		; Yes? Extended	character
	  @DispCh 7			; No? Illegal, so ring bell
	  jmp	  SHORT	readkey		;   and	get another
gotext:	  mov	  string[0],'0'		; Extended flag	value is "0<char>"
	  mov	  string[1],al
	  mov	  actual,2		; Length is 2

	  ret
GetChar	  ENDP

; Procedure GetStr
; Purpose   Get	a string
; Input	    Prompt pointed to by prompt	(optional)
; Output    String in "string";	length to AX

GetStr	  PROC

	  call	  ShowPrmpt		; Display prompt if there is one

	  cmp	  extend,1		; Extend flag true?
	  je	  password		; Yes? Then don't echo

	  @GetStr guess,0		; Get string (null-terminated)
	  jmp	  SHORT	gotstr		; Done

password: mov	  bx,OFFSET string	; Load offset of string	buffer
	  mov	  cx,80			; Maximum count
nextkey:  @GetKey 0,1			; Get key, no echo
	  cmp	  al,13			; Is it	carriage return
	  je	  gotpass		; Yes? Done
	  mov	  [bx],al		; No? Put key in buffer
	  inc	  bx			; Point	to next
	  loop	  nextkey

gotpass:  sub	  bx,OFFSET string	; Adjust pointer to get	count
	  mov	  actual,bl		; Save count

gotstr:	  @DispCh 13,10
	  mov	  ax,bx			; Save string length
	  ret
GetStr	  ENDP

; Procedure GetDOS
; Purpose   Get	DOS version
; Input	    None
; Output    Major or minor version in "string";	(major *10)+minor in AX

GetDOS	  PROC
	  @GetVer			; Get DOS version
	  mov	  string,al		; Put major in string
	  mov	  bh,al			; Save copy
	  mov	  al,ah			; Divide minor to get one digit
	  sub	  ah,ah			; Clear	top
	  mov	  cl,10			; Divide by 10
	  div	  cl
	  xchg	  al,bh			; Exchange major and minor
	  mul	  cl			; Multiply major by 10
	  add	  al,bh			; (Major*10)+Minor - 3.2 is now	32
	  cmp	  extend,1		; Extend?
	  jne	  gotver		; No? Already got it
	  mov	  string,bh		; Save number
gotver:	  mov	  actual,1		; Save length 1
	  add	  string,30h		; Convert to ASCII
	  ret
GetDOS	  ENDP

; Procedure GetEnvSz
; Purpose   Get	environment bytes available
; Input	    None
; Output    Environment	bytes available

GetEnvSz  PROC
	  push	  es			; Save ES
	  call	  GetEnv		; Get the environment size
	  pop	  es			; Restore
	  sub	  ax,cx			; Subtract length used from total
					;   length to get length remaining
	  call	  BinToDec		; Convert to string
	  call	  Byticize		; Handle values	too large for byte
	  ret
GetEnvSz  ENDP

; Procedure GetFilSz
; Purpose   Get	the size of a specified	file
; Input	    Filespec pointed to	by "arg"
; Output    File size

GetFilSz  PROC
	  cmp	  arg,0			; File name argument?
	  jne	  isfile
	  call	  NoCmd
isfile:	  mov	  di,arg		; Point	to start and end of arg
	  mov	  bx,larg
	  mov	  BYTE PTR es:[bx+di],0	; Make null-terminated

	  push	  ds
	  @OpenFil arg,0,es		; Open file for	reading
	  pop	  ds
	  jc	  ferror		; Error	if carry

notdir:	  @GetFilSz ax
	  jc	  ferror		; Error	if carry
	  mov	  cx,1000		; Convert to thousands
	  div	  cx
	  inc	  ax			; Round	up
	  jmp	  SHORT	gotsize

ferror:	  cmp	  ax,5			; Access denied? Probably a directory
	  jne	  nofile		; No file or some other	error
	  mov	  ax,0FFh		; Call directory size 255
	  jmp	  SHORT	gotsize
nofile:	  sub	  ax,ax			; Size of nothing is 0

gotsize:  call	  BinToDec		; Convert to string
	  call	  Byticize		; Handle large values
	  ret
GetFilSz  ENDP

; Procedure GetDskSz
; Purpose   Get	K remaining on specified disk
; Input	    Drive letter pointed to by "arg"
; Output    Disk space remaining

GetDskSz  PROC
	  sub	  ax,ax			; Assume default drive
	  cmp	  arg,0			; Was there an argument?
	  je	  defdrive		; No? Got drive
	  mov	  al,BYTE PTR es:6Dh	; Yes? Get drive letter
	  sub	  al,'A'-1		; Convert to binary
defdrive: @ChkDrv al			; Get disk space
	  cmp	  ax,0FFFFh		; Is drive valid?
	  jne	  valid
	  call	  NoCmd
valid:	  mul	  bx			; Sectors = sectors/cluster * clusters
	  mul	  cx			; Bytes	= bytes/sector * sectors
	  mov	  cx,1000		; Convert to thousand
	  div	  cx
	  inc	  ax			; Round	up
	  call	  BinToDec		; Convert to string
	  call	  Byticize		; Handle large values

	  ret
GetDskSz  ENDP

; Procedure GetMem
; Purpose   Get	memory available
; Input	    None
; Output    Available memory

GetMem	  PROC
	  int	  12h			; Get memory available in K
	  mov	  bx,es			; Get memory used
	  mov	  cx,6			; Convert to K
	  shr	  bx,cl
	  sub	  ax,bx			; Calculate how	much is	left
	  sub	  dx,dx			; Clear	DX
	  mov	  cx,1024		; Multiply to get bytes
	  mul	  cx
	  mov	  cx,1000		; Divide to get	thousands (not K)
	  div	  cx
	  call	  BinToDec		; Convert to string
	  call	  Byticize		; Handle large values
	  ret
GetMem	  ENDP

; Procedure VeriPrint
; Purpose   See	if LPT1	(PRN) is available
; Input	    None
; Output    1 for yes or 0 for no

VeriPrint PROC
	  mov	  ax,200h		; Check	printer	status
	  sub	  dx,dx			;   for	main parallel printer (port 0)
	  int	  17h
	  xchg	  dx,ax			; Put 0	(for error) in AX
	  test	  dh,00101001b		; Are any error	bits on?
	  jne	  printerr		; Yes? Leave 0
	  test	  dh,10010000b		; Are both operation bits on?
	  jz	  printerr		; No? Leave 0
	  inc	  ax			; Yes? Return 1
printerr: call	  BinToDec		; Convert to string
	  ret
VeriPrint ENDP

; Procedure DoVid
; Purpose   Get	current	video mode and optionally set a	new mode
; Input	    New	video mode pointed to by "arg" (optional)
; Output    Current video mode (before change)

DoVid	  PROC
	  mov	  ah,0Fh		; Get video mode
	  int	  10h

	  cmp	  larg,1		; How many digits in mode?
	  jl	  gotmode		; None?	Get out
	  push	  ax			; Some?	Save mode
	  mov	  bx,arg		; Load address of argument string
	  mov	  ax,es:WORD PTR [bx]	; Get address of mode string
	  je	  one			; One digit - skip the reverse

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -