; Project name : XTIDE Universal BIOS ; Description : Functions for creating Disk Parameter Table. ; Section containing code SECTION .text ;-------------------------------------------------------------------- ; Creates new Disk Parameter Table for detected hard disk. ; Drive is then fully accessible using any BIOS function. ; ; CreateDPT_FromAtaInformation ; Parameters: ; BH: Drive Select byte for Drive and Head Register ; ES:SI: Ptr to 512-byte ATA information read from the drive ; CS:BP: Ptr to IDEVARS for the controller ; DS: RAMVARS segment ; ES: BDA Segment ; Returns: ; DL: Drive number for new drive ; DS:DI: Ptr to Disk Parameter Table (if successful) ; CF: Cleared if DPT created successfully ; Set if any error ; Corrupts registers: ; AX, BX, CX, DH ;-------------------------------------------------------------------- CreateDPT_FromAtaInformation: call FindDPT_ForNewDriveToDSDI ; Fall to .InitializeDPT ;-------------------------------------------------------------------- ; .InitializeDPT ; Parameters: ; BH: Drive Select byte for Drive and Head Register ; DS:DI: Ptr to Disk Parameter Table ; CS:BP: Ptr to IDEVARS for the controller ; Returns: ; Nothing ; Corrupts registers: ; AX ;-------------------------------------------------------------------- .InitializeDPT: mov [di+DPT.bIdevarsOffset], bp ; IDEVARS must start in first 256 bytes of ROM ; Fall to .StoreDriveSelectAndDriveControlByte ;-------------------------------------------------------------------- ; .StoreDriveSelectAndDriveControlByte ; Parameters: ; BH: Drive Select byte for Drive and Head Register ; DS:DI: Ptr to Disk Parameter Table ; ES:SI: Ptr to 512-byte ATA information read from the drive ; CS:BP: Ptr to IDEVARS for the controller ; Returns: ; Nothing ; Corrupts registers: ; AX ;-------------------------------------------------------------------- .StoreDriveSelectAndDriveControlByte: mov al, bh and ax, BYTE FLG_DRVNHEAD_DRV ; AL now has Master/Slave bit cmp [cs:bp+IDEVARS.bIRQ], ah ; Interrupts enabled? jz SHORT .StoreFlags ; If not, do not set interrupt flag or al, FLGL_DPT_ENABLE_IRQ .StoreFlags: mov [di+DPT.wFlags], ax ; Fall to .StoreAddressing ;-------------------------------------------------------------------- ; .StoreAddressing ; Parameters: ; DS:DI: Ptr to Disk Parameter Table ; ES:SI: Ptr to 512-byte ATA information read from the drive ; CS:BP: Ptr to IDEVARS for the controller ; Returns: ; Nothing ; Corrupts registers: ; AX, BX, CX, DX ;-------------------------------------------------------------------- .StoreAddressing: ; Check if CHS defined in ROMVARS call AccessDPT_GetPointerToDRVPARAMStoCSBX test byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS ; User specified CHS? jnz SHORT .StoreUserDefinedPCHS ; Check if LBA supported call AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI test BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8 jz SHORT .StoreCHSfromAXBHBL ; Small old drive with CHS addressing only ; Store LBA 28/48 addressing and total sector count call AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI call StoreLbaAddressingAndTotalSectorCountFromBXDXAX ; Replace sector count with user defined if necessary call AccessDPT_GetPointerToDRVPARAMStoCSBX test BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA jz SHORT .KeepTotalSectorsFromAtaID mov ax, [cs:bx+DRVPARAMS.dwMaximumLBA] mov dx, [cs:bx+DRVPARAMS.dwMaximumLBA+2] xor bx, bx ; Compare user defined and ATA-ID sector count and select smaller cmp bx, [di+DPT.twLbaSectors+4] jb SHORT .StoreUserDefinedSectorCountToDPT cmp dx, [di+DPT.twLbaSectors+2] jb SHORT .StoreUserDefinedSectorCountToDPT ja SHORT .KeepTotalSectorsFromAtaID cmp ax, [di+DPT.twLbaSectors] jae SHORT .KeepTotalSectorsFromAtaID .StoreUserDefinedSectorCountToDPT: call StoreLbaAddressingAndTotalSectorCountFromBXDXAX ; Calculate L-CHS for old INT 13h .KeepTotalSectorsFromAtaID: mov bx, [di+DPT.twLbaSectors+4] ; Restore BX call AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH mov [di+DPT.bLbaHeads], bl jmp SHORT .StoreBlockMode ;-------------------------------------------------------------------- ; .StoreUserDefinedPCHS ; Parameters: ; DS:DI: Ptr to Disk Parameter Table ; ES:SI: Ptr to 512-byte ATA information read from the drive ; CS:BP: Ptr to IDEVARS for the controller ; Returns: ; AX: Number of P-CHS cylinders ; BH: Number of P-CHS sectors per track ; BL: Number of P-CHS heads ; Corrupts registers: ; Nothing ;-------------------------------------------------------------------- .StoreUserDefinedPCHS: call AccessDPT_GetPointerToDRVPARAMStoCSBX mov ax, [cs:bx+DRVPARAMS.wCylinders] mov bx, [cs:bx+DRVPARAMS.wHeadsAndSectors] ; Fall to .StoreCHSfromAXBHBL ;-------------------------------------------------------------------- ; .StoreCHSfromAXBHBL ; Parameters: ; AX: Number of P-CHS cylinders ; BH: Number of P-CHS sectors per track ; BL: Number of P-CHS heads ; DS:DI: Ptr to Disk Parameter Table ; ES:SI: Ptr to 512-byte ATA information read from the drive ; CS:BP: Ptr to IDEVARS for the controller ; Returns: ; AX: Number of P-CHS cylinders ; BH: Number of P-CHS sectors per track ; BL: Number of P-CHS heads ; Corrupts registers: ; CX ;-------------------------------------------------------------------- .StoreCHSfromAXBHBL: push ax push bx call AccessDPT_ShiftPCHinAXBLtoLCH ; Get number of bits to shift pop bx pop ax jcxz .StorePCHSfromAXDX ; Small drive so use L-CHS addressing ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation or cl, ADDRESSING_MODE_PCHS<