This is the code for reading :
Code: Select all
; ebx - base port of selected ATA/IDE channel
; eax - lba value
; ecx - sectors to read
; edi - address where to load data
command_packet times 12 db 0
load_sector_lba_cd :
push esi
push edx
push eax
push ecx
mov dx, bx
add dx, ERROR_FEATURES_OFFSET
xor al, al
out dx, al
sub dx, ERROR_FEATURES_OFFSET
add dx, LBA_MIDDLE_OFFSET
mov ax, ATAPI_SECTOR_SIZE
out dx, al
sub dx, LBA_MIDDLE_OFFSET
add dx, LBA_HIGH_OFFSET
shr ax, 8
out dx, al
sub dx, LBA_HIGH_OFFSET
add dx, COMMAND_STATUS_OFFSET
mov al, 0xa0 ;ATAPI_COMMAND_PACKET
out dx, al
call ata_status_wait
poll_for_drq_1 :
in al, dx
test al, ATA_ERROR_BIT
jnz end_of_reading
test al, ATA_DRQ_BIT
jz poll_for_drq_1
setup_command_packet :
pop ecx
pop eax
mov byte [command_packet], 0xa8 ;READ_ATAPI_COMMAND
mov edx, eax
shr edx, 24
mov byte [command_packet + 2], dl
mov edx, eax
shr edx, 16
mov byte [command_packet + 3], dl
mov edx, eax
shr edx, 8
mov byte [command_packet + 4], dl
mov edx, eax
shr edx, 0
mov byte [command_packet + 5], dl
;mov edx, ecx
;shr edx, 16
;mov byte [command_packet + 6], dl
;mov edx, ecx
;shr edx, 8
;mov byte [command_packet + 7], dl
;mov edx, ecx
;shr edx, 0
; mov byte [command_packet + 8], dl
mov byte [command_packet + 9], 1
push eax
push ecx
writing_command :
mov dx, bx
mov ecx, 6
mov esi, command_packet
rep outsw
wait_irq_atapi :
cmp byte [IRQ_received], 0
je wait_irq_atapi
mov byte [IRQ_received], 0
get_length_sector :
xor eax, eax
mov dx, bx
add dx, LBA_HIGH_OFFSET
in al, dx
shl ax, 8
sub dx, LBA_HIGH_OFFSET
add dx, LBA_MIDDLE_OFFSET
in al, dx
sub dx, LBA_MIDDLE_OFFSET
push eax
add dx, COMMAND_STATUS_OFFSET
in al, dx
read_data :
pop eax
mov dx, 0
mov cx, 2
div cx
mov ecx, eax
mov dx, bx
rep insw
wait_irq2_atapi :
cmp byte [IRQ_received], 0
je wait_irq2_atapi
mov byte [IRQ_received], 0
wait_drq_bsy_clear :
add dx, COMMAND_STATUS_OFFSET
call ata_status_wait
poll_for_drq_2:
in al, dx
test al, ATA_ERROR_BIT
jnz end_of_reading
test al, ATA_DRQ_BIT
jz end_of_reading
jnz poll_for_drq_2
end_of_reading :
pop ecx
pop eax
pop edx
pop esi
ret
Code: Select all
mov ebx, 0x170
mov al, 0x0
mov edx, 0x176
out dx, al
mov edi, KERNEL_OFFSET
mov ecx, 1
mov eax, 36
reading_loop :
inc eax
call load_sector_lba_cd
cmp eax, 66 ; some value beyond 40 kb size
jne reading_loop
call 0x200000
jmp $
KERNEL_OFFSET equ 0x200000
does somebody know a possible reason for that ?
upd. i have a question about cdrom splitting by sectors. what offset in bytes has second sector from start of cdrom ? and how bios can read only 512 bytes if cdrom's sector size is 2048 ?