title: Assembly interrupt problem: int 13h (ah = 42h) failed returning cf = 1, ah = 1
body: <p>I want to write a program in assembly language to read primary partitions of a hard disk. I Googled a lot last several days and I found that maybe int 13h (ah = 42h) is for me. But I failed at the beginning. After INT 13H was called, CF was set to 1 and AH was 1. From the docs I know the interrupt was failed.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>ASSUME CS:CodeSeg, DS:DataSeg, SS:StackSeg
  
  DataSeg SEGMENT
  
  BSBuffer:             ; Abbr for Boot Sector Buffer.
  MBRecord:             ; Master Boot Record.
      MBR DB 446 DUP (0)
  
  PartitionA:
      StatusA      DB 0 ;
      BeginHeadA   DB 0 ;
      BeginSeclynA DW 0 ;
      FileSystemA  DB 0 ;
      FinalHeadA   DB 0 ;
      FinalSeclynA DW 0 ;
      BeginSectorA DD 0 ;
      SectorCountA DD 0 ;
  
  PartitionB:
      StatusB      DB 0 ;
      BeginHeadB   DB 0 ;
      BeginSeclynB DW 0 ;
      FileSystemB  DB 0 ;
      FinalHeadB   DB 0 ;
      FinalSeclynB DW 0 ;
      BeginSectorB DD 0 ;
      SectorCountB DD 0 ;
  
  PartitionC:
      StatusC      DB 0 ;
      BeginHeadC   DB 0 ;
      BeginSeclynC DW 0 ;
      FileSystemC  DB 0 ;
      FinalHeadC   DB 0 ;
      FinalSeclynC DW 0 ;
      BeginSectorC DD 0 ;
      SectorCountC DD 0 ;
  
  PartitionD:
      StatusD      DB 0 ;
      BeginHeadD   DB 0 ;
      BeginSeclynD DW 0 ;
      FileSystemD  DB 0 ;
      FinalHeadD   DB 0 ;
      FinalSeclynD DW 0 ;
      BeginSectorD DD 0 ;
      SectorCountD DD 0 ;
  
  Validation:
      VALID DW 0 ; Should be 55AAH.
  
  ; DAPacket is used as the input parameter of ReadBootSector PROC
  
  DAPacket:                ; Abbr for Disk Address Packet.
      PacketSize    DB 16  ; Always 16.
      Reserved      DB 0   ; Reserved.
      SectorCount   DW 1   ; Should be 1 to read boot sector.
      BufferOffset  DW 0
      BufferSegment DW 0
      BlockNumber DB 8 DUP (0)
  
  DataSeg ENDS
  
  StackSeg SEGMENT
      DB 4096 DUP (0)
  StackSeg ENDS
  
  CodeSeg SEGMENT
  START:
  
      MOV AX, DataSeg
      MOV DS, AX
      MOV AX, StackSeg
      MOV SS, AX
      MOV SP, 4096
  
      MOV DL, 80H
      CALL ReadDisk
  
      MOV CX, VALID
  
      MOV AX, 4C00H
      INT 21H
  
  ; This process is used to read the boot sector of a given disk.
  ; Input:
  ;     DL - Disk ID, 0~79H for floppies, 80H~FFH for hds.
  ; Output:
  ;     BSBuffer - Boot sector of the disk indicated by DL.
  
  ReadDisk:
  
      PUSH AX
      PUSH SI
      MOV SI, DAPacket
      MOV PacketSize, 16
      MOV SectorCount, 1
      MOV BufferOffset, BSBuffer
      MOV BufferSegment, DataSeg
  
      MOV AH, 42H
  
      INT 13H
  
      POP SI
      POP AX
  
      RET
  
  CodeSeg ENDS
  END START
  </code></pre>
  
  <p>Thanks!</p>