               PAGE 60,132
TITLE  WHAT.COM  VER.2.0  14-AUG-83  19:00
comment *

                        WHAT.COM


        VERSION 2.0     14-AUG-83

        Written by      Warren Craycroft
                        6236 Oakdale Ave.
                        Oakland, CA  94605


        (C)  1983  by Warren Craycroft.  Permission is granted to copy and
        distribute this program, including source code, provided that no
        charge shall be made except for a reasonable charge for the media
        and handling, and that this notice shall remain intact in all copies.


*
comment *
        This program is a utility that can be used with DOS 2.0 to
        obtain equipment configuration information.  This information
        is passed back from WHAT in the form of a returning
        "errorlevel", and may therefore be tested by appropriate
        IF subcommands in subsequent Batch File lines.

        The configuration information is obtained from BIOS from the
        system board switch settings  and from system parameters that
        DOS manages.


        WHAT is called with one parameter naming the equipment
        to be reported.  Only the first letter of the parameter
        need be entered on the WHAT command line.  The parameters
        are as follows:

        D  or   DRIVES          returns the number of valid disk drive letters
                                of floppy drives and fixed disks. This is the
                                parameter that is usually patched by virtual
                                disk enhancement programs.  DOS considers a
                                one physical drive system to have two valid
                                virtual drives, so you will get a 2 with this
                                parameter on such a system.

        F  or  FLOPPIES         returns the number of physical diskette drives
                                that is set on the System Board Switches
                                With a one physical drive system, you will get
                                a 1 with this parameter.

        V  or   VIDEO           returns:        0  no monitor
                                                1  40x25, color adaptor
                                                2  80x25, color adaptor
                                                3  80x25, either color
                                                   adaptor or monochrome
                                                   adaptor

        J  or   JOY adaptor     returns         0  no adaptor present
                                                1  adaptor present
                                                (NOT the number of joy STICKS)

        P  or   PARALLEL ports  returns number of parallel ports: 0,1,2, ...

        S  or   SERIAL ports    returns number of serial ports: 0,1,2, ...

        K  or   K blocks        returns number of 4 K memory blocks set on
                                switches


        R  or  RELEASE          returns the major release number of the
                                DOS you are running (e.g. 2 = DOS 2.0)
                                (returns zero for versions less than 2.0)

        M  or  MINOR            returns the minor release number of the
                                DOS you are running (e.g. 0 = DOS 2.0)
                                (returns zero for versions less than 2.0)

        C  or  CURRENT          returns the current default drive number.
                                (0 = A:, 1 = B:, etc)


        If the command line is empty or if the parameter does not begin with
        one of the above letters, an error message is printed and this
        utility halts execution of a Batch File in progress by executing
        a CONTROL-BREAK.
*
;
;               constant equates
;
BEL_CHAR        EQU     07              ;ascii BEL keycode
CR              EQU     0DH             ;ascii carriage return
LF              EQU     0AH             ;ascii line feed
TAB_CHAR        EQU     09              ;ascii tab
BLANK_CHAR      EQU     ' '             ;ascii blank
;
;
;       declare a relocatable segment.  Follow the .COM file requirements
;       of entry point at 100H and making all seg register references relative
;       to CS (no relocatable values MOV'ed into segment registers).
;
;
COM_CODE      SEGMENT
;
                ORG     80H             ;PSP offset 80:  user's command line
PSP_CMD_LINE    LABEL   BYTE            ;define a label for address refs
;
                ORG     100H            ;for COM file
;
;
                ASSUME  CS:COM_CODE,DS:COM_CODE    ;tell assembler value of CS
                                                   ; and DS
;
;
START           PROC            FAR     ;FAR is meaningless; no RETS
;
                SUB     CX,CX                   ;clear CX
                MOV     CL,PSP_CMD_LINE         ;byte count of line
                OR      CL,CL                   ;zero?
                JZ      BAD_PARAM               ;jump if yes, no param
                SUB     BX,BX                   ;else zero index
;
;       find first non-blank or non-tab character of command line
;
FIND_PARAM:     INC     BX                      ;point to next byte
                CMP     PSP_CMD_LINE[BX], BLANK_CHAR    ;blank char?
                JE      LOOP_FIND               ;keep looking if yes
                CMP     PSP_CMD_LINE[BX], TAB_CHAR      ;tab ?
                JNE     FOUND_PARAM             ;if not, 1st non blank
LOOP_FIND:      LOOP    FIND_PARAM              ;loop on char count
;
;       command line parameter was missing or was not recognized.
;
;       display message and return through CONTROL BREAK handler
;
BAD_PARAM:      MOV     DX,OFFSET ERROR_MESSAGE ;display error message
                MOV     AH,9                    ;"display string" DOS call
                INT     21H                     ;call DOS to display message
                INT     23H                     ;exit through CNTRL BREAK
                MOV     AH,255                  ;error errorlevel
                JMP     EXIT                    ;exit through 4CH fn call
;
;       else a non-blank character was found in command line.
;
;       call INT 11H (because most of following procedures need the
;       BIOS configuration report; only K blocks of memory request needs
;       INT 12H.
;
FOUND_PARAM:    INT     11H                     ;report returned in AX
;
;       now search in PARAMS table for the first letter. When matched,
;       BX pointing to corresponding entries in other tables.  Call
;       the procedure in PROCEDURES[BX], which will may use mask in
;       FIELD_MASK[BX] to get bit field, and shift count in
;       SHIFT_COUNT[BX] to right justify or divide the result of masking.
;
                MOV     DL,PSP_CMD_LINE[BX]     ;get the parameter from line
                MOV     CX,NUMBER_PARAMS        ;get table length for looping
                SUB     BX,BX                   ;zero index
TABLE_LOOKUP:   CMP     DL,PARAMS[BX]           ;param in left byte of table?
                JE      DO_PARAM                ;jump if matched
                CMP     DL,PARAMS[BX+1]         ;else param in right byte?
                JE      DO_PARAM                ;jump if matched
                INC     BX                      ;else next table entry
                INC     BX
                LOOP    TABLE_LOOKUP            ;loop on table length
                JMP     BAD_PARAM               ;param not in table
;
;       param found.  execute the procedure to prepare the errorlevel
;       code from the report from INT 11H or INT 12H (report is in AX)
;
DO_PARAM:       CALL    PROCEDURES[BX]
;
;       AL contains the errorlevel, return to DOS
;
EXIT:           MOV     AH,4CH                  ;"terminate" func call
                INT     21H                     ;return to DOS with errorlev
START           ENDP
;
;*****************************************************************************
;
;       procedures to prepare the errorlevel code for the different requests
;
MASK_SHIFT      PROC    NEAR
                AND     AX,FIELD_MASK[BX]       ;pass desired bit field
                                                ;through mask
                MOV     CX,SHIFT_COUNT[BX]      ;right justify or divide
                ROR     AX,CL
                RET                             ;errorlevel in AL
MASK_SHIFT      ENDP
;
;
FLOPPIES        PROC    NEAR
;
;       returns the number of physcial drives set on switches
;
                PUSH    AX                      ;save report
                ROR     AX,1                    ;shift bit 0 into CY
                POP     AX                      ;restore report
                JC      DISKS_PRESENT           ;bit 0 = 1 means disks present
                SUB     AL,AL                   ;else report zero disks
                RET
DISKS_PRESENT:  CALL    MASK_SHIFT              ;get 0,1,2, or 3 from report
                INC     AL
                RET                             ;return 1,2,3, or 4
FLOPPIES        ENDP
;
;
MEMORY          PROC    NEAR
;
;       use INT 12H to get 1K blocks, then divide by 4 to get number 4K blocks
;
                INT     12H                     ;get memory report
                CALL    MASK_SHIFT              ;divide by 4
                RET                             ;4K blocks in AL
MEMORY          ENDP
;
;
RELEASE         PROC    NEAR
;
;       use DOS fn 30H to get DOS version number.  AL = major,  AH = minor
;
                MOV     AH,30H                  ;DOS fn "get version numbers"
                INT     21H                     ;call DOS to get version
                CALL    MASK_SHIFT              ;mask_shift has the correct
                                                ;params for major or minor
                RET
RELEASE         ENDP
;
;
CURRENT         PROC    NEAR
;
;       Use DOS fn 19H to get the current default drive number
;
                MOV     AH,19H                  ;DOS fn "get current def drive"
                INT     21H                     ;call DOS to get default drive
                CALL    MASK_SHIFT              ;mask_shift has the correct
                                                ;params
                RET
CURRENT         ENDP
;
;
DRIVES          PROC    NEAR
;
;       returns the number of valid drives letters for floppies, fixed, and
;       virtual disks
;
                MOV     AH,19H                  ;DOS fn "return current drive"
                INT     21H                     ;current drive returned in AL
                MOV     DL,AL                   ;put current in DL for next call
                                                ;(so we dont disturb current )
                MOV     AH,0EH                  ;DOS fn "sel disk, return number
                INT     21H                     ;number of drives retd in AL
                RET
DRIVES          ENDP
;*****************************************************************************
;
;               tables for parameter execution
;
;               total number of parameters (table lengths)
;
NUMBER_PARAMS   EQU     10              ;all tables have this many entries
;
;               FIELD_MASK table
;
;       Each equipment request has a mask that passes the bits in the
;       equipment report word that correspond to the request
;
FIELD_MASK      DW      00C0H           ;FLOPPIES       bits 7, 6
                DW      0030H           ;VIDEO          bits 5,4
                DW      1000H           ;JOY            bit 12
                DW      0C000H          ;PARALLEL       bits 15,14
                DW      0E00H           ;SERIAL         bits 11,10,9
                DW      0FFFFH          ;K MEMORY       pass entire number
                DW      00FFH           ;RELEASE(MAJOR) pass AL
                DW      0FF00H          ;MINOR RELEASE  pass AH
                DW      00FFH           ;CURRENT        pass AL
                DW      00FFH           ;DRIVES         pass AL
;
;               SHIFT_COUNT table
;
;       Each different equipment request has a shift count that either
;       right justifies the bit field passed by the mask or else divides
;       the number in AX
;
SHIFT_COUNT     DW      6               ;FLOPPIES
                DW      4               ;VIDEO
                DW      12              ;JOY
                DW      14              ;PARALLELS
                DW      9               ;SERIALS
                DW      2               ;K BLOCKS (divide by 4)
                DW      0               ;RELEASE (MAJOR) NUMBER
                DW      8               ;MINOR RELEASE NUMBER
                DW      0               ;CURRENT DRIVE
                DW      0               ;DRIVES
;
;               PARAMS table
;
;       contains the legal parameter letters.  a match in this table
;       points BX to corresponding entries in other tables
;
PARAMS          DB      'F','f'         ;FLOPPIES
                DB      'V','v'         ;VIDEO
                DB      'J','j'         ;JOY
                DB      'P','p'         ;PARALLEL
                DB      'S','s'         ;SERIAL
                DB      'K','k'         ;K BLOCKS
                DB      'R','r'         ;RELEASE (MAJOR) NUMBER
                DB      'M','m'         ;MINOR RELEASE NUMBER
                DB      'C','c'         ;CURRENT DRIVE
                DB      'D','d'         ;DRIVES
;
;               PROCEDURES table
;
;       Each equipment request is treated by a procedure called through
;       this table.
;
PROCEDURES      DW      FLOPPIES
                DW      MASK_SHIFT
                DW      MASK_SHIFT
                DW      MASK_SHIFT
                DW      MASK_SHIFT
                DW      MEMORY
                DW      RELEASE
                DW      RELEASE
                DW      CURRENT
                DW      DRIVES
;
;
ERROR_MESSAGE   DB      CR,LF,BEL_CHAR
                DB      '****  WHAT cannot recognize parameter ****$'
COM_CODE        ENDS
                END     START
