hw.asm 3.6 KB
Newer Older
Ercan Ersoy's avatar
Ercan Ersoy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
; HW.ASM
;
; License CC0 PUBLIC DOMAIN
;
; To the extent possible under law, Mark J. Olesen has waived all copyright
; and related or neighboring rights to FDOSTUI Library. This work is published
; from: United States.

include DPMI.INC

.MODEL flat

.DATA

PUBLIC __hw_drives

__hw_drives db 26 dup(0) ; drives 'A'-'Z' 0=not available 1=available

.CODE

; int 21 fun 29 parse file name
; used in testing if drive letter is valid
; ds:si null terminated string contains drive letter followed by colon
; es:di 37-byte dummy fcb buffer
; on return if al is ff the drive is invalid

; detect drives 
; inputs 
;  none
; ouputs
;  __hw_drives
; destroys:
;  none
;
PUBLIC hw_detect_drives_ 
hw_detect_drives_ PROC

    push ebp 
    mov ebp, esp 
    sub esp, SIZE realmode_regs ; setup stck for realmode regs
    
    push eax
    push ebx
    push ecx
    push edx
    push esi
    push edi
    push es
   
    ; fcb needs 40 bytes
    ; filespec needs 3 bytes
    ; allocate 3 pages (3*16=48)
    ; int 31h function 100h Allocate DOS memory block
    ; bx = number of 16 byte paragahs desired
    mov ax, 0100h
    mov bx, 03h ; 3 * 16 = 48
    int 031h
    jc drive_error
    ; returns 
    ; cf clear
    ;  ax = real mode segment base address of allocated block
    ;  dx = selector for allocated block
    
    mov fs, dx ; fs:esi file spec 
    xor esi, esi
    mov [byte ptr fs:esi+0], 'A'
    mov [byte ptr fs:esi+1], ':'
    mov [byte ptr fs:esi+2],  0
    mov edx, eax  ; dx = real mode segment for filespec & fcb
    
    push ss ; es:edi realmode_regs
    pop es
    lea edi, [ebp - SIZE realmode_regs]
    
    xor ebx, ebx ; index into __hw_drives/drive number
    
drive_loop:

    ; zero out realmode_regs struct
    push edi
    mov ecx, SIZE realmode_regs
    xor eax, eax
    rep stosb
    pop edi
   
    mov [word ptr es:edi]._ds, dx ; filespec segment
    mov [word ptr es:edi]._es, dx ; fcb segment
    mov [dword ptr es:edi]._edi, 4 ; fcb offset

    push ebx
    
    ; simulate real mode interrupt
    mov [dword ptr es:edi]._eax, 02900h ; parse filename
    xor ebx, ebx
    mov bl, 021h  
    xor ecx, ecx
    mov ax, 0300h
    int 031h
    
    pop ebx
    
    mov eax, [dword ptr es:edi]._eax
    cmp al, 0ffh   ; ffh = invalid
    je drive_invalid
    mov ax, 1
    jmp drive_store 

drive_invalid:
    xor ax, ax
    
drive_store:

    push esi
    lea esi, __hw_drives
    add esi, ebx
    mov [byte ptr esi], al
    pop esi
    inc [byte ptr fs:esi]
    inc ebx
    cmp ebx, 25
    jle drive_loop    
    
    ; int 31h function 101h Free DOS memory block */
    ; dx = selecttor of block to be freed */
    mov dx, fs
    mov ax, 0101h
    int 031h
    
    ; a&b are always reported above
    ; check BIOS equipment word to see how many floppies there are
    mov ebx, 0410h; BIOS data area equipment word
    mov dx, [word ptr ebx]
    
    ; bit 0 indictates if floppy installed
    ; 0 not installed
    ; 1 installed
    mov ax, dx
    and ax, 01h
    jnz drive_testflop
    
    mov [byte ptr __hw_drives], 0
    mov [byte ptr __hw_drives+1], 0
    jmp drive_exit 
   
drive_testflop:
    ; bits 6 & 7 number of floppies less 1
    mov cl, 05h
    shr dx, cl
    and dx, 011b
    dec dx
    cmp dx, 2 
    jge drive_exit
    
    mov [byte ptr __hw_drives+1], 0 ; no b drive
    
drive_error:
    
drive_exit: 

    pop es
    pop edi
    pop esi
    pop edx
    pop ecx
    pop ebx
    pop eax

    mov esp, ebp 
    pop ebp 
    
    ret
hw_detect_drives_  ENDP

END