INT 25H/26H: Absolute Disk Read/Write

                                                         Compatibility: 2.0+ 
 Expects:       (on drives < 32M and DOS < 4.0)
          AL    drive number (0=A, 1=B, etc.)
          CX    count of sectors to read
          DX    beginning sector (DOS logical sector number)
          DS:BX transfer address (destination or source buffer)

 Expects:       (on drives > 32M and DOS >= 4.0)
          AL    drive number (0=A, 1=B, etc.)
          CX    ffffH
          DX    beginning sector (DOS logical sector number)
          DS:BX address of a AbsDiskIORec structure.
          ──────────────────────────────────────────────────────────────────
 Returns: AX    special error code (see below) if CF is set to CY

                IMPORTANT! This interrupt leaves one word of data on the
                stack.  You must pop it off (see below).
          ──────────────────────────────────────────────────────────────────
    Info: These DOS services provide direct access to any disk sector
          available through DOS and installed block device drivers.

           ■  INT 25H reads sectors
           ■  INT 26H writes sectors

    CX,DX and...
    DS:BX Prior to DOS 4.0, CX specified the sector count and DS:BX pointed
          to the transfer buffer.  With DOS 4.0+, a mechanism was added to
          allow access to sector numbers higher than 65535 (the largest
          number than can fit in the 16-bit CX register).  The layout of
          the input parameters changes, depending upon the value in CX.  In
          summary:

          When CX is NOT equal to ffffH, it specifies now many sectors you
          want to read or write, DX indicates the starting sector, and
          DS:BX points the data buffer.  Note that values larger than about
          1024 (400H) are as much as can be read or written, given the
          constraints of conventional memory.

          When CX IS equal to ffffH, you must set DS:BX to point to an
          AbsDiskIORec structure which identifies the starting sector,
          desired number of sectors, and the location of the memory buffer.
          DX is ignored.

          Note: Most disks have a sector size of 512 bytes (½K), but you
                should not assume that size when allocating the transfer
                buffer.  Use fn 1cH or 32H to find the true sector size.

       DX (or AbsDiskIORec.lStartSect, when CX=ffffH) specifies the
          starting sector, using a DOS logical sector number.

          DOS logical sector 0 is the DOS boot sector (the first sector in
          the DOS partition).  Logical sector numbers increment first
          through each sector on a cylinder, then through each head, and
          finally through each cylinder on the drive (the exact layout is
          rarely important--just know that you can access any sector from 0
          through n, where n can be derived via fn 1cH or 32H).

          Notice that the Master Boot Record and any other sectors outside
          of the DOS partition are not available through this service.
          BIOS INT 13H provides complete access to all parts of a hard
          disk.  DOS 3.2+ device drivers provide direct access via fns
          440dH 41H (write track) and 440dH 61H (read track).

          See File Allocation Table for an overview of how DOS maps logical
          sector numbers to physical head/track/sector numbers and how to
          convert a cluster number into a logical sector number.

█▌Pop the Stack!▐█
  INT 25H and INT 26H both leave one 16-bit word of data on the stack (it is
  the Flags register that would have been used in an IRET, but was left
  there when DOS use a FAR RET to get back to your program.  An IRET was not
  used since that would overwrite the value in CF (used to indicate errors).

  Be sure to pop one word off of the stack upon return.  See the example,
  below.

█▌Error Codes▐█
  Errors occurring during INT 25H/26H are NOT handled by the INT 24H
  critical error handler.  Upon return from INT 25H or INT 26H, the Carry
  Flag set (CF=CY=1) when a error occurred.  When CF is set:

       AL is a device error code (00H-0cH). It is the same as bits 0-7 of
          DI upon INT 24H.

          Add 13H to this value (yielding 13H-1fH) and it will match one of
          the errors listed under DOS Error Codes.

       AH  is one of these values:
               80H = attachment failed to respond
               40H = disk seek operation failed
               08H = Bad CRC on diskette read
               04H = requested sector not found
               03H = Attempted write on write-protected diskette
               02H = some error other than these listed above

█▌Examples▐█
  Sample use of INT 25H to read the boot sector of a <32 MB diskette:

          mov   al,0      ;select drive A
          mov   dx,0      ;select the DOS Boot Sector
          mov   cx,1      ;read one sector ..
          lea   bx,myBuf  ; ... into buffer at DS:BX
          INT   25H
          pop   dx        ;discard the extra word on the stack
          jnc   noErr
          ...etc...       ;code to handle any disk error (code in AX)
   noErr: ...etc...       ;code continues when no error

  Sample use of INT 25H to read 20 sectors starting at logical sector 80,000
  of a >32 MB hard disk partition:

          mov   al,0                         ;select drive C
          lea   bx,  ioRec                   ;set up the local AbsDiskIORec
          mov   word ptr [bx],  14464        ;large sector number, low word
          mov   word ptr [bx+2],1            ;large sector number, high word
          mov   word ptr [bx+4],20           ;read 20 sectors
          mov   word ptr [bx+6],offset myBuf ;set buffer addr offset
          mov   word ptr [bx+8],seg myBuf    ;                segment
          INT   25H
          pop   dx        ;discard the extra word on the stack
          jnc   noErr
          ...etc...

█▌Diskette Duplication▐█
  DOS technical documents recommend avoiding INT 25H/26H whenever possible.
  For instance, to duplicate diskettes (as with the DOS Diskcopy command),
  it is better to use IOCTL Functions:

    Fn 440dH 61H (read track)
    Fn 440dH 42H (format and verify track)
    Fn 440dH 41H (write track)

  Of course, that only works if you are certain to be running under
  DOS 3.2 or later and the device driver supports IOCTL services.

See Also: INT 13H (ROM-BIOS disk access)
          fn 440dH 41H (write track)
          fn 440dH 61H (read track)
          File Allocation Table
          DOS Functions
                                    -♦-