;; File: ata.inc ;; ;; Usefull links: ;; - ;; - ATA_PRIMARY_IO = 0x1F0 ATA_PRIMARY_IO_CTRL = 0x3F6 ATA_SECONDARY_IO = 0x170 ATA_SECONDARY_IO_CTRL = 0x376 ATA_CHAN0_IO = 0x1F0 ATA_CHAN1_IO = 0x170 ATA_CHAN2_IO = 0x1E8 ATA_CHAN3_IO = 0x168 ;; Constant: ATA_DATA ;; Read/Write data ATA_DATA = 0x0 ;; Constant: ATA_ERROR ;; ;; > ┌────┬─────┬────┬───┬────┬──┬───┬───┐ ;; > │AMNF│TKZNF│ABRT│MCR│IDNF│MC│UNC│BBK│ ;; > └────┴─────┴────┴───┴────┴──┴───┴───┘ ;; > 7 6 5 4 3 2 1 0 ;; ;; AMNF - Address mark not found. ;; TKZNF - Track zero not found. ;; ABRT - Aborted command. ;; MCR - Media change request. ;; IDNF - ID not found. ;; MC - Media changed ;; UNC - Uncorrectable data error. ;; BBK - Bad Block detected. ;; ATA_ERROR = 0x1 ATA_ERROR_AMNF = 0x01 ATA_ERROR_TKZNF = 0x02 ATA_ERROR_ABRT = 0x04 ATA_ERROR_MCR = 0x08 ATA_ERROR_IDNF = 0x10 ATA_ERROR_MC = 0x20 ATA_ERROR_UNC = 0x40 ATA_ERROR_BBK = 0x80 ;; Constant: ATA_FEATURES ATA_FEATURES = 0x1 ;; Constant: ATA_SECCOUNT ATA_SECCOUNT = 0x2 ;; Constant: ATA_SECNUM ATA_SECNUM = 0x3 ;; Constant: ATA_CYLLO ATA_CYLLO = 0x4 ;; Constant: ATA_CYLHI ATA_CYLHI = 0x5 ;; Constant: ATA_DRVHEAD ;; Drive/Head register ;; ATA_DRVHEAD = 0x6 ATA_DRVHEAD_DRV = 0x10 ATA_DRVHEAD_LBA = 0x40 ;; Constant: ATA_COMMAND ATA_COMMAND = 0x7 ;; Constant: ATA_CMD_RESTORE ;; Recalibrate ATA_CMD_RESTORE = 0x10 ;; Constant: ATA_CMD_DIAGNOSTIC ;; Execute device diagnostic ATA_CMD_DIAGNOSTIC = 0x90 ;; Constant: ATA_CMD_IDENTIFY ATA_CMD_IDENTIFY = 0xA0 ;; Constant: ATA_STATUS ;; ATA_STATUS = 0x7 ATA_STATUS_ERR = 0x01 ATA_STATUS_IDX = 0x02 ATA_STATUS_CORR = 0x04 ATA_STATUS_DRQ = 0x08 ATA_STATUS_SRV = 0x10 ATA_STATUS_DF = 0x20 ATA_STATUS_RDY = 0x40 ATA_STATUS_BSY = 0x80 ;; Constant: ATA_CTRL ;; Device control register (Control base + 0) ATA_CTRL = 0x0 ATA_CTRL_nIEN = 0x02 ATA_CTRL_SRST = 0x04 ATA_CTRL_HOB = 0x80 ;; Constant: ATA_DRVADDR ;; ATA_DRVADDR = 0x1 ATA_DRVADDR_DS0 = 0x01 ATA_DRVADDR_DS1 = 0x02 ATA_DRVADDR_WTG = 0x40 ;; Function: ata_wait ;; ;; In: ;; AX - IO port ;; ata_wait: mov dx, ax add dx, ATA_STATUS xor ecx, ecx @@: inc ecx cmp ecx, 5000 jg @f in al, dx and al, ATA_STATUS_BSY jnz @b @@: ret ;; Function: ata_select ata_select: ret ata_cmd: ret ;; Function: ata_probe ;; In: ;; AX - IO port ;; ata_probe: push bx mov bx, ax xor ecx, ecx .loop: push ecx call ata_wait pop ecx ; select drive mov dx, bx add dx, ATA_DRVHEAD mov al, cl shl al, 4 or al, 0xa0 out dx, al mov ax, bx push ecx call ata_wait pop ecx mov dx, bx add dx, ATA_COMMAND mov al, ATA_CMD_DIAGNOSTIC out dx, al mov ax, bx push ecx call ata_wait pop ecx mov dx, bx add dx, ATA_STATUS in al, dx and al, ATA_STATUS_ERR or ATA_STATUS_DRQ jnz .skip mov ax, bx push ecx call ata_wait pop ecx mov dx, bx add dx, ATA_COMMAND mov al, ATA_CMD_RESTORE out dx, al mov ax, bx push ecx call ata_wait pop ecx mov dx, bx add dx, ATA_STATUS in al, dx and al, ATA_STATUS_ERR or ATA_STATUS_DRQ jnz .skip push ecx cmp bx, ATA_CHAN1_IO jne @f add ecx, 2 jmp .drive_found @@: cmp bx, ATA_CHAN2_IO jne @f add ecx, 4 jmp .drive_found @@: cmp bx, ATA_CHAN3_IO jne @f add ecx, 8 jmp .drive_found @@: .drive_found: push ecx mov esi, szMsgAtaFound call klog pop ecx .skip: inc cl cmp cl, 2 jb .loop pop bx ret ;; Function: ata_init ata_init: mov ecx, aAtaChans @@: push ecx mov ax, word [ecx] call ata_probe pop ecx add ecx, 2 cmp ecx, aAtaChans.end jb @b ret ata_primary_irq: iret ata_secondary_irq: iret ata_device: db "ata", 0, 0, 0, 0, 0 dd ata_init aAtaChans: dw ATA_CHAN0_IO dw ATA_CHAN1_IO dw ATA_CHAN2_IO dw ATA_CHAN3_IO .end: ata_bdevsw: dd 0 szMsgAtaFound db "ATA: hd%u found", 0