есть рабочий код который читает и пишет сектора в режиме PIO lba-28, можно ли его переделать под lba-48 используя 32 битный режим (в интернете нашел только для 64 битного) ниже код который успешно использую:
/* экспорт функции чтения и записи секторов из asm */ extern void ata_read_pio(); extern void ata_write_pio();
/* буфер для записи */ int bufw[15]; /* буфер для чтения */ int bufr[15]; /* кол-во секторов для чтения или записи */ uint32_t sect=1; /* адрес сектора куда писать или откуда читать */ uint32_t lbasec=3; /* жесткий диск подключен к мастеру */ uint32_t drive_hdd=0x00;
/* тестовая функция записи */ void testatawrite() { bufw[0]=70; bufw[1]=70; bufw[2]=69; bufw[3]=32; bufw[4]=32; bufw[5]=32; bufw[6]=32; bufw[7]=32; bufw[8]=32; bufw[9]=71; bufw[10]=68; bufw[11]=70; bufw[12]=70; bufw[13]=70; bufw[14]=70; bufw[15]=70; ata_write_pio(bufw, drive_hdd, lbasec, sect ); }
/* тестовая функция чтения */ void testataread() { ata_read_pio(bufr, drive_hdd, lbasec, sect); int systest=bufr[10]; printsys(systest, 300, 150, 0xffffff); }
функции из асма:
global ata_read_pio ata_read_pio: push ebp mov ebp, esp push edi push ebx pushf mov ecx, [ebp + 12] mov dx, cx and dx, ~1 mov dx, [ata_port_bases] add dx, 6 ; set specified drive & lba on & bits 24-27 of lba address mov al, cl and al, 1 shl al, 4 or al, 0xe0 mov ecx, [ebp + 16] shr ecx, 24 and cl, 0xf or al, cl out dx, al ; set sector count sub dx, 4 mov eax, [ebp + 20] out dx, al ; set bits 0-23 of lba address inc dx mov eax, [ebp + 16] out dx, al shr eax, 8 inc dx out dx, al shr eax, 8 inc dx out dx, al ; send read command add dx, 2 mov al, 0x20 out dx, al ; delay for 400ns for command to register mov ecx, 4 .delay400ns: in al, dx loop .delay400ns cld ; poll status while drive is busy .wait_until_done:
in al, dx test al, 0x80 jne .wait_until_done ; check for error in al, dx test al, 1 jne .return_err push es mov ax, gs mov es, ax ; read data mov ebx, [ebp + 20] mov edi, [ebp + 8] .read_loop: in al, dx test al, 8 je .read_loop_break sub dx, 7 mov ecx, 0x100 rep insw add dx, 7 dec ebx test ebx, ebx jne .read_loop .read_loop_break: pop es ; return mov ecx, [ebp + 8] mov eax, edi sub eax, ecx jmp .return .return_err: sub dx, 6 in al, dx or eax, 0xffffff00 .return: popf pop ebx pop edi pop ebp xor eax,eax xor ecx,ecx ret
; ata_write_pio(source, drive, lba, sector_count) global ata_write_pio ata_write_pio: push ebp mov ebp, esp push esi push ebx pushf mov ecx, [ebp + 12] mov dx, cx and dx, ~1 mov dx, [ata_port_bases] add dx, 6 ; set specified drive & lba on & bits 24-27 of lba address mov al, cl and al, 1 shl al, 4 or al, 0xe0 mov ecx, [ebp + 16] shr ecx, 24 and cl, 0xf or al, cl out dx, al ; set sector count sub dx, 4 mov eax, [ebp + 20] out dx, al ; set bits 0-23 of lba address inc dx mov eax, [ebp + 16] out dx, al shr eax, 8 inc dx out dx, al shr eax, 8 inc dx out dx, al ; send write command add dx, 2 mov al, 0x30 out dx, al ; delay for 400ns for command to register mov ecx, 4 .delay400ns: in al, dx loop .delay400ns cld ; poll status while drive is busy .wait_until_done:
in al, dx test al, 0x80 jne .wait_until_done ; check for error in al, dx test al, 1 jne .return_err push ds mov ax, gs mov ds, ax ; write data mov ebx, [ebp + 20] mov esi, [ebp + 8] .read_loop: in al, dx test al, 8 je .read_loop_break sub dx, 7 mov ecx, 0x100 rep outsw add dx, 7 dec ebx test ebx, ebx jne .read_loop .read_loop_break: pop ds ; return mov ecx, [ebp + 8] mov eax, esi sub eax, ecx jmp .return .return_err: sub dx, 6 in al, dx or eax, 0xffffff00 .return: popf pop ebx pop esi pop ebp ret
ata_port_bases: dw 0x1f0 dw 0x3f0 dw 0x170 dw 0x370 dw 0x1e8 dw 0x3e0 dw 0x168 dw 0x360
|