.MODEL small
LOCALS

main  segment public
  assume cs:main, ds:main, es:main

OldDOS  db 0Dh,0Ah,0Ah
  db 'DOS ver. 3.20 or higher required',0Dh,0Ah,'$'

Bye  db 0Dh,0Ah,0Ah
  db 'Good luck!',0Dh,0Ah,'$'

DefaultDisk db ?
NoOfDrives db ?

Drive  db 0Dh,0Ah
DiskName db 'A: - $'

DeviceTypes db '320K/360K floppy disk$'
  db '1.2M floppy disk$'
  db '720K floppy disk$'
  db 'single-density 8" floppy disk$'
  db 'double-density 8" floppy disk$'
  db 'fixed disk$'
  db 'tape drive$'
  db '1.44M floppy disk$'
  db 'optical or Superstor disk$'
  db '2.88M floppy disk$'
  db 'unknown device$'
  db 'network disk$'
  db 'virtual/subst/assign disk$'

;-----------------------------------------------

DrivesInfo proc far
  push cs
  pop ds
  mov ah,19h
  int 21h
  mov DefaultDisk,al
  call GetDrivesNo
  jc @@exit
  push cs
  pop es
  xor bx,bx
@@next:
  push bx
  call GetDriveType
  push ax
  mov dx,offset Drive
  mov ah,9
  int 21h
  mov di,offset DeviceTypes
  pop dx
  mov al,'$'
  mov cl,0FFh
@@loop:
  sub dl,1
  jc @@skip
  repnz scasb
  jmp short @@loop
@@skip:
  mov dx,di
  int 21h
  inc DiskName
  pop bx
  inc bx
  cmp bl,NoOfDrives
  jb @@next
  mov bl,DefaultDisk
  call GetDriveType  ; to avoid "Insert disk..." message
  mov dx,offset Bye
@@exit:
  mov ah,9
  int 21h
  mov ax,4C00h
  int 21h
DrivesInfo endp

;----------------------------------------------- Get Drives No

GetDrivesNo proc near
  mov ah,30h   ;Get Dos Version
  int 21h
  xchg al,ah
  mov dx,offset OldDOS
  cmp ax,314h
  jc @@retn

  mov ah,52h
  int 21h   ;Get Dos Variables Block
  mov al,es:[bx+20h]
  mov NoOfDrives,al
@@retn:  retn
GetDrivesNo endp

;----------------------------------------------- Get Device Type
;  BL=logical drive (0=A, 1=B, ...)
; RETURN: AL=device type: 0 - floppy 360Kb
;    1 - floppy 1.2Mb
;    2 - floppy 720Kb
;    3 - floppy 8"/1 side
;    4 - floppy 8"/2 side
;    5 - hard drive
;    6 - tape device
;    7 - floppy 1.44Mb
;    8 - optical / superstore
;    9 - floppy 2.88M
;    A - unknown
;    B - network
;    C - virtual/subst/assign
; Note: drive BL became default drive after this procedure -
;       useful for fantom drives!!!

GetDriveType proc near
  inc bl
  mov ax,4409h
  int 21h   ;Check if block device remote
  jc @@unknown
  and dx,9200h
  mov al,0Bh
  jnz @@retn   ;jmp if network device

  mov ax,440Fh
  int 21h   ;Set logical drive map
  mov al,0Ch
  jc @@retn   ;jmp if virtual/subst/assign

  mov ax,440Dh
  mov cx,0860h
  mov dx,offset Buffer ;Buffer length > 200 bytes
  mov Buffer,0
  int 21h   ;Get device parameters
  mov al,Buffer+1  ;0-360K  1-1.2M  2-720K
      ;3,4-8"  5-HDD  6-Tape
      ;7-1.44M 8-Optic 9-2.88M
  cmp al,9
  jna @@retn
@@unknown: mov al,0Ah   ;invalid or unknown drive
@@retn:  retn
GetDriveType endp

;-------------------------------------- Buffer for device parameter block

Buffer  db 256 dup (?)

.STACK  128

main  ends
  end DrivesInfo
