i get irq, i get everything...but bochs does not see this command. when i try to read the returned trasnfer length (from lbas registers) - it will return zero length. (and thanks, i will use something else instead of outsw) here is the complete source:
Code: Select all
atapi_readsec:
;ecx = lba
;bl = drive, 0 = master, 1 = slave
;edi = location, where to put data
cli
mov ecx, eax
mov ds, dx
mov es, dx
mov dx, ATA_DRIVSEL
xchg bx, bx
shl bl, 4
mov al, bl
out dx, al
call ata_wait_not_busy
xor al, al
mov dx, ATA_FEAT
out dx, al
mov ax, ATAPI_SECTOR_SIZE
and ax, 0xff
mov dx, ATA_ADDR2
out dx, ax
mov ax, ATAPI_SECTOR_SIZE
shr ax, 8
;mov dx, ATA_ADDR2
mov dx, ATA_ADDR3 ;?
out dx, ax
mov dx, ATA_COMMAND
mov al, 0xa0 ; packet command
out dx, al
mov dx, ATA_COMMAND
dev_bsy:
in al, dx
and al, 10000000b
cmp al, 10000000b
jz dev_bsy
mov dx, ATA_COMMAND
xchg bx, bx
nodrq:
in al, dx
test al, 1
jnz ata_failure
and al, 00001000b
cmp al, 8
jnz nodrq
mov word [sig0], 0xA8 ; read command
push ecx
shr ecx, 0x18
and ecx, 0xff
mov byte [sig2], cl
pop ecx
push ecx
shr ecx, 0x10
and ecx, 0xff
mov byte [sig3], cl
pop ecx
push ecx
shr ecx, 8
and ecx, 0xff
mov byte [sig4], cl
pop ecx
push ecx
and ecx, 0xff
mov byte [sig5], cl
pop ecx
call atapi_sendpacket2
mov dx, ATA_FEAT
in al, dx
mov eax, dword [ack1] ; irq
push ds
push word 0x10 ; ack1 address must have base 0
pop ds
sti
noirq:
cmp byte [ds:eax], 1 ; irq received fine
jnz noirq
pop ds
mov dx, ATA_ADDR3
in al, dx
shl al, 8
mov bl, al
mov dx, ATA_ADDR2
in al, dx
or bl, al
xor eax, eax
xor ecx, ecx
mov al, bl
mov bl, 2
div bl
mov cl, al ; returned zero length (because bochs ignored the atapi read command)
mov dx, 0x10
mov es, dx
mov dx, ATA_DATA
rep insw
mov dx, ATA_COMMAND
bsydrq:
in al, dx
and al, 0x88
cmp al, 0x88
jnz bsydrq
clc
ret
ata_failure:
mov esi, error_msg0
call prints
mov dx, ATA_FEAT
in al, dx
stc
ret