Category : Batch File Utilities - mostly for DOS
Archive   : CHECKELA.ZIP
Filename : CHECKEL.ASM

 
Output of file : CHECKEL.ASM contained in archive : CHECKELA.ZIP
CSEG SEGMENT PARA PUBLIC 'CODE'
ORG 80H
CCOUNT DB ? ;command line params
CLINE DB 127 DUP (?) ;command line tail
ORG 100H ;set up for COM file
ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;

PROGRAM PROC NEAR
JMP START

DESIGN DB 'Designed by Glenn Snow '
OLDSS DW 0 ;used to store SS
OLDSP DW 0 ;used to store SP
OLDDI DW OFFSET SETCMD ;used as string counter
MULT DB 0 ;flag for multiple
; command.com's
SETLEN DB 0 ;length of SET command
SETCMD DB 'SET' ;beginning of SET cmd
SET1 DB 124 DUP (0) ;rest of set goes here
TBUFF DB 4 DUP (?) ;buffer for decimal str
VAL DW ? ;store errorlevel here
ELOFS DW ? ;store magic err flag address
C1 DW ? ;store command.com seg
C2 DW ? ;store command.com seg
MSG1 DB 0DH,0AH,'The current errorlevel is: $'
MSG2 DB 0DH,0AH,24H
MSG3 DB 0DH,0AH,'Sorry, this version only works with DOS 3.1, 3.2, 3.3, and '
DB '4.0$'
MSG4 DB 0DH,0AH,'A secondary command processor has been loaded.',0DH,0AH
DB 'The errorlevel in the primary command processor is: $'
MSG5 DB 'The errorlevel in the CURRENT command processor is: $'

START: CMP CCOUNT,0 ;was a variable entered?
JZ NOVAR ;if not, go to NOVAR
MOV CL,CCOUNT ;if so, move the variable
XOR CH,CH ; entered on the command line
MOV SI,OFFSET CLINE ; into the SET command line
MOV DI,OFFSET SET1 ;
REP MOVSB ;
MOV AL,'=' ;and now make it SET [var]=
STOSB ;
MOV AL,CCOUNT ;record the current length of
ADD AL,4 ; the set command string
MOV SETLEN,AL ; in the various places where
MOV AX,OLDDI ; we will need it
MOV CL,SETLEN ;
XOR CH,CH ;
ADD AX,CX ;
MOV OLDDI,AX ;
NOVAR: MOV AH,30H ;set up to get DOS version
INT 21H ;go get it
CMP AX,0004H ;is it version 4.0 ?
JZ V400 ;if so, jump to v400
CMP AX,1E03H ;is it version 3.3 ?
JZ V330 ;if so, jump to v330
CMP AX,1403H ;is it version 3.2 ?
JZ V320 ;if so, jump to v320
CMP AX,0A03H ;is it version 3.1 ?
JZ V310 ;if so, jump to v310
JMP WRONGVER ;otherwise, jump to wrongver message

V400: MOV ELOFS,0F2CH ;load 4.0 errorlevel flag offset
JMP CONT1 ;and continue

V330: MOV ELOFS,0BEAH ;load 3.3 errorlevel flag offset
JMP CONT1 ;and continue

V320: MOV ELOFS,0AFAH ;load 3.2 errorlevel flag offset
JMP CONT1 ;and continue

V310: MOV ELOFS,0AC8H ;load 3.1 errorlevel flag offset
JMP CONT1 ;and continue

CONT1: MOV AX,352Eh ;set up to get primary COMMAND.COM seg
INT 21h ;and go get it (address of int 2Eh)
MOV C1,ES ;save the segment in variable C1
MOV AX,3523h ;set up to get second COMMAND.COM seg
INT 21H ;and go get it (address of int 23h)
MOV C2,ES ;save the segment in variable C2
PUSH ES ;put this segment...
POP AX ;into AX register, and
CMP AX,C1 ;compare it to first one
JZ SINGLE ;if same, then only one COMMAND.COM
MOV MULT,1
MOV DX,OFFSET MSG4 ;otherwise, set up to notify user
CALL OUTMSG ;tell user of secondary COMMAND.COM
MOV AX,C1 ;move primary address into ax
PUSH AX ;and then load it into
POP DS ;DS to get errorlevel
CALL GETEL ;go find the errorlevel and report
MOV DX,OFFSET MSG5 ;now do the same for the secondary
CALL OUTMSG ;command processor...first the msg
MOV AX,C2 ;then the
MOV MULT,0
PUSH AX ;
POP DS ;
CALL GETEL ;secondary errorlevel message
JMP EXIT ;and jump to the quit routine

WRONGVER:
MOV VAL,0 ;set up new errorlevel as zero
MOV DX,OFFSET MSG3 ;load the error message
CALL OUTMSG ;and send it out
JMP EXIT ;then exit routine

SINGLE: MOV DX,OFFSET MSG1 ;load the message
CALL OUTMSG ;and send it out
MOV AX,C1 ;get primary COMMAND address
PUSH AX ;and put it
POP DS ;into DS
CALL GETEL ;then get errorlevel and report
JMP EXIT ;now jump to exit routine

GETEL: PUSH DS ;save the DS register
PUSH CS ;and load the CS register
POP DS ;into DS instead
MOV SI,ELOFS ;now get the ERRORLEVEL flag offset
POP DS ;and restore DS
LODSB ;load the flag into AL
PUSH CS ;and now reload the CS register
POP DS ;into DS
MOV VAL,AX ;and save the errorlevel for our exit
MOV DX,VAL ;set up to print the errorlevel
CALL OUTVAL ;and send it out
MOV DX,OFFSET MSG2 ;set up to print out blank line
CALL OUTMSG ;and go print it
RET ;now go back to where you came from

OUTVAL: MOV CX,0 ;These routines just
MOV DI,OFFSET TBUFF ; print out the values
DEC8OUT1: ; in a readable (decimal) manner.
PUSH CX ;
MOV AL,DL ; They were basically stolen
MOV AH,0 ; from the "Bluebook of Assembly
MOV CL,10 ; Routines" published by
DIV CL ; The Waite Group
MOV DL,AL ;
MOV AL,AH ;
ADD AL,30H ;
MOV [DI],AL ;
INC DI ;
POP CX ;
INC CX ;
CMP DL,0 ;
JNZ DEC8OUT1 ;

DEC8OUT2:
DEC DI ; More stolen routines
MOV AL,[DI]
CALL STDOUT
LOOP DEC8OUT2
RET

STDOUT: PUSH DX ; And yet again
MOV DL,AL
CMP CCOUNT,0 ;but here, we put in our routine
JZ STD1 ; to save the errorlevel string
CMP MULT,1 ; to our SET command
JZ STD1 ; (unless there are multiple
PUSH ES ; command.com's present, then we
PUSH CS ; just save the latest one
POP ES
PUSH DI
MOV DI,CS:OLDDI
STOSB
MOV CS:OLDDI,DI
POP DI
POP ES
INC CS:SETLEN
STD1: MOV AH,2 ;print out the errorlevel to screen
INT 21H
POP DX
RET

OUTMSG: PUSH AX ; Still...
MOV AH,9
INT 21H
POP AX
RET

EXIT: CMP CCOUNT,0 ;run SET command?
JZ EXIT1 ;no? then exit
PUSH CS ;otherwise, we need to get
POP DS ; ready for the undocumented
PUSH CS ; DOS interrupt 2Eh
POP ES ; which executes a command
MOV SI,OFFSET SETLEN ; from the ORIGINAL
MOV DI,CS:OLDDI ; COMMAND.COM, not a shell
MOV AL,0DH
STOSB
MOV AL,0AH
STOSB
MOV AX,CS
MOV BX,OFFSET ENDCODE ;save our own program memory
MOV CL,4 ; in paragraph form
SAR BX,CL
INC BX ;add a bit, just for safety
MOV AH,4AH ;and release the rest to DOS
INT 21H
JC EXIT1 ;if problem, then forget it

PUSHF ;unfortunately, this interrupt
MOV OLDSS,SS ; is incredibly messy, and
MOV OLDSP,SP ; trashes everything, so we
; must save what we need and
; then we can.....
INT 2EH ;run our SET command
MOV SS,CS:OLDSS ;get back our stack segment
MOV SP,CS:OLDSP ; and pointer
POPF ; and flags

EXIT1: MOV AX,CS:VAL ;And FINALLY, the exit routine
MOV AH,4CH ; leaves the ERRORLEVEL unchanged
INT 21H ; from when we entered this program

ENDCODE: ;label so we know where our code ends

PROGRAM ENDP
CSEG ENDS

END PROGRAM


  3 Responses to “Category : Batch File Utilities - mostly for DOS
Archive   : CHECKELA.ZIP
Filename : CHECKEL.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/