⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dos.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:

cEnd

;*--------------------------------------------------------------------------
;*
;*  LONG DosDiskFreeSpace(Drive)
;*
;*  note:
;*      Drive == 0      default
;*      Drive == 1      A
;*      Drive == 2      B
;*--------------------------------------------------------------------------

; Returns the number of bytes free in DX:AX

cProc DosDiskFreeSpace, <FAR, PUBLIC>
ParmW Drive
cBegin
            mov     dx,Drive
            mov     ah,36h              ; Set Current Drive
            int     21h
            cmp     ax, 0ffffh          ; bogus drive?
            je      error
            mul     cx                  ;
            mul     bx
            jmp     done                ; DX:AX contains free space
error:
            mov     dx, ax              ; return dx:ax = -1L
done:
cEnd


;*--------------------------------------------------------------------------*
;*                                                                          *
;* BOOL DosIsRemote(int);                                                   *
;*                                                                          *
;* ENTRY:  Word, iPDrive: must be of the form ( logical volume A = 0 )      *
;*               Physical Drive Spec.                          B = 1        *
;*                                                             C = 2        *
;*                                                             ect.         *
;* EXIT: BOOL  returned in AX Remote = Remote                               *
;*                            False  = Local                                *
;*                            not_supported                                 *
;*                                                                          *
;* DESTROYS: AX. (preserves all registers except AX for return value)       *
;*                                                                          *
;* AUTHOR: MC                                                               *
;*                                                                          *
;*--------------------------------------------------------------------------*

cProc   DosIsRemote, <FAR, PUBLIC>, <BX,CX,DX,SI,DI,ES,DS>

ParmW   iPDrive                   ; Int Physical drive spec 0 - 25
localV  local_name,     16d       ; Buffer to hold redirected local name.
localV  net_name,      128d       ; Buffer to hold remote device name.
localV  remote_list,    42d       ; Buffer, will be filled with list of
                                  ; redirected local device names.
cBegin

        ; First, we need to make a list of remote devices (logical Volumes)
        ; I have to use DOS call int 21h/5f02h because DOS call int 21h/4409h
        ; is not reliable under DOS versions 4.00 and 4.01. (IBM fuck-up).

        xor     cx,cx
        xor     dx,dx

next_entry:
        mov     bx,cx                 ; CX = redirection list index.
        mov     ax,ss                 ; Load segs for stack vars.
        mov     es,ax
        mov     ds,ax
        mov     ax,5f02h              ; func 5f/02 Get redirection list.
        lea     si,local_name         ; ds:si = local_name
        lea     di,net_name           ; es:di = net_name
        push    cx                    ; save CX
        push    dx                    ; save DX
        int     21h
        pop     dx                    ; restore DX
        pop     cx                    ; restore CX
        jc      check_support         ; error, not supported or end of list.
        cmp     bl,04h                ; Is redirected device a drive ?
        jne     not_a_drive           ; If not, we don't care !

        mov     al,byte ptr ds:[si]   ; Grab volume name.
        sub     al,41h                ; Convert to volume number A=0 ect.
        lea     di,remote_list        ; get a pointer to our remote list.
        add     di,dx                 ; DX is index into list of devices.
        mov     byte ptr es:[di],al   ; save remote device into out list.
        inc     dx                    ; Increment list index pointer.

not_a_drive:
        inc     cx                    ; CX = redirection list index.
        jmp     short next_entry

check_support:
        cmp     ax,12h                ; AX = 12h means end of redir list !
        jne     Game_Over_Man         ; If not then soooo long.
        lea     di,remote_list
        add     di,dx                 ; DX is index into list of devices.
        mov     byte ptr es:[di],0ffh ; Terminate list.

        ;
        ; Is the drive remote ?
        ; See if it matches any entries in list of redirected devices.
        ;

        lea     di,remote_list        ; pointer to list of redirected drives.
        mov     bx,iPDrive            ; Grab the parameter.

next_in_list:
        cmp     byte ptr es:[di],0ffh ; Are we at the end of the redir list ?
        jne     keep_checking
        mov     ax,FALSE              ; Indicate Volume not remote !
        jmp     IsRemoteDone

keep_checking:
        xor     cx,cx
        mov     cl,byte ptr es:[di]
        cmp     bx,cx
        je      Found_Remote
        inc     di
        jmp     short next_in_list

Game_Over_Man:
        mov     ax,NOT_SUPPORTED      ; Indicate no support in return value.
        jmp     short IsRemoteDone

Found_Remote:
        mov     ax,REMOTE             ; Indicate Volume is remote !

IsRemoteDone:

cEnd

;*--------------------------------------------------------------------------*
;*                                                                          *
;* int GetFixedDisks(int foo[26]);                                          *
;*                                                                          *
;* Returns the number of active LOCAL FIXED disk drives in the system AND   *
;* puts their indexes into rgiDrive[].                                      *
;*                                                                          *
;* ENTRY: Pointer to array of 26 integers.                                  *
;*                                                                          *
;* EXIT:  Returns the number of active LOCAL FIXED disk drives in the       *
;*        system puts their indexes into rgiDrive[].                        * 
;*                                                                          *
;* DESTROYS: AX. (preserves all registers except AX for return value)       *
;*                                                                          *
;* AUTHOR: MC                                                               *
;*                                                                          *
;*--------------------------------------------------------------------------*

cProc GetFixedDisks, <FAR, PUBLIC>, <BX,SI,DI>

ParmW   rgiDrive
localW  cRealDrives

cBegin
        ; Preserve the current drive setting.
        call    GetCurrentDrive
        mov     di,ax                ; Save original drive.

        xor     si,si                ; SI = iLogDrives = zero
        mov     cRealDrives,si       ; cRealDrives = zero

GDCLoop:
        ; Attempt to set the current drive to SI.
        
        push    si
        call    SetCurrentDrive

        ; Did it actually work?
        ;
        call    GetCurrentDrive
        cmp     ax,si
        jnz     GDC300                ; Nope, skip

        ;
        ; Is the drive remote ?
        ;

        push    si
        call    DosIsRemote
        cmp     ax,REMOTE             ; Is the drive remote ?
        je      GDC300

        ; Here we have found the drive is not Remote or we cannot tell if
        ; the drive is remote so lets find out if
        ; its removable before we add it to the cRealDrives list.
        
        mov     ax,4408h             ; IOCTL is removeable            
        mov     bx,si            
        inc     bx                   ; map from 0=A to 1=A            
        int     21h            
        jc      check_call           ; error, skip            
        or      al,al            
        jz      GDC300               ; removeable, skip            
        
        ; Store the drive number in rgiDrive[]
        mov     ax,rgiDrive
        mov     bx,cRealDrives
        inc     cRealDrives
        shl     bx,1
        add     bx,ax
        mov     word ptr [bx],si
        jmp     short GDC300

; We have a problem if IOCTL int 21h/4408h is not supported because then
; we have know way of knowing weather or not the machine in question really
; does have a fixed disk connected. Therefore, in this case, we'll give the
; user the benifit of the doubt and let them continue to install windows.
            
check_call:
        cmp     ax,1                 ; Is this call supported ?
        jnz     GDC300               ; If yes, continue on normally.
        mov     cRealDrives,1        ; If not, we better indicate we have
        jmp     short no_chance      ; a fixed disk and return.

GDC300:
        inc     si
        cmp     si,26                ; Loop through all 26 drives
        jne     GDCLoop

no_chance:
        ; Restore the original current drive.

        push    di                   ; Put pram on stack for call.
        call    SetCurrentDrive      ; Restore original drive.
        mov     ax,cRealDrives       ; Return num local drives in AX.
cEnd

;*--------------------------------------------------------------------------*
;*                                                                          *
;* BOOL DosRemoveable(char);                                                *
;*                                                                          *
;* ENTRY: Word iLDrive - Logical drive spec. A - Z. (case does not matter)  *
;*                                                                          *
;* EXIT:  BOOL Returns TRUE if media is removable. False if Remote or fixed *
;*                                                                          *
;* DESTROYS: AX. (preserves all registers except AX for return value)       *
;*                                                                          *
;* AUTHOR: MC                                                               *
;*                                                                          *
;*--------------------------------------------------------------------------*

cProc DosRemoveable, <FAR, PUBLIC>, <BX>

ParmW   iLDrive                     ; Logical Drive spec A - Z.

cBegin

        mov     bx,iLDrive          ; Grab the parameter.
        or      bx,20h              ; case insensitive.
        sub     bx,'a'              ; map to A=0
        push    bx                  ; Put param on stack for call.
        call    DosIsRemote         ; Find out if logical volume is remote
        or      ax,ax               ; check IsRemote return ?
        jnz     Remote_Or_Removable ; False ( 0 ) means local.

        ; Now we have found the volume is local, we can check to
        ; see if it's removable or not.
        
        mov     ax,4408h            ; IOCTL is removeable
        inc     bx                  ; Map from A=0 to A=1 ...
        int     21h
        jc      Remote_Or_Removable ; error, skip
        or      al,al
        jnz     Remote_Or_Removable ; NOT removeable
        inc     ax
        jnz     ir_exit

Remote_Or_Removable:
        xor     ax,ax               ; Return FALSE for remote or removable.

ir_exit:                            ; Finished.

cEnd

;*--------------------------------------------------------------------------*
;*                                                                          *
;*  MyReadWriteSector() -                                                   *
;*                                                                          *
;*--------------------------------------------------------------------------*

; Uses INT 13h to read/write an absolute sector.

cProc MyReadWriteSector, <PUBLIC, FAR>, <SI,DI>

ParmD   lpBuffer
ParmW   Function                       ; 02 for Read and 03 for Write
ParmW   Drive
ParmW   Cylinder
ParmW   Head
ParmW   Count

LocalW  wRetryCount 

cBegin
        ; Retry this operation three times.
        mov     wRetryCount,4

MRWS_TryAgain:
        mov     ax,Count                ; AL = Number of sectors
        mov     ah,byte ptr Function    ; AH = Function #
        mov     ch,byte ptr Cylinder    ; CH = Starting Cylinder
        mov     cl,1                    ; CL = Starting Sector

        mov     dx,Drive        ; DL = INT 13h drive designation

        mov     dh,byte ptr Head        ; DH = Head #
        les     bx,lpBuffer             ; ES:BX = Buffer
        int     13h
        
        mov     ax, 1                   ; success

        jnc     MRWS_End_success        ; Problems?
        dec     wRetryCount             ; Yup, retry
        jz      MRWS_End_fail           ; Are we out of retries?

        xor     ah,ah                   ; Nope, reset the disk
        mov     dx,Drive
        int     13h
        jmp     short MRWS_TryAgain
MRWS_End_fail:
        xor     al,al           ; AH contains the error code, if any.
MRWS_End_success:

cEnd

;*--------------------------------------------------------------------------*
;*                                                                          *
;*  GetCurrentVolume() -                                                    *
;*                                                                          *
;*--------------------------------------------------------------------------*

; Returns ZERO if successful.

cProc GetCurrentVolume, <FAR, PUBLIC>, <SI, DI>

ParmD lpszVol

cBegin
            push    ds

            ; Set the DTA
            mov     dx,offset DGROUP:DTA
            mov     ah,1Ah              ; Set DTA
            int     21h

            ; Get the current volume name.
            mov     dx,offset DGROUP:VolExtendedFCB
            mov     ah,11h              ; Search for First Entry
            int     21h
            test    al,al
            jnz     GVNoVol

            ; Copy volume name into buffer.
            les     di,lpszVol
            mov     al,'['
            stosb
            cld
            mov     si,offset DGROUP:DTA + 8
            mov     cl,11
GVLoop:
            lodsb
            cmp     al,' '
            jz      GVCont
            stosb
            loop    GVLoop
GVCont:
            mov     al,']'
            stosb

            ; NULL terminate.
            xor     ax,ax

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -