259 lines
4.1 KiB
PHP
259 lines
4.1 KiB
PHP
;; File: ata.inc
|
|
;;
|
|
;; Usefull links:
|
|
;; - <ATA PIO Mode at https://wiki.osdev.org/ATA_PIO_Mode>
|
|
;; - <IDE spec at https://www.cpcwiki.eu/imgs/a/a2/IDE_SPEC.PDF>
|
|
|
|
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
|