home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / pcmag / vol6n03.arc / CHECK.ASM next >
Assembly Source File  |  1987-12-13  |  26KB  |  481 lines

  1. ;CHECK.COM for the IBM Personal Computer - 1986 by Jeff Prosise
  2.               .8087                         ;recognize 8087/80287 instructions
  3. code          segment para public 'code'
  4.               assume cs:code,ds:code
  5.               org 100h
  6. begin:        jmp check                     ;skip data area
  7. ;
  8. notice        db ' Copyright 1986 Ziff-Davis Publishing Co.'
  9. notice_2      db ' Programmed by Jeff Prosise'
  10.  
  11. keywords      db 'MEMORY',0,'FILESIZE',0,'VIDEOCARD',0
  12.               db 'MODEL',0,'8087',0,'80287',0
  13.               db 'FILEFOUND',0,'FILETEXT',0,'DISKSPACE',0
  14.               db 'VIDEOMODE',0,'TIME',0,'DAY',0,'MONTH',0
  15.               db 'VERSION',0,'KEYBOARD',0,'KEYPRESS',0
  16. ;
  17. jump_table    dw offset keypress            ;vector dispatch table
  18.               dw offset keyboard
  19.               dw offset version
  20.               dw offset month
  21.               dw offset day
  22.               dw offset time
  23.               dw offset videomode
  24.               dw offset diskspace
  25.               dw offset filetext
  26.               dw offset filefound
  27.               dw offset mathproc
  28.               dw offset mathproc
  29.               dw offset model
  30.               dw offset videocard
  31.               dw offset filesize
  32.               dw offset memory
  33. ;
  34. ibm                db 'IBM'                 ;EGA signature
  35. parameter_count    db ?                     ;number of command line parameters
  36. string_length      dw 0                     ;length of text string in bytes
  37. file_handle        dw ?                     ;storage area for DOS file handle
  38. command_index      dw ?                     ;storage for parsing index
  39. keyword_buffer     dw offset endprog        ;pointer to keyword buffer
  40. param1_buffer      dw offset endprog+16     ;pointer to parameter buffer
  41. text_string        dw offset endprog+144    ;pointer to text string buffer
  42. dta                dw offset endprog+272    ;pointer to Disk Transfer Area
  43. control_bytes      label byte               ;byte accessor to control word
  44. control_8087       dw 0                     ;8087/80287 control word
  45. ;
  46. errmsg1            db 13,10,'Invalid Keyword',13,10,'$'
  47. errmsg2            db 13,10,'Missing Parameter',13,10,'$'
  48. errmsg3            db 13,10,'Invalid Drive Specifier',13,10,'$'
  49. errmsg4            db 13,10,'Invalid String Specifier',13,10,'$'
  50. errmsg5            db 13,10,'File Not Found',13,10,'$'
  51. ;
  52. check         proc near
  53.               cld                           ;clear DF for string instructions
  54.               call parse_line               ;parse command line for entries
  55.               cmp parameter_count,0         ;any parameters entered?
  56.               jne check1                    ;yes, then continue
  57.               lea dx,errmsg2                ;no - load error msg address
  58.               jmp error1                    ;abort on error
  59. check1:       lea si,keywords               ;point SI to keyword list
  60.               mov cx,16                     ;number of reserved keywords
  61. check2:       mov di,keyword_buffer         ;point DI to keyword just entered
  62. check3:       lodsb                         ;get character
  63.               or al,al                      ;is it a zero byte?
  64.               je match_found                ;yes, then keywords match
  65.               scasb                         ;compare it to byte in buffer
  66.               je check3                     ;loop back on match
  67.               dec cx                        ;no match - decrement counter
  68.               jcxz error_exit               ;list scanned unsuccessfully
  69. check4:       lodsb                         ;index SI to next word in list
  70.               or al,al                      ;is this byte a zero?
  71.               jne check4                    ;no, try again
  72.               jmp check2                    ;SI set - try another keyword
  73. ;
  74. ;Execution comes here when the keyword entered on the command line matches one
  75. ;of the recognized keywords.  The count in CX is translated into a pointer to
  76. ;the address of the routine to be vectored to.
  77. ;
  78. match_found:  mov bx,cx                     ;get keyword number in BX
  79.               dec bx                        ;decrement it by 1
  80.               shl bx,1                      ;multiply by two to form index
  81.               jmp word ptr cs:[offset jump_table+bx]       ;goto handler
  82. ;
  83. ;Execution comes here when an error is encountered.
  84. ;
  85. error_exit:   lea dx,errmsg1                ;load address of error message
  86. error1:       push ax                       ;save error return code in AL
  87.               mov ah,9                      ;DOS function - Print String
  88.               int 21h                       ;print error message
  89.               pop ax                        ;retrieve return code
  90. ;
  91. ;EXIT is the common point of exit for all routines in the program.  A return
  92. ;code is set that can be read as the ERRORLEVEL parameter by batch processes.
  93. ;
  94. exit:         mov ah,4Ch                    ;DOS function - Exit Program
  95.               int 21h                       ;exit with return code
  96. check         endp
  97. ;
  98. ;Model routine returns the machine ID byte of the computer being used.
  99. ;
  100. model         proc near
  101.               mov ax,0F000h                 ;set ES to ROM segment
  102.               mov es,ax
  103.               mov di,0FFFEh                 ;load DI with offset of ID byte
  104.               mov al,es:[di]                ;get machine ID byte into AL
  105.               jmp exit                      ;exit
  106. model         endp
  107. ;
  108. ;VideoMode routine returns the current video mode (0-16).
  109. ;
  110. videomode     proc near
  111.               mov ah,15                     ;INT 10h function - Get Video Data
  112.               int 10h                       ;get video mode in AL
  113.               jmp exit                      ;exit
  114. videomode     endp
  115. ;
  116. ;VideoCard routine returns a value indicating what kind of video adapter is
  117. ;being used in the system (0=MDA, 1=CGA, 2=EGA).
  118. ;
  119. videocard     proc near
  120.               mov dl,2                      ;initialize DL
  121.               mov bx,0C000h                 ;set ES to EGA BIOS segment
  122.               mov es,bx
  123.               mov di,1Eh                    ;set DI to IBM signature address
  124.               lea si,ibm                    ;set SI to 'IBM' text
  125.               mov cx,3                      ;three bytes to check
  126.               repe cmpsb                    ;compare the three bytes
  127.               je card1                      ;this is an EGA - jump to exit
  128.               dec dl                        ;adjust DL for MDA or CGA
  129.               mov ah,15                     ;get current video mode
  130.               int 10h
  131.               cmp al,7                      ;is it mode 7?
  132.               jne card1                     ;no, then this is a CGA
  133.               dec dl                        ;zero DL for MDA
  134. card1:        mov al,dl                     ;set AL for exit
  135.               jmp exit                      ;and exit
  136. videocard     endp
  137. ;
  138. ;Memory routine returns the number of 16K RAM modules present in the system.
  139. ;
  140. memory        proc near
  141.               int 12h                       ;get memory size from BIOS
  142.               mov cl,4                      ;set CL to 4 for shift
  143.               shr ax,cl                     ;shift 4 times to divide by 16
  144.               jmp exit
  145. memory        endp
  146. ;
  147. ;FileFound returns 0 if the indicated file is found, 1 if it's not.
  148. ;
  149. filefound     proc near
  150.               cmp parameter_count,1         ;more than 1 parameter entered?
  151.               ja filefnd1                   ;yes, then continue
  152.               lea dx,errmsg2                ;no, then get error msg address
  153.               mov al,1                      ;set AL to 1 to indicate failure
  154.               jmp error1                    ;and exit
  155. filefnd1:     mov dx,param1_buffer          ;point DX to filename
  156.               mov ah,3Dh                    ;use DOS Open File function
  157.               xor al,al                     ;set AL to 0 for read-only access
  158.               int 21h                       ;attempt to open the file
  159.               jnc filefnd2                  ;open process succeeded
  160.               mov al,1                      ;open failed - set AL to 1
  161.               jmp exit
  162. filefnd2:     mov bx,ax                     ;get file handle in BX
  163.               mov ah,3Eh                    ;use DOS Close File function
  164.               int 21h                       ;close file just opened
  165.               xor al,al                     ;zero AL for exit
  166.               jmp exit
  167. filefound     endp
  168. ;
  169. ;KeyBoard returns 1 if a key has been pressed, 0 if one has not.
  170. ;
  171. keyboard      proc near
  172.               mov ah,1                      ;use BIOS to check buffer
  173.               int 16h                       ;get status of keyboard buffer
  174.               je kb1                        ;empty if ZF set
  175.               mov al,1                      ;not empty - set AL to 1
  176.               jmp exit
  177. kb1:          xor al,al                     ;buffer empty - zero AL
  178.               jmp exit
  179. keyboard      endp
  180. ;
  181. ;KeyPress returns waits for a keypress (if one isn't already buffered) and
  182. ;returns its ASCII code.
  183. ;
  184. keypress      proc near
  185.               mov ah,0                      ;use BIOS function to read keypress
  186.               int 16h                       ;get keypress - ASCII code in AL
  187.               jmp exit
  188. keypress      endp
  189. ;
  190. ;Version returns the major number of the version of DOS in use.
  191. ;
  192. version       proc near
  193.               mov ah,30h                    ;use DOS Get Version function
  194.               int 21h                       ;get version number
  195.               jmp exit
  196. version       endp
  197. ;
  198. ;DiskSpace returns the number of whole 16K blocks of free disk space from the
  199. ;indicated or default drive.  AL is 0 on exit if an error is encountered.  A
  200. ;return value of 255 means there are that many blocks or more free.
  201. ;
  202. diskspace     proc near
  203.               xor dl,dl                     ;set DL to 0 for default drive
  204.               cmp parameter_count,1         ;only one parameter entered?
  205.               je dspace1                    ;yes, then use default drive
  206.               mov si,param1_buffer          ;set SI to parameter text
  207.               lodsb                         ;get first character in parameter
  208.               sub al,64                     ;convert to DOS drive designator
  209.               mov dl,al                     ;shift designator to DL
  210.               lodsb                         ;get following character
  211.               cmp al,':'                    ;is it a colon?
  212.               je dspace1                    ;yes, then continue
  213.               lea dx,errmsg3                ;no, then load error msg address
  214.               xor al,al                     ;set AL for failure
  215.               jmp error1                    ;exit on error
  216. dspace1:      mov ah,36h                    ;use DOS Get Free Space function
  217.               int 21h                       ;get disk information
  218.               cmp ax,0FFFFh                 ;drive designator error?
  219.               jne dspace2                   ;no, then continue
  220.               lea dx,errmsg3                ;abort on drive error
  221.               xor al,al
  222.               jmp error1
  223. dspace2:      mul cx                        ;multiply to get bytes per cluster
  224.               mul bx                        ;multiply again to get free bytes
  225.               mov cx,14                     ;set shift counter
  226. dspace3:      shr dx,1                      ;shift AX:DX right 14 bits
  227.               rcr ax,1
  228.               loop dspace3                  ;loop until done
  229.               or ah,ah                      ;is the MSB zero?
  230.               je dspace4                    ;yes, then continue
  231.               mov al,255                    ;no, then set AL to 255
  232. dspace4:      jmp exit
  233. diskspace     endp
  234. ;
  235. ;Time returns the current hour of the day (0-23).
  236. ;
  237. time          proc near
  238.               mov ah,44                     ;get current time from DOS
  239.               int 21h
  240.               mov al,ch                     ;place hour in AL
  241.               jmp exit
  242. time          endp
  243. ;
  244. ;Day returns the current day of the month (1-31).
  245. ;
  246. day           proc near
  247.               mov ah,42                     ;get current date from DOS
  248.               int 21h
  249.               mov al,dl                     ;put day in AL
  250.               jmp exit
  251. day endp
  252. ;
  253. ;Month returns the current month number (1-12).
  254. ;
  255. month         proc near
  256.               mov ah,42                     ;get date from DOS
  257.               int 21h
  258.               mov al,dh                     ;put month in AL
  259.               jmp exit
  260. month         endp
  261. ;
  262. ;FileText returns 0 if the specified string is found within the indicated
  263. ;file.  A 1 is returned if the string is not contained within the file, if
  264. ;the file is not found, or if a syntax error is detected on the command line.
  265. ;
  266. filetext      proc near
  267.               cmp parameter_count,2         ;at least two parameters entered?
  268.               je text1                      ;yes, then continue
  269.               lea dx,errmsg2                ;no, then abort
  270.               mov al,1
  271.               jmp error1
  272. text1:        mov si,command_index          ;point SI to end of second param
  273.               mov di,text_string            ;point DI to string buffer
  274. text2:        lodsb                         ;get next character
  275.               cmp al,32                     ;is it a space character?
  276.               je text2                      ;yes, then go back for another
  277.               cmp al,39                     ;is it a quote mark?
  278.               je text4                      ;yes, then branch and continue
  279.               cmp al,13                     ;end-of-line marker?
  280.               jne text3                     ;no, it's an invalid character
  281.               lea dx,errmsg2                ;abort - string missing
  282.               mov al,1
  283.               jmp error1
  284. text3:        lea dx,errmsg4                ;abort - syntax error in string
  285.               mov al,1
  286.               jmp error1
  287. text4:        lodsb                         ;get character in string
  288.               cmp al,13                     ;end-of-line marker?
  289.               je text3                      ;yes, then abort
  290.               cmp al,39                     ;quote mark?
  291.               je text5                      ;yes, then end of string reached
  292.               stosb                         ;copy character to string buffer
  293.               inc string_length             ;increment length count
  294.               jmp text4                     ;go back for another character
  295. text5:        cmp string_length,0           ;any characters in string?
  296.               jne text6                     ;yes, then continue
  297.               lea dx,errmsg4                ;no, then abort
  298.               mov al,1
  299.               jmp error1
  300. text6:        mov dx,param1_buffer          ;point DX to filename
  301.               mov ah,3Dh                    ;open the file
  302.               xor al,al
  303.               int 21h
  304.               jnc text7                     ;continue if open succeeded
  305.               lea dx,errmsg5                ;abort if it failed
  306.               mov al,1
  307.               jmp error1
  308. text7:        mov file_handle,ax            ;save file handle
  309. text8:        mov dx,dta                    ;point DX to Data Transfer Area
  310.               mov cx,0C000h                 ;specify C000h bytes to be read
  311.               mov bx,file_handle            ;get DOS file handle
  312.               mov ah,3Fh                    ;DOS function - Read Block
  313.               int 21h                       ;read block from file on disk
  314.               cmp ax,string_length          ;enough bytes read in to compare?
  315.               jb not_found                  ;no, then terminate
  316.               mov bx,ax                     ;save actual bytes read in BX
  317.               mov cx,ax                     ;prepare CX for comparison loop
  318.               sub cx,string_length
  319.               inc cx
  320.               mov di,dta                    ;point DI to block just read
  321. text9:        push cx                       ;save loop counter
  322.               push di                       ;save start index
  323.               mov cx,string_length          ;prepare to compare string
  324.               mov si,text_string            ;point SI to string text
  325.               repe cmpsb                    ;compare while equal
  326.               pop di                        ;restore saved registers
  327.               pop cx
  328.               je text_found                 ;match found if ZF set
  329.               inc di                        ;increment starting index
  330.               loop text9                    ;loop until entire block examined
  331.               cmp bx,0C000h                 ;was end-of-file reached?
  332.               jne not_found                 ;yes, then exit - string not found
  333.               mov ah,42h                    ;DOS function - Move File Pointer
  334.               mov al,1                      ;method code - current pos + offset
  335.               mov cx,0FFFFh                 ;form negative integer in DX:CX
  336.               mov dx,string_length          ;get string length in low word
  337.               not dx                        ;form complement
  338.               add dx,1                      ;form two's complement
  339.               adc cx,0                      ;carry into high word (CX)
  340.               mov bx,file_handle            ;get file handle
  341.               int 21h                       ;move file pointer back
  342.               jmp text8                     ;read another block from disk
  343. text_found:   xor al,al                     ;text found - zero AL
  344.               jmp close_file
  345. not_found:    mov al,1                      ;text not found - set AL to 1
  346. close_file:   push ax                       ;save return code in AL
  347.               mov ah,3Eh                    ;close file before exiting
  348.               mov bx,file_handle
  349.               int 21h
  350.               pop ax                        ;restore AL
  351.               jmp exit
  352. filetext      endp
  353. ;
  354. ;FileSize returns the length in kilobytes of the specified file.  A value of
  355. ;255 means the file is 255K or greater in length.  0 is returned if the file
  356. ;cannot be found.
  357. ;
  358. filesize      proc near
  359.               cmp parameter_count,1         ;more than 1 parameter entered?
  360.               ja size1                      ;yes, then continue
  361.               lea dx,errmsg2                ;no filename - abort
  362.               xor al,al
  363.               jmp error1
  364. size1:        mov dx,param1_buffer          ;point DX to ASCIIZ filename
  365.               mov ah,3Dh                    ;use DOS Open File function
  366.               xor al,al                     ;open for reading only
  367.               int 21h                       ;open the file
  368.               jnc size2                     ;continue if open succeeded
  369.               lea dx,errmsg5                ;abort if it did not
  370.               xor al,al
  371.               jmp error1
  372. size2:        push ax                       ;save file handle on stack
  373.               mov bx,ax                     ;get file handle in BX
  374.               mov ah,42h                    ;use DOS to move file pointer
  375.               mov al,2                      ;method code - EOF + offset
  376.               xor cx,cx                     ;specify 0 offset in DX:CX
  377.               xor dx,dx
  378.               int 21h                       ;move file pointer to EOF
  379.               pop bx                        ;get file handle
  380.               push ax                       ;save EOF address
  381.               push dx
  382.               mov ah,3Eh                    ;close file
  383.               int 21h
  384.               pop dx                        ;retrieve address
  385.               pop ax
  386.               mov cl,10                     ;prepare CL for shift
  387. size3:        shr dx,1                      ;shift AX:DX right 10 bits
  388.               rcr ax,1
  389.               loop size3
  390.               or dx,dx                      ;DX = 0 ?
  391.               jne max_length                ;no, filesize > 255K
  392.               or ah,ah                      ;AH = 0 ?
  393.               jne max_length                ;no, filesize > 255K
  394.               jmp exit                      ;length in AL
  395. max_length:   mov al,255                    ;set AL to 255 for exit
  396.               jmp exit
  397. filesize      endp
  398. ;
  399. ;Mathproc returns a 1 if neither an 8087 nor an 80287 math coprocessor is
  400. ;detected in the system or a 0 if one of them is.
  401. ;
  402. mathproc      proc near
  403.               fninit                        ;initialize (set control word)
  404.               fnstcw control_8087           ;write control word to memory
  405.               cmp control_bytes[1],3        ;control word correctly written?
  406.               je found_8087                 ;yes, then 8087/80287 is there
  407.               mov al,1                      ;no coprocessor - set AL to 1
  408.               jmp exit
  409. found_8087:   xor al,al                     ;zero AL
  410.               jmp exit
  411. mathproc      endp
  412. ;
  413. ;------------------------------------------------------------------------------
  414. ;PARSE_LINE parses the command line for the first two parameters entered and
  415. ;writes them into their respective storage buffers.
  416. ;------------------------------------------------------------------------------
  417. parse_line    proc near
  418.               mov parameter_count,0         ;zero count of entries
  419.               mov si,81h                    ;set SI to start of text
  420.               call next_parameter           ;index to next parameter
  421.               jc parse_exit                 ;exit if there's not one
  422.               mov di,keyword_buffer         ;set DI for output
  423.               call get_parameter            ;parse parameter to buffer
  424.               inc parameter_count           ;increment count
  425.               call next_parameter           ;index to next parameter
  426.               jc parse_exit                 ;exit if there's not one
  427.               mov di,param1_buffer          ;set DI for output
  428.               call get_parameter            ;get next parameter
  429.               inc parameter_count           ;increase count
  430. parse_exit:   mov command_index,si          ;save SI for additional parsing
  431.               ret                           ;and exit
  432. parse_line    endp
  433. ;
  434. ;------------------------------------------------------------------------------
  435. ;NEXT_PARAMETER indexes SI to the next non-space character.
  436. ;Entry:  DS:SI - current character     | Exit:  CF clear - character found
  437. ;                                      |        CF set   - end-of-line reached
  438. ;------------------------------------------------------------------------------
  439. next_parameter proc near
  440.               cmp byte ptr [si],13          ;end-of-line reached?
  441.               je end_of_line                ;yes, then jump
  442.               cmp byte ptr [si],32          ;space character (delimiter)?
  443.               jne no_space                  ;no, then character found
  444.               inc si                        ;advance pointer
  445.               jmp next_parameter            ;check another character
  446. no_space:     clc                           ;clear CF for exit
  447.               ret
  448. end_of_line:  stc                           ;set CF to indicate EOL
  449.               ret
  450. next_parameter endp
  451. ;
  452. ;------------------------------------------------------------------------------
  453. ;GET_PARAMETER transfers the command line parameter indexed by SI into the
  454. ;designated buffer area, capitalizing lowercase characters in the process and
  455. ;terminating the string with a zero for ASCIIZ representation.
  456. ;Entry:  DS:SI - parameter address
  457. ;        ES:DI - buffer address
  458. ;------------------------------------------------------------------------------
  459. get_parameter proc near
  460.               cmp byte ptr [si],13          ;end-of-line reached?
  461.               je end_get                    ;yes, then we're done
  462.               cmp byte ptr [si],32          ;space delimiter encountered?
  463.               je end_get                    ;yes, then we're done
  464.               lodsb                         ;get the character
  465.               cmp al,97                     ;is it a lowercase character?
  466.               jb getparam1
  467.               cmp al,122
  468.               ja getparam1
  469.               and al,0DFh                   ;yes, then capitalize it
  470. getparam1:    stosb                         ;buffer the character
  471.               jmp get_parameter             ;loop back for more
  472. end_get:      xor al,al                     ;zero AL
  473.               stosb                         ;end string with 0 delimiter
  474.               ret
  475. get_parameter endp
  476. ;
  477. endprog       label byte                    ;start of buffer area
  478. ;
  479. code          ends
  480.               end begin
  481.