;*******************************************************************
; Listing 3.
; Get DOS version and INT-21 handler offset correction
; Copyright (C) 1994 FM de Monasterio
;
; Input:  None
; Output: AL = major DOS version
;         AH = minor DOS version
;         CX = value to add to CP/M handler offset to get INT-21h
;              handler offset; 0 if OS/2 or WINDOWS NT DOS box
;         DL = 0:MS-DOS, 63h:DR-DOS 3.41, 65h:DR-DOS 5, 67h:DR-DOS 6
;              70h:DR PalmDOS, 71h:DR-DOS 6 WfW, 72h:Novell DOS 7
;         DH bits 0-6 = 10h:DOS in HMA, 8:DOS in ROM, 0:DOS in RAM
;            bit 7 = 0:MS-based DOS, 1:DR-DOS/Novell DOS
; Alters: AX BX CX DX
;*******************************************************************
EVEN
DosCheck PROC NEAR

        ; Test for DR-DOS version 3.41-6.0 or Novell DOS 7.0

            stc                   ; preload CF=1
            mov  ax,4452h         ; fxn get BDOS kernel codes:
            int  21h              ; AH=uni/multi code, AL=BDOS code
            jc   DosCheck2        ; CF=1, not DR-DOS

            mov  dl,al            ; save BDOS kernel code
            sub  dh,dh            ; assume DOS 3.xx (no HMA)
            cmp  al,65h           ; earlier than DR-DOS 5?
            jb   DosCheck1        ; yes, get fake version

            push es
            mov  ax,4458h         ; fxn get int vars table
            int  21h              ; returns ES:BX-> table
            mov  es,es:[bx+0Eh]   ; get segm of kernel redirector
            mov  bx,es:[3]        ; get segment of CP/M far jump
            pop  es
            dec  bx               ; relocated to HMA (FFFF)?
            jnz  DosCheck1        ; no, keep DH=0
            mov  dh,10h           ; else signal DOS in HMA
DosCheck1:  or   dh,80h           ; signal DR-DOS/Novell DOS

            mov  ax,3000h         ; fxn get DOS version
            int  21h
            mov  cx,10            ; INT-21h address correction
            retn


        ; Test for MS-DOS/PC-DOS 5+
EVEN
DosCheck2:  xor  bx,bx            ; preload CF=0, BX=0
            mov  cx,bx            ; CX=0
            mov  dx,bx            ; and DX=0

            mov  ax,3306h         ; fxn get true MS-DOS version
            int  21h

        ; MS-DOS and PC-DOS 5+ return:
        ; BH = minor version
        ; BL = major version
        ; DL = revision no., 0:A, 1:B, etc...
        ; DH = 8: DOS in ROM, 16: DOS in HMA
        ; CF = 0: DOS 5.x-6.x revision A
        ; CF = 1: DOS 5.0 revision B

        ; DR-DOS 3.41 through 6.0 return AX=1, CF=1
        ; OS/2 2.1 returns version 20.10
        ; WINDOWS NT DOS box returns version 5.50

            cmp  al,0FFh          ; is this MS-DOS 2-4?
            je   DosCheck4        ; yes, not supported
            cmp  ax,1             ; is this DR-DOS 5-6?
            je   DosCheck4        ; yes, not supported

            cmp  bl,14h           ; is it OS/2 2.1?
            jae  DosCheck3        ; yes, return CX=0
            cmp  bx,3205h         ; WINDOWS NT box?
            je   DosCheck3        ; yes, return CX=0

            cmp  bh,64h           ; PowerLAN redirector?
            jae  DosCheck4        ; yes, assume not reliable
            cmp  bl,5             ; else MS-DOS 5+?
            jb   DosCheck4        ; below 5, not supported

            mov  ax,bx            ; else get true version and
            mov  cx,37            ; assume kernel is in low ram
            test dh,10h           ; HMA relocation?
            jz   DosCheck3        ; no, skip
            mov  cx,-50           ; else adjust correction
DosCheck3:  retn


        ; Get standard MS-DOS version
EVEN
DosCheck4:  mov  ax,3001h         ; fxn get DOS version
            int  21h

        ; Returns:
        ; AH = minor, AL = major version
        ; BL:CX = optional 24-bit user SN (usually none)
        ; if DOS 2-4 or AL=0: BH = 0:IBM, 1:COMPAQ...FF:Microsoft
        ; if DOS 5+ and AL=1: BH = 8:DOS in ROM

            sub  dx,dx            ; (no DR-DOS or HMA kernel)
            mov  cx,dx            ; assume OS/2
            cmp  al,10h           ; OS/2 1+?
            jae  DosCheck5        ; yes, return CX=DX=0

            mov  cx,-9            ; assume DOS-2 offset bias
            cmp  al,2             ; is this DOS 2.x?
            je   DosCheck5        ; yes, exit

            mov  cx,37            ; assume DOS 5+ ignoring 3306h
            mov  dh,bh            ; (else BH=0)
            cmp  al,5             ; is this DOS 5+?
            jae  DosCheck5        ; yes, exit

            mov  cl,26            ; else assume DOS 3.1x-4.0x
            cmp  ax,0A03h         ; is this 3.10 or later?
            jae  DosCheck5        ; yes, exit
            sub  cl,2             ; else is DOS 3.0x
DosCheck5:  retn
DosCheck ENDP
;********************************************* End of Listings *****
