andyross@infopls.chi.il.us (Andrew Rossmann) (02/10/91)
  Some of the Int 25h routines posted here will fail miserably under DOS
3.31 and 4.0 if large partitions are present. The following code is from my
Infoplus program. It's sort of limited, but is at least a good starting
point.
;--------------------------------------------------------------------
;       INFOPLUS.ASM
;       Version 1.45
;               DISKREAD        - reads absolute sectors from disk
;       mods by Andrew Rossmann (2/9/91) (1.45 still under construction)
;--------------------------------------------------------------------
        public  DISKREAD
CODE    segment byte
DISKREAD        proc    far
assume cs:CODE, ds:DATA, es:nothing
;       On entry:
;
;               BP
;       SP =>   near return address
;               offset  of disk buffer
;               segment "   "     "
;               number of sectors to read
;               starting logical sector number
;               drive number (0=A, 1=B, etc.)
;
;       On exit:
;
;               AX      = function result
;                       00      - function successful
;                       01..FF  - DOS INT 25H error result
; Pascal format:
;   function diskread(drive: byte; starting_sector: longint;
;       number_of_sectors: word; var buffer): word; external
; WARNING! Some drivers such as Disk Manager can have 'logical' sectors
; that are > 512 bytes!! Make sure your buffer is big enough.
        drive                   equ     [bp + 16]
        starting_sector         equ     [bp + 12]
        number_of_sectors       equ     [bp + 10]
        buffer                  equ     [bp + 6]
        push    bp
        mov     bp,sp
        mov     ax,3000h                ;get DOS version
        int     21h
        cmp     al,4                    ;DOS 4?
        jge     read4                   ;We have 4 or newer, so use extended
        cmp     ax,1d04h                ;use old for anything less than 3.30
        jle     read3
;
;Check bit 1 of the device attributes bit. If it's set, then the driver
;supports use of the extended access method
;
        push    es                      ;save regs
        push    ds
        mov     dl,drive                ;get drive number (0=A,1=B,etc)
        inc     dl                      ;func uses 0=dflt, 1=A, etc..
        mov     ah,32h                  ;get driver parameter block
        int     21h
        push    ds                      ;move ds to es
        pop     es
        pop     ds                      ;restore original ds
        les     bx,[es:bx + 12h]        ;point ES:BX to device driver
        test    word ptr [es:bx + 4],2  ;test device attributes
        pop     es
        jz      read3                   ;wasn't, so use old method
read4:
        mov     al,drive
        mov     bx,starting_sector      ;copy info into parameter block
        mov     extd_starting_sector_lo,bx
        mov     bx,starting_sector + 2
        mov     extd_starting_sector_hi,bx
        mov     bx,number_of_sectors
        mov     extd_number_of_sectors,bx
        les     bx,buffer               ;get seg:ofs of buffer in ES:BX
        mov     extd_bufofs,bx          ;put into block
        mov     extd_bufseg,es
        mov     bx,offset dos4_block    ;DS:BX points to block
        mov     cx,-1                   ;-1 means extended read
        push    ds                      ;save DS (not really needed, but lets
                                        ;me share code with DOS 3 read.)
        jmp     short readit
read3:  mov     al,drive
        mov     dx,starting_sector
        mov     cx,number_of_sectors
        push    ds
        lds     bx,buffer               ;get seg:ofs of buffer in DS:BX
readit: int     25H
        inc     sp                      ; fix broken stack
        inc     sp
        pop     ds
        jc      short diskread_01
        xor     ax,ax
diskread_01:
        pop     bp
        ret     10
DISKREAD        endp
code    ends
;--------------------------------------------------------------------
DATA    segment byte
; storage for DISKREAD
; DOS 4.0 extended read parameter block
dos4_block                      label   byte
extd_starting_sector_lo         dw      ?
extd_starting_sector_hi         dw      ?
extd_number_of_sectors          dw      ?
extd_bufofs                     dw      ?
extd_bufseg                     dw      ?
DATA    ends
        end
---------------
Andrew Rossmann               | Sysop of Infoplus BBS, +1 708 537 0247
 andyross@infopls.chi.il.us   | Infoplus Support, latest version available
 uunet!ddsw1!infopls!andyross | by logging in as infoplus.dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (02/12/91)
In article <5eg5w1w163w@infopls.chi.il.us> andyross@infopls.chi.il.us (Andrew Rossmann) writes: > > Some of the Int 25h routines posted here will fail miserably under DOS >3.31 and 4.0 if large partitions are present. The following code is from my >Infoplus program. It's sort of limited, but is at least a good starting >point. Zenith 3.30 Plus (which reports itself as version 3.30) also supports the large partitions, so your code will fail on machines using it. A more reliable (but slower) test is to use DOS function 36h, Get Disk Information, to find the number of clusters and the sectors/cluster. Multiply these and if you have more than 64K of sectors, you need the large disk calls. (This is from Object Professional's detection method. They started out with the version test that you use, until I pointed out the problem. I highly recommend Object Professional from Turbopower software.) Duncan Murdoch dmurdoch@watstat.waterloo.edu
andyross@infopls.chi.il.us (Andrew Rossmann) (02/16/91)
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) writes: > In article <5eg5w1w163w@infopls.chi.il.us> andyross@infopls.chi.il.us (Andrew > > > > Some of the Int 25h routines posted here will fail miserably under DOS > >3.31 and 4.0 if large partitions are present. The following code is from my > >Infoplus program. It's sort of limited, but is at least a good starting > >point. > > Zenith 3.30 Plus (which reports itself as version 3.30) also supports the lar > partitions, so your code will fail on machines using it. A more reliable If any version between 3.30 and 3.99 is returned, my routine checks the device attribute word for the driver. Unless 3.30+ doesn't support that bit, it should work. It was a bug in that routine that was causing problems for many people. The check routine was looking at the word for one drive lower (B: if C: was current.) --------------- Andrew Rossmann | Sysop of Infoplus BBS, +1 708 537 0247 andyross@infopls.chi.il.us | Infoplus Support, latest version available uunet!ddsw1!infopls!andyross | by logging in as infoplus.